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

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

Issue 1148233002: [Cast] Compute utilization metrics and add performance overlay. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed hubbe's comments. Created 5 years, 7 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') | 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/vp8_encoder.h" 5 #include "media/cast/sender/vp8_encoder.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "media/base/video_frame.h" 8 #include "media/base/video_frame.h"
9 #include "media/cast/cast_defines.h" 9 #include "media/cast/cast_defines.h"
10 #include "media/cast/net/cast_transport_config.h"
11 #include "third_party/libvpx/source/libvpx/vpx/vp8cx.h" 10 #include "third_party/libvpx/source/libvpx/vpx/vp8cx.h"
12 11
13 namespace media { 12 namespace media {
14 namespace cast { 13 namespace cast {
15 14
16 namespace { 15 namespace {
17 16
18 // After a pause in the video stream, what is the maximum duration amount to 17 // After a pause in the video stream, what is the maximum duration amount to
19 // pass to the encoder for the next frame (in terms of 1/max_fps sized periods)? 18 // pass to the encoder for the next frame (in terms of 1/max_fps sized periods)?
20 // This essentially controls the encoded size of the first frame that follows a 19 // This essentially controls the encoded size of the first frame that follows a
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 // Improve quality by enabling sets of codec features that utilize more CPU. 156 // Improve quality by enabling sets of codec features that utilize more CPU.
158 // The default is zero, with increasingly more CPU to be used as the value is 157 // The default is zero, with increasingly more CPU to be used as the value is
159 // more negative. 158 // more negative.
160 // TODO(miu): Document why this value was chosen and expected behaviors. 159 // TODO(miu): Document why this value was chosen and expected behaviors.
161 // Should this be dynamic w.r.t. hardware performance? 160 // Should this be dynamic w.r.t. hardware performance?
162 CHECK_EQ(vpx_codec_control(&encoder_, VP8E_SET_CPUUSED, -6), VPX_CODEC_OK); 161 CHECK_EQ(vpx_codec_control(&encoder_, VP8E_SET_CPUUSED, -6), VPX_CODEC_OK);
163 } 162 }
164 163
165 void Vp8Encoder::Encode(const scoped_refptr<media::VideoFrame>& video_frame, 164 void Vp8Encoder::Encode(const scoped_refptr<media::VideoFrame>& video_frame,
166 const base::TimeTicks& reference_time, 165 const base::TimeTicks& reference_time,
167 EncodedFrame* encoded_frame) { 166 SenderEncodedFrame* encoded_frame) {
168 DCHECK(thread_checker_.CalledOnValidThread()); 167 DCHECK(thread_checker_.CalledOnValidThread());
169 DCHECK(encoded_frame); 168 DCHECK(encoded_frame);
170 169
170 // Note: This is used to compute the |deadline_utilization| and so it uses the
171 // real-world clock instead of the CastEnvironment clock, the latter of which
172 // might be simulated.
173 const base::TimeTicks start_time = base::TimeTicks::Now();
174
171 // Initialize on-demand. Later, if the video frame size has changed, update 175 // Initialize on-demand. Later, if the video frame size has changed, update
172 // the encoder configuration. 176 // the encoder configuration.
173 const gfx::Size frame_size = video_frame->visible_rect().size(); 177 const gfx::Size frame_size = video_frame->visible_rect().size();
174 if (!is_initialized() || gfx::Size(config_.g_w, config_.g_h) != frame_size) 178 if (!is_initialized() || gfx::Size(config_.g_w, config_.g_h) != frame_size)
175 ConfigureForNewFrameSize(frame_size); 179 ConfigureForNewFrameSize(frame_size);
176 180
177 uint32 latest_frame_id_to_reference; 181 uint32 latest_frame_id_to_reference;
178 Vp8Buffers buffer_to_update; 182 Vp8Buffers buffer_to_update;
179 vpx_codec_flags_t flags = 0; 183 vpx_codec_flags_t flags = 0;
180 if (key_frame_requested_) { 184 if (key_frame_requested_) {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 TimeDeltaToRtpDelta(video_frame->timestamp(), kVideoFrequency); 276 TimeDeltaToRtpDelta(video_frame->timestamp(), kVideoFrequency);
273 encoded_frame->reference_time = reference_time; 277 encoded_frame->reference_time = reference_time;
274 encoded_frame->data.assign( 278 encoded_frame->data.assign(
275 static_cast<const uint8*>(pkt->data.frame.buf), 279 static_cast<const uint8*>(pkt->data.frame.buf),
276 static_cast<const uint8*>(pkt->data.frame.buf) + pkt->data.frame.sz); 280 static_cast<const uint8*>(pkt->data.frame.buf) + pkt->data.frame.sz);
277 break; // Done, since all data is provided in one CX_FRAME_PKT packet. 281 break; // Done, since all data is provided in one CX_FRAME_PKT packet.
278 } 282 }
279 DCHECK(!encoded_frame->data.empty()) 283 DCHECK(!encoded_frame->data.empty())
280 << "BUG: Encoder must provide data since lagged encoding is disabled."; 284 << "BUG: Encoder must provide data since lagged encoding is disabled.";
281 285
286 // Compute deadline utilization as the real-world time elapsed divided by the
287 // frame duration.
288 const base::TimeDelta processing_time = base::TimeTicks::Now() - start_time;
289 encoded_frame->deadline_utilization =
290 processing_time.InSecondsF() / predicted_frame_duration.InSecondsF();
291
292 // Compute lossy utilization. The VP8 encoder took an estimated guess at what
293 // quantizer value would produce an encoded frame size as close to the target
294 // as possible. Now that the frame has been encoded and the number of bytes
295 // is known, the perfect quantizer value (i.e., the one that should have been
296 // used) can be determined. This perfect quantizer is then normalized and
297 // used as the lossy utilization.
298 const double actual_bitrate =
299 encoded_frame->data.size() * 8.0 / predicted_frame_duration.InSecondsF();
300 const double target_bitrate = 1000.0 * config_.rc_target_bitrate;
301 DCHECK_GT(target_bitrate, 0.0);
302 const double bitrate_utilization = actual_bitrate / target_bitrate;
303 int quantizer = -1;
304 CHECK_EQ(vpx_codec_control(&encoder_, VP8E_GET_LAST_QUANTIZER_64, &quantizer),
305 VPX_CODEC_OK);
306 const double perfect_quantizer = bitrate_utilization * std::max(0, quantizer);
307 // Side note: If it was possible for the encoder to encode within the target
308 // number of bytes, the |perfect_quantizer| will be in the range [0.0,63.0].
309 // If it was never possible, the value will be greater than 63.0.
310 encoded_frame->lossy_utilization = perfect_quantizer / 63.0;
311
282 DVLOG(2) << "VP8 encoded frame_id " << encoded_frame->frame_id 312 DVLOG(2) << "VP8 encoded frame_id " << encoded_frame->frame_id
283 << ", sized:" << encoded_frame->data.size(); 313 << ", sized: " << encoded_frame->data.size()
314 << ", deadline_utilization: " << encoded_frame->deadline_utilization
315 << ", lossy_utilization: " << encoded_frame->lossy_utilization
316 << " (quantizer chosen by the encoder was " << quantizer << ')';
284 317
285 if (encoded_frame->dependency == EncodedFrame::KEY) { 318 if (encoded_frame->dependency == EncodedFrame::KEY) {
286 key_frame_requested_ = false; 319 key_frame_requested_ = false;
287 320
288 for (int i = 0; i < kNumberOfVp8VideoBuffers; ++i) { 321 for (int i = 0; i < kNumberOfVp8VideoBuffers; ++i) {
289 buffer_state_[i].state = kBufferSent; 322 buffer_state_[i].state = kBufferSent;
290 buffer_state_[i].frame_id = encoded_frame->frame_id; 323 buffer_state_[i].frame_id = encoded_frame->frame_id;
291 } 324 }
292 } else { 325 } else {
293 if (buffer_to_update != kNoBuffer) { 326 if (buffer_to_update != kNoBuffer) {
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 } 509 }
477 } 510 }
478 511
479 void Vp8Encoder::GenerateKeyFrame() { 512 void Vp8Encoder::GenerateKeyFrame() {
480 DCHECK(thread_checker_.CalledOnValidThread()); 513 DCHECK(thread_checker_.CalledOnValidThread());
481 key_frame_requested_ = true; 514 key_frame_requested_ = true;
482 } 515 }
483 516
484 } // namespace cast 517 } // namespace cast
485 } // namespace media 518 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/sender/vp8_encoder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698