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

Side by Side Diff: remoting/codec/webrtc_video_encoder_vpx.cc

Issue 2616213002: Fix WebrtcVideoStream to handle failed capture requests. (Closed)
Patch Set: Created 3 years, 11 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/codec/webrtc_video_encoder_vpx.h" 5 #include "remoting/codec/webrtc_video_encoder_vpx.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 // TODO(wez): Switch to ConfigureCodec() path once libvpx supports it. 267 // TODO(wez): Switch to ConfigureCodec() path once libvpx supports it.
268 // See https://code.google.com/p/webm/issues/detail?id=913. 268 // See https://code.google.com/p/webm/issues/detail?id=913.
269 // if (codec_) 269 // if (codec_)
270 // Configure(webrtc::DesktopSize(codec_->config.enc->g_w, 270 // Configure(webrtc::DesktopSize(codec_->config.enc->g_w,
271 // codec_->config.enc->g_h)); 271 // codec_->config.enc->g_h));
272 codec_.reset(); 272 codec_.reset();
273 } 273 }
274 } 274 }
275 275
276 std::unique_ptr<WebrtcVideoEncoder::EncodedFrame> WebrtcVideoEncoderVpx::Encode( 276 std::unique_ptr<WebrtcVideoEncoder::EncodedFrame> WebrtcVideoEncoderVpx::Encode(
277 const webrtc::DesktopFrame& frame, 277 const webrtc::DesktopFrame* frame,
278 const FrameParams& params) { 278 const FrameParams& params) {
279 DCHECK_LE(32, frame.size().width()); 279 webrtc::DesktopSize previous_frame_size =
280 DCHECK_LE(32, frame.size().height()); 280 image_ ? webrtc::DesktopSize(image_->w, image_->h)
281 : webrtc::DesktopSize();
282
283 webrtc::DesktopSize frame_size = frame ? frame->size() : previous_frame_size;
284
285 // Don't need to send anything until we get the first non-null frame.
286 if (frame_size.is_empty()) {
287 return nullptr;
288 }
289
290 DCHECK_GE(frame_size.width(), 32);
291 DCHECK_GE(frame_size.height(), 32);
281 292
282 // Create or reconfigure the codec to match the size of |frame|. 293 // Create or reconfigure the codec to match the size of |frame|.
283 if (!codec_ || 294 if (!codec_ || !frame_size.equals(previous_frame_size)) {
284 (image_ && 295 Configure(frame_size);
285 !frame.size().equals(webrtc::DesktopSize(image_->w, image_->h)))) {
286 Configure(frame.size());
287 } 296 }
288 297
289 UpdateConfig(params); 298 UpdateConfig(params);
290 299
291 vpx_active_map_t act_map; 300 vpx_active_map_t act_map;
292 act_map.rows = active_map_size_.height(); 301 act_map.rows = active_map_size_.height();
293 act_map.cols = active_map_size_.width(); 302 act_map.cols = active_map_size_.width();
294 act_map.active_map = active_map_.get(); 303 act_map.active_map = active_map_.get();
295 304
296 webrtc::DesktopRegion updated_region; 305 webrtc::DesktopRegion updated_region;
297 // Convert the updated capture data ready for encode. 306 // Convert the updated capture data ready for encode.
298 PrepareImage(frame, &updated_region); 307 PrepareImage(frame, &updated_region);
299 308
300 // Update active map based on updated region. 309 // Update active map based on updated region.
301 if (params.clear_active_map) 310 if (params.clear_active_map)
302 ClearActiveMap(); 311 ClearActiveMap();
303 312
304 if (params.key_frame) 313 if (params.key_frame)
305 updated_region.SetRect(webrtc::DesktopRect::MakeSize(frame.size())); 314 updated_region.SetRect(webrtc::DesktopRect::MakeSize(frame_size));
306 315
307 SetActiveMapFromRegion(updated_region); 316 SetActiveMapFromRegion(updated_region);
308 317
309 // Apply active map to the encoder. 318 // Apply active map to the encoder.
310 if (vpx_codec_control(codec_.get(), VP8E_SET_ACTIVEMAP, &act_map)) { 319 if (vpx_codec_control(codec_.get(), VP8E_SET_ACTIVEMAP, &act_map)) {
311 LOG(ERROR) << "Unable to apply active map"; 320 LOG(ERROR) << "Unable to apply active map";
312 } 321 }
313 322
314 vpx_codec_err_t ret = vpx_codec_encode( 323 vpx_codec_err_t ret = vpx_codec_encode(
315 codec_.get(), image_.get(), 0, params.duration.InMicroseconds(), 324 codec_.get(), image_.get(), 0, params.duration.InMicroseconds(),
(...skipping 14 matching lines...) Expand all
330 } 339 }
331 340
332 UpdateRegionFromActiveMap(&updated_region); 341 UpdateRegionFromActiveMap(&updated_region);
333 } 342 }
334 343
335 // Read the encoded data. 344 // Read the encoded data.
336 vpx_codec_iter_t iter = nullptr; 345 vpx_codec_iter_t iter = nullptr;
337 bool got_data = false; 346 bool got_data = false;
338 347
339 std::unique_ptr<EncodedFrame> encoded_frame(new EncodedFrame()); 348 std::unique_ptr<EncodedFrame> encoded_frame(new EncodedFrame());
340 encoded_frame->size = frame.size(); 349 encoded_frame->size = frame_size;
341 350
342 while (!got_data) { 351 while (!got_data) {
343 const vpx_codec_cx_pkt_t* vpx_packet = 352 const vpx_codec_cx_pkt_t* vpx_packet =
344 vpx_codec_get_cx_data(codec_.get(), &iter); 353 vpx_codec_get_cx_data(codec_.get(), &iter);
345 if (!vpx_packet) 354 if (!vpx_packet)
346 continue; 355 continue;
347 356
348 switch (vpx_packet->kind) { 357 switch (vpx_packet->kind) {
349 case VPX_CODEC_CX_FRAME_PKT: { 358 case VPX_CODEC_CX_FRAME_PKT: {
350 got_data = true; 359 got_data = true;
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 if (!changed) 474 if (!changed)
466 return; 475 return;
467 476
468 // Update encoder context. 477 // Update encoder context.
469 if (vpx_codec_enc_config_set(codec_.get(), &config_)) 478 if (vpx_codec_enc_config_set(codec_.get(), &config_))
470 NOTREACHED() << "Unable to set encoder config"; 479 NOTREACHED() << "Unable to set encoder config";
471 480
472 } 481 }
473 482
474 void WebrtcVideoEncoderVpx::PrepareImage( 483 void WebrtcVideoEncoderVpx::PrepareImage(
475 const webrtc::DesktopFrame& frame, 484 const webrtc::DesktopFrame* frame,
476 webrtc::DesktopRegion* updated_region) { 485 webrtc::DesktopRegion* updated_region) {
477 if (frame.updated_region().is_empty()) { 486 if (!frame || frame->updated_region().is_empty()) {
478 updated_region->Clear(); 487 updated_region->Clear();
479 return; 488 return;
480 } 489 }
481 490
482 updated_region->Clear(); 491 updated_region->Clear();
483 if (image_) { 492 if (image_) {
484 // Pad each rectangle to avoid the block-artifact filters in libvpx from 493 // Pad each rectangle to avoid the block-artifact filters in libvpx from
485 // introducing artifacts; VP9 includes up to 8px either side, and VP8 up to 494 // introducing artifacts; VP9 includes up to 8px either side, and VP8 up to
486 // 3px, so unchanged pixels up to that far out may still be affected by the 495 // 3px, so unchanged pixels up to that far out may still be affected by the
487 // changes in the updated region, and so must be listed in the active map. 496 // changes in the updated region, and so must be listed in the active map.
488 // After padding we align each rectangle to 16x16 active-map macroblocks. 497 // After padding we align each rectangle to 16x16 active-map macroblocks.
489 // This implicitly ensures all rects have even top-left coords, which is 498 // This implicitly ensures all rects have even top-left coords, which is
490 // is required by ConvertRGBToYUVWithRect(). 499 // is required by ConvertRGBToYUVWithRect().
491 // TODO(wez): Do we still need 16x16 align, or is even alignment sufficient? 500 // TODO(wez): Do we still need 16x16 align, or is even alignment sufficient?
492 int padding = use_vp9_ ? 8 : 3; 501 int padding = use_vp9_ ? 8 : 3;
493 for (webrtc::DesktopRegion::Iterator r(frame.updated_region()); 502 for (webrtc::DesktopRegion::Iterator r(frame->updated_region());
494 !r.IsAtEnd(); r.Advance()) { 503 !r.IsAtEnd(); r.Advance()) {
495 const webrtc::DesktopRect& rect = r.rect(); 504 const webrtc::DesktopRect& rect = r.rect();
496 updated_region->AddRect(AlignRect(webrtc::DesktopRect::MakeLTRB( 505 updated_region->AddRect(AlignRect(webrtc::DesktopRect::MakeLTRB(
497 rect.left() - padding, rect.top() - padding, rect.right() + padding, 506 rect.left() - padding, rect.top() - padding, rect.right() + padding,
498 rect.bottom() + padding))); 507 rect.bottom() + padding)));
499 } 508 }
500 DCHECK(!updated_region->is_empty()); 509 DCHECK(!updated_region->is_empty());
501 510
502 // Clip back to the screen dimensions, in case they're not macroblock 511 // Clip back to the screen dimensions, in case they're not macroblock
503 // aligned. The conversion routines don't require even width & height, 512 // aligned. The conversion routines don't require even width & height,
504 // so this is safe even if the source dimensions are not even. 513 // so this is safe even if the source dimensions are not even.
505 updated_region->IntersectWith( 514 updated_region->IntersectWith(
506 webrtc::DesktopRect::MakeWH(image_->w, image_->h)); 515 webrtc::DesktopRect::MakeWH(image_->w, image_->h));
507 } else { 516 } else {
508 CreateImage(lossless_color_, frame.size(), &image_, &image_buffer_); 517 CreateImage(lossless_color_, frame->size(), &image_, &image_buffer_);
509 updated_region->AddRect(webrtc::DesktopRect::MakeWH(image_->w, image_->h)); 518 updated_region->AddRect(webrtc::DesktopRect::MakeWH(image_->w, image_->h));
510 } 519 }
511 520
512 // Convert the updated region to YUV ready for encoding. 521 // Convert the updated region to YUV ready for encoding.
513 const uint8_t* rgb_data = frame.data(); 522 const uint8_t* rgb_data = frame->data();
514 const int rgb_stride = frame.stride(); 523 const int rgb_stride = frame->stride();
515 const int y_stride = image_->stride[0]; 524 const int y_stride = image_->stride[0];
516 DCHECK_EQ(image_->stride[1], image_->stride[2]); 525 DCHECK_EQ(image_->stride[1], image_->stride[2]);
517 const int uv_stride = image_->stride[1]; 526 const int uv_stride = image_->stride[1];
518 uint8_t* y_data = image_->planes[0]; 527 uint8_t* y_data = image_->planes[0];
519 uint8_t* u_data = image_->planes[1]; 528 uint8_t* u_data = image_->planes[1];
520 uint8_t* v_data = image_->planes[2]; 529 uint8_t* v_data = image_->planes[2];
521 530
522 switch (image_->fmt) { 531 switch (image_->fmt) {
523 case VPX_IMG_FMT_I444: 532 case VPX_IMG_FMT_I444:
524 for (webrtc::DesktopRegion::Iterator r(*updated_region); !r.IsAtEnd(); 533 for (webrtc::DesktopRegion::Iterator r(*updated_region); !r.IsAtEnd();
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 kMacroBlockSize * (y + 1))); 607 kMacroBlockSize * (y + 1)));
599 } 608 }
600 x0 = x1 + 1; 609 x0 = x1 + 1;
601 } 610 }
602 } 611 }
603 updated_region->IntersectWith( 612 updated_region->IntersectWith(
604 webrtc::DesktopRect::MakeWH(image_->w, image_->h)); 613 webrtc::DesktopRect::MakeWH(image_->w, image_->h));
605 } 614 }
606 615
607 } // namespace remoting 616 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698