OLD | NEW |
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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 return decode_threads; | 53 return decode_threads; |
54 } | 54 } |
55 | 55 |
56 FFmpegVideoDecoder::FFmpegVideoDecoder( | 56 FFmpegVideoDecoder::FFmpegVideoDecoder( |
57 const base::Callback<MessageLoop*()>& message_loop_cb) | 57 const base::Callback<MessageLoop*()>& message_loop_cb) |
58 : message_loop_factory_cb_(message_loop_cb), | 58 : message_loop_factory_cb_(message_loop_cb), |
59 message_loop_(NULL), | 59 message_loop_(NULL), |
60 state_(kUninitialized), | 60 state_(kUninitialized), |
61 codec_context_(NULL), | 61 codec_context_(NULL), |
62 av_frame_(NULL), | 62 av_frame_(NULL), |
63 frame_rate_numerator_(0), | |
64 frame_rate_denominator_(0), | |
65 decryptor_(NULL) { | 63 decryptor_(NULL) { |
66 } | 64 } |
67 | 65 |
68 int FFmpegVideoDecoder::GetVideoBuffer(AVCodecContext* codec_context, | 66 int FFmpegVideoDecoder::GetVideoBuffer(AVCodecContext* codec_context, |
69 AVFrame* frame) { | 67 AVFrame* frame) { |
70 // Don't use |codec_context_| here! With threaded decoding, | 68 // Don't use |codec_context_| here! With threaded decoding, |
71 // it will contain unsynchronized width/height/pix_fmt values, | 69 // it will contain unsynchronized width/height/pix_fmt values, |
72 // whereas |codec_context| contains the current threads's | 70 // whereas |codec_context| contains the current threads's |
73 // updated width/height/pix_fmt, which can change for adaptive | 71 // updated width/height/pix_fmt, which can change for adaptive |
74 // content. | 72 // content. |
75 VideoFrame::Format format = PixelFormatToVideoFormat(codec_context->pix_fmt); | 73 VideoFrame::Format format = PixelFormatToVideoFormat(codec_context->pix_fmt); |
76 if (format == VideoFrame::INVALID) | 74 if (format == VideoFrame::INVALID) |
77 return AVERROR(EINVAL); | 75 return AVERROR(EINVAL); |
78 DCHECK(format == VideoFrame::YV12 || format == VideoFrame::YV16); | 76 DCHECK(format == VideoFrame::YV12 || format == VideoFrame::YV16); |
79 | 77 |
80 int width = codec_context->width; | 78 int width = codec_context->width; |
81 int height = codec_context->height; | 79 int height = codec_context->height; |
82 int ret; | 80 int ret; |
83 if ((ret = av_image_check_size(width, height, 0, NULL)) < 0) | 81 if ((ret = av_image_check_size(width, height, 0, NULL)) < 0) |
84 return ret; | 82 return ret; |
85 | 83 |
86 scoped_refptr<VideoFrame> video_frame = | 84 scoped_refptr<VideoFrame> video_frame = |
87 VideoFrame::CreateFrame(format, width, height, | 85 VideoFrame::CreateFrame(format, width, height, kNoTimestamp()); |
88 kNoTimestamp(), kNoTimestamp()); | |
89 | 86 |
90 for (int i = 0; i < 3; i++) { | 87 for (int i = 0; i < 3; i++) { |
91 frame->base[i] = video_frame->data(i); | 88 frame->base[i] = video_frame->data(i); |
92 frame->data[i] = video_frame->data(i); | 89 frame->data[i] = video_frame->data(i); |
93 frame->linesize[i] = video_frame->stride(i); | 90 frame->linesize[i] = video_frame->stride(i); |
94 } | 91 } |
95 | 92 |
96 frame->opaque = video_frame.release(); | 93 frame->opaque = video_frame.release(); |
97 frame->type = FF_BUFFER_TYPE_USER; | 94 frame->type = FF_BUFFER_TYPE_USER; |
98 frame->pkt_pts = codec_context->pkt ? codec_context->pkt->pts : | 95 frame->pkt_pts = codec_context->pkt ? codec_context->pkt->pts : |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 | 179 |
183 if (avcodec_open2(codec_context_, codec, NULL) < 0) { | 180 if (avcodec_open2(codec_context_, codec, NULL) < 0) { |
184 status_cb.Run(PIPELINE_ERROR_DECODE); | 181 status_cb.Run(PIPELINE_ERROR_DECODE); |
185 return; | 182 return; |
186 } | 183 } |
187 | 184 |
188 // Success! | 185 // Success! |
189 state_ = kNormal; | 186 state_ = kNormal; |
190 av_frame_ = avcodec_alloc_frame(); | 187 av_frame_ = avcodec_alloc_frame(); |
191 natural_size_ = config.natural_size(); | 188 natural_size_ = config.natural_size(); |
192 frame_rate_numerator_ = config.frame_rate_numerator(); | |
193 frame_rate_denominator_ = config.frame_rate_denominator(); | |
194 status_cb.Run(PIPELINE_OK); | 189 status_cb.Run(PIPELINE_OK); |
195 } | 190 } |
196 | 191 |
197 void FFmpegVideoDecoder::Read(const ReadCB& read_cb) { | 192 void FFmpegVideoDecoder::Read(const ReadCB& read_cb) { |
198 // Complete operation asynchronously on different stack of execution as per | 193 // Complete operation asynchronously on different stack of execution as per |
199 // the API contract of VideoDecoder::Read() | 194 // the API contract of VideoDecoder::Read() |
200 message_loop_->PostTask(FROM_HERE, base::Bind( | 195 message_loop_->PostTask(FROM_HERE, base::Bind( |
201 &FFmpegVideoDecoder::DoRead, this, read_cb)); | 196 &FFmpegVideoDecoder::DoRead, this, read_cb)); |
202 } | 197 } |
203 | 198 |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 *video_frame = NULL; | 493 *video_frame = NULL; |
499 return false; | 494 return false; |
500 } | 495 } |
501 | 496 |
502 if (!av_frame_->opaque) { | 497 if (!av_frame_->opaque) { |
503 LOG(ERROR) << "VideoFrame object associated with frame data not set."; | 498 LOG(ERROR) << "VideoFrame object associated with frame data not set."; |
504 return false; | 499 return false; |
505 } | 500 } |
506 *video_frame = static_cast<VideoFrame*>(av_frame_->opaque); | 501 *video_frame = static_cast<VideoFrame*>(av_frame_->opaque); |
507 | 502 |
508 if (frame_rate_numerator_ == 0) { | |
509 // A framerate of zero indicates that no timing information was available | |
510 // during initial stream demuxing, and that the framerate should be inferred | |
511 // from the first frame's duration. | |
512 frame_rate_numerator_ = buffer->GetDuration().InMicroseconds(); | |
513 frame_rate_denominator_ = base::Time::kMicrosecondsPerSecond; | |
514 } | |
515 | |
516 // Determine timestamp and calculate the duration based on the repeat | |
517 // picture count. According to FFmpeg docs, the total duration can be | |
518 // calculated as follows: | |
519 // fps = 1 / time_base | |
520 // | |
521 // duration = (1 / fps) + (repeat_pict) / (2 * fps) | |
522 // = (2 + repeat_pict) / (2 * fps) | |
523 // = (2 + repeat_pict) / (2 * (1 / time_base)) | |
524 DCHECK_LE(av_frame_->repeat_pict, 2); // Sanity check. | |
525 AVRational doubled_time_base; | |
526 doubled_time_base.num = frame_rate_denominator_; | |
527 doubled_time_base.den = frame_rate_numerator_ * 2; | |
528 | |
529 (*video_frame)->SetTimestamp( | 503 (*video_frame)->SetTimestamp( |
530 base::TimeDelta::FromMicroseconds(av_frame_->reordered_opaque)); | 504 base::TimeDelta::FromMicroseconds(av_frame_->reordered_opaque)); |
531 (*video_frame)->SetDuration( | |
532 ConvertFromTimeBase(doubled_time_base, 2 + av_frame_->repeat_pict)); | |
533 | 505 |
534 return true; | 506 return true; |
535 } | 507 } |
536 | 508 |
537 void FFmpegVideoDecoder::ReleaseFFmpegResources() { | 509 void FFmpegVideoDecoder::ReleaseFFmpegResources() { |
538 if (codec_context_) { | 510 if (codec_context_) { |
539 av_free(codec_context_->extradata); | 511 av_free(codec_context_->extradata); |
540 avcodec_close(codec_context_); | 512 avcodec_close(codec_context_); |
541 av_free(codec_context_); | 513 av_free(codec_context_); |
542 codec_context_ = NULL; | 514 codec_context_ = NULL; |
543 } | 515 } |
544 if (av_frame_) { | 516 if (av_frame_) { |
545 av_free(av_frame_); | 517 av_free(av_frame_); |
546 av_frame_ = NULL; | 518 av_frame_ = NULL; |
547 } | 519 } |
548 } | 520 } |
549 | 521 |
550 } // namespace media | 522 } // namespace media |
OLD | NEW |