1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_encoder.h" 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 133f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <assert.h> 143f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org 15695ff2a7e4a306e31bdc655d638c79daf115848dstefan@webrtc.org#include <algorithm> 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 172e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org#include "webrtc/common_video/interface/video_image.h" 18281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" 19281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/modules/pacing/include/paced_sender.h" 20281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" 21281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/modules/utility/interface/process_thread.h" 22281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" 23281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/modules/video_coding/main/interface/video_coding.h" 24281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/modules/video_coding/main/interface/video_coding_defines.h" 252e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org#include "webrtc/modules/video_coding/main/source/encoded_frame.h" 26c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org#include "webrtc/system_wrappers/interface/clock.h" 27281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 28281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/system_wrappers/interface/logging.h" 29281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/system_wrappers/interface/tick_util.h" 30281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/system_wrappers/interface/trace_event.h" 31281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/include/vie_codec.h" 32281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/include/vie_image_process.h" 3324e2089750e9e51228b82d6c7ebf4fa064c797bapbos@webrtc.org#include "webrtc/frame_callback.h" 34281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_defines.h" 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc { 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 3836bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org// Margin on when we pause the encoder when the pacing buffer overflows relative 3936bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org// to the configured buffer delay. 4036bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.orgstatic const float kEncoderPausePacerMargin = 2.0f; 4136bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org 423816c527a9fdf4de6f625ccd5b984d2a59b50131pwestin@webrtc.org// Don't stop the encoder unless the delay is above this configured value. 433816c527a9fdf4de6f625ccd5b984d2a59b50131pwestin@webrtc.orgstatic const int kMinPacingDelayMs = 200; 443816c527a9fdf4de6f625ccd5b984d2a59b50131pwestin@webrtc.org 45dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org// Allow packets to be transmitted in up to 2 times max video bitrate if the 46dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org// bandwidth estimate allows it. 47dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org// TODO(holmer): Expose transmission start, min and max bitrates in the 48dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org// VideoEngine API and remove the kTransmissionMaxBitrateMultiplier. 49dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.orgstatic const int kTransmissionMaxBitrateMultiplier = 2; 505e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org 515e74d9693504416a5b72a9c8c9a7626f802f969estefan@webrtc.orgstatic const float kStopPaddingThresholdMs = 2000; 525e74d9693504416a5b72a9c8c9a7626f802f969estefan@webrtc.org 537dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.orgstd::vector<uint32_t> AllocateStreamBitrates( 547dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org uint32_t total_bitrate, 557dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org const SimulcastStream* stream_configs, 567dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org size_t number_of_streams) { 577dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org if (number_of_streams == 0) { 587dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org std::vector<uint32_t> stream_bitrates(1, 0); 597dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org stream_bitrates[0] = total_bitrate; 607dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org return stream_bitrates; 617dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org } 627dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org std::vector<uint32_t> stream_bitrates(number_of_streams, 0); 637dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org uint32_t bitrate_remainder = total_bitrate; 647dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org for (size_t i = 0; i < stream_bitrates.size() && bitrate_remainder > 0; ++i) { 657dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org if (stream_configs[i].maxBitrate * 1000 > bitrate_remainder) { 667dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org stream_bitrates[i] = bitrate_remainder; 677dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org } else { 687dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org stream_bitrates[i] = stream_configs[i].maxBitrate * 1000; 697dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org } 707dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org bitrate_remainder -= stream_bitrates[i]; 717dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org } 727dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org return stream_bitrates; 737dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org} 747dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass QMVideoSettingsCallback : public VCMQMSettingsCallback { 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public: 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org explicit QMVideoSettingsCallback(VideoProcessingModule* vpm); 78bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ~QMVideoSettingsCallback(); 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update VPM with QM (quality modes: frame size & frame rate) settings. 8267879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org int32_t SetVideoQMSettings(const uint32_t frame_rate, 8367879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org const uint32_t width, 8467879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org const uint32_t height); 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org private: 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VideoProcessingModule* vpm_; 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}; 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass ViEBitrateObserver : public BitrateObserver { 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public: 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org explicit ViEBitrateObserver(ViEEncoder* owner) 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : owner_(owner) { 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 95bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org virtual ~ViEBitrateObserver() {} 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Implements BitrateObserver. 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org virtual void OnNetworkChanged(const uint32_t bitrate_bps, 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const uint8_t fraction_lost, 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const uint32_t rtt) { 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org owner_->OnNetworkChanged(bitrate_bps, fraction_lost, rtt); 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org private: 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ViEEncoder* owner_; 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}; 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1065e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.orgclass ViEPacedSenderCallback : public PacedSender::Callback { 1075e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org public: 1085e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org explicit ViEPacedSenderCallback(ViEEncoder* owner) 1095e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org : owner_(owner) { 1105e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org } 111bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org virtual ~ViEPacedSenderCallback() {} 1120f6f7cb4232fea07a4b2a5a53f8eec6933c08a23hclam@chromium.org virtual bool TimeToSendPacket(uint32_t ssrc, uint16_t sequence_number, 113b748c9d2022042b2cc04eaf89052945ba7149ba6stefan@webrtc.org int64_t capture_time_ms, bool retransmission) { 114b748c9d2022042b2cc04eaf89052945ba7149ba6stefan@webrtc.org return owner_->TimeToSendPacket(ssrc, sequence_number, capture_time_ms, 115b748c9d2022042b2cc04eaf89052945ba7149ba6stefan@webrtc.org retransmission); 1165e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org } 117695ff2a7e4a306e31bdc655d638c79daf115848dstefan@webrtc.org virtual int TimeToSendPadding(int bytes) { 11869f76054f5dc242b313e7e0642c8657a885682bastefan@webrtc.org return owner_->TimeToSendPadding(bytes); 1195e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org } 1205e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org private: 1215e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org ViEEncoder* owner_; 1225e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org}; 1235e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org 12467879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgViEEncoder::ViEEncoder(int32_t engine_id, 12567879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org int32_t channel_id, 12667879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org uint32_t number_of_cores, 127ac6d919eec548c708588f29923f617a17283c7e2andresp@webrtc.org const Config& config, 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ProcessThread& module_process_thread, 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org BitrateController* bitrate_controller) 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : engine_id_(engine_id), 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org channel_id_(channel_id), 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org number_of_cores_(number_of_cores), 1338edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org vcm_(*webrtc::VideoCodingModule::Create()), 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org vpm_(*webrtc::VideoProcessingModule::Create(ViEModuleId(engine_id, 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org channel_id))), 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org callback_cs_(CriticalSectionWrapper::CreateCriticalSection()), 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org data_cs_(CriticalSectionWrapper::CreateCriticalSection()), 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bitrate_controller_(bitrate_controller), 1395e74d9693504416a5b72a9c8c9a7626f802f969estefan@webrtc.org time_of_last_incoming_frame_ms_(0), 14069f76054f5dc242b313e7e0642c8657a885682bastefan@webrtc.org send_padding_(false), 1413f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org min_transmit_bitrate_kbps_(0), 142dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org target_delay_ms_(0), 143dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org network_is_transmitting_(true), 144dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org encoder_paused_(false), 14536bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org encoder_paused_and_dropped_frame_(false), 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fec_enabled_(false), 147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org nack_enabled_(false), 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org codec_observer_(NULL), 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org effect_filter_(NULL), 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org module_process_thread_(module_process_thread), 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org has_received_sli_(false), 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org picture_id_sli_(0), 153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org has_received_rpsi_(false), 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org picture_id_rpsi_(0), 15539079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org qm_callback_(NULL), 1564590177aa3346a742e8f71c8bcc5b81618d21919henrik.lundin@webrtc.org video_suspended_(false), 15763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org pre_encode_callback_(NULL) { 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RtpRtcp::Configuration configuration; 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org configuration.id = ViEModuleId(engine_id_, channel_id_); 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org configuration.audio = false; // Video. 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default_rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(configuration)); 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bitrate_observer_.reset(new ViEBitrateObserver(this)); 1645e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org pacing_callback_.reset(new ViEPacedSenderCallback(this)); 16536bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org paced_sender_.reset( 166c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org new PacedSender(Clock::GetRealTimeClock(), pacing_callback_.get(), 167c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org PacedSender::kDefaultInitialPaceKbps, 0)); 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool ViEEncoder::Init() { 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (vcm_.InitializeSender() != 0) { 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org vpm_.EnableTemporalDecimation(true); 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Enable/disable content analysis: off by default for now. 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org vpm_.EnableContentAnalysis(false); 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1795e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org if (module_process_thread_.RegisterModule(&vcm_) != 0 || 1805e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org module_process_thread_.RegisterModule(default_rtp_rtcp_.get()) != 0 || 1815e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org module_process_thread_.RegisterModule(paced_sender_.get()) != 0) { 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (qm_callback_) { 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete qm_callback_; 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_callback_ = new QMVideoSettingsCallback(&vpm_); 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef VIDEOCODEC_VP8 190c1696da9a74c7ed4ed793ce993352bd370cfc414andresp@webrtc.org VideoCodecType codec_type = webrtc::kVideoCodecVP8; 191c1696da9a74c7ed4ed793ce993352bd370cfc414andresp@webrtc.org#else 192c1696da9a74c7ed4ed793ce993352bd370cfc414andresp@webrtc.org VideoCodecType codec_type = webrtc::kVideoCodecI420; 193c1696da9a74c7ed4ed793ce993352bd370cfc414andresp@webrtc.org#endif 194c1696da9a74c7ed4ed793ce993352bd370cfc414andresp@webrtc.org 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VideoCodec video_codec; 196c1696da9a74c7ed4ed793ce993352bd370cfc414andresp@webrtc.org if (vcm_.Codec(codec_type, &video_codec) != VCM_OK) { 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1995fcd7dfc6c4bdece48d90000e09d635485031dffstefan@webrtc.org { 2005fcd7dfc6c4bdece48d90000e09d635485031dffstefan@webrtc.org CriticalSectionScoped cs(data_cs_.get()); 2015fcd7dfc6c4bdece48d90000e09d635485031dffstefan@webrtc.org send_padding_ = video_codec.numberOfSimulcastStreams > 1; 2025fcd7dfc6c4bdece48d90000e09d635485031dffstefan@webrtc.org } 203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (vcm_.RegisterSendCodec(&video_codec, number_of_cores_, 204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default_rtp_rtcp_->MaxDataPayloadLength()) != 0) { 205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (default_rtp_rtcp_->RegisterSendPayload(video_codec) != 0) { 208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (vcm_.RegisterTransportCallback(this) != 0) { 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (vcm_.RegisterSendStatisticsCallback(this) != 0) { 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (vcm_.RegisterVideoQMCallback(qm_callback_) != 0) { 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return true; 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgViEEncoder::~ViEEncoder() { 223c0539d9351f8942308bf6142adfbb9d1a6c1816cstefan@webrtc.org if (bitrate_controller_) { 224c0539d9351f8942308bf6142adfbb9d1a6c1816cstefan@webrtc.org bitrate_controller_->RemoveBitrateObserver(bitrate_observer_.get()); 225c0539d9351f8942308bf6142adfbb9d1a6c1816cstefan@webrtc.org } 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org module_process_thread_.DeRegisterModule(&vcm_); 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org module_process_thread_.DeRegisterModule(&vpm_); 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org module_process_thread_.DeRegisterModule(default_rtp_rtcp_.get()); 2295e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org module_process_thread_.DeRegisterModule(paced_sender_.get()); 230c6242c92d4357adf377ed7a70f99575e9be1afe8mflodman@webrtc.org VideoCodingModule::Destroy(&vcm_); 231c6242c92d4357adf377ed7a70f99575e9be1afe8mflodman@webrtc.org VideoProcessingModule::Destroy(&vpm_); 232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete qm_callback_; 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEEncoder::Owner() const { 236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return channel_id_; 237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 239dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.orgvoid ViEEncoder::SetNetworkTransmissionState(bool is_transmitting) { 240dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org { 241dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org CriticalSectionScoped cs(data_cs_.get()); 242dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org network_is_transmitting_ = is_transmitting; 243dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org } 244dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org if (is_transmitting) { 245dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org paced_sender_->Resume(); 246dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org } else { 247dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org paced_sender_->Pause(); 248dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org } 249dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org} 250dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid ViEEncoder::Pause() { 252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(data_cs_.get()); 253dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org encoder_paused_ = true; 254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid ViEEncoder::Restart() { 257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(data_cs_.get()); 258dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org encoder_paused_ = false; 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 26167879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orguint8_t ViEEncoder::NumberOfCodecs() { 262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return vcm_.NumberOfCodecs(); 263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 26567879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t ViEEncoder::GetCodec(uint8_t list_index, VideoCodec* video_codec) { 266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (vcm_.Codec(list_index, video_codec) != 0) { 267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 27267879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t ViEEncoder::RegisterExternalEncoder(webrtc::VideoEncoder* encoder, 27367879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org uint8_t pl_type, 27467879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org bool internal_source) { 275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (encoder == NULL) 276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 27871f3f686b5b3896cf842b9665a6c28b40a7aa040stefan@webrtc.org if (vcm_.RegisterExternalEncoder(encoder, pl_type, internal_source) != 279022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org VCM_OK) { 280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 28567879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t ViEEncoder::DeRegisterExternalEncoder(uint8_t pl_type) { 286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::VideoCodec current_send_codec; 287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (vcm_.SendCodec(¤t_send_codec) == VCM_OK) { 28863136921ece04448f1bc71ce6f3e43974f9d385astefan@webrtc.org uint32_t current_bitrate_bps = 0; 28963136921ece04448f1bc71ce6f3e43974f9d385astefan@webrtc.org if (vcm_.Bitrate(¤t_bitrate_bps) != 0) { 290022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org LOG(LS_WARNING) << "Failed to get the current encoder target bitrate."; 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 29263136921ece04448f1bc71ce6f3e43974f9d385astefan@webrtc.org current_send_codec.startBitrate = (current_bitrate_bps + 500) / 1000; 293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (vcm_.RegisterExternalEncoder(NULL, pl_type) != VCM_OK) { 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 29969f76054f5dc242b313e7e0642c8657a885682bastefan@webrtc.org // If the external encoder is the current send codec, use vcm internal 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // encoder. 301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (current_send_codec.plType == pl_type) { 30267879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org uint16_t max_data_payload_length = 303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default_rtp_rtcp_->MaxDataPayloadLength(); 3045fcd7dfc6c4bdece48d90000e09d635485031dffstefan@webrtc.org { 3055fcd7dfc6c4bdece48d90000e09d635485031dffstefan@webrtc.org CriticalSectionScoped cs(data_cs_.get()); 3065fcd7dfc6c4bdece48d90000e09d635485031dffstefan@webrtc.org send_padding_ = current_send_codec.numberOfSimulcastStreams > 1; 3075fcd7dfc6c4bdece48d90000e09d635485031dffstefan@webrtc.org } 308bbbe9b8714e1f0966327b6a472f116c0f34a7c30fischman@webrtc.org // TODO(mflodman): Unfortunately the VideoCodec that VCM has cached a 309bbbe9b8714e1f0966327b6a472f116c0f34a7c30fischman@webrtc.org // raw pointer to an |extra_options| that's long gone. Clearing it here is 310bbbe9b8714e1f0966327b6a472f116c0f34a7c30fischman@webrtc.org // a hack to prevent the following code from crashing. This should be fixed 311bbbe9b8714e1f0966327b6a472f116c0f34a7c30fischman@webrtc.org // for realz. https://code.google.com/p/chromium/issues/detail?id=348222 312bbbe9b8714e1f0966327b6a472f116c0f34a7c30fischman@webrtc.org current_send_codec.extra_options = NULL; 313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (vcm_.RegisterSendCodec(¤t_send_codec, number_of_cores_, 314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org max_data_payload_length) != VCM_OK) { 3156111d79329d4fffec4eb6b443dc4e04222dec949stefan@webrtc.org LOG(LS_INFO) << "De-registered the currently used external encoder (" 3166111d79329d4fffec4eb6b443dc4e04222dec949stefan@webrtc.org << static_cast<int>(pl_type) << ") and therefore tried to " 3176111d79329d4fffec4eb6b443dc4e04222dec949stefan@webrtc.org << "register the corresponding internal encoder, but none " 3186111d79329d4fffec4eb6b443dc4e04222dec949stefan@webrtc.org << "was supported."; 319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 32467879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec) { 325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Setting target width and height for VPM. 326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (vpm_.SetTargetResolution(video_codec.width, video_codec.height, 327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org video_codec.maxFramerate) != VPM_OK) { 328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (default_rtp_rtcp_->RegisterSendPayload(video_codec) != 0) { 332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Convert from kbps to bps. 3357dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org std::vector<uint32_t> stream_bitrates = AllocateStreamBitrates( 3367dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org video_codec.startBitrate * 1000, 3377dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org video_codec.simulcastStream, 3387dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org video_codec.numberOfSimulcastStreams); 3397dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org default_rtp_rtcp_->SetTargetSendBitrate(stream_bitrates); 340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 34167879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org uint16_t max_data_payload_length = 342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org default_rtp_rtcp_->MaxDataPayloadLength(); 343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 3445a6e6911e6e218a86b585ddd6df906e1ffe52dcfstefan@webrtc.org { 3455a6e6911e6e218a86b585ddd6df906e1ffe52dcfstefan@webrtc.org CriticalSectionScoped cs(data_cs_.get()); 3465a6e6911e6e218a86b585ddd6df906e1ffe52dcfstefan@webrtc.org send_padding_ = video_codec.numberOfSimulcastStreams > 1; 3475a6e6911e6e218a86b585ddd6df906e1ffe52dcfstefan@webrtc.org } 348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (vcm_.RegisterSendCodec(&video_codec, number_of_cores_, 349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org max_data_payload_length) != VCM_OK) { 350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Set this module as sending right away, let the slave module in the channel 354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // start and stop sending. 355c1696da9a74c7ed4ed793ce993352bd370cfc414andresp@webrtc.org if (default_rtp_rtcp_->SetSendingStatus(true) != 0) { 356c1696da9a74c7ed4ed793ce993352bd370cfc414andresp@webrtc.org return -1; 357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 358c1696da9a74c7ed4ed793ce993352bd370cfc414andresp@webrtc.org 359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bitrate_controller_->SetBitrateObserver(bitrate_observer_.get(), 360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org video_codec.startBitrate * 1000, 361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org video_codec.minBitrate * 1000, 362dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org kTransmissionMaxBitrateMultiplier * 363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org video_codec.maxBitrate * 1000); 364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 3653f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org CriticalSectionScoped crit(data_cs_.get()); 3663f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org int pad_up_to_bitrate_kbps = video_codec.startBitrate; 3673f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org if (pad_up_to_bitrate_kbps < min_transmit_bitrate_kbps_) 3683f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org pad_up_to_bitrate_kbps = min_transmit_bitrate_kbps_; 3693f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org 370c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org paced_sender_->UpdateBitrate( 371c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org PacedSender::kDefaultPaceMultiplier * video_codec.startBitrate, 372c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org pad_up_to_bitrate_kbps); 3733f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org 374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 37767879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t ViEEncoder::GetEncoder(VideoCodec* video_codec) { 378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (vcm_.SendCodec(video_codec) != 0) { 379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 38467879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t ViEEncoder::GetCodecConfigParameters( 385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned char config_parameters[kConfigParameterSize], 386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org unsigned char& config_parameters_size) { 38767879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org int32_t num_parameters = 388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org vcm_.CodecConfigParameters(config_parameters, kConfigParameterSize); 389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (num_parameters <= 0) { 390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org config_parameters_size = 0; 391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org config_parameters_size = static_cast<unsigned char>(num_parameters); 394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 39767879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t ViEEncoder::ScaleInputImage(bool enable) { 398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VideoFrameResampling resampling_mode = kFastRescaling; 399022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org // TODO(mflodman) What? 400022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org if (enable) { 401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // kInterpolation is currently not supported. 402022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org LOG_F(LS_ERROR) << "Not supported."; 403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org vpm_.SetInputFrameResampleMode(resampling_mode); 406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 410b748c9d2022042b2cc04eaf89052945ba7149ba6stefan@webrtc.orgbool ViEEncoder::TimeToSendPacket(uint32_t ssrc, 411b748c9d2022042b2cc04eaf89052945ba7149ba6stefan@webrtc.org uint16_t sequence_number, 412b748c9d2022042b2cc04eaf89052945ba7149ba6stefan@webrtc.org int64_t capture_time_ms, 413b748c9d2022042b2cc04eaf89052945ba7149ba6stefan@webrtc.org bool retransmission) { 4140f6f7cb4232fea07a4b2a5a53f8eec6933c08a23hclam@chromium.org return default_rtp_rtcp_->TimeToSendPacket(ssrc, sequence_number, 415b748c9d2022042b2cc04eaf89052945ba7149ba6stefan@webrtc.org capture_time_ms, retransmission); 4165e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org} 4175e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org 41869f76054f5dc242b313e7e0642c8657a885682bastefan@webrtc.orgint ViEEncoder::TimeToSendPadding(int bytes) { 419b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org bool send_padding; 420b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org { 421b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org CriticalSectionScoped cs(data_cs_.get()); 4223f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org send_padding = 4233f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org send_padding_ || video_suspended_ || min_transmit_bitrate_kbps_ > 0; 424b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org } 425b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org if (send_padding) { 42669f76054f5dc242b313e7e0642c8657a885682bastefan@webrtc.org return default_rtp_rtcp_->TimeToSendPadding(bytes); 42769f76054f5dc242b313e7e0642c8657a885682bastefan@webrtc.org } 42869f76054f5dc242b313e7e0642c8657a885682bastefan@webrtc.org return 0; 42969f76054f5dc242b313e7e0642c8657a885682bastefan@webrtc.org} 43069f76054f5dc242b313e7e0642c8657a885682bastefan@webrtc.org 431dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.orgbool ViEEncoder::EncoderPaused() const { 4323816c527a9fdf4de6f625ccd5b984d2a59b50131pwestin@webrtc.org // Pause video if paused by caller or as long as the network is down or the 4333816c527a9fdf4de6f625ccd5b984d2a59b50131pwestin@webrtc.org // pacer queue has grown too large in buffered mode. 4343816c527a9fdf4de6f625ccd5b984d2a59b50131pwestin@webrtc.org if (encoder_paused_) { 4353816c527a9fdf4de6f625ccd5b984d2a59b50131pwestin@webrtc.org return true; 4363816c527a9fdf4de6f625ccd5b984d2a59b50131pwestin@webrtc.org } 4373816c527a9fdf4de6f625ccd5b984d2a59b50131pwestin@webrtc.org if (target_delay_ms_ > 0) { 4383816c527a9fdf4de6f625ccd5b984d2a59b50131pwestin@webrtc.org // Buffered mode. 4393816c527a9fdf4de6f625ccd5b984d2a59b50131pwestin@webrtc.org // TODO(pwestin): Workaround until nack is configured as a time and not 4403816c527a9fdf4de6f625ccd5b984d2a59b50131pwestin@webrtc.org // number of packets. 4413816c527a9fdf4de6f625ccd5b984d2a59b50131pwestin@webrtc.org return paced_sender_->QueueInMs() >= 44236bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org std::max(static_cast<int>(target_delay_ms_ * kEncoderPausePacerMargin), 44336bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org kMinPacingDelayMs); 4443816c527a9fdf4de6f625ccd5b984d2a59b50131pwestin@webrtc.org } 4453816c527a9fdf4de6f625ccd5b984d2a59b50131pwestin@webrtc.org return !network_is_transmitting_; 446dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org} 447dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org 448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgRtpRtcp* ViEEncoder::SendRtpRtcpModule() { 449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return default_rtp_rtcp_.get(); 450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid ViEEncoder::DeliverFrame(int id, 4533bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org I420VideoFrame* video_frame, 454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int num_csrcs, 45567879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org const uint32_t CSRC[kRtpCsrcSize]) { 45676cd2f7dec281c9842ebc5417eeea376fa54746cwuchengli@chromium.org if (default_rtp_rtcp_->SendingMedia() == false) { 45776cd2f7dec281c9842ebc5417eeea376fa54746cwuchengli@chromium.org // We've paused or we have no channels attached, don't encode. 45876cd2f7dec281c9842ebc5417eeea376fa54746cwuchengli@chromium.org return; 45976cd2f7dec281c9842ebc5417eeea376fa54746cwuchengli@chromium.org } 460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(data_cs_.get()); 4625e74d9693504416a5b72a9c8c9a7626f802f969estefan@webrtc.org time_of_last_incoming_frame_ms_ = TickTime::MillisecondTimestamp(); 46336bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org if (EncoderPaused()) { 46436bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org if (!encoder_paused_and_dropped_frame_) { 46536bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org TRACE_EVENT_ASYNC_BEGIN0("webrtc", "EncoderPaused", this); 46636bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org } 46736bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org encoder_paused_and_dropped_frame_ = true; 46836bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org return; 46936bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org } 47036bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org if (encoder_paused_and_dropped_frame_) { 47136bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this); 47236bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org } 47336bdba4e02894161bc657ef4d933821aba8421efpwestin@webrtc.org encoder_paused_and_dropped_frame_ = false; 474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Convert render time, in ms, to RTP timestamp. 477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const int kMsToRtpTimestamp = 90; 47867879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org const uint32_t time_stamp = 479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kMsToRtpTimestamp * 48067879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org static_cast<uint32_t>(video_frame->render_time_ms()); 48174472fe9852769d834e135bde1229c24ab844244hclam@chromium.org 4829c0f14d2cd43e388b5136f0ced7951ee58610e86hclam@chromium.org TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", video_frame->render_time_ms(), 4839c0f14d2cd43e388b5136f0ced7951ee58610e86hclam@chromium.org "Encode"); 4843bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org video_frame->set_timestamp(time_stamp); 485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Make sure the CSRC list is correct. 487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (num_csrcs > 0) { 48867879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org uint32_t tempCSRC[kRtpCsrcSize]; 489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int i = 0; i < num_csrcs; i++) { 490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (CSRC[i] == 1) { 491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tempCSRC[i] = default_rtp_rtcp_->SSRC(); 492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tempCSRC[i] = CSRC[i]; 494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 49667879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org default_rtp_rtcp_->SetCSRCs(tempCSRC, (uint8_t) num_csrcs); 497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 4984ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org 4993bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org I420VideoFrame* decimated_frame = NULL; 5004ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org // TODO(wuchengli): support texture frames. 5014ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org if (video_frame->native_handle() == NULL) { 5024ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org { 5034ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org CriticalSectionScoped cs(callback_cs_.get()); 5044ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org if (effect_filter_) { 5054ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org unsigned int length = 5064ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org CalcBufferSize(kI420, video_frame->width(), video_frame->height()); 5074ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org scoped_ptr<uint8_t[]> video_buffer(new uint8_t[length]); 5084ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org ExtractBuffer(*video_frame, length, video_buffer.get()); 5094ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org effect_filter_->Transform(length, 5104ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org video_buffer.get(), 5114ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org video_frame->ntp_time_ms(), 5124ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org video_frame->timestamp(), 5134ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org video_frame->width(), 5144ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org video_frame->height()); 5154ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org } 5164ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org } 5174ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org 5184ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org // Pass frame via preprocessor. 5194ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org const int ret = vpm_.PreprocessFrame(*video_frame, &decimated_frame); 5204ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org if (ret == 1) { 5214ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org // Drop this frame. 5224ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org return; 5234ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org } 5244ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org if (ret != VPM_OK) { 5254ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org return; 5264ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org } 527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 5284ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org // If the frame was not resampled or scaled => use original. 529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (decimated_frame == NULL) { 530b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org decimated_frame = video_frame; 531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 53263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 53363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org { 53463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org CriticalSectionScoped cs(callback_cs_.get()); 53563301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org if (pre_encode_callback_) 53663301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org pre_encode_callback_->FrameCallback(decimated_frame); 53763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org } 53863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 5394ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org if (video_frame->native_handle() != NULL) { 5404ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org // TODO(wuchengli): add texture support. http://crbug.com/362437 5414ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org return; 5424ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org } 5434ee63485f3d42c5fc47845be1d62c7d24bb0f96cwuchengli@chromium.org 54428f76e5249e883f269a5877e5de888035b23cd71pwestin@webrtc.org#ifdef VIDEOCODEC_VP8 54528f76e5249e883f269a5877e5de888035b23cd71pwestin@webrtc.org if (vcm_.SendCodec() == webrtc::kVideoCodecVP8) { 54628f76e5249e883f269a5877e5de888035b23cd71pwestin@webrtc.org webrtc::CodecSpecificInfo codec_specific_info; 54728f76e5249e883f269a5877e5de888035b23cd71pwestin@webrtc.org codec_specific_info.codecType = webrtc::kVideoCodecVP8; 548fedbe8b196306135b3834b34b19fd455c037172astefan@webrtc.org { 549fedbe8b196306135b3834b34b19fd455c037172astefan@webrtc.org CriticalSectionScoped cs(data_cs_.get()); 550fedbe8b196306135b3834b34b19fd455c037172astefan@webrtc.org codec_specific_info.codecSpecific.VP8.hasReceivedRPSI = 551fedbe8b196306135b3834b34b19fd455c037172astefan@webrtc.org has_received_rpsi_; 552fedbe8b196306135b3834b34b19fd455c037172astefan@webrtc.org codec_specific_info.codecSpecific.VP8.hasReceivedSLI = 553fedbe8b196306135b3834b34b19fd455c037172astefan@webrtc.org has_received_sli_; 554fedbe8b196306135b3834b34b19fd455c037172astefan@webrtc.org codec_specific_info.codecSpecific.VP8.pictureIdRPSI = 555fedbe8b196306135b3834b34b19fd455c037172astefan@webrtc.org picture_id_rpsi_; 556fedbe8b196306135b3834b34b19fd455c037172astefan@webrtc.org codec_specific_info.codecSpecific.VP8.pictureIdSLI = 557fedbe8b196306135b3834b34b19fd455c037172astefan@webrtc.org picture_id_sli_; 558fedbe8b196306135b3834b34b19fd455c037172astefan@webrtc.org has_received_sli_ = false; 559fedbe8b196306135b3834b34b19fd455c037172astefan@webrtc.org has_received_rpsi_ = false; 560fedbe8b196306135b3834b34b19fd455c037172astefan@webrtc.org } 56128f76e5249e883f269a5877e5de888035b23cd71pwestin@webrtc.org 562022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org vcm_.AddVideoFrame(*decimated_frame, vpm_.ContentMetrics(), 563022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org &codec_specific_info); 56428f76e5249e883f269a5877e5de888035b23cd71pwestin@webrtc.org return; 56528f76e5249e883f269a5877e5de888035b23cd71pwestin@webrtc.org } 56628f76e5249e883f269a5877e5de888035b23cd71pwestin@webrtc.org#endif 567022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org vcm_.AddVideoFrame(*decimated_frame); 568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid ViEEncoder::DelayChanged(int id, int frame_delay) { 57173ebe67b3e6f0a65efed02efd4eee4dfb1b7729estefan@webrtc.org default_rtp_rtcp_->SetCameraDelay(frame_delay); 572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEEncoder::GetPreferedFrameSettings(int* width, 575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int* height, 576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int* frame_rate) { 577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::VideoCodec video_codec; 578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(&video_codec, 0, sizeof(video_codec)); 579b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (vcm_.SendCodec(&video_codec) != VCM_OK) { 580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 582b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 583b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *width = video_codec.width; 584b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *height = video_codec.height; 585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *frame_rate = video_codec.maxFramerate; 586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEEncoder::SendKeyFrame() { 590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return vcm_.IntraFrameRequest(0); 591b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 59367879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t ViEEncoder::SendCodecStatistics( 59467879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org uint32_t* num_key_frames, uint32_t* num_delta_frames) { 595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::VCMFrameCount sent_frames; 596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (vcm_.SentFrameCount(sent_frames) != VCM_OK) { 597b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *num_key_frames = sent_frames.numKeyFrames; 600b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *num_delta_frames = sent_frames.numDeltaFrames; 601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 603b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 60455a2a27d1a1aa9bf8401312a0b31250af4e3bd11jiayl@webrtc.orgint32_t ViEEncoder::PacerQueuingDelayMs() const { 60555a2a27d1a1aa9bf8401312a0b31250af4e3bd11jiayl@webrtc.org return paced_sender_->QueueInMs(); 60655a2a27d1a1aa9bf8401312a0b31250af4e3bd11jiayl@webrtc.org} 60755a2a27d1a1aa9bf8401312a0b31250af4e3bd11jiayl@webrtc.org 60867879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint ViEEncoder::CodecTargetBitrate(uint32_t* bitrate) const { 609b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (vcm_.Bitrate(bitrate) != 0) 610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 6147fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.orgint32_t ViEEncoder::UpdateProtectionMethod(bool enable_nack) { 615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool fec_enabled = false; 61667879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org uint8_t dummy_ptype_red = 0; 61767879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org uint8_t dummy_ptypeFEC = 0; 618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Updated protection method to VCM to get correct packetization sizes. 620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // FEC has larger overhead than NACK -> set FEC if used. 62167879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org int32_t error = default_rtp_rtcp_->GenericFECStatus(fec_enabled, 62267879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org dummy_ptype_red, 62367879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org dummy_ptypeFEC); 624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (error) { 625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 626b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 6277fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org if (fec_enabled_ == fec_enabled && nack_enabled_ == enable_nack) { 628b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // No change needed, we're already in correct state. 629b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 630b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 631b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fec_enabled_ = fec_enabled; 6327fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org nack_enabled_ = enable_nack; 633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Set Video Protection for VCM. 6357fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org if (fec_enabled && nack_enabled_) { 636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org vcm_.SetVideoProtection(webrtc::kProtectionNackFEC, true); 637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org vcm_.SetVideoProtection(webrtc::kProtectionFEC, fec_enabled_); 6397fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org vcm_.SetVideoProtection(webrtc::kProtectionNackSender, nack_enabled_); 640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org vcm_.SetVideoProtection(webrtc::kProtectionNackFEC, false); 641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 6437fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org if (fec_enabled_ || nack_enabled_) { 644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org vcm_.RegisterProtectionCallback(this); 645b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // The send codec must be registered to set correct MTU. 646b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::VideoCodec codec; 647b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (vcm_.SendCodec(&codec) == 0) { 64867879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org uint16_t max_pay_load = default_rtp_rtcp_->MaxDataPayloadLength(); 64963136921ece04448f1bc71ce6f3e43974f9d385astefan@webrtc.org uint32_t current_bitrate_bps = 0; 65063136921ece04448f1bc71ce6f3e43974f9d385astefan@webrtc.org if (vcm_.Bitrate(¤t_bitrate_bps) != 0) { 651022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org LOG_F(LS_WARNING) << 652022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org "Failed to get the current encoder target bitrate."; 653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 65463136921ece04448f1bc71ce6f3e43974f9d385astefan@webrtc.org // Convert to start bitrate in kbps. 65563136921ece04448f1bc71ce6f3e43974f9d385astefan@webrtc.org codec.startBitrate = (current_bitrate_bps + 500) / 1000; 656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (vcm_.RegisterSendCodec(&codec, number_of_cores_, max_pay_load) != 0) { 657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 659b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // FEC and NACK are disabled. 663b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org vcm_.RegisterProtectionCallback(NULL); 664b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 665b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 666b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 667b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 6689d6fcb37be4c9f49e1bb0b32bb01314c31f5e1ddmikhal@webrtc.orgvoid ViEEncoder::SetSenderBufferingMode(int target_delay_ms) { 669dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org { 670dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org CriticalSectionScoped cs(data_cs_.get()); 671dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org target_delay_ms_ = target_delay_ms; 672dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org } 6730c66de6e75821a8e86fcbd166d725a5a859cab79mikhal@webrtc.org if (target_delay_ms > 0) { 674dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org // Disable external frame-droppers. 675dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org vcm_.EnableFrameDropper(false); 676dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org vpm_.EnableTemporalDecimation(false); 67704d6593fef1182e8106a67681a1c6c2ebc90f0c2stefan@webrtc.org // We don't put any limits on the pacer queue when running in buffered mode 67804d6593fef1182e8106a67681a1c6c2ebc90f0c2stefan@webrtc.org // since the encoder will be paused if the queue grow too large. 67904d6593fef1182e8106a67681a1c6c2ebc90f0c2stefan@webrtc.org paced_sender_->set_max_queue_length_ms(-1); 6800c66de6e75821a8e86fcbd166d725a5a859cab79mikhal@webrtc.org } else { 6819d6fcb37be4c9f49e1bb0b32bb01314c31f5e1ddmikhal@webrtc.org // Real-time mode - enable frame droppers. 6820c66de6e75821a8e86fcbd166d725a5a859cab79mikhal@webrtc.org vpm_.EnableTemporalDecimation(true); 6830c66de6e75821a8e86fcbd166d725a5a859cab79mikhal@webrtc.org vcm_.EnableFrameDropper(true); 68404d6593fef1182e8106a67681a1c6c2ebc90f0c2stefan@webrtc.org paced_sender_->set_max_queue_length_ms( 68504d6593fef1182e8106a67681a1c6c2ebc90f0c2stefan@webrtc.org PacedSender::kDefaultMaxQueueLengthMs); 6860c66de6e75821a8e86fcbd166d725a5a859cab79mikhal@webrtc.org } 6870c66de6e75821a8e86fcbd166d725a5a859cab79mikhal@webrtc.org} 6880c66de6e75821a8e86fcbd166d725a5a859cab79mikhal@webrtc.org 68967879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t ViEEncoder::SendData( 690b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const FrameType frame_type, 69167879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org const uint8_t payload_type, 69267879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org const uint32_t time_stamp, 693b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int64_t capture_time_ms, 69467879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org const uint8_t* payload_data, 69567879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org const uint32_t payload_size, 696b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const webrtc::RTPFragmentationHeader& fragmentation_header, 697b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const RTPVideoHeader* rtp_video_hdr) { 698b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // New encoded data, hand over to the rtp module. 699b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return default_rtp_rtcp_->SendOutgoingData(frame_type, 700b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org payload_type, 701b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org time_stamp, 702b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org capture_time_ms, 703b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org payload_data, 704b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org payload_size, 705b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &fragmentation_header, 706b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org rtp_video_hdr); 707b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 708b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 70967879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t ViEEncoder::ProtectionRequest( 710b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const FecProtectionParams* delta_fec_params, 711b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const FecProtectionParams* key_fec_params, 71267879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org uint32_t* sent_video_rate_bps, 71367879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org uint32_t* sent_nack_rate_bps, 71467879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org uint32_t* sent_fec_rate_bps) { 715022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org default_rtp_rtcp_->SetFecParameters(delta_fec_params, key_fec_params); 716022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org default_rtp_rtcp_->BitrateSent(NULL, sent_video_rate_bps, sent_fec_rate_bps, 717b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sent_nack_rate_bps); 718b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 719b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 720b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 72167879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t ViEEncoder::SendStatistics(const uint32_t bit_rate, 72267879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org const uint32_t frame_rate) { 723b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(callback_cs_.get()); 724b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (codec_observer_) { 725b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org codec_observer_->OutgoingRate(channel_id_, frame_rate, bit_rate); 726b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 727b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 728b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 729b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 73067879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t ViEEncoder::RegisterCodecObserver(ViEEncoderObserver* observer) { 731b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(callback_cs_.get()); 732022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org if (observer && codec_observer_) { 733022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org LOG_F(LS_ERROR) << "Observer already set."; 734022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org return -1; 735b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 736022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org codec_observer_ = observer; 737b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 738b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 739b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 740b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid ViEEncoder::OnReceivedSLI(uint32_t /*ssrc*/, 741b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t picture_id) { 742fedbe8b196306135b3834b34b19fd455c037172astefan@webrtc.org CriticalSectionScoped cs(data_cs_.get()); 743b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org picture_id_sli_ = picture_id; 744b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org has_received_sli_ = true; 745b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 746b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 747b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid ViEEncoder::OnReceivedRPSI(uint32_t /*ssrc*/, 748b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint64_t picture_id) { 749fedbe8b196306135b3834b34b19fd455c037172astefan@webrtc.org CriticalSectionScoped cs(data_cs_.get()); 750b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org picture_id_rpsi_ = picture_id; 751b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org has_received_rpsi_ = true; 752b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 753b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 754b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.orgvoid ViEEncoder::OnReceivedIntraFrameRequest(uint32_t ssrc) { 755b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Key frame request from remote side, signal to VCM. 756d474c1380229d8b301f6cb4c3b84ad0d4ac18632justinlin@chromium.org TRACE_EVENT0("webrtc", "OnKeyFrameRequest"); 757b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 758b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org int idx = 0; 759b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org { 760b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org CriticalSectionScoped cs(data_cs_.get()); 761b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org std::map<unsigned int, int>::iterator stream_it = ssrc_streams_.find(ssrc); 762b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org if (stream_it == ssrc_streams_.end()) { 763ac09423d1ac3c758462252a2f27275031a5859damflodman@webrtc.org LOG_F(LS_WARNING) << "ssrc not found: " << ssrc << ", map size " 764ac09423d1ac3c758462252a2f27275031a5859damflodman@webrtc.org << ssrc_streams_.size(); 765b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org return; 766b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org } 76767879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org std::map<unsigned int, int64_t>::iterator time_it = 768b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org time_last_intra_request_ms_.find(ssrc); 769b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org if (time_it == time_last_intra_request_ms_.end()) { 770b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org time_last_intra_request_ms_[ssrc] = 0; 771b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org } 772b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org 77367879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org int64_t now = TickTime::MillisecondTimestamp(); 774b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org if (time_last_intra_request_ms_[ssrc] + kViEMinKeyRequestIntervalMs > now) { 775b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org return; 776b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org } 777b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org time_last_intra_request_ms_[ssrc] = now; 778b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org idx = stream_it->second; 779b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 780b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org // Release the critsect before triggering key frame. 781b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org vcm_.IntraFrameRequest(idx); 782b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 783b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 7849f269d2d33e102713402c4c6aa84ac65a590f719vikasmarwaha@webrtc.orgvoid ViEEncoder::OnLocalSsrcChanged(uint32_t old_ssrc, uint32_t new_ssrc) { 785b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org CriticalSectionScoped cs(data_cs_.get()); 786b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org std::map<unsigned int, int>::iterator it = ssrc_streams_.find(old_ssrc); 787b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org if (it == ssrc_streams_.end()) { 788b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org return; 789b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org } 790b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org 791b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org ssrc_streams_[new_ssrc] = it->second; 792b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org ssrc_streams_.erase(it); 793b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org 794b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org std::map<unsigned int, int64_t>::iterator time_it = 795b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org time_last_intra_request_ms_.find(old_ssrc); 796b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org int64_t last_intra_request_ms = 0; 797b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org if (time_it != time_last_intra_request_ms_.end()) { 798b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org last_intra_request_ms = time_it->second; 799b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org time_last_intra_request_ms_.erase(time_it); 800b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org } 801b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org time_last_intra_request_ms_[new_ssrc] = last_intra_request_ms; 802b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org} 803b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org 804b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.orgbool ViEEncoder::SetSsrcs(const std::list<unsigned int>& ssrcs) { 805b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org VideoCodec codec; 806b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org if (vcm_.SendCodec(&codec) != 0) 807b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org return false; 808b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org 809b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org if (codec.numberOfSimulcastStreams > 0 && 810b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org ssrcs.size() != codec.numberOfSimulcastStreams) { 811b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org return false; 812b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org } 813b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org 814b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org CriticalSectionScoped cs(data_cs_.get()); 815b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org ssrc_streams_.clear(); 816b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org time_last_intra_request_ms_.clear(); 817b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org int idx = 0; 818b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org for (std::list<unsigned int>::const_iterator it = ssrcs.begin(); 819b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org it != ssrcs.end(); ++it, ++idx) { 820b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org unsigned int ssrc = *it; 821b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org ssrc_streams_[ssrc] = idx; 822b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org } 823b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org return true; 824b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 825b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 8263f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.orgvoid ViEEncoder::SetMinTransmitBitrate(int min_transmit_bitrate_kbps) { 8273f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org assert(min_transmit_bitrate_kbps >= 0); 8283f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org CriticalSectionScoped crit(data_cs_.get()); 8293f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org min_transmit_bitrate_kbps_ = min_transmit_bitrate_kbps; 8303f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org} 8313f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org 832b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Called from ViEBitrateObserver. 833b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid ViEEncoder::OnNetworkChanged(const uint32_t bitrate_bps, 834b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const uint8_t fraction_lost, 835b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const uint32_t round_trip_time_ms) { 836022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org LOG(LS_VERBOSE) << "OnNetworkChanged, bitrate" << bitrate_bps 837022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org << " packet loss " << fraction_lost 838022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org << " rtt " << round_trip_time_ms; 83972e204a700e985c1f0c65f7a566fe9aaf7713e64stefan@webrtc.org vcm_.SetChannelParameters(bitrate_bps, fraction_lost, round_trip_time_ms); 8404590177aa3346a742e8f71c8bcc5b81618d21919henrik.lundin@webrtc.org bool video_is_suspended = vcm_.VideoSuspended(); 8415e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org int bitrate_kbps = bitrate_bps / 1000; 84269f76054f5dc242b313e7e0642c8657a885682bastefan@webrtc.org VideoCodec send_codec; 84369f76054f5dc242b313e7e0642c8657a885682bastefan@webrtc.org if (vcm_.SendCodec(&send_codec) != 0) { 84469f76054f5dc242b313e7e0642c8657a885682bastefan@webrtc.org return; 84569f76054f5dc242b313e7e0642c8657a885682bastefan@webrtc.org } 8467dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org SimulcastStream* stream_configs = send_codec.simulcastStream; 8477dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org // Allocate the bandwidth between the streams. 8487dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org std::vector<uint32_t> stream_bitrates = AllocateStreamBitrates( 8497dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org bitrate_bps, 8507dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org stream_configs, 8517dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org send_codec.numberOfSimulcastStreams); 8527dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org // Find the max amount of padding we can allow ourselves to send at this 8537dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org // point, based on which streams are currently active and what our current 8547dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org // available bandwidth is. 85593cd39766e6484842666c1b2c77283c3c1885f33stefan@webrtc.org int pad_up_to_bitrate_kbps = 0; 85693cd39766e6484842666c1b2c77283c3c1885f33stefan@webrtc.org if (send_codec.numberOfSimulcastStreams == 0) { 85793cd39766e6484842666c1b2c77283c3c1885f33stefan@webrtc.org pad_up_to_bitrate_kbps = send_codec.minBitrate; 85893cd39766e6484842666c1b2c77283c3c1885f33stefan@webrtc.org } else { 85993cd39766e6484842666c1b2c77283c3c1885f33stefan@webrtc.org pad_up_to_bitrate_kbps = 86093cd39766e6484842666c1b2c77283c3c1885f33stefan@webrtc.org stream_configs[send_codec.numberOfSimulcastStreams - 1].minBitrate; 86193cd39766e6484842666c1b2c77283c3c1885f33stefan@webrtc.org for (int i = 0; i < send_codec.numberOfSimulcastStreams - 1; ++i) { 86293cd39766e6484842666c1b2c77283c3c1885f33stefan@webrtc.org pad_up_to_bitrate_kbps += stream_configs[i].targetBitrate; 8637dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org } 8647dc17903111cf74bc28f45d87e595c628481f1acstefan@webrtc.org } 8651d61e3a79d4a5c6693c959f59d9f9cc6c1bfb359pbos@webrtc.org 8661d61e3a79d4a5c6693c959f59d9f9cc6c1bfb359pbos@webrtc.org // Disable padding if only sending one stream and video isn't suspended and 8671d61e3a79d4a5c6693c959f59d9f9cc6c1bfb359pbos@webrtc.org // min-transmit bitrate isn't used (applied later). 8681d61e3a79d4a5c6693c959f59d9f9cc6c1bfb359pbos@webrtc.org if (!video_is_suspended && send_codec.numberOfSimulcastStreams <= 1) 86993cd39766e6484842666c1b2c77283c3c1885f33stefan@webrtc.org pad_up_to_bitrate_kbps = 0; 8705e74d9693504416a5b72a9c8c9a7626f802f969estefan@webrtc.org 8715e74d9693504416a5b72a9c8c9a7626f802f969estefan@webrtc.org { 8725e74d9693504416a5b72a9c8c9a7626f802f969estefan@webrtc.org CriticalSectionScoped cs(data_cs_.get()); 8731d61e3a79d4a5c6693c959f59d9f9cc6c1bfb359pbos@webrtc.org // The amount of padding should decay to zero if no frames are being 8741d61e3a79d4a5c6693c959f59d9f9cc6c1bfb359pbos@webrtc.org // captured unless a min-transmit bitrate is used. 8755e74d9693504416a5b72a9c8c9a7626f802f969estefan@webrtc.org int64_t now_ms = TickTime::MillisecondTimestamp(); 8765e74d9693504416a5b72a9c8c9a7626f802f969estefan@webrtc.org if (now_ms - time_of_last_incoming_frame_ms_ > kStopPaddingThresholdMs) 8771d61e3a79d4a5c6693c959f59d9f9cc6c1bfb359pbos@webrtc.org pad_up_to_bitrate_kbps = 0; 8785e74d9693504416a5b72a9c8c9a7626f802f969estefan@webrtc.org 8791d61e3a79d4a5c6693c959f59d9f9cc6c1bfb359pbos@webrtc.org // Pad up to min bitrate. 8803f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org if (pad_up_to_bitrate_kbps < min_transmit_bitrate_kbps_) 8813f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org pad_up_to_bitrate_kbps = min_transmit_bitrate_kbps_; 8821d61e3a79d4a5c6693c959f59d9f9cc6c1bfb359pbos@webrtc.org 8831d61e3a79d4a5c6693c959f59d9f9cc6c1bfb359pbos@webrtc.org // Padding may never exceed bitrate estimate. 8841d61e3a79d4a5c6693c959f59d9f9cc6c1bfb359pbos@webrtc.org if (pad_up_to_bitrate_kbps > bitrate_kbps) 8851d61e3a79d4a5c6693c959f59d9f9cc6c1bfb359pbos@webrtc.org pad_up_to_bitrate_kbps = bitrate_kbps; 8861d61e3a79d4a5c6693c959f59d9f9cc6c1bfb359pbos@webrtc.org 887c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org paced_sender_->UpdateBitrate( 888c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org PacedSender::kDefaultPaceMultiplier * bitrate_kbps, 889c9995bc06a99f8b82a0ca0ddf5a5bb982cb0c11bstefan@webrtc.org pad_up_to_bitrate_kbps); 8903f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org default_rtp_rtcp_->SetTargetSendBitrate(stream_bitrates); 8917673871382e063289a0f7fd8aa77918b243c1788pbos@webrtc.org if (video_suspended_ == video_is_suspended) 8927673871382e063289a0f7fd8aa77918b243c1788pbos@webrtc.org return; 8937673871382e063289a0f7fd8aa77918b243c1788pbos@webrtc.org video_suspended_ = video_is_suspended; 8947673871382e063289a0f7fd8aa77918b243c1788pbos@webrtc.org } 8951d61e3a79d4a5c6693c959f59d9f9cc6c1bfb359pbos@webrtc.org 8961d61e3a79d4a5c6693c959f59d9f9cc6c1bfb359pbos@webrtc.org // Video suspend-state changed, inform codec observer. 8973f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org CriticalSectionScoped crit(callback_cs_.get()); 8987673871382e063289a0f7fd8aa77918b243c1788pbos@webrtc.org if (codec_observer_) { 899022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org LOG(LS_INFO) << "Video suspended " << video_is_suspended 900022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org << " for channel " << channel_id_; 90182b883c27168fa801aef8e0530db298e6128eb5chenrik.lundin@webrtc.org codec_observer_->SuspendChange(channel_id_, video_is_suspended); 90239079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org } 903b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 904b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 9055e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.orgPacedSender* ViEEncoder::GetPacedSender() { 9065e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org return paced_sender_.get(); 9075e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org} 9085e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org 90967879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t ViEEncoder::RegisterEffectFilter(ViEEffectFilter* effect_filter) { 910b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CriticalSectionScoped cs(callback_cs_.get()); 911022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org if (effect_filter != NULL && effect_filter_ != NULL) { 912022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org LOG_F(LS_ERROR) << "Filter already set."; 913022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org return -1; 914b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 915b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org effect_filter_ = effect_filter; 916b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 917b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 918b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 919b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEEncoder::StartDebugRecording(const char* fileNameUTF8) { 920b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return vcm_.StartDebugRecording(fileNameUTF8); 921b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 922b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 923b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEEncoder::StopDebugRecording() { 924b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return vcm_.StopDebugRecording(); 925b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 926b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 9274590177aa3346a742e8f71c8bcc5b81618d21919henrik.lundin@webrtc.orgvoid ViEEncoder::SuspendBelowMinBitrate() { 9284590177aa3346a742e8f71c8bcc5b81618d21919henrik.lundin@webrtc.org vcm_.SuspendBelowMinBitrate(); 9294ce759057ec1d71b19bd706c5cdc9027096463fdhenrik.lundin@webrtc.org bitrate_controller_->EnforceMinBitrate(false); 93039079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org} 93139079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org 93263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.orgvoid ViEEncoder::RegisterPreEncodeCallback( 93363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org I420FrameCallback* pre_encode_callback) { 93463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org CriticalSectionScoped cs(callback_cs_.get()); 93563301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org pre_encode_callback_ = pre_encode_callback; 93663301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org} 93763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 93863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.orgvoid ViEEncoder::DeRegisterPreEncodeCallback() { 93963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org CriticalSectionScoped cs(callback_cs_.get()); 94063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org pre_encode_callback_ = NULL; 94163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org} 94263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 9432e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.orgvoid ViEEncoder::RegisterPostEncodeImageCallback( 9442e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org EncodedImageCallback* post_encode_callback) { 9452e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org vcm_.RegisterPostEncodeImageCallback(post_encode_callback); 9462e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org} 9472e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 9482e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.orgvoid ViEEncoder::DeRegisterPostEncodeImageCallback() { 9492e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org vcm_.RegisterPostEncodeImageCallback(NULL); 9502e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org} 9512e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 952b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgQMVideoSettingsCallback::QMVideoSettingsCallback(VideoProcessingModule* vpm) 953b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : vpm_(vpm) { 954b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 955b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 956b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgQMVideoSettingsCallback::~QMVideoSettingsCallback() { 957b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 958b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 95967879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t QMVideoSettingsCallback::SetVideoQMSettings( 96067879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org const uint32_t frame_rate, 96167879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org const uint32_t width, 96267879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org const uint32_t height) { 963b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return vpm_->SetTargetResolution(width, height, frame_rate); 964b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 965b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 966b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} // namespace webrtc 967