| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 class EncoderFactoryAdapter : public webrtc::VideoEncoderFactory { | 42 class EncoderFactoryAdapter : public webrtc::VideoEncoderFactory { |
| 43 public: | 43 public: |
| 44 // EncoderFactoryAdapter doesn't take ownership of |factory|, which is owned | 44 // EncoderFactoryAdapter doesn't take ownership of |factory|, which is owned |
| 45 // by e.g. PeerConnectionFactory. | 45 // by e.g. PeerConnectionFactory. |
| 46 explicit EncoderFactoryAdapter(cricket::WebRtcVideoEncoderFactory* factory) | 46 explicit EncoderFactoryAdapter(cricket::WebRtcVideoEncoderFactory* factory) |
| 47 : factory_(factory) {} | 47 : factory_(factory) {} |
| 48 virtual ~EncoderFactoryAdapter() {} | 48 virtual ~EncoderFactoryAdapter() {} |
| 49 | 49 |
| 50 // Implement webrtc::VideoEncoderFactory. | 50 // Implement webrtc::VideoEncoderFactory. |
| 51 webrtc::VideoEncoder* Create() override { | 51 webrtc::VideoEncoder* Create() override { |
| 52 return factory_->CreateVideoEncoder(webrtc::kVideoCodecVP8); | 52 return factory_->CreateVideoEncoder(VideoCodec(kVp8CodecName)); |
| 53 } | 53 } |
| 54 | 54 |
| 55 void Destroy(webrtc::VideoEncoder* encoder) override { | 55 void Destroy(webrtc::VideoEncoder* encoder) override { |
| 56 return factory_->DestroyVideoEncoder(encoder); | 56 return factory_->DestroyVideoEncoder(encoder); |
| 57 } | 57 } |
| 58 | 58 |
| 59 private: | 59 private: |
| 60 cricket::WebRtcVideoEncoderFactory* const factory_; | 60 cricket::WebRtcVideoEncoderFactory* const factory_; |
| 61 }; | 61 }; |
| 62 | 62 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 92 class WebRtcSimulcastEncoderFactory | 92 class WebRtcSimulcastEncoderFactory |
| 93 : public cricket::WebRtcVideoEncoderFactory { | 93 : public cricket::WebRtcVideoEncoderFactory { |
| 94 public: | 94 public: |
| 95 // WebRtcSimulcastEncoderFactory doesn't take ownership of |factory|, which is | 95 // WebRtcSimulcastEncoderFactory doesn't take ownership of |factory|, which is |
| 96 // owned by e.g. PeerConnectionFactory. | 96 // owned by e.g. PeerConnectionFactory. |
| 97 explicit WebRtcSimulcastEncoderFactory( | 97 explicit WebRtcSimulcastEncoderFactory( |
| 98 cricket::WebRtcVideoEncoderFactory* factory) | 98 cricket::WebRtcVideoEncoderFactory* factory) |
| 99 : factory_(factory) {} | 99 : factory_(factory) {} |
| 100 | 100 |
| 101 static bool UseSimulcastEncoderFactory( | 101 static bool UseSimulcastEncoderFactory( |
| 102 const std::vector<VideoCodec>& codecs) { | 102 const std::vector<cricket::VideoCodec>& codecs) { |
| 103 // If any codec is VP8, use the simulcast factory. If asked to create a | 103 // If any codec is VP8, use the simulcast factory. If asked to create a |
| 104 // non-VP8 codec, we'll just return a contained factory encoder directly. | 104 // non-VP8 codec, we'll just return a contained factory encoder directly. |
| 105 for (const auto& codec : codecs) { | 105 for (const auto& codec : codecs) { |
| 106 if (codec.type == webrtc::kVideoCodecVP8) { | 106 if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) { |
| 107 return true; | 107 return true; |
| 108 } | 108 } |
| 109 } | 109 } |
| 110 return false; | 110 return false; |
| 111 } | 111 } |
| 112 | 112 |
| 113 webrtc::VideoEncoder* CreateVideoEncoder( | 113 webrtc::VideoEncoder* CreateVideoEncoder( |
| 114 webrtc::VideoCodecType type) override { | 114 const cricket::VideoCodec& codec) override { |
| 115 RTC_DCHECK(factory_ != NULL); | 115 RTC_DCHECK(factory_ != NULL); |
| 116 // If it's a codec type we can simulcast, create a wrapped encoder. | 116 // If it's a codec type we can simulcast, create a wrapped encoder. |
| 117 if (type == webrtc::kVideoCodecVP8) { | 117 if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) { |
| 118 return new webrtc::SimulcastEncoderAdapter( | 118 return new webrtc::SimulcastEncoderAdapter( |
| 119 new EncoderFactoryAdapter(factory_)); | 119 new EncoderFactoryAdapter(factory_)); |
| 120 } | 120 } |
| 121 webrtc::VideoEncoder* encoder = factory_->CreateVideoEncoder(type); | 121 webrtc::VideoEncoder* encoder = factory_->CreateVideoEncoder(codec); |
| 122 if (encoder) { | 122 if (encoder) { |
| 123 non_simulcast_encoders_.push_back(encoder); | 123 non_simulcast_encoders_.push_back(encoder); |
| 124 } | 124 } |
| 125 return encoder; | 125 return encoder; |
| 126 } | 126 } |
| 127 | 127 |
| 128 const std::vector<VideoCodec>& codecs() const override { | 128 const std::vector<cricket::VideoCodec>& supported_codecs() const override { |
| 129 return factory_->codecs(); | 129 return factory_->supported_codecs(); |
| 130 } | 130 } |
| 131 | 131 |
| 132 bool EncoderTypeHasInternalSource( | 132 bool EncoderTypeHasInternalSource( |
| 133 webrtc::VideoCodecType type) const override { | 133 webrtc::VideoCodecType type) const override { |
| 134 return factory_->EncoderTypeHasInternalSource(type); | 134 return factory_->EncoderTypeHasInternalSource(type); |
| 135 } | 135 } |
| 136 | 136 |
| 137 void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override { | 137 void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override { |
| 138 // Check first to see if the encoder wasn't wrapped in a | 138 // Check first to see if the encoder wasn't wrapped in a |
| 139 // SimulcastEncoderAdapter. In that case, ask the factory to destroy it. | 139 // SimulcastEncoderAdapter. In that case, ask the factory to destroy it. |
| 140 if (std::remove(non_simulcast_encoders_.begin(), | 140 if (std::remove(non_simulcast_encoders_.begin(), |
| 141 non_simulcast_encoders_.end(), | 141 non_simulcast_encoders_.end(), |
| 142 encoder) != non_simulcast_encoders_.end()) { | 142 encoder) != non_simulcast_encoders_.end()) { |
| 143 factory_->DestroyVideoEncoder(encoder); | 143 factory_->DestroyVideoEncoder(encoder); |
| 144 return; | 144 return; |
| 145 } | 145 } |
| 146 | 146 |
| 147 // Otherwise, SimulcastEncoderAdapter can be deleted directly, and will call | 147 // Otherwise, SimulcastEncoderAdapter can be deleted directly, and will call |
| 148 // DestroyVideoEncoder on the factory for individual encoder instances. | 148 // DestroyVideoEncoder on the factory for individual encoder instances. |
| 149 delete encoder; | 149 delete encoder; |
| 150 } | 150 } |
| 151 | 151 |
| 152 private: | 152 private: |
| 153 cricket::WebRtcVideoEncoderFactory* factory_; | 153 cricket::WebRtcVideoEncoderFactory* factory_; |
| 154 // A list of encoders that were created without being wrapped in a | 154 // A list of encoders that were created without being wrapped in a |
| 155 // SimulcastEncoderAdapter. | 155 // SimulcastEncoderAdapter. |
| 156 std::vector<webrtc::VideoEncoder*> non_simulcast_encoders_; | 156 std::vector<webrtc::VideoEncoder*> non_simulcast_encoders_; |
| 157 }; | 157 }; |
| 158 | 158 |
| 159 bool CodecIsInternallySupported(const std::string& codec_name) { | |
| 160 if (CodecNamesEq(codec_name, kVp8CodecName)) { | |
| 161 return true; | |
| 162 } | |
| 163 if (CodecNamesEq(codec_name, kVp9CodecName)) { | |
| 164 return webrtc::VP9Encoder::IsSupported() && | |
| 165 webrtc::VP9Decoder::IsSupported(); | |
| 166 } | |
| 167 if (CodecNamesEq(codec_name, kH264CodecName)) { | |
| 168 return webrtc::H264Encoder::IsSupported() && | |
| 169 webrtc::H264Decoder::IsSupported(); | |
| 170 } | |
| 171 return false; | |
| 172 } | |
| 173 | |
| 174 void AddDefaultFeedbackParams(VideoCodec* codec) { | 159 void AddDefaultFeedbackParams(VideoCodec* codec) { |
| 175 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamCcm, kRtcpFbCcmParamFir)); | 160 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamCcm, kRtcpFbCcmParamFir)); |
| 176 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); | 161 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); |
| 177 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kRtcpFbNackParamPli)); | 162 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kRtcpFbNackParamPli)); |
| 178 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); | 163 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); |
| 179 codec->AddFeedbackParam( | 164 codec->AddFeedbackParam( |
| 180 FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty)); | 165 FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty)); |
| 181 } | 166 } |
| 182 | 167 |
| 183 static VideoCodec MakeVideoCodecWithDefaultFeedbackParams(int payload_type, | 168 static VideoCodec MakeVideoCodecWithDefaultFeedbackParams(int payload_type, |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 return; | 421 return; |
| 437 } | 422 } |
| 438 codecs->push_back(VideoCodec::CreateRtxCodec(rtx_payload_type, codec.id)); | 423 codecs->push_back(VideoCodec::CreateRtxCodec(rtx_payload_type, codec.id)); |
| 439 } | 424 } |
| 440 | 425 |
| 441 std::vector<VideoCodec> DefaultVideoCodecList() { | 426 std::vector<VideoCodec> DefaultVideoCodecList() { |
| 442 std::vector<VideoCodec> codecs; | 427 std::vector<VideoCodec> codecs; |
| 443 AddCodecAndMaybeRtxCodec( | 428 AddCodecAndMaybeRtxCodec( |
| 444 MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp8PlType, kVp8CodecName), | 429 MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp8PlType, kVp8CodecName), |
| 445 &codecs); | 430 &codecs); |
| 446 if (CodecIsInternallySupported(kVp9CodecName)) { | 431 if (webrtc::VP9Encoder::IsSupported() && webrtc::VP9Decoder::IsSupported()) { |
| 447 AddCodecAndMaybeRtxCodec(MakeVideoCodecWithDefaultFeedbackParams( | 432 AddCodecAndMaybeRtxCodec(MakeVideoCodecWithDefaultFeedbackParams( |
| 448 kDefaultVp9PlType, kVp9CodecName), | 433 kDefaultVp9PlType, kVp9CodecName), |
| 449 &codecs); | 434 &codecs); |
| 450 } | 435 } |
| 451 if (CodecIsInternallySupported(kH264CodecName)) { | 436 if (webrtc::H264Encoder::IsSupported() && |
| 437 webrtc::H264Decoder::IsSupported()) { |
| 452 VideoCodec codec = MakeVideoCodecWithDefaultFeedbackParams( | 438 VideoCodec codec = MakeVideoCodecWithDefaultFeedbackParams( |
| 453 kDefaultH264PlType, kH264CodecName); | 439 kDefaultH264PlType, kH264CodecName); |
| 454 // TODO(hta): Move all parameter generation for SDP into the codec | 440 // TODO(hta): Move all parameter generation for SDP into the codec |
| 455 // implementation, for all codecs and parameters. | 441 // implementation, for all codecs and parameters. |
| 456 // TODO(hta): Move selection of profile-level-id to H.264 codec | 442 // TODO(hta): Move selection of profile-level-id to H.264 codec |
| 457 // implementation. | 443 // implementation. |
| 458 // TODO(hta): Set FMTP parameters for all codecs of type H264. | 444 // TODO(hta): Set FMTP parameters for all codecs of type H264. |
| 459 codec.SetParam(kH264FmtpProfileLevelId, | 445 codec.SetParam(kH264FmtpProfileLevelId, |
| 460 kH264ProfileLevelConstrainedBaseline); | 446 kH264ProfileLevelConstrainedBaseline); |
| 461 codec.SetParam(kH264FmtpLevelAsymmetryAllowed, "1"); | 447 codec.SetParam(kH264FmtpLevelAsymmetryAllowed, "1"); |
| 462 codec.SetParam(kH264FmtpPacketizationMode, "1"); | 448 codec.SetParam(kH264FmtpPacketizationMode, "1"); |
| 463 AddCodecAndMaybeRtxCodec(codec, &codecs); | 449 AddCodecAndMaybeRtxCodec(codec, &codecs); |
| 464 } | 450 } |
| 465 AddCodecAndMaybeRtxCodec(VideoCodec(kDefaultRedPlType, kRedCodecName), | 451 AddCodecAndMaybeRtxCodec(VideoCodec(kDefaultRedPlType, kRedCodecName), |
| 466 &codecs); | 452 &codecs); |
| 467 codecs.push_back(VideoCodec(kDefaultUlpfecType, kUlpfecCodecName)); | 453 codecs.push_back(VideoCodec(kDefaultUlpfecType, kUlpfecCodecName)); |
| 468 return codecs; | 454 return codecs; |
| 469 } | 455 } |
| 470 | 456 |
| 457 static std::vector<VideoCodec> GetSupportedCodecs( |
| 458 const WebRtcVideoEncoderFactory* external_encoder_factory); |
| 459 |
| 471 rtc::scoped_refptr<webrtc::VideoEncoderConfig::EncoderSpecificSettings> | 460 rtc::scoped_refptr<webrtc::VideoEncoderConfig::EncoderSpecificSettings> |
| 472 WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( | 461 WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( |
| 473 const VideoCodec& codec) { | 462 const VideoCodec& codec) { |
| 474 RTC_DCHECK_RUN_ON(&thread_checker_); | 463 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 475 bool is_screencast = parameters_.options.is_screencast.value_or(false); | 464 bool is_screencast = parameters_.options.is_screencast.value_or(false); |
| 476 // No automatic resizing when using simulcast or screencast. | 465 // No automatic resizing when using simulcast or screencast. |
| 477 bool automatic_resize = | 466 bool automatic_resize = |
| 478 !is_screencast && parameters_.config.rtp.ssrcs.size() == 1; | 467 !is_screencast && parameters_.config.rtp.ssrcs.size() == 1; |
| 479 bool frame_dropping = !is_screencast; | 468 bool frame_dropping = !is_screencast; |
| 480 bool denoising; | 469 bool denoising; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 if (default_recv_ssrc_ != 0) { | 547 if (default_recv_ssrc_ != 0) { |
| 559 channel->SetSink(default_recv_ssrc_, default_sink_); | 548 channel->SetSink(default_recv_ssrc_, default_sink_); |
| 560 } | 549 } |
| 561 } | 550 } |
| 562 | 551 |
| 563 WebRtcVideoEngine2::WebRtcVideoEngine2() | 552 WebRtcVideoEngine2::WebRtcVideoEngine2() |
| 564 : initialized_(false), | 553 : initialized_(false), |
| 565 external_decoder_factory_(NULL), | 554 external_decoder_factory_(NULL), |
| 566 external_encoder_factory_(NULL) { | 555 external_encoder_factory_(NULL) { |
| 567 LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2()"; | 556 LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2()"; |
| 568 video_codecs_ = GetSupportedCodecs(); | 557 video_codecs_ = GetSupportedCodecs(external_encoder_factory_); |
| 569 } | 558 } |
| 570 | 559 |
| 571 WebRtcVideoEngine2::~WebRtcVideoEngine2() { | 560 WebRtcVideoEngine2::~WebRtcVideoEngine2() { |
| 572 LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2"; | 561 LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2"; |
| 573 } | 562 } |
| 574 | 563 |
| 575 void WebRtcVideoEngine2::Init() { | 564 void WebRtcVideoEngine2::Init() { |
| 576 LOG(LS_INFO) << "WebRtcVideoEngine2::Init"; | 565 LOG(LS_INFO) << "WebRtcVideoEngine2::Init"; |
| 577 initialized_ = true; | 566 initialized_ = true; |
| 578 } | 567 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 RTC_DCHECK(!initialized_); | 612 RTC_DCHECK(!initialized_); |
| 624 if (external_encoder_factory_ == encoder_factory) | 613 if (external_encoder_factory_ == encoder_factory) |
| 625 return; | 614 return; |
| 626 | 615 |
| 627 // No matter what happens we shouldn't hold on to a stale | 616 // No matter what happens we shouldn't hold on to a stale |
| 628 // WebRtcSimulcastEncoderFactory. | 617 // WebRtcSimulcastEncoderFactory. |
| 629 simulcast_encoder_factory_.reset(); | 618 simulcast_encoder_factory_.reset(); |
| 630 | 619 |
| 631 if (encoder_factory && | 620 if (encoder_factory && |
| 632 WebRtcSimulcastEncoderFactory::UseSimulcastEncoderFactory( | 621 WebRtcSimulcastEncoderFactory::UseSimulcastEncoderFactory( |
| 633 encoder_factory->codecs())) { | 622 encoder_factory->supported_codecs())) { |
| 634 simulcast_encoder_factory_.reset( | 623 simulcast_encoder_factory_.reset( |
| 635 new WebRtcSimulcastEncoderFactory(encoder_factory)); | 624 new WebRtcSimulcastEncoderFactory(encoder_factory)); |
| 636 encoder_factory = simulcast_encoder_factory_.get(); | 625 encoder_factory = simulcast_encoder_factory_.get(); |
| 637 } | 626 } |
| 638 external_encoder_factory_ = encoder_factory; | 627 external_encoder_factory_ = encoder_factory; |
| 639 | 628 |
| 640 video_codecs_ = GetSupportedCodecs(); | 629 video_codecs_ = GetSupportedCodecs(encoder_factory); |
| 641 } | 630 } |
| 642 | 631 |
| 643 std::vector<VideoCodec> WebRtcVideoEngine2::GetSupportedCodecs() const { | 632 static std::vector<VideoCodec> GetSupportedCodecs( |
| 633 const WebRtcVideoEncoderFactory* external_encoder_factory) { |
| 644 std::vector<VideoCodec> supported_codecs = DefaultVideoCodecList(); | 634 std::vector<VideoCodec> supported_codecs = DefaultVideoCodecList(); |
| 645 | 635 |
| 646 if (external_encoder_factory_ == NULL) { | 636 if (external_encoder_factory == nullptr) { |
| 647 LOG(LS_INFO) << "Supported codecs: " | 637 LOG(LS_INFO) << "Supported codecs: " |
| 648 << CodecVectorToString(supported_codecs); | 638 << CodecVectorToString(supported_codecs); |
| 649 return supported_codecs; | 639 return supported_codecs; |
| 650 } | 640 } |
| 651 | 641 |
| 652 std::stringstream out; | 642 std::stringstream out; |
| 653 const std::vector<WebRtcVideoEncoderFactory::VideoCodec>& codecs = | 643 const std::vector<VideoCodec>& codecs = |
| 654 external_encoder_factory_->codecs(); | 644 external_encoder_factory->supported_codecs(); |
| 655 for (size_t i = 0; i < codecs.size(); ++i) { | 645 for (size_t i = 0; i < codecs.size(); ++i) { |
| 656 out << codecs[i].name; | 646 VideoCodec codec = codecs[i]; |
| 647 out << codec.name; |
| 657 if (i != codecs.size() - 1) { | 648 if (i != codecs.size() - 1) { |
| 658 out << ", "; | 649 out << ", "; |
| 659 } | 650 } |
| 660 // Don't add internally-supported codecs twice. | 651 // Don't add internally-supported codecs twice. |
| 661 if (CodecIsInternallySupported(codecs[i].name)) { | 652 if (IsCodecSupported(supported_codecs, codec)) |
| 662 continue; | 653 continue; |
| 663 } | |
| 664 | 654 |
| 665 // External video encoders are given payloads 120-127. This also means that | 655 // External video encoders are given payloads 120-127. This also means that |
| 666 // we only support up to 8 external payload types. | 656 // we only support up to 8 external payload types. |
| 667 // TODO(deadbeef): mediasession.cc already has code to dynamically | 657 // TODO(deadbeef): mediasession.cc already has code to dynamically |
| 668 // determine a payload type. We should be able to just leave the payload | 658 // determine a payload type. We should be able to just leave the payload |
| 669 // type empty and let mediasession determine it. However, currently RTX | 659 // type empty and let mediasession determine it. However, currently RTX |
| 670 // codecs are associated to codecs by payload type, meaning we DO need | 660 // codecs are associated to codecs by payload type, meaning we DO need |
| 671 // to allocate unique payload types here. So to make this change we would | 661 // to allocate unique payload types here. So to make this change we would |
| 672 // need to make RTX codecs associated by name instead. | 662 // need to make RTX codecs associated by name instead. |
| 673 const int kExternalVideoPayloadTypeBase = 120; | 663 const int kExternalVideoPayloadTypeBase = 120; |
| 674 size_t payload_type = kExternalVideoPayloadTypeBase + i; | 664 size_t payload_type = kExternalVideoPayloadTypeBase + i; |
| 675 RTC_DCHECK(payload_type < 128); | 665 RTC_DCHECK(payload_type < 128); |
| 676 VideoCodec codec(static_cast<int>(payload_type), codecs[i].name); | 666 codec.id = payload_type; |
| 677 | 667 |
| 678 AddDefaultFeedbackParams(&codec); | 668 AddDefaultFeedbackParams(&codec); |
| 679 AddCodecAndMaybeRtxCodec(codec, &supported_codecs); | 669 AddCodecAndMaybeRtxCodec(codec, &supported_codecs); |
| 680 } | 670 } |
| 681 LOG(LS_INFO) << "Supported codecs (incl. external codecs): " | 671 LOG(LS_INFO) << "Supported codecs (incl. external codecs): " |
| 682 << CodecVectorToString(supported_codecs); | 672 << CodecVectorToString(supported_codecs); |
| 683 LOG(LS_INFO) << "Codecs supported by the external encoder factory: " | 673 LOG(LS_INFO) << "Codecs supported by the external encoder factory: " |
| 684 << out.str(); | 674 << out.str(); |
| 685 return supported_codecs; | 675 return supported_codecs; |
| 686 } | 676 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 709 recv_codecs_ = FilterSupportedCodecs(MapCodecs(recv_codecs)); | 699 recv_codecs_ = FilterSupportedCodecs(MapCodecs(recv_codecs)); |
| 710 } | 700 } |
| 711 | 701 |
| 712 WebRtcVideoChannel2::~WebRtcVideoChannel2() { | 702 WebRtcVideoChannel2::~WebRtcVideoChannel2() { |
| 713 for (auto& kv : send_streams_) | 703 for (auto& kv : send_streams_) |
| 714 delete kv.second; | 704 delete kv.second; |
| 715 for (auto& kv : receive_streams_) | 705 for (auto& kv : receive_streams_) |
| 716 delete kv.second; | 706 delete kv.second; |
| 717 } | 707 } |
| 718 | 708 |
| 719 bool WebRtcVideoChannel2::CodecIsExternallySupported( | |
| 720 const std::string& name) const { | |
| 721 if (external_encoder_factory_ == NULL) { | |
| 722 return false; | |
| 723 } | |
| 724 | |
| 725 const std::vector<WebRtcVideoEncoderFactory::VideoCodec> external_codecs = | |
| 726 external_encoder_factory_->codecs(); | |
| 727 for (size_t c = 0; c < external_codecs.size(); ++c) { | |
| 728 if (CodecNamesEq(name, external_codecs[c].name)) { | |
| 729 return true; | |
| 730 } | |
| 731 } | |
| 732 return false; | |
| 733 } | |
| 734 | |
| 735 std::vector<WebRtcVideoChannel2::VideoCodecSettings> | 709 std::vector<WebRtcVideoChannel2::VideoCodecSettings> |
| 736 WebRtcVideoChannel2::FilterSupportedCodecs( | 710 WebRtcVideoChannel2::FilterSupportedCodecs( |
| 737 const std::vector<WebRtcVideoChannel2::VideoCodecSettings>& mapped_codecs) | 711 const std::vector<VideoCodecSettings>& mapped_codecs) const { |
| 738 const { | 712 const std::vector<VideoCodec> supported_codecs = |
| 739 std::vector<VideoCodecSettings> supported_codecs; | 713 GetSupportedCodecs(external_encoder_factory_); |
| 740 for (size_t i = 0; i < mapped_codecs.size(); ++i) { | 714 std::vector<VideoCodecSettings> filtered_codecs; |
| 741 const VideoCodecSettings& codec = mapped_codecs[i]; | 715 for (const VideoCodecSettings& mapped_codec : mapped_codecs) { |
| 742 if (CodecIsInternallySupported(codec.codec.name) || | 716 if (IsCodecSupported(supported_codecs, mapped_codec.codec)) |
| 743 CodecIsExternallySupported(codec.codec.name)) { | 717 filtered_codecs.push_back(mapped_codec); |
| 744 supported_codecs.push_back(codec); | |
| 745 } | |
| 746 } | 718 } |
| 747 return supported_codecs; | 719 return filtered_codecs; |
| 748 } | 720 } |
| 749 | 721 |
| 750 bool WebRtcVideoChannel2::ReceiveCodecsHaveChanged( | 722 bool WebRtcVideoChannel2::ReceiveCodecsHaveChanged( |
| 751 std::vector<VideoCodecSettings> before, | 723 std::vector<VideoCodecSettings> before, |
| 752 std::vector<VideoCodecSettings> after) { | 724 std::vector<VideoCodecSettings> after) { |
| 753 if (before.size() != after.size()) { | 725 if (before.size() != after.size()) { |
| 754 return true; | 726 return true; |
| 755 } | 727 } |
| 756 // The receive codec order doesn't matter, so we sort the codecs before | 728 // The receive codec order doesn't matter, so we sort the codecs before |
| 757 // comparing. This is necessary because currently the | 729 // comparing. This is necessary because currently the |
| (...skipping 1005 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1763 // the source is changed since the next source might be screen capture | 1735 // the source is changed since the next source might be screen capture |
| 1764 // with another resolution and frame rate. | 1736 // with another resolution and frame rate. |
| 1765 cpu_restricted_counter_ = 0; | 1737 cpu_restricted_counter_ = 0; |
| 1766 } | 1738 } |
| 1767 | 1739 |
| 1768 const std::vector<uint32_t>& | 1740 const std::vector<uint32_t>& |
| 1769 WebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { | 1741 WebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { |
| 1770 return ssrcs_; | 1742 return ssrcs_; |
| 1771 } | 1743 } |
| 1772 | 1744 |
| 1773 webrtc::VideoCodecType CodecTypeFromName(const std::string& name) { | |
| 1774 if (CodecNamesEq(name, kVp8CodecName)) { | |
| 1775 return webrtc::kVideoCodecVP8; | |
| 1776 } else if (CodecNamesEq(name, kVp9CodecName)) { | |
| 1777 return webrtc::kVideoCodecVP9; | |
| 1778 } else if (CodecNamesEq(name, kH264CodecName)) { | |
| 1779 return webrtc::kVideoCodecH264; | |
| 1780 } | |
| 1781 return webrtc::kVideoCodecUnknown; | |
| 1782 } | |
| 1783 | |
| 1784 WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder | 1745 WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder |
| 1785 WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( | 1746 WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( |
| 1786 const VideoCodec& codec) { | 1747 const VideoCodec& codec) { |
| 1787 RTC_DCHECK_RUN_ON(&thread_checker_); | 1748 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 1788 webrtc::VideoCodecType type = CodecTypeFromName(codec.name); | 1749 webrtc::VideoCodecType type = CodecTypeFromName(codec.name); |
| 1789 | 1750 |
| 1790 // Do not re-create encoders of the same type. | 1751 // Do not re-create encoders of the same type. |
| 1791 if (type == allocated_encoder_.type && allocated_encoder_.encoder != NULL) { | 1752 if (type == allocated_encoder_.type && allocated_encoder_.encoder != NULL) { |
| 1792 return allocated_encoder_; | 1753 return allocated_encoder_; |
| 1793 } | 1754 } |
| 1794 | 1755 |
| 1795 if (external_encoder_factory_ != NULL) { | 1756 if (external_encoder_factory_ != NULL) { |
| 1796 webrtc::VideoEncoder* encoder = | 1757 webrtc::VideoEncoder* encoder = |
| 1797 external_encoder_factory_->CreateVideoEncoder(type); | 1758 external_encoder_factory_->CreateVideoEncoder(codec); |
| 1798 if (encoder != NULL) { | 1759 if (encoder != NULL) { |
| 1799 return AllocatedEncoder(encoder, type, true); | 1760 return AllocatedEncoder(encoder, type, true); |
| 1800 } | 1761 } |
| 1801 } | 1762 } |
| 1802 | 1763 |
| 1803 if (type == webrtc::kVideoCodecVP8) { | 1764 if (type == webrtc::kVideoCodecVP8) { |
| 1804 return AllocatedEncoder( | 1765 return AllocatedEncoder( |
| 1805 webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp8), type, false); | 1766 webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp8), type, false); |
| 1806 } else if (type == webrtc::kVideoCodecVP9) { | 1767 } else if (type == webrtc::kVideoCodecVP9) { |
| 1807 return AllocatedEncoder( | 1768 return AllocatedEncoder( |
| (...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2688 rtx_mapping[video_codecs[i].codec.id] != | 2649 rtx_mapping[video_codecs[i].codec.id] != |
| 2689 ulpfec_config.red_payload_type) { | 2650 ulpfec_config.red_payload_type) { |
| 2690 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; | 2651 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; |
| 2691 } | 2652 } |
| 2692 } | 2653 } |
| 2693 | 2654 |
| 2694 return video_codecs; | 2655 return video_codecs; |
| 2695 } | 2656 } |
| 2696 | 2657 |
| 2697 } // namespace cricket | 2658 } // namespace cricket |
| OLD | NEW |