1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
21 #pragma warning(push, 1)
22 #pragma warning(disable: 4917)
34 #include "framegrabber.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;
53 case( WM_GRAPHNOTIFY
):
54 pPlayer
->processEvent();
64 return( bProcessed
? 0 : DefWindowProc( hWnd
, nMsg
, nPar1
, nPar2
) );
68 bool isWindowsVistaOrHigher()
70 // POST: return true if we are at least on Windows Vista
72 ZeroMemory(&osvi
, sizeof(osvi
));
73 osvi
.dwOSVersionInfoSize
= sizeof(osvi
);
75 return osvi
.dwMajorVersion
>= 6;
82 Player::Player( const uno::Reference
< lang::XMultiServiceFactory
>& rxMgr
) :
83 Player_BASE(m_aMutex
),
99 mbAddWindow( sal_True
)
101 ::CoInitialize( NULL
);
104 // ------------------------------------------------------------------------------
109 ::DestroyWindow( (HWND
) mnFrameWnd
);
114 // ------------------------------------------------------------------------------
116 void SAL_CALL
Player::disposing()
118 ::osl::MutexGuard
aGuard(m_aMutex
);
137 mpME
->SetNotifyWindow( 0, WM_GRAPHNOTIFY
, 0);
153 // ------------------------------------------------------------------------------
154 bool Player::create( const OUString
& rURL
)
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
) ) )
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
) ) )
179 mpGB
->QueryInterface( IID_IVideoWindow
, (void**) &mpVW
);
180 mpGB
->QueryInterface( IID_IBasicVideo
, (void**) &mpBV
);
183 mpGB
->QueryInterface( IID_IBasicAudio
, (void**) &mpBA
);
186 mpBA
->put_Volume( mnUnmutedVolume
);
200 // ------------------------------------------------------------------------------
202 const IVideoWindow
* Player::getVideoWindow() const
207 // ------------------------------------------------------------------------------
209 void Player::setNotifyWnd( int nNotifyWnd
)
211 mbAddWindow
= sal_False
;
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()
232 LONG_PTR nParam1
, nParam2
;
234 while( mpME
&& SUCCEEDED( mpME
->GetEvent( &nCode
, &nParam1
, &nParam2
, 0 ) ) )
236 if( EC_COMPLETE
== nCode
)
245 setMediaTime( getDuration() );
250 mpME
->FreeEventParams( nCode
, nParam1
, nParam2
);
256 // ------------------------------------------------------------------------------
258 void SAL_CALL
Player::start( )
259 throw (uno::RuntimeException
)
261 ::osl::MutexGuard
aGuard(m_aMutex
);
266 static WNDCLASS
* mpWndClass
= NULL
;
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
);
283 mnFrameWnd
= (int) ::CreateWindow( mpWndClass
->lpszClassName
, NULL
,
286 (HWND
) NULL
, NULL
, mpWndClass
->hInstance
, 0 );
289 ::ShowWindow((HWND
) mnFrameWnd
, SW_HIDE
);
290 ::SetWindowLong( (HWND
) mnFrameWnd
, 0, (DWORD
) this );
291 // mpVW->put_Owner( (OAHWND) mnFrameWnd );
292 setNotifyWnd( mnFrameWnd
);
301 // ------------------------------------------------------------------------------
303 void SAL_CALL
Player::stop( )
304 throw (uno::RuntimeException
)
306 ::osl::MutexGuard
aGuard(m_aMutex
);
311 // ------------------------------------------------------------------------------
313 sal_Bool SAL_CALL
Player::isPlaying()
314 throw (uno::RuntimeException
)
316 ::osl::MutexGuard
aGuard(m_aMutex
);
318 OAFilterState eFilterState
;
321 if( mpMC
&& SUCCEEDED( mpMC
->GetState( 10, &eFilterState
) ) )
322 bRet
= ( State_Running
== eFilterState
);
327 // ------------------------------------------------------------------------------
329 double SAL_CALL
Player::getDuration( )
330 throw (uno::RuntimeException
)
332 ::osl::MutexGuard
aGuard(m_aMutex
);
334 REFTIME
aRefTime( 0.0 );
337 mpMP
->get_Duration( &aRefTime
);
342 // ------------------------------------------------------------------------------
344 void SAL_CALL
Player::setMediaTime( double fTime
)
345 throw (uno::RuntimeException
)
347 ::osl::MutexGuard
aGuard(m_aMutex
);
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 );
370 mpMP
->get_CurrentPosition( &aRefTime
);
375 // ------------------------------------------------------------------------------
377 double SAL_CALL
Player::getRate( )
378 throw (uno::RuntimeException
)
380 ::osl::MutexGuard
aGuard(m_aMutex
);
385 mpMP
->get_Rate( &fRet
);
390 // ------------------------------------------------------------------------------
392 void SAL_CALL
Player::setPlaybackLoop( sal_Bool bSet
)
393 throw (uno::RuntimeException
)
395 ::osl::MutexGuard
aGuard(m_aMutex
);
400 // ------------------------------------------------------------------------------
402 sal_Bool SAL_CALL
Player::isPlaybackLoop( )
403 throw (uno::RuntimeException
)
405 ::osl::MutexGuard
aGuard(m_aMutex
);
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
)))
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
);
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 );
468 long nWidth
= 0, nHeight
= 0;
470 mpBV
->GetVideoSize( &nWidth
, &nHeight
);
471 aSize
.Width
= nWidth
;
472 aSize
.Height
= nHeight
;
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 );
494 if( !pWindow
->create( aArguments
) )
495 xRet
= uno::Reference
< ::media::XPlayerWindow
>();
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
);
514 if( !pGrabber
->create( maURL
) )
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
;
549 } // namespace avmedia
551 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */