Re: [FFmpeg-devel] [PATCH] avdevice/alsa: simplify passing ff_alsa_open a channel layout

2025-02-10 Thread Nicolas George
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

2025-02-10 Thread Gyan Doshi




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

2025-02-10 Thread Jerome GORIN
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

2025-02-10 Thread Kieran Kunhya via ffmpeg-devel
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

2025-02-10 Thread James Almer

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

2025-02-10 Thread Martin Storsjö

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

2025-02-10 Thread Timo Rothenpieler
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

2025-02-10 Thread Gyan Doshi




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

2025-02-10 Thread Tong Wu
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

2025-02-10 Thread Martin Storsjö

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.

2025-02-10 Thread Ronald S. Bultje
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

2025-02-10 Thread Andreas Rheinhardt
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

2025-02-10 Thread Lynne



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

2025-02-10 Thread Andreas Rheinhardt
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

2025-02-10 Thread Lynne

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

2025-02-10 Thread Gyan Doshi
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

2025-02-10 Thread Martin Storsjö

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

2025-02-10 Thread Martin Storsjö

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

2025-02-10 Thread Gyan Doshi




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

2025-02-10 Thread Timo Rothenpieler

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

2025-02-10 Thread Martin Storsjö

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

2025-02-10 Thread Manuel Lauss
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

2025-02-10 Thread Manuel Lauss
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

2025-02-10 Thread Manuel Lauss
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

2025-02-10 Thread Michael Niedermayer
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

2025-02-10 Thread 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?

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.

2025-02-10 Thread Romain Beauxis
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

2025-02-10 Thread Marton Balint




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

2025-02-10 Thread Manuel Lauss
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.

2025-02-10 Thread Romain Beauxis
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.

2025-02-10 Thread Romain Beauxis
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.

2025-02-10 Thread Romain Beauxis
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

2025-02-10 Thread Romain Beauxis
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.

2025-02-10 Thread Romain Beauxis
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

2025-02-10 Thread Danny Hong
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

2025-02-10 Thread Manuel Lauss
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

2025-02-10 Thread Manuel Lauss
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

2025-02-10 Thread Manuel Lauss
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

2025-02-10 Thread Andreas Rheinhardt
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

2025-02-10 Thread Romain Beauxis
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".