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 |
| 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 | 17 |
| 18 #include "webrtc/base/copyonwritebuffer.h" | 18 #include "webrtc/base/copyonwritebuffer.h" |
| 19 #include "webrtc/base/logging.h" | 19 #include "webrtc/base/logging.h" |
| 20 #include "webrtc/base/stringutils.h" | 20 #include "webrtc/base/stringutils.h" |
| 21 #include "webrtc/base/timeutils.h" | 21 #include "webrtc/base/timeutils.h" |
| 22 #include "webrtc/base/trace_event.h" | 22 #include "webrtc/base/trace_event.h" |
| 23 #include "webrtc/call.h" | 23 #include "webrtc/call.h" |
| 24 #include "webrtc/media/base/videocapturer.h" | |
| 25 #include "webrtc/media/engine/constants.h" | 24 #include "webrtc/media/engine/constants.h" |
| 26 #include "webrtc/media/engine/simulcast.h" | 25 #include "webrtc/media/engine/simulcast.h" |
| 27 #include "webrtc/media/engine/webrtcmediaengine.h" | 26 #include "webrtc/media/engine/webrtcmediaengine.h" |
| 28 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" | 27 #include "webrtc/media/engine/webrtcvideoencoderfactory.h" |
| 29 #include "webrtc/media/engine/webrtcvideoframe.h" | 28 #include "webrtc/media/engine/webrtcvideoframe.h" |
| 30 #include "webrtc/media/engine/webrtcvoiceengine.h" | 29 #include "webrtc/media/engine/webrtcvoiceengine.h" |
| 31 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" | 30 #include "webrtc/modules/video_coding/codecs/h264/include/h264.h" |
| 32 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h" | 31 #include "webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h" |
| 33 #include "webrtc/system_wrappers/include/field_trial.h" | 32 #include "webrtc/system_wrappers/include/field_trial.h" |
| 34 #include "webrtc/video_decoder.h" | 33 #include "webrtc/video_decoder.h" |
| (...skipping 957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 992 { | 991 { |
| 993 rtc::CritScope stream_lock(&stream_crit_); | 992 rtc::CritScope stream_lock(&stream_crit_); |
| 994 for (const auto& kv : send_streams_) { | 993 for (const auto& kv : send_streams_) { |
| 995 kv.second->SetSend(send); | 994 kv.second->SetSend(send); |
| 996 } | 995 } |
| 997 } | 996 } |
| 998 sending_ = send; | 997 sending_ = send; |
| 999 return true; | 998 return true; |
| 1000 } | 999 } |
| 1001 | 1000 |
| 1001 // TODO(nisse): The enable argument was used for mute logic which has | |
| 1002 // been moved elsewhere. So delete this method, and use SetOptions | |
|
pbos-webrtc
2016/03/31 14:14:31
say where they moved please
| |
| 1003 // instead. | |
| 1002 bool WebRtcVideoChannel2::SetVideoSend(uint32_t ssrc, bool enable, | 1004 bool WebRtcVideoChannel2::SetVideoSend(uint32_t ssrc, bool enable, |
| 1003 const VideoOptions* options) { | 1005 const VideoOptions* options) { |
| 1004 TRACE_EVENT0("webrtc", "SetVideoSend"); | 1006 TRACE_EVENT0("webrtc", "SetVideoSend"); |
| 1005 LOG(LS_INFO) << "SetVideoSend (ssrc= " << ssrc << ", enable = " << enable | 1007 LOG(LS_INFO) << "SetVideoSend (ssrc= " << ssrc << ", enable = " << enable |
| 1006 << "options: " << (options ? options->ToString() : "nullptr") | 1008 << "options: " << (options ? options->ToString() : "nullptr") |
| 1007 << ")."; | 1009 << ")."; |
| 1008 | 1010 |
| 1009 // TODO(solenberg): The state change should be fully rolled back if any one of | |
| 1010 // these calls fail. | |
| 1011 if (!MuteStream(ssrc, !enable)) { | |
| 1012 return false; | |
| 1013 } | |
| 1014 if (enable && options) { | 1011 if (enable && options) { |
| 1015 SetOptions(ssrc, *options); | 1012 SetOptions(ssrc, *options); |
| 1016 } | 1013 } |
| 1017 return true; | 1014 return true; |
| 1018 } | 1015 } |
| 1019 | 1016 |
| 1020 bool WebRtcVideoChannel2::ValidateSendSsrcAvailability( | 1017 bool WebRtcVideoChannel2::ValidateSendSsrcAvailability( |
| 1021 const StreamParams& sp) const { | 1018 const StreamParams& sp) const { |
| 1022 for (uint32_t ssrc : sp.ssrcs) { | 1019 for (uint32_t ssrc : sp.ssrcs) { |
| 1023 if (send_ssrcs_.find(ssrc) != send_ssrcs_.end()) { | 1020 if (send_ssrcs_.find(ssrc) != send_ssrcs_.end()) { |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1323 // Get send stream bitrate stats. | 1320 // Get send stream bitrate stats. |
| 1324 rtc::CritScope stream_lock(&stream_crit_); | 1321 rtc::CritScope stream_lock(&stream_crit_); |
| 1325 for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator stream = | 1322 for (std::map<uint32_t, WebRtcVideoSendStream*>::iterator stream = |
| 1326 send_streams_.begin(); | 1323 send_streams_.begin(); |
| 1327 stream != send_streams_.end(); ++stream) { | 1324 stream != send_streams_.end(); ++stream) { |
| 1328 stream->second->FillBandwidthEstimationInfo(&bwe_info); | 1325 stream->second->FillBandwidthEstimationInfo(&bwe_info); |
| 1329 } | 1326 } |
| 1330 video_media_info->bw_estimations.push_back(bwe_info); | 1327 video_media_info->bw_estimations.push_back(bwe_info); |
| 1331 } | 1328 } |
| 1332 | 1329 |
| 1333 bool WebRtcVideoChannel2::SetCapturer(uint32_t ssrc, VideoCapturer* capturer) { | 1330 void WebRtcVideoChannel2::SetSource( |
| 1334 LOG(LS_INFO) << "SetCapturer: " << ssrc << " -> " | 1331 uint32_t ssrc, |
| 1335 << (capturer != NULL ? "(capturer)" : "NULL"); | 1332 rtc::VideoSourceInterface<cricket::VideoFrame>* source) { |
| 1333 LOG(LS_INFO) << "SetSource: " << ssrc << " -> " | |
| 1334 << (source ? "(source)" : "NULL"); | |
| 1336 RTC_DCHECK(ssrc != 0); | 1335 RTC_DCHECK(ssrc != 0); |
| 1337 { | 1336 |
| 1338 rtc::CritScope stream_lock(&stream_crit_); | 1337 rtc::CritScope stream_lock(&stream_crit_); |
| 1339 const auto& kv = send_streams_.find(ssrc); | 1338 const auto& kv = send_streams_.find(ssrc); |
| 1340 if (kv == send_streams_.end()) { | 1339 if (kv == send_streams_.end()) { |
| 1341 LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; | 1340 // Allow unknown ssrc only if source is null. |
| 1342 return false; | 1341 RTC_CHECK(source == nullptr); |
| 1343 } | 1342 } else { |
| 1344 if (!kv->second->SetCapturer(capturer)) { | 1343 kv->second->SetSource(source); |
| 1345 return false; | |
| 1346 } | |
| 1347 } | 1344 } |
| 1348 return true; | |
| 1349 } | 1345 } |
| 1350 | 1346 |
| 1351 void WebRtcVideoChannel2::OnPacketReceived( | 1347 void WebRtcVideoChannel2::OnPacketReceived( |
| 1352 rtc::CopyOnWriteBuffer* packet, | 1348 rtc::CopyOnWriteBuffer* packet, |
| 1353 const rtc::PacketTime& packet_time) { | 1349 const rtc::PacketTime& packet_time) { |
| 1354 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, | 1350 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, |
| 1355 packet_time.not_before); | 1351 packet_time.not_before); |
| 1356 const webrtc::PacketReceiver::DeliveryStatus delivery_result = | 1352 const webrtc::PacketReceiver::DeliveryStatus delivery_result = |
| 1357 call_->Receiver()->DeliverPacket( | 1353 call_->Receiver()->DeliverPacket( |
| 1358 webrtc::MediaType::VIDEO, | 1354 webrtc::MediaType::VIDEO, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1421 webrtc_packet_time); | 1417 webrtc_packet_time); |
| 1422 } | 1418 } |
| 1423 | 1419 |
| 1424 void WebRtcVideoChannel2::OnReadyToSend(bool ready) { | 1420 void WebRtcVideoChannel2::OnReadyToSend(bool ready) { |
| 1425 LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); | 1421 LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); |
| 1426 call_->SignalChannelNetworkState( | 1422 call_->SignalChannelNetworkState( |
| 1427 webrtc::MediaType::VIDEO, | 1423 webrtc::MediaType::VIDEO, |
| 1428 ready ? webrtc::kNetworkUp : webrtc::kNetworkDown); | 1424 ready ? webrtc::kNetworkUp : webrtc::kNetworkDown); |
| 1429 } | 1425 } |
| 1430 | 1426 |
| 1431 bool WebRtcVideoChannel2::MuteStream(uint32_t ssrc, bool mute) { | |
| 1432 LOG(LS_VERBOSE) << "MuteStream: " << ssrc << " -> " | |
| 1433 << (mute ? "mute" : "unmute"); | |
| 1434 RTC_DCHECK(ssrc != 0); | |
| 1435 rtc::CritScope stream_lock(&stream_crit_); | |
| 1436 const auto& kv = send_streams_.find(ssrc); | |
| 1437 if (kv == send_streams_.end()) { | |
| 1438 LOG(LS_ERROR) << "No sending stream on ssrc " << ssrc; | |
| 1439 return false; | |
| 1440 } | |
| 1441 | |
| 1442 kv->second->MuteStream(mute); | |
| 1443 return true; | |
| 1444 } | |
| 1445 | |
| 1446 // TODO(pbos): Remove SetOptions in favor of SetSendParameters. | 1427 // TODO(pbos): Remove SetOptions in favor of SetSendParameters. |
| 1447 void WebRtcVideoChannel2::SetOptions(uint32_t ssrc, | 1428 void WebRtcVideoChannel2::SetOptions(uint32_t ssrc, |
| 1448 const VideoOptions& options) { | 1429 const VideoOptions& options) { |
| 1449 LOG(LS_INFO) << "SetOptions: ssrc " << ssrc << ": " << options.ToString(); | 1430 LOG(LS_INFO) << "SetOptions: ssrc " << ssrc << ": " << options.ToString(); |
| 1450 | 1431 |
| 1451 rtc::CritScope stream_lock(&stream_crit_); | 1432 rtc::CritScope stream_lock(&stream_crit_); |
| 1452 const auto& kv = send_streams_.find(ssrc); | 1433 const auto& kv = send_streams_.find(ssrc); |
| 1453 if (kv == send_streams_.end()) { | 1434 if (kv == send_streams_.end()) { |
| 1454 return; | 1435 return; |
| 1455 } | 1436 } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1524 const std::vector<webrtc::RtpExtension>& rtp_extensions, | 1505 const std::vector<webrtc::RtpExtension>& rtp_extensions, |
| 1525 // TODO(deadbeef): Don't duplicate information between send_params, | 1506 // TODO(deadbeef): Don't duplicate information between send_params, |
| 1526 // rtp_extensions, options, etc. | 1507 // rtp_extensions, options, etc. |
| 1527 const VideoSendParameters& send_params) | 1508 const VideoSendParameters& send_params) |
| 1528 : worker_thread_(rtc::Thread::Current()), | 1509 : worker_thread_(rtc::Thread::Current()), |
| 1529 ssrcs_(sp.ssrcs), | 1510 ssrcs_(sp.ssrcs), |
| 1530 ssrc_groups_(sp.ssrc_groups), | 1511 ssrc_groups_(sp.ssrc_groups), |
| 1531 call_(call), | 1512 call_(call), |
| 1532 cpu_restricted_counter_(0), | 1513 cpu_restricted_counter_(0), |
| 1533 number_of_cpu_adapt_changes_(0), | 1514 number_of_cpu_adapt_changes_(0), |
| 1534 capturer_(nullptr), | 1515 source_(nullptr), |
| 1535 external_encoder_factory_(external_encoder_factory), | 1516 external_encoder_factory_(external_encoder_factory), |
| 1536 stream_(nullptr), | 1517 stream_(nullptr), |
| 1537 parameters_(config, options, max_bitrate_bps, codec_settings), | 1518 parameters_(config, options, max_bitrate_bps, codec_settings), |
| 1538 rtp_parameters_(CreateRtpParametersWithOneEncoding()), | 1519 rtp_parameters_(CreateRtpParametersWithOneEncoding()), |
| 1539 pending_encoder_reconfiguration_(false), | 1520 pending_encoder_reconfiguration_(false), |
| 1540 allocated_encoder_(nullptr, webrtc::kVideoCodecUnknown, false), | 1521 allocated_encoder_(nullptr, webrtc::kVideoCodecUnknown, false), |
| 1541 sending_(false), | 1522 sending_(false), |
| 1542 muted_(false), | |
| 1543 first_frame_timestamp_ms_(0), | 1523 first_frame_timestamp_ms_(0), |
| 1544 last_frame_timestamp_ms_(0) { | 1524 last_frame_timestamp_ms_(0) { |
| 1545 parameters_.config.rtp.max_packet_size = kVideoMtu; | 1525 parameters_.config.rtp.max_packet_size = kVideoMtu; |
| 1546 parameters_.conference_mode = send_params.conference_mode; | 1526 parameters_.conference_mode = send_params.conference_mode; |
| 1547 | 1527 |
| 1548 sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); | 1528 sp.GetPrimarySsrcs(¶meters_.config.rtp.ssrcs); |
| 1549 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, | 1529 sp.GetFidSsrcs(parameters_.config.rtp.ssrcs, |
| 1550 ¶meters_.config.rtp.rtx.ssrcs); | 1530 ¶meters_.config.rtp.rtx.ssrcs); |
| 1551 parameters_.config.rtp.c_name = sp.cname; | 1531 parameters_.config.rtp.c_name = sp.cname; |
| 1552 parameters_.config.rtp.extensions = rtp_extensions; | 1532 parameters_.config.rtp.extensions = rtp_extensions; |
| 1553 parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size | 1533 parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size |
| 1554 ? webrtc::RtcpMode::kReducedSize | 1534 ? webrtc::RtcpMode::kReducedSize |
| 1555 : webrtc::RtcpMode::kCompound; | 1535 : webrtc::RtcpMode::kCompound; |
| 1556 parameters_.config.overuse_callback = | 1536 parameters_.config.overuse_callback = |
| 1557 enable_cpu_overuse_detection ? this : nullptr; | 1537 enable_cpu_overuse_detection ? this : nullptr; |
| 1558 | 1538 |
| 1559 sink_wants_.rotation_applied = !ContainsHeaderExtension( | 1539 sink_wants_.rotation_applied = !ContainsHeaderExtension( |
| 1560 rtp_extensions, kRtpVideoRotationHeaderExtension); | 1540 rtp_extensions, kRtpVideoRotationHeaderExtension); |
| 1561 | 1541 |
| 1562 if (codec_settings) { | 1542 if (codec_settings) { |
| 1563 SetCodec(*codec_settings); | 1543 SetCodec(*codec_settings); |
| 1564 } | 1544 } |
| 1565 } | 1545 } |
| 1566 | 1546 |
| 1567 WebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { | 1547 WebRtcVideoChannel2::WebRtcVideoSendStream::~WebRtcVideoSendStream() { |
| 1568 DisconnectCapturer(); | 1548 DisconnectSource(); |
| 1569 if (stream_ != NULL) { | 1549 if (stream_ != NULL) { |
| 1570 call_->DestroyVideoSendStream(stream_); | 1550 call_->DestroyVideoSendStream(stream_); |
| 1571 } | 1551 } |
| 1572 DestroyVideoEncoder(&allocated_encoder_); | 1552 DestroyVideoEncoder(&allocated_encoder_); |
| 1573 } | 1553 } |
| 1574 | 1554 |
| 1575 static void CreateBlackFrame(webrtc::VideoFrame* video_frame, | 1555 static void CreateBlackFrame(webrtc::VideoFrame* video_frame, |
| 1576 int width, | 1556 int width, |
| 1577 int height, | 1557 int height, |
| 1578 webrtc::VideoRotation rotation) { | 1558 webrtc::VideoRotation rotation) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1591 const VideoFrame& frame) { | 1571 const VideoFrame& frame) { |
| 1592 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::OnFrame"); | 1572 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::OnFrame"); |
| 1593 webrtc::VideoFrame video_frame(frame.GetVideoFrameBuffer(), 0, 0, | 1573 webrtc::VideoFrame video_frame(frame.GetVideoFrameBuffer(), 0, 0, |
| 1594 frame.GetVideoRotation()); | 1574 frame.GetVideoRotation()); |
| 1595 rtc::CritScope cs(&lock_); | 1575 rtc::CritScope cs(&lock_); |
| 1596 if (stream_ == NULL) { | 1576 if (stream_ == NULL) { |
| 1597 // Frame input before send codecs are configured, dropping frame. | 1577 // Frame input before send codecs are configured, dropping frame. |
| 1598 return; | 1578 return; |
| 1599 } | 1579 } |
| 1600 | 1580 |
| 1601 if (muted_) { | |
| 1602 // Create a black frame to transmit instead. | |
| 1603 CreateBlackFrame(&video_frame, | |
| 1604 static_cast<int>(frame.GetWidth()), | |
| 1605 static_cast<int>(frame.GetHeight()), | |
| 1606 video_frame.rotation()); | |
| 1607 } | |
| 1608 | |
| 1609 int64_t frame_delta_ms = frame.GetTimeStamp() / rtc::kNumNanosecsPerMillisec; | 1581 int64_t frame_delta_ms = frame.GetTimeStamp() / rtc::kNumNanosecsPerMillisec; |
| 1610 // frame->GetTimeStamp() is essentially a delta, align to webrtc time | 1582 // frame->GetTimeStamp() is essentially a delta, align to webrtc time |
| 1611 if (first_frame_timestamp_ms_ == 0) { | 1583 if (first_frame_timestamp_ms_ == 0) { |
| 1612 first_frame_timestamp_ms_ = rtc::Time() - frame_delta_ms; | 1584 first_frame_timestamp_ms_ = rtc::Time() - frame_delta_ms; |
| 1613 } | 1585 } |
| 1614 | 1586 |
| 1615 last_frame_timestamp_ms_ = first_frame_timestamp_ms_ + frame_delta_ms; | 1587 last_frame_timestamp_ms_ = first_frame_timestamp_ms_ + frame_delta_ms; |
| 1616 video_frame.set_render_time_ms(last_frame_timestamp_ms_); | 1588 video_frame.set_render_time_ms(last_frame_timestamp_ms_); |
| 1617 // Reconfigure codec if necessary. | 1589 // Reconfigure codec if necessary. |
| 1618 SetDimensions(video_frame.width(), video_frame.height()); | 1590 SetDimensions(video_frame.width(), video_frame.height()); |
| 1619 last_rotation_ = video_frame.rotation(); | 1591 last_rotation_ = video_frame.rotation(); |
| 1620 | 1592 |
| 1621 // Not sending, abort after reconfiguration. Reconfiguration should still | 1593 // Not sending, abort after reconfiguration. Reconfiguration should still |
| 1622 // occur to permit sending this input as quickly as possible once we start | 1594 // occur to permit sending this input as quickly as possible once we start |
| 1623 // sending (without having to reconfigure then). | 1595 // sending (without having to reconfigure then). |
| 1624 if (!sending_) { | 1596 if (!sending_) { |
| 1625 return; | 1597 return; |
| 1626 } | 1598 } |
| 1627 | 1599 |
| 1628 stream_->Input()->IncomingCapturedFrame(video_frame); | 1600 stream_->Input()->IncomingCapturedFrame(video_frame); |
| 1629 } | 1601 } |
| 1630 | 1602 |
| 1631 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetCapturer( | 1603 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetSource( |
| 1632 VideoCapturer* capturer) { | 1604 rtc::VideoSourceInterface<cricket::VideoFrame>* source) { |
| 1633 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetCapturer"); | 1605 TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetSource"); |
| 1634 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1606 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 1635 if (!DisconnectCapturer() && capturer == NULL) { | 1607 |
| 1636 return false; | 1608 if (!source && !source_) |
| 1637 } | 1609 return; |
| 1610 DisconnectSource(); | |
| 1638 | 1611 |
| 1639 { | 1612 { |
| 1640 rtc::CritScope cs(&lock_); | 1613 rtc::CritScope cs(&lock_); |
| 1641 | 1614 |
| 1642 // Reset timestamps to realign new incoming frames to a webrtc timestamp. A | 1615 // Reset timestamps to realign new incoming frames to a webrtc timestamp. A |
| 1643 // new capturer may have a different timestamp delta than the previous one. | 1616 // new capturer may have a different timestamp delta than the previous one. |
| 1644 first_frame_timestamp_ms_ = 0; | 1617 first_frame_timestamp_ms_ = 0; |
| 1645 | 1618 |
| 1646 if (capturer == NULL) { | 1619 if (source == NULL) { |
| 1647 if (stream_ != NULL) { | 1620 if (stream_ != NULL) { |
| 1648 LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; | 1621 LOG(LS_VERBOSE) << "Disabling capturer, sending black frame."; |
| 1649 webrtc::VideoFrame black_frame; | 1622 webrtc::VideoFrame black_frame; |
| 1650 | 1623 |
| 1651 CreateBlackFrame(&black_frame, last_dimensions_.width, | 1624 CreateBlackFrame(&black_frame, last_dimensions_.width, |
| 1652 last_dimensions_.height, last_rotation_); | 1625 last_dimensions_.height, last_rotation_); |
| 1653 | 1626 |
| 1654 // Force this black frame not to be dropped due to timestamp order | 1627 // Force this black frame not to be dropped due to timestamp order |
| 1655 // check. As IncomingCapturedFrame will drop the frame if this frame's | 1628 // 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 | 1629 // 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 | 1630 // necessary to give this black frame a larger timestamp than the |
| 1658 // previous one. | 1631 // previous one. |
| 1659 last_frame_timestamp_ms_ += 1; | 1632 last_frame_timestamp_ms_ += 1; |
| 1660 black_frame.set_render_time_ms(last_frame_timestamp_ms_); | 1633 black_frame.set_render_time_ms(last_frame_timestamp_ms_); |
| 1661 stream_->Input()->IncomingCapturedFrame(black_frame); | 1634 stream_->Input()->IncomingCapturedFrame(black_frame); |
| 1662 } | 1635 } |
| 1663 | |
| 1664 capturer_ = NULL; | |
| 1665 return true; | |
| 1666 } | 1636 } |
| 1637 // Clear the original dimensions, set it from first frame. | |
| 1638 input_dimensions_.width = input_dimensions_.height = 0; | |
|
pbos-webrtc
2016/03/31 14:14:31
Rebase on top of other CL when it lands so this ha
nisse-webrtc
2016/04/01 09:35:39
Sure.
| |
| 1667 } | 1639 } |
| 1668 capturer_ = capturer; | 1640 source_ = source; |
| 1669 // |capturer_->AddOrUpdateSink| may not be called while holding |lock_| since | 1641 // |source_->AddOrUpdateSink| may not be called while holding |lock_| since |
| 1670 // that might cause a lock order inversion. | 1642 // that might cause a lock order inversion. |
| 1671 capturer_->AddOrUpdateSink(this, sink_wants_); | 1643 if (source_) { |
| 1672 return true; | 1644 source_->AddOrUpdateSink(this, sink_wants_); |
| 1645 } | |
| 1673 } | 1646 } |
| 1674 | 1647 |
| 1675 void WebRtcVideoChannel2::WebRtcVideoSendStream::MuteStream(bool mute) { | 1648 void WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectSource() { |
| 1676 rtc::CritScope cs(&lock_); | |
| 1677 muted_ = mute; | |
| 1678 } | |
| 1679 | |
| 1680 bool WebRtcVideoChannel2::WebRtcVideoSendStream::DisconnectCapturer() { | |
| 1681 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1649 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 1682 if (capturer_ == NULL) { | 1650 if (source_ == NULL) { |
| 1683 return false; | 1651 return; |
| 1684 } | 1652 } |
| 1685 | 1653 |
| 1686 // |capturer_->RemoveSink| may not be called while holding |lock_| since | 1654 // |source_->RemoveSink| may not be called while holding |lock_| since |
| 1687 // that might cause a lock order inversion. | 1655 // that might cause a lock order inversion. |
| 1688 capturer_->RemoveSink(this); | 1656 source_->RemoveSink(this); |
| 1689 capturer_ = NULL; | 1657 source_ = NULL; |
|
pbos-webrtc
2016/03/31 14:14:31
nullptr
nisse-webrtc
2016/04/01 09:35:39
Done. But it's really inconsistent in this file.
pbos-webrtc
2016/04/01 10:55:28
Acknowledged.
| |
| 1690 // Reset |cpu_restricted_counter_| if the capturer is changed. It is not | 1658 // Reset |cpu_restricted_counter_| if the capturer is changed. It is not |
| 1691 // possible to know if the video resolution is restricted by CPU usage after | 1659 // possible to know if the video resolution is restricted by CPU usage after |
| 1692 // the capturer is changed since the next capturer might be screen capture | 1660 // the capturer is changed since the next capturer might be screen capture |
| 1693 // with another resolution and frame rate. | 1661 // with another resolution and frame rate. |
| 1694 cpu_restricted_counter_ = 0; | 1662 cpu_restricted_counter_ = 0; |
| 1695 return true; | |
| 1696 } | 1663 } |
| 1697 | 1664 |
| 1698 const std::vector<uint32_t>& | 1665 const std::vector<uint32_t>& |
| 1699 WebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { | 1666 WebRtcVideoChannel2::WebRtcVideoSendStream::GetSsrcs() const { |
| 1700 return ssrcs_; | 1667 return ssrcs_; |
| 1701 } | 1668 } |
| 1702 | 1669 |
| 1703 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( | 1670 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( |
| 1704 const VideoOptions& options) { | 1671 const VideoOptions& options) { |
| 1705 rtc::CritScope cs(&lock_); | 1672 rtc::CritScope cs(&lock_); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1843 << "RecreateWebRtcStream (send) because of SetSendParameters"; | 1810 << "RecreateWebRtcStream (send) because of SetSendParameters"; |
| 1844 RecreateWebRtcStream(); | 1811 RecreateWebRtcStream(); |
| 1845 } | 1812 } |
| 1846 } // release |lock_| | 1813 } // release |lock_| |
| 1847 | 1814 |
| 1848 // |capturer_->AddOrUpdateSink| may not be called while holding |lock_| since | 1815 // |capturer_->AddOrUpdateSink| may not be called while holding |lock_| since |
| 1849 // that might cause a lock order inversion. | 1816 // that might cause a lock order inversion. |
| 1850 if (params.rtp_header_extensions) { | 1817 if (params.rtp_header_extensions) { |
| 1851 sink_wants_.rotation_applied = !ContainsHeaderExtension( | 1818 sink_wants_.rotation_applied = !ContainsHeaderExtension( |
| 1852 *params.rtp_header_extensions, kRtpVideoRotationHeaderExtension); | 1819 *params.rtp_header_extensions, kRtpVideoRotationHeaderExtension); |
| 1853 if (capturer_) { | 1820 if (source_) { |
| 1854 capturer_->AddOrUpdateSink(this, sink_wants_); | 1821 source_->AddOrUpdateSink(this, sink_wants_); |
| 1855 } | 1822 } |
| 1856 } | 1823 } |
| 1857 } | 1824 } |
| 1858 | 1825 |
| 1859 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpParameters( | 1826 bool WebRtcVideoChannel2::WebRtcVideoSendStream::SetRtpParameters( |
| 1860 const webrtc::RtpParameters& new_parameters) { | 1827 const webrtc::RtpParameters& new_parameters) { |
| 1861 if (!ValidateRtpParameters(new_parameters)) { | 1828 if (!ValidateRtpParameters(new_parameters)) { |
| 1862 return false; | 1829 return false; |
| 1863 } | 1830 } |
| 1864 | 1831 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1966 encoder_config.streams.size() == 1) { | 1933 encoder_config.streams.size() == 1) { |
| 1967 encoder_config.streams[0].temporal_layer_thresholds_bps.resize( | 1934 encoder_config.streams[0].temporal_layer_thresholds_bps.resize( |
| 1968 GetDefaultVp9TemporalLayers() - 1); | 1935 GetDefaultVp9TemporalLayers() - 1); |
| 1969 } | 1936 } |
| 1970 return encoder_config; | 1937 return encoder_config; |
| 1971 } | 1938 } |
| 1972 | 1939 |
| 1973 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( | 1940 void WebRtcVideoChannel2::WebRtcVideoSendStream::SetDimensions( |
| 1974 int width, | 1941 int width, |
| 1975 int height) { | 1942 int height) { |
| 1943 // TODO(nisse): Using the dimensions of the first seen frame is a | |
| 1944 // crude hack, which happens to more-or-less work with the current | |
| 1945 // cpu adaptation. The proper solution is to add attributes to the | |
| 1946 // frame with the original, pre-adaptation, size. We may want that | |
| 1947 // also for lazy scaling of frames. | |
| 1948 if (input_dimensions_.width == 0 && input_dimensions_.height == 0) { | |
| 1949 input_dimensions_.width = width; | |
| 1950 input_dimensions_.height = height; | |
| 1951 } | |
| 1976 if (last_dimensions_.width == width && last_dimensions_.height == height && | 1952 if (last_dimensions_.width == width && last_dimensions_.height == height && |
| 1977 !pending_encoder_reconfiguration_) { | 1953 !pending_encoder_reconfiguration_) { |
| 1978 // Configured using the same parameters, do not reconfigure. | 1954 // Configured using the same parameters, do not reconfigure. |
| 1979 return; | 1955 return; |
| 1980 } | 1956 } |
| 1981 | 1957 |
| 1982 last_dimensions_.width = width; | 1958 last_dimensions_.width = width; |
| 1983 last_dimensions_.height = height; | 1959 last_dimensions_.height = height; |
| 1984 | 1960 |
| 1985 RTC_DCHECK(!parameters_.encoder_config.streams.empty()); | 1961 RTC_DCHECK(!parameters_.encoder_config.streams.empty()); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 2009 | 1985 |
| 2010 void WebRtcVideoChannel2::WebRtcVideoSendStream::OnLoadUpdate(Load load) { | 1986 void WebRtcVideoChannel2::WebRtcVideoSendStream::OnLoadUpdate(Load load) { |
| 2011 if (worker_thread_ != rtc::Thread::Current()) { | 1987 if (worker_thread_ != rtc::Thread::Current()) { |
| 2012 invoker_.AsyncInvoke<void>( | 1988 invoker_.AsyncInvoke<void>( |
| 2013 worker_thread_, | 1989 worker_thread_, |
| 2014 rtc::Bind(&WebRtcVideoChannel2::WebRtcVideoSendStream::OnLoadUpdate, | 1990 rtc::Bind(&WebRtcVideoChannel2::WebRtcVideoSendStream::OnLoadUpdate, |
| 2015 this, load)); | 1991 this, load)); |
| 2016 return; | 1992 return; |
| 2017 } | 1993 } |
| 2018 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1994 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 2019 if (!capturer_) { | 1995 if (!source_) { |
| 2020 return; | 1996 return; |
| 2021 } | 1997 } |
| 2022 { | 1998 { |
| 2023 rtc::CritScope cs(&lock_); | 1999 rtc::CritScope cs(&lock_); |
| 2024 LOG(LS_INFO) << "OnLoadUpdate " << load << ", is_screencast: " | 2000 LOG(LS_INFO) << "OnLoadUpdate " << load << ", is_screencast: " |
| 2025 << (parameters_.options.is_screencast | 2001 << (parameters_.options.is_screencast |
| 2026 ? (*parameters_.options.is_screencast ? "true" | 2002 ? (*parameters_.options.is_screencast ? "true" |
| 2027 : "false") | 2003 : "false") |
| 2028 : "unset"); | 2004 : "unset"); |
| 2029 // Do not adapt resolution for screen content as this will likely result in | 2005 // Do not adapt resolution for screen content as this will likely result in |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 2056 if (sink_wants_.max_pixel_count || | 2032 if (sink_wants_.max_pixel_count || |
| 2057 (sink_wants_.max_pixel_count_step_up && | 2033 (sink_wants_.max_pixel_count_step_up && |
| 2058 *sink_wants_.max_pixel_count_step_up < *max_pixel_count_step_up)) { | 2034 *sink_wants_.max_pixel_count_step_up < *max_pixel_count_step_up)) { |
| 2059 ++number_of_cpu_adapt_changes_; | 2035 ++number_of_cpu_adapt_changes_; |
| 2060 --cpu_restricted_counter_; | 2036 --cpu_restricted_counter_; |
| 2061 } | 2037 } |
| 2062 } | 2038 } |
| 2063 sink_wants_.max_pixel_count = max_pixel_count; | 2039 sink_wants_.max_pixel_count = max_pixel_count; |
| 2064 sink_wants_.max_pixel_count_step_up = max_pixel_count_step_up; | 2040 sink_wants_.max_pixel_count_step_up = max_pixel_count_step_up; |
| 2065 } | 2041 } |
| 2066 // |capturer_->AddOrUpdateSink| may not be called while holding |lock_| since | 2042 // |source_->AddOrUpdateSink| may not be called while holding |lock_| since |
| 2067 // that might cause a lock order inversion. | 2043 // that might cause a lock order inversion. |
| 2068 capturer_->AddOrUpdateSink(this, sink_wants_); | 2044 source_->AddOrUpdateSink(this, sink_wants_); |
| 2069 } | 2045 } |
| 2070 | 2046 |
| 2071 VideoSenderInfo | 2047 VideoSenderInfo |
| 2072 WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { | 2048 WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() { |
| 2073 VideoSenderInfo info; | 2049 VideoSenderInfo info; |
| 2074 webrtc::VideoSendStream::Stats stats; | 2050 webrtc::VideoSendStream::Stats stats; |
| 2075 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2051 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 2076 { | 2052 { |
| 2077 rtc::CritScope cs(&lock_); | 2053 rtc::CritScope cs(&lock_); |
| 2078 for (uint32_t ssrc : parameters_.config.rtp.ssrcs) | 2054 for (uint32_t ssrc : parameters_.config.rtp.ssrcs) |
| 2079 info.add_ssrc(ssrc); | 2055 info.add_ssrc(ssrc); |
| 2080 | 2056 |
| 2081 if (parameters_.codec_settings) | 2057 if (parameters_.codec_settings) |
| 2082 info.codec_name = parameters_.codec_settings->codec.name; | 2058 info.codec_name = parameters_.codec_settings->codec.name; |
| 2083 for (size_t i = 0; i < parameters_.encoder_config.streams.size(); ++i) { | 2059 for (size_t i = 0; i < parameters_.encoder_config.streams.size(); ++i) { |
| 2084 if (i == parameters_.encoder_config.streams.size() - 1) { | 2060 if (i == parameters_.encoder_config.streams.size() - 1) { |
| 2085 info.preferred_bitrate += | 2061 info.preferred_bitrate += |
| 2086 parameters_.encoder_config.streams[i].max_bitrate_bps; | 2062 parameters_.encoder_config.streams[i].max_bitrate_bps; |
| 2087 } else { | 2063 } else { |
| 2088 info.preferred_bitrate += | 2064 info.preferred_bitrate += |
| 2089 parameters_.encoder_config.streams[i].target_bitrate_bps; | 2065 parameters_.encoder_config.streams[i].target_bitrate_bps; |
| 2090 } | 2066 } |
| 2091 } | 2067 } |
| 2092 | 2068 |
| 2093 if (stream_ == NULL) | 2069 if (stream_ == NULL) |
| 2094 return info; | 2070 return info; |
| 2095 | 2071 |
| 2096 stats = stream_->GetStats(); | 2072 stats = stream_->GetStats(); |
| 2073 | |
| 2074 info.input_frame_width = input_dimensions_.width; | |
| 2075 info.input_frame_height = input_dimensions_.height; | |
| 2097 } | 2076 } |
| 2098 info.adapt_changes = number_of_cpu_adapt_changes_; | 2077 info.adapt_changes = number_of_cpu_adapt_changes_; |
| 2099 info.adapt_reason = cpu_restricted_counter_ <= 0 | 2078 info.adapt_reason = cpu_restricted_counter_ <= 0 |
| 2100 ? CoordinatedVideoAdapter::ADAPTREASON_NONE | 2079 ? CoordinatedVideoAdapter::ADAPTREASON_NONE |
| 2101 : CoordinatedVideoAdapter::ADAPTREASON_CPU; | 2080 : CoordinatedVideoAdapter::ADAPTREASON_CPU; |
| 2102 | 2081 |
| 2103 if (capturer_) { | |
| 2104 VideoFormat last_captured_frame_format; | |
| 2105 capturer_->GetStats(&last_captured_frame_format); | |
| 2106 info.input_frame_width = last_captured_frame_format.width; | |
| 2107 info.input_frame_height = last_captured_frame_format.height; | |
| 2108 } | |
| 2109 | |
| 2110 // Get bandwidth limitation info from stream_->GetStats(). | 2082 // Get bandwidth limitation info from stream_->GetStats(). |
| 2111 // Input resolution (output from video_adapter) can be further scaled down or | 2083 // Input resolution (output from video_adapter) can be further scaled down or |
| 2112 // higher video layer(s) can be dropped due to bitrate constraints. | 2084 // higher video layer(s) can be dropped due to bitrate constraints. |
| 2113 // Note, adapt_changes only include changes from the video_adapter. | 2085 // Note, adapt_changes only include changes from the video_adapter. |
| 2114 if (stats.bw_limited_resolution) | 2086 if (stats.bw_limited_resolution) |
| 2115 info.adapt_reason |= CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH; | 2087 info.adapt_reason |= CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH; |
| 2116 | 2088 |
| 2117 info.encoder_implementation_name = stats.encoder_implementation_name; | 2089 info.encoder_implementation_name = stats.encoder_implementation_name; |
| 2118 info.ssrc_groups = ssrc_groups_; | 2090 info.ssrc_groups = ssrc_groups_; |
| 2119 info.framerate_input = stats.input_frame_rate; | 2091 info.framerate_input = stats.input_frame_rate; |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2604 rtx_mapping[video_codecs[i].codec.id] != | 2576 rtx_mapping[video_codecs[i].codec.id] != |
| 2605 fec_settings.red_payload_type) { | 2577 fec_settings.red_payload_type) { |
| 2606 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; | 2578 video_codecs[i].rtx_payload_type = rtx_mapping[video_codecs[i].codec.id]; |
| 2607 } | 2579 } |
| 2608 } | 2580 } |
| 2609 | 2581 |
| 2610 return video_codecs; | 2582 return video_codecs; |
| 2611 } | 2583 } |
| 2612 | 2584 |
| 2613 } // namespace cricket | 2585 } // namespace cricket |
| OLD | NEW |