Index: webrtc/video/rtp_stream_receiver.cc |
diff --git a/webrtc/video/rtp_stream_receiver.cc b/webrtc/video/rtp_stream_receiver.cc |
index 576543bef682d05aa6cabef4790da3bb44fb76b7..8fa5eb45c57f629f349c751cfed77c028c2d1355 100644 |
--- a/webrtc/video/rtp_stream_receiver.cc |
+++ b/webrtc/video/rtp_stream_receiver.cc |
@@ -11,6 +11,7 @@ |
#include "webrtc/video/rtp_stream_receiver.h" |
#include <vector> |
+#include <utility> |
#include "webrtc/base/checks.h" |
#include "webrtc/base/logging.h" |
@@ -24,7 +25,11 @@ |
#include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" |
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" |
#include "webrtc/modules/rtp_rtcp/include/ulpfec_receiver.h" |
+#include "webrtc/modules/video_coding/frame_object.h" |
+#include "webrtc/modules/video_coding/h264_sps_pps_tracker.h" |
+#include "webrtc/modules/video_coding/packet_buffer.h" |
#include "webrtc/modules/video_coding/video_coding_impl.h" |
+#include "webrtc/system_wrappers/include/field_trial.h" |
#include "webrtc/system_wrappers/include/metrics.h" |
#include "webrtc/system_wrappers/include/timestamp_extrapolator.h" |
#include "webrtc/system_wrappers/include/trace.h" |
@@ -33,6 +38,11 @@ |
namespace webrtc { |
+namespace { |
+constexpr int kPacketBufferStartSize = 32; |
+constexpr int kPacketBufferMaxSixe = 2048; |
+} |
+ |
std::unique_ptr<RtpRtcp> CreateRtpRtcpModule( |
ReceiveStatistics* receive_statistics, |
Transport* outgoing_transport, |
@@ -83,7 +93,11 @@ RtpStreamReceiver::RtpStreamReceiver( |
const VideoReceiveStream::Config* config, |
ReceiveStatisticsProxy* receive_stats_proxy, |
ProcessThread* process_thread, |
- RateLimiter* retransmission_rate_limiter) |
+ RateLimiter* retransmission_rate_limiter, |
+ NackSender* nack_sender, |
+ KeyFrameRequestSender* keyframe_request_sender, |
+ video_coding::OnCompleteFrameCallback* complete_frame_callback, |
+ VCMTiming* timing) |
: clock_(Clock::GetRealTimeClock()), |
config_(*config), |
video_receiver_(video_receiver), |
@@ -110,7 +124,10 @@ RtpStreamReceiver::RtpStreamReceiver( |
remote_bitrate_estimator_, |
paced_sender, |
packet_router, |
- retransmission_rate_limiter)) { |
+ retransmission_rate_limiter)), |
+ complete_frame_callback_(complete_frame_callback), |
+ keyframe_request_sender_(keyframe_request_sender), |
+ timing_(timing) { |
packet_router_->AddRtpModule(rtp_rtcp_.get()); |
rtp_receive_statistics_->RegisterRtpStatisticsCallback(receive_stats_proxy); |
rtp_receive_statistics_->RegisterRtcpStatisticsCallback(receive_stats_proxy); |
@@ -192,11 +209,27 @@ RtpStreamReceiver::RtpStreamReceiver( |
rtp_rtcp_->RegisterRtcpStatisticsCallback(receive_stats_proxy); |
process_thread_->RegisterModule(rtp_rtcp_.get()); |
+ |
+ jitter_buffer_experiment_ = |
+ field_trial::FindFullName("WebRTC-NewVideoJitterBuffer") == "Enabled"; |
+ |
+ if (jitter_buffer_experiment_) { |
+ nack_module_.reset( |
+ new NackModule(clock_, nack_sender, keyframe_request_sender)); |
+ process_thread_->RegisterModule(nack_module_.get()); |
+ |
+ packet_buffer_ = video_coding::PacketBuffer::Create( |
+ clock_, kPacketBufferStartSize, kPacketBufferMaxSixe, this); |
+ reference_finder_.reset(new video_coding::RtpFrameReferenceFinder(this)); |
+ } |
} |
RtpStreamReceiver::~RtpStreamReceiver() { |
process_thread_->DeRegisterModule(rtp_rtcp_.get()); |
+ if (jitter_buffer_experiment_) |
+ process_thread_->DeRegisterModule(nack_module_.get()); |
+ |
packet_router_->RemoveRtpModule(rtp_rtcp_.get()); |
rtp_rtcp_->SetREMBStatus(false); |
remb_->RemoveReceiveChannel(rtp_rtcp_.get()); |
@@ -236,10 +269,34 @@ int32_t RtpStreamReceiver::OnReceivedPayloadData( |
WebRtcRTPHeader rtp_header_with_ntp = *rtp_header; |
rtp_header_with_ntp.ntp_time_ms = |
ntp_estimator_.Estimate(rtp_header->header.timestamp); |
- if (video_receiver_->IncomingPacket(payload_data, payload_size, |
- rtp_header_with_ntp) != 0) { |
- // Check this... |
- return -1; |
+ if (jitter_buffer_experiment_) { |
+ VCMPacket packet(payload_data, payload_size, rtp_header_with_ntp); |
+ timing_->IncomingTimestamp(packet.timestamp, clock_->TimeInMilliseconds()); |
+ packet.timesNacked = nack_module_->OnReceivedPacket(packet); |
+ |
+ if (packet.codec == kVideoCodecH264) { |
+ switch (tracker_.CopyAndFixBitstream(&packet)) { |
+ case video_coding::H264SpsPpsTracker::kRequestKeyframe: |
+ keyframe_request_sender_->RequestKeyFrame(); |
+ FALLTHROUGH(); |
+ case video_coding::H264SpsPpsTracker::kDrop: |
+ return 0; |
+ case video_coding::H264SpsPpsTracker::kInsert: |
+ break; |
+ } |
+ } else { |
+ uint8_t* data = new uint8_t[packet.sizeBytes]; |
+ memcpy(data, packet.dataPtr, packet.sizeBytes); |
+ packet.dataPtr = data; |
+ } |
+ |
+ packet_buffer_->InsertPacket(packet); |
+ } else { |
+ if (video_receiver_->IncomingPacket(payload_data, payload_size, |
+ rtp_header_with_ntp) != 0) { |
+ // Check this... |
+ return -1; |
+ } |
} |
return 0; |
} |
@@ -357,6 +414,27 @@ int32_t RtpStreamReceiver::ResendPackets(const uint16_t* sequence_numbers, |
return rtp_rtcp_->SendNACK(sequence_numbers, length); |
} |
+void RtpStreamReceiver::OnReceivedFrame( |
philipel
2016/11/08 09:27:13
When the PacketBuffer finds a complete frame this
stefan-webrtc
2016/11/08 10:41:34
Can't we have RtpFrameReferenceFinder implement On
nisse-webrtc
2016/11/08 11:56:30
I think explanations like this belong in comments
philipel
2016/11/08 12:28:39
I don't think it makes sense to modify the RtpFram
philipel
2016/11/08 12:28:39
These comments were added to make reviewing easier
nisse-webrtc
2016/11/08 12:58:12
The code comment should explain the purpose of the
philipel
2016/11/08 13:35:51
There are comments for OnReceivedFrameCallback (pa
|
+ std::unique_ptr<video_coding::RtpFrameObject> frame) { |
+ reference_finder_->ManageFrame(std::move(frame)); |
+} |
+ |
+void RtpStreamReceiver::OnCompleteFrame( |
philipel
2016/11/08 09:27:13
When the RtpFrameReferenceFinder has found all the
|
+ std::unique_ptr<video_coding::FrameObject> frame) { |
+ { |
+ rtc::CritScope lock(&last_seq_num_cs_); |
+ video_coding::RtpFrameObject* rtp_frame = |
+ static_cast<video_coding::RtpFrameObject*>(frame.get()); |
+ last_seq_num_for_pic_id_[rtp_frame->picture_id] = rtp_frame->last_seq_num(); |
+ } |
+ complete_frame_callback_->OnCompleteFrame(std::move(frame)); |
+} |
+ |
+void RtpStreamReceiver::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { |
+ if (jitter_buffer_experiment_) |
+ nack_module_->UpdateRtt(max_rtt_ms); |
+} |
+ |
bool RtpStreamReceiver::ReceivePacket(const uint8_t* packet, |
size_t packet_length, |
const RTPHeader& header, |
@@ -481,6 +559,39 @@ bool RtpStreamReceiver::DeliverRtcp(const uint8_t* rtcp_packet, |
return true; |
} |
+void RtpStreamReceiver::FrameContinuous(uint16_t picture_id) { |
philipel
2016/11/08 09:27:13
This function is called from VideoReceiveStream::O
|
+ if (jitter_buffer_experiment_) { |
+ int seq_num = -1; |
+ { |
+ rtc::CritScope lock(&last_seq_num_cs_); |
+ auto seq_num_it = last_seq_num_for_pic_id_.find(picture_id); |
+ if (seq_num_it != last_seq_num_for_pic_id_.end()) |
+ seq_num = seq_num_it->second; |
+ } |
+ if (seq_num != -1) |
+ nack_module_->ClearUpTo(seq_num); |
+ } |
+} |
+ |
+void RtpStreamReceiver::FrameDecoded(uint16_t picture_id) { |
philipel
2016/11/08 09:27:13
Called from VideoReceiveStream::Decode when a fram
|
+ if (jitter_buffer_experiment_) { |
+ int seq_num = -1; |
+ { |
+ rtc::CritScope lock(&last_seq_num_cs_); |
+ auto seq_num_it = last_seq_num_for_pic_id_.find(picture_id); |
+ if (seq_num_it != last_seq_num_for_pic_id_.end()) { |
+ seq_num = seq_num_it->second; |
+ last_seq_num_for_pic_id_.erase(last_seq_num_for_pic_id_.begin(), |
+ ++seq_num_it); |
+ } |
+ } |
+ if (seq_num != -1) { |
+ packet_buffer_->ClearTo(seq_num); |
+ reference_finder_->ClearTo(seq_num); |
+ } |
+ } |
+} |
+ |
void RtpStreamReceiver::SignalNetworkState(NetworkState state) { |
rtp_rtcp_->SetRTCPStatus(state == kNetworkUp ? config_.rtp.rtcp_mode |
: RtcpMode::kOff); |