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

UPnP: important rewrite

This is splitting the UPnP module in 2 parts:
- A service discovery module that is solely responsible for discovering
UPnP devices on the network
- An access module that will leverage the recently introduced
pf_readdir callback to list directories.

This removes the need for recursion and handling of all the items from
within the SD module.
parent f890621c
This diff is collapsed.
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* Authors: Rémi Denis-Courmont <rem # videolan.org> (original plugin) * Authors: Rémi Denis-Courmont <rem # videolan.org> (original plugin)
* Christian Henz <henz # c-lab.de> * Christian Henz <henz # c-lab.de>
* Mirsal Ennaime <mirsal dot ennaime at gmail dot com> * Mirsal Ennaime <mirsal dot ennaime at gmail dot com>
* Hugo Beauzée-Luyssen <hugo@beauzee.fr>
* *
* UPnP Plugin using the Intel SDK (libupnp) instead of CyberLink * UPnP Plugin using the Intel SDK (libupnp) instead of CyberLink
* *
...@@ -33,62 +34,55 @@ ...@@ -33,62 +34,55 @@
#include <vlc_common.h> #include <vlc_common.h>
// Classes namespace SD
class Container;
class MediaServer
{ {
public: class MediaServerList;
}
static void parseDeviceDescription( IXML_Document* p_doc,
const char* psz_location, /*
services_discovery_t* p_sd ); * libUpnp allows only one instance per process, so we have to share one for
* both SD & Access module
MediaServer( const char* psz_udn, * Since the callback is bound to the UpnpClient_Handle, we have to register
const char* psz_friendly_name, * a wrapper callback, in order for the access module to be able to initialize
services_discovery_t* p_sd ); * libUpnp first.
* When a SD wishes to use libUpnp, it will provide its own callback, that the
~MediaServer(); * wrapper will forward.
* This way, we always have a register callback & a client handle.
const char* getUDN() const; */
const char* getFriendlyName() const; class UpnpInstanceWrapper
{
void setContentDirectoryEventURL( const char* psz_url ); public:
const char* getContentDirectoryEventURL() const; // This increases the refcount before returning the instance
static UpnpInstanceWrapper* get(vlc_object_t* p_obj, Upnp_FunPtr callback, SD::MediaServerList *opaque);
void setContentDirectoryControlURL( const char* psz_url ); void release(bool isSd);
const char* getContentDirectoryControlURL() const; UpnpClient_Handle handle() const;
void subscribeToContentDirectory();
void fetchContents();
void setInputItem( input_item_t* p_input_item );
input_item_t* getInputItem() const;
bool compareSID( const char* psz_sid );
private: private:
static int Callback( Upnp_EventType event_type, void* p_event, void* p_user_data );
bool _fetchContents( Container* p_parent, int i_starting_index ); UpnpInstanceWrapper();
void _buildPlaylist( Container* p_container, input_item_node_t *p_item_node ); ~UpnpInstanceWrapper();
IXML_Document* _browseAction( const char*, const char*,
const char*, const char*, const char*, const char* );
services_discovery_t* _p_sd;
Container* _p_contents;
input_item_t* _p_input_item;
std::string _UDN; private:
std::string _friendly_name; static UpnpInstanceWrapper* s_instance;
static vlc_mutex_t s_lock;
UpnpClient_Handle handle_;
SD::MediaServerList* opaque_;
Upnp_FunPtr callback_;
int refcount_;
};
std::string _content_directory_event_url; namespace SD
std::string _content_directory_control_url; {
int _i_subscription_timeout; struct MediaServerDesc
int _i_content_directory_service_version; {
Upnp_SID _subscription_id; MediaServerDesc(const std::string& udn, const std::string& fName, const std::string& loc);
~MediaServerDesc();
std::string UDN;
std::string friendlyName;
std::string location;
input_item_t* inputItem;
}; };
...@@ -99,87 +93,45 @@ public: ...@@ -99,87 +93,45 @@ public:
MediaServerList( services_discovery_t* p_sd ); MediaServerList( services_discovery_t* p_sd );
~MediaServerList(); ~MediaServerList();
bool addServer( MediaServer* p_server ); bool addServer(MediaServerDesc *desc );
void removeServer( const char* psz_udn ); void removeServer(const std::string &udn );
MediaServerDesc* getServer( const std::string& udn );
MediaServer* getServer( const char* psz_udn ); static int Callback( Upnp_EventType event_type, void* p_event, void* p_user_data );
MediaServer* getServerBySID( const char* psz_sid );
private: private:
void parseNewServer( IXML_Document* doc, const std::string& location );
services_discovery_t* _p_sd; private:
services_discovery_t* p_sd_;
std::vector<MediaServer*> _list; std::vector<MediaServerDesc*> list_;
vlc_mutex_t lock_;
}; };
}
class Item namespace Access
{ {
public:
Item( Container* parent,
const char* objectID,
const char* title,
const char* subtitles,
const char* resource,
mtime_t duration );
~Item();
const char* getObjectID() const;
const char* getTitle() const;
const char* getResource() const;
const char* getSubtitles() const;
char* buildInputSlaveOption() const;
char* buildSubTrackIdOption() const;
mtime_t getDuration() const;
void setInputItem( input_item_t* p_input_item );
private:
input_item_t* _p_input_item;
Container* _parent;
std::string _objectID;
std::string _title;
std::string _resource;
std::string _subtitles;
mtime_t _duration;
};
class Container class MediaServer
{ {
public: public:
MediaServer( const char* psz_url, access_t* p_access, input_item_node_t* node );
Container( Container* parent, const char* objectID, const char* title ); bool fetchContents();
~Container();
void addItem( Item* item );
void addContainer( Container* container );
const char* getObjectID() const;
const char* getTitle() const;
unsigned int getNumItems() const;
unsigned int getNumContainers() const;
Item* getItem( unsigned int i ) const;
Container* getContainer( unsigned int i ) const;
Container* getParent();
void setInputItem( input_item_t* p_input_item );
input_item_t* getInputItem() const;
private: private:
MediaServer(const MediaServer&);
MediaServer& operator=(const MediaServer&);
input_item_t* _p_input_item; void addItem(const char* objectID, const char* title);
void addItem(const char* title, const char* psz_objectID, const char* psz_subtitles, mtime_t duration, const char* psz_url );
Container* _parent; IXML_Document* _browseAction(const char*, const char*,
const char*, const char*, const char* );
std::string _objectID; private:
std::string _title; const std::string url_;
std::vector<Item*> _items; access_t* access_;
std::vector<Container*> _containers; input_item_node_t* node_;
}; };
}
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