Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(244)

Side by Side Diff: remoting/protocol/webrtc_video_encoder_factory.cc

Issue 1908203002: Adapt encoder behavior to target bitrate (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moved webrtc encoder to its own file Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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.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"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/ptr_util.h" 12 #include "base/memory/ptr_util.h"
13 #include "base/synchronization/lock.h" 13 #include "base/synchronization/lock.h"
14 14
15 namespace remoting { 15 namespace remoting {
(...skipping 21 matching lines...) Expand all
37 int streamCount = codec_settings->numberOfSimulcastStreams; 37 int streamCount = codec_settings->numberOfSimulcastStreams;
38 // Validate request is to support a single stream. 38 // Validate request is to support a single stream.
39 if (streamCount > 1) { 39 if (streamCount > 1) {
40 for (int i = 0; i < streamCount; ++i) { 40 for (int i = 0; i < streamCount; ++i) {
41 if (codec_settings->simulcastStream[i].maxBitrate != 0) { 41 if (codec_settings->simulcastStream[i].maxBitrate != 0) {
42 LOG(ERROR) << "Simulcast unsupported"; 42 LOG(ERROR) << "Simulcast unsupported";
43 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 43 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
44 } 44 }
45 } 45 }
46 } 46 }
47 target_bitrate_ = codec_settings->startBitrate;
48 state_ = kInitialized; 47 state_ = kInitialized;
49 return WEBRTC_VIDEO_CODEC_OK; 48 return WEBRTC_VIDEO_CODEC_OK;
50 } 49 }
51 50
52 int32_t WebRtcVideoEncoder::RegisterEncodeCompleteCallback( 51 int32_t WebRtcVideoEncoder::RegisterEncodeCompleteCallback(
53 webrtc::EncodedImageCallback* callback) { 52 webrtc::EncodedImageCallback* callback) {
54 base::AutoLock lock(lock_); 53 base::AutoLock lock(lock_);
55 DCHECK(callback); 54 DCHECK(callback);
56 encoded_callback_ = callback; 55 encoded_callback_ = callback;
57 return WEBRTC_VIDEO_CODEC_OK; 56 return WEBRTC_VIDEO_CODEC_OK;
(...skipping 19 matching lines...) Expand all
77 int64_t rtt) { 76 int64_t rtt) {
78 VLOG(1) << "WebRtcVideoEncoder::SetChannelParameters " 77 VLOG(1) << "WebRtcVideoEncoder::SetChannelParameters "
79 << "loss:RTT " << packet_loss << ":" << rtt; 78 << "loss:RTT " << packet_loss << ":" << rtt;
80 // Unused right now. 79 // Unused right now.
81 return WEBRTC_VIDEO_CODEC_OK; 80 return WEBRTC_VIDEO_CODEC_OK;
82 } 81 }
83 82
84 int32_t WebRtcVideoEncoder::SetRates(uint32_t bitrate, uint32_t framerate) { 83 int32_t WebRtcVideoEncoder::SetRates(uint32_t bitrate, uint32_t framerate) {
85 VLOG(1) << "WebRtcVideoEncoder::SetRates bitrate:framerate " << bitrate << ":" 84 VLOG(1) << "WebRtcVideoEncoder::SetRates bitrate:framerate " << bitrate << ":"
86 << framerate; 85 << framerate;
87 target_bitrate_ = bitrate; 86 if (!target_bitrate_cb_.is_null())
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(int64_t capture_timestamp_ms, 93 int WebRtcVideoEncoder::SendEncodedFrame(std::unique_ptr<VideoPacket> frame) {
94 std::unique_ptr<VideoPacket> frame) {
95 uint8_t* buffer = 94 uint8_t* buffer =
96 reinterpret_cast<uint8_t*>(const_cast<char*>(frame->data().data())); 95 reinterpret_cast<uint8_t*>(const_cast<char*>(frame->data().data()));
97 size_t buffer_size = frame->data().size(); 96 size_t buffer_size = frame->data().size();
98 base::AutoLock lock(lock_); 97 base::AutoLock lock(lock_);
99 if (state_ == kUninitialized) { 98 if (state_ == kUninitialized) {
100 LOG(ERROR) << "encoder interface uninitialized"; 99 LOG(ERROR) << "encoder interface uninitialized";
101 return -1; 100 return -1;
102 } 101 }
103 102
104 webrtc::EncodedImage encoded_image(buffer, buffer_size, buffer_size); 103 webrtc::EncodedImage encoded_image(buffer, buffer_size, buffer_size);
105 encoded_image._encodedWidth = frame->format().screen_width(); 104 encoded_image._encodedWidth = frame->format().screen_width();
106 encoded_image._encodedHeight = frame->format().screen_height(); 105 encoded_image._encodedHeight = frame->format().screen_height();
107 encoded_image._completeFrame = true; 106 encoded_image._completeFrame = true;
108 encoded_image._frameType = 107 encoded_image._frameType =
109 frame->key_frame() ? webrtc::kVideoFrameKey : webrtc::kVideoFrameDelta; 108 frame->key_frame() ? webrtc::kVideoFrameKey : webrtc::kVideoFrameDelta;
110 encoded_image.capture_time_ms_ = capture_timestamp_ms; 109 encoded_image.capture_time_ms_ = frame->capture_time_ms();
Sergey Ulanov 2016/05/10 00:00:58 VideoPacket::capture_time_ms() returns time it too
Irfan 2016/05/10 16:30:45 Agree that this is abuse of the VideoPacket captur
111 encoded_image._timeStamp = static_cast<uint32_t>(capture_timestamp_ms * 90); 110 encoded_image._timeStamp =
111 static_cast<uint32_t>(frame->capture_time_ms() * 90);
Sergey Ulanov 2016/05/10 00:00:58 same here. capture_time_ms() is not timestamp
112 112
113 webrtc::CodecSpecificInfo codec_specific_info; 113 webrtc::CodecSpecificInfo codec_specific_info;
114 memset(&codec_specific_info, 0, sizeof(codec_specific_info)); 114 memset(&codec_specific_info, 0, sizeof(codec_specific_info));
115 codec_specific_info.codecType = webrtc::kVideoCodecVP8; 115 codec_specific_info.codecType = webrtc::kVideoCodecVP8;
116 116
117 webrtc::RTPFragmentationHeader header; 117 webrtc::RTPFragmentationHeader header;
118 memset(&header, 0, sizeof(header)); 118 memset(&header, 0, sizeof(header));
119 119
120 codec_specific_info.codecSpecific.VP8.simulcastIdx = 0; 120 codec_specific_info.codecSpecific.VP8.simulcastIdx = 0;
121 codec_specific_info.codecSpecific.VP8.temporalIdx = webrtc::kNoTemporalIdx; 121 codec_specific_info.codecSpecific.VP8.temporalIdx = webrtc::kNoTemporalIdx;
(...skipping 15 matching lines...) Expand all
137 } 137 }
138 return result; 138 return result;
139 } 139 }
140 140
141 void WebRtcVideoEncoder::SetKeyFrameRequestCallback( 141 void WebRtcVideoEncoder::SetKeyFrameRequestCallback(
142 const base::Closure& key_frame_request) { 142 const base::Closure& key_frame_request) {
143 base::AutoLock lock(lock_); 143 base::AutoLock lock(lock_);
144 key_frame_request_ = key_frame_request; 144 key_frame_request_ = key_frame_request;
145 } 145 }
146 146
147 void WebRtcVideoEncoder::SetTargetBitrateCallback(
148 const TargetBitrateCallback& target_bitrate_cb) {
149 base::AutoLock lock(lock_);
150 target_bitrate_cb_ = target_bitrate_cb;
151 }
152
147 WebRtcVideoEncoderFactory::WebRtcVideoEncoderFactory() { 153 WebRtcVideoEncoderFactory::WebRtcVideoEncoderFactory() {
148 // TODO(isheriff): These do not really affect anything internally 154 // TODO(isheriff): These do not really affect anything internally
149 // in webrtc. 155 // in webrtc.
150 codecs_.push_back(cricket::WebRtcVideoEncoderFactory::VideoCodec( 156 codecs_.push_back(cricket::WebRtcVideoEncoderFactory::VideoCodec(
151 webrtc::kVideoCodecVP8, "VP8", 1280, 720, 30)); 157 webrtc::kVideoCodecVP8, "VP8", 1280, 720, 30));
152 } 158 }
153 159
154 WebRtcVideoEncoderFactory::~WebRtcVideoEncoderFactory() { 160 WebRtcVideoEncoderFactory::~WebRtcVideoEncoderFactory() {
155 DCHECK(encoders_.empty()); 161 DCHECK(encoders_.empty());
156 } 162 }
157 163
158 webrtc::VideoEncoder* WebRtcVideoEncoderFactory::CreateVideoEncoder( 164 webrtc::VideoEncoder* WebRtcVideoEncoderFactory::CreateVideoEncoder(
159 webrtc::VideoCodecType type) { 165 webrtc::VideoCodecType type) {
160 VLOG(2) << "WebRtcVideoEncoderFactory::CreateVideoEncoder " << type; 166 VLOG(2) << "WebRtcVideoEncoderFactory::CreateVideoEncoder " << type;
161 DCHECK(type == webrtc::kVideoCodecVP8); 167 DCHECK(type == webrtc::kVideoCodecVP8);
162 WebRtcVideoEncoder* encoder = new WebRtcVideoEncoder(type); 168 WebRtcVideoEncoder* encoder = new WebRtcVideoEncoder(type);
163 base::AutoLock lock(lock_); 169 base::AutoLock lock(lock_);
164 encoder->SetKeyFrameRequestCallback(key_frame_request_); 170 encoder->SetKeyFrameRequestCallback(key_frame_request_);
171 encoder->SetTargetBitrateCallback(target_bitrate_cb_);
165 VLOG(1) << "Created " << encoder; 172 VLOG(1) << "Created " << encoder;
166 encoders_.push_back(base::WrapUnique(encoder)); 173 encoders_.push_back(base::WrapUnique(encoder));
167 return encoder; 174 return encoder;
168 } 175 }
169 176
170 const std::vector<cricket::WebRtcVideoEncoderFactory::VideoCodec>& 177 const std::vector<cricket::WebRtcVideoEncoderFactory::VideoCodec>&
171 WebRtcVideoEncoderFactory::codecs() const { 178 WebRtcVideoEncoderFactory::codecs() const {
172 VLOG(2) << "WebRtcVideoEncoderFactory::codecs"; 179 VLOG(2) << "WebRtcVideoEncoderFactory::codecs";
173 return codecs_; 180 return codecs_;
174 } 181 }
(...skipping 14 matching lines...) Expand all
189 for (auto pos = encoders_.begin(); pos != encoders_.end(); ++pos) { 196 for (auto pos = encoders_.begin(); pos != encoders_.end(); ++pos) {
190 if ((*pos).get() == encoder) { 197 if ((*pos).get() == encoder) {
191 encoders_.erase(pos); 198 encoders_.erase(pos);
192 return; 199 return;
193 } 200 }
194 } 201 }
195 DCHECK(false) << "Asked to remove encoder not owned by factory"; 202 DCHECK(false) << "Asked to remove encoder not owned by factory";
196 } 203 }
197 204
198 int WebRtcVideoEncoderFactory::SendEncodedFrame( 205 int WebRtcVideoEncoderFactory::SendEncodedFrame(
199 int64_t capture_timestamp_ms,
200 std::unique_ptr<VideoPacket> frame) { 206 std::unique_ptr<VideoPacket> frame) {
201 if (encoders_.size() != 1) { 207 if (encoders_.size() != 1) {
202 LOG(ERROR) << "Unexpected number of encoders " << encoders_.size(); 208 LOG(ERROR) << "Unexpected number of encoders " << encoders_.size();
203 return -1; 209 return -1;
204 } 210 }
205 return encoders_.front()->SendEncodedFrame(capture_timestamp_ms, 211 return encoders_.front()->SendEncodedFrame(std::move(frame));
206 std::move(frame));
207 } 212 }
208 213
209 void WebRtcVideoEncoderFactory::SetKeyFrameRequestCallback( 214 void WebRtcVideoEncoderFactory::SetKeyFrameRequestCallback(
210 const base::Closure& key_frame_request) { 215 const base::Closure& key_frame_request) {
211 base::AutoLock lock(lock_); 216 base::AutoLock lock(lock_);
212 key_frame_request_ = key_frame_request; 217 key_frame_request_ = key_frame_request;
213 if (encoders_.size() == 1) { 218 if (encoders_.size() == 1) {
214 encoders_.front()->SetKeyFrameRequestCallback(key_frame_request); 219 encoders_.front()->SetKeyFrameRequestCallback(key_frame_request);
215 } else { 220 } else {
216 LOG(ERROR) << "Dropping key frame request callback with unexpected" 221 LOG(ERROR) << "Dropping key frame request callback with unexpected"
217 " number of encoders" 222 " number of encoders"
218 << encoders_.size(); 223 << encoders_.size();
219 } 224 }
220 } 225 }
226
227 void WebRtcVideoEncoderFactory::SetTargetBitrateCallback(
228 const TargetBitrateCallback& target_bitrate_cb) {
229 base::AutoLock lock(lock_);
230 target_bitrate_cb_ = target_bitrate_cb;
231 if (encoders_.size() == 1) {
232 encoders_.front()->SetTargetBitrateCallback(target_bitrate_cb);
233 } else {
234 LOG(ERROR) << "Dropping target bitrate request callback with unexpected"
235 " number of encoders"
236 << encoders_.size();
237 }
238 }
221 } // namespace remoting 239 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698