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

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

Issue 113611: Handle end of stream for media... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 6 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
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 media { 10 namespace media {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 void FFmpegVideoDecoder::OnDecode(Buffer* buffer) { 80 void FFmpegVideoDecoder::OnDecode(Buffer* buffer) {
81 // Check for end of stream. 81 // Check for end of stream.
82 // TODO(scherkus): check for end of stream. 82 // TODO(scherkus): check for end of stream.
83 83
84 // Check for discontinuous buffer. If we receive a discontinuous buffer here, 84 // Check for discontinuous buffer. If we receive a discontinuous buffer here,
85 // flush the internal buffer of FFmpeg. 85 // flush the internal buffer of FFmpeg.
86 if (buffer->IsDiscontinuous()) { 86 if (buffer->IsDiscontinuous()) {
87 avcodec_flush_buffers(codec_context_); 87 avcodec_flush_buffers(codec_context_);
88 } 88 }
89 89
90 // Queue the incoming timestamp.
91 TimeTuple times;
92 times.timestamp = buffer->GetTimestamp();
93 times.duration = buffer->GetDuration();
94 time_queue_.push(times);
95
96 // Create a packet for input data. 90 // Create a packet for input data.
97 // Due to FFmpeg API changes we no longer have const read-only pointers. 91 // Due to FFmpeg API changes we no longer have const read-only pointers.
98 AVPacket packet; 92 AVPacket packet;
99 av_init_packet(&packet); 93 av_init_packet(&packet);
100 packet.data = const_cast<uint8*>(buffer->GetData()); 94 packet.data = const_cast<uint8*>(buffer->GetData());
101 packet.size = buffer->GetDataSize(); 95 packet.size = buffer->GetDataSize();
102 96
103 // We don't allocate AVFrame on the stack since different versions of FFmpeg 97 // We don't allocate AVFrame on the stack since different versions of FFmpeg
104 // may change the size of AVFrame, causing stack corruption. The solution is 98 // may change the size of AVFrame, causing stack corruption. The solution is
105 // to let FFmpeg allocate the structure via avcodec_alloc_frame(). 99 // to let FFmpeg allocate the structure via avcodec_alloc_frame().
106 int decoded = 0; 100 int decoded = 0;
107 scoped_ptr_malloc<AVFrame, ScopedPtrAVFree> yuv_frame(avcodec_alloc_frame()); 101 scoped_ptr_malloc<AVFrame, ScopedPtrAVFree> yuv_frame(avcodec_alloc_frame());
108 int result = avcodec_decode_video2(codec_context_, yuv_frame.get(), &decoded, 102 int result = avcodec_decode_video2(codec_context_, yuv_frame.get(), &decoded,
109 &packet); 103 &packet);
110 104
111 // Log the problem if we can't decode a video frame. 105 // Log the problem if we can't decode a video frame.
112 if (result < 0) { 106 if (result < 0) {
113 LOG(INFO) << "Error decoding a video frame with timestamp: " 107 LOG(INFO) << "Error decoding a video frame with timestamp: "
114 << buffer->GetTimestamp().InMicroseconds() << " us" 108 << buffer->GetTimestamp().InMicroseconds() << " us"
115 << " , duration: " 109 << " , duration: "
116 << buffer->GetDuration().InMicroseconds() << " us" 110 << buffer->GetDuration().InMicroseconds() << " us"
117 << " , packet size: " 111 << " , packet size: "
118 << buffer->GetDataSize() << " bytes"; 112 << buffer->GetDataSize() << " bytes";
119 } 113 }
120 114
121 // Check for a decoded frame instead of checking the return value of 115 // Check for a decoded frame instead of checking the return value of
122 // avcodec_decode_video(). We don't need to stop the pipeline on 116 // avcodec_decode_video(). We don't need to stop the pipeline on
123 // decode errors. 117 // decode errors.
124 if (!decoded) 118 if (decoded == 0) {
119 // Three conditions to meet to declare end of stream for this decoder:
120 // 1. FFmpeg didn't read anything.
121 // 2. FFmpeg didn't output anything.
122 // 3. An end of stream buffer is received.
123 if (result == 0 && buffer->IsEndOfStream()) {
124 // Create an empty video frame and queue it.
125 scoped_refptr<VideoFrame> video_frame;
126 VideoFrameImpl::CreateEmptyFrame(&video_frame);
127 EnqueueResult(video_frame);
128 }
125 return; 129 return;
130 }
131
132 // Queue the incoming timestamp only if we can decode the frame successfully.
133 TimeTuple times;
134 times.timestamp = buffer->GetTimestamp();
135 times.duration = buffer->GetDuration();
136 time_queue_.push(times);
126 137
127 // J (Motion JPEG) versions of YUV are full range 0..255. 138 // J (Motion JPEG) versions of YUV are full range 0..255.
128 // Regular (MPEG) YUV is 16..240. 139 // Regular (MPEG) YUV is 16..240.
129 // For now we will ignore the distinction and treat them the same. 140 // For now we will ignore the distinction and treat them the same.
130 141
131 VideoSurface::Format surface_format; 142 VideoSurface::Format surface_format;
132 switch (codec_context_->pix_fmt) { 143 switch (codec_context_->pix_fmt) {
133 case PIX_FMT_YUV420P: 144 case PIX_FMT_YUV420P:
134 case PIX_FMT_YUVJ420P: 145 case PIX_FMT_YUVJ420P:
135 surface_format = VideoSurface::YV12; 146 surface_format = VideoSurface::YV12;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 } 208 }
198 DCHECK(bytes_per_line <= source_stride && bytes_per_line <= dest_stride); 209 DCHECK(bytes_per_line <= source_stride && bytes_per_line <= dest_stride);
199 for (size_t i = 0; i < copy_lines; ++i) { 210 for (size_t i = 0; i < copy_lines; ++i) {
200 memcpy(dest, source, bytes_per_line); 211 memcpy(dest, source, bytes_per_line);
201 source += source_stride; 212 source += source_stride;
202 dest += dest_stride; 213 dest += dest_stride;
203 } 214 }
204 } 215 }
205 216
206 } // namespace 217 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698