| 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/video/ffmpeg_video_decode_engine.h" | 5 #include "media/video/ffmpeg_video_decode_engine.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/string_number_conversions.h" | 8 #include "base/string_number_conversions.h" |
| 9 #include "base/task.h" | 9 #include "base/task.h" |
| 10 #include "media/base/buffers.h" | 10 #include "media/base/buffers.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 // Handling decoding on separate threads also frees up the pipeline thread to | 49 // Handling decoding on separate threads also frees up the pipeline thread to |
| 50 // continue processing. Although it'd be nice to have the option of a single | 50 // continue processing. Although it'd be nice to have the option of a single |
| 51 // decoding thread, FFmpeg treats having one thread the same as having zero | 51 // decoding thread, FFmpeg treats having one thread the same as having zero |
| 52 // threads (i.e., avcodec_decode_video() will execute on the calling thread). | 52 // threads (i.e., avcodec_decode_video() will execute on the calling thread). |
| 53 // Yet another reason for having two threads :) | 53 // Yet another reason for having two threads :) |
| 54 static const int kDecodeThreads = 2; | 54 static const int kDecodeThreads = 2; |
| 55 static const int kMaxDecodeThreads = 16; | 55 static const int kMaxDecodeThreads = 16; |
| 56 | 56 |
| 57 // Initialize AVCodecContext structure. | 57 // Initialize AVCodecContext structure. |
| 58 codec_context_ = avcodec_alloc_context(); | 58 codec_context_ = avcodec_alloc_context(); |
| 59 | 59 codec_context_->pix_fmt = VideoFormatToPixelFormat(config.video_format()); |
| 60 // TODO(scherkus): should video format get passed in via VideoDecoderConfig? | |
| 61 codec_context_->pix_fmt = PIX_FMT_YUV420P; | |
| 62 codec_context_->codec_type = AVMEDIA_TYPE_VIDEO; | 60 codec_context_->codec_type = AVMEDIA_TYPE_VIDEO; |
| 63 codec_context_->codec_id = VideoCodecToCodecID(config.codec()); | 61 codec_context_->codec_id = VideoCodecToCodecID(config.codec()); |
| 64 codec_context_->coded_width = config.coded_size().width(); | 62 codec_context_->coded_width = config.coded_size().width(); |
| 65 codec_context_->coded_height = config.coded_size().height(); | 63 codec_context_->coded_height = config.coded_size().height(); |
| 66 | 64 |
| 67 frame_rate_numerator_ = config.frame_rate_numerator(); | 65 frame_rate_numerator_ = config.frame_rate_numerator(); |
| 68 frame_rate_denominator_ = config.frame_rate_denominator(); | 66 frame_rate_denominator_ = config.frame_rate_denominator(); |
| 69 | 67 |
| 70 if (config.extra_data() != NULL) { | 68 if (config.extra_data() != NULL) { |
| 71 codec_context_->extradata_size = config.extra_data_size(); | 69 codec_context_->extradata_size = config.extra_data_size(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 VideoCodecInfo info; | 103 VideoCodecInfo info; |
| 106 info.success = false; | 104 info.success = false; |
| 107 info.natural_size = config.natural_size(); | 105 info.natural_size = config.natural_size(); |
| 108 | 106 |
| 109 // If we do not have enough buffers, we will report error too. | 107 // If we do not have enough buffers, we will report error too. |
| 110 frame_queue_available_.clear(); | 108 frame_queue_available_.clear(); |
| 111 | 109 |
| 112 // Create output buffer pool when direct rendering is not used. | 110 // Create output buffer pool when direct rendering is not used. |
| 113 for (size_t i = 0; i < Limits::kMaxVideoFrames; ++i) { | 111 for (size_t i = 0; i < Limits::kMaxVideoFrames; ++i) { |
| 114 scoped_refptr<VideoFrame> video_frame = | 112 scoped_refptr<VideoFrame> video_frame = |
| 115 VideoFrame::CreateFrame(VideoFrame::YV12, | 113 VideoFrame::CreateFrame(PixelFormatToVideoFormat(codec_context_->pix_fmt), |
| 116 config.visible_rect().width(), | 114 config.visible_rect().width(), |
| 117 config.visible_rect().height(), | 115 config.visible_rect().height(), |
| 118 kNoTimestamp, | 116 kNoTimestamp, |
| 119 kNoTimestamp); | 117 kNoTimestamp); |
| 120 frame_queue_available_.push_back(video_frame); | 118 frame_queue_available_.push_back(video_frame); |
| 121 } | 119 } |
| 122 | 120 |
| 123 codec_context_->thread_count = decode_threads; | 121 codec_context_->thread_count = decode_threads; |
| 124 if (codec && | 122 if (codec && |
| 125 avcodec_open(codec_context_, codec) >= 0 && | 123 avcodec_open(codec_context_, codec) >= 0 && |
| 126 av_frame_.get()) { | 124 av_frame_.get()) { |
| 127 info.success = true; | 125 info.success = true; |
| 128 } | 126 } |
| 129 event_handler_ = event_handler; | 127 event_handler_ = event_handler; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 // available frame, except the case of |frame_decoded| == 0, which | 241 // available frame, except the case of |frame_decoded| == 0, which |
| 244 // implies decoder order delay, and force us to read more inputs. | 242 // implies decoder order delay, and force us to read more inputs. |
| 245 DCHECK(frame_queue_available_.size()); | 243 DCHECK(frame_queue_available_.size()); |
| 246 video_frame = frame_queue_available_.front(); | 244 video_frame = frame_queue_available_.front(); |
| 247 frame_queue_available_.pop_front(); | 245 frame_queue_available_.pop_front(); |
| 248 | 246 |
| 249 // Copy the frame data since FFmpeg reuses internal buffers for AVFrame | 247 // Copy the frame data since FFmpeg reuses internal buffers for AVFrame |
| 250 // output, meaning the data is only valid until the next | 248 // output, meaning the data is only valid until the next |
| 251 // avcodec_decode_video() call. | 249 // avcodec_decode_video() call. |
| 252 int y_rows = codec_context_->height; | 250 int y_rows = codec_context_->height; |
| 253 int uv_rows = codec_context_->height / 2; | 251 int uv_rows = video_frame->rows(VideoFrame::kUPlane); |
| 252 |
| 254 CopyYPlane(av_frame_->data[0], av_frame_->linesize[0], y_rows, video_frame); | 253 CopyYPlane(av_frame_->data[0], av_frame_->linesize[0], y_rows, video_frame); |
| 255 CopyUPlane(av_frame_->data[1], av_frame_->linesize[1], uv_rows, video_frame); | 254 CopyUPlane(av_frame_->data[1], av_frame_->linesize[1], uv_rows, video_frame); |
| 256 CopyVPlane(av_frame_->data[2], av_frame_->linesize[2], uv_rows, video_frame); | 255 CopyVPlane(av_frame_->data[2], av_frame_->linesize[2], uv_rows, video_frame); |
| 257 | 256 |
| 258 video_frame->SetTimestamp(timestamp); | 257 video_frame->SetTimestamp(timestamp); |
| 259 video_frame->SetDuration(duration); | 258 video_frame->SetDuration(duration); |
| 260 | 259 |
| 261 pending_output_buffers_--; | 260 pending_output_buffers_--; |
| 262 event_handler_->ConsumeVideoFrame(video_frame, statistics); | 261 event_handler_->ConsumeVideoFrame(video_frame, statistics); |
| 263 } | 262 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 DCHECK_EQ(output_eos_reached_, false); | 299 DCHECK_EQ(output_eos_reached_, false); |
| 301 pending_input_buffers_++; | 300 pending_input_buffers_++; |
| 302 event_handler_->ProduceVideoSample(NULL); | 301 event_handler_->ProduceVideoSample(NULL); |
| 303 } | 302 } |
| 304 | 303 |
| 305 } // namespace media | 304 } // namespace media |
| 306 | 305 |
| 307 // Disable refcounting for this object because this object only lives | 306 // Disable refcounting for this object because this object only lives |
| 308 // on the video decoder thread and there's no need to refcount it. | 307 // on the video decoder thread and there's no need to refcount it. |
| 309 DISABLE_RUNNABLE_METHOD_REFCOUNT(media::FFmpegVideoDecodeEngine); | 308 DISABLE_RUNNABLE_METHOD_REFCOUNT(media::FFmpegVideoDecodeEngine); |
| OLD | NEW |