| OLD | NEW |
| 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" | 10 #include "media/cast/net/cast_transport_config.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 // pause in the video stream. | 21 // pause in the video stream. |
| 22 const int kRestartFramePeriods = 3; | 22 const int kRestartFramePeriods = 3; |
| 23 | 23 |
| 24 } // namespace | 24 } // namespace |
| 25 | 25 |
| 26 Vp8Encoder::Vp8Encoder(const VideoSenderConfig& video_config) | 26 Vp8Encoder::Vp8Encoder(const VideoSenderConfig& video_config) |
| 27 : cast_config_(video_config), | 27 : cast_config_(video_config), |
| 28 use_multiple_video_buffers_( | 28 use_multiple_video_buffers_( |
| 29 cast_config_.max_number_of_video_buffers_used == | 29 cast_config_.max_number_of_video_buffers_used == |
| 30 kNumberOfVp8VideoBuffers), | 30 kNumberOfVp8VideoBuffers), |
| 31 raw_image_(nullptr), | |
| 32 key_frame_requested_(true), | 31 key_frame_requested_(true), |
| 32 bitrate_kbit_(cast_config_.start_bitrate / 1000), |
| 33 last_encoded_frame_id_(kStartFrameId), | 33 last_encoded_frame_id_(kStartFrameId), |
| 34 last_acked_frame_id_(kStartFrameId), | 34 last_acked_frame_id_(kStartFrameId), |
| 35 undroppable_frames_(0) { | 35 undroppable_frames_(0) { |
| 36 config_.g_timebase.den = 0; // Not initialized. | 36 config_.g_timebase.den = 0; // Not initialized. |
| 37 | 37 |
| 38 // VP8 have 3 buffers available for prediction, with | 38 // VP8 have 3 buffers available for prediction, with |
| 39 // max_number_of_video_buffers_used set to 1 we maximize the coding efficiency | 39 // max_number_of_video_buffers_used set to 1 we maximize the coding efficiency |
| 40 // however in this mode we can not skip frames in the receiver to catch up | 40 // however in this mode we can not skip frames in the receiver to catch up |
| 41 // after a temporary network outage; with max_number_of_video_buffers_used | 41 // after a temporary network outage; with max_number_of_video_buffers_used |
| 42 // set to 3 we allow 2 frames to be skipped by the receiver without error | 42 // set to 3 we allow 2 frames to be skipped by the receiver without error |
| 43 // propagation. | 43 // propagation. |
| 44 DCHECK(cast_config_.max_number_of_video_buffers_used == 1 || | 44 DCHECK(cast_config_.max_number_of_video_buffers_used == 1 || |
| 45 cast_config_.max_number_of_video_buffers_used == | 45 cast_config_.max_number_of_video_buffers_used == |
| 46 kNumberOfVp8VideoBuffers) | 46 kNumberOfVp8VideoBuffers) |
| 47 << "Invalid argument"; | 47 << "Invalid argument"; |
| 48 | 48 |
| 49 thread_checker_.DetachFromThread(); | 49 thread_checker_.DetachFromThread(); |
| 50 } | 50 } |
| 51 | 51 |
| 52 Vp8Encoder::~Vp8Encoder() { | 52 Vp8Encoder::~Vp8Encoder() { |
| 53 DCHECK(thread_checker_.CalledOnValidThread()); | 53 DCHECK(thread_checker_.CalledOnValidThread()); |
| 54 if (is_initialized()) | 54 if (is_initialized()) |
| 55 vpx_codec_destroy(&encoder_); | 55 vpx_codec_destroy(&encoder_); |
| 56 vpx_img_free(raw_image_); | |
| 57 } | 56 } |
| 58 | 57 |
| 59 void Vp8Encoder::Initialize() { | 58 void Vp8Encoder::Initialize() { |
| 60 DCHECK(thread_checker_.CalledOnValidThread()); | 59 DCHECK(thread_checker_.CalledOnValidThread()); |
| 61 DCHECK(!is_initialized()); | 60 DCHECK(!is_initialized()); |
| 61 // The encoder will be created/configured when the first frame encode is |
| 62 // requested. |
| 63 } |
| 62 | 64 |
| 63 // Creating a wrapper to the image - setting image data to NULL. Actual | 65 void Vp8Encoder::ConfigureForNewFrameSize(const gfx::Size& frame_size) { |
| 64 // pointer will be set during encode. Setting align to 1, as it is | 66 if (is_initialized()) { |
| 65 // meaningless (actual memory is not allocated). | 67 // Workaround for VP8 bug: If the new size is strictly less-than-or-equal to |
| 66 raw_image_ = vpx_img_wrap( | 68 // the old size, in terms of area, the existing encoder instance can |
| 67 NULL, VPX_IMG_FMT_I420, cast_config_.width, cast_config_.height, 1, NULL); | 69 // continue. Otherwise, completely tear-down and re-create a new encoder to |
| 70 // avoid a shutdown crash. |
| 71 if (frame_size.GetArea() <= gfx::Size(config_.g_w, config_.g_h).GetArea()) { |
| 72 DVLOG(1) << "Continuing to use existing encoder at smaller frame size: " |
| 73 << gfx::Size(config_.g_w, config_.g_h).ToString() << " --> " |
| 74 << frame_size.ToString(); |
| 75 config_.g_w = frame_size.width(); |
| 76 config_.g_h = frame_size.height(); |
| 77 CHECK_EQ(vpx_codec_enc_config_set(&encoder_, &config_), VPX_CODEC_OK) |
| 78 << "Failed to update frame size in encoder config."; |
| 79 return; |
| 80 } |
| 81 |
| 82 DVLOG(1) << "Destroying/Re-Creating encoder for larger frame size: " |
| 83 << gfx::Size(config_.g_w, config_.g_h).ToString() << " --> " |
| 84 << frame_size.ToString(); |
| 85 vpx_codec_destroy(&encoder_); |
| 86 } else { |
| 87 DVLOG(1) << "Creating encoder for the first frame; size: " |
| 88 << frame_size.ToString(); |
| 89 } |
| 68 | 90 |
| 69 for (int i = 0; i < kNumberOfVp8VideoBuffers; ++i) { | 91 for (int i = 0; i < kNumberOfVp8VideoBuffers; ++i) { |
| 70 buffer_state_[i].frame_id = kStartFrameId; | 92 buffer_state_[i].frame_id = kStartFrameId; |
| 71 buffer_state_[i].state = kBufferStartState; | 93 buffer_state_[i].state = kBufferStartState; |
| 72 } | 94 } |
| 73 | 95 |
| 74 // Populate encoder configuration with default values. | 96 // Populate encoder configuration with default values. |
| 75 if (vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &config_, 0)) { | 97 CHECK_EQ(vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &config_, 0), |
| 76 NOTREACHED() << "Invalid return value"; | 98 VPX_CODEC_OK); |
| 77 config_.g_timebase.den = 0; // Do not call vpx_codec_destroy() in dtor. | |
| 78 return; | |
| 79 } | |
| 80 | 99 |
| 81 config_.g_threads = cast_config_.number_of_encode_threads; | 100 config_.g_threads = cast_config_.number_of_encode_threads; |
| 82 config_.g_w = cast_config_.width; | 101 config_.g_w = frame_size.width(); |
| 83 config_.g_h = cast_config_.height; | 102 config_.g_h = frame_size.height(); |
| 84 // Set the timebase to match that of base::TimeDelta. | 103 // Set the timebase to match that of base::TimeDelta. |
| 85 config_.g_timebase.num = 1; | 104 config_.g_timebase.num = 1; |
| 86 config_.g_timebase.den = base::Time::kMicrosecondsPerSecond; | 105 config_.g_timebase.den = base::Time::kMicrosecondsPerSecond; |
| 87 if (use_multiple_video_buffers_) { | 106 if (use_multiple_video_buffers_) { |
| 88 // We must enable error resilience when we use multiple buffers, due to | 107 // We must enable error resilience when we use multiple buffers, due to |
| 89 // codec requirements. | 108 // codec requirements. |
| 90 config_.g_error_resilient = 1; | 109 config_.g_error_resilient = 1; |
| 91 } | 110 } |
| 111 // |g_pass| and |g_lag_in_frames| must be "one pass" and zero, respectively, |
| 112 // in order for VP8 to support changing frame sizes during encoding: |
| 92 config_.g_pass = VPX_RC_ONE_PASS; | 113 config_.g_pass = VPX_RC_ONE_PASS; |
| 93 config_.g_lag_in_frames = 0; // Immediate data output for each frame. | 114 config_.g_lag_in_frames = 0; // Immediate data output for each frame. |
| 94 | 115 |
| 95 // Rate control settings. | 116 // Rate control settings. |
| 96 config_.rc_dropframe_thresh = 0; // The encoder may not drop any frames. | 117 config_.rc_dropframe_thresh = 0; // The encoder may not drop any frames. |
| 97 config_.rc_resize_allowed = 0; // TODO(miu): Why not? Investigate this. | 118 config_.rc_resize_allowed = 0; // TODO(miu): Why not? Investigate this. |
| 98 config_.rc_end_usage = VPX_CBR; | 119 config_.rc_end_usage = VPX_CBR; |
| 99 config_.rc_target_bitrate = cast_config_.start_bitrate / 1000; // In kbit/s. | 120 config_.rc_target_bitrate = bitrate_kbit_; |
| 100 config_.rc_min_quantizer = cast_config_.min_qp; | 121 config_.rc_min_quantizer = cast_config_.min_qp; |
| 101 config_.rc_max_quantizer = cast_config_.max_qp; | 122 config_.rc_max_quantizer = cast_config_.max_qp; |
| 102 // TODO(miu): Revisit these now that the encoder is being successfully | 123 // TODO(miu): Revisit these now that the encoder is being successfully |
| 103 // micro-managed. | 124 // micro-managed. |
| 104 config_.rc_undershoot_pct = 100; | 125 config_.rc_undershoot_pct = 100; |
| 105 config_.rc_overshoot_pct = 15; | 126 config_.rc_overshoot_pct = 15; |
| 106 // TODO(miu): Document why these rc_buf_*_sz values were chosen and/or | 127 // TODO(miu): Document why these rc_buf_*_sz values were chosen and/or |
| 107 // research for better values. Should they be computed from the target | 128 // research for better values. Should they be computed from the target |
| 108 // playout delay? | 129 // playout delay? |
| 109 config_.rc_buf_initial_sz = 500; | 130 config_.rc_buf_initial_sz = 500; |
| 110 config_.rc_buf_optimal_sz = 600; | 131 config_.rc_buf_optimal_sz = 600; |
| 111 config_.rc_buf_sz = 1000; | 132 config_.rc_buf_sz = 1000; |
| 112 | 133 |
| 113 config_.kf_mode = VPX_KF_DISABLED; | 134 config_.kf_mode = VPX_KF_DISABLED; |
| 114 | 135 |
| 115 vpx_codec_flags_t flags = 0; | 136 vpx_codec_flags_t flags = 0; |
| 116 if (vpx_codec_enc_init(&encoder_, vpx_codec_vp8_cx(), &config_, flags)) { | 137 CHECK_EQ(vpx_codec_enc_init(&encoder_, vpx_codec_vp8_cx(), &config_, flags), |
| 117 NOTREACHED() << "vpx_codec_enc_init() failed."; | 138 VPX_CODEC_OK); |
| 118 config_.g_timebase.den = 0; // Do not call vpx_codec_destroy() in dtor. | |
| 119 return; | |
| 120 } | |
| 121 | 139 |
| 122 // Raise the threshold for considering macroblocks as static. The default is | 140 // Raise the threshold for considering macroblocks as static. The default is |
| 123 // zero, so this setting makes the encoder less sensitive to motion. This | 141 // zero, so this setting makes the encoder less sensitive to motion. This |
| 124 // lowers the probability of needing to utilize more CPU to search for motion | 142 // lowers the probability of needing to utilize more CPU to search for motion |
| 125 // vectors. | 143 // vectors. |
| 126 vpx_codec_control(&encoder_, VP8E_SET_STATIC_THRESHOLD, 1); | 144 CHECK_EQ(vpx_codec_control(&encoder_, VP8E_SET_STATIC_THRESHOLD, 1), |
| 145 VPX_CODEC_OK); |
| 127 | 146 |
| 128 // Improve quality by enabling sets of codec features that utilize more CPU. | 147 // Improve quality by enabling sets of codec features that utilize more CPU. |
| 129 // The default is zero, with increasingly more CPU to be used as the value is | 148 // The default is zero, with increasingly more CPU to be used as the value is |
| 130 // more negative. | 149 // more negative. |
| 131 // TODO(miu): Document why this value was chosen and expected behaviors. | 150 // TODO(miu): Document why this value was chosen and expected behaviors. |
| 132 // Should this be dynamic w.r.t. hardware performance? | 151 // Should this be dynamic w.r.t. hardware performance? |
| 133 vpx_codec_control(&encoder_, VP8E_SET_CPUUSED, -6); | 152 CHECK_EQ(vpx_codec_control(&encoder_, VP8E_SET_CPUUSED, -6), VPX_CODEC_OK); |
| 134 } | 153 } |
| 135 | 154 |
| 136 void Vp8Encoder::Encode(const scoped_refptr<media::VideoFrame>& video_frame, | 155 void Vp8Encoder::Encode(const scoped_refptr<media::VideoFrame>& video_frame, |
| 137 const base::TimeTicks& reference_time, | 156 const base::TimeTicks& reference_time, |
| 138 EncodedFrame* encoded_frame) { | 157 EncodedFrame* encoded_frame) { |
| 139 DCHECK(thread_checker_.CalledOnValidThread()); | 158 DCHECK(thread_checker_.CalledOnValidThread()); |
| 140 DCHECK(encoded_frame); | 159 DCHECK(encoded_frame); |
| 141 | 160 |
| 142 CHECK(is_initialized()); // No illegal reference to |config_| or |encoder_|. | 161 // Initialize on-demand. Later, if the video frame size has changed, update |
| 143 | 162 // the encoder configuration. |
| 144 // Image in vpx_image_t format. | 163 const gfx::Size frame_size = video_frame->visible_rect().size(); |
| 145 // Input image is const. VP8's raw image is not defined as const. | 164 if (!is_initialized() || gfx::Size(config_.g_w, config_.g_h) != frame_size) |
| 146 raw_image_->planes[VPX_PLANE_Y] = | 165 ConfigureForNewFrameSize(frame_size); |
| 147 const_cast<uint8*>(video_frame->data(VideoFrame::kYPlane)); | |
| 148 raw_image_->planes[VPX_PLANE_U] = | |
| 149 const_cast<uint8*>(video_frame->data(VideoFrame::kUPlane)); | |
| 150 raw_image_->planes[VPX_PLANE_V] = | |
| 151 const_cast<uint8*>(video_frame->data(VideoFrame::kVPlane)); | |
| 152 | |
| 153 raw_image_->stride[VPX_PLANE_Y] = video_frame->stride(VideoFrame::kYPlane); | |
| 154 raw_image_->stride[VPX_PLANE_U] = video_frame->stride(VideoFrame::kUPlane); | |
| 155 raw_image_->stride[VPX_PLANE_V] = video_frame->stride(VideoFrame::kVPlane); | |
| 156 | 166 |
| 157 uint32 latest_frame_id_to_reference; | 167 uint32 latest_frame_id_to_reference; |
| 158 Vp8Buffers buffer_to_update; | 168 Vp8Buffers buffer_to_update; |
| 159 vpx_codec_flags_t flags = 0; | 169 vpx_codec_flags_t flags = 0; |
| 160 if (key_frame_requested_) { | 170 if (key_frame_requested_) { |
| 161 flags = VPX_EFLAG_FORCE_KF; | 171 flags = VPX_EFLAG_FORCE_KF; |
| 162 // Self reference. | 172 // Self reference. |
| 163 latest_frame_id_to_reference = last_encoded_frame_id_ + 1; | 173 latest_frame_id_to_reference = last_encoded_frame_id_ + 1; |
| 164 // We can pick any buffer as buffer_to_update since we update | 174 // We can pick any buffer as buffer_to_update since we update |
| 165 // them all. | 175 // them all. |
| 166 buffer_to_update = kLastBuffer; | 176 buffer_to_update = kLastBuffer; |
| 167 } else { | 177 } else { |
| 168 // Reference all acked frames (buffers). | 178 // Reference all acked frames (buffers). |
| 169 latest_frame_id_to_reference = GetCodecReferenceFlags(&flags); | 179 latest_frame_id_to_reference = GetCodecReferenceFlags(&flags); |
| 170 buffer_to_update = GetNextBufferToUpdate(); | 180 buffer_to_update = GetNextBufferToUpdate(); |
| 171 GetCodecUpdateFlags(buffer_to_update, &flags); | 181 GetCodecUpdateFlags(buffer_to_update, &flags); |
| 172 } | 182 } |
| 173 | 183 |
| 184 // Wrapper for vpx_codec_encode() to access the YUV data in the |video_frame|. |
| 185 // Only the VISIBLE rectangle within |video_frame| is exposed to the codec. |
| 186 vpx_image_t vpx_image; |
| 187 vpx_image_t* const result = vpx_img_wrap( |
| 188 &vpx_image, |
| 189 VPX_IMG_FMT_I420, |
| 190 frame_size.width(), |
| 191 frame_size.height(), |
| 192 1, |
| 193 video_frame->data(VideoFrame::kYPlane)); |
| 194 DCHECK_EQ(result, &vpx_image); |
| 195 vpx_image.planes[VPX_PLANE_Y] = |
| 196 video_frame->visible_data(VideoFrame::kYPlane); |
| 197 vpx_image.planes[VPX_PLANE_U] = |
| 198 video_frame->visible_data(VideoFrame::kUPlane); |
| 199 vpx_image.planes[VPX_PLANE_V] = |
| 200 video_frame->visible_data(VideoFrame::kVPlane); |
| 201 vpx_image.stride[VPX_PLANE_Y] = video_frame->stride(VideoFrame::kYPlane); |
| 202 vpx_image.stride[VPX_PLANE_U] = video_frame->stride(VideoFrame::kUPlane); |
| 203 vpx_image.stride[VPX_PLANE_V] = video_frame->stride(VideoFrame::kVPlane); |
| 204 |
| 174 // The frame duration given to the VP8 codec affects a number of important | 205 // The frame duration given to the VP8 codec affects a number of important |
| 175 // behaviors, including: per-frame bandwidth, CPU time spent encoding, | 206 // behaviors, including: per-frame bandwidth, CPU time spent encoding, |
| 176 // temporal quality trade-offs, and key/golden/alt-ref frame generation | 207 // temporal quality trade-offs, and key/golden/alt-ref frame generation |
| 177 // intervals. Use the actual amount of time between the current and previous | 208 // intervals. Use the actual amount of time between the current and previous |
| 178 // frames as a prediction for the next frame's duration, but bound the | 209 // frames as a prediction for the next frame's duration, but bound the |
| 179 // prediction to account for the fact that the frame rate can be highly | 210 // prediction to account for the fact that the frame rate can be highly |
| 180 // variable, including long pauses in the video stream. | 211 // variable, including long pauses in the video stream. |
| 181 const base::TimeDelta minimum_frame_duration = | 212 const base::TimeDelta minimum_frame_duration = |
| 182 base::TimeDelta::FromSecondsD(1.0 / cast_config_.max_frame_rate); | 213 base::TimeDelta::FromSecondsD(1.0 / cast_config_.max_frame_rate); |
| 183 const base::TimeDelta maximum_frame_duration = | 214 const base::TimeDelta maximum_frame_duration = |
| 184 base::TimeDelta::FromSecondsD(static_cast<double>(kRestartFramePeriods) / | 215 base::TimeDelta::FromSecondsD(static_cast<double>(kRestartFramePeriods) / |
| 185 cast_config_.max_frame_rate); | 216 cast_config_.max_frame_rate); |
| 186 const base::TimeDelta last_frame_duration = | 217 const base::TimeDelta last_frame_duration = |
| 187 video_frame->timestamp() - last_frame_timestamp_; | 218 video_frame->timestamp() - last_frame_timestamp_; |
| 188 const base::TimeDelta predicted_frame_duration = | 219 const base::TimeDelta predicted_frame_duration = |
| 189 std::max(minimum_frame_duration, | 220 std::max(minimum_frame_duration, |
| 190 std::min(maximum_frame_duration, last_frame_duration)); | 221 std::min(maximum_frame_duration, last_frame_duration)); |
| 191 last_frame_timestamp_ = video_frame->timestamp(); | 222 last_frame_timestamp_ = video_frame->timestamp(); |
| 192 | 223 |
| 193 // Encode the frame. The presentation time stamp argument here is fixed to | 224 // Encode the frame. The presentation time stamp argument here is fixed to |
| 194 // zero to force the encoder to base its single-frame bandwidth calculations | 225 // zero to force the encoder to base its single-frame bandwidth calculations |
| 195 // entirely on |predicted_frame_duration| and the target bitrate setting being | 226 // entirely on |predicted_frame_duration| and the target bitrate setting being |
| 196 // micro-managed via calls to UpdateRates(). | 227 // micro-managed via calls to UpdateRates(). |
| 197 CHECK_EQ(vpx_codec_encode(&encoder_, | 228 CHECK_EQ(vpx_codec_encode(&encoder_, |
| 198 raw_image_, | 229 &vpx_image, |
| 199 0, | 230 0, |
| 200 predicted_frame_duration.InMicroseconds(), | 231 predicted_frame_duration.InMicroseconds(), |
| 201 flags, | 232 flags, |
| 202 VPX_DL_REALTIME), | 233 VPX_DL_REALTIME), |
| 203 VPX_CODEC_OK) | 234 VPX_CODEC_OK) |
| 204 << "BUG: Invalid arguments passed to vpx_codec_encode()."; | 235 << "BUG: Invalid arguments passed to vpx_codec_encode()."; |
| 205 | 236 |
| 206 // Pull data from the encoder, populating a new EncodedFrame. | 237 // Pull data from the encoder, populating a new EncodedFrame. |
| 207 encoded_frame->frame_id = ++last_encoded_frame_id_; | 238 encoded_frame->frame_id = ++last_encoded_frame_id_; |
| 208 const vpx_codec_cx_pkt_t* pkt = NULL; | 239 const vpx_codec_cx_pkt_t* pkt = NULL; |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 void Vp8Encoder::UpdateRates(uint32 new_bitrate) { | 426 void Vp8Encoder::UpdateRates(uint32 new_bitrate) { |
| 396 DCHECK(thread_checker_.CalledOnValidThread()); | 427 DCHECK(thread_checker_.CalledOnValidThread()); |
| 397 | 428 |
| 398 if (!is_initialized()) | 429 if (!is_initialized()) |
| 399 return; | 430 return; |
| 400 | 431 |
| 401 uint32 new_bitrate_kbit = new_bitrate / 1000; | 432 uint32 new_bitrate_kbit = new_bitrate / 1000; |
| 402 if (config_.rc_target_bitrate == new_bitrate_kbit) | 433 if (config_.rc_target_bitrate == new_bitrate_kbit) |
| 403 return; | 434 return; |
| 404 | 435 |
| 405 config_.rc_target_bitrate = new_bitrate_kbit; | 436 config_.rc_target_bitrate = bitrate_kbit_ = new_bitrate_kbit; |
| 406 | 437 |
| 407 // Update encoder context. | 438 // Update encoder context. |
| 408 if (vpx_codec_enc_config_set(&encoder_, &config_)) { | 439 if (vpx_codec_enc_config_set(&encoder_, &config_)) { |
| 409 NOTREACHED() << "Invalid return value"; | 440 NOTREACHED() << "Invalid return value"; |
| 410 } | 441 } |
| 411 | 442 |
| 412 VLOG(1) << "VP8 new rc_target_bitrate: " << new_bitrate_kbit << " kbps"; | 443 VLOG(1) << "VP8 new rc_target_bitrate: " << new_bitrate_kbit << " kbps"; |
| 413 } | 444 } |
| 414 | 445 |
| 415 void Vp8Encoder::LatestFrameIdToReference(uint32 frame_id) { | 446 void Vp8Encoder::LatestFrameIdToReference(uint32 frame_id) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 429 } | 460 } |
| 430 } | 461 } |
| 431 | 462 |
| 432 void Vp8Encoder::GenerateKeyFrame() { | 463 void Vp8Encoder::GenerateKeyFrame() { |
| 433 DCHECK(thread_checker_.CalledOnValidThread()); | 464 DCHECK(thread_checker_.CalledOnValidThread()); |
| 434 key_frame_requested_ = true; | 465 key_frame_requested_ = true; |
| 435 } | 466 } |
| 436 | 467 |
| 437 } // namespace cast | 468 } // namespace cast |
| 438 } // namespace media | 469 } // namespace media |
| OLD | NEW |