Commit 6de088e2 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

Use shared/unique pointers to manage vlcpp/libvlc objects

parent cdb2aad7
...@@ -27,18 +27,13 @@ ...@@ -27,18 +27,13 @@
namespace VLC namespace VLC
{ {
EventManager::EventManager(const EventManager& em)
: Internal( em )
{
}
bool EventManager::attach(libvlc_event_type_t type, IMediaEventCb* cb) bool EventManager::attach(libvlc_event_type_t type, IMediaEventCb* cb)
{ {
if ( cb == NULL ) if ( cb == NULL )
return false; return false;
if ( type < libvlc_MediaMetaChanged || type > libvlc_MediaSubItemTreeAdded ) if ( type < libvlc_MediaMetaChanged || type > libvlc_MediaSubItemTreeAdded )
return false; return false;
libvlc_event_attach( *this, type, &handleMediaEvent, cb ); libvlc_event_attach( get(), type, &handleMediaEvent, cb );
return true; return true;
} }
...@@ -48,7 +43,7 @@ bool EventManager::attach(libvlc_event_type_t type, IMediaPlayerEventCb* cb) ...@@ -48,7 +43,7 @@ bool EventManager::attach(libvlc_event_type_t type, IMediaPlayerEventCb* cb)
return false; return false;
if ( type < libvlc_MediaPlayerMediaChanged || type > libvlc_MediaPlayerESSelected ) if ( type < libvlc_MediaPlayerMediaChanged || type > libvlc_MediaPlayerESSelected )
return false; return false;
libvlc_event_attach( *this, type, &handleMediaPlayerEvent, cb ); libvlc_event_attach( get(), type, &handleMediaPlayerEvent, cb );
return true; return true;
} }
...@@ -58,7 +53,7 @@ bool EventManager::attach(libvlc_event_type_t type, IMediaListEventCb* cb) ...@@ -58,7 +53,7 @@ bool EventManager::attach(libvlc_event_type_t type, IMediaListEventCb* cb)
return false; return false;
if ( type < libvlc_MediaListItemAdded || type > libvlc_MediaListWillDeleteItem ) if ( type < libvlc_MediaListItemAdded || type > libvlc_MediaListWillDeleteItem )
return false; return false;
libvlc_event_attach( *this, type, &handleMediaListEvent, cb ); libvlc_event_attach( get(), type, &handleMediaListEvent, cb );
return true; return true;
} }
...@@ -68,7 +63,7 @@ bool EventManager::attach(libvlc_event_type_t type, IMediaListPlayerEventCb* cb) ...@@ -68,7 +63,7 @@ bool EventManager::attach(libvlc_event_type_t type, IMediaListPlayerEventCb* cb)
return false; return false;
if ( type < libvlc_MediaListPlayerPlayed || type > libvlc_MediaListPlayerStopped ) if ( type < libvlc_MediaListPlayerPlayed || type > libvlc_MediaListPlayerStopped )
return false; return false;
libvlc_event_attach( *this, type, &handleMediaListPlayerEvent, cb ); libvlc_event_attach( get(), type, &handleMediaListPlayerEvent, cb );
return true; return true;
} }
...@@ -78,7 +73,7 @@ bool EventManager::attach(libvlc_event_type_t type, IMediaDiscovererEventCb* cb) ...@@ -78,7 +73,7 @@ bool EventManager::attach(libvlc_event_type_t type, IMediaDiscovererEventCb* cb)
return false; return false;
if ( type < libvlc_MediaDiscovererStarted || type > libvlc_MediaDiscovererEnded ) if ( type < libvlc_MediaDiscovererStarted || type > libvlc_MediaDiscovererEnded )
return false; return false;
libvlc_event_attach( *this, type, &handleMediaDiscovererEvent, cb ); libvlc_event_attach( get(), type, &handleMediaDiscovererEvent, cb );
return true; return true;
} }
...@@ -88,38 +83,38 @@ bool EventManager::attach( libvlc_event_type_t type, IVLMEventCb* cb ) ...@@ -88,38 +83,38 @@ bool EventManager::attach( libvlc_event_type_t type, IVLMEventCb* cb )
return false; return false;
if ( type < libvlc_VlmMediaAdded || type > libvlc_VlmMediaInstanceStatusError ) if ( type < libvlc_VlmMediaAdded || type > libvlc_VlmMediaInstanceStatusError )
return false; return false;
libvlc_event_attach( *this, type, &handleVLMEvent, cb ); libvlc_event_attach( get(), type, &handleVLMEvent, cb );
return true; return true;
} }
void EventManager::detach(libvlc_event_type_t type, IMediaEventCb* cb) void EventManager::detach(libvlc_event_type_t type, IMediaEventCb* cb)
{ {
libvlc_event_detach( *this, type, &handleMediaEvent, cb ); libvlc_event_detach( get(), type, &handleMediaEvent, cb );
} }
void EventManager::detach(libvlc_event_type_t type, IMediaPlayerEventCb* cb) void EventManager::detach(libvlc_event_type_t type, IMediaPlayerEventCb* cb)
{ {
libvlc_event_detach( *this, type, &handleMediaPlayerEvent, cb ); libvlc_event_detach( get(), type, &handleMediaPlayerEvent, cb );
} }
void EventManager::detach(libvlc_event_type_t type, IMediaListEventCb* cb) void EventManager::detach(libvlc_event_type_t type, IMediaListEventCb* cb)
{ {
libvlc_event_detach( *this, type, &handleMediaListEvent, cb ); libvlc_event_detach( get(), type, &handleMediaListEvent, cb );
} }
void EventManager::detach(libvlc_event_type_t type, IMediaListPlayerEventCb* cb) void EventManager::detach(libvlc_event_type_t type, IMediaListPlayerEventCb* cb)
{ {
libvlc_event_detach( *this, type, &handleMediaListPlayerEvent, cb ); libvlc_event_detach( get(), type, &handleMediaListPlayerEvent, cb );
} }
void EventManager::detach(libvlc_event_type_t type, IMediaDiscovererEventCb* cb) void EventManager::detach(libvlc_event_type_t type, IMediaDiscovererEventCb* cb)
{ {
libvlc_event_detach( *this, type, &handleMediaDiscovererEvent, cb ); libvlc_event_detach( get(), type, &handleMediaDiscovererEvent, cb );
} }
void EventManager::detach(libvlc_event_type_t type, IVLMEventCb* cb) void EventManager::detach(libvlc_event_type_t type, IVLMEventCb* cb)
{ {
libvlc_event_detach( *this, type, &handleVLMEvent, cb ); libvlc_event_detach( get(), type, &handleVLMEvent, cb );
} }
void EventManager::handleMediaEvent(const libvlc_event_t* event, void* data) void EventManager::handleMediaEvent(const libvlc_event_t* event, void* data)
...@@ -131,7 +126,7 @@ void EventManager::handleMediaEvent(const libvlc_event_t* event, void* data) ...@@ -131,7 +126,7 @@ void EventManager::handleMediaEvent(const libvlc_event_t* event, void* data)
cb->metaChanged( event->u.media_meta_changed.meta_type ); cb->metaChanged( event->u.media_meta_changed.meta_type );
break; break;
case libvlc_MediaSubItemAdded: case libvlc_MediaSubItemAdded:
cb->subItemAdded( Media( event->u.media_subitem_added.new_child, true ) ); cb->subItemAdded( std::make_shared<Media>( event->u.media_subitem_added.new_child, true ) );
break; break;
case libvlc_MediaDurationChanged: case libvlc_MediaDurationChanged:
cb->durationChanged( event->u.media_duration_changed.new_duration ); cb->durationChanged( event->u.media_duration_changed.new_duration );
...@@ -140,13 +135,13 @@ void EventManager::handleMediaEvent(const libvlc_event_t* event, void* data) ...@@ -140,13 +135,13 @@ void EventManager::handleMediaEvent(const libvlc_event_t* event, void* data)
cb->parsedChanged( event->u.media_parsed_changed.new_status != 0 ); cb->parsedChanged( event->u.media_parsed_changed.new_status != 0 );
break; break;
case libvlc_MediaFreed: case libvlc_MediaFreed:
cb->freed( Media( event->u.media_freed.md, true ) ); cb->freed( std::make_shared<Media>( event->u.media_freed.md, true ) );
break; break;
case libvlc_MediaStateChanged: case libvlc_MediaStateChanged:
cb->stateChanged( event->u.media_state_changed.new_state ); cb->stateChanged( event->u.media_state_changed.new_state );
break; break;
case libvlc_MediaSubItemTreeAdded: case libvlc_MediaSubItemTreeAdded:
cb->subItemTreeAdded( Media( event->u.media_subitemtree_added.item, true ) ); cb->subItemTreeAdded( std::make_shared<Media>( event->u.media_subitemtree_added.item, true ) );
break; break;
default: default:
assert(false); assert(false);
...@@ -159,7 +154,7 @@ void EventManager::handleMediaPlayerEvent(const libvlc_event_t* event, void* dat ...@@ -159,7 +154,7 @@ void EventManager::handleMediaPlayerEvent(const libvlc_event_t* event, void* dat
switch ( event->type ) switch ( event->type )
{ {
case libvlc_MediaPlayerMediaChanged: case libvlc_MediaPlayerMediaChanged:
cb->mediaChanged( Media( event->u.media_player_media_changed.new_media, true ) ); cb->mediaChanged( std::make_shared<Media>( event->u.media_player_media_changed.new_media, true ) );
break; break;
case libvlc_MediaPlayerNothingSpecial: case libvlc_MediaPlayerNothingSpecial:
cb->nothingSpecial(); cb->nothingSpecial();
...@@ -238,16 +233,16 @@ void EventManager::handleMediaListEvent(const libvlc_event_t* event, void* data) ...@@ -238,16 +233,16 @@ void EventManager::handleMediaListEvent(const libvlc_event_t* event, void* data)
switch ( event->type ) switch ( event->type )
{ {
case libvlc_MediaListItemAdded: case libvlc_MediaListItemAdded:
cb->itemAdded( Media( event->u.media_list_item_added.item, true ), event->u.media_list_item_added.index ); cb->itemAdded( std::make_shared<Media>( event->u.media_list_item_added.item, true ), event->u.media_list_item_added.index );
break; break;
case libvlc_MediaListWillAddItem: case libvlc_MediaListWillAddItem:
cb->willAddItem( Media( event->u.media_list_will_add_item.item, true ), event->u.media_list_will_add_item.index ); cb->willAddItem( std::make_shared<Media>( event->u.media_list_will_add_item.item, true ), event->u.media_list_will_add_item.index );
break; break;
case libvlc_MediaListItemDeleted: case libvlc_MediaListItemDeleted:
cb->itemDeleted( Media( event->u.media_list_item_deleted.item, true ), event->u.media_list_item_deleted.index ); cb->itemDeleted( std::make_shared<Media>( event->u.media_list_item_deleted.item, true ), event->u.media_list_item_deleted.index );
break; break;
case libvlc_MediaListWillDeleteItem: case libvlc_MediaListWillDeleteItem:
cb->willDeleteItem( Media( event->u.media_list_will_delete_item.item, true ), event->u.media_list_will_delete_item.index ); cb->willDeleteItem( std::make_shared<Media>( event->u.media_list_will_delete_item.item, true ), event->u.media_list_will_delete_item.index );
break; break;
default: default:
assert(false); assert(false);
...@@ -263,7 +258,7 @@ void EventManager::handleMediaListPlayerEvent(const libvlc_event_t* event, void* ...@@ -263,7 +258,7 @@ void EventManager::handleMediaListPlayerEvent(const libvlc_event_t* event, void*
cb->played(); cb->played();
break; break;
case libvlc_MediaListPlayerNextItemSet: case libvlc_MediaListPlayerNextItemSet:
cb->nextItemSet( Media( event->u.media_list_player_next_item_set.item, true ) ); cb->nextItemSet( std::make_shared<Media>( event->u.media_list_player_next_item_set.item, true ) );
break; break;
case libvlc_MediaListPlayerStopped: case libvlc_MediaListPlayerStopped:
cb->stopped(); cb->stopped();
...@@ -334,8 +329,8 @@ void EventManager::handleVLMEvent(const libvlc_event_t* event, void* data) ...@@ -334,8 +329,8 @@ void EventManager::handleVLMEvent(const libvlc_event_t* event, void* data)
} }
} }
EventManager::EventManager( InternalPtr obj) EventManager::EventManager(Internal::InternalPtr ptr)
: Internal( obj ) : Internal{ ptr, [](InternalPtr){ /* No-op; EventManager's are handled by their respective objects */ } }
{ {
} }
......
...@@ -37,19 +37,19 @@ class IMediaEventCb ...@@ -37,19 +37,19 @@ class IMediaEventCb
public: public:
virtual ~IMediaEventCb() {} virtual ~IMediaEventCb() {}
virtual void metaChanged( libvlc_meta_t ) {} virtual void metaChanged( libvlc_meta_t ) {}
virtual void subItemAdded( const Media& ) {} virtual void subItemAdded( MediaPtr ) {}
virtual void durationChanged( int64_t ) {} virtual void durationChanged( int64_t ) {}
virtual void parsedChanged( bool ) {} virtual void parsedChanged( bool ) {}
virtual void freed( const Media& ) {} virtual void freed( MediaPtr ) {}
virtual void stateChanged( libvlc_state_t ) {} virtual void stateChanged( libvlc_state_t ) {}
virtual void subItemTreeAdded( const Media& ) {} virtual void subItemTreeAdded( MediaPtr ) {}
}; };
class IMediaPlayerEventCb class IMediaPlayerEventCb
{ {
public: public:
virtual ~IMediaPlayerEventCb(){} virtual ~IMediaPlayerEventCb(){}
virtual void mediaChanged( const Media& ) {} virtual void mediaChanged( MediaPtr ) {}
virtual void nothingSpecial() {} virtual void nothingSpecial() {}
virtual void opening() {} virtual void opening() {}
virtual void buffering( float ) {} virtual void buffering( float ) {}
...@@ -78,10 +78,10 @@ class IMediaListEventCb ...@@ -78,10 +78,10 @@ class IMediaListEventCb
{ {
public: public:
virtual ~IMediaListEventCb() {} virtual ~IMediaListEventCb() {}
virtual void itemAdded( const Media&, int ) {} virtual void itemAdded( MediaPtr, int ) {}
virtual void willAddItem( const Media&, int ) {} virtual void willAddItem( MediaPtr, int ) {}
virtual void itemDeleted( const Media&, int ) {} virtual void itemDeleted( MediaPtr, int ) {}
virtual void willDeleteItem( const Media&, int ) {} virtual void willDeleteItem( MediaPtr, int ) {}
}; };
// MediaListView events are not being sent by VLC, so we don't implement them here // MediaListView events are not being sent by VLC, so we don't implement them here
...@@ -91,7 +91,7 @@ class IMediaListPlayerEventCb ...@@ -91,7 +91,7 @@ class IMediaListPlayerEventCb
public: public:
virtual ~IMediaListPlayerEventCb() {} virtual ~IMediaListPlayerEventCb() {}
virtual void played() {} virtual void played() {}
virtual void nextItemSet( const Media& ) {} virtual void nextItemSet( MediaPtr ) {}
virtual void stopped() {} virtual void stopped() {}
}; };
...@@ -123,7 +123,8 @@ class IVLMEventCb ...@@ -123,7 +123,8 @@ class IVLMEventCb
class VLCPP_API EventManager : public Internal<libvlc_event_manager_t> class VLCPP_API EventManager : public Internal<libvlc_event_manager_t>
{ {
public: public:
EventManager( const EventManager& em ); EventManager(InternalPtr ptr);
bool attach( libvlc_event_type_t type, IMediaEventCb* cb ); bool attach( libvlc_event_type_t type, IMediaEventCb* cb );
bool attach( libvlc_event_type_t type, IMediaPlayerEventCb* cb ); bool attach( libvlc_event_type_t type, IMediaPlayerEventCb* cb );
bool attach( libvlc_event_type_t type, IMediaListEventCb* cb ); bool attach( libvlc_event_type_t type, IMediaListEventCb* cb );
...@@ -147,13 +148,6 @@ class VLCPP_API EventManager : public Internal<libvlc_event_manager_t> ...@@ -147,13 +148,6 @@ class VLCPP_API EventManager : public Internal<libvlc_event_manager_t>
static void handleVLMEvent( const libvlc_event_t* event, void* data ); static void handleVLMEvent( const libvlc_event_t* event, void* data );
static void handleEvent( const libvlc_event_t* event, void* data ); static void handleEvent( const libvlc_event_t* event, void* data );
EventManager(InternalPtr obj );
friend class Media;
friend class MediaDiscoverer;
friend class MediaList;
friend class MediaListPlayer;
friend class MediaPlayer;
}; };
} }
......
...@@ -27,26 +27,8 @@ namespace VLC ...@@ -27,26 +27,8 @@ namespace VLC
{ {
Instance::Instance(int argc, const char* const* argv) Instance::Instance(int argc, const char* const* argv)
: Internal{ libvlc_new( argc, argv ), libvlc_release }
{ {
m_obj = libvlc_new( argc, argv );
}
Instance::Instance( const Instance& another )
: Internal( another )
{
retain();
}
Instance& Instance::operator=( const Instance& another )
{
if ( this == &another )
{
return *this;
}
release();
m_obj = another.m_obj;
retain();
return *this;
} }
bool Instance::operator==( const Instance& another ) const bool Instance::operator==( const Instance& another ) const
...@@ -54,49 +36,44 @@ bool Instance::operator==( const Instance& another ) const ...@@ -54,49 +36,44 @@ bool Instance::operator==( const Instance& another ) const
return m_obj == another.m_obj; return m_obj == another.m_obj;
} }
Instance::~Instance()
{
release();
}
int Instance::addIntf( const std::string& name ) int Instance::addIntf( const std::string& name )
{ {
return libvlc_add_intf( m_obj, name.c_str() ); return libvlc_add_intf( get(), name.c_str() );
} }
void Instance::setExitHandler( void(*cb)(void *), void * opaque ) void Instance::setExitHandler( void(*cb)(void *), void * opaque )
{ {
libvlc_set_exit_handler( m_obj, cb, opaque ); libvlc_set_exit_handler( get(), cb, opaque );
} }
void Instance::setUserAgent( const std::string& name, const std::string& http ) void Instance::setUserAgent( const std::string& name, const std::string& http )
{ {
libvlc_set_user_agent( m_obj, name.c_str(), http.c_str() ); libvlc_set_user_agent( get(), name.c_str(), http.c_str() );
} }
void Instance::setAppId( const std::string& id, const std::string& version, const std::string& icon ) void Instance::setAppId( const std::string& id, const std::string& version, const std::string& icon )
{ {
libvlc_set_app_id( m_obj, id.c_str(), version.c_str(), icon.c_str() ); libvlc_set_app_id( get(), id.c_str(), version.c_str(), icon.c_str() );
} }
void Instance::logUnset() void Instance::logUnset()
{ {
libvlc_log_unset( m_obj ); libvlc_log_unset( get() );
} }
void Instance::logSet( libvlc_log_cb cb, void * data ) void Instance::logSet( libvlc_log_cb cb, void * data )
{ {
libvlc_log_set(m_obj, cb, data); libvlc_log_set(get(), cb, data);
} }
void Instance::logSetFile( FILE * stream ) void Instance::logSetFile( FILE * stream )
{ {
libvlc_log_set_file( m_obj, stream ); libvlc_log_set_file( get(), stream );
} }
std::vector<ModuleDescription> Instance::audioFilterList() std::vector<ModuleDescription> Instance::audioFilterList()
{ {
libvlc_module_description_t* result = libvlc_audio_filter_list_get(m_obj); libvlc_module_description_t* result = libvlc_audio_filter_list_get(get());
std::vector<ModuleDescription> res; std::vector<ModuleDescription> res;
if ( result == NULL ) if ( result == NULL )
return res; return res;
...@@ -112,7 +89,7 @@ std::vector<ModuleDescription> Instance::audioFilterList() ...@@ -112,7 +89,7 @@ std::vector<ModuleDescription> Instance::audioFilterList()
std::vector<ModuleDescription> Instance::videoFilterList() std::vector<ModuleDescription> Instance::videoFilterList()
{ {
libvlc_module_description_t* result = libvlc_video_filter_list_get(m_obj); libvlc_module_description_t* result = libvlc_video_filter_list_get(get());
std::vector<ModuleDescription> res; std::vector<ModuleDescription> res;
if ( result == NULL ) if ( result == NULL )
return res; return res;
...@@ -128,7 +105,7 @@ std::vector<ModuleDescription> Instance::videoFilterList() ...@@ -128,7 +105,7 @@ std::vector<ModuleDescription> Instance::videoFilterList()
std::vector<AudioOutputDescription> Instance::audioOutputList() std::vector<AudioOutputDescription> Instance::audioOutputList()
{ {
libvlc_audio_output_t* result = libvlc_audio_output_list_get(m_obj); libvlc_audio_output_t* result = libvlc_audio_output_list_get(get());
std::vector<AudioOutputDescription> res; std::vector<AudioOutputDescription> res;
if ( result == NULL ) if ( result == NULL )
return res; return res;
...@@ -144,7 +121,7 @@ std::vector<AudioOutputDescription> Instance::audioOutputList() ...@@ -144,7 +121,7 @@ std::vector<AudioOutputDescription> Instance::audioOutputList()
std::vector<AudioOutputDeviceDescription> Instance::audioOutputDeviceList(const std::string& aout) std::vector<AudioOutputDeviceDescription> Instance::audioOutputDeviceList(const std::string& aout)
{ {
libvlc_audio_output_device_t* devices = libvlc_audio_output_device_list_get( m_obj, aout.c_str() ); libvlc_audio_output_device_t* devices = libvlc_audio_output_device_list_get( get(), aout.c_str() );
std::vector<AudioOutputDeviceDescription> res; std::vector<AudioOutputDeviceDescription> res;
if ( devices == NULL ) if ( devices == NULL )
return res; return res;
...@@ -154,17 +131,5 @@ std::vector<AudioOutputDeviceDescription> Instance::audioOutputDeviceList(const ...@@ -154,17 +131,5 @@ std::vector<AudioOutputDeviceDescription> Instance::audioOutputDeviceList(const
return res; return res;
} }
void Instance::release()
{
if ( isValid() )
libvlc_release(m_obj);
}
void Instance::retain()
{
if ( isValid() )
libvlc_retain(m_obj);
}
} // namespace VLC } // namespace VLC
...@@ -60,19 +60,6 @@ public: ...@@ -60,19 +60,6 @@ public:
*/ */
Instance(int argc, const char *const * argv); Instance(int argc, const char *const * argv);
/**
* Copy libvlc_instance_t from another to new Instance object.
* \param another existing Instance
*/
Instance(const Instance& another);
/**
* Copy libvlc_instance_t from another Instance
* to this Instance
* \param another existing Instance
*/
Instance& operator=(const Instance& another);
/** /**
* Check if 2 Instance objects contain the same libvlc_instance_t. * Check if 2 Instance objects contain the same libvlc_instance_t.
* \param another another Instance * \param another another Instance
...@@ -80,8 +67,6 @@ public: ...@@ -80,8 +67,6 @@ public:
*/ */
bool operator==(const Instance& another) const; bool operator==(const Instance& another) const;
~Instance();
/** /**
* Try to start a user interface for the libvlc instance. * Try to start a user interface for the libvlc instance.
* *
...@@ -240,20 +225,6 @@ public: ...@@ -240,20 +225,6 @@ public:
* \version LibVLC 2.1.0 or later. * \version LibVLC 2.1.0 or later.
*/ */
std::vector<AudioOutputDeviceDescription> audioOutputDeviceList(const std::string& aout); std::vector<AudioOutputDeviceDescription> audioOutputDeviceList(const std::string& aout);
private:
explicit Instance( InternalPtr ptr, bool increaseRefCount );
/**
* Decrement the reference count of a libvlc instance, and destroy it if
* it reaches zero.
*/
void release();
/**
* Increments the reference count of a libvlc instance. The initial
* reference count is 1 after Instance::Instance() returns.
*/
void retain();
}; };
} // namespace VLC } // namespace VLC
......
...@@ -26,31 +26,36 @@ ...@@ -26,31 +26,36 @@
#include <cassert> #include <cassert>
#include <stdlib.h> #include <stdlib.h>
#include <vlc/libvlc.h> #include <vlc/libvlc.h>
#include <memory>
#include <stdexcept>
namespace VLC