summaryrefslogtreecommitdiffstats
path: root/media/video
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-07 07:12:41 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-07 07:12:41 +0000
commite8d69ff6b29e372314d6e2677d363b80fed76390 (patch)
treed3d05ec22beae12ec5c7b9ef9de2b8736152e5d4 /media/video
parentd8593a6d7b3b78cec81810c436762aebcbe7e166 (diff)
downloadchromium_src-e8d69ff6b29e372314d6e2677d363b80fed76390.zip
chromium_src-e8d69ff6b29e372314d6e2677d363b80fed76390.tar.gz
chromium_src-e8d69ff6b29e372314d6e2677d363b80fed76390.tar.bz2
Collapse FFmpegVideoDecodeEngine into FFmpegVideoDecoder and remove VideoDecodeEngine.
Review URL: http://codereview.chromium.org/8772069 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113358 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/video')
-rw-r--r--media/video/ffmpeg_video_decode_engine.cc200
-rw-r--r--media/video/ffmpeg_video_decode_engine.h46
-rw-r--r--media/video/video_decode_engine.h45
3 files changed, 0 insertions, 291 deletions
diff --git a/media/video/ffmpeg_video_decode_engine.cc b/media/video/ffmpeg_video_decode_engine.cc
deleted file mode 100644
index a6bff26..0000000
--- a/media/video/ffmpeg_video_decode_engine.cc
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/video/ffmpeg_video_decode_engine.h"
-
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "base/string_number_conversions.h"
-#include "media/base/buffers.h"
-#include "media/base/media_switches.h"
-#include "media/base/video_decoder_config.h"
-#include "media/base/video_util.h"
-#include "media/ffmpeg/ffmpeg_common.h"
-
-namespace media {
-
-FFmpegVideoDecodeEngine::FFmpegVideoDecodeEngine()
- : codec_context_(NULL),
- av_frame_(NULL),
- frame_rate_numerator_(0),
- frame_rate_denominator_(0) {
-}
-
-FFmpegVideoDecodeEngine::~FFmpegVideoDecodeEngine() {
- Uninitialize();
-}
-
-bool FFmpegVideoDecodeEngine::Initialize(const VideoDecoderConfig& config) {
- frame_rate_numerator_ = config.frame_rate_numerator();
- frame_rate_denominator_ = config.frame_rate_denominator();
-
- // Always try to use three threads for video decoding. There is little reason
- // not to since current day CPUs tend to be multi-core and we measured
- // performance benefits on older machines such as P4s with hyperthreading.
- //
- // Handling decoding on separate threads also frees up the pipeline thread to
- // continue processing. Although it'd be nice to have the option of a single
- // decoding thread, FFmpeg treats having one thread the same as having zero
- // threads (i.e., avcodec_decode_video() will execute on the calling thread).
- // Yet another reason for having two threads :)
- static const int kDecodeThreads = 2;
- static const int kMaxDecodeThreads = 16;
-
- // Initialize AVCodecContext structure.
- codec_context_ = avcodec_alloc_context();
- 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_->error_recognition = FF_ER_CAREFUL;
-
- AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
-
- // TODO(fbarchard): Improve thread logic based on size / codec.
- // TODO(fbarchard): Fix bug affecting video-cookie.html
- // 07/21/11(ihf): Still about 20 failures when enabling.
- int decode_threads = (codec_context_->codec_id == CODEC_ID_THEORA) ?
- 1 : kDecodeThreads;
-
- const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
- std::string threads(cmd_line->GetSwitchValueASCII(switches::kVideoThreads));
- if ((!threads.empty() &&
- !base::StringToInt(threads, &decode_threads)) ||
- decode_threads < 0 || decode_threads > kMaxDecodeThreads) {
- decode_threads = kDecodeThreads;
- }
-
- codec_context_->thread_count = decode_threads;
-
- av_frame_ = avcodec_alloc_frame();
-
- // Open the codec!
- return codec && avcodec_open(codec_context_, codec) >= 0;
-}
-
-void FFmpegVideoDecodeEngine::Uninitialize() {
- if (codec_context_) {
- av_free(codec_context_->extradata);
- avcodec_close(codec_context_);
- av_free(codec_context_);
- codec_context_ = NULL;
- }
- if (av_frame_) {
- av_free(av_frame_);
- av_frame_ = NULL;
- }
- frame_rate_numerator_ = 0;
- frame_rate_denominator_ = 0;
-}
-
-bool FFmpegVideoDecodeEngine::Decode(const scoped_refptr<Buffer>& buffer,
- scoped_refptr<VideoFrame>* video_frame) {
- DCHECK(video_frame);
-
- // Create a packet for input data.
- // Due to FFmpeg API changes we no longer have const read-only pointers.
- AVPacket packet;
- av_init_packet(&packet);
- packet.data = const_cast<uint8*>(buffer->GetData());
- packet.size = buffer->GetDataSize();
-
- // Let FFmpeg handle presentation timestamp reordering.
- codec_context_->reordered_opaque = buffer->GetTimestamp().InMicroseconds();
-
- // This is for codecs not using get_buffer to initialize
- // |av_frame_->reordered_opaque|
- av_frame_->reordered_opaque = codec_context_->reordered_opaque;
-
- int frame_decoded = 0;
- int result = avcodec_decode_video2(codec_context_,
- av_frame_,
- &frame_decoded,
- &packet);
- // Log the problem if we can't decode a video frame and exit early.
- if (result < 0) {
- LOG(ERROR) << "Error decoding a video frame with timestamp: "
- << buffer->GetTimestamp().InMicroseconds() << " us, duration: "
- << buffer->GetDuration().InMicroseconds() << " us, packet size: "
- << buffer->GetDataSize() << " bytes";
- *video_frame = NULL;
- return false;
- }
-
- // If no frame was produced then signal that more data is required to
- // produce more frames. This can happen under two circumstances:
- // 1) Decoder was recently initialized/flushed
- // 2) End of stream was reached and all internal frames have been output
- if (frame_decoded == 0) {
- *video_frame = NULL;
- return true;
- }
-
- // 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 (!av_frame_->data[VideoFrame::kYPlane] ||
- !av_frame_->data[VideoFrame::kUPlane] ||
- !av_frame_->data[VideoFrame::kVPlane]) {
- LOG(ERROR) << "Video frame was produced yet has invalid frame data.";
- *video_frame = NULL;
- return false;
- }
-
- // We've got a frame! Make sure we have a place to store it.
- *video_frame = AllocateVideoFrame();
- if (!(*video_frame)) {
- LOG(ERROR) << "Failed to allocate video frame";
- return false;
- }
-
- // Determine timestamp and calculate the duration based on the repeat picture
- // count. According to FFmpeg docs, the total duration can be calculated as
- // follows:
- // fps = 1 / time_base
- //
- // duration = (1 / fps) + (repeat_pict) / (2 * fps)
- // = (2 + repeat_pict) / (2 * fps)
- // = (2 + repeat_pict) / (2 * (1 / time_base))
- DCHECK_LE(av_frame_->repeat_pict, 2); // Sanity check.
- AVRational doubled_time_base;
- doubled_time_base.num = frame_rate_denominator_;
- doubled_time_base.den = frame_rate_numerator_ * 2;
-
- (*video_frame)->SetTimestamp(
- base::TimeDelta::FromMicroseconds(av_frame_->reordered_opaque));
- (*video_frame)->SetDuration(
- ConvertFromTimeBase(doubled_time_base, 2 + av_frame_->repeat_pict));
-
- // 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.
- int y_rows = codec_context_->height;
- int uv_rows = codec_context_->height;
- if (codec_context_->pix_fmt == PIX_FMT_YUV420P) {
- uv_rows /= 2;
- }
-
- CopyYPlane(av_frame_->data[0], av_frame_->linesize[0], y_rows, *video_frame);
- CopyUPlane(av_frame_->data[1], av_frame_->linesize[1], uv_rows, *video_frame);
- CopyVPlane(av_frame_->data[2], av_frame_->linesize[2], uv_rows, *video_frame);
-
- return true;
-}
-
-void FFmpegVideoDecodeEngine::Flush() {
- avcodec_flush_buffers(codec_context_);
-}
-
-scoped_refptr<VideoFrame> FFmpegVideoDecodeEngine::AllocateVideoFrame() {
- VideoFrame::Format format = PixelFormatToVideoFormat(codec_context_->pix_fmt);
- size_t width = codec_context_->width;
- size_t height = codec_context_->height;
-
- return VideoFrame::CreateFrame(format, width, height,
- kNoTimestamp, kNoTimestamp);
-}
-
-} // namespace media
diff --git a/media/video/ffmpeg_video_decode_engine.h b/media/video/ffmpeg_video_decode_engine.h
deleted file mode 100644
index 072507a..0000000
--- a/media/video/ffmpeg_video_decode_engine.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_VIDEO_FFMPEG_VIDEO_DECODE_ENGINE_H_
-#define MEDIA_VIDEO_FFMPEG_VIDEO_DECODE_ENGINE_H_
-
-#include "base/compiler_specific.h"
-#include "media/video/video_decode_engine.h"
-
-struct AVCodecContext;
-struct AVFrame;
-
-namespace media {
-
-class MEDIA_EXPORT FFmpegVideoDecodeEngine : public VideoDecodeEngine {
- public:
- FFmpegVideoDecodeEngine();
- virtual ~FFmpegVideoDecodeEngine();
-
- // VideoDecodeEngine implementation.
- virtual bool Initialize(const VideoDecoderConfig& config) OVERRIDE;
- virtual void Uninitialize() OVERRIDE;
- virtual bool Decode(const scoped_refptr<Buffer>& buffer,
- scoped_refptr<VideoFrame>* video_frame) OVERRIDE;
- virtual void Flush() OVERRIDE;
-
- private:
- // Allocates a video frame based on the current format and dimensions based on
- // the current state of |codec_context_|.
- scoped_refptr<VideoFrame> AllocateVideoFrame();
-
- // FFmpeg structures owned by this object.
- AVCodecContext* codec_context_;
- AVFrame* av_frame_;
-
- // Frame rate of the video.
- int frame_rate_numerator_;
- int frame_rate_denominator_;
-
- DISALLOW_COPY_AND_ASSIGN(FFmpegVideoDecodeEngine);
-};
-
-} // namespace media
-
-#endif // MEDIA_VIDEO_FFMPEG_VIDEO_DECODE_ENGINE_H_
diff --git a/media/video/video_decode_engine.h b/media/video/video_decode_engine.h
deleted file mode 100644
index 4599331..0000000
--- a/media/video/video_decode_engine.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_VIDEO_VIDEO_DECODE_ENGINE_H_
-#define MEDIA_VIDEO_VIDEO_DECODE_ENGINE_H_
-
-#include "base/memory/ref_counted.h"
-#include "media/base/media_export.h"
-
-namespace media {
-
-class Buffer;
-class VideoDecoderConfig;
-class VideoFrame;
-
-class MEDIA_EXPORT VideoDecodeEngine {
- public:
- virtual ~VideoDecodeEngine() {}
-
- // Initialize the engine with specified configuration, returning true if
- // successful.
- virtual bool Initialize(const VideoDecoderConfig& config) = 0;
-
- // Uninitialize the engine, freeing all resources. Calls to Flush() or
- // Decode() will have no effect afterwards.
- virtual void Uninitialize() = 0;
-
- // Decode the encoded video data and store the result (if any) into
- // |video_frame|. Note that a frame may not always be produced if the
- // decode engine has insufficient encoded data. In such circumstances,
- // additional calls to Decode() may be required.
- //
- // Returns true if decoding was successful (includes zero length input and end
- // of stream), false if a decoding error occurred.
- virtual bool Decode(const scoped_refptr<Buffer>& buffer,
- scoped_refptr<VideoFrame>* video_frame) = 0;
-
- // Discard all pending data that has yet to be returned via Decode().
- virtual void Flush() = 0;
-};
-
-} // namespace media
-
-#endif // MEDIA_VIDEO_VIDEO_DECODE_ENGINE_H_