Re: [FFmpeg-devel] [PATCH] avdevice/alsa: simplify passing ff_alsa_open a channel layout
James Almer (12025-02-07): > This also ensures the layout set during the indev init is used instead of the > blank one in st->codecpar. No objection to the patch, but you were the one who added the access to st->codecpar, so that needs an explanation in the commit message. -- Nicolas George ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2] avfilter/scale*: add option reset_sar
On 2025-02-09 03:41 pm, Gyan Doshi wrote: For anamorphic videos, enabling this option leads to adjustment of output dimensions to obtain square pixels when the user requests proportional scaling through either of the w/h expressions or force_original_aspect_ratio. Output SAR is always reset to 1. Option added to scale, scale_cuda, scale_npp & scale_vaapi. libplacebo already has a similar option with different semantics, scale_vt and scale_vulkan don't implement force_oar, so for these three filters, I've made minimal changes needed to not break building or change output. --- v2: Rewrote doc option description Added doc examples w_adj init nit resolved Pushed as a28dc06869fe1f98c07e42f9b0a411d2744ff7d7 Regards, Gyan doc/filters.texi | 36 +-- libavfilter/scale_eval.c | 13 +++-- libavfilter/scale_eval.h | 5 - libavfilter/vf_libplacebo.c | 2 +- libavfilter/vf_scale.c| 13 +++-- libavfilter/vf_scale_cuda.c | 25 ++-- libavfilter/vf_scale_npp.c| 13 +++-- libavfilter/vf_scale_vaapi.c | 13 +++-- libavfilter/vf_scale_vt.c | 2 +- libavfilter/vf_scale_vulkan.c | 2 +- 10 files changed, 100 insertions(+), 24 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index a14c7e7e77..bf9a60712f 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -21285,6 +21285,14 @@ This option can be handy if you need to have a video fit within or exceed a defined resolution using @option{force_original_aspect_ratio} but also have encoder restrictions on width or height divisibility. +@item reset_sar +Enabling this option leads to the output SAR being reset to 1. +Additionally, if the user requests proportional scaling either +through the width or height expressions, e.g. @code{w=-4:h=360} or @code{w=iw/2:h=-1} +or by enabling @code{force_original_aspect_ratio}, then the input DAR is taken into +account and the output is scaled to produce square pixels. +Default is false. + @end table The values of the @option{w} and @option{h} options are expressions @@ -21445,10 +21453,28 @@ scale='trunc(ih*dar):ih',setsar=1/1 @end example @item -Make pixels square by combining scale and setsar, +Make pixels square using reset_sar, making sure the resulting resolution is even (required by some codecs): @example -scale='trunc(ih*dar/2)*2:trunc(ih/2)*2',setsar=1/1 +scale='-2:ih-mod(ih,2):reset_sar=1' +@end example + +@item +Scale to target exactly, however reset SAR to 1: +@example +scale='400:300:reset_sar=1' +@end example + +@item +Scale to even dimensions that fit within 400x300, preserving input SAR: +@example +scale='400:300:force_original_aspect_ratio=decrease:force_divisible_by=2' +@end example + +@item +Scale to produce square pixels with even dimensions that fit within 400x300: +@example +scale='400:300:force_original_aspect_ratio=decrease:force_divisible_by=2:reset_sar=1' @end example @item @@ -21538,6 +21564,9 @@ Affects the curves of the bicubic algorithm. @item force_divisible_by Work the same as the identical @ref{scale} filter options. +@item reset_sar +Works the same as the identical @ref{scale} filter option. + @end table @subsection Examples @@ -21641,6 +21670,9 @@ This option can be handy if you need to have a video fit within or exceed a defined resolution using @option{force_original_aspect_ratio} but also have encoder restrictions on width or height divisibility. +@item reset_sar +Works the same as the identical @ref{scale} filter option. + @item eval Specify when to evaluate @var{width} and @var{height} expression. It accepts the following values: diff --git a/libavfilter/scale_eval.c b/libavfilter/scale_eval.c index dc8d522b1e..53f5e22b0e 100644 --- a/libavfilter/scale_eval.c +++ b/libavfilter/scale_eval.c @@ -112,7 +112,8 @@ fail: int ff_scale_adjust_dimensions(AVFilterLink *inlink, int *ret_w, int *ret_h, -int force_original_aspect_ratio, int force_divisible_by) +int force_original_aspect_ratio, int force_divisible_by, +double w_adj) { int64_t w, h; int factor_w, factor_h; @@ -132,7 +133,7 @@ int ff_scale_adjust_dimensions(AVFilterLink *inlink, } if (w < 0 && h < 0) { -w = inlink->w; +w = inlink->w * w_adj; h = inlink->h; } @@ -140,18 +141,18 @@ int ff_scale_adjust_dimensions(AVFilterLink *inlink, * earlier. If no factor was set, nothing will happen as the default * factor is 1 */ if (w < 0) -w = av_rescale(h, inlink->w, inlink->h * factor_w) * factor_w; +w = av_rescale(h, inlink->w * w_adj, inlink->h * factor_w) * factor_w; if (h < 0) -h = av_rescale(w, inlink->h, inlink->w * factor_h) * factor_h; +h = av_rescale(w, inlink->h, inlink->w * w_adj * factor_h) * factor_h; /* Note that force_original_aspect_ratio may overwrite
[FFmpeg-devel] H.261 patch to detect Iframe in H.261 decoder
It's enclosed ! 0001-Fix-h261-I-frame-detection.patch Description: Binary data ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] checkasm/v210enc.c: Use checkasm_check_type
On Mon, Feb 10, 2025 at 12:40 PM Martin Storsjö wrote: > > On Sat, 8 Feb 2025, Kieran Kunhya via ffmpeg-devel wrote: > > > $subj > > > -if (memcmp(y0, y1, BUF_SIZE * sizeof(type)) > > \ > > -|| memcmp(u0, u1, BUF_SIZE * sizeof(type) / 2) > > \ > > -|| memcmp(v0, v1, BUF_SIZE * sizeof(type) / 2) > > \ > > -|| memcmp(dst0, dst1, width * 8 / 3)) > > \ > > +if (checkasm_check_##type(NULL, 0, y0, 0, y1, 0, BUF_SIZE, 0, > > NULL) \ > > +|| checkasm_check_##type(NULL, 0, u0, 0, u1, 0, > > BUF_SIZE / 2, 0, NULL) \ > > +|| checkasm_check_##type(NULL, 0, v0, 0, v1, 0, > > BUF_SIZE / 2, 0, NULL) \ > > +|| checkasm_check_uint8_t(NULL, 0, dst0, 0, dst1, 0, > > (width * 8 / 3), 0, NULL)) \ > > This actually doesn't detect any failures at all; you're passing it > parameters for checking a buffer of BUF_SIZE width and 0 height, so it > doesn't check anything. > > By passing height 1, it does seem to work as intended (detecting an > intentionally added error in the asm). > > It feels a little bit unwieldy to check (and print out, if checkasm is run > with "-v") the whole BUF_SIZE, but it's good to have testing for potential > writes out of bounds at least, like before. > > Further in dav1d there are more improvements to these checkasm helpers, > which we haven't backported to ffmpeg yet, that helps with allocating > padded buffers and checking that the padding isn't overwritten; that would > allow reducing the size of the checked area, to make it easier to read on > errors too. > > But until that's backported, I guess this is fine, if you change the > height to 1. > > // Martin > Sorry yes I had that fixed locally. I also noticed it was a lot of data to print the whole BUF_SIZE. Kieran ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avdevice/alsa: simplify passing ff_alsa_open a channel layout
On 2/10/2025 6:20 AM, Nicolas George wrote: James Almer (12025-02-07): This also ensures the layout set during the indev init is used instead of the blank one in st->codecpar. No objection to the patch, but you were the one who added the access to st->codecpar, so that needs an explanation in the commit message. No, i did not. ff_alsa_open() was already accessing it for channel_layout before ffc4fd3cc2, which was also blank. OpenPGP_signature.asc Description: OpenPGP digital signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avcodec/aarch64/opusdsp_neon: Simplify opus_postfilter_neon
On Sat, 8 Feb 2025, Krzysztof Pyrkosz via ffmpeg-devel wrote: On Sat, Feb 08, 2025 at 01:59:32AM +0100, Lynne wrote: On 07/02/2025 20:42, Krzysztof Pyrkosz via ffmpeg-devel wrote: This change removes one extra floating point operation and simplifies load operations at the beginning of the loop by using dedicated register for each of the 5 pointers and interleaving it with calculations. The first case seems to be a bit slower, but the performance increase is substantial in the other two. A78 before: postfilter_15_neon: 1684.8 ( 4.23x) postfilter_512_neon: 1395.5 ( 5.10x) postfilter_1022_neon: 1357.0 ( 5.25x) After: postfilter_15_neon: 1742.2 ( 4.09x) postfilter_512_neon: 1169.8 ( 6.09x) postfilter_1022_neon: 1160.0 ( 6.12x) A72 before: postfilter_15_neon: 3144.8 ( 2.39x) postfilter_512_neon: 3141.2 ( 2.39x) postfilter_1022_neon: 3230.0 ( 2.33x) After: postfilter_15_neon: 2847.8 ( 2.64x) postfilter_512_neon: 2877.8 ( 2.61x) postfilter_1022_neon: 2837.2 ( 2.65x) x13s before: postfilter_15_neon: 1615.4 ( 2.61x) postfilter_512_neon: 963.1 ( 4.39x) postfilter_1022_neon: 963.6 ( 4.39x) After: postfilter_15_neon: 1749.6 ( 2.41x) postfilter_512_neon: 707.1 ( 5.97x) postfilter_1022_neon: 706.1 ( 5.99x) Krzysztof --- libavcodec/aarch64/opusdsp_neon.S | 31 --- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/libavcodec/aarch64/opusdsp_neon.S b/libavcodec/aarch64/opusdsp_neon.S index 253825aa61..990fc44c70 100644 --- a/libavcodec/aarch64/opusdsp_neon.S +++ b/libavcodec/aarch64/opusdsp_neon.S @@ -55,35 +55,28 @@ endfunc function ff_opus_postfilter_neon, export=1 ld1 {v0.4s}, [x2] +sub x5, x0, w1, sxtw #2 +sub x1, x5, #8 dup v1.4s, v0.s[1] dup v2.4s, v0.s[2] dup v0.4s, v0.s[0] -add w1, w1, #2 -sub x1, x0, x1, lsl #2 - -ld1 {v3.4s}, [x1] +ld1 {v3.4s}, [x1], #16 +sub x4, x5, #4 +add x6, x5, #4 fmulv3.4s, v3.4s, v2.4s -1: add x1, x1, #4 -ld1 {v4.4s}, [x1] -add x1, x1, #4 -ld1 {v5.4s}, [x1] -add x1, x1, #4 -ld1 {v6.4s}, [x1] -add x1, x1, #4 -ld1 {v7.4s}, [x1] - +1: ld1 {v7.4s}, [x1], #16 +ld1 {v4.4s}, [x4], #16 fmlav3.4s, v7.4s, v2.4s +ld1 {v6.4s}, [x6], #16 +ld1 {v5.4s}, [x5], #16 faddv6.4s, v6.4s, v4.4s +fmlav3.4s, v5.4s, v0.4s ld1 {v4.4s}, [x0] -fmlav4.4s, v5.4s, v0.4s - -fmulv6.4s, v6.4s, v1.4s -faddv6.4s, v6.4s, v3.4s - -faddv4.4s, v4.4s, v6.4s +fmlav3.4s, v6.4s, v1.4s +faddv4.4s, v4.4s, v3.4s fmulv3.4s, v7.4s, v2.4s st1 {v4.4s}, [x0], #16 This function was written and optimized for A53 cores. The fmla chain is very performance sensitive on in-order CPUs? Could you post a perf difference from an in-order CPU? Here are my benchmarks on Raspberry Pi 3B+. Before: deemphasis_neon: 4121.8 ( 2.11x) postfilter_15_neon: 9405.2 ( 2.46x) postfilter_512_neon: 9457.0 ( 2.44x) postfilter_1022_neon: 9398.0 ( 2.46x) After: deemphasis_neon: 4135.8 ( 2.10x) postfilter_15_neon: 7967.2 ( 2.90x) postfilter_512_neon: 7980.2 ( 2.89x) postfilter_1022_neon: 7980.0 ( 2.89x) I'm also getting similar numbers on another A53. This patch looks good to me, so I pushed it. Thanks! // Martin ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] avfilter/vf_amf_common: implement reset_sar options
Implements the new reset_sar option from a28dc06869fe1f98c07e42f9b0a411d2744ff7d7. While at it, this also moves assigning the output sar on the outlink from the filter frame function to config props. --- libavfilter/vf_amf_common.c | 18 -- libavfilter/vf_amf_common.h | 1 + libavfilter/vf_vpp_amf.c| 5 +++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/libavfilter/vf_amf_common.c b/libavfilter/vf_amf_common.c index fbf364eac1..75339c9f01 100644 --- a/libavfilter/vf_amf_common.c +++ b/libavfilter/vf_amf_common.c @@ -158,11 +158,6 @@ int amf_filter_filter_frame(AVFilterLink *inlink, AVFrame *in) goto fail; } -if (inlink->sample_aspect_ratio.num) { -outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink->w, outlink->w * inlink->h}, inlink->sample_aspect_ratio); -} else -outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; - av_frame_free(&in); return ff_filter_frame(outlink, out); fail: @@ -274,6 +269,7 @@ int amf_init_filter_config(AVFilterLink *outlink, enum AVPixelFormat *in_format) enum AVPixelFormat out_sw_format = ctx->format; FilterLink*inl = ff_filter_link(inlink); FilterLink*outl = ff_filter_link(outlink); +double w_adj = 1.0; if ((err = ff_scale_eval_dimensions(avctx, ctx->w_expr, ctx->h_expr, @@ -281,8 +277,11 @@ int amf_init_filter_config(AVFilterLink *outlink, enum AVPixelFormat *in_format) &ctx->width, &ctx->height)) < 0) return err; +if (ctx->reset_sar && inlink->sample_aspect_ratio.num) +w_adj = (double)inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den; + ff_scale_adjust_dimensions(inlink, &ctx->width, &ctx->height, - ctx->force_original_aspect_ratio, ctx->force_divisible_by, 1.0); + ctx->force_original_aspect_ratio, ctx->force_divisible_by, w_adj); av_buffer_unref(&ctx->amf_device_ref); av_buffer_unref(&ctx->hwframes_in_ref); @@ -343,6 +342,13 @@ int amf_init_filter_config(AVFilterLink *outlink, enum AVPixelFormat *in_format) outlink->w = ctx->width; outlink->h = ctx->height; +if (ctx->reset_sar) +outlink->sample_aspect_ratio = (AVRational){1, 1}; +else if (inlink->sample_aspect_ratio.num) +outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink->w, outlink->w * inlink->h}, inlink->sample_aspect_ratio); +else +outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; + hwframes_out->width = outlink->w; hwframes_out->height = outlink->h; diff --git a/libavfilter/vf_amf_common.h b/libavfilter/vf_amf_common.h index c4b5ba659a..d0a0214978 100644 --- a/libavfilter/vf_amf_common.h +++ b/libavfilter/vf_amf_common.h @@ -48,6 +48,7 @@ typedef struct AMFFilterContext { char *format_str; int force_original_aspect_ratio; int force_divisible_by; +int reset_sar; AMFComponent*component; AVBufferRef *amf_device_ref; diff --git a/libavfilter/vf_vpp_amf.c b/libavfilter/vf_vpp_amf.c index 87bd68074f..2d9df50632 100644 --- a/libavfilter/vf_vpp_amf.c +++ b/libavfilter/vf_vpp_amf.c @@ -216,11 +216,12 @@ static const AVOption vpp_amf_options[] = { { "smpte428", "SMPTE428", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_COLOR_TRANSFER_CHARACTERISTIC_SMPTE428 }, 0, 0, FLAGS, "trc" }, { "arib-std-b67", "ARIB_STD_B67", 0, AV_OPT_TYPE_CONST, { .i64 = AMF_COLOR_TRANSFER_CHARACTERISTIC_ARIB_STD_B67 }, 0, 0, FLAGS, "trc" }, -{ "force_original_aspect_ratio", "decrease or increase w/h if necessary to keep the original AR", OFFSET(force_original_aspect_ratio), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 2, FLAGS, "force_oar" }, +{ "force_original_aspect_ratio", "decrease or increase w/h if necessary to keep the original AR", OFFSET(force_original_aspect_ratio), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, FLAGS, "force_oar" }, { "disable", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 0, FLAGS, "force_oar" }, { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, "force_oar" }, { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, "force_oar" }, -{ "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1}, 1, 256, FLAGS }, +{ "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 256, FLAGS }, +{ "reset_sar", "reset SAR to 1 and scale to square pixels if scaling proportionally", OFFSET(reset_sar), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS }, { NULL }, }; -- 2.43.0
Re: [FFmpeg-devel] [PATCH] avfilter/vpp_amf: add option reset_sar
On 2025-02-10 05:53 pm, Gyan Doshi wrote: 4b77a0a681 added a new consumer of ff_scale_adjust_dimensions which was recently modified to allow for square pixel output. This commit extends the new option to vpp_amf, and unbreaks the building of vf_amf_common.c Pushed as 7ee4936e0a61ad81c40d7a1afad9a850820213c6 with the outlink SAR assignment shifted as Timo suggested. Regards, Gyan --- doc/filters.texi| 3 +++ libavfilter/vf_amf_common.c | 10 -- libavfilter/vf_amf_common.h | 1 + libavfilter/vf_vpp_amf.c| 1 + 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index d72b0da7f3..4cefef6cbc 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -25796,6 +25796,9 @@ pixel format is used. @item force_divisible_by Work the same as the identical @ref{scale} filter options. +@item reset_sar +Works the same as the identical @ref{scale} filter option. + @anchor{color_profile} @item color_profile Specify all color properties at once. diff --git a/libavfilter/vf_amf_common.c b/libavfilter/vf_amf_common.c index 9c48b4218e..cbc532f822 100644 --- a/libavfilter/vf_amf_common.c +++ b/libavfilter/vf_amf_common.c @@ -158,7 +158,9 @@ int amf_filter_filter_frame(AVFilterLink *inlink, AVFrame *in) goto fail; } -if (inlink->sample_aspect_ratio.num) { +if (ctx->reset_sar) +outlink->sample_aspect_ratio = (AVRational){1, 1}; +else if (inlink->sample_aspect_ratio.num) { outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink->w, outlink->w * inlink->h}, inlink->sample_aspect_ratio); } else outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; @@ -274,6 +276,7 @@ int amf_init_filter_config(AVFilterLink *outlink, enum AVPixelFormat *in_format) enum AVPixelFormat out_sw_format = ctx->format; FilterLink*inl = ff_filter_link(inlink); FilterLink*outl = ff_filter_link(outlink); +double w_adj = 1.0; if ((err = ff_scale_eval_dimensions(avctx, ctx->w_expr, ctx->h_expr, @@ -281,8 +284,11 @@ int amf_init_filter_config(AVFilterLink *outlink, enum AVPixelFormat *in_format) &ctx->width, &ctx->height)) < 0) return err; +if (ctx->reset_sar) +w_adj = inlink->sample_aspect_ratio.num ? (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1.0; + ff_scale_adjust_dimensions(inlink, &ctx->width, &ctx->height, - ctx->force_original_aspect_ratio, ctx->force_divisible_by); + ctx->force_original_aspect_ratio, ctx->force_divisible_by, w_adj); av_buffer_unref(&ctx->amf_device_ref); av_buffer_unref(&ctx->hwframes_in_ref); diff --git a/libavfilter/vf_amf_common.h b/libavfilter/vf_amf_common.h index c4b5ba659a..d0a0214978 100644 --- a/libavfilter/vf_amf_common.h +++ b/libavfilter/vf_amf_common.h @@ -48,6 +48,7 @@ typedef struct AMFFilterContext { char *format_str; int force_original_aspect_ratio; int force_divisible_by; +int reset_sar; AMFComponent*component; AVBufferRef *amf_device_ref; diff --git a/libavfilter/vf_vpp_amf.c b/libavfilter/vf_vpp_amf.c index 87bd68074f..92923a4757 100644 --- a/libavfilter/vf_vpp_amf.c +++ b/libavfilter/vf_vpp_amf.c @@ -221,6 +221,7 @@ static const AVOption vpp_amf_options[] = { { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, "force_oar" }, { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, "force_oar" }, { "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1}, 1, 256, FLAGS }, +{ "reset_sar", "reset SAR to 1 and scale to square pixels if scaling proportionally", OFFSET(reset_sar), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, FLAGS }, { NULL }, }; ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avcodec/amfenc: DX12 Reference-only feature support
Araz Iusubov: >Subject: [FFmpeg-devel] [PATCH] avcodec/amfenc: DX12 Reference-only feature >support > >The Reference-Only feature in DirectX 12 is a memory optimization technique >designed for video decoding scenarios. >This feature requires that reference resources must be allocated with the >D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY resource flag. >Reference textures must also be separated from output textures. >This feature is not supported in the current version of ffmpeg. >Since AMD GPU uses this feature in Direct 12 decoder, ffmpeg does not support >AMD GPU Direct 12 decoding. >To properly support the Reference-Only feature, two parallel resource pools >must >be configured and managed: >General Resource Pool: >Contains resources used for output decoded frames. >Defined in AVHWFramesContext and manages the final decoded textures. >Reference-Only Resource Pool: >Intended for storing reference frame resources. >Resources created with the >D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY flag are allocated >to AVBufferPool. > >--- > libavcodec/d3d12va_decode.c | 58 --- > libavutil/hwcontext_d3d12va.c | 65 --- > 2 files changed, 115 insertions(+), 8 deletions(-) > >diff --git a/libavcodec/d3d12va_decode.c b/libavcodec/d3d12va_decode.c index >3b8978635e..8916f94d10 100644 >--- a/libavcodec/d3d12va_decode.c >+++ b/libavcodec/d3d12va_decode.c >@@ -51,11 +51,19 @@ unsigned ff_d3d12va_get_surface_index(const >AVCodecContext *avctx, > D3D12VADecodeContext *ctx, const > AVFrame *frame, > int curr) { >+AVHWFramesContext *frames_ctx = D3D12VA_FRAMES_CONTEXT(avctx); >+AVD3D12VAFramesContext *frames_hwctx = frames_ctx->hwctx; >+ > AVD3D12VAFrame *f; > ID3D12Resource *res; > unsigned i; > >-f = (AVD3D12VAFrame *)frame->data[0]; >+if (frames_hwctx->flags & >D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY) { >+f = (AVD3D12VAFrame*)frame->data[1]; >+} else { >+f = (AVD3D12VAFrame*)frame->data[0]; >+} >+ > if (!f) > goto fail; > >@@ -250,6 +258,11 @@ static int d3d12va_create_decoder(AVCodecContext >*avctx) > return AVERROR_PATCHWELCOME; > } Need to handle when DecodeTier == D3D12_VIDEO_DECODE_TIER_2? > >+if (feature.ConfigurationFlags & >D3D12_VIDEO_DECODE_CONFIGURATION_FLAG_REFERENCE_ONLY_ALLOCATI >ONS_REQUIRED) { >+frames_hwctx->flags |= >(D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY | >D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE); >+av_log(avctx, AV_LOG_INFO, "Reference-Only Allocations are required >for >this configuration.\n"); >+} >+ > desc = (D3D12_VIDEO_DECODER_DESC) { > .NodeMask = 0, > .Configuration = ctx->cfg, >@@ -440,8 +453,19 @@ int ff_d3d12va_common_end_frame(AVCodecContext >*avctx, AVFrame *frame, > D3D12VADecodeContext *ctx = D3D12VA_DECODE_CONTEXT(avctx); > ID3D12Resource *buffer= NULL; > ID3D12CommandAllocator *command_allocator = NULL; >-AVD3D12VAFrame *f = (AVD3D12VAFrame >*)frame->data[0]; >-ID3D12Resource *resource = (ID3D12Resource *)f->texture; >+AVHWFramesContext *frames_ctx= >D3D12VA_FRAMES_CONTEXT(avctx); >+AVD3D12VAFramesContext *frames_hwctx = frames_ctx->hwctx; >+AVD3D12VAFrame *f = NULL; >+AVD3D12VAFrame *output_data = NULL; >+ >+if (frames_hwctx->flags & >D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY) { >+f = (AVD3D12VAFrame*)frame->data[1]; >+output_data = (AVD3D12VAFrame*)frame->data[0]; >+} else { >+f = (AVD3D12VAFrame*)frame->data[0]; >+} >+ >+ID3D12Resource* resource = (ID3D12Resource*)f->texture; > > ID3D12VideoDecodeCommandList *cmd_list = ctx->command_list; > D3D12_RESOURCE_BARRIER barriers[32] = { 0 }; @@ -469,6 +493,14 @@ int >ff_d3d12va_common_end_frame(AVCodecContext *avctx, AVFrame *frame, > .pOutputTexture2D= resource, > }; > >+if (frames_hwctx->flags & >D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY) { >+output_args.pOutputTexture2D = output_data->texture; >+ >+output_args.ConversionArguments.Enable = 1; >+output_args.ConversionArguments.pReferenceTexture2D = resource; >+output_args.ConversionArguments.ReferenceSubresource = 0; >+} >+ > UINT num_barrier = 1; > barriers[0] = (D3D12_RESOURCE_BARRIER) { > .Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, >@@ -481,6 +513,20 @@ int ff_d3d12va_common_end_frame(AVCodecContext >*avctx, AVFrame *frame, > }, > }; > >+if (frames_hwctx->flags & >D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY) { >+barriers[1] = (D3D12_RESOURCE_BARRIER) { >+.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, >+.Flag
Re: [FFmpeg-devel] [PATCH v2 2/2] checkasm: aacencdsp: Actually test nonzero values in quant_bands
On Fri, 7 Feb 2025, Martin Storsjö wrote: On Wed, 5 Feb 2025, Martin Storsjö wrote: Previously, we read elements from ff_aac_pow34sf_tab; however that table is initialized to zero; one needs to call ff_aac_float_common_init() to make sure that the table is initialized. However, given the range of the input values, a large number of entries in ff_aac_pow34sf_tab would give results outside of the range for signed 32 bit integers. As the largest aac_cb_maxval entry is 16, it seems more reasonable to produce values within an order of mangitude of that value. (When hitting INT_MIN, implementations may end up with different results depending on whether the value is negated as a float or as an int. This corner case is irrelevant in practice as this is way outside of the expected value range here.) Coincidentally, this fixes linking checkasm with Apple's older linker. (In Xcode 15, Apple switched to a new linker. The one in older toolchains seems to have a bug where it won't figure out to load object files from a static library, if the only symbol referenced in the object file is a "common" symbol, i.e. one for a zero-initialized variable. This issue can also be reproduced with newer Apple toolchains by passing -Wl,-ld_classic to the linker.) --- tests/checkasm/aacencdsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/checkasm/aacencdsp.c b/tests/checkasm/aacencdsp.c index 5308a2ac03..713284211c 100644 --- a/tests/checkasm/aacencdsp.c +++ b/tests/checkasm/aacencdsp.c @@ -67,7 +67,7 @@ static void test_abs_pow34(AACEncDSPContext *s) static void test_quant_bands(AACEncDSPContext *s) { int maxval = randomize_elem(aac_cb_maxval); -float q34 = randomize_elem(ff_aac_pow34sf_tab); +float q34 = (float)rnd() / (UINT_MAX / 1024); float rounding = (rnd() & 1) ? ROUND_TO_ZERO : ROUND_STANDARD; LOCAL_ALIGNED_16(float, in, [BUF_SIZE]); LOCAL_ALIGNED_16(float, scaled, [BUF_SIZE]); -- 2.43.0 These changes were OK'd by Lynne on irc, I'll push them later if there's no more feedback on it. (I've tested these changes with thousands of different checkasm seeds now.) Pushed now. // Martin ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] threadprogress: reorder instructions to silence tsan warning.
Hi, On Sat, Feb 8, 2025 at 2:31 PM Ronald S. Bultje wrote: > Hi, > > On Fri, Feb 7, 2025 at 10:50 PM Zhao Zhili < > quinkblack-at-foxmail@ffmpeg.org> wrote: > >> >> >> > On Feb 8, 2025, at 00:05, Ronald S. Bultje wrote: >> > >> > Hi, >> > >> > On Fri, Feb 7, 2025 at 8:44 AM Zhao Zhili < >> > quinkblack-at-foxmail@ffmpeg.org> wrote: >> > >> >>> On Feb 7, 2025, at 21:26, Ronald S. Bultje >> wrote: >> >>> On Fri, Feb 7, 2025 at 6:22 AM Andreas Rheinhardt < >> >>> andreas.rheinha...@outlook.com> wrote: >> Ronald S. Bultje: >> > Fixes #11456. >> > --- >> > libavcodec/threadprogress.c | 3 +-- >> > 1 file changed, 1 insertion(+), 2 deletions(-) >> > >> > diff --git a/libavcodec/threadprogress.c >> b/libavcodec/threadprogress.c >> > index 62c4fd898b..aa72ff80e7 100644 >> > --- a/libavcodec/threadprogress.c >> > +++ b/libavcodec/threadprogress.c >> > @@ -55,9 +55,8 @@ void ff_thread_progress_report(ThreadProgress >> *pro, >> int n) >> >if (atomic_load_explicit(&pro->progress, memory_order_relaxed) >= >> >> n) >> >return; >> > >> > -atomic_store_explicit(&pro->progress, n, memory_order_release); >> > - >> >ff_mutex_lock(&pro->progress_mutex); >> > +atomic_store_explicit(&pro->progress, n, memory_order_release); >> >ff_cond_broadcast(&pro->progress_cond); >> >ff_mutex_unlock(&pro->progress_mutex); >> > } >> >> I don't really understand why this is supposed to fix a race; after >> all, >> the synchronisation of ff_thread_progress_(report|await) is not >> supposed >> to be provided by the mutex (which is avoided altogether in the fast >> path in ff_thread_report_await()), but by storing and loading the >> progress variable. >> That's also the reason why I moved this outside of the mutex >> (compared >> to ff_thread_report_progress(). (This way it is possible for a >> consumer >> thread to see the new progress value earlier and possibly avoid the >> mutex altogether.) >> >>> >> >>> >> >>> The consumer thread already checks the value without the lock. so the >> >>> significance of that last point seems minor to me. This would be >> >> different >> >>> if the wait() counterpart had no lockless path. Or am I missing >> >> something? >> >> >> >> What Andreas says is atomic_store before mutex_lock makes the first >> >> atomic_load in progress_wait has a higher chance to succeed. The >> earlier >> >> progress is set, the higher chance of progress_wait go into the fast >> path. >> > >> > >> > I understand that is true in theory - but I have doubts on whether this >> is >> > in any way significant in practice if wait() already has behaviour to >> > pre-empty locklessly >> > >> > I measured this in the most un-scientific way possible by decoding >> > gizmo.webm (from Firefox' bug report) 10x before and after my patch, >> taking >> > the average and standard deviation, and comparing these with each >> other. I >> > repeated this a couple of times. The values (before vs after avg +/- >> > stddev) are obviously never exactly the same, but they swarm around each >> > other like a random noise generator. Or to say it differently: in my >> highly >> > unscientific test, I see no performance difference. >> > >> > So ... Is this really worth it? >> >> I did another test by measure fast_path / (fast_path + slow_path) on >> macOS of hevc decoding with 10 threads. >> >> 1. Before the patch, it’s 99.741%. >> 2. With the patch, it’s 99.743%. >> 3. With while (atomic_load_explicit(&pro->progress, memory_order_acquire) >> < n), it’s 99.741%. >> >> So, it doesn’t matter for performance. Current patch is the most elegant >> solution in my opinion. > > > Thanks for testing. Andreas, any further thoughts? > After approval from Andreas on IRC, pushed with a slightly improved commit message ("silence tsan warning" -> "fix race"), as suggested by Andreas. Ronald ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] H.261 patch to detect Iframe in H.261 decoder
Jerome GORIN: > -skip_bits1(&s->gb); /* freeze picture release off */ > +intra_flag = get_bits1(&s->gb); /* Intra 1 = I-frame, 0 = P-frame */ > > +if (intra_flag){ > +s->pict_type = AV_PICTURE_TYPE_I; > +}else{ > +s->pict_type = AV_PICTURE_TYPE_P; > +} > + > format = get_bits1(&s->gb); > > // only 2 formats possible > @@ -498,10 +504,8 @@ static int h261_decode_picture_header(H261DecContext *h) > if (skip_1stop_8data_bits(&s->gb) < 0) > return AVERROR_INVALIDDATA; > > -/* H.261 has no I-frames, but if we pass AV_PICTURE_TYPE_I for the first > - * frame, the codec crashes if it does not contain all I-blocks > - * (e.g. when a packet is lost). */ > -s->pict_type = AV_PICTURE_TYPE_P; > + > + H.261 does not guarantee that a picture with the freeze picture release bit set is an actual keyframe; the macroblocks can nevertheless be inter coded (such a bitstream could cause a segfault with your patch because it tries to access references that aren't there). - Andreas ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avcodec/amfenc: DX12 Reference-only feature support
On 30/01/2025 15:09, Araz Iusubov wrote: The Reference-Only feature in DirectX 12 is a memory optimization technique designed for video decoding scenarios. This feature requires that reference resources must be allocated with the D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY resource flag. Reference textures must also be separated from output textures. This feature is not supported in the current version of ffmpeg. Since AMD GPU uses this feature in Direct 12 decoder, ffmpeg does not support AMD GPU Direct 12 decoding. To properly support the Reference-Only feature, two parallel resource pools must be configured and managed: General Resource Pool: Contains resources used for output decoded frames. Defined in AVHWFramesContext and manages the final decoded textures. Reference-Only Resource Pool: Intended for storing reference frame resources. Resources created with the D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY flag are allocated to AVBufferPool. --- libavcodec/d3d12va_decode.c | 58 --- libavutil/hwcontext_d3d12va.c | 65 --- 2 files changed, 115 insertions(+), 8 deletions(-) diff --git a/libavcodec/d3d12va_decode.c b/libavcodec/d3d12va_decode.c index 3b8978635e..8916f94d10 100644 --- a/libavcodec/d3d12va_decode.c +++ b/libavcodec/d3d12va_decode.c @@ -51,11 +51,19 @@ unsigned ff_d3d12va_get_surface_index(const AVCodecContext *avctx, D3D12VADecodeContext *ctx, const AVFrame *frame, int curr) { +AVHWFramesContext *frames_ctx = D3D12VA_FRAMES_CONTEXT(avctx); +AVD3D12VAFramesContext *frames_hwctx = frames_ctx->hwctx; + AVD3D12VAFrame *f; ID3D12Resource *res; unsigned i; -f = (AVD3D12VAFrame *)frame->data[0]; +if (frames_hwctx->flags & D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY) { +f = (AVD3D12VAFrame*)frame->data[1]; +} else { +f = (AVD3D12VAFrame*)frame->data[0]; +} + if (!f) goto fail; @@ -250,6 +258,11 @@ static int d3d12va_create_decoder(AVCodecContext *avctx) return AVERROR_PATCHWELCOME; } +if (feature.ConfigurationFlags & D3D12_VIDEO_DECODE_CONFIGURATION_FLAG_REFERENCE_ONLY_ALLOCATIONS_REQUIRED) { +frames_hwctx->flags |= (D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY | D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE); +av_log(avctx, AV_LOG_INFO, "Reference-Only Allocations are required for this configuration.\n"); +} + desc = (D3D12_VIDEO_DECODER_DESC) { .NodeMask = 0, .Configuration = ctx->cfg, @@ -440,8 +453,19 @@ int ff_d3d12va_common_end_frame(AVCodecContext *avctx, AVFrame *frame, D3D12VADecodeContext *ctx = D3D12VA_DECODE_CONTEXT(avctx); ID3D12Resource *buffer= NULL; ID3D12CommandAllocator *command_allocator = NULL; -AVD3D12VAFrame *f = (AVD3D12VAFrame *)frame->data[0]; -ID3D12Resource *resource = (ID3D12Resource *)f->texture; +AVHWFramesContext *frames_ctx= D3D12VA_FRAMES_CONTEXT(avctx); +AVD3D12VAFramesContext *frames_hwctx = frames_ctx->hwctx; +AVD3D12VAFrame *f = NULL; +AVD3D12VAFrame *output_data = NULL; + +if (frames_hwctx->flags & D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY) { +f = (AVD3D12VAFrame*)frame->data[1]; +output_data = (AVD3D12VAFrame*)frame->data[0]; +} else { +f = (AVD3D12VAFrame*)frame->data[0]; +} + +ID3D12Resource* resource = (ID3D12Resource*)f->texture; ID3D12VideoDecodeCommandList *cmd_list = ctx->command_list; D3D12_RESOURCE_BARRIER barriers[32] = { 0 }; @@ -469,6 +493,14 @@ int ff_d3d12va_common_end_frame(AVCodecContext *avctx, AVFrame *frame, .pOutputTexture2D= resource, }; +if (frames_hwctx->flags & D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY) { +output_args.pOutputTexture2D = output_data->texture; + +output_args.ConversionArguments.Enable = 1; +output_args.ConversionArguments.pReferenceTexture2D = resource; +output_args.ConversionArguments.ReferenceSubresource = 0; +} + UINT num_barrier = 1; barriers[0] = (D3D12_RESOURCE_BARRIER) { .Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, @@ -481,6 +513,20 @@ int ff_d3d12va_common_end_frame(AVCodecContext *avctx, AVFrame *frame, }, }; +if (frames_hwctx->flags & D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY) { +barriers[1] = (D3D12_RESOURCE_BARRIER) { +.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, +.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE, +.Transition = { +.pResource = output_data->texture, +.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES
Re: [FFmpeg-devel] [PATCH 3/6] avcodec/aac/aacdec_usac: Fix memory deallocation of pl_data
Michael Niedermayer: > Fixes: double free > Fixes: > 393523547/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_AAC_LATM_fuzzer-6740617236905984 > > Found-by: continuous fuzzing process > https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg > Signed-off-by: Michael Niedermayer > --- > libavcodec/aac/aacdec.c | 19 +-- > libavcodec/aac/aacdec_usac.c | 3 ++- > 2 files changed, 19 insertions(+), 3 deletions(-) > > diff --git a/libavcodec/aac/aacdec.c b/libavcodec/aac/aacdec.c > index 8d50ad6d095..16259b5ada9 100644 > --- a/libavcodec/aac/aacdec.c > +++ b/libavcodec/aac/aacdec.c > @@ -421,6 +421,21 @@ static uint64_t sniff_channel_order(uint8_t > (*layout_map)[3], int tags) > return layout; > } > > +static void copy_oc(OutputConfiguration *dst, OutputConfiguration *src) > +{ > +int err = 0; Seems unused. > + > +for(int i = 0; i < dst->usac.nb_elems; i++) > +av_freep(&dst->usac.elems[i].ext.pl_data); > + > +*dst = *src; > + > +for(int i = 0; i < dst->usac.nb_elems; i++) { > +AACUsacElemConfig *e = &dst->usac.elems[i]; > +e->ext.pl_data = av_memdup(e->ext.pl_data, e->ext.pl_data_offset); Unchecked allocation. Furthermore, the *dst = *src makes cleanup on error here a PITA. Would making pl_data reference-counted (via RefStruct) work instead? > +} > +} > + > /** > * Save current output configuration if and only if it has been locked. > */ > @@ -429,7 +444,7 @@ static int push_output_configuration(AACDecContext *ac) > int pushed = 0; > > if (ac->oc[1].status == OC_LOCKED || ac->oc[0].status == OC_NONE) { > -ac->oc[0] = ac->oc[1]; > +copy_oc(&ac->oc[0], &ac->oc[1]); > pushed = 1; > } > ac->oc[1].status = OC_NONE; > @@ -443,7 +458,7 @@ static int push_output_configuration(AACDecContext *ac) > static void pop_output_configuration(AACDecContext *ac) > { > if (ac->oc[1].status != OC_LOCKED && ac->oc[0].status != OC_NONE) { > -ac->oc[1] = ac->oc[0]; > +copy_oc(&ac->oc[1], &ac->oc[0]); > ac->avctx->ch_layout = ac->oc[1].ch_layout; > ff_aac_output_configure(ac, ac->oc[1].layout_map, > ac->oc[1].layout_map_tags, > ac->oc[1].status, 0); > diff --git a/libavcodec/aac/aacdec_usac.c b/libavcodec/aac/aacdec_usac.c > index ccdf58bc8e2..e6f86b4a677 100644 > --- a/libavcodec/aac/aacdec_usac.c > +++ b/libavcodec/aac/aacdec_usac.c > @@ -1604,7 +1604,8 @@ static int parse_ext_ele(AACDecContext *ac, > AACUsacElemConfig *e, > if (!(pl_frag_start && pl_frag_end)) { > tmp = av_realloc(e->ext.pl_data, e->ext.pl_data_offset + len); > if (!tmp) { > -av_free(e->ext.pl_data); > +av_freep(&e->ext.pl_data); > +e->ext.pl_data_offset = 0; > return AVERROR(ENOMEM); > } > e->ext.pl_data = tmp; ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [REFUND-REQUEST] FOSDEM '25 Expenses
Hi, I am requesting reimbursement for the following expenses made attending FOSDEM 2025, where I attended the meeting and discussed development topics with fellow developers. Eurostar tickets: 178.33 GBP Hotel: 97.04 GBP Thanks ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] avfilter/vpp_amf: add option reset_sar
4b77a0a681 added a new consumer of ff_scale_adjust_dimensions which was recently modified to allow for square pixel output. This commit extends the new option to vpp_amf, and unbreaks the building of vf_amf_common.c --- doc/filters.texi| 3 +++ libavfilter/vf_amf_common.c | 10 -- libavfilter/vf_amf_common.h | 1 + libavfilter/vf_vpp_amf.c| 1 + 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index d72b0da7f3..4cefef6cbc 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -25796,6 +25796,9 @@ pixel format is used. @item force_divisible_by Work the same as the identical @ref{scale} filter options. +@item reset_sar +Works the same as the identical @ref{scale} filter option. + @anchor{color_profile} @item color_profile Specify all color properties at once. diff --git a/libavfilter/vf_amf_common.c b/libavfilter/vf_amf_common.c index 9c48b4218e..cbc532f822 100644 --- a/libavfilter/vf_amf_common.c +++ b/libavfilter/vf_amf_common.c @@ -158,7 +158,9 @@ int amf_filter_filter_frame(AVFilterLink *inlink, AVFrame *in) goto fail; } -if (inlink->sample_aspect_ratio.num) { +if (ctx->reset_sar) +outlink->sample_aspect_ratio = (AVRational){1, 1}; +else if (inlink->sample_aspect_ratio.num) { outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink->w, outlink->w * inlink->h}, inlink->sample_aspect_ratio); } else outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; @@ -274,6 +276,7 @@ int amf_init_filter_config(AVFilterLink *outlink, enum AVPixelFormat *in_format) enum AVPixelFormat out_sw_format = ctx->format; FilterLink*inl = ff_filter_link(inlink); FilterLink*outl = ff_filter_link(outlink); +double w_adj = 1.0; if ((err = ff_scale_eval_dimensions(avctx, ctx->w_expr, ctx->h_expr, @@ -281,8 +284,11 @@ int amf_init_filter_config(AVFilterLink *outlink, enum AVPixelFormat *in_format) &ctx->width, &ctx->height)) < 0) return err; +if (ctx->reset_sar) +w_adj = inlink->sample_aspect_ratio.num ? (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1.0; + ff_scale_adjust_dimensions(inlink, &ctx->width, &ctx->height, - ctx->force_original_aspect_ratio, ctx->force_divisible_by); + ctx->force_original_aspect_ratio, ctx->force_divisible_by, w_adj); av_buffer_unref(&ctx->amf_device_ref); av_buffer_unref(&ctx->hwframes_in_ref); diff --git a/libavfilter/vf_amf_common.h b/libavfilter/vf_amf_common.h index c4b5ba659a..d0a0214978 100644 --- a/libavfilter/vf_amf_common.h +++ b/libavfilter/vf_amf_common.h @@ -48,6 +48,7 @@ typedef struct AMFFilterContext { char *format_str; int force_original_aspect_ratio; int force_divisible_by; +int reset_sar; AMFComponent*component; AVBufferRef *amf_device_ref; diff --git a/libavfilter/vf_vpp_amf.c b/libavfilter/vf_vpp_amf.c index 87bd68074f..92923a4757 100644 --- a/libavfilter/vf_vpp_amf.c +++ b/libavfilter/vf_vpp_amf.c @@ -221,6 +221,7 @@ static const AVOption vpp_amf_options[] = { { "decrease", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 0, FLAGS, "force_oar" }, { "increase", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 0, FLAGS, "force_oar" }, { "force_divisible_by", "enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used", OFFSET(force_divisible_by), AV_OPT_TYPE_INT, { .i64 = 1}, 1, 256, FLAGS }, +{ "reset_sar", "reset SAR to 1 and scale to square pixels if scaling proportionally", OFFSET(reset_sar), AV_OPT_TYPE_BOOL, { .i64 = 0}, 0, 1, FLAGS }, { NULL }, }; -- 2.46.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] checkasm/v210enc.c: Use checkasm_check_type
On Sat, 8 Feb 2025, Kieran Kunhya via ffmpeg-devel wrote: $subj -if (memcmp(y0, y1, BUF_SIZE * sizeof(type)) \ -|| memcmp(u0, u1, BUF_SIZE * sizeof(type) / 2) \ -|| memcmp(v0, v1, BUF_SIZE * sizeof(type) / 2) \ -|| memcmp(dst0, dst1, width * 8 / 3)) \ +if (checkasm_check_##type(NULL, 0, y0, 0, y1, 0, BUF_SIZE, 0, NULL) \ +|| checkasm_check_##type(NULL, 0, u0, 0, u1, 0, BUF_SIZE / 2, 0, NULL) \ +|| checkasm_check_##type(NULL, 0, v0, 0, v1, 0, BUF_SIZE / 2, 0, NULL) \ +|| checkasm_check_uint8_t(NULL, 0, dst0, 0, dst1, 0, (width * 8 / 3), 0, NULL)) \ This actually doesn't detect any failures at all; you're passing it parameters for checking a buffer of BUF_SIZE width and 0 height, so it doesn't check anything. By passing height 1, it does seem to work as intended (detecting an intentionally added error in the asm). It feels a little bit unwieldy to check (and print out, if checkasm is run with "-v") the whole BUF_SIZE, but it's good to have testing for potential writes out of bounds at least, like before. Further in dav1d there are more improvements to these checkasm helpers, which we haven't backported to ffmpeg yet, that helps with allocating padded buffers and checking that the padding isn't overwritten; that would allow reducing the size of the checked area, to make it easier to read on errors too. But until that's backported, I guess this is fine, if you change the height to 1. // Martin ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] swscale/aarch64/rgb2rgb_neon: Implemented uyvytoyuv422
On Fri, 7 Feb 2025, Krzysztof Pyrkosz via ffmpeg-devel wrote: The patch contains NEON code that splits the uyvy input array into 3 separate buffers. The existing test cases are covering scenarios with odd height and odd stride, but width is even in every instance. Is it safe to make that assumption about the width? For something like uyvy, I'm kinda ok with assuming that, especially if we don't have test coverage for it. But ideally, it would of course be clear how those aspects are handled wrt assembly functions, indeed! Just as I'm about to send this patch, I'm thinking if non-interleaved read followed by 4 invocations of TBL wouldn't be more performant. One call to generate a contiguous vector of u, second for v and two for y. I'm curious to find out. My guess is that it may be more performant on more modern cores, but probably not on older ones. The speed: A78: uyvytoyuv422_c: 42213.5 ( 1.00x) uyvytoyuv422_neon:5298.8 ( 7.97x) A72: uyvytoyuv422_c: 61797.6 ( 1.00x) uyvytoyuv422_neon: 12141.9 ( 5.09x) x13s: uyvytoyuv422_c: 28581.7 ( 1.00x) uyvytoyuv422_neon:4882.4 ( 5.85x) Krzysztof --- libswscale/aarch64/rgb2rgb.c | 5 +++ libswscale/aarch64/rgb2rgb_neon.S | 51 +++ 2 files changed, 56 insertions(+) diff --git a/libswscale/aarch64/rgb2rgb.c b/libswscale/aarch64/rgb2rgb.c index 7e1dba572d..096ed9f363 100644 --- a/libswscale/aarch64/rgb2rgb.c +++ b/libswscale/aarch64/rgb2rgb.c @@ -67,6 +67,10 @@ void ff_shuffle_bytes_2013_neon(const uint8_t *src, uint8_t *dst, int src_size); void ff_shuffle_bytes_2130_neon(const uint8_t *src, uint8_t *dst, int src_size); void ff_shuffle_bytes_1203_neon(const uint8_t *src, uint8_t *dst, int src_size); +void ff_uyvytoyuv422_neon(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, + const uint8_t *src, int width, int height, + int lumStride, int chromStride, int srcStride); + av_cold void rgb2rgb_init_aarch64(void) { int cpu_flags = av_get_cpu_flags(); @@ -84,5 +88,6 @@ av_cold void rgb2rgb_init_aarch64(void) shuffle_bytes_2013 = ff_shuffle_bytes_2013_neon; shuffle_bytes_2130 = ff_shuffle_bytes_2130_neon; shuffle_bytes_1203 = ff_shuffle_bytes_1203_neon; +uyvytoyuv422 = ff_uyvytoyuv422_neon; } } diff --git a/libswscale/aarch64/rgb2rgb_neon.S b/libswscale/aarch64/rgb2rgb_neon.S index 22ecdf7ac8..bdbee7df2e 100644 --- a/libswscale/aarch64/rgb2rgb_neon.S +++ b/libswscale/aarch64/rgb2rgb_neon.S @@ -427,3 +427,54 @@ neon_shuf 2013 neon_shuf 1203 neon_shuf 2130 neon_shuf 3210 + +function ff_uyvytoyuv422_neon, export=1 +sxtw x6, w6 The indentation of the arguments column is off by one char within this whole function. For testing various aarch64 assembly details (building with unusual toolchains etc), I've set up a little extra CI for that on github; have a look at the branch at the topmost 4 commits at https://github.com/mstorsjo/ffmpeg/commits/gha-aarch64. If you include those 4 commits in a branch and push to a personal fork at github, you'll get test results for that push like this: https://github.com/mstorsjo/FFmpeg/actions/runs/13240513523 For these two patches, I got the following results: https://github.com/mstorsjo/FFmpeg/actions/runs/13240526767 This points out the unexpected indentation here. +sxtw x7, w7 +ldrswx8, [sp] +ubfx x10, x4, #1, #31 The ubfx instruction is kinda esoteric; I presume what you're doing here is essentially the same as "lsr #1"? That'd be much more idiomatic and readable. +sub x8, x8, w4, sxtw #1 // src offset +sub x6, x6, w4, sxtw // lum offset +sub x7, x7, x10 // chr offset +1: +sub w5, w5, #1 It feels a bit unusual to do the decrement of the outer loop counter here at this point; I feel that it would be more readable in context if it was done at the end after the 3: label. (There can of course be good reasons for doing it early due to scheduling etc, but I don't see such a case here.) +ands w10, w4, #~31 +and w9, w4, #15 +and w11, w4, #16 +b.eq 7f +4: +ld4 {v0.16b - v3.16b}, [x3], #64 // handle 16 uyvy tuples per iteration +subs w10, w10, #32 +st1 {v2.16b}, [x2], #16 +st1 {v0.16b}, [x1], #16 +mov v2.16b, v1.16b +st2 {v2.16b,v3.16b}, [x0], #32 +b.ne 4b +7: +cbz w11, 5f //
Re: [FFmpeg-devel] [PATCH] avfilter/vf_amf_common: implement reset_sar options
On 2025-02-10 07:04 pm, Timo Rothenpieler wrote: Implements the new reset_sar option from a28dc06869fe1f98c07e42f9b0a411d2744ff7d7. Already posted a patch. Will push soon. Regards, Gyan ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avfilter/vf_amf_common: implement reset_sar options
On 10/02/2025 14:44, Gyan Doshi wrote: On 2025-02-10 07:04 pm, Timo Rothenpieler wrote: Implements the new reset_sar option from a28dc06869fe1f98c07e42f9b0a411d2744ff7d7. Already posted a patch. Will push soon. Ah, you might wanna look into moving the sar assignment as well then, cause assigning it on the outlink on every frame, but not in config props, seems wrong. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v2 2/2] random_seed: Improve behaviour with small timer increments with high precision timers
On Sun, 9 Feb 2025, Michael Niedermayer wrote: Hi Martin On Fri, Feb 07, 2025 at 12:04:53AM +0200, Martin Storsjö wrote: On Thu, 6 Feb 2025, Michael Niedermayer wrote: On Thu, Feb 06, 2025 at 02:38:48PM +0200, Martin Storsjö wrote: On Thu, 6 Feb 2025, Michael Niedermayer wrote: +// If the timer resolution is high, and we get the same timer +// value multiple times, use variances in the number of repeats +// of each timer value as entropy. If the number of repeats changed, +// proceed to the next index. Does it still work if you check against the last 2 ? or does this become too slow ? What iam thinking of is this 7,8,7,8,8,7,8,7,8,8,7,8,7,8,8,7,8,7,8,8,... and a 9 or 6 or further distant would trigger it I assume both the CPU clock and the wall time are quite precisse so if we just compare them the entropy could be low even with 2 alternating values Yes, that still works for making it terminate in a reasonable amount of time. I updated the patch to keep track of 3 numbers of repeats, and we consider that we got valid entropy once the new number of repeats is different from the last two. So in the sequence above, e.g. for 7,8,7,8,8,7, at the point of the last one, we have old repeats 8 and 8, and the new repeat count 7, which in that context looks unique. I was thinking that in 7,8,8 that 7 and 8 be the 2 least recent used values not 8,8 Sure, that's probably doable too. that is, something like: if (old2 == new) { FFSWAP(old,old2); I don't see why we'd need to check this if clause at all, it seems to me that it's enough to have the "if (old != new)" case. If we have old2 == new, we'd just end up with old2 = old, and old = (previous old2 value) anyway. It was intended to be a least recent used check with 2 entries If we have a clock running and sample that in precise intervalls lets say the clock runs at 1.9hz and we sample at 10hz we would get clock:0 0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5 6 6 6 6 6 7 7 7 7 7 7 8 8 8 8 8 9 9 difference: 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 Above adds no entropy after the initial entropy, this can be read forever it will not improve randomness here we have runs of repeated clock reads of 5,4,4,5,4,4,4,5,4 again we can read this as long as we want there is no entropy gained so after a 5,4,4,4 if a 5 happens thats not breaking the pattern and should not be counted as new entropy (if possible) Yes, I get that intent. It's just that your suggested pseudocode seems unnecessarily complex, or I'm missing something: if (old2 == new) { FFSWAP(old,old2); } else if (old != new) { old2 = old; old = new; } If we have the sequence "5, 4, 4, 4, 4", followed by another "5", we have old2 == 5, old == 4, new == 5. Then we get the same end result (old2 == 4, old == 5) both if we execute the code you suggest above, and if we just execute this: if (old != new) { old2 = old; old = new; } Or is there something I'm missing? I don't see the need for the FFSWAP case. As long as we check (new != old && new != old2) we should pick up actual deviation from the steady state but not the variance between two values. // Martin ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/3] avcodec/sanm: fobj left/top are signed
The left and top parameters of an FOBJ are signed values. Signed-off-by: Manuel Lauss --- libavcodec/sanm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index 37d2c915d4..0e7cd292d0 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -1238,8 +1238,8 @@ 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 left = bytestream2_get_le16u(&ctx->gb); -uint16_t top = bytestream2_get_le16u(&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); -- 2.48.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/3] avcodec/sanm: ignore unknown codecs in FOBJs
Don't error out, just ignore unknown codec numbers and pretend decode succeeded. This is useful for older LucasArts titles which stack a lot of different FOBJs with different codecs into a single frame. Signed-off-by: Manuel Lauss --- libavcodec/sanm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index c30095ed32..37d2c915d4 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -1274,7 +1274,7 @@ static int process_frame_obj(SANMVideoContext *ctx) return old_codec48(ctx, w, h); default: avpriv_request_sample(ctx->avctx, "Subcodec %d", codec); -return AVERROR_PATCHWELCOME; +return 0; } } -- 2.48.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/3] avcodec/sanm: add smush 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 --- Videos showing the before/after state (Rebel Assault II LEV09/09PLAY.SAN file) http://mlau.at/ffmpeg_c23_before.mp4 http://mlau.at/ffmpeg_c23_after.mp4 notice the blue transparent forcefields. libavcodec/sanm.c | 62 +-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index 0e7cd292d0..fb055b61c7 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 { @@ -555,6 +556,58 @@ 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->width * ctx->pitch; +uint8_t *dst, lut[256], c; +int i, j, k, pc, sk; +int32_t pxoff; + +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) { @@ -1237,11 +1290,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 || !h) { av_log(ctx->avctx, AV_LOG_ERROR, "Dimensions are invalid.\n"); @@ -1260,12 +1317,13 @@ static int process_frame_obj(SANMVideoContext *ctx) return AVERROR(ENOMEM); } } -bytestream2_skip(&ctx->gb, 4); switch (codec) { case 1: case 3: return old_codec1(ctx, top, left, w, h); +case 23: +return old_codec23(ctx, top, left, w, h, param, parm2); case 37: return old_codec37(ctx, top, left, w, h); case 47: -- 2.48.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] Trac accounts cleanup
Hi everyone Iam deleting half opened accounts that have never verified their email address. (this is limited to accounts unused since 2 years so it should affect noone) thx -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB If a bugfix only changes things apparently unrelated to the bug with no further explanation, that is a good sign that the bugfix is wrong. signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] Calling avformat_find_stream_info() more than once
Hello all, avformat_find_stream_info() calls av_freep() on FFStream::info, which will cause a segmentation fault if it is called more than once on the same AVFormatContext (assuming it still has at least one of the AVStreams from when it was called previously). Is this intentional and should this be documented? Thanks, Scott Theisen ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v4 6/6] tests: Add chained ogg/flac stream dump test.
Same test as for ogg/opus. Samples and output for both tests are available here: https://www.dropbox.com/scl/fo/xrtrna2rxr1j354hrtymq/AGwemlxHYecBLNmQ8Fsy--4?rlkey=lzilr4m9w4gfdqygoe172vvy8&dl=0 In this case, the secondary chained ogg/flac header packets are already visible before the changes. Before the changes: Stream ID: 0, codec name: flac, metadata: encoder=Lavc61.19.100 flac:title=First Stream Stream ID: 0, packet PTS: 0, packet DTS: 0 Stream ID: 0, frame PTS: 0, metadata: Stream ID: 0, packet PTS: 4608, packet DTS: 4608 Stream ID: 0, frame PTS: 4608, metadata: Stream ID: 0, packet PTS: 0, packet DTS: 0 Stream ID: 0, packet PTS: 0, packet DTS: 0 Stream ID: 0, packet PTS: 0, packet DTS: 0 Stream ID: 0, frame PTS: 0, metadata: Stream ID: 0, packet PTS: 4608, packet DTS: 4608 Stream ID: 0, frame PTS: 4608, metadata: After the changes: Stream ID: 0, codec name: flac, metadata: encoder=Lavc61.19.100 flac:title=First Stream Stream ID: 0, packet PTS: 0, packet DTS: 0 Stream ID: 0, frame PTS: 0, metadata: Stream ID: 0, packet PTS: 4608, packet DTS: 4608 Stream ID: 0, frame PTS: 4608, metadata: Stream ID: 0, packet PTS: 0, packet DTS: 0 Stream ID: 0, packet PTS: 0, packet DTS: 0 Stream ID: 0, packet PTS: 0, packet DTS: 0 Stream ID: 0, frame PTS: 0, metadata: encoder=Lavc61.19.100 flac:title=Second Stream Stream ID: 0, packet PTS: 4608, packet DTS: 4608 Stream ID: 0, frame PTS: 4608, metadata: --- tests/Makefile | 1 + tests/fate/ogg-flac.mak | 11 +++ 2 files changed, 12 insertions(+) create mode 100644 tests/fate/ogg-flac.mak diff --git a/tests/Makefile b/tests/Makefile index 5ba12e3f3f..7d16f7fe16 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -220,6 +220,7 @@ include $(SRC_PATH)/tests/fate/mpegps.mak include $(SRC_PATH)/tests/fate/mpegts.mak include $(SRC_PATH)/tests/fate/mxf.mak include $(SRC_PATH)/tests/fate/ogg-opus.mak +include $(SRC_PATH)/tests/fate/ogg-flac.mak include $(SRC_PATH)/tests/fate/oma.mak include $(SRC_PATH)/tests/fate/opus.mak include $(SRC_PATH)/tests/fate/pcm.mak diff --git a/tests/fate/ogg-flac.mak b/tests/fate/ogg-flac.mak new file mode 100644 index 00..22e2030534 --- /dev/null +++ b/tests/fate/ogg-flac.mak @@ -0,0 +1,11 @@ +FATE_OGG_FLAC += fate-ogg-flac-chained-meta +fate-ogg-flac-chained-meta: REF = $(SAMPLES)/ogg-flac/chained-meta.txt +fate-ogg-flac-chained-meta: CMD = $(APITESTSDIR)/api-dump-stream-meta-test$(EXESUF) $(TARGET_SAMPLES)/ogg-flac/chained-meta.ogg + +FATE_OGG_FLAC-$(call DEMDEC, OGG, FLAC) += $(FATE_OGG_FLAC) + +FATE_SAMPLES_DUMP_STREAM_META += $(FATE_OGG_FLAC-yes) + +FATE_EXTERN += $(FATE_OGG_FLAC-yes) + +fate-ogg-flac: $(FATE_OGG_FLAC-yes) -- 2.39.5 (Apple Git-154) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 1/3] avcodec/sanm: ignore unknown codecs in FOBJs
On Mon, 10 Feb 2025, Manuel Lauss wrote: Don't error out, just ignore unknown codec numbers and pretend decode succeeded. This is useful for older LucasArts titles which stack a lot of different FOBJs with different codecs into a single frame. Signed-off-by: Manuel Lauss --- libavcodec/sanm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index c30095ed32..37d2c915d4 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -1274,7 +1274,7 @@ static int process_frame_obj(SANMVideoContext *ctx) return old_codec48(ctx, w, h); default: avpriv_request_sample(ctx->avctx, "Subcodec %d", codec); -return AVERROR_PATCHWELCOME; +return 0; But if there is an unsupported FOBJ code that means that the frame might be only partially decoded, right? So you should set AV_FRAME_FLAG_CORRUPT flag in AVFrame->flags, and still log the error, not silently ignore it. Regards, Marton } } -- 2.48.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 1/3] avcodec/sanm: ignore unknown codecs in FOBJs
Hi Marton! Marton Balint schrieb am Mo., 10. Feb. 2025, 20:42: > > > On Mon, 10 Feb 2025, Manuel Lauss wrote: > > > Don't error out, just ignore unknown codec numbers and pretend > > decode succeeded. This is useful for older LucasArts titles > > which stack a lot of different FOBJs with different codecs into > > a single frame. > > > > Signed-off-by: Manuel Lauss > > --- > > libavcodec/sanm.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c > > index c30095ed32..37d2c915d4 100644 > > --- a/libavcodec/sanm.c > > +++ b/libavcodec/sanm.c > > @@ -1274,7 +1274,7 @@ static int process_frame_obj(SANMVideoContext *ctx) > > return old_codec48(ctx, w, h); > > default: > > avpriv_request_sample(ctx->avctx, "Subcodec %d", codec); > > -return AVERROR_PATCHWELCOME; > > +return 0; > > But if there is an unsupported FOBJ code that means that the frame might > be only partially decoded, right? Thats how the game engine works as well: A FRME can have >=0 FOBJs, all of them skippable based on game state. An unchanged image buffer from the previous FRME is absolutely posssible. So you should set AV_FRAME_FLAG_CORRUPT > flag in AVFrame->flags, and still log the error, not silently ignore it. > It's not corrupt per se. While working on codec 23, the other unsupported codecs in the test videos stop the decoding before getting to the c23 fobj. For a lot of Rebel Assault 2 videos this patch improves playback; nothing changes for the ones that were already supported by ffmpeg. Regards, > Marton > > > > } > > } > > > > -- > > 2.48.1 > > > > ___ > > ffmpeg-devel mailing list > > ffmpeg-devel@ffmpeg.org > > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > > To unsubscribe, visit link above, or email > > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". > > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v4 2/6] tests: Add stream dump test API util.
This is the code for the main utility used to dump chained streams and test for decoded metadata in subsequent patches. --- tests/Makefile| 1 + tests/api/Makefile| 2 +- tests/api/api-dump-stream-meta-test.c | 169 ++ 3 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 tests/api/api-dump-stream-meta-test.c diff --git a/tests/Makefile b/tests/Makefile index f9f5fc07f3..1f7e5003c2 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -277,6 +277,7 @@ $(FATE_FFPROBE) $(FATE_FFMPEG_FFPROBE) $(FATE_SAMPLES_FFPROBE) $(FATE_SAMPLES_FF $(FATE_SAMPLES_FASTSTART): tools/qt-faststart$(EXESUF) $(FATE_SAMPLES_DUMP_DATA) $(FATE_SAMPLES_DUMP_DATA-yes): tools/venc_data_dump$(EXESUF) $(FATE_SAMPLES_SCALE_SLICE): tools/scale_slice_test$(EXESUF) +$(FATE_SAMPLES_DUMP_STREAM_META): tests/api/api-dump-stream-meta-test$(EXESUF) ifdef SAMPLES FATE += $(FATE_EXTERN) diff --git a/tests/api/Makefile b/tests/api/Makefile index c96e636756..a2cb06a729 100644 --- a/tests/api/Makefile +++ b/tests/api/Makefile @@ -1,7 +1,7 @@ APITESTPROGS-$(call ENCDEC, FLAC, FLAC) += api-flac APITESTPROGS-$(call DEMDEC, H264, H264) += api-h264 APITESTPROGS-$(call DEMDEC, H264, H264) += api-h264-slice -APITESTPROGS-yes += api-seek +APITESTPROGS-yes += api-seek api-dump-stream-meta APITESTPROGS-$(call DEMDEC, H263, H263) += api-band APITESTPROGS-$(HAVE_THREADS) += api-threadmessage APITESTPROGS += $(APITESTPROGS-yes) diff --git a/tests/api/api-dump-stream-meta-test.c b/tests/api/api-dump-stream-meta-test.c new file mode 100644 index 00..4ffdfe8213 --- /dev/null +++ b/tests/api/api-dump-stream-meta-test.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2025 Romain Beauxis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * Dump stream metadata + */ + +#include "libavcodec/avcodec.h" +#include "libavformat/avformat.h" +#include "libavutil/timestamp.h" + +static int dump_stream_meta(const char *input_filename) +{ +const AVCodec *codec = NULL; +AVPacket *pkt = NULL; +AVFrame *fr = NULL; +AVFormatContext *fmt_ctx = NULL; +AVCodecContext *ctx = NULL; +AVCodecParameters *origin_par = NULL; +int audio_stream; +int result; +char *metadata; + +result = avformat_open_input(&fmt_ctx, input_filename, NULL, NULL); +if (result < 0) { +av_log(NULL, AV_LOG_ERROR, "Can't open file\n"); +return result; +} + +result = avformat_find_stream_info(fmt_ctx, NULL); +if (result < 0) { +av_log(NULL, AV_LOG_ERROR, "Can't get stream info\n"); +goto end; +} + +// TODO: add ability to work with video format +audio_stream = +av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0); +if (audio_stream < 0) { +av_log(NULL, AV_LOG_ERROR, "Can't find audio stream in input file\n"); +result = audio_stream; +goto end; +} + +origin_par = fmt_ctx->streams[audio_stream]->codecpar; + +result = av_dict_get_string( +fmt_ctx->streams[audio_stream]->metadata, &metadata, '=', ':'); +if (result < 0) +goto end; + +printf("Stream ID: %d, codec name: %s, metadata: %s\n", audio_stream, +avcodec_get_name(origin_par->codec_id), metadata); + +codec = avcodec_find_decoder(origin_par->codec_id); +if (!codec) { +av_log(NULL, AV_LOG_ERROR, "Can't find decoder\n"); +result = AVERROR_DECODER_NOT_FOUND; +goto end; +} + +ctx = avcodec_alloc_context3(codec); +if (!ctx) { +av_log(NULL, AV_LOG_ERROR, "Can't allocate decoder context\n"); +result = AVERROR(ENOMEM); +goto end; +} + +result = avcodec_parameters_to_context(ctx, origin_par); +if (result) { +av_log(NULL, AV_LOG_ERROR, "Can't copy decoder context\n"); +goto end; +} + +result = avcodec_open2(ctx, codec, NULL); +if (result < 0) {
[FFmpeg-devel] [PATCH v4 3/6] Pass secondary ogg/opus chained streams metadata.
These changes parse ogg/opus comment in secondary chained ogg/opus streams and attach them as extradata to the corresponding packet. They can then be decoded in the opus decoder and attached to the next decoded frame. libavformat/oggparseopus.c: Parse comments from secondary chained ogg/opus streams and pass them as ogg stream new_metadata. libavcodec/opus/dec.c: Unpack comments from secondary chained ogg/opus streams and attach them to the next decoded frame. --- libavcodec/opus/dec.c | 25 ++--- libavformat/oggparseopus.c | 16 +++- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/libavcodec/opus/dec.c b/libavcodec/opus/dec.c index 88a650c81c..cddcefcb5f 100644 --- a/libavcodec/opus/dec.c +++ b/libavcodec/opus/dec.c @@ -125,6 +125,8 @@ typedef struct OpusContext { AVFloatDSPContext *fdsp; float gain; +AVDictionary *pending_metadata; + OpusParseContext p; } OpusContext; @@ -485,12 +487,24 @@ static int opus_decode_packet(AVCodecContext *avctx, AVFrame *frame, int decoded_samples = INT_MAX; int delayed_samples = 0; int i, ret; +size_t size; +const uint8_t *side_metadata; -if (buf_size > 8 && ( - !memcmp(buf, "OpusHead", 8) || - !memcmp(buf, "OpusTags", 8))) +if (buf_size > 8 && !memcmp(buf, "OpusHead", 8)) return buf_size; +if (buf_size > 8 && !memcmp(buf, "OpusTags", 8)) { +/* New metadata */ +side_metadata = av_packet_get_side_data(avpkt, AV_PKT_DATA_METADATA_UPDATE, &size); +if (side_metadata) { +av_dict_free(&c->pending_metadata); +ret = av_packet_unpack_dictionary(side_metadata, size, &c->pending_metadata); +if (ret < 0) +return ret; +} +return buf_size; +} + /* calculate the number of delayed samples */ for (int i = 0; i < c->p.nb_streams; i++) { OpusStreamContext *s = &c->streams[i]; @@ -631,6 +645,11 @@ static int opus_decode_packet(AVCodecContext *avctx, AVFrame *frame, frame->nb_samples = decoded_samples; *got_frame_ptr= !!decoded_samples; +if (c->pending_metadata) { +av_dict_copy(&frame->metadata, c->pending_metadata, AV_DICT_APPEND); +av_dict_free(&c->pending_metadata); +} + return avpkt->size; } diff --git a/libavformat/oggparseopus.c b/libavformat/oggparseopus.c index 950b93bd31..3e94a7df3c 100644 --- a/libavformat/oggparseopus.c +++ b/libavformat/oggparseopus.c @@ -116,6 +116,7 @@ static int opus_packet(AVFormatContext *avf, int idx) AVStream *st = avf->streams[idx]; struct oggopus_private *priv = os->private; uint8_t *packet = os->buf + os->pstart; +AVDictionary *new_metadata = NULL; int ret; if (!os->psize) @@ -133,8 +134,21 @@ static int opus_packet(AVFormatContext *avf, int idx) return 0; } -if (os->psize > 8 && !memcmp(packet, "OpusTags", 8)) +if (os->psize > 8 && !memcmp(packet, "OpusTags", 8)) { +ret = ff_vorbis_comment(avf, &new_metadata, os->buf + os->pstart + 8, +os->psize - 8, 1); + +if (ret < 0) +return ret; + +os->new_metadata = av_packet_pack_dictionary(new_metadata, &os->new_metadata_size); +av_dict_free(&new_metadata); + +if (!os->new_metadata) +return AVERROR(ENOMEM); + return 0; +} if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) { int seg, d; -- 2.39.5 (Apple Git-154) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v4 5/6] Parse secondary chained ogg/flac stream comments.
This the same changes as done with ogg/opus: parse comments in secondary chained ogg/flac streams, attach them as packed extradata, decode and attach them to the next decoded stream in the flac decoder. libavformat/oggparseflac.c: Parse ogg/flac comments in new ogg packets, add them to ogg stream new_metadata. libavcodec/flacdec.c: Process AV_PKT_DATA_METADATA_UPDATE on new packets, add them as new metadata on the new decoded audio frame. --- libavcodec/flacdec.c | 20 +++- libavformat/oggparseflac.c | 28 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index ad921a1bd1..337f3e1702 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -68,6 +68,8 @@ typedef struct FLACContext { unsigned int decoded_buffer_size_33bps; int buggy_lpc; ///< use workaround for old lavc encoded files +AVDictionary *pending_metadata; + FLACDSPContext dsp; } FLACContext; @@ -718,6 +720,8 @@ static int flac_decode_frame(AVCodecContext *avctx, AVFrame *frame, int buf_size = avpkt->size; FLACContext *s = avctx->priv_data; int bytes_read = 0; +const uint8_t *side_metadata; +size_t size; int ret; *got_frame_ptr = 0; @@ -728,7 +732,14 @@ static int flac_decode_frame(AVCodecContext *avctx, AVFrame *frame, } if (buf_size > 0 && (*buf & 0x7F) == FLAC_METADATA_TYPE_VORBIS_COMMENT) { -av_log(s->avctx, AV_LOG_DEBUG, "skipping vorbis comment\n"); +/* New metadata */ +side_metadata = av_packet_get_side_data(avpkt, AV_PKT_DATA_METADATA_UPDATE, &size); +if (side_metadata) { +av_dict_free(&s->pending_metadata); +ret = av_packet_unpack_dictionary(side_metadata, size, &s->pending_metadata); +if (ret < 0) +return ret; +} return buf_size; } @@ -788,6 +799,12 @@ static int flac_decode_frame(AVCodecContext *avctx, AVFrame *frame, buf_size - bytes_read, buf_size); } + +if (s->pending_metadata) { +av_dict_copy(&frame->metadata, s->pending_metadata, AV_DICT_APPEND); +av_dict_free(&s->pending_metadata); +} + *got_frame_ptr = 1; return bytes_read; @@ -799,6 +816,7 @@ static av_cold int flac_decode_close(AVCodecContext *avctx) av_freep(&s->decoded_buffer); av_freep(&s->decoded_buffer_33bps); +av_dict_free(&s->pending_metadata); return 0; } diff --git a/libavformat/oggparseflac.c b/libavformat/oggparseflac.c index f25ed9cc15..3810806112 100644 --- a/libavformat/oggparseflac.c +++ b/libavformat/oggparseflac.c @@ -78,6 +78,32 @@ flac_header (AVFormatContext * s, int idx) return 1; } +static int +flac_packet (AVFormatContext * s, int idx) +{ +struct ogg *ogg = s->priv_data; +struct ogg_stream *os = ogg->streams + idx; +AVDictionary *new_metadata = NULL; +int ret; + +if (os->psize > 0 && os->buf[os->pstart] && +(os->buf[os->pstart] & 0x7F) == FLAC_METADATA_TYPE_VORBIS_COMMENT) { +ret = ff_vorbis_comment(s, &new_metadata, os->buf + os->pstart + 4, +os->psize - 4, 1); + +if (ret < 0) +return ret; + +os->new_metadata = av_packet_pack_dictionary(new_metadata, &os->new_metadata_size); +av_dict_free(&new_metadata); + +if (!os->new_metadata) +return AVERROR(ENOMEM); +} + +return 0; +} + static int old_flac_header (AVFormatContext * s, int idx) { @@ -130,6 +156,7 @@ const struct ogg_codec ff_flac_codec = { .magic = "\177FLAC", .magicsize = 5, .header = flac_header, +.packet = flac_packet, .nb_header = 2, }; @@ -137,5 +164,6 @@ const struct ogg_codec ff_old_flac_codec = { .magic = "fLaC", .magicsize = 4, .header = old_flac_header, +.packet = flac_packet, .nb_header = 0, }; -- 2.39.5 (Apple Git-154) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v4 1/6] Pass ogg/opus secondary header packets to the
These changes make it possible to access the initial header packets of secondary chained ogg/opus bitstreams. libavformat/oggparseopus.c: Parse extradata from secondary chained streams header packet. libavformat/oggdec.c: Do not force ogg stream header parsing on secondary ogg/opus chained streams. libavcodec/opus/dec.c: Ignore opus header packets from secondary chained streams. --- libavcodec/opus/dec.c | 5 + libavformat/oggdec.c | 4 libavformat/oggparseopus.c | 11 +++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/libavcodec/opus/dec.c b/libavcodec/opus/dec.c index 6c59dc1f46..88a650c81c 100644 --- a/libavcodec/opus/dec.c +++ b/libavcodec/opus/dec.c @@ -486,6 +486,11 @@ static int opus_decode_packet(AVCodecContext *avctx, AVFrame *frame, int delayed_samples = 0; int i, ret; +if (buf_size > 8 && ( + !memcmp(buf, "OpusHead", 8) || + !memcmp(buf, "OpusTags", 8))) +return buf_size; + /* calculate the number of delayed samples */ for (int i = 0; i < c->p.nb_streams; i++) { OpusStreamContext *s = &c->streams[i]; diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c index 5339fdd32c..4425279ce8 100644 --- a/libavformat/oggdec.c +++ b/libavformat/oggdec.c @@ -239,10 +239,6 @@ static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, char *magic, os->start_trimming = 0; os->end_trimming = 0; -/* Chained files have extradata as a new packet */ -if (codec == &ff_opus_codec) -os->header = -1; - return i; } diff --git a/libavformat/oggparseopus.c b/libavformat/oggparseopus.c index 218e9df581..950b93bd31 100644 --- a/libavformat/oggparseopus.c +++ b/libavformat/oggparseopus.c @@ -125,6 +125,17 @@ static int opus_packet(AVFormatContext *avf, int idx) return AVERROR_INVALIDDATA; } +if (os->psize > 8 && !memcmp(packet, "OpusHead", 8)) { +if ((ret = ff_alloc_extradata(st->codecpar, os->psize)) < 0) +return ret; + +memcpy(st->codecpar->extradata, packet, os->psize); +return 0; +} + +if (os->psize > 8 && !memcmp(packet, "OpusTags", 8)) +return 0; + if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) { int seg, d; int duration; -- 2.39.5 (Apple Git-154) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v4 4/6] tests: Add chained ogg/opus stream dump test.
This adds the test to confirm that secondary chained ogg/opus streams are properly decoded. Using the test output, we can confirm that secondary stream header packets are properly passed down and that the new metadata are properly parsed. Output before the changes: Stream ID: 0, codec name: opus, metadata: encoder=Lavc61.19.100 libopus:title=First Stream Stream ID: 0, packet PTS: -312, packet DTS: -312 Stream ID: 0, frame PTS: -312, metadata: Stream ID: 0, packet PTS: 648, packet DTS: 648 Stream ID: 0, frame PTS: 648, metadata: Stream ID: 0, packet PTS: 1608, packet DTS: 1608 Stream ID: 0, frame PTS: 1608, metadata: Stream ID: 0, packet PTS: 2568, packet DTS: 2568 Stream ID: 0, frame PTS: 2568, metadata: Stream ID: 0, packet PTS: 3528, packet DTS: 3528 Stream ID: 0, frame PTS: 3528, metadata: Stream ID: 0, packet PTS: 4488, packet DTS: 4488 Stream ID: 0, frame PTS: 4488, metadata: Stream ID: 0, packet PTS: -312, packet DTS: -312 Stream ID: 0, frame PTS: -312, metadata: Stream ID: 0, packet PTS: 648, packet DTS: 648 Stream ID: 0, frame PTS: 648, metadata: Stream ID: 0, packet PTS: 1608, packet DTS: 1608 Stream ID: 0, frame PTS: 1608, metadata: Stream ID: 0, packet PTS: 2568, packet DTS: 2568 Stream ID: 0, frame PTS: 2568, metadata: Stream ID: 0, packet PTS: 3528, packet DTS: 3528 Stream ID: 0, frame PTS: 3528, metadata: Stream ID: 0, packet PTS: 4488, packet DTS: 4488 Stream ID: 0, frame PTS: 4488, metadata: Output after the changes: Stream ID: 0, codec name: opus, metadata: encoder=Lavc61.19.100 libopus:title=First Stream Stream ID: 0, packet PTS: -312, packet DTS: -312 Stream ID: 0, frame PTS: -312, metadata: Stream ID: 0, packet PTS: 648, packet DTS: 648 Stream ID: 0, frame PTS: 648, metadata: Stream ID: 0, packet PTS: 1608, packet DTS: 1608 Stream ID: 0, frame PTS: 1608, metadata: Stream ID: 0, packet PTS: 2568, packet DTS: 2568 Stream ID: 0, frame PTS: 2568, metadata: Stream ID: 0, packet PTS: 3528, packet DTS: 3528 Stream ID: 0, frame PTS: 3528, metadata: Stream ID: 0, packet PTS: 4488, packet DTS: 4488 Stream ID: 0, frame PTS: 4488, metadata: Stream ID: 0, packet PTS: 0, packet DTS: 0 Stream ID: 0, packet PTS: 0, packet DTS: 0 Stream ID: 0, packet PTS: -312, packet DTS: -312 Stream ID: 0, frame PTS: -312, metadata: encoder=Lavc61.19.100 libopus:title=Second Stream Stream ID: 0, packet PTS: 648, packet DTS: 648 Stream ID: 0, frame PTS: 648, metadata: Stream ID: 0, packet PTS: 1608, packet DTS: 1608 Stream ID: 0, frame PTS: 1608, metadata: Stream ID: 0, packet PTS: 2568, packet DTS: 2568 Stream ID: 0, frame PTS: 2568, metadata: Stream ID: 0, packet PTS: 3528, packet DTS: 3528 Stream ID: 0, frame PTS: 3528, metadata: Stream ID: 0, packet PTS: 4488, packet DTS: 4488 Stream ID: 0, frame PTS: 4488, metadata: --- tests/Makefile | 1 + tests/fate/ogg-opus.mak | 11 +++ 2 files changed, 12 insertions(+) create mode 100644 tests/fate/ogg-opus.mak diff --git a/tests/Makefile b/tests/Makefile index 1f7e5003c2..5ba12e3f3f 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -219,6 +219,7 @@ include $(SRC_PATH)/tests/fate/mpeg4.mak include $(SRC_PATH)/tests/fate/mpegps.mak include $(SRC_PATH)/tests/fate/mpegts.mak include $(SRC_PATH)/tests/fate/mxf.mak +include $(SRC_PATH)/tests/fate/ogg-opus.mak include $(SRC_PATH)/tests/fate/oma.mak include $(SRC_PATH)/tests/fate/opus.mak include $(SRC_PATH)/tests/fate/pcm.mak diff --git a/tests/fate/ogg-opus.mak b/tests/fate/ogg-opus.mak new file mode 100644 index 00..75cb15bc05 --- /dev/null +++ b/tests/fate/ogg-opus.mak @@ -0,0 +1,11 @@ +FATE_OGG_OPUS += fate-ogg-opus-chained-meta +fate-ogg-opus-chained-meta: REF = $(SAMPLES)/ogg-opus/chained-meta.txt +fate-ogg-opus-chained-meta: CMD = $(APITESTSDIR)/api-dump-stream-meta-test$(EXESUF) $(TARGET_SAMPLES)/ogg-opus/chained-meta.ogg + +FATE_OGG_OPUS-$(call DEMDEC, OGG, OPUS) += $(FATE_OGG_OPUS) + +FATE_SAMPLES_DUMP_STREAM_META += $(FATE_OGG_OPUS-yes) + +FATE_EXTERN += $(FATE_OGG_OPUS-yes) + +fate-ogg-opus: $(FATE_OGG_OPUS-yes) -- 2.39.5 (Apple Git-154) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] 10bit MV-HEVC decoding support
On 2/7/2025 5:39 PM, James Almer wrote: > The existing code should be able > to handle 10bit streams for both base and second layers Thank you, James! I just went through verification with a 10bit encoded MV-HEVC and it seems to be decoding as expected. I compared the ffmpeg decoded with the HTM ref SW decoded and all pixels matched! There was a minor hiccup as the ref SW did not properly handle VPS being inserted prior to every IRAP AUs, but with that resolved, all seems to be matching. Thanks! ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 1/3] avcodec/sanm: ignore unknown codecs in FOBJs
Don't error out, just ignore unknown codec numbers and pretend decode succeeded. This is useful for older LucasArts titles which stack a lot of different FOBJs with different codecs into a single frame. Mark the frame as corrupt though since we werent' able to decode everything that is supposed to be visible. Signed-off-by: Manuel Lauss --- v2: Mark frame as corrupt, suggested by Marton Balint libavcodec/sanm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index c30095ed32..a4f0a28c7c 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -1274,7 +1274,8 @@ static int process_frame_obj(SANMVideoContext *ctx) return old_codec48(ctx, w, h); default: avpriv_request_sample(ctx->avctx, "Subcodec %d", codec); -return AVERROR_PATCHWELCOME; +ctx->frame->flags |= AV_FRAME_FLAG_CORRUPT; +return 0; } } -- 2.48.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 2/3] avcodec/sanm: fobj left/top are signed
The left and top parameters of an FOBJ are signed values. Signed-off-by: Manuel Lauss --- v2: no changes. libavcodec/sanm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index a4f0a28c7c..71dbac4320 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -1238,8 +1238,8 @@ 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 left = bytestream2_get_le16u(&ctx->gb); -uint16_t top = bytestream2_get_le16u(&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); -- 2.48.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v2 3/3] avcodec/sanm: add smush 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 --- v2: no changes. Videos showing the before/after state (Rebel Assault II LEV09/09PLAY.SAN file) http://mlau.at/ffmpeg_c23_before.mp4 http://mlau.at/ffmpeg_c23_after.mp4 notice the blue transparent forcefields. libavcodec/sanm.c | 62 +-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index 71dbac4320..d5c4191aa5 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 { @@ -555,6 +556,58 @@ 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->width * ctx->pitch; +uint8_t *dst, lut[256], c; +int i, j, k, pc, sk; +int32_t pxoff; + +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) { @@ -1237,11 +1290,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 || !h) { av_log(ctx->avctx, AV_LOG_ERROR, "Dimensions are invalid.\n"); @@ -1260,12 +1317,13 @@ static int process_frame_obj(SANMVideoContext *ctx) return AVERROR(ENOMEM); } } -bytestream2_skip(&ctx->gb, 4); switch (codec) { case 1: case 3: return old_codec1(ctx, top, left, w, h); +case 23: +return old_codec23(ctx, top, left, w, h, param, parm2); case 37: return old_codec37(ctx, top, left, w, h); case 47: -- 2.48.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] Calling avformat_find_stream_info() more than once
Scott Theisen: > Hello all, > > avformat_find_stream_info() calls av_freep() on FFStream::info, which > will cause a segmentation fault if it is called more than once on the > same AVFormatContext (assuming it still has at least one of the > AVStreams from when it was called previously). > > Is this intentional and should this be documented? > avformat_find_stream_info() is indeed not supposed to be called more than once (on the same AVFormatContext). - Andreas ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v4 0/5] Properly decode ogg metadata in ogg/flac and ogg/opus chained bitstreams
This is a series of patches to allow proper decoding of ogg metadata in chained ogg/flac and ogg/opus streams. Changes since v3: * Added opus implementation * Cleaned up, separated patches in a more logical way. Summary of code changes: The changes in this patch series allow proper decoding of metadata associated with subsequent streams in chained ogg/flac and ogg/opus bitstream. This is done by intercepting ogg packets with comments in the ogg demuxer, parsing the comment block and attaching it as packed AV_PKT_DATA_METADATA_UPDATE side-data. The new metadata can then be unpacked in the corresponding decoder and properly added to the first decoded audio frame after the comment packet. It is worth noting that is using a mechanism specific to ogg stream that seemed to only have been used for vorbis streams so far. Along with the changes are new FATE tests validating the implementation. Discussion and context: ogg/opus is a pretty popular combination of codec and encapsulation. In particular, it is widely used in Icecast streams, where chained streams are the norm because of the ogg specs requirement for inserting in-band metadata. ogg/flac streams are pretty important because there are perhaps the only combination of lossless audio codec and open-source container that allows for proper transmittion of lossless audio data accross systems such as Icecast, browser media tags and more. In the context of long-running audio streams, the ogg bitstream specs[1] have historically been very badly implemented. For each new track and each new metadata, the specs require the logical bitstream to come to a full EOF and then start with a full new logical stream. These specs have often been confused with a gobal EOF by most implementations. Furtunately, FFmpeg is a little better at that in that it is able to parse chained logical ogg bitstreams and properly output either encoded ogg packets or decoded audio. Current limitations with chained ogg streams in FFmpeg include: 1. Metadata from secondary chained ogg/flac and ogg/opus bitstreams are ignored by the demuxer/decoder. 2. Secondary chained streams packet headers are silently removed by the demuxer when decoding ogg/opus streams. 3. No adjustment underlying PTS or DTS: PTS and DTS of secondary chained streams reset from their own logical stream initial value causing timestamp discontinuity. 4. Chained bitstreams with more than one underlying type of content (audio+video, etc) is not yet supported though this is a much less needed feature. The changes in this patch series address issues #1 and #2. Future work could address the remaining issues. Thanks, -- Romain [1]: https://xiph.org/ogg/doc/framing.html Romain Beauxis (6): libavformat/oggparseopus.c: Parse extradata from secondary chained streams header packet. tests: Add stream dump test API util. libavformat/oggparseopus.c: Parse comments from secondary chained ogg/opus streams and pass them as ogg stream new_metadata. tests: Add chained ogg/opus stream dump test. libavformat/oggparseflac.c: Parse ogg/flac comments in new ogg packets, add them to ogg stream new_metadata. tests: Add chained ogg/flac stream dump test. libavcodec/flacdec.c | 20 ++- libavcodec/opus/dec.c | 24 libavformat/oggdec.c | 4 - libavformat/oggparseflac.c| 28 + libavformat/oggparseopus.c| 25 tests/Makefile| 3 + tests/api/Makefile| 2 +- tests/api/api-dump-stream-meta-test.c | 169 ++ tests/fate/ogg-flac.mak | 11 ++ tests/fate/ogg-opus.mak | 11 ++ 10 files changed, 291 insertions(+), 6 deletions(-) create mode 100644 tests/api/api-dump-stream-meta-test.c create mode 100644 tests/fate/ogg-flac.mak create mode 100644 tests/fate/ogg-opus.mak -- 2.39.5 (Apple Git-154) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".