VLCThumbnailer.cpp 4.19 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*****************************************************************************
 * Media Library
 *****************************************************************************
 * Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
 *
 * Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

23 24
#ifdef HAVE_CONFIG_H
#include "config.h"
25
#endif
26

27 28 29 30
#ifndef HAVE_LIBVLC
# error This file requires libvlc
#endif

31
#include "VLCThumbnailer.h"
32

33 34
#include "Media.h"
#include "File.h"
35
#include "logging/Logger.h"
36
#include "MediaLibrary.h"
37
#include "utils/VLCInstance.h"
38
#include "utils/ModificationsNotifier.h"
39

40 41 42 43
#include <vlcpp/vlc.hpp>

#if LIBVLC_VERSION_INT >= LIBVLC_VERSION(4, 0, 0, 0)
#include "CoreThumbnailer.h"
44
#else
45
#include "VmemThumbnailer.h"
46 47
#endif

48 49 50
namespace medialibrary
{

51 52 53
VLCThumbnailer::VLCThumbnailer( MediaLibraryPtr ml )
    : m_ml( ml )
    , m_run( false )
54
    , m_paused( false )
55
{
56 57 58 59
#if LIBVLC_VERSION_INT >= LIBVLC_VERSION(4, 0, 0, 0)
    m_generator.reset( new CoreThumbnailer( m_ml ) );
#else
    m_generator.reset( new VmemThumbnailer( m_ml ) );
60
#endif
61 62
}

63
VLCThumbnailer::~VLCThumbnailer()
64
{
65
    stop();
66 67
}

68
void VLCThumbnailer::requestThumbnail( MediaPtr media )
69
{
70 71
    {
        std::unique_lock<compat::Mutex> lock( m_mutex );
72
        m_tasks.push( std::move( media ) );
73 74 75 76 77 78
    }
    if ( m_thread.get_id() == compat::Thread::id{} )
    {
        m_run = true;
        m_thread = compat::Thread( &VLCThumbnailer::run, this );
    }
79 80
    else
        m_cond.notify_all();
81 82
}

83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
void VLCThumbnailer::pause()
{
    std::lock_guard<compat::Mutex> lock( m_mutex );
    m_paused = true;
}

void VLCThumbnailer::resume()
{
    std::lock_guard<compat::Mutex> lock( m_mutex );
    if ( m_paused == false )
        return;
    m_paused = false;
    m_cond.notify_all();
}

98
void VLCThumbnailer::run()
99
{
100 101 102
    LOG_INFO( "Starting thumbnailer thread" );
    while ( m_run == true )
    {
103
        MediaPtr media;
104 105
        {
            std::unique_lock<compat::Mutex> lock( m_mutex );
106
            if ( m_tasks.size() == 0 || m_paused == true )
107
            {
108 109 110 111
                m_cond.wait( lock, [this]() {
                    return ( m_tasks.size() > 0 && m_paused == false ) ||
                            m_run == false;
                });
112 113 114
                if ( m_run == false )
                    break;
            }
115
            media = std::move( m_tasks.front() );
116 117
            m_tasks.pop();
        }
118 119
        bool res = generateThumbnail( media );
        m_ml->getCb()->onMediaThumbnailReady( media, res );
120 121 122
    }
    LOG_INFO( "Exiting thumbnailer thread" );
}
123

124 125 126 127 128 129 130 131 132 133 134 135 136 137
void VLCThumbnailer::stop()
{
    bool running = true;
    if ( m_run.compare_exchange_strong( running, false ) )
    {
        {
            std::unique_lock<compat::Mutex> lock( m_mutex );
            while ( m_tasks.empty() == false )
                m_tasks.pop();
        }
        m_cond.notify_all();
        m_thread.join();
    }
}
138

139
bool VLCThumbnailer::generateThumbnail( MediaPtr media )
140
{
141
    assert( media->type() != Media::Type::Audio );
142

143
    auto files = media->files();
144
    if ( files.empty() == true )
145
    {
146
        LOG_WARN( "Can't generate thumbnail for a media without associated files (",
147
                  media->title() );
148
        return false;
149
    }
150
    auto mrl = files[0]->mrl();
151

152 153
    LOG_INFO( "Generating ", mrl, " thumbnail..." );
    if ( m_generator->generate( media, mrl ) == false )
154
        return false;
155

156
    m_ml->getNotifier()->notifyMediaModification( media );
157
    return true;
158
}
159

160
}