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

Fix VLCMetadataService

parent bad4cc4f
#include <iostream>
//debug
#include <chrono>
#include <thread>
#include "VLCMetadataService.h"
#include "IFile.h"
#include "IAlbum.h"
......@@ -15,6 +19,11 @@ VLCMetadataService::VLCMetadataService( const VLC::Instance& vlc )
{
}
VLCMetadataService::~VLCMetadataService()
{
cleanup();
}
bool VLCMetadataService::initialize( IMetadataServiceCb* callback, IMediaLibrary* ml )
{
m_cb = callback;
......@@ -29,21 +38,27 @@ unsigned int VLCMetadataService::priority() const
bool VLCMetadataService::run( FilePtr file, void* data )
{
// 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
cleanup();
auto ctx = new Context( file );
ctx->media = VLC::Media( m_instance, file->mrl(), VLC::Media::FromPath );
ctx->media.eventManager().onParsedChanged([this, ctx, data](bool status) mutable {
if ( status == false )
return;
auto res = handleMediaMeta( file, media );
m_cb->done( file, res, data );
auto res = handleMediaMeta( ctx->file, ctx->media );
m_cb->done( ctx->file, res, data );
// Delegate cleanup for a later time.
// Context owns a media, which owns an EventManager, which owns this lambda
// If we were to delete the context from here, the Media refcount would reach 0,
// thus deleting the media while in use.
// If we use a smart_ptr, then we get cyclic ownership:
// ctx -> media -> eventmanager -> event lambda -> ctx
// leading resources to never be released.
std::unique_lock<std::mutex> lock( m_cleanupLock );
m_cleanup.push_back( ctx );
});
media.parseAsync();
ctx->media.parseAsync();
return true;
}
......@@ -172,3 +187,11 @@ bool VLCMetadataService::parseVideoFile( FilePtr file, VLC::Media& media ) const
}
return true;
}
void VLCMetadataService::cleanup()
{
std::unique_lock<std::mutex> lock( m_cleanupLock );
for ( auto ctx : m_cleanup )
delete ctx;
m_cleanup.clear();
}
......@@ -2,13 +2,26 @@
#define VLCMETADATASERVICE_H
#include <vlcpp/vlc.hpp>
#include <mutex>
#include "IMetadataService.h"
class VLCMetadataService : public IMetadataService
{
struct Context
{
Context(FilePtr file_)
: file( file_ )
{
}
FilePtr file;
VLC::Media media;
};
public:
VLCMetadataService(const VLC::Instance& vlc);
~VLCMetadataService();
virtual bool initialize( IMetadataServiceCb *callback, IMediaLibrary* ml );
virtual unsigned int priority() const;
......@@ -19,9 +32,13 @@ class VLCMetadataService : public IMetadataService
bool parseAudioFile(FilePtr file , VLC::Media &media) const;
bool parseVideoFile(FilePtr file , VLC::Media &media) const;
void cleanup();
VLC::Instance m_instance;
IMetadataServiceCb* m_cb;
IMediaLibrary* m_ml;
std::mutex m_cleanupLock;
std::vector<Context*> m_cleanup;
};
#endif // VLCMETADATASERVICE_H
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