Shaka Packager SDK
wvm_media_parser.h
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 // Media parser for a Widevine Media Format (WVM) file.
5 
6 #ifndef PACKAGER_MEDIA_FORMATS_WVM_WVM_MEDIA_PARSER_H_
7 #define PACKAGER_MEDIA_FORMATS_WVM_WVM_MEDIA_PARSER_H_
8 
9 #include <deque>
10 #include <map>
11 #include <memory>
12 #include <string>
13 #include <vector>
14 
15 #include "packager/base/compiler_specific.h"
16 #include "packager/media/base/media_parser.h"
17 #include "packager/media/base/network_util.h"
18 #include "packager/media/codecs/h264_byte_to_unit_stream_converter.h"
19 
20 namespace shaka {
21 namespace media {
22 
23 class AesCbcDecryptor;
24 class KeySource;
25 struct EncryptionKey;
26 
27 namespace wvm {
28 
30  public:
33  uint32_t demux_stream_id;
34  uint32_t parsed_audio_or_video_stream_id;
35  std::shared_ptr<MediaSample> media_sample;
36 };
37 
39  public:
41  ~PrevSampleData();
42  void Reset();
43  std::shared_ptr<MediaSample> audio_sample;
44  std::shared_ptr<MediaSample> video_sample;
45  uint32_t audio_stream_id;
46  uint32_t video_stream_id;
47  int64_t audio_sample_duration;
48  int64_t video_sample_duration;
49 };
50 
51 class WvmMediaParser : public MediaParser {
52  public:
54  ~WvmMediaParser() override;
55 
58  void Init(const InitCB& init_cb,
59  const NewSampleCB& new_sample_cb,
60  KeySource* decryption_key_source) override;
61  bool Flush() override WARN_UNUSED_RESULT;
62  bool Parse(const uint8_t* buf, int size) override WARN_UNUSED_RESULT;
64 
65  private:
66  enum Tag {
67  CypherVersion = 0,
68  TrackOffset = 1,
69  TrackSize = 2,
70  TrackDuration = 3,
71  TrackBitRate = 4,
72  TrackTrickPlayFactor = 5,
73  TrackAdaptationInterval = 6,
74  TrackFlags = 7,
75  VideoType = 8,
76  VideoProfile = 9,
77  VideoLevel = 10,
78  VideoWidth = 11,
79  VideoHeight = 12,
80  VideoTicksPerFrame = 13,
81  VideoBitRate = 14,
82  AudioType = 15,
83  AudioProfile = 16,
84  AudioNumChannels = 17,
85  AudioSampleFrequency = 18,
86  AudioBitRate = 19,
87  TrackVersion = 20,
88  Title = 21,
89  Copyright = 22,
90  ChapterIndex = 23,
91  TimeIndex = 24,
92  Thumbnail = 25,
93  ObjectSeqNum = 26,
94  ThumbnailOffset = 27,
95  ThumbnailSize = 28,
96  NumEntries = 29,
97  Chapters = 30,
98  VideoPixelWidth = 31,
99  VideoPixelHeight = 32,
100  FileSize = 33,
101  SparseDownloadUrl = 34,
102  SparseDownloadRangeTranslations = 35,
103  SparseDownloadMap = 36,
104  AudioSampleSize = 37,
105  Audio_EsDescriptor = 38,
106  Video_AVCDecoderConfigurationRecord = 39,
107  Audio_EC3SpecificData = 40,
108  AudioIdentifier = 41,
109  VideoStreamId = 42,
110  VideoStreamType = 43,
111  AudioStreamId = 44,
112  AudioStreamType = 45,
113  Audio_DtsSpecificData = 46,
114  Audio_AC3SpecificData = 47,
115  Unset = 48
116  };
117 
118  enum State {
119  StartCode1 = 0,
120  StartCode2,
121  StartCode3,
122  StartCode4,
123  PackHeader1,
124  PackHeader2,
125  PackHeader3,
126  PackHeader4,
127  PackHeader5,
128  PackHeader6,
129  PackHeader7,
130  PackHeader8,
131  PackHeader9,
132  PackHeader10,
133  PackHeaderStuffingSkip,
134  SystemHeader1,
135  SystemHeader2,
136  SystemHeaderSkip,
137  PesStreamId,
138  PesPacketLength1,
139  PesPacketLength2,
140  PesExtension1,
141  PesExtension2,
142  PesExtension3,
143  Pts1,
144  Pts2,
145  Pts3,
146  Pts4,
147  Pts5,
148  Dts1,
149  Dts2,
150  Dts3,
151  Dts4,
152  Dts5,
153  PesHeaderData,
154  PesPayload,
155  EsPayload,
156  PsmPayload,
157  EcmPayload,
158  IndexPayload,
159  Padding,
160  ProgramEnd
161  };
162 
163  bool ProcessEcm();
164 
165  // Index denotes 'search index' in the WVM content.
166  bool ParseIndexEntry();
167 
168  bool DemuxNextPes(bool is_program_end);
169 
170  void StartMediaSampleDemux();
171 
172  template <typename T>
173  Tag GetTag(const uint8_t& tag,
174  const uint32_t& length,
175  const uint8_t* start_index,
176  T* value) {
177  if (length == sizeof(uint8_t)) {
178  *value = (uint8_t)(*start_index);
179  } else if (length == sizeof(int8_t)) {
180  *value = (int8_t)(*start_index);
181  } else if (length == sizeof(uint16_t)) {
182  *value = (uint16_t)(ntohsFromBuffer(start_index));
183  } else if (length == sizeof(int16_t)) {
184  *value = (int16_t)(ntohsFromBuffer(start_index));
185  } else if (length == sizeof(uint32_t)) {
186  *value = (uint32_t)(ntohlFromBuffer(start_index));
187  } else if (length == sizeof(int32_t)) {
188  *value = (int32_t)(ntohlFromBuffer(start_index));
189  } else if (length == sizeof(uint64_t)) {
190  *value = (uint64_t)(ntohllFromBuffer(start_index));
191  } else if (length == sizeof(int64_t)) {
192  *value = (int64_t)(ntohllFromBuffer(start_index));
193  } else {
194  *value = 0;
195  }
196  return Tag(tag);
197  }
198 
199  // |must_process_encrypted| setting determines if Output() should attempt
200  // to ouput media sample as encrypted.
201  bool Output(bool must_process_encrypted);
202 
203  bool GetAssetKey(const uint8_t* asset_id, EncryptionKey* encryption_key);
204 
205  // Callback invoked by the ES media parser
206  // to emit a new audio/video access unit.
207  bool EmitSample(uint32_t parsed_audio_or_video_stream_id,
208  uint32_t stream_id,
209  const std::shared_ptr<MediaSample>& new_sample,
210  bool isLastSample);
211 
212  bool EmitPendingSamples();
213 
214  bool EmitLastSample(uint32_t stream_id,
215  const std::shared_ptr<MediaSample>& new_sample);
216 
217  // List of callbacks.t
218  InitCB init_cb_;
219  NewSampleCB new_sample_cb_;
220 
221  // Whether |init_cb_| has been invoked.
222  bool is_initialized_;
223  // Internal content parsing state.
224  State parse_state_;
225 
226  uint32_t skip_bytes_;
227  bool metadata_is_complete_;
228  uint8_t current_program_id_;
229  uint32_t pes_stream_id_;
230  uint32_t prev_pes_stream_id_;
231  size_t pes_packet_bytes_;
232  uint8_t pes_flags_1_;
233  uint8_t pes_flags_2_;
234  uint8_t prev_pes_flags_1_;
235  size_t pes_header_data_bytes_;
236  uint64_t timestamp_;
237  uint64_t pts_;
238  uint64_t dts_;
239  uint8_t index_program_id_;
240  std::shared_ptr<MediaSample> media_sample_;
241  size_t crypto_unit_start_pos_;
242  PrevSampleData prev_media_sample_data_;
243  H264ByteToUnitStreamConverter byte_to_unit_stream_converter_;
244 
245  std::vector<uint8_t, std::allocator<uint8_t>> ecm_;
246  std::vector<uint8_t> psm_data_;
247  std::vector<uint8_t> index_data_;
248  std::map<std::string, uint32_t> program_demux_stream_map_;
249  int stream_id_count_;
250  std::vector<std::shared_ptr<StreamInfo>> stream_infos_;
251  std::deque<DemuxStreamIdMediaSample> media_sample_queue_;
252  std::vector<uint8_t> sample_data_;
253  KeySource* decryption_key_source_;
254  std::unique_ptr<AesCbcDecryptor> content_decryptor_;
255 
256  DISALLOW_COPY_AND_ASSIGN(WvmMediaParser);
257 };
258 
259 } // namespace wvm
260 } // namespace media
261 } // namespace shaka
262 
263 #endif // PACKAGER_MEDIA_FORMATS_WVM_WVM_MEDIA_PARSER_H_
All the methods that are virtual are virtual for mocking.
KeySource is responsible for encryption key acquisition.
Definition: key_source.h:50