Shaka Packager SDK
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/base/compiler_specific.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 
21 namespace shaka {
22 namespace 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  bool Flush() WARN_UNUSED_RESULT;
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_;
194  VPCodecConfigurationRecord vp_config_;
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_
base::Callback< bool(uint32_t track_id, std::shared_ptr< MediaSample > media_sample)> NewMediaSampleCB
Definition: media_parser.h:44
base::Callback< void(const std::vector< std::shared_ptr< StreamInfo > > &stream_info)> InitCB
Definition: media_parser.h:35
Class for parsing or writing VP codec configuration record.
@ kDefaultAudioBufferDurationInMs
Common 1k samples @44.1kHz.
WebMClusterParser(int64_t timecode_scale, std::shared_ptr< AudioStreamInfo > audio_stream_info, std::shared_ptr< VideoStreamInfo > video_stream_info, const VPCodecConfigurationRecord &vp_config, int64_t audio_default_duration, int64_t video_default_duration, const WebMTracksParser::TextTracks &text_tracks, const std::set< int64_t > &ignored_tracks, const std::string &audio_encryption_key_id, const std::string &video_encryption_key_id, const MediaParser::NewMediaSampleCB &new_sample_cb, const MediaParser::InitCB &init_cb, KeySource *decryption_key_source)
int Parse(const uint8_t *buf, int size)
void Reset()
Resets the parser state so it can accept a new cluster.
bool Flush() WARN_UNUSED_RESULT
All the methods that are virtual are virtual for mocking.