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