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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 video_frame->visible_data(VideoFrame::kUPlane); | 208 video_frame->visible_data(VideoFrame::kUPlane); |
209 vpx_image.planes[VPX_PLANE_V] = | 209 vpx_image.planes[VPX_PLANE_V] = |
210 video_frame->visible_data(VideoFrame::kVPlane); | 210 video_frame->visible_data(VideoFrame::kVPlane); |
211 vpx_image.stride[VPX_PLANE_Y] = video_frame->stride(VideoFrame::kYPlane); | 211 vpx_image.stride[VPX_PLANE_Y] = video_frame->stride(VideoFrame::kYPlane); |
212 vpx_image.stride[VPX_PLANE_U] = video_frame->stride(VideoFrame::kUPlane); | 212 vpx_image.stride[VPX_PLANE_U] = video_frame->stride(VideoFrame::kUPlane); |
213 vpx_image.stride[VPX_PLANE_V] = video_frame->stride(VideoFrame::kVPlane); | 213 vpx_image.stride[VPX_PLANE_V] = video_frame->stride(VideoFrame::kVPlane); |
214 | 214 |
215 // The frame duration given to the VP8 codec affects a number of important | 215 // The frame duration given to the VP8 codec affects a number of important |
216 // behaviors, including: per-frame bandwidth, CPU time spent encoding, | 216 // behaviors, including: per-frame bandwidth, CPU time spent encoding, |
217 // temporal quality trade-offs, and key/golden/alt-ref frame generation | 217 // temporal quality trade-offs, and key/golden/alt-ref frame generation |
218 // intervals. Use the actual amount of time between the current and previous | 218 // intervals. Bound the prediction to account for the fact that the frame |
219 // frames as a prediction for the next frame's duration, but bound the | 219 // rate can be highly variable, including long pauses in the video stream. |
220 // prediction to account for the fact that the frame rate can be highly | |
221 // variable, including long pauses in the video stream. | |
222 const base::TimeDelta minimum_frame_duration = | 220 const base::TimeDelta minimum_frame_duration = |
223 base::TimeDelta::FromSecondsD(1.0 / cast_config_.max_frame_rate); | 221 base::TimeDelta::FromSecondsD(1.0 / cast_config_.max_frame_rate); |
224 const base::TimeDelta maximum_frame_duration = | 222 const base::TimeDelta maximum_frame_duration = |
225 base::TimeDelta::FromSecondsD(static_cast<double>(kRestartFramePeriods) / | 223 base::TimeDelta::FromSecondsD(static_cast<double>(kRestartFramePeriods) / |
226 cast_config_.max_frame_rate); | 224 cast_config_.max_frame_rate); |
227 const base::TimeDelta last_frame_duration = | 225 base::TimeDelta predicted_frame_duration; |
228 video_frame->timestamp() - last_frame_timestamp_; | 226 if (!video_frame->metadata()->GetTimeDelta( |
229 const base::TimeDelta predicted_frame_duration = | 227 media::VideoFrameMetadata::FRAME_DURATION, |
| 228 &predicted_frame_duration) || |
| 229 predicted_frame_duration <= base::TimeDelta()) { |
| 230 // The source of the video frame did not provide the frame duration. Use |
| 231 // the actual amount of time between the current and previous frame as a |
| 232 // prediction for the next frame's duration. |
| 233 predicted_frame_duration = video_frame->timestamp() - last_frame_timestamp_; |
| 234 } |
| 235 predicted_frame_duration = |
230 std::max(minimum_frame_duration, | 236 std::max(minimum_frame_duration, |
231 std::min(maximum_frame_duration, last_frame_duration)); | 237 std::min(maximum_frame_duration, predicted_frame_duration)); |
232 last_frame_timestamp_ = video_frame->timestamp(); | 238 last_frame_timestamp_ = video_frame->timestamp(); |
233 | 239 |
234 // Encode the frame. The presentation time stamp argument here is fixed to | 240 // Encode the frame. The presentation time stamp argument here is fixed to |
235 // zero to force the encoder to base its single-frame bandwidth calculations | 241 // zero to force the encoder to base its single-frame bandwidth calculations |
236 // entirely on |predicted_frame_duration| and the target bitrate setting being | 242 // entirely on |predicted_frame_duration| and the target bitrate setting being |
237 // micro-managed via calls to UpdateRates(). | 243 // micro-managed via calls to UpdateRates(). |
238 CHECK_EQ(vpx_codec_encode(&encoder_, | 244 CHECK_EQ(vpx_codec_encode(&encoder_, |
239 &vpx_image, | 245 &vpx_image, |
240 0, | 246 0, |
241 predicted_frame_duration.InMicroseconds(), | 247 predicted_frame_duration.InMicroseconds(), |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 } | 476 } |
471 } | 477 } |
472 | 478 |
473 void Vp8Encoder::GenerateKeyFrame() { | 479 void Vp8Encoder::GenerateKeyFrame() { |
474 DCHECK(thread_checker_.CalledOnValidThread()); | 480 DCHECK(thread_checker_.CalledOnValidThread()); |
475 key_frame_requested_ = true; | 481 key_frame_requested_ = true; |
476 } | 482 } |
477 | 483 |
478 } // namespace cast | 484 } // namespace cast |
479 } // namespace media | 485 } // namespace media |
OLD | NEW |