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

Side by Side Diff: media/filters/ffmpeg_video_decoder.cc

Issue 9667018: Make FFmpegVideoDecoder defer a flush until the pending read completes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix rebase build buster Created 8 years, 9 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/filters/ffmpeg_video_decoder.h ('k') | media/filters/ffmpeg_video_decoder_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/filters/ffmpeg_video_decoder.h" 5 #include "media/filters/ffmpeg_video_decoder.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/string_number_conversions.h" 10 #include "base/string_number_conversions.h"
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 callback.Run(); 156 callback.Run();
157 } 157 }
158 158
159 void FFmpegVideoDecoder::Flush(const base::Closure& callback) { 159 void FFmpegVideoDecoder::Flush(const base::Closure& callback) {
160 if (MessageLoop::current() != message_loop_) { 160 if (MessageLoop::current() != message_loop_) {
161 message_loop_->PostTask(FROM_HERE, base::Bind( 161 message_loop_->PostTask(FROM_HERE, base::Bind(
162 &FFmpegVideoDecoder::Flush, this, callback)); 162 &FFmpegVideoDecoder::Flush, this, callback));
163 return; 163 return;
164 } 164 }
165 165
166 flush_cb_ = callback;
167
168 // Defer the flush if a read is pending.
169 if (!read_cb_.is_null())
170 return;
171
172 DoFlush();
173 }
174
175 void FFmpegVideoDecoder::DoFlush() {
176 DCHECK(read_cb_.is_null());
177
166 avcodec_flush_buffers(codec_context_); 178 avcodec_flush_buffers(codec_context_);
167 state_ = kNormal; 179 state_ = kNormal;
168 callback.Run(); 180 flush_cb_.Run();
181 flush_cb_.Reset();
169 } 182 }
170 183
171 void FFmpegVideoDecoder::Read(const ReadCB& read_cb) { 184 void FFmpegVideoDecoder::Read(const ReadCB& read_cb) {
172 // Complete operation asynchronously on different stack of execution as per 185 // Complete operation asynchronously on different stack of execution as per
173 // the API contract of VideoDecoder::Read() 186 // the API contract of VideoDecoder::Read()
174 message_loop_->PostTask(FROM_HERE, base::Bind( 187 message_loop_->PostTask(FROM_HERE, base::Bind(
175 &FFmpegVideoDecoder::DoRead, this, read_cb)); 188 &FFmpegVideoDecoder::DoRead, this, read_cb));
176 } 189 }
177 190
178 const gfx::Size& FFmpegVideoDecoder::natural_size() { 191 const gfx::Size& FFmpegVideoDecoder::natural_size() {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 DCHECK_EQ(MessageLoop::current(), message_loop_); 232 DCHECK_EQ(MessageLoop::current(), message_loop_);
220 DCHECK_NE(state_, kUninitialized); 233 DCHECK_NE(state_, kUninitialized);
221 DCHECK_NE(state_, kDecodeFinished); 234 DCHECK_NE(state_, kDecodeFinished);
222 DCHECK(!read_cb_.is_null()); 235 DCHECK(!read_cb_.is_null());
223 236
224 if (!buffer) { 237 if (!buffer) {
225 DeliverFrame(NULL); 238 DeliverFrame(NULL);
226 return; 239 return;
227 } 240 }
228 241
242 if (!flush_cb_.is_null()) {
243 DeliverFrame(NULL);
244 DoFlush();
245 return;
246 }
247
229 // During decode, because reads are issued asynchronously, it is possible to 248 // During decode, because reads are issued asynchronously, it is possible to
230 // receive multiple end of stream buffers since each read is acked. When the 249 // receive multiple end of stream buffers since each read is acked. When the
231 // first end of stream buffer is read, FFmpeg may still have frames queued 250 // first end of stream buffer is read, FFmpeg may still have frames queued
232 // up in the decoder so we need to go through the decode loop until it stops 251 // up in the decoder so we need to go through the decode loop until it stops
233 // giving sensible data. After that, the decoder should output empty 252 // giving sensible data. After that, the decoder should output empty
234 // frames. There are three states the decoder can be in: 253 // frames. There are three states the decoder can be in:
235 // 254 //
236 // kNormal: This is the starting state. Buffers are decoded. Decode errors 255 // kNormal: This is the starting state. Buffers are decoded. Decode errors
237 // are discarded. 256 // are discarded.
238 // kFlushCodec: There isn't any more input data. Call avcodec_decode_video2 257 // kFlushCodec: There isn't any more input data. Call avcodec_decode_video2
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 scoped_refptr<VideoFrame> FFmpegVideoDecoder::AllocateVideoFrame() { 436 scoped_refptr<VideoFrame> FFmpegVideoDecoder::AllocateVideoFrame() {
418 VideoFrame::Format format = PixelFormatToVideoFormat(codec_context_->pix_fmt); 437 VideoFrame::Format format = PixelFormatToVideoFormat(codec_context_->pix_fmt);
419 size_t width = codec_context_->width; 438 size_t width = codec_context_->width;
420 size_t height = codec_context_->height; 439 size_t height = codec_context_->height;
421 440
422 return VideoFrame::CreateFrame(format, width, height, 441 return VideoFrame::CreateFrame(format, width, height,
423 kNoTimestamp(), kNoTimestamp()); 442 kNoTimestamp(), kNoTimestamp());
424 } 443 }
425 444
426 } // namespace media 445 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/ffmpeg_video_decoder.h ('k') | media/filters/ffmpeg_video_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698