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