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:
mflodman 2016-05-03 21:22:04 -07:00 committed by Commit bot
parent fe4b21641b
commit cfc8e3b9ef
11 changed files with 230 additions and 432 deletions

View File

@ -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",

View File

@ -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 {

View File

@ -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,

View File

@ -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,

View File

@ -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_);

View File

@ -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_;

View File

@ -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;

View 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

View File

@ -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_

View File

@ -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

View File

@ -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',