[vlc-commits] [Git][videolan/vlc][master] 9 commits: media tree: make functions public

Steve Lhomme (@robUx4) gitlab at videolan.org
Tue Oct 11 11:20:17 UTC 2022



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
c808e3e8 by Romain Vimont at 2022-10-11T11:04:00+00:00
media tree: make functions public

This will allow to create and handle a media tree separately from a
media source (linked to a service discovery).

- - - - -
07fc99b9 by Romain Vimont at 2022-10-11T11:04:00+00:00
qt: remove unused default constructor

- - - - -
0aeafa2d by Romain Vimont at 2022-10-11T11:04:00+00:00
qt: remove unnecessary explicit destructor

- - - - -
1a9ab8b5 by Romain Vimont at 2022-10-11T11:04:00+00:00
qt: use static free functions for C callbacks

Callbacks to be called from C should be free functions rather than class
members.

- - - - -
eae4b0c0 by Romain Vimont at 2022-10-11T11:04:00+00:00
qt: use one "callbacks" instance per listener

For each model (NetworkDeviceModel and NetworkMediaModel), every
NetworkSourceListener instance were created with the same
SourceListenercb instance:

   +------------------+
   | SourceListenerCb |-----------------------------.
   +------------------+                             |
           ^                                        |
           | implements                             |
  +--------------------+                            |
  | NetworkDeviceModel |                            |
  +--------------------+                            |
           | m_listeners                            |
         +---+            +-----------------------+ |
         | ---------------| NetworkSourceListener |-|
         +---+            +-----------------------+ |
         | ----------     +-----------------------+ |
         +---+       `----| NetworkSourceListener |-|
         | -------...     +-----------------------+ .
         +---+                                      .
         |   |                                      .
         +---+

To prepare storing additional data for each registration, use one
SourceListenerCb instance per listener:

                                                  +------------------+
                                                  | SourceListenerCb |
                                                  +------------------+
                                                                   ^
                                                        implements |
  +--------------------+                                           |
  | NetworkDeviceModel |                                           |
  +--------------------+                                           |
           | m_listeners                                           |
         +---+         +-----------------------+  +--------------+ |
         | ------------| NetworkSourceListener |--| MyListenerCb |-|
         +---+         +-----------------------+  +--------------+ |
         | ----------  +-----------------------+  +--------------+ |
         +---+       `-| NetworkSourceListener |--| MyListenerCb |-|
         | -------...  +-----------------------+  +--------------+ .
         +---+                                                     .
         |   |                                                     .
         +---+

In practice, this will allow the SourceListenerCb (to be renamed to
MediaTreeListenerCb) to only use a media tree (not a media source), and
let the caller store an additional associated media source usable
from the callbacks implementation.

As a drawback, the MyListenerCb instance must be owned by the listener
(to avoid additional complexity on the client side), but then this
forces the client to always create a separate class for the listener
callbacks, even when not necessary (i.e. making NetworkMediaModel
"implement" SourceListenerCb is not possible anymore).

Alternatives considered:
 1. keep SourceListenerCb as is, but make NetworkSourceListener virtual
    (inheritable), so that the additional media source could be stored
    there. As a drawback, the SourceListenerCb methods would need to get
    the NetworkSourceListener instance as parameter (so yet another
    indirection). And having both the listener and the callbacks virtual
    seems odd.
 2. merge SourceListenerCb into NetworkSourceListener, so that the
    client can just inherit and store additional private data in the
    same class. But this requires more changes from the existing code
    base.

- - - - -
baacc656 by Romain Vimont at 2022-10-11T11:04:00+00:00
qt: remove unused include

- - - - -
104fa8e8 by Romain Vimont at 2022-10-11T11:04:00+00:00
qt: remove unused mediaSource

Only NetworkDeviceModel need to expose a mediaSource. The mediaSource
was forwarded to all media item, but it is never used, so remove it.

This paves the way to make NetworkMediaModel independent of media
sources.

- - - - -
b9552485 by Romain Vimont at 2022-10-11T11:04:00+00:00
qt: avoid unnecessary smart pointer copies

- - - - -
7cc8e707 by Romain Vimont at 2022-10-11T11:04:00+00:00
qt: refactor media tree listener

This C++ listener is actually a wrapper over a media tree listener, not
a media source listener.

This allows to make NetworkMediaModel independent of media sources, so
that it can be reused with only a media tree not linked to a media
source.

NetworkDeviceModel, which still requires a media source, stores it in
its listener callbacks implementation (ListenerCb).

- - - - -


17 changed files:

- include/vlc_media_source.h
- modules/gui/qt/Makefile.am
- + modules/gui/qt/network/mediatreelistener.cpp
- modules/gui/qt/network/networksourcelistener.hpp → modules/gui/qt/network/mediatreelistener.hpp
- modules/gui/qt/network/networkdevicemodel.cpp
- modules/gui/qt/network/networkdevicemodel.hpp
- modules/gui/qt/network/networkmediamodel.cpp
- modules/gui/qt/network/networkmediamodel.hpp
- − modules/gui/qt/network/networksourcelistener.cpp
- modules/gui/qt/network/networksourcesmodel.cpp
- modules/gui/qt/network/networksourcesmodel.hpp
- src/Makefile.am
- src/libvlccore.sym
- src/media_source/media_source.c
- src/media_source/media_tree.c
- − src/media_source/media_tree.h
- src/media_source/test.c


Changes:

=====================================
include/vlc_media_source.h
=====================================
@@ -126,6 +126,12 @@ struct vlc_media_tree_callbacks
                        void *userdata);
 };
 
+/**
+ * Create an empty media tree.
+ */
+VLC_API vlc_media_tree_t *
+vlc_media_tree_New(void);
+
 /**
  * Listener for media tree events.
  */
