Commit 4d4b192b authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

Fix build & update to new libvlcpp

parent 1b010996
......@@ -13,7 +13,7 @@ class IMetadataServiceCb
class IMetadataService
{
public:
virtual ~IMetadataService() {}
virtual ~IMetadataService() = default;
virtual bool initialize( IMetadataServiceCb* callback, IMediaLibrary* ml ) = 0;
virtual unsigned int priority() const = 0;
virtual bool run( FilePtr file, void* data ) = 0;
......
......@@ -15,11 +15,6 @@ VLCMetadataService::VLCMetadataService( const VLC::Instance& vlc )
{
}
VLCMetadataService::~VLCMetadataService()
{
cleanup();
}
bool VLCMetadataService::initialize( IMetadataServiceCb* callback, IMediaLibrary* ml )
{
m_cb = callback;
......@@ -27,7 +22,6 @@ bool VLCMetadataService::initialize( IMetadataServiceCb* callback, IMediaLibrary
return true;
}
unsigned int VLCMetadataService::priority() const
{
return 100;
......@@ -35,25 +29,27 @@ unsigned int VLCMetadataService::priority() const
bool VLCMetadataService::run( FilePtr file, void* data )
{
cleanup();
auto ctx = new Context( this, file, data );
// libvlc_audio_output_set( ctx->mp, "dummy" );
ctx->media.parseAsync();
// Keeping this old comment for future reference:
// We can't cleanup from the callback since it's called from a VLC thread.
// If the refcounter was to reach 0 from there, it would destroy resources
// that are still held.
// ------------------------
VLC::Media media( m_instance, file->mrl(), VLC::Media::FromPath );
media.eventManager().onParsedChanged([this, file, media, data](bool status) mutable {
//FIXME: This is probably leaking due to cross referencing
if ( status == false )
return;
auto res = handleMediaMeta( file, media );
m_cb->done( file, res, data );
});
media.parseAsync();
return true;
}
void VLCMetadataService::parse(VLCMetadataService::Context* ctx)
ServiceStatus VLCMetadataService::handleMediaMeta( FilePtr file, VLC::Media& media )
{
auto status = handleMediaMeta( ctx );
ctx->self->m_cb->done( ctx->file, status, ctx->data );
std::lock_guard<std::mutex> lock( m_lock );
m_cleanup.push_back( ctx );
}
ServiceStatus VLCMetadataService::handleMediaMeta( VLCMetadataService::Context* ctx )
{
auto tracks = ctx->media.tracks();
auto tracks = media.tracks();
if ( tracks.size() == 0 )
{
std::cerr << "Failed to fetch tracks" << std::endl;
......@@ -68,32 +64,32 @@ ServiceStatus VLCMetadataService::handleMediaMeta( VLCMetadataService::Context*
{
isAudio = false;
auto fps = (float)track.fpsNum() / (float)track.fpsDen();
ctx->file->addVideoTrack( fcc, track.width(), track.height(), fps );
file->addVideoTrack( fcc, track.width(), track.height(), fps );
}
else if ( track.type() == VLC::MediaTrack::Audio )
{
ctx->file->addAudioTrack( fcc, track.bitrate(), track.rate(),
file->addAudioTrack( fcc, track.bitrate(), track.rate(),
track.channels() );
}
}
if ( isAudio == true )
{
if ( parseAudioFile( ctx ) == false )
if ( parseAudioFile( file, media ) == false )
return StatusFatal;
}
else
{
if (parseVideoFile( ctx ) == false )
if (parseVideoFile( file, media ) == false )
return StatusFatal;
}
auto file = std::static_pointer_cast<File>( ctx->file );
file->setReady();
auto f = std::static_pointer_cast<File>( file );
f->setReady();
return StatusSuccess;
}
bool VLCMetadataService::parseAudioFile( VLCMetadataService::Context* ctx )
bool VLCMetadataService::parseAudioFile( FilePtr file, VLC::Media& media )
{
auto albumTitle = ctx->media.meta( libvlc_meta_Album );
auto albumTitle = media.meta( libvlc_meta_Album );
if ( albumTitle.length() == 0 )
return true;
auto album = m_ml->album( albumTitle );
......@@ -105,17 +101,17 @@ bool VLCMetadataService::parseAudioFile( VLCMetadataService::Context* ctx )
return false;
}
auto trackNbStr = ctx->media.meta( libvlc_meta_TrackNumber );
auto trackNbStr = media.meta( libvlc_meta_TrackNumber );
if ( trackNbStr.length() == 0 )
{
std::cerr << "Failed to get track id" << std::endl;
return false;
}
auto artwork = ctx->media.meta( libvlc_meta_ArtworkURL );
auto artwork = media.meta( libvlc_meta_ArtworkURL );
if ( artwork.length() != 0 )
album->setArtworkUrl( artwork );
auto title = ctx->media.meta( libvlc_meta_Title );
auto title = media.meta( libvlc_meta_Title );
if ( title.length() == 0 )
{
std::cerr << "Failed to compute track title" << std::endl;
......@@ -129,35 +125,35 @@ bool VLCMetadataService::parseAudioFile( VLCMetadataService::Context* ctx )
std::cerr << "Failure while creating album track" << std::endl;
return false;
}
ctx->file->setAlbumTrack( track );
file->setAlbumTrack( track );
auto genre = ctx->media.meta( libvlc_meta_Genre );
auto genre = media.meta( libvlc_meta_Genre );
if ( genre.length() != 0 )
track->setGenre( genre );
auto artist = ctx->media.meta( libvlc_meta_Artist );
auto artist = media.meta( libvlc_meta_Artist );
if ( artist.length() != 0 )
track->setArtist( artist );
return true;
}
bool VLCMetadataService::parseVideoFile( VLCMetadataService::Context* ctx )
bool VLCMetadataService::parseVideoFile( FilePtr file, VLC::Media& media )
{
auto title = ctx->media.meta( libvlc_meta_Title );
auto title = media.meta( libvlc_meta_Title );
if ( title.length() == 0 )
return true;
auto showName = ctx->media.meta( libvlc_meta_ShowName );
auto showName = media.meta( libvlc_meta_ShowName );
if ( showName.length() == 0 )
{
auto show = ctx->self->m_ml->show( showName );
auto show = m_ml->show( showName );
if ( show == nullptr )
{
show = ctx->self->m_ml->createShow( showName );
show = m_ml->createShow( showName );
if ( show == nullptr )
return false;
}
auto episodeIdStr = ctx->media.meta( libvlc_meta_Episode );
auto episodeIdStr = media.meta( libvlc_meta_Episode );
if ( episodeIdStr.length() > 0 )
{
size_t endpos;
......@@ -176,33 +172,3 @@ bool VLCMetadataService::parseVideoFile( VLCMetadataService::Context* ctx )
}
return true;
}
void VLCMetadataService::cleanup()
{
std::lock_guard<std::mutex> lock( m_lock );
while ( m_cleanup.empty() == false )
{
delete m_cleanup.back();
m_cleanup.pop_back();
}
}
VLCMetadataService::Context::Context( VLCMetadataService* self, FilePtr file, void* data )
: self( self )
, file( file )
, data( data )
, media( VLC::Media::fromPath( self->m_instance, file->mrl() ) )
{
media.eventManager().attach( libvlc_MediaParsedChanged, this );
}
VLCMetadataService::Context::~Context()
{
media.eventManager().detach( libvlc_MediaParsedChanged, this );
}
void VLCMetadataService::Context::parsedChanged(bool status)
{
if ( status == true )
self->parse( this );
}
#ifndef VLCMETADATASERVICE_H
#define VLCMETADATASERVICE_H
#include <vlc/vlc.h>
#include <vlcpp/vlc.hpp>
#include <mutex>
#include "IMetadataService.h"
......@@ -11,43 +9,19 @@ class VLCMetadataService : public IMetadataService
{
public:
VLCMetadataService(const VLC::Instance& vlc);
virtual ~VLCMetadataService();
virtual bool initialize( IMetadataServiceCb *callback, IMediaLibrary* ml );
virtual unsigned int priority() const;
virtual bool run( FilePtr file, void *data );
private:
struct Context : public ::VLC::IMediaEventCb
{
Context(VLCMetadataService* self, FilePtr file, void* data );
~Context();
VLCMetadataService* self;
FilePtr file;
void* data;
VLC::Media media;
private:
virtual void parsedChanged( bool status ) override;
};
private:
static void eventCallback( const libvlc_event_t* e, void* data );
void parse( Context* ctx );
ServiceStatus handleMediaMeta( Context* ctx );
bool parseAudioFile( Context* ctx );
bool parseVideoFile( Context* ctx );
void cleanup();
ServiceStatus handleMediaMeta(FilePtr file , VLC::Media &media);
bool parseAudioFile(FilePtr file , VLC::Media &media);
bool parseVideoFile(FilePtr file , VLC::Media &media);
VLC::Instance m_instance;
IMetadataServiceCb* m_cb;
IMediaLibrary* m_ml;
// We can't cleanup from the callback since it's called from a VLC thread.
// If the refcounter was to reach 0 from there, it would destroy resources
// that are still held.
std::vector<Context*> m_cleanup;
std::mutex m_lock;
};
#endif // VLCMETADATASERVICE_H
......@@ -51,6 +51,7 @@ add_dependencies(unittest gtest-dependency)
target_link_libraries(unittest medialibrary)
target_link_libraries(unittest gtest gtest_main)
include_directories(${LIBVLCPP_DIR})
# Also add pthread, as gtest requires it
if(UNIX)
target_link_libraries(unittest "pthread")
......
#include "Tests.h"
#include <vlc/vlc.h>
#include <chrono>
#include <condition_variable>
......@@ -59,11 +58,11 @@ class VLCMetadataServices : public Tests
const char* args[] = {
"-vv"
};
auto vlcInstance = VLC::Instance::create( sizeof(args) / sizeof(args[0]), args );
ASSERT_TRUE( vlcInstance.isValid() );
VLC::Instance vlcInstance( sizeof(args) / sizeof(args[0]), args );
auto vlcService = new VLCMetadataService( vlcInstance );
// This takes ownership of vlcService
//FIXME: This sucks because ownership isn't expressed properly...
ml->addMetadataService( vlcService );
}
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment