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