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

Side by Side Diff: webrtc/modules/video_coding/codec_database.cc

Issue 1474193002: Call InitDecode with proper resolution. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: nullptr woo Created 5 years 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 return vp9_settings; 59 return vp9_settings;
60 } 60 }
61 61
62 VideoCodecH264 VideoEncoder::GetDefaultH264Settings() { 62 VideoCodecH264 VideoEncoder::GetDefaultH264Settings() {
63 VideoCodecH264 h264_settings; 63 VideoCodecH264 h264_settings;
64 memset(&h264_settings, 0, sizeof(h264_settings)); 64 memset(&h264_settings, 0, sizeof(h264_settings));
65 65
66 h264_settings.profile = kProfileBase; 66 h264_settings.profile = kProfileBase;
67 h264_settings.frameDroppingOn = true; 67 h264_settings.frameDroppingOn = true;
68 h264_settings.keyFrameInterval = 3000; 68 h264_settings.keyFrameInterval = 3000;
69 h264_settings.spsData = NULL; 69 h264_settings.spsData = nullptr;
70 h264_settings.spsLen = 0; 70 h264_settings.spsLen = 0;
71 h264_settings.ppsData = NULL; 71 h264_settings.ppsData = nullptr;
72 h264_settings.ppsLen = 0; 72 h264_settings.ppsLen = 0;
73 73
74 return h264_settings; 74 return h264_settings;
75 } 75 }
76 76
77 VCMDecoderMapItem::VCMDecoderMapItem(VideoCodec* settings, 77 VCMDecoderMapItem::VCMDecoderMapItem(VideoCodec* settings,
78 int number_of_cores, 78 int number_of_cores,
79 bool require_key_frame) 79 bool require_key_frame)
80 : settings(settings), 80 : settings(settings),
81 number_of_cores(number_of_cores), 81 number_of_cores(number_of_cores),
(...skipping 13 matching lines...) Expand all
95 VCMCodecDataBase::VCMCodecDataBase( 95 VCMCodecDataBase::VCMCodecDataBase(
96 VideoEncoderRateObserver* encoder_rate_observer, 96 VideoEncoderRateObserver* encoder_rate_observer,
97 VCMEncodedFrameCallback* encoded_frame_callback) 97 VCMEncodedFrameCallback* encoded_frame_callback)
98 : number_of_cores_(0), 98 : number_of_cores_(0),
99 max_payload_size_(kDefaultPayloadSize), 99 max_payload_size_(kDefaultPayloadSize),
100 periodic_key_frames_(false), 100 periodic_key_frames_(false),
101 pending_encoder_reset_(true), 101 pending_encoder_reset_(true),
102 send_codec_(), 102 send_codec_(),
103 receive_codec_(), 103 receive_codec_(),
104 encoder_payload_type_(0), 104 encoder_payload_type_(0),
105 external_encoder_(NULL), 105 external_encoder_(nullptr),
106 internal_source_(false), 106 internal_source_(false),
107 encoder_rate_observer_(encoder_rate_observer), 107 encoder_rate_observer_(encoder_rate_observer),
108 encoded_frame_callback_(encoded_frame_callback), 108 encoded_frame_callback_(encoded_frame_callback),
109 ptr_decoder_(NULL), 109 ptr_decoder_(nullptr),
110 dec_map_(), 110 dec_map_(),
111 dec_external_map_() {} 111 dec_external_map_() {}
112 112
113 VCMCodecDataBase::~VCMCodecDataBase() { 113 VCMCodecDataBase::~VCMCodecDataBase() {
114 ResetSender(); 114 ResetSender();
115 ResetReceiver(); 115 ResetReceiver();
116 } 116 }
117 117
118 void VCMCodecDataBase::Codec(VideoCodecType codec_type, VideoCodec* settings) { 118 void VCMCodecDataBase::Codec(VideoCodecType codec_type, VideoCodec* settings) {
119 memset(settings, 0, sizeof(VideoCodec)); 119 memset(settings, 0, sizeof(VideoCodec));
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 if (encoder_payload_type_ != payload_type) { 293 if (encoder_payload_type_ != payload_type) {
294 return false; 294 return false;
295 } 295 }
296 if (send_codec_.plType == payload_type) { 296 if (send_codec_.plType == payload_type) {
297 // De-register as send codec if needed. 297 // De-register as send codec if needed.
298 DeleteEncoder(); 298 DeleteEncoder();
299 memset(&send_codec_, 0, sizeof(VideoCodec)); 299 memset(&send_codec_, 0, sizeof(VideoCodec));
300 *was_send_codec = true; 300 *was_send_codec = true;
301 } 301 }
302 encoder_payload_type_ = 0; 302 encoder_payload_type_ = 0;
303 external_encoder_ = NULL; 303 external_encoder_ = nullptr;
304 internal_source_ = false; 304 internal_source_ = false;
305 return true; 305 return true;
306 } 306 }
307 307
308 void VCMCodecDataBase::RegisterExternalEncoder( 308 void VCMCodecDataBase::RegisterExternalEncoder(
309 VideoEncoder* external_encoder, 309 VideoEncoder* external_encoder,
310 uint8_t payload_type, 310 uint8_t payload_type,
311 bool internal_source) { 311 bool internal_source) {
312 // Since only one encoder can be used at a given time, only one external 312 // Since only one encoder can be used at a given time, only one external
313 // encoder can be registered/used. 313 // encoder can be registered/used.
314 external_encoder_ = external_encoder; 314 external_encoder_ = external_encoder;
315 encoder_payload_type_ = payload_type; 315 encoder_payload_type_ = payload_type;
316 internal_source_ = internal_source; 316 internal_source_ = internal_source;
317 pending_encoder_reset_ = true; 317 pending_encoder_reset_ = true;
318 } 318 }
319 319
320 bool VCMCodecDataBase::RequiresEncoderReset(const VideoCodec& new_send_codec) { 320 bool VCMCodecDataBase::RequiresEncoderReset(const VideoCodec& new_send_codec) {
321 if (ptr_encoder_ == NULL) { 321 if (!ptr_encoder_)
322 return true; 322 return true;
323 }
324 323
325 // Does not check startBitrate or maxFramerate 324 // Does not check startBitrate or maxFramerate
326 if (new_send_codec.codecType != send_codec_.codecType || 325 if (new_send_codec.codecType != send_codec_.codecType ||
327 strcmp(new_send_codec.plName, send_codec_.plName) != 0 || 326 strcmp(new_send_codec.plName, send_codec_.plName) != 0 ||
328 new_send_codec.plType != send_codec_.plType || 327 new_send_codec.plType != send_codec_.plType ||
329 new_send_codec.width != send_codec_.width || 328 new_send_codec.width != send_codec_.width ||
330 new_send_codec.height != send_codec_.height || 329 new_send_codec.height != send_codec_.height ||
331 new_send_codec.maxBitrate != send_codec_.maxBitrate || 330 new_send_codec.maxBitrate != send_codec_.maxBitrate ||
332 new_send_codec.minBitrate != send_codec_.minBitrate || 331 new_send_codec.minBitrate != send_codec_.minBitrate ||
333 new_send_codec.qpMax != send_codec_.qpMax || 332 new_send_codec.qpMax != send_codec_.qpMax ||
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 bool VCMCodecDataBase::SetPeriodicKeyFrames(bool enable) { 392 bool VCMCodecDataBase::SetPeriodicKeyFrames(bool enable) {
394 periodic_key_frames_ = enable; 393 periodic_key_frames_ = enable;
395 if (ptr_encoder_) { 394 if (ptr_encoder_) {
396 return (ptr_encoder_->SetPeriodicKeyFrames(periodic_key_frames_) == 0); 395 return (ptr_encoder_->SetPeriodicKeyFrames(periodic_key_frames_) == 0);
397 } 396 }
398 return true; 397 return true;
399 } 398 }
400 399
401 void VCMCodecDataBase::ResetReceiver() { 400 void VCMCodecDataBase::ResetReceiver() {
402 ReleaseDecoder(ptr_decoder_); 401 ReleaseDecoder(ptr_decoder_);
403 ptr_decoder_ = NULL; 402 ptr_decoder_ = nullptr;
404 memset(&receive_codec_, 0, sizeof(VideoCodec)); 403 memset(&receive_codec_, 0, sizeof(VideoCodec));
405 while (!dec_map_.empty()) { 404 while (!dec_map_.empty()) {
406 DecoderMap::iterator it = dec_map_.begin(); 405 DecoderMap::iterator it = dec_map_.begin();
407 delete (*it).second; 406 delete (*it).second;
408 dec_map_.erase(it); 407 dec_map_.erase(it);
409 } 408 }
410 while (!dec_external_map_.empty()) { 409 while (!dec_external_map_.empty()) {
411 ExternalDecoderMap::iterator external_it = dec_external_map_.begin(); 410 ExternalDecoderMap::iterator external_it = dec_external_map_.begin();
412 delete (*external_it).second; 411 delete (*external_it).second;
413 dec_external_map_.erase(external_it); 412 dec_external_map_.erase(external_it);
414 } 413 }
415 } 414 }
416 415
417 bool VCMCodecDataBase::DeregisterExternalDecoder(uint8_t payload_type) { 416 bool VCMCodecDataBase::DeregisterExternalDecoder(uint8_t payload_type) {
418 ExternalDecoderMap::iterator it = dec_external_map_.find(payload_type); 417 ExternalDecoderMap::iterator it = dec_external_map_.find(payload_type);
419 if (it == dec_external_map_.end()) { 418 if (it == dec_external_map_.end()) {
420 // Not found 419 // Not found
421 return false; 420 return false;
422 } 421 }
423 // We can't use payload_type to check if the decoder is currently in use, 422 // We can't use payload_type to check if the decoder is currently in use,
424 // because payload type may be out of date (e.g. before we decode the first 423 // because payload type may be out of date (e.g. before we decode the first
425 // frame after RegisterReceiveCodec) 424 // frame after RegisterReceiveCodec)
426 if (ptr_decoder_ != NULL && 425 if (ptr_decoder_ != nullptr &&
427 &ptr_decoder_->_decoder == (*it).second->external_decoder_instance) { 426 &ptr_decoder_->_decoder == (*it).second->external_decoder_instance) {
428 // Release it if it was registered and in use. 427 // Release it if it was registered and in use.
429 ReleaseDecoder(ptr_decoder_); 428 ReleaseDecoder(ptr_decoder_);
430 ptr_decoder_ = NULL; 429 ptr_decoder_ = nullptr;
431 } 430 }
432 DeregisterReceiveCodec(payload_type); 431 DeregisterReceiveCodec(payload_type);
433 delete (*it).second; 432 delete (*it).second;
434 dec_external_map_.erase(it); 433 dec_external_map_.erase(it);
435 return true; 434 return true;
436 } 435 }
437 436
438 // Add the external encoder object to the list of external decoders. 437 // Add the external encoder object to the list of external decoders.
439 // Won't be registered as a receive codec until RegisterReceiveCodec is called. 438 // Won't be registered as a receive codec until RegisterReceiveCodec is called.
440 bool VCMCodecDataBase::RegisterExternalDecoder( 439 bool VCMCodecDataBase::RegisterExternalDecoder(
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 } 500 }
502 501
503 VideoCodecType VCMCodecDataBase::ReceiveCodec() const { 502 VideoCodecType VCMCodecDataBase::ReceiveCodec() const {
504 if (!ptr_decoder_) { 503 if (!ptr_decoder_) {
505 return kVideoCodecUnknown; 504 return kVideoCodecUnknown;
506 } 505 }
507 return receive_codec_.codecType; 506 return receive_codec_.codecType;
508 } 507 }
509 508
510 VCMGenericDecoder* VCMCodecDataBase::GetDecoder( 509 VCMGenericDecoder* VCMCodecDataBase::GetDecoder(
511 uint8_t payload_type, VCMDecodedFrameCallback* decoded_frame_callback) { 510 const VCMEncodedFrame& frame,
511 VCMDecodedFrameCallback* decoded_frame_callback) {
512 uint8_t payload_type = frame.PayloadType();
512 if (payload_type == receive_codec_.plType || payload_type == 0) { 513 if (payload_type == receive_codec_.plType || payload_type == 0) {
513 return ptr_decoder_; 514 return ptr_decoder_;
514 } 515 }
515 // Check for exisitng decoder, if exists - delete. 516 // Check for exisitng decoder, if exists - delete.
516 if (ptr_decoder_) { 517 if (ptr_decoder_) {
517 ReleaseDecoder(ptr_decoder_); 518 ReleaseDecoder(ptr_decoder_);
518 ptr_decoder_ = NULL; 519 ptr_decoder_ = nullptr;
519 memset(&receive_codec_, 0, sizeof(VideoCodec)); 520 memset(&receive_codec_, 0, sizeof(VideoCodec));
520 } 521 }
521 ptr_decoder_ = CreateAndInitDecoder(payload_type, &receive_codec_); 522 ptr_decoder_ = CreateAndInitDecoder(frame, &receive_codec_);
522 if (!ptr_decoder_) { 523 if (!ptr_decoder_) {
523 return NULL; 524 return nullptr;
524 } 525 }
525 VCMReceiveCallback* callback = decoded_frame_callback->UserReceiveCallback(); 526 VCMReceiveCallback* callback = decoded_frame_callback->UserReceiveCallback();
526 if (callback) callback->OnIncomingPayloadType(receive_codec_.plType); 527 if (callback) callback->OnIncomingPayloadType(receive_codec_.plType);
527 if (ptr_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback) 528 if (ptr_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback)
528 < 0) { 529 < 0) {
529 ReleaseDecoder(ptr_decoder_); 530 ReleaseDecoder(ptr_decoder_);
530 ptr_decoder_ = NULL; 531 ptr_decoder_ = nullptr;
531 memset(&receive_codec_, 0, sizeof(VideoCodec)); 532 memset(&receive_codec_, 0, sizeof(VideoCodec));
532 return NULL; 533 return nullptr;
533 } 534 }
534 return ptr_decoder_; 535 return ptr_decoder_;
535 } 536 }
536 537
537 void VCMCodecDataBase::ReleaseDecoder(VCMGenericDecoder* decoder) const { 538 void VCMCodecDataBase::ReleaseDecoder(VCMGenericDecoder* decoder) const {
538 if (decoder) { 539 if (decoder) {
539 assert(&decoder->_decoder); 540 assert(&decoder->_decoder);
540 decoder->Release(); 541 decoder->Release();
541 if (!decoder->External()) { 542 if (!decoder->External()) {
542 delete &decoder->_decoder; 543 delete &decoder->_decoder;
543 } 544 }
544 delete decoder; 545 delete decoder;
545 } 546 }
546 } 547 }
547 548
548 bool VCMCodecDataBase::SupportsRenderScheduling() const { 549 bool VCMCodecDataBase::SupportsRenderScheduling() const {
549 const VCMExtDecoderMapItem* ext_item = FindExternalDecoderItem( 550 const VCMExtDecoderMapItem* ext_item = FindExternalDecoderItem(
550 receive_codec_.plType); 551 receive_codec_.plType);
551 if (ext_item == nullptr) 552 if (!ext_item)
552 return true; 553 return true;
553 return ext_item->internal_render_timing; 554 return ext_item->internal_render_timing;
554 } 555 }
555 556
556 bool VCMCodecDataBase::MatchesCurrentResolution(int width, int height) const { 557 bool VCMCodecDataBase::MatchesCurrentResolution(int width, int height) const {
557 return send_codec_.width == width && send_codec_.height == height; 558 return send_codec_.width == width && send_codec_.height == height;
558 } 559 }
559 560
560 VCMGenericDecoder* VCMCodecDataBase::CreateAndInitDecoder( 561 VCMGenericDecoder* VCMCodecDataBase::CreateAndInitDecoder(
561 uint8_t payload_type, 562 const VCMEncodedFrame& frame,
562 VideoCodec* new_codec) const { 563 VideoCodec* new_codec) const {
564 uint8_t payload_type = frame.PayloadType();
563 assert(new_codec); 565 assert(new_codec);
564 const VCMDecoderMapItem* decoder_item = FindDecoderItem(payload_type); 566 const VCMDecoderMapItem* decoder_item = FindDecoderItem(payload_type);
565 if (!decoder_item) { 567 if (!decoder_item) {
566 LOG(LS_ERROR) << "Can't find a decoder associated with payload type: " 568 LOG(LS_ERROR) << "Can't find a decoder associated with payload type: "
567 << static_cast<int>(payload_type); 569 << static_cast<int>(payload_type);
568 return NULL; 570 return nullptr;
569 } 571 }
570 VCMGenericDecoder* ptr_decoder = NULL; 572 VCMGenericDecoder* ptr_decoder = nullptr;
571 const VCMExtDecoderMapItem* external_dec_item = 573 const VCMExtDecoderMapItem* external_dec_item =
572 FindExternalDecoderItem(payload_type); 574 FindExternalDecoderItem(payload_type);
573 if (external_dec_item) { 575 if (external_dec_item) {
574 // External codec. 576 // External codec.
575 ptr_decoder = new VCMGenericDecoder( 577 ptr_decoder = new VCMGenericDecoder(
576 *external_dec_item->external_decoder_instance, true); 578 *external_dec_item->external_decoder_instance, true);
577 } else { 579 } else {
578 // Create decoder. 580 // Create decoder.
579 ptr_decoder = CreateDecoder(decoder_item->settings->codecType); 581 ptr_decoder = CreateDecoder(decoder_item->settings->codecType);
580 } 582 }
581 if (!ptr_decoder) 583 if (!ptr_decoder)
582 return NULL; 584 return nullptr;
583 585
586 // Copy over input resolutions to prevent codec reinitialization due to
587 // the first frame being of a different resolution than the database values.
588 // This is best effort, since there's no guarantee that width/height have been
589 // parsed yet (and may be zero).
590 if (frame.EncodedImage()._encodedWidth > 0 &&
591 frame.EncodedImage()._encodedHeight > 0) {
592 decoder_item->settings->width = frame.EncodedImage()._encodedWidth;
593 decoder_item->settings->height = frame.EncodedImage()._encodedHeight;
594 }
584 if (ptr_decoder->InitDecode(decoder_item->settings.get(), 595 if (ptr_decoder->InitDecode(decoder_item->settings.get(),
585 decoder_item->number_of_cores) < 0) { 596 decoder_item->number_of_cores) < 0) {
586 ReleaseDecoder(ptr_decoder); 597 ReleaseDecoder(ptr_decoder);
587 return NULL; 598 return nullptr;
588 } 599 }
589 memcpy(new_codec, decoder_item->settings.get(), sizeof(VideoCodec)); 600 memcpy(new_codec, decoder_item->settings.get(), sizeof(VideoCodec));
590 return ptr_decoder; 601 return ptr_decoder;
591 } 602 }
592 603
593 void VCMCodecDataBase::DeleteEncoder() { 604 void VCMCodecDataBase::DeleteEncoder() {
594 if (!ptr_encoder_) 605 if (!ptr_encoder_)
595 return; 606 return;
596 ptr_encoder_->Release(); 607 ptr_encoder_->Release();
597 ptr_encoder_.reset(); 608 ptr_encoder_.reset();
598 } 609 }
599 610
600 VCMGenericDecoder* VCMCodecDataBase::CreateDecoder(VideoCodecType type) const { 611 VCMGenericDecoder* VCMCodecDataBase::CreateDecoder(VideoCodecType type) const {
601 switch (type) { 612 switch (type) {
602 case kVideoCodecVP8: 613 case kVideoCodecVP8:
603 return new VCMGenericDecoder(*(VP8Decoder::Create())); 614 return new VCMGenericDecoder(*(VP8Decoder::Create()));
604 case kVideoCodecVP9: 615 case kVideoCodecVP9:
605 return new VCMGenericDecoder(*(VP9Decoder::Create())); 616 return new VCMGenericDecoder(*(VP9Decoder::Create()));
606 case kVideoCodecI420: 617 case kVideoCodecI420:
607 return new VCMGenericDecoder(*(new I420Decoder)); 618 return new VCMGenericDecoder(*(new I420Decoder));
608 case kVideoCodecH264: 619 case kVideoCodecH264:
609 if (H264Decoder::IsSupported()) { 620 if (H264Decoder::IsSupported()) {
610 return new VCMGenericDecoder(*(H264Decoder::Create())); 621 return new VCMGenericDecoder(*(H264Decoder::Create()));
611 } 622 }
612 break; 623 break;
613 default: 624 default:
614 break; 625 break;
615 } 626 }
616 LOG(LS_WARNING) << "No internal decoder of this type exists."; 627 LOG(LS_WARNING) << "No internal decoder of this type exists.";
617 return NULL; 628 return nullptr;
618 } 629 }
619 630
620 const VCMDecoderMapItem* VCMCodecDataBase::FindDecoderItem( 631 const VCMDecoderMapItem* VCMCodecDataBase::FindDecoderItem(
621 uint8_t payload_type) const { 632 uint8_t payload_type) const {
622 DecoderMap::const_iterator it = dec_map_.find(payload_type); 633 DecoderMap::const_iterator it = dec_map_.find(payload_type);
623 if (it != dec_map_.end()) { 634 if (it != dec_map_.end()) {
624 return (*it).second; 635 return (*it).second;
625 } 636 }
626 return NULL; 637 return nullptr;
627 } 638 }
628 639
629 const VCMExtDecoderMapItem* VCMCodecDataBase::FindExternalDecoderItem( 640 const VCMExtDecoderMapItem* VCMCodecDataBase::FindExternalDecoderItem(
630 uint8_t payload_type) const { 641 uint8_t payload_type) const {
631 ExternalDecoderMap::const_iterator it = dec_external_map_.find(payload_type); 642 ExternalDecoderMap::const_iterator it = dec_external_map_.find(payload_type);
632 if (it != dec_external_map_.end()) { 643 if (it != dec_external_map_.end()) {
633 return (*it).second; 644 return (*it).second;
634 } 645 }
635 return NULL; 646 return nullptr;
636 } 647 }
637 } // namespace webrtc 648 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/codec_database.h ('k') | webrtc/modules/video_coding/video_receiver.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698