DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs Enumerator
stream_descriptor.cc
1 // Copyright 2014 Google Inc. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file or at
5 // https://developers.google.com/open-source/licenses/bsd
6 
7 #include "packager/app/stream_descriptor.h"
8 
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"
14 
15 namespace edash_packager {
16 namespace media {
17 
18 namespace {
19 
20 enum FieldType {
21  kUnknownField = 0,
22  kStreamSelectorField,
23  kInputField,
24  kOutputField,
25  kSegmentTemplateField,
26  kBandwidthField,
27  kLanguageField,
28  kOutputFormatField,
29 };
30 
31 struct FieldNameToTypeMapping {
32  const char* field_name;
33  FieldType field_type;
34 };
35 
36 const FieldNameToTypeMapping kFieldNameTypeMappings[] = {
37  { "stream_selector", kStreamSelectorField },
38  { "stream", kStreamSelectorField },
39  { "input", kInputField },
40  { "in", kInputField },
41  { "output", kOutputField },
42  { "out", kOutputField },
43  { "init_segment", kOutputField },
44  { "segment_template", kSegmentTemplateField },
45  { "template", kSegmentTemplateField },
46  { "bandwidth", kBandwidthField },
47  { "bw", kBandwidthField },
48  { "bitrate", kBandwidthField },
49  { "language", kLanguageField },
50  { "lang", kLanguageField },
51  { "output_format", kOutputFormatField },
52  { "format", kOutputFormatField },
53 };
54 
55 FieldType GetFieldType(const std::string& field_name) {
56  for (size_t idx = 0; idx < arraysize(kFieldNameTypeMappings); ++idx) {
57  if (field_name == kFieldNameTypeMappings[idx].field_name)
58  return kFieldNameTypeMappings[idx].field_type;
59  }
60  return kUnknownField;
61 }
62 
63 } // anonymous namespace
64 
65 StreamDescriptor::StreamDescriptor()
66  : bandwidth(0), output_format(CONTAINER_UNKNOWN) {}
67 
68 StreamDescriptor::~StreamDescriptor() {}
69 
70 bool InsertStreamDescriptor(const std::string& descriptor_string,
71  StreamDescriptorList* descriptor_list) {
72  StreamDescriptor descriptor;
73 
74  // Split descriptor string into name/value pairs.
75  base::StringPairs pairs;
76  if (!base::SplitStringIntoKeyValuePairs(descriptor_string,
77  '=',
78  ',',
79  &pairs)) {
80  LOG(ERROR) << "Invalid stream descriptors name/value pairs.";
81  return false;
82  }
83  for (base::StringPairs::const_iterator iter = pairs.begin();
84  iter != pairs.end(); ++iter) {
85  switch (GetFieldType(iter->first)) {
86  case kStreamSelectorField:
87  descriptor.stream_selector = iter->second;
88  break;
89  case kInputField:
90  descriptor.input = iter->second;
91  break;
92  case kOutputField:
93  descriptor.output = iter->second;
94  break;
95  case kSegmentTemplateField:
96  descriptor.segment_template = iter->second;
97  break;
98  case kBandwidthField: {
99  unsigned bw;
100  if (!base::StringToUint(iter->second, &bw)) {
101  LOG(ERROR) << "Non-numeric bandwidth specified.";
102  return false;
103  }
104  descriptor.bandwidth = bw;
105  break;
106  }
107  case kLanguageField: {
108  std::string language = LanguageToISO_639_2(iter->second);
109  if (language == "und") {
110  LOG(ERROR) << "Unknown/invalid language specified: " << iter->second;
111  return false;
112  }
113  DCHECK_EQ(3u, language.size());
114  descriptor.language = language;
115  break;
116  }
117  case kOutputFormatField: {
118  MediaContainerName output_format =
119  DetermineContainerFromFormatName(iter->second);
120  if (output_format == CONTAINER_UNKNOWN) {
121  LOG(ERROR) << "Unrecognized output format " << iter->second;
122  return false;
123  }
124  descriptor.output_format = output_format;
125  break;
126  }
127  default:
128  LOG(ERROR) << "Unknown field in stream descriptor (\"" << iter->first
129  << "\").";
130  return false;
131  break;
132  }
133  }
134  // Validate and insert the descriptor
135  if (descriptor.input.empty()) {
136  LOG(ERROR) << "Stream input not specified.";
137  return false;
138  }
139  if (!FLAGS_dump_stream_info && descriptor.stream_selector.empty()) {
140  LOG(ERROR) << "Stream stream_selector not specified.";
141  return false;
142  }
143  if (!FLAGS_dump_stream_info && descriptor.output.empty()) {
144  LOG(ERROR) << "Stream output not specified.";
145  return false;
146  }
147  descriptor_list->insert(descriptor);
148  return true;
149 }
150 
151 } // namespace media
152 } // namespace edash_packager
std::string LanguageToISO_639_2(const std::string &language)