PR #25042 opened by Zhao Zhili (quink) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25042 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25042.patch
# Summary of changes There is a known issue workaround by 7fe9d12f2571265b2a7b5c763d62ee80f9a9e2e2, but now shows on more devices like XiaoMi 18 Fold. Until the codec signals INFO_OUTPUT_FORMAT_CHANGED, MediaCodec returns the output format set up at configure time. The decoder parsed that format right after start() and copied its crop rectangle, display size and color description into the codec context, although at that point the codec has not decoded anything and these fields hold its defaults. For a 1920x1080 HLG stream, c2.xring.hevc.decoder reports the crop rectangle Rect(0, 0, 175, 143) and BT.601 SDR color there, and MediaTek decoders report rectangles such as Rect(0, 0, 318, 238). Callers reading the codec context after avcodec_open2() got 176x144 or 319x239 and a wrong color description instead of the stream properties. Keep the values set by the caller until the codec signals a format change. The pixel format is still taken from the initial format, as it reflects the configuration. If the first output buffer arrives without a format change, the initial format describes the decoded frames and is applied at that point. Now we can finally revert/drop 7fe9d12f2571265b2a7b5c763d62ee80f9a9e2e2. <!-- If this PR requires new FATE test samples, attach them to the PR and list their target paths below (relative to the fate-suite root). Attached filenames must match the sample's filename: ```fate-samples # e.g. vorbis/new-sample.ogg ``` --> >From 5a9219455d9e50da3be76ab7bb1bcee4dcd4d1ac Mon Sep 17 00:00:00 2001 From: Zhao Zhili <[email protected]> Date: Tue, 13 Oct 2026 19:15:39 +0800 Subject: [PATCH 1/2] avcodec/mediacodecdec_common: ignore stream info of the initial format Until the codec signals INFO_OUTPUT_FORMAT_CHANGED, MediaCodec returns the output format set up at configure time. The decoder parsed that format right after start() and copied its crop rectangle, display size and color description into the codec context, although at that point the codec has not decoded anything and these fields hold its defaults. For a 1920x1080 HLG stream, c2.xring.hevc.decoder reports the crop rectangle Rect(0, 0, 175, 143) and BT.601 SDR color there, and MediaTek decoders report rectangles such as Rect(0, 0, 318, 238). Callers reading the codec context after avcodec_open2() got 176x144 or 319x239 and a wrong color description instead of the stream properties. Keep the values set by the caller until the codec signals a format change. The pixel format is still taken from the initial format, as it reflects the configuration. If the first output buffer arrives without a format change, the initial format describes the decoded frames and is applied at that point. --- libavcodec/mediacodecdec_common.c | 25 +++++++++++++++++++++++++ libavcodec/mediacodecdec_common.h | 5 +++++ 2 files changed, 30 insertions(+) diff --git a/libavcodec/mediacodecdec_common.c b/libavcodec/mediacodecdec_common.c index 0cb9c092d7..fda5a3d9ce 100644 --- a/libavcodec/mediacodecdec_common.c +++ b/libavcodec/mediacodecdec_common.c @@ -597,6 +597,17 @@ static int mediacodec_dec_parse_video_format(AVCodecContext *avctx, MediaCodecDe goto fail; } + /* Until the codec signals a format change, the output format is the one + * set up by configure(), before the codec has seen any input. Its crop + * rectangle, display size and color description do not describe the + * stream, so keep the values set by the caller. The fields above + * describe the configured output buffers and always apply. + */ + if (!s->has_output_format) { + av_freep(&format); + return 0; + } + /* Optional fields */ AMEDIAFORMAT_GET_INT32(s->crop_top, "crop-top", 0); AMEDIAFORMAT_GET_INT32(s->crop_bottom, "crop-bottom", 0); @@ -1028,6 +1039,19 @@ int ff_mediacodec_dec_receive(AVCodecContext *avctx, MediaCodecDecContext *s, } if (info.size) { + if (s->format && !s->has_output_format) { + /* No format change preceded the first output buffer, so the + * initial output format describes the decoded frames. Only + * video fetches that format at init. + */ + s->has_output_format = true; + if ((ret = mediacodec_dec_parse_format(avctx, s)) < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to parse output format\n"); + ff_AMediaCodec_releaseOutputBuffer(codec, index, 0); + return ret; + } + } + if (s->surface) { if ((ret = mediacodec_wrap_hw_buffer(avctx, s, index, &info, frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to wrap MediaCodec buffer\n"); @@ -1066,6 +1090,7 @@ int ff_mediacodec_dec_receive(AVCodecContext *avctx, MediaCodecDecContext *s, } s->format = ff_AMediaCodec_getOutputFormat(codec); + s->has_output_format = true; if (!s->format) { av_log(avctx, AV_LOG_ERROR, "Failed to get output format\n"); return AVERROR_EXTERNAL; diff --git a/libavcodec/mediacodecdec_common.h b/libavcodec/mediacodecdec_common.h index 0ab29036bd..15a35390e0 100644 --- a/libavcodec/mediacodecdec_common.h +++ b/libavcodec/mediacodecdec_common.h @@ -44,6 +44,11 @@ typedef struct MediaCodecDecContext { FFAMediaCodec *codec; FFAMediaFormat *format; + /* Set once the codec has signalled an output format or produced output. + * Until then format is the one set up at configure time and its stream + * info is not applied. + */ + bool has_output_format; void *surface; -- 2.52.0 >From 6c04a6967327826a4e44fb8ea2b8c961fbdf3d73 Mon Sep 17 00:00:00 2001 From: Zhao Zhili <[email protected]> Date: Tue, 13 Oct 2026 19:16:02 +0800 Subject: [PATCH 2/2] avcodec/mediacodecdec_common: drop the MediaTek crop workaround MediaTek decoders report a default crop rectangle in the initial output format, and the workaround stopped reading the "crop" rectangle from them on the NDK path so that the default did not reach the codec context. The initial format no longer sets the crop rectangle of the codec context, while the workaround also discards the correct rectangle these decoders report with INFO_OUTPUT_FORMAT_CHANGED, which leaves the frames at the full width and height of the output buffers. This reverts commit 7fe9d12f2571265b2a7b5c763d62ee80f9a9e2e2. --- libavcodec/mediacodecdec_common.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavcodec/mediacodecdec_common.c b/libavcodec/mediacodecdec_common.c index fda5a3d9ce..4fe89982da 100644 --- a/libavcodec/mediacodecdec_common.c +++ b/libavcodec/mediacodecdec_common.c @@ -615,8 +615,7 @@ static int mediacodec_dec_parse_video_format(AVCodecContext *avctx, MediaCodecDe AMEDIAFORMAT_GET_INT32(s->crop_right, "crop-right", 0); // Try "crop" for NDK - // MediaTek SOC return some default value like Rect(0, 0, 318, 238) - if (!(s->crop_right && s->crop_bottom) && s->use_ndk_codec && !strstr(s->codec_name, ".mtk.")) + if (!(s->crop_right && s->crop_bottom) && s->use_ndk_codec) ff_AMediaFormat_getRect(s->format, "crop", &s->crop_left, &s->crop_top, &s->crop_right, &s->crop_bottom); if (s->crop_right && s->crop_bottom) { -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
