video_receive_stream.cc revision cd6702282a49448adda470934f4bd9e6181cab22
129d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org/* 229d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 329d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org * 429d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org * Use of this source code is governed by a BSD-style license 529d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org * that can be found in the LICENSE file in the root of the source 629d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org * tree. An additional intellectual property rights grant can be found 729d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org * in the file PATENTS. All contributing project authors may 829d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org * be found in the AUTHORS file in the root of the source tree. 929d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org */ 1029d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org 1116e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org#include "webrtc/video/video_receive_stream.h" 1229d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org 1312dc1a38ca54a000e4fecfbc6d41138b895c9ca5pbos@webrtc.org#include <stdlib.h> 1429d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org 15b429e516a98d2dee0c57d3263f6d21633939b564mflodman@webrtc.org#include <string> 16b429e516a98d2dee0c57d3263f6d21633939b564mflodman@webrtc.org 170d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org#include "webrtc/base/checks.h" 1829d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" 1929d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org#include "webrtc/system_wrappers/interface/clock.h" 202a034988257074183615615f0cc7f59f3411a21cpbos@webrtc.org#include "webrtc/system_wrappers/interface/logging.h" 2109315705b9caf3bff455e3515b9bd99492a7c3e3sprang@webrtc.org#include "webrtc/video/receive_statistics_proxy.h" 22776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org#include "webrtc/video_encoder.h" 2316e03b7bd8b88ba569987e20a7f29061f91a3d0dpbos@webrtc.org#include "webrtc/video_receive_stream.h" 2429d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org 2529d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.orgnamespace webrtc { 2632e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.orgstd::string VideoReceiveStream::Decoder::ToString() const { 2732e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org std::stringstream ss; 282b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org ss << "{decoder: " << (decoder != nullptr ? "(VideoDecoder)" : "nullptr"); 2932e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", payload_type: " << payload_type; 3032e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", payload_name: " << payload_name; 3132e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", is_renderer: " << (is_renderer ? "yes" : "no"); 3232e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", expected_delay_ms: " << expected_delay_ms; 3332e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << '}'; 3432e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org 3532e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org return ss.str(); 3632e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org} 3732e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org 3832e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.orgstd::string VideoReceiveStream::Config::ToString() const { 3932e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org std::stringstream ss; 4032e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << "{decoders: ["; 4132e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org for (size_t i = 0; i < decoders.size(); ++i) { 4232e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << decoders[i].ToString(); 4332e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org if (i != decoders.size() - 1) 4432e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", "; 4532e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org } 4632e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ']'; 4732e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", rtp: " << rtp.ToString(); 482b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org ss << ", renderer: " << (renderer != nullptr ? "(renderer)" : "nullptr"); 4932e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", render_delay_ms: " << render_delay_ms; 508fc7fa798f7a36955f1b933980401afad2aff592pbos if (!sync_group.empty()) 518fc7fa798f7a36955f1b933980401afad2aff592pbos ss << ", sync_group: " << sync_group; 5232e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", pre_decode_callback: " 532b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org << (pre_decode_callback != nullptr ? "(EncodedFrameObserver)" : "nullptr"); 5432e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", pre_render_callback: " 552b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org << (pre_render_callback != nullptr ? "(I420FrameCallback)" : "nullptr"); 5632e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", target_delay_ms: " << target_delay_ms; 5732e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << '}'; 5832e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org 5932e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org return ss.str(); 6032e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org} 6132e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org 6232e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.orgstd::string VideoReceiveStream::Config::Rtp::ToString() const { 6332e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org std::stringstream ss; 6432e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << "{remote_ssrc: " << remote_ssrc; 6532e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", local_ssrc: " << local_ssrc; 6632e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", rtcp_mode: " << (rtcp_mode == newapi::kRtcpCompound 6732e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ? "kRtcpCompound" 6832e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org : "kRtcpReducedSize"); 6932e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", rtcp_xr: "; 7032e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << "{receiver_reference_time_report: " 7132e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org << (rtcp_xr.receiver_reference_time_report ? "on" : "off"); 7232e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << '}'; 7332e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", remb: " << (remb ? "on" : "off"); 7432e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", nack: {rtp_history_ms: " << nack.rtp_history_ms << '}'; 7532e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", fec: " << fec.ToString(); 7632e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", rtx: {"; 7732e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org for (auto& kv : rtx) { 7832e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << kv.first << " -> "; 7932e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << "{ssrc: " << kv.second.ssrc; 8032e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", payload_type: " << kv.second.payload_type; 8132e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << '}'; 8232e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org } 8332e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << '}'; 8432e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", extensions: ["; 8532e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org for (size_t i = 0; i < extensions.size(); ++i) { 8632e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << extensions[i].ToString(); 8732e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org if (i != extensions.size() - 1) 8832e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ", "; 8932e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org } 9032e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << ']'; 9132e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org ss << '}'; 9232e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org return ss.str(); 9332e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org} 9432e852858101c3565cfc79cdda9310a3336d95a0pbos@webrtc.org 9529d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.orgnamespace internal { 96776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.orgnamespace { 979e4e524f3894c7eeee8a53bd3cbf21d27b5efc8cpbos@webrtc.org 98776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.orgVideoCodec CreateDecoderVideoCodec(const VideoReceiveStream::Decoder& decoder) { 99776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org VideoCodec codec; 100776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org memset(&codec, 0, sizeof(codec)); 101776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 102776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org codec.plType = decoder.payload_type; 103776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org strcpy(codec.plName, decoder.payload_name.c_str()); 104776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org if (decoder.payload_name == "VP8") { 105776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org codec.codecType = kVideoCodecVP8; 106776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } else if (decoder.payload_name == "H264") { 107776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org codec.codecType = kVideoCodecH264; 108776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } else { 109776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org codec.codecType = kVideoCodecGeneric; 110776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } 111776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 112776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org if (codec.codecType == kVideoCodecVP8) { 113776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org codec.codecSpecific.VP8 = VideoEncoder::GetDefaultVp8Settings(); 114776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } else if (codec.codecType == kVideoCodecH264) { 115776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org codec.codecSpecific.H264 = VideoEncoder::GetDefaultH264Settings(); 116776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org } 117776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 118776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org codec.width = 320; 119776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org codec.height = 180; 120776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org codec.startBitrate = codec.minBitrate = codec.maxBitrate = 121776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org Call::Config::kDefaultStartBitrateBps / 1000; 122776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 123776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org return codec; 124776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org} 125776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org} // namespace 12629d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org 12745553aefacb797818da83ccef1c3679a8aa0fc7fPeter BoströmVideoReceiveStream::VideoReceiveStream(int num_cpu_cores, 12845553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström int base_channel_id, 12976c53d36bc455fe89ca1f860d5171633198fe907Peter Boström ChannelGroup* channel_group, 13045553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström int channel_id, 1310181b5f8dd719f7b1f938d12875a96e59fef44f5pbos@webrtc.org const VideoReceiveStream::Config& config, 132b082ade3db118113bba284d0f8fd32901371a2a0stefan@webrtc.org newapi::Transport* transport, 13345553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström webrtc::VoiceEngine* voice_engine) 1344070935f4fb5b9fb2df246d7073fe0ba7e350791sprang@webrtc.org : transport_adapter_(transport), 1354070935f4fb5b9fb2df246d7073fe0ba7e350791sprang@webrtc.org encoded_frame_proxy_(config.pre_decode_callback), 1364070935f4fb5b9fb2df246d7073fe0ba7e350791sprang@webrtc.org config_(config), 13709315705b9caf3bff455e3515b9bd99492a7c3e3sprang@webrtc.org clock_(Clock::GetRealTimeClock()), 13876c53d36bc455fe89ca1f860d5171633198fe907Peter Boström channel_group_(channel_group), 1398fc7fa798f7a36955f1b933980401afad2aff592pbos channel_id_(channel_id) { 14045553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström CHECK(channel_group_->CreateReceiveChannel(channel_id_, 0, base_channel_id, 1412251d6e17438e1a085ff4f88ad19de513214bec1Peter Boström &transport_adapter_, num_cpu_cores, 1422251d6e17438e1a085ff4f88ad19de513214bec1Peter Boström true)); 14329d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org 14445553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström vie_channel_ = channel_group_->GetChannel(channel_id_); 14529d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org 146bbb07e69e55761ca43b38f929f3e39f4bba70ef1pbos@webrtc.org // TODO(pbos): This is not fine grained enough... 147ba8c15b857c0f341d9c1e02d41b6ccd56f9f1030pbos vie_channel_->SetProtectionMode(config_.rtp.nack.rtp_history_ms > 0, false, 148ba8c15b857c0f341d9c1e02d41b6ccd56f9f1030pbos -1, -1); 14976c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp); 15026c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org SetRtcpMode(config_.rtp.rtcp_mode); 151bbb07e69e55761ca43b38f929f3e39f4bba70ef1pbos@webrtc.org 1522b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org DCHECK(config_.rtp.remote_ssrc != 0); 153c279a5d72c885b1a1737018ee26dc7c0475a38bfpbos@webrtc.org // TODO(pbos): What's an appropriate local_ssrc for receive-only streams? 1542b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org DCHECK(config_.rtp.local_ssrc != 0); 1552b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org DCHECK(config_.rtp.remote_ssrc != config_.rtp.local_ssrc); 156b613b5ab2b03041942f04fd892e2ad5a4f9de027pbos@webrtc.org 15776c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->SetSSRC(config_.rtp.local_ssrc, kViEStreamTypeNormal, 0); 158c279a5d72c885b1a1737018ee26dc7c0475a38bfpbos@webrtc.org // TODO(pbos): Support multiple RTX, per video payload. 159c279a5d72c885b1a1737018ee26dc7c0475a38bfpbos@webrtc.org Config::Rtp::RtxMap::const_iterator it = config_.rtp.rtx.begin(); 160e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin for (; it != config_.rtp.rtx.end(); ++it) { 1612b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org DCHECK(it->second.ssrc != 0); 1622b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org DCHECK(it->second.payload_type != 0); 163c279a5d72c885b1a1737018ee26dc7c0475a38bfpbos@webrtc.org 16476c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->SetRemoteSSRCType(kViEStreamTypeRtx, it->second.ssrc); 165e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin vie_channel_->SetRtxReceivePayloadType(it->second.payload_type, it->first); 166c279a5d72c885b1a1737018ee26dc7c0475a38bfpbos@webrtc.org } 167c279a5d72c885b1a1737018ee26dc7c0475a38bfpbos@webrtc.org 16876c53d36bc455fe89ca1f860d5171633198fe907Peter Boström // TODO(pbos): Remove channel_group_ usage from VideoReceiveStream. This 16976c53d36bc455fe89ca1f860d5171633198fe907Peter Boström // should be configured in call.cc. 17076c53d36bc455fe89ca1f860d5171633198fe907Peter Boström channel_group_->SetChannelRembStatus(false, config_.rtp.remb, vie_channel_); 17129d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org 1725ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org for (size_t i = 0; i < config_.rtp.extensions.size(); ++i) { 1735ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org const std::string& extension = config_.rtp.extensions[i].name; 1745ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org int id = config_.rtp.extensions[i].id; 17523914fe756903353eae13fffc868d2c84f51f06fPeter Boström // One-byte-extension local identifiers are in the range 1-14 inclusive. 17623914fe756903353eae13fffc868d2c84f51f06fPeter Boström DCHECK_GE(id, 1); 17723914fe756903353eae13fffc868d2c84f51f06fPeter Boström DCHECK_LE(id, 14); 1785ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org if (extension == RtpExtension::kTOffset) { 17976c53d36bc455fe89ca1f860d5171633198fe907Peter Boström CHECK_EQ(0, vie_channel_->SetReceiveTimestampOffsetStatus(true, id)); 1805ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org } else if (extension == RtpExtension::kAbsSendTime) { 18176c53d36bc455fe89ca1f860d5171633198fe907Peter Boström CHECK_EQ(0, vie_channel_->SetReceiveAbsoluteSendTimeStatus(true, id)); 182fdd10579496123c9a7fdc0bf185e2a26a12ed340guoweis@webrtc.org } else if (extension == RtpExtension::kVideoRotation) { 18376c53d36bc455fe89ca1f860d5171633198fe907Peter Boström CHECK_EQ(0, vie_channel_->SetReceiveVideoRotationStatus(true, id)); 1845ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org } else { 1852b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org RTC_NOTREACHED() << "Unsupported RTP extension."; 1865ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org } 1875ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org } 1885ab756703ea32f2c2ff9878d6eae628c7380bc14pbos@webrtc.org 1892a034988257074183615615f0cc7f59f3411a21cpbos@webrtc.org if (config_.rtp.fec.ulpfec_payload_type != -1) { 1902a034988257074183615615f0cc7f59f3411a21cpbos@webrtc.org // ULPFEC without RED doesn't make sense. 1912b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org DCHECK(config_.rtp.fec.red_payload_type != -1); 1922a034988257074183615615f0cc7f59f3411a21cpbos@webrtc.org VideoCodec codec; 1932a034988257074183615615f0cc7f59f3411a21cpbos@webrtc.org memset(&codec, 0, sizeof(codec)); 1942a034988257074183615615f0cc7f59f3411a21cpbos@webrtc.org codec.codecType = kVideoCodecULPFEC; 1952a034988257074183615615f0cc7f59f3411a21cpbos@webrtc.org strcpy(codec.plName, "ulpfec"); 1962a034988257074183615615f0cc7f59f3411a21cpbos@webrtc.org codec.plType = config_.rtp.fec.ulpfec_payload_type; 19776c53d36bc455fe89ca1f860d5171633198fe907Peter Boström CHECK_EQ(0, vie_channel_->SetReceiveCodec(codec)); 1982a034988257074183615615f0cc7f59f3411a21cpbos@webrtc.org } 1992a034988257074183615615f0cc7f59f3411a21cpbos@webrtc.org if (config_.rtp.fec.red_payload_type != -1) { 2002a034988257074183615615f0cc7f59f3411a21cpbos@webrtc.org VideoCodec codec; 2012a034988257074183615615f0cc7f59f3411a21cpbos@webrtc.org memset(&codec, 0, sizeof(codec)); 2022a034988257074183615615f0cc7f59f3411a21cpbos@webrtc.org codec.codecType = kVideoCodecRED; 2032a034988257074183615615f0cc7f59f3411a21cpbos@webrtc.org strcpy(codec.plName, "red"); 2042a034988257074183615615f0cc7f59f3411a21cpbos@webrtc.org codec.plType = config_.rtp.fec.red_payload_type; 20576c53d36bc455fe89ca1f860d5171633198fe907Peter Boström CHECK_EQ(0, vie_channel_->SetReceiveCodec(codec)); 206e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin if (config_.rtp.fec.red_rtx_payload_type != -1) { 207e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin vie_channel_->SetRtxReceivePayloadType( 208e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin config_.rtp.fec.red_rtx_payload_type, 209e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin config_.rtp.fec.red_payload_type); 210e62202fedf57b74cc263246c0586ee353978caf8Shao Changbin } 2112a034988257074183615615f0cc7f59f3411a21cpbos@webrtc.org } 2122a034988257074183615615f0cc7f59f3411a21cpbos@webrtc.org 21376c53d36bc455fe89ca1f860d5171633198fe907Peter Boström if (config.rtp.rtcp_xr.receiver_reference_time_report) 21476c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->SetRtcpXrRrtrStatus(true); 21576c53d36bc455fe89ca1f860d5171633198fe907Peter Boström 21655707692105a4765f8f321ec7c30a1034d03d23apbos@webrtc.org stats_proxy_.reset( 2171d0fa5d352fe12092201fade249905c7e1ff974bpbos@webrtc.org new ReceiveStatisticsProxy(config_.rtp.remote_ssrc, clock_)); 21809315705b9caf3bff455e3515b9bd99492a7c3e3sprang@webrtc.org 21976c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->RegisterReceiveChannelRtcpStatisticsCallback( 22076c53d36bc455fe89ca1f860d5171633198fe907Peter Boström stats_proxy_.get()); 22176c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->RegisterReceiveChannelRtpStatisticsCallback(stats_proxy_.get()); 22276c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->RegisterRtcpPacketTypeCounterObserver(stats_proxy_.get()); 22376c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->RegisterCodecObserver(stats_proxy_.get()); 224ce4e9a356200170abcdd44ff2af95f87a6781b8epbos@webrtc.org 22576c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->RegisterReceiveStatisticsProxy(stats_proxy_.get()); 22609315705b9caf3bff455e3515b9bd99492a7c3e3sprang@webrtc.org 2272b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org DCHECK(!config_.decoders.empty()); 228776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org for (size_t i = 0; i < config_.decoders.size(); ++i) { 229776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org const Decoder& decoder = config_.decoders[i]; 23076c53d36bc455fe89ca1f860d5171633198fe907Peter Boström CHECK_EQ(0, vie_channel_->RegisterExternalDecoder( 23176c53d36bc455fe89ca1f860d5171633198fe907Peter Boström decoder.payload_type, decoder.decoder, decoder.is_renderer, 232def39883f00c25525dfd34c3cee92b428e54b9e5Peter Boström decoder.is_renderer ? decoder.expected_delay_ms 233def39883f00c25525dfd34c3cee92b428e54b9e5Peter Boström : config.render_delay_ms)); 234776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 235776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org VideoCodec codec = CreateDecoderVideoCodec(decoder); 236776e6f289c7396a1143b8b36b03f88b08ac8cba3pbos@webrtc.org 23776c53d36bc455fe89ca1f860d5171633198fe907Peter Boström CHECK_EQ(0, vie_channel_->SetReceiveCodec(codec)); 2380181b5f8dd719f7b1f938d12875a96e59fef44f5pbos@webrtc.org } 2390181b5f8dd719f7b1f938d12875a96e59fef44f5pbos@webrtc.org 24045553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström incoming_video_stream_.reset(new IncomingVideoStream(0)); 241c4188fd3c74688264621393fc622cb81c042c1acPeter Boström incoming_video_stream_->SetExpectedRenderDelay(config.render_delay_ms); 242c4188fd3c74688264621393fc622cb81c042c1acPeter Boström incoming_video_stream_->SetExternalCallback(this); 243c4188fd3c74688264621393fc622cb81c042c1acPeter Boström vie_channel_->SetIncomingVideoStream(incoming_video_stream_.get()); 244fe1ef935e7d35b465bd00744cc188f08198265b6pbos@webrtc.org 24576c53d36bc455fe89ca1f860d5171633198fe907Peter Boström if (config.pre_decode_callback) 24676c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->RegisterPreDecodeImageCallback(&encoded_frame_proxy_); 24776c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->RegisterPreRenderCallback(this); 24829d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org} 24929d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org 25029d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.orgVideoReceiveStream::~VideoReceiveStream() { 25152ef9d77386e8d3e40c8d3d07b93f06950aede72Peter Boström incoming_video_stream_->Stop(); 25276c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->RegisterPreRenderCallback(nullptr); 25376c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->RegisterPreDecodeImageCallback(nullptr); 254fe1ef935e7d35b465bd00744cc188f08198265b6pbos@webrtc.org 25576c53d36bc455fe89ca1f860d5171633198fe907Peter Boström for (size_t i = 0; i < config_.decoders.size(); ++i) 25676c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->DeRegisterExternalDecoder(config_.decoders[i].payload_type); 257fe1ef935e7d35b465bd00744cc188f08198265b6pbos@webrtc.org 25876c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->RegisterCodecObserver(nullptr); 25976c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->RegisterReceiveChannelRtpStatisticsCallback(nullptr); 26076c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->RegisterReceiveChannelRtcpStatisticsCallback(nullptr); 26176c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->RegisterRtcpPacketTypeCounterObserver(nullptr); 26245553aefacb797818da83ccef1c3679a8aa0fc7fPeter Boström channel_group_->DeleteChannel(channel_id_); 26329d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org} 26429d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org 265a5c8d2c9b39a2d20fead2147e60ed0cd6d62019cpbos@webrtc.orgvoid VideoReceiveStream::Start() { 266d9b9560ee50c236efcb690ee479021b415f7dfd4sprang@webrtc.org transport_adapter_.Enable(); 267c4188fd3c74688264621393fc622cb81c042c1acPeter Boström incoming_video_stream_->Start(); 26876c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->StartReceive(); 26929d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org} 27029d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org 271a5c8d2c9b39a2d20fead2147e60ed0cd6d62019cpbos@webrtc.orgvoid VideoReceiveStream::Stop() { 272c4188fd3c74688264621393fc622cb81c042c1acPeter Boström incoming_video_stream_->Stop(); 27376c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->StopReceive(); 274d9b9560ee50c236efcb690ee479021b415f7dfd4sprang@webrtc.org transport_adapter_.Disable(); 27529d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org} 27629d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org 2778fc7fa798f7a36955f1b933980401afad2aff592pbosvoid VideoReceiveStream::SetSyncChannel(VoiceEngine* voice_engine, 2788fc7fa798f7a36955f1b933980401afad2aff592pbos int audio_channel_id) { 2798fc7fa798f7a36955f1b933980401afad2aff592pbos if (voice_engine != nullptr && audio_channel_id != -1) { 2808fc7fa798f7a36955f1b933980401afad2aff592pbos VoEVideoSync* voe_sync_interface = VoEVideoSync::GetInterface(voice_engine); 2818fc7fa798f7a36955f1b933980401afad2aff592pbos vie_channel_->SetVoiceChannel(audio_channel_id, voe_sync_interface); 2828fc7fa798f7a36955f1b933980401afad2aff592pbos voe_sync_interface->Release(); 2838fc7fa798f7a36955f1b933980401afad2aff592pbos } else { 2848fc7fa798f7a36955f1b933980401afad2aff592pbos vie_channel_->SetVoiceChannel(-1, nullptr); 2858fc7fa798f7a36955f1b933980401afad2aff592pbos } 2868fc7fa798f7a36955f1b933980401afad2aff592pbos} 2878fc7fa798f7a36955f1b933980401afad2aff592pbos 2889510e53cc06b0aa5be2be78fbab375216067eea2sprang@webrtc.orgVideoReceiveStream::Stats VideoReceiveStream::GetStats() const { 28909315705b9caf3bff455e3515b9bd99492a7c3e3sprang@webrtc.org return stats_proxy_->GetStats(); 29009315705b9caf3bff455e3515b9bd99492a7c3e3sprang@webrtc.org} 29109315705b9caf3bff455e3515b9bd99492a7c3e3sprang@webrtc.org 292bbb07e69e55761ca43b38f929f3e39f4bba70ef1pbos@webrtc.orgbool VideoReceiveStream::DeliverRtcp(const uint8_t* packet, size_t length) { 29376c53d36bc455fe89ca1f860d5171633198fe907Peter Boström return vie_channel_->ReceivedRTCPPacket(packet, length) == 0; 29429d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org} 29529d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org 296bbb07e69e55761ca43b38f929f3e39f4bba70ef1pbos@webrtc.orgbool VideoReceiveStream::DeliverRtp(const uint8_t* packet, size_t length) { 29776c53d36bc455fe89ca1f860d5171633198fe907Peter Boström return vie_channel_->ReceivedRTPPacket(packet, length, PacketTime()) == 0; 29829d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org} 29929d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org 3004765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezvoid VideoReceiveStream::FrameCallback(VideoFrame* video_frame) { 30109315705b9caf3bff455e3515b9bd99492a7c3e3sprang@webrtc.org stats_proxy_->OnDecodedFrame(); 30209315705b9caf3bff455e3515b9bd99492a7c3e3sprang@webrtc.org 3031aff095b6cc39d843a3d85d09de599cfcff0e35eÅsa Persson // Post processing is not supported if the frame is backed by a texture. 3041aff095b6cc39d843a3d85d09de599cfcff0e35eÅsa Persson if (video_frame->native_handle() == NULL) { 3051aff095b6cc39d843a3d85d09de599cfcff0e35eÅsa Persson if (config_.pre_render_callback) 3061aff095b6cc39d843a3d85d09de599cfcff0e35eÅsa Persson config_.pre_render_callback->FrameCallback(video_frame); 3071aff095b6cc39d843a3d85d09de599cfcff0e35eÅsa Persson } 30809315705b9caf3bff455e3515b9bd99492a7c3e3sprang@webrtc.org} 30909315705b9caf3bff455e3515b9bd99492a7c3e3sprang@webrtc.org 310c4188fd3c74688264621393fc622cb81c042c1acPeter Boströmint VideoReceiveStream::RenderFrame(const uint32_t /*stream_id*/, 3114765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez const VideoFrame& video_frame) { 312c4188fd3c74688264621393fc622cb81c042c1acPeter Boström // TODO(pbos): Wire up config_.render->IsTextureSupported() and convert if not 313c4188fd3c74688264621393fc622cb81c042c1acPeter Boström // supported. Or provide methods for converting a texture frame in 3144765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez // VideoFrame. 3150d852d5c27a759fe7aadc500bd7b3cadfae3deb8pbos@webrtc.org 3162b4ce3a501b8d679f84c1ad10317dea5c78fa595pbos@webrtc.org if (config_.renderer != nullptr) 31709315705b9caf3bff455e3515b9bd99492a7c3e3sprang@webrtc.org config_.renderer->RenderFrame( 318f4c10d24dc8f1c3ce6859644077d7df6fb678dcdpbos@webrtc.org video_frame, 319f4c10d24dc8f1c3ce6859644077d7df6fb678dcdpbos@webrtc.org video_frame.render_time_ms() - clock_->TimeInMilliseconds()); 32009315705b9caf3bff455e3515b9bd99492a7c3e3sprang@webrtc.org 32109315705b9caf3bff455e3515b9bd99492a7c3e3sprang@webrtc.org stats_proxy_->OnRenderedFrame(); 32229d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org 32329d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org return 0; 32429d5839233b19743286a89676bd748a6bd8623d6pbos@webrtc.org} 32526c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org 326cd6702282a49448adda470934f4bd9e6181cab22Jelena Marusicvoid VideoReceiveStream::SignalNetworkState(NetworkState state) { 327cd6702282a49448adda470934f4bd9e6181cab22Jelena Marusic if (state == kNetworkUp) 32826c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org SetRtcpMode(config_.rtp.rtcp_mode); 329cd6702282a49448adda470934f4bd9e6181cab22Jelena Marusic if (state == kNetworkDown) 33076c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->SetRTCPMode(kRtcpOff); 33126c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org} 33226c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org 33326c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.orgvoid VideoReceiveStream::SetRtcpMode(newapi::RtcpMode mode) { 33426c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org switch (mode) { 33526c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org case newapi::kRtcpCompound: 33676c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->SetRTCPMode(kRtcpCompound); 33726c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org break; 33826c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org case newapi::kRtcpReducedSize: 33976c53d36bc455fe89ca1f860d5171633198fe907Peter Boström vie_channel_->SetRTCPMode(kRtcpNonCompound); 34026c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org break; 34126c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org } 34226c0c41a06d77af54df547169d952a21319dea8cpbos@webrtc.org} 343f3973e81d5aa7e4f1d6b5abdfe3a6dc53a32840cmflodman@webrtc.org} // namespace internal 344f3973e81d5aa7e4f1d6b5abdfe3a6dc53a32840cmflodman@webrtc.org} // namespace webrtc 345