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/webrtcvideoengine.h" | 11 #include "webrtc/media/engine/webrtcvideoengine.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/api/video/i420_buffer.h" | 19 #include "webrtc/api/video/i420_buffer.h" |
20 #include "webrtc/api/video_codecs/video_decoder.h" | 20 #include "webrtc/api/video_codecs/video_decoder.h" |
21 #include "webrtc/api/video_codecs/video_encoder.h" | 21 #include "webrtc/api/video_codecs/video_encoder.h" |
22 #include "webrtc/call/call.h" | 22 #include "webrtc/call/call.h" |
23 #include "webrtc/common_video/h264/profile_level_id.h" | 23 #include "webrtc/common_video/h264/profile_level_id.h" |
24 #include "webrtc/media/engine/constants.h" | 24 #include "webrtc/media/engine/constants.h" |
25 #include "webrtc/media/engine/internaldecoderfactory.h" | 25 #include "webrtc/media/engine/internaldecoderfactory.h" |
26 #include "webrtc/media/engine/internalencoderfactory.h" | 26 #include "webrtc/media/engine/internalencoderfactory.h" |
| 27 #include "webrtc/media/engine/scopedvideoencoder.h" |
27 #include "webrtc/media/engine/simulcast.h" | 28 #include "webrtc/media/engine/simulcast.h" |
28 #include "webrtc/media/engine/simulcast_encoder_adapter.h" | 29 #include "webrtc/media/engine/simulcast_encoder_adapter.h" |
29 #include "webrtc/media/engine/videodecodersoftwarefallbackwrapper.h" | 30 #include "webrtc/media/engine/videodecodersoftwarefallbackwrapper.h" |
30 #include "webrtc/media/engine/videoencodersoftwarefallbackwrapper.h" | 31 #include "webrtc/media/engine/videoencodersoftwarefallbackwrapper.h" |
31 #include "webrtc/media/engine/webrtcmediaengine.h" | 32 #include "webrtc/media/engine/webrtcmediaengine.h" |
32 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" | 33 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" |
33 #include "webrtc/media/engine/webrtcvoiceengine.h" | 34 #include "webrtc/media/engine/webrtcvoiceengine.h" |
34 #include "webrtc/rtc_base/copyonwritebuffer.h" | 35 #include "webrtc/rtc_base/copyonwritebuffer.h" |
35 #include "webrtc/rtc_base/logging.h" | 36 #include "webrtc/rtc_base/logging.h" |
36 #include "webrtc/rtc_base/stringutils.h" | 37 #include "webrtc/rtc_base/stringutils.h" |
(...skipping 11 matching lines...) Expand all Loading... |
48 return webrtc::field_trial::IsEnabled("WebRTC-FlexFEC-03"); | 49 return webrtc::field_trial::IsEnabled("WebRTC-FlexFEC-03"); |
49 } | 50 } |
50 | 51 |
51 // If this field trial is enabled, the "flexfec-03" codec may have been | 52 // If this field trial is enabled, the "flexfec-03" codec may have been |
52 // advertised as being supported in the local SDP. That means that we must be | 53 // advertised as being supported in the local SDP. That means that we must be |
53 // ready to receive FlexFEC packets. See internalencoderfactory.cc. | 54 // ready to receive FlexFEC packets. See internalencoderfactory.cc. |
54 bool IsFlexfecAdvertisedFieldTrialEnabled() { | 55 bool IsFlexfecAdvertisedFieldTrialEnabled() { |
55 return webrtc::field_trial::IsEnabled("WebRTC-FlexFEC-03-Advertised"); | 56 return webrtc::field_trial::IsEnabled("WebRTC-FlexFEC-03-Advertised"); |
56 } | 57 } |
57 | 58 |
58 // An encoder factory that wraps Create requests for simulcastable codec types | |
59 // with a webrtc::SimulcastEncoderAdapter. Non simulcastable codec type | |
60 // requests are just passed through to the contained encoder factory. | |
61 class WebRtcSimulcastEncoderFactory | |
62 : public cricket::WebRtcVideoEncoderFactory { | |
63 public: | |
64 // WebRtcSimulcastEncoderFactory doesn't take ownership of |factory|, which is | |
65 // owned by e.g. PeerConnectionFactory. | |
66 explicit WebRtcSimulcastEncoderFactory( | |
67 cricket::WebRtcVideoEncoderFactory* factory) | |
68 : factory_(factory) {} | |
69 | |
70 static bool UseSimulcastEncoderFactory( | |
71 const std::vector<cricket::VideoCodec>& codecs) { | |
72 // If any codec is VP8, use the simulcast factory. If asked to create a | |
73 // non-VP8 codec, we'll just return a contained factory encoder directly. | |
74 for (const auto& codec : codecs) { | |
75 if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) { | |
76 return true; | |
77 } | |
78 } | |
79 return false; | |
80 } | |
81 | |
82 webrtc::VideoEncoder* CreateVideoEncoder( | |
83 const cricket::VideoCodec& codec) override { | |
84 RTC_DCHECK(factory_ != NULL); | |
85 // If it's a codec type we can simulcast, create a wrapped encoder. | |
86 if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) { | |
87 return new webrtc::SimulcastEncoderAdapter(factory_); | |
88 } | |
89 webrtc::VideoEncoder* encoder = factory_->CreateVideoEncoder(codec); | |
90 if (encoder) { | |
91 non_simulcast_encoders_.push_back(encoder); | |
92 } | |
93 return encoder; | |
94 } | |
95 | |
96 const std::vector<cricket::VideoCodec>& supported_codecs() const override { | |
97 return factory_->supported_codecs(); | |
98 } | |
99 | |
100 bool EncoderTypeHasInternalSource( | |
101 webrtc::VideoCodecType type) const override { | |
102 return factory_->EncoderTypeHasInternalSource(type); | |
103 } | |
104 | |
105 void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override { | |
106 // Check first to see if the encoder wasn't wrapped in a | |
107 // SimulcastEncoderAdapter. In that case, ask the factory to destroy it. | |
108 if (std::remove(non_simulcast_encoders_.begin(), | |
109 non_simulcast_encoders_.end(), | |
110 encoder) != non_simulcast_encoders_.end()) { | |
111 factory_->DestroyVideoEncoder(encoder); | |
112 return; | |
113 } | |
114 | |
115 // Otherwise, SimulcastEncoderAdapter can be deleted directly, and will call | |
116 // DestroyVideoEncoder on the factory for individual encoder instances. | |
117 delete encoder; | |
118 } | |
119 | |
120 private: | |
121 cricket::WebRtcVideoEncoderFactory* factory_; | |
122 // A list of encoders that were created without being wrapped in a | |
123 // SimulcastEncoderAdapter. | |
124 std::vector<webrtc::VideoEncoder*> non_simulcast_encoders_; | |
125 }; | |
126 | |
127 void AddDefaultFeedbackParams(VideoCodec* codec) { | 59 void AddDefaultFeedbackParams(VideoCodec* codec) { |
128 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamCcm, kRtcpFbCcmParamFir)); | 60 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamCcm, kRtcpFbCcmParamFir)); |
129 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); | 61 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kParamValueEmpty)); |
130 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kRtcpFbNackParamPli)); | 62 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamNack, kRtcpFbNackParamPli)); |
131 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); | 63 codec->AddFeedbackParam(FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty)); |
132 codec->AddFeedbackParam( | 64 codec->AddFeedbackParam( |
133 FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty)); | 65 FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty)); |
134 } | 66 } |
135 | 67 |
136 static std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) { | 68 static std::string CodecVectorToString(const std::vector<VideoCodec>& codecs) { |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 | 366 |
435 void WebRtcVideoEngine::SetExternalDecoderFactory( | 367 void WebRtcVideoEngine::SetExternalDecoderFactory( |
436 WebRtcVideoDecoderFactory* decoder_factory) { | 368 WebRtcVideoDecoderFactory* decoder_factory) { |
437 RTC_DCHECK(!initialized_); | 369 RTC_DCHECK(!initialized_); |
438 external_decoder_factory_ = decoder_factory; | 370 external_decoder_factory_ = decoder_factory; |
439 } | 371 } |
440 | 372 |
441 void WebRtcVideoEngine::SetExternalEncoderFactory( | 373 void WebRtcVideoEngine::SetExternalEncoderFactory( |
442 WebRtcVideoEncoderFactory* encoder_factory) { | 374 WebRtcVideoEncoderFactory* encoder_factory) { |
443 RTC_DCHECK(!initialized_); | 375 RTC_DCHECK(!initialized_); |
444 if (external_encoder_factory_ == encoder_factory) | |
445 return; | |
446 | |
447 // No matter what happens we shouldn't hold on to a stale | |
448 // WebRtcSimulcastEncoderFactory. | |
449 simulcast_encoder_factory_.reset(); | |
450 | |
451 if (encoder_factory && | |
452 WebRtcSimulcastEncoderFactory::UseSimulcastEncoderFactory( | |
453 encoder_factory->supported_codecs())) { | |
454 simulcast_encoder_factory_.reset( | |
455 new WebRtcSimulcastEncoderFactory(encoder_factory)); | |
456 encoder_factory = simulcast_encoder_factory_.get(); | |
457 } | |
458 external_encoder_factory_ = encoder_factory; | 376 external_encoder_factory_ = encoder_factory; |
459 } | 377 } |
460 | 378 |
461 // This is a helper function for AppendVideoCodecs below. It will return the | 379 // This is a helper function for AppendVideoCodecs below. It will return the |
462 // first unused dynamic payload type (in the range [96, 127]), or nothing if no | 380 // first unused dynamic payload type (in the range [96, 127]), or nothing if no |
463 // payload type is unused. | 381 // payload type is unused. |
464 static rtc::Optional<int> NextFreePayloadType( | 382 static rtc::Optional<int> NextFreePayloadType( |
465 const std::vector<VideoCodec>& codecs) { | 383 const std::vector<VideoCodec>& codecs) { |
466 static const int kFirstDynamicPayloadType = 96; | 384 static const int kFirstDynamicPayloadType = 96; |
467 static const int kLastDynamicPayloadType = 127; | 385 static const int kLastDynamicPayloadType = 127; |
(...skipping 1021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1489 const VideoOptions& options, | 1407 const VideoOptions& options, |
1490 int max_bitrate_bps, | 1408 int max_bitrate_bps, |
1491 const rtc::Optional<VideoCodecSettings>& codec_settings) | 1409 const rtc::Optional<VideoCodecSettings>& codec_settings) |
1492 : config(std::move(config)), | 1410 : config(std::move(config)), |
1493 options(options), | 1411 options(options), |
1494 max_bitrate_bps(max_bitrate_bps), | 1412 max_bitrate_bps(max_bitrate_bps), |
1495 conference_mode(false), | 1413 conference_mode(false), |
1496 codec_settings(codec_settings) {} | 1414 codec_settings(codec_settings) {} |
1497 | 1415 |
1498 WebRtcVideoChannel::WebRtcVideoSendStream::AllocatedEncoder::AllocatedEncoder( | 1416 WebRtcVideoChannel::WebRtcVideoSendStream::AllocatedEncoder::AllocatedEncoder( |
1499 webrtc::VideoEncoder* encoder, | 1417 std::unique_ptr<webrtc::VideoEncoder> encoder, |
| 1418 std::unique_ptr<webrtc::VideoEncoder> external_encoder, |
1500 const cricket::VideoCodec& codec, | 1419 const cricket::VideoCodec& codec, |
1501 bool external) | 1420 bool has_internal_source) |
1502 : encoder(encoder), | 1421 : encoder_(std::move(encoder)), |
1503 external_encoder(nullptr), | 1422 external_encoder_(std::move(external_encoder)), |
1504 codec(codec), | 1423 codec_(codec), |
1505 external(external) { | 1424 has_internal_source_(has_internal_source) {} |
1506 if (external) { | 1425 |
1507 external_encoder = encoder; | 1426 void WebRtcVideoChannel::WebRtcVideoSendStream::AllocatedEncoder::Reset() { |
1508 this->encoder = | 1427 external_encoder_.reset(); |
1509 new webrtc::VideoEncoderSoftwareFallbackWrapper(codec, encoder); | 1428 encoder_.reset(); |
1510 } | 1429 codec_ = cricket::VideoCodec(); |
1511 } | 1430 } |
1512 | 1431 |
1513 WebRtcVideoChannel::WebRtcVideoSendStream::WebRtcVideoSendStream( | 1432 WebRtcVideoChannel::WebRtcVideoSendStream::WebRtcVideoSendStream( |
1514 webrtc::Call* call, | 1433 webrtc::Call* call, |
1515 const StreamParams& sp, | 1434 const StreamParams& sp, |
1516 webrtc::VideoSendStream::Config config, | 1435 webrtc::VideoSendStream::Config config, |
1517 const VideoOptions& options, | 1436 const VideoOptions& options, |
1518 WebRtcVideoEncoderFactory* external_encoder_factory, | 1437 WebRtcVideoEncoderFactory* external_encoder_factory, |
1519 bool enable_cpu_overuse_detection, | 1438 bool enable_cpu_overuse_detection, |
1520 int max_bitrate_bps, | 1439 int max_bitrate_bps, |
1521 const rtc::Optional<VideoCodecSettings>& codec_settings, | 1440 const rtc::Optional<VideoCodecSettings>& codec_settings, |
1522 const rtc::Optional<std::vector<webrtc::RtpExtension>>& rtp_extensions, | 1441 const rtc::Optional<std::vector<webrtc::RtpExtension>>& rtp_extensions, |
1523 // TODO(deadbeef): Don't duplicate information between send_params, | 1442 // TODO(deadbeef): Don't duplicate information between send_params, |
1524 // rtp_extensions, options, etc. | 1443 // rtp_extensions, options, etc. |
1525 const VideoSendParameters& send_params) | 1444 const VideoSendParameters& send_params) |
1526 : worker_thread_(rtc::Thread::Current()), | 1445 : worker_thread_(rtc::Thread::Current()), |
1527 ssrcs_(sp.ssrcs), | 1446 ssrcs_(sp.ssrcs), |
1528 ssrc_groups_(sp.ssrc_groups), | 1447 ssrc_groups_(sp.ssrc_groups), |
1529 call_(call), | 1448 call_(call), |
1530 enable_cpu_overuse_detection_(enable_cpu_overuse_detection), | 1449 enable_cpu_overuse_detection_(enable_cpu_overuse_detection), |
1531 source_(nullptr), | 1450 source_(nullptr), |
1532 external_encoder_factory_(external_encoder_factory), | 1451 external_encoder_factory_(external_encoder_factory), |
1533 internal_encoder_factory_(new InternalEncoderFactory()), | 1452 internal_encoder_factory_(new InternalEncoderFactory()), |
1534 stream_(nullptr), | 1453 stream_(nullptr), |
1535 encoder_sink_(nullptr), | 1454 encoder_sink_(nullptr), |
1536 parameters_(std::move(config), options, max_bitrate_bps, codec_settings), | 1455 parameters_(std::move(config), options, max_bitrate_bps, codec_settings), |
1537 rtp_parameters_(CreateRtpParametersWithOneEncoding()), | 1456 rtp_parameters_(CreateRtpParametersWithOneEncoding()), |
1538 allocated_encoder_(nullptr, cricket::VideoCodec(), false), | |
1539 sending_(false) { | 1457 sending_(false) { |
1540 parameters_.config.rtp.max_packet_size = kVideoMtu; | 1458 parameters_.config.rtp.max_packet_size = kVideoMtu; |
1541 parameters_.conference_mode = send_params.conference_mode; | 1459 parameters_.conference_mode = send_params.conference_mode; |
1542 | 1460 |
1543 sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); | 1461 sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); |
1544 | 1462 |
1545 // ValidateStreamParams should prevent this from happening. | 1463 // ValidateStreamParams should prevent this from happening. |
1546 RTC_CHECK(!parameters_.config.rtp.ssrcs.empty()); | 1464 RTC_CHECK(!parameters_.config.rtp.ssrcs.empty()); |
1547 rtp_parameters_.encodings[0].ssrc = | 1465 rtp_parameters_.encodings[0].ssrc = |
1548 rtc::Optional<uint32_t>(parameters_.config.rtp.ssrcs[0]); | 1466 rtc::Optional<uint32_t>(parameters_.config.rtp.ssrcs[0]); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1585 if (codec_settings) { | 1503 if (codec_settings) { |
1586 bool force_encoder_allocation = false; | 1504 bool force_encoder_allocation = false; |
1587 SetCodec(*codec_settings, force_encoder_allocation); | 1505 SetCodec(*codec_settings, force_encoder_allocation); |
1588 } | 1506 } |
1589 } | 1507 } |
1590 | 1508 |
1591 WebRtcVideoChannel::WebRtcVideoSendStream::~WebRtcVideoSendStream() { | 1509 WebRtcVideoChannel::WebRtcVideoSendStream::~WebRtcVideoSendStream() { |
1592 if (stream_ != NULL) { | 1510 if (stream_ != NULL) { |
1593 call_->DestroyVideoSendStream(stream_); | 1511 call_->DestroyVideoSendStream(stream_); |
1594 } | 1512 } |
1595 DestroyVideoEncoder(&allocated_encoder_); | 1513 // Release |allocated_encoder_|. |
| 1514 allocated_encoder_.Reset(); |
1596 } | 1515 } |
1597 | 1516 |
1598 bool WebRtcVideoChannel::WebRtcVideoSendStream::SetVideoSend( | 1517 bool WebRtcVideoChannel::WebRtcVideoSendStream::SetVideoSend( |
1599 bool enable, | 1518 bool enable, |
1600 const VideoOptions* options, | 1519 const VideoOptions* options, |
1601 rtc::VideoSourceInterface<webrtc::VideoFrame>* source) { | 1520 rtc::VideoSourceInterface<webrtc::VideoFrame>* source) { |
1602 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetVideoSend"); | 1521 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetVideoSend"); |
1603 RTC_DCHECK_RUN_ON(&thread_checker_); | 1522 RTC_DCHECK_RUN_ON(&thread_checker_); |
1604 | 1523 |
1605 // Ignore |options| pointer if |enable| is false. | 1524 // Ignore |options| pointer if |enable| is false. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1658 return degradation_preference; | 1577 return degradation_preference; |
1659 } | 1578 } |
1660 | 1579 |
1661 const std::vector<uint32_t>& | 1580 const std::vector<uint32_t>& |
1662 WebRtcVideoChannel::WebRtcVideoSendStream::GetSsrcs() const { | 1581 WebRtcVideoChannel::WebRtcVideoSendStream::GetSsrcs() const { |
1663 return ssrcs_; | 1582 return ssrcs_; |
1664 } | 1583 } |
1665 | 1584 |
1666 WebRtcVideoChannel::WebRtcVideoSendStream::AllocatedEncoder | 1585 WebRtcVideoChannel::WebRtcVideoSendStream::AllocatedEncoder |
1667 WebRtcVideoChannel::WebRtcVideoSendStream::CreateVideoEncoder( | 1586 WebRtcVideoChannel::WebRtcVideoSendStream::CreateVideoEncoder( |
1668 const VideoCodec& codec, | 1587 const VideoCodec& codec) { |
1669 bool force_encoder_allocation) { | |
1670 RTC_DCHECK_RUN_ON(&thread_checker_); | 1588 RTC_DCHECK_RUN_ON(&thread_checker_); |
1671 // Do not re-create encoders of the same type. | |
1672 if (!force_encoder_allocation && codec == allocated_encoder_.codec && | |
1673 allocated_encoder_.encoder != nullptr) { | |
1674 return allocated_encoder_; | |
1675 } | |
1676 | 1589 |
1677 // Try creating external encoder. | 1590 // Try creating external encoder. |
1678 if (external_encoder_factory_ != nullptr && | 1591 if (external_encoder_factory_ != nullptr && |
1679 FindMatchingCodec(external_encoder_factory_->supported_codecs(), codec)) { | 1592 FindMatchingCodec(external_encoder_factory_->supported_codecs(), codec)) { |
1680 webrtc::VideoEncoder* encoder = | 1593 std::unique_ptr<webrtc::VideoEncoder> external_encoder; |
1681 external_encoder_factory_->CreateVideoEncoder(codec); | 1594 if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) { |
1682 if (encoder != nullptr) | 1595 // If it's a codec type we can simulcast, create a wrapped encoder. |
1683 return AllocatedEncoder(encoder, codec, true /* is_external */); | 1596 external_encoder = std::unique_ptr<webrtc::VideoEncoder>( |
| 1597 new webrtc::SimulcastEncoderAdapter(external_encoder_factory_)); |
| 1598 } else { |
| 1599 external_encoder = |
| 1600 CreateScopedVideoEncoder(external_encoder_factory_, codec); |
| 1601 } |
| 1602 if (external_encoder) { |
| 1603 std::unique_ptr<webrtc::VideoEncoder> internal_encoder( |
| 1604 new webrtc::VideoEncoderSoftwareFallbackWrapper( |
| 1605 codec, external_encoder.get())); |
| 1606 const webrtc::VideoCodecType codec_type = |
| 1607 webrtc::PayloadStringToCodecType(codec.name); |
| 1608 const bool has_internal_source = |
| 1609 external_encoder_factory_->EncoderTypeHasInternalSource(codec_type); |
| 1610 return AllocatedEncoder(std::move(internal_encoder), |
| 1611 std::move(external_encoder), codec, |
| 1612 has_internal_source); |
| 1613 } |
1684 } | 1614 } |
1685 | 1615 |
1686 // Try creating internal encoder. | 1616 // Try creating internal encoder. |
| 1617 std::unique_ptr<webrtc::VideoEncoder> internal_encoder; |
1687 if (FindMatchingCodec(internal_encoder_factory_->supported_codecs(), codec)) { | 1618 if (FindMatchingCodec(internal_encoder_factory_->supported_codecs(), codec)) { |
1688 if (parameters_.encoder_config.content_type == | 1619 if (CodecNamesEq(codec.name.c_str(), kVp8CodecName) && |
| 1620 parameters_.encoder_config.content_type == |
1689 webrtc::VideoEncoderConfig::ContentType::kScreen && | 1621 webrtc::VideoEncoderConfig::ContentType::kScreen && |
1690 parameters_.conference_mode && UseSimulcastScreenshare()) { | 1622 parameters_.conference_mode && UseSimulcastScreenshare()) { |
1691 // TODO(sprang): Remove this adapter once libvpx supports simulcast with | 1623 // TODO(sprang): Remove this adapter once libvpx supports simulcast with |
1692 // same-resolution substreams. | 1624 // same-resolution substreams. |
1693 WebRtcSimulcastEncoderFactory adapter_factory( | 1625 internal_encoder = std::unique_ptr<webrtc::VideoEncoder>( |
1694 internal_encoder_factory_.get()); | 1626 new webrtc::SimulcastEncoderAdapter(internal_encoder_factory_.get())); |
1695 return AllocatedEncoder(adapter_factory.CreateVideoEncoder(codec), codec, | 1627 } else { |
1696 false /* is_external */); | 1628 internal_encoder = std::unique_ptr<webrtc::VideoEncoder>( |
| 1629 internal_encoder_factory_->CreateVideoEncoder(codec)); |
1697 } | 1630 } |
1698 return AllocatedEncoder( | 1631 return AllocatedEncoder(std::move(internal_encoder), |
1699 internal_encoder_factory_->CreateVideoEncoder(codec), codec, | 1632 nullptr /* external_encoder */, codec, |
1700 false /* is_external */); | 1633 false /* has_internal_source */); |
1701 } | 1634 } |
1702 | 1635 |
1703 // This shouldn't happen, we should not be trying to create something we don't | 1636 // This shouldn't happen, we should not be trying to create something we don't |
1704 // support. | 1637 // support. |
1705 RTC_NOTREACHED(); | 1638 RTC_NOTREACHED(); |
1706 return AllocatedEncoder(NULL, cricket::VideoCodec(), false); | 1639 return AllocatedEncoder(); |
1707 } | |
1708 | |
1709 void WebRtcVideoChannel::WebRtcVideoSendStream::DestroyVideoEncoder( | |
1710 AllocatedEncoder* encoder) { | |
1711 RTC_DCHECK_RUN_ON(&thread_checker_); | |
1712 if (encoder->external) { | |
1713 external_encoder_factory_->DestroyVideoEncoder(encoder->external_encoder); | |
1714 } | |
1715 delete encoder->encoder; | |
1716 } | 1640 } |
1717 | 1641 |
1718 void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec( | 1642 void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec( |
1719 const VideoCodecSettings& codec_settings, | 1643 const VideoCodecSettings& codec_settings, |
1720 bool force_encoder_allocation) { | 1644 bool force_encoder_allocation) { |
1721 RTC_DCHECK_RUN_ON(&thread_checker_); | 1645 RTC_DCHECK_RUN_ON(&thread_checker_); |
1722 parameters_.encoder_config = CreateVideoEncoderConfig(codec_settings.codec); | 1646 parameters_.encoder_config = CreateVideoEncoderConfig(codec_settings.codec); |
1723 RTC_DCHECK_GT(parameters_.encoder_config.number_of_streams, 0); | 1647 RTC_DCHECK_GT(parameters_.encoder_config.number_of_streams, 0); |
1724 | 1648 |
1725 AllocatedEncoder new_encoder = | 1649 // Do not re-create encoders of the same type. We can't overwrite |
1726 CreateVideoEncoder(codec_settings.codec, force_encoder_allocation); | 1650 // |allocated_encoder_| immediately, because we need to release it after the |
1727 parameters_.config.encoder_settings.encoder = new_encoder.encoder; | 1651 // RecreateWebRtcStream() call. |
1728 parameters_.config.encoder_settings.full_overuse_time = new_encoder.external; | 1652 AllocatedEncoder new_encoder; |
| 1653 if (force_encoder_allocation || !allocated_encoder_.encoder() || |
| 1654 allocated_encoder_.codec() != codec_settings.codec) { |
| 1655 new_encoder = CreateVideoEncoder(codec_settings.codec); |
| 1656 } else { |
| 1657 new_encoder = std::move(allocated_encoder_); |
| 1658 } |
| 1659 parameters_.config.encoder_settings.encoder = new_encoder.encoder(); |
| 1660 parameters_.config.encoder_settings.full_overuse_time = |
| 1661 new_encoder.IsExternal(); |
1729 parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; | 1662 parameters_.config.encoder_settings.payload_name = codec_settings.codec.name; |
1730 parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; | 1663 parameters_.config.encoder_settings.payload_type = codec_settings.codec.id; |
1731 if (new_encoder.external) { | 1664 parameters_.config.encoder_settings.internal_source = |
1732 webrtc::VideoCodecType type = | 1665 new_encoder.HasInternalSource(); |
1733 webrtc::PayloadStringToCodecType(codec_settings.codec.name); | |
1734 parameters_.config.encoder_settings.internal_source = | |
1735 external_encoder_factory_->EncoderTypeHasInternalSource(type); | |
1736 } else { | |
1737 parameters_.config.encoder_settings.internal_source = false; | |
1738 } | |
1739 parameters_.config.rtp.ulpfec = codec_settings.ulpfec; | 1666 parameters_.config.rtp.ulpfec = codec_settings.ulpfec; |
1740 parameters_.config.rtp.flexfec.payload_type = | 1667 parameters_.config.rtp.flexfec.payload_type = |
1741 codec_settings.flexfec_payload_type; | 1668 codec_settings.flexfec_payload_type; |
1742 | 1669 |
1743 // Set RTX payload type if RTX is enabled. | 1670 // Set RTX payload type if RTX is enabled. |
1744 if (!parameters_.config.rtp.rtx.ssrcs.empty()) { | 1671 if (!parameters_.config.rtp.rtx.ssrcs.empty()) { |
1745 if (codec_settings.rtx_payload_type == -1) { | 1672 if (codec_settings.rtx_payload_type == -1) { |
1746 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " | 1673 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " |
1747 "payload type. Ignoring."; | 1674 "payload type. Ignoring."; |
1748 parameters_.config.rtp.rtx.ssrcs.clear(); | 1675 parameters_.config.rtp.rtx.ssrcs.clear(); |
1749 } else { | 1676 } else { |
1750 parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; | 1677 parameters_.config.rtp.rtx.payload_type = codec_settings.rtx_payload_type; |
1751 } | 1678 } |
1752 } | 1679 } |
1753 | 1680 |
1754 parameters_.config.rtp.nack.rtp_history_ms = | 1681 parameters_.config.rtp.nack.rtp_history_ms = |
1755 HasNack(codec_settings.codec) ? kNackHistoryMs : 0; | 1682 HasNack(codec_settings.codec) ? kNackHistoryMs : 0; |
1756 | 1683 |
1757 parameters_.codec_settings = | 1684 parameters_.codec_settings = |
1758 rtc::Optional<WebRtcVideoChannel::VideoCodecSettings>(codec_settings); | 1685 rtc::Optional<WebRtcVideoChannel::VideoCodecSettings>(codec_settings); |
1759 | 1686 |
1760 LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetCodec."; | 1687 LOG(LS_INFO) << "RecreateWebRtcStream (send) because of SetCodec."; |
1761 RecreateWebRtcStream(); | 1688 RecreateWebRtcStream(); |
1762 if (allocated_encoder_.encoder != new_encoder.encoder) { | 1689 allocated_encoder_ = std::move(new_encoder); |
1763 DestroyVideoEncoder(&allocated_encoder_); | |
1764 allocated_encoder_ = new_encoder; | |
1765 } | |
1766 } | 1690 } |
1767 | 1691 |
1768 void WebRtcVideoChannel::WebRtcVideoSendStream::SetSendParameters( | 1692 void WebRtcVideoChannel::WebRtcVideoSendStream::SetSendParameters( |
1769 const ChangedSendParameters& params) { | 1693 const ChangedSendParameters& params) { |
1770 RTC_DCHECK_RUN_ON(&thread_checker_); | 1694 RTC_DCHECK_RUN_ON(&thread_checker_); |
1771 // |recreate_stream| means construction-time parameters have changed and the | 1695 // |recreate_stream| means construction-time parameters have changed and the |
1772 // sending stream needs to be reset with the new config. | 1696 // sending stream needs to be reset with the new config. |
1773 bool recreate_stream = false; | 1697 bool recreate_stream = false; |
1774 if (params.rtcp_mode) { | 1698 if (params.rtcp_mode) { |
1775 parameters_.config.rtp.rtcp_mode = *params.rtcp_mode; | 1699 parameters_.config.rtp.rtcp_mode = *params.rtcp_mode; |
(...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2649 stream.temporal_layer_thresholds_bps.resize(GetDefaultVp9TemporalLayers() - | 2573 stream.temporal_layer_thresholds_bps.resize(GetDefaultVp9TemporalLayers() - |
2650 1); | 2574 1); |
2651 } | 2575 } |
2652 | 2576 |
2653 std::vector<webrtc::VideoStream> streams; | 2577 std::vector<webrtc::VideoStream> streams; |
2654 streams.push_back(stream); | 2578 streams.push_back(stream); |
2655 return streams; | 2579 return streams; |
2656 } | 2580 } |
2657 | 2581 |
2658 } // namespace cricket | 2582 } // namespace cricket |
OLD | NEW |