Commit 17713f13 authored by Hirokazu Honda's avatar Hirokazu Honda Committed by Commit Bot

Revert "WebRTC: Migrate completely to new video codec factories API"

This reverts commit c47b4d11.

BUG=chromium:791131
TEST=video_ChromeRTCHWDecodeUsed on peach_pit
Reason for revert: This CL breaks video_ChromeRTCHWDecodeUsed

Original change's description:
> WebRTC: Migrate completely to new video codec factories API
> 
> This CL makes the Chromium HW video factories implement the new
> interfaces directly. It also adds SW codecs, simulcast, and SW fallback
> codecs manually, instead of relying on WebRTC to do this. This will
> give Chromium more flexibility in the future, and will allow us to
> simplify the WebRTC code, since it's only Chromium that uses some of
> these features.
> 
> Bug: webrtc:7925
> Change-Id: I2bbd8b9a8c52bfe963d601f34188faf47d59e67e
> Reviewed-on: https://chromium-review.googlesource.com/788410
> Reviewed-by: Kentaro Hara <haraken@chromium.org>
> Reviewed-by: Emircan Uysaler <emircan@chromium.org>
> Commit-Queue: Magnus Jedvert <magjed@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#520062}

TBR=haraken@chromium.org,emircan@chromium.org,magjed@chromium.org

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: webrtc:7925
Change-Id: I081f9f5d961707924fe6eed4a97ead9c9f5ed12c
Reviewed-on: https://chromium-review.googlesource.com/810429Reviewed-by: default avatarPawel Osciak <posciak@chromium.org>
Commit-Queue: Pawel Osciak <posciak@chromium.org>
Cr-Commit-Position: refs/heads/master@{#522056}
parent 3f2dd6b5
......@@ -820,8 +820,6 @@ target(link_target_type, "renderer") {
"media/webrtc/track_observer.cc",
"media/webrtc/track_observer.h",
"media/webrtc/two_keys_adapter_map.h",
"media/webrtc/video_codec_factory.cc",
"media/webrtc/video_codec_factory.h",
"media/webrtc/webrtc_audio_sink.cc",
"media/webrtc/webrtc_audio_sink.h",
"media/webrtc/webrtc_media_stream_adapter.cc",
......
......@@ -133,6 +133,12 @@ std::unique_ptr<RTCVideoDecoder> RTCVideoDecoder::Create(
return decoder;
}
// static
void RTCVideoDecoder::Destroy(webrtc::VideoDecoder* decoder,
media::GpuVideoAcceleratorFactories* factories) {
factories->GetTaskRunner()->DeleteSoon(FROM_HERE, decoder);
}
int32_t RTCVideoDecoder::InitDecode(const webrtc::VideoCodec* codecSettings,
int32_t /*numberOfCores*/) {
DVLOG(2) << "InitDecode";
......@@ -271,10 +277,6 @@ int32_t RTCVideoDecoder::RegisterDecodeCompleteCallback(
return WEBRTC_VIDEO_CODEC_OK;
}
const char* RTCVideoDecoder::ImplementationName() const {
return "RTCVideoDecoder";
}
int32_t RTCVideoDecoder::Release() {
DVLOG(2) << "Release";
// Do not destroy VDA because WebRTC can call InitDecode and start decoding
......
......@@ -85,8 +85,6 @@ class CONTENT_EXPORT RTCVideoDecoder
// this runs.
int32_t Release() override;
const char* ImplementationName() const override;
// VideoDecodeAccelerator::Client implementation.
void ProvidePictureBuffers(uint32_t count,
media::VideoPixelFormat format,
......
......@@ -6,89 +6,31 @@
#include <memory>
#include "base/memory/ptr_util.h"
#include "content/renderer/media/gpu/rtc_video_decoder.h"
#include "media/video/gpu_video_accelerator_factories.h"
#include "third_party/webrtc/api/video_codecs/sdp_video_format.h"
namespace content {
namespace {
// This extra indirection is needed so that we can delete the decoder on the
// correct thread.
class ScopedVideoDecoder : public webrtc::VideoDecoder {
public:
ScopedVideoDecoder(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
std::unique_ptr<webrtc::VideoDecoder> decoder)
: task_runner_(task_runner), decoder_(std::move(decoder)) {}
int32_t InitDecode(const webrtc::VideoCodec* codec_settings,
int32_t number_of_cores) override {
return decoder_->InitDecode(codec_settings, number_of_cores);
}
int32_t RegisterDecodeCompleteCallback(
webrtc::DecodedImageCallback* callback) override {
return decoder_->RegisterDecodeCompleteCallback(callback);
}
int32_t Release() override { return decoder_->Release(); }
int32_t Decode(const webrtc::EncodedImage& input_image,
bool missing_frames,
const webrtc::RTPFragmentationHeader* fragmentation,
const webrtc::CodecSpecificInfo* codec_specific_info,
int64_t render_time_ms) override {
return decoder_->Decode(input_image, missing_frames, fragmentation,
codec_specific_info, render_time_ms);
}
bool PrefersLateDecoding() const override {
return decoder_->PrefersLateDecoding();
}
const char* ImplementationName() const override {
return decoder_->ImplementationName();
}
// Runs on Chrome_libJingle_WorkerThread. The child thread is blocked while
// this runs.
~ScopedVideoDecoder() override {
task_runner_->DeleteSoon(FROM_HERE, decoder_.release());
}
private:
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
std::unique_ptr<webrtc::VideoDecoder> decoder_;
};
} // namespace
RTCVideoDecoderFactory::RTCVideoDecoderFactory(
media::GpuVideoAcceleratorFactories* gpu_factories)
: gpu_factories_(gpu_factories) {
DVLOG(2) << __func__;
}
std::vector<webrtc::SdpVideoFormat>
RTCVideoDecoderFactory::GetSupportedFormats() const {
// TODO(magjed): Implement this based on
// gpu_factories_->GetVideoDecodeAcceleratorSupportedProfiles(). This function
// is currently unused by WebRTC.
return std::vector<webrtc::SdpVideoFormat>();
RTCVideoDecoderFactory::~RTCVideoDecoderFactory() {
DVLOG(2) << __func__;
}
RTCVideoDecoderFactory::~RTCVideoDecoderFactory() {
webrtc::VideoDecoder* RTCVideoDecoderFactory::CreateVideoDecoder(
webrtc::VideoCodecType type) {
DVLOG(2) << __func__;
return RTCVideoDecoder::Create(type, gpu_factories_).release();
}
std::unique_ptr<webrtc::VideoDecoder>
RTCVideoDecoderFactory::CreateVideoDecoder(
const webrtc::SdpVideoFormat& format) {
void RTCVideoDecoderFactory::DestroyVideoDecoder(
webrtc::VideoDecoder* decoder) {
DVLOG(2) << __func__;
std::unique_ptr<webrtc::VideoDecoder> decoder = RTCVideoDecoder::Create(
webrtc::PayloadStringToCodecType(format.name), gpu_factories_);
// Make sure the decoder is destructed on the correct thread.
return decoder ? base::MakeUnique<ScopedVideoDecoder>(
gpu_factories_->GetTaskRunner(), std::move(decoder))
: nullptr;
RTCVideoDecoder::Destroy(decoder, gpu_factories_);
}
} // namespace content
......@@ -8,7 +8,7 @@
#include "base/macros.h"
#include "base/threading/thread.h"
#include "content/common/content_export.h"
#include "third_party/webrtc/api/video_codecs/video_decoder_factory.h"
#include "third_party/webrtc/media/engine/webrtcvideodecoderfactory.h"
#include "third_party/webrtc/modules/video_coding/include/video_codec_interface.h"
namespace webrtc {
......@@ -23,7 +23,7 @@ namespace content {
// TODO(wuchengli): add unittest.
class CONTENT_EXPORT RTCVideoDecoderFactory
: public webrtc::VideoDecoderFactory {
: public cricket::WebRtcVideoDecoderFactory {
public:
explicit RTCVideoDecoderFactory(
media::GpuVideoAcceleratorFactories* gpu_factories);
......@@ -31,10 +31,12 @@ class CONTENT_EXPORT RTCVideoDecoderFactory
// Runs on Chrome_libJingle_WorkerThread. The child thread is blocked while
// this runs.
std::unique_ptr<webrtc::VideoDecoder> CreateVideoDecoder(
const webrtc::SdpVideoFormat& format) override;
webrtc::VideoDecoder* CreateVideoDecoder(
webrtc::VideoCodecType type) override;
std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override;
// Runs on Chrome_libJingle_WorkerThread. The child thread is blocked while
// this runs.
void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) override;
private:
media::GpuVideoAcceleratorFactories* gpu_factories_;
......
......@@ -941,8 +941,4 @@ bool RTCVideoEncoder::SupportsNativeHandle() const {
return true;
}
const char* RTCVideoEncoder::ImplementationName() const {
return "RTCVideoEncoder";
}
} // namespace content
......@@ -59,7 +59,6 @@ class CONTENT_EXPORT RTCVideoEncoder : public webrtc::VideoEncoder {
int32_t SetChannelParameters(uint32_t packet_loss, int64_t rtt) override;
int32_t SetRates(uint32_t new_bit_rate, uint32_t frame_rate) override;
bool SupportsNativeHandle() const override;
const char* ImplementationName() const override;
private:
class Impl;
......
......@@ -11,24 +11,23 @@
#include "content/renderer/media/gpu/rtc_video_encoder.h"
#include "media/gpu/ipc/client/gpu_video_encode_accelerator_host.h"
#include "media/video/gpu_video_accelerator_factories.h"
#include "third_party/webrtc/api/video_codecs/sdp_video_format.h"
#include "third_party/webrtc/common_video/h264/profile_level_id.h"
#include "third_party/webrtc/media/base/codec.h"
namespace content {
namespace {
// Translate from media::VideoEncodeAccelerator::SupportedProfile to
// webrtc::SdpVideoFormat, or return nothing if the profile isn't supported.
base::Optional<webrtc::SdpVideoFormat> VEAToWebRTCFormat(
// cricket::WebRtcVideoEncoderFactory::VideoCodec, or return nothing if the
// profile isn't supported.
base::Optional<cricket::VideoCodec> VEAToWebRTCCodec(
const media::VideoEncodeAccelerator::SupportedProfile& profile) {
DCHECK_EQ(profile.max_framerate_denominator, 1U);
if (profile.profile >= media::VP8PROFILE_MIN &&
profile.profile <= media::VP8PROFILE_MAX) {
if (base::FeatureList::IsEnabled(features::kWebRtcHWVP8Encoding)) {
return webrtc::SdpVideoFormat("VP8");
return base::Optional<cricket::VideoCodec>(cricket::VideoCodec("VP8"));
}
} else if (profile.profile >= media::H264PROFILE_MIN &&
profile.profile <= media::H264PROFILE_MAX) {
......@@ -55,7 +54,7 @@ base::Optional<webrtc::SdpVideoFormat> VEAToWebRTCFormat(
break;
default:
// Unsupported H264 profile in WebRTC.
return base::nullopt;
return base::Optional<cricket::VideoCodec>();
}
const int width = profile.max_resolution.width();
......@@ -68,22 +67,15 @@ base::Optional<webrtc::SdpVideoFormat> VEAToWebRTCFormat(
const webrtc::H264::ProfileLevelId profile_level_id(
h264_profile, h264_level.value_or(webrtc::H264::kLevel1));
webrtc::SdpVideoFormat format("H264");
format.parameters = {
{cricket::kH264FmtpProfileLevelId,
*webrtc::H264::ProfileLevelIdToString(profile_level_id)},
{cricket::kH264FmtpLevelAsymmetryAllowed, "1"},
{cricket::kH264FmtpPacketizationMode, "1"}};
return format;
cricket::VideoCodec codec("H264");
codec.SetParam(cricket::kH264FmtpProfileLevelId,
*webrtc::H264::ProfileLevelIdToString(profile_level_id));
codec.SetParam(cricket::kH264FmtpLevelAsymmetryAllowed, "1");
codec.SetParam(cricket::kH264FmtpPacketizationMode, "1");
return base::Optional<cricket::VideoCodec>(codec);
}
}
return base::nullopt;
}
bool IsSameFormat(const webrtc::SdpVideoFormat& format1,
const webrtc::SdpVideoFormat& format2) {
return cricket::IsSameCodec(format1.name, format2.parameters, format2.name,
format2.parameters);
return base::Optional<cricket::VideoCodec>();
}
} // anonymous namespace
......@@ -94,45 +86,47 @@ RTCVideoEncoderFactory::RTCVideoEncoderFactory(
const media::VideoEncodeAccelerator::SupportedProfiles& profiles =
gpu_factories_->GetVideoEncodeAcceleratorSupportedProfiles();
for (const auto& profile : profiles) {
base::Optional<webrtc::SdpVideoFormat> format = VEAToWebRTCFormat(profile);
if (format) {
supported_formats_.push_back(std::move(*format));
base::Optional<cricket::VideoCodec> codec = VEAToWebRTCCodec(profile);
if (codec) {
supported_codecs_.push_back(std::move(*codec));
profiles_.push_back(profile.profile);
}
}
// There should be a 1:1 mapping between media::VideoCodecProfile and
// webrtc::SdpVideoFormat.
CHECK_EQ(profiles_.size(), supported_formats_.size());
// cricket::VideoCodec.
CHECK_EQ(profiles_.size(), supported_codecs_.size());
}
RTCVideoEncoderFactory::~RTCVideoEncoderFactory() {}
std::unique_ptr<webrtc::VideoEncoder>
RTCVideoEncoderFactory::CreateVideoEncoder(
const webrtc::SdpVideoFormat& format) {
for (size_t i = 0; i < supported_formats_.size(); ++i) {
if (IsSameFormat(format, supported_formats_[i])) {
// There should be a 1:1 mapping between media::VideoCodecProfile and
// webrtc::SdpVideoFormat.
CHECK_EQ(profiles_.size(), supported_formats_.size());
return base::MakeUnique<RTCVideoEncoder>(profiles_[i], gpu_factories_);
webrtc::VideoEncoder* RTCVideoEncoderFactory::CreateVideoEncoder(
const cricket::VideoCodec& codec) {
for (size_t i = 0; i < supported_codecs_.size(); ++i) {
if (!cricket::CodecNamesEq(codec.name, supported_codecs_[i].name))
continue;
// Check H264 profile.
using webrtc::H264::ParseSdpProfileLevelId;
if (cricket::CodecNamesEq(codec.name.c_str(), cricket::kH264CodecName) &&
ParseSdpProfileLevelId(codec.params)->profile !=
ParseSdpProfileLevelId(supported_codecs_[i].params)->profile) {
continue;
}
// There should be a 1:1 mapping between media::VideoCodecProfile and
// cricket::VideoCodec.
CHECK_EQ(profiles_.size(), supported_codecs_.size());
return new RTCVideoEncoder(profiles_[i], gpu_factories_);
}
return nullptr;
}
std::vector<webrtc::SdpVideoFormat>
RTCVideoEncoderFactory::GetSupportedFormats() const {
return supported_formats_;
const std::vector<cricket::VideoCodec>&
RTCVideoEncoderFactory::supported_codecs() const {
return supported_codecs_;
}
webrtc::VideoEncoderFactory::CodecInfo
RTCVideoEncoderFactory::QueryVideoEncoder(
const webrtc::SdpVideoFormat& format) const {
CodecInfo info;
info.has_internal_source = false;
info.is_hardware_accelerated = true;
return info;
void RTCVideoEncoderFactory::DestroyVideoEncoder(
webrtc::VideoEncoder* encoder) {
delete encoder;
}
} // namespace content
......@@ -12,7 +12,7 @@
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "media/base/video_codecs.h"
#include "third_party/webrtc/api/video_codecs/video_encoder_factory.h"
#include "third_party/webrtc/media/engine/webrtcvideoencoderfactory.h"
namespace media {
class GpuVideoAcceleratorFactories;
......@@ -23,27 +23,26 @@ namespace content {
// This class creates RTCVideoEncoder instances (each wrapping a
// media::VideoEncodeAccelerator) on behalf of the WebRTC stack.
class CONTENT_EXPORT RTCVideoEncoderFactory
: public webrtc::VideoEncoderFactory {
: public cricket::WebRtcVideoEncoderFactory {
public:
explicit RTCVideoEncoderFactory(
media::GpuVideoAcceleratorFactories* gpu_factories);
~RTCVideoEncoderFactory() override;
// webrtc::VideoEncoderFactory implementation.
std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder(
const webrtc::SdpVideoFormat& format) override;
std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override;
webrtc::VideoEncoderFactory::CodecInfo QueryVideoEncoder(
const webrtc::SdpVideoFormat& format) const override;
// cricket::WebRtcVideoEncoderFactory implementation.
webrtc::VideoEncoder* CreateVideoEncoder(
const cricket::VideoCodec& codec) override;
const std::vector<cricket::VideoCodec>& supported_codecs() const override;
void DestroyVideoEncoder(webrtc::VideoEncoder* encoder) override;
private:
media::GpuVideoAcceleratorFactories* gpu_factories_;
// List of supported webrtc::SdpVideoFormat. |profiles_| and
// |supported_formats_| have the same length and the profile for
// |supported_formats_[i]| is |profiles_[i]|.
// List of supported cricket::WebRtcVideoEncoderFactory::VideoCodec.
// |profiles_| and |supported_codecs_| have the same length and the profile
// for |supported_codecs_[i]| is |profiles_[i]|.
std::vector<media::VideoCodecProfile> profiles_;
std::vector<webrtc::SdpVideoFormat> supported_formats_;
std::vector<cricket::VideoCodec> supported_codecs_;
DISALLOW_COPY_AND_ASSIGN(RTCVideoEncoderFactory);
};
......
......@@ -31,12 +31,13 @@
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/webrtc_ip_handling_policy.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/renderer/media/gpu/rtc_video_decoder_factory.h"
#include "content/renderer/media/gpu/rtc_video_encoder_factory.h"
#include "content/renderer/media/media_stream_video_source.h"
#include "content/renderer/media/media_stream_video_track.h"
#include "content/renderer/media/rtc_peer_connection_handler.h"
#include "content/renderer/media/webrtc/audio_codec_factory.h"
#include "content/renderer/media/webrtc/stun_field_trial.h"
#include "content/renderer/media/webrtc/video_codec_factory.h"
#include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h"
#include "content/renderer/media/webrtc_audio_device_impl.h"
#include "content/renderer/media/webrtc_logging.h"
......@@ -62,11 +63,18 @@
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/webrtc/api/mediaconstraintsinterface.h"
#include "third_party/webrtc/api/video_codecs/video_decoder_factory.h"
#include "third_party/webrtc/api/video_codecs/video_encoder_factory.h"
#include "third_party/webrtc/api/videosourceproxy.h"
#include "third_party/webrtc/media/engine/convert_legacy_video_factory.h"
#include "third_party/webrtc/modules/video_coding/codecs/h264/include/h264.h"
#include "third_party/webrtc/rtc_base/refcountedobject.h"
#include "third_party/webrtc/rtc_base/ssladapter.h"
#if defined(OS_ANDROID)
#include "media/base/android/media_codec_util.h"
#endif
namespace content {
namespace {
......@@ -230,15 +238,35 @@ void PeerConnectionDependencyFactory::InitializeSignalingThread(
socket_factory_.reset(
new IpcPacketSocketFactory(p2p_socket_dispatcher_.get()));
std::unique_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory;
std::unique_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory;
const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
if (gpu_factories && gpu_factories->IsGpuVideoAcceleratorEnabled()) {
if (!cmd_line->HasSwitch(switches::kDisableWebRtcHWDecoding))
decoder_factory.reset(new RTCVideoDecoderFactory(gpu_factories));
if (!cmd_line->HasSwitch(switches::kDisableWebRtcHWEncoding)) {
encoder_factory.reset(new RTCVideoEncoderFactory(gpu_factories));
}
}
#if defined(OS_ANDROID)
if (!media::MediaCodecUtil::SupportsSetParameters())
encoder_factory.reset();
#endif
// TODO(magjed): Update RTCVideoEncoderFactory/RTCVideoDecoderFactory to new
// interface and let Chromium be responsible in what order video codecs are
// listed, instead of using
// cricket::ConvertVideoEncoderFactory/cricket::ConvertVideoDecoderFactory.
pc_factory_ = webrtc::CreatePeerConnectionFactory(
worker_thread_ /* network thread */, worker_thread_, signaling_thread_,
audio_device_.get(), CreateWebrtcAudioEncoderFactory(),
CreateWebrtcAudioDecoderFactory(),
CreateWebrtcVideoEncoderFactory(gpu_factories),
CreateWebrtcVideoDecoderFactory(gpu_factories), nullptr /* audio_mixer */,
nullptr /* audio_processing */);
cricket::ConvertVideoEncoderFactory(std::move(encoder_factory)),
cricket::ConvertVideoDecoderFactory(std::move(decoder_factory)),
nullptr /* audio_mixer */, nullptr /* audio_processing */);
CHECK(pc_factory_.get());
webrtc::PeerConnectionFactoryInterface::Options factory_options;
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/renderer/media/webrtc/video_codec_factory.h"
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/memory/ptr_util.h"
#include "build/build_config.h"
#include "content/public/common/content_switches.h"
#include "content/renderer/media/gpu/rtc_video_decoder_factory.h"
#include "content/renderer/media/gpu/rtc_video_encoder_factory.h"
#include "third_party/webrtc/media/base/codec.h"
#include "third_party/webrtc/media/engine/internaldecoderfactory.h"
#include "third_party/webrtc/media/engine/internalencoderfactory.h"
#include "third_party/webrtc/media/engine/simulcast_encoder_adapter.h"
#include "third_party/webrtc/media/engine/videodecodersoftwarefallbackwrapper.h"
#include "third_party/webrtc/media/engine/videoencodersoftwarefallbackwrapper.h"
#include "third_party/webrtc/media/engine/vp8_encoder_simulcast_proxy.h"
#if defined(OS_ANDROID)
#include "media/base/android/media_codec_util.h"
#endif
namespace content {
namespace {
bool IsFormatSupported(
const std::vector<webrtc::SdpVideoFormat>& supported_formats,
const webrtc::SdpVideoFormat& format) {
for (const webrtc::SdpVideoFormat& supported_format : supported_formats) {
if (cricket::IsSameCodec(format.name, format.parameters,
supported_format.name,
supported_format.parameters)) {
return true;
}
}
return false;
}
template <typename Factory>
bool IsFormatSupported(Factory* factory, const webrtc::SdpVideoFormat& format) {
return factory && IsFormatSupported(factory->GetSupportedFormats(), format);
}
// Merge |formats1| and |formats2|, but avoid adding duplicate formats.
std::vector<webrtc::SdpVideoFormat> MergeFormats(
std::vector<webrtc::SdpVideoFormat> formats1,
std::vector<webrtc::SdpVideoFormat> formats2) {
for (const webrtc::SdpVideoFormat& format : formats2) {
// Don't add same format twice.
if (!IsFormatSupported(formats1, format))
formats1.push_back(format);
}
return formats1;
}
std::unique_ptr<webrtc::VideoDecoder> CreateDecoder(
webrtc::VideoDecoderFactory* factory,
const webrtc::SdpVideoFormat& format) {
return IsFormatSupported(factory, format)
? factory->CreateVideoDecoder(format)
: nullptr;
}
template <typename SoftwareWrapperClass, typename CoderClass>
std::unique_ptr<CoderClass> Wrap(std::unique_ptr<CoderClass> internal_coder,
std::unique_ptr<CoderClass> external_coder) {
if (internal_coder && external_coder) {
return base::MakeUnique<SoftwareWrapperClass>(std::move(internal_coder),
std::move(external_coder));
}
return external_coder ? std::move(external_coder) : std::move(internal_coder);
}
// This class combines an external factory with the internal factory and adds
// internal SW codecs, simulcast, and SW fallback wrappers.
class EncoderAdapter : public webrtc::VideoEncoderFactory {
public:
explicit EncoderAdapter(
std::unique_ptr<webrtc::VideoEncoderFactory> external_encoder_factory)
: external_encoder_factory_(std::move(external_encoder_factory)) {}
webrtc::VideoEncoderFactory::CodecInfo QueryVideoEncoder(
const webrtc::SdpVideoFormat& format) const override {
const webrtc::VideoEncoderFactory* factory =
IsFormatSupported(external_encoder_factory_.get(), format)
? external_encoder_factory_.get()
: &internal_encoder_factory_;
return factory->QueryVideoEncoder(format);
}
std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder(
const webrtc::SdpVideoFormat& format) override {
std::unique_ptr<webrtc::VideoEncoder> internal_encoder;
if (IsFormatSupported(internal_encoder_factory_.GetSupportedFormats(),
format)) {
internal_encoder =
cricket::CodecNamesEq(format.name.c_str(), cricket::kVp8CodecName)
? base::MakeUnique<webrtc::VP8EncoderSimulcastProxy>(
&internal_encoder_factory_)
: internal_encoder_factory_.CreateVideoEncoder(format);
}
std::unique_ptr<webrtc::VideoEncoder> external_encoder;
if (IsFormatSupported(external_encoder_factory_.get(), format)) {
external_encoder =
cricket::CodecNamesEq(format.name.c_str(), cricket::kVp8CodecName)
? base::MakeUnique<webrtc::SimulcastEncoderAdapter>(
external_encoder_factory_.get())
: external_encoder_factory_->CreateVideoEncoder(format);
}
return Wrap<webrtc::VideoEncoderSoftwareFallbackWrapper>(
std::move(internal_encoder), std::move(external_encoder));
}
std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override {
std::vector<webrtc::SdpVideoFormat> internal_formats =
internal_encoder_factory_.GetSupportedFormats();
return external_encoder_factory_
? MergeFormats(internal_formats,
external_encoder_factory_->GetSupportedFormats())
: internal_formats;
}
private:
webrtc::InternalEncoderFactory internal_encoder_factory_;
const std::unique_ptr<webrtc::VideoEncoderFactory> external_encoder_factory_;
};
// This class combines an external factory with the internal factory and adds
// internal SW codecs and SW fallback wrappers.
class DecoderAdapter : public webrtc::VideoDecoderFactory {
public:
explicit DecoderAdapter(
std::unique_ptr<webrtc::VideoDecoderFactory> external_decoder_factory)
: external_decoder_factory_(std::move(external_decoder_factory)) {}
std::unique_ptr<webrtc::VideoDecoder> CreateVideoDecoder(
const webrtc::SdpVideoFormat& format) override {
std::unique_ptr<webrtc::VideoDecoder> internal_decoder =
CreateDecoder(&internal_decoder_factory_, format);
std::unique_ptr<webrtc::VideoDecoder> external_decoder =
CreateDecoder(external_decoder_factory_.get(), format);
return Wrap<webrtc::VideoDecoderSoftwareFallbackWrapper>(
std::move(internal_decoder), std::move(external_decoder));
}
std::vector<webrtc::SdpVideoFormat> GetSupportedFormats() const override {
std::vector<webrtc::SdpVideoFormat> internal_formats =
internal_decoder_factory_.GetSupportedFormats();
return external_decoder_factory_
? MergeFormats(internal_formats,
external_decoder_factory_->GetSupportedFormats())
: internal_formats;
}
private:
webrtc::InternalDecoderFactory internal_decoder_factory_;
const std::unique_ptr<webrtc::VideoDecoderFactory> external_decoder_factory_;
};
} // namespace
std::unique_ptr<webrtc::VideoEncoderFactory> CreateWebrtcVideoEncoderFactory(
media::GpuVideoAcceleratorFactories* gpu_factories) {
std::unique_ptr<webrtc::VideoEncoderFactory> encoder_factory;
const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
if (gpu_factories && gpu_factories->IsGpuVideoAcceleratorEnabled() &&
!cmd_line->HasSwitch(switches::kDisableWebRtcHWEncoding)) {
encoder_factory.reset(new RTCVideoEncoderFactory(gpu_factories));
}
#if defined(OS_ANDROID)
if (!media::MediaCodecUtil::SupportsSetParameters())
encoder_factory.reset();
#endif
return base::MakeUnique<EncoderAdapter>(std::move(encoder_factory));
}
std::unique_ptr<webrtc::VideoDecoderFactory> CreateWebrtcVideoDecoderFactory(
media::GpuVideoAcceleratorFactories* gpu_factories) {
std::unique_ptr<webrtc::VideoDecoderFactory> decoder_factory;
const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
if (gpu_factories && gpu_factories->IsGpuVideoAcceleratorEnabled() &&
!cmd_line->HasSwitch(switches::kDisableWebRtcHWDecoding)) {
decoder_factory.reset(new RTCVideoDecoderFactory(gpu_factories));
}
return base::MakeUnique<DecoderAdapter>(std::move(decoder_factory));
}
} // namespace content
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_VIDEO_CODEC_FACTORY_H_
#define CONTENT_RENDERER_MEDIA_WEBRTC_VIDEO_CODEC_FACTORY_H_
#include "media/video/gpu_video_accelerator_factories.h"
#include "third_party/webrtc/api/video_codecs/video_decoder_factory.h"
#include "third_party/webrtc/api/video_codecs/video_encoder_factory.h"
namespace content {
std::unique_ptr<webrtc::VideoEncoderFactory> CreateWebrtcVideoEncoderFactory(
media::GpuVideoAcceleratorFactories* gpu_factories);
std::unique_ptr<webrtc::VideoDecoderFactory> CreateWebrtcVideoDecoderFactory(
media::GpuVideoAcceleratorFactories* gpu_factories);
} // namespace content
#endif // CONTENT_RENDERER_MEDIA_WEBRTC_VIDEO_CODEC_FACTORY_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment