tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / avmedia / source / win / player.cxx
blobb52ac8171dfc80b6a3831340f6330d8d128e4f66
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 #include <objbase.h>
21 #include <strmif.h>
22 #include <control.h>
23 #include <uuids.h>
24 #include <evcode.h>
26 #include "player.hxx"
27 #include "framegrabber.hxx"
28 #include "window.hxx"
29 #include <cppuhelper/supportsservice.hxx>
30 #include <o3tl/char16_t2wchar_t.hxx>
31 #include <osl/file.hxx>
32 #include <rtl/ref.hxx>
34 constexpr OUStringLiteral AVMEDIA_WIN_PLAYER_IMPLEMENTATIONNAME = u"com.sun.star.comp.avmedia.Player_DirectX";
35 constexpr OUString AVMEDIA_WIN_PLAYER_SERVICENAME = u"com.sun.star.media.Player_DirectX"_ustr;
37 using namespace ::com::sun::star;
39 namespace avmedia::win {
41 static LRESULT CALLBACK MediaPlayerWndProc_2( HWND hWnd,UINT nMsg, WPARAM nPar1, LPARAM nPar2 )
43 Player* pPlayer = reinterpret_cast<Player*>(::GetWindowLongPtrW( hWnd, 0 ));
44 bool bProcessed = true;
46 if( pPlayer )
48 switch( nMsg )
50 case WM_GRAPHNOTIFY:
51 pPlayer->processEvent();
52 break;
53 default:
54 bProcessed = false;
55 break;
58 else
59 bProcessed = false;
61 return( bProcessed ? 0 : DefWindowProcW( hWnd, nMsg, nPar1, nPar2 ) );
65 Player::Player() :
66 Player_BASE(m_aMutex),
67 sal::systools::CoInitializeGuard(COINIT_APARTMENTTHREADED, false,
68 sal::systools::CoInitializeGuard::WhenFailed::NoThrow),
69 mnUnmutedVolume( 0 ),
70 mnFrameWnd( nullptr ),
71 mbMuted( false ),
72 mbLooping( false ),
73 mbAddWindow( true )
78 Player::~Player()
80 if( mnFrameWnd )
81 ::DestroyWindow( mnFrameWnd );
85 void SAL_CALL Player::disposing()
87 ::osl::MutexGuard aGuard(m_aMutex);
88 stop();
89 if( mpME )
90 mpME->SetNotifyWindow( 0, WM_GRAPHNOTIFY, 0);
94 bool Player::create( const OUString& rURL )
96 bool bRet = false;
98 if( SUCCEEDED(mpGB.CoCreateInstance(CLSID_FilterGraph, nullptr, CLSCTX_INPROC_SERVER)) )
100 // Don't use the overlay mixer on Windows Vista
101 // It disables the desktop composition as soon as RenderFile is called
102 // also causes some other problems: video rendering is not reliable
104 // tdf#128057: IGraphBuilder::RenderFile seems to fail to handle file URIs properly when
105 // they contain encoded characters like "%23"; so pass system path in that case instead.
106 OUString aFile(rURL);
107 if (aFile.startsWithIgnoreAsciiCase("file:"))
108 osl::FileBase::getSystemPathFromFileURL(rURL, aFile);
110 if( SUCCEEDED( mpGB->RenderFile( o3tl::toW(aFile.getStr()), nullptr ) ) &&
111 mpMC.set(mpGB, sal::systools::COM_QUERY) &&
112 mpME.set(mpGB, sal::systools::COM_QUERY) &&
113 mpMP.set(mpGB, sal::systools::COM_QUERY) )
115 // Video interfaces
116 mpVW.set(mpGB, sal::systools::COM_QUERY);
117 mpBV.set(mpGB, sal::systools::COM_QUERY);
119 // Audio interface
120 mpBA.set(mpGB, sal::systools::COM_QUERY);
122 if( mpBA )
123 mpBA->put_Volume( mnUnmutedVolume );
125 bRet = true;
129 if( bRet )
130 maURL = rURL;
131 else
132 maURL.clear();
134 return bRet;
138 const IVideoWindow* Player::getVideoWindow() const
140 return mpVW;
144 void Player::setNotifyWnd( HWND nNotifyWnd )
146 mbAddWindow = false;
147 if( mpME )
148 mpME->SetNotifyWindow( reinterpret_cast<OAHWND>(nNotifyWnd), WM_GRAPHNOTIFY, reinterpret_cast< LONG_PTR>( this ) );
152 void Player::processEvent()
154 long nCode;
155 LONG_PTR nParam1, nParam2;
157 while( mpME && SUCCEEDED( mpME->GetEvent( &nCode, &nParam1, &nParam2, 0 ) ) )
159 if( EC_COMPLETE == nCode )
161 if( mbLooping )
163 setMediaTime( 0.0 );
164 start();
166 else
168 setMediaTime( getDuration() );
169 stop();
173 mpME->FreeEventParams( nCode, nParam1, nParam2 );
178 void SAL_CALL Player::start( )
180 ::osl::MutexGuard aGuard(m_aMutex);
181 if( mpMC )
183 if ( mbAddWindow )
185 static WNDCLASSW* mpWndClass = nullptr;
186 if ( !mpWndClass )
188 mpWndClass = new WNDCLASSW;
190 memset( mpWndClass, 0, sizeof( *mpWndClass ) );
191 mpWndClass->hInstance = GetModuleHandleW( nullptr );
192 mpWndClass->cbWndExtra = sizeof( DWORD );
193 mpWndClass->lpfnWndProc = MediaPlayerWndProc_2;
194 mpWndClass->lpszClassName = L"com_sun_star_media_Sound_Player";
195 mpWndClass->hbrBackground = static_cast<HBRUSH>(::GetStockObject( BLACK_BRUSH ));
196 mpWndClass->hCursor = ::LoadCursor( nullptr, IDC_ARROW );
198 RegisterClassW( mpWndClass );
200 if ( !mnFrameWnd )
202 mnFrameWnd = CreateWindowW( mpWndClass->lpszClassName, nullptr,
204 0, 0, 0, 0,
205 nullptr, nullptr, mpWndClass->hInstance, nullptr );
206 if ( mnFrameWnd )
208 ::ShowWindow(mnFrameWnd, SW_HIDE);
209 SetWindowLongPtrW( mnFrameWnd, 0, reinterpret_cast<LONG_PTR>(this) );
210 // mpVW->put_Owner( (OAHWND) mnFrameWnd );
211 setNotifyWnd( mnFrameWnd );
216 mpMC->Run();
221 void SAL_CALL Player::stop( )
223 ::osl::MutexGuard aGuard(m_aMutex);
224 if( mpMC )
225 mpMC->Stop();
229 sal_Bool SAL_CALL Player::isPlaying()
231 ::osl::MutexGuard aGuard(m_aMutex);
233 OAFilterState eFilterState;
234 bool bRet = false;
236 if( mpMC && SUCCEEDED( mpMC->GetState( 10, &eFilterState ) ) )
237 bRet = ( State_Running == eFilterState );
239 return bRet;
243 double SAL_CALL Player::getDuration( )
245 ::osl::MutexGuard aGuard(m_aMutex);
247 REFTIME aRefTime( 0.0 );
249 if( mpMP )
250 mpMP->get_Duration( &aRefTime );
252 return aRefTime;
256 void SAL_CALL Player::setMediaTime( double fTime )
258 ::osl::MutexGuard aGuard(m_aMutex);
260 if( mpMP )
262 const bool bPlaying = isPlaying();
264 mpMP->put_CurrentPosition( fTime );
266 if( !bPlaying && mpMC )
267 mpMC->StopWhenReady();
272 double SAL_CALL Player::getMediaTime( )
274 ::osl::MutexGuard aGuard(m_aMutex);
276 REFTIME aRefTime( 0.0 );
278 if( mpMP )
279 mpMP->get_CurrentPosition( &aRefTime );
281 return aRefTime;
285 void SAL_CALL Player::setPlaybackLoop( sal_Bool bSet )
287 ::osl::MutexGuard aGuard(m_aMutex);
289 mbLooping = bSet;
293 sal_Bool SAL_CALL Player::isPlaybackLoop( )
295 ::osl::MutexGuard aGuard(m_aMutex);
297 return mbLooping;
301 void SAL_CALL Player::setMute( sal_Bool bSet )
303 ::osl::MutexGuard aGuard(m_aMutex);
305 if (mpBA && (mbMuted != static_cast<bool>(bSet)))
307 mbMuted = bSet;
308 mpBA->put_Volume( mbMuted ? -10000 : mnUnmutedVolume );
313 sal_Bool SAL_CALL Player::isMute( )
315 ::osl::MutexGuard aGuard(m_aMutex);
317 return mbMuted;
321 void SAL_CALL Player::setVolumeDB( sal_Int16 nVolumeDB )
323 ::osl::MutexGuard aGuard(m_aMutex);
325 mnUnmutedVolume = static_cast< long >( nVolumeDB ) * 100;
327 if( !mbMuted && mpBA )
328 mpBA->put_Volume( mnUnmutedVolume );
332 sal_Int16 SAL_CALL Player::getVolumeDB( )
334 ::osl::MutexGuard aGuard(m_aMutex);
336 return static_cast< sal_Int16 >( mnUnmutedVolume / 100 );
340 awt::Size SAL_CALL Player::getPreferredPlayerWindowSize( )
342 ::osl::MutexGuard aGuard(m_aMutex);
344 awt::Size aSize( 0, 0 );
346 if( mpBV )
348 long nWidth = 0, nHeight = 0;
350 mpBV->GetVideoSize( &nWidth, &nHeight );
351 aSize.Width = nWidth;
352 aSize.Height = nHeight;
355 return aSize;
359 uno::Reference< ::media::XPlayerWindow > SAL_CALL Player::createPlayerWindow( const uno::Sequence< uno::Any >& aArguments )
361 ::osl::MutexGuard aGuard(m_aMutex);
363 uno::Reference< ::media::XPlayerWindow > xRet;
364 awt::Size aSize( getPreferredPlayerWindowSize() );
366 if( mpVW && aSize.Width > 0 && aSize.Height > 0 )
368 rtl::Reference<::avmedia::win::Window> pWindow = new ::avmedia::win::Window( *this );
370 xRet = pWindow;
372 if( !pWindow->create( aArguments ) )
373 xRet.clear();
376 return xRet;
380 uno::Reference< media::XFrameGrabber > SAL_CALL Player::createFrameGrabber( )
382 uno::Reference< media::XFrameGrabber > xRet;
384 if( !maURL.isEmpty() )
386 rtl::Reference<FrameGrabber> pGrabber = new FrameGrabber();
388 xRet = pGrabber;
390 if( !pGrabber->create( maURL ) )
391 xRet.clear();
394 return xRet;
398 OUString SAL_CALL Player::getImplementationName( )
400 return AVMEDIA_WIN_PLAYER_IMPLEMENTATIONNAME;
404 sal_Bool SAL_CALL Player::supportsService( const OUString& ServiceName )
406 return cppu::supportsService(this, ServiceName);
410 uno::Sequence< OUString > SAL_CALL Player::getSupportedServiceNames( )
412 return { AVMEDIA_WIN_PLAYER_SERVICENAME };
415 } // namespace avmedia::win
418 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */