diff --git a/src/video_core/host1x/ffmpeg/ffmpeg.cpp b/src/video_core/host1x/ffmpeg/ffmpeg.cpp
index 95394b5d2f..170b42872f 100644
--- a/src/video_core/host1x/ffmpeg/ffmpeg.cpp
+++ b/src/video_core/host1x/ffmpeg/ffmpeg.cpp
@@ -1,9 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
-// SPDX-FileCopyrightText: Copyright 2024 suyu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
// SPDX-FileCopyrightText: Copyright 2025 eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -54,8 +51,7 @@ AVPixelFormat GetGpuFormat(AVCodecContext* codec_context, const AVPixelFormat* p
return codec_context->pix_fmt;
}
-std::string AVError(int errnum)
-{
+std::string AVError(int errnum) {
char errbuf[AV_ERROR_MAX_STRING_SIZE] = {};
av_make_error_string(errbuf, sizeof(errbuf) - 1, errnum);
return errbuf;
@@ -223,167 +219,6 @@ bool DecoderContext::OpenContext(const Decoder& decoder) {
return true;
}
-// Nasty but allows linux builds to pass.
-// Requires double checks when FFMPEG gets updated.
-// Hopefully a future FFMPEG update will all and expose a solution in the public API.
-namespace {
-
-typedef struct FFCodecDefault {
- const char* key;
- const char* value;
-} FFCodecDefault;
-
-typedef struct FFCodec {
- /**
- * The public AVCodec. See codec.h for it.
- */
- AVCodec p;
-
- /**
- * Internal codec capabilities FF_CODEC_CAP_*.
- */
- unsigned caps_internal : 29;
-
- /**
- * This field determines the type of the codec (decoder/encoder)
- * and also the exact callback cb implemented by the codec.
- * cb_type uses enum FFCodecType values.
- */
- unsigned cb_type : 3;
-
- int priv_data_size;
- /**
- * @name Frame-level threading support functions
- * @{
- */
- /**
- * Copy necessary context variables from a previous thread context to the current one.
- * If not defined, the next thread will start automatically; otherwise, the codec
- * must call ff_thread_finish_setup().
- *
- * dst and src will (rarely) point to the same context, in which case memcpy should be skipped.
- */
- int (*update_thread_context)(struct AVCodecContext* dst, const struct AVCodecContext* src);
-
- /**
- * Copy variables back to the user-facing context
- */
- int (*update_thread_context_for_user)(struct AVCodecContext* dst,
- const struct AVCodecContext* src);
- /** @} */
-
- /**
- * Private codec-specific defaults.
- */
- const FFCodecDefault* defaults;
-
- /**
- * Initialize codec static data, called from av_codec_iterate().
- *
- * This is not intended for time consuming operations as it is
- * run for every codec regardless of that codec being used.
- */
- void (*init_static_data)(struct FFCodec* codec);
-
- int (*init)(struct AVCodecContext*);
-
- union {
- /**
- * Decode to an AVFrame.
- * cb is in this state if cb_type is FF_CODEC_CB_TYPE_DECODE.
- *
- * @param avctx codec context
- * @param[out] frame AVFrame for output
- * @param[out] got_frame_ptr decoder sets to 0 or 1 to indicate that
- * a non-empty frame was returned in frame.
- * @param[in] avpkt AVPacket containing the data to be decoded
- * @return amount of bytes read from the packet on success,
- * negative error code on failure
- */
- int (*decode)(struct AVCodecContext* avctx, struct AVFrame* frame, int* got_frame_ptr,
- struct AVPacket* avpkt);
- /**
- * Decode subtitle data to an AVSubtitle.
- * cb is in this state if cb_type is FF_CODEC_CB_TYPE_DECODE_SUB.
- *
- * Apart from that this is like the decode callback.
- */
- int (*decode_sub)(struct AVCodecContext* avctx, struct AVSubtitle* sub, int* got_frame_ptr,
- const struct AVPacket* avpkt);
- /**
- * Decode API with decoupled packet/frame dataflow.
- * cb is in this state if cb_type is FF_CODEC_CB_TYPE_RECEIVE_FRAME.
- *
- * This function is called to get one output frame. It should call
- * ff_decode_get_packet() to obtain input data.
- */
- int (*receive_frame)(struct AVCodecContext* avctx, struct AVFrame* frame);
- /**
- * Encode data to an AVPacket.
- * cb is in this state if cb_type is FF_CODEC_CB_TYPE_ENCODE
- *
- * @param avctx codec context
- * @param[out] avpkt output AVPacket
- * @param[in] frame AVFrame containing the input to be encoded
- * @param[out] got_packet_ptr encoder sets to 0 or 1 to indicate that a
- * non-empty packet was returned in avpkt.
- * @return 0 on success, negative error code on failure
- */
- int (*encode)(struct AVCodecContext* avctx, struct AVPacket* avpkt,
- const struct AVFrame* frame, int* got_packet_ptr);
- /**
- * Encode subtitles to a raw buffer.
- * cb is in this state if cb_type is FF_CODEC_CB_TYPE_ENCODE_SUB.
- */
- int (*encode_sub)(struct AVCodecContext* avctx, uint8_t* buf, int buf_size,
- const struct AVSubtitle* sub);
- /**
- * Encode API with decoupled frame/packet dataflow.
- * cb is in this state if cb_type is FF_CODEC_CB_TYPE_RECEIVE_PACKET.
- *
- * This function is called to get one output packet.
- * It should call ff_encode_get_frame() to obtain input data.
- */
- int (*receive_packet)(struct AVCodecContext* avctx, struct AVPacket* avpkt);
- } cb;
-
- int (*close)(struct AVCodecContext*);
-
- /**
- * Flush buffers.
- * Will be called when seeking
- */
- void (*flush)(struct AVCodecContext*);
-
- /**
- * Decoding only, a comma-separated list of bitstream filters to apply to
- * packets before decoding.
- */
- const char* bsfs;
-
- /**
- * Array of pointers to hardware configurations supported by the codec,
- * or NULL if no hardware supported. The array is terminated by a NULL
- * pointer.
- *
- * The user can only access this field via avcodec_get_hw_config().
- */
- const struct AVCodecHWConfigInternal* const* hw_configs;
-
- /**
- * List of supported codec_tags, terminated by FF_CODEC_TAGS_END.
- */
- const uint32_t* codec_tags;
-} FFCodec;
-
-#ifndef ANDROID
-static av_always_inline const FFCodec* ffcodec(const AVCodec* codec) {
- return (const FFCodec*)codec;
-}
-#endif
-} // namespace
-
-
bool DecoderContext::SendPacket(const Packet& packet) {
m_temp_frame = std::make_shared();
m_got_frame = 0;
@@ -394,10 +229,8 @@ bool DecoderContext::SendPacket(const Packet& packet) {
if (!m_codec_context->hw_device_ctx && m_codec_context->codec_id == AV_CODEC_ID_H264) {
m_decode_order = true;
auto* codec{ffcodec(m_decoder.GetCodec())};
- if (const int ret = codec->cb.decode(m_codec_context,
- m_temp_frame->GetFrame(),
- &m_got_frame,
- packet.GetPacket());
+ if (const int ret = codec->cb.decode(m_codec_context, m_temp_frame->GetFrame(),
+ &m_got_frame, packet.GetPacket());
ret < 0) {
LOG_DEBUG(Service_NVDRV, "avcodec_send_packet error {}", AVError(ret));
return false;
@@ -417,7 +250,6 @@ bool DecoderContext::SendPacket(const Packet& packet) {
std::shared_ptr DecoderContext::ReceiveFrame() {
// Android can randomly crash when calling decode directly, so skip.
// TODO update ffmpeg and hope that fixes it.
-// TODO: This is causing issues on linux, need to bisect
#ifndef ANDROID
if (!m_codec_context->hw_device_ctx && m_codec_context->codec_id == AV_CODEC_ID_H264) {
m_decode_order = true;
@@ -475,8 +307,12 @@ std::shared_ptr DecoderContext::ReceiveFrame() {
}
#if defined(FF_API_INTERLACED_FRAME) || LIBAVUTIL_VERSION_MAJOR >= 59
- m_temp_frame->GetFrame()->interlaced_frame =
- (m_temp_frame->GetFrame()->flags & AV_FRAME_FLAG_INTERLACED) != 0;
+ if (m_temp_frame->GetFrame()->flags & AV_FRAME_FLAG_INTERLACED)
+ m_temp_frame->GetFrame()->flags &= ~AV_FRAME_FLAG_INTERLACED;
+ else
+ m_temp_frame->GetFrame()->flags |= AV_FRAME_FLAG_INTERLACED;
+#else
+ m_temp_frame->GetFrame()->interlaced_frame = !m_temp_frame->GetFrame()->interlaced_frame;
#endif
return std::move(m_temp_frame);
}
diff --git a/src/video_core/host1x/ffmpeg/ffmpeg.h b/src/video_core/host1x/ffmpeg/ffmpeg.h
index bd0ad97adc..20e12b3616 100644
--- a/src/video_core/host1x/ffmpeg/ffmpeg.h
+++ b/src/video_core/host1x/ffmpeg/ffmpeg.h
@@ -22,7 +22,7 @@ extern "C" {
#include
#include
#ifndef ANDROID
-#include
+#include
#endif
#if defined(__GNUC__) || defined(__clang__)
@@ -106,7 +106,11 @@ public:
}
bool IsInterlaced() const {
- return m_frame->interlaced_frame != 0;
+#if defined(FF_API_INTERLACED_FRAME) || LIBAVUTIL_VERSION_MAJOR >= 59
+ return m_frame->flags & AV_FRAME_FLAG_INTERLACED;
+#else
+ return m_frame->interlaced_frame;
+#endif
}
bool IsHardwareDecoded() const {