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