7 #include "packager/app/stream_descriptor.h"
9 #include "packager/base/logging.h"
10 #include "packager/base/strings/string_number_conversions.h"
11 #include "packager/base/strings/string_split.h"
22 kSegmentTemplateField,
29 kHlsPlaylistNameField,
30 kHlsIframePlaylistNameField,
31 kTrickPlayFactorField,
34 kHlsCharacteristicsField,
35 kDashAccessiblitiesField,
41 struct FieldNameToTypeMapping {
42 const char* field_name;
46 const FieldNameToTypeMapping kFieldNameTypeMappings[] = {
47 {
"stream_selector", kStreamSelectorField},
48 {
"stream", kStreamSelectorField},
49 {
"input", kInputField},
51 {
"output", kOutputField},
52 {
"out", kOutputField},
53 {
"init_segment", kOutputField},
54 {
"segment_template", kSegmentTemplateField},
55 {
"template", kSegmentTemplateField},
56 {
"bandwidth", kBandwidthField},
57 {
"bw", kBandwidthField},
58 {
"bitrate", kBandwidthField},
59 {
"language", kLanguageField},
60 {
"lang", kLanguageField},
61 {
"cc_index", kCcIndexField},
62 {
"output_format", kOutputFormatField},
63 {
"format", kOutputFormatField},
64 {
"hls_name", kHlsNameField},
65 {
"hls_group_id", kHlsGroupIdField},
66 {
"playlist_name", kHlsPlaylistNameField},
67 {
"iframe_playlist_name", kHlsIframePlaylistNameField},
68 {
"trick_play_factor", kTrickPlayFactorField},
69 {
"tpf", kTrickPlayFactorField},
70 {
"skip_encryption", kSkipEncryptionField},
71 {
"drm_stream_label", kDrmStreamLabelField},
72 {
"drm_label", kDrmStreamLabelField},
73 {
"hls_characteristics", kHlsCharacteristicsField},
74 {
"characteristics", kHlsCharacteristicsField},
75 {
"charcs", kHlsCharacteristicsField},
76 {
"dash_accessibilities", kDashAccessiblitiesField},
77 {
"dash_accessibility", kDashAccessiblitiesField},
78 {
"accessibilities", kDashAccessiblitiesField},
79 {
"accessibility", kDashAccessiblitiesField},
80 {
"dash_roles", kDashRolesField},
81 {
"dash_role", kDashRolesField},
82 {
"roles", kDashRolesField},
83 {
"role", kDashRolesField},
84 {
"dash_only", kDashOnlyField},
85 {
"hls_only", kHlsOnlyField},
88 FieldType GetFieldType(
const std::string& field_name) {
89 for (
size_t idx = 0; idx < arraysize(kFieldNameTypeMappings); ++idx) {
90 if (field_name == kFieldNameTypeMappings[idx].field_name)
91 return kFieldNameTypeMappings[idx].field_type;
99 const std::string& descriptor_string) {
103 base::StringPairs pairs;
104 if (!base::SplitStringIntoKeyValuePairs(descriptor_string,
'=',
',',
106 LOG(ERROR) <<
"Invalid stream descriptors name/value pairs: "
107 << descriptor_string;
108 return base::nullopt;
110 for (base::StringPairs::const_iterator iter = pairs.begin();
111 iter != pairs.end(); ++iter) {
112 switch (GetFieldType(iter->first)) {
113 case kStreamSelectorField:
117 descriptor.
input = iter->second;
120 descriptor.
output = iter->second;
122 case kSegmentTemplateField:
125 case kBandwidthField: {
127 if (!base::StringToUint(iter->second, &bw)) {
128 LOG(ERROR) <<
"Non-numeric bandwidth specified.";
129 return base::nullopt;
134 case kLanguageField: {
138 case kCcIndexField: {
140 if (!base::StringToUint(iter->second, &index)) {
141 LOG(ERROR) <<
"Non-numeric cc_index specified.";
142 return base::nullopt;
147 case kOutputFormatField: {
151 case kHlsNameField: {
155 case kHlsGroupIdField: {
159 case kHlsPlaylistNameField: {
163 case kHlsIframePlaylistNameField: {
167 case kTrickPlayFactorField: {
169 if (!base::StringToUint(iter->second, &factor)) {
170 LOG(ERROR) <<
"Non-numeric trick play factor " << iter->second
172 return base::nullopt;
175 LOG(ERROR) <<
"Stream trick_play_factor should be > 0.";
176 return base::nullopt;
181 case kSkipEncryptionField: {
182 unsigned skip_encryption_value;
183 if (!base::StringToUint(iter->second, &skip_encryption_value)) {
184 LOG(ERROR) <<
"Non-numeric option for skip encryption field "
185 "specified (" << iter->second <<
").";
186 return base::nullopt;
188 if (skip_encryption_value > 1) {
189 LOG(ERROR) <<
"skip_encryption should be either 0 or 1.";
190 return base::nullopt;
196 case kDrmStreamLabelField:
199 case kHlsCharacteristicsField:
201 base::SplitString(iter->second,
";:", base::TRIM_WHITESPACE,
202 base::SPLIT_WANT_NONEMPTY);
204 case kDashAccessiblitiesField:
206 base::SplitString(iter->second,
";", base::TRIM_WHITESPACE,
207 base::SPLIT_WANT_NONEMPTY);
208 for (
const std::string& accessibility :
210 size_t pos = accessibility.find(
'=');
211 if (pos == std::string::npos) {
213 <<
"Accessibility should be in scheme=value format, but seeing "
215 return base::nullopt;
219 case kDashRolesField:
221 base::SplitString(iter->second,
";", base::TRIM_WHITESPACE,
222 base::SPLIT_WANT_NONEMPTY);
225 unsigned dash_only_value;
226 if (!base::StringToUint(iter->second, &dash_only_value)) {
227 LOG(ERROR) <<
"Non-numeric option for dash_only field "
228 "specified (" << iter->second <<
").";
229 return base::nullopt;
231 if (dash_only_value > 1) {
232 LOG(ERROR) <<
"dash_only should be either 0 or 1.";
233 return base::nullopt;
235 descriptor.
dash_only = dash_only_value > 0;
238 unsigned hls_only_value;
239 if (!base::StringToUint(iter->second, &hls_only_value)) {
240 LOG(ERROR) <<
"Non-numeric option for hls_only field "
241 "specified (" << iter->second <<
").";
242 return base::nullopt;
244 if (hls_only_value > 1) {
245 LOG(ERROR) <<
"hls_only should be either 0 or 1.";
246 return base::nullopt;
248 descriptor.
hls_only = hls_only_value > 0;
251 LOG(ERROR) <<
"Unknown field in stream descriptor (\"" << iter->first
253 return base::nullopt;