From b78f1fa51db4913e27cc85d4842ce3a27fe181b5 Mon Sep 17 00:00:00 2001 From: Rintaro Kuroiwa Date: Mon, 18 Nov 2013 15:39:20 -0800 Subject: [PATCH] Helper functions for MPD builder class Change-Id: Ice97c734903c35b1356a445daa953dd2162d30b2 --- mpd/base/content_protection_element.h | 27 ++++++++ mpd/base/mpd_utils.cc | 96 +++++++++++++++++++++++++++ mpd/base/mpd_utils.h | 38 +++++++++++ 3 files changed, 161 insertions(+) create mode 100644 mpd/base/content_protection_element.h create mode 100644 mpd/base/mpd_utils.cc create mode 100644 mpd/base/mpd_utils.h diff --git a/mpd/base/content_protection_element.h b/mpd/base/content_protection_element.h new file mode 100644 index 0000000000..d80de4a0c1 --- /dev/null +++ b/mpd/base/content_protection_element.h @@ -0,0 +1,27 @@ +// ContentProtectionElement is shared a structure that can be passed to +// MPD generator classes to add ContentProtection element in the resulting MPD +// file. +// http://goo.gl/UrsSlF + +#ifndef MPD_BASE_CONTENT_PROTECTION_ELEMENT_H_ +#define MPD_BASE_CONTENT_PROTECTION_ELEMENT_H_ + +#include +#include + +namespace dash_packager { + +struct ContentProtectionElement { + std::string value; // Will be set for 'value' attribute. + std::string scheme_id_uri; // Will be set for 'schemeIdUri' attribute. + + // Other attributes for this element. + std::map additional_attributes; + + // The elements that will be in this element. + std::string subelements; +}; + +} // namespace dash_packager + +#endif // MPD_BASE_CONTENT_PROTECTION_ELEMENT_H_ diff --git a/mpd/base/mpd_utils.cc b/mpd/base/mpd_utils.cc new file mode 100644 index 0000000000..f6c5b3d774 --- /dev/null +++ b/mpd/base/mpd_utils.cc @@ -0,0 +1,96 @@ +#include "mpd/base/mpd_utils.h" + +#include + +#include "base/logging.h" +#include "base/strings/string_number_conversions.h" +#include "mpd/base/content_protection_element.h" +#include "mpd/base/xml/scoped_xml_ptr.h" +#include "third_party/libxml/src/include/libxml/tree.h" + + +namespace { + +// Concatenate all the codecs in |repeated_stream_info|. +template +std::string CodecsString(const RepeatedStreamInfoType& repeated_stream_info) { + std::string codecs; + for (int i = 0; i < repeated_stream_info.size(); ++i) { + codecs.append(repeated_stream_info.Get(i).codec()); + codecs.append(","); + } + + if (!codecs.empty()) { + DCHECK_EQ(codecs[codecs.size() - 1], ','); + codecs.resize(codecs.size() - 1); // Cut off ',' at the end. + } + + return codecs; +} + +} // namespace + +namespace dash_packager { + +bool HasVODOnlyFields(const MediaInfo& media_info) { + return media_info.has_init_range() || media_info.has_index_range() || + media_info.has_media_file_name() || media_info.has_media_duration(); +} + +bool HasLiveOnlyFields(const MediaInfo& media_info) { + return media_info.has_init_segment_name() || + media_info.has_segment_template() || media_info.has_segment_duration(); +} + +void RemoveDuplicateAttributes( + ContentProtectionElement* content_protection_element) { + DCHECK(content_protection_element); + typedef std::map AttributesMap; + + AttributesMap& attributes = content_protection_element->additional_attributes; + if (!content_protection_element->value.empty()) + attributes.erase("value"); + + if (!content_protection_element->scheme_id_uri.empty()) + attributes.erase("schemeIdUri"); +} + +std::string GetCodecs(const MediaInfo& media_info) { + std::string video_codecs; + if (media_info.video_info_size() > 0) + video_codecs = CodecsString(media_info.video_info()); + + std::string audio_codecs; + if (media_info.audio_info_size() > 0) + audio_codecs = CodecsString(media_info.audio_info()); + + if (!video_codecs.empty() && !audio_codecs.empty()) { + return video_codecs + "," + audio_codecs; + } else if (!video_codecs.empty()) { + return video_codecs; + } else if (!audio_codecs.empty()) { + return audio_codecs; + } + + return ""; +} + +std::string SecondsToXmlDuration(uint32 seconds) { + return "P" + base::UintToString(seconds) + "S"; +} + +bool GetDurationAttribute(xmlNodePtr node, uint32* duration) { + DCHECK(node); + DCHECK(duration); + static const char kDuration[] = "duration"; + xml::ScopedXmlPtr::type duration_value( + xmlGetProp(node, BAD_CAST kDuration)); + + if (!duration_value) + return false; + + return base::StringToUint(reinterpret_cast(duration_value.get()), + duration); +} + +} // namespace dash_packager diff --git a/mpd/base/mpd_utils.h b/mpd/base/mpd_utils.h new file mode 100644 index 0000000000..fb408b84b0 --- /dev/null +++ b/mpd/base/mpd_utils.h @@ -0,0 +1,38 @@ +// Funtions used by MpdBuilder class to generate an MPD file. +#ifndef MPD_BASE_MPD_UTILS_H_ +#define MPD_BASE_MPD_UTILS_H_ + +#include + +#include "base/basictypes.h" +#include "mpd/base/media_info.pb.h" +#include "third_party/libxml/src/include/libxml/tree.h" + +namespace dash_packager { + +class ContentProtectionElement; + +bool HasVODOnlyFields(const MediaInfo& media_info); + +bool HasLiveOnlyFields(const MediaInfo& media_info); + +// If |content_protection_element| has 'value' or 'schemeIdUri' set but it's +// also in the map, then this removes them from the map. +// |content_protection_element| cannot be NULL. +void RemoveDuplicateAttributes( + ContentProtectionElement* content_protection_element); + +// Returns a 'codecs' string that has all the video and audio codecs joined with +// comma. +std::string GetCodecs(const MediaInfo& media_info); + +// TODO(rkuroiwa): This probably needs to change to floating point number. +// Returns "PS". +std::string SecondsToXmlDuration(uint32 seconds); + +// Tries to get "duration" attribute from |node|. On success |duration| is set. +bool GetDurationAttribute(xmlNodePtr node, uint32* duration); + +} // namespace dash_packager + +#endif // MPD_BASE_MPD_UTILS_H_