7 #include "packager/app/stream_descriptor.h"
9 #include "packager/app/packager_util.h"
10 #include "packager/base/logging.h"
11 #include "packager/base/strings/string_number_conversions.h"
12 #include "packager/base/strings/string_split.h"
13 #include "packager/mpd/base/language_utils.h"
25 kSegmentTemplateField,
31 kHlsPlaylistNameField,
34 struct FieldNameToTypeMapping {
35 const char* field_name;
39 const FieldNameToTypeMapping kFieldNameTypeMappings[] = {
40 {
"stream_selector", kStreamSelectorField},
41 {
"stream", kStreamSelectorField},
42 {
"input", kInputField},
44 {
"output", kOutputField},
45 {
"out", kOutputField},
46 {
"init_segment", kOutputField},
47 {
"segment_template", kSegmentTemplateField},
48 {
"template", kSegmentTemplateField},
49 {
"bandwidth", kBandwidthField},
50 {
"bw", kBandwidthField},
51 {
"bitrate", kBandwidthField},
52 {
"language", kLanguageField},
53 {
"lang", kLanguageField},
54 {
"output_format", kOutputFormatField},
55 {
"format", kOutputFormatField},
56 {
"hls_name", kHlsNameField},
57 {
"hls_group_id", kHlsGroupIdField},
58 {
"playlist_name", kHlsPlaylistNameField},
61 FieldType GetFieldType(
const std::string& field_name) {
62 for (
size_t idx = 0; idx < arraysize(kFieldNameTypeMappings); ++idx) {
63 if (field_name == kFieldNameTypeMappings[idx].field_name)
64 return kFieldNameTypeMappings[idx].field_type;
71 StreamDescriptor::StreamDescriptor()
72 : bandwidth(0), output_format(CONTAINER_UNKNOWN) {}
74 StreamDescriptor::~StreamDescriptor() {}
76 bool InsertStreamDescriptor(
const std::string& descriptor_string,
77 StreamDescriptorList* descriptor_list) {
78 StreamDescriptor descriptor;
81 base::StringPairs pairs;
82 if (!base::SplitStringIntoKeyValuePairs(descriptor_string,
86 LOG(ERROR) <<
"Invalid stream descriptors name/value pairs.";
89 for (base::StringPairs::const_iterator iter = pairs.begin();
90 iter != pairs.end(); ++iter) {
91 switch (GetFieldType(iter->first)) {
92 case kStreamSelectorField:
93 descriptor.stream_selector = iter->second;
96 descriptor.input = iter->second;
99 descriptor.output = iter->second;
101 case kSegmentTemplateField:
102 descriptor.segment_template = iter->second;
104 case kBandwidthField: {
106 if (!base::StringToUint(iter->second, &bw)) {
107 LOG(ERROR) <<
"Non-numeric bandwidth specified.";
110 descriptor.bandwidth = bw;
113 case kLanguageField: {
115 if (language ==
"und") {
116 LOG(ERROR) <<
"Unknown/invalid language specified: " << iter->second;
119 DCHECK_EQ(3u, language.size());
120 descriptor.language = language;
123 case kOutputFormatField: {
124 MediaContainerName output_format =
125 DetermineContainerFromFormatName(iter->second);
126 if (output_format == CONTAINER_UNKNOWN) {
127 LOG(ERROR) <<
"Unrecognized output format " << iter->second;
130 descriptor.output_format = output_format;
133 case kHlsNameField: {
134 descriptor.hls_name = iter->second;
137 case kHlsGroupIdField: {
138 descriptor.hls_group_id = iter->second;
141 case kHlsPlaylistNameField: {
142 descriptor.hls_playlist_name = iter->second;
146 LOG(ERROR) <<
"Unknown field in stream descriptor (\"" << iter->first
153 if (descriptor.input.empty()) {
154 LOG(ERROR) <<
"Stream input not specified.";
157 if (!FLAGS_dump_stream_info && descriptor.stream_selector.empty()) {
158 LOG(ERROR) <<
"Stream stream_selector not specified.";
164 const bool is_mpeg2ts_with_segment_template =
165 descriptor.output_format == MediaContainerName::CONTAINER_MPEG2TS &&
166 !descriptor.segment_template.empty();
167 if (!FLAGS_dump_stream_info && descriptor.output.empty() &&
168 !is_mpeg2ts_with_segment_template) {
169 LOG(ERROR) <<
"Stream output not specified.";
172 descriptor_list->insert(descriptor);
std::string LanguageToISO_639_2(const std::string &language)