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