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

Unified Diff: media/filters/frame_processor.cc

Issue 381443002: MSE: Optimize frame processor appends to streams (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address CR comments and rebase Created 6 years, 5 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/frame_processor.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/filters/frame_processor.cc
diff --git a/media/filters/frame_processor.cc b/media/filters/frame_processor.cc
index bf0b2a5c4a4d20e3ea04d46f7360f6a62845a2ec..a10ed5017ed50814a2269dd0fde06d8fa3189618 100644
--- a/media/filters/frame_processor.cc
+++ b/media/filters/frame_processor.cc
@@ -67,6 +67,14 @@ class MseTrackBuffer {
// monotonically increasing.
void SetHighestPresentationTimestampIfIncreased(base::TimeDelta timestamp);
+ // Adds |frame| to the end of |processed_frames_|.
+ void EnqueueProcessedFrame(const scoped_refptr<StreamParserBuffer>& frame);
+
+ // Appends |processed_frames_|, if not empty, to |stream_| and clears
+ // |processed_frames_|. Returns false if append failed, true otherwise.
+ // |processed_frames_| is cleared in both cases.
+ bool FlushProcessedFrames();
+
private:
// The decode timestamp of the last coded frame appended in the current coded
// frame group. Initially kNoTimestamp(), meaning "unset".
@@ -91,6 +99,11 @@ class MseTrackBuffer {
// by |this|.
ChunkDemuxerStream* const stream_;
+ // Queue of processed frames that have not yet been appended to |stream_|.
+ // EnqueueProcessedFrame() adds to this queue, and FlushProcessedFrames()
+ // clears it.
+ StreamParser::BufferQueue processed_frames_;
+
DISALLOW_COPY_AND_ASSIGN(MseTrackBuffer);
};
@@ -124,6 +137,23 @@ void MseTrackBuffer::SetHighestPresentationTimestampIfIncreased(
}
}
+void MseTrackBuffer::EnqueueProcessedFrame(
+ const scoped_refptr<StreamParserBuffer>& frame) {
+ processed_frames_.push_back(frame);
+}
+
+bool MseTrackBuffer::FlushProcessedFrames() {
+ if (processed_frames_.empty())
+ return true;
+
+ bool result = stream_->Append(processed_frames_);
+ processed_frames_.clear();
+ DVLOG_IF(3, !result) << __FUNCTION__
+ << "(): Failure appending processed frames to stream";
+
+ return result;
+}
+
FrameProcessor::FrameProcessor(const UpdateDurationCB& update_duration_cb)
: sequence_mode_(false),
group_start_timestamp_(kNoTimestamp()),
@@ -180,10 +210,14 @@ bool FrameProcessor::ProcessFrames(
frames_itr != frames.end(); ++frames_itr) {
if (!ProcessFrame(*frames_itr, append_window_start, append_window_end,
timestamp_offset, new_media_segment)) {
+ FlushProcessedFrames();
return false;
}
}
+ if (!FlushProcessedFrames())
+ return false;
+
// 2. - 4. Are handled by the WebMediaPlayer / Pipeline / Media Element.
// Step 5:
@@ -278,6 +312,20 @@ void FrameProcessor::NotifyNewMediaSegmentStarting(
}
}
+bool FrameProcessor::FlushProcessedFrames() {
+ DVLOG(2) << __FUNCTION__ << "()";
+
+ bool result = true;
+ for (TrackBufferMap::iterator itr = track_buffers_.begin();
+ itr != track_buffers_.end();
+ ++itr) {
+ if (!itr->second->FlushProcessedFrames())
+ result = false;
+ }
+
+ return result;
+}
+
bool FrameProcessor::HandlePartialAppendWindowTrimming(
base::TimeDelta append_window_start,
base::TimeDelta append_window_end,
@@ -595,6 +643,11 @@ bool FrameProcessor::ProcessFrame(
// If it is the first in a new media segment or following a discontinuity,
// notify all the track buffers' streams that a new segment is beginning.
if (*new_media_segment) {
+ // First, complete the append to track buffer streams of previous media
+ // segment's frames, if any.
+ if (!FlushProcessedFrames())
+ return false;
+
*new_media_segment = false;
NotifyNewMediaSegmentStarting(decode_timestamp);
}
@@ -603,16 +656,12 @@ bool FrameProcessor::ProcessFrame(
<< "PTS=" << presentation_timestamp.InSecondsF()
<< ", DTS=" << decode_timestamp.InSecondsF();
- // Steps 13-18:
- // TODO(wolenetz): Collect and emit more than one buffer at a time, if
- // possible. Also refactor SourceBufferStream to conform to spec GC timing.
+ // Steps 13-18: Note, we optimize by appending groups of contiguous
+ // processed frames for each track buffer at end of ProcessFrames() or prior
+ // to NotifyNewMediaSegmentStarting().
+ // TODO(wolenetz): Refactor SourceBufferStream to conform to spec GC timing.
// See http://crbug.com/371197.
- StreamParser::BufferQueue buffer_to_append;
- buffer_to_append.push_back(frame);
- if (!track_buffer->stream()->Append(buffer_to_append)) {
- DVLOG(3) << __FUNCTION__ << ": Failure appending frame to stream";
- return false;
- }
+ track_buffer->EnqueueProcessedFrame(frame);
// 19. Set last decode timestamp for track buffer to decode timestamp.
track_buffer->set_last_decode_timestamp(decode_timestamp);
« no previous file with comments | « media/filters/frame_processor.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698