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

Side by Side Diff: media/cast/sender/external_video_encoder.cc

Issue 2149843002: Remove command-line switch: cast-encoder-util-heuristic=backlog<N> (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 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 unified diff | Download patch
« no previous file with comments | « media/base/media_switches.cc ('k') | 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/cast/sender/external_video_encoder.h" 5 #include "media/cast/sender/external_video_encoder.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 26 matching lines...) Expand all
37 37
38 enum { MAX_H264_QUANTIZER = 51 }; 38 enum { MAX_H264_QUANTIZER = 51 };
39 39
40 // Number of buffers for encoded bit stream. 40 // Number of buffers for encoded bit stream.
41 constexpr size_t kOutputBufferCount = 3; 41 constexpr size_t kOutputBufferCount = 3;
42 42
43 // Maximum number of extra input buffers for encoder. The input buffers are only 43 // Maximum number of extra input buffers for encoder. The input buffers are only
44 // used when copy is needed to match the required coded size. 44 // used when copy is needed to match the required coded size.
45 constexpr size_t kExtraInputBufferCount = 2; 45 constexpr size_t kExtraInputBufferCount = 2;
46 46
47 // Parses the command-line flag and returns 0 (default) to use the old/flawed 47 // This value is used to calculate the encoder utilization. The encoder is
48 // "deadline utilization" heuristic to measure encoder utilization. Otherwise, 48 // assumed to be in full usage when the number of frames in progress reaches it.
49 // returns the "redline" value for the "backlog" heuristic (i.e., num_frames / 49 constexpr int kBacklogRedlineThreshold = 4;
50 // redline = utilization).
51 //
52 // Example command line switches and results:
53 //
54 // --cast-encoder-util-heuristic=foobar ==> 0 (unrecognized, use deadline)
55 // --cast-encoder-util-heuristic=backlog ==> 6 (use backlog, default)
56 // --cast-encoder-util-heuristic=backlog7 ==> 7 (use backlog, redline=7)
57 //
58 // TODO(miu): This is temporary, for lab performance testing, until a
59 // good "works for all" solution is confirmed.
60 // https://code.google.com/p/chrome-os-partner/issues/detail?id=54806
61 int GetConfiguredBacklogRedline() {
62 constexpr char kBacklogSwitchValue[] = "backlog";
63 constexpr int kBacklogDefaultRedline = 6;
64
65 const std::string& switch_value =
66 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
67 switches::kCastEncoderUtilHeuristic);
68 if (!base::StartsWith(switch_value, kBacklogSwitchValue,
69 base::CompareCase::SENSITIVE)) {
70 return 0;
71 }
72
73 int redline = kBacklogDefaultRedline;
74 if (!base::StringToInt(switch_value.substr(sizeof(kBacklogSwitchValue) - 1),
75 &redline)) {
76 redline = kBacklogDefaultRedline;
77 }
78 VLOG(1) << "Using 'backlog' heuristic with a redline of " << redline
79 << " to compute encoder utilization.";
80 return redline;
81 }
82 50
83 } // namespace 51 } // namespace
84 52
85 namespace media { 53 namespace media {
86 namespace cast { 54 namespace cast {
87 55
88 // Container for the associated data of a video frame being processed. 56 // Container for the associated data of a video frame being processed.
89 struct InProgressFrameEncode { 57 struct InProgressFrameEncode {
90 // The source content to encode. 58 // The source content to encode.
91 const scoped_refptr<VideoFrame> video_frame; 59 const scoped_refptr<VideoFrame> video_frame;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 std::unique_ptr<media::VideoEncodeAccelerator> vea, 97 std::unique_ptr<media::VideoEncodeAccelerator> vea,
130 double max_frame_rate, 98 double max_frame_rate,
131 const StatusChangeCallback& status_change_cb, 99 const StatusChangeCallback& status_change_cb,
132 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb) 100 const CreateVideoEncodeMemoryCallback& create_video_encode_memory_cb)
133 : cast_environment_(cast_environment), 101 : cast_environment_(cast_environment),
134 task_runner_(encoder_task_runner), 102 task_runner_(encoder_task_runner),
135 max_frame_rate_(max_frame_rate), 103 max_frame_rate_(max_frame_rate),
136 status_change_cb_(status_change_cb), 104 status_change_cb_(status_change_cb),
137 create_video_encode_memory_cb_(create_video_encode_memory_cb), 105 create_video_encode_memory_cb_(create_video_encode_memory_cb),
138 video_encode_accelerator_(std::move(vea)), 106 video_encode_accelerator_(std::move(vea)),
139 backlog_redline_threshold_(GetConfiguredBacklogRedline()),
140 encoder_active_(false), 107 encoder_active_(false),
141 next_frame_id_(FrameId::first()), 108 next_frame_id_(FrameId::first()),
142 key_frame_encountered_(false), 109 key_frame_encountered_(false),
143 codec_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN), 110 codec_profile_(media::VIDEO_CODEC_PROFILE_UNKNOWN),
144 key_frame_quantizer_parsable_(false), 111 key_frame_quantizer_parsable_(false),
145 requested_bit_rate_(-1), 112 requested_bit_rate_(-1),
146 has_seen_zero_length_encoded_frame_(false), 113 has_seen_zero_length_encoded_frame_(false),
147 max_allowed_input_buffers_(0), 114 max_allowed_input_buffers_(0),
148 allocate_input_buffer_in_progress_(false) {} 115 allocate_input_buffer_in_progress_(false) {}
149 116
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 } 308 }
342 encoded_frame->data.append( 309 encoded_frame->data.append(
343 static_cast<const char*>(output_buffer->memory()), payload_size); 310 static_cast<const char*>(output_buffer->memory()), payload_size);
344 311
345 // If FRAME_DURATION metadata was provided in the source VideoFrame, 312 // If FRAME_DURATION metadata was provided in the source VideoFrame,
346 // compute the utilization metrics. 313 // compute the utilization metrics.
347 base::TimeDelta frame_duration; 314 base::TimeDelta frame_duration;
348 if (request.video_frame->metadata()->GetTimeDelta( 315 if (request.video_frame->metadata()->GetTimeDelta(
349 media::VideoFrameMetadata::FRAME_DURATION, &frame_duration) && 316 media::VideoFrameMetadata::FRAME_DURATION, &frame_duration) &&
350 frame_duration > base::TimeDelta()) { 317 frame_duration > base::TimeDelta()) {
351 if (backlog_redline_threshold_ == 0) { 318 // Compute encoder utilization in terms of the number of frames in
352 // Compute encoder utilization as the real-world time elapsed divided 319 // backlog, including the current frame encode that is finishing
353 // by the frame duration. 320 // here. This "backlog" model works as follows: First, assume that all
354 const base::TimeDelta processing_time = 321 // frames utilize the encoder by the same amount. This is actually a
355 base::TimeTicks::Now() - request.start_time; 322 // false assumption, but it still works well because any frame that
356 encoded_frame->encoder_utilization = 323 // takes longer to encode will naturally cause the backlog to
357 processing_time.InSecondsF() / frame_duration.InSecondsF(); 324 // increase, and this will result in a higher computed utilization for
358 } else { 325 // the offending frame. If the backlog continues to increase, because
359 // Compute encoder utilization in terms of the number of frames in 326 // the following frames are also taking too long to encode, the
360 // backlog, including the current frame encode that is finishing 327 // computed utilization for each successive frame will be higher. At
361 // here. This "backlog" model works as follows: First, assume that all 328 // some point, upstream control logic will decide that the data volume
362 // frames utilize the encoder by the same amount. This is actually a 329 // must be reduced.
363 // false assumption, but it still works well because any frame that 330 encoded_frame->encoder_utilization =
364 // takes longer to encode will naturally cause the backlog to 331 static_cast<double>(in_progress_frame_encodes_.size()) /
365 // increase, and this will result in a higher computed utilization for 332 kBacklogRedlineThreshold;
366 // the offending frame. If the backlog continues to increase, because
367 // the following frames are also taking too long to encode, the
368 // computed utilization for each successive frame will be higher. At
369 // some point, upstream control logic will decide that the data volume
370 // must be reduced.
371 encoded_frame->encoder_utilization =
372 static_cast<double>(in_progress_frame_encodes_.size()) /
373 backlog_redline_threshold_;
374 }
375 333
376 const double actual_bit_rate = 334 const double actual_bit_rate =
377 encoded_frame->data.size() * 8.0 / frame_duration.InSecondsF(); 335 encoded_frame->data.size() * 8.0 / frame_duration.InSecondsF();
378 DCHECK_GT(request.target_bit_rate, 0); 336 DCHECK_GT(request.target_bit_rate, 0);
379 const double bitrate_utilization = 337 const double bitrate_utilization =
380 actual_bit_rate / request.target_bit_rate; 338 actual_bit_rate / request.target_bit_rate;
381 double quantizer = QuantizerEstimator::NO_RESULT; 339 double quantizer = QuantizerEstimator::NO_RESULT;
382 // If the quantizer can be parsed from the key frame, try to parse 340 // If the quantizer can be parsed from the key frame, try to parse
383 // the following delta frames as well. 341 // the following delta frames as well.
384 // Otherwise, switch back to entropy estimation for the key frame 342 // Otherwise, switch back to entropy estimation for the key frame
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 } 550 }
593 return (num_slices == 0) ? -1 : (total_quantizer / num_slices); 551 return (num_slices == 0) ? -1 : (total_quantizer / num_slices);
594 } 552 }
595 553
596 const scoped_refptr<CastEnvironment> cast_environment_; 554 const scoped_refptr<CastEnvironment> cast_environment_;
597 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 555 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
598 const double max_frame_rate_; 556 const double max_frame_rate_;
599 const StatusChangeCallback status_change_cb_; // Must be run on MAIN thread. 557 const StatusChangeCallback status_change_cb_; // Must be run on MAIN thread.
600 const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_; 558 const CreateVideoEncodeMemoryCallback create_video_encode_memory_cb_;
601 std::unique_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_; 559 std::unique_ptr<media::VideoEncodeAccelerator> video_encode_accelerator_;
602 const int backlog_redline_threshold_;
603 bool encoder_active_; 560 bool encoder_active_;
604 FrameId next_frame_id_; 561 FrameId next_frame_id_;
605 bool key_frame_encountered_; 562 bool key_frame_encountered_;
606 std::string stream_header_; 563 std::string stream_header_;
607 VideoCodecProfile codec_profile_; 564 VideoCodecProfile codec_profile_;
608 bool key_frame_quantizer_parsable_; 565 bool key_frame_quantizer_parsable_;
609 H264Parser h264_parser_; 566 H264Parser h264_parser_;
610 567
611 // Shared memory buffers for output with the VideoAccelerator. 568 // Shared memory buffers for output with the VideoAccelerator.
612 std::vector<std::unique_ptr<base::SharedMemory>> output_buffers_; 569 std::vector<std::unique_ptr<base::SharedMemory>> output_buffers_;
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
954 const double kEntropyAtMaxQuantizer = 7.5; 911 const double kEntropyAtMaxQuantizer = 7.5;
955 const double slope = 912 const double slope =
956 (MAX_VP8_QUANTIZER - MIN_VP8_QUANTIZER) / kEntropyAtMaxQuantizer; 913 (MAX_VP8_QUANTIZER - MIN_VP8_QUANTIZER) / kEntropyAtMaxQuantizer;
957 const double quantizer = std::min<double>( 914 const double quantizer = std::min<double>(
958 MAX_VP8_QUANTIZER, MIN_VP8_QUANTIZER + slope * shannon_entropy); 915 MAX_VP8_QUANTIZER, MIN_VP8_QUANTIZER + slope * shannon_entropy);
959 return quantizer; 916 return quantizer;
960 } 917 }
961 918
962 } // namespace cast 919 } // namespace cast
963 } // namespace media 920 } // namespace media
OLDNEW
« no previous file with comments | « media/base/media_switches.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698