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 23 matching lines...) Expand all Loading... |
34 avcodec_close(codec_context_); | 34 avcodec_close(codec_context_); |
35 av_free(codec_context_); | 35 av_free(codec_context_); |
36 } | 36 } |
37 } | 37 } |
38 | 38 |
39 void FFmpegVideoDecodeEngine::Initialize( | 39 void FFmpegVideoDecodeEngine::Initialize( |
40 MessageLoop* message_loop, | 40 MessageLoop* message_loop, |
41 VideoDecodeEngine::EventHandler* event_handler, | 41 VideoDecodeEngine::EventHandler* event_handler, |
42 VideoDecodeContext* context, | 42 VideoDecodeContext* context, |
43 const VideoDecoderConfig& config) { | 43 const VideoDecoderConfig& config) { |
| 44 frame_rate_numerator_ = config.frame_rate_numerator(); |
| 45 frame_rate_denominator_ = config.frame_rate_denominator(); |
| 46 |
44 // Always try to use three threads for video decoding. There is little reason | 47 // Always try to use three threads for video decoding. There is little reason |
45 // not to since current day CPUs tend to be multi-core and we measured | 48 // not to since current day CPUs tend to be multi-core and we measured |
46 // performance benefits on older machines such as P4s with hyperthreading. | 49 // performance benefits on older machines such as P4s with hyperthreading. |
47 // | 50 // |
48 // Handling decoding on separate threads also frees up the pipeline thread to | 51 // Handling decoding on separate threads also frees up the pipeline thread to |
49 // continue processing. Although it'd be nice to have the option of a single | 52 // continue processing. Although it'd be nice to have the option of a single |
50 // decoding thread, FFmpeg treats having one thread the same as having zero | 53 // decoding thread, FFmpeg treats having one thread the same as having zero |
51 // threads (i.e., avcodec_decode_video() will execute on the calling thread). | 54 // threads (i.e., avcodec_decode_video() will execute on the calling thread). |
52 // Yet another reason for having two threads :) | 55 // Yet another reason for having two threads :) |
53 static const int kDecodeThreads = 2; | 56 static const int kDecodeThreads = 2; |
54 static const int kMaxDecodeThreads = 16; | 57 static const int kMaxDecodeThreads = 16; |
55 | 58 |
56 // Initialize AVCodecContext structure. | 59 // Initialize AVCodecContext structure. |
57 codec_context_ = avcodec_alloc_context(); | 60 codec_context_ = avcodec_alloc_context(); |
58 codec_context_->pix_fmt = VideoFormatToPixelFormat(config.format()); | 61 VideoDecoderConfigToAVCodecContext(config, codec_context_); |
59 codec_context_->codec_type = AVMEDIA_TYPE_VIDEO; | |
60 codec_context_->codec_id = VideoCodecToCodecID(config.codec()); | |
61 codec_context_->coded_width = config.coded_size().width(); | |
62 codec_context_->coded_height = config.coded_size().height(); | |
63 | |
64 frame_rate_numerator_ = config.frame_rate_numerator(); | |
65 frame_rate_denominator_ = config.frame_rate_denominator(); | |
66 | |
67 if (config.extra_data() != NULL) { | |
68 codec_context_->extradata_size = config.extra_data_size(); | |
69 codec_context_->extradata = reinterpret_cast<uint8_t*>( | |
70 av_malloc(config.extra_data_size() + FF_INPUT_BUFFER_PADDING_SIZE)); | |
71 memcpy(codec_context_->extradata, config.extra_data(), | |
72 config.extra_data_size()); | |
73 memset(codec_context_->extradata + config.extra_data_size(), '\0', | |
74 FF_INPUT_BUFFER_PADDING_SIZE); | |
75 } | |
76 | 62 |
77 // Enable motion vector search (potentially slow), strong deblocking filter | 63 // Enable motion vector search (potentially slow), strong deblocking filter |
78 // for damaged macroblocks, and set our error detection sensitivity. | 64 // for damaged macroblocks, and set our error detection sensitivity. |
79 codec_context_->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK; | 65 codec_context_->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK; |
80 codec_context_->error_recognition = FF_ER_CAREFUL; | 66 codec_context_->error_recognition = FF_ER_CAREFUL; |
81 | 67 |
82 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); | 68 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); |
83 | 69 |
84 // TODO(fbarchard): Improve thread logic based on size / codec. | 70 // TODO(fbarchard): Improve thread logic based on size / codec. |
85 // TODO(fbarchard): Fix bug affecting video-cookie.html | 71 // TODO(fbarchard): Fix bug affecting video-cookie.html |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 DCHECK_EQ(output_eos_reached_, false); | 288 DCHECK_EQ(output_eos_reached_, false); |
303 pending_input_buffers_++; | 289 pending_input_buffers_++; |
304 event_handler_->ProduceVideoSample(NULL); | 290 event_handler_->ProduceVideoSample(NULL); |
305 } | 291 } |
306 | 292 |
307 } // namespace media | 293 } // namespace media |
308 | 294 |
309 // Disable refcounting for this object because this object only lives | 295 // Disable refcounting for this object because this object only lives |
310 // on the video decoder thread and there's no need to refcount it. | 296 // on the video decoder thread and there's no need to refcount it. |
311 DISABLE_RUNNABLE_METHOD_REFCOUNT(media::FFmpegVideoDecodeEngine); | 297 DISABLE_RUNNABLE_METHOD_REFCOUNT(media::FFmpegVideoDecodeEngine); |
OLD | NEW |