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

Unified Diff: media/filters/video_decoder_impl.cc

Issue 1669002: remove AVFrame Dependency (Closed)
Patch Set: more patch Created 10 years, 8 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
« no previous file with comments | « media/filters/video_decoder_impl.h ('k') | media/filters/video_decoder_impl_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/filters/video_decoder_impl.cc
diff --git a/media/filters/video_decoder_impl.cc b/media/filters/video_decoder_impl.cc
index 9592dbb2d367b2433780284a40b3decc7de6b157..a4a655efd13e493a7fda11f3dcdc7c1c7f23ee18 100644
--- a/media/filters/video_decoder_impl.cc
+++ b/media/filters/video_decoder_impl.cc
@@ -139,31 +139,31 @@ void VideoDecoderImpl::DoDecode(Buffer* buffer, Task* done_cb) {
}
// Otherwise, attempt to decode a single frame.
- AVFrame* yuv_frame = avcodec_alloc_frame();
bool* got_frame = new bool;
+ scoped_refptr<VideoFrame>* video_frame = new scoped_refptr<VideoFrame>(NULL);
decode_engine_->DecodeFrame(
buffer,
- yuv_frame,
+ video_frame,
got_frame,
NewRunnableMethod(this,
&VideoDecoderImpl::OnDecodeComplete,
- yuv_frame,
+ video_frame,
got_frame,
done_runner.release()));
}
-void VideoDecoderImpl::OnDecodeComplete(AVFrame* yuv_frame, bool* got_frame,
- Task* done_cb) {
+void VideoDecoderImpl::OnDecodeComplete(scoped_refptr<VideoFrame>* video_frame,
+ bool* got_frame, Task* done_cb) {
// Note: The |done_runner| must be declared *last* to ensure proper
// destruction order.
- scoped_ptr_malloc<AVFrame, ScopedPtrAVFree> yuv_frame_deleter(yuv_frame);
scoped_ptr<bool> got_frame_deleter(got_frame);
+ scoped_ptr<scoped_refptr<VideoFrame> > video_frame_deleter(video_frame);
AutoTaskRunner done_runner(done_cb);
// If we actually got data back, enqueue a frame.
if (*got_frame) {
last_pts_ = FindPtsAndDuration(*time_base_, pts_heap_, last_pts_,
- yuv_frame);
+ video_frame->get());
// Pop off a pts on a successful decode since we are "using up" one
// timestamp.
@@ -179,12 +179,9 @@ void VideoDecoderImpl::OnDecodeComplete(AVFrame* yuv_frame, bool* got_frame,
NOTREACHED() << "Attempting to decode more frames than were input.";
}
- if (!EnqueueVideoFrame(
- decode_engine_->GetSurfaceFormat(), last_pts_, yuv_frame)) {
- // On an EnqueueEmptyFrame error, error out the whole pipeline and
- // set the state to kDecodeFinished.
- SignalPipelineError();
- }
+ (*video_frame)->SetTimestamp(last_pts_.timestamp);
+ (*video_frame)->SetDuration(last_pts_.duration);
+ EnqueueVideoFrame(*video_frame);
} else {
// When in kFlushCodec, any errored decode, or a 0-lengthed frame,
// is taken as a signal to stop decoding.
@@ -195,59 +192,9 @@ void VideoDecoderImpl::OnDecodeComplete(AVFrame* yuv_frame, bool* got_frame,
}
}
-bool VideoDecoderImpl::EnqueueVideoFrame(VideoFrame::Format surface_format,
- const TimeTuple& time,
- const AVFrame* frame) {
- // TODO(fbarchard): Work around for FFmpeg http://crbug.com/27675
- // The decoder is in a bad state and not decoding correctly.
- // Checking for NULL avoids a crash in CopyPlane().
- if (!frame->data[VideoFrame::kYPlane] ||
- !frame->data[VideoFrame::kUPlane] ||
- !frame->data[VideoFrame::kVPlane]) {
- return true;
- }
-
- scoped_refptr<VideoFrame> video_frame;
- VideoFrame::CreateFrame(surface_format, width_, height_,
- time.timestamp, time.duration, &video_frame);
- if (!video_frame) {
- return false;
- }
-
- // Copy the frame data since FFmpeg reuses internal buffers for AVFrame
- // output, meaning the data is only valid until the next
- // avcodec_decode_video() call.
- // TODO(scherkus): figure out pre-allocation/buffer cycling scheme.
- // TODO(scherkus): is there a cleaner way to figure out the # of planes?
- CopyPlane(VideoFrame::kYPlane, *video_frame, frame);
- CopyPlane(VideoFrame::kUPlane, *video_frame, frame);
- CopyPlane(VideoFrame::kVPlane, *video_frame, frame);
+void VideoDecoderImpl::EnqueueVideoFrame(
+ const scoped_refptr<VideoFrame>& video_frame) {
EnqueueResult(video_frame);
- return true;
-}
-
-void VideoDecoderImpl::CopyPlane(size_t plane,
- const VideoFrame& video_frame,
- const AVFrame* frame) {
- DCHECK(video_frame.width() % 2 == 0);
- const uint8* source = frame->data[plane];
- const size_t source_stride = frame->linesize[plane];
- uint8* dest = video_frame.data(plane);
- const size_t dest_stride = video_frame.stride(plane);
- size_t bytes_per_line = video_frame.width();
- size_t copy_lines = video_frame.height();
- if (plane != VideoFrame::kYPlane) {
- bytes_per_line /= 2;
- if (video_frame.format() == VideoFrame::YV12) {
- copy_lines = (copy_lines + 1) / 2;
- }
- }
- DCHECK(bytes_per_line <= source_stride && bytes_per_line <= dest_stride);
- for (size_t i = 0; i < copy_lines; ++i) {
- memcpy(dest, source, bytes_per_line);
- source += source_stride;
- dest += dest_stride;
- }
}
void VideoDecoderImpl::EnqueueEmptyFrame() {
@@ -260,29 +207,24 @@ VideoDecoderImpl::TimeTuple VideoDecoderImpl::FindPtsAndDuration(
const AVRational& time_base,
const PtsHeap& pts_heap,
const TimeTuple& last_pts,
- const AVFrame* frame) {
+ const VideoFrame* frame) {
TimeTuple pts;
- // Default |repeat_pict| to 0 because if there is no frame information,
- // we just assume the frame only plays for one time_base.
- int repeat_pict = 0;
+ // First search the VideoFrame for the pts. This is the most authoritative.
+ // Make a special exclusion for the value pts == 0. Though this is
+ // technically a valid value, it seems a number of ffmpeg codecs will
+ // mistakenly always set pts to 0.
+ DCHECK(frame);
+ base::TimeDelta timestamp = frame->GetTimestamp();
+ if (timestamp != StreamSample::kInvalidTimestamp &&
+ timestamp.ToInternalValue() != 0) {
+ pts.timestamp = ConvertTimestamp(time_base, timestamp.ToInternalValue());
+ pts.duration = ConvertTimestamp(time_base, 1 + frame->GetRepeatCount());
+ return pts;
+ }
- // First search the AVFrame for the pts. This is the most authoritative.
- // Make a special exclusion for the value frame->pts == 0. Though this
- // is technically a valid value, it seems a number of ffmpeg codecs will
- // mistakenly always set frame->pts to 0.
- //
- // Oh, and we have to cast AV_NOPTS_VALUE since it ends up becoming unsigned
- // because the value they use doesn't fit in a signed 64-bit number which
- // produces a signedness comparison warning on gcc.
- if (frame &&
- (frame->pts != static_cast<int64_t>(AV_NOPTS_VALUE)) &&
- (frame->pts != 0)) {
- pts.timestamp = ConvertTimestamp(time_base, frame->pts);
- repeat_pict = frame->repeat_pict;
- } else if (!pts_heap.IsEmpty()) {
- // If the frame did not have pts, try to get the pts from the
- // |pts_heap|.
+ if (!pts_heap.IsEmpty()) {
+ // If the frame did not have pts, try to get the pts from the |pts_heap|.
pts.timestamp = pts_heap.Top();
} else {
DCHECK(last_pts.timestamp != StreamSample::kInvalidTimestamp);
@@ -292,9 +234,7 @@ VideoDecoderImpl::TimeTuple VideoDecoderImpl::FindPtsAndDuration(
}
// Fill in the duration while accounting for repeated frames.
- //
- // TODO(ajwong): Make sure this formula is correct.
- pts.duration = ConvertTimestamp(time_base, 1 + repeat_pict);
+ pts.duration = ConvertTimestamp(time_base, 1);
return pts;
}
« no previous file with comments | « media/filters/video_decoder_impl.h ('k') | media/filters/video_decoder_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698