Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(553)

Unified Diff: media/formats/webm/webm_cluster_parser.h

Issue 239343007: MSE: Make WebMClusterParser hold back buffers at or beyond buffer missing duration (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix nit. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/filters/chunk_demuxer_unittest.cc ('k') | media/formats/webm/webm_cluster_parser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
« no previous file with comments | « media/filters/chunk_demuxer_unittest.cc ('k') | media/formats/webm/webm_cluster_parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698