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 .
27 #include "framegrabber.hxx"
29 #include <cppuhelper/supportsservice.hxx>
30 #include <o3tl/char16_t2wchar_t.hxx>
32 #define AVMEDIA_WIN_PLAYER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.Player_DirectX"
33 #define AVMEDIA_WIN_PLAYER_SERVICENAME "com.sun.star.media.Player_DirectX"
35 using namespace ::com::sun::star
;
37 namespace avmedia
{ namespace win
{
39 static LRESULT CALLBACK
MediaPlayerWndProc_2( HWND hWnd
,UINT nMsg
, WPARAM nPar1
, LPARAM nPar2
)
41 Player
* pPlayer
= reinterpret_cast<Player
*>(::GetWindowLongPtrW( hWnd
, 0 ));
42 bool bProcessed
= true;
49 pPlayer
->processEvent();
59 return( bProcessed
? 0 : DefWindowProcW( hWnd
, nMsg
, nPar1
, nPar2
) );
63 Player::Player( const uno::Reference
< lang::XMultiServiceFactory
>& rxMgr
) :
64 Player_BASE(m_aMutex
),
77 mnFrameWnd( nullptr ),
82 ::CoInitialize( nullptr );
89 ::DestroyWindow( mnFrameWnd
);
95 void SAL_CALL
Player::disposing()
97 ::osl::MutexGuard
aGuard(m_aMutex
);
116 mpME
->SetNotifyWindow( 0, WM_GRAPHNOTIFY
, 0);
134 bool Player::create( const OUString
& rURL
)
139 if( SUCCEEDED( hR
= CoCreateInstance( CLSID_FilterGraph
, nullptr, CLSCTX_INPROC_SERVER
, IID_IGraphBuilder
, reinterpret_cast<void**>(&mpGB
) ) ) )
141 // Don't use the overlay mixer on Windows Vista
142 // It disables the desktop composition as soon as RenderFile is called
143 // also causes some other problems: video rendering is not reliable
145 if( SUCCEEDED( hR
= mpGB
->RenderFile( o3tl::toW(rURL
.getStr()), nullptr ) ) &&
146 SUCCEEDED( hR
= mpGB
->QueryInterface( IID_IMediaControl
, reinterpret_cast<void**>(&mpMC
) ) ) &&
147 SUCCEEDED( hR
= mpGB
->QueryInterface( IID_IMediaEventEx
, reinterpret_cast<void**>(&mpME
) ) ) &&
148 SUCCEEDED( hR
= mpGB
->QueryInterface( IID_IMediaSeeking
, reinterpret_cast<void**>(&mpMS
) ) ) &&
149 SUCCEEDED( hR
= mpGB
->QueryInterface( IID_IMediaPosition
, reinterpret_cast<void**>(&mpMP
) ) ) )
152 mpGB
->QueryInterface( IID_IVideoWindow
, reinterpret_cast<void**>(&mpVW
) );
153 mpGB
->QueryInterface( IID_IBasicVideo
, reinterpret_cast<void**>(&mpBV
) );
156 mpGB
->QueryInterface( IID_IBasicAudio
, reinterpret_cast<void**>(&mpBA
) );
159 mpBA
->put_Volume( mnUnmutedVolume
);
174 const IVideoWindow
* Player::getVideoWindow() const
180 void Player::setNotifyWnd( HWND nNotifyWnd
)
184 mpME
->SetNotifyWindow( reinterpret_cast<OAHWND
>(nNotifyWnd
), WM_GRAPHNOTIFY
, reinterpret_cast< LONG_PTR
>( this ) );
188 long Player::processEvent()
191 LONG_PTR nParam1
, nParam2
;
193 while( mpME
&& SUCCEEDED( mpME
->GetEvent( &nCode
, &nParam1
, &nParam2
, 0 ) ) )
195 if( EC_COMPLETE
== nCode
)
204 setMediaTime( getDuration() );
209 mpME
->FreeEventParams( nCode
, nParam1
, nParam2
);
216 void SAL_CALL
Player::start( )
218 ::osl::MutexGuard
aGuard(m_aMutex
);
223 static WNDCLASSW
* mpWndClass
= nullptr;
226 mpWndClass
= new WNDCLASSW
;
228 memset( mpWndClass
, 0, sizeof( *mpWndClass
) );
229 mpWndClass
->hInstance
= GetModuleHandleW( nullptr );
230 mpWndClass
->cbWndExtra
= sizeof( DWORD
);
231 mpWndClass
->lpfnWndProc
= MediaPlayerWndProc_2
;
232 mpWndClass
->lpszClassName
= L
"com_sun_star_media_Sound_Player";
233 mpWndClass
->hbrBackground
= static_cast<HBRUSH
>(::GetStockObject( BLACK_BRUSH
));
234 mpWndClass
->hCursor
= ::LoadCursor( nullptr, IDC_ARROW
);
236 RegisterClassW( mpWndClass
);
240 mnFrameWnd
= CreateWindowW( mpWndClass
->lpszClassName
, nullptr,
243 nullptr, nullptr, mpWndClass
->hInstance
, nullptr );
246 ::ShowWindow(mnFrameWnd
, SW_HIDE
);
247 SetWindowLongPtrW( mnFrameWnd
, 0, reinterpret_cast<LONG_PTR
>(this) );
248 // mpVW->put_Owner( (OAHWND) mnFrameWnd );
249 setNotifyWnd( mnFrameWnd
);
259 void SAL_CALL
Player::stop( )
261 ::osl::MutexGuard
aGuard(m_aMutex
);
267 sal_Bool SAL_CALL
Player::isPlaying()
269 ::osl::MutexGuard
aGuard(m_aMutex
);
271 OAFilterState eFilterState
;
274 if( mpMC
&& SUCCEEDED( mpMC
->GetState( 10, &eFilterState
) ) )
275 bRet
= ( State_Running
== eFilterState
);
281 double SAL_CALL
Player::getDuration( )
283 ::osl::MutexGuard
aGuard(m_aMutex
);
285 REFTIME
aRefTime( 0.0 );
288 mpMP
->get_Duration( &aRefTime
);
294 void SAL_CALL
Player::setMediaTime( double fTime
)
296 ::osl::MutexGuard
aGuard(m_aMutex
);
300 const bool bPlaying
= isPlaying();
302 mpMP
->put_CurrentPosition( fTime
);
304 if( !bPlaying
&& mpMC
)
305 mpMC
->StopWhenReady();
310 double SAL_CALL
Player::getMediaTime( )
312 ::osl::MutexGuard
aGuard(m_aMutex
);
314 REFTIME
aRefTime( 0.0 );
317 mpMP
->get_CurrentPosition( &aRefTime
);
323 void SAL_CALL
Player::setPlaybackLoop( sal_Bool bSet
)
325 ::osl::MutexGuard
aGuard(m_aMutex
);
331 sal_Bool SAL_CALL
Player::isPlaybackLoop( )
333 ::osl::MutexGuard
aGuard(m_aMutex
);
339 void SAL_CALL
Player::setMute( sal_Bool bSet
)
341 ::osl::MutexGuard
aGuard(m_aMutex
);
343 if (mpBA
&& (mbMuted
!= static_cast<bool>(bSet
)))
346 mpBA
->put_Volume( mbMuted
? -10000 : mnUnmutedVolume
);
351 sal_Bool SAL_CALL
Player::isMute( )
353 ::osl::MutexGuard
aGuard(m_aMutex
);
359 void SAL_CALL
Player::setVolumeDB( sal_Int16 nVolumeDB
)
361 ::osl::MutexGuard
aGuard(m_aMutex
);
363 mnUnmutedVolume
= static_cast< long >( nVolumeDB
) * 100;
365 if( !mbMuted
&& mpBA
)
366 mpBA
->put_Volume( mnUnmutedVolume
);
370 sal_Int16 SAL_CALL
Player::getVolumeDB( )
372 ::osl::MutexGuard
aGuard(m_aMutex
);
374 return static_cast< sal_Int16
>( mnUnmutedVolume
/ 100 );
378 awt::Size SAL_CALL
Player::getPreferredPlayerWindowSize( )
380 ::osl::MutexGuard
aGuard(m_aMutex
);
382 awt::Size
aSize( 0, 0 );
386 long nWidth
= 0, nHeight
= 0;
388 mpBV
->GetVideoSize( &nWidth
, &nHeight
);
389 aSize
.Width
= nWidth
;
390 aSize
.Height
= nHeight
;
397 uno::Reference
< ::media::XPlayerWindow
> SAL_CALL
Player::createPlayerWindow( const uno::Sequence
< uno::Any
>& aArguments
)
399 ::osl::MutexGuard
aGuard(m_aMutex
);
401 uno::Reference
< ::media::XPlayerWindow
> xRet
;
402 awt::Size
aSize( getPreferredPlayerWindowSize() );
404 if( mpVW
&& aSize
.Width
> 0 && aSize
.Height
> 0 )
406 ::avmedia::win::Window
* pWindow
= new ::avmedia::win::Window( mxMgr
, *this );
410 if( !pWindow
->create( aArguments
) )
418 uno::Reference
< media::XFrameGrabber
> SAL_CALL
Player::createFrameGrabber( )
420 uno::Reference
< media::XFrameGrabber
> xRet
;
422 if( !maURL
.isEmpty() )
424 FrameGrabber
* pGrabber
= new FrameGrabber( mxMgr
);
428 if( !pGrabber
->create( maURL
) )
436 OUString SAL_CALL
Player::getImplementationName( )
438 return OUString( AVMEDIA_WIN_PLAYER_IMPLEMENTATIONNAME
);
442 sal_Bool SAL_CALL
Player::supportsService( const OUString
& ServiceName
)
444 return cppu::supportsService(this, ServiceName
);
448 uno::Sequence
< OUString
> SAL_CALL
Player::getSupportedServiceNames( )
450 return { AVMEDIA_WIN_PLAYER_SERVICENAME
};
454 } // namespace avmedia
456 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */