| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "remoting/protocol/webrtc_video_encoder_factory.h" | 5 #include "remoting/protocol/webrtc_video_encoder_factory.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 int32_t WebrtcVideoEncoder::SetRates(uint32_t bitrate, uint32_t framerate) { | 83 int32_t WebrtcVideoEncoder::SetRates(uint32_t bitrate, uint32_t framerate) { |
| 84 VLOG(1) << "WebrtcVideoEncoder::SetRates bitrate:framerate " << bitrate << ":" | 84 VLOG(1) << "WebrtcVideoEncoder::SetRates bitrate:framerate " << bitrate << ":" |
| 85 << framerate; | 85 << framerate; |
| 86 if (!target_bitrate_cb_.is_null()) | 86 if (!target_bitrate_cb_.is_null()) |
| 87 target_bitrate_cb_.Run(bitrate); | 87 target_bitrate_cb_.Run(bitrate); |
| 88 // framerate is not expected to be valid given we never report captured | 88 // framerate is not expected to be valid given we never report captured |
| 89 // frames | 89 // frames |
| 90 return WEBRTC_VIDEO_CODEC_OK; | 90 return WEBRTC_VIDEO_CODEC_OK; |
| 91 } | 91 } |
| 92 | 92 |
| 93 int WebrtcVideoEncoder::SendEncodedFrame(std::unique_ptr<VideoPacket> frame) { | 93 webrtc::EncodedImageCallback::Result WebrtcVideoEncoder::SendEncodedFrame( |
| 94 std::unique_ptr<VideoPacket> frame, |
| 95 base::TimeTicks capture_time) { |
| 94 uint8_t* buffer = | 96 uint8_t* buffer = |
| 95 reinterpret_cast<uint8_t*>(const_cast<char*>(frame->data().data())); | 97 reinterpret_cast<uint8_t*>(const_cast<char*>(frame->data().data())); |
| 96 size_t buffer_size = frame->data().size(); | 98 size_t buffer_size = frame->data().size(); |
| 97 base::AutoLock lock(lock_); | 99 base::AutoLock lock(lock_); |
| 98 if (state_ == kUninitialized) { | 100 if (state_ == kUninitialized) { |
| 99 LOG(ERROR) << "encoder interface uninitialized"; | 101 LOG(ERROR) << "encoder interface uninitialized"; |
| 100 return -1; | 102 return webrtc::EncodedImageCallback::Result( |
| 103 webrtc::EncodedImageCallback::Result::ERROR_SEND_FAILED); |
| 101 } | 104 } |
| 102 | 105 |
| 103 webrtc::EncodedImage encoded_image(buffer, buffer_size, buffer_size); | 106 webrtc::EncodedImage encoded_image(buffer, buffer_size, buffer_size); |
| 104 encoded_image._encodedWidth = frame->format().screen_width(); | 107 encoded_image._encodedWidth = frame->format().screen_width(); |
| 105 encoded_image._encodedHeight = frame->format().screen_height(); | 108 encoded_image._encodedHeight = frame->format().screen_height(); |
| 106 encoded_image._completeFrame = true; | 109 encoded_image._completeFrame = true; |
| 107 encoded_image._frameType = | 110 encoded_image._frameType = |
| 108 frame->key_frame() ? webrtc::kVideoFrameKey : webrtc::kVideoFrameDelta; | 111 frame->key_frame() ? webrtc::kVideoFrameKey : webrtc::kVideoFrameDelta; |
| 109 encoded_image.capture_time_ms_ = frame->capture_time_ms(); | 112 int64_t capture_time_ms = (capture_time - base::TimeTicks()).InMilliseconds(); |
| 110 encoded_image._timeStamp = | 113 encoded_image.capture_time_ms_ = capture_time_ms; |
| 111 static_cast<uint32_t>(frame->capture_time_ms() * 90); | 114 encoded_image._timeStamp = static_cast<uint32_t>(capture_time_ms * 90); |
| 112 encoded_image.playout_delay_.min_ms = 0; | 115 encoded_image.playout_delay_.min_ms = 0; |
| 113 encoded_image.playout_delay_.max_ms = 0; | 116 encoded_image.playout_delay_.max_ms = 0; |
| 114 | 117 |
| 115 webrtc::CodecSpecificInfo codec_specific_info; | 118 webrtc::CodecSpecificInfo codec_specific_info; |
| 116 memset(&codec_specific_info, 0, sizeof(codec_specific_info)); | 119 memset(&codec_specific_info, 0, sizeof(codec_specific_info)); |
| 117 codec_specific_info.codecType = webrtc::kVideoCodecVP8; | 120 codec_specific_info.codecType = webrtc::kVideoCodecVP8; |
| 118 | 121 |
| 119 webrtc::RTPFragmentationHeader header; | 122 webrtc::RTPFragmentationHeader header; |
| 120 memset(&header, 0, sizeof(header)); | 123 memset(&header, 0, sizeof(header)); |
| 121 | 124 |
| 122 codec_specific_info.codecSpecific.VP8.simulcastIdx = 0; | 125 codec_specific_info.codecSpecific.VP8.simulcastIdx = 0; |
| 123 codec_specific_info.codecSpecific.VP8.temporalIdx = webrtc::kNoTemporalIdx; | 126 codec_specific_info.codecSpecific.VP8.temporalIdx = webrtc::kNoTemporalIdx; |
| 124 codec_specific_info.codecSpecific.VP8.tl0PicIdx = webrtc::kNoTl0PicIdx; | 127 codec_specific_info.codecSpecific.VP8.tl0PicIdx = webrtc::kNoTl0PicIdx; |
| 125 codec_specific_info.codecSpecific.VP8.pictureId = webrtc::kNoPictureId; | 128 codec_specific_info.codecSpecific.VP8.pictureId = webrtc::kNoPictureId; |
| 126 | 129 |
| 127 header.VerifyAndAllocateFragmentationHeader(1); | 130 header.VerifyAndAllocateFragmentationHeader(1); |
| 128 header.fragmentationOffset[0] = 0; | 131 header.fragmentationOffset[0] = 0; |
| 129 header.fragmentationLength[0] = buffer_size; | 132 header.fragmentationLength[0] = buffer_size; |
| 130 header.fragmentationPlType[0] = 0; | 133 header.fragmentationPlType[0] = 0; |
| 131 header.fragmentationTimeDiff[0] = 0; | 134 header.fragmentationTimeDiff[0] = 0; |
| 132 | 135 |
| 133 int result = | 136 return encoded_callback_->OnEncodedImage(encoded_image, &codec_specific_info, |
| 134 encoded_callback_->Encoded(encoded_image, &codec_specific_info, &header); | 137 &header); |
| 135 if (result < 0) { | |
| 136 LOG(ERROR) << "Encoded callback failed: " << result; | |
| 137 } else if (result > 0) { | |
| 138 VLOG(1) << "Drop request from webrtc"; | |
| 139 } | |
| 140 return result; | |
| 141 } | 138 } |
| 142 | 139 |
| 143 void WebrtcVideoEncoder::SetKeyFrameRequestCallback( | 140 void WebrtcVideoEncoder::SetKeyFrameRequestCallback( |
| 144 const base::Closure& key_frame_request) { | 141 const base::Closure& key_frame_request) { |
| 145 base::AutoLock lock(lock_); | 142 base::AutoLock lock(lock_); |
| 146 key_frame_request_ = key_frame_request; | 143 key_frame_request_ = key_frame_request; |
| 147 } | 144 } |
| 148 | 145 |
| 149 void WebrtcVideoEncoder::SetTargetBitrateCallback( | 146 void WebrtcVideoEncoder::SetTargetBitrateCallback( |
| 150 const TargetBitrateCallback& target_bitrate_cb) { | 147 const TargetBitrateCallback& target_bitrate_cb) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 } | 194 } |
| 198 for (auto pos = encoders_.begin(); pos != encoders_.end(); ++pos) { | 195 for (auto pos = encoders_.begin(); pos != encoders_.end(); ++pos) { |
| 199 if ((*pos).get() == encoder) { | 196 if ((*pos).get() == encoder) { |
| 200 encoders_.erase(pos); | 197 encoders_.erase(pos); |
| 201 return; | 198 return; |
| 202 } | 199 } |
| 203 } | 200 } |
| 204 DCHECK(false) << "Asked to remove encoder not owned by factory"; | 201 DCHECK(false) << "Asked to remove encoder not owned by factory"; |
| 205 } | 202 } |
| 206 | 203 |
| 207 int WebrtcVideoEncoderFactory::SendEncodedFrame( | 204 webrtc::EncodedImageCallback::Result |
| 208 std::unique_ptr<VideoPacket> frame) { | 205 WebrtcVideoEncoderFactory::SendEncodedFrame(std::unique_ptr<VideoPacket> frame, |
| 206 base::TimeTicks capture_time) { |
| 209 if (encoders_.size() != 1) { | 207 if (encoders_.size() != 1) { |
| 210 LOG(ERROR) << "Unexpected number of encoders " << encoders_.size(); | 208 LOG(ERROR) << "Unexpected number of encoders " << encoders_.size(); |
| 211 return -1; | 209 return webrtc::EncodedImageCallback::Result( |
| 210 webrtc::EncodedImageCallback::Result::ERROR_SEND_FAILED); |
| 212 } | 211 } |
| 213 return encoders_.front()->SendEncodedFrame(std::move(frame)); | 212 return encoders_.front()->SendEncodedFrame(std::move(frame), capture_time); |
| 214 } | 213 } |
| 215 | 214 |
| 216 void WebrtcVideoEncoderFactory::SetKeyFrameRequestCallback( | 215 void WebrtcVideoEncoderFactory::SetKeyFrameRequestCallback( |
| 217 const base::Closure& key_frame_request) { | 216 const base::Closure& key_frame_request) { |
| 218 base::AutoLock lock(lock_); | 217 base::AutoLock lock(lock_); |
| 219 key_frame_request_ = key_frame_request; | 218 key_frame_request_ = key_frame_request; |
| 220 if (encoders_.size() == 1) { | 219 if (encoders_.size() == 1) { |
| 221 encoders_.front()->SetKeyFrameRequestCallback(key_frame_request); | 220 encoders_.front()->SetKeyFrameRequestCallback(key_frame_request); |
| 222 } else { | 221 } else { |
| 223 LOG(ERROR) << "Dropping key frame request callback with unexpected" | 222 LOG(ERROR) << "Dropping key frame request callback with unexpected" |
| 224 " number of encoders: " | 223 " number of encoders: " |
| 225 << encoders_.size(); | 224 << encoders_.size(); |
| 226 } | 225 } |
| 227 } | 226 } |
| 228 | 227 |
| 229 void WebrtcVideoEncoderFactory::SetTargetBitrateCallback( | 228 void WebrtcVideoEncoderFactory::SetTargetBitrateCallback( |
| 230 const TargetBitrateCallback& target_bitrate_cb) { | 229 const TargetBitrateCallback& target_bitrate_cb) { |
| 231 base::AutoLock lock(lock_); | 230 base::AutoLock lock(lock_); |
| 232 target_bitrate_cb_ = target_bitrate_cb; | 231 target_bitrate_cb_ = target_bitrate_cb; |
| 233 if (encoders_.size() == 1) { | 232 if (encoders_.size() == 1) { |
| 234 encoders_.front()->SetTargetBitrateCallback(target_bitrate_cb); | 233 encoders_.front()->SetTargetBitrateCallback(target_bitrate_cb); |
| 235 } else { | 234 } else { |
| 236 LOG(ERROR) << "Dropping target bitrate request callback with unexpected" | 235 LOG(ERROR) << "Dropping target bitrate request callback with unexpected" |
| 237 " number of encoders: " | 236 " number of encoders: " |
| 238 << encoders_.size(); | 237 << encoders_.size(); |
| 239 } | 238 } |
| 240 } | 239 } |
| 240 |
| 241 } // namespace remoting | 241 } // namespace remoting |
| OLD | NEW |