| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <deque> | 7 #include <deque> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/task.h" | 10 #include "base/task.h" |
| 11 #include "media/base/callback.h" | 11 #include "media/base/callback.h" |
| 12 #include "media/base/filters.h" | 12 #include "media/base/filters.h" |
| 13 #include "media/base/filter_host.h" | 13 #include "media/base/filter_host.h" |
| 14 #include "media/base/limits.h" | 14 #include "media/base/limits.h" |
| 15 #include "media/base/media_format.h" | |
| 16 #include "media/base/video_frame.h" | 15 #include "media/base/video_frame.h" |
| 17 #include "media/ffmpeg/ffmpeg_common.h" | 16 #include "media/ffmpeg/ffmpeg_common.h" |
| 18 #include "media/video/ffmpeg_video_decode_engine.h" | 17 #include "media/video/ffmpeg_video_decode_engine.h" |
| 19 #include "media/video/video_decode_context.h" | 18 #include "media/video/video_decode_context.h" |
| 20 | 19 |
| 21 namespace media { | 20 namespace media { |
| 22 | 21 |
| 23 FFmpegVideoDecoder::FFmpegVideoDecoder(MessageLoop* message_loop, | 22 FFmpegVideoDecoder::FFmpegVideoDecoder(MessageLoop* message_loop, |
| 24 VideoDecodeContext* decode_context) | 23 VideoDecodeContext* decode_context) |
| 25 : message_loop_(message_loop), | 24 : message_loop_(message_loop), |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 } | 87 } |
| 89 | 88 |
| 90 void FFmpegVideoDecoder::OnInitializeComplete(const VideoCodecInfo& info) { | 89 void FFmpegVideoDecoder::OnInitializeComplete(const VideoCodecInfo& info) { |
| 91 DCHECK_EQ(MessageLoop::current(), message_loop_); | 90 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 92 DCHECK(initialize_callback_.get()); | 91 DCHECK(initialize_callback_.get()); |
| 93 | 92 |
| 94 info_ = info; | 93 info_ = info; |
| 95 AutoCallbackRunner done_runner(initialize_callback_.release()); | 94 AutoCallbackRunner done_runner(initialize_callback_.release()); |
| 96 | 95 |
| 97 if (info.success) { | 96 if (info.success) { |
| 98 media_format_.SetAsInteger(MediaFormat::kWidth, | |
| 99 info.stream_info.surface_width); | |
| 100 media_format_.SetAsInteger(MediaFormat::kHeight, | |
| 101 info.stream_info.surface_height); | |
| 102 media_format_.SetAsInteger( | |
| 103 MediaFormat::kSurfaceFormat, | |
| 104 static_cast<int>(info.stream_info.surface_format)); | |
| 105 state_ = kNormal; | 97 state_ = kNormal; |
| 106 } else { | 98 } else { |
| 107 host()->SetError(PIPELINE_ERROR_DECODE); | 99 host()->SetError(PIPELINE_ERROR_DECODE); |
| 108 } | 100 } |
| 109 } | 101 } |
| 110 | 102 |
| 111 void FFmpegVideoDecoder::Stop(FilterCallback* callback) { | 103 void FFmpegVideoDecoder::Stop(FilterCallback* callback) { |
| 112 if (MessageLoop::current() != message_loop_) { | 104 if (MessageLoop::current() != message_loop_) { |
| 113 message_loop_->PostTask(FROM_HERE, | 105 message_loop_->PostTask(FROM_HERE, |
| 114 NewRunnableMethod(this, | 106 NewRunnableMethod(this, |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 // TODO(ajwong): This push logic, along with the pop logic below needs to | 257 // TODO(ajwong): This push logic, along with the pop logic below needs to |
| 266 // be reevaluated to correctly handle decode errors. | 258 // be reevaluated to correctly handle decode errors. |
| 267 if (state_ == kNormal) { | 259 if (state_ == kNormal) { |
| 268 pts_stream_.EnqueuePts(buffer.get()); | 260 pts_stream_.EnqueuePts(buffer.get()); |
| 269 } | 261 } |
| 270 | 262 |
| 271 // Otherwise, attempt to decode a single frame. | 263 // Otherwise, attempt to decode a single frame. |
| 272 decode_engine_->ConsumeVideoSample(buffer); | 264 decode_engine_->ConsumeVideoSample(buffer); |
| 273 } | 265 } |
| 274 | 266 |
| 275 const MediaFormat& FFmpegVideoDecoder::media_format() { | |
| 276 return media_format_; | |
| 277 } | |
| 278 | |
| 279 void FFmpegVideoDecoder::ProduceVideoFrame( | 267 void FFmpegVideoDecoder::ProduceVideoFrame( |
| 280 scoped_refptr<VideoFrame> video_frame) { | 268 scoped_refptr<VideoFrame> video_frame) { |
| 281 if (MessageLoop::current() != message_loop_) { | 269 if (MessageLoop::current() != message_loop_) { |
| 282 message_loop_->PostTask( | 270 message_loop_->PostTask( |
| 283 FROM_HERE, | 271 FROM_HERE, |
| 284 NewRunnableMethod(this, | 272 NewRunnableMethod(this, |
| 285 &FFmpegVideoDecoder::ProduceVideoFrame, video_frame)); | 273 &FFmpegVideoDecoder::ProduceVideoFrame, video_frame)); |
| 286 return; | 274 return; |
| 287 } | 275 } |
| 288 | 276 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 | 333 |
| 346 demuxer_stream_->Read(base::Bind(&FFmpegVideoDecoder::OnReadComplete, | 334 demuxer_stream_->Read(base::Bind(&FFmpegVideoDecoder::OnReadComplete, |
| 347 this)); | 335 this)); |
| 348 } | 336 } |
| 349 | 337 |
| 350 bool FFmpegVideoDecoder::ProvidesBuffer() { | 338 bool FFmpegVideoDecoder::ProvidesBuffer() { |
| 351 DCHECK(info_.success); | 339 DCHECK(info_.success); |
| 352 return info_.provides_buffers; | 340 return info_.provides_buffers; |
| 353 } | 341 } |
| 354 | 342 |
| 343 int FFmpegVideoDecoder::width() { |
| 344 DCHECK(info_.success); |
| 345 return info_.stream_info.surface_width; |
| 346 } |
| 347 |
| 348 int FFmpegVideoDecoder::height() { |
| 349 DCHECK(info_.success); |
| 350 return info_.stream_info.surface_height; |
| 351 } |
| 352 |
| 355 void FFmpegVideoDecoder::FlushBuffers() { | 353 void FFmpegVideoDecoder::FlushBuffers() { |
| 356 while (!frame_queue_flushed_.empty()) { | 354 while (!frame_queue_flushed_.empty()) { |
| 357 scoped_refptr<VideoFrame> video_frame; | 355 scoped_refptr<VideoFrame> video_frame; |
| 358 video_frame = frame_queue_flushed_.front(); | 356 video_frame = frame_queue_flushed_.front(); |
| 359 frame_queue_flushed_.pop_front(); | 357 frame_queue_flushed_.pop_front(); |
| 360 | 358 |
| 361 // Depends on who own the buffers, we either return it to the renderer | 359 // Depends on who own the buffers, we either return it to the renderer |
| 362 // or return it to the decode engine. | 360 // or return it to the decode engine. |
| 363 if (ProvidesBuffer()) | 361 if (ProvidesBuffer()) |
| 364 decode_engine_->ProduceVideoFrame(video_frame); | 362 decode_engine_->ProduceVideoFrame(video_frame); |
| 365 else | 363 else |
| 366 VideoFrameReady(video_frame); | 364 VideoFrameReady(video_frame); |
| 367 } | 365 } |
| 368 } | 366 } |
| 369 | 367 |
| 370 void FFmpegVideoDecoder::SetVideoDecodeEngineForTest( | 368 void FFmpegVideoDecoder::SetVideoDecodeEngineForTest( |
| 371 VideoDecodeEngine* engine) { | 369 VideoDecodeEngine* engine) { |
| 372 decode_engine_.reset(engine); | 370 decode_engine_.reset(engine); |
| 373 } | 371 } |
| 374 | 372 |
| 375 } // namespace media | 373 } // namespace media |
| OLD | NEW |