[vlc-devel] [PATCH 3/4] dlna: add GetProtocolInfo action
Hugo Beauzée-Luyssen
hugo at beauzee.fr
Thu Jan 10 12:03:53 CET 2019
Hi,
On Wed, Jan 9, 2019, at 4:10 PM, Shaleen Jain wrote:
> Adds support for querying media formats supported
> by a Media Renderer device. Profiles related to
> H264/HEVC and MP3/AAC/AC-3 codecs are added.
>
> We transcode to the default/mandatory DLNA audio and video profiles
> for any non-supported formats since these are suppose
> to be supported by every DLNA certified device.
> ---
> modules/services_discovery/Makefile.am | 1 +
> modules/stream_out/dlna/dlna.cpp | 265 ++++++-
> modules/stream_out/dlna/dlna.hpp | 41 +-
> modules/stream_out/dlna/profile_names.hpp | 849 ++++++++++++++++++++++
> 4 files changed, 1120 insertions(+), 36 deletions(-)
> create mode 100644 modules/stream_out/dlna/profile_names.hpp
>
> diff --git a/modules/services_discovery/Makefile.am b/modules/
> services_discovery/Makefile.am
> index 1359460477..4f234c5fff 100644
> --- a/modules/services_discovery/Makefile.am
> +++ b/modules/services_discovery/Makefile.am
> @@ -31,6 +31,7 @@ libupnp_plugin_la_SOURCES = services_discovery/
> upnp.cpp services_discovery/upnp.
> services_discovery/upnp-wrapper.cpp \
> stream_out/renderer_common.hpp \
> stream_out/renderer_common.cpp \
> + stream_out/dlna/profile_names.hpp \
> stream_out/dlna/dlna_common.hpp \
> stream_out/dlna/dlna.hpp \
> stream_out/dlna/dlna.cpp
> diff --git a/modules/stream_out/dlna/dlna.cpp b/modules/stream_out/dlna/
> dlna.cpp
> index ccef3fb7b8..f9f7a61c29 100644
> --- a/modules/stream_out/dlna/dlna.cpp
> +++ b/modules/stream_out/dlna/dlna.cpp
> @@ -67,8 +67,9 @@ struct sout_stream_sys_t
> std::shared_ptr<MediaRenderer> renderer;
> UpnpInstanceWrapper *p_upnp;
>
> - bool canDecodeAudio( vlc_fourcc_t i_codec ) const;
> - bool canDecodeVideo( vlc_fourcc_t i_codec ) const;
> + ProtocolPtr canDecodeAudio( vlc_fourcc_t i_codec ) const;
> + ProtocolPtr canDecodeVideo( vlc_fourcc_t audio_codec,
> + vlc_fourcc_t video_codec ) const;
> bool startSoutChain( sout_stream_t* p_stream,
> const std::vector<sout_stream_id_sys_t*> &new_streams,
> const std::string &sout );
> @@ -85,6 +86,7 @@ struct sout_stream_sys_t
> int http_port;
> std::vector<sout_stream_id_sys_t*> streams;
> std::vector<sout_stream_id_sys_t*> out_streams;
> + std::vector<protocol_info_t> device_protocols;
>
> private:
> std::string GetAcodecOption( sout_stream_t *, vlc_fourcc_t *, const
> audio_format_t *, int );
> @@ -152,14 +154,67 @@ char *getServerIPAddress() {
> return ip;
> }
>
> -bool sout_stream_sys_t::canDecodeAudio(vlc_fourcc_t i_codec) const
> +std::string dlna_write_protocol_info (const protocol_info_t info)
> {
> - return i_codec == VLC_CODEC_MP4A;
> + std::ostringstream protocol;
> + char dlna_info[448];
> +
> + if (info.transport == DLNA_TRANSPORT_PROTOCOL_HTTP)
> + protocol << "http-get:*:";
> +
> + protocol << info.profile.mime;
> + protocol << ":";
> +
> + if (info.profile.name != "*")
> + protocol << "DLNA.ORG_PN=" << info.profile.name.c_str() << ";";
> +
> + dlna_org_flags_t flags = DLNA_ORG_FLAG_STREAMING_TRANSFER_MODE |
> + DLNA_ORG_FLAG_BACKGROUND_TRANSFERT_MODE |
> + DLNA_ORG_FLAG_CONNECTION_STALL |
> + DLNA_ORG_FLAG_DLNA_V15;
> + sprintf (dlna_info, "%s=%.2x;%s=%d;%s=%.8x%.24x",
> + "DLNA.ORG_OP", DLNA_ORG_OPERATION_RANGE,
> + "DLNA.ORG_CI", info.ci,
> + "DLNA.ORG_FLAGS", flags, 0);
> + protocol << dlna_info;
> +
> + return protocol.str();
> +}
> +
> +std::vector<std::string> split(const std::string &s, char delim) {
> + std::stringstream ss(s);
> + std::string item;
> + std::vector<std::string> elems;
> + while (std::getline(ss, item, delim)) {
> + elems.push_back(item);
You could move the string in the vector to avoid a copy
> + }
> + return elems;
> +}
> +
> +ProtocolPtr sout_stream_sys_t::canDecodeAudio(vlc_fourcc_t audio_codec)
> const
> +{
> + for (protocol_info_t protocol : device_protocols) {
> + if (protocol.profile.media == DLNA_CLASS_AUDIO
> + && protocol.profile.audio_codec == audio_codec)
> + {
> + return std::unique_ptr<protocol_info_t>(new
> protocol_info_t(protocol));
> + }
> + }
> + return nullptr;
> }
>
> -bool sout_stream_sys_t::canDecodeVideo(vlc_fourcc_t i_codec) const
> +ProtocolPtr sout_stream_sys_t::canDecodeVideo(vlc_fourcc_t audio_codec,
> + vlc_fourcc_t video_codec) const
> {
> - return i_codec == VLC_CODEC_H264;
> + for (protocol_info_t protocol : device_protocols) {
> + if (protocol.profile.media == DLNA_CLASS_AV
> + && protocol.profile.audio_codec == audio_codec
> + && protocol.profile.video_codec == video_codec)
> + {
> + return std::unique_ptr<protocol_info_t>(new
> protocol_info_t(protocol));
> + }
> + }
> + return nullptr;
> }
>
> bool sout_stream_sys_t::startSoutChain(sout_stream_t *p_stream,
> @@ -277,32 +332,12 @@ int sout_stream_sys_t::UpdateOutput( sout_stream_t
> *p_stream )
> const es_format_t *p_es = &stream->fmt;
> if (p_es->i_cat == AUDIO_ES)
> {
> - if (!canDecodeAudio( p_es->i_codec ))
> - {
> - msg_Dbg( p_stream, "can't remux audio track %d codec
> %4.4s",
> - p_es->i_id, (const char*)&p_es->i_codec );
> - p_original_audio = p_es;
> - canRemux = false;
> - }
> - else if (i_codec_audio == 0)
> - {
> - i_codec_audio = p_es->i_codec;
> - }
> + p_original_audio = p_es;
> new_streams.push_back(stream);
> }
> else if (b_supports_video && p_es->i_cat == VIDEO_ES)
> {
> - if (!canDecodeVideo( p_es->i_codec ))
> - {
> - msg_Dbg( p_stream, "can't remux video track %d codec
> %4.4s",
> - p_es->i_id, (const char*)&p_es->i_codec );
> - p_original_video = p_es;
> - canRemux = false;
> - }
> - else if (i_codec_video == 0)
> - {
> - i_codec_video = p_es->i_codec;
> - }
> + p_original_video = p_es;
> new_streams.push_back(stream);
> }
> }
> @@ -310,6 +345,62 @@ int sout_stream_sys_t::UpdateOutput( sout_stream_t
> *p_stream )
> if (new_streams.empty())
> return VLC_SUCCESS;
>
> + ProtocolPtr stream_protocol;
> + // check if we have an audio only stream
> + if (!p_original_video && p_original_audio)
> + {
> + if( !(stream_protocol = canDecodeAudio(p_original_audio-
> >i_codec)) )
> + {
> + msg_Dbg( p_stream, "can't remux audio track %d codec
> %4.4s",
> + p_original_audio->i_id, (const char*)&p_original_audio-
> >i_codec );
> + stream_protocol = make_protocol(default_audio_protocol);
> + canRemux = false;
> + }
> + else
> + i_codec_audio = p_original_audio->i_codec;
> + }
> + // video only stream
> + else if (p_original_video && !p_original_audio)
> + {
> + if( !(stream_protocol = canDecodeVideo(VLC_CODEC_NONE,
> + p_original_video->i_codec)) )
> + {
> + msg_Dbg(p_stream, "can't remux video track %d codec:
> %4.4s",
> + p_original_video->i_id, (const char*)&p_original_video-
> >i_codec);
> + stream_protocol = make_protocol(default_video_protocol);
> + canRemux = false;
> + }
> + else
> + i_codec_video = p_original_video->i_codec;
> + }
> + else
> + {
> + if( !(stream_protocol = canDecodeVideo( p_original_audio-
> >i_codec,
> + p_original_video->i_codec)) )
> + {
> + msg_Dbg(p_stream, "can't remux video track %d with audio:
> %4.4s and video: %4.4s",
> + p_original_video->i_id, (const char*)&p_original_audio-
> >i_codec,
> + (const char*)&p_original_video->i_codec);
> + stream_protocol = make_protocol(default_video_protocol);
> + canRemux = false;
> +
> + // check which codec needs transcoding
> + if (stream_protocol->profile.audio_codec ==
> p_original_audio->i_codec)
> + i_codec_audio = p_original_audio->i_codec;
> + if (stream_protocol->profile.video_codec ==
> p_original_video->i_codec)
> + i_codec_video = p_original_video->i_codec;
> + }
> + else
> + {
> + i_codec_audio = p_original_audio->i_codec;
> + i_codec_video = p_original_video->i_codec;
> + }
> + }
> +
> + msg_Dbg( p_stream, "using DLNA profile %s:%s",
> + stream_protocol->profile.mime.c_str(),
> + stream_protocol->profile.name.c_str() );
> +
> std::ostringstream ssout;
> if ( !canRemux )
> {
> @@ -336,13 +427,13 @@ int sout_stream_sys_t::UpdateOutput( sout_stream_t
> *p_stream )
> ssout << "transcode{";
> if ( i_codec_audio == 0 && p_original_audio )
> {
> - i_codec_audio = VLC_CODEC_MP4A;
> + i_codec_audio = stream_protocol->profile.audio_codec;
> ssout << GetAcodecOption( p_stream, &i_codec_audio,
> &p_original_audio->audio,
> i_quality );
> }
> if ( i_codec_video == 0 && p_original_video )
> {
> - i_codec_video = VLC_CODEC_H264;
> + i_codec_video = stream_protocol->profile.video_codec;
> try {
> ssout << vlc_sout_renderer_GetVcodecOption( p_stream,
> { i_codec_video },
> @@ -362,8 +453,8 @@ int sout_stream_sys_t::UpdateOutput( sout_stream_t
> *p_stream )
> std::string root_url = ss.str();
>
> ssout << "http{dst=:" << http_port << root_url
> - << ",mux=" << "mp4stream"
> - << ",access=http{mime=" << "video/mp4" << "}}";
> + << ",mux=" << stream_protocol->profile.mux
> + << ",access=http{mime=" << stream_protocol->profile.mime << "}}";
>
> auto ip = vlc::wrap_cptr<char>(getServerIPAddress());
> if (ip.get() == nullptr)
> @@ -382,7 +473,7 @@ int sout_stream_sys_t::UpdateOutput( sout_stream_t
> *p_stream )
>
> msg_Dbg(p_stream, "AVTransportURI: %s", uri);
> renderer->Stop();
> - renderer->SetAVTransportURI(uri);
> + renderer->SetAVTransportURI(uri, *stream_protocol);
> renderer->Play("1");
>
> free(uri);
> @@ -502,16 +593,118 @@ int MediaRenderer::Stop()
> return VLC_SUCCESS;
> }
>
> -int MediaRenderer::SetAVTransportURI(const char* uri)
> +std::vector<protocol_info_t> MediaRenderer::GetProtocolInfo()
> +{
> + std::string protocol_csv;
> + std::vector<protocol_info_t> supported_protocols;
> + std::list<std::pair<const char*, const char*>> arg_list;
> +
> + IXML_Document *response = SendAction("GetProtocolInfo",
> + CONNECTION_MANAGER_SERVICE_TYPE,
> arg_list);
> + if(!response)
> + {
> + return supported_protocols;
> + }
> +
> + // Get the CSV list of protocols/profiles supported by the device
> + if( IXML_NodeList *protocol_list =
> ixmlDocument_getElementsByTagName( response , "Sink" ) )
> + {
> + if ( IXML_Node* protocol_node =
> ixmlNodeList_item( protocol_list, 0 ) )
> + {
> + IXML_Node* p_text_node =
> ixmlNode_getFirstChild( protocol_node );
> + if ( p_text_node )
> + {
> +
> protocol_csv.assign(ixmlNode_getNodeValue( p_text_node ));
> + }
> + }
> + ixmlNodeList_free( protocol_list);
> + }
> + ixmlDocument_free(response);
> +
> + msg_Dbg(parent, "Device supports protocols: %s",
> protocol_csv.c_str());
> + // parse the CSV list
> + // format: <transportProtocol>:<network>:<mime>:<additionalInfo>
> + std::vector<std::string> protocols = split(protocol_csv, ',');
> + for (std::string protocol : protocols ) {
> + std::vector<std::string> protocol_info = split(protocol, ':');
> +
> + // We only support http transport for now.
> + if (protocol_info.size() == 4 && protocol_info.at(0) == "http-
> get")
> + {
> + protocol_info_t proto;
> +
> + // Get the DLNA profile name
> + std::string profile_name;
> + std::string tag = "DLNA.ORG_PN=";
> +
> + if (protocol_info.at(3) == "*")
> + {
> + profile_name = "*";
> + }
> + else if (std::size_t index =
> protocol_info.at(3).find(tag) != std::string::npos)
That's a C++17 feature, which we don't require yet.
> + {
> + std::size_t end = protocol_info.at(3).find(';', index +
> 1);
> + int start = index + tag.length() - 1;
> + int length = end - start;
> + profile_name = protocol_info.at(3).substr(start,
> length);
> + }
> +
> + // Match our supported profiles to device profiles
> + for (dlna_profile_t profile : dlna_profile_list) {
> + if (protocol_info.at(2) == profile.mime
> + && (profile_name == profile.name ||
> profile_name == "*"))
> + {
> + proto.profile = std::move(profile);
> + supported_protocols.push_back(proto);
> + // we do not break here to account for wildcards
> + // as protocolInfo's fourth field aka
> <additionalInfo>
> + }
> + }
> + }
> + }
> +
> + msg_Dbg( parent , "Got %zu supported profiles",
> supported_protocols.size() );
> + return supported_protocols;
> +}
> +
> +int MediaRenderer::SetAVTransportURI(const char* uri, const
> protocol_info_t& proto)
> {
> + static const char didl[] =
> + "<DIDL-Lite "
> + "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" "
> + "xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" "
> + "xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" "
> + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
> + "<item id=\"f-0\" parentID=\"0\" restricted=\"0\">"
> + "<dc:title>%s</dc:title>"
> + "<upnp:class>%s</upnp:class>"
> + "<res protocolInfo=\"%s\">%s</res>"
> + "</item>"
> + "</DIDL-Lite>";
> +
> + bool audio = proto.profile.media == DLNA_CLASS_AUDIO;
> + std::string dlna_protocol = dlna_write_protocol_info(proto);
> +
> + char *meta_data;
> + if (asprintf(&meta_data, didl,
> + audio ? "Audio" : "Video",
> + audio ? "object.item.audioItem" :
> "object.item.videoItem",
> + dlna_protocol.c_str(),
> + uri) < 0) {
> + return VLC_ENOMEM;
> + }
> +
> + msg_Dbg(parent, "didl: %s", meta_data);
> std::list<std::pair<const char*, const char*>> arg_list = {
> {"InstanceID", "0"},
> {"CurrentURI", uri},
> - {"CurrentURIMetaData", ""}, // NOT_IMPLEMENTED
> + {"CurrentURIMetaData", meta_data},
> };
>
> IXML_Document *p_response = SendAction("SetAVTransportURI",
> AV_TRANSPORT_SERVICE_TYPE, arg_list);
> +
> + free(meta_data);
> if(!p_response)
> {
> return VLC_EGENERIC;
> @@ -646,6 +839,8 @@ int OpenSout( vlc_object_t *p_this )
> goto error;
> }
>
> + p_sys->device_protocols = p_sys->renderer->GetProtocolInfo();
> +
> p_stream->pf_add = Add;
> p_stream->pf_del = Del;
> p_stream->pf_send = Send;
> diff --git a/modules/stream_out/dlna/dlna.hpp b/modules/stream_out/dlna/dlna.hpp
> index 9768d38336..d4a18ebd52 100644
> --- a/modules/stream_out/dlna/dlna.hpp
> +++ b/modules/stream_out/dlna/dlna.hpp
> @@ -26,6 +26,44 @@
>
> #include "../../services_discovery/upnp-wrapper.hpp"
> #include "dlna_common.hpp"
> +#include "profile_names.hpp"
> +
> +struct protocol_info_t {
> + protocol_info_t() = default;
> + protocol_info_t(const protocol_info_t&) = default;
> +
> + // aggreate initializers do not work in c++11
> + // for class types with default member initializers
> + protocol_info_t(dlna_transport_protocol_t transport,
> + dlna_org_conversion_t ci,
> + dlna_profile_t profile)
> + : transport(transport)
> + , ci(ci)
> + , profile(profile)
> + {}
> +
> + dlna_transport_protocol_t transport = DLNA_TRANSPORT_PROTOCOL_HTTP;
> + dlna_org_conversion_t ci = DLNA_ORG_CONVERSION_NONE;
> + dlna_profile_t profile;
> +};
> +
> +using ProtocolPtr = std::unique_ptr<protocol_info_t>;
> +static inline ProtocolPtr make_protocol(protocol_info_t a)
> +{
> + return std::unique_ptr<protocol_info_t>(new protocol_info_t(a));
> +}
> +
> +const protocol_info_t default_audio_protocol = {
> + DLNA_TRANSPORT_PROTOCOL_HTTP,
> + DLNA_ORG_CONVERSION_TRANSCODED,
> + default_audio_profile,
> +};
> +
> +const protocol_info_t default_video_protocol = {
> + DLNA_TRANSPORT_PROTOCOL_HTTP,
> + DLNA_ORG_CONVERSION_TRANSCODED,
> + default_video_profile,
> +};
>
> namespace DLNA
> {
> @@ -53,7 +91,8 @@ public:
>
> int Play(const char *speed);
> int Stop();
> - int SetAVTransportURI(const char* uri);
> + std::vector<protocol_info_t> GetProtocolInfo();
> + int SetAVTransportURI(const char* uri, const protocol_info_t& proto);
> };
>
> }
> diff --git a/modules/stream_out/dlna/profile_names.hpp b/modules/
> stream_out/dlna/profile_names.hpp
> new file mode 100644
> index 0000000000..fe118d52d9
> --- /dev/null
> +++ b/modules/stream_out/dlna/profile_names.hpp
> @@ -0,0 +1,849 @@
> +/
> *****************************************************************************
> + * profile_names.hpp : DLNA media profile names
> +
> *****************************************************************************
> + * Copyright © 2018 VLC authors and VideoLAN
> + *
> + * Authors: Shaleen Jain <shaleen at jain.sh>
> + *
> + * 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 DLNA_PROFILES_H
> +#define DLNA_PROFILES_H
> +
> +#include<string>
> +#include<vlc_common.h>
> +#include<vlc_fourcc.h>
> +#include<vector>
> +
> +#define VLC_CODEC_NONE 0
> +#define CODEC_PROFILE_NONE 0
> +
> +enum dlna_transport_protocol_t {
> + DLNA_TRANSPORT_PROTOCOL_UNKNOWN,
> + DLNA_TRANSPORT_PROTOCOL_HTTP,
> + DLNA_TRANSPORT_PROTOCOL_RTP,
> + DLNA_TRANSPORT_PROTOCOL_ANY
> +};
> +
> +/**
> + * DLNA.ORG_CI: conversion indicator parameter (integer)
> + * 0 not transcoded
> + * 1 transcoded
> + */
> +enum dlna_org_conversion_t {
> + DLNA_ORG_CONVERSION_NONE = 0,
> + DLNA_ORG_CONVERSION_TRANSCODED = 1,
> +};
> +
> +/**
> + * DLNA.ORG_OP: operations parameter (string)
> + * "00" (or "0") neither time seek range nor range supported
> + * "01" range supported
> + * "10" time seek range supported
> + * "11" both time seek range and range supported
> + */
> +enum dlna_org_operation_t {
> + DLNA_ORG_OPERATION_NONE = 0x00,
> + DLNA_ORG_OPERATION_RANGE = 0x01,
> + DLNA_ORG_OPERATION_TIMESEEK = 0x10,
> +};
> +
> +/**
> + * DLNA.ORG_FLAGS, padded with 24 trailing 0s
> + * 80000000 31 senderPaced
> + * 40000000 30 lsopTimeBasedSeekSupported
> + * 20000000 29 lsopByteBasedSeekSupported
> + * 10000000 28 playcontainerSupported
> + * 8000000 27 s0IncreasingSupported
> + * 4000000 26 sNIncreasingSupported
> + * 2000000 25 rtspPauseSupported
> + * 1000000 24 streamingTransferModeSupported
> + * 800000 23 interactiveTransferModeSupported
> + * 400000 22 backgroundTransferModeSupported
> + * 200000 21 connectionStallingSupported
> + * 100000 20 dlnaVersion15Supported
> + *
> + * Example: (1 << 24) | (1 << 22) | (1 << 21) | (1 << 20)
> + * DLNA.ORG_FLAGS=01700000[000000000000000000000000] // [] show
> padding
> + */
> +enum dlna_org_flags_t {
> + DLNA_ORG_FLAG_SENDER_PACED = (1 << 31),
> + DLNA_ORG_FLAG_TIME_BASED_SEEK = (1 << 30),
> + DLNA_ORG_FLAG_BYTE_BASED_SEEK = (1 << 29),
> + DLNA_ORG_FLAG_PLAY_CONTAINER = (1 << 28),
> + DLNA_ORG_FLAG_S0_INCREASE = (1 << 27),
> + DLNA_ORG_FLAG_SN_INCREASE = (1 << 26),
> + DLNA_ORG_FLAG_RTSP_PAUSE = (1 << 25),
> + DLNA_ORG_FLAG_STREAMING_TRANSFER_MODE = (1 << 24),
> + DLNA_ORG_FLAG_INTERACTIVE_TRANSFERT_MODE = (1 << 23),
> + DLNA_ORG_FLAG_BACKGROUND_TRANSFERT_MODE = (1 << 22),
> + DLNA_ORG_FLAG_CONNECTION_STALL = (1 << 21),
> + DLNA_ORG_FLAG_DLNA_V15 = (1 << 20),
> +};
> +
> +inline dlna_org_flags_t operator|(dlna_org_flags_t a, dlna_org_flags_t
> b)
> +{
> + return static_cast<dlna_org_flags_t>(static_cast<int>(a) |
> static_cast<int>(b));
> +}
> +
> +enum dlna_media_class_t {
> + DLNA_CLASS_UNKNOWN,
> + DLNA_CLASS_IMAGE,
> + DLNA_CLASS_AUDIO,
> + DLNA_CLASS_AV,
> + DLNA_CLASS_COLLECTION
> +};
> +
> +/**
> + * DLNA profile.
> + * This specifies the DLNA profile one file/stream is compatible with.
> + */
> +class dlna_profile_t {
> +public:
> + std::string name;
> + std::string mux;
> + std::string mime;
> + dlna_media_class_t media;
> + vlc_fourcc_t video_codec;
> + vlc_fourcc_t audio_codec;
> +
> + dlna_profile_t()
> + : name()
That's implicit
> + , mux()
> + , mime()
> + , video_codec(VLC_CODEC_UNKNOWN)
> + , audio_codec(VLC_CODEC_UNKNOWN)
> + {};
> +
> + dlna_profile_t(std::string profile, std::string mux, std::string
> mime,
> + vlc_fourcc_t video, vlc_fourcc_t audio)
> + : name(profile)
Since you pass the strings as copies, you should move them to their destination rather than copying
> + , mux(mux)
> + , mime(mime)
> + , media(DLNA_CLASS_AV)
> + , video_codec(video)
> + , audio_codec(audio)
> + {};
> +
> + dlna_profile_t(std::string profile, std::string mux, std::string
> mime,
> + dlna_media_class_t media, vlc_fourcc_t video, vlc_fourcc_t
> audio)
> + : name(profile)
> + , mux(mux)
> + , mime(mime)
> + , media(media)
> + , video_codec(video)
> + , audio_codec(audio)
> + {};
> +};
> +
> +const dlna_profile_t default_audio_profile = {
> + "AAC_ISO_320",
> + "mp4stream",
> + "audio/mp4",
> + DLNA_CLASS_AUDIO,
> + VLC_CODEC_NONE,
> + VLC_CODEC_MP4A,
> +};
> +
> +/**
> + * AVC Main Profile SD video with MPEG-4 AAC audio, encapsulated in
> MP4.
> + */
> +const dlna_profile_t default_video_profile = {
> + "AVC_MP4_MP_SD",
> + "mp4stream",
> + "video/mp4",
> + DLNA_CLASS_AV,
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> +};
> +
> +std::vector<dlna_profile_t> dlna_profile_list = {
> +
> + default_audio_profile,
> + default_video_profile,
> +
> + //------ Audio Profiles ------//
> +
> + {
> + "*",
> + "ogg",
> + "application/ogg",
> + DLNA_CLASS_AUDIO,
> + VLC_CODEC_NONE,
> + VLC_CODEC_VORBIS,
> + },
> + {
> + "*",
> + "ogg",
> + "application/ogg",
> + DLNA_CLASS_AUDIO,
> + VLC_CODEC_NONE,
> + VLC_CODEC_OPUS,
> + },
> + {
> + "*",
> + "ogg",
> + "audio/x-vorbis",
> + DLNA_CLASS_AUDIO,
> + VLC_CODEC_NONE,
> + VLC_CODEC_VORBIS,
> + },
> + {
> + "*",
> + "ogg",
> + "audio/x-vorbis+ogg",
> + DLNA_CLASS_AUDIO,
> + VLC_CODEC_NONE,
> + VLC_CODEC_VORBIS,
> + },
> + {
> + "*",
> + "ogg",
> + "audio/ogg",
> + DLNA_CLASS_AUDIO,
> + VLC_CODEC_NONE,
> + VLC_CODEC_OPUS,
> + },
> + {
> + "*",
> + "ogg",
> + "audio/ogg",
> + DLNA_CLASS_AUDIO,
> + VLC_CODEC_NONE,
> + VLC_CODEC_VORBIS,
> + },
> + {
> + "AAC_ISO",
> + "mp4stream",
> + "audio/mp4",
> + DLNA_CLASS_AUDIO,
> + VLC_CODEC_NONE,
> + VLC_CODEC_MP4A,
> + },
> + {
> + "MP3",
> + "ts",
> + "audio/mpeg",
> + DLNA_CLASS_AUDIO,
> + VLC_CODEC_NONE,
> + VLC_CODEC_MP3,
> + },
> + {
> + "MP3",
> + "ts",
> + "audio/mpeg",
> + DLNA_CLASS_AUDIO,
> + VLC_CODEC_NONE,
> + VLC_CODEC_MPGA,
> + },
> + {
> + "MP3X",
> + "ts",
> + "audio/mpeg",
> + DLNA_CLASS_AUDIO,
> + VLC_CODEC_NONE,
> + VLC_CODEC_MPGA,
> + },
> + {
> + "MP3X",
> + "ts",
> + "audio/mpeg",
> + DLNA_CLASS_AUDIO,
> + VLC_CODEC_NONE,
> + VLC_CODEC_MP3,
> + },
> +
> + //------ Video Profiles ------//
> +
> + /**
> + * MPEG-2 HD/SD video wrapped in MPEG-2 transport stream as
> constrained by
> + * SCTE-43 standards, with AC-3 audio, without a timestamp field
> + */
> + {
> + "MPEG_TS_NA_ISO",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_MP2V,
> + VLC_CODEC_A52,
> + },
> + /**
> + * North America region profile for MPEG-2 HD
> + * 3Dframe-compatible video with AC-3 audio,
> + * utilizing a DLNA Transport Packet without a Timestamp field
> + */
> + {
> + "MPEG_TS_NA_3DFC_ISO",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_MP2V,
> + VLC_CODEC_A52,
> + },
> + /**
> + * MPEG-2 Video, wrapped in MPEG-2 transport stream, Main Profile,
> + * Standard Definition, with AC-3 audio, without a timestamp field.
> + */
> + {
> + "MPEG_TS_SD_EU_AC3_ISO",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_MP2V,
> + VLC_CODEC_A52,
> + },
> + /**
> + * MPEG-2 Video, wrapped in MPEG-2 transport stream, Main Profile
> + * Standard Definition, with AC-3 audio, with a valid non-zero
> timestamp
> + * field.
> + */
> + {
> + "MPEG_TS_SD_EU_AC3_T",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_MP2V,
> + VLC_CODEC_A52,
> + },
> + /**
> + * MPEG-2 Main Profile at Main, High-1 440 and High Level with
> MPEG-2 AAC
> + * encapsulated in MPEG-2 TS with valid timestamp
> + */
> + {
> + "MPEG_TS_JP_T",
> + "ts",
> + "video/vnd.dlna.mpeg-tts",
> + VLC_CODEC_MP2V,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * MPEG-2 Video, encapsulated in MPEG-2 transport stream, Main
> Profile
> + * at Main Level, with MPEG-1 L2 audio, with a valid non-zero
> timestamp
> + * field.
> + */
> + {
> + "MPEG_TS_SD_JP_MPEG1_L2_T",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_MP2V,
> + VLC_CODEC_MP2,
> + },
> + /**
> + * AVC video wrapped in MPEG-2 transport stream, as
> + * constrained by SCTE standards,
> + * with AC-3, Enhanced AC-3, MPEG-4 HE-AAC
> + * v2 or MPEG-1 Layer II audio, with a valid
> + * non-zero timestamp field.
> + */
> + {
> + "AVC_TS_NA_T",
> + "ts",
> + "video/vnd.dlna.mpeg-tts",
> + VLC_CODEC_H264,
> + VLC_CODEC_A52,
> + },
> + /**
> + * AVC video wrapped in MPEG-2 transport stream, as
> + * constrained by SCTE standards,
> + * with AC-3, Enhanced AC-3, MPEG-4 HE-AAC
> + * v2 or MPEG-1 Layer II audio, with a valid
> + * non-zero timestamp field.
> + */
> + {
> + "AVC_TS_NA_T",
> + "ts",
> + "video/vnd.dlna.mpeg-tts",
> + VLC_CODEC_H264,
> + VLC_CODEC_EAC3,
> + },
> + /**
> + * AVC video wrapped in MPEG-2 transport stream, as
> + * constrained by SCTE standards,
> + * with AC-3, Enhanced AC-3, MPEG-4 HE-AAC
> + * v2 or MPEG-1 Layer II audio, with a valid
> + * non-zero timestamp field.
> + */
> + {
> + "AVC_TS_NA_T",
> + "ts",
> + "video/vnd.dlna.mpeg-tts",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC video wrapped in MPEG-2 transport stream, as
> + * constrained by SCTE standards,
> + * with AC-3, Enhanced AC-3, MPEG-4 HE-AAC
> + * v2 or MPEG-1 Layer II audio, with a valid
> + * non-zero timestamp field.
> + */
> + {
> + "AVC_TS_NA_T",
> + "ts",
> + "video/vnd.dlna.mpeg-tts",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP2,
> + },
> + /**
> + * AVC video wrapped in MPEG-2 transport stream, as
> + * constrained by SCTE standards,
> + * with AC-3, Enhanced AC-3, MPEG-4 HE-AAC
> + * v2 or MPEG-1 Layer II audio,
> + * without a timestamp field.
> + */
> + {
> + "AVC_TS_NA_ISO",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_H264,
> + VLC_CODEC_A52,
> + },
> + /**
> + * AVC video wrapped in MPEG-2 transport stream, as
> + * constrained by SCTE standards,
> + * with AC-3, Enhanced AC-3, MPEG-4 HE-AAC
> + * v2 or MPEG-1 Layer II audio,
> + * without a timestamp field.
> + */
> + {
> + "AVC_TS_NA_ISO",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_H264,
> + VLC_CODEC_EAC3,
> + },
> + /**
> + * AVC video wrapped in MPEG-2 transport stream, as
> + * constrained by SCTE standards,
> + * with AC-3, Enhanced AC-3, MPEG-4 HE-AAC
> + * v2 or MPEG-1 Layer II audio,
> + * without a timestamp field.
> + */
> + {
> + "AVC_TS_NA_ISO",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC video wrapped in MPEG-2 transport stream, as
> + * constrained by SCTE standards,
> + * with AC-3, Enhanced AC-3, MPEG-4 HE-AAC
> + * v2 or MPEG-1 Layer II audio,
> + * without a timestamp field.
> + */
> + {
> + "AVC_TS_NA_ISO",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP2,
> + },
> + /**
> + * AVC high profile, HD 3D frame-compatible video
> + * wrapped in MPEG-2 transport stream with AC-3,
> + * Enhanced AC-3 or HE AAC audio, without a Timestamp field.
> + */
> + {
> + "AVC_TS_NA_3DFC_ISO",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_H264,
> + VLC_CODEC_A52,
> + },
> + /**
> + * AVC high profile, HD 3D frame-compatible video
> + * wrapped in MPEG-2 transport stream with AC-3,
> + * Enhanced AC-3 or HE AAC audio, without a Timestamp field.
> + */
> + {
> + "AVC_TS_NA_3DFC_ISO",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_H264,
> + VLC_CODEC_EAC3,
> + },
> + /**
> + * AVC high profile, HD 3D frame-compatible video
> + * wrapped in MPEG-2 transport stream with AC-3,
> + * Enhanced AC-3 or HE AAC audio, without a Timestamp field.
> + */
> + {
> + "AVC_TS_NA_3DFC_ISO",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC video wrapped in MPEG-2 TS transport stream
> + * as constrained by DVB standards, with AC-3,
> + * Enhanced AC-3 and MPEG-4 HE-AAC v2 audio.
> + */
> + {
> + "AVC_TS_EU_ISO",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_H264,
> + VLC_CODEC_A52,
> + },
> + /**
> + * AVC video wrapped in MPEG-2 TS transport stream
> + * as constrained by DVB standards, with AC-3,
> + * Enhanced AC-3 and MPEG-4 HE-AAC v2 audio.
> + */
> + {
> + "AVC_TS_EU_ISO",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_H264,
> + VLC_CODEC_EAC3,
> + },
> + /**
> + * AVC video wrapped in MPEG-2 TS transport stream
> + * as constrained by DVB standards, with AC-3,
> + * Enhanced AC-3 and MPEG-4 HE-AAC v2 audio.
> + */
> + {
> + "AVC_TS_EU_ISO",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_H264,
> + VLC_CODEC_EAC3,
> + },
> + /**
> + * European region profile for HD/SD resolution.
> + * AVC video using the Scalable High Profile (SVC)
> + * wrapped in MPEG-2 Transport Stream with AC-3 audio,
> + * with a valid non-zero timestamp field.
> + */
> + {
> + "AVC_TS_SHP_HD_EU_AC3_T",
> + "ts",
> + "video/vnd.dlna.mpeg-tts",
> + VLC_CODEC_H264,
> + VLC_CODEC_A52,
> + },
> + /**
> + * European region profile for HD/SD resolution. AVC video using
> the
> + * Scalable High Profile (SVC) wrapped in MPEG-2 Transport Stream
> + * with MPEG-4 HE-AAC v2 Level 4 audio, with a valid non-zero
> timestamp field.
> + */
> + {
> + "AVC_TS_SHP_HD_EU_HEAACv2_L4_T",
> + "ts",
> + "video/vnd.dlna.mpeg-tts",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC HD/SD video with AC-3 audio including dual-mono channel
> mode, wrapped
> + * in MPEG-2 TS with valid timestamp for 24 Hz system.
> + */
> + {
> + "AVC_TS_HD_24_AC3_X_T",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_H264,
> + VLC_CODEC_A52,
> + },
> + /**
> + * AVC HD/SD video with AC-3 audio including dual-mono channel
> mode, wrapped
> + * in MPEG-2 TS with valid timestamp for 50 Hz system.
> + */
> + {
> + "AVC_TS_HD_50_AC3_X_T",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_H264,
> + VLC_CODEC_A52,
> + },
> + /**
> + * AVC HD/SD video with AC-3 audio including dual-mono channel
> mode,
> + * wrapped in MPEG-2 TS with valid timestamp for 60 Hz system.
> + */
> + {
> + "AVC_TS_HD_60_AC3_X_T",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_H264,
> + VLC_CODEC_A52,
> + },
> + /**
> + * AVC wrapped in MPEG-2 transport stream, Main/High profile, with
> + * MPEG-2 AAC audio, with a valid non-zero timestamp field.
> + */
> + {
> + "AVC_TS_JP_AAC_T",
> + "ts",
> + "video/mpeg",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC video with MPEG-4 HE-AAC v2
> + * and Enhanced AC-3 audio, encapsulated in MP4.
> + */
> + {
> + "AVC_MP4_EU",
> + "mp4stream",
> + "video/mp4",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC video with MPEG-4 HE-AAC v2
> + * and Enhanced AC-3 audio, encapsulated in MP4.
> + */
> + {
> + "AVC_MP4_EU",
> + "mp4stream",
> + "video/mp4",
> + VLC_CODEC_H264,
> + VLC_CODEC_A52,
> + },
> + /**
> + * AVC wrapped in MP4 baseline profile CIF15 with AAC LC audio.
> + */
> + {
> + "AVC_MP4_BL_CIF15_AAC_520",
> + "mp4stream",
> + "video/mp4",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC wrapped in MP4 baseline profile CIF30 with AAC LC audio.
> + */
> + {
> + "AVC_MP4_BL_CIF30_AAC_940",
> + "mp4stream",
> + "video/mp4",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC Main Profile video with Enhanced AC-3 audio, encapsulated in
> MP4.
> + */
> + {
> + "AVC_MP4_MP_SD_EAC3",
> + "mp4stream",
> + "video/mp4",
> + VLC_CODEC_H264,
> + VLC_CODEC_EAC3,
> + },
> + /**
> + * AVC High Profile HD video with MPEG-4 AAC audio, encapsulated in
> MP4.
> + */
> + {
> + "AVC_MP4_MP_SD",
> + "mp4stream",
> + "video/mp4",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC High Profile video with Enhanced AC-3 audio, encapsulated in
> MP4.
> + */
> + {
> + "AVC_MP4_HP_HD_EAC3",
> + "mp4stream",
> + "video/mp4",
> + VLC_CODEC_H264,
> + VLC_CODEC_EAC3,
> + },
> + /**
> + * AVC high profile video with HE AAC v2 stereo or HE AAC 7.1-
> channel audio,
> + * encapsulated in an MP4 file.
> + */
> + {
> + "AVC_MP4_HD_HEAACv2_L6",
> + "mp4stream",
> + "video/mp4",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC Main Profile video with MPEG-4 AAC audio, encapsulated in
> MKV.
> + */
> + {
> + "AVC_MKV_MP_HD_AAC_MULT5",
> + "avformat{mux=matroska,options={live=1}}",
> + "video/x-matroska",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC Main Profile video with MPEG-4 HE-AAC audio, encapsulated in
> MKV.
> + */
> + {
> + "AVC_MKV_MP_HD_HEAAC_L4",
> + "avformat{mux=matroska,options={live=1}}",
> + "video/x-matroska",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC Main Profile video with MP3 audio, encapsulated in MKV
> + */
> + {
> + "AVC_MKV_MP_HD_MPEG1_L3",
> + "avformat{mux=matroska,options={live=1}}",
> + "video/x-matroska",
> + VLC_CODEC_H264,
> + VLC_CODEC_MPGA,
> + },
> + /**
> + * AVC Main Profile video with MP3 audio, encapsulated in MKV
> + */
> + {
> + "AVC_MKV_MP_HD_MPEG1_L3",
> + "avformat{mux=matroska,options={live=1}}",
> + "video/x-matroska",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP3,
> + },
> + /**
> + * AVC High Profile video with MP3 audio, encapsulated in MKV
> + */
> + {
> + "AVC_MKV_HP_HD_MPEG1_L3",
> + "avformat{mux=matroska,options={live=1}}",
> + "video/x-matroska",
> + VLC_CODEC_H264,
> + VLC_CODEC_MPGA,
> + },
> + /**
> + * AVC High Profile video with MP3 audio, encapsulated in MKV
> + */
> + {
> + "AVC_MKV_HP_HD_MPEG1_L3",
> + "avformat{mux=matroska,options={live=1}}",
> + "video/x-matroska",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP3,
> + },
> + /**
> + * AVC High Profile video with MPEG-4 AAC audio, encapsulated in
> MKV.
> + */
> + {
> + "AVC_MKV_HP_HD_AAC_MULT5",
> + "avformat{mux=matroska,options={live=1}}",
> + "video/x-matroska",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC High Profile video with MPEG-4 HE-AAC audio, encapsulated in
> MKV.
> + */
> + {
> + "AVC_MKV_HP_HD_HEAAC_L4",
> + "avformat{mux=matroska,options={live=1}}",
> + "video/x-matroska",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC SD video wrapped in MPEG-2 transport stream, as constrained
> by
> + * SCTE standards, with AAC audio and optional enhanced audio,
> + * without a timestamp field and constrained to an SD video profile
> + */
> + {
> + "DASH_AVC_TS_SD_ISO",
> + "ts",
> + "video/mp2t",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC HD video wrapped in MPEG-2 transport stream, as constrained
> by
> + * SCTE standards, with AAC audio and optional enhanced audio,
> + * without a timestamp field and constrained to an HD video profile
> + */
> + {
> + "DASH_AVC_TS_HD_ISO",
> + "ts",
> + "video/mp2t",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC Main Profile SD video with AAC audio and optional enhanced
> audio,
> + * encapsulated in MP4 conforming to the additional DECE CFF
> requirements
> + * including encryption and constrained to the DECE SD profile
> requirements.
> + */
> + {
> + "DASH_AVC_MP4_SD",
> + "mp4stream",
> + "video/mp4",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC Main Profile HD video with AAC audio and optional enhanced
> audio,
> + * encapsulated in MP4 conforming to the additional DECE CFF
> requirements
> + * including encryption and constrained to the DECE HD profile
> requirements.
> + */
> + {
> + "DASH_AVC_MP4_HD",
> + "mp4stream",
> + "video/mp4",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC Main Profile video with HE AACv2 L4 audio, encapsulated in
> MP4.
> + */
> + {
> + "DASH_AVC_MP4_SD_HEAACv2_L4",
> + "mp4stream",
> + "video/mp4",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC High Profile video with HE AACv2 L4 audio, encapsulated in
> MP4.
> + */
> + {
> + "DASH_AVC_MP4_HD_HEAACv2_L4",
> + "mp4stream",
> + "video/mp4",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * AVC high profile video with HE AAC v2 stereo or HE AAC 7.1-
> channel audio,
> + * encapsulated in an MP4 file suitable for MPEG DASH conformant
> adaptive delivery
> + */
> + {
> + "DASH_AVC_MP4_HD_HEAACv2_L6",
> + "mp4stream",
> + "video/mp4",
> + VLC_CODEC_H264,
> + VLC_CODEC_MP4A,
> + },
> + /**
> + * HEVC High Profile HD and UHD video with AC-3,
> + * Enhanced AC-3, HE-AACv2 or MPEG-1 LII audio,
> + * encapsulated in MP4.
> + */
> + {
> + "DASH_HEVC_MP4_UHD_NA",
> + "mp4stream",
> + "video/mp4",
> + VLC_CODEC_HEVC,
> + VLC_CODEC_MP2,
> + },
> +};
> +
> +#endif /* DLNA_PROFILES_H */
> --
> 2.20.1
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
--
Hugo Beauzée-Luyssen
hugo at beauzee.fr
More information about the vlc-devel
mailing list