[FFmpeg-cvslog] configure: improve ar test for response files
ffmpeg | branch: master | Gyan Doshi | Tue Mar 18 19:37:56 2025 +0530| [b75b568b3d290ce827b80568ced1d68c277309e6] | committer: Gyan Doshi configure: improve ar test for response files > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=b75b568b3d290ce827b80568ced1d68c277309e6 --- configure | 13 +++-- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/configure b/configure index d84e32196d..14f7bcde0e 100755 --- a/configure +++ b/configure @@ -5230,12 +5230,6 @@ else ar_o='$@' fi -if $ar 2>&1 | grep -qi "@.*file"; then -ar_objs="true" -else -ar_objs="" -fi - add_cflags $extra_cflags add_cxxflags $extra_cxxflags add_objcflags $extra_objcflags @@ -7759,6 +7753,13 @@ case $ld_type in ;; esac +{ +ar_out=${FFTMPDIR}/test$LIBSUF +respfile="@/dev/null" +out_arg="$(echo $ar_o | sed "s;\$@;$ar_out;g")" +test_cmd $ar $arflags $out_arg $respfile && ar_objs="true" || ar_objs="" +} + enable frame_thread_encoder enabled asm || { arch=c; disable $ARCH_LIST $ARCH_EXT_LIST; } ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avformat/hlsenc: fix CODECS Attribute hard code in hevc EXT-X-STREAM-INF
ffmpeg | branch: master | Jack Lau | Wed Mar 19 19:17:59 2025 +0800| [1502551dd363b3651a0e41f981f47657a8d29f82] | committer: Steven Liu avformat/hlsenc: fix CODECS Attribute hard code in hevc EXT-X-STREAM-INF fix ticket: 10786 parse the SPS from extradata and get profile_compatibility, tier, constraints which was been hard code before. HEVC CODECS Attribute reference to: ISO/IEC14496-15 Signed-off-by: Jack Lau Signed-off-by: Steven Liu > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1502551dd363b3651a0e41f981f47657a8d29f82 --- libavformat/hlsenc.c | 38 +++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 6148685f40..e4e2777d6c 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -379,7 +379,10 @@ static void write_codec_attr(AVStream *st, VariantStream *vs) } else if (st->codecpar->codec_id == AV_CODEC_ID_HEVC) { uint8_t *data = st->codecpar->extradata; int profile = AV_PROFILE_UNKNOWN; +uint32_t profile_compatibility = AV_PROFILE_UNKNOWN; +char tier = 0; int level = AV_LEVEL_UNKNOWN; +char constraints[8] = ""; if (st->codecpar->profile != AV_PROFILE_UNKNOWN) profile = st->codecpar->profile; @@ -393,6 +396,8 @@ static void write_codec_attr(AVStream *st, VariantStream *vs) uint8_t *rbsp_buf; int remain_size = 0; int rbsp_size = 0; +uint32_t profile_compatibility_flags = 0; +uint8_t high_nibble = 0; /* skip start code + nalu header */ data += 6; /* process by reference General NAL unit syntax */ @@ -406,8 +411,32 @@ static void write_codec_attr(AVStream *st, VariantStream *vs) } /* skip sps_video_parameter_set_id u(4), * sps_max_sub_layers_minus1u(3), - * and sps_temporal_id_nesting_flag u(1) */ + * and sps_temporal_id_nesting_flag u(1) + * + * TIER represents the general_tier_flag, with 'L' indicating the flag is 0, + * and 'H' indicating the flag is 1 + */ +tier = (rbsp_buf[1] & 0x20) == 0 ? 'L' : 'H'; profile = rbsp_buf[1] & 0x1f; +/* PROFILE_COMPATIBILITY is general_profile_compatibility_flags, but in reverse bit order, + * in a hexadecimal representation (leading zeroes may be omitted). + */ +profile_compatibility_flags = AV_RB32(rbsp_buf + 2); +/* revise these bits to get the profile compatibility value */ +profile_compatibility_flags = ((profile_compatibility_flags & 0xU) << 1) | ((profile_compatibility_flags >> 1) & 0xU); +profile_compatibility_flags = ((profile_compatibility_flags & 0xU) << 2) | ((profile_compatibility_flags >> 2) & 0xU); +profile_compatibility_flags = ((profile_compatibility_flags & 0x0F0F0F0FU) << 4) | ((profile_compatibility_flags >> 4) & 0x0F0F0F0FU); +profile_compatibility_flags = ((profile_compatibility_flags & 0x00FF00FFU) << 8) | ((profile_compatibility_flags >> 8) & 0x00FF00FFU); +profile_compatibility = (profile_compatibility_flags << 16) | (profile_compatibility_flags >> 16); +/* skip 8 + 8 + 32 + * CONSTRAINTS is a hexadecimal representation of the general_constraint_indicator_flags. + * each byte is separated by a '.', and trailing zero bytes may be omitted. + * drop the trailing zero bytes refer to ISO/IEC14496-15. + */ +high_nibble = rbsp_buf[7] >> 4; +snprintf(constraints, sizeof(constraints), + high_nibble ? "%02x.%x" : "%02x", + rbsp_buf[6], high_nibble); /* skip 8 + 8 + 32 + 4 + 43 + 1 bit */ level = rbsp_buf[12]; av_freep(&rbsp_buf); @@ -417,8 +446,11 @@ static void write_codec_attr(AVStream *st, VariantStream *vs) } if (st->codecpar->codec_tag == MKTAG('h','v','c','1') && profile != AV_PROFILE_UNKNOWN && -level != AV_LEVEL_UNKNOWN) { -snprintf(attr, sizeof(attr), "%s.%d.4.L%d.B01", av_fourcc2str(st->codecpar->codec_tag), profile, level); +profile_compatibility != AV_PROFILE_UNKNOWN && +tier != 0 && +level != AV_LEVEL_UNKNOWN && +constraints[0] != '\0') { +snprintf(attr, sizeof(attr), "%s.%d.%x.%c%d.%s", av_fourcc2str(st->codecpar->codec_tag), profile, profile_compatibility, tier, level, constraints); } else goto fail; } else if (st->codecpar->codec_id == AV_CODEC_ID_MP2) { _
[FFmpeg-cvslog] swscale/output: add support for NV20
ffmpeg | branch: master | James Almer | Sun Mar 16 17:14:20 2025 -0300| [b8dc87524908e708cc8f6362d093c47d021a4e6a] | committer: James Almer swscale/output: add support for NV20 Signed-off-by: James Almer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=b8dc87524908e708cc8f6362d093c47d021a4e6a --- libswscale/format.c | 4 +-- libswscale/output.c | 49 ++-- libswscale/version.h | 2 +- tests/ref/fate/filter-pixdesc-nv20be | 1 + tests/ref/fate/filter-pixdesc-nv20le | 1 + tests/ref/fate/filter-pixfmts-copy | 2 ++ tests/ref/fate/filter-pixfmts-crop | 2 ++ tests/ref/fate/filter-pixfmts-field | 2 ++ tests/ref/fate/filter-pixfmts-fieldorder | 2 ++ tests/ref/fate/filter-pixfmts-hflip | 2 ++ tests/ref/fate/filter-pixfmts-il | 2 ++ tests/ref/fate/filter-pixfmts-null | 2 ++ tests/ref/fate/filter-pixfmts-pad| 1 + tests/ref/fate/filter-pixfmts-scale | 2 ++ tests/ref/fate/filter-pixfmts-vflip | 2 ++ 15 files changed, 52 insertions(+), 24 deletions(-) diff --git a/libswscale/format.c b/libswscale/format.c index fd0269a23e..cdffb3e863 100644 --- a/libswscale/format.c +++ b/libswscale/format.c @@ -226,8 +226,8 @@ static const FormatEntry format_entries[] = { [AV_PIX_FMT_Y216LE] = { 1, 1 }, [AV_PIX_FMT_X2RGB10LE] = { 1, 1 }, [AV_PIX_FMT_X2BGR10LE] = { 1, 1 }, -[AV_PIX_FMT_NV20BE] = { 1, 0 }, -[AV_PIX_FMT_NV20LE] = { 1, 0 }, +[AV_PIX_FMT_NV20BE] = { 1, 1 }, +[AV_PIX_FMT_NV20LE] = { 1, 1 }, [AV_PIX_FMT_P210BE] = { 1, 1 }, [AV_PIX_FMT_P210LE] = { 1, 1 }, [AV_PIX_FMT_P212BE] = { 1, 1 }, diff --git a/libswscale/output.c b/libswscale/output.c index 21c3bdc307..2253706c6a 100644 --- a/libswscale/output.c +++ b/libswscale/output.c @@ -472,11 +472,10 @@ static void yuv2nv12cX_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither, static void yuv2p01xl1_c(const int16_t *src, uint16_t *dest, int dstW, - int big_endian, int output_bits) + int big_endian, int output_bits, int output_shift) { int i; int shift = 15 - output_bits; -int output_shift = 16 - output_bits; for (i = 0; i < dstW; i++) { int val = src[i] + (1 << (shift - 1)); @@ -486,11 +485,10 @@ static void yuv2p01xl1_c(const int16_t *src, static void yuv2p01xlX_c(const int16_t *filter, int filterSize, const int16_t **src, uint16_t *dest, int dstW, - int big_endian, int output_bits) + int big_endian, int output_bits, int output_shift) { int i, j; int shift = 11 + 16 - output_bits; -int output_shift = 16 - output_bits; for (i = 0; i < dstW; i++) { int val = 1 << (shift - 1); @@ -505,12 +503,11 @@ static void yuv2p01xlX_c(const int16_t *filter, int filterSize, static void yuv2p01xcX_c(int big_endian, const uint8_t *chrDither, const int16_t *chrFilter, int chrFilterSize, const int16_t **chrUSrc, const int16_t **chrVSrc, - uint8_t *dest8, int chrDstW, int output_bits) + uint8_t *dest8, int chrDstW, int output_bits, int output_shift) { uint16_t *dest = (uint16_t*)dest8; int i, j; int shift = 11 + 16 - output_bits; -int output_shift = 16 - output_bits; for (i = 0; i < chrDstW; i++) { int u = 1 << (shift - 1); @@ -528,38 +525,40 @@ static void yuv2p01xcX_c(int big_endian, const uint8_t *chrDither, #undef output_pixel -#define yuv2p01x_wrapper(bits) \ -static void yuv2p0 ## bits ## l1_LE_c(const int16_t *src, \ +#define yuv2p01x_wrapper(fmt, bits, shift) \ +static void yuv2 ## fmt ## l1_LE_c(const int16_t *src, \ uint8_t *dest, int dstW, \ const uint8_t *dither, int offset) \ { \ -yuv2p01xl1_c(src, (uint16_t*)dest, dstW, 0, bits); \ +yuv2p01xl1_c(src, (uint16_t*)dest, dstW, 0, bits, shift); \ } \ \ -static void yuv2p0 ## bits ## l1_BE_c(const int16_t *src, \ +static void yuv2 ## fmt ## l1_BE_c(const int16_t *src, \ uint8_t *dest, int dstW, \ const uint8_t *dit
[FFmpeg-cvslog] avcodec/sanm: implement STOR/FTCH for ANIMv1
ffmpeg | branch: master | Manuel Lauss | Fri Mar 14 22:17:21 2025 +0100| [b48bd23321d8eee916dbe7afce96a749d29333f4] | committer: Manuel Lauss avcodec/sanm: implement STOR/FTCH for ANIMv1 Handle STOR/FTCH the same way the RA1 game engine does: On STOR, save the next following FOBJ (not the decoded image) in a buffer; decode it on FTCH. The RA1 codecs and the fobj handler now take an explicit GetByteContext in order to be able to replay stored data. Used extensively by Rebel Assault 1 for e.g. backgrounds and the cockpit overlay. For ANIMv2 keep the current system to store the decoded image, as replaying a FOBJ would not work with codecs37/47/48 due to sequence violations. Signed-off-by: Manuel Lauss > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=b48bd23321d8eee916dbe7afce96a749d29333f4 --- libavcodec/sanm.c | 226 -- 1 file changed, 151 insertions(+), 75 deletions(-) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index 9486e298cf..e3f4112756 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -598,19 +598,17 @@ static void codec4_gen_tiles(SANMVideoContext *ctx, uint16_t param1) } -static int codec4_load_tiles(SANMVideoContext *ctx, uint16_t param2, uint8_t clr) +static int codec4_load_tiles(SANMVideoContext *ctx, GetByteContext *gb, + uint16_t param2, uint8_t clr) { uint8_t c, *dst = (uint8_t *)&(ctx->c4tbl[1][0][0]); uint32_t loop = param2 * 8; -if (param2 > 256) -return AVERROR_INVALIDDATA; - -if (bytestream2_get_bytes_left(&ctx->gb) < loop) +if ((param2 > 256) || (bytestream2_get_bytes_left(gb) < loop)) return AVERROR_INVALIDDATA; while (loop--) { -c = bytestream2_get_byteu(&ctx->gb); +c = bytestream2_get_byteu(gb); *dst++ = (c >> 4) + clr; *dst++ = (c & 0xf) + clr; } @@ -671,8 +669,8 @@ static av_cold int decode_end(AVCodecContext *avctx) return 0; } -static int old_codec4(SANMVideoContext *ctx, int top, int left, int w, int h, - uint8_t param, uint16_t param2, int codec) +static int old_codec4(SANMVideoContext *ctx, GetByteContext *gb, int top, int left, + int w, int h, uint8_t param, uint16_t param2, int codec) { const uint16_t p = ctx->pitch; const uint32_t maxpxo = ctx->height * p; @@ -688,7 +686,7 @@ static int old_codec4(SANMVideoContext *ctx, int top, int left, int w, int h, ctx->c4param = param; } if (param2 > 0) { -ret = codec4_load_tiles(ctx, param2, param); +ret = codec4_load_tiles(ctx, gb, param2, param); if (ret) return ret; } @@ -702,9 +700,9 @@ static int old_codec4(SANMVideoContext *ctx, int top, int left, int w, int h, pxoff = j + left + ((top + i) * p); if (param2 > 0) { if (bits == 0) { -if (bytestream2_get_bytes_left(&ctx->gb) < 1) +if (bytestream2_get_bytes_left(gb) < 1) return AVERROR_INVALIDDATA; -mask = bytestream2_get_byteu(&ctx->gb); +mask = bytestream2_get_byteu(gb); bits = 8; } bit = !!(mask & 0x80); @@ -714,9 +712,9 @@ static int old_codec4(SANMVideoContext *ctx, int top, int left, int w, int h, bit = 0; } -if (bytestream2_get_bytes_left(&ctx->gb) < 1) +if (bytestream2_get_bytes_left(gb) < 1) return AVERROR_INVALIDDATA; -idx = bytestream2_get_byteu(&ctx->gb); +idx = bytestream2_get_byteu(gb); if ((bit == 0) && (idx == 0x80) && (codec != 5)) continue; @@ -756,23 +754,23 @@ static int old_codec4(SANMVideoContext *ctx, int top, int left, int w, int h, return 0; } -static int rle_decode(SANMVideoContext *ctx, uint8_t *dst, const int out_size) +static int rle_decode(SANMVideoContext *ctx, GetByteContext *gb, uint8_t *dst, const int out_size) { int opcode, color, run_len, left = out_size; while (left > 0) { -opcode = bytestream2_get_byte(&ctx->gb); +opcode = bytestream2_get_byte(gb); run_len = (opcode >> 1) + 1; -if (run_len > left || bytestream2_get_bytes_left(&ctx->gb) <= 0) +if (run_len > left || bytestream2_get_bytes_left(gb) <= 0) return AVERROR_INVALIDDATA; if (opcode & 1) { -color = bytestream2_get_byte(&ctx->gb); +color = bytestream2_get_byte(gb); memset(dst, color, run_len); } else { -if (bytestream2_get_bytes_left(&ctx->gb) < run_len) +if (bytestream2_get_bytes_left(gb) < run_len) return AVERROR_INVALIDDATA; -bytestream2_get_bufferu(&ctx->gb, dst, run_len); +bytestream2_get_bufferu(gb, dst, run_len); }
[FFmpeg-cvslog] avcodec/sanm: codec20 decoder
ffmpeg | branch: master | Manuel Lauss | Mon Mar 17 17:39:44 2025 +0100| [950ad969fb3891ccbc872c05262009f152e678ab] | committer: Manuel Lauss avcodec/sanm: codec20 decoder codec20 is raw uncompressed image data. It exists in Rebel Assault 1 as a special format for STOR/FTCH and is used again in the Full Throttle Remaster from 2017. Signed-off-by: Manuel Lauss > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=950ad969fb3891ccbc872c05262009f152e678ab --- libavcodec/sanm.c | 20 1 file changed, 20 insertions(+) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index 91be83029f..6b1da2e30c 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -947,6 +947,24 @@ static int old_codec2(SANMVideoContext *ctx, GetByteContext *gb, int top, return 0; } +static int old_codec20(SANMVideoContext *ctx, int w, int h) +{ +uint8_t *dst = (uint8_t *)ctx->frm0; + +if (bytestream2_get_bytes_left(&ctx->gb) < w * h) +return AVERROR_INVALIDDATA; + +if (w == ctx->pitch) { +bytestream2_get_bufferu(&ctx->gb, dst, w * h); +} else { +for (int i = 0; i < h; i++) { +bytestream2_get_bufferu(&ctx->gb, dst, w); +dst += ctx->pitch; +} +} +return 0; +} + static inline void codec37_mv(uint8_t *dst, const uint8_t *src, int height, int stride, int x, int y) { @@ -1667,6 +1685,8 @@ static int process_frame_obj(SANMVideoContext *ctx, GetByteContext *gb) case 33: case 34: return old_codec4(ctx, gb, top, left, w, h, param, parm2, codec); +case 20: +return old_codec20(ctx, w, h); case 21: return old_codec21(ctx, gb, top, left, w, h); case 23: ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avcodec/sanm: codec21 decoder
ffmpeg | branch: master | Manuel Lauss | Tue Mar 11 13:55:51 2025 +0100| [e1fd6bc8b49be7cc83b7b8e4b81d58693e7cd6e4] | committer: Manuel Lauss avcodec/sanm: codec21 decoder similar to codec23, this one alternatingly skips and writes bytes. Signed-off-by: Manuel Lauss > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=e1fd6bc8b49be7cc83b7b8e4b81d58693e7cd6e4 --- libavcodec/sanm.c | 45 + 1 file changed, 45 insertions(+) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index 6302c62f43..95ff8596ab 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -614,6 +614,49 @@ static int old_codec23(SANMVideoContext *ctx, int top, int left, int width, return 0; } +static int old_codec21(SANMVideoContext *ctx, int top, int left, int width, + int height) +{ +const uint32_t maxpxo = ctx->height * ctx->pitch; +uint8_t *dst = (uint8_t *)ctx->frm0, c; +int i, j, k, pc, sk, pxoff; + +dst = (uint8_t *)ctx->frm0; +for (i = 0; i < height; i++) { +if (bytestream2_get_bytes_left(&ctx->gb) < 2) +return 0; +pxoff = left + ((top + i) * ctx->pitch); +k = bytestream2_get_le16u(&ctx->gb); +sk = 1; +pc = 0; +while (k > 0 && pc <= width) { +if (bytestream2_get_bytes_left(&ctx->gb) < 2) +return AVERROR_INVALIDDATA; +j = bytestream2_get_le16u(&ctx->gb); +k -= 2; +if (sk) { +pxoff += j; +pc += j; +} else { +if (bytestream2_get_bytes_left(&ctx->gb) < (j + 1)) +return AVERROR_INVALIDDATA; +do { +c = bytestream2_get_byteu(&ctx->gb); +if (pxoff >=0 && pxoff < maxpxo) { +*(dst + pxoff) = c; +} +pxoff++; +pc++; +j--; +k--; +} while (j > -1); +} +sk ^= 1; +} +} +return 0; +} + static int old_codec1(SANMVideoContext *ctx, int top, int left, int width, int height, int opaque) { @@ -1393,6 +1436,8 @@ static int process_frame_obj(SANMVideoContext *ctx) return old_codec1(ctx, top, left, w, h, codec == 3); case 2: return old_codec2(ctx, top, left, w, h); +case 21: +return old_codec21(ctx, top, left, w, h); case 23: return old_codec23(ctx, top, left, w, h, param, parm2); case 37: ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avcodec/sanm: codec37: reimplement comp4
ffmpeg | branch: master | Manuel Lauss | Tue Mar 11 12:26:24 2025 +0100| [8a045260808be660818d58589fbb6b36dd0dfb5d] | committer: Manuel Lauss avcodec/sanm: codec37: reimplement comp4 Compression 4 code 0 means copy from delta buffer without mv, AND start of a skip run. This gets rid of the extra case and column index manipulation and implements this as it is implemented in the original game exe, i.e. as a special case for after mv copy. Signed-off-by: Manuel Lauss > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=8a045260808be660818d58589fbb6b36dd0dfb5d --- libavcodec/sanm.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index 5bb35df9e0..9486e298cf 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -1106,16 +1106,17 @@ static int old_codec37(SANMVideoContext *ctx, int width, int height) t = bytestream2_get_byteu(&ctx->gb); for (k = 0; k < 4; k++) memset(dst + i + k * stride, t, 4); - } else if ((compr == 4) && (code == 0)) { -if (bytestream2_get_bytes_left(&ctx->gb) < 1) -return AVERROR_INVALIDDATA; -skip_run = bytestream2_get_byteu(&ctx->gb) + 1; -i -= 4; } else { mx = c37_mv[(mvoff * 255 + code) * 2]; my = c37_mv[(mvoff * 255 + code) * 2 + 1]; codec37_mv(dst + i, prev + i + mx + my * stride, ctx->height, stride, i + mx, j + my); + +if ((compr == 4) && (code == 0)) { +if (bytestream2_get_bytes_left(&ctx->gb) < 1) +return AVERROR_INVALIDDATA; +skip_run = bytestream2_get_byteu(&ctx->gb); +} } } dst += stride * 4; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avcodec/sanm: codec23 decoder
ffmpeg | branch: master | Manuel Lauss | Tue Mar 11 13:35:33 2025 +0100| [77b5a0c13422cb67c1194c3b423d18b2339b0499] | committer: Manuel Lauss avcodec/sanm: codec23 decoder This codec alternatingly skips and changes existing pixels. A second 16bit parameter in the FOBJ header indicates how to do the pixel changes: either by specifying a LUT in the codec datastream or by adding a constant value to the pixel. Signed-off-by: Manuel Lauss > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=77b5a0c13422cb67c1194c3b423d18b2339b0499 --- libavcodec/sanm.c | 66 +-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index 3fa6c334df..6302c62f43 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -292,6 +292,7 @@ typedef struct SANMVideoContext { int8_t p4x4glyphs[NGLYPHS][16]; int8_t p8x8glyphs[NGLYPHS][64]; uint8_t c47itbl[0x1]; +uint8_t c23lut[256]; } SANMVideoContext; typedef struct SANMFrameHeader { @@ -557,6 +558,62 @@ static int rle_decode(SANMVideoContext *ctx, uint8_t *dst, const int out_size) return 0; } +static int old_codec23(SANMVideoContext *ctx, int top, int left, int width, + int height, uint8_t param, uint16_t param2) +{ +const uint32_t maxpxo = ctx->height * ctx->pitch; +uint8_t *dst, lut[256], c; +int i, j, k, pc, sk; +int32_t pxoff; + +if (ctx->subversion < 2) { +/* Rebel Assault 1: constant offset + 0xd0 */ +for (i = 0; i < 256; i++) +lut[i] = (i + param + 0xd0) & 0xff; +} else if (param2 == 256) { +if (bytestream2_get_bytes_left(&ctx->gb) < 256) +return AVERROR_INVALIDDATA; +bytestream2_get_bufferu(&ctx->gb, ctx->c23lut, 256); +} else if (param2 < 256) { +for (i = 0; i < 256; i++) +lut[i] = (i + param2) & 0xff; +} else { +memcpy(lut, ctx->c23lut, 256); +} +if (bytestream2_get_bytes_left(&ctx->gb) < 1) +return 0; /* some c23 frames just set up the LUT */ + +dst = (uint8_t *)ctx->frm0; +for (i = 0; i < height; i++) { +if (bytestream2_get_bytes_left(&ctx->gb) < 2) +return 0; +pxoff = left + ((top + i) * ctx->pitch); +k = bytestream2_get_le16u(&ctx->gb); +sk = 1; +pc = 0; +while (k > 0 && pc <= width) { +if (bytestream2_get_bytes_left(&ctx->gb) < 1) +return AVERROR_INVALIDDATA; +j = bytestream2_get_byteu(&ctx->gb); +if (sk) { +pxoff += j; +pc += j; +} else { +while (j--) { +if (pxoff >=0 && pxoff < maxpxo) { +c = *(dst + pxoff); +*(dst + pxoff) = lut[c]; +} +pxoff++; +pc++; +} +} +sk ^= 1; +} +} +return 0; +} + static int old_codec1(SANMVideoContext *ctx, int top, int left, int width, int height, int opaque) { @@ -1258,11 +1315,15 @@ static int old_codec48(SANMVideoContext *ctx, int width, int height) static int process_frame_obj(SANMVideoContext *ctx) { -uint16_t codec = bytestream2_get_le16u(&ctx->gb); +uint16_t parm2; +uint8_t codec = bytestream2_get_byteu(&ctx->gb); +uint8_t param = bytestream2_get_byteu(&ctx->gb); int16_t left = bytestream2_get_le16u(&ctx->gb); int16_t top = bytestream2_get_le16u(&ctx->gb); uint16_t w = bytestream2_get_le16u(&ctx->gb); uint16_t h = bytestream2_get_le16u(&ctx->gb); +bytestream2_skip(&ctx->gb, 2); +parm2 = bytestream2_get_le16u(&ctx->gb); if (w < 1 || h < 1 || w > 800 || h > 600 || left > 800 || top > 600) { av_log(ctx->avctx, AV_LOG_WARNING, @@ -1316,7 +1377,6 @@ static int process_frame_obj(SANMVideoContext *ctx) h = ctx->height; } } -bytestream2_skip(&ctx->gb, 4); /* on first FOBJ, when the codec is not one of the * full-buffer codecs (37/47/48), frm0 needs to be cleared. @@ -1333,6 +1393,8 @@ static int process_frame_obj(SANMVideoContext *ctx) return old_codec1(ctx, top, left, w, h, codec == 3); case 2: return old_codec2(ctx, top, left, w, h); +case 23: +return old_codec23(ctx, top, left, w, h, param, parm2); case 37: return old_codec37(ctx, w, h); case 47: ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avcodec/sanm: better frame size detection for old codecs
ffmpeg | branch: master | Manuel Lauss | Tue Mar 11 12:31:37 2025 +0100| [93b0ca26acb912b8f080f221f6165542806bceb3] | committer: Manuel Lauss avcodec/sanm: better frame size detection for old codecs The size of the video frame (FOBJ) of the old codecs (ANIMv0/1/2) can very reliably be determined: - ANIMv0/1 (=Rebel Assault 1) uses a 384x242 internal buffer for everything. The codec parameters only describe the size and offset of the specific FOBJ on that buffer. - ANIMv2 titles usually use one of the fullscreen codecs (37/47/48) as first FOBJ, and their dimensions can generally be trusted. - RA2 uses 424x260 as internal buffer, use that if encountered: 08PLAY.SAN does not use codec37 so we need to guess using the codec coordinates. - ignore sizes smaller than 2x2 or larger than 800x600. - some game videos have an initial fobj with either 1x1 or -1x-1 pixels in size, ignore them with a warning (Full Throttle and the Rebel Assault 2 xxRETRY.SAN videos). Once a known/valid dimension set has been discovered, use it and don't change it for subsequent FOBJs, rather clamp the large frame to the determined dimensions. Tested with RA1, RA2, Full Throttle, Dig, Outlaws, SotE and MotS videos. Signed-off-by: Manuel Lauss > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=93b0ca26acb912b8f080f221f6165542806bceb3 --- libavcodec/sanm.c | 63 ++- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index 65ca525b9d..38cdb533eb 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -264,7 +264,7 @@ typedef struct SANMVideoContext { AVCodecContext *avctx; GetByteContext gb; -int version, subversion; +int version, subversion, have_dimensions; uint32_t pal[PALETTE_SIZE]; int16_t delta_pal[PALETTE_DELTA]; @@ -1244,21 +1244,56 @@ static int process_frame_obj(SANMVideoContext *ctx) uint16_t w = bytestream2_get_le16u(&ctx->gb); uint16_t h = bytestream2_get_le16u(&ctx->gb); -if (!w || !h) { -av_log(ctx->avctx, AV_LOG_ERROR, "Dimensions are invalid.\n"); -return AVERROR_INVALIDDATA; +if (w < 1 || h < 1 || w > 800 || h > 600 || left > 800 || top > 600) { +av_log(ctx->avctx, AV_LOG_WARNING, + "ignoring invalid fobj dimensions: c%d %d %d @ %d %d\n", + codec, w, h, left, top); +return 0; } -if (ctx->width < left + w || ctx->height < top + h) { -int ret = ff_set_dimensions(ctx->avctx, FFMAX(left + w, ctx->width), -FFMAX(top + h, ctx->height)); -if (ret < 0) -return ret; -init_sizes(ctx, FFMAX(left + w, ctx->width), - FFMAX(top + h, ctx->height)); -if (init_buffers(ctx)) { -av_log(ctx->avctx, AV_LOG_ERROR, "Error resizing buffers.\n"); -return AVERROR(ENOMEM); +if (!ctx->have_dimensions) { +int xres, yres; +if (ctx->subversion < 2) { +/* Rebel Assault 1: 384x242 internal size */ +xres = 384; +yres = 242; +ctx->have_dimensions = 1; +} else if (codec == 37 || codec == 47 || codec == 48) { +/* these codecs work on full frames, trust their dimensions */ +xres = w; +yres = h; +ctx->have_dimensions = 1; +} else { +/* Rebel Assault 2: 424x260 internal size */ +if (((left + w) == 424) && ((top + h) == 260)) +ctx->have_dimensions = 1; + +xres = FFMAX(left + w, ctx->width); +yres = FFMAX(top + h, ctx->height); +} + +if (ctx->width < xres || ctx->height < yres) { +int ret = ff_set_dimensions(ctx->avctx, xres, yres); +if (ret < 0) +return ret; +init_sizes(ctx, xres, yres); +if (init_buffers(ctx)) { +av_log(ctx->avctx, AV_LOG_ERROR, "Error resizing buffers.\n"); +return AVERROR(ENOMEM); +} +} +} else { +if (((left + w > ctx->width) || (top + h > ctx->height)) +&& (codec >= 37)) { +/* correct unexpected overly large frames: this happens + * for instance with The Dig's sq1.san video: it has a few + * (all black) 640x480 frames halfway in, while the rest is + * 320x200. + */ +av_log(ctx->avctx, AV_LOG_WARNING, + "resizing too large fobj: c%d %d %d @ %d %d\n", codec, w, h, left, top); +w = ctx->width; +h = ctx->height; } } bytestream2_skip(&ctx->gb, 4); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "
[FFmpeg-cvslog] avcodec/sanm: ignore codec45
ffmpeg | branch: master | Manuel Lauss | Fri Mar 14 22:26:46 2025 +0100| [fd6bfaab55148a7e016fb77f31cf177d31e5568f] | committer: Manuel Lauss avcodec/sanm: ignore codec45 Codec45 is used in some RA2 videos on top of codec37. It consists of 2 tables (768 and 32768 bytes), and datapackets like codec2 (delta-x, delta-y) with a pixel counter instead of a color value. It then reads the 4 surrounding pixels, looks up 3 separate values for each in table1, adds them together to form an index into table2 for a new pixel value, in a row. The data coming in gets the x/y coordinates out of the visible area very quickly (2-3 iterations); I don't see any visual difference between the ffmpeg-produced frames and ones captured with dosbox from rebel assault 2, which leads me to believe this codec never worked as intended. Signed-off-by: Manuel Lauss > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=fd6bfaab55148a7e016fb77f31cf177d31e5568f --- libavcodec/sanm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index e3f4112756..91be83029f 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -1673,6 +1673,8 @@ static int process_frame_obj(SANMVideoContext *ctx, GetByteContext *gb) return old_codec23(ctx, gb, top, left, w, h, param, parm2); case 37: return old_codec37(ctx, w, h); +case 45: +return 0; case 47: return old_codec47(ctx, w, h); case 48: ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avcodec/sanm: codec2 decoder
ffmpeg | branch: master | Manuel Lauss | Tue Mar 11 13:32:21 2025 +0100| [968ffbe64a6f8a93a84cb99cedae0fc4ba8c5fb9] | committer: Manuel Lauss avcodec/sanm: codec2 decoder this codec consists of 4 byte packets: 2bytes delta-x, 1 byte delta-y and 1 byte color to put at that spot. Used in Rebel Assault 1 only. Signed-off-by: Manuel Lauss > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=968ffbe64a6f8a93a84cb99cedae0fc4ba8c5fb9 --- libavcodec/sanm.c | 20 1 file changed, 20 insertions(+) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index e1471211d6..3fa6c334df 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -607,6 +607,24 @@ static int old_codec1(SANMVideoContext *ctx, int top, return 0; } +static int old_codec2(SANMVideoContext *ctx, int top, + int left, int width, int height) +{ +uint8_t *dst = (uint8_t *)ctx->frm0, col; +int16_t xpos = left, ypos = top; + +while (bytestream2_get_bytes_left(&ctx->gb) > 3) { +xpos += bytestream2_get_le16u(&ctx->gb); +ypos += bytestream2_get_byteu(&ctx->gb); +col = bytestream2_get_byteu(&ctx->gb); +if (xpos >= 0 && ypos >= 0 && +xpos < ctx->width && ypos < ctx->height) { +*(dst + xpos + ypos * ctx->pitch) = col; +} +} +return 0; +} + static inline void codec37_mv(uint8_t *dst, const uint8_t *src, int height, int stride, int x, int y) { @@ -1313,6 +1331,8 @@ static int process_frame_obj(SANMVideoContext *ctx) case 1: case 3: return old_codec1(ctx, top, left, w, h, codec == 3); +case 2: +return old_codec2(ctx, top, left, w, h); case 37: return old_codec37(ctx, w, h); case 47: ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avcodec/sanm: fix codec3
ffmpeg | branch: master | Manuel Lauss | Tue Mar 11 13:02:14 2025 +0100| [aa2f2befaa786b4b0970c08b2837c07ff77ebabc] | committer: Manuel Lauss avcodec/sanm: fix codec3 codec3 is codec1 which writes zero values instead of skipping them. This fixes a lot of RA1 videos. Signed-off-by: Manuel Lauss > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=aa2f2befaa786b4b0970c08b2837c07ff77ebabc --- libavcodec/sanm.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index 395548ee2d..e1471211d6 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -558,7 +558,7 @@ static int rle_decode(SANMVideoContext *ctx, uint8_t *dst, const int out_size) } static int old_codec1(SANMVideoContext *ctx, int top, - int left, int width, int height) + int left, int width, int height, int opaque) { int i, j, len, flag, code, val, end, pxoff; const int maxpxo = ctx->height * ctx->pitch; @@ -581,7 +581,7 @@ static int old_codec1(SANMVideoContext *ctx, int top, code = (code >> 1) + 1; if (flag) { val = bytestream2_get_byteu(&ctx->gb); -if (val) { +if (val || opaque) { for (j = 0; j < code; j++) { if (pxoff >= 0 && pxoff < maxpxo) *(dst + pxoff) = val; @@ -595,7 +595,7 @@ static int old_codec1(SANMVideoContext *ctx, int top, return AVERROR_INVALIDDATA; for (j = 0; j < code; j++) { val = bytestream2_get_byteu(&ctx->gb); -if ((pxoff >= 0) && (pxoff < maxpxo) && val) +if ((pxoff >= 0) && (pxoff < maxpxo) && (val || opaque)) *(dst + pxoff) = val; pxoff++; } @@ -1312,7 +1312,7 @@ static int process_frame_obj(SANMVideoContext *ctx) switch (codec) { case 1: case 3: -return old_codec1(ctx, top, left, w, h); +return old_codec1(ctx, top, left, w, h, codec == 3); case 37: return old_codec37(ctx, w, h); case 47: ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avutil/tests/pixfmt_best: add more semi planar format tests
ffmpeg | branch: master | James Almer | Sun Mar 16 18:30:31 2025 -0300| [f7e6070c5130644cbf0af17a9485a97e9aca051e] | committer: James Almer avutil/tests/pixfmt_best: add more semi planar format tests Signed-off-by: James Almer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=f7e6070c5130644cbf0af17a9485a97e9aca051e --- libavutil/tests/pixfmt_best.c | 22 ++ tests/ref/fate/pixfmt_best| 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/libavutil/tests/pixfmt_best.c b/libavutil/tests/pixfmt_best.c index fb16fe6f2f..5f6d510c4d 100644 --- a/libavutil/tests/pixfmt_best.c +++ b/libavutil/tests/pixfmt_best.c @@ -43,6 +43,12 @@ static const enum AVPixelFormat semiplanar_list[] = { AV_PIX_FMT_P016, AV_PIX_FMT_P012, AV_PIX_FMT_P010, +AV_PIX_FMT_P216, +AV_PIX_FMT_P210, +AV_PIX_FMT_NV16, +AV_PIX_FMT_P416, +AV_PIX_FMT_P410, +AV_PIX_FMT_NV24, AV_PIX_FMT_NV12, }; @@ -118,8 +124,16 @@ int main(void) TEST(AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_MONOWHITE); TEST(AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P); TEST(AV_PIX_FMT_P010, AV_PIX_FMT_YUV420P10); +TEST(AV_PIX_FMT_P012, AV_PIX_FMT_YUV420P16); TEST(AV_PIX_FMT_P016, AV_PIX_FMT_YUV420P16); +TEST(AV_PIX_FMT_P210, AV_PIX_FMT_YUV422P10); +TEST(AV_PIX_FMT_P212, AV_PIX_FMT_YUV422P16); +TEST(AV_PIX_FMT_P216, AV_PIX_FMT_YUV422P16); +TEST(AV_PIX_FMT_P410, AV_PIX_FMT_YUV444P10); +TEST(AV_PIX_FMT_P412, AV_PIX_FMT_YUV444P16); +TEST(AV_PIX_FMT_P416, AV_PIX_FMT_YUV444P16); TEST(AV_PIX_FMT_NV16, AV_PIX_FMT_YUV422P); +TEST(AV_PIX_FMT_NV20, AV_PIX_FMT_YUV422P10); TEST(AV_PIX_FMT_NV24, AV_PIX_FMT_YUV444P); TEST(AV_PIX_FMT_YUYV422, AV_PIX_FMT_YUV422P); TEST(AV_PIX_FMT_UYVY422, AV_PIX_FMT_YUV422P); @@ -197,6 +211,14 @@ int main(void) TEST_SEMIPLANAR(AV_PIX_FMT_YUV420P12, AV_PIX_FMT_P012); TEST_SEMIPLANAR(AV_PIX_FMT_YUV420P16, AV_PIX_FMT_P016); TEST_SEMIPLANAR(AV_PIX_FMT_YUV420P9, AV_PIX_FMT_P010); +TEST_SEMIPLANAR(AV_PIX_FMT_YUV422P, AV_PIX_FMT_NV16); +TEST_SEMIPLANAR(AV_PIX_FMT_YUV422P10, AV_PIX_FMT_P210); +TEST_SEMIPLANAR(AV_PIX_FMT_YUV422P12, AV_PIX_FMT_P216); +TEST_SEMIPLANAR(AV_PIX_FMT_YUV422P16, AV_PIX_FMT_P216); +TEST_SEMIPLANAR(AV_PIX_FMT_YUV444P, AV_PIX_FMT_NV24); +TEST_SEMIPLANAR(AV_PIX_FMT_YUV444P10, AV_PIX_FMT_P410); +TEST_SEMIPLANAR(AV_PIX_FMT_YUV444P12, AV_PIX_FMT_P416); +TEST_SEMIPLANAR(AV_PIX_FMT_YUV444P16, AV_PIX_FMT_P416); #define TEST_PACKED(input, expected) \ test(input, expected, &pass, &fail, find_best_packed) diff --git a/tests/ref/fate/pixfmt_best b/tests/ref/fate/pixfmt_best index 90ced69245..89092cc850 100644 --- a/tests/ref/fate/pixfmt_best +++ b/tests/ref/fate/pixfmt_best @@ -1 +1 @@ -113 tests passed, 0 tests failed. +135 tests passed, 0 tests failed. ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] swscale/input: add support for NV20
ffmpeg | branch: master | James Almer | Sun Mar 16 16:52:29 2025 -0300| [2f856b488bfa72b0291c9710136498b8ee876485] | committer: James Almer swscale/input: add support for NV20 Signed-off-by: James Almer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2f856b488bfa72b0291c9710136498b8ee876485 --- libswscale/format.c | 2 ++ libswscale/input.c | 37 +++-- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/libswscale/format.c b/libswscale/format.c index c3ef499438..fd0269a23e 100644 --- a/libswscale/format.c +++ b/libswscale/format.c @@ -226,6 +226,8 @@ static const FormatEntry format_entries[] = { [AV_PIX_FMT_Y216LE] = { 1, 1 }, [AV_PIX_FMT_X2RGB10LE] = { 1, 1 }, [AV_PIX_FMT_X2BGR10LE] = { 1, 1 }, +[AV_PIX_FMT_NV20BE] = { 1, 0 }, +[AV_PIX_FMT_NV20LE] = { 1, 0 }, [AV_PIX_FMT_P210BE] = { 1, 1 }, [AV_PIX_FMT_P210LE] = { 1, 1 }, [AV_PIX_FMT_P212BE] = { 1, 1 }, diff --git a/libswscale/input.c b/libswscale/input.c index cab8de6d3f..aa3cfebc87 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -945,8 +945,9 @@ static void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV, nvXXtoUV_c(dstV, dstU, src1, width); } -#define p01x_uv_wrapper(bits, shift) \ -static void p0 ## bits ## LEToUV_c(uint8_t *dstU, uint8_t *dstV, \ +#define p01x_uv_wrapper(fmt, shift) \ +static void fmt ## LEToUV ## _c(uint8_t *dstU, \ + uint8_t *dstV,\ const uint8_t *unused0, \ const uint8_t *src1, \ const uint8_t *src2, int width, \ @@ -959,7 +960,8 @@ static void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV, }\ }\ \ -static void p0 ## bits ## BEToUV_c(uint8_t *dstU, uint8_t *dstV, \ +static void fmt ## BEToUV ## _c(uint8_t *dstU, \ + uint8_t *dstV,\ const uint8_t *unused0, \ const uint8_t *src1, \ const uint8_t *src2, int width, \ @@ -972,8 +974,9 @@ static void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV, }\ } -#define p01x_wrapper(bits, shift) \ -static void p0 ## bits ## LEToY_c(uint8_t *dst, const uint8_t *src, \ +#define p01x_wrapper(fmt, shift) \ +static void fmt ## LEToY ## _c(uint8_t *dst, \ + const uint8_t *src,\ const uint8_t *unused1,\ const uint8_t *unused2, int width, \ uint32_t *unused, void *opq) \ @@ -984,7 +987,8 @@ static void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV, }\ }\ \ -static void p0 ## bits ## BEToY_c(uint8_t *dst, const uint8_t *src, \ +static void fmt ## BEToY ## _c(uint8_t *dst, \ + const uint8_t *src,\ const uint8_t *unused1,\ const uint8_t *unused2, int width, \ uint32_t *unused, void *opq) \ @@ -994,11 +998,12 @@ static void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV, AV_WN16(dst + i * 2, AV_RB16(src + i * 2) >> shift); \ }\ }\ -p01x_uv_wrapper(bits, shift) +p01x_uv_wrapper(fmt, shift) -p01x_wrapper(10, 6) -p01x_wrapper(12, 4) -p01x_uv_wrapper(16, 0) +p01x_wrapper(nv20, 0) +p01x_wrapper(p010, 6) +p01x_wrapper(p012, 4) +p01x_uv_wrapper(p016, 0) static void bgr24ToY_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2, int width, uint32_t *rgb2yuv, void *opq) @@ -1910,11 +1915,17 @@ av_cold void ff_sws_init_input_funcs(SwsInternal *c, case AV_PIX_FMT_XV48BE: *chrToYV12 = read_xv48be_UV_c; break; +case AV_PIX_FMT_NV20LE: +*chrToYV12 = nv20LEToUV_c; +break; case AV_PIX_FMT_P0