Removed all RTP dependencies from ViEChannel and renamed class.
ViEChannel is now called VideoStreamReceiver. There will be a follow up CL removing all rtp references from VideoReceiveStream, but that made this CL to big and it will be done separately. BUG=webrtc:5079 Review-Url: https://codereview.webrtc.org/1929313002 Cr-Commit-Position: refs/heads/master@{#12619}
This commit is contained in:
parent
fe4b21641b
commit
cfc8e3b9ef
@ -40,8 +40,8 @@ source_set("video") {
|
||||
"video_receive_stream.h",
|
||||
"video_send_stream.cc",
|
||||
"video_send_stream.h",
|
||||
"vie_channel.cc",
|
||||
"vie_channel.h",
|
||||
"video_stream_decoder.cc",
|
||||
"video_stream_decoder.h",
|
||||
"vie_encoder.cc",
|
||||
"vie_encoder.h",
|
||||
"vie_remb.cc",
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
#include "webrtc/common_video/include/frame_callback.h"
|
||||
#include "webrtc/modules/video_coding/include/video_coding_defines.h"
|
||||
#include "webrtc/video/report_block_stats.h"
|
||||
#include "webrtc/video/vie_channel.h"
|
||||
#include "webrtc/video/video_stream_decoder.h"
|
||||
#include "webrtc/video_receive_stream.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/common_types.h"
|
||||
#include "webrtc/config.h"
|
||||
#include "webrtc/modules/pacing/packet_router.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
@ -27,6 +28,7 @@
|
||||
#include "webrtc/system_wrappers/include/tick_util.h"
|
||||
#include "webrtc/system_wrappers/include/timestamp_extrapolator.h"
|
||||
#include "webrtc/system_wrappers/include/trace.h"
|
||||
#include "webrtc/video/receive_statistics_proxy.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -65,7 +67,6 @@ std::unique_ptr<RtpRtcp> CreateRtpRtcpModule(
|
||||
return rtp_rtcp;
|
||||
}
|
||||
|
||||
|
||||
static const int kPacketLogIntervalMs = 10000;
|
||||
|
||||
RtpStreamReceiver::RtpStreamReceiver(
|
||||
@ -74,7 +75,9 @@ RtpStreamReceiver::RtpStreamReceiver(
|
||||
Transport* transport,
|
||||
RtcpRttStats* rtt_stats,
|
||||
PacedSender* paced_sender,
|
||||
PacketRouter* packet_router)
|
||||
PacketRouter* packet_router,
|
||||
const VideoReceiveStream::Config& config,
|
||||
ReceiveStatisticsProxy* receive_stats_proxy)
|
||||
: clock_(Clock::GetRealTimeClock()),
|
||||
video_receiver_(video_receiver),
|
||||
remote_bitrate_estimator_(remote_bitrate_estimator),
|
||||
@ -94,12 +97,27 @@ RtpStreamReceiver::RtpStreamReceiver(
|
||||
rtp_rtcp_(CreateRtpRtcpModule(rtp_receive_statistics_.get(),
|
||||
transport,
|
||||
rtt_stats,
|
||||
&rtcp_packet_type_counter_observer_,
|
||||
receive_stats_proxy,
|
||||
remote_bitrate_estimator_,
|
||||
paced_sender,
|
||||
packet_router)) {
|
||||
packet_router_->AddRtpModule(rtp_rtcp_.get());
|
||||
rtp_receive_statistics_->RegisterRtpStatisticsCallback(receive_stats_proxy);
|
||||
rtp_receive_statistics_->RegisterRtcpStatisticsCallback(receive_stats_proxy);
|
||||
|
||||
RTC_DCHECK(config.rtp.rtcp_mode != RtcpMode::kOff)
|
||||
<< "A stream should not be configured with RTCP disabled. This value is "
|
||||
"reserved for internal usage.";
|
||||
rtp_rtcp_->SetRTCPStatus(config.rtp.rtcp_mode);
|
||||
rtp_rtcp_->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp);
|
||||
|
||||
static const int kMaxPacketAgeToNack = 450;
|
||||
NACKMethod nack_method =
|
||||
config.rtp.nack.rtp_history_ms > 0 ? kNackRtcp : kNackOff;
|
||||
const int max_reordering_threshold = (nack_method == kNackRtcp)
|
||||
? kMaxPacketAgeToNack : kDefaultMaxReorderingThreshold;
|
||||
rtp_receiver_->SetNACKStatus(nack_method);
|
||||
rtp_receive_statistics_->SetMaxReorderingThreshold(max_reordering_threshold);
|
||||
}
|
||||
|
||||
RtpStreamReceiver::~RtpStreamReceiver() {
|
||||
@ -135,18 +153,6 @@ bool RtpStreamReceiver::SetReceiveCodec(const VideoCodec& video_codec) {
|
||||
0, 0) == 0;
|
||||
}
|
||||
|
||||
void RtpStreamReceiver::SetNackStatus(bool enable,
|
||||
int max_nack_reordering_threshold) {
|
||||
if (!enable) {
|
||||
// Reset the threshold back to the lower default threshold when NACK is
|
||||
// disabled since we no longer will be receiving retransmissions.
|
||||
max_nack_reordering_threshold = kDefaultMaxReorderingThreshold;
|
||||
}
|
||||
rtp_receive_statistics_->SetMaxReorderingThreshold(
|
||||
max_nack_reordering_threshold);
|
||||
rtp_receiver_->SetNACKStatus(enable ? kNackRtcp : kNackOff);
|
||||
}
|
||||
|
||||
void RtpStreamReceiver::SetRtxPayloadType(int payload_type,
|
||||
int associated_payload_type) {
|
||||
rtp_payload_registry_.SetRtxPayloadType(payload_type,
|
||||
@ -188,12 +194,6 @@ void RtpStreamReceiver::EnableReceiveRtpHeaderExtension(
|
||||
StringToRtpExtensionType(extension), id));
|
||||
}
|
||||
|
||||
void RtpStreamReceiver::RegisterRtcpPacketTypeCounterObserver(
|
||||
RtcpPacketTypeCounterObserver* observer) {
|
||||
rtcp_packet_type_counter_observer_.Set(observer);
|
||||
}
|
||||
|
||||
|
||||
int32_t RtpStreamReceiver::OnReceivedPayloadData(
|
||||
const uint8_t* payload_data,
|
||||
const size_t payload_size,
|
||||
@ -294,6 +294,21 @@ bool RtpStreamReceiver::DeliverRtp(const uint8_t* rtp_packet,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t RtpStreamReceiver::RequestKeyFrame() {
|
||||
return rtp_rtcp_->RequestKeyFrame();
|
||||
}
|
||||
|
||||
int32_t RtpStreamReceiver::SliceLossIndicationRequest(
|
||||
const uint64_t picture_id) {
|
||||
return rtp_rtcp_->SendRTCPSliceLossIndication(
|
||||
static_cast<uint8_t>(picture_id));
|
||||
}
|
||||
|
||||
int32_t RtpStreamReceiver::ResendPackets(const uint16_t* sequence_numbers,
|
||||
uint16_t length) {
|
||||
return rtp_rtcp_->SendNACK(sequence_numbers, length);
|
||||
}
|
||||
|
||||
bool RtpStreamReceiver::ReceivePacket(const uint8_t* packet,
|
||||
size_t packet_length,
|
||||
const RTPHeader& header,
|
||||
|
||||
@ -24,7 +24,9 @@
|
||||
#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
|
||||
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
|
||||
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "webrtc/modules/video_coding/include/video_coding_defines.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
#include "webrtc/video_receive_stream.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -33,6 +35,7 @@ class PacedSender;
|
||||
class PacketRouter;
|
||||
class RemoteNtpTimeEstimator;
|
||||
class ReceiveStatistics;
|
||||
class ReceiveStatisticsProxy;
|
||||
class RemoteBitrateEstimator;
|
||||
class RtcpRttStats;
|
||||
class RtpHeaderParser;
|
||||
@ -44,19 +47,22 @@ namespace vcm {
|
||||
class VideoReceiver;
|
||||
} // namespace vcm
|
||||
|
||||
class RtpStreamReceiver : public RtpData, public RtpFeedback {
|
||||
class RtpStreamReceiver : public RtpData, public RtpFeedback,
|
||||
public VCMFrameTypeCallback,
|
||||
public VCMPacketRequestCallback {
|
||||
public:
|
||||
RtpStreamReceiver(vcm::VideoReceiver* video_receiver,
|
||||
RemoteBitrateEstimator* remote_bitrate_estimator,
|
||||
Transport* transport,
|
||||
RtcpRttStats* rtt_stats,
|
||||
PacedSender* paced_sender,
|
||||
PacketRouter* packet_router);
|
||||
PacketRouter* packet_router,
|
||||
const VideoReceiveStream::Config& config,
|
||||
ReceiveStatisticsProxy* receive_stats_proxy);
|
||||
~RtpStreamReceiver();
|
||||
|
||||
bool SetReceiveCodec(const VideoCodec& video_codec);
|
||||
|
||||
void SetNackStatus(bool enable, int max_nack_reordering_threshold);
|
||||
void SetRtxPayloadType(int payload_type, int associated_payload_type);
|
||||
// If set to true, the RTX payload type mapping supplied in
|
||||
// |SetRtxPayloadType| will be used when restoring RTX packets. Without it,
|
||||
@ -75,8 +81,6 @@ class RtpStreamReceiver : public RtpData, public RtpFeedback {
|
||||
RtpRtcp* rtp_rtcp() const { return rtp_rtcp_.get(); }
|
||||
|
||||
void EnableReceiveRtpHeaderExtension(const std::string& extension, int id);
|
||||
void RegisterRtcpPacketTypeCounterObserver(
|
||||
RtcpPacketTypeCounterObserver* observer);
|
||||
|
||||
void StartReceive();
|
||||
void StopReceive();
|
||||
@ -101,43 +105,16 @@ class RtpStreamReceiver : public RtpData, public RtpFeedback {
|
||||
void OnIncomingSSRCChanged(const uint32_t ssrc) override;
|
||||
void OnIncomingCSRCChanged(const uint32_t CSRC, const bool added) override {}
|
||||
|
||||
// Implements VCMFrameTypeCallback.
|
||||
int32_t RequestKeyFrame() override;
|
||||
int32_t SliceLossIndicationRequest(const uint64_t picture_id) override;
|
||||
|
||||
// Implements VCMPacketRequestCallback.
|
||||
int32_t ResendPackets(const uint16_t* sequenceNumbers,
|
||||
uint16_t length) override;
|
||||
|
||||
ReceiveStatistics* GetReceiveStatistics() const;
|
||||
|
||||
template <class T>
|
||||
class RegisterableCallback : public T {
|
||||
public:
|
||||
RegisterableCallback() : callback_(nullptr) {}
|
||||
|
||||
void Set(T* callback) {
|
||||
rtc::CritScope lock(&critsect_);
|
||||
callback_ = callback;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Note: this should be implemented with a RW-lock to allow simultaneous
|
||||
// calls into the callback. However that doesn't seem to be needed for the
|
||||
// current type of callbacks covered by this class.
|
||||
rtc::CriticalSection critsect_;
|
||||
T* callback_ GUARDED_BY(critsect_);
|
||||
|
||||
private:
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(RegisterableCallback);
|
||||
};
|
||||
|
||||
class RegisterableRtcpPacketTypeCounterObserver
|
||||
: public RegisterableCallback<RtcpPacketTypeCounterObserver> {
|
||||
public:
|
||||
void RtcpPacketTypesCounterUpdated(
|
||||
uint32_t ssrc,
|
||||
const RtcpPacketTypeCounter& packet_counter) override {
|
||||
rtc::CritScope lock(&critsect_);
|
||||
if (callback_)
|
||||
callback_->RtcpPacketTypesCounterUpdated(ssrc, packet_counter);
|
||||
}
|
||||
|
||||
private:
|
||||
} rtcp_packet_type_counter_observer_;
|
||||
|
||||
private:
|
||||
bool ReceivePacket(const uint8_t* packet,
|
||||
size_t packet_length,
|
||||
|
||||
@ -171,29 +171,30 @@ VideoReceiveStream::VideoReceiveStream(
|
||||
&transport_adapter_,
|
||||
call_stats_->rtcp_rtt_stats(),
|
||||
congestion_controller_->pacer(),
|
||||
congestion_controller_->packet_router()),
|
||||
vie_channel_(&video_receiver_,
|
||||
&rtp_stream_receiver_),
|
||||
congestion_controller_->packet_router(),
|
||||
config,
|
||||
&stats_proxy_),
|
||||
video_stream_decoder_(&video_receiver_,
|
||||
&rtp_stream_receiver_,
|
||||
&rtp_stream_receiver_,
|
||||
config.rtp.nack.rtp_history_ms > 0,
|
||||
&stats_proxy_,
|
||||
&incoming_video_stream_,
|
||||
this),
|
||||
vie_sync_(&video_receiver_),
|
||||
rtp_rtcp_(vie_channel_.rtp_rtcp()) {
|
||||
rtp_rtcp_(rtp_stream_receiver_.rtp_rtcp()) {
|
||||
LOG(LS_INFO) << "VideoReceiveStream: " << config_.ToString();
|
||||
|
||||
RTC_DCHECK(process_thread_);
|
||||
RTC_DCHECK(congestion_controller_);
|
||||
RTC_DCHECK(call_stats_);
|
||||
RTC_DCHECK(remb_);
|
||||
RTC_CHECK(vie_channel_.Init() == 0);
|
||||
|
||||
// Register the channel to receive stats updates.
|
||||
call_stats_->RegisterStatsObserver(vie_channel_.GetStatsObserver());
|
||||
|
||||
// TODO(pbos): This is not fine grained enough...
|
||||
vie_channel_.SetProtectionMode(config_.rtp.nack.rtp_history_ms > 0, false, -1,
|
||||
-1);
|
||||
RTC_DCHECK(config_.rtp.rtcp_mode != RtcpMode::kOff)
|
||||
<< "A stream should not be configured with RTCP disabled. This value is "
|
||||
"reserved for internal usage.";
|
||||
rtp_rtcp_->SetRTCPStatus(config_.rtp.rtcp_mode);
|
||||
|
||||
// Register the channel to receive stats updates.
|
||||
call_stats_->RegisterStatsObserver(&video_stream_decoder_);
|
||||
|
||||
RTC_DCHECK(config_.rtp.remote_ssrc != 0);
|
||||
// TODO(pbos): What's an appropriate local_ssrc for receive-only streams?
|
||||
@ -255,14 +256,8 @@ VideoReceiveStream::VideoReceiveStream(
|
||||
if (config.rtp.rtcp_xr.receiver_reference_time_report)
|
||||
rtp_rtcp_->SetRtcpXrRrtrStatus(true);
|
||||
|
||||
vie_channel_.RegisterReceiveStatisticsProxy(&stats_proxy_);
|
||||
rtp_stream_receiver_.GetReceiveStatistics()->RegisterRtpStatisticsCallback(
|
||||
&stats_proxy_);
|
||||
rtp_stream_receiver_.GetReceiveStatistics()->RegisterRtcpStatisticsCallback(
|
||||
&stats_proxy_);
|
||||
// Stats callback for CNAME changes.
|
||||
rtp_rtcp_->RegisterRtcpStatisticsCallback(&stats_proxy_);
|
||||
vie_channel_.RegisterRtcpPacketTypeCounterObserver(&stats_proxy_);
|
||||
|
||||
RTC_DCHECK(!config_.decoders.empty());
|
||||
std::set<int> decoder_payload_types;
|
||||
@ -286,8 +281,6 @@ VideoReceiveStream::VideoReceiveStream(
|
||||
video_receiver_.SetRenderDelay(config.render_delay_ms);
|
||||
incoming_video_stream_.SetExpectedRenderDelay(config.render_delay_ms);
|
||||
incoming_video_stream_.SetExternalCallback(this);
|
||||
vie_channel_.SetIncomingVideoStream(&incoming_video_stream_);
|
||||
vie_channel_.RegisterPreRenderCallback(this);
|
||||
|
||||
process_thread_->RegisterModule(rtp_stream_receiver_.GetReceiveStatistics());
|
||||
process_thread_->RegisterModule(rtp_stream_receiver_.rtp_rtcp());
|
||||
@ -305,16 +298,14 @@ VideoReceiveStream::~VideoReceiveStream() {
|
||||
process_thread_->DeRegisterModule(
|
||||
rtp_stream_receiver_.GetReceiveStatistics());
|
||||
|
||||
// Deregister external decoders so that they are no longer running during
|
||||
// Deregister external decoders so they are no longer running during
|
||||
// destruction. This effectively stops the VCM since the decoder thread is
|
||||
// stopped, the VCM is deregistered and no asynchronous decoder threads are
|
||||
// running.
|
||||
for (const Decoder& decoder : config_.decoders)
|
||||
video_receiver_.RegisterExternalDecoder(nullptr, decoder.payload_type);
|
||||
|
||||
vie_channel_.RegisterPreRenderCallback(nullptr);
|
||||
|
||||
call_stats_->DeregisterStatsObserver(vie_channel_.GetStatsObserver());
|
||||
call_stats_->DeregisterStatsObserver(&video_stream_decoder_);
|
||||
rtp_rtcp_->SetREMBStatus(false);
|
||||
remb_->RemoveReceiveChannel(rtp_rtcp_);
|
||||
|
||||
|
||||
@ -22,9 +22,8 @@
|
||||
#include "webrtc/system_wrappers/include/clock.h"
|
||||
#include "webrtc/video/encoded_frame_callback_adapter.h"
|
||||
#include "webrtc/video/receive_statistics_proxy.h"
|
||||
#include "webrtc/video/vie_channel.h"
|
||||
#include "webrtc/video/vie_encoder.h"
|
||||
#include "webrtc/video_encoder.h"
|
||||
#include "webrtc/video/rtp_stream_receiver.h"
|
||||
#include "webrtc/video/video_stream_decoder.h"
|
||||
#include "webrtc/video_receive_stream.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -107,7 +106,7 @@ class VideoReceiveStream : public webrtc::VideoReceiveStream,
|
||||
IncomingVideoStream incoming_video_stream_;
|
||||
ReceiveStatisticsProxy stats_proxy_;
|
||||
RtpStreamReceiver rtp_stream_receiver_;
|
||||
ViEChannel vie_channel_;
|
||||
VideoStreamDecoder video_stream_decoder_;
|
||||
ViESyncModule vie_sync_;
|
||||
RtpRtcp* const rtp_rtcp_;
|
||||
|
||||
|
||||
@ -25,7 +25,6 @@
|
||||
#include "webrtc/video/send_delay_stats.h"
|
||||
#include "webrtc/video/send_statistics_proxy.h"
|
||||
#include "webrtc/video/video_capture_input.h"
|
||||
#include "webrtc/video/vie_channel.h"
|
||||
#include "webrtc/video/vie_encoder.h"
|
||||
#include "webrtc/video_receive_stream.h"
|
||||
#include "webrtc/video_send_stream.h"
|
||||
@ -37,7 +36,6 @@ class CallStats;
|
||||
class CongestionController;
|
||||
class ProcessThread;
|
||||
class RtpRtcp;
|
||||
class ViEChannel;
|
||||
class ViEEncoder;
|
||||
class VieRemb;
|
||||
|
||||
|
||||
132
webrtc/video/video_stream_decoder.cc
Normal file
132
webrtc/video/video_stream_decoder.cc
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/video/video_stream_decoder.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/common_video/include/frame_callback.h"
|
||||
#include "webrtc/common_video/include/incoming_video_stream.h"
|
||||
#include "webrtc/modules/video_coding/video_coding_impl.h"
|
||||
#include "webrtc/modules/video_processing/include/video_processing.h"
|
||||
#include "webrtc/system_wrappers/include/metrics.h"
|
||||
#include "webrtc/video/call_stats.h"
|
||||
#include "webrtc/video/payload_router.h"
|
||||
#include "webrtc/video/receive_statistics_proxy.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
VideoStreamDecoder::VideoStreamDecoder(
|
||||
vcm::VideoReceiver* video_receiver,
|
||||
VCMFrameTypeCallback* vcm_frame_type_callback,
|
||||
VCMPacketRequestCallback* vcm_packet_request_callback,
|
||||
bool enable_nack,
|
||||
ReceiveStatisticsProxy* receive_statistics_proxy,
|
||||
IncomingVideoStream* incoming_video_stream,
|
||||
I420FrameCallback* pre_render_callback)
|
||||
: video_receiver_(video_receiver),
|
||||
receive_stats_callback_(receive_statistics_proxy),
|
||||
incoming_video_stream_(incoming_video_stream),
|
||||
pre_render_callback_(pre_render_callback),
|
||||
last_rtt_ms_(0) {
|
||||
RTC_DCHECK(video_receiver_);
|
||||
|
||||
static const int kMaxPacketAgeToNack = 450;
|
||||
static const int kMaxNackListSize = 250;
|
||||
video_receiver_->SetNackSettings(kMaxNackListSize,
|
||||
kMaxPacketAgeToNack, 0);
|
||||
video_receiver_->RegisterReceiveCallback(this);
|
||||
video_receiver_->RegisterFrameTypeCallback(vcm_frame_type_callback);
|
||||
video_receiver_->RegisterReceiveStatisticsCallback(this);
|
||||
video_receiver_->RegisterDecoderTimingCallback(this);
|
||||
static const int kDefaultRenderDelayMs = 10;
|
||||
video_receiver_->SetRenderDelay(kDefaultRenderDelayMs);
|
||||
|
||||
VCMVideoProtection video_protection = enable_nack ? kProtectionNack
|
||||
: kProtectionNone;
|
||||
VCMDecodeErrorMode decode_error_mode = enable_nack ? kNoErrors : kWithErrors;
|
||||
video_receiver_->SetVideoProtection(video_protection, true);
|
||||
video_receiver_->SetDecodeErrorMode(decode_error_mode);
|
||||
VCMPacketRequestCallback* packet_request_callback =
|
||||
enable_nack ? vcm_packet_request_callback : nullptr;
|
||||
video_receiver_->RegisterPacketRequestCallback(packet_request_callback);
|
||||
}
|
||||
|
||||
VideoStreamDecoder::~VideoStreamDecoder() {}
|
||||
|
||||
// Do not acquire the lock of |video_receiver_| in this function. Decode
|
||||
// callback won't necessarily be called from the decoding thread. The decoding
|
||||
// thread may have held the lock when calling VideoDecoder::Decode, Reset, or
|
||||
// Release. Acquiring the same lock in the path of decode callback can deadlock.
|
||||
int32_t VideoStreamDecoder::FrameToRender(VideoFrame& video_frame) { // NOLINT
|
||||
if (pre_render_callback_)
|
||||
pre_render_callback_->FrameCallback(&video_frame);
|
||||
|
||||
incoming_video_stream_->OnFrame(video_frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t VideoStreamDecoder::ReceivedDecodedReferenceFrame(
|
||||
const uint64_t picture_id) {
|
||||
RTC_NOTREACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void VideoStreamDecoder::OnIncomingPayloadType(int payload_type) {
|
||||
receive_stats_callback_->OnIncomingPayloadType(payload_type);
|
||||
}
|
||||
|
||||
void VideoStreamDecoder::OnDecoderImplementationName(
|
||||
const char* implementation_name) {
|
||||
receive_stats_callback_->OnDecoderImplementationName(implementation_name);
|
||||
}
|
||||
|
||||
void VideoStreamDecoder::OnReceiveRatesUpdated(uint32_t bit_rate,
|
||||
uint32_t frame_rate) {
|
||||
receive_stats_callback_->OnIncomingRate(frame_rate, bit_rate);
|
||||
}
|
||||
|
||||
void VideoStreamDecoder::OnDiscardedPacketsUpdated(int discarded_packets) {
|
||||
receive_stats_callback_->OnDiscardedPacketsUpdated(discarded_packets);
|
||||
}
|
||||
|
||||
void VideoStreamDecoder::OnFrameCountsUpdated(const FrameCounts& frame_counts) {
|
||||
receive_stats_callback_->OnFrameCountsUpdated(frame_counts);
|
||||
}
|
||||
|
||||
void VideoStreamDecoder::OnDecoderTiming(int decode_ms,
|
||||
int max_decode_ms,
|
||||
int current_delay_ms,
|
||||
int target_delay_ms,
|
||||
int jitter_buffer_ms,
|
||||
int min_playout_delay_ms,
|
||||
int render_delay_ms) {
|
||||
int last_rtt = -1;
|
||||
{
|
||||
rtc::CritScope lock(&crit_);
|
||||
last_rtt = last_rtt_ms_;
|
||||
}
|
||||
|
||||
receive_stats_callback_->OnDecoderTiming(
|
||||
decode_ms, max_decode_ms, current_delay_ms, target_delay_ms,
|
||||
jitter_buffer_ms, min_playout_delay_ms, render_delay_ms, last_rtt);
|
||||
}
|
||||
|
||||
void VideoStreamDecoder::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
|
||||
video_receiver_->SetReceiveChannelParameters(max_rtt_ms);
|
||||
|
||||
rtc::CritScope lock(&crit_);
|
||||
last_rtt_ms_ = avg_rtt_ms;
|
||||
}
|
||||
} // namespace webrtc
|
||||
@ -8,8 +8,8 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_VIDEO_VIE_CHANNEL_H_
|
||||
#define WEBRTC_VIDEO_VIE_CHANNEL_H_
|
||||
#ifndef WEBRTC_VIDEO_VIDEO_STREAM_DECODER_H_
|
||||
#define WEBRTC_VIDEO_VIDEO_STREAM_DECODER_H_
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
@ -20,12 +20,9 @@
|
||||
#include "webrtc/base/platform_thread.h"
|
||||
#include "webrtc/base/scoped_ref_ptr.h"
|
||||
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
|
||||
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "webrtc/modules/video_coding/include/video_coding_defines.h"
|
||||
#include "webrtc/system_wrappers/include/tick_util.h"
|
||||
#include "webrtc/typedefs.h"
|
||||
#include "webrtc/video/rtp_stream_receiver.h"
|
||||
#include "webrtc/video/vie_sync_module.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -36,12 +33,8 @@ class Config;
|
||||
class EncodedImageCallback;
|
||||
class I420FrameCallback;
|
||||
class IncomingVideoStream;
|
||||
class PacedSender;
|
||||
class PacketRouter;
|
||||
class PayloadRouter;
|
||||
class ReceiveStatisticsProxy;
|
||||
class RtcpRttStats;
|
||||
class ViERTPObserver;
|
||||
class VideoRenderCallback;
|
||||
class VoEVideoSync;
|
||||
|
||||
namespace vcm {
|
||||
@ -53,39 +46,25 @@ enum StreamType {
|
||||
kViEStreamTypeRtx = 1 // Retransmission media stream
|
||||
};
|
||||
|
||||
class ViEChannel : public VCMFrameTypeCallback,
|
||||
public VCMReceiveCallback,
|
||||
public VCMReceiveStatisticsCallback,
|
||||
public VCMDecoderTimingCallback,
|
||||
public VCMPacketRequestCallback {
|
||||
class VideoStreamDecoder : public VCMReceiveCallback,
|
||||
public VCMReceiveStatisticsCallback,
|
||||
public VCMDecoderTimingCallback,
|
||||
public CallStatsObserver {
|
||||
public:
|
||||
friend class ChannelStatsObserver;
|
||||
|
||||
ViEChannel(vcm::VideoReceiver* video_receiver,
|
||||
RtpStreamReceiver* rtp_stream_receiver);
|
||||
~ViEChannel();
|
||||
|
||||
int32_t Init();
|
||||
|
||||
RtpRtcp* rtp_rtcp() const { return rtp_rtcp_; }
|
||||
|
||||
void SetProtectionMode(bool enable_nack,
|
||||
bool enable_fec,
|
||||
int payload_type_red,
|
||||
int payload_type_fec);
|
||||
|
||||
RtpState GetRtpStateForSsrc(uint32_t ssrc) const;
|
||||
|
||||
|
||||
CallStatsObserver* GetStatsObserver();
|
||||
VideoStreamDecoder(vcm::VideoReceiver* video_receiver,
|
||||
VCMFrameTypeCallback* vcm_frame_type_callback,
|
||||
VCMPacketRequestCallback* vcm_packet_request_callback,
|
||||
bool enable_nack,
|
||||
ReceiveStatisticsProxy* receive_statistics_proxy,
|
||||
IncomingVideoStream* incoming_video_stream,
|
||||
I420FrameCallback* pre_render_callback);
|
||||
~VideoStreamDecoder();
|
||||
|
||||
// Implements VCMReceiveCallback.
|
||||
int32_t FrameToRender(VideoFrame& video_frame) override; // NOLINT
|
||||
|
||||
// Implements VCMReceiveCallback.
|
||||
int32_t ReceivedDecodedReferenceFrame(const uint64_t picture_id) override;
|
||||
|
||||
// Implements VCMReceiveCallback.
|
||||
void OnIncomingPayloadType(int payload_type) override;
|
||||
void OnDecoderImplementationName(const char* implementation_name) override;
|
||||
|
||||
@ -103,58 +82,31 @@ class ViEChannel : public VCMFrameTypeCallback,
|
||||
int min_playout_delay_ms,
|
||||
int render_delay_ms) override;
|
||||
|
||||
// Implements FrameTypeCallback.
|
||||
int32_t RequestKeyFrame() override;
|
||||
|
||||
// Implements FrameTypeCallback.
|
||||
int32_t SliceLossIndicationRequest(
|
||||
const uint64_t picture_id) override;
|
||||
|
||||
// Implements VideoPacketRequestCallback.
|
||||
int32_t ResendPackets(const uint16_t* sequence_numbers,
|
||||
uint16_t length) override;
|
||||
|
||||
void RegisterPreRenderCallback(I420FrameCallback* pre_render_callback);
|
||||
|
||||
void RegisterRtcpPacketTypeCounterObserver(
|
||||
RtcpPacketTypeCounterObserver* observer);
|
||||
void RegisterReceiveStatisticsProxy(
|
||||
ReceiveStatisticsProxy* receive_statistics_proxy);
|
||||
void SetIncomingVideoStream(IncomingVideoStream* incoming_video_stream);
|
||||
|
||||
protected:
|
||||
void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms);
|
||||
// Implements StatsObserver.
|
||||
void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override;
|
||||
|
||||
private:
|
||||
// Assumed to be protected.
|
||||
void StartDecodeThread();
|
||||
void StopDecodeThread();
|
||||
|
||||
void ProcessNACKRequest(const bool enable);
|
||||
// Compute NACK list parameters for the buffering mode.
|
||||
int GetRequiredNackListSize(int target_delay_ms);
|
||||
|
||||
// Used for all registered callbacks except rendering.
|
||||
rtc::CriticalSection crit_;
|
||||
|
||||
vcm::VideoReceiver* const video_receiver_;
|
||||
RtpStreamReceiver* const rtp_stream_receiver_;
|
||||
RtpRtcp* const rtp_rtcp_;
|
||||
|
||||
// Helper to report call statistics.
|
||||
std::unique_ptr<ChannelStatsObserver> stats_observer_;
|
||||
ReceiveStatisticsProxy* const receive_stats_callback_;
|
||||
IncomingVideoStream* const incoming_video_stream_;
|
||||
|
||||
// Not owned.
|
||||
ReceiveStatisticsProxy* receive_stats_callback_ GUARDED_BY(crit_);
|
||||
FrameCounts receive_frame_counts_ GUARDED_BY(crit_);
|
||||
IncomingVideoStream* incoming_video_stream_ GUARDED_BY(crit_);
|
||||
|
||||
int max_nack_reordering_threshold_;
|
||||
I420FrameCallback* pre_render_callback_ GUARDED_BY(crit_);
|
||||
I420FrameCallback* const pre_render_callback_;
|
||||
|
||||
int64_t last_rtt_ms_ GUARDED_BY(crit_);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_VIDEO_VIE_CHANNEL_H_
|
||||
#endif // WEBRTC_VIDEO_VIDEO_STREAM_DECODER_H_
|
||||
@ -1,266 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/video/vie_channel.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/common_video/include/frame_callback.h"
|
||||
#include "webrtc/common_video/include/incoming_video_stream.h"
|
||||
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
|
||||
#include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h"
|
||||
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
|
||||
#include "webrtc/modules/video_coding/video_coding_impl.h"
|
||||
#include "webrtc/modules/video_processing/include/video_processing.h"
|
||||
#include "webrtc/system_wrappers/include/metrics.h"
|
||||
#include "webrtc/video/call_stats.h"
|
||||
#include "webrtc/video/payload_router.h"
|
||||
#include "webrtc/video/receive_statistics_proxy.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
static const int kMaxPacketAgeToNack = 450;
|
||||
static const int kMaxNackListSize = 250;
|
||||
|
||||
// Helper class receiving statistics callbacks.
|
||||
class ChannelStatsObserver : public CallStatsObserver {
|
||||
public:
|
||||
explicit ChannelStatsObserver(ViEChannel* owner) : owner_(owner) {}
|
||||
virtual ~ChannelStatsObserver() {}
|
||||
|
||||
// Implements StatsObserver.
|
||||
virtual void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
|
||||
owner_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
|
||||
}
|
||||
|
||||
private:
|
||||
ViEChannel* const owner_;
|
||||
};
|
||||
|
||||
ViEChannel::ViEChannel(vcm::VideoReceiver* video_receiver,
|
||||
RtpStreamReceiver* rtp_stream_receiver)
|
||||
: video_receiver_(video_receiver),
|
||||
rtp_stream_receiver_(rtp_stream_receiver),
|
||||
rtp_rtcp_(rtp_stream_receiver_->rtp_rtcp()),
|
||||
stats_observer_(new ChannelStatsObserver(this)),
|
||||
receive_stats_callback_(nullptr),
|
||||
incoming_video_stream_(nullptr),
|
||||
max_nack_reordering_threshold_(kMaxPacketAgeToNack),
|
||||
pre_render_callback_(nullptr),
|
||||
last_rtt_ms_(0) {
|
||||
RTC_DCHECK(video_receiver_);
|
||||
video_receiver_->SetNackSettings(kMaxNackListSize,
|
||||
max_nack_reordering_threshold_, 0);
|
||||
}
|
||||
|
||||
ViEChannel::~ViEChannel() {}
|
||||
|
||||
int32_t ViEChannel::Init() {
|
||||
static const int kDefaultRenderDelayMs = 10;
|
||||
|
||||
if (video_receiver_->RegisterReceiveCallback(this) != 0) {
|
||||
return -1;
|
||||
}
|
||||
video_receiver_->RegisterFrameTypeCallback(this);
|
||||
video_receiver_->RegisterReceiveStatisticsCallback(this);
|
||||
video_receiver_->RegisterDecoderTimingCallback(this);
|
||||
video_receiver_->SetRenderDelay(kDefaultRenderDelayMs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ViEChannel::SetProtectionMode(bool enable_nack,
|
||||
bool enable_fec,
|
||||
int payload_type_red,
|
||||
int payload_type_fec) {
|
||||
// Validate payload types. If either RED or FEC payload types are set then
|
||||
// both should be. If FEC is enabled then they both have to be set.
|
||||
if (enable_fec || payload_type_red != -1 || payload_type_fec != -1) {
|
||||
RTC_DCHECK_GE(payload_type_red, 0);
|
||||
RTC_DCHECK_GE(payload_type_fec, 0);
|
||||
RTC_DCHECK_LE(payload_type_red, 127);
|
||||
RTC_DCHECK_LE(payload_type_fec, 127);
|
||||
} else {
|
||||
// Payload types unset.
|
||||
RTC_DCHECK_EQ(payload_type_red, -1);
|
||||
RTC_DCHECK_EQ(payload_type_fec, -1);
|
||||
// Set to valid uint8_ts to be castable later without signed overflows.
|
||||
payload_type_red = 0;
|
||||
payload_type_fec = 0;
|
||||
}
|
||||
|
||||
VCMVideoProtection protection_method;
|
||||
if (enable_nack) {
|
||||
protection_method = enable_fec ? kProtectionNackFEC : kProtectionNack;
|
||||
} else {
|
||||
protection_method = kProtectionNone;
|
||||
}
|
||||
|
||||
video_receiver_->SetVideoProtection(protection_method, true);
|
||||
|
||||
// Set NACK.
|
||||
ProcessNACKRequest(enable_nack);
|
||||
|
||||
// Set FEC.
|
||||
rtp_rtcp_->SetGenericFECStatus(enable_fec,
|
||||
static_cast<uint8_t>(payload_type_red),
|
||||
static_cast<uint8_t>(payload_type_fec));
|
||||
}
|
||||
|
||||
void ViEChannel::ProcessNACKRequest(const bool enable) {
|
||||
if (enable) {
|
||||
// Turn on NACK.
|
||||
if (rtp_rtcp_->RTCP() == RtcpMode::kOff)
|
||||
return;
|
||||
rtp_stream_receiver_->SetNackStatus(true, max_nack_reordering_threshold_);
|
||||
video_receiver_->RegisterPacketRequestCallback(this);
|
||||
// Don't introduce errors when NACK is enabled.
|
||||
video_receiver_->SetDecodeErrorMode(kNoErrors);
|
||||
|
||||
} else {
|
||||
video_receiver_->RegisterPacketRequestCallback(nullptr);
|
||||
// When NACK is off, allow decoding with errors. Otherwise, the video
|
||||
// will freeze, and will only recover with a complete key frame.
|
||||
video_receiver_->SetDecodeErrorMode(kWithErrors);
|
||||
rtp_stream_receiver_->SetNackStatus(false, max_nack_reordering_threshold_);
|
||||
}
|
||||
}
|
||||
|
||||
int ViEChannel::GetRequiredNackListSize(int target_delay_ms) {
|
||||
// The max size of the nack list should be large enough to accommodate the
|
||||
// the number of packets (frames) resulting from the increased delay.
|
||||
// Roughly estimating for ~40 packets per frame @ 30fps.
|
||||
return target_delay_ms * 40 * 30 / 1000;
|
||||
}
|
||||
|
||||
RtpState ViEChannel::GetRtpStateForSsrc(uint32_t ssrc) const {
|
||||
RTC_DCHECK(!rtp_rtcp_->Sending());
|
||||
RTC_DCHECK_EQ(ssrc, rtp_rtcp_->SSRC());
|
||||
return rtp_rtcp_->GetRtpState();
|
||||
}
|
||||
|
||||
void ViEChannel::RegisterRtcpPacketTypeCounterObserver(
|
||||
RtcpPacketTypeCounterObserver* observer) {
|
||||
rtp_stream_receiver_->RegisterRtcpPacketTypeCounterObserver(observer);
|
||||
}
|
||||
|
||||
CallStatsObserver* ViEChannel::GetStatsObserver() {
|
||||
return stats_observer_.get();
|
||||
}
|
||||
|
||||
// Do not acquire the lock of |video_receiver_| in this function. Decode
|
||||
// callback won't necessarily be called from the decoding thread. The decoding
|
||||
// thread may have held the lock when calling VideoDecoder::Decode, Reset, or
|
||||
// Release. Acquiring the same lock in the path of decode callback can deadlock.
|
||||
int32_t ViEChannel::FrameToRender(VideoFrame& video_frame) { // NOLINT
|
||||
rtc::CritScope lock(&crit_);
|
||||
|
||||
if (pre_render_callback_)
|
||||
pre_render_callback_->FrameCallback(&video_frame);
|
||||
|
||||
incoming_video_stream_->OnFrame(video_frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ViEChannel::ReceivedDecodedReferenceFrame(
|
||||
const uint64_t picture_id) {
|
||||
return rtp_rtcp_->SendRTCPReferencePictureSelection(picture_id);
|
||||
}
|
||||
|
||||
void ViEChannel::OnIncomingPayloadType(int payload_type) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
if (receive_stats_callback_)
|
||||
receive_stats_callback_->OnIncomingPayloadType(payload_type);
|
||||
}
|
||||
|
||||
void ViEChannel::OnDecoderImplementationName(const char* implementation_name) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
if (receive_stats_callback_)
|
||||
receive_stats_callback_->OnDecoderImplementationName(implementation_name);
|
||||
}
|
||||
|
||||
void ViEChannel::OnReceiveRatesUpdated(uint32_t bit_rate, uint32_t frame_rate) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
if (receive_stats_callback_)
|
||||
receive_stats_callback_->OnIncomingRate(frame_rate, bit_rate);
|
||||
}
|
||||
|
||||
void ViEChannel::OnDiscardedPacketsUpdated(int discarded_packets) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
if (receive_stats_callback_)
|
||||
receive_stats_callback_->OnDiscardedPacketsUpdated(discarded_packets);
|
||||
}
|
||||
|
||||
void ViEChannel::OnFrameCountsUpdated(const FrameCounts& frame_counts) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
receive_frame_counts_ = frame_counts;
|
||||
if (receive_stats_callback_)
|
||||
receive_stats_callback_->OnFrameCountsUpdated(frame_counts);
|
||||
}
|
||||
|
||||
void ViEChannel::OnDecoderTiming(int decode_ms,
|
||||
int max_decode_ms,
|
||||
int current_delay_ms,
|
||||
int target_delay_ms,
|
||||
int jitter_buffer_ms,
|
||||
int min_playout_delay_ms,
|
||||
int render_delay_ms) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
if (!receive_stats_callback_)
|
||||
return;
|
||||
receive_stats_callback_->OnDecoderTiming(
|
||||
decode_ms, max_decode_ms, current_delay_ms, target_delay_ms,
|
||||
jitter_buffer_ms, min_playout_delay_ms, render_delay_ms, last_rtt_ms_);
|
||||
}
|
||||
|
||||
int32_t ViEChannel::RequestKeyFrame() {
|
||||
return rtp_rtcp_->RequestKeyFrame();
|
||||
}
|
||||
|
||||
int32_t ViEChannel::SliceLossIndicationRequest(
|
||||
const uint64_t picture_id) {
|
||||
return rtp_rtcp_->SendRTCPSliceLossIndication(
|
||||
static_cast<uint8_t>(picture_id));
|
||||
}
|
||||
|
||||
int32_t ViEChannel::ResendPackets(const uint16_t* sequence_numbers,
|
||||
uint16_t length) {
|
||||
return rtp_rtcp_->SendNACK(sequence_numbers, length);
|
||||
}
|
||||
|
||||
void ViEChannel::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
|
||||
video_receiver_->SetReceiveChannelParameters(max_rtt_ms);
|
||||
|
||||
rtc::CritScope lock(&crit_);
|
||||
last_rtt_ms_ = avg_rtt_ms;
|
||||
}
|
||||
|
||||
void ViEChannel::RegisterPreRenderCallback(
|
||||
I420FrameCallback* pre_render_callback) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
pre_render_callback_ = pre_render_callback;
|
||||
}
|
||||
|
||||
void ViEChannel::RegisterReceiveStatisticsProxy(
|
||||
ReceiveStatisticsProxy* receive_statistics_proxy) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
receive_stats_callback_ = receive_statistics_proxy;
|
||||
}
|
||||
|
||||
void ViEChannel::SetIncomingVideoStream(
|
||||
IncomingVideoStream* incoming_video_stream) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
incoming_video_stream_ = incoming_video_stream;
|
||||
}
|
||||
} // namespace webrtc
|
||||
@ -54,8 +54,8 @@
|
||||
'video/video_receive_stream.h',
|
||||
'video/video_send_stream.cc',
|
||||
'video/video_send_stream.h',
|
||||
'video/vie_channel.cc',
|
||||
'video/vie_channel.h',
|
||||
'video/video_stream_decoder.cc',
|
||||
'video/video_stream_decoder.h',
|
||||
'video/vie_encoder.cc',
|
||||
'video/vie_encoder.h',
|
||||
'video/vie_remb.cc',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user