summaryrefslogtreecommitdiff
path: root/avmedia
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@suse.com>2012-09-24 21:54:36 +0100
committerMichael Meeks <michael.meeks@suse.com>2012-09-25 19:14:25 +0100
commitfc6351f5d36f8b6be5e52a2ea1f191de81eacc71 (patch)
tree90f6b2ba952a9c50bdb54a9420761d83a8696e9e /avmedia
parent3e46a434eb50f8d73f64be8619598dae6dc32a06 (diff)
avmedia: first cut at gstreamer frame grabber.
with thanks to Tim-Philipp Müller and Wim Taymans. Change-Id: Ia095d06ea3cbed85570cc33038f98da0362c1e62
Diffstat (limited to 'avmedia')
-rw-r--r--avmedia/Library_avmediagst.mk1
-rw-r--r--avmedia/source/gstreamer/gst_0_10.cxx1
-rw-r--r--avmedia/source/gstreamer/gstframegrabber.cxx287
-rw-r--r--avmedia/source/gstreamer/gstframegrabber.hxx35
-rw-r--r--avmedia/source/gstreamer/gstplayer.cxx102
-rw-r--r--avmedia/source/gstreamer/gstplayer.hxx19
6 files changed, 256 insertions, 189 deletions
diff --git a/avmedia/Library_avmediagst.mk b/avmedia/Library_avmediagst.mk
index ee8a09aadb98..528960bfa1b1 100644
--- a/avmedia/Library_avmediagst.mk
+++ b/avmedia/Library_avmediagst.mk
@@ -60,6 +60,7 @@ $(eval $(call gb_Library_add_exception_objects,avmediagst,\
avmedia/source/gstreamer/gstplayer \
avmedia/source/gstreamer/gstuno \
avmedia/source/gstreamer/gstwindow \
+ avmedia/source/gstreamer/gstframegrabber \
))
# vim: set noet sw=4 ts=4:
diff --git a/avmedia/source/gstreamer/gst_0_10.cxx b/avmedia/source/gstreamer/gst_0_10.cxx
index c24ec4e5d84f..9f2715b5d9e6 100644
--- a/avmedia/source/gstreamer/gst_0_10.cxx
+++ b/avmedia/source/gstreamer/gst_0_10.cxx
@@ -21,3 +21,4 @@
#include "gstplayer.cxx"
#include "gstuno.cxx"
#include "gstwindow.cxx"
+#include "gstframegrabber.cxx"
diff --git a/avmedia/source/gstreamer/gstframegrabber.cxx b/avmedia/source/gstreamer/gstframegrabber.cxx
index a8c09773e24d..c4046f11a1af 100644
--- a/avmedia/source/gstreamer/gstframegrabber.cxx
+++ b/avmedia/source/gstreamer/gstframegrabber.cxx
@@ -17,206 +17,207 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-#include <objbase.h>
-#include <strmif.h>
-#include <Amvideo.h>
-#include <Qedit.h>
-#include <uuids.h>
+#include "gstframegrabber.hxx"
+#include "gstplayer.hxx"
-#include "framegrabber.hxx"
-#include "player.hxx"
+#include <gst/gstbuffer.h>
+#include <gst/video/video.h>
+#include <gst/video/gstvideosink.h>
-#include <tools/stream.hxx>
#include <vcl/graph.hxx>
-#include <unotools/localfilehelper.hxx>
+#include <vcl/bmpacc.hxx>
-#define AVMEDIA_GST_FRAMEGRABBER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.FrameGrabber_GStreamer"
-#define AVMEDIA_GST_FRAMEGRABBER_SERVICENAME "com.sun.star.media.FrameGrabber_GStreamer"
+#include <string>
+
+#ifdef AVMEDIA_GST_0_10
+# define AVMEDIA_GST_FRAMEGRABBER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.FrameGrabber_GStreamer_0_10"
+# define AVMEDIA_GST_FRAMEGRABBER_SERVICENAME "com.sun.star.media.FrameGrabber_GStreamer_0_10"
+#else
+# define AVMEDIA_GST_FRAMEGRABBER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.FrameGrabber_GStreamer"
+# define AVMEDIA_GST_FRAMEGRABBER_SERVICENAME "com.sun.star.media.FrameGrabber_GStreamer"
+#endif
using namespace ::com::sun::star;
namespace avmedia { namespace gstreamer {
-// ----------------
-// - FrameGrabber -
-// ----------------
-
-FrameGrabber::FrameGrabber( const uno::Reference< lang::XMultiServiceFactory >& rxMgr ) :
- mxMgr( rxMgr )
-{
- ::CoInitialize( NULL );
-}
-
-// ------------------------------------------------------------------------------
-
-FrameGrabber::~FrameGrabber()
+void FrameGrabber::disposePipeline()
{
- ::CoUninitialize();
+ if( mpPipeline != NULL )
+ {
+ gst_element_set_state( mpPipeline, GST_STATE_NULL );
+ g_object_unref( G_OBJECT( mpPipeline ) );
+ mpPipeline = NULL;
+ }
}
-// ------------------------------------------------------------------------------
-
-IMediaDet* FrameGrabber::implCreateMediaDet( const OUString& rURL ) const
+FrameGrabber::FrameGrabber( const rtl::OUString &rURL ) :
+ FrameGrabber_BASE()
{
- IMediaDet* pDet = NULL;
-
- if( SUCCEEDED( CoCreateInstance( CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER, IID_IMediaDet, (void**) &pDet ) ) )
- {
- String aLocalStr;
+ gchar *pPipelineStr;
+ pPipelineStr = g_strdup_printf(
+#ifdef AVMEDIA_GST_0_10
+ "uridecodebin uri=%s ! ffmpegcolorspace ! videoscale ! appsink "
+ "name=sink caps=\"video/x-raw-rgb,format=RGB,pixel-aspect-ratio=1/1,"
+ "bpp=(int)24,depth=(int)24,endianness=(int)4321,"
+ "red_mask=(int)0xff0000, green_mask=(int)0x00ff00, blue_mask=(int)0x0000ff\"",
+#else
+ "uridecodebin uri=%s ! videoconvert ! videoscale ! appsink "
+ "name=sink caps=\"video/x-raw,format=RGB,pixel-aspect-ratio=1/1\"",
+#endif
+ rtl::OUStringToOString( rURL, RTL_TEXTENCODING_UTF8 ).getStr() );
+
+ GError *pError = NULL;
+ mpPipeline = gst_parse_launch( pPipelineStr, &pError );
+ if( pError != NULL) {
+ g_warning( "Failed to construct frame-grabber pipeline '%s'\n", pError->message );
+ g_error_free( pError );
+ disposePipeline();
+ }
- if( ::utl::LocalFileHelper::ConvertURLToPhysicalName( rURL, aLocalStr ) && aLocalStr.Len() )
- {
- if( !SUCCEEDED( pDet->put_Filename( ::SysAllocString( aLocalStr.GetBuffer() ) ) ) )
- {
- pDet->Release();
- pDet = NULL;
- }
+ if( mpPipeline ) {
+ // pre-roll
+ switch( gst_element_set_state( mpPipeline, GST_STATE_PAUSED ) ) {
+ case GST_STATE_CHANGE_FAILURE:
+ case GST_STATE_CHANGE_NO_PREROLL:
+ g_warning( "failure pre-rolling media" );
+ disposePipeline();
+ break;
+ default:
+ break;
}
}
-
- return pDet;
+ if( mpPipeline &&
+ gst_element_get_state( mpPipeline, NULL, NULL, 5 * GST_SECOND ) == GST_STATE_CHANGE_FAILURE )
+ disposePipeline();
}
-// ------------------------------------------------------------------------------
-
-bool FrameGrabber::create( const OUString& rURL )
+FrameGrabber::~FrameGrabber()
{
- // just check if a MediaDet interface can be created with the given URL
- IMediaDet* pDet = implCreateMediaDet( rURL );
-
- if( pDet )
- {
- maURL = rURL;
- pDet->Release();
- pDet = NULL;
- }
- else
- maURL = OUString();
-
- return( maURL.getLength() > 0 );
+ disposePipeline();
}
-// ------------------------------------------------------------------------------
+FrameGrabber* FrameGrabber::create( const rtl::OUString &rURL )
+{
+ return new FrameGrabber( rURL );
+}
uno::Reference< graphic::XGraphic > SAL_CALL FrameGrabber::grabFrame( double fMediaTime )
throw (uno::RuntimeException)
{
uno::Reference< graphic::XGraphic > xRet;
- IMediaDet* pDet = implCreateMediaDet( maURL );
- if( pDet )
- {
- double fLength;
- long nStreamCount;
- bool bFound = false;
-
- if( SUCCEEDED( pDet->get_OutputStreams( &nStreamCount ) ) )
- {
- for( long n = 0; ( n < nStreamCount ) && !bFound; ++n )
- {
- GUID aMajorType;
+ if( !mpPipeline )
+ return xRet;
- if( SUCCEEDED( pDet->put_CurrentStream( n ) ) &&
- SUCCEEDED( pDet->get_StreamType( &aMajorType ) ) &&
- ( aMajorType == MEDIATYPE_Video ) )
- {
- bFound = true;
- }
- }
- }
+ gint64 gst_position = llround( fMediaTime * 1E9 );
+ gst_element_seek_simple(
+ mpPipeline, GST_FORMAT_TIME,
+ (GstSeekFlags)(GST_SEEK_FLAG_KEY_UNIT | GST_SEEK_FLAG_FLUSH),
+ gst_position );
- if( bFound &&
- ( S_OK == pDet->get_StreamLength( &fLength ) ) &&
- ( fLength > 0.0 ) && ( fMediaTime >= 0.0 ) && ( fMediaTime <= fLength ) )
- {
- AM_MEDIA_TYPE aMediaType;
- long nWidth = 0, nHeight = 0, nSize = 0;
+ GstElement *pSink = gst_bin_get_by_name( GST_BIN( mpPipeline ), "sink" );
+ if( !pSink )
+ return xRet;
- if( SUCCEEDED( pDet->get_StreamMediaType( &aMediaType ) ) )
- {
- if( ( aMediaType.formattype == FORMAT_VideoInfo ) &&
- ( aMediaType.cbFormat >= sizeof( VIDEOINFOHEADER ) ) )
- {
- VIDEOINFOHEADER* pVih = reinterpret_cast< VIDEOINFOHEADER* >( aMediaType.pbFormat );
+ GstBuffer *pBuf = NULL;
+ GstCaps *pCaps = NULL;
- nWidth = pVih->bmiHeader.biWidth;
- nHeight = pVih->bmiHeader.biHeight;
+ // synchronously fetch the frame
+#ifdef AVMEDIA_GST_0_10
+ g_signal_emit_by_name( pSink, "pull-preroll", &pBuf, NULL );
+ if( pBuf )
+ pCaps = GST_BUFFER_CAPS( pBuf );
+#else
+ GstSample *pSample = NULL;
+ g_signal_emit_by_name( pSink, "pull-preroll", &pSample, NULL );
- if( nHeight < 0 )
- nHeight *= -1;
- }
+ if( pSample )
+ {
+ pBuf = gst_sample_get_buffer( pSample );
+ pCaps = gst_sample_get_caps( pSample );
+ }
+#endif
- if( aMediaType.cbFormat != 0 )
- {
- ::CoTaskMemFree( (PVOID) aMediaType.pbFormat );
- aMediaType.cbFormat = 0;
- aMediaType.pbFormat = NULL;
- }
+ // get geometry
+ int nWidth = 0, nHeight = 0;
+ if( !pCaps )
+ g_warning( "could not get snapshot format\n" );
+ else
+ {
+ GstStructure *pStruct = gst_caps_get_structure( pCaps, 0 );
- if( aMediaType.pUnk != NULL )
- {
- aMediaType.pUnk->Release();
- aMediaType.pUnk = NULL;
- }
- }
+ /* we need to get the final caps on the buffer to get the size */
+ if( !gst_structure_get_int( pStruct, "width", &nWidth ) ||
+ !gst_structure_get_int( pStruct, "height", &nHeight ) )
+ nWidth = nHeight = 0;
+ }
- if( ( nWidth > 0 ) && ( nHeight > 0 ) &&
- SUCCEEDED( pDet->GetBitmapBits( 0, &nSize, NULL, nWidth, nHeight ) ) &&
- ( nSize > 0 ) )
+ if( pBuf && nWidth > 0 && nHeight > 0 &&
+ // sanity check the size
+#ifdef AVMEDIA_GST_0_10
+ GST_BUFFER_SIZE( pBuf ) >= ( nWidth * nHeight * 3 )
+#else
+ gst_buffer_get_size( pBuf ) >= ( nWidth * nHeight * 3 )
+#endif
+ )
+ {
+ sal_uInt8 *pData = NULL;
+#ifdef AVMEDIA_GST_0_10
+ pData = GST_BUFFER_DATA( pBuf );
+#else
+ GstMapInfo aMapInfo;
+ gst_buffer_map( pBuf, &aMapInfo, GST_MAP_READ );
+ pData = aMapInfo.data;
+#endif
+
+ int nStride = GST_ROUND_UP_4( nWidth * 3 );
+ Bitmap aBmp( Size( nWidth, nHeight ), 24 );
+
+ BitmapWriteAccess *pWrite = aBmp.AcquireWriteAccess();
+ if( pWrite )
+ {
+ // yet another cheesy pixel copying loop
+ for( int y = 0; y < nHeight; ++y )
{
- char* pBuffer = new char[ nSize ];
-
- try
+ sal_uInt8 *p = pData + y * nStride;
+ for( int x = 0; x < nWidth; ++x )
{
- if( SUCCEEDED( pDet->GetBitmapBits( fMediaTime, NULL, pBuffer, nWidth, nHeight ) ) )
- {
- SvMemoryStream aMemStm( pBuffer, nSize, STREAM_READ | STREAM_WRITE );
- Bitmap aBmp;
-
- if( aBmp.Read( aMemStm, false ) && !aBmp.IsEmpty() )
- {
- const Graphic aGraphic( aBmp );
- xRet = aGraphic.GetXGraphic();
- }
- }
+ BitmapColor col( p[0], p[1], p[2] );
+ pWrite->SetPixel( y, x, col );
+ p += 3;
}
- catch( ... )
- {
- }
-
- delete [] pBuffer;
}
}
+ aBmp.ReleaseAccess( pWrite );
+
+#ifndef AVMEDIA_GST_0_10
+ gst_buffer_unmap( pBuf, &aMapInfo );
+#endif
- pDet->Release();
+ xRet = Graphic( aBmp ).GetXGraphic();
}
return xRet;
}
-// ------------------------------------------------------------------------------
-
-OUString SAL_CALL FrameGrabber::getImplementationName( )
+::rtl::OUString SAL_CALL FrameGrabber::getImplementationName( )
throw (uno::RuntimeException)
{
- return OUString( AVMEDIA_GST_FRAMEGRABBER_IMPLEMENTATIONNAME );
+ return ::rtl::OUString( AVMEDIA_GST_FRAMEGRABBER_IMPLEMENTATIONNAME );
}
-// ------------------------------------------------------------------------------
-
-sal_Bool SAL_CALL FrameGrabber::supportsService( const OUString& ServiceName )
+sal_Bool SAL_CALL FrameGrabber::supportsService( const ::rtl::OUString& ServiceName )
throw (uno::RuntimeException)
{
return ServiceName == AVMEDIA_GST_FRAMEGRABBER_SERVICENAME;
}
-// ------------------------------------------------------------------------------
-
-uno::Sequence< OUString > SAL_CALL FrameGrabber::getSupportedServiceNames( )
+uno::Sequence< ::rtl::OUString > SAL_CALL FrameGrabber::getSupportedServiceNames()
throw (uno::RuntimeException)
{
- uno::Sequence< OUString > aRet(1);
- aRet[0] = AVMEDIA_GST_FRAMEGRABBER_SERVICENAME ;
+ uno::Sequence< ::rtl::OUString > aRet(1);
+ aRet[0] = AVMEDIA_GST_FRAMEGRABBER_SERVICENAME;
return aRet;
}
diff --git a/avmedia/source/gstreamer/gstframegrabber.hxx b/avmedia/source/gstreamer/gstframegrabber.hxx
index a16317aa4eae..af23cca1ab7a 100644
--- a/avmedia/source/gstreamer/gstframegrabber.hxx
+++ b/avmedia/source/gstreamer/gstframegrabber.hxx
@@ -20,9 +20,9 @@
#ifndef _FRAMEGRABBER_HXX
#define _FRAMEGRABBER_HXX
-#include "gstcommon.hxx"
-
-#include "com/sun/star/media/XFrameGrabber.hpp"
+#include "gstplayer.hxx"
+#include "com/sun/star/media/XFrameGrabber.hdl"
+#include <cppuhelper/implbase2.hxx>
namespace avmedia { namespace gstreamer {
@@ -30,31 +30,34 @@ namespace avmedia { namespace gstreamer {
// - FrameGrabber -
// ----------------
-class FrameGrabber : public ::cppu::WeakImplHelper2 < ::com::sun::star::media::XFrameGrabber,
- ::com::sun::star::lang::XServiceInfo >
+typedef ::cppu::WeakImplHelper2< ::com::sun::star::media::XFrameGrabber,
+ ::com::sun::star::lang::XServiceInfo > FrameGrabber_BASE;
+
+class FrameGrabber : public FrameGrabber_BASE
{
+ GstElement *mpPipeline;
+ void disposePipeline();
public:
+ // static create method instead of public Ctor
+ static FrameGrabber* create( const rtl::OUString &rURL );
- FrameGrabber( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxMgr );
- ~FrameGrabber();
-
- bool create( const OUString& rURL );
+ virtual ~FrameGrabber();
// XFrameGrabber
virtual ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > SAL_CALL grabFrame( double fMediaTime ) throw (::com::sun::star::uno::RuntimeException);
// XServiceInfo
- virtual OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException);
- virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException);
- virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException);
private:
-
- ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxMgr;
- OUString maURL;
+ FrameGrabber( const rtl::OUString &aURL );
+ FrameGrabber( const FrameGrabber& );
+ FrameGrabber& operator=( const FrameGrabber& );
};
-} // namespace gstreamer
+} // namespace gst
} // namespace avmedia
#endif // _FRAMEGRABBER_HXX
diff --git a/avmedia/source/gstreamer/gstplayer.cxx b/avmedia/source/gstreamer/gstplayer.cxx
index b8b1ceb7246a..6e002301194d 100644
--- a/avmedia/source/gstreamer/gstplayer.cxx
+++ b/avmedia/source/gstreamer/gstplayer.cxx
@@ -28,13 +28,15 @@
#include "gstframegrabber.hxx"
#include "gstwindow.hxx"
-#ifndef AVMEDIA_GST_0_10
+#ifdef AVMEDIA_GST_0_10
+# define AVMEDIA_GST_PLAYER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.Player_GStreamer_0_10"
+# define AVMEDIA_GST_PLAYER_SERVICENAME "com.sun.star.media.Player_GStreamer_0_10"
+#else
# include <gst/video/videooverlay.h>
+# define AVMEDIA_GST_PLAYER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.Player_GStreamer"
+# define AVMEDIA_GST_PLAYER_SERVICENAME "com.sun.star.media.Player_GStreamer"
#endif
-#define AVMEDIA_GST_PLAYER_IMPLEMENTATIONNAME "com.sun.star.comp.avmedia.Player_GStreamer"
-#define AVMEDIA_GST_PLAYER_SERVICENAME "com.sun.star.media.Player_GStreamer"
-
#ifdef AVMEDIA_GST_0_10
# define AVVERSION "gst 0.10: "
#else
@@ -58,6 +60,7 @@ namespace avmedia { namespace gstreamer {
// ----------------
Player::Player( const uno::Reference< lang::XMultiServiceFactory >& rxMgr ) :
+ GstPlayer_BASE( m_aMutex ),
mxMgr( rxMgr ),
mpPlaybin( NULL ),
mbFakeVideo (sal_False ),
@@ -96,6 +99,17 @@ Player::Player( const uno::Reference< lang::XMultiServiceFactory >& rxMgr ) :
Player::~Player()
{
DBG( "%p Player::~Player", this );
+ if( mbInitialized )
+ disposing();
+}
+
+void SAL_CALL Player::disposing()
+{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ stop();
+
+ DBG( "%p Player::disposing", this );
// Release the elements and pipeline
if( mbInitialized )
@@ -204,7 +218,7 @@ GstBusSyncReply Player::processSyncMessage( GstMessage *message )
#endif
{
DBG( "%p processSyncMessage prepare window id: %s %d", this,
- GST_MESSAGE_TYPE_NAME( message ), (int)mnWindowId );
+ GST_MESSAGE_TYPE_NAME( message ), (int)mnWindowID );
if( mpXOverlay )
g_object_unref( G_OBJECT ( mpXOverlay ) );
g_object_set( GST_MESSAGE_SRC( message ), "force-aspect-ratio", FALSE, NULL );
@@ -316,7 +330,7 @@ GstBusSyncReply Player::processSyncMessage( GstMessage *message )
return GST_BUS_PASS;
}
-void Player::preparePlaybin( const OUString& rURL, bool bFakeVideo )
+void Player::preparePlaybin( const OUString& rURL, GstElement *pSink )
{
GstBus *pBus;
@@ -327,11 +341,13 @@ void Player::preparePlaybin( const OUString& rURL, bool bFakeVideo )
}
mpPlaybin = gst_element_factory_make( "playbin", NULL );
- if( bFakeVideo ) // used for getting prefered size etc.
- g_object_set( G_OBJECT( mpPlaybin ), "video-sink",
- gst_element_factory_make( "fakesink", NULL ), NULL );
-
- mbFakeVideo = bFakeVideo;
+ if( pSink != NULL ) // used for getting prefered size etc.
+ {
+ g_object_set( G_OBJECT( mpPlaybin ), "video-sink", pSink, NULL );
+ mbFakeVideo = true;
+ }
+ else
+ mbFakeVideo = false;
rtl::OString ascURL = OUStringToOString( rURL, RTL_TEXTENCODING_UTF8 );
g_object_set( G_OBJECT( mpPlaybin ), "uri", ascURL.getStr() , NULL );
@@ -355,9 +371,10 @@ bool Player::create( const OUString& rURL )
DBG("create player, URL: %s", OUStringToOString( rURL, RTL_TEXTENCODING_UTF8 ).getStr());
- if( mbInitialized )
+ if( mbInitialized && !rURL.isEmpty() )
{
- preparePlaybin( rURL, true );
+ // fakesink for pre-roll & sizing ...
+ preparePlaybin( rURL, gst_element_factory_make( "fakesink", NULL ) );
gst_element_set_state( mpPlaybin, GST_STATE_PAUSED );
mbPlayPending = false;
@@ -378,6 +395,8 @@ bool Player::create( const OUString& rURL )
void SAL_CALL Player::start()
throw (uno::RuntimeException)
{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
// set the pipeline state to READY and run the loop
if( mbInitialized && NULL != mpPlaybin )
{
@@ -391,6 +410,8 @@ void SAL_CALL Player::start()
void SAL_CALL Player::stop()
throw (uno::RuntimeException)
{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
// set the pipeline in PAUSED STATE
if( mpPlaybin )
gst_element_set_state( mpPlaybin, GST_STATE_PAUSED );
@@ -404,6 +425,8 @@ void SAL_CALL Player::stop()
sal_Bool SAL_CALL Player::isPlaying()
throw (uno::RuntimeException)
{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
bool bRet = mbPlayPending;
// return whether the pipeline is in PLAYING STATE or not
@@ -422,6 +445,8 @@ sal_Bool SAL_CALL Player::isPlaying()
double SAL_CALL Player::getDuration()
throw (uno::RuntimeException)
{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
// slideshow checks for non-zero duration, so cheat here
double duration = 0.01;
@@ -437,6 +462,8 @@ double SAL_CALL Player::getDuration()
void SAL_CALL Player::setMediaTime( double fTime )
throw (uno::RuntimeException)
{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
if( mpPlaybin ) {
gint64 gst_position = llround (fTime * 1E9);
@@ -457,6 +484,8 @@ void SAL_CALL Player::setMediaTime( double fTime )
double SAL_CALL Player::getMediaTime()
throw (uno::RuntimeException)
{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
double position = 0.0;
if( mpPlaybin ) {
@@ -474,13 +503,12 @@ double SAL_CALL Player::getMediaTime()
double SAL_CALL Player::getRate()
throw (uno::RuntimeException)
{
- double rate = 0.0;
+ ::osl::MutexGuard aGuard(m_aMutex);
- // TODO get the window rate
- if( mbInitialized )
- {
+ double rate = 1.0;
- }
+ // TODO get the window rate - but no need since
+ // higher levels never set rate > 1
return rate;
}
@@ -490,6 +518,7 @@ double SAL_CALL Player::getRate()
void SAL_CALL Player::setPlaybackLoop( sal_Bool bSet )
throw (uno::RuntimeException)
{
+ ::osl::MutexGuard aGuard(m_aMutex);
// TODO check how to do with GST
mbLooping = bSet;
}
@@ -499,6 +528,7 @@ void SAL_CALL Player::setPlaybackLoop( sal_Bool bSet )
sal_Bool SAL_CALL Player::isPlaybackLoop()
throw (uno::RuntimeException)
{
+ ::osl::MutexGuard aGuard(m_aMutex);
// TODO check how to do with GST
return mbLooping;
}
@@ -508,6 +538,8 @@ sal_Bool SAL_CALL Player::isPlaybackLoop()
void SAL_CALL Player::setMute( sal_Bool bSet )
throw (uno::RuntimeException)
{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
DBG( "set mute: %d muted: %d unmuted volume: %lf", bSet, mbMuted, mnUnmutedVolume );
// change the volume to 0 or the unmuted volume
@@ -530,6 +562,8 @@ void SAL_CALL Player::setMute( sal_Bool bSet )
sal_Bool SAL_CALL Player::isMute()
throw (uno::RuntimeException)
{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
return mbMuted;
}
@@ -538,6 +572,8 @@ sal_Bool SAL_CALL Player::isMute()
void SAL_CALL Player::setVolumeDB( sal_Int16 nVolumeDB )
throw (uno::RuntimeException)
{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
mnUnmutedVolume = pow( 10.0, nVolumeDB / 20.0 );
DBG( "set volume: %d gst volume: %lf", nVolumeDB, mnUnmutedVolume );
@@ -554,6 +590,8 @@ void SAL_CALL Player::setVolumeDB( sal_Int16 nVolumeDB )
sal_Int16 SAL_CALL Player::getVolumeDB()
throw (uno::RuntimeException)
{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
sal_Int16 nVolumeDB(0);
if( mpPlaybin ) {
@@ -572,9 +610,17 @@ sal_Int16 SAL_CALL Player::getVolumeDB()
awt::Size SAL_CALL Player::getPreferredPlayerWindowSize()
throw (uno::RuntimeException)
{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
awt::Size aSize( 0, 0 );
- DBG( "%p Player::getPreferredPlayerWindowSize, member %d x %d", this, mnWidth, mnHeight );
+ if( maURL.isEmpty() )
+ {
+ DBG( "%p Player::getPreferredPlayerWindowSize - empty URL => 0x0", this );
+ return aSize;
+ }
+
+ DBG( "%p pre-Player::getPreferredPlayerWindowSize, member %d x %d", this, mnWidth, mnHeight );
TimeValue aTimeout = { 10, 0 };
#if OSL_DEBUG_LEVEL > 2
@@ -582,9 +628,6 @@ awt::Size SAL_CALL Player::getPreferredPlayerWindowSize()
#endif
maSizeCondition.wait( &aTimeout );
- if( mbFakeVideo ) // ready ourselves for the real thing
- preparePlaybin( maURL, false );
-
DBG( "%p Player::getPreferredPlayerWindowSize after waitCondition %d, member %d x %d", this, aResult, mnWidth, mnHeight );
if( mnWidth != 0 && mnHeight != 0 ) {
@@ -600,9 +643,14 @@ awt::Size SAL_CALL Player::getPreferredPlayerWindowSize()
uno::Reference< ::media::XPlayerWindow > SAL_CALL Player::createPlayerWindow( const uno::Sequence< uno::Any >& rArguments )
throw (uno::RuntimeException)
{
+ ::osl::MutexGuard aGuard(m_aMutex);
+
uno::Reference< ::media::XPlayerWindow > xRet;
awt::Size aSize( getPreferredPlayerWindowSize() );
+ if( mbFakeVideo )
+ preparePlaybin( maURL, NULL );
+
DBG( "Player::createPlayerWindow %d %d length: %d", aSize.Width, aSize.Height, rArguments.getLength() );
if( aSize.Width > 0 && aSize.Height > 0 )
@@ -637,9 +685,15 @@ uno::Reference< ::media::XPlayerWindow > SAL_CALL Player::createPlayerWindow( co
uno::Reference< media::XFrameGrabber > SAL_CALL Player::createFrameGrabber()
throw (uno::RuntimeException)
{
- uno::Reference< media::XFrameGrabber > xRet;
+ ::osl::MutexGuard aGuard(m_aMutex);
+ FrameGrabber* pFrameGrabber = NULL;
+ const awt::Size aPrefSize( getPreferredPlayerWindowSize() );
- return xRet;
+ if( ( aPrefSize.Width > 0 ) && ( aPrefSize.Height > 0 ) )
+ pFrameGrabber = FrameGrabber::create( maURL );
+ DBG( "created FrameGrabber %p", pFrameGrabber );
+
+ return pFrameGrabber;
}
// ------------------------------------------------------------------------------
diff --git a/avmedia/source/gstreamer/gstplayer.hxx b/avmedia/source/gstreamer/gstplayer.hxx
index 82a93e8fa984..5a84a0095689 100644
--- a/avmedia/source/gstreamer/gstplayer.hxx
+++ b/avmedia/source/gstreamer/gstplayer.hxx
@@ -24,6 +24,8 @@
#include "gstcommon.hxx"
#include "com/sun/star/media/XPlayer.hpp"
+#include <cppuhelper/compbase2.hxx>
+#include <cppuhelper/basemutex.hxx>
typedef struct _GstVideoOverlay GstVideoOverlay;
@@ -33,18 +35,21 @@ namespace avmedia { namespace gstreamer {
// - Player -
// ----------
-class Player : public ::cppu::WeakImplHelper2< ::com::sun::star::media::XPlayer,
- ::com::sun::star::lang::XServiceInfo >
+typedef ::cppu::WeakComponentImplHelper2< ::com::sun::star::media::XPlayer,
+ ::com::sun::star::lang::XServiceInfo > GstPlayer_BASE;
+
+class Player : public ::cppu::BaseMutex,
+ public GstPlayer_BASE
{
public:
Player( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxMgr );
~Player();
- void preparePlaybin( const OUString& rURL, bool bFakeVideo );
+ void preparePlaybin( const OUString& rURL, GstElement *pSink );
bool create( const OUString& rURL );
- void processMessage( GstMessage *message );
- GstBusSyncReply processSyncMessage( GstMessage *message );
+ virtual void processMessage( GstMessage *message );
+ virtual GstBusSyncReply processSyncMessage( GstMessage *message );
// XPlayer
virtual void SAL_CALL start( ) throw (::com::sun::star::uno::RuntimeException);
@@ -69,8 +74,10 @@ public:
virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException);
virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException);
-private:
+ // ::cppu::OComponentHelper
+ virtual void SAL_CALL disposing(void);
+protected:
::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxMgr;
OUString maURL;