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

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

Issue 11993002: Tighten up media::DecoderBuffer API contract for end of stream buffers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 11 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_demuxer_unittest.cc ('k') | no next file » | 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 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 } 302 }
303 303
304 scoped_refptr<VideoFrame> video_frame; 304 scoped_refptr<VideoFrame> video_frame;
305 if (!Decode(buffer, &video_frame)) { 305 if (!Decode(buffer, &video_frame)) {
306 state_ = kDecodeFinished; 306 state_ = kDecodeFinished;
307 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); 307 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL);
308 return; 308 return;
309 } 309 }
310 310
311 // Any successful decode counts! 311 // Any successful decode counts!
312 if (buffer->GetDataSize()) { 312 if (!buffer->IsEndOfStream() && buffer->GetDataSize() > 0) {
313 PipelineStatistics statistics; 313 PipelineStatistics statistics;
314 statistics.video_bytes_decoded = buffer->GetDataSize(); 314 statistics.video_bytes_decoded = buffer->GetDataSize();
315 statistics_cb_.Run(statistics); 315 statistics_cb_.Run(statistics);
316 } 316 }
317 317
318 // If we didn't get a frame then we've either completely finished decoding or 318 // If we didn't get a frame then we've either completely finished decoding or
319 // we need more data. 319 // we need more data.
320 if (!video_frame) { 320 if (!video_frame) {
321 if (state_ == kFlushCodec) { 321 if (state_ == kFlushCodec) {
322 state_ = kDecodeFinished; 322 state_ = kDecodeFinished;
323 base::ResetAndReturn(&read_cb_).Run(kOk, VideoFrame::CreateEmptyFrame()); 323 base::ResetAndReturn(&read_cb_).Run(kOk, VideoFrame::CreateEmptyFrame());
324 return; 324 return;
325 } 325 }
326 326
327 ReadFromDemuxerStream(); 327 ReadFromDemuxerStream();
328 return; 328 return;
329 } 329 }
330 330
331 base::ResetAndReturn(&read_cb_).Run(kOk, video_frame); 331 base::ResetAndReturn(&read_cb_).Run(kOk, video_frame);
332 } 332 }
333 333
334 bool FFmpegVideoDecoder::Decode( 334 bool FFmpegVideoDecoder::Decode(
335 const scoped_refptr<DecoderBuffer>& buffer, 335 const scoped_refptr<DecoderBuffer>& buffer,
336 scoped_refptr<VideoFrame>* video_frame) { 336 scoped_refptr<VideoFrame>* video_frame) {
337 DCHECK(video_frame); 337 DCHECK(video_frame);
338 338
339 // Reset frame to default values.
340 avcodec_get_frame_defaults(av_frame_);
341
339 // Create a packet for input data. 342 // Create a packet for input data.
340 // Due to FFmpeg API changes we no longer have const read-only pointers. 343 // Due to FFmpeg API changes we no longer have const read-only pointers.
341 AVPacket packet; 344 AVPacket packet;
342 av_init_packet(&packet); 345 av_init_packet(&packet);
343 packet.data = const_cast<uint8*>(buffer->GetData()); 346 if (buffer->IsEndOfStream()) {
344 packet.size = buffer->GetDataSize(); 347 packet.data = NULL;
348 packet.size = 0;
349 } else {
350 packet.data = const_cast<uint8*>(buffer->GetData());
351 packet.size = buffer->GetDataSize();
345 352
346 // Let FFmpeg handle presentation timestamp reordering. 353 // Let FFmpeg handle presentation timestamp reordering.
347 codec_context_->reordered_opaque = buffer->GetTimestamp().InMicroseconds(); 354 codec_context_->reordered_opaque = buffer->GetTimestamp().InMicroseconds();
348 355
349 // Reset frame to default values. 356 // This is for codecs not using get_buffer to initialize
350 avcodec_get_frame_defaults(av_frame_); 357 // |av_frame_->reordered_opaque|
351 358 av_frame_->reordered_opaque = codec_context_->reordered_opaque;
352 // This is for codecs not using get_buffer to initialize 359 }
353 // |av_frame_->reordered_opaque|
354 av_frame_->reordered_opaque = codec_context_->reordered_opaque;
355 360
356 int frame_decoded = 0; 361 int frame_decoded = 0;
357 int result = avcodec_decode_video2(codec_context_, 362 int result = avcodec_decode_video2(codec_context_,
358 av_frame_, 363 av_frame_,
359 &frame_decoded, 364 &frame_decoded,
360 &packet); 365 &packet);
361 // Log the problem if we can't decode a video frame and exit early. 366 // Log the problem if we can't decode a video frame and exit early.
362 if (result < 0) { 367 if (result < 0) {
363 LOG(ERROR) << "Error decoding a video frame with timestamp: " 368 LOG(ERROR) << "Error decoding video: " << buffer->AsHumanReadableString();
364 << buffer->GetTimestamp().InMicroseconds() << " us, duration: "
365 << buffer->GetDuration().InMicroseconds() << " us, packet size: "
366 << buffer->GetDataSize() << " bytes";
367 *video_frame = NULL; 369 *video_frame = NULL;
368 return false; 370 return false;
369 } 371 }
370 372
371 // If no frame was produced then signal that more data is required to 373 // If no frame was produced then signal that more data is required to
372 // produce more frames. This can happen under two circumstances: 374 // produce more frames. This can happen under two circumstances:
373 // 1) Decoder was recently initialized/flushed 375 // 1) Decoder was recently initialized/flushed
374 // 2) End of stream was reached and all internal frames have been output 376 // 2) End of stream was reached and all internal frames have been output
375 if (frame_decoded == 0) { 377 if (frame_decoded == 0) {
376 *video_frame = NULL; 378 *video_frame = NULL;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 if (!codec || avcodec_open2(codec_context_, codec, NULL) < 0) { 448 if (!codec || avcodec_open2(codec_context_, codec, NULL) < 0) {
447 ReleaseFFmpegResources(); 449 ReleaseFFmpegResources();
448 return false; 450 return false;
449 } 451 }
450 452
451 av_frame_ = avcodec_alloc_frame(); 453 av_frame_ = avcodec_alloc_frame();
452 return true; 454 return true;
453 } 455 }
454 456
455 } // namespace media 457 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/ffmpeg_demuxer_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698