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

Side by Side Diff: webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc

Issue 2489843002: Revert of Extract bitrate allocation of spatial/temporal layers out of codec impl. (Closed)
Patch Set: Created 4 years, 1 month 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 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 VP8Encoder* VP8Encoder::Create() { 106 VP8Encoder* VP8Encoder::Create() {
107 return new VP8EncoderImpl(); 107 return new VP8EncoderImpl();
108 } 108 }
109 109
110 VP8Decoder* VP8Decoder::Create() { 110 VP8Decoder* VP8Decoder::Create() {
111 return new VP8DecoderImpl(); 111 return new VP8DecoderImpl();
112 } 112 }
113 113
114 VP8EncoderImpl::VP8EncoderImpl() 114 VP8EncoderImpl::VP8EncoderImpl()
115 : encoded_complete_callback_(nullptr), 115 : encoded_complete_callback_(nullptr),
116 rate_allocator_(new SimulcastRateAllocator(codec_)),
116 inited_(false), 117 inited_(false),
117 timestamp_(0), 118 timestamp_(0),
118 feedback_mode_(false), 119 feedback_mode_(false),
119 qp_max_(56), // Setting for max quantizer. 120 qp_max_(56), // Setting for max quantizer.
120 cpu_speed_default_(-6), 121 cpu_speed_default_(-6),
121 number_of_cores_(0), 122 number_of_cores_(0),
122 rc_max_intra_target_(0), 123 rc_max_intra_target_(0),
123 token_partitions_(VP8_ONE_TOKENPARTITION), 124 token_partitions_(VP8_ONE_TOKENPARTITION),
124 down_scale_requested_(false), 125 down_scale_requested_(false),
125 down_scale_bitrate_(0), 126 down_scale_bitrate_(0),
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 raw_images_.pop_back(); 168 raw_images_.pop_back();
168 } 169 }
169 while (!temporal_layers_.empty()) { 170 while (!temporal_layers_.empty()) {
170 delete temporal_layers_.back(); 171 delete temporal_layers_.back();
171 temporal_layers_.pop_back(); 172 temporal_layers_.pop_back();
172 } 173 }
173 inited_ = false; 174 inited_ = false;
174 return ret_val; 175 return ret_val;
175 } 176 }
176 177
177 int VP8EncoderImpl::SetRateAllocation(const BitrateAllocation& bitrate, 178 int VP8EncoderImpl::SetRates(uint32_t new_bitrate_kbit,
178 uint32_t new_framerate) { 179 uint32_t new_framerate) {
179 if (!inited_) 180 if (!inited_) {
180 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; 181 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
181 182 }
182 if (encoders_[0].err) 183 if (encoders_[0].err) {
183 return WEBRTC_VIDEO_CODEC_ERROR; 184 return WEBRTC_VIDEO_CODEC_ERROR;
184 185 }
185 if (new_framerate < 1) 186 if (new_framerate < 1) {
186 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 187 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
187
188 if (bitrate.get_sum_bps() == 0) {
189 // Encoder paused, turn off all encoding.
190 const int num_streams = static_cast<size_t>(encoders_.size());
191 for (int i = 0; i < num_streams; ++i)
192 SetStreamState(false, i);
193 return WEBRTC_VIDEO_CODEC_OK;
194 } 188 }
195 189 if (codec_.maxBitrate > 0 && new_bitrate_kbit > codec_.maxBitrate) {
196 // At this point, bitrate allocation should already match codec settings. 190 new_bitrate_kbit = codec_.maxBitrate;
197 if (codec_.maxBitrate > 0) 191 }
198 RTC_DCHECK_LE(bitrate.get_sum_kbps(), codec_.maxBitrate); 192 if (new_bitrate_kbit < codec_.minBitrate) {
199 RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.minBitrate); 193 new_bitrate_kbit = codec_.minBitrate;
200 if (codec_.numberOfSimulcastStreams > 0) 194 }
201 RTC_DCHECK_GE(bitrate.get_sum_kbps(), codec_.simulcastStream[0].minBitrate); 195 if (codec_.numberOfSimulcastStreams > 0 &&
202 196 new_bitrate_kbit < codec_.simulcastStream[0].minBitrate) {
197 new_bitrate_kbit = codec_.simulcastStream[0].minBitrate;
198 }
203 codec_.maxFramerate = new_framerate; 199 codec_.maxFramerate = new_framerate;
204 200
205 if (encoders_.size() == 1) { 201 if (encoders_.size() == 1) {
206 // 1:1. 202 // 1:1.
207 // Calculate a rough limit for when to trigger a potental down scale. 203 // Calculate a rough limit for when to trigger a potental down scale.
208 uint32_t k_pixels_per_frame = codec_.width * codec_.height / 1000; 204 uint32_t k_pixels_per_frame = codec_.width * codec_.height / 1000;
209 // TODO(pwestin): we currently lack CAMA, this is a temporary fix to work 205 // TODO(pwestin): we currently lack CAMA, this is a temporary fix to work
210 // around the current limitations. 206 // around the current limitations.
211 // Only trigger keyframes if we are allowed to scale down. 207 // Only trigger keyframes if we are allowed to scale down.
212 if (configurations_[0].rc_resize_allowed) { 208 if (configurations_[0].rc_resize_allowed) {
213 if (!down_scale_requested_) { 209 if (!down_scale_requested_) {
214 if (k_pixels_per_frame > bitrate.get_sum_kbps()) { 210 if (k_pixels_per_frame > new_bitrate_kbit) {
215 down_scale_requested_ = true; 211 down_scale_requested_ = true;
216 down_scale_bitrate_ = bitrate.get_sum_kbps(); 212 down_scale_bitrate_ = new_bitrate_kbit;
217 key_frame_request_[0] = true; 213 key_frame_request_[0] = true;
218 } 214 }
219 } else { 215 } else {
220 if (bitrate.get_sum_kbps() > (2 * down_scale_bitrate_) || 216 if (new_bitrate_kbit > (2 * down_scale_bitrate_) ||
221 bitrate.get_sum_kbps() < (down_scale_bitrate_ / 2)) { 217 new_bitrate_kbit < (down_scale_bitrate_ / 2)) {
222 down_scale_requested_ = false; 218 down_scale_requested_ = false;
223 } 219 }
224 } 220 }
225 } 221 }
226 } else { 222 } else {
227 // If we have more than 1 stream, reduce the qp_max for the low resolution 223 // If we have more than 1 stream, reduce the qp_max for the low resolution
228 // stream if frame rate is not too low. The trade-off with lower qp_max is 224 // stream if frame rate is not too low. The trade-off with lower qp_max is
229 // possibly more dropped frames, so we only do this if the frame rate is 225 // possibly more dropped frames, so we only do this if the frame rate is
230 // above some threshold (base temporal layer is down to 1/4 for 3 layers). 226 // above some threshold (base temporal layer is down to 1/4 for 3 layers).
231 // We may want to condition this on bitrate later. 227 // We may want to condition this on bitrate later.
232 if (new_framerate > 20) { 228 if (new_framerate > 20) {
233 configurations_[encoders_.size() - 1].rc_max_quantizer = 45; 229 configurations_[encoders_.size() - 1].rc_max_quantizer = 45;
234 } else { 230 } else {
235 // Go back to default value set in InitEncode. 231 // Go back to default value set in InitEncode.
236 configurations_[encoders_.size() - 1].rc_max_quantizer = qp_max_; 232 configurations_[encoders_.size() - 1].rc_max_quantizer = qp_max_;
237 } 233 }
238 } 234 }
239 235
236 std::vector<uint32_t> stream_bitrates =
237 rate_allocator_->GetAllocation(new_bitrate_kbit);
240 size_t stream_idx = encoders_.size() - 1; 238 size_t stream_idx = encoders_.size() - 1;
241 for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) { 239 for (size_t i = 0; i < encoders_.size(); ++i, --stream_idx) {
242 unsigned int target_bitrate_kbps = 240 if (encoders_.size() > 1)
243 bitrate.GetSpatialLayerSum(stream_idx) / 1000; 241 SetStreamState(stream_bitrates[stream_idx] > 0, stream_idx);
244 242
245 bool send_stream = target_bitrate_kbps > 0; 243 unsigned int target_bitrate = stream_bitrates[stream_idx];
246 if (send_stream || encoders_.size() > 1) 244 unsigned int max_bitrate = codec_.maxBitrate;
247 SetStreamState(send_stream, stream_idx); 245 int framerate = new_framerate;
248 246 // TODO(holmer): This is a temporary hack for screensharing, where we
249 configurations_[i].rc_target_bitrate = target_bitrate_kbps; 247 // interpret the startBitrate as the encoder target bitrate. This is
250 temporal_layers_[stream_idx]->UpdateConfiguration(&configurations_[i]); 248 // to allow for a different max bitrate, so if the codec can't meet
251 249 // the target we still allow it to overshoot up to the max before dropping
250 // frames. This hack should be improved.
251 if (codec_.targetBitrate > 0 &&
252 (codec_.VP8()->numberOfTemporalLayers == 2 ||
253 codec_.simulcastStream[0].numberOfTemporalLayers == 2)) {
254 int tl0_bitrate = std::min(codec_.targetBitrate, target_bitrate);
255 max_bitrate = std::min(codec_.maxBitrate, target_bitrate);
256 target_bitrate = tl0_bitrate;
257 }
258 configurations_[i].rc_target_bitrate = target_bitrate;
259 temporal_layers_[stream_idx]->ConfigureBitrates(
260 target_bitrate, max_bitrate, framerate, &configurations_[i]);
252 if (vpx_codec_enc_config_set(&encoders_[i], &configurations_[i])) { 261 if (vpx_codec_enc_config_set(&encoders_[i], &configurations_[i])) {
253 return WEBRTC_VIDEO_CODEC_ERROR; 262 return WEBRTC_VIDEO_CODEC_ERROR;
254 } 263 }
255 } 264 }
256 quality_scaler_.ReportFramerate(new_framerate); 265 quality_scaler_.ReportFramerate(new_framerate);
257 return WEBRTC_VIDEO_CODEC_OK; 266 return WEBRTC_VIDEO_CODEC_OK;
258 } 267 }
259 268
260 void VP8EncoderImpl::OnDroppedFrame() { 269 void VP8EncoderImpl::OnDroppedFrame() {
261 if (quality_scaler_enabled_) 270 if (quality_scaler_enabled_)
262 quality_scaler_.ReportDroppedFrame(); 271 quality_scaler_.ReportDroppedFrame();
263 } 272 }
264 273
265 const char* VP8EncoderImpl::ImplementationName() const { 274 const char* VP8EncoderImpl::ImplementationName() const {
266 return "libvpx"; 275 return "libvpx";
267 } 276 }
268 277
269 void VP8EncoderImpl::SetStreamState(bool send_stream, 278 void VP8EncoderImpl::SetStreamState(bool send_stream,
270 int stream_idx) { 279 int stream_idx) {
271 if (send_stream && !send_stream_[stream_idx]) { 280 if (send_stream && !send_stream_[stream_idx]) {
272 // Need a key frame if we have not sent this stream before. 281 // Need a key frame if we have not sent this stream before.
273 key_frame_request_[stream_idx] = true; 282 key_frame_request_[stream_idx] = true;
274 } 283 }
275 send_stream_[stream_idx] = send_stream; 284 send_stream_[stream_idx] = send_stream;
276 } 285 }
277 286
278 void VP8EncoderImpl::SetupTemporalLayers(int num_streams, 287 void VP8EncoderImpl::SetupTemporalLayers(int num_streams,
279 int num_temporal_layers, 288 int num_temporal_layers,
280 const VideoCodec& codec) { 289 const VideoCodec& codec) {
281 RTC_DCHECK(codec.codecSpecific.VP8.tl_factory != nullptr); 290 TemporalLayersFactory default_factory;
282 const TemporalLayersFactory* tl_factory = codec.codecSpecific.VP8.tl_factory; 291 const TemporalLayersFactory* tl_factory = codec.VP8().tl_factory;
292 if (!tl_factory)
293 tl_factory = &default_factory;
283 if (num_streams == 1) { 294 if (num_streams == 1) {
284 temporal_layers_.push_back( 295 if (codec.mode == kScreensharing) {
285 tl_factory->Create(0, num_temporal_layers, rand())); 296 // Special mode when screensharing on a single stream.
297 temporal_layers_.push_back(new ScreenshareLayers(
298 num_temporal_layers, rand(), webrtc::Clock::GetRealTimeClock()));
299 } else {
300 temporal_layers_.push_back(
301 tl_factory->Create(num_temporal_layers, rand()));
302 }
286 } else { 303 } else {
287 for (int i = 0; i < num_streams; ++i) { 304 for (int i = 0; i < num_streams; ++i) {
288 RTC_CHECK_GT(num_temporal_layers, 0); 305 // TODO(andresp): crash if layers is invalid.
289 int layers = std::max(static_cast<uint8_t>(1), 306 int layers = codec.simulcastStream[i].numberOfTemporalLayers;
290 codec.simulcastStream[i].numberOfTemporalLayers); 307 if (layers < 1)
291 temporal_layers_.push_back(tl_factory->Create(i, layers, rand())); 308 layers = 1;
309 temporal_layers_.push_back(tl_factory->Create(layers, rand()));
292 } 310 }
293 } 311 }
294 } 312 }
295 313
296 int VP8EncoderImpl::InitEncode(const VideoCodec* inst, 314 int VP8EncoderImpl::InitEncode(const VideoCodec* inst,
297 int number_of_cores, 315 int number_of_cores,
298 size_t /*maxPayloadSize */) { 316 size_t /*maxPayloadSize */) {
299 if (inst == NULL) { 317 if (inst == NULL) {
300 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 318 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
301 } 319 }
(...skipping 24 matching lines...) Expand all
326 int number_of_streams = NumberOfStreams(*inst); 344 int number_of_streams = NumberOfStreams(*inst);
327 bool doing_simulcast = (number_of_streams > 1); 345 bool doing_simulcast = (number_of_streams > 1);
328 346
329 if (doing_simulcast && !ValidSimulcastResolutions(*inst, number_of_streams)) { 347 if (doing_simulcast && !ValidSimulcastResolutions(*inst, number_of_streams)) {
330 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; 348 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
331 } 349 }
332 350
333 int num_temporal_layers = 351 int num_temporal_layers =
334 doing_simulcast ? inst->simulcastStream[0].numberOfTemporalLayers 352 doing_simulcast ? inst->simulcastStream[0].numberOfTemporalLayers
335 : inst->VP8().numberOfTemporalLayers; 353 : inst->VP8().numberOfTemporalLayers;
336 RTC_DCHECK_GT(num_temporal_layers, 0);
337 354
355 // TODO(andresp): crash if num temporal layers is bananas.
356 if (num_temporal_layers < 1)
357 num_temporal_layers = 1;
338 SetupTemporalLayers(number_of_streams, num_temporal_layers, *inst); 358 SetupTemporalLayers(number_of_streams, num_temporal_layers, *inst);
339 359
340 feedback_mode_ = inst->VP8().feedbackModeOn; 360 feedback_mode_ = inst->VP8().feedbackModeOn;
341 361
342 number_of_cores_ = number_of_cores; 362 number_of_cores_ = number_of_cores;
343 timestamp_ = 0; 363 timestamp_ = 0;
344 codec_ = *inst; 364 codec_ = *inst;
365 rate_allocator_.reset(new SimulcastRateAllocator(codec_));
345 366
346 // Code expects simulcastStream resolutions to be correct, make sure they are 367 // Code expects simulcastStream resolutions to be correct, make sure they are
347 // filled even when there are no simulcast layers. 368 // filled even when there are no simulcast layers.
348 if (codec_.numberOfSimulcastStreams == 0) { 369 if (codec_.numberOfSimulcastStreams == 0) {
349 codec_.simulcastStream[0].width = codec_.width; 370 codec_.simulcastStream[0].width = codec_.width;
350 codec_.simulcastStream[0].height = codec_.height; 371 codec_.simulcastStream[0].height = codec_.height;
351 } 372 }
352 373
353 picture_id_.resize(number_of_streams); 374 picture_id_.resize(number_of_streams);
354 last_key_frame_picture_id_.resize(number_of_streams); 375 last_key_frame_picture_id_.resize(number_of_streams);
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 // TODO(fbarchard): Consider number of Simulcast layers. 507 // TODO(fbarchard): Consider number of Simulcast layers.
487 configurations_[0].g_threads = NumberOfThreads( 508 configurations_[0].g_threads = NumberOfThreads(
488 configurations_[0].g_w, configurations_[0].g_h, number_of_cores); 509 configurations_[0].g_w, configurations_[0].g_h, number_of_cores);
489 510
490 // Creating a wrapper to the image - setting image data to NULL. 511 // Creating a wrapper to the image - setting image data to NULL.
491 // Actual pointer will be set in encode. Setting align to 1, as it 512 // Actual pointer will be set in encode. Setting align to 1, as it
492 // is meaningless (no memory allocation is done here). 513 // is meaningless (no memory allocation is done here).
493 vpx_img_wrap(&raw_images_[0], VPX_IMG_FMT_I420, inst->width, inst->height, 1, 514 vpx_img_wrap(&raw_images_[0], VPX_IMG_FMT_I420, inst->width, inst->height, 1,
494 NULL); 515 NULL);
495 516
496 // Note the order we use is different from webm, we have lowest resolution 517 if (encoders_.size() == 1) {
497 // at position 0 and they have highest resolution at position 0. 518 configurations_[0].rc_target_bitrate = inst->startBitrate;
498 int stream_idx = encoders_.size() - 1; 519 temporal_layers_[0]->ConfigureBitrates(inst->startBitrate, inst->maxBitrate,
499 SimulcastRateAllocator init_allocator(codec_, nullptr); 520 inst->maxFramerate,
500 BitrateAllocation allocation = init_allocator.GetAllocation( 521 &configurations_[0]);
501 inst->startBitrate * 1000, inst->maxFramerate); 522 } else {
502 std::vector<uint32_t> stream_bitrates; 523 // Note the order we use is different from webm, we have lowest resolution
503 for (int i = 0; i == 0 || i < inst->numberOfSimulcastStreams; ++i) { 524 // at position 0 and they have highest resolution at position 0.
504 uint32_t bitrate = allocation.GetSpatialLayerSum(i) / 1000; 525 int stream_idx = encoders_.size() - 1;
505 stream_bitrates.push_back(bitrate); 526 std::vector<uint32_t> stream_bitrates =
506 } 527 rate_allocator_->GetAllocation(inst->startBitrate);
528 SetStreamState(stream_bitrates[stream_idx] > 0, stream_idx);
529 configurations_[0].rc_target_bitrate = stream_bitrates[stream_idx];
530 temporal_layers_[stream_idx]->ConfigureBitrates(
531 stream_bitrates[stream_idx], inst->maxBitrate, inst->maxFramerate,
532 &configurations_[0]);
533 --stream_idx;
534 for (size_t i = 1; i < encoders_.size(); ++i, --stream_idx) {
535 memcpy(&configurations_[i], &configurations_[0],
536 sizeof(configurations_[0]));
507 537
508 configurations_[0].rc_target_bitrate = stream_bitrates[stream_idx]; 538 configurations_[i].g_w = inst->simulcastStream[stream_idx].width;
509 temporal_layers_[stream_idx]->OnRatesUpdated( 539 configurations_[i].g_h = inst->simulcastStream[stream_idx].height;
510 stream_bitrates[stream_idx], inst->maxBitrate, inst->maxFramerate);
511 temporal_layers_[stream_idx]->UpdateConfiguration(&configurations_[0]);
512 --stream_idx;
513 for (size_t i = 1; i < encoders_.size(); ++i, --stream_idx) {
514 memcpy(&configurations_[i], &configurations_[0],
515 sizeof(configurations_[0]));
516 540
517 configurations_[i].g_w = inst->simulcastStream[stream_idx].width; 541 // Use 1 thread for lower resolutions.
518 configurations_[i].g_h = inst->simulcastStream[stream_idx].height; 542 configurations_[i].g_threads = 1;
519 543
520 // Use 1 thread for lower resolutions. 544 // Setting alignment to 32 - as that ensures at least 16 for all
521 configurations_[i].g_threads = 1; 545 // planes (32 for Y, 16 for U,V). Libvpx sets the requested stride for
522 546 // the y plane, but only half of it to the u and v planes.
523 // Setting alignment to 32 - as that ensures at least 16 for all 547 vpx_img_alloc(&raw_images_[i], VPX_IMG_FMT_I420,
524 // planes (32 for Y, 16 for U,V). Libvpx sets the requested stride for 548 inst->simulcastStream[stream_idx].width,
525 // the y plane, but only half of it to the u and v planes. 549 inst->simulcastStream[stream_idx].height, kVp832ByteAlign);
526 vpx_img_alloc(&raw_images_[i], VPX_IMG_FMT_I420, 550 SetStreamState(stream_bitrates[stream_idx] > 0, stream_idx);
527 inst->simulcastStream[stream_idx].width, 551 configurations_[i].rc_target_bitrate = stream_bitrates[stream_idx];
528 inst->simulcastStream[stream_idx].height, kVp832ByteAlign); 552 temporal_layers_[stream_idx]->ConfigureBitrates(
529 SetStreamState(stream_bitrates[stream_idx] > 0, stream_idx); 553 stream_bitrates[stream_idx], inst->maxBitrate, inst->maxFramerate,
530 configurations_[i].rc_target_bitrate = stream_bitrates[stream_idx]; 554 &configurations_[i]);
531 temporal_layers_[stream_idx]->OnRatesUpdated( 555 }
532 stream_bitrates[stream_idx], inst->maxBitrate, inst->maxFramerate);
533 temporal_layers_[stream_idx]->UpdateConfiguration(&configurations_[i]);
534 } 556 }
535 557
536 rps_.Init(); 558 rps_.Init();
537 quality_scaler_.Init(codec_.codecType, codec_.startBitrate, codec_.width, 559 quality_scaler_.Init(codec_.codecType, codec_.startBitrate, codec_.width,
538 codec_.height, codec_.maxFramerate); 560 codec_.height, codec_.maxFramerate);
539 561
540 // Only apply scaling to improve for single-layer streams. The scaling metrics 562 // Only apply scaling to improve for single-layer streams. The scaling metrics
541 // use frame drops as a signal and is only applicable when we drop frames. 563 // use frame drops as a signal and is only applicable when we drop frames.
542 quality_scaler_enabled_ = encoders_.size() == 1 && 564 quality_scaler_enabled_ = encoders_.size() == 1 &&
543 configurations_[0].rc_dropframe_thresh > 0 && 565 configurations_[0].rc_dropframe_thresh > 0 &&
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 return -1; 1334 return -1;
1313 } 1335 }
1314 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) != 1336 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) !=
1315 VPX_CODEC_OK) { 1337 VPX_CODEC_OK) {
1316 return -1; 1338 return -1;
1317 } 1339 }
1318 return 0; 1340 return 0;
1319 } 1341 }
1320 1342
1321 } // namespace webrtc 1343 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/codecs/vp8/vp8_impl.h ('k') | webrtc/modules/video_coding/codecs/vp9/vp9_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698