Update FFmpeg to 7.1.1, libvpx to 1.13.1 and libx264 to c24e06c on Android (#187)
All checks were successful
eden-build / source (push) Successful in 3m49s
eden-build / android (push) Successful in 21m25s
eden-build / windows (msvc) (push) Successful in 30m15s
eden-build / linux (push) Successful in 22m34s

This updates FFmpeg to 7.1.1, libvpx to 1.13.1 and libx264 to c24e06c on Android.

Co-authored-by: MaranBr <maranbr@outlook.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/187
Reviewed-by: crueter <crueter@noreply.localhost>
Co-authored-by: MaranBr <maranbr@noreply.localhost>
Co-committed-by: MaranBr <maranbr@noreply.localhost>
This commit is contained in:
MaranBr 2025-06-14 17:42:22 +00:00 committed by crueter
parent 6b46aca0b7
commit cc7f2808ed
3 changed files with 11 additions and 32 deletions

View file

@ -225,7 +225,7 @@ if (NOT WIN32 AND NOT ANDROID)
elseif(ANDROID) elseif(ANDROID)
# Use yuzu FFmpeg binaries # Use yuzu FFmpeg binaries
if (ARCHITECTURE_arm64) if (ARCHITECTURE_arm64)
set(FFmpeg_EXT_NAME "ffmpeg-android-v5.1.LTS-aarch64") set(FFmpeg_EXT_NAME "ffmpeg-android-7.1.1-aarch64")
elseif (ARCHITECTURE_x86_64) elseif (ARCHITECTURE_x86_64)
set(FFmpeg_EXT_NAME "ffmpeg-android-v5.1.LTS-x86_64") set(FFmpeg_EXT_NAME "ffmpeg-android-v5.1.LTS-x86_64")
else() else()

View file

@ -34,7 +34,7 @@ constexpr std::array PreferredGpuDecoders = {
AV_HWDEVICE_TYPE_VAAPI, AV_HWDEVICE_TYPE_VAAPI,
AV_HWDEVICE_TYPE_VDPAU, AV_HWDEVICE_TYPE_VDPAU,
#endif #endif
AV_HWDEVICE_TYPE_VULKAN, AV_HWDEVICE_TYPE_VULKAN
}; };
AVPixelFormat GetGpuFormat(AVCodecContext* codec_context, const AVPixelFormat* pix_fmts) { AVPixelFormat GetGpuFormat(AVCodecContext* codec_context, const AVPixelFormat* pix_fmts) {
@ -99,8 +99,7 @@ bool Decoder::SupportsDecodingOnDevice(AVPixelFormat* out_pix_fmt, AVHWDeviceTyp
for (int i = 0;; i++) { for (int i = 0;; i++) {
const AVCodecHWConfig* config = avcodec_get_hw_config(m_codec, i); const AVCodecHWConfig* config = avcodec_get_hw_config(m_codec, i);
if (!config) { if (!config) {
LOG_DEBUG(HW_GPU, "{} decoder does not support device type {}", m_codec->name, LOG_DEBUG(HW_GPU, "{} decoder does not support device type {}", m_codec->name, av_hwdevice_get_type_name(type));
av_hwdevice_get_type_name(type));
break; break;
} }
if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && config->device_type == type) { if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && config->device_type == type) {
@ -131,8 +130,7 @@ HardwareContext::~HardwareContext() {
av_buffer_unref(&m_gpu_decoder); av_buffer_unref(&m_gpu_decoder);
} }
bool HardwareContext::InitializeForDecoder(DecoderContext& decoder_context, bool HardwareContext::InitializeForDecoder(DecoderContext& decoder_context, const Decoder& decoder) {
const Decoder& decoder) {
const auto supported_types = GetSupportedDeviceTypes(); const auto supported_types = GetSupportedDeviceTypes();
for (const auto type : PreferredGpuDecoders) { for (const auto type : PreferredGpuDecoders) {
AVPixelFormat hw_pix_fmt; AVPixelFormat hw_pix_fmt;
@ -152,17 +150,14 @@ bool HardwareContext::InitializeForDecoder(DecoderContext& decoder_context,
} }
} }
LOG_INFO(HW_GPU, "Hardware decoding is disabled due to implementation issues, using CPU.");
return false; return false;
} }
bool HardwareContext::InitializeWithType(AVHWDeviceType type) { bool HardwareContext::InitializeWithType(AVHWDeviceType type) {
av_buffer_unref(&m_gpu_decoder); av_buffer_unref(&m_gpu_decoder);
if (const int ret = av_hwdevice_ctx_create(&m_gpu_decoder, type, nullptr, nullptr, 0); if (const int ret = av_hwdevice_ctx_create(&m_gpu_decoder, type, nullptr, nullptr, 0); ret < 0) {
ret < 0) { LOG_DEBUG(HW_GPU, "av_hwdevice_ctx_create({}) failed: {}", av_hwdevice_get_type_name(type), AVError(ret));
LOG_DEBUG(HW_GPU, "av_hwdevice_ctx_create({}) failed: {}", av_hwdevice_get_type_name(type),
AVError(ret));
return false; return false;
} }
@ -189,6 +184,7 @@ bool HardwareContext::InitializeWithType(AVHWDeviceType type) {
DecoderContext::DecoderContext(const Decoder& decoder) : m_decoder{decoder} { DecoderContext::DecoderContext(const Decoder& decoder) : m_decoder{decoder} {
m_codec_context = avcodec_alloc_context3(m_decoder.GetCodec()); m_codec_context = avcodec_alloc_context3(m_decoder.GetCodec());
av_opt_set(m_codec_context->priv_data, "preset", "veryfast", 0);
av_opt_set(m_codec_context->priv_data, "tune", "zerolatency", 0); av_opt_set(m_codec_context->priv_data, "tune", "zerolatency", 0);
m_codec_context->thread_count = 0; m_codec_context->thread_count = 0;
m_codec_context->thread_type &= ~FF_THREAD_FRAME; m_codec_context->thread_type &= ~FF_THREAD_FRAME;
@ -199,8 +195,7 @@ DecoderContext::~DecoderContext() {
avcodec_free_context(&m_codec_context); avcodec_free_context(&m_codec_context);
} }
void DecoderContext::InitializeHardwareDecoder(const HardwareContext& context, void DecoderContext::InitializeHardwareDecoder(const HardwareContext& context, AVPixelFormat hw_pix_fmt) {
AVPixelFormat hw_pix_fmt) {
m_codec_context->hw_device_ctx = av_buffer_ref(context.GetBufferRef()); m_codec_context->hw_device_ctx = av_buffer_ref(context.GetBufferRef());
m_codec_context->get_format = GetGpuFormat; m_codec_context->get_format = GetGpuFormat;
m_codec_context->pix_fmt = hw_pix_fmt; m_codec_context->pix_fmt = hw_pix_fmt;
@ -223,21 +218,15 @@ bool DecoderContext::SendPacket(const Packet& packet) {
m_temp_frame = std::make_shared<Frame>(); m_temp_frame = std::make_shared<Frame>();
m_got_frame = 0; m_got_frame = 0;
// Android can randomly crash when calling decode directly, so skip.
// TODO update ffmpeg and hope that fixes it.
#ifndef ANDROID
if (!m_codec_context->hw_device_ctx && m_codec_context->codec_id == AV_CODEC_ID_H264) { if (!m_codec_context->hw_device_ctx && m_codec_context->codec_id == AV_CODEC_ID_H264) {
m_decode_order = true; m_decode_order = true;
auto* codec{ffcodec(m_decoder.GetCodec())}; auto* codec{ffcodec(m_decoder.GetCodec())};
if (const int ret = codec->cb.decode(m_codec_context, m_temp_frame->GetFrame(), if (const int ret = codec->cb.decode(m_codec_context, m_temp_frame->GetFrame(), &m_got_frame, packet.GetPacket()); ret < 0) {
&m_got_frame, packet.GetPacket());
ret < 0) {
LOG_DEBUG(Service_NVDRV, "avcodec_send_packet error {}", AVError(ret)); LOG_DEBUG(Service_NVDRV, "avcodec_send_packet error {}", AVError(ret));
return false; return false;
} }
return true; return true;
} }
#endif
if (const int ret = avcodec_send_packet(m_codec_context, packet.GetPacket()); ret < 0) { if (const int ret = avcodec_send_packet(m_codec_context, packet.GetPacket()); ret < 0) {
LOG_ERROR(HW_GPU, "avcodec_send_packet error: {}", AVError(ret)); LOG_ERROR(HW_GPU, "avcodec_send_packet error: {}", AVError(ret));
@ -248,9 +237,6 @@ bool DecoderContext::SendPacket(const Packet& packet) {
} }
std::shared_ptr<Frame> DecoderContext::ReceiveFrame() { std::shared_ptr<Frame> DecoderContext::ReceiveFrame() {
// Android can randomly crash when calling decode directly, so skip.
// TODO update ffmpeg and hope that fixes it.
#ifndef ANDROID
if (!m_codec_context->hw_device_ctx && m_codec_context->codec_id == AV_CODEC_ID_H264) { if (!m_codec_context->hw_device_ctx && m_codec_context->codec_id == AV_CODEC_ID_H264) {
m_decode_order = true; m_decode_order = true;
auto* codec{ffcodec(m_decoder.GetCodec())}; auto* codec{ffcodec(m_decoder.GetCodec())};
@ -269,10 +255,7 @@ std::shared_ptr<Frame> DecoderContext::ReceiveFrame() {
LOG_ERROR(Service_NVDRV, "Failed to receive a frame! error {}", ret); LOG_ERROR(Service_NVDRV, "Failed to receive a frame! error {}", ret);
return {}; return {};
} }
} else } else {
#endif
{
const auto ReceiveImpl = [&](AVFrame* frame) { const auto ReceiveImpl = [&](AVFrame* frame) {
if (const int ret = avcodec_receive_frame(m_codec_context, frame); ret < 0) { if (const int ret = avcodec_receive_frame(m_codec_context, frame); ret < 0) {
LOG_ERROR(HW_GPU, "avcodec_receive_frame error: {}", AVError(ret)); LOG_ERROR(HW_GPU, "avcodec_receive_frame error: {}", AVError(ret));
@ -292,9 +275,7 @@ std::shared_ptr<Frame> DecoderContext::ReceiveFrame() {
} }
m_temp_frame->SetFormat(PreferredGpuFormat); m_temp_frame->SetFormat(PreferredGpuFormat);
if (const int ret = av_hwframe_transfer_data(m_temp_frame->GetFrame(), if (const int ret = av_hwframe_transfer_data(m_temp_frame->GetFrame(), intermediate_frame.GetFrame(), 0); ret < 0) {
intermediate_frame.GetFrame(), 0);
ret < 0) {
LOG_ERROR(HW_GPU, "av_hwframe_transfer_data error: {}", AVError(ret)); LOG_ERROR(HW_GPU, "av_hwframe_transfer_data error: {}", AVError(ret));
return {}; return {};
} }

View file

@ -21,9 +21,7 @@ extern "C" {
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <libavutil/opt.h> #include <libavutil/opt.h>
#ifndef ANDROID
#include <libavcodec/codec_internal.h> #include <libavcodec/codec_internal.h>
#endif
#if defined(__GNUC__) || defined(__clang__) #if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop