From 0828a0c09440cb7edbfacc94d362bf08414c7655 Mon Sep 17 00:00:00 2001 From: mflodman Date: Tue, 31 Mar 2015 15:29:23 +0200 Subject: [PATCH] Revert "Avoid critsect for protection- and qm setting callbacks in VideoSender." This reverts commit 903c0f2e7649a2b98659286dc228447facd49bb7, aka #8899. TBR=pbos@webrtc.org Review URL: https://webrtc-codereview.appspot.com/46759004 Cr-Commit-Position: refs/heads/master@{#8901} --- .../modules/rtp_rtcp/source/producer_fec.cc | 74 +++-- webrtc/modules/rtp_rtcp/source/producer_fec.h | 14 +- .../rtp_rtcp/source/producer_fec_unittest.cc | 41 +-- .../modules/rtp_rtcp/source/rtp_rtcp_impl.cc | 2 +- webrtc/modules/rtp_rtcp/source/rtp_sender.cc | 37 ++- webrtc/modules/rtp_rtcp/source/rtp_sender.h | 13 +- .../rtp_rtcp/source/rtp_sender_unittest.cc | 2 +- .../rtp_rtcp/source/rtp_sender_video.cc | 296 ++++++++++-------- .../rtp_rtcp/source/rtp_sender_video.h | 85 ++--- .../main/interface/video_coding.h | 14 +- .../main/source/media_optimization.cc | 2 +- .../main/source/video_coding_impl.cc | 23 +- .../main/source/video_coding_impl.h | 6 +- .../video_coding/main/source/video_sender.cc | 58 ++-- .../main/source/video_sender_unittest.cc | 3 +- webrtc/video_engine/vie_channel.cc | 4 +- webrtc/video_engine/vie_encoder.cc | 157 ++++++---- webrtc/video_engine/vie_encoder.h | 8 +- 18 files changed, 457 insertions(+), 382 deletions(-) diff --git a/webrtc/modules/rtp_rtcp/source/producer_fec.cc b/webrtc/modules/rtp_rtcp/source/producer_fec.cc index 6ec213ee43..a271a75263 100644 --- a/webrtc/modules/rtp_rtcp/source/producer_fec.cc +++ b/webrtc/modules/rtp_rtcp/source/producer_fec.cc @@ -88,6 +88,7 @@ ProducerFec::ProducerFec(ForwardErrorCorrection* fec) media_packets_fec_(), fec_packets_(), num_frames_(0), + incomplete_frame_(false), num_first_partition_(0), minimum_media_packets_fec_(1), params_(), @@ -124,8 +125,9 @@ RedPacket* ProducerFec::BuildRedPacket(const uint8_t* data_buffer, size_t payload_length, size_t rtp_header_length, int red_pl_type) { - RedPacket* red_packet = new RedPacket( - payload_length + kREDForFECHeaderLength + rtp_header_length); + RedPacket* red_packet = new RedPacket(payload_length + + kREDForFECHeaderLength + + rtp_header_length); int pl_type = data_buffer[1] & 0x7f; red_packet->CreateHeader(data_buffer, rtp_header_length, red_pl_type, pl_type); @@ -140,7 +142,7 @@ int ProducerFec::AddRtpPacketAndGenerateFec(const uint8_t* data_buffer, if (media_packets_fec_.empty()) { params_ = new_params_; } - bool complete_frame = false; + incomplete_frame_ = true; const bool marker_bit = (data_buffer[1] & kRtpMarkerBitMask) ? true : false; if (media_packets_fec_.size() < ForwardErrorCorrection::kMaxMediaPackets) { // Generic FEC can only protect up to kMaxMediaPackets packets. @@ -151,13 +153,13 @@ int ProducerFec::AddRtpPacketAndGenerateFec(const uint8_t* data_buffer, } if (marker_bit) { ++num_frames_; - complete_frame = true; + incomplete_frame_ = false; } // Produce FEC over at most |params_.max_fec_frames| frames, or as soon as: // (1) the excess overhead (actual overhead - requested/target overhead) is // less than |kMaxExcessOverhead|, and // (2) at least |minimum_media_packets_fec_| media packets is reached. - if (complete_frame && + if (!incomplete_frame_ && (num_frames_ == params_.max_fec_frames || (ExcessOverheadBelowMax() && MinimumMediaPacketsReached()))) { assert(num_first_partition_ <= @@ -204,43 +206,37 @@ bool ProducerFec::MinimumMediaPacketsReached() { } bool ProducerFec::FecAvailable() const { - return !fec_packets_.empty(); + return (fec_packets_.size() > 0); } -size_t ProducerFec::NumAvailableFecPackets() const { - return fec_packets_.size(); -} - -std::vector ProducerFec::GetFecPackets(int red_pl_type, - int fec_pl_type, - uint16_t first_seq_num, - size_t rtp_header_length) { - std::vector fec_packets; - fec_packets.reserve(fec_packets_.size()); - uint16_t sequence_number = first_seq_num; - while (!fec_packets_.empty()) { - // Build FEC packet. The FEC packets in |fec_packets_| doesn't - // have RTP headers, so we're reusing the header from the last - // media packet. - ForwardErrorCorrection::Packet* packet_to_send = fec_packets_.front(); - ForwardErrorCorrection::Packet* last_media_packet = - media_packets_fec_.back(); - - RedPacket* red_packet = new RedPacket( - packet_to_send->length + kREDForFECHeaderLength + rtp_header_length); - red_packet->CreateHeader(last_media_packet->data, rtp_header_length, - red_pl_type, fec_pl_type); - red_packet->SetSeqNum(sequence_number++); - red_packet->ClearMarkerBit(); - red_packet->AssignPayload(packet_to_send->data, packet_to_send->length); - - fec_packets.push_back(red_packet); - - fec_packets_.pop_front(); +RedPacket* ProducerFec::GetFecPacket(int red_pl_type, + int fec_pl_type, + uint16_t seq_num, + size_t rtp_header_length) { + if (fec_packets_.empty()) + return NULL; + // Build FEC packet. The FEC packets in |fec_packets_| doesn't + // have RTP headers, so we're reusing the header from the last + // media packet. + ForwardErrorCorrection::Packet* packet_to_send = fec_packets_.front(); + ForwardErrorCorrection::Packet* last_media_packet = media_packets_fec_.back(); + RedPacket* return_packet = new RedPacket(packet_to_send->length + + kREDForFECHeaderLength + + rtp_header_length); + return_packet->CreateHeader(last_media_packet->data, + rtp_header_length, + red_pl_type, + fec_pl_type); + return_packet->SetSeqNum(seq_num); + return_packet->ClearMarkerBit(); + return_packet->AssignPayload(packet_to_send->data, packet_to_send->length); + fec_packets_.pop_front(); + if (fec_packets_.empty()) { + // Done with all the FEC packets. Reset for next run. + DeletePackets(); + num_frames_ = 0; } - DeletePackets(); - num_frames_ = 0; - return fec_packets; + return return_packet; } int ProducerFec::Overhead() const { diff --git a/webrtc/modules/rtp_rtcp/source/producer_fec.h b/webrtc/modules/rtp_rtcp/source/producer_fec.h index b2fdfeccac..ec58bcf629 100644 --- a/webrtc/modules/rtp_rtcp/source/producer_fec.h +++ b/webrtc/modules/rtp_rtcp/source/producer_fec.h @@ -12,7 +12,6 @@ #define WEBRTC_MODULES_RTP_RTCP_SOURCE_PRODUCER_FEC_H_ #include -#include #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h" @@ -46,7 +45,6 @@ class ProducerFec { void SetFecParameters(const FecProtectionParams* params, int max_fec_frames); - // The caller is expected to delete the memory when done. RedPacket* BuildRedPacket(const uint8_t* data_buffer, size_t payload_length, size_t rtp_header_length, @@ -61,14 +59,11 @@ class ProducerFec { bool MinimumMediaPacketsReached(); bool FecAvailable() const; - size_t NumAvailableFecPackets() const; - // GetFecPackets allocates memory and creates FEC packets, but the caller is - // assumed to delete the memory when done with the packets. - std::vector GetFecPackets(int red_pl_type, - int fec_pl_type, - uint16_t first_seq_num, - size_t rtp_header_length); + RedPacket* GetFecPacket(int red_pl_type, + int fec_pl_type, + uint16_t seq_num, + size_t rtp_header_length); private: void DeletePackets(); @@ -77,6 +72,7 @@ class ProducerFec { std::list media_packets_fec_; std::list fec_packets_; int num_frames_; + bool incomplete_frame_; int num_first_partition_; int minimum_media_packets_fec_; FecProtectionParams params_; diff --git a/webrtc/modules/rtp_rtcp/source/producer_fec_unittest.cc b/webrtc/modules/rtp_rtcp/source/producer_fec_unittest.cc index 683b951f1e..f6d36d93d3 100644 --- a/webrtc/modules/rtp_rtcp/source/producer_fec_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/producer_fec_unittest.cc @@ -77,19 +77,19 @@ TEST_F(ProducerFecTest, OneFrameFec) { } EXPECT_TRUE(producer_->FecAvailable()); uint16_t seq_num = generator_->NextSeqNum(); - std::vector packets = producer_->GetFecPackets(kRedPayloadType, - kFecPayloadType, - seq_num, - kRtpHeaderSize); + RedPacket* packet = producer_->GetFecPacket(kRedPayloadType, + kFecPayloadType, + seq_num, + kRtpHeaderSize); EXPECT_FALSE(producer_->FecAvailable()); - ASSERT_EQ(1u, packets.size()); + ASSERT_TRUE(packet != NULL); VerifyHeader(seq_num, last_timestamp, - kRedPayloadType, kFecPayloadType, packets.front(), false); + kRedPayloadType, kFecPayloadType, packet, false); while (!rtp_packets.empty()) { delete rtp_packets.front(); rtp_packets.pop_front(); } - delete packets.front(); + delete packet; } TEST_F(ProducerFecTest, TwoFrameFec) { @@ -120,36 +120,39 @@ TEST_F(ProducerFecTest, TwoFrameFec) { } EXPECT_TRUE(producer_->FecAvailable()); uint16_t seq_num = generator_->NextSeqNum(); - std::vector packets = producer_->GetFecPackets(kRedPayloadType, - kFecPayloadType, - seq_num, - kRtpHeaderSize); + RedPacket* packet = producer_->GetFecPacket(kRedPayloadType, + kFecPayloadType, + seq_num, + kRtpHeaderSize); EXPECT_FALSE(producer_->FecAvailable()); - ASSERT_EQ(1u, packets.size()); - VerifyHeader(seq_num, last_timestamp, kRedPayloadType, kFecPayloadType, - packets.front(), false); + EXPECT_TRUE(packet != NULL); + VerifyHeader(seq_num, last_timestamp, + kRedPayloadType, kFecPayloadType, packet, false); while (!rtp_packets.empty()) { delete rtp_packets.front(); rtp_packets.pop_front(); } - delete packets.front(); + delete packet; } TEST_F(ProducerFecTest, BuildRedPacket) { generator_->NewFrame(1); RtpPacket* packet = generator_->NextPacket(0, 10); - rtc::scoped_ptr red_packet(producer_->BuildRedPacket( - packet->data, packet->length - kRtpHeaderSize, kRtpHeaderSize, - kRedPayloadType)); + RedPacket* red_packet = producer_->BuildRedPacket(packet->data, + packet->length - + kRtpHeaderSize, + kRtpHeaderSize, + kRedPayloadType); EXPECT_EQ(packet->length + 1, red_packet->length()); VerifyHeader(packet->header.header.sequenceNumber, packet->header.header.timestamp, kRedPayloadType, packet->header.header.payloadType, - red_packet.get(), + red_packet, true); // Marker bit set. for (int i = 0; i < 10; ++i) EXPECT_EQ(i, red_packet->data()[kRtpHeaderSize + 1 + i]); + delete red_packet; delete packet; } diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index c6efb90e39..d483e76c78 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -403,7 +403,7 @@ int32_t ModuleRtpRtcpImpl::SendOutgoingData( } return rtp_sender_.SendOutgoingData( frame_type, payload_type, time_stamp, capture_time_ms, payload_data, - payload_size, fragmentation, rtp_video_hdr); + payload_size, fragmentation, NULL, rtp_video_hdr); } bool ModuleRtpRtcpImpl::TimeToSendPacket(uint32_t ssrc, diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc index a38b5cf7d4..35f885a3e2 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc @@ -318,14 +318,14 @@ int32_t RTPSender::RegisterPayload( } return -1; } - int32_t ret_val = 0; + int32_t ret_val = -1; RtpUtility::Payload* payload = NULL; if (audio_configured_) { - // TODO(mflodman): Change to CreateAudioPayload and make static. ret_val = audio_->RegisterAudioPayload(payload_name, payload_number, frequency, channels, rate, payload); } else { - payload = video_->CreateVideoPayload(payload_name, payload_number, rate); + ret_val = video_->RegisterVideoPayload(payload_name, payload_number, rate, + payload); } if (payload) { payload_type_map_[payload_number] = payload; @@ -469,6 +469,7 @@ int32_t RTPSender::SendOutgoingData(FrameType frame_type, const uint8_t* payload_data, size_t payload_size, const RTPFragmentationHeader* fragmentation, + VideoCodecInformation* codec_info, const RTPVideoHeader* rtp_hdr) { uint32_t ssrc; { @@ -505,7 +506,7 @@ int32_t RTPSender::SendOutgoingData(FrameType frame_type, ret_val = video_->SendVideo(video_type, frame_type, payload_type, capture_timestamp, capture_time_ms, payload_data, - payload_size, fragmentation, rtp_hdr); + payload_size, fragmentation, codec_info, rtp_hdr); } CriticalSectionScoped cs(statistics_crit_.get()); @@ -724,8 +725,7 @@ int RTPSender::SelectiveRetransmissions() const { int RTPSender::SetSelectiveRetransmissions(uint8_t settings) { if (!video_) return -1; - video_->SetSelectiveRetransmissions(settings); - return 0; + return video_->SetSelectiveRetransmissions(settings); } void RTPSender::OnReceivedNACK(const std::list& nack_sequence_numbers, @@ -1066,11 +1066,9 @@ size_t RTPSender::RTPHeaderLength() const { return rtp_header_length; } -uint16_t RTPSender::AllocateSequenceNumber(uint16_t packets_to_send) { +uint16_t RTPSender::IncrementSequenceNumber() { CriticalSectionScoped cs(send_critsect_.get()); - uint16_t first_allocated_sequence_number = sequence_number_; - sequence_number_ += packets_to_send; - return first_allocated_sequence_number; + return sequence_number_++; } void RTPSender::ResetDataCounters() { @@ -1712,6 +1710,14 @@ int32_t RTPSender::RED(int8_t *payload_type) const { return audio_->RED(*payload_type); } +// Video +VideoCodecInformation *RTPSender::CodecInformationVideo() { + if (audio_configured_) { + return NULL; + } + return video_->CodecInformationVideo(); +} + RtpVideoCodecTypes RTPSender::VideoCodecType() const { assert(!audio_configured_ && "Sender is an audio stream!"); return video_->VideoCodecType(); @@ -1737,8 +1743,8 @@ int32_t RTPSender::SetGenericFECStatus(bool enable, if (audio_configured_) { return -1; } - video_->SetGenericFECStatus(enable, payload_type_red, payload_type_fec); - return 0; + return video_->SetGenericFECStatus(enable, payload_type_red, + payload_type_fec); } int32_t RTPSender::GenericFECStatus(bool* enable, @@ -1747,8 +1753,8 @@ int32_t RTPSender::GenericFECStatus(bool* enable, if (audio_configured_) { return -1; } - video_->GenericFECStatus(*enable, *payload_type_red, *payload_type_fec); - return 0; + return video_->GenericFECStatus( + *enable, *payload_type_red, *payload_type_fec); } int32_t RTPSender::SetFecParameters( @@ -1757,8 +1763,7 @@ int32_t RTPSender::SetFecParameters( if (audio_configured_) { return -1; } - video_->SetFecParameters(delta_params, key_params); - return 0; + return video_->SetFecParameters(delta_params, key_params); } void RTPSender::BuildRtxPacket(uint8_t* buffer, size_t* length, diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.h b/webrtc/modules/rtp_rtcp/source/rtp_sender.h index 6a5c4f00a6..baa067c5c0 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender.h +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.h @@ -24,8 +24,8 @@ #include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h" #include "webrtc/modules/rtp_rtcp/source/rtp_packet_history.h" #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_config.h" -#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" #include "webrtc/modules/rtp_rtcp/source/ssrc_database.h" +#include "webrtc/modules/rtp_rtcp/source/video_codec_information.h" #define MAX_INIT_RTP_SEQ_NUMBER 32767 // 2^15 -1. @@ -53,10 +53,7 @@ class RTPSenderInterface { bool inc_sequence_number = true) = 0; virtual size_t RTPHeaderLength() const = 0; - // Returns the next sequence number to use for a packet and allocates - // 'packets_to_send' number of sequence numbers. It's important all allocated - // sequence numbers are used in sequence to avoid perceived packet loss. - virtual uint16_t AllocateSequenceNumber(uint16_t packets_to_send) = 0; + virtual uint16_t IncrementSequenceNumber() = 0; virtual uint16_t SequenceNumber() const = 0; virtual size_t MaxPayloadLength() const = 0; virtual size_t MaxDataPayloadLength() const = 0; @@ -149,6 +146,7 @@ class RTPSender : public RTPSenderInterface { const uint8_t* payload_data, size_t payload_size, const RTPFragmentationHeader* fragmentation, + VideoCodecInformation* codec_info = NULL, const RTPVideoHeader* rtp_hdr = NULL); // RTP header extension @@ -219,7 +217,7 @@ class RTPSender : public RTPSenderInterface { const bool inc_sequence_number = true) override; size_t RTPHeaderLength() const override; - uint16_t AllocateSequenceNumber(uint16_t packets_to_send) override; + uint16_t IncrementSequenceNumber() override; size_t MaxPayloadLength() const override; uint16_t PacketOverHead() const override; @@ -253,6 +251,9 @@ class RTPSender : public RTPSenderInterface { // Get payload type for Redundant Audio Data RFC 2198. int32_t RED(int8_t *payload_type) const; + // Video. + VideoCodecInformation *CodecInformationVideo(); + RtpVideoCodecTypes VideoCodecType() const; uint32_t MaxConfiguredBitrateVideo() const; diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc index f337d2bb87..a55ca977f7 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc @@ -1346,7 +1346,7 @@ TEST_F(RtpSenderVideoTest, SendVideoWithCVO) { rtp_sender_video_->SendVideo(kRtpVideoGeneric, kVideoFrameKey, kPayload, kTimestamp, 0, packet_, sizeof(packet_), NULL, - &hdr); + NULL, &hdr); RtpHeaderExtensionMap map; map.Register(kRtpExtensionVideoRotation, kVideoRotationExtensionId); diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc index 6da30da2a0..2b14cfefa6 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc @@ -10,12 +10,10 @@ #include "webrtc/modules/rtp_rtcp/source/rtp_sender_video.h" +#include #include #include -#include - -#include "webrtc/base/checks.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" #include "webrtc/modules/rtp_rtcp/source/byte_io.h" #include "webrtc/modules/rtp_rtcp/source/producer_fec.h" @@ -35,8 +33,8 @@ struct RtpPacket { RTPSenderVideo::RTPSenderVideo(Clock* clock, RTPSenderInterface* rtpSender) : _rtpSender(*rtpSender), - crit_(CriticalSectionWrapper::CreateCriticalSection()), _videoType(kRtpVideoGeneric), + _videoCodecInformation(NULL), _maxBitrate(0), _retransmissionSettings(kRetransmitBaseLayer), @@ -45,6 +43,7 @@ RTPSenderVideo::RTPSenderVideo(Clock* clock, RTPSenderInterface* rtpSender) _fecEnabled(false), _payloadTypeRED(-1), _payloadTypeFEC(-1), + _numberFirstPartition(0), delta_fec_params_(), key_fec_params_(), producer_fec_(&_fec), @@ -58,6 +57,9 @@ RTPSenderVideo::RTPSenderVideo(Clock* clock, RTPSenderInterface* rtpSender) } RTPSenderVideo::~RTPSenderVideo() { + if (_videoCodecInformation) { + delete _videoCodecInformation; + } } void RTPSenderVideo::SetVideoCodecType(RtpVideoCodecTypes videoType) { @@ -68,11 +70,11 @@ RtpVideoCodecTypes RTPSenderVideo::VideoCodecType() const { return _videoType; } -// Static. -RtpUtility::Payload* RTPSenderVideo::CreateVideoPayload( +int32_t RTPSenderVideo::RegisterVideoPayload( const char payloadName[RTP_PAYLOAD_NAME_SIZE], const int8_t payloadType, - const uint32_t maxBitRate) { + const uint32_t maxBitRate, + RtpUtility::Payload*& payload) { RtpVideoCodecTypes videoType = kRtpVideoGeneric; if (RtpUtility::StringCompare(payloadName, "VP8", 3)) { videoType = kRtpVideoVp8; @@ -83,93 +85,103 @@ RtpUtility::Payload* RTPSenderVideo::CreateVideoPayload( } else { videoType = kRtpVideoGeneric; } - RtpUtility::Payload* payload = new RtpUtility::Payload(); + payload = new RtpUtility::Payload; payload->name[RTP_PAYLOAD_NAME_SIZE - 1] = 0; strncpy(payload->name, payloadName, RTP_PAYLOAD_NAME_SIZE - 1); payload->typeSpecific.Video.videoCodecType = videoType; payload->typeSpecific.Video.maxRate = maxBitRate; payload->audio = false; - return payload; + return 0; } -void RTPSenderVideo::SendVideoPacket(uint8_t* data_buffer, - const size_t payload_length, - const size_t rtp_header_length, - uint16_t seq_num, - const uint32_t capture_timestamp, - int64_t capture_time_ms, - StorageType storage) { - if (_rtpSender.SendToNetwork(data_buffer, payload_length, rtp_header_length, - capture_time_ms, storage, - PacedSender::kNormalPriority) == 0) { - _videoBitrate.Update(payload_length + rtp_header_length); - TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), - "Video::PacketNormal", "timestamp", capture_timestamp, - "seqnum", seq_num); - } else { - LOG(LS_WARNING) << "Failed to send video packet " << seq_num; - } -} +int32_t RTPSenderVideo::SendVideoPacket(uint8_t* data_buffer, + const size_t payload_length, + const size_t rtp_header_length, + const uint32_t capture_timestamp, + int64_t capture_time_ms, + StorageType storage, + bool protect) { + if (_fecEnabled) { + int ret = 0; + size_t fec_overhead_sent = 0; + size_t video_sent = 0; -void RTPSenderVideo::SendVideoPacketAsRed(uint8_t* data_buffer, - const size_t payload_length, - const size_t rtp_header_length, - uint16_t media_seq_num, - const uint32_t capture_timestamp, - int64_t capture_time_ms, - StorageType media_packet_storage, - bool protect) { - rtc::scoped_ptr red_packet; - std::vector fec_packets; - StorageType fec_storage = kDontRetransmit; - uint16_t first_fec_sequence_number = 0; - { - // Only protect while creating RED and FEC packets, not when sending. - CriticalSectionScoped cs(crit_.get()); - red_packet.reset(producer_fec_.BuildRedPacket( - data_buffer, payload_length, rtp_header_length, _payloadTypeRED)); - if (protect) { - producer_fec_.AddRtpPacketAndGenerateFec(data_buffer, payload_length, - rtp_header_length); - } - uint16_t num_fec_packets = producer_fec_.NumAvailableFecPackets(); - if (num_fec_packets > 0) { - first_fec_sequence_number = - _rtpSender.AllocateSequenceNumber(num_fec_packets); - fec_packets = producer_fec_.GetFecPackets( - _payloadTypeRED, _payloadTypeFEC, first_fec_sequence_number, - rtp_header_length); - DCHECK_EQ(num_fec_packets, fec_packets.size()); - if (_retransmissionSettings & kRetransmitFECPackets) - fec_storage = kAllowRetransmission; - } - } - if (_rtpSender.SendToNetwork( - red_packet->data(), red_packet->length() - rtp_header_length, - rtp_header_length, capture_time_ms, media_packet_storage, - PacedSender::kNormalPriority) == 0) { - _videoBitrate.Update(red_packet->length()); + RedPacket* red_packet = producer_fec_.BuildRedPacket( + data_buffer, payload_length, rtp_header_length, _payloadTypeRED); TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "Video::PacketRed", "timestamp", capture_timestamp, - "seqnum", media_seq_num); - } else { - LOG(LS_WARNING) << "Failed to send RED packet " << media_seq_num; - } - for (RedPacket* fec_packet : fec_packets) { - if (_rtpSender.SendToNetwork(fec_packet->data(), - fec_packet->length() - rtp_header_length, - rtp_header_length, capture_time_ms, - fec_storage, PacedSender::kNormalPriority)) { - _fecOverheadRate.Update(fec_packet->length()); + "seqnum", _rtpSender.SequenceNumber()); + // Sending the media packet with RED header. + int packet_success = + _rtpSender.SendToNetwork(red_packet->data(), + red_packet->length() - rtp_header_length, + rtp_header_length, + capture_time_ms, + storage, + PacedSender::kNormalPriority); + + ret |= packet_success; + + if (packet_success == 0) { + video_sent += red_packet->length(); + } + delete red_packet; + red_packet = NULL; + + if (protect) { + ret = producer_fec_.AddRtpPacketAndGenerateFec( + data_buffer, payload_length, rtp_header_length); + if (ret != 0) + return ret; + } + + while (producer_fec_.FecAvailable()) { + red_packet = + producer_fec_.GetFecPacket(_payloadTypeRED, + _payloadTypeFEC, + _rtpSender.IncrementSequenceNumber(), + rtp_header_length); + StorageType storage = kDontRetransmit; + if (_retransmissionSettings & kRetransmitFECPackets) { + storage = kAllowRetransmission; + } TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "Video::PacketFec", "timestamp", capture_timestamp, - "seqnum", first_fec_sequence_number++); - } else { - LOG(LS_WARNING) << "Failed to send FEC packet " - << first_fec_sequence_number - 1; + "seqnum", _rtpSender.SequenceNumber()); + // Sending FEC packet with RED header. + int packet_success = + _rtpSender.SendToNetwork(red_packet->data(), + red_packet->length() - rtp_header_length, + rtp_header_length, + capture_time_ms, + storage, + PacedSender::kNormalPriority); + + ret |= packet_success; + + if (packet_success == 0) { + fec_overhead_sent += red_packet->length(); + } + delete red_packet; + red_packet = NULL; } - delete fec_packet; + _videoBitrate.Update(video_sent); + _fecOverheadRate.Update(fec_overhead_sent); + return ret; } + TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), + "Video::PacketNormal", "timestamp", capture_timestamp, + "seqnum", _rtpSender.SequenceNumber()); + int ret = _rtpSender.SendToNetwork(data_buffer, + payload_length, + rtp_header_length, + capture_time_ms, + storage, + PacedSender::kNormalPriority); + if (ret == 0) { + _videoBitrate.Update(payload_length + rtp_header_length); + } + return ret; } int32_t RTPSenderVideo::SendRTPIntraRequest() { @@ -192,10 +204,9 @@ int32_t RTPSenderVideo::SendRTPIntraRequest() { data, 0, length, -1, kDontStore, PacedSender::kNormalPriority); } -void RTPSenderVideo::SetGenericFECStatus(const bool enable, - const uint8_t payloadTypeRED, - const uint8_t payloadTypeFEC) { - CriticalSectionScoped cs(crit_.get()); +int32_t RTPSenderVideo::SetGenericFECStatus(const bool enable, + const uint8_t payloadTypeRED, + const uint8_t payloadTypeFEC) { _fecEnabled = enable; _payloadTypeRED = payloadTypeRED; _payloadTypeFEC = payloadTypeFEC; @@ -204,19 +215,19 @@ void RTPSenderVideo::SetGenericFECStatus(const bool enable, delta_fec_params_.max_fec_frames = key_fec_params_.max_fec_frames = 1; delta_fec_params_.fec_mask_type = key_fec_params_.fec_mask_type = kFecMaskRandom; + return 0; } -void RTPSenderVideo::GenericFECStatus(bool& enable, - uint8_t& payloadTypeRED, - uint8_t& payloadTypeFEC) const { - CriticalSectionScoped cs(crit_.get()); +int32_t RTPSenderVideo::GenericFECStatus(bool& enable, + uint8_t& payloadTypeRED, + uint8_t& payloadTypeFEC) const { enable = _fecEnabled; payloadTypeRED = _payloadTypeRED; payloadTypeFEC = _payloadTypeFEC; + return 0; } size_t RTPSenderVideo::FECPacketOverhead() const { - CriticalSectionScoped cs(crit_.get()); if (_fecEnabled) { // Overhead is FEC headers plus RED for FEC header plus anything in RTP // header beyond the 12 bytes base header (CSRC list, extensions...) @@ -229,13 +240,14 @@ size_t RTPSenderVideo::FECPacketOverhead() const { return 0; } -void RTPSenderVideo::SetFecParameters(const FecProtectionParams* delta_params, - const FecProtectionParams* key_params) { - CriticalSectionScoped cs(crit_.get()); - DCHECK(delta_params); - DCHECK(key_params); +int32_t RTPSenderVideo::SetFecParameters( + const FecProtectionParams* delta_params, + const FecProtectionParams* key_params) { + assert(delta_params); + assert(key_params); delta_fec_params_ = *delta_params; key_fec_params_ = *key_params; + return 0; } int32_t RTPSenderVideo::SendVideo(const RtpVideoCodecTypes videoType, @@ -246,30 +258,56 @@ int32_t RTPSenderVideo::SendVideo(const RtpVideoCodecTypes videoType, const uint8_t* payloadData, const size_t payloadSize, const RTPFragmentationHeader* fragmentation, + VideoCodecInformation* codecInfo, const RTPVideoHeader* rtpHdr) { if (payloadSize == 0) { return -1; } - rtc::scoped_ptr packetizer( - RtpPacketizer::Create(videoType, _rtpSender.MaxDataPayloadLength(), - &(rtpHdr->codecHeader), frameType)); - - StorageType storage = kDontStore; - bool fec_enabled = false; - { - CriticalSectionScoped cs(crit_.get()); - FecProtectionParams* fec_params = - frameType == kVideoFrameKey ? &key_fec_params_ : &delta_fec_params_; - producer_fec_.SetFecParameters(fec_params, 0); - storage = packetizer->GetStorageType(_retransmissionSettings); - fec_enabled = _fecEnabled; + if (frameType == kVideoFrameKey) { + producer_fec_.SetFecParameters(&key_fec_params_, _numberFirstPartition); + } else { + producer_fec_.SetFecParameters(&delta_fec_params_, _numberFirstPartition); } + // Default setting for number of first partition packets: + // Will be extracted in SendVP8 for VP8 codec; other codecs use 0 + _numberFirstPartition = 0; + return Send(videoType, frameType, payloadType, captureTimeStamp, + capture_time_ms, payloadData, payloadSize, fragmentation, rtpHdr) + ? 0 + : -1; +} + +VideoCodecInformation* RTPSenderVideo::CodecInformationVideo() { + return _videoCodecInformation; +} + +void RTPSenderVideo::SetMaxConfiguredBitrateVideo(const uint32_t maxBitrate) { + _maxBitrate = maxBitrate; +} + +uint32_t RTPSenderVideo::MaxConfiguredBitrateVideo() const { + return _maxBitrate; +} + +bool RTPSenderVideo::Send(const RtpVideoCodecTypes videoType, + const FrameType frameType, + const int8_t payloadType, + const uint32_t captureTimeStamp, + int64_t capture_time_ms, + const uint8_t* payloadData, + const size_t payloadSize, + const RTPFragmentationHeader* fragmentation, + const RTPVideoHeader* rtpHdr) { uint16_t rtp_header_length = _rtpSender.RTPHeaderLength(); size_t payload_bytes_to_send = payloadSize; const uint8_t* data = payloadData; + size_t max_payload_length = _rtpSender.MaxDataPayloadLength(); + + rtc::scoped_ptr packetizer(RtpPacketizer::Create( + videoType, max_payload_length, &(rtpHdr->codecHeader), frameType)); // TODO(changbin): we currently don't support to configure the codec to // output multiple partitions for VP8. Should remove below check after the @@ -283,14 +321,16 @@ int32_t RTPSenderVideo::SendVideo(const RtpVideoCodecTypes videoType, while (!last) { uint8_t dataBuffer[IP_PACKET_SIZE] = {0}; size_t payload_bytes_in_packet = 0; - if (!packetizer->NextPacket(&dataBuffer[rtp_header_length], - &payload_bytes_in_packet, &last)) { - return -1; + if (!packetizer->NextPacket( + &dataBuffer[rtp_header_length], &payload_bytes_in_packet, &last)) { + return false; } + // Write RTP header. // Set marker bit true if this is the last packet in frame. _rtpSender.BuildRTPheader( dataBuffer, payloadType, last, captureTimeStamp, capture_time_ms); + // According to // http://www.etsi.org/deliver/etsi_ts/126100_126199/126114/12.07.00_60/ // ts_126114v120700p.pdf Section 7.4.5: @@ -303,7 +343,7 @@ int32_t RTPSenderVideo::SendVideo(const RtpVideoCodecTypes videoType, // value sent. // Here we are adding it to the last packet of every frame at this point. if (!rtpHdr) { - DCHECK(!_rtpSender.IsRtpHeaderExtensionRegistered( + assert(!_rtpSender.IsRtpHeaderExtensionRegistered( kRtpExtensionVideoRotation)); } else if (last) { // Checking whether CVO header extension is registered will require taking @@ -315,29 +355,22 @@ int32_t RTPSenderVideo::SendVideo(const RtpVideoCodecTypes videoType, _rtpSender.UpdateVideoRotation(dataBuffer, packetSize, rtp_header, rtpHdr->rotation); } - if (fec_enabled) { - SendVideoPacketAsRed(dataBuffer, payload_bytes_in_packet, - rtp_header_length, _rtpSender.SequenceNumber(), - captureTimeStamp, capture_time_ms, storage, - packetizer->GetProtectionType() == kProtectedPacket); - } else { - SendVideoPacket(dataBuffer, payload_bytes_in_packet, rtp_header_length, - _rtpSender.SequenceNumber(), captureTimeStamp, - capture_time_ms, storage); + if (SendVideoPacket(dataBuffer, + payload_bytes_in_packet, + rtp_header_length, + captureTimeStamp, + capture_time_ms, + packetizer->GetStorageType(_retransmissionSettings), + packetizer->GetProtectionType() == kProtectedPacket)) { + LOG(LS_WARNING) << packetizer->ToString() + << " failed to send packet number " + << _rtpSender.SequenceNumber(); } } TRACE_EVENT_ASYNC_END1( "webrtc", "Video", capture_time_ms, "timestamp", _rtpSender.Timestamp()); - return 0; -} - -void RTPSenderVideo::SetMaxConfiguredBitrateVideo(const uint32_t maxBitrate) { - _maxBitrate = maxBitrate; -} - -uint32_t RTPSenderVideo::MaxConfiguredBitrateVideo() const { - return _maxBitrate; + return true; } void RTPSenderVideo::ProcessBitrate() { @@ -354,13 +387,12 @@ uint32_t RTPSenderVideo::FecOverheadRate() const { } int RTPSenderVideo::SelectiveRetransmissions() const { - CriticalSectionScoped cs(crit_.get()); return _retransmissionSettings; } -void RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) { - CriticalSectionScoped cs(crit_.get()); +int RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) { _retransmissionSettings = settings; + return 0; } } // namespace webrtc diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_video.h b/webrtc/modules/rtp_rtcp/source/rtp_sender_video.h index f412542d86..92c312f5e9 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender_video.h +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_video.h @@ -13,8 +13,6 @@ #include -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/thread_annotations.h" #include "webrtc/common_types.h" #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" #include "webrtc/modules/rtp_rtcp/source/bitrate.h" @@ -39,10 +37,10 @@ class RTPSenderVideo { size_t FECPacketOverhead() const; - static RtpUtility::Payload* CreateVideoPayload( - const char payloadName[RTP_PAYLOAD_NAME_SIZE], - const int8_t payloadType, - const uint32_t maxBitRate); + int32_t RegisterVideoPayload(const char payloadName[RTP_PAYLOAD_NAME_SIZE], + const int8_t payloadType, + const uint32_t maxBitRate, + RtpUtility::Payload*& payload); int32_t SendVideo(const RtpVideoCodecTypes videoType, const FrameType frameType, @@ -52,27 +50,30 @@ class RTPSenderVideo { const uint8_t* payloadData, const size_t payloadSize, const RTPFragmentationHeader* fragmentation, + VideoCodecInformation* codecInfo, const RTPVideoHeader* rtpHdr); int32_t SendRTPIntraRequest(); void SetVideoCodecType(RtpVideoCodecTypes type); + VideoCodecInformation* CodecInformationVideo(); + void SetMaxConfiguredBitrateVideo(const uint32_t maxBitrate); uint32_t MaxConfiguredBitrateVideo() const; // FEC - void SetGenericFECStatus(const bool enable, - const uint8_t payloadTypeRED, - const uint8_t payloadTypeFEC); + int32_t SetGenericFECStatus(const bool enable, + const uint8_t payloadTypeRED, + const uint8_t payloadTypeFEC); - void GenericFECStatus(bool& enable, - uint8_t& payloadTypeRED, - uint8_t& payloadTypeFEC) const; + int32_t GenericFECStatus(bool& enable, + uint8_t& payloadTypeRED, + uint8_t& payloadTypeFEC) const; - void SetFecParameters(const FecProtectionParams* delta_params, - const FecProtectionParams* key_params); + int32_t SetFecParameters(const FecProtectionParams* delta_params, + const FecProtectionParams* key_params); void ProcessBitrate(); @@ -80,43 +81,45 @@ class RTPSenderVideo { uint32_t FecOverheadRate() const; int SelectiveRetransmissions() const; - void SetSelectiveRetransmissions(uint8_t settings); + int SetSelectiveRetransmissions(uint8_t settings); -private: - void SendVideoPacket(uint8_t* dataBuffer, - const size_t payloadLength, - const size_t rtpHeaderLength, - uint16_t seq_num, - const uint32_t capture_timestamp, - int64_t capture_time_ms, - StorageType storage); + protected: + virtual int32_t SendVideoPacket(uint8_t* dataBuffer, + const size_t payloadLength, + const size_t rtpHeaderLength, + const uint32_t capture_timestamp, + int64_t capture_time_ms, + StorageType storage, + bool protect); - void SendVideoPacketAsRed(uint8_t* dataBuffer, - const size_t payloadLength, - const size_t rtpHeaderLength, - uint16_t video_seq_num, - const uint32_t capture_timestamp, - int64_t capture_time_ms, - StorageType media_packet_storage, - bool protect); + private: + bool Send(const RtpVideoCodecTypes videoType, + const FrameType frameType, + const int8_t payloadType, + const uint32_t captureTimeStamp, + int64_t capture_time_ms, + const uint8_t* payloadData, + const size_t payloadSize, + const RTPFragmentationHeader* fragmentation, + const RTPVideoHeader* rtpHdr); + private: RTPSenderInterface& _rtpSender; - // Should never be held when calling out of this class. - const rtc::scoped_ptr crit_; - RtpVideoCodecTypes _videoType; + VideoCodecInformation* _videoCodecInformation; uint32_t _maxBitrate; - int32_t _retransmissionSettings GUARDED_BY(crit_); + int32_t _retransmissionSettings; // FEC ForwardErrorCorrection _fec; - bool _fecEnabled GUARDED_BY(crit_); - int8_t _payloadTypeRED GUARDED_BY(crit_); - int8_t _payloadTypeFEC GUARDED_BY(crit_); - FecProtectionParams delta_fec_params_ GUARDED_BY(crit_); - FecProtectionParams key_fec_params_ GUARDED_BY(crit_); - ProducerFec producer_fec_ GUARDED_BY(crit_); + bool _fecEnabled; + int8_t _payloadTypeRED; + int8_t _payloadTypeFEC; + unsigned int _numberFirstPartition; + FecProtectionParams delta_fec_params_; + FecProtectionParams key_fec_params_; + ProducerFec producer_fec_; // Bitrate used for FEC payload, RED headers, RTP headers for FEC packets // and any padding overhead. diff --git a/webrtc/modules/video_coding/main/interface/video_coding.h b/webrtc/modules/video_coding/main/interface/video_coding.h index 1c77197eb4..4d01da9705 100644 --- a/webrtc/modules/video_coding/main/interface/video_coding.h +++ b/webrtc/modules/video_coding/main/interface/video_coding.h @@ -82,9 +82,7 @@ public: }; static VideoCodingModule* Create( - Clock* clock, - VideoEncoderRateObserver* encoder_rate_observer, - VCMQMSettingsCallback* qm_settings_callback); + VideoEncoderRateObserver* encoder_rate_observer); static VideoCodingModule* Create(Clock* clock, EventFactory* event_factory); @@ -269,6 +267,16 @@ public: virtual int32_t RegisterSendStatisticsCallback( VCMSendStatisticsCallback* sendStats) = 0; + // Register a video quality settings callback which will be called when + // frame rate/dimensions need to be updated for video quality optimization + // + // Input: + // - videoQMSettings : The callback object to register. + // + // Return value : VCM_OK, on success. + // < 0, on error + virtual int32_t RegisterVideoQMCallback(VCMQMSettingsCallback* videoQMSettings) = 0; + // Register a video protection callback which will be called to deliver // the requested FEC rate and NACK status (on/off). // diff --git a/webrtc/modules/video_coding/main/source/media_optimization.cc b/webrtc/modules/video_coding/main/source/media_optimization.cc index cbf3dea00e..1f0eb5c662 100644 --- a/webrtc/modules/video_coding/main/source/media_optimization.cc +++ b/webrtc/modules/video_coding/main/source/media_optimization.cc @@ -246,7 +246,7 @@ uint32_t MediaOptimization::SetTargetRates( // Update protection settings, when applicable. float sent_video_rate_kbps = 0.0f; - if (loss_prot_logic_->SelectedType() != kNone) { + if (selected_method) { // Update protection method with content metrics. selected_method->UpdateContentMetrics(content_->ShortTermAvgData()); diff --git a/webrtc/modules/video_coding/main/source/video_coding_impl.cc b/webrtc/modules/video_coding/main/source/video_coding_impl.cc index 0ae0eaf39e..c2741ae56a 100644 --- a/webrtc/modules/video_coding/main/source/video_coding_impl.cc +++ b/webrtc/modules/video_coding/main/source/video_coding_impl.cc @@ -74,13 +74,11 @@ class VideoCodingModuleImpl : public VideoCodingModule { VideoCodingModuleImpl(Clock* clock, EventFactory* event_factory, bool owns_event_factory, - VideoEncoderRateObserver* encoder_rate_observer, - VCMQMSettingsCallback* qm_settings_callback) + VideoEncoderRateObserver* encoder_rate_observer) : VideoCodingModule(), sender_(new vcm::VideoSender(clock, &post_encode_callback_, - encoder_rate_observer, - qm_settings_callback)), + encoder_rate_observer)), receiver_(new vcm::VideoReceiver(clock, event_factory)), own_event_factory_(owns_event_factory ? event_factory : NULL) {} @@ -163,6 +161,11 @@ class VideoCodingModuleImpl : public VideoCodingModule { return sender_->RegisterSendStatisticsCallback(sendStats); } + int32_t RegisterVideoQMCallback( + VCMQMSettingsCallback* videoQMSettings) override { + return sender_->RegisterVideoQMCallback(videoQMSettings); + } + int32_t RegisterProtectionCallback( VCMProtectionCallback* protection) override { return sender_->RegisterProtectionCallback(protection); @@ -356,11 +359,10 @@ int32_t VideoCodingModule::Codec(VideoCodecType codecType, VideoCodec* codec) { } VideoCodingModule* VideoCodingModule::Create( - Clock* clock, - VideoEncoderRateObserver* encoder_rate_observer, - VCMQMSettingsCallback* qm_settings_callback) { - return new VideoCodingModuleImpl(clock, new EventFactoryImpl, true, - encoder_rate_observer, qm_settings_callback); + VideoEncoderRateObserver* encoder_rate_observer) { + return new VideoCodingModuleImpl(Clock::GetRealTimeClock(), + new EventFactoryImpl, true, + encoder_rate_observer); } VideoCodingModule* VideoCodingModule::Create( @@ -368,8 +370,7 @@ VideoCodingModule* VideoCodingModule::Create( EventFactory* event_factory) { assert(clock); assert(event_factory); - return new VideoCodingModuleImpl(clock, event_factory, false, nullptr, - nullptr); + return new VideoCodingModuleImpl(clock, event_factory, false, nullptr); } void VideoCodingModule::Destroy(VideoCodingModule* module) { diff --git a/webrtc/modules/video_coding/main/source/video_coding_impl.h b/webrtc/modules/video_coding/main/source/video_coding_impl.h index c3ea896be4..bb643bf20d 100644 --- a/webrtc/modules/video_coding/main/source/video_coding_impl.h +++ b/webrtc/modules/video_coding/main/source/video_coding_impl.h @@ -58,8 +58,7 @@ class VideoSender { VideoSender(Clock* clock, EncodedImageCallback* post_encode_callback, - VideoEncoderRateObserver* encoder_rate_observer, - VCMQMSettingsCallback* qm_settings_callback); + VideoEncoderRateObserver* encoder_rate_observer); ~VideoSender(); @@ -100,6 +99,7 @@ class VideoSender { int32_t RegisterTransportCallback(VCMPacketizationCallback* transport); int32_t RegisterSendStatisticsCallback(VCMSendStatisticsCallback* sendStats); + int32_t RegisterVideoQMCallback(VCMQMSettingsCallback* videoQMSettings); int32_t RegisterProtectionCallback(VCMProtectionCallback* protection); void SetVideoProtection(bool enable, VCMVideoProtection videoProtection); @@ -139,7 +139,7 @@ class VideoSender { VideoCodec current_codec_; rtc::ThreadChecker main_thread_; - VCMQMSettingsCallback* const qm_settings_callback_; + VCMQMSettingsCallback* qm_settings_callback_; VCMProtectionCallback* protection_callback_; }; diff --git a/webrtc/modules/video_coding/main/source/video_sender.cc b/webrtc/modules/video_coding/main/source/video_sender.cc index 93e15502f6..1d63d2e807 100644 --- a/webrtc/modules/video_coding/main/source/video_sender.cc +++ b/webrtc/modules/video_coding/main/source/video_sender.cc @@ -26,7 +26,7 @@ namespace vcm { class DebugRecorder { public: DebugRecorder() - : cs_(CriticalSectionWrapper::CreateCriticalSection()), file_(nullptr) {} + : cs_(CriticalSectionWrapper::CreateCriticalSection()), file_(NULL) {} ~DebugRecorder() { Stop(); } @@ -44,7 +44,7 @@ class DebugRecorder { CriticalSectionScoped cs(cs_.get()); if (file_) { fclose(file_); - file_ = nullptr; + file_ = NULL; } } @@ -61,8 +61,7 @@ class DebugRecorder { VideoSender::VideoSender(Clock* clock, EncodedImageCallback* post_encode_callback, - VideoEncoderRateObserver* encoder_rate_observer, - VCMQMSettingsCallback* qm_settings_callback) + VideoEncoderRateObserver* encoder_rate_observer) : clock_(clock), recorder_(new DebugRecorder()), process_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), @@ -71,17 +70,16 @@ VideoSender::VideoSender(Clock* clock, _encodedFrameCallback(post_encode_callback), _nextFrameTypes(1, kVideoFrameDelta), _mediaOpt(clock_), - _sendStatsCallback(nullptr), + _sendStatsCallback(NULL), _codecDataBase(encoder_rate_observer), frame_dropper_enabled_(true), _sendStatsTimer(1000, clock_), current_codec_(), - qm_settings_callback_(qm_settings_callback), - protection_callback_(nullptr) { + qm_settings_callback_(NULL), + protection_callback_(NULL) { // Allow VideoSender to be created on one thread but used on another, post // construction. This is currently how this class is being used by at least // one external project (diffractor). - _mediaOpt.EnableQM(qm_settings_callback_ != nullptr); main_thread_.DetachFromThread(); } @@ -95,7 +93,7 @@ int32_t VideoSender::Process() { if (_sendStatsTimer.TimeUntilProcess() == 0) { _sendStatsTimer.Processed(); CriticalSectionScoped cs(process_crit_sect_.get()); - if (_sendStatsCallback != nullptr) { + if (_sendStatsCallback != NULL) { uint32_t bitRate = _mediaOpt.SentBitRate(); uint32_t frameRate = _mediaOpt.SentFrameRate(); _sendStatsCallback->SendStatistics(bitRate, frameRate); @@ -110,8 +108,8 @@ int32_t VideoSender::InitializeSender() { DCHECK(main_thread_.CalledOnValidThread()); CriticalSectionScoped cs(_sendCritSect); _codecDataBase.ResetSender(); - _encoder = nullptr; - _encodedFrameCallback.SetTransportCallback(nullptr); + _encoder = NULL; + _encodedFrameCallback.SetTransportCallback(NULL); _mediaOpt.Reset(); // Resetting frame dropper return VCM_OK; } @@ -126,7 +124,7 @@ int32_t VideoSender::RegisterSendCodec(const VideoCodec* sendCodec, uint32_t maxPayloadSize) { DCHECK(main_thread_.CalledOnValidThread()); CriticalSectionScoped cs(_sendCritSect); - if (sendCodec == nullptr) { + if (sendCodec == NULL) { return VCM_PARAMETER_ERROR; } @@ -179,7 +177,7 @@ const VideoCodec& VideoSender::GetSendCodec() const { int32_t VideoSender::SendCodecBlocking(VideoCodec* currentSendCodec) const { CriticalSectionScoped cs(_sendCritSect); - if (currentSendCodec == nullptr) { + if (currentSendCodec == NULL) { return VCM_PARAMETER_ERROR; } return _codecDataBase.SendCodec(currentSendCodec) ? 0 : -1; @@ -199,13 +197,13 @@ int32_t VideoSender::RegisterExternalEncoder(VideoEncoder* externalEncoder, CriticalSectionScoped cs(_sendCritSect); - if (externalEncoder == nullptr) { + if (externalEncoder == NULL) { bool wasSendCodec = false; const bool ret = _codecDataBase.DeregisterExternalEncoder(payloadType, &wasSendCodec); if (wasSendCodec) { // Make sure the VCM doesn't use the de-registered codec - _encoder = nullptr; + _encoder = NULL; } return ret ? 0 : -1; } @@ -218,7 +216,7 @@ int32_t VideoSender::RegisterExternalEncoder(VideoEncoder* externalEncoder, int32_t VideoSender::CodecConfigParameters(uint8_t* buffer, int32_t size) const { CriticalSectionScoped cs(_sendCritSect); - if (_encoder != nullptr) { + if (_encoder != NULL) { return _encoder->CodecConfigParameters(buffer, size); } return VCM_UNINITIALIZED; @@ -268,6 +266,7 @@ int32_t VideoSender::SetChannelParameters(uint32_t target_bitrate, // here? This effectively means that the network thread will be blocked for // as much as frame encoding period. + CriticalSectionScoped sendCs(_sendCritSect); uint32_t target_rate = _mediaOpt.SetTargetRates(target_bitrate, lossRate, rtt, @@ -275,11 +274,10 @@ int32_t VideoSender::SetChannelParameters(uint32_t target_bitrate, qm_settings_callback_); uint32_t input_frame_rate = _mediaOpt.InputFrameRate(); - CriticalSectionScoped sendCs(_sendCritSect); int32_t ret = VCM_UNINITIALIZED; static_assert(VCM_UNINITIALIZED < 0, "VCM_UNINITIALIZED must be negative."); - if (_encoder != nullptr) { + if (_encoder != NULL) { ret = _encoder->SetChannelParameters(lossRate, rtt); if (ret >= 0) { ret = _encoder->SetRates(target_rate, input_frame_rate); @@ -306,13 +304,27 @@ int32_t VideoSender::RegisterSendStatisticsCallback( return VCM_OK; } +// Register a video quality settings callback which will be called when frame +// rate/dimensions need to be updated for video quality optimization +int32_t VideoSender::RegisterVideoQMCallback( + VCMQMSettingsCallback* qm_settings_callback) { + CriticalSectionScoped cs(_sendCritSect); + DCHECK(qm_settings_callback_ == qm_settings_callback || + !qm_settings_callback_ || + !qm_settings_callback) << "Overwriting the previous callback?"; + qm_settings_callback_ = qm_settings_callback; + _mediaOpt.EnableQM(qm_settings_callback_ != NULL); + return VCM_OK; +} + // Register a video protection callback which will be called to deliver the // requested FEC rate and NACK status (on/off). -// Note: this callback is assumed to only be registered once and before it is -// used in this class. int32_t VideoSender::RegisterProtectionCallback( VCMProtectionCallback* protection_callback) { - DCHECK(protection_callback == nullptr || protection_callback_ == nullptr); + CriticalSectionScoped cs(_sendCritSect); + DCHECK(protection_callback_ == protection_callback || + !protection_callback_ || + !protection_callback) << "Overwriting the previous callback?"; protection_callback_ = protection_callback; return VCM_OK; } @@ -347,7 +359,7 @@ int32_t VideoSender::AddVideoFrame(const I420VideoFrame& videoFrame, const VideoContentMetrics* contentMetrics, const CodecSpecificInfo* codecSpecificInfo) { CriticalSectionScoped cs(_sendCritSect); - if (_encoder == nullptr) { + if (_encoder == NULL) { return VCM_UNINITIALIZED; } // TODO(holmer): Add support for dropping frames per stream. Currently we @@ -386,7 +398,7 @@ int32_t VideoSender::IntraFrameRequest(int stream_index) { return -1; } _nextFrameTypes[stream_index] = kVideoFrameKey; - if (_encoder != nullptr && _encoder->InternalSource()) { + if (_encoder != NULL && _encoder->InternalSource()) { // Try to request the frame if we have an external encoder with // internal source since AddVideoFrame never will be called. if (_encoder->RequestFrame(_nextFrameTypes) == WEBRTC_VIDEO_CODEC_OK) { diff --git a/webrtc/modules/video_coding/main/source/video_sender_unittest.cc b/webrtc/modules/video_coding/main/source/video_sender_unittest.cc index 9c01ad539e..f28b9dfba4 100644 --- a/webrtc/modules/video_coding/main/source/video_sender_unittest.cc +++ b/webrtc/modules/video_coding/main/source/video_sender_unittest.cc @@ -177,8 +177,7 @@ class TestVideoSender : public ::testing::Test { TestVideoSender() : clock_(1000), packetization_callback_(&clock_) {} void SetUp() override { - sender_.reset( - new VideoSender(&clock_, &post_encode_callback_, nullptr, nullptr)); + sender_.reset(new VideoSender(&clock_, &post_encode_callback_, nullptr)); EXPECT_EQ(0, sender_->InitializeSender()); EXPECT_EQ(0, sender_->RegisterTransportCallback(&packetization_callback_)); } diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc index cd30ab7d76..82555d79b6 100644 --- a/webrtc/video_engine/vie_channel.cc +++ b/webrtc/video_engine/vie_channel.cc @@ -104,9 +104,7 @@ ViEChannel::ViEChannel(int32_t channel_id, rtp_rtcp_cs_(CriticalSectionWrapper::CreateCriticalSection()), send_payload_router_(new PayloadRouter()), vcm_protection_callback_(new ViEChannelProtectionCallback(this)), - vcm_(VideoCodingModule::Create(Clock::GetRealTimeClock(), - nullptr, - nullptr)), + vcm_(VideoCodingModule::Create(nullptr)), vie_receiver_(channel_id, vcm_, remote_bitrate_estimator, this), vie_sender_(channel_id), vie_sync_(vcm_, this), diff --git a/webrtc/video_engine/vie_encoder.cc b/webrtc/video_engine/vie_encoder.cc index 689e928e9e..a03d38e5ce 100644 --- a/webrtc/video_engine/vie_encoder.cc +++ b/webrtc/video_engine/vie_encoder.cc @@ -111,12 +111,10 @@ ViEEncoder::ViEEncoder(int32_t channel_id, : channel_id_(channel_id), number_of_cores_(number_of_cores), disable_default_encoder_(disable_default_encoder), - vpm_(VideoProcessingModule::Create(ViEModuleId(-1, channel_id))), - qm_callback_(new QMVideoSettingsCallback(vpm_.get())), - vcm_(VideoCodingModule::Create(Clock::GetRealTimeClock(), - this, - qm_callback_.get())), + vcm_(*webrtc::VideoCodingModule::Create(this)), + vpm_(*webrtc::VideoProcessingModule::Create(ViEModuleId(-1, channel_id))), send_payload_router_(NULL), + vcm_protection_callback_(NULL), callback_cs_(CriticalSectionWrapper::CreateCriticalSection()), data_cs_(CriticalSectionWrapper::CreateCriticalSection()), pacer_(pacer), @@ -139,6 +137,7 @@ ViEEncoder::ViEEncoder(int32_t channel_id, picture_id_sli_(0), has_received_rpsi_(false), picture_id_rpsi_(0), + qm_callback_(NULL), video_suspended_(false), pre_encode_callback_(NULL), start_ms_(Clock::GetRealTimeClock()->TimeInMilliseconds()), @@ -147,13 +146,18 @@ ViEEncoder::ViEEncoder(int32_t channel_id, } bool ViEEncoder::Init() { - if (vcm_->InitializeSender() != 0) { + if (vcm_.InitializeSender() != 0) { return false; } - vpm_->EnableTemporalDecimation(true); + vpm_.EnableTemporalDecimation(true); // Enable/disable content analysis: off by default for now. - vpm_->EnableContentAnalysis(false); + vpm_.EnableContentAnalysis(false); + + if (qm_callback_) { + delete qm_callback_; + } + qm_callback_ = new QMVideoSettingsCallback(&vpm_); if (!disable_default_encoder_) { #ifdef VIDEOCODEC_VP8 @@ -162,23 +166,25 @@ bool ViEEncoder::Init() { VideoCodecType codec_type = webrtc::kVideoCodecI420; #endif VideoCodec video_codec; - if (vcm_->Codec(codec_type, &video_codec) != VCM_OK) { + if (vcm_.Codec(codec_type, &video_codec) != VCM_OK) { return false; } { CriticalSectionScoped cs(data_cs_.get()); send_padding_ = video_codec.numberOfSimulcastStreams > 1; } - if (vcm_->RegisterSendCodec(&video_codec, number_of_cores_, - PayloadRouter::DefaultMaxPayloadLength()) != - 0) { + if (vcm_.RegisterSendCodec(&video_codec, number_of_cores_, + PayloadRouter::DefaultMaxPayloadLength()) != 0) { return false; } } - if (vcm_->RegisterTransportCallback(this) != 0) { + if (vcm_.RegisterTransportCallback(this) != 0) { return false; } - if (vcm_->RegisterSendStatisticsCallback(this) != 0) { + if (vcm_.RegisterSendStatisticsCallback(this) != 0) { + return false; + } + if (vcm_.RegisterVideoQMCallback(qm_callback_) != 0) { return false; } return true; @@ -188,21 +194,28 @@ void ViEEncoder::StartThreadsAndSetSharedMembers( scoped_refptr send_payload_router, VCMProtectionCallback* vcm_protection_callback) { DCHECK(send_payload_router_ == NULL); + DCHECK(vcm_protection_callback_ == NULL); send_payload_router_ = send_payload_router; - vcm_->RegisterProtectionCallback(vcm_protection_callback); - module_process_thread_.RegisterModule(vcm_.get()); + vcm_protection_callback_ = vcm_protection_callback; + + module_process_thread_.RegisterModule(&vcm_); } void ViEEncoder::StopThreadsAndRemoveSharedMembers() { - if (bitrate_allocator_) - bitrate_allocator_->RemoveBitrateObserver(bitrate_observer_.get()); - module_process_thread_.DeRegisterModule(vcm_.get()); - module_process_thread_.DeRegisterModule(vpm_.get()); + vcm_.RegisterProtectionCallback(NULL); + vcm_protection_callback_ = NULL; + module_process_thread_.DeRegisterModule(&vcm_); + module_process_thread_.DeRegisterModule(&vpm_); } ViEEncoder::~ViEEncoder() { UpdateHistograms(); + if (bitrate_allocator_) + bitrate_allocator_->RemoveBitrateObserver(bitrate_observer_.get()); + VideoCodingModule::Destroy(&vcm_); + VideoProcessingModule::Destroy(&vpm_); + delete qm_callback_; } void ViEEncoder::UpdateHistograms() { @@ -212,7 +225,7 @@ void ViEEncoder::UpdateHistograms() { return; } webrtc::VCMFrameCount frames; - if (vcm_->SentFrameCount(frames) != VCM_OK) { + if (vcm_.SentFrameCount(frames) != VCM_OK) { return; } uint32_t total_frames = frames.numKeyFrames + frames.numDeltaFrames; @@ -250,11 +263,11 @@ void ViEEncoder::Restart() { } uint8_t ViEEncoder::NumberOfCodecs() { - return vcm_->NumberOfCodecs(); + return vcm_.NumberOfCodecs(); } int32_t ViEEncoder::GetCodec(uint8_t list_index, VideoCodec* video_codec) { - if (vcm_->Codec(list_index, video_codec) != 0) { + if (vcm_.Codec(list_index, video_codec) != 0) { return -1; } return 0; @@ -266,7 +279,7 @@ int32_t ViEEncoder::RegisterExternalEncoder(webrtc::VideoEncoder* encoder, if (encoder == NULL) return -1; - if (vcm_->RegisterExternalEncoder(encoder, pl_type, internal_source) != + if (vcm_.RegisterExternalEncoder(encoder, pl_type, internal_source) != VCM_OK) { return -1; } @@ -276,15 +289,15 @@ int32_t ViEEncoder::RegisterExternalEncoder(webrtc::VideoEncoder* encoder, int32_t ViEEncoder::DeRegisterExternalEncoder(uint8_t pl_type) { DCHECK(send_payload_router_ != NULL); webrtc::VideoCodec current_send_codec; - if (vcm_->SendCodec(¤t_send_codec) == VCM_OK) { + if (vcm_.SendCodec(¤t_send_codec) == VCM_OK) { uint32_t current_bitrate_bps = 0; - if (vcm_->Bitrate(¤t_bitrate_bps) != 0) { + if (vcm_.Bitrate(¤t_bitrate_bps) != 0) { LOG(LS_WARNING) << "Failed to get the current encoder target bitrate."; } current_send_codec.startBitrate = (current_bitrate_bps + 500) / 1000; } - if (vcm_->RegisterExternalEncoder(NULL, pl_type) != VCM_OK) { + if (vcm_.RegisterExternalEncoder(NULL, pl_type) != VCM_OK) { return -1; } @@ -304,8 +317,8 @@ int32_t ViEEncoder::DeRegisterExternalEncoder(uint8_t pl_type) { // for realz. https://code.google.com/p/chromium/issues/detail?id=348222 current_send_codec.extra_options = NULL; size_t max_data_payload_length = send_payload_router_->MaxPayloadLength(); - if (vcm_->RegisterSendCodec(¤t_send_codec, number_of_cores_, - max_data_payload_length) != VCM_OK) { + if (vcm_.RegisterSendCodec(¤t_send_codec, number_of_cores_, + max_data_payload_length) != VCM_OK) { LOG(LS_INFO) << "De-registered the currently used external encoder (" << static_cast(pl_type) << ") and therefore tried to " << "register the corresponding internal encoder, but none " @@ -318,8 +331,8 @@ int32_t ViEEncoder::DeRegisterExternalEncoder(uint8_t pl_type) { int32_t ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec) { DCHECK(send_payload_router_ != NULL); // Setting target width and height for VPM. - if (vpm_->SetTargetResolution(video_codec.width, video_codec.height, - video_codec.maxFramerate) != VPM_OK) { + if (vpm_.SetTargetResolution(video_codec.width, video_codec.height, + video_codec.maxFramerate) != VPM_OK) { return -1; } @@ -359,15 +372,15 @@ int32_t ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec) { modified_video_codec.startBitrate = allocated_bitrate_bps / 1000; size_t max_data_payload_length = send_payload_router_->MaxPayloadLength(); - if (vcm_->RegisterSendCodec(&modified_video_codec, number_of_cores_, - max_data_payload_length) != VCM_OK) { + if (vcm_.RegisterSendCodec(&modified_video_codec, number_of_cores_, + max_data_payload_length) != VCM_OK) { return -1; } return 0; } int32_t ViEEncoder::GetEncoder(VideoCodec* video_codec) { - *video_codec = vcm_->GetSendCodec(); + *video_codec = vcm_.GetSendCodec(); return 0; } @@ -375,7 +388,7 @@ int32_t ViEEncoder::GetCodecConfigParameters( unsigned char config_parameters[kConfigParameterSize], unsigned char& config_parameters_size) { int32_t num_parameters = - vcm_->CodecConfigParameters(config_parameters, kConfigParameterSize); + vcm_.CodecConfigParameters(config_parameters, kConfigParameterSize); if (num_parameters <= 0) { config_parameters_size = 0; return -1; @@ -392,7 +405,7 @@ int32_t ViEEncoder::ScaleInputImage(bool enable) { LOG_F(LS_ERROR) << "Not supported."; return -1; } - vpm_->SetInputFrameResampleMode(resampling_mode); + vpm_.SetInputFrameResampleMode(resampling_mode); return 0; } @@ -411,14 +424,14 @@ int ViEEncoder::GetPaddingNeededBps(int bitrate_bps) const { } VideoCodec send_codec; - if (vcm_->SendCodec(&send_codec) != 0) + if (vcm_.SendCodec(&send_codec) != 0) return 0; SimulcastStream* stream_configs = send_codec.simulcastStream; // Allocate the bandwidth between the streams. std::vector stream_bitrates = AllocateStreamBitrates( bitrate_bps, stream_configs, send_codec.numberOfSimulcastStreams); - bool video_is_suspended = vcm_->VideoSuspended(); + bool video_is_suspended = vcm_.VideoSuspended(); // Find the max amount of padding we can allow ourselves to send at this // point, based on which streams are currently active and what our current @@ -538,7 +551,7 @@ void ViEEncoder::DeliverFrame(int id, } // Pass frame via preprocessor. - const int ret = vpm_->PreprocessFrame(*video_frame, &decimated_frame); + const int ret = vpm_.PreprocessFrame(*video_frame, &decimated_frame); if (ret == 1) { // Drop this frame. return; @@ -564,7 +577,7 @@ void ViEEncoder::DeliverFrame(int id, } #ifdef VIDEOCODEC_VP8 - if (vcm_->SendCodec() == webrtc::kVideoCodecVP8) { + if (vcm_.SendCodec() == webrtc::kVideoCodecVP8) { webrtc::CodecSpecificInfo codec_specific_info; codec_specific_info.codecType = webrtc::kVideoCodecVP8; { @@ -581,12 +594,12 @@ void ViEEncoder::DeliverFrame(int id, has_received_rpsi_ = false; } - vcm_->AddVideoFrame(*decimated_frame, vpm_->ContentMetrics(), - &codec_specific_info); + vcm_.AddVideoFrame(*decimated_frame, vpm_.ContentMetrics(), + &codec_specific_info); return; } #endif - vcm_->AddVideoFrame(*decimated_frame); + vcm_.AddVideoFrame(*decimated_frame); } void ViEEncoder::DelayChanged(int id, int frame_delay) { @@ -597,7 +610,7 @@ int ViEEncoder::GetPreferedFrameSettings(int* width, int* frame_rate) { webrtc::VideoCodec video_codec; memset(&video_codec, 0, sizeof(video_codec)); - if (vcm_->SendCodec(&video_codec) != VCM_OK) { + if (vcm_.SendCodec(&video_codec) != VCM_OK) { return -1; } @@ -608,13 +621,13 @@ int ViEEncoder::GetPreferedFrameSettings(int* width, } int ViEEncoder::SendKeyFrame() { - return vcm_->IntraFrameRequest(0); + return vcm_.IntraFrameRequest(0); } int32_t ViEEncoder::SendCodecStatistics( uint32_t* num_key_frames, uint32_t* num_delta_frames) { webrtc::VCMFrameCount sent_frames; - if (vcm_->SentFrameCount(sent_frames) != VCM_OK) { + if (vcm_.SentFrameCount(sent_frames) != VCM_OK) { return -1; } *num_key_frames = sent_frames.numKeyFrames; @@ -628,13 +641,14 @@ uint32_t ViEEncoder::LastObservedBitrateBps() const { } int ViEEncoder::CodecTargetBitrate(uint32_t* bitrate) const { - if (vcm_->Bitrate(bitrate) != 0) + if (vcm_.Bitrate(bitrate) != 0) return -1; return 0; } int32_t ViEEncoder::UpdateProtectionMethod(bool nack, bool fec) { DCHECK(send_payload_router_ != NULL); + DCHECK(vcm_protection_callback_ != NULL); if (fec_enabled_ == fec && nack_enabled_ == nack) { // No change needed, we're already in correct state. @@ -645,30 +659,35 @@ int32_t ViEEncoder::UpdateProtectionMethod(bool nack, bool fec) { // Set Video Protection for VCM. if (fec_enabled_ && nack_enabled_) { - vcm_->SetVideoProtection(webrtc::kProtectionNackFEC, true); + vcm_.SetVideoProtection(webrtc::kProtectionNackFEC, true); } else { - vcm_->SetVideoProtection(webrtc::kProtectionFEC, fec_enabled_); - vcm_->SetVideoProtection(webrtc::kProtectionNackSender, nack_enabled_); - vcm_->SetVideoProtection(webrtc::kProtectionNackFEC, false); + vcm_.SetVideoProtection(webrtc::kProtectionFEC, fec_enabled_); + vcm_.SetVideoProtection(webrtc::kProtectionNackSender, nack_enabled_); + vcm_.SetVideoProtection(webrtc::kProtectionNackFEC, false); } if (fec_enabled_ || nack_enabled_) { + vcm_.RegisterProtectionCallback(vcm_protection_callback_); // The send codec must be registered to set correct MTU. webrtc::VideoCodec codec; - if (vcm_->SendCodec(&codec) == 0) { + if (vcm_.SendCodec(&codec) == 0) { uint32_t current_bitrate_bps = 0; - if (vcm_->Bitrate(¤t_bitrate_bps) != 0) { + if (vcm_.Bitrate(¤t_bitrate_bps) != 0) { LOG_F(LS_WARNING) << "Failed to get the current encoder target bitrate."; } // Convert to start bitrate in kbps. codec.startBitrate = (current_bitrate_bps + 500) / 1000; size_t max_payload_length = send_payload_router_->MaxPayloadLength(); - if (vcm_->RegisterSendCodec(&codec, number_of_cores_, - max_payload_length) != 0) { + if (vcm_.RegisterSendCodec(&codec, number_of_cores_, + max_payload_length) != 0) { return -1; } } + return 0; + } else { + // FEC and NACK are disabled. + vcm_.RegisterProtectionCallback(NULL); } return 0; } @@ -680,12 +699,12 @@ void ViEEncoder::SetSenderBufferingMode(int target_delay_ms) { } if (target_delay_ms > 0) { // Disable external frame-droppers. - vcm_->EnableFrameDropper(false); - vpm_->EnableTemporalDecimation(false); + vcm_.EnableFrameDropper(false); + vpm_.EnableTemporalDecimation(false); } else { // Real-time mode - enable frame droppers. - vpm_->EnableTemporalDecimation(true); - vcm_->EnableFrameDropper(true); + vpm_.EnableTemporalDecimation(true); + vcm_.EnableFrameDropper(true); } } @@ -775,7 +794,7 @@ void ViEEncoder::OnReceivedIntraFrameRequest(uint32_t ssrc) { idx = stream_it->second; } // Release the critsect before triggering key frame. - vcm_->IntraFrameRequest(idx); + vcm_.IntraFrameRequest(idx); } void ViEEncoder::OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) { @@ -800,7 +819,7 @@ void ViEEncoder::OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) { bool ViEEncoder::SetSsrcs(const std::list& ssrcs) { VideoCodec codec; - if (vcm_->SendCodec(&codec) != 0) + if (vcm_.SendCodec(&codec) != 0) return false; if (codec.numberOfSimulcastStreams > 0 && @@ -834,11 +853,11 @@ void ViEEncoder::OnNetworkChanged(uint32_t bitrate_bps, << " packet loss " << fraction_lost << " rtt " << round_trip_time_ms; DCHECK(send_payload_router_ != NULL); - vcm_->SetChannelParameters(bitrate_bps, fraction_lost, round_trip_time_ms); - bool video_is_suspended = vcm_->VideoSuspended(); + vcm_.SetChannelParameters(bitrate_bps, fraction_lost, round_trip_time_ms); + bool video_is_suspended = vcm_.VideoSuspended(); VideoCodec send_codec; - if (vcm_->SendCodec(&send_codec) != 0) { + if (vcm_.SendCodec(&send_codec) != 0) { return; } SimulcastStream* stream_configs = send_codec.simulcastStream; @@ -874,15 +893,15 @@ int32_t ViEEncoder::RegisterEffectFilter(ViEEffectFilter* effect_filter) { } int ViEEncoder::StartDebugRecording(const char* fileNameUTF8) { - return vcm_->StartDebugRecording(fileNameUTF8); + return vcm_.StartDebugRecording(fileNameUTF8); } int ViEEncoder::StopDebugRecording() { - return vcm_->StopDebugRecording(); + return vcm_.StopDebugRecording(); } void ViEEncoder::SuspendBelowMinBitrate() { - vcm_->SuspendBelowMinBitrate(); + vcm_.SuspendBelowMinBitrate(); bitrate_allocator_->EnforceMinBitrate(false); } @@ -899,11 +918,11 @@ void ViEEncoder::DeRegisterPreEncodeCallback() { void ViEEncoder::RegisterPostEncodeImageCallback( EncodedImageCallback* post_encode_callback) { - vcm_->RegisterPostEncodeImageCallback(post_encode_callback); + vcm_.RegisterPostEncodeImageCallback(post_encode_callback); } void ViEEncoder::DeRegisterPostEncodeImageCallback() { - vcm_->RegisterPostEncodeImageCallback(NULL); + vcm_.RegisterPostEncodeImageCallback(NULL); } void ViEEncoder::RegisterSendStatisticsProxy( diff --git a/webrtc/video_engine/vie_encoder.h b/webrtc/video_engine/vie_encoder.h index d229325705..8683b07803 100644 --- a/webrtc/video_engine/vie_encoder.h +++ b/webrtc/video_engine/vie_encoder.h @@ -197,10 +197,10 @@ class ViEEncoder const uint32_t number_of_cores_; const bool disable_default_encoder_; - const rtc::scoped_ptr vpm_; - const rtc::scoped_ptr qm_callback_; - const rtc::scoped_ptr vcm_; + VideoCodingModule& vcm_; + VideoProcessingModule& vpm_; scoped_refptr send_payload_router_; + VCMProtectionCallback* vcm_protection_callback_; rtc::scoped_ptr callback_cs_; rtc::scoped_ptr data_cs_; @@ -234,6 +234,8 @@ class ViEEncoder uint64_t picture_id_rpsi_ GUARDED_BY(data_cs_); std::map ssrc_streams_ GUARDED_BY(data_cs_); + // Quality modes callback + QMVideoSettingsCallback* qm_callback_; bool video_suspended_ GUARDED_BY(data_cs_); I420FrameCallback* pre_encode_callback_ GUARDED_BY(callback_cs_); const int64_t start_ms_;