Shaka Packager SDK
Loading...
Searching...
No Matches
webm_cluster_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
5#ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CLUSTER_PARSER_H_
6#define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CLUSTER_PARSER_H_
7
8#include <cstdint>
9#include <deque>
10#include <map>
11#include <memory>
12#include <set>
13#include <string>
14
15#include <packager/macros/classes.h>
16#include <packager/media/base/decryptor_source.h>
17#include <packager/media/base/media_parser.h>
18#include <packager/media/base/media_sample.h>
19#include <packager/media/formats/webm/webm_parser.h>
20#include <packager/media/formats/webm/webm_tracks_parser.h>
21
22namespace shaka {
23namespace media {
24
26 public:
29 enum {
32
36 };
37
38 private:
39 // Helper class that manages per-track state.
40 class Track {
41 public:
42 Track(int track_num,
43 bool is_video,
44 int64_t default_duration,
45 const MediaParser::NewMediaSampleCB& new_sample_cb);
46 ~Track();
47
48 int track_num() const { return track_num_; }
49
50 // If |last_added_buffer_missing_duration_| is set, updates its duration
51 // relative to |buffer|'s timestamp, and emits it and unsets
52 // |last_added_buffer_missing_duration_|. Otherwise, if |buffer| is missing
53 // duration, saves |buffer| into |last_added_buffer_missing_duration_|.
54 bool EmitBuffer(const std::shared_ptr<MediaSample>& buffer);
55
56 // If |last_added_buffer_missing_duration_| is set, estimate the duration
57 // for this buffer using helper function GetDurationEstimate() then emits it
58 // and unsets |last_added_buffer_missing_duration_| (This method helps
59 // stream parser emit all buffers in a media segment).
60 bool ApplyDurationEstimateIfNeeded();
61
62 // Clears all buffer state, including any possibly held-aside buffer that
63 // was missing duration.
64 void Reset();
65
66 private:
67 // Helper that sanity-checks |buffer| duration, updates
68 // |estimated_next_frame_duration_|, and emits |buffer|.
69 // Returns false if |buffer| failed sanity check and therefore was not
70 // emitted. Returns true otherwise.
71 bool EmitBufferHelp(const std::shared_ptr<MediaSample>& buffer);
72
73 // Helper function that calculates the buffer duration to use in
74 // ApplyDurationEstimateIfNeeded().
75 int64_t GetDurationEstimate();
76
77 int track_num_;
78 bool is_video_;
79
80 // Holding the sample that is missing duration. The duration will be
81 // computed from the difference in timestamp when next sample arrives; or
82 // estimated if it is the last sample in this track.
83 std::shared_ptr<MediaSample> last_added_buffer_missing_duration_;
84
85 // If kNoTimestamp, then |estimated_next_frame_duration_| will be used.
86 int64_t default_duration_;
87
88 // If kNoTimestamp, then a hardcoded default value will be used. This
89 // estimate is the maximum duration seen so far for this track, and is used
90 // only if |default_duration_| is kNoTimestamp.
91 int64_t estimated_next_frame_duration_;
92
93 MediaParser::NewMediaSampleCB new_sample_cb_;
94 };
95
96 typedef std::map<int, Track> TextTrackMap;
97
98 public:
123 WebMClusterParser(int64_t timecode_scale,
124 std::shared_ptr<AudioStreamInfo> audio_stream_info,
125 std::shared_ptr<VideoStreamInfo> video_stream_info,
126 const VPCodecConfigurationRecord& vp_config,
127 int64_t audio_default_duration,
128 int64_t video_default_duration,
129 const WebMTracksParser::TextTracks& text_tracks,
130 const std::set<int64_t>& ignored_tracks,
131 const std::string& audio_encryption_key_id,
132 const std::string& video_encryption_key_id,
133 const MediaParser::NewMediaSampleCB& new_sample_cb,
134 const MediaParser::InitCB& init_cb,
135 KeySource* decryption_key_source);
136 ~WebMClusterParser() override;
137
139 void Reset();
140
144 [[nodiscard]] bool Flush();
145
150 int Parse(const uint8_t* buf, int size);
151
152 int64_t cluster_start_time() const { return cluster_start_time_; }
153
155 bool cluster_ended() const { return cluster_ended_; }
156
157 private:
158 // WebMParserClient methods.
159 WebMParserClient* OnListStart(int id) override;
160 bool OnListEnd(int id) override;
161 bool OnUInt(int id, int64_t val) override;
162 bool OnBinary(int id, const uint8_t* data, int size) override;
163
164 bool ParseBlock(bool is_simple_block,
165 const uint8_t* buf,
166 int size,
167 const uint8_t* additional,
168 int additional_size,
169 int duration,
170 int64_t discard_padding,
171 bool reference_block_set);
172 bool OnBlock(bool is_simple_block,
173 int track_num,
174 int timecode,
175 int duration,
176 const uint8_t* data,
177 int size,
178 const uint8_t* additional,
179 int additional_size,
180 int64_t discard_padding,
181 bool is_key_frame);
182
183 // Resets the Track objects associated with each text track.
184 void ResetTextTracks();
185
186 // Search for the indicated track_num among the text tracks. Returns NULL
187 // if that track num is not a text track.
188 Track* FindTextTrack(int track_num);
189
190 // Multiplier used to convert timecodes into microseconds.
191 double timecode_multiplier_;
192
193 std::shared_ptr<AudioStreamInfo> audio_stream_info_;
194 std::shared_ptr<VideoStreamInfo> video_stream_info_;
196 std::set<int64_t> ignored_tracks_;
197
198 std::unique_ptr<DecryptorSource> decryptor_source_;
199 std::string audio_encryption_key_id_;
200 std::string video_encryption_key_id_;
201
202 WebMListParser parser_;
203
204 // Indicates whether init_cb has been executed. |init_cb| is executed when we
205 // have codec configuration of video stream, which is extracted from the first
206 // video sample.
207 bool initialized_;
208 MediaParser::InitCB init_cb_;
209
210 int64_t last_block_timecode_ = -1;
211 std::unique_ptr<uint8_t[]> block_data_;
212 int block_data_size_ = -1;
213 int64_t block_duration_ = -1;
214 int64_t block_add_id_ = -1;
215
216 std::unique_ptr<uint8_t[]> block_additional_data_;
217 // Must be 0 if |block_additional_data_| is null. Must be > 0 if
218 // |block_additional_data_| is NOT null.
219 int block_additional_data_size_ = 0;
220
221 int64_t discard_padding_ = -1;
222 bool discard_padding_set_ = false;
223
224 bool reference_block_set_ = false;
225
226 int64_t cluster_timecode_ = -1;
227 int64_t cluster_start_time_;
228 bool cluster_ended_ = false;
229
230 Track audio_;
231 Track video_;
232 TextTrackMap text_track_map_;
233
234 DISALLOW_COPY_AND_ASSIGN(WebMClusterParser);
235};
236
237} // namespace media
238} // namespace shaka
239
240#endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_CLUSTER_PARSER_H_
std::function< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
std::function< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
Class for parsing or writing VP codec configuration record.
@ kDefaultAudioBufferDurationInMs
Common 1k samples @44.1kHz.
int Parse(const uint8_t *buf, int size)
void Reset()
Resets the parser state so it can accept a new cluster.
All the methods that are virtual are virtual for mocking.