OLD | NEW |
---|---|
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 <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
51 return decode_threads; | 51 return decode_threads; |
52 | 52 |
53 decode_threads = std::max(decode_threads, 0); | 53 decode_threads = std::max(decode_threads, 0); |
54 decode_threads = std::min(decode_threads, kMaxDecodeThreads); | 54 decode_threads = std::min(decode_threads, kMaxDecodeThreads); |
55 return decode_threads; | 55 return decode_threads; |
56 } | 56 } |
57 | 57 |
58 FFmpegVideoDecoder::FFmpegVideoDecoder( | 58 FFmpegVideoDecoder::FFmpegVideoDecoder( |
59 const scoped_refptr<base::MessageLoopProxy>& message_loop) | 59 const scoped_refptr<base::MessageLoopProxy>& message_loop) |
60 : message_loop_(message_loop), | 60 : message_loop_(message_loop), |
61 weak_factory_(this), | |
61 state_(kUninitialized), | 62 state_(kUninitialized), |
62 codec_context_(NULL), | 63 codec_context_(NULL), |
63 av_frame_(NULL) { | 64 av_frame_(NULL) { |
64 } | 65 } |
65 | 66 |
66 int FFmpegVideoDecoder::GetVideoBuffer(AVCodecContext* codec_context, | 67 int FFmpegVideoDecoder::GetVideoBuffer(AVCodecContext* codec_context, |
67 AVFrame* frame) { | 68 AVFrame* frame) { |
68 // Don't use |codec_context_| here! With threaded decoding, | 69 // Don't use |codec_context_| here! With threaded decoding, |
69 // it will contain unsynchronized width/height/pix_fmt values, | 70 // it will contain unsynchronized width/height/pix_fmt values, |
70 // whereas |codec_context| contains the current threads's | 71 // whereas |codec_context| contains the current threads's |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
127 // this callback | 128 // this callback |
128 memset(frame->data, 0, sizeof(frame->data)); | 129 memset(frame->data, 0, sizeof(frame->data)); |
129 frame->opaque = NULL; | 130 frame->opaque = NULL; |
130 } | 131 } |
131 | 132 |
132 void FFmpegVideoDecoder::Initialize(const scoped_refptr<DemuxerStream>& stream, | 133 void FFmpegVideoDecoder::Initialize(const scoped_refptr<DemuxerStream>& stream, |
133 const PipelineStatusCB& status_cb, | 134 const PipelineStatusCB& status_cb, |
134 const StatisticsCB& statistics_cb) { | 135 const StatisticsCB& statistics_cb) { |
135 DCHECK(message_loop_->BelongsToCurrentThread()); | 136 DCHECK(message_loop_->BelongsToCurrentThread()); |
136 PipelineStatusCB initialize_cb = BindToCurrentLoop(status_cb); | 137 PipelineStatusCB initialize_cb = BindToCurrentLoop(status_cb); |
138 weak_this_ = weak_factory_.GetWeakPtr(); | |
137 | 139 |
138 FFmpegGlue::InitializeFFmpeg(); | 140 FFmpegGlue::InitializeFFmpeg(); |
139 DCHECK(!demuxer_stream_) << "Already initialized."; | 141 DCHECK(!demuxer_stream_) << "Already initialized."; |
140 | 142 |
141 if (!stream) { | 143 if (!stream) { |
142 initialize_cb.Run(PIPELINE_ERROR_DECODE); | 144 initialize_cb.Run(PIPELINE_ERROR_DECODE); |
143 return; | 145 return; |
144 } | 146 } |
145 | 147 |
146 demuxer_stream_ = stream; | 148 demuxer_stream_ = stream; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
217 if (!decoded_frames_.empty()) { | 219 if (!decoded_frames_.empty()) { |
218 scoped_refptr<VideoFrame> frame = decoded_frames_.front(); | 220 scoped_refptr<VideoFrame> frame = decoded_frames_.front(); |
219 decoded_frames_.pop_front(); | 221 decoded_frames_.pop_front(); |
220 base::ResetAndReturn(&read_cb_).Run(kOk, frame); | 222 base::ResetAndReturn(&read_cb_).Run(kOk, frame); |
221 return; | 223 return; |
222 } | 224 } |
223 | 225 |
224 DCHECK_NE(state_, kUninitialized); | 226 DCHECK_NE(state_, kUninitialized); |
225 DCHECK_NE(state_, kDecodeFinished); | 227 DCHECK_NE(state_, kDecodeFinished); |
226 DCHECK(!read_cb_.is_null()); | 228 DCHECK(!read_cb_.is_null()); |
227 demuxer_stream_->Read(base::Bind(&FFmpegVideoDecoder::BufferReady, this)); | 229 demuxer_stream_->Read(base::Bind( |
Ami GONE FROM CHROMIUM
2013/03/22 23:48:01
Again, BindToCurrentLoop ?
scherkus (not reviewing)
2013/03/28 02:00:01
ditto
| |
230 &FFmpegVideoDecoder::BufferReady, weak_this_)); | |
228 } | 231 } |
229 | 232 |
230 void FFmpegVideoDecoder::BufferReady( | 233 void FFmpegVideoDecoder::BufferReady( |
231 DemuxerStream::Status status, | 234 DemuxerStream::Status status, |
232 const scoped_refptr<DecoderBuffer>& buffer) { | 235 const scoped_refptr<DecoderBuffer>& buffer) { |
233 DCHECK(message_loop_->BelongsToCurrentThread()); | 236 DCHECK(message_loop_->BelongsToCurrentThread()); |
234 DCHECK_NE(state_, kDecodeFinished); | 237 DCHECK_NE(state_, kDecodeFinished); |
235 DCHECK_EQ(status != DemuxerStream::kOk, !buffer) << status; | 238 DCHECK_EQ(status != DemuxerStream::kOk, !buffer) << status; |
236 | 239 |
237 if (state_ == kUninitialized) | 240 if (state_ == kUninitialized) |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
473 if (!codec || avcodec_open2(codec_context_, codec, NULL) < 0) { | 476 if (!codec || avcodec_open2(codec_context_, codec, NULL) < 0) { |
474 ReleaseFFmpegResources(); | 477 ReleaseFFmpegResources(); |
475 return false; | 478 return false; |
476 } | 479 } |
477 | 480 |
478 av_frame_ = avcodec_alloc_frame(); | 481 av_frame_ = avcodec_alloc_frame(); |
479 return true; | 482 return true; |
480 } | 483 } |
481 | 484 |
482 } // namespace media | 485 } // namespace media |
OLD | NEW |