Move VideoDecoder::Create() logic to separate internal video decoder factory
The goal with this CL is to move implementation details out from the
webrtc root (webrtc/video_decoder.h) to simplify the dependency graph.
Another goal is to streamline the creation of VideoDecoders in
webrtcvideoengine2.cc; it will now have two factories of the same
WebRtcVideoDecoderFactory type, one internal and one external.
Specifically, this CL:
* Removes webrtc::VideoDecoder::DecoderType and use webrtc::VideoCodecType
instead.
* Removes 'static VideoDecoder* Create(DecoderType codec_type)' and
moves the create function to the internal decoder factory instead.
* Removes video_decoder.cc. webrtc::VideoDecoder is now just an
interface without any static functions.
BUG=webrtc:6743
Review-Url: https://codereview.webrtc.org/2521203002
Cr-Commit-Position: refs/heads/master@{#15350}
diff --git a/webrtc/media/BUILD.gn b/webrtc/media/BUILD.gn
index 93f98a9..f88ff49 100644
--- a/webrtc/media/BUILD.gn
+++ b/webrtc/media/BUILD.gn
@@ -136,6 +136,8 @@
"base/videocommon.h",
"base/videoframe.h",
"base/videosourcebase.h",
+ "engine/internaldecoderfactory.cc",
+ "engine/internaldecoderfactory.h",
"engine/internalencoderfactory.cc",
"engine/internalencoderfactory.h",
"engine/nullwebrtcvideoengine.h",
@@ -348,6 +350,7 @@
"base/videocapturer_unittest.cc",
"base/videocommon_unittest.cc",
"base/videoengine_unittest.h",
+ "engine/internaldecoderfactory_unittest.cc",
"engine/nullwebrtcvideoengine_unittest.cc",
"engine/payload_type_mapper_unittest.cc",
"engine/simulcast_unittest.cc",
diff --git a/webrtc/media/engine/internaldecoderfactory.cc b/webrtc/media/engine/internaldecoderfactory.cc
new file mode 100644
index 0000000..760575d
--- /dev/null
+++ b/webrtc/media/engine/internaldecoderfactory.cc
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016 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 "webrtc/media/engine/internaldecoderfactory.h"
+
+#include <utility>
+
+#include "webrtc/base/logging.h"
+#include "webrtc/modules/video_coding/codecs/h264/include/h264.h"
+#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
+#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
+
+namespace cricket {
+
+namespace {
+
+// Video decoder class to be used for unknown codecs. Doesn't support decoding
+// but logs messages to LS_ERROR.
+class NullVideoDecoder : public webrtc::VideoDecoder {
+ public:
+ int32_t InitDecode(const webrtc::VideoCodec* codec_settings,
+ int32_t number_of_cores) override {
+ LOG(LS_ERROR) << "Can't initialize NullVideoDecoder.";
+ return WEBRTC_VIDEO_CODEC_OK;
+ }
+
+ 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 {
+ LOG(LS_ERROR) << "The NullVideoDecoder doesn't support decoding.";
+ return WEBRTC_VIDEO_CODEC_OK;
+ }
+
+ int32_t RegisterDecodeCompleteCallback(
+ webrtc::DecodedImageCallback* callback) override {
+ LOG(LS_ERROR)
+ << "Can't register decode complete callback on NullVideoDecoder.";
+ return WEBRTC_VIDEO_CODEC_OK;
+ }
+
+ int32_t Release() override { return WEBRTC_VIDEO_CODEC_OK; }
+
+ const char* ImplementationName() const override { return "NullVideoDecoder"; }
+};
+
+} // anonymous namespace
+
+InternalDecoderFactory::InternalDecoderFactory() {}
+
+InternalDecoderFactory::~InternalDecoderFactory() {}
+
+// WebRtcVideoDecoderFactory implementation.
+webrtc::VideoDecoder* InternalDecoderFactory::CreateVideoDecoder(
+ webrtc::VideoCodecType type) {
+ switch (type) {
+ case webrtc::kVideoCodecH264:
+ if (webrtc::H264Decoder::IsSupported())
+ return webrtc::H264Decoder::Create();
+ // This could happen in a software-fallback for a codec type only
+ // supported externally (e.g. H.264 on iOS or Android) or in current usage
+ // in WebRtcVideoEngine2 if the external decoder fails to be created.
+ LOG(LS_ERROR) << "Unable to create an H.264 decoder fallback. "
+ << "Decoding of this stream will be broken.";
+ return new NullVideoDecoder();
+ case webrtc::kVideoCodecVP8:
+ return webrtc::VP8Decoder::Create();
+ case webrtc::kVideoCodecVP9:
+ RTC_DCHECK(webrtc::VP9Decoder::IsSupported());
+ return webrtc::VP9Decoder::Create();
+ default:
+ LOG(LS_ERROR) << "Creating NullVideoDecoder for unsupported codec.";
+ return new NullVideoDecoder();
+ }
+}
+
+void InternalDecoderFactory::DestroyVideoDecoder(
+ webrtc::VideoDecoder* decoder) {
+ delete decoder;
+}
+
+} // namespace cricket
diff --git a/webrtc/media/engine/internaldecoderfactory.h b/webrtc/media/engine/internaldecoderfactory.h
new file mode 100644
index 0000000..20ceecc
--- /dev/null
+++ b/webrtc/media/engine/internaldecoderfactory.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016 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 WEBRTC_MEDIA_ENGINE_INTERNALDECODERFACTORY_H_
+#define WEBRTC_MEDIA_ENGINE_INTERNALDECODERFACTORY_H_
+
+#include <vector>
+
+#include "webrtc/media/engine/webrtcvideodecoderfactory.h"
+
+namespace cricket {
+
+class InternalDecoderFactory : public WebRtcVideoDecoderFactory {
+ public:
+ InternalDecoderFactory();
+ virtual ~InternalDecoderFactory();
+
+ // WebRtcVideoDecoderFactory implementation.
+ webrtc::VideoDecoder* CreateVideoDecoder(
+ webrtc::VideoCodecType type) override;
+
+ void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) override;
+};
+
+} // namespace cricket
+
+#endif // WEBRTC_MEDIA_ENGINE_INTERNALDECODERFACTORY_H_
diff --git a/webrtc/media/engine/internaldecoderfactory_unittest.cc b/webrtc/media/engine/internaldecoderfactory_unittest.cc
new file mode 100644
index 0000000..bf1ca50
--- /dev/null
+++ b/webrtc/media/engine/internaldecoderfactory_unittest.cc
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2016 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 "webrtc/media/engine/internaldecoderfactory.h"
+
+#include "webrtc/test/gtest.h"
+
+TEST(InternalDecoderFactory, TestVP8) {
+ cricket::InternalDecoderFactory factory;
+ webrtc::VideoDecoder* decoder =
+ factory.CreateVideoDecoder(webrtc::kVideoCodecVP8);
+ EXPECT_TRUE(decoder);
+ factory.DestroyVideoDecoder(decoder);
+}
diff --git a/webrtc/media/engine/videodecodersoftwarefallbackwrapper.cc b/webrtc/media/engine/videodecodersoftwarefallbackwrapper.cc
index 8dd0f84..cd6eef9 100644
--- a/webrtc/media/engine/videodecodersoftwarefallbackwrapper.cc
+++ b/webrtc/media/engine/videodecodersoftwarefallbackwrapper.cc
@@ -13,34 +13,15 @@
#include <string>
#include "webrtc/base/logging.h"
+#include "webrtc/media/engine/internaldecoderfactory.h"
#include "webrtc/modules/video_coding/include/video_error_codes.h"
namespace webrtc {
-namespace {
-
-VideoDecoder::DecoderType CodecTypeToDecoderType(VideoCodecType codec_type) {
- switch (codec_type) {
- case kVideoCodecH264:
- return VideoDecoder::kH264;
- case kVideoCodecVP8:
- return VideoDecoder::kVp8;
- case kVideoCodecVP9:
- return VideoDecoder::kVp9;
- default:
- return VideoDecoder::kUnsupportedCodec;
- }
-}
-
-} // anonymous namespace
-
VideoDecoderSoftwareFallbackWrapper::VideoDecoderSoftwareFallbackWrapper(
VideoCodecType codec_type,
VideoDecoder* decoder)
- : decoder_type_(CodecTypeToDecoderType(codec_type)),
- decoder_(decoder),
- callback_(nullptr) {
-}
+ : codec_type_(codec_type), decoder_(decoder), callback_(nullptr) {}
int32_t VideoDecoderSoftwareFallbackWrapper::InitDecode(
const VideoCodec* codec_settings,
@@ -51,10 +32,12 @@
}
bool VideoDecoderSoftwareFallbackWrapper::InitFallbackDecoder() {
- RTC_CHECK(decoder_type_ != kUnsupportedCodec)
+ RTC_CHECK(codec_type_ != kVideoCodecUnknown)
<< "Decoder requesting fallback to codec not supported in software.";
LOG(LS_WARNING) << "Decoder falling back to software decoding.";
- fallback_decoder_.reset(VideoDecoder::Create(decoder_type_));
+ cricket::InternalDecoderFactory internal_decoder_factory;
+ fallback_decoder_.reset(
+ internal_decoder_factory.CreateVideoDecoder(codec_type_));
if (fallback_decoder_->InitDecode(&codec_settings_, number_of_cores_) !=
WEBRTC_VIDEO_CODEC_OK) {
LOG(LS_ERROR) << "Failed to initialize software-decoder fallback.";
diff --git a/webrtc/media/engine/videodecodersoftwarefallbackwrapper.h b/webrtc/media/engine/videodecodersoftwarefallbackwrapper.h
index 8e1a97d..93c9278 100644
--- a/webrtc/media/engine/videodecodersoftwarefallbackwrapper.h
+++ b/webrtc/media/engine/videodecodersoftwarefallbackwrapper.h
@@ -46,7 +46,7 @@
private:
bool InitFallbackDecoder();
- const DecoderType decoder_type_;
+ const VideoCodecType codec_type_;
VideoDecoder* const decoder_;
VideoCodec codec_settings_;
diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc
index fc91ca6..9396fcc 100644
--- a/webrtc/media/engine/webrtcvideoengine2.cc
+++ b/webrtc/media/engine/webrtcvideoengine2.cc
@@ -25,6 +25,7 @@
#include "webrtc/common_video/h264/profile_level_id.h"
#include "webrtc/media/engine/constants.h"
#include "webrtc/media/engine/internalencoderfactory.h"
+#include "webrtc/media/engine/internaldecoderfactory.h"
#include "webrtc/media/engine/simulcast.h"
#include "webrtc/media/engine/videoencodersoftwarefallbackwrapper.h"
#include "webrtc/media/engine/videodecodersoftwarefallbackwrapper.h"
@@ -2225,28 +2226,14 @@
external_decoder_factory_->CreateVideoDecoderWithParams(
type, {stream_params_.id});
if (decoder != NULL) {
- return AllocatedDecoder(decoder, type, true);
+ return AllocatedDecoder(decoder, type, true /* is_external */);
}
}
- if (type == webrtc::kVideoCodecVP8) {
- return AllocatedDecoder(
- webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kVp8), type, false);
- }
-
- if (type == webrtc::kVideoCodecVP9) {
- return AllocatedDecoder(
- webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kVp9), type, false);
- }
-
- if (type == webrtc::kVideoCodecH264) {
- return AllocatedDecoder(
- webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kH264), type, false);
- }
-
- return AllocatedDecoder(
- webrtc::VideoDecoder::Create(webrtc::VideoDecoder::kUnsupportedCodec),
- webrtc::kVideoCodecUnknown, false);
+ InternalDecoderFactory internal_decoder_factory;
+ return AllocatedDecoder(internal_decoder_factory.CreateVideoDecoderWithParams(
+ type, {stream_params_.id}),
+ type, false /* is_external */);
}
void WebRtcVideoChannel2::WebRtcVideoReceiveStream::ConfigureCodecs(