| Index: media/engine/webrtcvideoengine.cc
|
| diff --git a/media/engine/webrtcvideoengine.cc b/media/engine/webrtcvideoengine.cc
|
| index 29fc442cb1f2742a88ba882107abec1fa5c88eca..dc3ca66d2b2308156bca8c42f49a0577b8c31436 100644
|
| --- a/media/engine/webrtcvideoengine.cc
|
| +++ b/media/engine/webrtcvideoengine.cc
|
| @@ -24,6 +24,7 @@
|
| #include "api/video_codecs/video_encoder_factory.h"
|
| #include "call/call.h"
|
| #include "common_video/h264/profile_level_id.h"
|
| +#include "media/base/codec.h"
|
| #include "media/engine/constants.h"
|
| #include "media/engine/internaldecoderfactory.h"
|
| #include "media/engine/internalencoderfactory.h"
|
| @@ -36,6 +37,8 @@
|
| #include "media/engine/webrtcmediaengine.h"
|
| #include "media/engine/webrtcvideoencoderfactory.h"
|
| #include "media/engine/webrtcvoiceengine.h"
|
| +#include "modules/video_coding/codecs/stereo/include/stereo_decoder_adapter.h"
|
| +#include "modules/video_coding/codecs/stereo/include/stereo_encoder_adapter.h"
|
| #include "rtc_base/copyonwritebuffer.h"
|
| #include "rtc_base/logging.h"
|
| #include "rtc_base/stringutils.h"
|
| @@ -68,7 +71,8 @@ class EncoderFactoryAdapter {
|
|
|
| virtual AllocatedEncoder CreateVideoEncoder(
|
| const VideoCodec& codec,
|
| - bool is_conference_mode_screenshare) const = 0;
|
| + bool is_conference_mode_screenshare,
|
| + bool is_stereo_codec) const = 0;
|
|
|
| virtual std::vector<VideoCodec> GetSupportedCodecs() const = 0;
|
| };
|
| @@ -79,7 +83,8 @@ class DecoderFactoryAdapter {
|
|
|
| virtual std::unique_ptr<webrtc::VideoDecoder> CreateVideoDecoder(
|
| const VideoCodec& codec,
|
| - const VideoDecoderParams& decoder_params) const = 0;
|
| + const VideoDecoderParams& decoder_params,
|
| + bool is_stereo_codec) const = 0;
|
| };
|
|
|
| namespace {
|
| @@ -105,12 +110,14 @@ class CricketEncoderFactoryAdapter : public EncoderFactoryAdapter {
|
|
|
| AllocatedEncoder CreateVideoEncoder(
|
| const VideoCodec& codec,
|
| - bool is_conference_mode_screenshare) const override;
|
| + bool is_conference_mode_screenshare,
|
| + bool is_stereo_codec) const override;
|
|
|
| std::vector<VideoCodec> GetSupportedCodecs() const override;
|
|
|
| const std::unique_ptr<WebRtcVideoEncoderFactory> internal_encoder_factory_;
|
| WebRtcVideoEncoderFactory* const external_encoder_factory_;
|
| + std::unique_ptr<WebRtcVideoEncoderFactory> stereo_encoder_factory_;
|
| };
|
|
|
| class CricketDecoderFactoryAdapter : public DecoderFactoryAdapter {
|
| @@ -127,10 +134,12 @@ class CricketDecoderFactoryAdapter : public DecoderFactoryAdapter {
|
|
|
| std::unique_ptr<webrtc::VideoDecoder> CreateVideoDecoder(
|
| const VideoCodec& codec,
|
| - const VideoDecoderParams& decoder_params) const override;
|
| + const VideoDecoderParams& decoder_params,
|
| + bool is_stereo_codec) const override;
|
|
|
| const std::unique_ptr<WebRtcVideoDecoderFactory> internal_decoder_factory_;
|
| WebRtcVideoDecoderFactory* const external_decoder_factory_;
|
| + std::unique_ptr<WebRtcVideoDecoderFactory> stereo_decoder_factory_;
|
| };
|
|
|
| // Wraps webrtc::VideoEncoderFactory into common EncoderFactoryAdapter
|
| @@ -144,7 +153,8 @@ class WebRtcEncoderFactoryAdapter : public EncoderFactoryAdapter {
|
| private:
|
| AllocatedEncoder CreateVideoEncoder(
|
| const VideoCodec& codec,
|
| - bool is_conference_mode_screenshare) const override {
|
| + bool is_conference_mode_screenshare,
|
| + bool is_stereo_codec) const override {
|
| if (!encoder_factory_)
|
| return AllocatedEncoder();
|
| const webrtc::SdpVideoFormat format(codec.name, codec.params);
|
| @@ -183,7 +193,8 @@ class WebRtcDecoderFactoryAdapter : public DecoderFactoryAdapter {
|
| private:
|
| std::unique_ptr<webrtc::VideoDecoder> CreateVideoDecoder(
|
| const VideoCodec& codec,
|
| - const VideoDecoderParams& decoder_params) const override {
|
| + const VideoDecoderParams& decoder_params,
|
| + bool is_stereo_codec) const override {
|
| return decoder_factory_
|
| ? decoder_factory_->CreateVideoDecoder(
|
| webrtc::SdpVideoFormat(codec.name, codec.params))
|
| @@ -556,6 +567,14 @@ std::vector<VideoCodec> AssignPayloadTypesAndAddAssociatedRtxCodecs(
|
| if (payload_type > kLastDynamicPayloadType)
|
| break;
|
| }
|
| +
|
| + if (CodecNamesEq(codec.name, kVp9CodecName)) {
|
| + output_codecs.push_back(
|
| + VideoCodec::CreateStereoCodec(payload_type, codec));
|
| + ++payload_type;
|
| + if (payload_type > kLastDynamicPayloadType)
|
| + break;
|
| + }
|
| }
|
| return output_codecs;
|
| }
|
| @@ -583,12 +602,11 @@ std::vector<VideoCodec> CricketEncoderFactoryAdapter::GetSupportedCodecs()
|
| return AssignPayloadTypesAndAddAssociatedRtxCodecs(codecs);
|
| }
|
|
|
| -WebRtcVideoChannel::WebRtcVideoChannel(
|
| - webrtc::Call* call,
|
| - const MediaConfig& config,
|
| - const VideoOptions& options,
|
| - const EncoderFactoryAdapter* encoder_factory,
|
| - const DecoderFactoryAdapter* decoder_factory)
|
| +WebRtcVideoChannel::WebRtcVideoChannel(webrtc::Call* call,
|
| + const MediaConfig& config,
|
| + const VideoOptions& options,
|
| + EncoderFactoryAdapter* encoder_factory,
|
| + DecoderFactoryAdapter* decoder_factory)
|
| : VideoMediaChannel(config),
|
| call_(call),
|
| unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_),
|
| @@ -619,6 +637,9 @@ WebRtcVideoChannel::SelectSendVideoCodec(
|
| encoder_factory_->GetSupportedCodecs();
|
| // Select the first remote codec that is supported locally.
|
| for (const VideoCodecSettings& remote_mapped_codec : remote_mapped_codecs) {
|
| + // HARDCODE TO ALPHA
|
| + if (!cricket::VideoCodec::IsStereoCodec(remote_mapped_codec.codec))
|
| + continue;
|
| // For H264, we will limit the encode level to the remote offered level
|
| // regardless if level asymmetry is allowed or not. This is strictly not
|
| // following the spec in https://tools.ietf.org/html/rfc6184#section-8.2.2
|
| @@ -631,6 +652,24 @@ WebRtcVideoChannel::SelectSendVideoCodec(
|
| return rtc::Optional<VideoCodecSettings>();
|
| }
|
|
|
| +rtc::Optional<WebRtcVideoChannel::VideoCodecSettings>
|
| +WebRtcVideoChannel::SelectStereoAssociatedVideoCodec(
|
| + const std::vector<VideoCodecSettings>& remote_mapped_codecs) const {
|
| + const std::vector<VideoCodec> local_supported_codecs =
|
| + encoder_factory_->GetSupportedCodecs();
|
| +
|
| + // Select the first remote codec that is supported locally.
|
| + for (const VideoCodecSettings& remote_mapped_codec : remote_mapped_codecs) {
|
| + // HARDCODE TO VP9
|
| + if (!CodecNamesEq(remote_mapped_codec.codec.name.c_str(), kVp9CodecName))
|
| + continue;
|
| + if (!cricket::VideoCodec::IsStereoCodec(remote_mapped_codec.codec) &&
|
| + FindMatchingCodec(local_supported_codecs, remote_mapped_codec.codec))
|
| + return rtc::Optional<VideoCodecSettings>(remote_mapped_codec);
|
| + }
|
| + return rtc::Optional<VideoCodecSettings>();
|
| +}
|
| +
|
| bool WebRtcVideoChannel::NonFlexfecReceiveCodecsHaveChanged(
|
| std::vector<VideoCodecSettings> before,
|
| std::vector<VideoCodecSettings> after) {
|
| @@ -677,6 +716,19 @@ bool WebRtcVideoChannel::GetChangedSendParameters(
|
| return false;
|
| }
|
|
|
| + if (VideoCodec::IsStereoCodec(selected_send_codec->codec)) {
|
| + rtc::Optional<VideoCodecSettings> associated_codec_settings =
|
| + SelectStereoAssociatedVideoCodec(MapCodecs(params.codecs));
|
| + LOG(LS_ERROR) << __func__ << associated_codec_settings->codec.ToString();
|
| + if (!associated_codec_settings) {
|
| + LOG(LS_ERROR)
|
| + << "Stereo codec is not associated with any supported codec.";
|
| + return false;
|
| + }
|
| + associated_codec_settings->stereo_codec.emplace(selected_send_codec->codec);
|
| + selected_send_codec = associated_codec_settings;
|
| + }
|
| +
|
| // Never enable sending FlexFEC, unless we are in the experiment.
|
| if (!IsFlexfecFieldTrialEnabled()) {
|
| if (selected_send_codec->flexfec_payload_type != -1) {
|
| @@ -1549,7 +1601,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::WebRtcVideoSendStream(
|
| const StreamParams& sp,
|
| webrtc::VideoSendStream::Config config,
|
| const VideoOptions& options,
|
| - const EncoderFactoryAdapter* encoder_factory,
|
| + EncoderFactoryAdapter* encoder_factory,
|
| bool enable_cpu_overuse_detection,
|
| int max_bitrate_bps,
|
| const rtc::Optional<VideoCodecSettings>& codec_settings,
|
| @@ -1699,7 +1751,30 @@ WebRtcVideoChannel::WebRtcVideoSendStream::GetSsrcs() const {
|
| EncoderFactoryAdapter::AllocatedEncoder
|
| CricketEncoderFactoryAdapter::CreateVideoEncoder(
|
| const VideoCodec& codec,
|
| - bool is_conference_mode_screenshare) const {
|
| + bool is_conference_mode_screenshare,
|
| + bool is_stereo_codec) const {
|
| + if (is_stereo_codec) {
|
| + if (external_encoder_factory_ != nullptr &&
|
| + FindMatchingCodec(external_encoder_factory_->supported_codecs(),
|
| + codec)) {
|
| + std::unique_ptr<webrtc::VideoEncoder> stereo_encoder(
|
| + new webrtc::StereoEncoderAdapter(external_encoder_factory_));
|
| + return AllocatedEncoder(std::move(stereo_encoder),
|
| + true /* is_hardware_accelerated */,
|
| + false /* is_external */);
|
| + }
|
| + if (FindMatchingCodec(internal_encoder_factory_->supported_codecs(),
|
| + codec)) {
|
| + std::unique_ptr<webrtc::VideoEncoder> stereo_encoder(
|
| + new webrtc::StereoEncoderAdapter(internal_encoder_factory_.get()));
|
| + return AllocatedEncoder(std::move(stereo_encoder),
|
| + false /* is_hardware_accelerated */,
|
| + false /* is_external */);
|
| + }
|
| + RTC_NOTREACHED();
|
| + return AllocatedEncoder();
|
| + }
|
| +
|
| // Try creating external encoder.
|
| if (external_encoder_factory_ != nullptr &&
|
| FindMatchingCodec(external_encoder_factory_->supported_codecs(), codec)) {
|
| @@ -1757,6 +1832,8 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec(
|
| parameters_.encoder_config = CreateVideoEncoderConfig(codec_settings.codec);
|
| RTC_DCHECK_GT(parameters_.encoder_config.number_of_streams, 0);
|
|
|
| + const bool is_stereo_codec = codec_settings.stereo_codec.has_value();
|
| +
|
| // Do not re-create encoders of the same type. We can't overwrite
|
| // |allocated_encoder_| immediately, because we need to release it after the
|
| // RecreateWebRtcStream() call.
|
| @@ -1769,7 +1846,8 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec(
|
| parameters_.conference_mode;
|
| EncoderFactoryAdapter::AllocatedEncoder new_allocated_encoder =
|
| encoder_factory_->CreateVideoEncoder(codec_settings.codec,
|
| - is_conference_mode_screenshare);
|
| + is_conference_mode_screenshare,
|
| + is_stereo_codec);
|
| new_encoder = std::unique_ptr<webrtc::VideoEncoder>(
|
| std::move(new_allocated_encoder.encoder));
|
| parameters_.config.encoder_settings.encoder = new_encoder.get();
|
| @@ -1780,8 +1858,13 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec(
|
| } else {
|
| new_encoder = std::move(allocated_encoder_);
|
| }
|
| - parameters_.config.encoder_settings.payload_name = codec_settings.codec.name;
|
| - parameters_.config.encoder_settings.payload_type = codec_settings.codec.id;
|
| + VideoCodec payload_codec = is_stereo_codec
|
| + ? codec_settings.stereo_codec.value()
|
| + : codec_settings.codec;
|
| + parameters_.config.encoder_settings.payload_name = payload_codec.name;
|
| + parameters_.config.encoder_settings.payload_type = payload_codec.id;
|
| + parameters_.config.encoder_settings.stereo_associated_payload_name =
|
| + codec_settings.codec.name;
|
| parameters_.config.rtp.ulpfec = codec_settings.ulpfec;
|
| parameters_.config.rtp.flexfec.payload_type =
|
| codec_settings.flexfec_payload_type;
|
| @@ -2024,6 +2107,7 @@ VideoSenderInfo WebRtcVideoChannel::WebRtcVideoSendStream::GetVideoSenderInfo(
|
| for (uint32_t ssrc : parameters_.config.rtp.ssrcs)
|
| info.add_ssrc(ssrc);
|
|
|
| + // TODO(emircan): Add stereo codec case.
|
| if (parameters_.codec_settings) {
|
| info.codec_name = parameters_.codec_settings->codec.name;
|
| info.codec_payload_type = rtc::Optional<int>(
|
| @@ -2150,7 +2234,7 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream(
|
| webrtc::Call* call,
|
| const StreamParams& sp,
|
| webrtc::VideoReceiveStream::Config config,
|
| - const DecoderFactoryAdapter* decoder_factory,
|
| + DecoderFactoryAdapter* decoder_factory,
|
| bool default_stream,
|
| const std::vector<VideoCodecSettings>& recv_codecs,
|
| const webrtc::FlexfecReceiveStream::Config& flexfec_config)
|
| @@ -2204,7 +2288,19 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::GetFirstPrimarySsrc() const {
|
| std::unique_ptr<webrtc::VideoDecoder>
|
| CricketDecoderFactoryAdapter::CreateVideoDecoder(
|
| const VideoCodec& codec,
|
| - const VideoDecoderParams& decoder_params) const {
|
| + const VideoDecoderParams& decoder_params,
|
| + bool is_stereo_codec) const {
|
| + if (is_stereo_codec) {
|
| + if (external_decoder_factory_ != nullptr) {
|
| + std::unique_ptr<webrtc::VideoDecoder> external_decoder(
|
| + new webrtc::StereoDecoderAdapter(external_decoder_factory_));
|
| + return external_decoder;
|
| + }
|
| + std::unique_ptr<webrtc::VideoDecoder> internal_decoder(
|
| + new webrtc::StereoDecoderAdapter(internal_decoder_factory_.get()));
|
| + return internal_decoder;
|
| + }
|
| +
|
| if (external_decoder_factory_ != nullptr) {
|
| std::unique_ptr<webrtc::VideoDecoder> external_decoder =
|
| CreateScopedVideoDecoder(external_decoder_factory_, codec,
|
| @@ -2232,19 +2328,21 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::ConfigureCodecs(
|
| config_.decoders.clear();
|
| config_.rtp.rtx_associated_payload_types.clear();
|
| for (const auto& recv_codec : recv_codecs) {
|
| + const bool is_stereo_codec =
|
| + cricket::VideoCodec::IsStereoCodec(recv_codec.codec);
|
| webrtc::SdpVideoFormat video_format(recv_codec.codec.name,
|
| recv_codec.codec.params);
|
| std::unique_ptr<webrtc::VideoDecoder> new_decoder;
|
|
|
| auto it = old_decoders->find(video_format);
|
| - if (it != old_decoders->end()) {
|
| + if (it != old_decoders->end() && !is_stereo_codec) {
|
| new_decoder = std::move(it->second);
|
| old_decoders->erase(it);
|
| }
|
|
|
| if (!new_decoder) {
|
| - new_decoder = decoder_factory_->CreateVideoDecoder(recv_codec.codec,
|
| - {stream_params_.id});
|
| + new_decoder = decoder_factory_->CreateVideoDecoder(
|
| + recv_codec.codec, {stream_params_.id}, is_stereo_codec);
|
| }
|
|
|
| webrtc::VideoReceiveStream::Decoder decoder;
|
|
|