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

Side by Side Diff: media/filters/ffmpeg_video_decoder.cc

Issue 10828425: Add support for config changes during playback to FFmpegVideoDecoder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add config_change_pending_ initializers to constructors. Created 8 years, 4 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/filters/ffmpeg_video_decoder.h ('k') | media/filters/pipeline_integration_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 DCHECK(!demuxer_stream_); 151 DCHECK(!demuxer_stream_);
152 152
153 if (!stream) { 153 if (!stream) {
154 status_cb.Run(PIPELINE_ERROR_DECODE); 154 status_cb.Run(PIPELINE_ERROR_DECODE);
155 return; 155 return;
156 } 156 }
157 157
158 demuxer_stream_ = stream; 158 demuxer_stream_ = stream;
159 statistics_cb_ = statistics_cb; 159 statistics_cb_ = statistics_cb;
160 160
161 const VideoDecoderConfig& config = stream->video_decoder_config(); 161 if (!ConfigureDecoder()) {
162
163 // TODO(scherkus): this check should go in Pipeline prior to creating
164 // decoder objects.
165 if (!config.IsValidConfig()) {
166 DLOG(ERROR) << "Invalid video stream - " << config.AsHumanReadableString();
167 status_cb.Run(PIPELINE_ERROR_DECODE);
168 return;
169 }
170
171 // Initialize AVCodecContext structure.
172 codec_context_ = avcodec_alloc_context3(NULL);
173 VideoDecoderConfigToAVCodecContext(config, codec_context_);
174
175 // Enable motion vector search (potentially slow), strong deblocking filter
176 // for damaged macroblocks, and set our error detection sensitivity.
177 codec_context_->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
178 codec_context_->err_recognition = AV_EF_CAREFUL;
179 codec_context_->thread_count = GetThreadCount(codec_context_->codec_id);
180 codec_context_->opaque = this;
181 codec_context_->flags |= CODEC_FLAG_EMU_EDGE;
182 codec_context_->get_buffer = GetVideoBufferImpl;
183 codec_context_->release_buffer = ReleaseVideoBufferImpl;
184
185 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
186 if (!codec) {
187 status_cb.Run(PIPELINE_ERROR_DECODE);
188 return;
189 }
190
191 if (avcodec_open2(codec_context_, codec, NULL) < 0) {
192 status_cb.Run(PIPELINE_ERROR_DECODE); 162 status_cb.Run(PIPELINE_ERROR_DECODE);
193 return; 163 return;
194 } 164 }
195 165
196 // Success! 166 // Success!
197 state_ = kNormal; 167 state_ = kNormal;
198 av_frame_ = avcodec_alloc_frame();
199 status_cb.Run(PIPELINE_OK); 168 status_cb.Run(PIPELINE_OK);
200 } 169 }
201 170
202 void FFmpegVideoDecoder::Read(const ReadCB& read_cb) { 171 void FFmpegVideoDecoder::Read(const ReadCB& read_cb) {
203 // Complete operation asynchronously on different stack of execution as per 172 // Complete operation asynchronously on different stack of execution as per
204 // the API contract of VideoDecoder::Read() 173 // the API contract of VideoDecoder::Read()
205 message_loop_->PostTask(FROM_HERE, base::Bind( 174 message_loop_->PostTask(FROM_HERE, base::Bind(
206 &FFmpegVideoDecoder::DoRead, this, read_cb)); 175 &FFmpegVideoDecoder::DoRead, this, read_cb));
207 } 176 }
208 177
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 DoStop(); 282 DoStop();
314 return; 283 return;
315 } 284 }
316 285
317 if (!reset_cb_.is_null()) { 286 if (!reset_cb_.is_null()) {
318 base::ResetAndReturn(&read_cb_).Run(kOk, NULL); 287 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
319 DoReset(); 288 DoReset();
320 return; 289 return;
321 } 290 }
322 291
323 if (status != DemuxerStream::kOk) { 292 if (status == DemuxerStream::kAborted) {
324 Status decoder_status = 293 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
325 (status == DemuxerStream::kAborted) ? kOk : kDecodeError;
326 base::ResetAndReturn(&read_cb_).Run(decoder_status, NULL);
327 return; 294 return;
328 } 295 }
329 296
297 if (status == DemuxerStream::kConfigChanged) {
298 if (!ConfigureDecoder()) {
299 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL);
300 return;
301 }
302
303 ReadFromDemuxerStream();
304 return;
305 }
306
330 DCHECK_EQ(status, DemuxerStream::kOk); 307 DCHECK_EQ(status, DemuxerStream::kOk);
331 308
332 if (buffer->GetDecryptConfig() && buffer->GetDataSize()) { 309 if (buffer->GetDecryptConfig() && buffer->GetDataSize()) {
333 decryptor_->Decrypt(buffer, 310 decryptor_->Decrypt(buffer,
334 base::Bind(&FFmpegVideoDecoder::BufferDecrypted, this)); 311 base::Bind(&FFmpegVideoDecoder::BufferDecrypted, this));
335 return; 312 return;
336 } 313 }
337 314
338 DecodeBuffer(buffer); 315 DecodeBuffer(buffer);
339 } 316 }
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 avcodec_close(codec_context_); 494 avcodec_close(codec_context_);
518 av_free(codec_context_); 495 av_free(codec_context_);
519 codec_context_ = NULL; 496 codec_context_ = NULL;
520 } 497 }
521 if (av_frame_) { 498 if (av_frame_) {
522 av_free(av_frame_); 499 av_free(av_frame_);
523 av_frame_ = NULL; 500 av_frame_ = NULL;
524 } 501 }
525 } 502 }
526 503
504 bool FFmpegVideoDecoder::ConfigureDecoder() {
505 const VideoDecoderConfig& config = demuxer_stream_->video_decoder_config();
506
507 if (!config.IsValidConfig()) {
508 DLOG(ERROR) << "Invalid video stream - " << config.AsHumanReadableString();
509 return false;
510 }
511
512 // Release existing decoder resources if necessary.
513 ReleaseFFmpegResources();
514
515 // Initialize AVCodecContext structure.
516 codec_context_ = avcodec_alloc_context3(NULL);
517 VideoDecoderConfigToAVCodecContext(config, codec_context_);
518
519 // Enable motion vector search (potentially slow), strong deblocking filter
520 // for damaged macroblocks, and set our error detection sensitivity.
521 codec_context_->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
522 codec_context_->err_recognition = AV_EF_CAREFUL;
523 codec_context_->thread_count = GetThreadCount(codec_context_->codec_id);
524 codec_context_->opaque = this;
525 codec_context_->flags |= CODEC_FLAG_EMU_EDGE;
526 codec_context_->get_buffer = GetVideoBufferImpl;
527 codec_context_->release_buffer = ReleaseVideoBufferImpl;
528
529 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
530 if (!codec)
531 return false;
532
533 if (avcodec_open2(codec_context_, codec, NULL) < 0)
534 return false;
535
536 av_frame_ = avcodec_alloc_frame();
537 return true;
538 }
539
527 } // namespace media 540 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/ffmpeg_video_decoder.h ('k') | media/filters/pipeline_integration_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698