summaryrefslogtreecommitdiff
path: root/avmedia/source/win/player.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'avmedia/source/win/player.cxx')
-rw-r--r--avmedia/source/win/player.cxx494
1 files changed, 494 insertions, 0 deletions
diff --git a/avmedia/source/win/player.cxx b/avmedia/source/win/player.cxx
new file mode 100644
index 000000000000..d27b2b55ff93
--- /dev/null
+++ b/avmedia/source/win/player.cxx
@@ -0,0 +1,494 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <tools/prewin.h>
+#if defined _MSC_VER
+#pragma warning(push, 1)
+#pragma warning(disable: 4917)
+#endif
+#include <windows.h>
+#include <objbase.h>
+#include <strmif.h>
+#include <control.h>
+#include <uuids.h>
+#include <evcode.h>
+#if defined _MSC_VER
+#pragma warning(pop)
+#endif
+#include <tools/postwin.h>
+
+#include "player.hxx"
+#include "framegrabber.hxx"
+#include "window.hxx"
+
+#define AVMEDIA_WIN_PLAYER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.Player_DirectX"
+#define AVMEDIA_WIN_PLAYER_SERVICENAME "com.sun.star.media.Player_DirectX"
+
+using namespace ::com::sun::star;
+
+namespace avmedia { namespace win {
+
+bool isWindowsVistaOrHigher()
+{
+ // POST: return true if we are at least on Windows Vista
+ OSVERSIONINFO osvi;
+ ZeroMemory(&osvi, sizeof(osvi));
+ osvi.dwOSVersionInfoSize = sizeof(osvi);
+ GetVersionEx(&osvi);
+ if ( osvi.dwMajorVersion >= 6 )
+ return true;
+
+ return false;
+}
+
+// ----------------
+// - Player -
+// ----------------
+
+Player::Player( const uno::Reference< lang::XMultiServiceFactory >& rxMgr ) :
+ mxMgr( rxMgr ),
+ mpGB( NULL ),
+ mpOMF( NULL ),
+ mpMC( NULL ),
+ mpME( NULL ),
+ mpMS( NULL ),
+ mpMP( NULL ),
+ mpBA( NULL ),
+ mpBV( NULL ),
+ mpVW( NULL ),
+ mpEV( NULL ),
+ mnUnmutedVolume( 0 ),
+ mbMuted( false ),
+ mbLooping( false )
+{
+ ::CoInitialize( NULL );
+}
+
+// ------------------------------------------------------------------------------
+
+Player::~Player()
+{
+ if( mpBA )
+ mpBA->Release();
+
+ if( mpBV )
+ mpBV->Release();
+
+ if( mpVW )
+ mpVW->Release();
+
+ if( mpMP )
+ mpMP->Release();
+
+ if( mpMS )
+ mpMS->Release();
+
+ if( mpME )
+ mpME->Release();
+
+ if( mpMC )
+ mpMC->Release();
+
+ if( mpEV )
+ mpEV->Release();
+
+ if( mpOMF )
+ mpOMF->Release();
+
+ if( mpGB )
+ mpGB->Release();
+
+ ::CoUninitialize();
+}
+
+// ------------------------------------------------------------------------------
+
+bool Player::create( const ::rtl::OUString& rURL )
+{
+ HRESULT hR;
+ bool bRet = false;
+
+ if( SUCCEEDED( hR = CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**) &mpGB ) ) )
+ {
+ // Don't use the overlay mixer on Windows Vista
+ // It disables the desktop composition as soon as RenderFile is called
+ // also causes some other problems: video rendering is not reliable
+ if( !isWindowsVistaOrHigher() )
+ {
+ if( SUCCEEDED( CoCreateInstance( CLSID_OverlayMixer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**) &mpOMF ) ) )
+ {
+ mpGB->AddFilter( mpOMF, L"com_sun_star_media_OverlayMixerFilter" );
+
+ if( !SUCCEEDED( mpOMF->QueryInterface( IID_IDDrawExclModeVideo, (void**) &mpEV ) ) )
+ mpEV = NULL;
+ }
+ }
+
+ if( SUCCEEDED( hR = mpGB->RenderFile( reinterpret_cast<LPCWSTR>(rURL.getStr()), NULL ) ) &&
+ SUCCEEDED( hR = mpGB->QueryInterface( IID_IMediaControl, (void**) &mpMC ) ) &&
+ SUCCEEDED( hR = mpGB->QueryInterface( IID_IMediaEventEx, (void**) &mpME ) ) &&
+ SUCCEEDED( hR = mpGB->QueryInterface( IID_IMediaSeeking, (void**) &mpMS ) ) &&
+ SUCCEEDED( hR = mpGB->QueryInterface( IID_IMediaPosition, (void**) &mpMP ) ) )
+ {
+ // Video interfaces
+ mpGB->QueryInterface( IID_IVideoWindow, (void**) &mpVW );
+ mpGB->QueryInterface( IID_IBasicVideo, (void**) &mpBV );
+
+ // Audio interface
+ mpGB->QueryInterface( IID_IBasicAudio, (void**) &mpBA );
+
+ if( mpBA )
+ mpBA->put_Volume( mnUnmutedVolume );
+
+ bRet = true;
+ }
+ }
+
+ if( bRet )
+ maURL = rURL;
+ else
+ maURL = ::rtl::OUString();
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------------
+
+const IVideoWindow* Player::getVideoWindow() const
+{
+ return mpVW;
+}
+
+// ------------------------------------------------------------------------------
+
+void Player::setNotifyWnd( int nNotifyWnd )
+{
+ if( mpME )
+ mpME->SetNotifyWindow( (OAHWND) nNotifyWnd, WM_GRAPHNOTIFY, reinterpret_cast< LONG_PTR>( this ) );
+}
+
+// ------------------------------------------------------------------------------
+
+void Player::setDDrawParams( IDirectDraw* pDDraw, IDirectDrawSurface* pDDrawSurface )
+{
+ if( mpEV && pDDraw && pDDrawSurface )
+ {
+ mpEV->SetDDrawObject( pDDraw );
+ mpEV->SetDDrawSurface( pDDrawSurface );
+ }
+}
+
+// ------------------------------------------------------------------------------
+
+long Player::processEvent()
+{
+ long nCode, nParam1, nParam2;
+
+ if( mpME && SUCCEEDED( mpME->GetEvent( &nCode, &nParam1, &nParam2, 0 ) ) )
+ {
+ if( EC_COMPLETE == nCode )
+ {
+ if( mbLooping )
+ {
+ setMediaTime( 0.0 );
+ start();
+ }
+ else
+ {
+ setMediaTime( getDuration() );
+ stop();
+ }
+ }
+
+ mpME->FreeEventParams( nCode, nParam1, nParam2 );
+ }
+
+ return 0;
+}
+
+// ------------------------------------------------------------------------------
+
+void SAL_CALL Player::start( )
+ throw (uno::RuntimeException)
+{
+ if( mpMC )
+ mpMC->Run();
+}
+
+// ------------------------------------------------------------------------------
+
+void SAL_CALL Player::stop( )
+ throw (uno::RuntimeException)
+{
+ if( mpMC )
+ mpMC->Stop();
+}
+
+// ------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL Player::isPlaying()
+ throw (uno::RuntimeException)
+{
+ OAFilterState eFilterState;
+ bool bRet = false;
+
+ if( mpMC && SUCCEEDED( mpMC->GetState( 10, &eFilterState ) ) )
+ bRet = ( State_Running == eFilterState );
+
+ return bRet;
+}
+
+// ------------------------------------------------------------------------------
+
+double SAL_CALL Player::getDuration( )
+ throw (uno::RuntimeException)
+{
+ REFTIME aRefTime( 0.0 );
+
+ if( mpMP )
+ mpMP->get_Duration( &aRefTime );
+
+ return aRefTime;
+}
+
+// ------------------------------------------------------------------------------
+
+void SAL_CALL Player::setMediaTime( double fTime )
+ throw (uno::RuntimeException)
+{
+ if( mpMP )
+ {
+ const bool bPlaying = isPlaying();
+
+ mpMP->put_CurrentPosition( fTime );
+
+ if( !bPlaying && mpMC )
+ mpMC->StopWhenReady();
+ }
+}
+
+// ------------------------------------------------------------------------------
+
+double SAL_CALL Player::getMediaTime( )
+ throw (uno::RuntimeException)
+{
+ REFTIME aRefTime( 0.0 );
+
+ if( mpMP )
+ mpMP->get_CurrentPosition( &aRefTime );
+
+ return aRefTime;
+}
+
+// ------------------------------------------------------------------------------
+
+void SAL_CALL Player::setStopTime( double fTime )
+ throw (uno::RuntimeException)
+{
+ if( mpMP )
+ mpMP->put_StopTime( fTime );
+}
+
+// ------------------------------------------------------------------------------
+
+double SAL_CALL Player::getStopTime( )
+ throw (uno::RuntimeException)
+{
+ REFTIME aRefTime( 0.0 );
+
+ if( mpMP )
+ mpMP->get_StopTime( &aRefTime );
+
+ return aRefTime;
+}
+
+// ------------------------------------------------------------------------------
+
+void SAL_CALL Player::setRate( double fRate )
+ throw (uno::RuntimeException)
+{
+ if( mpMP )
+ mpMP->put_Rate( fRate );
+}
+
+// ------------------------------------------------------------------------------
+
+double SAL_CALL Player::getRate( )
+ throw (uno::RuntimeException)
+{
+ double fRet( 0.0 );
+
+ if( mpMP )
+ mpMP->get_Rate( &fRet );
+
+ return fRet;
+}
+
+// ------------------------------------------------------------------------------
+
+void SAL_CALL Player::setPlaybackLoop( sal_Bool bSet )
+ throw (uno::RuntimeException)
+{
+ mbLooping = bSet;
+}
+
+// ------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL Player::isPlaybackLoop( )
+ throw (uno::RuntimeException)
+{
+ return mbLooping;
+}
+
+// ------------------------------------------------------------------------------
+
+void SAL_CALL Player::setMute( sal_Bool bSet )
+ throw (uno::RuntimeException)
+{
+ if( mpBA && ( mbMuted != bSet ) )
+ {
+ mbMuted = bSet;
+ mpBA->put_Volume( mbMuted ? -10000 : mnUnmutedVolume );
+ }
+}
+
+// ------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL Player::isMute( )
+ throw (uno::RuntimeException)
+{
+ return mbMuted;
+}
+
+// ------------------------------------------------------------------------------
+
+void SAL_CALL Player::setVolumeDB( sal_Int16 nVolumeDB )
+ throw (uno::RuntimeException)
+{
+ mnUnmutedVolume = static_cast< long >( nVolumeDB ) * 100;
+
+ if( !mbMuted && mpBA )
+ mpBA->put_Volume( mnUnmutedVolume );
+}
+
+// ------------------------------------------------------------------------------
+
+sal_Int16 SAL_CALL Player::getVolumeDB( )
+ throw (uno::RuntimeException)
+{
+ return( static_cast< sal_Int16 >( mnUnmutedVolume / 100 ) );
+}
+
+// ------------------------------------------------------------------------------
+
+awt::Size SAL_CALL Player::getPreferredPlayerWindowSize( )
+ throw (uno::RuntimeException)
+{
+ awt::Size aSize( 0, 0 );
+
+ if( mpBV )
+ {
+ long nWidth = 0, nHeight = 0;
+
+ mpBV->GetVideoSize( &nWidth, &nHeight );
+ aSize.Width = nWidth;
+ aSize.Height = nHeight;
+ }
+
+ return aSize;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Reference< ::media::XPlayerWindow > SAL_CALL Player::createPlayerWindow( const uno::Sequence< uno::Any >& aArguments )
+ throw (uno::RuntimeException)
+{
+ uno::Reference< ::media::XPlayerWindow > xRet;
+ awt::Size aSize( getPreferredPlayerWindowSize() );
+
+ if( mpVW && aSize.Width > 0 && aSize.Height > 0 )
+ {
+ ::avmedia::win::Window* pWindow = new ::avmedia::win::Window( mxMgr, *this );
+
+ xRet = pWindow;
+
+ if( !pWindow->create( aArguments ) )
+ xRet = uno::Reference< ::media::XPlayerWindow >();
+ }
+
+ return xRet;
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Reference< media::XFrameGrabber > SAL_CALL Player::createFrameGrabber( )
+ throw (uno::RuntimeException)
+{
+ uno::Reference< media::XFrameGrabber > xRet;
+
+ if( maURL.getLength() > 0 )
+ {
+ FrameGrabber* pGrabber = new FrameGrabber( mxMgr );
+
+ xRet = pGrabber;
+
+ if( !pGrabber->create( maURL ) )
+ xRet.clear();
+ }
+
+ return xRet;
+}
+
+// ------------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL Player::getImplementationName( )
+ throw (uno::RuntimeException)
+{
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( AVMEDIA_WIN_PLAYER_IMPLEMENTATIONNAME ) );
+}
+
+// ------------------------------------------------------------------------------
+
+sal_Bool SAL_CALL Player::supportsService( const ::rtl::OUString& ServiceName )
+ throw (uno::RuntimeException)
+{
+ return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( AVMEDIA_WIN_PLAYER_SERVICENAME ) );
+}
+
+// ------------------------------------------------------------------------------
+
+uno::Sequence< ::rtl::OUString > SAL_CALL Player::getSupportedServiceNames( )
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< ::rtl::OUString > aRet(1);
+ aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( AVMEDIA_WIN_PLAYER_SERVICENAME ) );
+
+ return aRet;
+}
+
+} // namespace win
+} // namespace avmedia