| 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 1535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1546 ssrc_groups_(sp.ssrc_groups), | 1546 ssrc_groups_(sp.ssrc_groups), |
| 1547 call_(call), | 1547 call_(call), |
| 1548 enable_cpu_overuse_detection_(enable_cpu_overuse_detection), | 1548 enable_cpu_overuse_detection_(enable_cpu_overuse_detection), |
| 1549 source_(nullptr), | 1549 source_(nullptr), |
| 1550 external_encoder_factory_(external_encoder_factory), | 1550 external_encoder_factory_(external_encoder_factory), |
| 1551 stream_(nullptr), | 1551 stream_(nullptr), |
| 1552 encoder_sink_(nullptr), | 1552 encoder_sink_(nullptr), |
| 1553 parameters_(std::move(config), options, max_bitrate_bps, codec_settings), | 1553 parameters_(std::move(config), options, max_bitrate_bps, codec_settings), |
| 1554 rtp_parameters_(CreateRtpParametersWithOneEncoding()), | 1554 rtp_parameters_(CreateRtpParametersWithOneEncoding()), |
| 1555 allocated_encoder_(nullptr, cricket::VideoCodec(), false), | 1555 allocated_encoder_(nullptr, cricket::VideoCodec(), false), |
| 1556 sending_(false), | 1556 sending_(false) { |
| 1557 last_frame_timestamp_us_(0) { | |
| 1558 parameters_.config.rtp.max_packet_size = kVideoMtu; | 1557 parameters_.config.rtp.max_packet_size = kVideoMtu; |
| 1559 parameters_.conference_mode = send_params.conference_mode; | 1558 parameters_.conference_mode = send_params.conference_mode; |
| 1560 | 1559 |
| 1561 sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); | 1560 sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); |
| 1562 | 1561 |
| 1563 // ValidateStreamParams should prevent this from happening. | 1562 // ValidateStreamParams should prevent this from happening. |
| 1564 RTC_CHECK(!parameters_.config.rtp.ssrcs.empty()); | 1563 RTC_CHECK(!parameters_.config.rtp.ssrcs.empty()); |
| 1565 rtp_parameters_.encodings[0].ssrc = | 1564 rtp_parameters_.encodings[0].ssrc = |
| 1566 rtc::Optional<uint32_t>(parameters_.config.rtp.ssrcs[0]); | 1565 rtc::Optional<uint32_t>(parameters_.config.rtp.ssrcs[0]); |
| 1567 | 1566 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1605 } | 1604 } |
| 1606 } | 1605 } |
| 1607 | 1606 |
| 1608 WebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { | 1607 WebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { |
| 1609 if (stream_ != NULL) { | 1608 if (stream_ != NULL) { |
| 1610 call_->DestroyVideoSendStream(stream_); | 1609 call_->DestroyVideoSendStream(stream_); |
| 1611 } | 1610 } |
| 1612 DestroyVideoEncoder(&allocated_encoder_); | 1611 DestroyVideoEncoder(&allocated_encoder_); |
| 1613 } | 1612 } |
| 1614 | 1613 |
| 1615 void WebRtcVideoChannel2::WebRtcVideoSendStream::OnFrame( | |
| 1616 const webrtc::VideoFrame& frame) { | |
| 1617 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::OnFrame"); | |
| 1618 webrtc::VideoFrame video_frame(frame.video_frame_buffer(), | |
| 1619 frame.rotation(), | |
| 1620 frame.timestamp_us()); | |
| 1621 | |
| 1622 rtc::CritScope cs(&lock_); | |
| 1623 | |
| 1624 if (video_frame.width() != last_frame_info_.width || | |
| 1625 video_frame.height() != last_frame_info_.height || | |
| 1626 video_frame.rotation() != last_frame_info_.rotation || | |
| 1627 video_frame.is_texture() != last_frame_info_.is_texture) { | |
| 1628 last_frame_info_.width = video_frame.width(); | |
| 1629 last_frame_info_.height = video_frame.height(); | |
| 1630 last_frame_info_.rotation = video_frame.rotation(); | |
| 1631 last_frame_info_.is_texture = video_frame.is_texture(); | |
| 1632 | |
| 1633 LOG(LS_INFO) << "Video frame parameters changed: dimensions=" | |
| 1634 << last_frame_info_.width << "x" << last_frame_info_.height | |
| 1635 << ", rotation=" << last_frame_info_.rotation | |
| 1636 << ", texture=" << last_frame_info_.is_texture; | |
| 1637 } | |
| 1638 | |
| 1639 if (encoder_sink_ == NULL) { | |
| 1640 // Frame input before send codecs are configured, dropping frame. | |
| 1641 return; | |
| 1642 } | |
| 1643 | |
| 1644 last_frame_timestamp_us_ = video_frame.timestamp_us(); | |
| 1645 | |
| 1646 // Forward frame to the encoder regardless if we are sending or not. This is | |
| 1647 // to ensure that the encoder can be reconfigured with the correct frame size | |
| 1648 // as quickly as possible. | |
| 1649 encoder_sink_->OnFrame(video_frame); | |
| 1650 } | |
| 1651 | |
| 1652 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoSend( | 1614 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoSend( |
| 1653 bool enable, | 1615 bool enable, |
| 1654 const VideoOptions* options, | 1616 const VideoOptions* options, |
| 1655 rtc::VideoSourceInterface<webrtc::VideoFrame>* source) { | 1617 rtc::VideoSourceInterface<webrtc::VideoFrame>* source) { |
| 1656 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetVideoSend"); | 1618 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetVideoSend"); |
| 1657 RTC_DCHECK_RUN_ON(&thread_checker_); | 1619 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 1658 | 1620 |
| 1659 // Ignore |options| pointer if |enable| is false. | 1621 // Ignore |options| pointer if |enable| is false. |
| 1660 bool options_present = enable && options; | 1622 bool options_present = enable && options; |
| 1661 bool source_changing = source_ != source; | |
| 1662 | 1623 |
| 1663 if (options_present) { | 1624 if (options_present) { |
| 1664 VideoOptions old_options = parameters_.options; | 1625 VideoOptions old_options = parameters_.options; |
| 1665 parameters_.options.SetAll(*options); | 1626 parameters_.options.SetAll(*options); |
| 1666 if (parameters_.options != old_options) { | 1627 if (parameters_.options != old_options) { |
| 1667 ReconfigureEncoder(); | 1628 ReconfigureEncoder(); |
| 1668 } | 1629 } |
| 1669 } | 1630 } |
| 1670 | 1631 |
| 1671 if (source_changing) { | |
| 1672 rtc::CritScope cs(&lock_); | |
| 1673 if (source == nullptr && last_frame_info_.width > 0 && encoder_sink_) { | |
| 1674 LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; | |
| 1675 // Force this black frame not to be dropped due to timestamp order | |
| 1676 // check. As IncomingCapturedFrame will drop the frame if this frame's | |
| 1677 // timestamp is less than or equal to last frame's timestamp, it is | |
| 1678 // necessary to give this black frame a larger timestamp than the | |
| 1679 // previous one. | |
| 1680 last_frame_timestamp_us_ += rtc::kNumMicrosecsPerMillisec; | |
| 1681 rtc::scoped_refptr<webrtc::I420Buffer> black_buffer( | |
| 1682 webrtc::I420Buffer::Create(last_frame_info_.width, | |
| 1683 last_frame_info_.height)); | |
| 1684 webrtc::I420Buffer::SetBlack(black_buffer); | |
| 1685 | |
| 1686 encoder_sink_->OnFrame(webrtc::VideoFrame( | |
| 1687 black_buffer, last_frame_info_.rotation, last_frame_timestamp_us_)); | |
| 1688 } | |
| 1689 } | |
| 1690 | |
| 1691 // TODO(perkj, nisse): Remove |source_| and directly call | |
| 1692 // |stream_|->SetSource(source) once the video frame types have been | |
| 1693 // merged. | |
| 1694 if (source_ && stream_) { | 1632 if (source_ && stream_) { |
| 1695 stream_->SetSource( | 1633 stream_->SetSource( |
| 1696 nullptr, webrtc::VideoSendStream::DegradationPreference::kBalanced); | 1634 nullptr, webrtc::VideoSendStream::DegradationPreference::kBalanced); |
| 1697 } | 1635 } |
| 1698 // Switch to the new source. | 1636 // Switch to the new source. |
| 1699 source_ = source; | 1637 source_ = source; |
| 1700 if (source && stream_) { | 1638 if (source && stream_) { |
| 1701 // Do not adapt resolution for screen content as this will likely | 1639 // Do not adapt resolution for screen content as this will likely |
| 1702 // result in blurry and unreadable text. | 1640 // result in blurry and unreadable text. |
| 1641 // |this| acts like a VideoSource to make sure SinkWants are handled on the |
| 1642 // correct thread. |
| 1703 stream_->SetSource( | 1643 stream_->SetSource( |
| 1704 this, enable_cpu_overuse_detection_ && | 1644 this, enable_cpu_overuse_detection_ && |
| 1705 !parameters_.options.is_screencast.value_or(false) | 1645 !parameters_.options.is_screencast.value_or(false) |
| 1706 ? webrtc::VideoSendStream::DegradationPreference::kBalanced | 1646 ? webrtc::VideoSendStream::DegradationPreference::kBalanced |
| 1707 : webrtc::VideoSendStream::DegradationPreference:: | 1647 : webrtc::VideoSendStream::DegradationPreference:: |
| 1708 kMaintainResolution); | 1648 kMaintainResolution); |
| 1709 } | 1649 } |
| 1710 return true; | 1650 return true; |
| 1711 } | 1651 } |
| 1712 | 1652 |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1966 parameters_.encoder_config = std::move(encoder_config); | 1906 parameters_.encoder_config = std::move(encoder_config); |
| 1967 } | 1907 } |
| 1968 | 1908 |
| 1969 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSend(bool send) { | 1909 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSend(bool send) { |
| 1970 RTC_DCHECK_RUN_ON(&thread_checker_); | 1910 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 1971 sending_ = send; | 1911 sending_ = send; |
| 1972 UpdateSendState(); | 1912 UpdateSendState(); |
| 1973 } | 1913 } |
| 1974 | 1914 |
| 1975 void WebRtcVideoChannel2::WebRtcVideoSendStream::RemoveSink( | 1915 void WebRtcVideoChannel2::WebRtcVideoSendStream::RemoveSink( |
| 1976 VideoSinkInterface<webrtc::VideoFrame>* sink) { | 1916 rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) { |
| 1977 RTC_DCHECK_RUN_ON(&thread_checker_); | 1917 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 1978 { | 1918 RTC_DCHECK(encoder_sink_ == sink); |
| 1979 rtc::CritScope cs(&lock_); | 1919 encoder_sink_ = nullptr; |
| 1980 RTC_DCHECK(encoder_sink_ == sink); | 1920 source_->RemoveSink(sink); |
| 1981 encoder_sink_ = nullptr; | |
| 1982 } | |
| 1983 source_->RemoveSink(this); | |
| 1984 } | 1921 } |
| 1985 | 1922 |
| 1986 void WebRtcVideoChannel2::WebRtcVideoSendStream::AddOrUpdateSink( | 1923 void WebRtcVideoChannel2::WebRtcVideoSendStream::AddOrUpdateSink( |
| 1987 VideoSinkInterface<webrtc::VideoFrame>* sink, | 1924 rtc::VideoSinkInterface<webrtc::VideoFrame>* sink, |
| 1988 const rtc::VideoSinkWants& wants) { | 1925 const rtc::VideoSinkWants& wants) { |
| 1989 if (worker_thread_ == rtc::Thread::Current()) { | 1926 if (worker_thread_ == rtc::Thread::Current()) { |
| 1990 // AddOrUpdateSink is called on |worker_thread_| if this is the first | 1927 // AddOrUpdateSink is called on |worker_thread_| if this is the first |
| 1991 // registration of |sink|. | 1928 // registration of |sink|. |
| 1992 RTC_DCHECK_RUN_ON(&thread_checker_); | 1929 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 1993 { | 1930 encoder_sink_ = sink; |
| 1994 rtc::CritScope cs(&lock_); | 1931 source_->AddOrUpdateSink(encoder_sink_, wants); |
| 1995 encoder_sink_ = sink; | |
| 1996 } | |
| 1997 source_->AddOrUpdateSink(this, wants); | |
| 1998 } else { | 1932 } else { |
| 1999 // Subsequent calls to AddOrUpdateSink will happen on the encoder task | 1933 // Subsequent calls to AddOrUpdateSink will happen on the encoder task |
| 2000 // queue. | 1934 // queue. |
| 2001 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [this, wants] { | 1935 invoker_.AsyncInvoke<void>( |
| 2002 RTC_DCHECK_RUN_ON(&thread_checker_); | 1936 RTC_FROM_HERE, worker_thread_, [this, sink, wants] { |
| 2003 bool encoder_sink_valid = true; | 1937 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 2004 { | 1938 // |sink| may be invalidated after this task was posted since |
| 2005 rtc::CritScope cs(&lock_); | 1939 // RemoveSink is called on the worker thread. |
| 2006 encoder_sink_valid = encoder_sink_ != nullptr; | 1940 bool encoder_sink_valid = (sink == encoder_sink_); |
| 2007 } | 1941 if (source_ && encoder_sink_valid) { |
| 2008 // Since |source_| is still valid after a call to RemoveSink, check if | 1942 source_->AddOrUpdateSink(encoder_sink_, wants); |
| 2009 // |encoder_sink_| is still valid to check if this call should be | 1943 } |
| 2010 // cancelled. | 1944 }); |
| 2011 if (source_ && encoder_sink_valid) { | |
| 2012 source_->AddOrUpdateSink(this, wants); | |
| 2013 } | |
| 2014 }); | |
| 2015 } | 1945 } |
| 2016 } | 1946 } |
| 2017 | 1947 |
| 2018 VideoSenderInfo WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo( | 1948 VideoSenderInfo WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo( |
| 2019 bool log_stats) { | 1949 bool log_stats) { |
| 2020 VideoSenderInfo info; | 1950 VideoSenderInfo info; |
| 2021 RTC_DCHECK_RUN_ON(&thread_checker_); | 1951 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 2022 for (uint32_t ssrc : parameters_.config.rtp.ssrcs) | 1952 for (uint32_t ssrc : parameters_.config.rtp.ssrcs) |
| 2023 info.add_ssrc(ssrc); | 1953 info.add_ssrc(ssrc); |
| 2024 | 1954 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2128 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " | 2058 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " |
| 2129 "payload type the set codec. Ignoring RTX."; | 2059 "payload type the set codec. Ignoring RTX."; |
| 2130 config.rtp.rtx.ssrcs.clear(); | 2060 config.rtp.rtx.ssrcs.clear(); |
| 2131 } | 2061 } |
| 2132 stream_ = call_->CreateVideoSendStream(std::move(config), | 2062 stream_ = call_->CreateVideoSendStream(std::move(config), |
| 2133 parameters_.encoder_config.Copy()); | 2063 parameters_.encoder_config.Copy()); |
| 2134 | 2064 |
| 2135 parameters_.encoder_config.encoder_specific_settings = NULL; | 2065 parameters_.encoder_config.encoder_specific_settings = NULL; |
| 2136 | 2066 |
| 2137 if (source_) { | 2067 if (source_) { |
| 2138 // TODO(perkj, nisse): Remove |source_| and directly call | |
| 2139 // |stream_|->SetSource(source) once the video frame types have been | |
| 2140 // merged and |stream_| internally reconfigure the encoder on frame | |
| 2141 // resolution change. | |
| 2142 // Do not adapt resolution for screen content as this will likely result in | 2068 // Do not adapt resolution for screen content as this will likely result in |
| 2143 // blurry and unreadable text. | 2069 // blurry and unreadable text. |
| 2070 // |this| acts like a VideoSource to make sure SinkWants are handled on the |
| 2071 // correct thread. |
| 2144 stream_->SetSource( | 2072 stream_->SetSource( |
| 2145 this, enable_cpu_overuse_detection_ && | 2073 this, enable_cpu_overuse_detection_ && |
| 2146 !parameters_.options.is_screencast.value_or(false) | 2074 !parameters_.options.is_screencast.value_or(false) |
| 2147 ? webrtc::VideoSendStream::DegradationPreference::kBalanced | 2075 ? webrtc::VideoSendStream::DegradationPreference::kBalanced |
| 2148 : webrtc::VideoSendStream::DegradationPreference:: | 2076 : webrtc::VideoSendStream::DegradationPreference:: |
| 2149 kMaintainResolution); | 2077 kMaintainResolution); |
| 2150 } | 2078 } |
| 2151 | 2079 |
| 2152 // Call stream_->Start() if necessary conditions are met. | 2080 // Call stream_->Start() if necessary conditions are met. |
| 2153 UpdateSendState(); | 2081 UpdateSendState(); |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2587 rtx_mapping[video_codecs[i].codec.id] != | 2515 rtx_mapping[video_codecs[i].codec.id] != |
| 2588 ulpfec_config.red_payload_type) { | 2516 ulpfec_config.red_payload_type) { |
| 2589 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; | 2517 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; |
| 2590 } | 2518 } |
| 2591 } | 2519 } |
| 2592 | 2520 |
| 2593 return video_codecs; | 2521 return video_codecs; |
| 2594 } | 2522 } |
| 2595 | 2523 |
| 2596 } // namespace cricket | 2524 } // namespace cricket |
| OLD | NEW |