diff options
author | Michael Niedermayer <michael@niedermayer.cc> | 2023-03-09 13:57:15 +0100 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2023-06-04 20:18:23 +0200 |
commit | 09e16d736b6cadd401b6a37d4ecce619a67d4459 (patch) | |
tree | 9f97c264fb85a2fa4b87c087ad3cecc283c15800 | |
parent | 9989fd451685b1b050622b6c5a21c1f99e22f0db (diff) | |
download | ffmpeg-09e16d736b6cadd401b6a37d4ecce619a67d4459.tar.gz |
avcodec/lcldec: Support 4:1:1 and 4:2:2 with odd width
Fixes: Ticket10240
Fixes: zlib_306_306_yuv422.avi
Fixes: zlib_306_306_yuv411.avi
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 0cf1ac905d2d97355a389c3baa4e132824b29f21)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r-- | libavcodec/lcldec.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c index ed87e6179b..97813b0e00 100644 --- a/libavcodec/lcldec.c +++ b/libavcodec/lcldec.c @@ -399,6 +399,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac v_out[ col >> 1 ] = *encoded++ + 128; v_out[(col >> 1) + 1] = *encoded++ + 128; } + if (col && col < width) { + u_out[ col >> 1 ] = u_out[(col>>1) - 1]; + v_out[ col >> 1 ] = v_out[(col>>1) - 1]; + } + y_out -= frame->linesize[0]; u_out -= frame->linesize[1]; v_out -= frame->linesize[2]; @@ -420,6 +425,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac u_out[col >> 2] = *encoded++ + 128; v_out[col >> 2] = *encoded++ + 128; } + if (col && col < width) { + u_out[col >> 2] = u_out[(col>>2) - 1]; + v_out[col >> 2] = v_out[(col>>2) - 1]; + } y_out -= frame->linesize[0]; u_out -= frame->linesize[1]; v_out -= frame->linesize[2]; @@ -477,6 +486,7 @@ static av_cold int decode_init(AVCodecContext *avctx) FFALIGN(avctx->height, 4); unsigned int max_decomp_size; int subsample_h, subsample_v; + int partial_h_supported = 0; if (avctx->extradata_size < 8) { av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); @@ -498,14 +508,11 @@ static av_cold int decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 1:1:1.\n"); break; case IMGTYPE_YUV422: - c->decomp_size = basesize * 2; + c->decomp_size = (avctx->width & ~3) * avctx->height * 2; max_decomp_size = max_basesize * 2; avctx->pix_fmt = AV_PIX_FMT_YUV422P; av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:2.\n"); - if (avctx->width % 4) { - avpriv_request_sample(avctx, "Unsupported dimensions"); - return AVERROR_INVALIDDATA; - } + partial_h_supported = 1; break; case IMGTYPE_RGB24: c->decomp_size = basesize * 3; @@ -514,10 +521,11 @@ static av_cold int decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_DEBUG, "Image type is RGB 24.\n"); break; case IMGTYPE_YUV411: - c->decomp_size = basesize / 2 * 3; + c->decomp_size = (avctx->width & ~3) * avctx->height / 2 * 3; max_decomp_size = max_basesize / 2 * 3; avctx->pix_fmt = AV_PIX_FMT_YUV411P; av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:1:1.\n"); + partial_h_supported = 1; break; case IMGTYPE_YUV211: c->decomp_size = basesize * 2; @@ -537,7 +545,7 @@ static av_cold int decode_init(AVCodecContext *avctx) } av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &subsample_h, &subsample_v); - if (avctx->width % (1<<subsample_h) || avctx->height % (1<<subsample_v)) { + if ((avctx->width % (1<<subsample_h) && !partial_h_supported) || avctx->height % (1<<subsample_v)) { avpriv_request_sample(avctx, "Unsupported dimensions"); return AVERROR_INVALIDDATA; } |