Shaka Packager SDK
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
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/base/logging.h"
10 #include "packager/base/strings/string_number_conversions.h"
11 #include "packager/base/strings/string_split.h"
12 
13 namespace shaka {
14 
15 namespace {
16 
17 enum FieldType {
18  kUnknownField = 0,
19  kStreamSelectorField,
20  kInputField,
21  kOutputField,
22  kSegmentTemplateField,
23  kBandwidthField,
24  kLanguageField,
25  kOutputFormatField,
26  kHlsNameField,
27  kHlsGroupIdField,
28  kHlsPlaylistNameField,
29  kTrickPlayFactorField,
30  kSkipEncryptionField,
31  kDrmStreamLabelField,
32 };
33 
34 struct FieldNameToTypeMapping {
35  const char* field_name;
36  FieldType field_type;
37 };
38 
39 const FieldNameToTypeMapping kFieldNameTypeMappings[] = {
40  {"stream_selector", kStreamSelectorField},
41  {"stream", kStreamSelectorField},
42  {"input", kInputField},
43  {"in", 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},
62  {"drm_stream_label", kDrmStreamLabelField},
63  {"drm_label", kDrmStreamLabelField},
64 };
65 
66 FieldType GetFieldType(const std::string& field_name) {
67  for (size_t idx = 0; idx < arraysize(kFieldNameTypeMappings); ++idx) {
68  if (field_name == kFieldNameTypeMappings[idx].field_name)
69  return kFieldNameTypeMappings[idx].field_type;
70  }
71  return kUnknownField;
72 }
73 
74 } // anonymous namespace
75 
76 base::Optional<StreamDescriptor> ParseStreamDescriptor(
77  const std::string& descriptor_string) {
78  StreamDescriptor descriptor;
79 
80  // Split descriptor string into name/value pairs.
81  base::StringPairs pairs;
82  if (!base::SplitStringIntoKeyValuePairs(descriptor_string, '=', ',',
83  &pairs)) {
84  LOG(ERROR) << "Invalid stream descriptors name/value pairs.";
85  return base::nullopt;
86  }
87  for (base::StringPairs::const_iterator iter = pairs.begin();
88  iter != pairs.end(); ++iter) {
89  switch (GetFieldType(iter->first)) {
90  case kStreamSelectorField:
91  descriptor.stream_selector = iter->second;
92  break;
93  case kInputField:
94  descriptor.input = iter->second;
95  break;
96  case kOutputField:
97  descriptor.output = iter->second;
98  break;
99  case kSegmentTemplateField:
100  descriptor.segment_template = iter->second;
101  break;
102  case kBandwidthField: {
103  unsigned bw;
104  if (!base::StringToUint(iter->second, &bw)) {
105  LOG(ERROR) << "Non-numeric bandwidth specified.";
106  return base::nullopt;
107  }
108  descriptor.bandwidth = bw;
109  break;
110  }
111  case kLanguageField: {
112  descriptor.language = iter->second;
113  break;
114  }
115  case kOutputFormatField: {
116  descriptor.output_format = iter->second;
117  break;
118  }
119  case kHlsNameField: {
120  descriptor.hls_name = iter->second;
121  break;
122  }
123  case kHlsGroupIdField: {
124  descriptor.hls_group_id = iter->second;
125  break;
126  }
127  case kHlsPlaylistNameField: {
128  descriptor.hls_playlist_name = iter->second;
129  break;
130  }
131  case kTrickPlayFactorField: {
132  unsigned factor;
133  if (!base::StringToUint(iter->second, &factor)) {
134  LOG(ERROR) << "Non-numeric trick play factor " << iter->second
135  << " specified.";
136  return base::nullopt;
137  }
138  if (factor == 0) {
139  LOG(ERROR) << "Stream trick_play_factor should be > 0.";
140  return base::nullopt;
141  }
142  descriptor.trick_play_factor = factor;
143  break;
144  }
145  case kSkipEncryptionField: {
146  unsigned skip_encryption_value;
147  if (!base::StringToUint(iter->second, &skip_encryption_value)) {
148  LOG(ERROR) << "Non-numeric option for skip encryption field "
149  "specified (" << iter->second << ").";
150  return base::nullopt;
151  }
152  if (skip_encryption_value > 1) {
153  LOG(ERROR) << "skip_encryption should be either 0 or 1.";
154  return base::nullopt;
155  }
156 
157  descriptor.skip_encryption = skip_encryption_value > 0;
158  break;
159  }
160  case kDrmStreamLabelField: {
161  descriptor.drm_label = iter->second;
162  break;
163  }
164  default:
165  LOG(ERROR) << "Unknown field in stream descriptor (\"" << iter->first
166  << "\").";
167  return base::nullopt;
168  }
169  }
170  return descriptor;
171 }
172 
173 } // namespace shaka
std::string stream_selector
Definition: packager.h:75
Defines a single input/output stream.
Definition: packager.h:69
std::string input
Input/source media file path or network stream URL. Required.
Definition: packager.h:71
std::string hls_playlist_name
Definition: packager.h:114
std::string hls_name
Definition: packager.h:108
base::Optional< StreamDescriptor > ParseStreamDescriptor(const std::string &descriptor_string)
std::string segment_template
Specifies segment template. Can be empty.
Definition: packager.h:81
std::string output_format
Definition: packager.h:85
std::string drm_label
Definition: packager.h:93
uint32_t trick_play_factor
Definition: packager.h:97
std::string output
Definition: packager.h:79
std::string language
Definition: packager.h:104
std::string hls_group_id
Definition: packager.h:111