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

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

Issue 2966823002: A few simplifications to CodecDatabase and VCMGenericDecoder (Closed)
Patch Set: Created 3 years, 5 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 /* 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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 h264_settings.keyFrameInterval = 3000; 64 h264_settings.keyFrameInterval = 3000;
65 h264_settings.spsData = nullptr; 65 h264_settings.spsData = nullptr;
66 h264_settings.spsLen = 0; 66 h264_settings.spsLen = 0;
67 h264_settings.ppsData = nullptr; 67 h264_settings.ppsData = nullptr;
68 h264_settings.ppsLen = 0; 68 h264_settings.ppsLen = 0;
69 h264_settings.profile = H264::kProfileConstrainedBaseline; 69 h264_settings.profile = H264::kProfileConstrainedBaseline;
70 70
71 return h264_settings; 71 return h264_settings;
72 } 72 }
73 73
74 // Create an internal Decoder given a codec type
75 static std::unique_ptr<VCMGenericDecoder> CreateDecoder(VideoCodecType type) {
76 switch (type) {
77 case kVideoCodecVP8:
78 return std::unique_ptr<VCMGenericDecoder>(
79 new VCMGenericDecoder(VP8Decoder::Create()));
80 case kVideoCodecVP9:
81 return std::unique_ptr<VCMGenericDecoder>(
82 new VCMGenericDecoder(VP9Decoder::Create()));
83 case kVideoCodecI420:
84 return std::unique_ptr<VCMGenericDecoder>(
85 new VCMGenericDecoder(new I420Decoder()));
86 case kVideoCodecH264:
87 if (H264Decoder::IsSupported()) {
88 return std::unique_ptr<VCMGenericDecoder>(
89 new VCMGenericDecoder(H264Decoder::Create()));
90 }
91 break;
92 default:
93 break;
94 }
95 LOG(LS_WARNING) << "No internal decoder of this type exists.";
96 return std::unique_ptr<VCMGenericDecoder>();
97 }
98
74 VCMDecoderMapItem::VCMDecoderMapItem(VideoCodec* settings, 99 VCMDecoderMapItem::VCMDecoderMapItem(VideoCodec* settings,
75 int number_of_cores, 100 int number_of_cores,
76 bool require_key_frame) 101 bool require_key_frame)
77 : settings(settings), 102 : settings(settings),
78 number_of_cores(number_of_cores), 103 number_of_cores(number_of_cores),
79 require_key_frame(require_key_frame) { 104 require_key_frame(require_key_frame) {
80 RTC_DCHECK_GE(number_of_cores, 0); 105 RTC_DCHECK_GE(number_of_cores, 0);
81 } 106 }
82 107
83 VCMExtDecoderMapItem::VCMExtDecoderMapItem( 108 VCMExtDecoderMapItem::VCMExtDecoderMapItem(
84 VideoDecoder* external_decoder_instance, 109 VideoDecoder* external_decoder_instance,
85 uint8_t payload_type) 110 uint8_t payload_type)
86 : payload_type(payload_type), 111 : payload_type(payload_type),
87 external_decoder_instance(external_decoder_instance) {} 112 external_decoder_instance(external_decoder_instance) {}
88 113
89 VCMCodecDataBase::VCMCodecDataBase( 114 VCMCodecDataBase::VCMCodecDataBase(
90 VCMEncodedFrameCallback* encoded_frame_callback) 115 VCMEncodedFrameCallback* encoded_frame_callback)
91 : number_of_cores_(0), 116 : number_of_cores_(0),
92 max_payload_size_(kDefaultPayloadSize), 117 max_payload_size_(kDefaultPayloadSize),
93 periodic_key_frames_(false), 118 periodic_key_frames_(false),
94 pending_encoder_reset_(true), 119 pending_encoder_reset_(true),
95 send_codec_(), 120 send_codec_(),
96 receive_codec_(), 121 receive_codec_(),
97 encoder_payload_type_(0), 122 encoder_payload_type_(0),
98 external_encoder_(nullptr), 123 external_encoder_(nullptr),
99 internal_source_(false), 124 internal_source_(false),
100 encoded_frame_callback_(encoded_frame_callback), 125 encoded_frame_callback_(encoded_frame_callback),
101 ptr_decoder_(nullptr),
102 dec_map_(), 126 dec_map_(),
103 dec_external_map_() {} 127 dec_external_map_() {}
104 128
105 VCMCodecDataBase::~VCMCodecDataBase() { 129 VCMCodecDataBase::~VCMCodecDataBase() {
106 DeleteEncoder(); 130 DeleteEncoder();
107 ReleaseDecoder(ptr_decoder_); 131 ptr_decoder_.reset();
108 for (auto& kv : dec_map_) 132 for (auto& kv : dec_map_)
109 delete kv.second; 133 delete kv.second;
110 for (auto& kv : dec_external_map_) 134 for (auto& kv : dec_external_map_)
111 delete kv.second; 135 delete kv.second;
112 } 136 }
113 137
114 void VCMCodecDataBase::Codec(VideoCodecType codec_type, VideoCodec* settings) { 138 void VCMCodecDataBase::Codec(VideoCodecType codec_type, VideoCodec* settings) {
115 memset(settings, 0, sizeof(VideoCodec)); 139 memset(settings, 0, sizeof(VideoCodec));
116 switch (codec_type) { 140 switch (codec_type) {
117 case kVideoCodecVP8: 141 case kVideoCodecVP8:
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 417
394 bool VCMCodecDataBase::DeregisterExternalDecoder(uint8_t payload_type) { 418 bool VCMCodecDataBase::DeregisterExternalDecoder(uint8_t payload_type) {
395 ExternalDecoderMap::iterator it = dec_external_map_.find(payload_type); 419 ExternalDecoderMap::iterator it = dec_external_map_.find(payload_type);
396 if (it == dec_external_map_.end()) { 420 if (it == dec_external_map_.end()) {
397 // Not found 421 // Not found
398 return false; 422 return false;
399 } 423 }
400 // We can't use payload_type to check if the decoder is currently in use, 424 // We can't use payload_type to check if the decoder is currently in use,
401 // because payload type may be out of date (e.g. before we decode the first 425 // because payload type may be out of date (e.g. before we decode the first
402 // frame after RegisterReceiveCodec) 426 // frame after RegisterReceiveCodec)
403 if (ptr_decoder_ != nullptr && 427 if (ptr_decoder_ &&
404 ptr_decoder_->_decoder == (*it).second->external_decoder_instance) { 428 ptr_decoder_->IsSameDecoder((*it).second->external_decoder_instance)) {
405 // Release it if it was registered and in use. 429 // Release it if it was registered and in use.
406 ReleaseDecoder(ptr_decoder_); 430 ptr_decoder_.reset();
407 ptr_decoder_ = nullptr;
408 } 431 }
409 DeregisterReceiveCodec(payload_type); 432 DeregisterReceiveCodec(payload_type);
410 delete it->second; 433 delete it->second;
411 dec_external_map_.erase(it); 434 dec_external_map_.erase(it);
412 return true; 435 return true;
413 } 436 }
414 437
415 // Add the external encoder object to the list of external decoders. 438 // Add the external encoder object to the list of external decoders.
416 // Won't be registered as a receive codec until RegisterReceiveCodec is called. 439 // Won't be registered as a receive codec until RegisterReceiveCodec is called.
417 void VCMCodecDataBase::RegisterExternalDecoder(VideoDecoder* external_decoder, 440 void VCMCodecDataBase::RegisterExternalDecoder(VideoDecoder* external_decoder,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 } 480 }
458 return true; 481 return true;
459 } 482 }
460 483
461 VCMGenericDecoder* VCMCodecDataBase::GetDecoder( 484 VCMGenericDecoder* VCMCodecDataBase::GetDecoder(
462 const VCMEncodedFrame& frame, 485 const VCMEncodedFrame& frame,
463 VCMDecodedFrameCallback* decoded_frame_callback) { 486 VCMDecodedFrameCallback* decoded_frame_callback) {
464 RTC_DCHECK(decoded_frame_callback->UserReceiveCallback()); 487 RTC_DCHECK(decoded_frame_callback->UserReceiveCallback());
465 uint8_t payload_type = frame.PayloadType(); 488 uint8_t payload_type = frame.PayloadType();
466 if (payload_type == receive_codec_.plType || payload_type == 0) { 489 if (payload_type == receive_codec_.plType || payload_type == 0) {
467 return ptr_decoder_; 490 return ptr_decoder_.get();
468 } 491 }
469 // Check for exisitng decoder, if exists - delete. 492 // Check for exisitng decoder, if exists - delete.
470 if (ptr_decoder_) { 493 if (ptr_decoder_) {
471 ReleaseDecoder(ptr_decoder_); 494 ptr_decoder_.reset();
472 ptr_decoder_ = nullptr;
473 memset(&receive_codec_, 0, sizeof(VideoCodec)); 495 memset(&receive_codec_, 0, sizeof(VideoCodec));
474 } 496 }
475 ptr_decoder_ = CreateAndInitDecoder(frame, &receive_codec_); 497 ptr_decoder_ = CreateAndInitDecoder(frame, &receive_codec_);
476 if (!ptr_decoder_) { 498 if (!ptr_decoder_) {
477 return nullptr; 499 return nullptr;
478 } 500 }
479 VCMReceiveCallback* callback = decoded_frame_callback->UserReceiveCallback(); 501 VCMReceiveCallback* callback = decoded_frame_callback->UserReceiveCallback();
480 callback->OnIncomingPayloadType(receive_codec_.plType); 502 callback->OnIncomingPayloadType(receive_codec_.plType);
481 if (ptr_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback) < 503 if (ptr_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback) <
482 0) { 504 0) {
483 ReleaseDecoder(ptr_decoder_); 505 ptr_decoder_.reset();
484 ptr_decoder_ = nullptr;
485 memset(&receive_codec_, 0, sizeof(VideoCodec)); 506 memset(&receive_codec_, 0, sizeof(VideoCodec));
486 return nullptr; 507 return nullptr;
487 } 508 }
488 return ptr_decoder_; 509 return ptr_decoder_.get();
489 } 510 }
490 511
491 void VCMCodecDataBase::ReleaseDecoder(VCMGenericDecoder* decoder) const { 512 VCMGenericDecoder* VCMCodecDataBase::GetCurrentDecoder() {
492 if (decoder) { 513 return ptr_decoder_.get();
493 RTC_DCHECK(decoder->_decoder);
494 decoder->Release();
495 if (!decoder->External()) {
496 delete decoder->_decoder;
497 }
498 delete decoder;
499 }
500 } 514 }
501 515
502 bool VCMCodecDataBase::PrefersLateDecoding() const { 516 bool VCMCodecDataBase::PrefersLateDecoding() const {
503 if (!ptr_decoder_) 517 return ptr_decoder_ ? ptr_decoder_->PrefersLateDecoding() : true;
504 return true;
505 return ptr_decoder_->PrefersLateDecoding();
506 } 518 }
507 519
508 bool VCMCodecDataBase::MatchesCurrentResolution(int width, int height) const { 520 bool VCMCodecDataBase::MatchesCurrentResolution(int width, int height) const {
509 return send_codec_.width == width && send_codec_.height == height; 521 return send_codec_.width == width && send_codec_.height == height;
510 } 522 }
511 523
512 VCMGenericDecoder* VCMCodecDataBase::CreateAndInitDecoder( 524 std::unique_ptr<VCMGenericDecoder> VCMCodecDataBase::CreateAndInitDecoder(
513 const VCMEncodedFrame& frame, 525 const VCMEncodedFrame& frame,
514 VideoCodec* new_codec) const { 526 VideoCodec* new_codec) const {
515 uint8_t payload_type = frame.PayloadType(); 527 uint8_t payload_type = frame.PayloadType();
516 LOG(LS_INFO) << "Initializing decoder with payload type '" 528 LOG(LS_INFO) << "Initializing decoder with payload type '"
517 << static_cast<int>(payload_type) << "'."; 529 << static_cast<int>(payload_type) << "'.";
518 RTC_DCHECK(new_codec); 530 RTC_DCHECK(new_codec);
519 const VCMDecoderMapItem* decoder_item = FindDecoderItem(payload_type); 531 const VCMDecoderMapItem* decoder_item = FindDecoderItem(payload_type);
520 if (!decoder_item) { 532 if (!decoder_item) {
521 LOG(LS_ERROR) << "Can't find a decoder associated with payload type: " 533 LOG(LS_ERROR) << "Can't find a decoder associated with payload type: "
522 << static_cast<int>(payload_type); 534 << static_cast<int>(payload_type);
523 return nullptr; 535 return nullptr;
524 } 536 }
525 VCMGenericDecoder* ptr_decoder = nullptr; 537 std::unique_ptr<VCMGenericDecoder> ptr_decoder;
526 const VCMExtDecoderMapItem* external_dec_item = 538 const VCMExtDecoderMapItem* external_dec_item =
527 FindExternalDecoderItem(payload_type); 539 FindExternalDecoderItem(payload_type);
528 if (external_dec_item) { 540 if (external_dec_item) {
529 // External codec. 541 // External codec.
530 ptr_decoder = new VCMGenericDecoder( 542 ptr_decoder.reset(new VCMGenericDecoder(
531 external_dec_item->external_decoder_instance, true); 543 external_dec_item->external_decoder_instance, true));
532 } else { 544 } else {
533 // Create decoder. 545 // Create decoder.
534 ptr_decoder = CreateDecoder(decoder_item->settings->codecType); 546 ptr_decoder = CreateDecoder(decoder_item->settings->codecType);
535 } 547 }
536 if (!ptr_decoder) 548 if (!ptr_decoder)
537 return nullptr; 549 return nullptr;
538 550
539 // Copy over input resolutions to prevent codec reinitialization due to 551 // Copy over input resolutions to prevent codec reinitialization due to
540 // the first frame being of a different resolution than the database values. 552 // the first frame being of a different resolution than the database values.
541 // This is best effort, since there's no guarantee that width/height have been 553 // This is best effort, since there's no guarantee that width/height have been
542 // parsed yet (and may be zero). 554 // parsed yet (and may be zero).
543 if (frame.EncodedImage()._encodedWidth > 0 && 555 if (frame.EncodedImage()._encodedWidth > 0 &&
544 frame.EncodedImage()._encodedHeight > 0) { 556 frame.EncodedImage()._encodedHeight > 0) {
545 decoder_item->settings->width = frame.EncodedImage()._encodedWidth; 557 decoder_item->settings->width = frame.EncodedImage()._encodedWidth;
546 decoder_item->settings->height = frame.EncodedImage()._encodedHeight; 558 decoder_item->settings->height = frame.EncodedImage()._encodedHeight;
547 } 559 }
548 if (ptr_decoder->InitDecode(decoder_item->settings.get(), 560 if (ptr_decoder->InitDecode(decoder_item->settings.get(),
549 decoder_item->number_of_cores) < 0) { 561 decoder_item->number_of_cores) < 0) {
550 ReleaseDecoder(ptr_decoder);
551 return nullptr; 562 return nullptr;
552 } 563 }
553 memcpy(new_codec, decoder_item->settings.get(), sizeof(VideoCodec)); 564 memcpy(new_codec, decoder_item->settings.get(), sizeof(VideoCodec));
554 return ptr_decoder; 565 return ptr_decoder;
555 } 566 }
556 567
557 void VCMCodecDataBase::DeleteEncoder() { 568 void VCMCodecDataBase::DeleteEncoder() {
558 if (!ptr_encoder_) 569 if (!ptr_encoder_)
559 return; 570 return;
560 ptr_encoder_->Release(); 571 ptr_encoder_->Release();
561 ptr_encoder_.reset(); 572 ptr_encoder_.reset();
562 } 573 }
563 574
564 VCMGenericDecoder* VCMCodecDataBase::CreateDecoder(VideoCodecType type) const {
565 switch (type) {
566 case kVideoCodecVP8:
567 return new VCMGenericDecoder(VP8Decoder::Create());
568 case kVideoCodecVP9:
569 return new VCMGenericDecoder(VP9Decoder::Create());
570 case kVideoCodecI420:
571 return new VCMGenericDecoder(new I420Decoder());
572 case kVideoCodecH264:
573 if (H264Decoder::IsSupported()) {
574 return new VCMGenericDecoder(H264Decoder::Create());
575 }
576 break;
577 default:
578 break;
579 }
580 LOG(LS_WARNING) << "No internal decoder of this type exists.";
581 return nullptr;
582 }
583
584 const VCMDecoderMapItem* VCMCodecDataBase::FindDecoderItem( 575 const VCMDecoderMapItem* VCMCodecDataBase::FindDecoderItem(
585 uint8_t payload_type) const { 576 uint8_t payload_type) const {
586 DecoderMap::const_iterator it = dec_map_.find(payload_type); 577 DecoderMap::const_iterator it = dec_map_.find(payload_type);
587 if (it != dec_map_.end()) { 578 if (it != dec_map_.end()) {
588 return (*it).second; 579 return (*it).second;
589 } 580 }
590 return nullptr; 581 return nullptr;
591 } 582 }
592 583
593 const VCMExtDecoderMapItem* VCMCodecDataBase::FindExternalDecoderItem( 584 const VCMExtDecoderMapItem* VCMCodecDataBase::FindExternalDecoderItem(
594 uint8_t payload_type) const { 585 uint8_t payload_type) const {
595 ExternalDecoderMap::const_iterator it = dec_external_map_.find(payload_type); 586 ExternalDecoderMap::const_iterator it = dec_external_map_.find(payload_type);
596 if (it != dec_external_map_.end()) { 587 if (it != dec_external_map_.end()) {
597 return (*it).second; 588 return (*it).second;
598 } 589 }
599 return nullptr; 590 return nullptr;
600 } 591 }
601 } // namespace webrtc 592 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/codec_database.h ('k') | webrtc/modules/video_coding/generic_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698