Updated core
[LibreOffice.git] / avmedia / source / win / player.cxx
blobf91c906d930bae4f89069cbe823ab3564a24ad25
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #if defined _MSC_VER
21 #pragma warning(push, 1)
22 #pragma warning(disable: 4917)
23 #endif
24 #include <objbase.h>
25 #include <strmif.h>
26 #include <control.h>
27 #include <uuids.h>
28 #include <evcode.h>
29 #if defined _MSC_VER
30 #pragma warning(pop)
31 #endif
33 #include "player.hxx"
34 #include "framegrabber.hxx"
35 #include "window.hxx"
37 #define AVMEDIA_WIN_PLAYER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.Player_DirectX"
38 #define AVMEDIA_WIN_PLAYER_SERVICENAME "com.sun.star.media.Player_DirectX"
40 using namespace ::com::sun::star;
42 namespace avmedia { namespace win {
44 LRESULT CALLBACK MediaPlayerWndProc_2( HWND hWnd,UINT nMsg, WPARAM nPar1, LPARAM nPar2 )
46 Player* pPlayer = (Player*) ::GetWindowLong( hWnd, 0 );
47 bool bProcessed = true;
49 if( pPlayer )
51 switch( nMsg )
53 case( WM_GRAPHNOTIFY ):
54 pPlayer->processEvent();
55 break;
56 default:
57 bProcessed = false;
58 break;
61 else
62 bProcessed = false;
64 return( bProcessed ? 0 : DefWindowProc( hWnd, nMsg, nPar1, nPar2 ) );
68 bool isWindowsVistaOrHigher()
70 // POST: return true if we are at least on Windows Vista
71 OSVERSIONINFO osvi;
72 ZeroMemory(&osvi, sizeof(osvi));
73 osvi.dwOSVersionInfoSize = sizeof(osvi);
74 GetVersionEx(&osvi);
75 return osvi.dwMajorVersion >= 6;
78 // ----------------
79 // - Player -
80 // ----------------
82 Player::Player( const uno::Reference< lang::XMultiServiceFactory >& rxMgr ) :
83 Player_BASE(m_aMutex),
84 mxMgr( rxMgr ),
85 mpGB( NULL ),
86 mpOMF( NULL ),
87 mpMC( NULL ),
88 mpME( NULL ),
89 mpMS( NULL ),
90 mpMP( NULL ),
91 mpBA( NULL ),
92 mpBV( NULL ),
93 mpVW( NULL ),
94 mpEV( NULL ),
95 mnUnmutedVolume( 0 ),
96 mnFrameWnd( 0 ),
97 mbMuted( false ),
98 mbLooping( false ),
99 mbAddWindow( sal_True )
101 ::CoInitialize( NULL );
104 // ------------------------------------------------------------------------------
106 Player::~Player()
108 if( mnFrameWnd )
109 ::DestroyWindow( (HWND) mnFrameWnd );
111 ::CoUninitialize();
114 // ------------------------------------------------------------------------------
116 void SAL_CALL Player::disposing()
118 ::osl::MutexGuard aGuard(m_aMutex);
119 stop();
120 if( mpBA )
121 mpBA->Release();
123 if( mpBV )
124 mpBV->Release();
126 if( mpVW )
127 mpVW->Release();
129 if( mpMP )
130 mpMP->Release();
132 if( mpMS )
133 mpMS->Release();
135 if( mpME )
137 mpME->SetNotifyWindow( 0, WM_GRAPHNOTIFY, 0);
138 mpME->Release();
141 if( mpMC )
142 mpMC->Release();
144 if( mpEV )
145 mpEV->Release();
147 if( mpOMF )
148 mpOMF->Release();
150 if( mpGB )
151 mpGB->Release();
153 // ------------------------------------------------------------------------------
154 bool Player::create( const OUString& rURL )
156 HRESULT hR;
157 bool bRet = false;
159 if( SUCCEEDED( hR = CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**) &mpGB ) ) )
161 // Don't use the overlay mixer on Windows Vista
162 // It disables the desktop composition as soon as RenderFile is called
163 // also causes some other problems: video rendering is not reliable
164 if( !isWindowsVistaOrHigher() && SUCCEEDED( CoCreateInstance( CLSID_OverlayMixer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**) &mpOMF ) ) )
166 mpGB->AddFilter( mpOMF, L"com_sun_star_media_OverlayMixerFilter" );
168 if( !SUCCEEDED( mpOMF->QueryInterface( IID_IDDrawExclModeVideo, (void**) &mpEV ) ) )
169 mpEV = NULL;
172 if( SUCCEEDED( hR = mpGB->RenderFile( reinterpret_cast<LPCWSTR>(rURL.getStr()), NULL ) ) &&
173 SUCCEEDED( hR = mpGB->QueryInterface( IID_IMediaControl, (void**) &mpMC ) ) &&
174 SUCCEEDED( hR = mpGB->QueryInterface( IID_IMediaEventEx, (void**) &mpME ) ) &&
175 SUCCEEDED( hR = mpGB->QueryInterface( IID_IMediaSeeking, (void**) &mpMS ) ) &&
176 SUCCEEDED( hR = mpGB->QueryInterface( IID_IMediaPosition, (void**) &mpMP ) ) )
178 // Video interfaces
179 mpGB->QueryInterface( IID_IVideoWindow, (void**) &mpVW );
180 mpGB->QueryInterface( IID_IBasicVideo, (void**) &mpBV );
182 // Audio interface
183 mpGB->QueryInterface( IID_IBasicAudio, (void**) &mpBA );
185 if( mpBA )
186 mpBA->put_Volume( mnUnmutedVolume );
188 bRet = true;
192 if( bRet )
193 maURL = rURL;
194 else
195 maURL = OUString();
197 return bRet;
200 // ------------------------------------------------------------------------------
202 const IVideoWindow* Player::getVideoWindow() const
204 return mpVW;
207 // ------------------------------------------------------------------------------
209 void Player::setNotifyWnd( int nNotifyWnd )
211 mbAddWindow = sal_False;
212 if( mpME )
213 mpME->SetNotifyWindow( (OAHWND) nNotifyWnd, WM_GRAPHNOTIFY, reinterpret_cast< LONG_PTR>( this ) );
216 // ------------------------------------------------------------------------------
218 void Player::setDDrawParams( IDirectDraw* pDDraw, IDirectDrawSurface* pDDrawSurface )
220 if( mpEV && pDDraw && pDDrawSurface )
222 mpEV->SetDDrawObject( pDDraw );
223 mpEV->SetDDrawSurface( pDDrawSurface );
227 // ------------------------------------------------------------------------------
229 long Player::processEvent()
231 long nCode;
232 LONG_PTR nParam1, nParam2;
234 while( mpME && SUCCEEDED( mpME->GetEvent( &nCode, &nParam1, &nParam2, 0 ) ) )
236 if( EC_COMPLETE == nCode )
238 if( mbLooping )
240 setMediaTime( 0.0 );
241 start();
243 else
245 setMediaTime( getDuration() );
246 stop();
250 mpME->FreeEventParams( nCode, nParam1, nParam2 );
253 return 0;
256 // ------------------------------------------------------------------------------
258 void SAL_CALL Player::start( )
259 throw (uno::RuntimeException)
261 ::osl::MutexGuard aGuard(m_aMutex);
262 if( mpMC )
264 if ( mbAddWindow )
266 static WNDCLASS* mpWndClass = NULL;
267 if ( !mpWndClass )
269 mpWndClass = new WNDCLASS;
271 memset( mpWndClass, 0, sizeof( *mpWndClass ) );
272 mpWndClass->hInstance = GetModuleHandle( NULL );
273 mpWndClass->cbWndExtra = sizeof( DWORD );
274 mpWndClass->lpfnWndProc = MediaPlayerWndProc_2;
275 mpWndClass->lpszClassName = "com_sun_star_media_Sound_Player";
276 mpWndClass->hbrBackground = (HBRUSH) ::GetStockObject( BLACK_BRUSH );
277 mpWndClass->hCursor = ::LoadCursor( NULL, IDC_ARROW );
279 ::RegisterClass( mpWndClass );
281 if ( !mnFrameWnd )
283 mnFrameWnd = (int) ::CreateWindow( mpWndClass->lpszClassName, NULL,
285 0, 0, 0, 0,
286 (HWND) NULL, NULL, mpWndClass->hInstance, 0 );
287 if ( mnFrameWnd )
289 ::ShowWindow((HWND) mnFrameWnd, SW_HIDE);
290 ::SetWindowLong( (HWND) mnFrameWnd, 0, (DWORD) this );
291 // mpVW->put_Owner( (OAHWND) mnFrameWnd );
292 setNotifyWnd( mnFrameWnd );
297 mpMC->Run();
301 // ------------------------------------------------------------------------------
303 void SAL_CALL Player::stop( )
304 throw (uno::RuntimeException)
306 ::osl::MutexGuard aGuard(m_aMutex);
307 if( mpMC )
308 mpMC->Stop();
311 // ------------------------------------------------------------------------------
313 sal_Bool SAL_CALL Player::isPlaying()
314 throw (uno::RuntimeException)
316 ::osl::MutexGuard aGuard(m_aMutex);
318 OAFilterState eFilterState;
319 bool bRet = false;
321 if( mpMC && SUCCEEDED( mpMC->GetState( 10, &eFilterState ) ) )
322 bRet = ( State_Running == eFilterState );
324 return bRet;
327 // ------------------------------------------------------------------------------
329 double SAL_CALL Player::getDuration( )
330 throw (uno::RuntimeException)
332 ::osl::MutexGuard aGuard(m_aMutex);
334 REFTIME aRefTime( 0.0 );
336 if( mpMP )
337 mpMP->get_Duration( &aRefTime );
339 return aRefTime;
342 // ------------------------------------------------------------------------------
344 void SAL_CALL Player::setMediaTime( double fTime )
345 throw (uno::RuntimeException)
347 ::osl::MutexGuard aGuard(m_aMutex);
349 if( mpMP )
351 const bool bPlaying = isPlaying();
353 mpMP->put_CurrentPosition( fTime );
355 if( !bPlaying && mpMC )
356 mpMC->StopWhenReady();
360 // ------------------------------------------------------------------------------
362 double SAL_CALL Player::getMediaTime( )
363 throw (uno::RuntimeException)
365 ::osl::MutexGuard aGuard(m_aMutex);
367 REFTIME aRefTime( 0.0 );
369 if( mpMP )
370 mpMP->get_CurrentPosition( &aRefTime );
372 return aRefTime;
375 // ------------------------------------------------------------------------------
377 double SAL_CALL Player::getRate( )
378 throw (uno::RuntimeException)
380 ::osl::MutexGuard aGuard(m_aMutex);
382 double fRet( 0.0 );
384 if( mpMP )
385 mpMP->get_Rate( &fRet );
387 return fRet;
390 // ------------------------------------------------------------------------------
392 void SAL_CALL Player::setPlaybackLoop( sal_Bool bSet )
393 throw (uno::RuntimeException)
395 ::osl::MutexGuard aGuard(m_aMutex);
397 mbLooping = bSet;
400 // ------------------------------------------------------------------------------
402 sal_Bool SAL_CALL Player::isPlaybackLoop( )
403 throw (uno::RuntimeException)
405 ::osl::MutexGuard aGuard(m_aMutex);
407 return mbLooping;
410 // ------------------------------------------------------------------------------
412 void SAL_CALL Player::setMute( sal_Bool bSet )
413 throw (uno::RuntimeException)
415 ::osl::MutexGuard aGuard(m_aMutex);
417 if (mpBA && (mbMuted != static_cast<bool>(bSet)))
419 mbMuted = bSet;
420 mpBA->put_Volume( mbMuted ? -10000 : mnUnmutedVolume );
424 // ------------------------------------------------------------------------------
426 sal_Bool SAL_CALL Player::isMute( )
427 throw (uno::RuntimeException)
429 ::osl::MutexGuard aGuard(m_aMutex);
431 return mbMuted;
434 // ------------------------------------------------------------------------------
436 void SAL_CALL Player::setVolumeDB( sal_Int16 nVolumeDB )
437 throw (uno::RuntimeException)
439 ::osl::MutexGuard aGuard(m_aMutex);
441 mnUnmutedVolume = static_cast< long >( nVolumeDB ) * 100;
443 if( !mbMuted && mpBA )
444 mpBA->put_Volume( mnUnmutedVolume );
447 // ------------------------------------------------------------------------------
449 sal_Int16 SAL_CALL Player::getVolumeDB( )
450 throw (uno::RuntimeException)
452 ::osl::MutexGuard aGuard(m_aMutex);
454 return( static_cast< sal_Int16 >( mnUnmutedVolume / 100 ) );
457 // ------------------------------------------------------------------------------
459 awt::Size SAL_CALL Player::getPreferredPlayerWindowSize( )
460 throw (uno::RuntimeException)
462 ::osl::MutexGuard aGuard(m_aMutex);
464 awt::Size aSize( 0, 0 );
466 if( mpBV )
468 long nWidth = 0, nHeight = 0;
470 mpBV->GetVideoSize( &nWidth, &nHeight );
471 aSize.Width = nWidth;
472 aSize.Height = nHeight;
475 return aSize;
478 // ------------------------------------------------------------------------------
480 uno::Reference< ::media::XPlayerWindow > SAL_CALL Player::createPlayerWindow( const uno::Sequence< uno::Any >& aArguments )
481 throw (uno::RuntimeException)
483 ::osl::MutexGuard aGuard(m_aMutex);
485 uno::Reference< ::media::XPlayerWindow > xRet;
486 awt::Size aSize( getPreferredPlayerWindowSize() );
488 if( mpVW && aSize.Width > 0 && aSize.Height > 0 )
490 ::avmedia::win::Window* pWindow = new ::avmedia::win::Window( mxMgr, *this );
492 xRet = pWindow;
494 if( !pWindow->create( aArguments ) )
495 xRet = uno::Reference< ::media::XPlayerWindow >();
498 return xRet;
501 // ------------------------------------------------------------------------------
503 uno::Reference< media::XFrameGrabber > SAL_CALL Player::createFrameGrabber( )
504 throw (uno::RuntimeException)
506 uno::Reference< media::XFrameGrabber > xRet;
508 if( maURL.getLength() > 0 )
510 FrameGrabber* pGrabber = new FrameGrabber( mxMgr );
512 xRet = pGrabber;
514 if( !pGrabber->create( maURL ) )
515 xRet.clear();
518 return xRet;
521 // ------------------------------------------------------------------------------
523 OUString SAL_CALL Player::getImplementationName( )
524 throw (uno::RuntimeException)
526 return OUString( AVMEDIA_WIN_PLAYER_IMPLEMENTATIONNAME );
529 // ------------------------------------------------------------------------------
531 sal_Bool SAL_CALL Player::supportsService( const OUString& ServiceName )
532 throw (uno::RuntimeException)
534 return ServiceName == AVMEDIA_WIN_PLAYER_SERVICENAME;
537 // ------------------------------------------------------------------------------
539 uno::Sequence< OUString > SAL_CALL Player::getSupportedServiceNames( )
540 throw (uno::RuntimeException)
542 uno::Sequence< OUString > aRet(1);
543 aRet[0] = AVMEDIA_WIN_PLAYER_SERVICENAME ;
545 return aRet;
548 } // namespace win
549 } // namespace avmedia
551 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */