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

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

Issue 2133903002: RELAND: Merge VideoSenderConfig and AudioSenderConfig. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Disabled two unittests. 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/cast/sender/vp8_encoder.h ('k') | media/cast/sender/vp8_quantizer_parser_unittest.cc » ('j') | 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/vp8_encoder.h" 5 #include "media/cast/sender/vp8_encoder.h"
6 6
7 #include "base/debug/crash_logging.h" 7 #include "base/debug/crash_logging.h"
8 #include "base/debug/dump_without_crashing.h" 8 #include "base/debug/dump_without_crashing.h"
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 56
57 bool HasSufficientFeedback( 57 bool HasSufficientFeedback(
58 const FeedbackSignalAccumulator<base::TimeDelta>& accumulator) { 58 const FeedbackSignalAccumulator<base::TimeDelta>& accumulator) {
59 const base::TimeDelta amount_of_history = 59 const base::TimeDelta amount_of_history =
60 accumulator.update_time() - accumulator.reset_time(); 60 accumulator.update_time() - accumulator.reset_time();
61 return amount_of_history.InMicroseconds() >= 250000; // 0.25 second. 61 return amount_of_history.InMicroseconds() >= 250000; // 0.25 second.
62 } 62 }
63 63
64 } // namespace 64 } // namespace
65 65
66 Vp8Encoder::Vp8Encoder(const VideoSenderConfig& video_config) 66 Vp8Encoder::Vp8Encoder(const FrameSenderConfig& video_config)
67 : cast_config_(video_config), 67 : cast_config_(video_config),
68 target_encoder_utilization_( 68 target_encoder_utilization_(
69 video_config.number_of_encode_threads > 2 69 video_config.video_codec_params.number_of_encode_threads > 2
70 ? kHiTargetEncoderUtilization 70 ? kHiTargetEncoderUtilization
71 : (video_config.number_of_encode_threads > 1 71 : (video_config.video_codec_params.number_of_encode_threads > 1
72 ? kMidTargetEncoderUtilization 72 ? kMidTargetEncoderUtilization
73 : kLoTargetEncoderUtilization)), 73 : kLoTargetEncoderUtilization)),
74 key_frame_requested_(true), 74 key_frame_requested_(true),
75 bitrate_kbit_(cast_config_.start_bitrate / 1000), 75 bitrate_kbit_(cast_config_.start_bitrate / 1000),
76 next_frame_id_(FrameId::first()), 76 next_frame_id_(FrameId::first()),
77 has_seen_zero_length_encoded_frame_(false), 77 has_seen_zero_length_encoded_frame_(false),
78 encoding_speed_acc_( 78 encoding_speed_acc_(
79 base::TimeDelta::FromMicroseconds(kEncodingSpeedAccHalfLife)), 79 base::TimeDelta::FromMicroseconds(kEncodingSpeedAccHalfLife)),
80 encoding_speed_(kHighestEncodingSpeed) { 80 encoding_speed_(kHighestEncodingSpeed) {
81 config_.g_timebase.den = 0; // Not initialized. 81 config_.g_timebase.den = 0; // Not initialized.
82 DCHECK_LE(cast_config_.min_qp, cast_config_.max_cpu_saver_qp); 82 DCHECK_LE(cast_config_.video_codec_params.min_qp,
83 DCHECK_LE(cast_config_.max_cpu_saver_qp, cast_config_.max_qp); 83 cast_config_.video_codec_params.max_cpu_saver_qp);
84 DCHECK_LE(cast_config_.video_codec_params.max_cpu_saver_qp,
85 cast_config_.video_codec_params.max_qp);
84 86
85 thread_checker_.DetachFromThread(); 87 thread_checker_.DetachFromThread();
86 } 88 }
87 89
88 Vp8Encoder::~Vp8Encoder() { 90 Vp8Encoder::~Vp8Encoder() {
89 DCHECK(thread_checker_.CalledOnValidThread()); 91 DCHECK(thread_checker_.CalledOnValidThread());
90 if (is_initialized()) 92 if (is_initialized())
91 vpx_codec_destroy(&encoder_); 93 vpx_codec_destroy(&encoder_);
92 } 94 }
93 95
94 void Vp8Encoder::Initialize() { 96 void Vp8Encoder::Initialize() {
95 DCHECK(thread_checker_.CalledOnValidThread()); 97 DCHECK(thread_checker_.CalledOnValidThread());
96 DCHECK(!is_initialized()); 98 DCHECK(!is_initialized());
97 // The encoder will be created/configured when the first frame encode is 99 // The encoder will be created/configured when the first frame encode is
98 // requested. 100 // requested.
99 } 101 }
100 102
101 void Vp8Encoder::ConfigureForNewFrameSize(const gfx::Size& frame_size) { 103 void Vp8Encoder::ConfigureForNewFrameSize(const gfx::Size& frame_size) {
102 if (is_initialized()) { 104 if (is_initialized()) {
103 // Workaround for VP8 bug: If the new size is strictly less-than-or-equal to 105 // Workaround for VP8 bug: If the new size is strictly less-than-or-equal to
104 // the old size, in terms of area, the existing encoder instance can 106 // the old size, in terms of area, the existing encoder instance can
105 // continue. Otherwise, completely tear-down and re-create a new encoder to 107 // continue. Otherwise, completely tear-down and re-create a new encoder to
106 // avoid a shutdown crash. 108 // avoid a shutdown crash.
107 if (frame_size.GetArea() <= gfx::Size(config_.g_w, config_.g_h).GetArea()) { 109 if (frame_size.GetArea() <= gfx::Size(config_.g_w, config_.g_h).GetArea()) {
108 DVLOG(1) << "Continuing to use existing encoder at smaller frame size: " 110 DVLOG(1) << "Continuing to use existing encoder at smaller frame size: "
109 << gfx::Size(config_.g_w, config_.g_h).ToString() << " --> " 111 << gfx::Size(config_.g_w, config_.g_h).ToString() << " --> "
110 << frame_size.ToString(); 112 << frame_size.ToString();
111 config_.g_w = frame_size.width(); 113 config_.g_w = frame_size.width();
112 config_.g_h = frame_size.height(); 114 config_.g_h = frame_size.height();
113 config_.rc_min_quantizer = cast_config_.min_qp; 115 config_.rc_min_quantizer = cast_config_.video_codec_params.min_qp;
114 if (vpx_codec_enc_config_set(&encoder_, &config_) == VPX_CODEC_OK) 116 if (vpx_codec_enc_config_set(&encoder_, &config_) == VPX_CODEC_OK)
115 return; 117 return;
116 DVLOG(1) << "libvpx rejected the attempt to use a smaller frame size in " 118 DVLOG(1) << "libvpx rejected the attempt to use a smaller frame size in "
117 "the current instance."; 119 "the current instance.";
118 } 120 }
119 121
120 DVLOG(1) << "Destroying/Re-Creating encoder for larger frame size: " 122 DVLOG(1) << "Destroying/Re-Creating encoder for larger frame size: "
121 << gfx::Size(config_.g_w, config_.g_h).ToString() << " --> " 123 << gfx::Size(config_.g_w, config_.g_h).ToString() << " --> "
122 << frame_size.ToString(); 124 << frame_size.ToString();
123 vpx_codec_destroy(&encoder_); 125 vpx_codec_destroy(&encoder_);
124 } else { 126 } else {
125 DVLOG(1) << "Creating encoder for the first frame; size: " 127 DVLOG(1) << "Creating encoder for the first frame; size: "
126 << frame_size.ToString(); 128 << frame_size.ToString();
127 } 129 }
128 130
129 // Populate encoder configuration with default values. 131 // Populate encoder configuration with default values.
130 CHECK_EQ(vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &config_, 0), 132 CHECK_EQ(vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &config_, 0),
131 VPX_CODEC_OK); 133 VPX_CODEC_OK);
132 134
133 config_.g_threads = cast_config_.number_of_encode_threads; 135 config_.g_threads = cast_config_.video_codec_params.number_of_encode_threads;
134 config_.g_w = frame_size.width(); 136 config_.g_w = frame_size.width();
135 config_.g_h = frame_size.height(); 137 config_.g_h = frame_size.height();
136 // Set the timebase to match that of base::TimeDelta. 138 // Set the timebase to match that of base::TimeDelta.
137 config_.g_timebase.num = 1; 139 config_.g_timebase.num = 1;
138 config_.g_timebase.den = base::Time::kMicrosecondsPerSecond; 140 config_.g_timebase.den = base::Time::kMicrosecondsPerSecond;
139 141
140 // |g_pass| and |g_lag_in_frames| must be "one pass" and zero, respectively, 142 // |g_pass| and |g_lag_in_frames| must be "one pass" and zero, respectively,
141 // in order for VP8 to support changing frame sizes during encoding: 143 // in order for VP8 to support changing frame sizes during encoding:
142 config_.g_pass = VPX_RC_ONE_PASS; 144 config_.g_pass = VPX_RC_ONE_PASS;
143 config_.g_lag_in_frames = 0; // Immediate data output for each frame. 145 config_.g_lag_in_frames = 0; // Immediate data output for each frame.
144 146
145 // Rate control settings. 147 // Rate control settings.
146 config_.rc_dropframe_thresh = 0; // The encoder may not drop any frames. 148 config_.rc_dropframe_thresh = 0; // The encoder may not drop any frames.
147 config_.rc_resize_allowed = 0; // TODO(miu): Why not? Investigate this. 149 config_.rc_resize_allowed = 0; // TODO(miu): Why not? Investigate this.
148 config_.rc_end_usage = VPX_CBR; 150 config_.rc_end_usage = VPX_CBR;
149 config_.rc_target_bitrate = bitrate_kbit_; 151 config_.rc_target_bitrate = bitrate_kbit_;
150 config_.rc_min_quantizer = cast_config_.min_qp; 152 config_.rc_min_quantizer = cast_config_.video_codec_params.min_qp;
151 config_.rc_max_quantizer = cast_config_.max_qp; 153 config_.rc_max_quantizer = cast_config_.video_codec_params.max_qp;
152 // TODO(miu): Revisit these now that the encoder is being successfully 154 // TODO(miu): Revisit these now that the encoder is being successfully
153 // micro-managed. 155 // micro-managed.
154 config_.rc_undershoot_pct = 100; 156 config_.rc_undershoot_pct = 100;
155 config_.rc_overshoot_pct = 15; 157 config_.rc_overshoot_pct = 15;
156 // TODO(miu): Document why these rc_buf_*_sz values were chosen and/or 158 // TODO(miu): Document why these rc_buf_*_sz values were chosen and/or
157 // research for better values. Should they be computed from the target 159 // research for better values. Should they be computed from the target
158 // playout delay? 160 // playout delay?
159 config_.rc_buf_initial_sz = 500; 161 config_.rc_buf_initial_sz = 500;
160 config_.rc_buf_optimal_sz = 600; 162 config_.rc_buf_optimal_sz = 600;
161 config_.rc_buf_sz = 1000; 163 config_.rc_buf_sz = 1000;
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 key_frame_requested_ = false; 346 key_frame_requested_ = false;
345 } 347 }
346 if (encoded_frame->dependency == EncodedFrame::KEY) { 348 if (encoded_frame->dependency == EncodedFrame::KEY) {
347 encoding_speed_acc_.Reset(kHighestEncodingSpeed, video_frame->timestamp()); 349 encoding_speed_acc_.Reset(kHighestEncodingSpeed, video_frame->timestamp());
348 } else { 350 } else {
349 // Equivalent encoding speed considering both cpu_used setting and 351 // Equivalent encoding speed considering both cpu_used setting and
350 // quantizer. 352 // quantizer.
351 double actual_encoding_speed = 353 double actual_encoding_speed =
352 encoding_speed_ + 354 encoding_speed_ +
353 kEquivalentEncodingSpeedStepPerQpStep * 355 kEquivalentEncodingSpeedStepPerQpStep *
354 std::max(0, quantizer - cast_config_.min_qp); 356 std::max(0, quantizer - cast_config_.video_codec_params.min_qp);
355 double adjusted_encoding_speed = actual_encoding_speed * 357 double adjusted_encoding_speed = actual_encoding_speed *
356 encoded_frame->encoder_utilization / 358 encoded_frame->encoder_utilization /
357 target_encoder_utilization_; 359 target_encoder_utilization_;
358 encoding_speed_acc_.Update(adjusted_encoding_speed, 360 encoding_speed_acc_.Update(adjusted_encoding_speed,
359 video_frame->timestamp()); 361 video_frame->timestamp());
360 } 362 }
361 363
362 if (HasSufficientFeedback(encoding_speed_acc_)) { 364 if (HasSufficientFeedback(encoding_speed_acc_)) {
363 // Predict |encoding_speed_| and |min_quantizer| for next frame. 365 // Predict |encoding_speed_| and |min_quantizer| for next frame.
364 // When CPU is constrained, increase encoding speed and increase 366 // When CPU is constrained, increase encoding speed and increase
365 // |min_quantizer| if needed. 367 // |min_quantizer| if needed.
366 double next_encoding_speed = encoding_speed_acc_.current(); 368 double next_encoding_speed = encoding_speed_acc_.current();
367 int next_min_qp; 369 int next_min_qp;
368 if (next_encoding_speed > kHighestEncodingSpeed) { 370 if (next_encoding_speed > kHighestEncodingSpeed) {
369 double remainder = next_encoding_speed - kHighestEncodingSpeed; 371 double remainder = next_encoding_speed - kHighestEncodingSpeed;
370 next_encoding_speed = kHighestEncodingSpeed; 372 next_encoding_speed = kHighestEncodingSpeed;
371 next_min_qp = 373 next_min_qp =
372 static_cast<int>(remainder / kEquivalentEncodingSpeedStepPerQpStep + 374 static_cast<int>(remainder / kEquivalentEncodingSpeedStepPerQpStep +
373 cast_config_.min_qp + 0.5); 375 cast_config_.video_codec_params.min_qp + 0.5);
374 next_min_qp = std::min(next_min_qp, cast_config_.max_cpu_saver_qp); 376 next_min_qp = std::min(next_min_qp,
377 cast_config_.video_codec_params.max_cpu_saver_qp);
375 } else { 378 } else {
376 next_encoding_speed = 379 next_encoding_speed =
377 std::max<double>(kLowestEncodingSpeed, next_encoding_speed) + 0.5; 380 std::max<double>(kLowestEncodingSpeed, next_encoding_speed) + 0.5;
378 next_min_qp = cast_config_.min_qp; 381 next_min_qp = cast_config_.video_codec_params.min_qp;
379 } 382 }
380 if (encoding_speed_ != static_cast<int>(next_encoding_speed)) { 383 if (encoding_speed_ != static_cast<int>(next_encoding_speed)) {
381 encoding_speed_ = static_cast<int>(next_encoding_speed); 384 encoding_speed_ = static_cast<int>(next_encoding_speed);
382 CHECK_EQ(vpx_codec_control(&encoder_, VP8E_SET_CPUUSED, -encoding_speed_), 385 CHECK_EQ(vpx_codec_control(&encoder_, VP8E_SET_CPUUSED, -encoding_speed_),
383 VPX_CODEC_OK); 386 VPX_CODEC_OK);
384 } 387 }
385 if (config_.rc_min_quantizer != static_cast<unsigned int>(next_min_qp)) { 388 if (config_.rc_min_quantizer != static_cast<unsigned int>(next_min_qp)) {
386 config_.rc_min_quantizer = static_cast<unsigned int>(next_min_qp); 389 config_.rc_min_quantizer = static_cast<unsigned int>(next_min_qp);
387 CHECK_EQ(vpx_codec_enc_config_set(&encoder_, &config_), VPX_CODEC_OK); 390 CHECK_EQ(vpx_codec_enc_config_set(&encoder_, &config_), VPX_CODEC_OK);
388 } 391 }
(...skipping 20 matching lines...) Expand all
409 VLOG(1) << "VP8 new rc_target_bitrate: " << new_bitrate_kbit << " kbps"; 412 VLOG(1) << "VP8 new rc_target_bitrate: " << new_bitrate_kbit << " kbps";
410 } 413 }
411 414
412 void Vp8Encoder::GenerateKeyFrame() { 415 void Vp8Encoder::GenerateKeyFrame() {
413 DCHECK(thread_checker_.CalledOnValidThread()); 416 DCHECK(thread_checker_.CalledOnValidThread());
414 key_frame_requested_ = true; 417 key_frame_requested_ = true;
415 } 418 }
416 419
417 } // namespace cast 420 } // namespace cast
418 } // namespace media 421 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/sender/vp8_encoder.h ('k') | media/cast/sender/vp8_quantizer_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698