| Index: media/filters/ffmpeg_video_decode_engine.cc
|
| ===================================================================
|
| --- media/filters/ffmpeg_video_decode_engine.cc (revision 47632)
|
| +++ media/filters/ffmpeg_video_decode_engine.cc (working copy)
|
| @@ -4,10 +4,12 @@
|
|
|
| #include "media/filters/ffmpeg_video_decode_engine.h"
|
|
|
| +#include "base/command_line.h"
|
| #include "base/task.h"
|
| #include "media/base/buffers.h"
|
| #include "media/base/callback.h"
|
| #include "media/base/limits.h"
|
| +#include "media/base/media_switches.h"
|
| #include "media/ffmpeg/ffmpeg_common.h"
|
| #include "media/ffmpeg/ffmpeg_util.h"
|
| #include "media/filters/ffmpeg_demuxer.h"
|
| @@ -24,8 +26,9 @@
|
|
|
| void FFmpegVideoDecodeEngine::Initialize(AVStream* stream, Task* done_cb) {
|
| AutoTaskRunner done_runner(done_cb);
|
| + CHECK(state_ == kCreated);
|
|
|
| - // Always try to use two threads for video decoding. There is little reason
|
| + // 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.
|
| //
|
| @@ -33,10 +36,10 @@
|
| // 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;
|
| + // Yet another reason for having three threads :)
|
| + static const int kDecodeThreads = 3;
|
| + static const int kMaxDecodeThreads = 16;
|
|
|
| - CHECK(state_ == kCreated);
|
|
|
| codec_context_ = stream->codec;
|
| codec_context_->flags2 |= CODEC_FLAG2_FAST; // Enable faster H264 decode.
|
| @@ -47,10 +50,18 @@
|
|
|
| AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
|
|
|
| - // TODO(fbarchard): On next ffmpeg roll, retest Theora multi-threading.
|
| + // TODO(fbarchard): Improve thread logic based on size / codec.
|
| 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() &&
|
| + !StringToInt(threads, &decode_threads)) ||
|
| + decode_threads < 0 || decode_threads > kMaxDecodeThreads) {
|
| + decode_threads = kDecodeThreads;
|
| + }
|
| +
|
| // We don't allocate AVFrame on the stack since different versions of FFmpeg
|
| // may change the size of AVFrame, causing stack corruption. The solution is
|
| // to let FFmpeg allocate the structure via avcodec_alloc_frame().
|
| @@ -66,10 +77,11 @@
|
| }
|
| }
|
|
|
| +// TODO(fbarchard): Find way to remove this memcpy of the entire image.
|
| static void CopyPlane(size_t plane,
|
| scoped_refptr<VideoFrame> video_frame,
|
| const AVFrame* frame) {
|
| - DCHECK(video_frame->width() % 2 == 0);
|
| + DCHECK_EQ(video_frame->width() % 2, 0u);
|
| const uint8* source = frame->data[plane];
|
| const size_t source_stride = frame->linesize[plane];
|
| uint8* dest = video_frame->data(plane);
|
|
|