@@ -157,6 +163,24 @@ VLC_API void
 vlc_media_tree_RemoveListener(vlc_media_tree_t *tree,
                               vlc_media_tree_listener_id *listener);
 
+/**
+ * Increase the media tree reference count.
+ *
+ * \param tree the media tree, unlocked
+ */
+VLC_API void
+vlc_media_tree_Hold(vlc_media_tree_t *tree);
+
+/**
+ * Decrease the media tree reference count.
+ *
+ * Destroy the media tree if it reaches 0.
+ *
+ * \param tree the media tree, unlocked
+ */
+VLC_API void
+vlc_media_tree_Release(vlc_media_tree_t *tree);
+
 /**
  * Lock the media tree (non-recursive).
  */
@@ -169,6 +193,26 @@ vlc_media_tree_Lock(vlc_media_tree_t *);
 VLC_API void
 vlc_media_tree_Unlock(vlc_media_tree_t *);
 
+/**
+ * Add an item to the media tree.
+ *
+ * \param tree the media tree, locked
+ * \param parent the parent node, belonging to the media tree
+ * \param media the media to add as a child of `parent`
+ */
+VLC_API input_item_node_t *
+vlc_media_tree_Add(vlc_media_tree_t *tree, input_item_node_t *parent,
+                   input_item_t *media);
+
+/**
+ * Remove an item from the media tree.
+ *
+ * \param tree the media tree, locked
+ * \param media the media to remove
+ */
+VLC_API bool
+vlc_media_tree_Remove(vlc_media_tree_t *tree, input_item_t *media);
+
 /**
  * Find the node containing the requested input item (and its parent).
  *


=====================================
modules/gui/qt/Makefile.am
=====================================
@@ -230,14 +230,14 @@ libqt_plugin_la_SOURCES = \
 	gui/qt/menus/qml_menu_wrapper.cpp \
 	gui/qt/menus/qml_menu_wrapper.hpp \
 	gui/qt/menus/menus.cpp gui/qt/menus/menus.hpp \
+	gui/qt/network/mediatreelistener.cpp \
+	gui/qt/network/mediatreelistener.hpp \
 	gui/qt/network/networkdevicemodel.cpp \
 	gui/qt/network/networkdevicemodel.hpp \
 	gui/qt/network/networksourcesmodel.cpp \
 	gui/qt/network/networksourcesmodel.hpp \
 	gui/qt/network/networkmediamodel.cpp \
 	gui/qt/network/networkmediamodel.hpp \
-	gui/qt/network/networksourcelistener.cpp \
-	gui/qt/network/networksourcelistener.hpp \
 	gui/qt/network/servicesdiscoverymodel.cpp \
 	gui/qt/network/servicesdiscoverymodel.hpp \
 	gui/qt/player/input_models.cpp gui/qt/player/input_models.hpp \


=====================================
modules/gui/qt/network/mediatreelistener.cpp
=====================================
@@ -0,0 +1,51 @@
+#include "mediatreelistener.hpp"
+
+static void onItemCleared(vlc_media_tree_t*, input_item_node_t *node,
+                          void* userdata)
+{
+    auto* self = static_cast<MediaTreeListener*>( userdata );
+    self->cb->onItemCleared( self->tree, node );
+}
+
+static void onItemAdded(vlc_media_tree_t *, input_item_node_t *parent,
+                        input_item_node_t *const children[], size_t count,
+                        void *userdata)
+{
+    auto* self = static_cast<MediaTreeListener*>( userdata );
+    self->cb->onItemAdded( self->tree, parent, children, count );
+}
+
+static void onItemRemoved(vlc_media_tree_t *, input_item_node_t *node,
+                          input_item_node_t *const children[], size_t count,
+                          void *userdata)
+{
+    auto* self = static_cast<MediaTreeListener*>( userdata );
+    self->cb->onItemRemoved( self->tree, node, children, count );
+}
+
+static void onItemPreparseEnded(vlc_media_tree_t *, input_item_node_t * node,
+                                enum input_item_preparse_status status,
+                                void *userdata)
+{
+    auto* self = static_cast<MediaTreeListener*>( userdata );
+    self->cb->onItemPreparseEnded( self->tree, node, status );
+}
+
+MediaTreeListener::MediaTreeListener(MediaTreePtr tree, std::unique_ptr<MediaTreeListenerCb> &&cb )
+    : tree( tree )
+    , listener( nullptr, [tree]( vlc_media_tree_listener_id* l ) {
+            vlc_media_tree_RemoveListener( tree.get(), l );
+        } )
+    , cb( std::move( cb ) )
+{
+    static const vlc_media_tree_callbacks cbs {
+        &onItemCleared,
+        &onItemAdded,
+        &onItemRemoved,
+        &onItemPreparseEnded
+    };
+    auto l = vlc_media_tree_AddListener( tree.get(), &cbs, this, true );
+    if ( l == nullptr )
+        return;
+    listener.reset( l );
+}


=====================================
modules/gui/qt/network/networksourcelistener.hpp → modules/gui/qt/network/mediatreelistener.hpp
=====================================
@@ -31,51 +31,37 @@
 #include <memory>
 #include <functional>
 
-class NetworkSourceListener
+class MediaTreeListener
 {
 public:
-    using MediaSourcePtr = vlc_shared_data_ptr_type(vlc_media_source_t,
-                                    vlc_media_source_Hold, vlc_media_source_Release);
+    using MediaTreePtr = vlc_shared_data_ptr_type(vlc_media_tree_t,
+                                                  vlc_media_tree_Hold,
+                                                  vlc_media_tree_Release);
 
     using ListenerPtr = std::unique_ptr<vlc_media_tree_listener_id,
                                         std::function<void(vlc_media_tree_listener_id*)>>;
 
-    class SourceListenerCb
+    class MediaTreeListenerCb
     {
     public:
-        virtual ~SourceListenerCb();
-
-        virtual void onItemCleared( MediaSourcePtr mediaSource, input_item_node_t* node ) = 0;
-        virtual void onItemAdded( MediaSourcePtr mediaSource, input_item_node_t* parent, input_item_node_t *const children[], size_t count ) = 0;
-        virtual void onItemRemoved( MediaSourcePtr mediaSource, input_item_node_t* node, input_item_node_t *const children[], size_t count ) = 0;
-        virtual void onItemPreparseEnded( MediaSourcePtr mediaSource, input_item_node_t* node, enum input_item_preparse_status status ) = 0;
+        virtual ~MediaTreeListenerCb() = default;
+        virtual void onItemCleared( MediaTreePtr tree, input_item_node_t* node ) = 0;
+        virtual void onItemAdded( MediaTreePtr tree, input_item_node_t* parent, input_item_node_t *const children[], size_t count ) = 0;
+        virtual void onItemRemoved( MediaTreePtr tree, input_item_node_t* node, input_item_node_t *const children[], size_t count ) = 0;
+        virtual void onItemPreparseEnded( MediaTreePtr tree, input_item_node_t* node, enum input_item_preparse_status status ) = 0;
     };
 
 public:
-    NetworkSourceListener( MediaSourcePtr s, SourceListenerCb* m );
-    NetworkSourceListener();
-
-    NetworkSourceListener( NetworkSourceListener&& ) = default;
-    NetworkSourceListener& operator=( NetworkSourceListener&& ) = default;
-
-    NetworkSourceListener( const NetworkSourceListener& ) = delete;
-    NetworkSourceListener& operator=( const NetworkSourceListener& ) = delete;
+    MediaTreeListener( MediaTreePtr tree, std::unique_ptr<MediaTreeListenerCb> &&cb );
 
-    static void onItemCleared( vlc_media_tree_t* tree, input_item_node_t* node,
-                               void* userdata );
-    static void onItemAdded( vlc_media_tree_t *tree, input_item_node_t *node,
-                             input_item_node_t *const children[], size_t count,
-                             void *userdata );
-    static void onItemRemoved( vlc_media_tree_t *tree, input_item_node_t *node,
-                               input_item_node_t *const children[], size_t count,
-                               void *userdata );
+    MediaTreeListener( MediaTreeListener&& ) = default;
+    MediaTreeListener& operator=( MediaTreeListener&& ) = default;
 
-    static void onItemPreparseEnded( vlc_media_tree_t *tree, input_item_node_t *node,
-                                     enum input_item_preparse_status status,
-                                     void *userdata );
+    MediaTreeListener( const MediaTreeListener& ) = delete;
+    MediaTreeListener& operator=( const MediaTreeListener& ) = delete;
 
-    MediaSourcePtr source;
+    MediaTreePtr tree;
     ListenerPtr listener = nullptr;
-    SourceListenerCb *cb = nullptr;
+    std::unique_ptr<MediaTreeListenerCb> cb;
 };
 #endif // MLNETWORKSOURCELISTENER_HPP


=====================================
modules/gui/qt/network/networkdevicemodel.cpp
=====================================
@@ -49,7 +49,7 @@ QVariant NetworkDeviceModel::data( const QModelIndex& index, int role ) const
         case NETWORK_SOURCE:
             return item.mediaSource->description;
         case NETWORK_TREE:
-            return QVariant::fromValue( NetworkTreeItem(item.mediaSource, item.inputItem.get()) );
+            return QVariant::fromValue( NetworkTreeItem(MediaTreePtr{ item.mediaSource->tree }, item.inputItem.get()) );
         case NETWORK_ARTWORK:
             return item.artworkUrl;
         default:
@@ -288,8 +288,9 @@ bool NetworkDeviceModel::initializeMediaSources()
                                                                      meta->name );
         if ( mediaSource == nullptr )
             continue;
-        std::unique_ptr<NetworkSourceListener> l{ new NetworkSourceListener(
-                        MediaSourcePtr{ mediaSource, false }, this ) };
+        std::unique_ptr<MediaTreeListener> l{ new MediaTreeListener(
+                        MediaTreePtr{ mediaSource->tree },
+                        std::make_unique<ListenerCb>(this, MediaSourcePtr{ mediaSource }) ) };
         if ( l->listener == nullptr )
             return false;
         m_listeners.push_back( std::move( l ) );
@@ -298,27 +299,27 @@ bool NetworkDeviceModel::initializeMediaSources()
 }
 
 
-void NetworkDeviceModel::onItemCleared( MediaSourcePtr mediaSource, input_item_node_t* node )
+void NetworkDeviceModel::ListenerCb::onItemCleared( MediaTreePtr tree, input_item_node_t* node )
 {
-    if (node != &mediaSource->tree->root)
+    if (node != &tree->root)
         return;
-    refreshDeviceList( std::move( mediaSource), node->pp_children, node->i_children, true );
+    model->refreshDeviceList( mediaSource, node->pp_children, node->i_children, true );
 }
 
-void NetworkDeviceModel::onItemAdded( MediaSourcePtr mediaSource, input_item_node_t* parent,
-                                  input_item_node_t *const children[],
-                                  size_t count )
+void NetworkDeviceModel::ListenerCb::onItemAdded( MediaTreePtr tree, input_item_node_t* parent,
+                                                  input_item_node_t *const children[],
+                                                  size_t count )
 {
-    if (parent != &mediaSource->tree->root)
+    if (parent != &tree->root)
         return;
-    refreshDeviceList( std::move( mediaSource ), children, count, false );
+    model->refreshDeviceList( mediaSource, children, count, false );
 }
 
-void NetworkDeviceModel::onItemRemoved(MediaSourcePtr mediaSource, input_item_node_t* node,
-                                    input_item_node_t *const children[],
-                                    size_t count )
+void NetworkDeviceModel::ListenerCb::onItemRemoved( MediaTreePtr tree, input_item_node_t* node,
+                                                    input_item_node_t *const children[],
+                                                    size_t count )
 {
-    if (node != &mediaSource->tree->root)
+    if (node != &tree->root)
         return;
 
     std::vector<InputItemPtr> itemList;
@@ -326,15 +327,15 @@ void NetworkDeviceModel::onItemRemoved(MediaSourcePtr mediaSource, input_item_no
     for ( auto i = 0u; i < count; ++i )
         itemList.emplace_back( children[i]->p_item );
 
-    QMetaObject::invokeMethod(this, [this, itemList=std::move(itemList)]() {
+    QMetaObject::invokeMethod(model, [model=model, itemList=std::move(itemList)]() {
         for (auto p_item : itemList)
         {
             QUrl itemUri = QUrl::fromEncoded(p_item->psz_uri);
-            auto it = std::find_if( begin( m_items ), end( m_items ), [p_item, itemUri](const Item& i) {
+            auto it = std::find_if( begin( model->m_items ), end( model->m_items ), [p_item, itemUri](const Item& i) {
                 return QString::compare( qfu(p_item->psz_name), i.name, Qt::CaseInsensitive ) == 0 &&
                     itemUri.scheme() == i.mainMrl.scheme();
             });
-            if ( it == end( m_items ) )
+            if ( it == end( model->m_items ) )
                 continue;
 
             auto mrlIt = std::find_if( begin( (*it).mrls ), end( (*it).mrls),
@@ -347,11 +348,11 @@ void NetworkDeviceModel::onItemRemoved(MediaSourcePtr mediaSource, input_item_no
             (*it).mrls.erase( mrlIt );
             if ( (*it).mrls.empty() == false )
                 continue;
-            auto idx = std::distance( begin( m_items ), it );
-            beginRemoveRows({}, idx, idx );
-            m_items.erase( it );
-            endRemoveRows();
-            emit countChanged();
+            auto idx = std::distance( begin( model->m_items ), it );
+            model->beginRemoveRows({}, idx, idx );
+            model->m_items.erase( it );
+            model->endRemoveRows();
+            model->emit countChanged();
         }
     }, Qt::QueuedConnection);
 }
@@ -362,7 +363,7 @@ void NetworkDeviceModel::refreshDeviceList( MediaSourcePtr mediaSource, input_it
     {
         QMetaObject::invokeMethod(this, [this, mediaSource]() {
             beginResetModel();
-            m_items.erase(std::remove_if(m_items.begin(), m_items.end(), [mediaSource](const Item& value) {
+            m_items.erase(std::remove_if(m_items.begin(), m_items.end(), [&mediaSource](const Item& value) {
                 return value.mediaSource == mediaSource;
             }), m_items.end());
             endResetModel();
@@ -384,7 +385,7 @@ void NetworkDeviceModel::refreshDeviceList( MediaSourcePtr mediaSource, input_it
             item.mrls.push_back( item.mainMrl );
             item.type = static_cast<ItemType>( p_item->i_type );
             item.protocol = item.mainMrl.scheme();
-            item.mediaSource = mediaSource;
+            item.mediaSource = std::move(mediaSource);
             item.inputItem = InputItemPtr(p_item);
 
             char* artwork = input_item_GetArtworkURL( p_item.get() );


=====================================
modules/gui/qt/network/networkdevicemodel.hpp
=====================================
@@ -31,12 +31,12 @@
 #include <vlc_threads.h>
 #include <vlc_cxx_helpers.hpp>
 
-#include "networksourcelistener.hpp"
+#include "mediatreelistener.hpp"
 
 #include <memory>
 
 class MainCtx;
-class NetworkDeviceModel : public QAbstractListModel, public NetworkSourceListener::SourceListenerCb
+class NetworkDeviceModel : public QAbstractListModel
 {
     Q_OBJECT
 public:
@@ -122,6 +122,10 @@ private:
     using MediaSourcePtr = vlc_shared_data_ptr_type(vlc_media_source_t,
                                     vlc_media_source_Hold, vlc_media_source_Release);
 
+    using MediaTreePtr = vlc_shared_data_ptr_type(vlc_media_tree_t,
+                                                  vlc_media_tree_Hold,
+                                                  vlc_media_tree_Release);
+
     using InputItemPtr = vlc_shared_data_ptr_type(input_item_t,
                                                   input_item_Hold,
                                                   input_item_Release);
@@ -139,21 +143,32 @@ private:
     };
 
     bool initializeMediaSources();
-    void onItemCleared( MediaSourcePtr mediaSource, input_item_node_t* node ) override;
-    void onItemAdded( MediaSourcePtr mediaSource, input_item_node_t* parent, input_item_node_t *const children[], size_t count ) override;
-    void onItemRemoved( MediaSourcePtr mediaSource, input_item_node_t * node, input_item_node_t *const children[], size_t count ) override;
-    inline void onItemPreparseEnded( MediaSourcePtr, input_item_node_t *, enum input_item_preparse_status ) override {}
 
     void refreshDeviceList(MediaSourcePtr mediaSource, input_item_node_t* const children[], size_t count , bool clear);
 
 private:
+    struct ListenerCb : public MediaTreeListener::MediaTreeListenerCb {
+        ListenerCb(NetworkDeviceModel *model, MediaSourcePtr mediaSource)
+            : model(model)
+            , mediaSource(std::move(mediaSource))
+        {}
+
+        void onItemCleared( MediaTreePtr tree, input_item_node_t* node ) override;
+        void onItemAdded( MediaTreePtr tree, input_item_node_t* parent, input_item_node_t *const children[], size_t count ) override;
+        void onItemRemoved( MediaTreePtr tree, input_item_node_t * node, input_item_node_t *const children[], size_t count ) override;
+        inline void onItemPreparseEnded( MediaTreePtr, input_item_node_t *, enum input_item_preparse_status ) override {}
+
+        NetworkDeviceModel *model;
+        MediaSourcePtr mediaSource;
+    };
+
     std::vector<Item> m_items;
     MainCtx* m_ctx = nullptr;
     SDCatType m_sdSource = CAT_UNDEFINED;
     QString m_sourceName; // '*' -> all sources
     QString m_name; // source long name
 
-    std::vector<std::unique_ptr<NetworkSourceListener>> m_listeners;
+    std::vector<std::unique_ptr<MediaTreeListener>> m_listeners;
 };
 
 #endif // MLNETWORKDEVICEMODEL_HPP


=====================================
modules/gui/qt/network/networkmediamodel.cpp
=====================================
@@ -69,8 +69,6 @@ QVariant NetworkMediaModel::data( const QModelIndex& index, int role ) const
             return item.protocol;
         case NETWORK_TREE:
             return QVariant::fromValue( item.tree );
-        case NETWORK_SOURCE:
-            return item.mediaSource->description;
         case NETWORK_ARTWORK:
             return item.artworkUrl;
         case NETWORK_FILE_SIZE:
@@ -92,7 +90,6 @@ QHash<int, QByteArray> NetworkMediaModel::roleNames() const
         { NETWORK_TYPE, "type" },
         { NETWORK_PROTOCOL, "protocol" },
         { NETWORK_TREE, "tree" },
-        { NETWORK_SOURCE, "source" },
         { NETWORK_ARTWORK, "artwork" },
         { NETWORK_FILE_SIZE, "fileSizeRaw64" },
         { NETWORK_FILE_MODIFIED, "fileModified" }
@@ -382,8 +379,9 @@ bool NetworkMediaModel::initializeMediaSources()
     if (!m_treeItem)
         return false;
 
-    auto tree = m_treeItem.source->tree;
-    auto l = std::make_unique<NetworkSourceListener>( m_treeItem.source, this );
+    auto tree = m_treeItem.tree.get();
+    auto l = std::make_unique<MediaTreeListener>( m_treeItem.tree,
+                                                  std::make_unique<ListenerCb>(this) );
     if ( l->listener == nullptr )
         return false;
 
@@ -434,7 +432,9 @@ bool NetworkMediaModel::initializeMediaSources()
                 itemList.emplace_back(mediaNode->pp_children[i]->p_item);
 
             while (parent && parent->p_item) {
-                m_path.push_front(QVariant::fromValue(PathNode(NetworkTreeItem(m_treeItem.source, parent->p_item), parent->p_item->psz_name)));
+                m_path.push_front(QVariant::fromValue(PathNode(
+                        NetworkTreeItem(m_treeItem.tree, parent->p_item),
+                        parent->p_item->psz_name)));
                 input_item_node_t *node = nullptr;
                 input_item_node_t *grandParent = nullptr;
                 if (!vlc_media_tree_Find( tree, parent->p_item, &node, &grandParent)) {
@@ -445,7 +445,7 @@ bool NetworkMediaModel::initializeMediaSources()
         }
         vlc_media_tree_Unlock(tree);
         if (!itemList.empty())
-            refreshMediaList( m_treeItem.source, std::move( itemList ), true );
+            refreshMediaList( m_treeItem.tree, std::move( itemList ), true );
         emit pathChanged();
     }
 
@@ -459,18 +459,19 @@ bool NetworkMediaModel::initializeMediaSources()
     return true;
 }
 
-void NetworkMediaModel::onItemCleared( MediaSourcePtr mediaSource, input_item_node_t* node)
+void NetworkMediaModel::ListenerCb::onItemCleared( MediaTreePtr tree, input_item_node_t* node)
 {
     InputItemPtr p_node { node->p_item };
-    QMetaObject::invokeMethod(this, [this, p_node = std::move(p_node), mediaSource = std::move(mediaSource)]() {
-        if (p_node != m_treeItem.media)
+    QMetaObject::invokeMethod(model, [model=model, p_node = std::move(p_node), tree = std::move(tree)]() {
+        if (p_node != model->m_treeItem.media)
             return;
         input_item_node_t *res;
         input_item_node_t *parent;
-        vlc_media_tree_Lock( m_treeItem.source->tree );
-        bool found = vlc_media_tree_Find( m_treeItem.source->tree, m_treeItem.media.get(),
+        // XXX is tree == m_treeItem.tree?
+        vlc_media_tree_Lock( model->m_treeItem.tree.get() );
+        bool found = vlc_media_tree_Find( model->m_treeItem.tree.get(), model->m_treeItem.media.get(),
                                           &res, &parent );
-        vlc_media_tree_Unlock( m_treeItem.source->tree );
+        vlc_media_tree_Unlock( model->m_treeItem.tree.get() );
         if (!found)
             return;
 
@@ -479,13 +480,13 @@ void NetworkMediaModel::onItemCleared( MediaSourcePtr mediaSource, input_item_no
         for (int i = 0; i < res->i_children; i++)
             itemList.emplace_back(res->pp_children[i]->p_item);
 
-        refreshMediaList( std::move( mediaSource ), std::move( itemList ), true );
+        model->refreshMediaList( std::move( tree ), std::move( itemList ), true );
     }, Qt::QueuedConnection);
 }
 
-void NetworkMediaModel::onItemAdded( MediaSourcePtr mediaSource, input_item_node_t* parent,
-                                  input_item_node_t *const children[],
-                                  size_t count )
+void NetworkMediaModel::ListenerCb::onItemAdded( MediaTreePtr tree, input_item_node_t* parent,
+                                                 input_item_node_t *const children[],
+                                                 size_t count )
 {
     InputItemPtr p_parent { parent->p_item };
     std::vector<InputItemPtr> itemList;
@@ -493,15 +494,15 @@ void NetworkMediaModel::onItemAdded( MediaSourcePtr mediaSource, input_item_node
     for (size_t i = 0; i < count; i++)
         itemList.emplace_back(children[i]->p_item);
 
-    QMetaObject::invokeMethod(this, [this, p_parent = std::move(p_parent), mediaSource = std::move(mediaSource), itemList=std::move(itemList)]() {
-        if ( p_parent == m_treeItem.media )
-            refreshMediaList( std::move( mediaSource ), std::move( itemList ), false );
+    QMetaObject::invokeMethod(model, [model=model, p_parent = std::move(p_parent), tree = std::move(tree), itemList=std::move(itemList)]() {
+        if ( p_parent == model->m_treeItem.media )
+            model->refreshMediaList( std::move( tree ), std::move( itemList ), false );
     }, Qt::QueuedConnection);
 }
 
-void NetworkMediaModel::onItemRemoved(MediaSourcePtr, input_item_node_t * node,
-                                    input_item_node_t *const children[],
-                                    size_t count )
+void NetworkMediaModel::ListenerCb::onItemRemoved( MediaTreePtr, input_item_node_t * node,
+                                                   input_item_node_t *const children[],
+                                                   size_t count )
 {
     std::vector<InputItemPtr> itemList;
     itemList.reserve( count );
@@ -509,18 +510,18 @@ void NetworkMediaModel::onItemRemoved(MediaSourcePtr, input_item_node_t * node,
         itemList.emplace_back( children[i]->p_item );
 
     InputItemPtr p_node { node->p_item };
-    QMetaObject::invokeMethod(this, [this, p_node=std::move(p_node), itemList=std::move(itemList)]() {
-        if (p_node != m_treeItem.media)
+    QMetaObject::invokeMethod(model, [model=model, p_node=std::move(p_node), itemList=std::move(itemList)]() {
+        if (p_node != model->m_treeItem.media)
             return;
 
         for (auto p_item : itemList)
         {
             QUrl itemUri = QUrl::fromEncoded(p_item->psz_uri);
-            auto it = std::find_if( begin( m_items ), end( m_items ), [&](const Item& i) {
+            auto it = std::find_if( begin( model->m_items ), end( model->m_items ), [&](const Item& i) {
                 return QString::compare( qfu(p_item->psz_name), i.name, Qt::CaseInsensitive ) == 0 &&
                     itemUri.scheme() == i.mainMrl.scheme();
             });
-            if ( it == end( m_items ) )
+            if ( it == end( model->m_items ) )
                 continue;
 
             auto mrlIt = std::find_if( begin( (*it).mrls ), end( (*it).mrls),
@@ -532,31 +533,31 @@ void NetworkMediaModel::onItemRemoved(MediaSourcePtr, input_item_node_t * node,
             (*it).mrls.erase( mrlIt );
             if ( (*it).mrls.empty() == false )
                 continue;
-            auto idx = std::distance( begin( m_items ), it );
-            beginRemoveRows({}, idx, idx );
-            m_items.erase( it );
-            endRemoveRows();
-            emit countChanged();
+            auto idx = std::distance( begin( model->m_items ), it );
+            model->beginRemoveRows({}, idx, idx );
+            model->m_items.erase( it );
+            model->endRemoveRows();
+            model->emit countChanged();
         }
     }, Qt::QueuedConnection);
 }
 
-void NetworkMediaModel::onItemPreparseEnded(MediaSourcePtr, input_item_node_t* node, enum input_item_preparse_status )
+void NetworkMediaModel::ListenerCb::onItemPreparseEnded(MediaTreePtr, input_item_node_t* node, enum input_item_preparse_status )
 {
-    m_preparseSem.release();
+    model->m_preparseSem.release();
     InputItemPtr p_node { node->p_item };
-    QMetaObject::invokeMethod(this, [this, p_node=std::move(p_node)]() {
-        if (p_node != m_treeItem.media)
+    QMetaObject::invokeMethod(model, [model=model, p_node=std::move(p_node)]() {
+        if (p_node != model->m_treeItem.media)
             return;
 
-        m_parsingPending = false;
-        emit parsingPendingChanged(false);
+        model->m_parsingPending = false;
+        model->emit parsingPendingChanged(false);
     });
 }
 
-void NetworkMediaModel::refreshMediaList( MediaSourcePtr mediaSource,
-                                       std::vector<InputItemPtr> children,
-                                       bool clear )
+void NetworkMediaModel::refreshMediaList( MediaTreePtr tree,
+                                          std::vector<InputItemPtr> children,
+                                          bool clear )
 {
     std::vector<Item> items;
     for ( auto it: children)
@@ -571,7 +572,6 @@ void NetworkMediaModel::refreshMediaList( MediaSourcePtr mediaSource,
                     QUrl::fromEncoded(it->psz_uri);
 
         item.canBeIndexed = canBeIndexed( item.mainMrl , item.type );
-        item.mediaSource = mediaSource;
 
         input_item_t * inputItem = it.get();
 
@@ -635,7 +635,7 @@ void NetworkMediaModel::refreshMediaList( MediaSourcePtr mediaSource,
                 }
             });
         }
-        item.tree = NetworkTreeItem( mediaSource, it.get() );
+        item.tree = NetworkTreeItem( tree, it.get() );
         items.push_back( std::move( item ) );
     }
     if ( clear == true )


=====================================
modules/gui/qt/network/networkmediamodel.hpp
=====================================
@@ -30,7 +30,7 @@
 #include <vlc_threads.h>
 #include <vlc_cxx_helpers.hpp>
 
-#include "networksourcelistener.hpp"
+#include "mediatreelistener.hpp"
 #include <maininterface/mainctx.hpp>
 
 #include <QSemaphore>
@@ -41,6 +41,10 @@
 using MediaSourcePtr = vlc_shared_data_ptr_type(vlc_media_source_t,
                                 vlc_media_source_Hold, vlc_media_source_Release);
 
+using MediaTreePtr = vlc_shared_data_ptr_type(vlc_media_tree_t,
+                                              vlc_media_tree_Hold,
+                                              vlc_media_tree_Release);
+
 using InputItemPtr = vlc_shared_data_ptr_type(input_item_t,
                                               input_item_Hold,
                                               input_item_Release);
@@ -49,9 +53,9 @@ class NetworkTreeItem
 {
     Q_GADGET
 public:
-    NetworkTreeItem() : source(nullptr), media(nullptr) {}
-    NetworkTreeItem( MediaSourcePtr s, input_item_t* m )
-        : source( std::move( s ) )
+    NetworkTreeItem() : tree(nullptr), media(nullptr) {}
+    NetworkTreeItem( MediaTreePtr tree, input_item_t* m )
+        : tree( std::move( tree ) )
         , media( m )
     {
     }
@@ -63,18 +67,18 @@ public:
 
     operator bool() const
     {
-        return source.get() != nullptr;
+        return tree.get() != nullptr;
     }
 
     bool isValid() {
-        vlc_media_tree_Lock(source->tree);
+        vlc_media_tree_Lock(tree.get());
         input_item_node_t* node;
-        bool ret = vlc_media_tree_Find( source->tree, media.get(), &node, nullptr);
-        vlc_media_tree_Unlock(source->tree);
+        bool ret = vlc_media_tree_Find( tree.get(), media.get(), &node, nullptr);
+        vlc_media_tree_Unlock(tree.get());
         return ret;
     }
 
-    MediaSourcePtr source;
+    MediaTreePtr tree;
     InputItemPtr media;
 };
 
@@ -102,7 +106,7 @@ private:
 
 Q_DECLARE_METATYPE(PathNode)
 
-class NetworkMediaModel : public QAbstractListModel, public NetworkSourceListener::SourceListenerCb
+class NetworkMediaModel : public QAbstractListModel
 {
     Q_OBJECT
 
@@ -115,7 +119,6 @@ public:
         NETWORK_TYPE,
         NETWORK_PROTOCOL,
         NETWORK_TREE,
-        NETWORK_SOURCE,
         NETWORK_ARTWORK,
         NETWORK_FILE_SIZE,
         NETWORK_FILE_MODIFIED,
@@ -210,23 +213,29 @@ private:
         ItemType type;
         bool canBeIndexed;
         NetworkTreeItem tree;
-        MediaSourcePtr mediaSource;
         QUrl artworkUrl;
         qint64 fileSize;
         QDateTime fileModified;
     };
 
     bool initializeMediaSources();
-    void onItemCleared( MediaSourcePtr mediaSource, input_item_node_t* node ) override;
-    void onItemAdded( MediaSourcePtr mediaSource, input_item_node_t* parent, input_item_node_t *const children[], size_t count ) override;
-    void onItemRemoved( MediaSourcePtr mediaSource, input_item_node_t * node, input_item_node_t *const children[], size_t count ) override;
-    void onItemPreparseEnded( MediaSourcePtr mediaSource, input_item_node_t* node, enum input_item_preparse_status status ) override;
 
-    void refreshMediaList(MediaSourcePtr s, std::vector<InputItemPtr> children , bool clear);
+    void refreshMediaList(MediaTreePtr tree, std::vector<InputItemPtr> children , bool clear);
 
     bool canBeIndexed(const QUrl& url , ItemType itemType );
 
 private:
+    struct ListenerCb : public MediaTreeListener::MediaTreeListenerCb {
+        ListenerCb(NetworkMediaModel *model) : model(model) {}
+
+        void onItemCleared( MediaTreePtr tree, input_item_node_t* node ) override;
+        void onItemAdded( MediaTreePtr tree, input_item_node_t* parent, input_item_node_t *const children[], size_t count ) override;
+        void onItemRemoved( MediaTreePtr tree, input_item_node_t * node, input_item_node_t *const children[], size_t count ) override;
+        void onItemPreparseEnded( MediaTreePtr tree, input_item_node_t* node, enum input_item_preparse_status status ) override;
+
+        NetworkMediaModel *model;
+    };
+
     //properties of the current node
     QString m_name;
     QUrl m_url;
@@ -241,7 +250,7 @@ private:
     MediaLib* m_mediaLib;
     bool m_hasTree = false;
     NetworkTreeItem m_treeItem;
-    std::unique_ptr<NetworkSourceListener> m_listener;
+    std::unique_ptr<MediaTreeListener> m_listener;
     QVariantList m_path;
 };
 


=====================================
modules/gui/qt/network/networksourcelistener.cpp deleted
=====================================
@@ -1,58 +0,0 @@
-#include "networksourcelistener.hpp"
-
-NetworkSourceListener::SourceListenerCb::~SourceListenerCb()
-{
-}
-
-NetworkSourceListener::NetworkSourceListener(MediaSourcePtr s, SourceListenerCb* m)
-    : source( s )
-    , listener( nullptr, [s]( vlc_media_tree_listener_id* l ) {
-            vlc_media_tree_RemoveListener( s->tree, l );
-        } )
-    , cb( m )
-{
-    static const vlc_media_tree_callbacks cbs {
-        &NetworkSourceListener::onItemCleared,
-        &NetworkSourceListener::onItemAdded,
-        &NetworkSourceListener::onItemRemoved,
-        &NetworkSourceListener::onItemPreparseEnded
-    };
-    auto l = vlc_media_tree_AddListener( s->tree, &cbs, this, true );
-    if ( l == nullptr )
-        return;
-    listener.reset( l );
-}
-
-NetworkSourceListener::NetworkSourceListener()
-{
-}
-
-void NetworkSourceListener::onItemCleared( vlc_media_tree_t*, input_item_node_t* node,
-                                                    void* userdata)
-{
-    auto* self = static_cast<NetworkSourceListener*>( userdata );
-    self->cb->onItemCleared( self->source, node );
-}
-
-void NetworkSourceListener::onItemAdded( vlc_media_tree_t *, input_item_node_t * parent,
-                                  input_item_node_t *const children[], size_t count,
-                                  void *userdata )
-{
-    auto* self = static_cast<NetworkSourceListener*>( userdata );
-    auto source = self->source;
-    self->cb->onItemAdded( self->source, parent, children, count );
-}
-
-void NetworkSourceListener::onItemRemoved( vlc_media_tree_t *, input_item_node_t * node,
-                                    input_item_node_t *const children[], size_t count,
-                                    void *userdata )
-{
-    auto* self = static_cast<NetworkSourceListener*>( userdata );
-    self->cb->onItemRemoved( self->source, node, children, count );
-}
-
-void NetworkSourceListener::onItemPreparseEnded(vlc_media_tree_t *, input_item_node_t * node, enum input_item_preparse_status status, void *userdata)
-{
-    auto* self = static_cast<NetworkSourceListener*>( userdata );
-    self->cb->onItemPreparseEnded( self->source, node, status );
-}


=====================================
modules/gui/qt/network/networksourcesmodel.cpp
=====================================
@@ -76,7 +76,7 @@ void NetworkSourcesModel::setCtx(MainCtx* ctx)
         m_ctx = ctx;
     }
     if (m_ctx) {
-        initializeMediaSources();
+        initializeMediaTree();
     }
     emit ctxChanged();
 }
@@ -97,7 +97,7 @@ QMap<QString, QVariant> NetworkSourcesModel::getDataAt(int idx)
     return dataDict;
 }
 
-bool NetworkSourcesModel::initializeMediaSources()
+bool NetworkSourcesModel::initializeMediaTree()
 {
     auto libvlc = vlc_object_instance(m_ctx->getIntf());
 


=====================================
modules/gui/qt/network/networksourcesmodel.hpp
=====================================
@@ -31,7 +31,6 @@
 #include <vlc_cxx_helpers.hpp>
 
 #include <maininterface/mainctx.hpp>
-#include "networksourcelistener.hpp"
 
 #include <memory>
 
@@ -83,7 +82,7 @@ private:
         QUrl artworkUrl;
     };
 
-    bool initializeMediaSources();
+    bool initializeMediaTree();
 
 private:
     std::vector<Item> m_items;


=====================================
src/Makefile.am
=====================================
@@ -223,7 +223,6 @@ libvlccore_la_SOURCES = \
 	media_source/media_source.c \
 	media_source/media_source.h \
 	media_source/media_tree.c \
-	media_source/media_tree.h \
 	modules/modules.h \
 	modules/modules.c \
 	modules/bank.c \


=====================================
src/libvlccore.sym
=====================================
@@ -995,8 +995,11 @@ vlc_media_source_provider_List
 vlc_media_source_meta_list_Count
 vlc_media_source_meta_list_Get
 vlc_media_source_meta_list_Delete
+vlc_media_tree_New
 vlc_media_tree_AddListener
 vlc_media_tree_RemoveListener
+vlc_media_tree_Hold
+vlc_media_tree_Release
 vlc_media_tree_Lock
 vlc_media_tree_Unlock
 vlc_media_tree_Find


=====================================
src/media_source/media_source.c
=====================================
@@ -30,7 +30,6 @@
 #include <vlc_services_discovery.h>
 #include <vlc_vector.h>
 #include "libvlc.h"
-#include "media_tree.h"
 
 #ifdef TEST_MEDIA_SOURCE
 #define vlc_module_name "test"


=====================================
src/media_source/media_tree.c
=====================================
@@ -22,7 +22,7 @@
 # include "config.h"
 #endif
 
-#include "media_tree.h"
+#include <vlc_media_source.h>
 
 #include <assert.h>
 #include <vlc_common.h>


=====================================
src/media_source/media_tree.h deleted
=====================================
@@ -1,42 +0,0 @@
-/*****************************************************************************
- * media_tree.h
- *****************************************************************************
- * Copyright (C) 2018 VLC authors and VideoLAN
- *
- * 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.
- *****************************************************************************/
-
-#ifndef MEDIA_TREE_H
-#define MEDIA_TREE_H
-
-#include <vlc_media_source.h>
-
-vlc_media_tree_t *
-vlc_media_tree_New(void);
-
-void
-vlc_media_tree_Hold(vlc_media_tree_t *tree);
-
-void
-vlc_media_tree_Release(vlc_media_tree_t *tree);
-
-input_item_node_t *
-vlc_media_tree_Add(vlc_media_tree_t *tree, input_item_node_t *parent,
-                   input_item_t *media);
-
-bool
-vlc_media_tree_Remove(vlc_media_tree_t *tree, input_item_t *media);
-
-#endif


=====================================
src/media_source/test.c
=====================================
@@ -26,7 +26,6 @@
 #include <vlc_common.h>
 #include <vlc_vector.h>
 #include "media_source.h"
-#include "media_tree.h"
 
 static void
 test_media_tree(void)



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/9dafb994caf9e3a21a0afa34e68bf3f13130ab5a...7cc8e7072e2c2b8df0a7ea038ce8ebe5c769196f

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/9dafb994caf9e3a21a0afa34e68bf3f13130ab5a...7cc8e7072e2c2b8df0a7ea038ce8ebe5c769196f
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list