| Index: media/cast/sender/vp8_encoder.cc
|
| diff --git a/media/cast/sender/vp8_encoder.cc b/media/cast/sender/vp8_encoder.cc
|
| index b68935c36f0cc499549e0759d06b755f60d530e9..97139e8d84d6609f23402033de96edef7c4d368c 100644
|
| --- a/media/cast/sender/vp8_encoder.cc
|
| +++ b/media/cast/sender/vp8_encoder.cc
|
| @@ -7,7 +7,6 @@
|
| #include "base/logging.h"
|
| #include "media/base/video_frame.h"
|
| #include "media/cast/cast_defines.h"
|
| -#include "media/cast/net/cast_transport_config.h"
|
| #include "third_party/libvpx/source/libvpx/vpx/vp8cx.h"
|
|
|
| namespace media {
|
| @@ -164,10 +163,15 @@ void Vp8Encoder::ConfigureForNewFrameSize(const gfx::Size& frame_size) {
|
|
|
| void Vp8Encoder::Encode(const scoped_refptr<media::VideoFrame>& video_frame,
|
| const base::TimeTicks& reference_time,
|
| - EncodedFrame* encoded_frame) {
|
| + SenderEncodedFrame* encoded_frame) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| DCHECK(encoded_frame);
|
|
|
| + // Note: This is used to compute the |deadline_utilization| and so it uses the
|
| + // real-world clock instead of the CastEnvironment clock, the latter of which
|
| + // might be simulated.
|
| + const base::TimeTicks start_time = base::TimeTicks::Now();
|
| +
|
| // Initialize on-demand. Later, if the video frame size has changed, update
|
| // the encoder configuration.
|
| const gfx::Size frame_size = video_frame->visible_rect().size();
|
| @@ -279,8 +283,37 @@ void Vp8Encoder::Encode(const scoped_refptr<media::VideoFrame>& video_frame,
|
| DCHECK(!encoded_frame->data.empty())
|
| << "BUG: Encoder must provide data since lagged encoding is disabled.";
|
|
|
| + // Compute deadline utilization as the real-world time elapsed divided by the
|
| + // frame duration.
|
| + const base::TimeDelta processing_time = base::TimeTicks::Now() - start_time;
|
| + encoded_frame->deadline_utilization =
|
| + processing_time.InSecondsF() / predicted_frame_duration.InSecondsF();
|
| +
|
| + // Compute lossy utilization. The VP8 encoder took an estimated guess at what
|
| + // quantizer value would produce an encoded frame size as close to the target
|
| + // as possible. Now that the frame has been encoded and the number of bytes
|
| + // is known, the perfect quantizer value (i.e., the one that should have been
|
| + // used) can be determined. This perfect quantizer is then normalized and
|
| + // used as the lossy utilization.
|
| + const double actual_bitrate =
|
| + encoded_frame->data.size() * 8.0 / predicted_frame_duration.InSecondsF();
|
| + const double target_bitrate = 1000.0 * config_.rc_target_bitrate;
|
| + DCHECK_GT(target_bitrate, 0.0);
|
| + const double bitrate_utilization = actual_bitrate / target_bitrate;
|
| + int quantizer = -1;
|
| + CHECK_EQ(vpx_codec_control(&encoder_, VP8E_GET_LAST_QUANTIZER_64, &quantizer),
|
| + VPX_CODEC_OK);
|
| + const double perfect_quantizer = bitrate_utilization * std::max(0, quantizer);
|
| + // Side note: If it was possible for the encoder to encode within the target
|
| + // number of bytes, the |perfect_quantizer| will be in the range [0.0,63.0].
|
| + // If it was never possible, the value will be greater than 63.0.
|
| + encoded_frame->lossy_utilization = perfect_quantizer / 63.0;
|
| +
|
| DVLOG(2) << "VP8 encoded frame_id " << encoded_frame->frame_id
|
| - << ", sized:" << encoded_frame->data.size();
|
| + << ", sized: " << encoded_frame->data.size()
|
| + << ", deadline_utilization: " << encoded_frame->deadline_utilization
|
| + << ", lossy_utilization: " << encoded_frame->lossy_utilization
|
| + << " (quantizer chosen by the encoder was " << quantizer << ')';
|
|
|
| if (encoded_frame->dependency == EncodedFrame::KEY) {
|
| key_frame_requested_ = false;
|
|
|