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