[Libreoffice-commits] .: avmedia/Library_avmediagst.mk avmedia/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Tue Sep 25 11:18:32 PDT 2012


 avmedia/Library_avmediagst.mk                |    1 
 avmedia/source/gstreamer/gst_0_10.cxx        |    1 
 avmedia/source/gstreamer/gstframegrabber.cxx |  287 +++++++++++++--------------
 avmedia/source/gstreamer/gstframegrabber.hxx |   35 +--
 avmedia/source/gstreamer/gstplayer.cxx       |  102 +++++++--
 avmedia/source/gstreamer/gstplayer.hxx       |   19 +
 6 files changed, 256 insertions(+), 189 deletions(-)

New commits:
commit fc6351f5d36f8b6be5e52a2ea1f191de81eacc71
Author: Michael Meeks <michael.meeks at suse.com>
Date:   Mon Sep 24 21:54:36 2012 +0100

    avmedia: first cut at gstreamer frame grabber.
    
    with thanks to Tim-Philipp Müller and Wim Taymans.
    
    Change-Id: Ia095d06ea3cbed85570cc33038f98da0362c1e62

diff --git a/avmedia/Library_avmediagst.mk b/avmedia/Library_avmediagst.mk
index ee8a09a..528960b 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 c24ec4e..9f2715b 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 a8c0977..c4046f1 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 a16317a..af23cca 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 b8b1ceb..6e00230 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 82a93e8..5a84a00 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;


More information about the Libreoffice-commits mailing list