Index: media/formats/webm/webm_cluster_parser.h |
diff --git a/media/formats/webm/webm_cluster_parser.h b/media/formats/webm/webm_cluster_parser.h |
index add21f23f91d432a20efd47cc32bbaa1e8d8bfc1..ab1d4a11fb11505ba34f664b840bb998c17521ab 100644 |
--- a/media/formats/webm/webm_cluster_parser.h |
+++ b/media/formats/webm/webm_cluster_parser.h |
@@ -23,6 +23,8 @@ namespace media { |
class MEDIA_EXPORT WebMClusterParser : public WebMParserClient { |
public: |
typedef StreamParser::TrackId TrackId; |
+ typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; |
+ typedef std::map<TrackId, const BufferQueue> TextBufferQueueMap; |
// Arbitrarily-chosen numbers to estimate the duration of a buffer if none is |
// set and there is not enough information to get a better estimate. |
@@ -37,13 +39,24 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient { |
// Helper class that manages per-track state. |
class Track { |
public: |
- Track(int track_num, bool is_video, base::TimeDelta default_duration); |
+ Track(int track_num, |
+ bool is_video, |
+ base::TimeDelta default_duration, |
+ const LogCB& log_cb); |
~Track(); |
int track_num() const { return track_num_; } |
- const std::deque<scoped_refptr<StreamParserBuffer> >& buffers() const { |
- return buffers_; |
- } |
+ |
+ // If a buffer is currently held aside pending duration calculation, returns |
+ // its decode timestamp. Otherwise, returns kInfiniteDuration(). |
+ base::TimeDelta GetReadyUpperBound(); |
+ |
+ // Prepares |ready_buffers_| for retrieval. Prior to calling, |
+ // |ready_buffers_| must be empty. Moves all |buffers_| with timestamp |
+ // before |before_timestamp| to |ready_buffers_|, preserving their order. |
+ void ExtractReadyBuffers(const base::TimeDelta before_timestamp); |
+ |
+ const BufferQueue& ready_buffers() const { return ready_buffers_; } |
// If |last_added_buffer_missing_duration_| is set, updates its duration |
// relative to |buffer|'s timestamp, and adds it to |buffers_| and unsets |
@@ -59,12 +72,14 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient { |
// emit all buffers in a media segment before signaling end of segment.) |
void ApplyDurationEstimateIfNeeded(); |
- // Clears all buffer state, except a possibly held-aside buffer that is |
+ // Clears |ready_buffers_| (use ExtractReadyBuffers() to fill it again). |
+ // Leaves as-is |buffers_| and any possibly held-aside buffer that is |
// missing duration. |
- void ClearBuffersButKeepLastIfMissingDuration(); |
+ void ClearReadyBuffers(); |
// Clears all buffer state, including any possibly held-aside buffer that |
- // was missing duration. |
+ // was missing duration, and all contents of |buffers_| and |
+ // |ready_buffers_|. |
void Reset(); |
// Helper function used to inspect block data to determine if the |
@@ -87,27 +102,37 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient { |
base::TimeDelta GetDurationEstimate(); |
int track_num_; |
- std::deque<scoped_refptr<StreamParserBuffer> > buffers_; |
bool is_video_; |
+ |
+ // Parsed track buffers, each with duration and in (decode) timestamp order, |
+ // that have not yet been extracted into |ready_buffers_|. Note that up to |
+ // one additional buffer missing duration may be tracked by |
+ // |last_added_buffer_missing_duration_|. |
+ BufferQueue buffers_; |
scoped_refptr<StreamParserBuffer> last_added_buffer_missing_duration_; |
+ // Buffers in (decode) timestamp order that were previously parsed into and |
+ // extracted from |buffers_|. Buffers are moved from |buffers_| to |
+ // |ready_buffers_| by ExtractReadyBuffers() if they are below a specified |
+ // upper bound timestamp. Track users can therefore extract only those |
+ // parsed buffers which are "ready" for emission (all before some maximum |
+ // timestamp). |
+ BufferQueue ready_buffers_; |
+ |
// If kNoTimestamp(), then |estimated_next_frame_duration_| will be used. |
base::TimeDelta default_duration_; |
+ |
// If kNoTimestamp(), then a default value will be used. This estimate is |
// the maximum duration seen or derived so far for this track, and is valid |
// only if |default_duration_| is kNoTimestamp(). |
- // |
- // TODO(wolenetz): Add unittests for duration estimation and default |
- // duration handling. http://crbug.com/361786 . |
base::TimeDelta estimated_next_frame_duration_; |
+ |
+ LogCB log_cb_; |
}; |
typedef std::map<int, Track> TextTrackMap; |
public: |
- typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; |
- typedef std::map<TrackId, const BufferQueue> TextBufferQueueMap; |
- |
WebMClusterParser(int64 timecode_scale, |
int audio_track_num, |
base::TimeDelta audio_default_duration, |
@@ -132,17 +157,32 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient { |
base::TimeDelta cluster_start_time() const { return cluster_start_time_; } |
- // Get the buffers resulting from Parse(). |
+ // Get the current ready buffers resulting from Parse(). |
// If the parse reached the end of cluster and the last buffer was held aside |
// due to missing duration, the buffer is given an estimated duration and |
// included in the result. |
+ // Otherwise, if there are is a buffer held aside due to missing duration for |
+ // any of the tracks, no buffers with same or greater (decode) timestamp will |
+ // be included in the buffers. |
+ // The returned deques are cleared by Parse() or Reset() and updated by the |
+ // next calls to Get{Audio,Video}Buffers(). |
+ // If no Parse() or Reset() has occurred since the last call to Get{Audio, |
+ // Video,Text}Buffers(), then the previous BufferQueue& is returned again |
+ // without any recalculation. |
const BufferQueue& GetAudioBuffers(); |
const BufferQueue& GetVideoBuffers(); |
// Constructs and returns a subset of |text_track_map_| containing only |
- // tracks with non-empty buffer queues produced by the last Parse(). |
+ // tracks with non-empty buffer queues produced by the last Parse() and |
+ // filtered to exclude any buffers that have (decode) timestamp same or |
+ // greater than the lowest (decode) timestamp across all tracks of any buffer |
+ // held aside due to missing duration (unless the end of cluster has been |
+ // reached). |
// The returned map is cleared by Parse() or Reset() and updated by the next |
// call to GetTextBuffers(). |
+ // If no Parse() or Reset() has occurred since the last call to |
+ // GetTextBuffers(), then the previous TextBufferQueueMap& is returned again |
+ // without any recalculation. |
const TextBufferQueueMap& GetTextBuffers(); |
// Returns true if the last Parse() call stopped at the end of a cluster. |
@@ -166,6 +206,22 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient { |
// Resets the Track objects associated with each text track. |
void ResetTextTracks(); |
+ // Clears the the ready buffers associated with each text track. |
+ void ClearTextTrackReadyBuffers(); |
+ |
+ // Helper method for Get{Audio,Video,Text}Buffers() that recomputes |
+ // |ready_buffer_upper_bound_| and calls ExtractReadyBuffers() on each track. |
+ // If |cluster_ended_| is true, first applies duration estimate if needed for |
+ // |audio_| and |video_| and sets |ready_buffer_upper_bound_| to |
+ // kInfiniteDuration(). Otherwise, sets |ready_buffer_upper_bound_| to the |
+ // minimum upper bound across |audio_| and |video_|. (Text tracks can have no |
+ // buffers missing duration, so they are not involved in calculating the upper |
+ // bound.) |
+ // Parse() or Reset() must be called between calls to UpdateReadyBuffers() to |
+ // clear each track's ready buffers and to reset |ready_buffer_upper_bound_| |
+ // to kNoTimestamp(). |
+ void UpdateReadyBuffers(); |
+ |
// Search for the indicated track_num among the text tracks. Returns NULL |
// if that track num is not a text track. |
Track* FindTextTrack(int track_num); |
@@ -197,10 +253,18 @@ class MEDIA_EXPORT WebMClusterParser : public WebMParserClient { |
TextTrackMap text_track_map_; |
// Subset of |text_track_map_| maintained by GetTextBuffers(), and cleared by |
- // ResetTextTracks(). Callers of GetTextBuffers() get a const-ref to this |
- // member. |
+ // ClearTextTrackReadyBuffers(). Callers of GetTextBuffers() get a const-ref |
+ // to this member. |
TextBufferQueueMap text_buffers_map_; |
+ // Limits the range of buffers returned by Get{Audio,Video,Text}Buffers() to |
+ // this exclusive upper bound. Set to kNoTimestamp(), meaning not yet |
+ // calculated, by Reset() and Parse(). If kNoTimestamp(), then |
+ // Get{Audio,Video,Text}Buffers() will calculate it to be the minimum (decode) |
+ // timestamp across all tracks' |last_buffer_missing_duration_|, or |
+ // kInfiniteDuration() if no buffers are currently missing duration. |
+ base::TimeDelta ready_buffer_upper_bound_; |
+ |
LogCB log_cb_; |
DISALLOW_IMPLICIT_CONSTRUCTORS(WebMClusterParser); |