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)
29 #ifdef _WIN32_WINNT_WINBLUE
30 #include <VersionHelpers.h>
37 #include "framegrabber.hxx"
39 #include <cppuhelper/supportsservice.hxx>
41 #define AVMEDIA_WIN_PLAYER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.Player_DirectX"
42 #define AVMEDIA_WIN_PLAYER_SERVICENAME "com.sun.star.media.Player_DirectX"
44 using namespace ::com::sun::star
;
46 namespace avmedia
{ namespace win
{
48 LRESULT CALLBACK
MediaPlayerWndProc_2( HWND hWnd
,UINT nMsg
, WPARAM nPar1
, LPARAM nPar2
)
50 Player
* pPlayer
= (Player
*) ::GetWindowLong( hWnd
, 0 );
51 bool bProcessed
= true;
57 case( WM_GRAPHNOTIFY
):
58 pPlayer
->processEvent();
68 return( bProcessed
? 0 : DefWindowProc( hWnd
, nMsg
, nPar1
, nPar2
) );
72 bool isWindowsVistaOrHigher()
74 // the Win32 SDK 8.1 deprecates GetVersionEx()
75 #ifdef _WIN32_WINNT_WINBLUE
76 return IsWindowsVistaOrGreater() ? true : false;
78 // POST: return true if we are at least on Windows Vista
80 ZeroMemory(&osvi
, sizeof(osvi
));
81 osvi
.dwOSVersionInfoSize
= sizeof(osvi
);
83 return osvi
.dwMajorVersion
>= 6;
91 Player::Player( const uno::Reference
< lang::XMultiServiceFactory
>& rxMgr
) :
92 Player_BASE(m_aMutex
),
104 mnUnmutedVolume( 0 ),
110 ::CoInitialize( NULL
);
116 ::DestroyWindow( (HWND
) mnFrameWnd
);
121 void SAL_CALL
Player::disposing()
123 ::osl::MutexGuard
aGuard(m_aMutex
);
142 mpME
->SetNotifyWindow( 0, WM_GRAPHNOTIFY
, 0);
159 bool Player::create( const OUString
& rURL
)
164 if( SUCCEEDED( hR
= CoCreateInstance( CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
, IID_IGraphBuilder
, (void**) &mpGB
) ) )
166 // Don't use the overlay mixer on Windows Vista
167 // It disables the desktop composition as soon as RenderFile is called
168 // also causes some other problems: video rendering is not reliable
169 if( !isWindowsVistaOrHigher() && SUCCEEDED( CoCreateInstance( CLSID_OverlayMixer
, NULL
, CLSCTX_INPROC_SERVER
, IID_IBaseFilter
, (void**) &mpOMF
) ) )
171 mpGB
->AddFilter( mpOMF
, L
"com_sun_star_media_OverlayMixerFilter" );
173 if( !SUCCEEDED( mpOMF
->QueryInterface( IID_IDDrawExclModeVideo
, (void**) &mpEV
) ) )
177 if( SUCCEEDED( hR
= mpGB
->RenderFile( reinterpret_cast<LPCWSTR
>(rURL
.getStr()), NULL
) ) &&
178 SUCCEEDED( hR
= mpGB
->QueryInterface( IID_IMediaControl
, (void**) &mpMC
) ) &&
179 SUCCEEDED( hR
= mpGB
->QueryInterface( IID_IMediaEventEx
, (void**) &mpME
) ) &&
180 SUCCEEDED( hR
= mpGB
->QueryInterface( IID_IMediaSeeking
, (void**) &mpMS
) ) &&
181 SUCCEEDED( hR
= mpGB
->QueryInterface( IID_IMediaPosition
, (void**) &mpMP
) ) )
184 mpGB
->QueryInterface( IID_IVideoWindow
, (void**) &mpVW
);
185 mpGB
->QueryInterface( IID_IBasicVideo
, (void**) &mpBV
);
188 mpGB
->QueryInterface( IID_IBasicAudio
, (void**) &mpBA
);
191 mpBA
->put_Volume( mnUnmutedVolume
);
205 const IVideoWindow
* Player::getVideoWindow() const
210 void Player::setNotifyWnd( int nNotifyWnd
)
214 mpME
->SetNotifyWindow( (OAHWND
) nNotifyWnd
, WM_GRAPHNOTIFY
, reinterpret_cast< LONG_PTR
>( this ) );
217 long Player::processEvent()
220 LONG_PTR nParam1
, nParam2
;
222 while( mpME
&& SUCCEEDED( mpME
->GetEvent( &nCode
, &nParam1
, &nParam2
, 0 ) ) )
224 if( EC_COMPLETE
== nCode
)
233 setMediaTime( getDuration() );
238 mpME
->FreeEventParams( nCode
, nParam1
, nParam2
);
244 void SAL_CALL
Player::start( )
245 throw (uno::RuntimeException
)
247 ::osl::MutexGuard
aGuard(m_aMutex
);
252 static WNDCLASS
* mpWndClass
= NULL
;
255 mpWndClass
= new WNDCLASS
;
257 memset( mpWndClass
, 0, sizeof( *mpWndClass
) );
258 mpWndClass
->hInstance
= GetModuleHandle( NULL
);
259 mpWndClass
->cbWndExtra
= sizeof( DWORD
);
260 mpWndClass
->lpfnWndProc
= MediaPlayerWndProc_2
;
261 mpWndClass
->lpszClassName
= "com_sun_star_media_Sound_Player";
262 mpWndClass
->hbrBackground
= (HBRUSH
) ::GetStockObject( BLACK_BRUSH
);
263 mpWndClass
->hCursor
= ::LoadCursor( NULL
, IDC_ARROW
);
265 ::RegisterClass( mpWndClass
);
269 mnFrameWnd
= (int) ::CreateWindow( mpWndClass
->lpszClassName
, NULL
,
272 (HWND
) NULL
, NULL
, mpWndClass
->hInstance
, 0 );
275 ::ShowWindow((HWND
) mnFrameWnd
, SW_HIDE
);
276 ::SetWindowLong( (HWND
) mnFrameWnd
, 0, (DWORD
) this );
277 // mpVW->put_Owner( (OAHWND) mnFrameWnd );
278 setNotifyWnd( mnFrameWnd
);
287 void SAL_CALL
Player::stop( )
288 throw (uno::RuntimeException
)
290 ::osl::MutexGuard
aGuard(m_aMutex
);
295 sal_Bool SAL_CALL
Player::isPlaying()
296 throw (uno::RuntimeException
)
298 ::osl::MutexGuard
aGuard(m_aMutex
);
300 OAFilterState eFilterState
;
303 if( mpMC
&& SUCCEEDED( mpMC
->GetState( 10, &eFilterState
) ) )
304 bRet
= ( State_Running
== eFilterState
);
309 double SAL_CALL
Player::getDuration( )
310 throw (uno::RuntimeException
)
312 ::osl::MutexGuard
aGuard(m_aMutex
);
314 REFTIME
aRefTime( 0.0 );
317 mpMP
->get_Duration( &aRefTime
);
322 void SAL_CALL
Player::setMediaTime( double fTime
)
323 throw (uno::RuntimeException
)
325 ::osl::MutexGuard
aGuard(m_aMutex
);
329 const bool bPlaying
= isPlaying();
331 mpMP
->put_CurrentPosition( fTime
);
333 if( !bPlaying
&& mpMC
)
334 mpMC
->StopWhenReady();
338 double SAL_CALL
Player::getMediaTime( )
339 throw (uno::RuntimeException
)
341 ::osl::MutexGuard
aGuard(m_aMutex
);
343 REFTIME
aRefTime( 0.0 );
346 mpMP
->get_CurrentPosition( &aRefTime
);
351 void SAL_CALL
Player::setPlaybackLoop( sal_Bool bSet
)
352 throw (uno::RuntimeException
)
354 ::osl::MutexGuard
aGuard(m_aMutex
);
359 sal_Bool SAL_CALL
Player::isPlaybackLoop( )
360 throw (uno::RuntimeException
)
362 ::osl::MutexGuard
aGuard(m_aMutex
);
367 void SAL_CALL
Player::setMute( sal_Bool bSet
)
368 throw (uno::RuntimeException
)
370 ::osl::MutexGuard
aGuard(m_aMutex
);
372 if (mpBA
&& (mbMuted
!= static_cast<bool>(bSet
)))
375 mpBA
->put_Volume( mbMuted
? -10000 : mnUnmutedVolume
);
379 sal_Bool SAL_CALL
Player::isMute( )
380 throw (uno::RuntimeException
)
382 ::osl::MutexGuard
aGuard(m_aMutex
);
387 void SAL_CALL
Player::setVolumeDB( sal_Int16 nVolumeDB
)
388 throw (uno::RuntimeException
)
390 ::osl::MutexGuard
aGuard(m_aMutex
);
392 mnUnmutedVolume
= static_cast< long >( nVolumeDB
) * 100;
394 if( !mbMuted
&& mpBA
)
395 mpBA
->put_Volume( mnUnmutedVolume
);
398 sal_Int16 SAL_CALL
Player::getVolumeDB( )
399 throw (uno::RuntimeException
)
401 ::osl::MutexGuard
aGuard(m_aMutex
);
403 return( static_cast< sal_Int16
>( mnUnmutedVolume
/ 100 ) );
406 awt::Size SAL_CALL
Player::getPreferredPlayerWindowSize( )
407 throw (uno::RuntimeException
)
409 ::osl::MutexGuard
aGuard(m_aMutex
);
411 awt::Size
aSize( 0, 0 );
415 long nWidth
= 0, nHeight
= 0;
417 mpBV
->GetVideoSize( &nWidth
, &nHeight
);
418 aSize
.Width
= nWidth
;
419 aSize
.Height
= nHeight
;
425 uno::Reference
< ::media::XPlayerWindow
> SAL_CALL
Player::createPlayerWindow( const uno::Sequence
< uno::Any
>& aArguments
)
426 throw (uno::RuntimeException
)
428 ::osl::MutexGuard
aGuard(m_aMutex
);
430 uno::Reference
< ::media::XPlayerWindow
> xRet
;
431 awt::Size
aSize( getPreferredPlayerWindowSize() );
433 if( mpVW
&& aSize
.Width
> 0 && aSize
.Height
> 0 )
435 ::avmedia::win::Window
* pWindow
= new ::avmedia::win::Window( mxMgr
, *this );
439 if( !pWindow
->create( aArguments
) )
440 xRet
= uno::Reference
< ::media::XPlayerWindow
>();
446 uno::Reference
< media::XFrameGrabber
> SAL_CALL
Player::createFrameGrabber( )
447 throw (uno::RuntimeException
)
449 uno::Reference
< media::XFrameGrabber
> xRet
;
451 if( !maURL
.isEmpty() )
453 FrameGrabber
* pGrabber
= new FrameGrabber( mxMgr
);
457 if( !pGrabber
->create( maURL
) )
464 OUString SAL_CALL
Player::getImplementationName( )
465 throw (uno::RuntimeException
)
467 return OUString( AVMEDIA_WIN_PLAYER_IMPLEMENTATIONNAME
);
470 sal_Bool SAL_CALL
Player::supportsService( const OUString
& ServiceName
)
471 throw (uno::RuntimeException
)
473 return cppu::supportsService(this, ServiceName
);
476 uno::Sequence
< OUString
> SAL_CALL
Player::getSupportedServiceNames( )
477 throw (uno::RuntimeException
)
479 uno::Sequence
< OUString
> aRet(1);
480 aRet
[0] = AVMEDIA_WIN_PLAYER_SERVICENAME
;
486 } // namespace avmedia
488 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */