15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifndef MEDIA_FORMATS_WEBM_WEBM_CLUSTER_PARSER_H_
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define MEDIA_FORMATS_WEBM_WEBM_CLUSTER_PARSER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <map>
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <set>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/media_export.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/media_log.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/base/stream_parser.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/stream_parser_buffer.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/webm/webm_parser.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/webm/webm_tracks_parser.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MEDIA_EXPORT WebMClusterParser : public WebMParserClient {
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef StreamParser::TrackId TrackId;
265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue;
275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  typedef std::map<TrackId, const BufferQueue> TextBufferQueueMap;
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Arbitrarily-chosen numbers to estimate the duration of a buffer if none is
300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // set and there is not enough information to get a better estimate.
310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // TODO(wolenetz/acolwell): Parse audio codebook to determine missing audio
320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // frame durations. See http://crbug.com/351166.
330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  enum {
340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    kDefaultAudioBufferDurationInMs = 23,  // Common 1k samples @44.1kHz
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    kDefaultVideoBufferDurationInMs = 42  // Low 24fps to reduce stalls
360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Helper class that manages per-track state.
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class Track {
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   public:
425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    Track(int track_num,
435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          bool is_video,
445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          base::TimeDelta default_duration,
455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          const LogCB& log_cb);
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ~Track();
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int track_num() const { return track_num_; }
495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // If a buffer is currently held aside pending duration calculation, returns
515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // its decode timestamp. Otherwise, returns kInfiniteDuration().
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    DecodeTimestamp GetReadyUpperBound();
535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Prepares |ready_buffers_| for retrieval. Prior to calling,
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // |ready_buffers_| must be empty. Moves all |buffers_| with decode
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // timestamp before |before_timestamp| to |ready_buffers_|, preserving their
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // order.
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    void ExtractReadyBuffers(const DecodeTimestamp before_timestamp);
595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const BufferQueue& ready_buffers() const { return ready_buffers_; }
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // If |last_added_buffer_missing_duration_| is set, updates its duration
63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // relative to |buffer|'s timestamp, and adds it to |buffers_| and unsets
64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // |last_added_buffer_missing_duration_|. Then, if |buffer| is missing
65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // duration, saves |buffer| into |last_added_buffer_missing_duration_|, or
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // otherwise adds |buffer| to |buffers_|.
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool AddBuffer(const scoped_refptr<StreamParserBuffer>& buffer);
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // If |last_added_buffer_missing_duration_| is set, updates its duration to
70a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // be non-kNoTimestamp() value of |estimated_next_frame_duration_| or an
71a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // arbitrary default, then adds it to |buffers_| and unsets
72a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // |last_added_buffer_missing_duration_|. (This method helps stream parser
73a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // emit all buffers in a media segment before signaling end of segment.)
74a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    void ApplyDurationEstimateIfNeeded();
75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Clears |ready_buffers_| (use ExtractReadyBuffers() to fill it again).
775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Leaves as-is |buffers_| and any possibly held-aside buffer that is
78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // missing duration.
795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    void ClearReadyBuffers();
80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Clears all buffer state, including any possibly held-aside buffer that
825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // was missing duration, and all contents of |buffers_| and
835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // |ready_buffers_|.
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    void Reset();
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Helper function used to inspect block data to determine if the
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // block is a keyframe.
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // |data| contains the bytes in the block.
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // |size| indicates the number of bytes in |data|.
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool IsKeyframe(const uint8* data, int size) const;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    base::TimeDelta default_duration() const { return default_duration_; }
93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   private:
95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Helper that sanity-checks |buffer| duration, updates
96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // |estimated_next_frame_duration_|, and adds |buffer| to |buffers_|.
97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Returns false if |buffer| failed sanity check and therefore was not added
98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // to |buffers_|. Returns true otherwise.
99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    bool QueueBuffer(const scoped_refptr<StreamParserBuffer>& buffer);
100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // Helper that calculates the buffer duration to use in
102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // ApplyDurationEstimateIfNeeded().
103a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    base::TimeDelta GetDurationEstimate();
104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int track_num_;
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool is_video_;
1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Parsed track buffers, each with duration and in (decode) timestamp order,
1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // that have not yet been extracted into |ready_buffers_|. Note that up to
1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // one additional buffer missing duration may be tracked by
1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // |last_added_buffer_missing_duration_|.
1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    BufferQueue buffers_;
113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    scoped_refptr<StreamParserBuffer> last_added_buffer_missing_duration_;
114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Buffers in (decode) timestamp order that were previously parsed into and
1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // extracted from |buffers_|. Buffers are moved from |buffers_| to
1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // |ready_buffers_| by ExtractReadyBuffers() if they are below a specified
1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // upper bound timestamp. Track users can therefore extract only those
1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // parsed buffers which are "ready" for emission (all before some maximum
1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // timestamp).
1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    BufferQueue ready_buffers_;
1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // If kNoTimestamp(), then |estimated_next_frame_duration_| will be used.
124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    base::TimeDelta default_duration_;
1255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // If kNoTimestamp(), then a default value will be used. This estimate is
127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // the maximum duration seen or derived so far for this track, and is valid
128effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // only if |default_duration_| is kNoTimestamp().
129effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    base::TimeDelta estimated_next_frame_duration_;
1305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    LogCB log_cb_;
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef std::map<int, Track> TextTrackMap;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebMClusterParser(int64 timecode_scale,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int audio_track_num,
139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                    base::TimeDelta audio_default_duration,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int video_track_num,
141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                    base::TimeDelta video_default_duration,
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                    const WebMTracksParser::TextTracks& text_tracks,
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const std::set<int64>& ignored_tracks,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const std::string& audio_encryption_key_id,
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const std::string& video_encryption_key_id,
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const LogCB& log_cb);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~WebMClusterParser();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Resets the parser state so it can accept a new cluster.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Reset();
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parses a WebM cluster element in |buf|.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns -1 if the parse fails.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns 0 if more data is needed.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the number of bytes parsed on success.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int Parse(const uint8* buf, int size);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta cluster_start_time() const { return cluster_start_time_; }
160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Get the current ready buffers resulting from Parse().
162effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // If the parse reached the end of cluster and the last buffer was held aside
163effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // due to missing duration, the buffer is given an estimated duration and
164effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // included in the result.
1655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Otherwise, if there are is a buffer held aside due to missing duration for
1665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // any of the tracks, no buffers with same or greater (decode) timestamp will
1675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // be included in the buffers.
1685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // The returned deques are cleared by Parse() or Reset() and updated by the
1695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // next calls to Get{Audio,Video}Buffers().
1705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // If no Parse() or Reset() has occurred since the last call to Get{Audio,
1715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Video,Text}Buffers(), then the previous BufferQueue& is returned again
1725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // without any recalculation.
173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const BufferQueue& GetAudioBuffers();
174effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const BufferQueue& GetVideoBuffers();
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Constructs and returns a subset of |text_track_map_| containing only
1775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // tracks with non-empty buffer queues produced by the last Parse() and
1785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // filtered to exclude any buffers that have (decode) timestamp same or
1795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // greater than the lowest (decode) timestamp across all tracks of any buffer
1805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // held aside due to missing duration (unless the end of cluster has been
1815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // reached).
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The returned map is cleared by Parse() or Reset() and updated by the next
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // call to GetTextBuffers().
1845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // If no Parse() or Reset() has occurred since the last call to
1855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // GetTextBuffers(), then the previous TextBufferQueueMap& is returned again
1865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // without any recalculation.
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const TextBufferQueueMap& GetTextBuffers();
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the last Parse() call stopped at the end of a cluster.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool cluster_ended() const { return cluster_ended_; }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebMParserClient methods.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual WebMParserClient* OnListStart(int id) OVERRIDE;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnListEnd(int id) OVERRIDE;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnUInt(int id, int64 val) OVERRIDE;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnBinary(int id, const uint8* data, int size) OVERRIDE;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool ParseBlock(bool is_simple_block, const uint8* buf, int size,
20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  const uint8* additional, int additional_size, int duration,
20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                  int64 discard_padding);
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool OnBlock(bool is_simple_block, int track_num, int timecode, int duration,
20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)               int flags, const uint8* data, int size,
20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)               const uint8* additional, int additional_size,
20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)               int64 discard_padding);
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Resets the Track objects associated with each text track.
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ResetTextTracks();
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Clears the the ready buffers associated with each text track.
2115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void ClearTextTrackReadyBuffers();
2125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Helper method for Get{Audio,Video,Text}Buffers() that recomputes
2145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // |ready_buffer_upper_bound_| and calls ExtractReadyBuffers() on each track.
2155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // If |cluster_ended_| is true, first applies duration estimate if needed for
2165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // |audio_| and |video_| and sets |ready_buffer_upper_bound_| to
2175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // kInfiniteDuration(). Otherwise, sets |ready_buffer_upper_bound_| to the
2185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // minimum upper bound across |audio_| and |video_|. (Text tracks can have no
2195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // buffers missing duration, so they are not involved in calculating the upper
2205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // bound.)
2215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Parse() or Reset() must be called between calls to UpdateReadyBuffers() to
2225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // clear each track's ready buffers and to reset |ready_buffer_upper_bound_|
2236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // to kNoDecodeTimestamp().
2245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void UpdateReadyBuffers();
2255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Search for the indicated track_num among the text tracks.  Returns NULL
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // if that track num is not a text track.
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Track* FindTextTrack(int track_num);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  double timecode_multiplier_;  // Multiplier used to convert timecodes into
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                // microseconds.
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<int64> ignored_tracks_;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string audio_encryption_key_id_;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string video_encryption_key_id_;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebMListParser parser_;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 last_block_timecode_;
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<uint8[]> block_data_;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int block_data_size_;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 block_duration_;
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int64 block_add_id_;
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<uint8[]> block_additional_data_;
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int block_additional_data_size_;
24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int64 discard_padding_;
24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool discard_padding_set_;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 cluster_timecode_;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeDelta cluster_start_time_;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool cluster_ended_;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Track audio_;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Track video_;
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TextTrackMap text_track_map_;
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Subset of |text_track_map_| maintained by GetTextBuffers(), and cleared by
2575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // ClearTextTrackReadyBuffers(). Callers of GetTextBuffers() get a const-ref
2585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // to this member.
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TextBufferQueueMap text_buffers_map_;
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Limits the range of buffers returned by Get{Audio,Video,Text}Buffers() to
2626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // this exclusive upper bound. Set to kNoDecodeTimestamp(), meaning not yet
2636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // calculated, by Reset() and Parse(). If kNoDecodeTimestamp(), then
2645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Get{Audio,Video,Text}Buffers() will calculate it to be the minimum (decode)
2655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // timestamp across all tracks' |last_buffer_missing_duration_|, or
2665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // kInfiniteDuration() if no buffers are currently missing duration.
2676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DecodeTimestamp ready_buffer_upper_bound_;
2685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LogCB log_cb_;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_IMPLICIT_CONSTRUCTORS(WebMClusterParser);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // MEDIA_FORMATS_WEBM_WEBM_CLUSTER_PARSER_H_
277