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