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