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 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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); | |
stefan-webrtc
2017/03/31 13:42:07
Why don't we release here?
tommi
2017/04/04 10:13:52
|ptr_decoder| is now a std::unique_ptr which goes
| |
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 |
OLD | NEW |