Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1238)

Unified Diff: media/filters/ffmpeg_video_decoder.cc

Issue 10704175: Add config change support to FFmpegVideoDecoder (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698