diff --git a/webrtc/video/call.cc b/webrtc/video/call.cc index bfa45a3b06..37f9f2d60a 100644 --- a/webrtc/video/call.cc +++ b/webrtc/video/call.cc @@ -169,7 +169,8 @@ Call::Call(const Call::Config& config) // TODO(pbos): Remove base channel when CreateReceiveChannel no longer // requires one. - CHECK(channel_group_->CreateSendChannel(base_channel_id_, 0, num_cpu_cores_)); + CHECK(channel_group_->CreateSendChannel(base_channel_id_, 0, num_cpu_cores_, + true)); if (config.overuse_callback) { overuse_observer_proxy_.reset( diff --git a/webrtc/video/video_receive_stream.cc b/webrtc/video/video_receive_stream.cc index aedb1a5e38..12933caee8 100644 --- a/webrtc/video/video_receive_stream.cc +++ b/webrtc/video/video_receive_stream.cc @@ -138,7 +138,7 @@ VideoReceiveStream::VideoReceiveStream(int num_cpu_cores, channel_id_(channel_id), voe_sync_interface_(nullptr) { CHECK(channel_group_->CreateReceiveChannel(channel_id_, 0, base_channel_id, - num_cpu_cores)); + num_cpu_cores, true)); vie_channel_ = channel_group_->GetChannel(channel_id_); diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc index 385e269994..8fc03c50ac 100644 --- a/webrtc/video/video_send_stream.cc +++ b/webrtc/video/video_send_stream.cc @@ -119,7 +119,7 @@ VideoSendStream::VideoSendStream( channel_id_(channel_id), use_config_bitrate_(true), stats_proxy_(Clock::GetRealTimeClock(), config) { - CHECK(channel_group->CreateSendChannel(channel_id_, 0, num_cpu_cores)); + CHECK(channel_group->CreateSendChannel(channel_id_, 0, num_cpu_cores, true)); vie_channel_ = channel_group_->GetChannel(channel_id_); vie_encoder_ = channel_group_->GetEncoder(channel_id_); diff --git a/webrtc/video_engine/encoder_state_feedback_unittest.cc b/webrtc/video_engine/encoder_state_feedback_unittest.cc index 337bfb9d62..eab33d407a 100644 --- a/webrtc/video_engine/encoder_state_feedback_unittest.cc +++ b/webrtc/video_engine/encoder_state_feedback_unittest.cc @@ -31,7 +31,7 @@ namespace webrtc { class MockVieEncoder : public ViEEncoder { public: explicit MockVieEncoder(ProcessThread* process_thread, PacedSender* pacer) - : ViEEncoder(1, 1, config_, *process_thread, pacer, NULL, NULL) {} + : ViEEncoder(1, 1, config_, *process_thread, pacer, NULL, NULL, false) {} ~MockVieEncoder() {} MOCK_METHOD1(OnReceivedIntraFrameRequest, diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc index 94cb7e0b15..0ee0e97efc 100644 --- a/webrtc/video_engine/vie_channel.cc +++ b/webrtc/video_engine/vie_channel.cc @@ -90,7 +90,8 @@ ViEChannel::ViEChannel(int32_t channel_id, RtcpRttStats* rtt_stats, PacedSender* paced_sender, PacketRouter* packet_router, - bool sender) + bool sender, + bool disable_default_encoder) : channel_id_(channel_id), engine_id_(engine_id), number_of_cores_(number_of_cores), @@ -123,6 +124,7 @@ ViEChannel::ViEChannel(int32_t channel_id, wait_for_key_frame_(false), mtu_(0), sender_(sender), + disable_default_encoder_(disable_default_encoder), nack_history_size_sender_(kSendSidePacketHistorySize), max_nack_reordering_threshold_(kMaxPacketAgeToNack), pre_render_callback_(NULL), @@ -167,6 +169,24 @@ int32_t ViEChannel::Init() { module_process_thread_.RegisterModule(vcm_); module_process_thread_.RegisterModule(&vie_sync_); +#ifdef VIDEOCODEC_VP8 + if (!disable_default_encoder_) { + VideoCodec video_codec; + if (vcm_->Codec(kVideoCodecVP8, &video_codec) == VCM_OK) { + rtp_rtcp_->RegisterSendPayload(video_codec); + // TODO(holmer): Can we call SetReceiveCodec() here instead? + if (!vie_receiver_.RegisterPayload(video_codec)) { + return -1; + } + vcm_->RegisterReceiveCodec(&video_codec, number_of_cores_); + vcm_->RegisterSendCodec(&video_codec, number_of_cores_, + rtp_rtcp_->MaxDataPayloadLength()); + } else { + assert(false); + } + } +#endif + return 0; } diff --git a/webrtc/video_engine/vie_channel.h b/webrtc/video_engine/vie_channel.h index c8666eb075..57e187a7a4 100644 --- a/webrtc/video_engine/vie_channel.h +++ b/webrtc/video_engine/vie_channel.h @@ -112,7 +112,8 @@ class ViEChannel : public VCMFrameTypeCallback, RtcpRttStats* rtt_stats, PacedSender* paced_sender, PacketRouter* packet_router, - bool sender); + bool sender, + bool disable_default_encoder); ~ViEChannel(); int32_t Init(); @@ -521,6 +522,8 @@ class ViEChannel : public VCMFrameTypeCallback, // User set MTU, -1 if not set. uint16_t mtu_; const bool sender_; + // Used to skip default encoder in the new API. + const bool disable_default_encoder_; int nack_history_size_sender_; int max_nack_reordering_threshold_; diff --git a/webrtc/video_engine/vie_channel_group.cc b/webrtc/video_engine/vie_channel_group.cc index 327dc72499..9330c44631 100644 --- a/webrtc/video_engine/vie_channel_group.cc +++ b/webrtc/video_engine/vie_channel_group.cc @@ -200,16 +200,17 @@ ChannelGroup::~ChannelGroup() { bool ChannelGroup::CreateSendChannel(int channel_id, int engine_id, - int number_of_cores) { + int number_of_cores, + bool disable_default_encoder) { rtc::scoped_ptr vie_encoder(new ViEEncoder( channel_id, number_of_cores, *config_, *process_thread_, pacer_.get(), - bitrate_allocator_.get(), bitrate_controller_.get())); + bitrate_allocator_.get(), bitrate_controller_.get(), false)); if (!vie_encoder->Init()) { return false; } ViEEncoder* encoder = vie_encoder.get(); if (!CreateChannel(channel_id, engine_id, number_of_cores, - vie_encoder.release(), true)) { + vie_encoder.release(), true, disable_default_encoder)) { return false; } ViEChannel* channel = channel_map_[channel_id]; @@ -231,16 +232,19 @@ bool ChannelGroup::CreateSendChannel(int channel_id, bool ChannelGroup::CreateReceiveChannel(int channel_id, int engine_id, int base_channel_id, - int number_of_cores) { + int number_of_cores, + bool disable_default_encoder) { ViEEncoder* encoder = GetEncoder(base_channel_id); - return CreateChannel(channel_id, engine_id, number_of_cores, encoder, false); + return CreateChannel(channel_id, engine_id, number_of_cores, encoder, false, + disable_default_encoder); } bool ChannelGroup::CreateChannel(int channel_id, int engine_id, int number_of_cores, ViEEncoder* vie_encoder, - bool sender) { + bool sender, + bool disable_default_encoder) { DCHECK(vie_encoder); rtc::scoped_ptr channel(new ViEChannel( @@ -248,10 +252,19 @@ bool ChannelGroup::CreateChannel(int channel_id, encoder_state_feedback_->GetRtcpIntraFrameObserver(), bitrate_controller_->CreateRtcpBandwidthObserver(), remote_bitrate_estimator_.get(), call_stats_->rtcp_rtt_stats(), - pacer_.get(), packet_router_.get(), sender)); + pacer_.get(), packet_router_.get(), sender, disable_default_encoder)); if (channel->Init() != 0) { return false; } + if (!disable_default_encoder) { + VideoCodec encoder; + if (vie_encoder->GetEncoder(&encoder) != 0) { + return false; + } + if (sender && channel->SetSendCodec(encoder) != 0) { + return false; + } + } // Register the channel to receive stats updates. call_stats_->RegisterStatsObserver(channel->GetStatsObserver()); diff --git a/webrtc/video_engine/vie_channel_group.h b/webrtc/video_engine/vie_channel_group.h index c359e6f50c..36bf683a9d 100644 --- a/webrtc/video_engine/vie_channel_group.h +++ b/webrtc/video_engine/vie_channel_group.h @@ -44,11 +44,13 @@ class ChannelGroup : public BitrateObserver { ~ChannelGroup(); bool CreateSendChannel(int channel_id, int engine_id, - int number_of_cores); + int number_of_cores, + bool disable_default_encoder); bool CreateReceiveChannel(int channel_id, int engine_id, int base_channel_id, - int number_of_cores); + int number_of_cores, + bool disable_default_encoder); void DeleteChannel(int channel_id); void AddChannel(int channel_id); void RemoveChannel(int channel_id); @@ -84,7 +86,8 @@ class ChannelGroup : public BitrateObserver { int engine_id, int number_of_cores, ViEEncoder* vie_encoder, - bool sender); + bool sender, + bool disable_default_encoder); ViEChannel* PopChannel(int channel_id); ViEEncoder* PopEncoder(int channel_id); diff --git a/webrtc/video_engine/vie_encoder.cc b/webrtc/video_engine/vie_encoder.cc index acdc5cf107..6fe7132f5b 100644 --- a/webrtc/video_engine/vie_encoder.cc +++ b/webrtc/video_engine/vie_encoder.cc @@ -104,9 +104,11 @@ ViEEncoder::ViEEncoder(int32_t channel_id, ProcessThread& module_process_thread, PacedSender* pacer, BitrateAllocator* bitrate_allocator, - BitrateController* bitrate_controller) + BitrateController* bitrate_controller, + bool disable_default_encoder) : 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(), @@ -147,6 +149,26 @@ bool ViEEncoder::Init() { // Enable/disable content analysis: off by default for now. vpm_->EnableContentAnalysis(false); + if (!disable_default_encoder_) { +#ifdef VIDEOCODEC_VP8 + VideoCodecType codec_type = webrtc::kVideoCodecVP8; +#else + VideoCodecType codec_type = webrtc::kVideoCodecI420; +#endif + VideoCodec video_codec; + 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) { + return false; + } + } if (vcm_->RegisterTransportCallback(this) != 0) { return false; } @@ -260,6 +282,30 @@ int32_t ViEEncoder::DeRegisterExternalEncoder(uint8_t pl_type) { return -1; } + if (disable_default_encoder_) + return 0; + + // If the external encoder is the current send codec, use vcm internal + // encoder. + if (current_send_codec.plType == pl_type) { + { + CriticalSectionScoped cs(data_cs_.get()); + send_padding_ = current_send_codec.numberOfSimulcastStreams > 1; + } + // TODO(mflodman): Unfortunately the VideoCodec that VCM has cached a + // raw pointer to an |extra_options| that's long gone. Clearing it here is + // a hack to prevent the following code from crashing. This should be fixed + // 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) { + 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 " + << "was supported."; + } + } return 0; } diff --git a/webrtc/video_engine/vie_encoder.h b/webrtc/video_engine/vie_encoder.h index accd1fc6d6..c56450d378 100644 --- a/webrtc/video_engine/vie_encoder.h +++ b/webrtc/video_engine/vie_encoder.h @@ -78,7 +78,8 @@ class ViEEncoder ProcessThread& module_process_thread, PacedSender* pacer, BitrateAllocator* bitrate_allocator, - BitrateController* bitrate_controller); + BitrateController* bitrate_controller, + bool disable_default_encoder); ~ViEEncoder(); bool Init(); @@ -194,6 +195,7 @@ class ViEEncoder const int channel_id_; const uint32_t number_of_cores_; + const bool disable_default_encoder_; const rtc::scoped_ptr vpm_; const rtc::scoped_ptr qm_callback_;