Chromium Code Reviews| 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 1546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1557 ssrc_groups_(sp.ssrc_groups), | 1557 ssrc_groups_(sp.ssrc_groups), |
| 1558 call_(call), | 1558 call_(call), |
| 1559 enable_cpu_overuse_detection_(enable_cpu_overuse_detection), | 1559 enable_cpu_overuse_detection_(enable_cpu_overuse_detection), |
| 1560 source_(nullptr), | 1560 source_(nullptr), |
| 1561 external_encoder_factory_(external_encoder_factory), | 1561 external_encoder_factory_(external_encoder_factory), |
| 1562 stream_(nullptr), | 1562 stream_(nullptr), |
| 1563 encoder_sink_(nullptr), | 1563 encoder_sink_(nullptr), |
| 1564 parameters_(std::move(config), options, max_bitrate_bps, codec_settings), | 1564 parameters_(std::move(config), options, max_bitrate_bps, codec_settings), |
| 1565 rtp_parameters_(CreateRtpParametersWithOneEncoding()), | 1565 rtp_parameters_(CreateRtpParametersWithOneEncoding()), |
| 1566 allocated_encoder_(nullptr, webrtc::kVideoCodecUnknown, false), | 1566 allocated_encoder_(nullptr, webrtc::kVideoCodecUnknown, false), |
| 1567 sending_(false), | 1567 sending_(false) { |
| 1568 last_frame_timestamp_us_(0) { | |
| 1569 parameters_.config.rtp.max_packet_size = kVideoMtu; | 1568 parameters_.config.rtp.max_packet_size = kVideoMtu; |
| 1570 parameters_.conference_mode = send_params.conference_mode; | 1569 parameters_.conference_mode = send_params.conference_mode; |
| 1571 | 1570 |
| 1572 sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); | 1571 sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); |
| 1573 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, | 1572 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, |
| 1574 ¶meters_.config.rtp.rtx.ssrcs); | 1573 ¶meters_.config.rtp.rtx.ssrcs); |
| 1575 parameters_.config.rtp.c_name = sp.cname; | 1574 parameters_.config.rtp.c_name = sp.cname; |
| 1576 if (rtp_extensions) { | 1575 if (rtp_extensions) { |
| 1577 parameters_.config.rtp.extensions = *rtp_extensions; | 1576 parameters_.config.rtp.extensions = *rtp_extensions; |
| 1578 } | 1577 } |
| 1579 parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size | 1578 parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size |
| 1580 ? webrtc::RtcpMode::kReducedSize | 1579 ? webrtc::RtcpMode::kReducedSize |
| 1581 : webrtc::RtcpMode::kCompound; | 1580 : webrtc::RtcpMode::kCompound; |
| 1582 if (codec_settings) { | 1581 if (codec_settings) { |
| 1583 SetCodec(*codec_settings); | 1582 SetCodec(*codec_settings); |
| 1584 } | 1583 } |
| 1585 } | 1584 } |
| 1586 | 1585 |
| 1587 WebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { | 1586 WebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { |
| 1588 if (stream_ != NULL) { | 1587 if (stream_ != NULL) { |
| 1589 call_->DestroyVideoSendStream(stream_); | 1588 call_->DestroyVideoSendStream(stream_); |
| 1590 } | 1589 } |
| 1591 DestroyVideoEncoder(&allocated_encoder_); | 1590 DestroyVideoEncoder(&allocated_encoder_); |
| 1592 } | 1591 } |
| 1593 | 1592 |
| 1594 void WebRtcVideoChannel2::WebRtcVideoSendStream::OnFrame( | |
| 1595 const VideoFrame& frame) { | |
| 1596 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::OnFrame"); | |
| 1597 webrtc::VideoFrame video_frame(frame.video_frame_buffer(), | |
| 1598 frame.rotation(), | |
| 1599 frame.timestamp_us()); | |
| 1600 | |
| 1601 rtc::CritScope cs(&lock_); | |
| 1602 | |
| 1603 if (video_frame.width() != last_frame_info_.width || | |
| 1604 video_frame.height() != last_frame_info_.height || | |
| 1605 video_frame.rotation() != last_frame_info_.rotation || | |
| 1606 video_frame.is_texture() != last_frame_info_.is_texture) { | |
| 1607 last_frame_info_.width = video_frame.width(); | |
| 1608 last_frame_info_.height = video_frame.height(); | |
| 1609 last_frame_info_.rotation = video_frame.rotation(); | |
| 1610 last_frame_info_.is_texture = video_frame.is_texture(); | |
| 1611 | |
| 1612 LOG(LS_INFO) << "Video frame parameters changed: dimensions=" | |
| 1613 << last_frame_info_.width << "x" << last_frame_info_.height | |
| 1614 << ", rotation=" << last_frame_info_.rotation | |
| 1615 << ", texture=" << last_frame_info_.is_texture; | |
| 1616 } | |
| 1617 | |
| 1618 if (encoder_sink_ == NULL) { | |
| 1619 // Frame input before send codecs are configured, dropping frame. | |
| 1620 return; | |
| 1621 } | |
| 1622 | |
| 1623 last_frame_timestamp_us_ = video_frame.timestamp_us(); | |
| 1624 | |
| 1625 // Forward frame to the encoder regardless if we are sending or not. This is | |
| 1626 // to ensure that the encoder can be reconfigured with the correct frame size | |
| 1627 // as quickly as possible. | |
| 1628 encoder_sink_->OnFrame(video_frame); | |
| 1629 } | |
| 1630 | |
| 1631 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoSend( | 1593 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetVideoSend( |
| 1632 bool enable, | 1594 bool enable, |
| 1633 const VideoOptions* options, | 1595 const VideoOptions* options, |
| 1634 rtc::VideoSourceInterface<cricket::VideoFrame>* source) { | 1596 rtc::VideoSourceInterface<cricket::VideoFrame>* source) { |
| 1635 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetVideoSend"); | 1597 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetVideoSend"); |
| 1636 RTC_DCHECK_RUN_ON(&thread_checker_); | 1598 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 1637 | 1599 |
| 1638 // Ignore |options| pointer if |enable| is false. | 1600 // Ignore |options| pointer if |enable| is false. |
| 1639 bool options_present = enable && options; | 1601 bool options_present = enable && options; |
| 1640 bool source_changing = source_ != source; | |
| 1641 | 1602 |
| 1642 if (options_present) { | 1603 if (options_present) { |
| 1643 VideoOptions old_options = parameters_.options; | 1604 VideoOptions old_options = parameters_.options; |
| 1644 parameters_.options.SetAll(*options); | 1605 parameters_.options.SetAll(*options); |
| 1645 if (parameters_.options != old_options) { | 1606 if (parameters_.options != old_options) { |
| 1646 ReconfigureEncoder(); | 1607 ReconfigureEncoder(); |
| 1647 } | 1608 } |
| 1648 } | 1609 } |
| 1649 | 1610 |
| 1650 if (source_changing) { | |
| 1651 rtc::CritScope cs(&lock_); | |
| 1652 if (source == nullptr && last_frame_info_.width > 0 && encoder_sink_) { | |
| 1653 LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; | |
| 1654 // Force this black frame not to be dropped due to timestamp order | |
| 1655 // check. As IncomingCapturedFrame will drop the frame if this frame's | |
| 1656 // timestamp is less than or equal to last frame's timestamp, it is | |
| 1657 // necessary to give this black frame a larger timestamp than the | |
| 1658 // previous one. | |
| 1659 last_frame_timestamp_us_ += rtc::kNumMicrosecsPerMillisec; | |
| 1660 rtc::scoped_refptr<webrtc::I420Buffer> black_buffer( | |
| 1661 webrtc::I420Buffer::Create(last_frame_info_.width, | |
| 1662 last_frame_info_.height)); | |
| 1663 black_buffer->SetToBlack(); | |
| 1664 | |
| 1665 encoder_sink_->OnFrame(webrtc::VideoFrame( | |
| 1666 black_buffer, last_frame_info_.rotation, last_frame_timestamp_us_)); | |
| 1667 } | |
| 1668 } | |
| 1669 | |
| 1670 // TODO(perkj, nisse): Remove |source_| and directly call | |
| 1671 // |stream_|->SetSource(source) once the video frame types have been | |
| 1672 // merged. | |
| 1673 if (source_ && stream_) { | 1611 if (source_ && stream_) { |
| 1674 stream_->SetSource( | 1612 stream_->SetSource( |
| 1675 nullptr, webrtc::VideoSendStream::DegradationPreference::kBalanced); | 1613 nullptr, webrtc::VideoSendStream::DegradationPreference::kBalanced); |
| 1676 } | 1614 } |
| 1677 // Switch to the new source. | 1615 // Switch to the new source. |
| 1678 source_ = source; | 1616 source_ = source; |
| 1679 if (source && stream_) { | 1617 if (source && stream_) { |
| 1680 // Do not adapt resolution for screen content as this will likely | 1618 // Do not adapt resolution for screen content as this will likely |
| 1681 // result in blurry and unreadable text. | 1619 // result in blurry and unreadable text. |
| 1682 stream_->SetSource( | 1620 stream_->SetSource( |
| 1683 this, enable_cpu_overuse_detection_ && | 1621 source, enable_cpu_overuse_detection_ && |
|
perkj_webrtc
2016/11/16 21:27:24
ops, this should still be |this|
| |
| 1684 !parameters_.options.is_screencast.value_or(false) | 1622 !parameters_.options.is_screencast.value_or(false) |
| 1685 ? webrtc::VideoSendStream::DegradationPreference::kBalanced | 1623 ? webrtc::VideoSendStream::DegradationPreference::kBalanced |
| 1686 : webrtc::VideoSendStream::DegradationPreference:: | 1624 : webrtc::VideoSendStream::DegradationPreference:: |
| 1687 kMaintainResolution); | 1625 kMaintainResolution); |
| 1688 } | 1626 } |
| 1689 return true; | 1627 return true; |
| 1690 } | 1628 } |
| 1691 | 1629 |
| 1692 const std::vector<uint32_t>& | 1630 const std::vector<uint32_t>& |
| 1693 WebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { | 1631 WebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { |
| 1694 return ssrcs_; | 1632 return ssrcs_; |
| 1695 } | 1633 } |
| 1696 | 1634 |
| 1697 WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder | 1635 WebRtcVideoChannel2::WebRtcVideoSendStream::AllocatedEncoder |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1938 parameters_.encoder_config = std::move(encoder_config); | 1876 parameters_.encoder_config = std::move(encoder_config); |
| 1939 } | 1877 } |
| 1940 | 1878 |
| 1941 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSend(bool send) { | 1879 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSend(bool send) { |
| 1942 RTC_DCHECK_RUN_ON(&thread_checker_); | 1880 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 1943 sending_ = send; | 1881 sending_ = send; |
| 1944 UpdateSendState(); | 1882 UpdateSendState(); |
| 1945 } | 1883 } |
| 1946 | 1884 |
| 1947 void WebRtcVideoChannel2::WebRtcVideoSendStream::RemoveSink( | 1885 void WebRtcVideoChannel2::WebRtcVideoSendStream::RemoveSink( |
| 1948 VideoSinkInterface<webrtc::VideoFrame>* sink) { | 1886 rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) { |
| 1949 RTC_DCHECK_RUN_ON(&thread_checker_); | 1887 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 1950 { | 1888 RTC_DCHECK(encoder_sink_ == sink); |
| 1951 rtc::CritScope cs(&lock_); | 1889 encoder_sink_ = nullptr; |
| 1952 RTC_DCHECK(encoder_sink_ == sink); | 1890 source_->RemoveSink(sink); |
| 1953 encoder_sink_ = nullptr; | |
| 1954 } | |
| 1955 source_->RemoveSink(this); | |
| 1956 } | 1891 } |
| 1957 | 1892 |
| 1958 void WebRtcVideoChannel2::WebRtcVideoSendStream::AddOrUpdateSink( | 1893 void WebRtcVideoChannel2::WebRtcVideoSendStream::AddOrUpdateSink( |
| 1959 VideoSinkInterface<webrtc::VideoFrame>* sink, | 1894 rtc::VideoSinkInterface<webrtc::VideoFrame>* sink, |
| 1960 const rtc::VideoSinkWants& wants) { | 1895 const rtc::VideoSinkWants& wants) { |
| 1961 if (worker_thread_ == rtc::Thread::Current()) { | 1896 if (worker_thread_ == rtc::Thread::Current()) { |
| 1962 // AddOrUpdateSink is called on |worker_thread_| if this is the first | 1897 // AddOrUpdateSink is called on |worker_thread_| if this is the first |
| 1963 // registration of |sink|. | 1898 // registration of |sink|. |
| 1964 RTC_DCHECK_RUN_ON(&thread_checker_); | 1899 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 1965 { | 1900 encoder_sink_ = sink; |
| 1966 rtc::CritScope cs(&lock_); | 1901 source_->AddOrUpdateSink(encoder_sink_, wants); |
| 1967 encoder_sink_ = sink; | |
| 1968 } | |
| 1969 source_->AddOrUpdateSink(this, wants); | |
| 1970 } else { | 1902 } else { |
| 1971 // Subsequent calls to AddOrUpdateSink will happen on the encoder task | 1903 // Subsequent calls to AddOrUpdateSink will happen on the encoder task |
| 1972 // queue. | 1904 // queue. |
| 1973 invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_, [this, wants] { | 1905 invoker_.AsyncInvoke<void>( |
| 1974 RTC_DCHECK_RUN_ON(&thread_checker_); | 1906 RTC_FROM_HERE, worker_thread_, [this, sink, wants] { |
| 1975 bool encoder_sink_valid = true; | 1907 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 1976 { | 1908 // |sink| may be invalidated after this task was posted since |
| 1977 rtc::CritScope cs(&lock_); | 1909 // RemoveSink is called on the worker thread. |
| 1978 encoder_sink_valid = encoder_sink_ != nullptr; | 1910 bool encoder_sink_valid = sink == encoder_sink_; |
|
nisse-webrtc
2016/11/07 09:52:46
Hmm, this also appears to be the only use of the e
nisse-webrtc
2016/11/07 09:52:46
Style: I'd prefer a pair of () around the comparis
perkj_webrtc
2016/11/16 21:27:24
Since we can not use rtc::Threads on lower levels
nisse-webrtc
2016/11/17 08:07:13
Not sure what other use cases there are with AddOr
| |
| 1979 } | 1911 if (source_ && encoder_sink_valid) { |
| 1980 // Since |source_| is still valid after a call to RemoveSink, check if | 1912 source_->AddOrUpdateSink(encoder_sink_, wants); |
| 1981 // |encoder_sink_| is still valid to check if this call should be | 1913 } |
| 1982 // cancelled. | 1914 }); |
| 1983 if (source_ && encoder_sink_valid) { | |
| 1984 source_->AddOrUpdateSink(this, wants); | |
| 1985 } | |
| 1986 }); | |
| 1987 } | 1915 } |
| 1988 } | 1916 } |
| 1989 | 1917 |
| 1990 VideoSenderInfo WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo( | 1918 VideoSenderInfo WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo( |
| 1991 bool log_stats) { | 1919 bool log_stats) { |
| 1992 VideoSenderInfo info; | 1920 VideoSenderInfo info; |
| 1993 RTC_DCHECK_RUN_ON(&thread_checker_); | 1921 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 1994 for (uint32_t ssrc : parameters_.config.rtp.ssrcs) | 1922 for (uint32_t ssrc : parameters_.config.rtp.ssrcs) |
| 1995 info.add_ssrc(ssrc); | 1923 info.add_ssrc(ssrc); |
| 1996 | 1924 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2097 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " | 2025 LOG(LS_WARNING) << "RTX SSRCs configured but there's no configured RTX " |
| 2098 "payload type the set codec. Ignoring RTX."; | 2026 "payload type the set codec. Ignoring RTX."; |
| 2099 config.rtp.rtx.ssrcs.clear(); | 2027 config.rtp.rtx.ssrcs.clear(); |
| 2100 } | 2028 } |
| 2101 stream_ = call_->CreateVideoSendStream(std::move(config), | 2029 stream_ = call_->CreateVideoSendStream(std::move(config), |
| 2102 parameters_.encoder_config.Copy()); | 2030 parameters_.encoder_config.Copy()); |
| 2103 | 2031 |
| 2104 parameters_.encoder_config.encoder_specific_settings = NULL; | 2032 parameters_.encoder_config.encoder_specific_settings = NULL; |
| 2105 | 2033 |
| 2106 if (source_) { | 2034 if (source_) { |
| 2107 // TODO(perkj, nisse): Remove |source_| and directly call | |
| 2108 // |stream_|->SetSource(source) once the video frame types have been | |
| 2109 // merged and |stream_| internally reconfigure the encoder on frame | |
| 2110 // resolution change. | |
| 2111 // Do not adapt resolution for screen content as this will likely result in | 2035 // Do not adapt resolution for screen content as this will likely result in |
| 2112 // blurry and unreadable text. | 2036 // blurry and unreadable text. |
| 2113 stream_->SetSource( | 2037 stream_->SetSource( |
| 2114 this, enable_cpu_overuse_detection_ && | 2038 source_, enable_cpu_overuse_detection_ && |
| 2115 !parameters_.options.is_screencast.value_or(false) | 2039 !parameters_.options.is_screencast.value_or(false) |
| 2116 ? webrtc::VideoSendStream::DegradationPreference::kBalanced | 2040 ? webrtc::VideoSendStream::DegradationPreference::kBalanced |
| 2117 : webrtc::VideoSendStream::DegradationPreference:: | 2041 : webrtc::VideoSendStream::DegradationPreference:: |
| 2118 kMaintainResolution); | 2042 kMaintainResolution); |
| 2119 } | 2043 } |
| 2120 | 2044 |
| 2121 // Call stream_->Start() if necessary conditions are met. | 2045 // Call stream_->Start() if necessary conditions are met. |
| 2122 UpdateSendState(); | 2046 UpdateSendState(); |
| 2123 } | 2047 } |
| 2124 | 2048 |
| 2125 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( | 2049 WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( |
| 2126 webrtc::Call* call, | 2050 webrtc::Call* call, |
| 2127 const StreamParams& sp, | 2051 const StreamParams& sp, |
| 2128 webrtc::VideoReceiveStream::Config config, | 2052 webrtc::VideoReceiveStream::Config config, |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2563 rtx_mapping[video_codecs[i].codec.id] != | 2487 rtx_mapping[video_codecs[i].codec.id] != |
| 2564 ulpfec_config.red_payload_type) { | 2488 ulpfec_config.red_payload_type) { |
| 2565 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; | 2489 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; |
| 2566 } | 2490 } |
| 2567 } | 2491 } |
| 2568 | 2492 |
| 2569 return video_codecs; | 2493 return video_codecs; |
| 2570 } | 2494 } |
| 2571 | 2495 |
| 2572 } // namespace cricket | 2496 } // namespace cricket |
| OLD | NEW |