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

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

Issue 2764573002: Deliver video frames on Android, on the decode thread. (Closed)
Patch Set: Update comments Created 3 years, 8 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 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 408
385 bool VCMCodecDataBase::DeregisterExternalDecoder(uint8_t payload_type) { 409 bool VCMCodecDataBase::DeregisterExternalDecoder(uint8_t payload_type) {
386 ExternalDecoderMap::iterator it = dec_external_map_.find(payload_type); 410 ExternalDecoderMap::iterator it = dec_external_map_.find(payload_type);
387 if (it == dec_external_map_.end()) { 411 if (it == dec_external_map_.end()) {
388 // Not found 412 // Not found
389 return false; 413 return false;
390 } 414 }
391 // We can't use payload_type to check if the decoder is currently in use, 415 // We can't use payload_type to check if the decoder is currently in use,
392 // because payload type may be out of date (e.g. before we decode the first 416 // because payload type may be out of date (e.g. before we decode the first
393 // frame after RegisterReceiveCodec) 417 // frame after RegisterReceiveCodec)
394 if (ptr_decoder_ != nullptr && 418 if (ptr_decoder_ &&
395 ptr_decoder_->_decoder == (*it).second->external_decoder_instance) { 419 ptr_decoder_->IsSameDecoder((*it).second->external_decoder_instance)) {
396 // Release it if it was registered and in use. 420 // Release it if it was registered and in use.
397 ReleaseDecoder(ptr_decoder_); 421 ptr_decoder_.reset();
398 ptr_decoder_ = nullptr;
399 } 422 }
400 DeregisterReceiveCodec(payload_type); 423 DeregisterReceiveCodec(payload_type);
401 delete it->second; 424 delete it->second;
402 dec_external_map_.erase(it); 425 dec_external_map_.erase(it);
403 return true; 426 return true;
404 } 427 }
405 428
406 // Add the external encoder object to the list of external decoders. 429 // Add the external encoder object to the list of external decoders.
407 // Won't be registered as a receive codec until RegisterReceiveCodec is called. 430 // Won't be registered as a receive codec until RegisterReceiveCodec is called.
408 void VCMCodecDataBase::RegisterExternalDecoder(VideoDecoder* external_decoder, 431 void VCMCodecDataBase::RegisterExternalDecoder(VideoDecoder* external_decoder,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 } 471 }
449 return true; 472 return true;
450 } 473 }
451 474
452 VCMGenericDecoder* VCMCodecDataBase::GetDecoder( 475 VCMGenericDecoder* VCMCodecDataBase::GetDecoder(
453 const VCMEncodedFrame& frame, 476 const VCMEncodedFrame& frame,
454 VCMDecodedFrameCallback* decoded_frame_callback) { 477 VCMDecodedFrameCallback* decoded_frame_callback) {
455 RTC_DCHECK(decoded_frame_callback->UserReceiveCallback()); 478 RTC_DCHECK(decoded_frame_callback->UserReceiveCallback());
456 uint8_t payload_type = frame.PayloadType(); 479 uint8_t payload_type = frame.PayloadType();
457 if (payload_type == receive_codec_.plType || payload_type == 0) { 480 if (payload_type == receive_codec_.plType || payload_type == 0) {
458 return ptr_decoder_; 481 return ptr_decoder_.get();
459 } 482 }
460 // Check for exisitng decoder, if exists - delete. 483 // Check for exisitng decoder, if exists - delete.
461 if (ptr_decoder_) { 484 if (ptr_decoder_) {
462 ReleaseDecoder(ptr_decoder_); 485 ptr_decoder_.reset();
463 ptr_decoder_ = nullptr;
464 memset(&receive_codec_, 0, sizeof(VideoCodec)); 486 memset(&receive_codec_, 0, sizeof(VideoCodec));
465 } 487 }
466 ptr_decoder_ = CreateAndInitDecoder(frame, &receive_codec_); 488 ptr_decoder_ = CreateAndInitDecoder(frame, &receive_codec_);
467 if (!ptr_decoder_) { 489 if (!ptr_decoder_) {
468 return nullptr; 490 return nullptr;
469 } 491 }
470 VCMReceiveCallback* callback = decoded_frame_callback->UserReceiveCallback(); 492 VCMReceiveCallback* callback = decoded_frame_callback->UserReceiveCallback();
471 callback->OnIncomingPayloadType(receive_codec_.plType); 493 callback->OnIncomingPayloadType(receive_codec_.plType);
472 if (ptr_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback) < 494 if (ptr_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback) <
473 0) { 495 0) {
474 ReleaseDecoder(ptr_decoder_); 496 ptr_decoder_.reset();
475 ptr_decoder_ = nullptr;
476 memset(&receive_codec_, 0, sizeof(VideoCodec)); 497 memset(&receive_codec_, 0, sizeof(VideoCodec));
477 return nullptr; 498 return nullptr;
478 } 499 }
479 return ptr_decoder_; 500 return ptr_decoder_.get();
480 } 501 }
481 502
482 void VCMCodecDataBase::ReleaseDecoder(VCMGenericDecoder* decoder) const { 503 VCMGenericDecoder* VCMCodecDataBase::GetCurrentDecoder() {
483 if (decoder) { 504 return ptr_decoder_.get();
484 RTC_DCHECK(decoder->_decoder);
485 decoder->Release();
486 if (!decoder->External()) {
487 delete decoder->_decoder;
488 }
489 delete decoder;
490 }
491 } 505 }
492 506
493 bool VCMCodecDataBase::PrefersLateDecoding() const { 507 bool VCMCodecDataBase::PrefersLateDecoding() const {
494 if (!ptr_decoder_) 508 return ptr_decoder_ ? ptr_decoder_->PrefersLateDecoding() : true;
495 return true;
496 return ptr_decoder_->PrefersLateDecoding();
497 } 509 }
498 510
499 bool VCMCodecDataBase::MatchesCurrentResolution(int width, int height) const { 511 bool VCMCodecDataBase::MatchesCurrentResolution(int width, int height) const {
500 return send_codec_.width == width && send_codec_.height == height; 512 return send_codec_.width == width && send_codec_.height == height;
501 } 513 }
502 514
503 VCMGenericDecoder* VCMCodecDataBase::CreateAndInitDecoder( 515 std::unique_ptr<VCMGenericDecoder> VCMCodecDataBase::CreateAndInitDecoder(
504 const VCMEncodedFrame& frame, 516 const VCMEncodedFrame& frame,
505 VideoCodec* new_codec) const { 517 VideoCodec* new_codec) const {
506 uint8_t payload_type = frame.PayloadType(); 518 uint8_t payload_type = frame.PayloadType();
507 LOG(LS_INFO) << "Initializing decoder with payload type '" 519 LOG(LS_INFO) << "Initializing decoder with payload type '"
508 << static_cast<int>(payload_type) << "'."; 520 << static_cast<int>(payload_type) << "'.";
509 RTC_DCHECK(new_codec); 521 RTC_DCHECK(new_codec);
510 const VCMDecoderMapItem* decoder_item = FindDecoderItem(payload_type); 522 const VCMDecoderMapItem* decoder_item = FindDecoderItem(payload_type);
511 if (!decoder_item) { 523 if (!decoder_item) {
512 LOG(LS_ERROR) << "Can't find a decoder associated with payload type: " 524 LOG(LS_ERROR) << "Can't find a decoder associated with payload type: "
513 << static_cast<int>(payload_type); 525 << static_cast<int>(payload_type);
514 return nullptr; 526 return nullptr;
515 } 527 }
516 VCMGenericDecoder* ptr_decoder = nullptr; 528 std::unique_ptr<VCMGenericDecoder> ptr_decoder;
517 const VCMExtDecoderMapItem* external_dec_item = 529 const VCMExtDecoderMapItem* external_dec_item =
518 FindExternalDecoderItem(payload_type); 530 FindExternalDecoderItem(payload_type);
519 if (external_dec_item) { 531 if (external_dec_item) {
520 // External codec. 532 // External codec.
521 ptr_decoder = new VCMGenericDecoder( 533 ptr_decoder.reset(new VCMGenericDecoder(
522 external_dec_item->external_decoder_instance, true); 534 external_dec_item->external_decoder_instance, true));
523 } else { 535 } else {
524 // Create decoder. 536 // Create decoder.
525 ptr_decoder = CreateDecoder(decoder_item->settings->codecType); 537 ptr_decoder = CreateDecoder(decoder_item->settings->codecType);
526 } 538 }
527 if (!ptr_decoder) 539 if (!ptr_decoder)
528 return nullptr; 540 return nullptr;
529 541
530 // Copy over input resolutions to prevent codec reinitialization due to 542 // Copy over input resolutions to prevent codec reinitialization due to
531 // the first frame being of a different resolution than the database values. 543 // the first frame being of a different resolution than the database values.
532 // This is best effort, since there's no guarantee that width/height have been 544 // This is best effort, since there's no guarantee that width/height have been
533 // parsed yet (and may be zero). 545 // parsed yet (and may be zero).
534 if (frame.EncodedImage()._encodedWidth > 0 && 546 if (frame.EncodedImage()._encodedWidth > 0 &&
535 frame.EncodedImage()._encodedHeight > 0) { 547 frame.EncodedImage()._encodedHeight > 0) {
536 decoder_item->settings->width = frame.EncodedImage()._encodedWidth; 548 decoder_item->settings->width = frame.EncodedImage()._encodedWidth;
537 decoder_item->settings->height = frame.EncodedImage()._encodedHeight; 549 decoder_item->settings->height = frame.EncodedImage()._encodedHeight;
538 } 550 }
539 if (ptr_decoder->InitDecode(decoder_item->settings.get(), 551 if (ptr_decoder->InitDecode(decoder_item->settings.get(),
540 decoder_item->number_of_cores) < 0) { 552 decoder_item->number_of_cores) < 0) {
541 ReleaseDecoder(ptr_decoder);
542 return nullptr; 553 return nullptr;
543 } 554 }
544 memcpy(new_codec, decoder_item->settings.get(), sizeof(VideoCodec)); 555 memcpy(new_codec, decoder_item->settings.get(), sizeof(VideoCodec));
545 return ptr_decoder; 556 return ptr_decoder;
546 } 557 }
547 558
548 void VCMCodecDataBase::DeleteEncoder() { 559 void VCMCodecDataBase::DeleteEncoder() {
549 if (!ptr_encoder_) 560 if (!ptr_encoder_)
550 return; 561 return;
551 ptr_encoder_->Release(); 562 ptr_encoder_->Release();
552 ptr_encoder_.reset(); 563 ptr_encoder_.reset();
553 } 564 }
554 565
555 VCMGenericDecoder* VCMCodecDataBase::CreateDecoder(VideoCodecType type) const {
556 switch (type) {
557 case kVideoCodecVP8:
558 return new VCMGenericDecoder(VP8Decoder::Create());
559 case kVideoCodecVP9:
560 return new VCMGenericDecoder(VP9Decoder::Create());
561 case kVideoCodecI420:
562 return new VCMGenericDecoder(new I420Decoder());
563 case kVideoCodecH264:
564 if (H264Decoder::IsSupported()) {
565 return new VCMGenericDecoder(H264Decoder::Create());
566 }
567 break;
568 default:
569 break;
570 }
571 LOG(LS_WARNING) << "No internal decoder of this type exists.";
572 return nullptr;
573 }
574
575 const VCMDecoderMapItem* VCMCodecDataBase::FindDecoderItem( 566 const VCMDecoderMapItem* VCMCodecDataBase::FindDecoderItem(
576 uint8_t payload_type) const { 567 uint8_t payload_type) const {
577 DecoderMap::const_iterator it = dec_map_.find(payload_type); 568 DecoderMap::const_iterator it = dec_map_.find(payload_type);
578 if (it != dec_map_.end()) { 569 if (it != dec_map_.end()) {
579 return (*it).second; 570 return (*it).second;
580 } 571 }
581 return nullptr; 572 return nullptr;
582 } 573 }
583 574
584 const VCMExtDecoderMapItem* VCMCodecDataBase::FindExternalDecoderItem( 575 const VCMExtDecoderMapItem* VCMCodecDataBase::FindExternalDecoderItem(
585 uint8_t payload_type) const { 576 uint8_t payload_type) const {
586 ExternalDecoderMap::const_iterator it = dec_external_map_.find(payload_type); 577 ExternalDecoderMap::const_iterator it = dec_external_map_.find(payload_type);
587 if (it != dec_external_map_.end()) { 578 if (it != dec_external_map_.end()) {
588 return (*it).second; 579 return (*it).second;
589 } 580 }
590 return nullptr; 581 return nullptr;
591 } 582 }
592 } // namespace webrtc 583 } // 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