Move VideoDecoderSoftwareFallbackWrapper from webrtc/video_decoder.h to webrtc/media/engine/
The class VideoDecoderSoftwareFallbackWrapper is an implementation detail of webrtc/media/engine/webrtcvideoengine2.cc and should not be directly under webrtc/video_decoder.h. The main purpose is to improve the dependency graph in WebRTC so that VideoDecoderSoftwareFallbackWrapper can depend on cricket::VideoCodec. The test for VideoDecoderSoftwareFallbackWrapper is also moved from webrtc/video/video_decoder_unittest.cc to webrtc/media/engine/videodecodersoftwarefallbackwrapper_unittest.cc. BUG=webrtc:6743 TBR=stefan@webrtc.org Review-Url: https://codereview.webrtc.org/2518263003 Cr-Commit-Position: refs/heads/master@{#15180}
This commit is contained in:
parent
0ce6aafc32
commit
f6acc2a710
@ -88,6 +88,8 @@ rtc_static_library("rtc_media") {
|
||||
"engine/payload_type_mapper.h",
|
||||
"engine/simulcast.cc",
|
||||
"engine/simulcast.h",
|
||||
"engine/videodecodersoftwarefallbackwrapper.cc",
|
||||
"engine/videodecodersoftwarefallbackwrapper.h",
|
||||
"engine/videoencodersoftwarefallbackwrapper.cc",
|
||||
"engine/videoencodersoftwarefallbackwrapper.h",
|
||||
"engine/webrtccommon.h",
|
||||
@ -294,6 +296,7 @@ if (rtc_include_tests) {
|
||||
"engine/nullwebrtcvideoengine_unittest.cc",
|
||||
"engine/payload_type_mapper_unittest.cc",
|
||||
"engine/simulcast_unittest.cc",
|
||||
"engine/videodecodersoftwarefallbackwrapper_unittest.cc",
|
||||
"engine/videoencodersoftwarefallbackwrapper_unittest.cc",
|
||||
"engine/webrtcmediaengine_unittest.cc",
|
||||
"engine/webrtcvideocapturer_unittest.cc",
|
||||
|
||||
130
webrtc/media/engine/videodecodersoftwarefallbackwrapper.cc
Normal file
130
webrtc/media/engine/videodecodersoftwarefallbackwrapper.cc
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* 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/videodecodersoftwarefallbackwrapper.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "webrtc/base/logging.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) {
|
||||
}
|
||||
|
||||
int32_t VideoDecoderSoftwareFallbackWrapper::InitDecode(
|
||||
const VideoCodec* codec_settings,
|
||||
int32_t number_of_cores) {
|
||||
codec_settings_ = *codec_settings;
|
||||
number_of_cores_ = number_of_cores;
|
||||
return decoder_->InitDecode(codec_settings, number_of_cores);
|
||||
}
|
||||
|
||||
bool VideoDecoderSoftwareFallbackWrapper::InitFallbackDecoder() {
|
||||
RTC_CHECK(decoder_type_ != kUnsupportedCodec)
|
||||
<< "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_));
|
||||
if (fallback_decoder_->InitDecode(&codec_settings_, number_of_cores_) !=
|
||||
WEBRTC_VIDEO_CODEC_OK) {
|
||||
LOG(LS_ERROR) << "Failed to initialize software-decoder fallback.";
|
||||
fallback_decoder_.reset();
|
||||
return false;
|
||||
}
|
||||
if (callback_)
|
||||
fallback_decoder_->RegisterDecodeCompleteCallback(callback_);
|
||||
fallback_implementation_name_ =
|
||||
std::string(fallback_decoder_->ImplementationName()) +
|
||||
" (fallback from: " + decoder_->ImplementationName() + ")";
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t VideoDecoderSoftwareFallbackWrapper::Decode(
|
||||
const EncodedImage& input_image,
|
||||
bool missing_frames,
|
||||
const RTPFragmentationHeader* fragmentation,
|
||||
const CodecSpecificInfo* codec_specific_info,
|
||||
int64_t render_time_ms) {
|
||||
// Try decoding with the provided decoder on every keyframe or when there's no
|
||||
// fallback decoder. This is the normal case.
|
||||
if (!fallback_decoder_ || input_image._frameType == kVideoFrameKey) {
|
||||
int32_t ret = decoder_->Decode(input_image, missing_frames, fragmentation,
|
||||
codec_specific_info, render_time_ms);
|
||||
if (ret == WEBRTC_VIDEO_CODEC_OK) {
|
||||
if (fallback_decoder_) {
|
||||
// Decode OK -> stop using fallback decoder.
|
||||
fallback_decoder_->Release();
|
||||
fallback_decoder_.reset();
|
||||
return WEBRTC_VIDEO_CODEC_OK;
|
||||
}
|
||||
}
|
||||
if (ret != WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE)
|
||||
return ret;
|
||||
if (!fallback_decoder_) {
|
||||
// Try to initialize fallback decoder.
|
||||
if (!InitFallbackDecoder())
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return fallback_decoder_->Decode(input_image, missing_frames, fragmentation,
|
||||
codec_specific_info, render_time_ms);
|
||||
}
|
||||
|
||||
int32_t VideoDecoderSoftwareFallbackWrapper::RegisterDecodeCompleteCallback(
|
||||
DecodedImageCallback* callback) {
|
||||
callback_ = callback;
|
||||
int32_t ret = decoder_->RegisterDecodeCompleteCallback(callback);
|
||||
if (fallback_decoder_)
|
||||
return fallback_decoder_->RegisterDecodeCompleteCallback(callback);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t VideoDecoderSoftwareFallbackWrapper::Release() {
|
||||
if (fallback_decoder_)
|
||||
fallback_decoder_->Release();
|
||||
return decoder_->Release();
|
||||
}
|
||||
|
||||
bool VideoDecoderSoftwareFallbackWrapper::PrefersLateDecoding() const {
|
||||
if (fallback_decoder_)
|
||||
return fallback_decoder_->PrefersLateDecoding();
|
||||
return decoder_->PrefersLateDecoding();
|
||||
}
|
||||
|
||||
const char* VideoDecoderSoftwareFallbackWrapper::ImplementationName() const {
|
||||
if (fallback_decoder_)
|
||||
return fallback_implementation_name_.c_str();
|
||||
return decoder_->ImplementationName();
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
61
webrtc/media/engine/videodecodersoftwarefallbackwrapper.h
Normal file
61
webrtc/media/engine/videodecodersoftwarefallbackwrapper.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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_VIDEODECODERSOFTWAREFALLBACKWRAPPER_H_
|
||||
#define WEBRTC_MEDIA_ENGINE_VIDEODECODERSOFTWAREFALLBACKWRAPPER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "webrtc/video_decoder.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Class used to wrap external VideoDecoders to provide a fallback option on
|
||||
// software decoding when a hardware decoder fails to decode a stream due to
|
||||
// hardware restrictions, such as max resolution.
|
||||
class VideoDecoderSoftwareFallbackWrapper : public webrtc::VideoDecoder {
|
||||
public:
|
||||
VideoDecoderSoftwareFallbackWrapper(VideoCodecType codec_type,
|
||||
VideoDecoder* decoder);
|
||||
|
||||
int32_t InitDecode(const VideoCodec* codec_settings,
|
||||
int32_t number_of_cores) override;
|
||||
|
||||
int32_t Decode(const EncodedImage& input_image,
|
||||
bool missing_frames,
|
||||
const RTPFragmentationHeader* fragmentation,
|
||||
const CodecSpecificInfo* codec_specific_info,
|
||||
int64_t render_time_ms) override;
|
||||
|
||||
int32_t RegisterDecodeCompleteCallback(
|
||||
DecodedImageCallback* callback) override;
|
||||
|
||||
int32_t Release() override;
|
||||
bool PrefersLateDecoding() const override;
|
||||
|
||||
const char* ImplementationName() const override;
|
||||
|
||||
private:
|
||||
bool InitFallbackDecoder();
|
||||
|
||||
const DecoderType decoder_type_;
|
||||
VideoDecoder* const decoder_;
|
||||
|
||||
VideoCodec codec_settings_;
|
||||
int32_t number_of_cores_;
|
||||
std::string fallback_implementation_name_;
|
||||
std::unique_ptr<VideoDecoder> fallback_decoder_;
|
||||
DecodedImageCallback* callback_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_MEDIA_ENGINE_VIDEODECODERSOFTWAREFALLBACKWRAPPER_H_
|
||||
@ -11,6 +11,7 @@
|
||||
#include "webrtc/video_decoder.h"
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/media/engine/videodecodersoftwarefallbackwrapper.h"
|
||||
#include "webrtc/modules/video_coding/include/video_error_codes.h"
|
||||
#include "webrtc/test/gtest.h"
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "webrtc/media/engine/internalencoderfactory.h"
|
||||
#include "webrtc/media/engine/simulcast.h"
|
||||
#include "webrtc/media/engine/videoencodersoftwarefallbackwrapper.h"
|
||||
#include "webrtc/media/engine/videodecodersoftwarefallbackwrapper.h"
|
||||
#include "webrtc/media/engine/webrtcmediaengine.h"
|
||||
#include "webrtc/media/engine/webrtcvideoencoderfactory.h"
|
||||
#include "webrtc/media/engine/webrtcvoiceengine.h"
|
||||
|
||||
@ -154,7 +154,6 @@ if (rtc_include_tests) {
|
||||
"send_statistics_proxy_unittest.cc",
|
||||
"stats_counter_unittest.cc",
|
||||
"stream_synchronization_unittest.cc",
|
||||
"video_decoder_unittest.cc",
|
||||
"video_send_stream_tests.cc",
|
||||
"vie_encoder_unittest.cc",
|
||||
"vie_remb_unittest.cc",
|
||||
|
||||
@ -43,112 +43,6 @@ VideoDecoder* VideoDecoder::Create(VideoDecoder::DecoderType codec_type) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
VideoDecoderSoftwareFallbackWrapper::VideoDecoderSoftwareFallbackWrapper(
|
||||
VideoCodecType codec_type,
|
||||
VideoDecoder* decoder)
|
||||
: decoder_type_(CodecTypeToDecoderType(codec_type)),
|
||||
decoder_(decoder),
|
||||
callback_(nullptr) {
|
||||
}
|
||||
|
||||
int32_t VideoDecoderSoftwareFallbackWrapper::InitDecode(
|
||||
const VideoCodec* codec_settings,
|
||||
int32_t number_of_cores) {
|
||||
codec_settings_ = *codec_settings;
|
||||
number_of_cores_ = number_of_cores;
|
||||
return decoder_->InitDecode(codec_settings, number_of_cores);
|
||||
}
|
||||
|
||||
bool VideoDecoderSoftwareFallbackWrapper::InitFallbackDecoder() {
|
||||
RTC_CHECK(decoder_type_ != kUnsupportedCodec)
|
||||
<< "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_));
|
||||
if (fallback_decoder_->InitDecode(&codec_settings_, number_of_cores_) !=
|
||||
WEBRTC_VIDEO_CODEC_OK) {
|
||||
LOG(LS_ERROR) << "Failed to initialize software-decoder fallback.";
|
||||
fallback_decoder_.reset();
|
||||
return false;
|
||||
}
|
||||
if (callback_)
|
||||
fallback_decoder_->RegisterDecodeCompleteCallback(callback_);
|
||||
fallback_implementation_name_ =
|
||||
std::string(fallback_decoder_->ImplementationName()) +
|
||||
" (fallback from: " + decoder_->ImplementationName() + ")";
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t VideoDecoderSoftwareFallbackWrapper::Decode(
|
||||
const EncodedImage& input_image,
|
||||
bool missing_frames,
|
||||
const RTPFragmentationHeader* fragmentation,
|
||||
const CodecSpecificInfo* codec_specific_info,
|
||||
int64_t render_time_ms) {
|
||||
// Try decoding with the provided decoder on every keyframe or when there's no
|
||||
// fallback decoder. This is the normal case.
|
||||
if (!fallback_decoder_ || input_image._frameType == kVideoFrameKey) {
|
||||
int32_t ret = decoder_->Decode(input_image, missing_frames, fragmentation,
|
||||
codec_specific_info, render_time_ms);
|
||||
if (ret == WEBRTC_VIDEO_CODEC_OK) {
|
||||
if (fallback_decoder_) {
|
||||
// Decode OK -> stop using fallback decoder.
|
||||
fallback_decoder_->Release();
|
||||
fallback_decoder_.reset();
|
||||
return WEBRTC_VIDEO_CODEC_OK;
|
||||
}
|
||||
}
|
||||
if (ret != WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE)
|
||||
return ret;
|
||||
if (!fallback_decoder_) {
|
||||
// Try to initialize fallback decoder.
|
||||
if (!InitFallbackDecoder())
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return fallback_decoder_->Decode(input_image, missing_frames, fragmentation,
|
||||
codec_specific_info, render_time_ms);
|
||||
}
|
||||
|
||||
int32_t VideoDecoderSoftwareFallbackWrapper::RegisterDecodeCompleteCallback(
|
||||
DecodedImageCallback* callback) {
|
||||
callback_ = callback;
|
||||
int32_t ret = decoder_->RegisterDecodeCompleteCallback(callback);
|
||||
if (fallback_decoder_)
|
||||
return fallback_decoder_->RegisterDecodeCompleteCallback(callback);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t VideoDecoderSoftwareFallbackWrapper::Release() {
|
||||
if (fallback_decoder_)
|
||||
fallback_decoder_->Release();
|
||||
return decoder_->Release();
|
||||
}
|
||||
|
||||
bool VideoDecoderSoftwareFallbackWrapper::PrefersLateDecoding() const {
|
||||
if (fallback_decoder_)
|
||||
return fallback_decoder_->PrefersLateDecoding();
|
||||
return decoder_->PrefersLateDecoding();
|
||||
}
|
||||
|
||||
const char* VideoDecoderSoftwareFallbackWrapper::ImplementationName() const {
|
||||
if (fallback_decoder_)
|
||||
return fallback_implementation_name_.c_str();
|
||||
return decoder_->ImplementationName();
|
||||
}
|
||||
|
||||
NullVideoDecoder::NullVideoDecoder() {}
|
||||
|
||||
int32_t NullVideoDecoder::InitDecode(const VideoCodec* codec_settings,
|
||||
|
||||
@ -83,44 +83,6 @@ class VideoDecoder {
|
||||
virtual const char* ImplementationName() const { return "unknown"; }
|
||||
};
|
||||
|
||||
// Class used to wrap external VideoDecoders to provide a fallback option on
|
||||
// software decoding when a hardware decoder fails to decode a stream due to
|
||||
// hardware restrictions, such as max resolution.
|
||||
class VideoDecoderSoftwareFallbackWrapper : public webrtc::VideoDecoder {
|
||||
public:
|
||||
VideoDecoderSoftwareFallbackWrapper(VideoCodecType codec_type,
|
||||
VideoDecoder* decoder);
|
||||
|
||||
int32_t InitDecode(const VideoCodec* codec_settings,
|
||||
int32_t number_of_cores) override;
|
||||
|
||||
int32_t Decode(const EncodedImage& input_image,
|
||||
bool missing_frames,
|
||||
const RTPFragmentationHeader* fragmentation,
|
||||
const CodecSpecificInfo* codec_specific_info,
|
||||
int64_t render_time_ms) override;
|
||||
|
||||
int32_t RegisterDecodeCompleteCallback(
|
||||
DecodedImageCallback* callback) override;
|
||||
|
||||
int32_t Release() override;
|
||||
bool PrefersLateDecoding() const override;
|
||||
|
||||
const char* ImplementationName() const override;
|
||||
|
||||
private:
|
||||
bool InitFallbackDecoder();
|
||||
|
||||
const DecoderType decoder_type_;
|
||||
VideoDecoder* const decoder_;
|
||||
|
||||
VideoCodec codec_settings_;
|
||||
int32_t number_of_cores_;
|
||||
std::string fallback_implementation_name_;
|
||||
std::unique_ptr<VideoDecoder> fallback_decoder_;
|
||||
DecodedImageCallback* callback_;
|
||||
};
|
||||
|
||||
// Video decoder class to be used for unknown codecs. Doesn't support decoding
|
||||
// but logs messages to LS_ERROR.
|
||||
class NullVideoDecoder : public VideoDecoder {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user