Use new avcodec_get_supported_config() API in FFmpeg 7.1

This commit is contained in:
Cameron Gutman 2024-09-29 22:23:37 -05:00
parent ec69dad8d7
commit 13880353d8

View File

@ -1076,15 +1076,15 @@ bool FFmpegVideoDecoder::tryInitializeRenderer(const AVCodec* decoder,
#define TRY_PREFERRED_PIXEL_FORMAT(RENDERER_TYPE) \ #define TRY_PREFERRED_PIXEL_FORMAT(RENDERER_TYPE) \
{ \ { \
RENDERER_TYPE renderer; \ RENDERER_TYPE renderer; \
if (renderer.getPreferredPixelFormat(params->videoFormat) == decoder->pix_fmts[i]) { \ if (renderer.getPreferredPixelFormat(params->videoFormat) == decoder_pix_fmts[i]) { \
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, \ SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, \
"Trying " #RENDERER_TYPE " for codec %s due to preferred pixel format: 0x%x", \ "Trying " #RENDERER_TYPE " for codec %s due to preferred pixel format: 0x%x", \
decoder->name, decoder->pix_fmts[i]); \ decoder->name, decoder_pix_fmts[i]); \
if (tryInitializeRenderer(decoder, decoder->pix_fmts[i], params, nullptr, nullptr, \ if (tryInitializeRenderer(decoder, decoder_pix_fmts[i], params, nullptr, nullptr, \
[]() -> IFFmpegRenderer* { return new RENDERER_TYPE(); })) { \ []() -> IFFmpegRenderer* { return new RENDERER_TYPE(); })) { \
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, \ SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, \
"Chose " #RENDERER_TYPE " for codec %s due to preferred pixel format: 0x%x", \ "Chose " #RENDERER_TYPE " for codec %s due to preferred pixel format: 0x%x", \
decoder->name, decoder->pix_fmts[i]); \ decoder->name, decoder_pix_fmts[i]); \
return true; \ return true; \
} \ } \
} \ } \
@ -1093,16 +1093,16 @@ bool FFmpegVideoDecoder::tryInitializeRenderer(const AVCodec* decoder,
#define TRY_SUPPORTED_NON_PREFERRED_PIXEL_FORMAT(RENDERER_TYPE) \ #define TRY_SUPPORTED_NON_PREFERRED_PIXEL_FORMAT(RENDERER_TYPE) \
{ \ { \
RENDERER_TYPE renderer; \ RENDERER_TYPE renderer; \
if (decoder->pix_fmts[i] != renderer.getPreferredPixelFormat(params->videoFormat) && \ if (decoder_pix_fmts[i] != renderer.getPreferredPixelFormat(params->videoFormat) && \
renderer.isPixelFormatSupported(params->videoFormat, decoder->pix_fmts[i])) { \ renderer.isPixelFormatSupported(params->videoFormat, decoder_pix_fmts[i])) { \
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, \ SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, \
"Trying " #RENDERER_TYPE " for codec %s due to compatible pixel format: 0x%x", \ "Trying " #RENDERER_TYPE " for codec %s due to compatible pixel format: 0x%x", \
decoder->name, decoder->pix_fmts[i]); \ decoder->name, decoder_pix_fmts[i]); \
if (tryInitializeRenderer(decoder, decoder->pix_fmts[i], params, nullptr, nullptr, \ if (tryInitializeRenderer(decoder, decoder_pix_fmts[i], params, nullptr, nullptr, \
[]() -> IFFmpegRenderer* { return new RENDERER_TYPE(); })) { \ []() -> IFFmpegRenderer* { return new RENDERER_TYPE(); })) { \
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, \ SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, \
"Chose " #RENDERER_TYPE " for codec %s due to compatible pixel format: 0x%x", \ "Chose " #RENDERER_TYPE " for codec %s due to compatible pixel format: 0x%x", \
decoder->name, decoder->pix_fmts[i]); \ decoder->name, decoder_pix_fmts[i]); \
return true; \ return true; \
} \ } \
} \ } \
@ -1116,6 +1116,16 @@ bool FFmpegVideoDecoder::tryInitializeRendererForUnknownDecoder(const AVCodec* d
return false; return false;
} }
const AVPixelFormat* decoder_pix_fmts;
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100)
if (avcodec_get_supported_config(nullptr, decoder, AV_CODEC_CONFIG_PIX_FORMAT, 0,
(const void**)&decoder_pix_fmts, nullptr) < 0) {
decoder_pix_fmts = nullptr;
}
#else
decoder_pix_fmts = decoder->pix_fmts;
#endif
// This might be a hwaccel decoder, so try any hw configs first // This might be a hwaccel decoder, so try any hw configs first
if (tryHwAccel) { if (tryHwAccel) {
for (int pass = 0; pass <= MAX_DECODER_PASS; pass++) { for (int pass = 0; pass <= MAX_DECODER_PASS; pass++) {
@ -1141,7 +1151,7 @@ bool FFmpegVideoDecoder::tryInitializeRendererForUnknownDecoder(const AVCodec* d
} }
} }
if (decoder->pix_fmts == NULL) { if (decoder_pix_fmts == NULL) {
// Supported output pixel formats are unknown. We'll just try DRM/SDL and hope it can cope. // Supported output pixel formats are unknown. We'll just try DRM/SDL and hope it can cope.
#if defined(HAVE_DRM) && defined(GL_IS_SLOW) #if defined(HAVE_DRM) && defined(GL_IS_SLOW)
@ -1177,11 +1187,11 @@ bool FFmpegVideoDecoder::tryInitializeRendererForUnknownDecoder(const AVCodec* d
// Even if it didn't completely deadlock us, the performance would likely be atrocious. // Even if it didn't completely deadlock us, the performance would likely be atrocious.
if (strcmp(decoder->name, "h264_mmal") == 0) { if (strcmp(decoder->name, "h264_mmal") == 0) {
#ifdef HAVE_MMAL #ifdef HAVE_MMAL
for (int i = 0; decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) { for (int i = 0; decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
TRY_PREFERRED_PIXEL_FORMAT(MmalRenderer); TRY_PREFERRED_PIXEL_FORMAT(MmalRenderer);
} }
for (int i = 0; decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) { for (int i = 0; decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
TRY_SUPPORTED_NON_PREFERRED_PIXEL_FORMAT(MmalRenderer); TRY_SUPPORTED_NON_PREFERRED_PIXEL_FORMAT(MmalRenderer);
} }
#endif #endif
@ -1191,7 +1201,7 @@ bool FFmpegVideoDecoder::tryInitializeRendererForUnknownDecoder(const AVCodec* d
} }
// Check if any of our decoders prefer any of the pixel formats first // Check if any of our decoders prefer any of the pixel formats first
for (int i = 0; decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) { for (int i = 0; decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
#ifdef HAVE_DRM #ifdef HAVE_DRM
TRY_PREFERRED_PIXEL_FORMAT(DrmRenderer); TRY_PREFERRED_PIXEL_FORMAT(DrmRenderer);
#endif #endif
@ -1204,7 +1214,7 @@ bool FFmpegVideoDecoder::tryInitializeRendererForUnknownDecoder(const AVCodec* d
} }
// Nothing prefers any of them. Let's see if anyone will tolerate one. // Nothing prefers any of them. Let's see if anyone will tolerate one.
for (int i = 0; decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) { for (int i = 0; decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
#ifdef HAVE_DRM #ifdef HAVE_DRM
TRY_SUPPORTED_NON_PREFERRED_PIXEL_FORMAT(DrmRenderer); TRY_SUPPORTED_NON_PREFERRED_PIXEL_FORMAT(DrmRenderer);
#endif #endif
@ -1219,10 +1229,10 @@ bool FFmpegVideoDecoder::tryInitializeRendererForUnknownDecoder(const AVCodec* d
#if defined(HAVE_LIBPLACEBO_VULKAN) && defined(VULKAN_IS_SLOW) #if defined(HAVE_LIBPLACEBO_VULKAN) && defined(VULKAN_IS_SLOW)
// If we got here with VULKAN_IS_SLOW, DrmRenderer didn't work, // If we got here with VULKAN_IS_SLOW, DrmRenderer didn't work,
// so we have to resort to PlVkRenderer. // so we have to resort to PlVkRenderer.
for (int i = 0; decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) { for (int i = 0; decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
TRY_PREFERRED_PIXEL_FORMAT(PlVkRenderer); TRY_PREFERRED_PIXEL_FORMAT(PlVkRenderer);
} }
for (int i = 0; decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) { for (int i = 0; decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
TRY_SUPPORTED_NON_PREFERRED_PIXEL_FORMAT(PlVkRenderer); TRY_SUPPORTED_NON_PREFERRED_PIXEL_FORMAT(PlVkRenderer);
} }
#endif #endif
@ -1230,10 +1240,10 @@ bool FFmpegVideoDecoder::tryInitializeRendererForUnknownDecoder(const AVCodec* d
#ifdef GL_IS_SLOW #ifdef GL_IS_SLOW
// If we got here with GL_IS_SLOW, DrmRenderer didn't work, so we have // If we got here with GL_IS_SLOW, DrmRenderer didn't work, so we have
// to resort to SdlRenderer. // to resort to SdlRenderer.
for (int i = 0; decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) { for (int i = 0; decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
TRY_PREFERRED_PIXEL_FORMAT(SdlRenderer); TRY_PREFERRED_PIXEL_FORMAT(SdlRenderer);
} }
for (int i = 0; decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) { for (int i = 0; decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
TRY_SUPPORTED_NON_PREFERRED_PIXEL_FORMAT(SdlRenderer); TRY_SUPPORTED_NON_PREFERRED_PIXEL_FORMAT(SdlRenderer);
} }
#endif #endif
@ -1369,9 +1379,18 @@ bool FFmpegVideoDecoder::tryInitializeNonHwAccelDecoder(PDECODER_PARAMETERS para
// Skip decoders without zero-copy output formats if requested // Skip decoders without zero-copy output formats if requested
if (requireZeroCopyFormat) { if (requireZeroCopyFormat) {
const AVPixelFormat* decoder_pix_fmts;
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100)
if (avcodec_get_supported_config(nullptr, decoder, AV_CODEC_CONFIG_PIX_FORMAT, 0,
(const void**)&decoder_pix_fmts, nullptr) < 0) {
decoder_pix_fmts = nullptr;
}
#else
decoder_pix_fmts = decoder->pix_fmts;
#endif
bool foundZeroCopyFormat = false; bool foundZeroCopyFormat = false;
for (int i = 0; decoder->pix_fmts && decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) { for (int i = 0; decoder_pix_fmts && decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
if (isZeroCopyFormat(decoder->pix_fmts[i])) { if (isZeroCopyFormat(decoder_pix_fmts[i])) {
foundZeroCopyFormat = true; foundZeroCopyFormat = true;
break; break;
} }