From 71b2e88ff292f8b622b3e1026de164df9433f1b7 Mon Sep 17 00:00:00 2001 From: Minh Ngo Date: Thu, 18 Jul 2013 18:23:32 +0300 Subject: Frame grabber implementation. Change-Id: I50e6c2681f515aa3f52e7d730cd8bc3001c2d3d4 --- avmedia/source/vlc/vlcframegrabber.cxx | 104 ++++++++++++++++++++++++++++++++- avmedia/source/vlc/vlcframegrabber.hxx | 11 +++- avmedia/source/vlc/vlcplayer.cxx | 12 ++-- avmedia/source/vlc/vlcplayer.hxx | 2 +- 4 files changed, 118 insertions(+), 11 deletions(-) (limited to 'avmedia') 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 +#include #include +#include #include "vlcframegrabber.hxx" +#include "vlcplayer.hxx" +#include 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& player, const rtl::OUString& url ) : FrameGrabber_BASE() + , mPlayer( player ) + , mUrl( url ) { } +namespace +{ + struct FrameData + { + ::osl::Condition mCondition; + + std::vector 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( data ); + + frameData->updateSize(); + + *pPixels = frameData->buffer.data(); + + return *pPixels; + } + + void FrameUnlock( void *data, void */* id */, void *const * /* pPixels */ ) + { + FrameData *frameData = static_cast( 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 +#include #include #include #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 mPlayer; + const rtl::OUString& mUrl; public: - SAL_CALL VLCFrameGrabber(); + SAL_CALL VLCFrameGrabber( boost::shared_ptr& 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 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( libvlc_media_get_duration( mMedia.get() ) ) / MS_IN_SEC; + return static_cast( 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 mInstance; boost::shared_ptr mPlayer; - boost::shared_ptr mMedia; + const rtl::OUString mUrl; public: VLCPlayer( const rtl::OUString& url ); -- cgit