summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinh Ngo <nlminhtl@gmail.com>2013-07-18 18:23:32 +0300
committerMichael Meeks <michael.meeks@suse.com>2013-07-26 07:11:52 +0100
commitb9a70eb2685c8656ff6de00e98e2db57667775c4 (patch)
treea38944e66c397ab23d28002a6f75c26f4b76e184
parent39ade2f88cdd517ccd1c47a6c76768797cdc6011 (diff)
Frame grabber implementation.
Change-Id: I50e6c2681f515aa3f52e7d730cd8bc3001c2d3d4
-rw-r--r--avmedia/source/vlc/vlcframegrabber.cxx104
-rw-r--r--avmedia/source/vlc/vlcframegrabber.hxx11
-rw-r--r--avmedia/source/vlc/vlcplayer.cxx12
-rw-r--r--avmedia/source/vlc/vlcplayer.hxx2
4 files changed, 118 insertions, 11 deletions
diff --git a/avmedia/source/vlc/vlcframegrabber.cxx b/avmedia/source/vlc/vlcframegrabber.cxx
index b8abf30cd828..165abc2dafbb 100644
--- a/avmedia/source/vlc/vlcframegrabber.cxx
+++ b/avmedia/source/vlc/vlcframegrabber.cxx
@@ -1,5 +1,10 @@
+#include <osl/conditn.hxx>
+#include <vcl/bmpacc.hxx>
#include <vcl/graph.hxx>
+#include <avmedia/mediawindow.hxx>
#include "vlcframegrabber.hxx"
+#include "vlcplayer.hxx"
+#include <vlc/libvlc_media_player.h>
using namespace ::com::sun::star;
@@ -8,16 +13,109 @@ namespace vlc {
const ::rtl::OUString AVMEDIA_VLC_GRABBER_IMPLEMENTATIONNAME = "com.sun.star.comp.avmedia.VLCFrameGrabber_VLC";
const ::rtl::OUString AVMEDIA_VLC_GRABBER_SERVICENAME = "com.sun.star.media.VLCFrameGrabber_VLC";
+const int MSEC_IN_SEC = 1000;
-SAL_CALL VLCFrameGrabber::VLCFrameGrabber()
+SAL_CALL VLCFrameGrabber::VLCFrameGrabber( boost::shared_ptr<libvlc_media_player_t>& player, const rtl::OUString& url )
: FrameGrabber_BASE()
+ , mPlayer( player )
+ , mUrl( url )
{
}
+namespace
+{
+ struct FrameData
+ {
+ ::osl::Condition mCondition;
+
+ std::vector<sal_uInt8> buffer;
+
+ libvlc_media_player_t *mpPlayer;
+
+ FrameData( libvlc_media_player_t *pPlayer )
+ : mpPlayer( pPlayer )
+ {
+ }
+
+ void updateSize()
+ {
+ unsigned int w, h;
+ libvlc_video_get_size( mpPlayer, 0, &w, &h );
+
+ buffer.resize(w * h * 3);
+ }
+
+ ~FrameData()
+ {
+ }
+ };
+
+ void *FrameLock( void *data, void **pPixels )
+ {
+ FrameData *frameData = static_cast<FrameData*>( data );
+
+ frameData->updateSize();
+
+ *pPixels = frameData->buffer.data();
+
+ return *pPixels;
+ }
+
+ void FrameUnlock( void *data, void */* id */, void *const * /* pPixels */ )
+ {
+ FrameData *frameData = static_cast<FrameData*>( data );
+
+ frameData->mCondition.set();
+ }
+
+ void FrameDisplay( void */* data */, void */* id */ )
+ {
+ }
+}
+
::uno::Reference< css::graphic::XGraphic > SAL_CALL VLCFrameGrabber::grabFrame( double fMediaTime )
{
- std::cout << __PRETTY_FUNCTION__ << std::endl;
- return ::uno::Reference< css::graphic::XGraphic >();
+ if ( mUrl.isEmpty() )
+ return ::uno::Reference< css::graphic::XGraphic >();
+
+ libvlc_media_player_t *pPlayer = mPlayer.get();
+ FrameData frameData( pPlayer );
+ libvlc_video_set_callbacks( pPlayer, FrameLock, FrameUnlock, FrameDisplay, &frameData );
+
+ const unsigned int w = 480, h = 360;
+
+ libvlc_video_set_format( pPlayer, "RV24", w, h, w * 3 );
+
+ libvlc_media_player_set_time( pPlayer, fMediaTime * MSEC_IN_SEC );
+ libvlc_media_player_play( pPlayer );
+
+ const TimeValue t = {2, 0};
+ frameData.mCondition.wait( &t );
+
+ if ( !frameData.mCondition.check() )
+ return ::uno::Reference< css::graphic::XGraphic >();
+
+ Bitmap aBmp( Size( w, h ), 24 );
+ std::cout << 1 << std::endl;
+ sal_uInt8 *pData = frameData.buffer.data();
+ BitmapWriteAccess *pWrite = aBmp.AcquireWriteAccess();
+ if ( pWrite )
+ {
+ for ( std::size_t y = 0; y < h; ++y )
+ {
+ for ( std::size_t x = 0; x < w; ++x )
+ {
+ sal_uInt8 *p = pData + ( y * w + x ) * 3;
+ BitmapColor col( p[0], p[1], p[2] );
+ pWrite->SetPixel( y, x, col );
+ }
+ }
+ }
+ aBmp.ReleaseAccess( pWrite );
+
+ libvlc_media_player_stop( pPlayer );
+
+ return Graphic( aBmp ).GetXGraphic();
}
::rtl::OUString SAL_CALL VLCFrameGrabber::getImplementationName()
diff --git a/avmedia/source/vlc/vlcframegrabber.hxx b/avmedia/source/vlc/vlcframegrabber.hxx
index 7d4d6647a92c..222e15dccf52 100644
--- a/avmedia/source/vlc/vlcframegrabber.hxx
+++ b/avmedia/source/vlc/vlcframegrabber.hxx
@@ -20,21 +20,26 @@
#ifndef _VLCFRAMEGRABBER_HXX
#define _VLCFRAMEGRABBER_HXX
-#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
#include <com/sun/star/media/XFrameGrabber.hpp>
#include <cppuhelper/implbase2.hxx>
#include "vlccommon.hxx"
+struct libvlc_media_player_t;
+
namespace avmedia {
namespace vlc {
typedef ::cppu::WeakImplHelper2< ::com::sun::star::media::XFrameGrabber,
::com::sun::star::lang::XServiceInfo > FrameGrabber_BASE;
-class VLCFrameGrabber : public FrameGrabber_BASE, boost::noncopyable
+class VLCFrameGrabber : public FrameGrabber_BASE
{
+ boost::shared_ptr<libvlc_media_player_t> mPlayer;
+ const rtl::OUString& mUrl;
public:
- SAL_CALL VLCFrameGrabber();
+ SAL_CALL VLCFrameGrabber( boost::shared_ptr<libvlc_media_player_t>& player, const rtl::OUString& url );
+ void setPlayer( );
::com::sun::star::uno::Reference< css::graphic::XGraphic > SAL_CALL grabFrame( double fMediaTime );
diff --git a/avmedia/source/vlc/vlcplayer.cxx b/avmedia/source/vlc/vlcplayer.cxx
index 376604dc9ef4..3c74bb399914 100644
--- a/avmedia/source/vlc/vlcplayer.cxx
+++ b/avmedia/source/vlc/vlcplayer.cxx
@@ -29,6 +29,7 @@ namespace
{
rtl::OString dest;
url.convertToString(&dest, RTL_TEXTENCODING_UTF8, 0);
+
return libvlc_media_new_path(instance.get(), dest.getStr());
}
}
@@ -37,9 +38,10 @@ VLCPlayer::VLCPlayer( const rtl::OUString& url )
: VLC_Base(m_aMutex)
, mInstance( libvlc_new( sizeof( VLC_ARGS ) / sizeof( VLC_ARGS[0] ), VLC_ARGS ), libvlc_release )
, mPlayer( libvlc_media_player_new( mInstance.get() ), libvlc_media_player_release )
- , mMedia( InitMedia( url, mInstance ), libvlc_media_release )
+ , mUrl( url )
{
- libvlc_media_player_set_media( mPlayer.get(), mMedia.get() );
+ boost::shared_ptr<libvlc_media_t> media( InitMedia( url, mInstance ), libvlc_media_release );
+ mPlayer.reset( libvlc_media_player_new_from_media( media.get() ), libvlc_media_player_release );
}
void SAL_CALL VLCPlayer::start()
@@ -63,7 +65,7 @@ void SAL_CALL VLCPlayer::stop()
double SAL_CALL VLCPlayer::getDuration()
{
::osl::MutexGuard aGuard(m_aMutex);
- return static_cast<double>( libvlc_media_get_duration( mMedia.get() ) ) / MS_IN_SEC;
+ return static_cast<double>( libvlc_media_player_get_length( mPlayer.get() ) ) / MS_IN_SEC;
}
void SAL_CALL VLCPlayer::setMediaTime( double fTime )
@@ -178,7 +180,9 @@ uno::Reference< css::media::XPlayerWindow > SAL_CALL VLCPlayer::createPlayerWind
uno::Reference< css::media::XFrameGrabber > SAL_CALL VLCPlayer::createFrameGrabber()
{
::osl::MutexGuard aGuard(m_aMutex);
- return uno::Reference< css::media::XFrameGrabber >( new VLCFrameGrabber() );
+
+ VLCFrameGrabber *frameGrabber = new VLCFrameGrabber( mPlayer, mUrl );
+ return uno::Reference< css::media::XFrameGrabber >( frameGrabber );
}
::rtl::OUString SAL_CALL VLCPlayer::getImplementationName()
diff --git a/avmedia/source/vlc/vlcplayer.hxx b/avmedia/source/vlc/vlcplayer.hxx
index 7417060f56a9..0c29f3fc9770 100644
--- a/avmedia/source/vlc/vlcplayer.hxx
+++ b/avmedia/source/vlc/vlcplayer.hxx
@@ -39,7 +39,7 @@ class VLCPlayer : public ::cppu::BaseMutex,
{
boost::shared_ptr<libvlc_instance_t> mInstance;
boost::shared_ptr<libvlc_media_player_t> mPlayer;
- boost::shared_ptr<libvlc_media_t> mMedia;
+ const rtl::OUString mUrl;
public:
VLCPlayer( const rtl::OUString& url );