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/media_parser.h"
15 #include "packager/media/base/media_sample.h"
16 #include "packager/media/formats/webm/webm_parser.h"
17 #include "packager/media/formats/webm/webm_tracks_parser.h"
18 
19 namespace edash_packager {
20 namespace media {
21 
23  public:
26  enum {
29 
33  };
34 
39  static const uint16_t kOpusFrameDurationsMu[];
40 
41  private:
42  // Helper class that manages per-track state.
43  class Track {
44  public:
45  Track(int track_num,
46  bool is_video,
47  int64_t default_duration,
48  const MediaParser::NewSampleCB& new_sample_cb);
49  ~Track();
50 
51  int track_num() const { return track_num_; }
52 
53  // If |last_added_buffer_missing_duration_| is set, updates its duration
54  // relative to |buffer|'s timestamp, and emits it and unsets
55  // |last_added_buffer_missing_duration_|. Otherwise, if |buffer| is missing
56  // duration, saves |buffer| into |last_added_buffer_missing_duration_|.
57  bool EmitBuffer(const scoped_refptr<MediaSample>& buffer);
58 
59  // If |last_added_buffer_missing_duration_| is set, updates its duration to
60  // be non-kNoTimestamp value of |estimated_next_frame_duration_| or a
61  // hard-coded default, then emits it and unsets
62  // |last_added_buffer_missing_duration_|. (This method helps stream parser
63  // emit all buffers in a media segment before signaling end of segment.)
64  void ApplyDurationEstimateIfNeeded();
65 
66  // Clears all buffer state, including any possibly held-aside buffer that
67  // was missing duration.
68  void Reset();
69 
70  // Helper function used to inspect block data to determine if the
71  // block is a keyframe.
72  // |data| contains the bytes in the block.
73  // |size| indicates the number of bytes in |data|.
74  bool IsKeyframe(const uint8_t* data, int size) const;
75 
76  int64_t default_duration() const { return default_duration_; }
77 
78  private:
79  // Helper that sanity-checks |buffer| duration, updates
80  // |estimated_next_frame_duration_|, and emits |buffer|.
81  // Returns false if |buffer| failed sanity check and therefore was not
82  // emitted. Returns true otherwise.
83  bool EmitBufferHelp(const scoped_refptr<MediaSample>& buffer);
84 
85  // Helper that calculates the buffer duration to use in
86  // ApplyDurationEstimateIfNeeded().
87  int64_t GetDurationEstimate();
88 
89  // Counts the number of estimated durations used in this track. Used to
90  // prevent log spam for LOG()s about estimated duration.
91  int num_duration_estimates_ = 0;
92 
93  int track_num_;
94  bool is_video_;
95 
96  // Parsed track buffers, each with duration and in (decode) timestamp order,
97  // that have not yet been emitted. Note that up to one additional buffer
98  // missing duration may be tracked by |last_added_buffer_missing_duration_|.
99  scoped_refptr<MediaSample> last_added_buffer_missing_duration_;
100 
101  // If kNoTimestamp, then |estimated_next_frame_duration_| will be used.
102  int64_t default_duration_;
103 
104  // If kNoTimestamp, then a default value will be used. This estimate is the
105  // maximum (for video), or minimum (for audio) duration seen so far for this
106  // track, and is used only if |default_duration_| is kNoTimestamp.
107  // TODO: Use maximum for audio too, adding checks to disable splicing when
108  // these estimates are observed in SourceBufferStream.
109  int64_t estimated_next_frame_duration_;
110 
111  MediaParser::NewSampleCB new_sample_cb_;
112  };
113 
114  typedef std::map<int, Track> TextTrackMap;
115 
116  public:
117  WebMClusterParser(int64_t timecode_scale,
118  int audio_track_num,
119  int64_t audio_default_duration,
120  int video_track_num,
121  int64_t video_default_duration,
122  const WebMTracksParser::TextTracks& text_tracks,
123  const std::set<int64_t>& ignored_tracks,
124  const std::string& audio_encryption_key_id,
125  const std::string& video_encryption_key_id,
126  const AudioCodec audio_codec,
127  const MediaParser::NewSampleCB& new_sample_cb);
128  ~WebMClusterParser() override;
129 
131  void Reset();
132 
137  int Parse(const uint8_t* buf, int size);
138 
139  int64_t cluster_start_time() const { return cluster_start_time_; }
140 
142  bool cluster_ended() const { return cluster_ended_; }
143 
144  private:
145  // WebMParserClient methods.
146  WebMParserClient* OnListStart(int id) override;
147  bool OnListEnd(int id) override;
148  bool OnUInt(int id, int64_t val) override;
149  bool OnBinary(int id, const uint8_t* data, int size) override;
150 
151  bool ParseBlock(bool is_simple_block,
152  const uint8_t* buf,
153  int size,
154  const uint8_t* additional,
155  int additional_size,
156  int duration,
157  int64_t discard_padding);
158  bool OnBlock(bool is_simple_block,
159  int track_num,
160  int timecode,
161  int duration,
162  int flags,
163  const uint8_t* data,
164  int size,
165  const uint8_t* additional,
166  int additional_size,
167  int64_t discard_padding);
168 
169  // Resets the Track objects associated with each text track.
170  void ResetTextTracks();
171 
172  // Search for the indicated track_num among the text tracks. Returns NULL
173  // if that track num is not a text track.
174  Track* FindTextTrack(int track_num);
175 
176  // Attempts to read the duration from the encoded audio data, returning as
177  // kNoTimestamp if duration cannot be retrieved.
178  // Avoid calling if encrypted; may produce unexpected output. See
179  // implementation for supported codecs.
180  int64_t TryGetEncodedAudioDuration(const uint8_t* data, int size);
181 
182  // Reads Opus packet header to determine packet duration. Duration returned
183  // as kNoTimestamp upon failure to read duration from packet.
184  int64_t ReadOpusDuration(const uint8_t* data, int size);
185 
186  // Tracks the number of LOGs made in process of reading encoded duration.
187  // Useful to prevent log spam.
188  int num_duration_errors_ = 0;
189 
190  double timecode_multiplier_; // Multiplier used to convert timecodes into
191  // microseconds.
192  std::set<int64_t> ignored_tracks_;
193  std::string audio_encryption_key_id_;
194  std::string video_encryption_key_id_;
195  const AudioCodec audio_codec_;
196 
197  WebMListParser parser_;
198 
199  int64_t last_block_timecode_ = -1;
200  scoped_ptr<uint8_t[]> block_data_;
201  int block_data_size_ = -1;
202  int64_t block_duration_ = -1;
203  int64_t block_add_id_ = -1;
204 
205  scoped_ptr<uint8_t[]> block_additional_data_;
206  // Must be 0 if |block_additional_data_| is null. Must be > 0 if
207  // |block_additional_data_| is NOT null.
208  int block_additional_data_size_ = 0;
209 
210  int64_t discard_padding_ = -1;
211  bool discard_padding_set_ = false;
212 
213  int64_t cluster_timecode_ = -1;
214  int64_t cluster_start_time_;
215  bool cluster_ended_ = false;
216 
217  Track audio_;
218  Track video_;
219  TextTrackMap text_track_map_;
220 
221  DISALLOW_IMPLICIT_CONSTRUCTORS(WebMClusterParser);
222 };
223 
224 } // namespace media
225 } // namespace edash_packager
226 
227 #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