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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 encoder_payload_type_(0), | 104 encoder_payload_type_(0), |
105 external_encoder_(nullptr), | 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_(nullptr), | 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 DeleteEncoder(); |
115 ResetReceiver(); | 115 ReleaseDecoder(ptr_decoder_); |
| 116 for (auto& kv : dec_map_) |
| 117 delete kv.second; |
| 118 for (auto& kv : dec_external_map_) |
| 119 delete kv.second; |
116 } | 120 } |
117 | 121 |
118 void VCMCodecDataBase::Codec(VideoCodecType codec_type, VideoCodec* settings) { | 122 void VCMCodecDataBase::Codec(VideoCodecType codec_type, VideoCodec* settings) { |
119 memset(settings, 0, sizeof(VideoCodec)); | 123 memset(settings, 0, sizeof(VideoCodec)); |
120 switch (codec_type) { | 124 switch (codec_type) { |
121 case kVideoCodecVP8: | 125 case kVideoCodecVP8: |
122 strncpy(settings->plName, "VP8", 4); | 126 strncpy(settings->plName, "VP8", 4); |
123 settings->codecType = kVideoCodecVP8; | 127 settings->codecType = kVideoCodecVP8; |
124 // 96 to 127 dynamic payload types for video codecs. | 128 // 96 to 127 dynamic payload types for video codecs. |
125 settings->plType = kDefaultPayloadType; | 129 settings->plType = kDefaultPayloadType; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 return; | 185 return; |
182 case kVideoCodecRED: | 186 case kVideoCodecRED: |
183 case kVideoCodecULPFEC: | 187 case kVideoCodecULPFEC: |
184 case kVideoCodecGeneric: | 188 case kVideoCodecGeneric: |
185 case kVideoCodecUnknown: | 189 case kVideoCodecUnknown: |
186 RTC_NOTREACHED(); | 190 RTC_NOTREACHED(); |
187 return; | 191 return; |
188 } | 192 } |
189 } | 193 } |
190 | 194 |
191 void VCMCodecDataBase::ResetSender() { | |
192 DeleteEncoder(); | |
193 periodic_key_frames_ = false; | |
194 } | |
195 | |
196 // Assuming only one registered encoder - since only one used, no need for more. | 195 // Assuming only one registered encoder - since only one used, no need for more. |
197 bool VCMCodecDataBase::SetSendCodec(const VideoCodec* send_codec, | 196 bool VCMCodecDataBase::SetSendCodec(const VideoCodec* send_codec, |
198 int number_of_cores, | 197 int number_of_cores, |
199 size_t max_payload_size) { | 198 size_t max_payload_size) { |
200 RTC_DCHECK(send_codec); | 199 RTC_DCHECK(send_codec); |
201 if (max_payload_size == 0) { | 200 if (max_payload_size == 0) { |
202 max_payload_size = kDefaultPayloadSize; | 201 max_payload_size = kDefaultPayloadSize; |
203 } | 202 } |
204 RTC_DCHECK_GE(number_of_cores, 1); | 203 RTC_DCHECK_GE(number_of_cores, 1); |
205 RTC_DCHECK_GE(send_codec->plType, 1); | 204 RTC_DCHECK_GE(send_codec->plType, 1); |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 } | 389 } |
391 | 390 |
392 bool VCMCodecDataBase::SetPeriodicKeyFrames(bool enable) { | 391 bool VCMCodecDataBase::SetPeriodicKeyFrames(bool enable) { |
393 periodic_key_frames_ = enable; | 392 periodic_key_frames_ = enable; |
394 if (ptr_encoder_) { | 393 if (ptr_encoder_) { |
395 return (ptr_encoder_->SetPeriodicKeyFrames(periodic_key_frames_) == 0); | 394 return (ptr_encoder_->SetPeriodicKeyFrames(periodic_key_frames_) == 0); |
396 } | 395 } |
397 return true; | 396 return true; |
398 } | 397 } |
399 | 398 |
400 void VCMCodecDataBase::ResetReceiver() { | |
401 ReleaseDecoder(ptr_decoder_); | |
402 ptr_decoder_ = nullptr; | |
403 memset(&receive_codec_, 0, sizeof(VideoCodec)); | |
404 while (!dec_map_.empty()) { | |
405 DecoderMap::iterator it = dec_map_.begin(); | |
406 delete (*it).second; | |
407 dec_map_.erase(it); | |
408 } | |
409 while (!dec_external_map_.empty()) { | |
410 ExternalDecoderMap::iterator external_it = dec_external_map_.begin(); | |
411 delete (*external_it).second; | |
412 dec_external_map_.erase(external_it); | |
413 } | |
414 } | |
415 | |
416 bool VCMCodecDataBase::DeregisterExternalDecoder(uint8_t payload_type) { | 399 bool VCMCodecDataBase::DeregisterExternalDecoder(uint8_t payload_type) { |
417 ExternalDecoderMap::iterator it = dec_external_map_.find(payload_type); | 400 ExternalDecoderMap::iterator it = dec_external_map_.find(payload_type); |
418 if (it == dec_external_map_.end()) { | 401 if (it == dec_external_map_.end()) { |
419 // Not found | 402 // Not found |
420 return false; | 403 return false; |
421 } | 404 } |
422 // We can't use payload_type to check if the decoder is currently in use, | 405 // We can't use payload_type to check if the decoder is currently in use, |
423 // because payload type may be out of date (e.g. before we decode the first | 406 // because payload type may be out of date (e.g. before we decode the first |
424 // frame after RegisterReceiveCodec) | 407 // frame after RegisterReceiveCodec) |
425 if (ptr_decoder_ != nullptr && | 408 if (ptr_decoder_ != nullptr && |
426 &ptr_decoder_->_decoder == (*it).second->external_decoder_instance) { | 409 ptr_decoder_->_decoder == (*it).second->external_decoder_instance) { |
427 // Release it if it was registered and in use. | 410 // Release it if it was registered and in use. |
428 ReleaseDecoder(ptr_decoder_); | 411 ReleaseDecoder(ptr_decoder_); |
429 ptr_decoder_ = nullptr; | 412 ptr_decoder_ = nullptr; |
430 } | 413 } |
431 DeregisterReceiveCodec(payload_type); | 414 DeregisterReceiveCodec(payload_type); |
432 delete (*it).second; | 415 delete it->second; |
433 dec_external_map_.erase(it); | 416 dec_external_map_.erase(it); |
434 return true; | 417 return true; |
435 } | 418 } |
436 | 419 |
437 // Add the external encoder object to the list of external decoders. | 420 // Add the external encoder object to the list of external decoders. |
438 // Won't be registered as a receive codec until RegisterReceiveCodec is called. | 421 // Won't be registered as a receive codec until RegisterReceiveCodec is called. |
439 void VCMCodecDataBase::RegisterExternalDecoder( | 422 void VCMCodecDataBase::RegisterExternalDecoder( |
440 VideoDecoder* external_decoder, | 423 VideoDecoder* external_decoder, |
441 uint8_t payload_type, | 424 uint8_t payload_type, |
442 bool internal_render_timing) { | 425 bool internal_render_timing) { |
(...skipping 26 matching lines...) Expand all Loading... |
469 require_key_frame); | 452 require_key_frame); |
470 return true; | 453 return true; |
471 } | 454 } |
472 | 455 |
473 bool VCMCodecDataBase::DeregisterReceiveCodec( | 456 bool VCMCodecDataBase::DeregisterReceiveCodec( |
474 uint8_t payload_type) { | 457 uint8_t payload_type) { |
475 DecoderMap::iterator it = dec_map_.find(payload_type); | 458 DecoderMap::iterator it = dec_map_.find(payload_type); |
476 if (it == dec_map_.end()) { | 459 if (it == dec_map_.end()) { |
477 return false; | 460 return false; |
478 } | 461 } |
479 VCMDecoderMapItem* dec_item = (*it).second; | 462 delete it->second; |
480 delete dec_item; | |
481 dec_map_.erase(it); | 463 dec_map_.erase(it); |
482 if (receive_codec_.plType == payload_type) { | 464 if (receive_codec_.plType == payload_type) { |
483 // This codec is currently in use. | 465 // This codec is currently in use. |
484 memset(&receive_codec_, 0, sizeof(VideoCodec)); | 466 memset(&receive_codec_, 0, sizeof(VideoCodec)); |
485 } | 467 } |
486 return true; | 468 return true; |
487 } | 469 } |
488 | 470 |
489 bool VCMCodecDataBase::ReceiveCodec(VideoCodec* current_receive_codec) const { | 471 bool VCMCodecDataBase::ReceiveCodec(VideoCodec* current_receive_codec) const { |
490 assert(current_receive_codec); | 472 assert(current_receive_codec); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 ReleaseDecoder(ptr_decoder_); | 508 ReleaseDecoder(ptr_decoder_); |
527 ptr_decoder_ = nullptr; | 509 ptr_decoder_ = nullptr; |
528 memset(&receive_codec_, 0, sizeof(VideoCodec)); | 510 memset(&receive_codec_, 0, sizeof(VideoCodec)); |
529 return nullptr; | 511 return nullptr; |
530 } | 512 } |
531 return ptr_decoder_; | 513 return ptr_decoder_; |
532 } | 514 } |
533 | 515 |
534 void VCMCodecDataBase::ReleaseDecoder(VCMGenericDecoder* decoder) const { | 516 void VCMCodecDataBase::ReleaseDecoder(VCMGenericDecoder* decoder) const { |
535 if (decoder) { | 517 if (decoder) { |
536 assert(&decoder->_decoder); | 518 assert(decoder->_decoder); |
537 decoder->Release(); | 519 decoder->Release(); |
538 if (!decoder->External()) { | 520 if (!decoder->External()) { |
539 delete &decoder->_decoder; | 521 delete decoder->_decoder; |
540 } | 522 } |
541 delete decoder; | 523 delete decoder; |
542 } | 524 } |
543 } | 525 } |
544 | 526 |
545 bool VCMCodecDataBase::SupportsRenderScheduling() const { | 527 bool VCMCodecDataBase::SupportsRenderScheduling() const { |
546 const VCMExtDecoderMapItem* ext_item = FindExternalDecoderItem( | 528 const VCMExtDecoderMapItem* ext_item = FindExternalDecoderItem( |
547 receive_codec_.plType); | 529 receive_codec_.plType); |
548 if (!ext_item) | 530 if (!ext_item) |
549 return true; | 531 return true; |
(...skipping 14 matching lines...) Expand all Loading... |
564 LOG(LS_ERROR) << "Can't find a decoder associated with payload type: " | 546 LOG(LS_ERROR) << "Can't find a decoder associated with payload type: " |
565 << static_cast<int>(payload_type); | 547 << static_cast<int>(payload_type); |
566 return nullptr; | 548 return nullptr; |
567 } | 549 } |
568 VCMGenericDecoder* ptr_decoder = nullptr; | 550 VCMGenericDecoder* ptr_decoder = nullptr; |
569 const VCMExtDecoderMapItem* external_dec_item = | 551 const VCMExtDecoderMapItem* external_dec_item = |
570 FindExternalDecoderItem(payload_type); | 552 FindExternalDecoderItem(payload_type); |
571 if (external_dec_item) { | 553 if (external_dec_item) { |
572 // External codec. | 554 // External codec. |
573 ptr_decoder = new VCMGenericDecoder( | 555 ptr_decoder = new VCMGenericDecoder( |
574 *external_dec_item->external_decoder_instance, true); | 556 external_dec_item->external_decoder_instance, true); |
575 } else { | 557 } else { |
576 // Create decoder. | 558 // Create decoder. |
577 ptr_decoder = CreateDecoder(decoder_item->settings->codecType); | 559 ptr_decoder = CreateDecoder(decoder_item->settings->codecType); |
578 } | 560 } |
579 if (!ptr_decoder) | 561 if (!ptr_decoder) |
580 return nullptr; | 562 return nullptr; |
581 | 563 |
582 // Copy over input resolutions to prevent codec reinitialization due to | 564 // Copy over input resolutions to prevent codec reinitialization due to |
583 // the first frame being of a different resolution than the database values. | 565 // the first frame being of a different resolution than the database values. |
584 // This is best effort, since there's no guarantee that width/height have been | 566 // This is best effort, since there's no guarantee that width/height have been |
(...skipping 15 matching lines...) Expand all Loading... |
600 void VCMCodecDataBase::DeleteEncoder() { | 582 void VCMCodecDataBase::DeleteEncoder() { |
601 if (!ptr_encoder_) | 583 if (!ptr_encoder_) |
602 return; | 584 return; |
603 ptr_encoder_->Release(); | 585 ptr_encoder_->Release(); |
604 ptr_encoder_.reset(); | 586 ptr_encoder_.reset(); |
605 } | 587 } |
606 | 588 |
607 VCMGenericDecoder* VCMCodecDataBase::CreateDecoder(VideoCodecType type) const { | 589 VCMGenericDecoder* VCMCodecDataBase::CreateDecoder(VideoCodecType type) const { |
608 switch (type) { | 590 switch (type) { |
609 case kVideoCodecVP8: | 591 case kVideoCodecVP8: |
610 return new VCMGenericDecoder(*(VP8Decoder::Create())); | 592 return new VCMGenericDecoder(VP8Decoder::Create()); |
611 case kVideoCodecVP9: | 593 case kVideoCodecVP9: |
612 return new VCMGenericDecoder(*(VP9Decoder::Create())); | 594 return new VCMGenericDecoder(VP9Decoder::Create()); |
613 case kVideoCodecI420: | 595 case kVideoCodecI420: |
614 return new VCMGenericDecoder(*(new I420Decoder)); | 596 return new VCMGenericDecoder(new I420Decoder()); |
615 case kVideoCodecH264: | 597 case kVideoCodecH264: |
616 if (H264Decoder::IsSupported()) { | 598 if (H264Decoder::IsSupported()) { |
617 return new VCMGenericDecoder(*(H264Decoder::Create())); | 599 return new VCMGenericDecoder(H264Decoder::Create()); |
618 } | 600 } |
619 break; | 601 break; |
620 default: | 602 default: |
621 break; | 603 break; |
622 } | 604 } |
623 LOG(LS_WARNING) << "No internal decoder of this type exists."; | 605 LOG(LS_WARNING) << "No internal decoder of this type exists."; |
624 return nullptr; | 606 return nullptr; |
625 } | 607 } |
626 | 608 |
627 const VCMDecoderMapItem* VCMCodecDataBase::FindDecoderItem( | 609 const VCMDecoderMapItem* VCMCodecDataBase::FindDecoderItem( |
628 uint8_t payload_type) const { | 610 uint8_t payload_type) const { |
629 DecoderMap::const_iterator it = dec_map_.find(payload_type); | 611 DecoderMap::const_iterator it = dec_map_.find(payload_type); |
630 if (it != dec_map_.end()) { | 612 if (it != dec_map_.end()) { |
631 return (*it).second; | 613 return (*it).second; |
632 } | 614 } |
633 return nullptr; | 615 return nullptr; |
634 } | 616 } |
635 | 617 |
636 const VCMExtDecoderMapItem* VCMCodecDataBase::FindExternalDecoderItem( | 618 const VCMExtDecoderMapItem* VCMCodecDataBase::FindExternalDecoderItem( |
637 uint8_t payload_type) const { | 619 uint8_t payload_type) const { |
638 ExternalDecoderMap::const_iterator it = dec_external_map_.find(payload_type); | 620 ExternalDecoderMap::const_iterator it = dec_external_map_.find(payload_type); |
639 if (it != dec_external_map_.end()) { | 621 if (it != dec_external_map_.end()) { |
640 return (*it).second; | 622 return (*it).second; |
641 } | 623 } |
642 return nullptr; | 624 return nullptr; |
643 } | 625 } |
644 } // namespace webrtc | 626 } // namespace webrtc |
OLD | NEW |