/*****************************************************************************
* Copyright (C) 2019 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.
*
* You should have received a copy of the GNU 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.
*****************************************************************************/
#pragma once
#include <QQuickItem>
#include <memory>
#include "qt.hpp"
#include "mlthreadpool.hpp"
#include "mlqmltypes.hpp"
namespace vlc {
namespace playlist {
class Media;
}
}
struct vlc_medialibrary_t;
class MediaLib : public QObject
{
Q_OBJECT
public:
Q_PROPERTY(bool discoveryPending READ discoveryPending NOTIFY discoveryPendingChanged FINAL)
Q_PROPERTY(int parsingProgress READ parsingProgress NOTIFY parsingProgressChanged FINAL)
Q_PROPERTY(QString discoveryEntryPoint READ discoveryEntryPoint NOTIFY discoveryEntryPointChanged FINAL)
Q_PROPERTY(bool idle READ idle NOTIFY idleChanged FINAL)
public:
MediaLib(qt_intf_t* _intf, vlc::playlist::PlaylistController* playlistController, QObject* _parent = nullptr );
~MediaLib();
Q_INVOKABLE static MLItemId deserializeMlItemIdFromString(const QString& serialized_id);
Q_INVOKABLE void addToPlaylist(const MLItemId &itemId, const QStringList &options = {});
Q_INVOKABLE void addToPlaylist(const QString& mrl, const QStringList &options = {});
Q_INVOKABLE void addToPlaylist(const QUrl& mrl, const QStringList &options = {});
Q_INVOKABLE void addToPlaylist(const QVariantList& itemIdList, const QStringList &options = {});
Q_INVOKABLE void addAndPlay(const MLItemId &itemId, const QStringList &options = {});
Q_INVOKABLE void addAndPlay(const QString& mrl, const QStringList &options = {});
Q_INVOKABLE void addAndPlay(const QUrl& mrl, const QStringList &options = {});
Q_INVOKABLE void addAndPlay(const QVariantList&itemIdList, const QStringList &options = {});
Q_INVOKABLE void insertIntoPlaylist(size_t index, const QVariantList &itemIds /*QList<MLParentId>*/, const QStringList &options = {});
Q_INVOKABLE void reload();
Q_INVOKABLE void mlInputItem(const QVector<MLItemId>& itemIdVector, QJSValue callback);
inline bool idle() const { return m_idle; }
inline int discoveryPending() const { return m_discoveryPending; }
inline QString discoveryEntryPoint() const { return m_discoveryEntryPoint; }
inline int parsingProgress() const { return m_parsingProgress; }
vlc_ml_event_callback_t* registerEventListener(void (*callback)(void*, const vlc_ml_event_t*), void* data);
void unregisterEventListener(vlc_ml_event_callback_t*);
/**
* this function allows to run lambdas on the ML thread,
* this should be used to perform operation that requires to call vlc_ml_xxx functions
* as vlc_ml_xxx should *not* be called from the UI thread
*
* @param Ctx is the type of context, this context is created by the runner and passed sequentially to
* the ML callback then to UI callback, the ML callback may modify its properties as a way to pass
* data to the UI callback
*
* @param obj: this is the instance of the calling QObject, we ensure that this object is still live when
* calling the ui callback, if this object gets destroyed the task is canceled
*
* @param mlCb, this callback is executed in a background thread (thread pool), it takes as arguments
* the instance of the medialibrary, and a context, the context can be modified to pass data to the
* UI callback
*
* @param uiCB, this callback is executed on the Qt thread, it takes as first argument the
* id of the tasks, and as second argument the context that was created for the ML callback
*
* @param queue, this allows to specify if the task must be executed on a specific queue, if nullptr
* task may be run by any thread in the threadpool. this is useful if you want to ensure that tasks must
* be executed in order.
*
* @warning the ml callback **SHOULD NOT** capture the obj object or point to its properties by reference,
* as the obj object may potentially be destroyed when the functio is called
*
* the ui callback **MAY** capture the object obj as we will ensure that the object still exists before calling
* the callback
*
* the uiCb **MAY NOT** be called if the object obj is released earlier
*
* anything stored int the context Ctx **MUST** auto release when the context is destroyed
*
* sample usage:
*
* @code
* struct Ctx {
* bool result;
* Data mydata;
* };
* runOnMLThread<Ctx>(this,
* //run on ML thread
* [](vlc_medialibrary_t* ml, Ctx& ctx){
* ctx.result = vlc_ml_xxx(ml, &ctx.mydata):
* },
* //run on UI thread
* [this](quint64 taskId, Ctx& ctx) {
* if (ctx.result)
* emit dataUpdated(ctx.mydata);
* })
* @endcode
*/
template<typename Ctx>
quint64 runOnMLThread(const QObject* obj,
std::function< void(vlc_medialibrary_t* ml, Ctx& ctx)> mlCb,
std::function< void(quint64 taskId, Ctx& ctx)> uiCB,
const char* queue = nullptr);
/**
* same as runOnMLThread<Ctx> when no context passing is required
*/
quint64 runOnMLThread(const QObject* obj,
std::function< void(vlc_medialibrary_t* ml)> mlCb,
std::function< void()> uiCB,
const char* queue = nullptr);
/**
* same as runOnMLThread<Ctx> when no context passing is required
*/
quint64 runOnMLThread(const QObject* obj,
std::function< void(vlc_medialibrary_t* ml)> mlCb,
std::function< void(quint64 taskId)> uiCB,
const char* queue = nullptr);
/**
* same as runOnMLThread<Ctx> when no ui callback is required
*/
quint64 runOnMLThread(const QObject* obj,
std::function< void(vlc_medialibrary_t* ml)> mlCb,
const char* queue = nullptr);
/**
* @brief cancelMLTask, explicitly cancel a running task
*
* @param object the object passed to runOnMLThread
* @param taskId the id of the task to cancel
*
* @note there is warranty whether the ML callback will be run or not.
* The UI callback won't be run unless the task is already terminated.
*
* this must be called from the Qt thread.
*/
void cancelMLTask(const QObject* object, quint64 taskId);
signals:
void discoveryStarted();
void discoveryCompleted();
void parsingProgressChanged( quint32 percent );
void discoveryEntryPointChanged( QString entryPoint );
void discoveryPendingChanged( bool state );
void idleChanged();
private:
static void onMediaLibraryEvent( void* data, const vlc_ml_event_t* event );
private:
qt_intf_t* m_intf;
vlc::playlist::PlaylistController* m_playlistController = nullptr;
bool m_idle = false;
bool m_discoveryPending = false;
int m_parsingProgress = 0;
QString m_discoveryEntryPoint;
/* Medialibrary */
vlc_medialibrary_t* m_ml;
std::unique_ptr<vlc_ml_event_callback_t, std::function<void(vlc_ml_event_callback_t*)>> m_event_cb;
ThreadRunner* m_runner = nullptr;
QMap<QVector<MLItemId>, QVector<QJSValue>> m_inputItemQuery;
};
template<typename Ctx>
quint64 MediaLib::runOnMLThread(const QObject* obj,
std::function<void (vlc_medialibrary_t*, Ctx&)> mlFun,
std::function<void (quint64 taskId, Ctx&)> uiFun,
const char* queue)
{
return m_runner->runOnThread<Ctx>(obj, [ml = m_ml, mlFun](Ctx& ctx){mlFun(ml,ctx);}, uiFun, queue);
}
¤ Dauer der Verarbeitung: 0.6 Sekunden
¤
*© Formatika GbR, Deutschland
|
|