This CL adds a GN build flag to include builtin software codecs (enabled by default). When setting the flag to false, libvpx can also be excluded. The benefit is that the resulting binary is smaller. Replaces https://webrtc-review.googlesource.com/c/src/+/29203 Bug: webrtc:7925 Change-Id: Id330ea8a43169e449ee139eca18e4557cc932e10 Reviewed-on: https://webrtc-review.googlesource.com/36340 Commit-Queue: Anders Carlsson <andersc@webrtc.org> Reviewed-by: Patrik Höglund <phoglund@webrtc.org> Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Reviewed-by: Magnus Jedvert <magjed@webrtc.org> Cr-Commit-Position: refs/heads/master@{#21818}
141 lines
4.9 KiB
C++
141 lines
4.9 KiB
C++
/*
|
|
* 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 "media/engine/videodecodersoftwarefallbackwrapper.h"
|
|
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
#include "modules/video_coding/include/video_error_codes.h"
|
|
#include "rtc_base/checks.h"
|
|
#include "rtc_base/logging.h"
|
|
#include "rtc_base/trace_event.h"
|
|
|
|
namespace webrtc {
|
|
|
|
VideoDecoderSoftwareFallbackWrapper::VideoDecoderSoftwareFallbackWrapper(
|
|
std::unique_ptr<VideoDecoder> sw_fallback_decoder,
|
|
std::unique_ptr<VideoDecoder> hw_decoder)
|
|
: use_hw_decoder_(true),
|
|
hw_decoder_(std::move(hw_decoder)),
|
|
hw_decoder_initialized_(false),
|
|
fallback_decoder_(std::move(sw_fallback_decoder)),
|
|
fallback_implementation_name_(
|
|
std::string(fallback_decoder_->ImplementationName()) +
|
|
" (fallback from: " + hw_decoder_->ImplementationName() + ")"),
|
|
callback_(nullptr) {}
|
|
|
|
int32_t VideoDecoderSoftwareFallbackWrapper::InitDecode(
|
|
const VideoCodec* codec_settings,
|
|
int32_t number_of_cores) {
|
|
// Always try to use the HW decoder in this state.
|
|
use_hw_decoder_ = true;
|
|
codec_settings_ = *codec_settings;
|
|
number_of_cores_ = number_of_cores;
|
|
int32_t ret = hw_decoder_->InitDecode(codec_settings, number_of_cores);
|
|
if (ret == WEBRTC_VIDEO_CODEC_OK) {
|
|
hw_decoder_initialized_ = true;
|
|
return ret;
|
|
}
|
|
hw_decoder_initialized_ = false;
|
|
|
|
// Try to initialize fallback decoder.
|
|
if (InitFallbackDecoder())
|
|
return WEBRTC_VIDEO_CODEC_OK;
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool VideoDecoderSoftwareFallbackWrapper::InitFallbackDecoder() {
|
|
RTC_LOG(LS_WARNING) << "Decoder falling back to software decoding.";
|
|
if (fallback_decoder_->InitDecode(&codec_settings_, number_of_cores_) !=
|
|
WEBRTC_VIDEO_CODEC_OK) {
|
|
RTC_LOG(LS_ERROR) << "Failed to initialize software-decoder fallback.";
|
|
use_hw_decoder_ = true;
|
|
return false;
|
|
}
|
|
if (callback_)
|
|
fallback_decoder_->RegisterDecodeCompleteCallback(callback_);
|
|
use_hw_decoder_ = false;
|
|
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) {
|
|
TRACE_EVENT0("webrtc", "VideoDecoderSoftwareFallbackWrapper::Decode");
|
|
// Try initializing and decoding with the provided decoder on every keyframe
|
|
// or when there's no fallback decoder. This is the normal case.
|
|
if (use_hw_decoder_ || input_image._frameType == kVideoFrameKey) {
|
|
int32_t ret = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
|
|
// Try reinitializing the decoder if it had failed before.
|
|
if (!hw_decoder_initialized_) {
|
|
hw_decoder_initialized_ =
|
|
hw_decoder_->InitDecode(&codec_settings_, number_of_cores_) ==
|
|
WEBRTC_VIDEO_CODEC_OK;
|
|
}
|
|
if (hw_decoder_initialized_) {
|
|
ret = hw_decoder_->Decode(input_image, missing_frames, fragmentation,
|
|
codec_specific_info, render_time_ms);
|
|
}
|
|
if (ret == WEBRTC_VIDEO_CODEC_OK) {
|
|
if (!use_hw_decoder_) {
|
|
// Decode OK -> stop using fallback decoder.
|
|
RTC_LOG(LS_WARNING)
|
|
<< "Decode OK, no longer using the software fallback decoder.";
|
|
use_hw_decoder_ = true;
|
|
return WEBRTC_VIDEO_CODEC_OK;
|
|
}
|
|
}
|
|
if (ret != WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE)
|
|
return ret;
|
|
if (use_hw_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 = hw_decoder_->RegisterDecodeCompleteCallback(callback);
|
|
if (!use_hw_decoder_)
|
|
return fallback_decoder_->RegisterDecodeCompleteCallback(callback);
|
|
return ret;
|
|
}
|
|
|
|
int32_t VideoDecoderSoftwareFallbackWrapper::Release() {
|
|
if (!use_hw_decoder_) {
|
|
RTC_LOG(LS_INFO) << "Releasing software fallback decoder.";
|
|
fallback_decoder_->Release();
|
|
}
|
|
hw_decoder_initialized_ = false;
|
|
return hw_decoder_->Release();
|
|
}
|
|
|
|
bool VideoDecoderSoftwareFallbackWrapper::PrefersLateDecoding() const {
|
|
return use_hw_decoder_ ? hw_decoder_->PrefersLateDecoding()
|
|
: fallback_decoder_->PrefersLateDecoding();
|
|
}
|
|
|
|
const char* VideoDecoderSoftwareFallbackWrapper::ImplementationName() const {
|
|
return use_hw_decoder_ ? hw_decoder_->ImplementationName()
|
|
: fallback_implementation_name_.c_str();
|
|
}
|
|
|
|
} // namespace webrtc
|