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"
12 #include "packager/media/base/language_utils.h"
23 kSegmentTemplateField,
29 kHlsPlaylistNameField,
30 kTrickPlayFactorField,
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},
59 {
"trick_play_factor", kTrickPlayFactorField},
60 {
"tpf", kTrickPlayFactorField},
61 {
"skip_encryption", kSkipEncryptionField},
64 FieldType GetFieldType(
const std::string& field_name) {
65 for (
size_t idx = 0; idx < arraysize(kFieldNameTypeMappings); ++idx) {
66 if (field_name == kFieldNameTypeMappings[idx].field_name)
67 return kFieldNameTypeMappings[idx].field_type;
75 const std::string& descriptor_string) {
76 StreamDescriptor descriptor;
79 base::StringPairs pairs;
80 if (!base::SplitStringIntoKeyValuePairs(descriptor_string,
'=',
',',
82 LOG(ERROR) <<
"Invalid stream descriptors name/value pairs.";
85 for (base::StringPairs::const_iterator iter = pairs.begin();
86 iter != pairs.end(); ++iter) {
87 switch (GetFieldType(iter->first)) {
88 case kStreamSelectorField:
89 descriptor.stream_selector = iter->second;
92 descriptor.input = iter->second;
95 descriptor.output = iter->second;
97 case kSegmentTemplateField:
98 descriptor.segment_template = iter->second;
100 case kBandwidthField: {
102 if (!base::StringToUint(iter->second, &bw)) {
103 LOG(ERROR) <<
"Non-numeric bandwidth specified.";
104 return base::nullopt;
106 descriptor.bandwidth = bw;
109 case kLanguageField: {
112 if (language ==
"und") {
113 LOG(ERROR) <<
"Unknown/invalid language specified: " << iter->second;
114 return base::nullopt;
116 descriptor.language = language;
119 case kOutputFormatField: {
120 descriptor.output_format = iter->second;
123 case kHlsNameField: {
124 descriptor.hls_name = iter->second;
127 case kHlsGroupIdField: {
128 descriptor.hls_group_id = iter->second;
131 case kHlsPlaylistNameField: {
132 descriptor.hls_playlist_name = iter->second;
135 case kTrickPlayFactorField: {
137 if (!base::StringToUint(iter->second, &factor)) {
138 LOG(ERROR) <<
"Non-numeric trick play factor " << iter->second
140 return base::nullopt;
143 LOG(ERROR) <<
"Stream trick_play_factor should be > 0.";
144 return base::nullopt;
146 descriptor.trick_play_factor = factor;
149 case kSkipEncryptionField: {
150 unsigned skip_encryption_value;
151 if (!base::StringToUint(iter->second, &skip_encryption_value)) {
152 LOG(ERROR) <<
"Non-numeric option for skip encryption field "
153 "specified (" << iter->second <<
").";
154 return base::nullopt;
156 if (skip_encryption_value > 1) {
157 LOG(ERROR) <<
"skip_encryption should be either 0 or 1.";
158 return base::nullopt;
161 descriptor.skip_encryption = skip_encryption_value > 0;
165 LOG(ERROR) <<
"Unknown field in stream descriptor (\"" << iter->first
167 return base::nullopt;
base::Optional< StreamDescriptor > ParseStreamDescriptor(const std::string &descriptor_string)
std::string LanguageToISO_639_2(const std::string &language)