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

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

Issue 159476: Merge 21611 - Implemented proper pausethenseek behaviour for the media pipeli... (Closed) Base URL: svn://chrome-svn/chrome/branches/195/src/
Patch Set: Created 11 years, 4 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')
Property Changes:
Added: svn:mergeinfo
Merged /trunk/src/media/filters/ffmpeg_video_decoder.cc:r21611
Merged /branches/chrome_webkit_merge_branch/media/filters/ffmpeg_video_decoder.cc:r69-2775
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the 2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file. 3 // LICENSE file.
4 4
5 #include "media/base/video_frame_impl.h" 5 #include "media/base/video_frame_impl.h"
6 #include "media/filters/ffmpeg_common.h" 6 #include "media/filters/ffmpeg_common.h"
7 #include "media/filters/ffmpeg_demuxer.h" 7 #include "media/filters/ffmpeg_demuxer.h"
8 #include "media/filters/ffmpeg_video_decoder.h" 8 #include "media/filters/ffmpeg_video_decoder.h"
9 9
10 namespace { 10 namespace {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 return false; 88 return false;
89 } 89 }
90 } 90 }
91 return true; 91 return true;
92 } 92 }
93 93
94 void FFmpegVideoDecoder::OnSeek(base::TimeDelta time) { 94 void FFmpegVideoDecoder::OnSeek(base::TimeDelta time) {
95 // Everything in the presentation time queue is invalid, clear the queue. 95 // Everything in the presentation time queue is invalid, clear the queue.
96 while (!pts_queue_.empty()) 96 while (!pts_queue_.empty())
97 pts_queue_.pop(); 97 pts_queue_.pop();
98
99 // We're back where we started. It should be completely safe to flush here
100 // since DecoderBase uses |expecting_discontinuous_| to verify that the next
101 // time OnDecode() is called we will have a discontinuous buffer.
102 state_ = kNormal;
103 avcodec_flush_buffers(codec_context_);
98 } 104 }
99 105
100 void FFmpegVideoDecoder::OnDecode(Buffer* buffer) { 106 void FFmpegVideoDecoder::OnDecode(Buffer* buffer) {
101 // During decode, because reads are issued asynchronously, it is possible to 107 // During decode, because reads are issued asynchronously, it is possible to
102 // recieve multiple end of stream buffers since each read is acked. When the 108 // receive multiple end of stream buffers since each read is acked. When the
103 // first end of stream buffer is read, FFmpeg may still have frames queued 109 // first end of stream buffer is read, FFmpeg may still have frames queued
104 // up in the decoder so we need to go through the decode loop until it stops 110 // up in the decoder so we need to go through the decode loop until it stops
105 // giving sensible data. After that, the decoder should output empty 111 // giving sensible data. After that, the decoder should output empty
106 // frames. There are three states the decoder can be in: 112 // frames. There are three states the decoder can be in:
107 // 113 //
108 // kNormal: This is the starting state. Buffers are decoded. Decode errors 114 // kNormal: This is the starting state. Buffers are decoded. Decode errors
109 // are discarded. 115 // are discarded.
110 // kFlushCodec: There isn't any more input data. Call avcodec_decode_video2 116 // kFlushCodec: There isn't any more input data. Call avcodec_decode_video2
111 // until no more data is returned to flush out remaining 117 // until no more data is returned to flush out remaining
112 // frames. The input buffer is ignored at this point. 118 // frames. The input buffer is ignored at this point.
113 // kDecodeFinished: All calls return empty frames. 119 // kDecodeFinished: All calls return empty frames.
114 // 120 //
115 // These are the possible state transitions. 121 // These are the possible state transitions.
116 // 122 //
117 // kNormal -> kFlushCodec: 123 // kNormal -> kFlushCodec:
118 // When buffer->IsEndOfStream() is first true. 124 // When buffer->IsEndOfStream() is first true.
119 // kNormal -> kDecodeFinished: 125 // kNormal -> kDecodeFinished:
120 // A catastrophic failure occurs, and decoding needs to stop. 126 // A catastrophic failure occurs, and decoding needs to stop.
121 // kFlushCodec -> kDecodeFinished: 127 // kFlushCodec -> kDecodeFinished:
122 // When avcodec_decode_video2() returns 0 data or errors out. 128 // When avcodec_decode_video2() returns 0 data or errors out.
129 // (any state) -> kNormal:
130 // Any time buffer->IsDiscontinuous() is true.
123 // 131 //
124 // If the decoding is finished, we just always return empty frames. 132 // If the decoding is finished, we just always return empty frames.
125 if (state_ == kDecodeFinished) { 133 if (state_ == kDecodeFinished) {
126 EnqueueEmptyFrame(); 134 EnqueueEmptyFrame();
127 return; 135 return;
128 } 136 }
129 137
130 // Transition to kFlushCodec on the first end of stream buffer. 138 // Transition to kFlushCodec on the first end of stream buffer.
131 if (state_ == kNormal && buffer->IsEndOfStream()) { 139 if (state_ == kNormal && buffer->IsEndOfStream()) {
132 state_ = kFlushCodec; 140 state_ = kFlushCodec;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 241
234 void FFmpegVideoDecoder::EnqueueEmptyFrame() { 242 void FFmpegVideoDecoder::EnqueueEmptyFrame() {
235 scoped_refptr<VideoFrame> video_frame; 243 scoped_refptr<VideoFrame> video_frame;
236 VideoFrameImpl::CreateEmptyFrame(&video_frame); 244 VideoFrameImpl::CreateEmptyFrame(&video_frame);
237 EnqueueResult(video_frame); 245 EnqueueResult(video_frame);
238 } 246 }
239 247
240 bool FFmpegVideoDecoder::DecodeFrame(const Buffer& buffer, 248 bool FFmpegVideoDecoder::DecodeFrame(const Buffer& buffer,
241 AVCodecContext* codec_context, 249 AVCodecContext* codec_context,
242 AVFrame* yuv_frame) { 250 AVFrame* yuv_frame) {
243 // Check for discontinuous buffer. If we receive a discontinuous buffer here,
244 // flush the internal buffer of FFmpeg.
245 if (buffer.IsDiscontinuous()) {
246 avcodec_flush_buffers(codec_context);
247 }
248
249 // Create a packet for input data. 251 // Create a packet for input data.
250 // Due to FFmpeg API changes we no longer have const read-only pointers. 252 // Due to FFmpeg API changes we no longer have const read-only pointers.
251 AVPacket packet; 253 AVPacket packet;
252 av_init_packet(&packet); 254 av_init_packet(&packet);
253 packet.data = const_cast<uint8*>(buffer.GetData()); 255 packet.data = const_cast<uint8*>(buffer.GetData());
254 packet.size = buffer.GetDataSize(); 256 packet.size = buffer.GetDataSize();
255 257
256 // We don't allocate AVFrame on the stack since different versions of FFmpeg 258 // We don't allocate AVFrame on the stack since different versions of FFmpeg
257 // may change the size of AVFrame, causing stack corruption. The solution is 259 // may change the size of AVFrame, causing stack corruption. The solution is
258 // to let FFmpeg allocate the structure via avcodec_alloc_frame(). 260 // to let FFmpeg allocate the structure via avcodec_alloc_frame().
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 // static 346 // static
345 bool FFmpegVideoDecoder::PtsHeapOrdering::operator()( 347 bool FFmpegVideoDecoder::PtsHeapOrdering::operator()(
346 const base::TimeDelta& lhs, 348 const base::TimeDelta& lhs,
347 const base::TimeDelta& rhs) const { 349 const base::TimeDelta& rhs) const {
348 // std::priority_queue is a max-heap. We want lower timestamps to show up 350 // std::priority_queue is a max-heap. We want lower timestamps to show up
349 // first so reverse the natural less-than comparison. 351 // first so reverse the natural less-than comparison.
350 return rhs < lhs; 352 return rhs < lhs;
351 } 353 }
352 354
353 } // namespace 355 } // namespace
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