vlc | branch: master | Mirsal Ennaime <[email protected]> | Fri Nov 9 13:50:18 2012 +0100| [5725edf9fb32b1dbe89300d3c1045a8b9e2bb6c6] | committer: Mirsal Ennaime
upnp sd: Add support for Samsung devices' subtitles extensions * Request the sec:CaptionInfo and sec:CaptionInfoEx DIDL attributes * If one of the two caption attributes are present, build and add an input-slave option string which forces the subtitle demux * Add the sub-track-id option to input items with subtitles so the subtitles are immediately visible > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=5725edf9fb32b1dbe89300d3c1045a8b9e2bb6c6 --- modules/services_discovery/upnp.cpp | 112 ++++++++++++++++++++++++++++++++--- modules/services_discovery/upnp.hpp | 5 ++ 2 files changed, 108 insertions(+), 9 deletions(-) diff --git a/modules/services_discovery/upnp.cpp b/modules/services_discovery/upnp.cpp index a95b68c..e934956 100644 --- a/modules/services_discovery/upnp.cpp +++ b/modules/services_discovery/upnp.cpp @@ -791,7 +791,8 @@ bool MediaServer::_fetchContents( Container* p_parent, int i_offset ) IXML_Document* p_response = _browseAction( p_parent->getObjectID(), "BrowseDirectChildren", - "*", /* Filter */ + "id,dc:title,res," /* Filter */ + "sec:CaptionInfo,sec:CaptionInfoEx", psz_starting_index, /* StartingIndex */ "0", /* RequestedCount */ "" /* SortCriteria */ @@ -874,6 +875,13 @@ bool MediaServer::_fetchContents( Container* p_parent, int i_offset ) if ( !title ) continue; + const char* psz_subtitles = xml_getChildElementValue( itemElement, + "sec:CaptionInfo" ); + + if ( !psz_subtitles ) + psz_subtitles = xml_getChildElementValue( itemElement, + "sec:CaptionInfoEx" ); + /* Try to extract all resources in DIDL */ IXML_NodeList* p_resource_list = ixmlDocument_getElementsByTagName( (IXML_Document*) itemElement, "res" ); if ( p_resource_list ) @@ -897,7 +905,8 @@ bool MediaServer::_fetchContents( Container* p_parent, int i_offset ) i_minutes*60 + i_seconds ); } - Item* item = new Item( p_parent, objectID, title, psz_resource_url, i_duration ); + + Item* item = new Item( p_parent, objectID, title, psz_resource_url, psz_subtitles, i_duration ); p_parent->addItem( item ); } ixmlNodeList_free( p_resource_list ); @@ -975,14 +984,32 @@ void MediaServer::_buildPlaylist( Container* p_parent, input_item_node_t *p_inpu { Item* p_item = p_parent->getItem( i ); + char **ppsz_opts = NULL; + char *psz_input_slave = p_item->buildInputSlaveOption(); + if( psz_input_slave ) + { + ppsz_opts = (char**)malloc( 2 * sizeof( char* ) ); + ppsz_opts[0] = psz_input_slave; + ppsz_opts[1] = p_item->buildSubTrackIdOption(); + } + input_item_t* p_input_item = input_item_NewExt( p_item->getResource(), - p_item->getTitle(), - 0, - NULL, - 0, - p_item->getDuration() ); + p_item->getTitle(), + psz_input_slave ? 2 : 0, + psz_input_slave ? ppsz_opts : NULL, + VLC_INPUT_OPTION_TRUSTED, /* XXX */ + p_item->getDuration() ); assert( p_input_item ); + if( ppsz_opts ) + { + free( ppsz_opts[0] ); + free( ppsz_opts[1] ); + free( ppsz_opts ); + + psz_input_slave = NULL; + } + input_item_node_AppendItem( p_input_node, p_input_item ); p_item->setInputItem( p_input_item ); } @@ -1107,14 +1134,17 @@ void MediaServerList::removeServer( const char* psz_udn ) /* * Item class */ -Item::Item( Container* p_parent, const char* psz_object_id, const char* psz_title, - const char* psz_resource, mtime_t i_duration ) +Item::Item( Container* p_parent, + const char* psz_object_id, const char* psz_title, + const char* psz_resource, const char* psz_subtitles, + mtime_t i_duration ) { _parent = p_parent; _objectID = psz_object_id; _title = psz_title; _resource = psz_resource; + _subtitles = psz_subtitles ? psz_subtitles : ""; _duration = i_duration; _p_input_item = NULL; @@ -1141,11 +1171,75 @@ const char* Item::getResource() const return _resource.c_str(); } +const char* Item::getSubtitles() const +{ + if( !_subtitles.size() ) + return NULL; + + return _subtitles.c_str(); +} + mtime_t Item::getDuration() const { return _duration; } +char* Item::buildInputSlaveOption() const +{ + const char *psz_subtitles = getSubtitles(); + + const char *psz_scheme_delim = "://"; + const char *psz_sub_opt_fmt = ":input-slave=%s/%s://%s"; + const char *psz_demux = "subtitle"; + + char *psz_uri_scheme = NULL; + const char *psz_scheme_end = NULL; + const char *psz_uri_location = NULL; + char *psz_input_slave = NULL; + + size_t i_scheme_len; + + if( !psz_subtitles ) + return NULL; + + psz_scheme_end = strstr( psz_subtitles, psz_scheme_delim ); + + /* subtitles not being an URI would make no sense */ + if( !psz_scheme_end ) + return NULL; + + i_scheme_len = psz_scheme_end - psz_subtitles; + psz_uri_scheme = (char*)malloc( i_scheme_len + 1 ); + + if( !psz_uri_scheme ) + return NULL; + + memcpy( psz_uri_scheme, psz_subtitles, i_scheme_len ); + psz_uri_scheme[i_scheme_len] = '\0'; + + /* If the subtitles try to force a vlc demux, + * then something is very wrong */ + if( strchr( psz_uri_scheme, '/' ) ) + { + free( psz_uri_scheme ); + return NULL; + } + + psz_uri_location = psz_scheme_end + strlen( psz_scheme_delim ); + + if( -1 == asprintf( &psz_input_slave, psz_sub_opt_fmt, + psz_uri_scheme, psz_demux, psz_uri_location ) ) + psz_input_slave = NULL; + + free( psz_uri_scheme ); + return psz_input_slave; +} + +char* Item::buildSubTrackIdOption() const +{ + return strdup( ":sub-track-id=2" ); +} + void Item::setInputItem( input_item_t* p_input_item ) { if( _p_input_item == p_input_item ) diff --git a/modules/services_discovery/upnp.hpp b/modules/services_discovery/upnp.hpp index 2bfa4f7..23fe4db 100644 --- a/modules/services_discovery/upnp.hpp +++ b/modules/services_discovery/upnp.hpp @@ -120,6 +120,7 @@ public: Item( Container* parent, const char* objectID, const char* title, + const char* subtitles, const char* resource, mtime_t duration ); ~Item(); @@ -127,6 +128,9 @@ public: 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 ); @@ -139,6 +143,7 @@ private: std::string _objectID; std::string _title; std::string _resource; + std::string _subtitles; mtime_t _duration; }; _______________________________________________ vlc-commits mailing list [email protected] http://mailman.videolan.org/listinfo/vlc-commits
