| 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 |
| 11 #include "webrtc/media/engine/webrtcvideoengine2.h" | 11 #include "webrtc/media/engine/webrtcvideoengine2.h" |
| 12 | 12 |
| 13 #include <stdio.h> | 13 #include <stdio.h> |
| 14 #include <algorithm> | 14 #include <algorithm> |
| 15 #include <set> | 15 #include <set> |
| 16 #include <string> | 16 #include <string> |
| 17 #include <utility> | 17 #include <utility> |
| 18 | 18 |
| 19 #include "webrtc/base/copyonwritebuffer.h" | 19 #include "webrtc/base/copyonwritebuffer.h" |
| 20 #include "webrtc/base/logging.h" | 20 #include "webrtc/base/logging.h" |
| 21 #include "webrtc/base/stringutils.h" | 21 #include "webrtc/base/stringutils.h" |
| 22 #include "webrtc/base/timeutils.h" | 22 #include "webrtc/base/timeutils.h" |
| 23 #include "webrtc/base/trace_event.h" | 23 #include "webrtc/base/trace_event.h" |
| 24 #include "webrtc/call.h" | 24 #include "webrtc/call.h" |
| 25 #include "webrtc/common_video/h264/profile_level_id.h" | 25 #include "webrtc/common_video/h264/profile_level_id.h" |
| 26 #include "webrtc/media/engine/constants.h" | 26 #include "webrtc/media/engine/constants.h" |
| 27 #include "webrtc/media/engine/internalencoderfactory.h" |
| 27 #include "webrtc/media/engine/simulcast.h" | 28 #include "webrtc/media/engine/simulcast.h" |
| 28 #include "webrtc/media/engine/videoencodersoftwarefallbackwrapper.h" | 29 #include "webrtc/media/engine/videoencodersoftwarefallbackwrapper.h" |
| 29 #include "webrtc/media/engine/webrtcmediaengine.h" | 30 #include "webrtc/media/engine/webrtcmediaengine.h" |
| 30 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" | 31 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" |
| 31 #include "webrtc/media/engine/webrtcvoiceengine.h" | 32 #include "webrtc/media/engine/webrtcvoiceengine.h" |
| 32 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" | |
| 33 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h" | 33 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h" |
| 34 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" | |
| 35 #include "webrtc/system_wrappers/include/field_trial.h" | 34 #include "webrtc/system_wrappers/include/field_trial.h" |
| 36 #include "webrtc/video_decoder.h" | 35 #include "webrtc/video_decoder.h" |
| 37 #include "webrtc/video_encoder.h" | 36 #include "webrtc/video_encoder.h" |
| 38 | 37 |
| 39 namespace cricket { | 38 namespace cricket { |
| 40 namespace { | 39 namespace { |
| 41 | 40 |
| 42 // Wrap cricket::WebRtcVideoEncoderFactory as a webrtc::VideoEncoderFactory. | 41 // Wrap cricket::WebRtcVideoEncoderFactory as a webrtc::VideoEncoderFactory. |
| 43 class EncoderFactoryAdapter : public webrtc::VideoEncoderFactory { | 42 class EncoderFactoryAdapter : public webrtc::VideoEncoderFactory { |
| 44 public: | 43 public: |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 | 162 |
| 164 void AddDefaultFeedbackParams(VideoCodec* codec) { | 163 void AddDefaultFeedbackParams(VideoCodec* codec) { |
| 165 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamCcm, kRtcpFbCcmParamFir)); | 164 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamCcm, kRtcpFbCcmParamFir)); |
| 166 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); | 165 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); |
| 167 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kRtcpFbNackParamPli)); | 166 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kRtcpFbNackParamPli)); |
| 168 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); | 167 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); |
| 169 codec->AddFeedbackParam( | 168 codec->AddFeedbackParam( |
| 170 FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty)); | 169 FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty)); |
| 171 } | 170 } |
| 172 | 171 |
| 173 static VideoCodec MakeVideoCodecWithDefaultFeedbackParams(int payload_type, | |
| 174 const char* name) { | |
| 175 VideoCodec codec(payload_type, name); | |
| 176 AddDefaultFeedbackParams(&codec); | |
| 177 return codec; | |
| 178 } | |
| 179 | |
| 180 static std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) { | 172 static std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) { |
| 181 std::stringstream out; | 173 std::stringstream out; |
| 182 out << '{'; | 174 out << '{'; |
| 183 for (size_t i = 0; i < codecs.size(); ++i) { | 175 for (size_t i = 0; i < codecs.size(); ++i) { |
| 184 out << codecs[i].ToString(); | 176 out << codecs[i].ToString(); |
| 185 if (i != codecs.size() - 1) { | 177 if (i != codecs.size() - 1) { |
| 186 out << ", "; | 178 out << ", "; |
| 187 } | 179 } |
| 188 } | 180 } |
| 189 out << '}'; | 181 out << '}'; |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 // duration hasn't been implemented. | 377 // duration hasn't been implemented. |
| 386 static const int kNackHistoryMs = 1000; | 378 static const int kNackHistoryMs = 1000; |
| 387 | 379 |
| 388 static const int kDefaultQpMax = 56; | 380 static const int kDefaultQpMax = 56; |
| 389 | 381 |
| 390 static const int kDefaultRtcpReceiverReportSsrc = 1; | 382 static const int kDefaultRtcpReceiverReportSsrc = 1; |
| 391 | 383 |
| 392 // Minimum time interval for logging stats. | 384 // Minimum time interval for logging stats. |
| 393 static const int64_t kStatsLogIntervalMs = 10000; | 385 static const int64_t kStatsLogIntervalMs = 10000; |
| 394 | 386 |
| 395 // Adds |codec| to |list|, and also adds an RTX codec if |codec|'s name is | |
| 396 // recognized. | |
| 397 // TODO(deadbeef): Should we add RTX codecs for external codecs whose names we | |
| 398 // don't recognize? | |
| 399 void AddCodecAndMaybeRtxCodec(const VideoCodec& codec, | |
| 400 std::vector<VideoCodec>* codecs) { | |
| 401 codecs->push_back(codec); | |
| 402 int rtx_payload_type = 0; | |
| 403 if (CodecNamesEq(codec.name, kVp8CodecName)) { | |
| 404 rtx_payload_type = kDefaultRtxVp8PlType; | |
| 405 } else if (CodecNamesEq(codec.name, kVp9CodecName)) { | |
| 406 rtx_payload_type = kDefaultRtxVp9PlType; | |
| 407 } else if (CodecNamesEq(codec.name, kH264CodecName)) { | |
| 408 // Parse H264 profile. | |
| 409 const rtc::Optional<webrtc::H264::ProfileLevelId> profile_level_id = | |
| 410 webrtc::H264::ParseSdpProfileLevelId(codec.params); | |
| 411 if (!profile_level_id) | |
| 412 return; | |
| 413 const webrtc::H264::Profile profile = profile_level_id->profile; | |
| 414 // In H.264, we only support rtx for constrained baseline and constrained | |
| 415 // high profile. | |
| 416 if (profile == webrtc::H264::kProfileConstrainedBaseline) { | |
| 417 rtx_payload_type = kDefaultRtxH264ConstrainedBaselinePlType; | |
| 418 } else if (profile == webrtc::H264::kProfileConstrainedHigh) { | |
| 419 rtx_payload_type = kDefaultRtxH264ConstrainedHighPlType; | |
| 420 } else { | |
| 421 return; | |
| 422 } | |
| 423 } else if (CodecNamesEq(codec.name, kRedCodecName)) { | |
| 424 rtx_payload_type = kDefaultRtxRedPlType; | |
| 425 } else { | |
| 426 return; | |
| 427 } | |
| 428 codecs->push_back(VideoCodec::CreateRtxCodec(rtx_payload_type, codec.id)); | |
| 429 } | |
| 430 | |
| 431 std::vector<VideoCodec> DefaultVideoCodecList() { | |
| 432 std::vector<VideoCodec> codecs; | |
| 433 AddCodecAndMaybeRtxCodec( | |
| 434 MakeVideoCodecWithDefaultFeedbackParams(kDefaultVp8PlType, kVp8CodecName), | |
| 435 &codecs); | |
| 436 if (webrtc::VP9Encoder::IsSupported() && webrtc::VP9Decoder::IsSupported()) { | |
| 437 AddCodecAndMaybeRtxCodec(MakeVideoCodecWithDefaultFeedbackParams( | |
| 438 kDefaultVp9PlType, kVp9CodecName), | |
| 439 &codecs); | |
| 440 } | |
| 441 if (webrtc::H264Encoder::IsSupported() && | |
| 442 webrtc::H264Decoder::IsSupported()) { | |
| 443 VideoCodec codec = MakeVideoCodecWithDefaultFeedbackParams( | |
| 444 kDefaultH264PlType, kH264CodecName); | |
| 445 // TODO(hta): Move all parameter generation for SDP into the codec | |
| 446 // implementation, for all codecs and parameters. | |
| 447 // TODO(hta): Move selection of profile-level-id to H.264 codec | |
| 448 // implementation. | |
| 449 // TODO(hta): Set FMTP parameters for all codecs of type H264. | |
| 450 codec.SetParam(kH264FmtpProfileLevelId, | |
| 451 kH264ProfileLevelConstrainedBaseline); | |
| 452 codec.SetParam(kH264FmtpLevelAsymmetryAllowed, "1"); | |
| 453 codec.SetParam(kH264FmtpPacketizationMode, "1"); | |
| 454 AddCodecAndMaybeRtxCodec(codec, &codecs); | |
| 455 } | |
| 456 AddCodecAndMaybeRtxCodec(VideoCodec(kDefaultRedPlType, kRedCodecName), | |
| 457 &codecs); | |
| 458 codecs.push_back(VideoCodec(kDefaultUlpfecType, kUlpfecCodecName)); | |
| 459 return codecs; | |
| 460 } | |
| 461 | |
| 462 static std::vector<VideoCodec> GetSupportedCodecs( | 387 static std::vector<VideoCodec> GetSupportedCodecs( |
| 463 const WebRtcVideoEncoderFactory* external_encoder_factory); | 388 const WebRtcVideoEncoderFactory* external_encoder_factory); |
| 464 | 389 |
| 465 rtc::scoped_refptr<webrtc::VideoEncoderConfig::EncoderSpecificSettings> | 390 rtc::scoped_refptr<webrtc::VideoEncoderConfig::EncoderSpecificSettings> |
| 466 WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( | 391 WebRtcVideoChannel2::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( |
| 467 const VideoCodec& codec) { | 392 const VideoCodec& codec) { |
| 468 RTC_DCHECK_RUN_ON(&thread_checker_); | 393 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 469 bool is_screencast = parameters_.options.is_screencast.value_or(false); | 394 bool is_screencast = parameters_.options.is_screencast.value_or(false); |
| 470 // No automatic resizing when using simulcast or screencast. | 395 // No automatic resizing when using simulcast or screencast. |
| 471 bool automatic_resize = | 396 bool automatic_resize = |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 encoder_factory->supported_codecs())) { | 552 encoder_factory->supported_codecs())) { |
| 628 simulcast_encoder_factory_.reset( | 553 simulcast_encoder_factory_.reset( |
| 629 new WebRtcSimulcastEncoderFactory(encoder_factory)); | 554 new WebRtcSimulcastEncoderFactory(encoder_factory)); |
| 630 encoder_factory = simulcast_encoder_factory_.get(); | 555 encoder_factory = simulcast_encoder_factory_.get(); |
| 631 } | 556 } |
| 632 external_encoder_factory_ = encoder_factory; | 557 external_encoder_factory_ = encoder_factory; |
| 633 | 558 |
| 634 video_codecs_ = GetSupportedCodecs(encoder_factory); | 559 video_codecs_ = GetSupportedCodecs(encoder_factory); |
| 635 } | 560 } |
| 636 | 561 |
| 562 // This is a helper function for AppendVideoCodecs below. It will return the |
| 563 // first unused dynamic payload type (in the range [96, 127]), or nothing if no |
| 564 // payload type is unused. |
| 565 static rtc::Optional<int> NextFreePayloadType( |
| 566 const std::vector<VideoCodec>& codecs) { |
| 567 static const int kFirstDynamicPayloadType = 96; |
| 568 static const int kLastDynamicPayloadType = 127; |
| 569 bool is_payload_used[1 + kLastDynamicPayloadType - kFirstDynamicPayloadType] = |
| 570 {false}; |
| 571 for (const VideoCodec& codec : codecs) { |
| 572 if (kFirstDynamicPayloadType <= codec.id && |
| 573 codec.id <= kLastDynamicPayloadType) { |
| 574 is_payload_used[codec.id - kFirstDynamicPayloadType] = true; |
| 575 } |
| 576 } |
| 577 for (int i = kFirstDynamicPayloadType; i <= kLastDynamicPayloadType; ++i) { |
| 578 if (!is_payload_used[i - kFirstDynamicPayloadType]) |
| 579 return rtc::Optional<int>(i); |
| 580 } |
| 581 // No free payload type. |
| 582 return rtc::Optional<int>(); |
| 583 } |
| 584 |
| 585 // This is a helper function for GetSupportedCodecs below. It will append new |
| 586 // unique codecs from |input_codecs| to |unified_codecs|. It will add default |
| 587 // feedback params to the codecs and will also add an associated RTX codec for |
| 588 // recognized codecs (VP8, VP9, H264, and Red). |
| 589 static void AppendVideoCodecs(const std::vector<VideoCodec>& input_codecs, |
| 590 std::vector<VideoCodec>* unified_codecs) { |
| 591 for (VideoCodec codec : input_codecs) { |
| 592 const rtc::Optional<int> payload_type = |
| 593 NextFreePayloadType(*unified_codecs); |
| 594 if (!payload_type) |
| 595 return; |
| 596 codec.id = *payload_type; |
| 597 // TODO(magjed): Move the responsibility of setting these parameters to the |
| 598 // encoder factories instead. |
| 599 if (codec.name != kRedCodecName && codec.name != kUlpfecCodecName) |
| 600 AddDefaultFeedbackParams(&codec); |
| 601 // Don't add same codec twice. |
| 602 if (FindMatchingCodec(*unified_codecs, codec)) |
| 603 continue; |
| 604 |
| 605 unified_codecs->push_back(codec); |
| 606 |
| 607 // Add associated RTX codec for recognized codecs. |
| 608 // TODO(deadbeef): Should we add RTX codecs for external codecs whose names |
| 609 // we don't recognize? |
| 610 if (CodecNamesEq(codec.name, kVp8CodecName) || |
| 611 CodecNamesEq(codec.name, kVp9CodecName) || |
| 612 CodecNamesEq(codec.name, kH264CodecName) || |
| 613 CodecNamesEq(codec.name, kRedCodecName)) { |
| 614 const rtc::Optional<int> rtx_payload_type = |
| 615 NextFreePayloadType(*unified_codecs); |
| 616 if (!rtx_payload_type) |
| 617 return; |
| 618 unified_codecs->push_back( |
| 619 VideoCodec::CreateRtxCodec(*rtx_payload_type, codec.id)); |
| 620 } |
| 621 } |
| 622 } |
| 623 |
| 637 static std::vector<VideoCodec> GetSupportedCodecs( | 624 static std::vector<VideoCodec> GetSupportedCodecs( |
| 638 const WebRtcVideoEncoderFactory* external_encoder_factory) { | 625 const WebRtcVideoEncoderFactory* external_encoder_factory) { |
| 639 std::vector<VideoCodec> supported_codecs = DefaultVideoCodecList(); | 626 const std::vector<VideoCodec>& internal_codecs = |
| 627 InternalEncoderFactory::GetInstance().supported_codecs(); |
| 628 LOG(LS_INFO) << "Internally supported codecs: " |
| 629 << CodecVectorToString(internal_codecs); |
| 640 | 630 |
| 641 if (external_encoder_factory == nullptr) { | 631 std::vector<VideoCodec> unified_codecs; |
| 642 LOG(LS_INFO) << "Supported codecs: " | 632 AppendVideoCodecs(internal_codecs, &unified_codecs); |
| 643 << CodecVectorToString(supported_codecs); | 633 |
| 644 return supported_codecs; | 634 if (external_encoder_factory != nullptr) { |
| 635 const std::vector<VideoCodec>& external_codecs = |
| 636 external_encoder_factory->supported_codecs(); |
| 637 AppendVideoCodecs(external_codecs, &unified_codecs); |
| 638 LOG(LS_INFO) << "Codecs supported by the external encoder factory: " |
| 639 << CodecVectorToString(external_codecs); |
| 645 } | 640 } |
| 646 | 641 |
| 647 std::stringstream out; | 642 return unified_codecs; |
| 648 const std::vector<VideoCodec>& codecs = | |
| 649 external_encoder_factory->supported_codecs(); | |
| 650 for (size_t i = 0; i < codecs.size(); ++i) { | |
| 651 VideoCodec codec = codecs[i]; | |
| 652 out << codec.name; | |
| 653 if (i != codecs.size() - 1) { | |
| 654 out << ", "; | |
| 655 } | |
| 656 // Don't add internally-supported codecs twice. | |
| 657 if (FindMatchingCodec(supported_codecs, codec)) | |
| 658 continue; | |
| 659 | |
| 660 // External video encoders are given payloads 120-127. This also means that | |
| 661 // we only support up to 8 external payload types. | |
| 662 // TODO(deadbeef): mediasession.cc already has code to dynamically | |
| 663 // determine a payload type. We should be able to just leave the payload | |
| 664 // type empty and let mediasession determine it. However, currently RTX | |
| 665 // codecs are associated to codecs by payload type, meaning we DO need | |
| 666 // to allocate unique payload types here. So to make this change we would | |
| 667 // need to make RTX codecs associated by name instead. | |
| 668 const int kExternalVideoPayloadTypeBase = 120; | |
| 669 size_t payload_type = kExternalVideoPayloadTypeBase + i; | |
| 670 RTC_DCHECK(payload_type < 128); | |
| 671 codec.id = payload_type; | |
| 672 | |
| 673 AddDefaultFeedbackParams(&codec); | |
| 674 AddCodecAndMaybeRtxCodec(codec, &supported_codecs); | |
| 675 } | |
| 676 LOG(LS_INFO) << "Supported codecs (incl. external codecs): " | |
| 677 << CodecVectorToString(supported_codecs); | |
| 678 LOG(LS_INFO) << "Codecs supported by the external encoder factory: " | |
| 679 << out.str(); | |
| 680 return supported_codecs; | |
| 681 } | 643 } |
| 682 | 644 |
| 683 WebRtcVideoChannel2::WebRtcVideoChannel2( | 645 WebRtcVideoChannel2::WebRtcVideoChannel2( |
| 684 webrtc::Call* call, | 646 webrtc::Call* call, |
| 685 const MediaConfig& config, | 647 const MediaConfig& config, |
| 686 const VideoOptions& options, | 648 const VideoOptions& options, |
| 687 WebRtcVideoEncoderFactory* external_encoder_factory, | 649 WebRtcVideoEncoderFactory* external_encoder_factory, |
| 688 WebRtcVideoDecoderFactory* external_decoder_factory) | 650 WebRtcVideoDecoderFactory* external_decoder_factory) |
| 689 : VideoMediaChannel(config), | 651 : VideoMediaChannel(config), |
| 690 call_(call), | 652 call_(call), |
| (...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1548 int max_bitrate_bps, | 1510 int max_bitrate_bps, |
| 1549 const rtc::Optional<VideoCodecSettings>& codec_settings) | 1511 const rtc::Optional<VideoCodecSettings>& codec_settings) |
| 1550 : config(std::move(config)), | 1512 : config(std::move(config)), |
| 1551 options(options), | 1513 options(options), |
| 1552 max_bitrate_bps(max_bitrate_bps), | 1514 max_bitrate_bps(max_bitrate_bps), |
| 1553 conference_mode(false), | 1515 conference_mode(false), |
| 1554 codec_settings(codec_settings) {} | 1516 codec_settings(codec_settings) {} |
| 1555 | 1517 |
| 1556 WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder::AllocatedEncoder( | 1518 WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder::AllocatedEncoder( |
| 1557 webrtc::VideoEncoder* encoder, | 1519 webrtc::VideoEncoder* encoder, |
| 1558 webrtc::VideoCodecType type, | 1520 const cricket::VideoCodec& codec, |
| 1559 bool external) | 1521 bool external) |
| 1560 : encoder(encoder), | 1522 : encoder(encoder), |
| 1561 external_encoder(nullptr), | 1523 external_encoder(nullptr), |
| 1562 type(type), | 1524 codec(codec), |
| 1563 external(external) { | 1525 external(external) { |
| 1564 if (external) { | 1526 if (external) { |
| 1565 external_encoder = encoder; | 1527 external_encoder = encoder; |
| 1566 this->encoder = | 1528 this->encoder = |
| 1567 new webrtc::VideoEncoderSoftwareFallbackWrapper(type, encoder); | 1529 new webrtc::VideoEncoderSoftwareFallbackWrapper(codec, encoder); |
| 1568 } | 1530 } |
| 1569 } | 1531 } |
| 1570 | 1532 |
| 1571 WebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( | 1533 WebRtcVideoChannel2::WebRtcVideoSendStream::WebRtcVideoSendStream( |
| 1572 webrtc::Call* call, | 1534 webrtc::Call* call, |
| 1573 const StreamParams& sp, | 1535 const StreamParams& sp, |
| 1574 webrtc::VideoSendStream::Config config, | 1536 webrtc::VideoSendStream::Config config, |
| 1575 const VideoOptions& options, | 1537 const VideoOptions& options, |
| 1576 WebRtcVideoEncoderFactory* external_encoder_factory, | 1538 WebRtcVideoEncoderFactory* external_encoder_factory, |
| 1577 bool enable_cpu_overuse_detection, | 1539 bool enable_cpu_overuse_detection, |
| 1578 int max_bitrate_bps, | 1540 int max_bitrate_bps, |
| 1579 const rtc::Optional<VideoCodecSettings>& codec_settings, | 1541 const rtc::Optional<VideoCodecSettings>& codec_settings, |
| 1580 const rtc::Optional<std::vector<webrtc::RtpExtension>>& rtp_extensions, | 1542 const rtc::Optional<std::vector<webrtc::RtpExtension>>& rtp_extensions, |
| 1581 // TODO(deadbeef): Don't duplicate information between send_params, | 1543 // TODO(deadbeef): Don't duplicate information between send_params, |
| 1582 // rtp_extensions, options, etc. | 1544 // rtp_extensions, options, etc. |
| 1583 const VideoSendParameters& send_params) | 1545 const VideoSendParameters& send_params) |
| 1584 : worker_thread_(rtc::Thread::Current()), | 1546 : worker_thread_(rtc::Thread::Current()), |
| 1585 ssrcs_(sp.ssrcs), | 1547 ssrcs_(sp.ssrcs), |
| 1586 ssrc_groups_(sp.ssrc_groups), | 1548 ssrc_groups_(sp.ssrc_groups), |
| 1587 call_(call), | 1549 call_(call), |
| 1588 enable_cpu_overuse_detection_(enable_cpu_overuse_detection), | 1550 enable_cpu_overuse_detection_(enable_cpu_overuse_detection), |
| 1589 source_(nullptr), | 1551 source_(nullptr), |
| 1590 external_encoder_factory_(external_encoder_factory), | 1552 external_encoder_factory_(external_encoder_factory), |
| 1591 stream_(nullptr), | 1553 stream_(nullptr), |
| 1592 encoder_sink_(nullptr), | 1554 encoder_sink_(nullptr), |
| 1593 parameters_(std::move(config), options, max_bitrate_bps, codec_settings), | 1555 parameters_(std::move(config), options, max_bitrate_bps, codec_settings), |
| 1594 rtp_parameters_(CreateRtpParametersWithOneEncoding()), | 1556 rtp_parameters_(CreateRtpParametersWithOneEncoding()), |
| 1595 allocated_encoder_(nullptr, webrtc::kVideoCodecUnknown, false), | 1557 allocated_encoder_(nullptr, cricket::VideoCodec(), false), |
| 1596 sending_(false), | 1558 sending_(false), |
| 1597 last_frame_timestamp_us_(0) { | 1559 last_frame_timestamp_us_(0) { |
| 1598 parameters_.config.rtp.max_packet_size = kVideoMtu; | 1560 parameters_.config.rtp.max_packet_size = kVideoMtu; |
| 1599 parameters_.conference_mode = send_params.conference_mode; | 1561 parameters_.conference_mode = send_params.conference_mode; |
| 1600 | 1562 |
| 1601 sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); | 1563 sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); |
| 1602 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, | 1564 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, |
| 1603 ¶meters_.config.rtp.rtx.ssrcs); | 1565 ¶meters_.config.rtp.rtx.ssrcs); |
| 1604 parameters_.config.rtp.c_name = sp.cname; | 1566 parameters_.config.rtp.c_name = sp.cname; |
| 1605 if (rtp_extensions) { | 1567 if (rtp_extensions) { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1720 | 1682 |
| 1721 const std::vector<uint32_t>& | 1683 const std::vector<uint32_t>& |
| 1722 WebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { | 1684 WebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { |
| 1723 return ssrcs_; | 1685 return ssrcs_; |
| 1724 } | 1686 } |
| 1725 | 1687 |
| 1726 WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder | 1688 WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder |
| 1727 WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( | 1689 WebRtcVideoChannel2::WebRtcVideoSendStream::CreateVideoEncoder( |
| 1728 const VideoCodec& codec) { | 1690 const VideoCodec& codec) { |
| 1729 RTC_DCHECK_RUN_ON(&thread_checker_); | 1691 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 1730 webrtc::VideoCodecType type = CodecTypeFromName(codec.name); | |
| 1731 | |
| 1732 // Do not re-create encoders of the same type. | 1692 // Do not re-create encoders of the same type. |
| 1733 if (type == allocated_encoder_.type && allocated_encoder_.encoder != NULL) { | 1693 if (codec == allocated_encoder_.codec && |
| 1694 allocated_encoder_.encoder != nullptr) { |
| 1734 return allocated_encoder_; | 1695 return allocated_encoder_; |
| 1735 } | 1696 } |
| 1736 | 1697 |
| 1737 if (external_encoder_factory_ != NULL) { | 1698 // Try creating external encoder. |
| 1699 if (external_encoder_factory_ != nullptr && |
| 1700 FindMatchingCodec(external_encoder_factory_->supported_codecs(), codec)) { |
| 1738 webrtc::VideoEncoder* encoder = | 1701 webrtc::VideoEncoder* encoder = |
| 1739 external_encoder_factory_->CreateVideoEncoder(codec); | 1702 external_encoder_factory_->CreateVideoEncoder(codec); |
| 1740 if (encoder != NULL) { | 1703 if (encoder != nullptr) |
| 1741 return AllocatedEncoder(encoder, type, true); | 1704 return AllocatedEncoder(encoder, codec, true /* is_external */); |
| 1742 } | |
| 1743 } | 1705 } |
| 1744 | 1706 |
| 1745 if (type == webrtc::kVideoCodecVP8) { | 1707 // Try creating internal encoder. |
| 1746 return AllocatedEncoder( | 1708 WebRtcVideoEncoderFactory& internal_encoder_factory = |
| 1747 webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp8), type, false); | 1709 InternalEncoderFactory::GetInstance(); |
| 1748 } else if (type == webrtc::kVideoCodecVP9) { | 1710 if (FindMatchingCodec(internal_encoder_factory.supported_codecs(), codec)) { |
| 1749 return AllocatedEncoder( | 1711 return AllocatedEncoder(internal_encoder_factory.CreateVideoEncoder(codec), |
| 1750 webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kVp9), type, false); | 1712 codec, false /* is_external */); |
| 1751 } else if (type == webrtc::kVideoCodecH264) { | |
| 1752 return AllocatedEncoder( | |
| 1753 webrtc::VideoEncoder::Create(webrtc::VideoEncoder::kH264), type, false); | |
| 1754 } | 1713 } |
| 1755 | 1714 |
| 1756 // This shouldn't happen, we should not be trying to create something we don't | 1715 // This shouldn't happen, we should not be trying to create something we don't |
| 1757 // support. | 1716 // support. |
| 1758 RTC_DCHECK(false); | 1717 RTC_DCHECK(false); |
| 1759 return AllocatedEncoder(NULL, webrtc::kVideoCodecUnknown, false); | 1718 return AllocatedEncoder(NULL, cricket::VideoCodec(), false); |
| 1760 } | 1719 } |
| 1761 | 1720 |
| 1762 void WebRtcVideoChannel2::WebRtcVideoSendStream::DestroyVideoEncoder( | 1721 void WebRtcVideoChannel2::WebRtcVideoSendStream::DestroyVideoEncoder( |
| 1763 AllocatedEncoder* encoder) { | 1722 AllocatedEncoder* encoder) { |
| 1764 RTC_DCHECK_RUN_ON(&thread_checker_); | 1723 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 1765 if (encoder->external) { | 1724 if (encoder->external) { |
| 1766 external_encoder_factory_->DestroyVideoEncoder(encoder->external_encoder); | 1725 external_encoder_factory_->DestroyVideoEncoder(encoder->external_encoder); |
| 1767 } | 1726 } |
| 1768 delete encoder->encoder; | 1727 delete encoder->encoder; |
| 1769 } | 1728 } |
| (...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2590 rtx_mapping[video_codecs[i].codec.id] != | 2549 rtx_mapping[video_codecs[i].codec.id] != |
| 2591 ulpfec_config.red_payload_type) { | 2550 ulpfec_config.red_payload_type) { |
| 2592 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; | 2551 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; |
| 2593 } | 2552 } |
| 2594 } | 2553 } |
| 2595 | 2554 |
| 2596 return video_codecs; | 2555 return video_codecs; |
| 2597 } | 2556 } |
| 2598 | 2557 |
| 2599 } // namespace cricket | 2558 } // namespace cricket |
| OLD | NEW |