Add helper functions for migrating to new video codec factories

This CL adds helper functions in media/engine/convert_legacy_video_factory.h to
convert from the old WebRtcVideoEncoder and WebRtcVideoDecoder to the new
webrtc::VideoEncoder and webrtc::VideoDecoder.

The purpose is to make it as easy as possible for clients to migrate to the new
API and allow us to stop depending on the internal SW codecs as soon as possible.

There still exists an ugly decoder adapter class in the video engine. The reason
is that we need to continue to pass in the |receive_stream_id| decoder params to
some legacy clients.

Bug: webrtc:7925
Change-Id: I43ff03e036411a85d4940fe517a34489f171d698
Reviewed-on: https://webrtc-review.googlesource.com/15181
Commit-Queue: Magnus Jedvert <magjed@webrtc.org>
Reviewed-by: Anders Carlsson <andersc@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20475}
This commit is contained in:
Magnus Jedvert 2017-10-30 14:26:20 +01:00 committed by Commit Bot
parent 9da7c7480b
commit 1c9623c70d
7 changed files with 357 additions and 269 deletions

View File

@ -143,6 +143,8 @@ rtc_static_library("rtc_audio_video") {
"engine/apm_helpers.cc",
"engine/apm_helpers.h",
"engine/constants.h",
"engine/convert_legacy_video_factory.cc",
"engine/convert_legacy_video_factory.h",
"engine/internaldecoderfactory.cc",
"engine/internaldecoderfactory.h",
"engine/internalencoderfactory.cc",

View File

@ -0,0 +1,191 @@
/*
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "media/engine/convert_legacy_video_factory.h"
#include <utility>
#include <vector>
#include "api/video_codecs/video_decoder_factory.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "media/engine/internaldecoderfactory.h"
#include "media/engine/internalencoderfactory.h"
#include "media/engine/scopedvideodecoder.h"
#include "media/engine/scopedvideoencoder.h"
#include "media/engine/simulcast_encoder_adapter.h"
#include "media/engine/videodecodersoftwarefallbackwrapper.h"
#include "media/engine/videoencodersoftwarefallbackwrapper.h"
#include "media/engine/vp8_encoder_simulcast_proxy.h"
#include "media/engine/webrtcvideodecoderfactory.h"
#include "media/engine/webrtcvideoencoderfactory.h"
#include "rtc_base/checks.h"
namespace cricket {
namespace {
class EncoderAdapter : public webrtc::VideoEncoderFactory {
public:
explicit EncoderAdapter(
std::unique_ptr<WebRtcVideoEncoderFactory> external_encoder_factory)
: internal_encoder_factory_(new InternalEncoderFactory()),
external_encoder_factory_(std::move(external_encoder_factory)) {}
webrtc::VideoEncoderFactory::CodecInfo QueryVideoEncoder(
const webrtc::SdpVideoFormat& format) const {
const VideoCodec codec(format);
if (external_encoder_factory_ != nullptr &&
FindMatchingCodec(external_encoder_factory_->supported_codecs(),
codec)) {
// Format is supported by the external factory.
const webrtc::VideoCodecType codec_type =
webrtc::PayloadStringToCodecType(codec.name);
webrtc::VideoEncoderFactory::CodecInfo info;
info.has_internal_source =
external_encoder_factory_->EncoderTypeHasInternalSource(codec_type);
info.is_hardware_accelerated = true;
return info;
}
// Format must be one of the internal formats.
RTC_DCHECK(FindMatchingCodec(internal_encoder_factory_->supported_codecs(),
codec));
webrtc::VideoEncoderFactory::CodecInfo info;
info.has_internal_source = false;
info.is_hardware_accelerated = false;
return info;
}
std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder(
const webrtc::SdpVideoFormat& format) {
const VideoCodec codec(format);
// Try creating external encoder.
if (external_encoder_factory_ != nullptr &&
FindMatchingCodec(external_encoder_factory_->supported_codecs(),
codec)) {
std::unique_ptr<webrtc::VideoEncoder> external_encoder;
if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) {
// If it's a codec type we can simulcast, create a wrapped encoder.
external_encoder = std::unique_ptr<webrtc::VideoEncoder>(
new webrtc::SimulcastEncoderAdapter(
external_encoder_factory_.get()));
} else {
external_encoder =
CreateScopedVideoEncoder(external_encoder_factory_.get(), codec);
}
if (external_encoder) {
return std::unique_ptr<webrtc::VideoEncoder>(
new webrtc::VideoEncoderSoftwareFallbackWrapper(
codec, std::move(external_encoder)));
}
}
// Try creating internal encoder.
if (FindMatchingCodec(internal_encoder_factory_->supported_codecs(),
codec)) {
if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) {
return std::unique_ptr<webrtc::VideoEncoder>(
new webrtc::VP8EncoderSimulcastProxy(
internal_encoder_factory_.get()));
} else {
return std::unique_ptr<webrtc::VideoEncoder>(
internal_encoder_factory_->CreateVideoEncoder(codec));
}
}
// This shouldn't happen, we should not be trying to create something we
// don't support.
RTC_NOTREACHED();
return nullptr;
}
std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const {
std::vector<VideoCodec> codecs =
InternalEncoderFactory().supported_codecs();
// Add external codecs.
if (external_encoder_factory_ != nullptr) {
const std::vector<VideoCodec>& external_codecs =
external_encoder_factory_->supported_codecs();
for (const VideoCodec& codec : external_codecs) {
// Don't add same codec twice.
if (!FindMatchingCodec(codecs, codec))
codecs.push_back(codec);
}
}
std::vector<webrtc::SdpVideoFormat> formats;
for (const VideoCodec& codec : codecs) {
formats.push_back(webrtc::SdpVideoFormat(codec.name, codec.params));
}
return formats;
}
private:
const std::unique_ptr<WebRtcVideoEncoderFactory> internal_encoder_factory_;
const std::unique_ptr<WebRtcVideoEncoderFactory> external_encoder_factory_;
};
class DecoderAdapter : public webrtc::VideoDecoderFactory {
public:
explicit DecoderAdapter(
std::unique_ptr<WebRtcVideoDecoderFactory> external_decoder_factory)
: internal_decoder_factory_(new InternalDecoderFactory()),
external_decoder_factory_(std::move(external_decoder_factory)) {}
std::unique_ptr<webrtc::VideoDecoder> CreateVideoDecoder(
const webrtc::SdpVideoFormat& format) override {
const VideoCodec codec(format);
const VideoDecoderParams params;
if (external_decoder_factory_ != nullptr) {
std::unique_ptr<webrtc::VideoDecoder> external_decoder =
CreateScopedVideoDecoder(external_decoder_factory_.get(), codec,
params);
if (external_decoder) {
webrtc::VideoCodecType type =
webrtc::PayloadStringToCodecType(codec.name);
std::unique_ptr<webrtc::VideoDecoder> internal_decoder(
new webrtc::VideoDecoderSoftwareFallbackWrapper(
type, std::move(external_decoder)));
return internal_decoder;
}
}
std::unique_ptr<webrtc::VideoDecoder> internal_decoder(
internal_decoder_factory_->CreateVideoDecoderWithParams(codec, params));
return internal_decoder;
}
std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override {
// This is not implemented for the legacy decoder factory.
RTC_NOTREACHED();
return std::vector<webrtc::SdpVideoFormat>();
}
private:
const std::unique_ptr<WebRtcVideoDecoderFactory> internal_decoder_factory_;
const std::unique_ptr<WebRtcVideoDecoderFactory> external_decoder_factory_;
};
} // namespace
std::unique_ptr<webrtc::VideoEncoderFactory> ConvertVideoEncoderFactory(
std::unique_ptr<WebRtcVideoEncoderFactory> external_encoder_factory) {
return std::unique_ptr<webrtc::VideoEncoderFactory>(
new EncoderAdapter(std::move(external_encoder_factory)));
}
std::unique_ptr<webrtc::VideoDecoderFactory> ConvertVideoDecoderFactory(
std::unique_ptr<WebRtcVideoDecoderFactory> external_decoder_factory) {
return std::unique_ptr<webrtc::VideoDecoderFactory>(
new DecoderAdapter(std::move(external_decoder_factory)));
}
} // namespace cricket

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MEDIA_ENGINE_CONVERT_LEGACY_VIDEO_FACTORY_H_
#define MEDIA_ENGINE_CONVERT_LEGACY_VIDEO_FACTORY_H_
#include <memory>
namespace webrtc {
class VideoEncoderFactory;
class VideoDecoderFactory;
} // namespace webrtc
namespace cricket {
class WebRtcVideoEncoderFactory;
class WebRtcVideoDecoderFactory;
// Adds internal SW codecs, simulcast, SW fallback wrappers, and converts to the
// new type of codec factories. The purpose of these functions is to provide an
// easy way for clients to migrate to the API with new factory types.
// TODO(magjed): Remove once old factories are gone, webrtc:7925.
std::unique_ptr<webrtc::VideoEncoderFactory> ConvertVideoEncoderFactory(
std::unique_ptr<WebRtcVideoEncoderFactory> external_encoder_factory);
std::unique_ptr<webrtc::VideoDecoderFactory> ConvertVideoDecoderFactory(
std::unique_ptr<WebRtcVideoDecoderFactory> external_decoder_factory);
} // namespace cricket
#endif // MEDIA_ENGINE_CONVERT_LEGACY_VIDEO_FACTORY_H_

View File

@ -12,6 +12,8 @@
namespace cricket {
VideoDecoderParams::VideoDecoderParams() = default;
webrtc::VideoDecoder* WebRtcVideoDecoderFactory::CreateVideoDecoderWithParams(
const VideoCodec& codec,
VideoDecoderParams params) {

View File

@ -22,6 +22,7 @@ class VideoDecoder;
namespace cricket {
struct VideoDecoderParams {
VideoDecoderParams();
std::string receive_stream_id;
};

View File

@ -25,16 +25,9 @@
#include "call/call.h"
#include "common_video/h264/profile_level_id.h"
#include "media/engine/constants.h"
#include "media/engine/internaldecoderfactory.h"
#include "media/engine/internalencoderfactory.h"
#include "media/engine/scopedvideodecoder.h"
#include "media/engine/scopedvideoencoder.h"
#include "media/engine/convert_legacy_video_factory.h"
#include "media/engine/simulcast.h"
#include "media/engine/simulcast_encoder_adapter.h"
#include "media/engine/videodecodersoftwarefallbackwrapper.h"
#include "media/engine/videoencodersoftwarefallbackwrapper.h"
#include "media/engine/webrtcmediaengine.h"
#include "media/engine/webrtcvideoencoderfactory.h"
#include "media/engine/webrtcvoiceengine.h"
#include "rtc_base/copyonwritebuffer.h"
#include "rtc_base/logging.h"
@ -42,141 +35,103 @@
#include "rtc_base/timeutils.h"
#include "rtc_base/trace_event.h"
#include "system_wrappers/include/field_trial.h"
#include "vp8_encoder_simulcast_proxy.h"
using DegradationPreference = webrtc::VideoSendStream::DegradationPreference;
namespace cricket {
// This class represents all encoders, i.e. both internal and external. It
// serves as a temporary adapter between WebRtcVideoEncoderFactory* and the new
// factory interface that is being developed.
// TODO(magjed): Remove once WebRtcVideoEncoderFactory* is deprecated and
// Hack in order to pass in |receive_stream_id| to legacy clients.
// TODO(magjed): Remove once WebRtcVideoDecoderFactory is deprecated and
// webrtc:7925 is fixed.
class EncoderFactoryAdapter {
public:
struct AllocatedEncoder {
AllocatedEncoder() = default;
AllocatedEncoder(std::unique_ptr<webrtc::VideoEncoder> encoder,
bool is_hardware_accelerated,
bool has_internal_source);
std::unique_ptr<webrtc::VideoEncoder> encoder;
bool is_hardware_accelerated;
bool has_internal_source;
};
virtual ~EncoderFactoryAdapter() {}
virtual AllocatedEncoder CreateVideoEncoder(
const VideoCodec& codec) const = 0;
virtual std::vector<VideoCodec> GetSupportedCodecs() const = 0;
};
class DecoderFactoryAdapter {
public:
virtual ~DecoderFactoryAdapter() {}
explicit DecoderFactoryAdapter(
std::unique_ptr<WebRtcVideoDecoderFactory> external_video_decoder_factory)
: cricket_decoder_with_params_(new CricketDecoderWithParams(
std::move(external_video_decoder_factory))),
decoder_factory_(ConvertVideoDecoderFactory(
std::unique_ptr<WebRtcVideoDecoderFactory>(
cricket_decoder_with_params_))) {}
virtual std::unique_ptr<webrtc::VideoDecoder> CreateVideoDecoder(
const VideoCodec& codec,
const VideoDecoderParams& decoder_params) const = 0;
explicit DecoderFactoryAdapter(
std::unique_ptr<webrtc::VideoDecoderFactory> video_decoder_factory)
: cricket_decoder_with_params_(nullptr),
decoder_factory_(std::move(video_decoder_factory)) {}
void SetReceiveStreamId(const std::string& receive_stream_id) {
if (cricket_decoder_with_params_)
cricket_decoder_with_params_->SetReceiveStreamId(receive_stream_id);
}
std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const {
return decoder_factory_->GetSupportedFormats();
}
std::unique_ptr<webrtc::VideoDecoder> CreateVideoDecoder(
const webrtc::SdpVideoFormat& format) {
return decoder_factory_->CreateVideoDecoder(format);
}
private:
// WebRtcVideoDecoderFactory implementation that allows to override
// |receive_stream_id|.
class CricketDecoderWithParams : public WebRtcVideoDecoderFactory {
public:
explicit CricketDecoderWithParams(
std::unique_ptr<WebRtcVideoDecoderFactory> external_decoder_factory)
: external_decoder_factory_(std::move(external_decoder_factory)) {}
void SetReceiveStreamId(const std::string& receive_stream_id) {
receive_stream_id_ = receive_stream_id;
}
private:
webrtc::VideoDecoder* CreateVideoDecoderWithParams(
const VideoCodec& codec,
VideoDecoderParams params) override {
if (!external_decoder_factory_)
return nullptr;
params.receive_stream_id = receive_stream_id_;
return external_decoder_factory_->CreateVideoDecoderWithParams(codec,
params);
}
webrtc::VideoDecoder* CreateVideoDecoderWithParams(
webrtc::VideoCodecType type,
VideoDecoderParams params) override {
RTC_NOTREACHED();
return nullptr;
}
void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) override {
if (external_decoder_factory_) {
external_decoder_factory_->DestroyVideoDecoder(decoder);
} else {
delete decoder;
}
}
const std::unique_ptr<WebRtcVideoDecoderFactory> external_decoder_factory_;
std::string receive_stream_id_;
};
// If |cricket_decoder_with_params_| is non-null, it's owned by
// |decoder_factory_|.
CricketDecoderWithParams* const cricket_decoder_with_params_;
std::unique_ptr<webrtc::VideoDecoderFactory> decoder_factory_;
};
namespace {
std::vector<VideoCodec> AssignPayloadTypesAndAddAssociatedRtxCodecs(
const std::vector<VideoCodec>& input_codecs);
const std::vector<webrtc::SdpVideoFormat>& input_formats);
// Wraps cricket::WebRtcVideoEncoderFactory into common EncoderFactoryAdapter
// interface.
// TODO(magjed): Remove once WebRtcVideoEncoderFactory is deprecated and
// webrtc:7925 is fixed.
class CricketEncoderFactoryAdapter : public EncoderFactoryAdapter {
public:
explicit CricketEncoderFactoryAdapter(
std::unique_ptr<WebRtcVideoEncoderFactory> external_encoder_factory)
: internal_encoder_factory_(new InternalEncoderFactory()),
external_encoder_factory_(std::move(external_encoder_factory)) {}
private:
AllocatedEncoder CreateVideoEncoder(const VideoCodec& codec) const override;
std::vector<VideoCodec> GetSupportedCodecs() const override;
const std::unique_ptr<WebRtcVideoEncoderFactory> internal_encoder_factory_;
const std::unique_ptr<WebRtcVideoEncoderFactory> external_encoder_factory_;
};
class CricketDecoderFactoryAdapter : public DecoderFactoryAdapter {
public:
explicit CricketDecoderFactoryAdapter(
std::unique_ptr<WebRtcVideoDecoderFactory> external_decoder_factory)
: internal_decoder_factory_(new InternalDecoderFactory()),
external_decoder_factory_(std::move(external_decoder_factory)) {}
private:
std::unique_ptr<webrtc::VideoDecoder> CreateVideoDecoder(
const VideoCodec& codec,
const VideoDecoderParams& decoder_params) const override;
const std::unique_ptr<WebRtcVideoDecoderFactory> internal_decoder_factory_;
const std::unique_ptr<WebRtcVideoDecoderFactory> external_decoder_factory_;
};
// Wraps webrtc::VideoEncoderFactory into common EncoderFactoryAdapter
// interface.
class WebRtcEncoderFactoryAdapter : public EncoderFactoryAdapter {
public:
explicit WebRtcEncoderFactoryAdapter(
std::unique_ptr<webrtc::VideoEncoderFactory> encoder_factory)
: encoder_factory_(std::move(encoder_factory)) {}
private:
AllocatedEncoder CreateVideoEncoder(const VideoCodec& codec) const override {
if (!encoder_factory_)
return AllocatedEncoder();
const webrtc::SdpVideoFormat format(codec.name, codec.params);
const webrtc::VideoEncoderFactory::CodecInfo info =
encoder_factory_->QueryVideoEncoder(format);
return AllocatedEncoder(encoder_factory_->CreateVideoEncoder(format),
info.is_hardware_accelerated,
info.has_internal_source);
}
std::vector<VideoCodec> GetSupportedCodecs() const override {
if (!encoder_factory_)
return std::vector<VideoCodec>();
std::vector<VideoCodec> codecs;
for (const webrtc::SdpVideoFormat& format :
encoder_factory_->GetSupportedFormats()) {
codecs.push_back(VideoCodec(format));
}
return AssignPayloadTypesAndAddAssociatedRtxCodecs(codecs);
}
std::unique_ptr<webrtc::VideoEncoderFactory> encoder_factory_;
};
// Wraps webrtc::VideoDecoderFactory into common DecoderFactoryAdapter
// interface.
class WebRtcDecoderFactoryAdapter : public DecoderFactoryAdapter {
public:
explicit WebRtcDecoderFactoryAdapter(
std::unique_ptr<webrtc::VideoDecoderFactory> decoder_factory)
: decoder_factory_(std::move(decoder_factory)) {}
private:
std::unique_ptr<webrtc::VideoDecoder> CreateVideoDecoder(
const VideoCodec& codec,
const VideoDecoderParams& decoder_params) const override {
return decoder_factory_
? decoder_factory_->CreateVideoDecoder(
webrtc::SdpVideoFormat(codec.name, codec.params))
: nullptr;
}
std::unique_ptr<webrtc::VideoDecoderFactory> decoder_factory_;
};
std::vector<VideoCodec> AssignPayloadTypesAndAddAssociatedRtxCodecs(
const webrtc::VideoEncoderFactory* encoder_factory) {
return encoder_factory ? AssignPayloadTypesAndAddAssociatedRtxCodecs(
encoder_factory->GetSupportedFormats())
: std::vector<VideoCodec>();
}
// If this field trial is enabled, we will enable sending FlexFEC and disable
// sending ULPFEC whenever the former has been negotiated in the SDPs.
@ -448,9 +403,9 @@ void DefaultUnsignalledSsrcHandler::SetDefaultSink(
WebRtcVideoEngine::WebRtcVideoEngine(
std::unique_ptr<WebRtcVideoEncoderFactory> external_video_encoder_factory,
std::unique_ptr<WebRtcVideoDecoderFactory> external_video_decoder_factory)
: decoder_factory_(new CricketDecoderFactoryAdapter(
std::move(external_video_decoder_factory))),
encoder_factory_(new CricketEncoderFactoryAdapter(
: decoder_factory_(
new DecoderFactoryAdapter(std::move(external_video_decoder_factory))),
encoder_factory_(ConvertVideoEncoderFactory(
std::move(external_video_encoder_factory))) {
LOG(LS_INFO) << "WebRtcVideoEngine::WebRtcVideoEngine()";
}
@ -459,9 +414,8 @@ WebRtcVideoEngine::WebRtcVideoEngine(
std::unique_ptr<webrtc::VideoEncoderFactory> video_encoder_factory,
std::unique_ptr<webrtc::VideoDecoderFactory> video_decoder_factory)
: decoder_factory_(
new WebRtcDecoderFactoryAdapter(std::move(video_decoder_factory))),
encoder_factory_(
new WebRtcEncoderFactoryAdapter(std::move(video_encoder_factory))) {
new DecoderFactoryAdapter(std::move(video_decoder_factory))),
encoder_factory_(std::move(video_encoder_factory)) {
LOG(LS_INFO) << "WebRtcVideoEngine::WebRtcVideoEngine()";
}
@ -479,7 +433,7 @@ WebRtcVideoChannel* WebRtcVideoEngine::CreateChannel(
}
std::vector<VideoCodec> WebRtcVideoEngine::codecs() const {
return encoder_factory_->GetSupportedCodecs();
return AssignPayloadTypesAndAddAssociatedRtxCodecs(encoder_factory_.get());
}
RtpCapabilities WebRtcVideoEngine::GetCapabilities() const {
@ -514,12 +468,13 @@ namespace {
// (VP8, VP9, H264, and RED). It will also add default feedback params to the
// codecs.
std::vector<VideoCodec> AssignPayloadTypesAndAddAssociatedRtxCodecs(
const std::vector<VideoCodec>& input_codecs) {
const std::vector<webrtc::SdpVideoFormat>& input_formats) {
static const int kFirstDynamicPayloadType = 96;
static const int kLastDynamicPayloadType = 127;
int payload_type = kFirstDynamicPayloadType;
std::vector<VideoCodec> output_codecs;
for (VideoCodec codec : input_codecs) {
for (const webrtc::SdpVideoFormat& format : input_formats) {
VideoCodec codec(format);
codec.id = payload_type;
AddDefaultFeedbackParams(&codec);
output_codecs.push_back(codec);
@ -549,34 +504,12 @@ std::vector<VideoCodec> AssignPayloadTypesAndAddAssociatedRtxCodecs(
}
} // namespace
std::vector<VideoCodec> CricketEncoderFactoryAdapter::GetSupportedCodecs()
const {
std::vector<VideoCodec> codecs = InternalEncoderFactory().supported_codecs();
LOG(LS_INFO) << "Internally supported codecs: "
<< CodecVectorToString(codecs);
// Add external codecs.
if (external_encoder_factory_ != nullptr) {
const std::vector<VideoCodec>& external_codecs =
external_encoder_factory_->supported_codecs();
for (const VideoCodec& codec : external_codecs) {
// Don't add same codec twice.
if (!FindMatchingCodec(codecs, codec))
codecs.push_back(codec);
}
LOG(LS_INFO) << "Codecs supported by the external encoder factory: "
<< CodecVectorToString(external_codecs);
}
return AssignPayloadTypesAndAddAssociatedRtxCodecs(codecs);
}
WebRtcVideoChannel::WebRtcVideoChannel(
webrtc::Call* call,
const MediaConfig& config,
const VideoOptions& options,
const EncoderFactoryAdapter* encoder_factory,
const DecoderFactoryAdapter* decoder_factory)
webrtc::VideoEncoderFactory* encoder_factory,
DecoderFactoryAdapter* decoder_factory)
: VideoMediaChannel(config),
call_(call),
unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_),
@ -589,7 +522,8 @@ WebRtcVideoChannel::WebRtcVideoChannel(
rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc;
sending_ = false;
recv_codecs_ = MapCodecs(encoder_factory_->GetSupportedCodecs());
recv_codecs_ =
MapCodecs(AssignPayloadTypesAndAddAssociatedRtxCodecs(encoder_factory_));
recv_flexfec_payload_type_ = recv_codecs_.front().flexfec_payload_type;
}
@ -604,7 +538,7 @@ rtc::Optional<WebRtcVideoChannel::VideoCodecSettings>
WebRtcVideoChannel::SelectSendVideoCodec(
const std::vector<VideoCodecSettings>& remote_mapped_codecs) const {
const std::vector<VideoCodec> local_supported_codecs =
encoder_factory_->GetSupportedCodecs();
AssignPayloadTypesAndAddAssociatedRtxCodecs(encoder_factory_);
// Select the first remote codec that is supported locally.
for (const VideoCodecSettings& remote_mapped_codec : remote_mapped_codecs) {
// For H264, we will limit the encode level to the remote offered level
@ -916,7 +850,7 @@ bool WebRtcVideoChannel::GetChangedRecvParameters(
// Verify that every mapped codec is supported locally.
const std::vector<VideoCodec> local_supported_codecs =
encoder_factory_->GetSupportedCodecs();
AssignPayloadTypesAndAddAssociatedRtxCodecs(encoder_factory_);
for (const VideoCodecSettings& mapped_codec : mapped_codecs) {
if (!FindMatchingCodec(local_supported_codecs, mapped_codec.codec)) {
LOG(LS_ERROR) << "SetRecvParameters called with unsupported video codec: "
@ -1524,20 +1458,12 @@ WebRtcVideoChannel::WebRtcVideoSendStream::VideoSendStreamParameters::
conference_mode(false),
codec_settings(codec_settings) {}
EncoderFactoryAdapter::AllocatedEncoder::AllocatedEncoder(
std::unique_ptr<webrtc::VideoEncoder> encoder,
bool is_hardware_accelerated,
bool has_internal_source)
: encoder(std::move(encoder)),
is_hardware_accelerated(is_hardware_accelerated),
has_internal_source(has_internal_source) {}
WebRtcVideoChannel::WebRtcVideoSendStream::WebRtcVideoSendStream(
webrtc::Call* call,
const StreamParams& sp,
webrtc::VideoSendStream::Config config,
const VideoOptions& options,
const EncoderFactoryAdapter* encoder_factory,
webrtc::VideoEncoderFactory* encoder_factory,
bool enable_cpu_overuse_detection,
int max_bitrate_bps,
const rtc::Optional<VideoCodecSettings>& codec_settings,
@ -1685,57 +1611,6 @@ WebRtcVideoChannel::WebRtcVideoSendStream::GetSsrcs() const {
return ssrcs_;
}
EncoderFactoryAdapter::AllocatedEncoder
CricketEncoderFactoryAdapter::CreateVideoEncoder(
const VideoCodec& codec) const {
// Try creating external encoder.
if (external_encoder_factory_ != nullptr &&
FindMatchingCodec(external_encoder_factory_->supported_codecs(), codec)) {
std::unique_ptr<webrtc::VideoEncoder> external_encoder;
if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) {
// If it's a codec type we can simulcast, create a wrapped encoder.
external_encoder = std::unique_ptr<webrtc::VideoEncoder>(
new webrtc::SimulcastEncoderAdapter(external_encoder_factory_.get()));
} else {
external_encoder =
CreateScopedVideoEncoder(external_encoder_factory_.get(), codec);
}
if (external_encoder) {
std::unique_ptr<webrtc::VideoEncoder> internal_encoder(
new webrtc::VideoEncoderSoftwareFallbackWrapper(
codec, std::move(external_encoder)));
const webrtc::VideoCodecType codec_type =
webrtc::PayloadStringToCodecType(codec.name);
const bool has_internal_source =
external_encoder_factory_->EncoderTypeHasInternalSource(codec_type);
return AllocatedEncoder(std::move(internal_encoder),
true /* is_hardware_accelerated */,
has_internal_source);
}
}
// Try creating internal encoder.
std::unique_ptr<webrtc::VideoEncoder> internal_encoder;
if (FindMatchingCodec(internal_encoder_factory_->supported_codecs(), codec)) {
if (CodecNamesEq(codec.name.c_str(), kVp8CodecName)) {
internal_encoder = std::unique_ptr<webrtc::VideoEncoder>(
new webrtc::VP8EncoderSimulcastProxy(
internal_encoder_factory_.get()));
} else {
internal_encoder = std::unique_ptr<webrtc::VideoEncoder>(
internal_encoder_factory_->CreateVideoEncoder(codec));
}
return AllocatedEncoder(std::move(internal_encoder),
false /* is_hardware_accelerated */,
false /* has_internal_source */);
}
// This shouldn't happen, we should not be trying to create something we don't
// support.
RTC_NOTREACHED();
return AllocatedEncoder();
}
void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec(
const VideoCodecSettings& codec_settings,
bool force_encoder_allocation) {
@ -1749,15 +1624,18 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec(
std::unique_ptr<webrtc::VideoEncoder> new_encoder;
if (force_encoder_allocation || !allocated_encoder_ ||
allocated_codec_ != codec_settings.codec) {
EncoderFactoryAdapter::AllocatedEncoder new_allocated_encoder =
encoder_factory_->CreateVideoEncoder(codec_settings.codec);
new_encoder = std::unique_ptr<webrtc::VideoEncoder>(
std::move(new_allocated_encoder.encoder));
const webrtc::SdpVideoFormat format(codec_settings.codec.name,
codec_settings.codec.params);
new_encoder = encoder_factory_->CreateVideoEncoder(format);
parameters_.config.encoder_settings.encoder = new_encoder.get();
const webrtc::VideoEncoderFactory::CodecInfo info =
encoder_factory_->QueryVideoEncoder(format);
parameters_.config.encoder_settings.full_overuse_time =
new_allocated_encoder.is_hardware_accelerated;
info.is_hardware_accelerated;
parameters_.config.encoder_settings.internal_source =
new_allocated_encoder.has_internal_source;
info.has_internal_source;
} else {
new_encoder = std::move(allocated_encoder_);
}
@ -2131,7 +2009,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)
@ -2182,30 +2060,6 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::GetFirstPrimarySsrc() const {
}
}
std::unique_ptr<webrtc::VideoDecoder>
CricketDecoderFactoryAdapter::CreateVideoDecoder(
const VideoCodec& codec,
const VideoDecoderParams& decoder_params) const {
if (external_decoder_factory_ != nullptr) {
std::unique_ptr<webrtc::VideoDecoder> external_decoder =
CreateScopedVideoDecoder(external_decoder_factory_.get(), codec,
decoder_params);
if (external_decoder) {
webrtc::VideoCodecType type =
webrtc::PayloadStringToCodecType(codec.name);
std::unique_ptr<webrtc::VideoDecoder> internal_decoder(
new webrtc::VideoDecoderSoftwareFallbackWrapper(
type, std::move(external_decoder)));
return internal_decoder;
}
}
std::unique_ptr<webrtc::VideoDecoder> internal_decoder(
internal_decoder_factory_->CreateVideoDecoderWithParams(codec,
decoder_params));
return internal_decoder;
}
void WebRtcVideoChannel::WebRtcVideoReceiveStream::ConfigureCodecs(
const std::vector<VideoCodecSettings>& recv_codecs,
DecoderMap* old_decoders) {
@ -2224,9 +2078,10 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::ConfigureCodecs(
old_decoders->erase(it);
}
if (!new_decoder) {
new_decoder = decoder_factory_->CreateVideoDecoder(recv_codec.codec,
{stream_params_.id});
if (!new_decoder && decoder_factory_) {
decoder_factory_->SetReceiveStreamId(stream_params_.id);
new_decoder = decoder_factory_->CreateVideoDecoder(webrtc::SdpVideoFormat(
recv_codec.codec.name, recv_codec.codec.params));
}
webrtc::VideoReceiveStream::Decoder decoder;

View File

@ -51,7 +51,6 @@ class Thread;
namespace cricket {
class DecoderFactoryAdapter;
class EncoderFactoryAdapter;
class VideoCapturer;
class VideoProcessor;
class VideoRenderer;
@ -122,7 +121,7 @@ class WebRtcVideoEngine {
private:
const std::unique_ptr<DecoderFactoryAdapter> decoder_factory_;
const std::unique_ptr<EncoderFactoryAdapter> encoder_factory_;
const std::unique_ptr<webrtc::VideoEncoderFactory> encoder_factory_;
};
class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
@ -130,8 +129,8 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
WebRtcVideoChannel(webrtc::Call* call,
const MediaConfig& config,
const VideoOptions& options,
const EncoderFactoryAdapter* encoder_factory,
const DecoderFactoryAdapter* decoder_factory);
webrtc::VideoEncoderFactory* encoder_factory,
DecoderFactoryAdapter* decoder_factory);
~WebRtcVideoChannel() override;
// VideoMediaChannel implementation
@ -259,7 +258,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
const StreamParams& sp,
webrtc::VideoSendStream::Config config,
const VideoOptions& options,
const EncoderFactoryAdapter* encoder_factory,
webrtc::VideoEncoderFactory* encoder_factory,
bool enable_cpu_overuse_detection,
int max_bitrate_bps,
const rtc::Optional<VideoCodecSettings>& codec_settings,
@ -337,7 +336,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
const bool enable_cpu_overuse_detection_;
rtc::VideoSourceInterface<webrtc::VideoFrame>* source_
RTC_ACCESS_ON(&thread_checker_);
const EncoderFactoryAdapter* const encoder_factory_
webrtc::VideoEncoderFactory* const encoder_factory_
RTC_ACCESS_ON(&thread_checker_);
webrtc::VideoSendStream* stream_ RTC_ACCESS_ON(&thread_checker_);
@ -369,7 +368,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
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);
@ -430,7 +429,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
webrtc::FlexfecReceiveStream::Config flexfec_config_;
webrtc::FlexfecReceiveStream* flexfec_stream_;
const DecoderFactoryAdapter* decoder_factory_;
DecoderFactoryAdapter* decoder_factory_;
DecoderMap allocated_decoders_;
rtc::CriticalSection sink_lock_;
@ -494,8 +493,8 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
rtc::Optional<VideoCodecSettings> send_codec_;
rtc::Optional<std::vector<webrtc::RtpExtension>> send_rtp_extensions_;
const EncoderFactoryAdapter* const encoder_factory_;
const DecoderFactoryAdapter* const decoder_factory_;
webrtc::VideoEncoderFactory* const encoder_factory_;
DecoderFactoryAdapter* const decoder_factory_;
std::vector<VideoCodecSettings> recv_codecs_;
std::vector<webrtc::RtpExtension> recv_rtp_extensions_;
// See reason for keeping track of the FlexFEC payload type separately in