Index: media/filters/ffmpeg_video_decoder.cc |
diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc |
index 7fc80885d474546d33ad5a0676906a02b2d546df..6bcbdabc8b8b5911b12f1e2b192affabb494dee5 100644 |
--- a/media/filters/ffmpeg_video_decoder.cc |
+++ b/media/filters/ffmpeg_video_decoder.cc |
@@ -83,6 +83,8 @@ int FFmpegVideoDecoder::GetVideoBuffer(AVCodecContext* codec_context, |
scoped_refptr<VideoFrame> video_frame = |
VideoFrame::CreateFrame(format, width, height, |
+ natural_size_.width(), |
+ natural_size_.height(), |
kNoTimestamp(), kNoTimestamp()); |
for (int i = 0; i < 3; i++) { |
@@ -158,34 +160,13 @@ void FFmpegVideoDecoder::Initialize(const scoped_refptr<DemuxerStream>& stream, |
return; |
} |
- // Initialize AVCodecContext structure. |
- codec_context_ = avcodec_alloc_context3(NULL); |
- VideoDecoderConfigToAVCodecContext(config, codec_context_); |
- |
- // Enable motion vector search (potentially slow), strong deblocking filter |
- // for damaged macroblocks, and set our error detection sensitivity. |
- codec_context_->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK; |
- codec_context_->err_recognition = AV_EF_CAREFUL; |
- codec_context_->thread_count = GetThreadCount(codec_context_->codec_id); |
- codec_context_->opaque = this; |
- codec_context_->flags |= CODEC_FLAG_EMU_EDGE; |
- codec_context_->get_buffer = GetVideoBufferImpl; |
- codec_context_->release_buffer = ReleaseVideoBufferImpl; |
- |
- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); |
- if (!codec) { |
- status_cb.Run(PIPELINE_ERROR_DECODE); |
- return; |
- } |
- |
- if (avcodec_open2(codec_context_, codec, NULL) < 0) { |
+ if (!AllocateFFmpegResources(config)) { |
Ami GONE FROM CHROMIUM
2012/07/13 00:59:05
I wonder if it doesn't make sense to inline AFFMR(
|
status_cb.Run(PIPELINE_ERROR_DECODE); |
return; |
} |
// Success! |
state_ = kNormal; |
- av_frame_ = avcodec_alloc_frame(); |
natural_size_ = config.natural_size(); |
frame_rate_numerator_ = config.frame_rate_numerator(); |
frame_rate_denominator_ = config.frame_rate_denominator(); |
Ami GONE FROM CHROMIUM
2012/07/13 00:59:05
...in which case these can go away
|
@@ -301,10 +282,18 @@ void FFmpegVideoDecoder::DoDecodeBuffer( |
return; |
} |
- if (status != DemuxerStream::kOk) { |
- DecoderStatus decoder_status = |
- (status == DemuxerStream::kAborted) ? kOk : kDecodeError; |
- base::ResetAndReturn(&read_cb_).Run(decoder_status, NULL); |
+ if (status == DemuxerStream::kAborted) { |
+ base::ResetAndReturn(&read_cb_).Run(kOk, NULL); |
+ return; |
+ } |
+ |
+ if (status == DemuxerStream::kConfigChanged) { |
+ if (!HandleConfigChange()) { |
+ base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); |
+ return; |
+ } |
+ |
+ ReadFromDemuxerStream(); |
return; |
} |
@@ -477,6 +466,36 @@ void FFmpegVideoDecoder::DeliverFrame( |
base::ResetAndReturn(&read_cb_).Run(kOk, video_frame); |
} |
+bool FFmpegVideoDecoder::AllocateFFmpegResources( |
+ const VideoDecoderConfig& config) { |
+ DCHECK(!codec_context_); |
+ DCHECK(!av_frame_); |
+ |
+ // Initialize AVCodecContext structure. |
+ codec_context_ = avcodec_alloc_context3(NULL); |
+ VideoDecoderConfigToAVCodecContext(config, codec_context_); |
+ |
+ // Enable motion vector search (potentially slow), strong deblocking filter |
+ // for damaged macroblocks, and set our error detection sensitivity. |
+ codec_context_->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK; |
+ codec_context_->err_recognition = AV_EF_CAREFUL; |
+ codec_context_->thread_count = GetThreadCount(codec_context_->codec_id); |
+ codec_context_->opaque = this; |
+ codec_context_->flags |= CODEC_FLAG_EMU_EDGE; |
+ codec_context_->get_buffer = GetVideoBufferImpl; |
+ codec_context_->release_buffer = ReleaseVideoBufferImpl; |
+ |
+ AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); |
+ if (!codec) |
+ return false; |
+ |
+ if (avcodec_open2(codec_context_, codec, NULL) < 0) |
+ return false; |
+ |
+ av_frame_ = avcodec_alloc_frame(); |
+ return true; |
+} |
+ |
void FFmpegVideoDecoder::ReleaseFFmpegResources() { |
if (codec_context_) { |
av_free(codec_context_->extradata); |
@@ -490,4 +509,20 @@ void FFmpegVideoDecoder::ReleaseFFmpegResources() { |
} |
} |
+bool FFmpegVideoDecoder::HandleConfigChange() { |
+ const VideoDecoderConfig& config = demuxer_stream_->video_decoder_config(); |
+ |
+ if (!config.IsValidConfig()) |
+ return false; |
+ |
+ ReleaseFFmpegResources(); |
+ if (!AllocateFFmpegResources(config)) |
+ return false; |
+ |
+ natural_size_ = config.natural_size(); |
+ frame_rate_numerator_ = config.frame_rate_numerator(); |
+ frame_rate_denominator_ = config.frame_rate_denominator(); |
+ return true; |
+} |
+ |
} // namespace media |