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 <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
21namespace shaka {
22namespace media {
23
24class AesCbcDecryptor;
25class KeySource;
26struct EncryptionKey;
27
28namespace 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:
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
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
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.