| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |