Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 // TODO (pwestin): add a link to the design document describing the generic | 5 // TODO (pwestin): add a link to the design document describing the generic |
| 6 // protocol and the VP8 specific details. | 6 // protocol and the VP8 specific details. |
| 7 #include "media/cast/video_sender/codecs/vp8/vp8_encoder.h" | 7 #include "media/cast/video_sender/codecs/vp8/vp8_encoder.h" |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 return; | 128 return; |
| 129 } | 129 } |
| 130 vpx_codec_control(encoder_.get(), VP8E_SET_STATIC_THRESHOLD, 1); | 130 vpx_codec_control(encoder_.get(), VP8E_SET_STATIC_THRESHOLD, 1); |
| 131 vpx_codec_control(encoder_.get(), VP8E_SET_NOISE_SENSITIVITY, 0); | 131 vpx_codec_control(encoder_.get(), VP8E_SET_NOISE_SENSITIVITY, 0); |
| 132 vpx_codec_control(encoder_.get(), VP8E_SET_CPUUSED, -6); | 132 vpx_codec_control(encoder_.get(), VP8E_SET_CPUUSED, -6); |
| 133 vpx_codec_control( | 133 vpx_codec_control( |
| 134 encoder_.get(), VP8E_SET_MAX_INTRA_BITRATE_PCT, rc_max_intra_target); | 134 encoder_.get(), VP8E_SET_MAX_INTRA_BITRATE_PCT, rc_max_intra_target); |
| 135 } | 135 } |
| 136 | 136 |
| 137 bool Vp8Encoder::Encode(const scoped_refptr<media::VideoFrame>& video_frame, | 137 bool Vp8Encoder::Encode(const scoped_refptr<media::VideoFrame>& video_frame, |
| 138 transport::EncodedVideoFrame* encoded_image) { | 138 transport::EncodedFrame* encoded_image) { |
| 139 DCHECK(thread_checker_.CalledOnValidThread()); | 139 DCHECK(thread_checker_.CalledOnValidThread()); |
| 140 // Image in vpx_image_t format. | 140 // Image in vpx_image_t format. |
| 141 // Input image is const. VP8's raw image is not defined as const. | 141 // Input image is const. VP8's raw image is not defined as const. |
| 142 raw_image_->planes[PLANE_Y] = | 142 raw_image_->planes[PLANE_Y] = |
| 143 const_cast<uint8*>(video_frame->data(VideoFrame::kYPlane)); | 143 const_cast<uint8*>(video_frame->data(VideoFrame::kYPlane)); |
| 144 raw_image_->planes[PLANE_U] = | 144 raw_image_->planes[PLANE_U] = |
| 145 const_cast<uint8*>(video_frame->data(VideoFrame::kUPlane)); | 145 const_cast<uint8*>(video_frame->data(VideoFrame::kUPlane)); |
| 146 raw_image_->planes[PLANE_V] = | 146 raw_image_->planes[PLANE_V] = |
| 147 const_cast<uint8*>(video_frame->data(VideoFrame::kVPlane)); | 147 const_cast<uint8*>(video_frame->data(VideoFrame::kVPlane)); |
| 148 | 148 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 192 duration, | 192 duration, |
| 193 flags, | 193 flags, |
| 194 VPX_DL_REALTIME) != VPX_CODEC_OK) { | 194 VPX_DL_REALTIME) != VPX_CODEC_OK) { |
| 195 LOG(ERROR) << "Failed to encode for once."; | 195 LOG(ERROR) << "Failed to encode for once."; |
| 196 return false; | 196 return false; |
| 197 } | 197 } |
| 198 | 198 |
| 199 // Get encoded frame. | 199 // Get encoded frame. |
| 200 const vpx_codec_cx_pkt_t* pkt = NULL; | 200 const vpx_codec_cx_pkt_t* pkt = NULL; |
| 201 vpx_codec_iter_t iter = NULL; | 201 vpx_codec_iter_t iter = NULL; |
| 202 size_t total_size = 0; | 202 bool is_key_frame = false; |
| 203 encoded_image->data.clear(); | |
| 203 while ((pkt = vpx_codec_get_cx_data(encoder_.get(), &iter)) != NULL) { | 204 while ((pkt = vpx_codec_get_cx_data(encoder_.get(), &iter)) != NULL) { |
| 204 if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { | 205 if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) |
| 205 total_size += pkt->data.frame.sz; | 206 continue; |
| 206 encoded_image->data.reserve(total_size); | 207 encoded_image->data.insert( |
| 207 encoded_image->data.insert( | 208 encoded_image->data.end(), |
| 208 encoded_image->data.end(), | 209 static_cast<const uint8*>(pkt->data.frame.buf), |
| 209 static_cast<const uint8*>(pkt->data.frame.buf), | 210 static_cast<const uint8*>(pkt->data.frame.buf) + pkt->data.frame.sz); |
| 210 static_cast<const uint8*>(pkt->data.frame.buf) + pkt->data.frame.sz); | 211 is_key_frame |= !!(pkt->data.frame.flags & VPX_FRAME_IS_KEY); |
|
Alpha Left Google
2014/05/16 18:35:22
There is only one packet of kind VPX_CODEC_CX_FRAM
miu
2014/05/16 21:28:46
Done.
| |
| 211 if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) { | |
| 212 encoded_image->key_frame = true; | |
| 213 } else { | |
| 214 encoded_image->key_frame = false; | |
| 215 } | |
| 216 } | |
| 217 } | 212 } |
| 218 // Don't update frame_id for zero size frames. | 213 // Don't update frame_id for zero size frames. |
| 219 if (total_size == 0) | 214 if (encoded_image->data.empty()) |
| 220 return true; | 215 return true; |
| 221 | 216 |
| 222 // Populate the encoded frame. | 217 // Populate the encoded frame. |
| 223 encoded_image->codec = transport::kVp8; | |
| 224 encoded_image->last_referenced_frame_id = latest_frame_id_to_reference; | |
| 225 encoded_image->frame_id = ++last_encoded_frame_id_; | 218 encoded_image->frame_id = ++last_encoded_frame_id_; |
| 219 if (is_key_frame) { | |
| 220 encoded_image->relationship = transport::EncodedFrame::KEY; | |
| 221 encoded_image->referenced_frame_id = encoded_image->frame_id; | |
| 222 } else { | |
| 223 encoded_image->relationship = transport::EncodedFrame::DEPENDENT; | |
| 224 encoded_image->referenced_frame_id = latest_frame_id_to_reference; | |
| 225 } | |
| 226 | 226 |
| 227 VLOG(1) << "VP8 encoded frame:" << static_cast<int>(encoded_image->frame_id) | 227 DVLOG(1) << "VP8 encoded frame_id " << encoded_image->frame_id |
| 228 << " sized:" << total_size; | 228 << ", sized:" << encoded_image->data.size(); |
| 229 | 229 |
| 230 if (encoded_image->key_frame) { | 230 if (is_key_frame) { |
| 231 key_frame_requested_ = false; | 231 key_frame_requested_ = false; |
| 232 | 232 |
| 233 for (int i = 0; i < kNumberOfVp8VideoBuffers; ++i) { | 233 for (int i = 0; i < kNumberOfVp8VideoBuffers; ++i) { |
| 234 used_buffers_frame_id_[i] = encoded_image->frame_id; | 234 used_buffers_frame_id_[i] = encoded_image->frame_id; |
| 235 } | 235 } |
| 236 // We can pick any buffer as last_used_vp8_buffer_ since we update | 236 // We can pick any buffer as last_used_vp8_buffer_ since we update |
| 237 // them all. | 237 // them all. |
| 238 last_used_vp8_buffer_ = buffer_to_update; | 238 last_used_vp8_buffer_ = buffer_to_update; |
| 239 } else { | 239 } else { |
| 240 if (buffer_to_update != kNoBuffer) { | 240 if (buffer_to_update != kNoBuffer) { |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 407 float scale_parameter = 0.5; | 407 float scale_parameter = 0.5; |
| 408 uint32 target_pct = optimal_buffer_size_ms * scale_parameter * | 408 uint32 target_pct = optimal_buffer_size_ms * scale_parameter * |
| 409 cast_config_.max_frame_rate / 10; | 409 cast_config_.max_frame_rate / 10; |
| 410 | 410 |
| 411 // Don't go below 3 times the per frame bandwidth. | 411 // Don't go below 3 times the per frame bandwidth. |
| 412 return std::max(target_pct, kMinIntra); | 412 return std::max(target_pct, kMinIntra); |
| 413 } | 413 } |
| 414 | 414 |
| 415 } // namespace cast | 415 } // namespace cast |
| 416 } // namespace media | 416 } // namespace media |
| OLD | NEW |