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

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

Issue 2448453004: scale video threads with resolution (Closed)
Patch Set: comment update Created 4 years, 1 month 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
« no previous file with comments | « no previous file | 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 <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <string> 11 #include <string>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/callback_helpers.h" 14 #include "base/callback_helpers.h"
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/location.h" 16 #include "base/location.h"
17 #include "base/single_thread_task_runner.h" 17 #include "base/single_thread_task_runner.h"
18 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_number_conversions.h"
19 #include "base/sys_info.h"
19 #include "media/base/bind_to_current_loop.h" 20 #include "media/base/bind_to_current_loop.h"
20 #include "media/base/decoder_buffer.h" 21 #include "media/base/decoder_buffer.h"
21 #include "media/base/limits.h" 22 #include "media/base/limits.h"
22 #include "media/base/media_switches.h" 23 #include "media/base/media_switches.h"
23 #include "media/base/timestamp_constants.h" 24 #include "media/base/timestamp_constants.h"
24 #include "media/base/video_frame.h" 25 #include "media/base/video_frame.h"
25 #include "media/base/video_util.h" 26 #include "media/base/video_util.h"
26 #include "media/ffmpeg/ffmpeg_common.h" 27 #include "media/ffmpeg/ffmpeg_common.h"
27 #include "media/filters/ffmpeg_glue.h" 28 #include "media/filters/ffmpeg_glue.h"
28 29
29 namespace media { 30 namespace media {
30 31
31 // Always try to use three threads for video decoding. There is little reason 32 // Always try to use three threads for video decoding. There is little reason
DaleCurtis 2016/10/27 18:11:34 Ahem :)
hubbe 2016/10/27 20:36:47 Comment updated.
32 // not to since current day CPUs tend to be multi-core and we measured 33 // not to since current day CPUs tend to be multi-core and we measured
33 // performance benefits on older machines such as P4s with hyperthreading. 34 // performance benefits on older machines such as P4s with hyperthreading.
34 // 35 //
35 // Handling decoding on separate threads also frees up the pipeline thread to 36 // Handling decoding on separate threads also frees up the pipeline thread to
36 // continue processing. Although it'd be nice to have the option of a single 37 // continue processing. Although it'd be nice to have the option of a single
37 // decoding thread, FFmpeg treats having one thread the same as having zero 38 // decoding thread, FFmpeg treats having one thread the same as having zero
38 // threads (i.e., avcodec_decode_video() will execute on the calling thread). 39 // threads (i.e., avcodec_decode_video() will execute on the calling thread).
39 // Yet another reason for having two threads :) 40 // Yet another reason for having two threads :)
40 static const int kDecodeThreads = 2; 41 static const int kDecodeThreads = 2;
41 static const int kMaxDecodeThreads = 16; 42 static const int kMaxDecodeThreads = 16;
42 43
43 // Returns the number of threads given the FFmpeg CodecID. Also inspects the 44 // Returns the number of threads given the FFmpeg CodecID. Also inspects the
44 // command line for a valid --video-threads flag. 45 // command line for a valid --video-threads flag.
45 static int GetThreadCount(AVCodecID codec_id) { 46 static int GetThreadCount(const VideoDecoderConfig& config) {
46 // Refer to http://crbug.com/93932 for tsan suppressions on decoding. 47 // Refer to http://crbug.com/93932 for tsan suppressions on decoding.
47 int decode_threads = kDecodeThreads; 48 int decode_threads = kDecodeThreads;
48 49
49 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); 50 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
50 std::string threads(cmd_line->GetSwitchValueASCII(switches::kVideoThreads)); 51 std::string threads(cmd_line->GetSwitchValueASCII(switches::kVideoThreads));
51 if (threads.empty() || !base::StringToInt(threads, &decode_threads)) 52 if (threads.empty() || !base::StringToInt(threads, &decode_threads)) {
52 return decode_threads; 53 decode_threads = config.coded_size().width() *
DaleCurtis 2016/10/27 18:11:34 Logic needs a description and some example values.
hubbe 2016/10/27 20:36:47 Done.
54 config.coded_size().height() * 3 / 1920 / 1080;
55
56 int cores = base::SysInfo::NumberOfProcessors();
57 // Leave two threads for other things to run.
58 decode_threads = std::min(decode_threads, cores - 2);
59 // Use at least two threads, or ffmpeg will decode on the calling thread.
60 decode_threads = std::max(decode_threads, kDecodeThreads);
61 }
53 62
54 decode_threads = std::max(decode_threads, 0); 63 decode_threads = std::max(decode_threads, 0);
55 decode_threads = std::min(decode_threads, kMaxDecodeThreads); 64 decode_threads = std::min(decode_threads, kMaxDecodeThreads);
56 return decode_threads; 65 return decode_threads;
57 } 66 }
58 67
59 static int GetVideoBufferImpl(struct AVCodecContext* s, 68 static int GetVideoBufferImpl(struct AVCodecContext* s,
60 AVFrame* frame, 69 AVFrame* frame,
61 int flags) { 70 int flags) {
62 FFmpegVideoDecoder* decoder = static_cast<FFmpegVideoDecoder*>(s->opaque); 71 FFmpegVideoDecoder* decoder = static_cast<FFmpegVideoDecoder*>(s->opaque);
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 DCHECK(config_.IsValidConfig()); 377 DCHECK(config_.IsValidConfig());
369 DCHECK(!config_.is_encrypted()); 378 DCHECK(!config_.is_encrypted());
370 379
371 // Release existing decoder resources if necessary. 380 // Release existing decoder resources if necessary.
372 ReleaseFFmpegResources(); 381 ReleaseFFmpegResources();
373 382
374 // Initialize AVCodecContext structure. 383 // Initialize AVCodecContext structure.
375 codec_context_.reset(avcodec_alloc_context3(NULL)); 384 codec_context_.reset(avcodec_alloc_context3(NULL));
376 VideoDecoderConfigToAVCodecContext(config_, codec_context_.get()); 385 VideoDecoderConfigToAVCodecContext(config_, codec_context_.get());
377 386
378 codec_context_->thread_count = GetThreadCount(codec_context_->codec_id); 387 codec_context_->thread_count = GetThreadCount(config_);
379 codec_context_->thread_type = low_delay ? FF_THREAD_SLICE : FF_THREAD_FRAME; 388 codec_context_->thread_type =
389 FF_THREAD_SLICE | (low_delay ? 0 : FF_THREAD_FRAME);
380 codec_context_->opaque = this; 390 codec_context_->opaque = this;
381 codec_context_->flags |= CODEC_FLAG_EMU_EDGE; 391 codec_context_->flags |= CODEC_FLAG_EMU_EDGE;
382 codec_context_->get_buffer2 = GetVideoBufferImpl; 392 codec_context_->get_buffer2 = GetVideoBufferImpl;
383 codec_context_->refcounted_frames = 1; 393 codec_context_->refcounted_frames = 1;
384 394
385 if (decode_nalus_) 395 if (decode_nalus_)
386 codec_context_->flags2 |= CODEC_FLAG2_CHUNKS; 396 codec_context_->flags2 |= CODEC_FLAG2_CHUNKS;
387 397
388 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id); 398 AVCodec* codec = avcodec_find_decoder(codec_context_->codec_id);
389 if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) { 399 if (!codec || avcodec_open2(codec_context_.get(), codec, NULL) < 0) {
390 ReleaseFFmpegResources(); 400 ReleaseFFmpegResources();
391 return false; 401 return false;
392 } 402 }
393 403
394 av_frame_.reset(av_frame_alloc()); 404 av_frame_.reset(av_frame_alloc());
395 return true; 405 return true;
396 } 406 }
397 407
398 } // namespace media 408 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698