DASH Media Packaging SDK
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator
packager_util.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/packager_util.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 #include "packager/file/file.h"
13 #include "packager/media/base/fixed_key_source.h"
14 #include "packager/media/base/media_handler.h"
15 #include "packager/media/base/muxer_options.h"
16 #include "packager/media/base/playready_key_source.h"
17 #include "packager/media/base/request_signer.h"
18 #include "packager/media/base/widevine_key_source.h"
19 #include "packager/media/chunking/chunking_handler.h"
20 #include "packager/media/crypto/encryption_handler.h"
21 #include "packager/mpd/base/mpd_options.h"
22 #include "packager/packager.h"
23 #include "packager/status.h"
24 
25 namespace shaka {
26 namespace media {
27 namespace {
28 
29 FourCC GetProtectionScheme(const std::string& protection_scheme) {
30  if (protection_scheme == "cenc") {
31  return FOURCC_cenc;
32  } else if (protection_scheme == "cens") {
33  return FOURCC_cens;
34  } else if (protection_scheme == "cbc1") {
35  return FOURCC_cbc1;
36  } else if (protection_scheme == "cbcs") {
37  return FOURCC_cbcs;
38  } else {
39  LOG(ERROR) << "Unknown protection scheme: " << protection_scheme;
40  return FOURCC_NULL;
41  }
42 }
43 
44 } // namespace
45 
46 std::unique_ptr<RequestSigner> CreateSigner(const WidevineSigner& signer) {
47  std::unique_ptr<RequestSigner> request_signer;
48  switch (signer.signing_key_type) {
49  case WidevineSigner::SigningKeyType::kAes:
50  request_signer.reset(AesRequestSigner::CreateSigner(
51  signer.signer_name, signer.aes.key, signer.aes.iv));
52  break;
53  case WidevineSigner::SigningKeyType::kRsa:
54  request_signer.reset(
55  RsaRequestSigner::CreateSigner(signer.signer_name, signer.rsa.key));
56  break;
57  case WidevineSigner::SigningKeyType::kNone:
58  break;
59  }
60  if (!request_signer)
61  LOG(ERROR) << "Failed to create the signer object.";
62  return request_signer;
63 }
64 
65 std::unique_ptr<KeySource> CreateEncryptionKeySource(
66  FourCC protection_scheme,
67  const EncryptionParams& encryption_params) {
68  std::unique_ptr<KeySource> encryption_key_source;
69  switch (encryption_params.key_provider) {
70  case KeyProvider::kWidevine: {
71  const WidevineEncryptionParams& widevine = encryption_params.widevine;
72  if (widevine.key_server_url.empty()) {
73  LOG(ERROR) << "'key_server_url' should not be empty.";
74  return std::unique_ptr<KeySource>();
75  }
76  if (widevine.content_id.empty()) {
77  LOG(ERROR) << "'content_id' should not be empty.";
78  return std::unique_ptr<KeySource>();
79  }
80  std::unique_ptr<WidevineKeySource> widevine_key_source(
81  new WidevineKeySource(widevine.key_server_url,
82  widevine.include_common_pssh));
83  widevine_key_source->set_protection_scheme(protection_scheme);
84  if (!widevine.signer.signer_name.empty()) {
85  std::unique_ptr<RequestSigner> request_signer(
86  CreateSigner(widevine.signer));
87  if (!request_signer)
88  return std::unique_ptr<KeySource>();
89  widevine_key_source->set_signer(std::move(request_signer));
90  }
91  widevine_key_source->set_group_id(widevine.group_id);
92 
93  Status status =
94  widevine_key_source->FetchKeys(widevine.content_id, widevine.policy);
95  if (!status.ok()) {
96  LOG(ERROR) << "Widevine encryption key source failed to fetch keys: "
97  << status.ToString();
98  return std::unique_ptr<KeySource>();
99  }
100  encryption_key_source = std::move(widevine_key_source);
101  break;
102  }
103  case KeyProvider::kRawKey: {
104  const RawKeyEncryptionParams& raw_key = encryption_params.raw_key;
105  const std::string kDefaultTrackType;
106  // TODO(kqyang): Refactor FixedKeySource.
107  encryption_key_source = FixedKeySource::Create(
108  raw_key.key_map.find("")->second.key_id,
109  raw_key.key_map.find("")->second.key, raw_key.pssh, raw_key.iv);
110  break;
111  }
112  case KeyProvider::kPlayready: {
113  const PlayreadyEncryptionParams& playready = encryption_params.playready;
114  if (!playready.key_id.empty() && !playready.key.empty()) {
115  encryption_key_source = PlayReadyKeySource::CreateFromKeyAndKeyId(
116  playready.key_id, playready.key);
117  } else if (!playready.key_server_url.empty() &&
118  !playready.program_identifier.empty()) {
119  std::unique_ptr<PlayReadyKeySource> playready_key_source;
120  if (!playready.client_cert_file.empty() &&
121  !playready.client_cert_private_key_file.empty() &&
122  !playready.client_cert_private_key_password.empty()) {
123  playready_key_source.reset(new PlayReadyKeySource(
124  playready.key_server_url, playready.client_cert_file,
125  playready.client_cert_private_key_file,
126  playready.client_cert_private_key_password));
127  } else {
128  playready_key_source.reset(
129  new PlayReadyKeySource(playready.key_server_url));
130  }
131  if (!playready.ca_file.empty()) {
132  playready_key_source->SetCaFile(playready.ca_file);
133  }
134  playready_key_source->FetchKeysWithProgramIdentifier(
135  playready.program_identifier);
136  encryption_key_source = std::move(playready_key_source);
137  } else {
138  LOG(ERROR) << "Error creating PlayReady key source.";
139  return std::unique_ptr<KeySource>();
140  }
141  break;
142  }
143  case KeyProvider::kNone:
144  break;
145  }
146  return encryption_key_source;
147 }
148 
149 std::unique_ptr<KeySource> CreateDecryptionKeySource(
150  const DecryptionParams& decryption_params) {
151  std::unique_ptr<KeySource> decryption_key_source;
152  switch (decryption_params.key_provider) {
153  case KeyProvider::kWidevine: {
154  const WidevineDecryptionParams& widevine = decryption_params.widevine;
155  if (widevine.key_server_url.empty()) {
156  LOG(ERROR) << "'key_server_url' should not be empty.";
157  return std::unique_ptr<KeySource>();
158  }
159  std::unique_ptr<WidevineKeySource> widevine_key_source(
160  new WidevineKeySource(widevine.key_server_url,
161  true /* commmon pssh, does not matter here */));
162  if (!widevine.signer.signer_name.empty()) {
163  std::unique_ptr<RequestSigner> request_signer(
164  CreateSigner(widevine.signer));
165  if (!request_signer)
166  return std::unique_ptr<KeySource>();
167  widevine_key_source->set_signer(std::move(request_signer));
168  }
169 
170  decryption_key_source = std::move(widevine_key_source);
171  break;
172  }
173  case KeyProvider::kRawKey: {
174  const RawKeyDecryptionParams& raw_key = decryption_params.raw_key;
175  const std::vector<uint8_t> kNoPssh;
176  const std::vector<uint8_t> kNoIv;
177  decryption_key_source = FixedKeySource::Create(
178  raw_key.key_map.find("")->second.key_id,
179  raw_key.key_map.find("")->second.key, kNoPssh, kNoIv);
180  break;
181  }
182  case KeyProvider::kNone:
183  case KeyProvider::kPlayready:
184  break;
185  }
186  return decryption_key_source;
187 }
188 
189 ChunkingOptions GetChunkingOptions(const ChunkingParams& chunking_params) {
190  ChunkingOptions chunking_options;
191  chunking_options.segment_duration_in_seconds =
192  chunking_params.segment_duration_in_seconds;
193  chunking_options.subsegment_duration_in_seconds =
194  chunking_params.subsegment_duration_in_seconds;
195  chunking_options.segment_sap_aligned = chunking_params.segment_sap_aligned;
196  chunking_options.subsegment_sap_aligned =
197  chunking_params.subsegment_sap_aligned;
198  return chunking_options;
199 }
200 
201 EncryptionOptions GetEncryptionOptions(
202  const EncryptionParams& encryption_params) {
203  EncryptionOptions encryption_options;
204  encryption_options.clear_lead_in_seconds =
205  encryption_params.clear_lead_in_seconds;
206  encryption_options.protection_scheme =
207  GetProtectionScheme(encryption_params.protection_scheme);
208  encryption_options.crypto_period_duration_in_seconds =
209  encryption_params.crypto_period_duration_in_seconds;
210  encryption_options.vp9_subsample_encryption =
211  encryption_params.vp9_subsample_encryption;
212  encryption_options.stream_label_func = encryption_params.stream_label_func;
213  return encryption_options;
214 }
215 
216 MuxerOptions GetMuxerOptions(const std::string& temp_dir,
217  const Mp4OutputParams& mp4_params) {
218  MuxerOptions muxer_options;
219  muxer_options.num_subsegments_per_sidx = mp4_params.num_subsegments_per_sidx;
220  muxer_options.mp4_include_pssh_in_stream = mp4_params.include_pssh_in_stream;
221  muxer_options.mp4_use_decoding_timestamp_in_timeline =
222  mp4_params.use_decoding_timestamp_in_timeline;
223  muxer_options.temp_dir = temp_dir;
224  return muxer_options;
225 }
226 
227 MpdOptions GetMpdOptions(bool on_demand_profile, const MpdParams& mpd_params) {
228  MpdOptions mpd_options;
229  mpd_options.dash_profile =
230  on_demand_profile ? DashProfile::kOnDemand : DashProfile::kLive;
231  mpd_options.mpd_type =
232  (on_demand_profile || mpd_params.generate_static_live_mpd)
233  ? MpdType::kStatic
234  : MpdType::kDynamic;
235  mpd_options.minimum_update_period = mpd_params.minimum_update_period;
236  mpd_options.min_buffer_time = mpd_params.min_buffer_time;
237  mpd_options.time_shift_buffer_depth = mpd_params.time_shift_buffer_depth;
238  mpd_options.suggested_presentation_delay =
239  mpd_params.suggested_presentation_delay;
240  mpd_options.default_language = mpd_params.default_language;
241  return mpd_options;
242 }
243 
244 Status ConnectHandlers(std::vector<std::shared_ptr<MediaHandler>>& handlers) {
245  size_t num_handlers = handlers.size();
246  Status status;
247  for (size_t i = 1; i < num_handlers; ++i) {
248  status.Update(handlers[i - 1]->AddHandler(handlers[i]));
249  }
250  return status;
251 }
252 
253 } // namespace media
254 } // namespace shaka
static RsaRequestSigner * CreateSigner(const std::string &signer_name, const std::string &pkcs1_rsa_key)
static AesRequestSigner * CreateSigner(const std::string &signer_name, const std::vector< uint8_t > &aes_key, const std::vector< uint8_t > &iv)
void SetCaFile(const std::string &ca_file)
Sets the Certificate Authority file for validating self-signed certificates.
double clear_lead_in_seconds
Clear lead duration in seconds.
double segment_duration_in_seconds
Segment duration in seconds.
static std::unique_ptr< FixedKeySource > Create(const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &key, const std::vector< uint8_t > &pssh_boxes, const std::vector< uint8_t > &iv)
static std::unique_ptr< PlayReadyKeySource > CreateFromKeyAndKeyId(const std::vector< uint8_t > &key_id, const std::vector< uint8_t > &key)