Re: [FFmpeg-devel] Query from Reuters on XZ, open source, and Microsoft

2024-04-08 Thread Rémi Denis-Courmont
Hi,

Le 9 avril 2024 01:13:31 GMT+07:00, Romain Beauxis  a 
écrit :
>I would like to offer a constructive feedback really not intended as
>trolling. I believe that supporting a more modern development workflow such
>as the GitHub PR or gitlab MR would go very long way in helping onboarding
>new developers.

Switching to Github would certainly make it easier for new contributors to 
join. But it is most definitely not acceptable for political reasons for FFmpeg 
to switch over to a proprietary and US-based forge. Also most MRs would 
probably be craptastic kludges, which would only add to the review burden.

Switching to an own Gitlab instance would simplify code review (that's why I'm 
in favour) but it will add more burden on system admins, and make joining the 
project harder.

This may be counter-intuitive. But just look at the sad situation for projects 
hosted on code.videolan.org: people are back to submitting patches by mail or 
give up entirely due to how hard it is to create an account.

Lastly, I don't see how any of this helps motivate funding from big corps. 
Let's not miw things up here, please.
___
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 02/27] avcodec/decode: Add new ProgressFrame API

2024-04-08 Thread Michael Niedermayer
On Mon, Apr 08, 2024 at 10:13:40PM +0200, Andreas Rheinhardt wrote:
> Frame-threaded decoders with inter-frame dependencies
> use the ThreadFrame API for syncing. It works as follows:
> 
> During init each thread allocates an AVFrame for every
> ThreadFrame.
> 
> Thread A reads the header of its packet and allocates
> a buffer for an AVFrame with ff_thread_get_ext_buffer()
> (which also allocates a small structure that is shared
> with other references to this frame) and sets its fields,
> including side data. Then said thread calls ff_thread_finish_setup().
> From that moment onward it is not allowed to change any
> of the AVFrame fields at all any more, but it may change
> fields which are an indirection away, like the content of
> AVFrame.data or already existing side data.
> 
> After thread A has called ff_thread_finish_setup(),
> another thread (the user one) calls the codec's update_thread_context
> callback which in turn calls ff_thread_ref_frame() which
> calls av_frame_ref() which reads every field of A's
> AVFrame; hence the above restriction on modifications
> of the AVFrame (as any modification of the AVFrame by A after
> ff_thread_finish_setup() would be a data race). Of course,
> this av_frame_ref() also incurs allocations and therefore
> needs to be checked. ff_thread_ref_frame() also references
> the small structure used for communicating progress.
> 
> This av_frame_ref() makes it awkward to propagate values that
> only become known during decoding to later threads (in case of
> frame reordering or other mechanisms of delayed output (like
> show-existing-frames) it's not the decoding thread, but a later
> thread that returns the AVFrame). E.g. for VP9 when exporting video
> encoding parameters as side data the number of blocks only
> becomes known during decoding, so one can't allocate the side data
> before ff_thread_finish_setup(). It is currently being done afterwards
> and this leads to a data race in the vp9-encparams test when using
> frame-threading. Returning decode_error_flags is also complicated
> by this.
> 
> To perform this exchange a buffer shared between the references
> is needed (notice that simply giving the later threads a pointer
> to the original AVFrame does not work, because said AVFrame will
> be reused lateron when thread A decodes the next packet given to it).
> One could extend the buffer already used for progress for this
> or use a new one (requiring yet another allocation), yet both
> of these approaches have the drawback of being unnatural, ugly
> and requiring quite a lot of ad-hoc code. E.g. in case of the VP9
> side data mentioned above one could not simply use the helper
> that allocates and adds the side data to an AVFrame in one go.
> 
> The ProgressFrame API meanwhile offers a different solution to all
> of this. It is based around the idea that the most natural
> shared object for sharing information about an AVFrame between
> decoding threads is the AVFrame itself. To actually implement this
> the AVFrame needs to be reference counted. This is achieved by
> putting a (ownership) pointer into a shared (and opaque) structure
> that is managed by the RefStruct API and which also contains
> the stuff necessary for progress reporting.
> The users get a pointer to this AVFrame with the understanding
> that the owner may set all the fields until it has indicated
> that it has finished decoding this AVFrame; then the users are
> allowed to read everything. Every decoder may of course employ
> a different contract than the one outlined above.
> 
> Given that there is no underlying av_frame_ref(), creating
> references to a ProgressFrame can't fail. Only
> ff_thread_progress_get_buffer() can fail, but given that
> it will replace calls to ff_thread_get_ext_buffer() it is
> at places where errors are already expected and properly
> taken care of.
> 
> The ProgressFrames are empty (i.e. the AVFrame pointer is NULL
> and the AVFrames are not allocated during init at all)
> while not being in use; ff_thread_progress_get_buffer() both
> sets up the actual ProgressFrame and already calls
> ff_thread_get_buffer(). So instead of checking for
> ThreadFrame.f->data[0] or ThreadFrame.f->buf[0] being NULL
> for "this reference frame is non-existing" one should check for
> ProgressFrame.f.
> 
> This also implies that one can only set AVFrame properties
> after having allocated the buffer. This restriction is not deep:
> if it becomes onerous for any codec, ff_thread_progress_get_buffer()
> can be broken up. The user would then have to get a buffer
> himself.
> 
> In order to avoid unnecessary allocations, the shared structure
> is pooled, so that both the structure as well as the AVFrame
> itself are reused. This means that there won't be lots of
> unnecessary allocations in case of non-frame-threaded decoding.
> It might even turn out to have fewer than the current code
> (the current code allocates AVFrames for every DPB slot, but
> these are often excessively large and 

[FFmpeg-devel] [PATCH] avformat/lc3: Add file format for LC3/LC3plus transport

2024-04-08 Thread Antoine Soulier via ffmpeg-devel
From: Antoine SOULIER 

A file format is described in Bluetooth SIG LC3 and ETSI TS 103 634, for
test purpose. This is the format implemented here.
---
 Changelog|   1 +
 doc/muxers.texi  |   6 ++
 libavformat/Makefile |   2 +
 libavformat/allformats.c |   2 +
 libavformat/lc3dec.c | 173 +++
 libavformat/lc3enc.c | 114 ++
 6 files changed, 298 insertions(+)
 create mode 100644 libavformat/lc3dec.c
 create mode 100644 libavformat/lc3enc.c

diff --git a/Changelog b/Changelog
index 18e83b99a1..02ed7831ec 100644
--- a/Changelog
+++ b/Changelog
@@ -4,6 +4,7 @@ releases are sorted from youngest to oldest.
 version :
 - Raw Captions with Time (RCWT) closed caption demuxer
 - LC3/LC3plus decoding/encoding using external library liblc3
+- LC3/LC3plus demuxer and muxer
 
 
 version 7.0:
diff --git a/doc/muxers.texi b/doc/muxers.texi
index d8a1f83309..ed4144f6d1 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -2700,6 +2700,12 @@ computer-generated compositions.
 
 This muxer accepts a single audio stream containing PCM data.
 
+@section lc3
+Bluetooth SIG Low Complexity Communication Codec audio (LC3), or
+ETSI TS 103 634 Low Complexity Communication Codec plus (LC3plus).
+
+This muxer accepts a single @code{lc3} audio stream.
+
 @section matroska
 
 Matroska container muxer.
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 9981799cc9..027d0cdae5 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -332,6 +332,8 @@ OBJS-$(CONFIG_KVAG_DEMUXER)  += kvag.o
 OBJS-$(CONFIG_KVAG_MUXER)+= kvag.o rawenc.o
 OBJS-$(CONFIG_LAF_DEMUXER)   += lafdec.o
 OBJS-$(CONFIG_LATM_MUXER)+= latmenc.o rawenc.o
+OBJS-$(CONFIG_LC3_DEMUXER)   += lc3dec.o
+OBJS-$(CONFIG_LC3_MUXER) += lc3enc.o
 OBJS-$(CONFIG_LMLM4_DEMUXER) += lmlm4.o
 OBJS-$(CONFIG_LOAS_DEMUXER)  += loasdec.o rawdec.o
 OBJS-$(CONFIG_LUODAT_DEMUXER)+= luodatdec.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index ae925dcf60..305fa46532 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -252,6 +252,8 @@ extern const FFInputFormat  ff_kvag_demuxer;
 extern const FFOutputFormat ff_kvag_muxer;
 extern const FFInputFormat  ff_laf_demuxer;
 extern const FFOutputFormat ff_latm_muxer;
+extern const FFInputFormat  ff_lc3_demuxer;
+extern const FFOutputFormat ff_lc3_muxer;
 extern const FFInputFormat  ff_lmlm4_demuxer;
 extern const FFInputFormat  ff_loas_demuxer;
 extern const FFInputFormat  ff_luodat_demuxer;
diff --git a/libavformat/lc3dec.c b/libavformat/lc3dec.c
new file mode 100644
index 00..371e9242d5
--- /dev/null
+++ b/libavformat/lc3dec.c
@@ -0,0 +1,173 @@
+/*
+ * LC3 demuxer
+ * Copyright (C) 2024  Antoine Soulier 
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Based on the file format specified by :
+ *
+ * - Bluetooth SIG - Low Complexity Communication Codec Test Suite
+ *   https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=502301
+ *   3.2.8.2 Reference LC3 Codec Bitstream Format
+ *
+ * - ETSI TI 103 634 V1.4.1 - Low Complexity Communication Codec plus
+ *   
https://www.etsi.org/deliver/etsi_ts/103600_103699/103634/01.04.01_60/ts_103634v010401p.pdf
+ *   LC3plus conformance script package
+ */
+
+#include "libavcodec/packet.h"
+#include "libavutil/intreadwrite.h"
+
+#include "avformat.h"
+#include "avio.h"
+#include "demux.h"
+#include "internal.h"
+
+typedef struct LC3DemuxContext {
+int frame_samples;
+int64_t end_dts;
+} LC3DemuxContext;
+
+static int lc3_read_probe(const AVProbeData *p)
+{
+int frame_us, srate_hz;
+
+if (p->buf_size < 12)
+return 0;
+
+if (AV_RB16(p->buf + 0) != 0x1ccc ||
+AV_RL16(p->buf + 2) <  9 * sizeof(uint16_t))
+return 0;
+
+srate_hz = AV_RL16(p->buf + 4) * 100;
+if (srate_hz !=  8000 && srate_hz != 16000 && srate_hz != 24000 &&
+srate_hz != 32000 && srate_hz != 48000 && srate_hz != 96000)
+return 0;
+
+frame_us = AV_RL16(p->buf + 10) * 10;
+if (frame_us != 2500 && frame_us !=  5000 &&
+frame_us != 7500 && frame_us != 

Re: [FFmpeg-devel] [PATCH 01/11] avcodec: add avcodec_get_supported_config()

2024-04-08 Thread Niklas Haas
On Mon, 08 Apr 2024 22:18:33 +0200 Michael Niedermayer  
wrote:
> On Fri, Apr 05, 2024 at 08:57:11PM +0200, Niklas Haas wrote:
> > From: Niklas Haas 
> > 
> > This replaces the myriad of existing lists in AVCodec by a unified API
> > call, allowing us to (ultimately) trim down the sizeof(AVCodec) quite
> > substantially, while also making this more trivially extensible.
> > 
> > In addition to the already covered lists, add two new entries for color
> > space and color range, mirroring the newly added negotiable fields in
> > libavfilter.
> > 
> > I decided to drop the explicit length field from the API proposed by
> > Andreas Rheinhardt, because having it in place ended up complicating
> > both the codec side and the client side implementations, while also
> > being strictly less flexible (it's trivial to recover a length given
> > a terminator, but requires allocation to add a terminator given
> > a length). Using a terminator also presents less of a porting challenge
> > for existing users of the current API.
> > 
> > Once the deprecation period passes for the existing public fields, the
> > rough plan is to move the commonly used fields (such as
> > pix_fmt/sample_fmt) into FFCodec, possibly as a union of audio and video
> > configuration types, and then implement the rarely used fields with
> > custom callbacks.
> > ---
> >  doc/APIchanges  |  5 
> >  libavcodec/avcodec.c| 51 +
> >  libavcodec/avcodec.h| 27 
> >  libavcodec/codec.h  | 19 +++---
> >  libavcodec/codec_internal.h | 21 +++
> >  libavcodec/version.h|  4 +--
> >  6 files changed, 121 insertions(+), 6 deletions(-)
> 
> This patchset seems to overlap a bit with AVOptionRanges
> 
> I think ideally the user should at some point be able to query using some
> API on a AVCodecContext/AVCodecParameters/AVFormatContex/AVStream
> what for that specific instance are supported settings for each field
> 
> The API here seems to use a enum, which can make sense but it differs from
> how AVOption works which doesnt use enums to identify fields

I didn't know AVOptionRanges exists; indeed it can be seen as somewhat
overlapping here. That said, there is a vital distinction here: AVOptionRanges
represents *static* limits on what options can be set (e.g. via
`av_opt_set_int`), whereas this API represents *dynamic* limits on what can be
coded.

In particular, the list of supported colorspaces etc. can *depend* on the value
of other options. Currently, only strict_std_compliance, but I can easily see
this list growing in the future (e.g. for different profiles, dolbyvision,
...).

That aside, I personally find an API based on strings and doubles rather
cumbersome to use, especially when downstream clients expect an enum list.

> 
> 
> [...]
> -- 
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
> 
> Never trust a computer, one day, it may think you are the virus. -- Compn
> ___
> 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] Query from Reuters on XZ, open source, and Microsoft

2024-04-08 Thread Vittorio Giovara
On Mon, Apr 8, 2024 at 2:14 PM Romain Beauxis 
wrote:

> I would like to offer a constructive feedback really not intended as
> trolling. I believe that supporting a more modern development workflow such
> as the GitHub PR or gitlab MR would go very long way in helping onboarding
> new developers.
>

Plus one(thousdand). While I don't think using MR or mailing list for
patches will immediately convince big tech corps to sponsor ffmpeg, it
would definitely help the developer community and make sure we don't lose
patchsets.

The other open source community that I am involved with, the OCaml
> compiler, moved to GitHub maybe 5/6 years ago and this has really done
> wonders bringing in new contributors. And, you know, this is a niche
> compiler that is also not getting much attention from AI/Machine Learning
> people.
>

Other open source projects are probably less plagued by patents.
-- 
Vittorio
___
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 19/27] avcodec/hevcdec: Switch to ProgressFrames

2024-04-08 Thread Andreas Rheinhardt
Avoids implicit av_frame_ref() and therefore allocations
and error checks. It also avoids explicitly allocating
the AVFrames (done implicitly when getting the buffer).

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/hevc_filter.c |  8 
 libavcodec/hevc_mvs.c|  6 +++---
 libavcodec/hevc_refs.c   | 22 ++
 libavcodec/hevcdec.c | 24 ++--
 libavcodec/hevcdec.h |  4 ++--
 5 files changed, 29 insertions(+), 35 deletions(-)

diff --git a/libavcodec/hevc_filter.c b/libavcodec/hevc_filter.c
index 0c45310ea6..b1e2ea7a66 100644
--- a/libavcodec/hevc_filter.c
+++ b/libavcodec/hevc_filter.c
@@ -26,7 +26,7 @@
 #include "libavutil/internal.h"
 
 #include "hevcdec.h"
-#include "threadframe.h"
+#include "progressframe.h"
 
 #define LUMA 0
 #define CB 1
@@ -874,15 +874,15 @@ void ff_hevc_hls_filter(HEVCLocalContext *lc, int x, int 
y, int ctb_size)
 if (y && x_end) {
 sao_filter_CTB(lc, s, x, y - ctb_size);
 if (s->threads_type & FF_THREAD_FRAME )
-ff_thread_report_progress(>ref->tf, y, 0);
+ff_progress_frame_report(>ref->tf, y);
 }
 if (x_end && y_end) {
 sao_filter_CTB(lc, s, x , y);
 if (s->threads_type & FF_THREAD_FRAME )
-ff_thread_report_progress(>ref->tf, y + ctb_size, 0);
+ff_progress_frame_report(>ref->tf, y + ctb_size);
 }
 } else if (s->threads_type & FF_THREAD_FRAME && x_end)
-ff_thread_report_progress(>ref->tf, y + ctb_size - 4, 0);
+ff_progress_frame_report(>ref->tf, y + ctb_size - 4);
 }
 
 void ff_hevc_hls_filters(HEVCLocalContext *lc, int x_ctb, int y_ctb, int 
ctb_size)
diff --git a/libavcodec/hevc_mvs.c b/libavcodec/hevc_mvs.c
index 0a8cc2c43d..5591919e2e 100644
--- a/libavcodec/hevc_mvs.c
+++ b/libavcodec/hevc_mvs.c
@@ -23,7 +23,7 @@
 
 #include "hevc.h"
 #include "hevcdec.h"
-#include "threadframe.h"
+#include "progressframe.h"
 
 static const uint8_t l0_l1_cand_idx[12][2] = {
 { 0, 1, },
@@ -248,7 +248,7 @@ static int temporal_luma_motion_vector(const HEVCContext 
*s, int x0, int y0,
 x &= ~15;
 y &= ~15;
 if (s->threads_type == FF_THREAD_FRAME)
-ff_thread_await_progress(>tf, y, 0);
+ff_progress_frame_await(>tf, y);
 x_pu   = x >> s->ps.sps->log2_min_pu_size;
 y_pu   = y >> s->ps.sps->log2_min_pu_size;
 temp_col   = TAB_MVF(x_pu, y_pu);
@@ -262,7 +262,7 @@ static int temporal_luma_motion_vector(const HEVCContext 
*s, int x0, int y0,
 x &= ~15;
 y &= ~15;
 if (s->threads_type == FF_THREAD_FRAME)
-ff_thread_await_progress(>tf, y, 0);
+ff_progress_frame_await(>tf, y);
 x_pu   = x >> s->ps.sps->log2_min_pu_size;
 y_pu   = y >> s->ps.sps->log2_min_pu_size;
 temp_col   = TAB_MVF(x_pu, y_pu);
diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c
index aed649933d..192d311696 100644
--- a/libavcodec/hevc_refs.c
+++ b/libavcodec/hevc_refs.c
@@ -26,18 +26,15 @@
 #include "decode.h"
 #include "hevc.h"
 #include "hevcdec.h"
+#include "progressframe.h"
 #include "refstruct.h"
-#include "threadframe.h"
 
 void ff_hevc_unref_frame(HEVCFrame *frame, int flags)
 {
-/* frame->frame can be NULL if context init failed */
-if (!frame->frame || !frame->frame->buf[0])
-return;
-
 frame->flags &= ~flags;
 if (!frame->flags) {
-ff_thread_release_ext_buffer(>tf);
+ff_progress_frame_unref(>tf);
+frame->frame = NULL;
 av_frame_unref(frame->frame_grain);
 frame->needs_fg = 0;
 
@@ -83,13 +80,14 @@ static HEVCFrame *alloc_frame(HEVCContext *s)
 int i, j, ret;
 for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
 HEVCFrame *frame = >DPB[i];
-if (frame->frame->buf[0])
+if (frame->frame)
 continue;
 
-ret = ff_thread_get_ext_buffer(s->avctx, >tf,
-   AV_GET_BUFFER_FLAG_REF);
+ret = ff_progress_frame_get_buffer(s->avctx, >tf,
+   AV_GET_BUFFER_FLAG_REF);
 if (ret < 0)
 return NULL;
+frame->frame = frame->tf.f;
 
 frame->rpl = ff_refstruct_allocz(s->pkt.nb_nals * sizeof(*frame->rpl));
 if (!frame->rpl)
@@ -135,7 +133,7 @@ int ff_hevc_set_new_ref(HEVCContext *s, AVFrame **frame, 
int poc)
 for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) {
 HEVCFrame *frame = >DPB[i];
 
-if (frame->frame->buf[0] && frame->sequence == s->seq_decode &&
+if (frame->frame && frame->sequence == s->seq_decode &&
 frame->poc == poc) {
 av_log(s->avctx, AV_LOG_ERROR, "Duplicate POC in a sequence: 
%d.\n",
poc);
@@ -394,7 +392,7 @@ static HEVCFrame 

Re: [FFmpeg-devel] [PATCH 01/11] avcodec: add avcodec_get_supported_config()

2024-04-08 Thread Michael Niedermayer
On Mon, Apr 08, 2024 at 10:18:33PM +0200, Michael Niedermayer wrote:
> On Fri, Apr 05, 2024 at 08:57:11PM +0200, Niklas Haas wrote:
> > From: Niklas Haas 
> > 
> > This replaces the myriad of existing lists in AVCodec by a unified API
> > call, allowing us to (ultimately) trim down the sizeof(AVCodec) quite
> > substantially, while also making this more trivially extensible.
> > 
> > In addition to the already covered lists, add two new entries for color
> > space and color range, mirroring the newly added negotiable fields in
> > libavfilter.
> > 
> > I decided to drop the explicit length field from the API proposed by
> > Andreas Rheinhardt, because having it in place ended up complicating
> > both the codec side and the client side implementations, while also
> > being strictly less flexible (it's trivial to recover a length given
> > a terminator, but requires allocation to add a terminator given
> > a length). Using a terminator also presents less of a porting challenge
> > for existing users of the current API.
> > 
> > Once the deprecation period passes for the existing public fields, the
> > rough plan is to move the commonly used fields (such as
> > pix_fmt/sample_fmt) into FFCodec, possibly as a union of audio and video
> > configuration types, and then implement the rarely used fields with
> > custom callbacks.
> > ---
> >  doc/APIchanges  |  5 
> >  libavcodec/avcodec.c| 51 +
> >  libavcodec/avcodec.h| 27 
> >  libavcodec/codec.h  | 19 +++---
> >  libavcodec/codec_internal.h | 21 +++
> >  libavcodec/version.h|  4 +--
> >  6 files changed, 121 insertions(+), 6 deletions(-)
> 
> This patchset seems to overlap a bit with AVOptionRanges
> 
> I think ideally the user should at some point be able to query using some
> API on a AVCodecContext/AVCodecParameters/AVFormatContex/AVStream
> what for that specific instance are supported settings for each field

let me clarify this a bit more, what i envission is some generic API
that can take any AVClass/AVOption suporting struct and query a instance
of it for supported ranges/lists of a AVOption field.
some AVCodec passed into that call in addition to a AVCodecContext would
be more messy in a generic API

thx

[...]

-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

No great genius has ever existed without some touch of madness. -- Aristotle


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".


Re: [FFmpeg-devel] [PATCH 01/11] avcodec: add avcodec_get_supported_config()

2024-04-08 Thread Michael Niedermayer
On Fri, Apr 05, 2024 at 08:57:11PM +0200, Niklas Haas wrote:
> From: Niklas Haas 
> 
> This replaces the myriad of existing lists in AVCodec by a unified API
> call, allowing us to (ultimately) trim down the sizeof(AVCodec) quite
> substantially, while also making this more trivially extensible.
> 
> In addition to the already covered lists, add two new entries for color
> space and color range, mirroring the newly added negotiable fields in
> libavfilter.
> 
> I decided to drop the explicit length field from the API proposed by
> Andreas Rheinhardt, because having it in place ended up complicating
> both the codec side and the client side implementations, while also
> being strictly less flexible (it's trivial to recover a length given
> a terminator, but requires allocation to add a terminator given
> a length). Using a terminator also presents less of a porting challenge
> for existing users of the current API.
> 
> Once the deprecation period passes for the existing public fields, the
> rough plan is to move the commonly used fields (such as
> pix_fmt/sample_fmt) into FFCodec, possibly as a union of audio and video
> configuration types, and then implement the rarely used fields with
> custom callbacks.
> ---
>  doc/APIchanges  |  5 
>  libavcodec/avcodec.c| 51 +
>  libavcodec/avcodec.h| 27 
>  libavcodec/codec.h  | 19 +++---
>  libavcodec/codec_internal.h | 21 +++
>  libavcodec/version.h|  4 +--
>  6 files changed, 121 insertions(+), 6 deletions(-)

This patchset seems to overlap a bit with AVOptionRanges

I think ideally the user should at some point be able to query using some
API on a AVCodecContext/AVCodecParameters/AVFormatContex/AVStream
what for that specific instance are supported settings for each field

The API here seems to use a enum, which can make sense but it differs from
how AVOption works which doesnt use enums to identify fields


[...]
-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Never trust a computer, one day, it may think you are the virus. -- Compn


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] [PATCH v2 27/27] avcodec/v4l2_(m2m|buffers): Use RefStruct API for context references

2024-04-08 Thread Andreas Rheinhardt
Avoids allocations and therefore error checks; also avoids
indirections and allows to remove the boilerplate code
for creating an object with a dedicated free function.

Signed-off-by: Andreas Rheinhardt 
---
This patch is also still untested.

 libavcodec/v4l2_buffers.c |  7 +++
 libavcodec/v4l2_buffers.h |  6 +++---
 libavcodec/v4l2_m2m.c | 25 +
 libavcodec/v4l2_m2m.h |  5 ++---
 4 files changed, 17 insertions(+), 26 deletions(-)

diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c
index 2277135699..23474ee143 100644
--- a/libavcodec/v4l2_buffers.c
+++ b/libavcodec/v4l2_buffers.c
@@ -29,6 +29,7 @@
 #include 
 #include "libavcodec/avcodec.h"
 #include "libavutil/pixdesc.h"
+#include "refstruct.h"
 #include "v4l2_context.h"
 #include "v4l2_buffers.h"
 #include "v4l2_m2m.h"
@@ -229,7 +230,7 @@ static void v4l2_free_buffer(void *opaque, uint8_t *unused)
 ff_v4l2_buffer_enqueue(avbuf);
 }
 
-av_buffer_unref(>context_ref);
+ff_refstruct_unref(>context_ref);
 }
 }
 
@@ -240,9 +241,7 @@ static int v4l2_buf_increase_ref(V4L2Buffer *in)
 if (in->context_ref)
 atomic_fetch_add(>context_refcount, 1);
 else {
-in->context_ref = av_buffer_ref(s->self_ref);
-if (!in->context_ref)
-return AVERROR(ENOMEM);
+in->context_ref = ff_refstruct_ref(s->self_ref);
 
 in->context_refcount = 1;
 }
diff --git a/libavcodec/v4l2_buffers.h b/libavcodec/v4l2_buffers.h
index 3d2ff1b9a5..e35b161309 100644
--- a/libavcodec/v4l2_buffers.h
+++ b/libavcodec/v4l2_buffers.h
@@ -28,7 +28,6 @@
 #include 
 #include 
 
-#include "libavutil/buffer.h"
 #include "libavutil/frame.h"
 #include "packet.h"
 
@@ -46,8 +45,9 @@ typedef struct V4L2Buffer {
 struct V4L2Context *context;
 
 /* This object is refcounted per-plane, so we need to keep track
- * of how many context-refs we are holding. */
-AVBufferRef *context_ref;
+ * of how many context-refs we are holding.
+ * This pointer is a RefStruct reference. */
+const struct V4L2m2mContext *context_ref;
 atomic_uint context_refcount;
 
 /* keep track of the mmap address and mmap length */
diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c
index ac086a7913..15415cfc4e 100644
--- a/libavcodec/v4l2_m2m.c
+++ b/libavcodec/v4l2_m2m.c
@@ -32,6 +32,7 @@
 #include "libavutil/pixdesc.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/pixfmt.h"
+#include "refstruct.h"
 #include "v4l2_context.h"
 #include "v4l2_fmt.h"
 #include "v4l2_m2m.h"
@@ -247,9 +248,9 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mContext *s)
 return 0;
 }
 
-static void v4l2_m2m_destroy_context(void *opaque, uint8_t *context)
+static void v4l2_m2m_destroy_context(FFRefStructOpaque unused, void *context)
 {
-V4L2m2mContext *s = (V4L2m2mContext*)context;
+V4L2m2mContext *s = context;
 
 ff_v4l2_context_release(>capture);
 sem_destroy(>refsync);
@@ -258,8 +259,6 @@ static void v4l2_m2m_destroy_context(void *opaque, uint8_t 
*context)
 close(s->fd);
 av_frame_free(>frame);
 av_packet_unref(>buf_pkt);
-
-av_free(s);
 }
 
 int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv)
@@ -283,7 +282,7 @@ int ff_v4l2_m2m_codec_end(V4L2m2mPriv *priv)
 ff_v4l2_context_release(>output);
 
 s->self_ref = NULL;
-av_buffer_unref(>context_ref);
+ff_refstruct_unref(>context);
 
 return 0;
 }
@@ -328,17 +327,11 @@ int ff_v4l2_m2m_codec_init(V4L2m2mPriv *priv)
 
 int ff_v4l2_m2m_create_context(V4L2m2mPriv *priv, V4L2m2mContext **s)
 {
-*s = av_mallocz(sizeof(V4L2m2mContext));
+*s = ff_refstruct_alloc_ext(sizeof(**s), 0, NULL,
+_m2m_destroy_context);
 if (!*s)
 return AVERROR(ENOMEM);
 
-priv->context_ref = av_buffer_create((uint8_t *) *s, 
sizeof(V4L2m2mContext),
- _m2m_destroy_context, NULL, 0);
-if (!priv->context_ref) {
-av_freep(s);
-return AVERROR(ENOMEM);
-}
-
 /* assign the context */
 priv->context = *s;
 (*s)->priv = priv;
@@ -346,13 +339,13 @@ int ff_v4l2_m2m_create_context(V4L2m2mPriv *priv, 
V4L2m2mContext **s)
 /* populate it */
 priv->context->capture.num_buffers = priv->num_capture_buffers;
 priv->context->output.num_buffers  = priv->num_output_buffers;
-priv->context->self_ref = priv->context_ref;
+priv->context->self_ref = priv->context;
 priv->context->fd = -1;
 
 priv->context->frame = av_frame_alloc();
 if (!priv->context->frame) {
-av_buffer_unref(>context_ref);
-*s = NULL; /* freed when unreferencing context_ref */
+ff_refstruct_unref(>context);
+*s = NULL; /* freed when unreferencing context */
 return AVERROR(ENOMEM);
 }
 
diff --git a/libavcodec/v4l2_m2m.h b/libavcodec/v4l2_m2m.h
index 04d86d7b92..4ba33dc335 100644
--- a/libavcodec/v4l2_m2m.h
+++ b/libavcodec/v4l2_m2m.h
@@ -62,7 +62,7 @@ 

[FFmpeg-devel] [PATCH v2 26/27] avcodec/rkmppdec: Allocate AVDRMFrameDescriptor and frame ctx jointly

2024-04-08 Thread Andreas Rheinhardt
Avoids an allocation and therefore one error path.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/rkmppdec.c | 39 +++
 1 file changed, 15 insertions(+), 24 deletions(-)

diff --git a/libavcodec/rkmppdec.c b/libavcodec/rkmppdec.c
index e137e7e820..47b076dbd8 100644
--- a/libavcodec/rkmppdec.c
+++ b/libavcodec/rkmppdec.c
@@ -301,12 +301,10 @@ static int rkmpp_send_packet(AVCodecContext *avctx, const 
AVPacket *avpkt)
 static void rkmpp_release_frame(void *opaque, uint8_t *data)
 {
 AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor *)data;
-AVBufferRef *framecontextref = (AVBufferRef *)opaque;
-RKMPPFrameContext *framecontext = (RKMPPFrameContext 
*)framecontextref->data;
+RKMPPFrameContext *framecontext = opaque;
 
 mpp_frame_deinit(>frame);
 ff_refstruct_unref(>decoder_ref);
-av_buffer_unref();
 
 av_free(desc);
 }
@@ -315,12 +313,9 @@ static int rkmpp_retrieve_frame(AVCodecContext *avctx, 
AVFrame *frame)
 {
 RKMPPDecodeContext *rk_context = avctx->priv_data;
 RKMPPDecoder *decoder = rk_context->decoder;
-RKMPPFrameContext *framecontext = NULL;
-AVBufferRef *framecontextref = NULL;
 int ret;
 MppFrame mppframe = NULL;
 MppBuffer buffer = NULL;
-AVDRMFrameDescriptor *desc = NULL;
 AVDRMLayerDescriptor *layer = NULL;
 int mode;
 MppFrameFormat mppformat;
@@ -409,11 +404,21 @@ static int rkmpp_retrieve_frame(AVCodecContext *avctx, 
AVFrame *frame)
 // now setup the frame buffer info
 buffer = mpp_frame_get_buffer(mppframe);
 if (buffer) {
-desc = av_mallocz(sizeof(AVDRMFrameDescriptor));
-if (!desc) {
+RKMPPFrameContext *framecontext;
+AVDRMFrameDescriptor *desc;
+// We allocate the descriptor in buf[0] jointly with a structure
+// that will allow to hold additional information
+// for properly releasing MPP frames and decoder.
+struct {
+AVDRMFrameDescriptor desc;
+RKMPPFrameContext framecontext;
+} *combined_desc = av_mallocz(sizeof(*combined_desc));
+if (!combined_desc) {
 ret = AVERROR(ENOMEM);
 goto fail;
 }
+desc = _desc->desc;
+framecontext = _desc->framecontext;
 
 desc->nb_objects = 1;
 desc->objects[0].fd = mpp_buffer_get_fd(buffer);
@@ -432,23 +437,15 @@ static int rkmpp_retrieve_frame(AVCodecContext *avctx, 
AVFrame *frame)
 layer->planes[1].offset = layer->planes[0].pitch * 
mpp_frame_get_ver_stride(mppframe);
 layer->planes[1].pitch = layer->planes[0].pitch;
 
-// we also allocate a struct in buf[0] that will allow to hold 
additionnal information
-// for releasing properly MPP frames and decoder
-framecontextref = av_buffer_allocz(sizeof(*framecontext));
-if (!framecontextref) {
-ret = AVERROR(ENOMEM);
-goto fail;
-}
-
 // MPP decoder needs to be closed only when all frames have been 
released.
-framecontext = (RKMPPFrameContext *)framecontextref->data;
 framecontext->frame = mppframe;
 
 frame->data[0]  = (uint8_t *)desc;
 frame->buf[0]   = av_buffer_create((uint8_t *)desc, sizeof(*desc), 
rkmpp_release_frame,
-   framecontextref, 
AV_BUFFER_FLAG_READONLY);
+   framecontext, 
AV_BUFFER_FLAG_READONLY);
 
 if (!frame->buf[0]) {
+av_free(combined_desc);
 ret = AVERROR(ENOMEM);
 goto fail;
 }
@@ -477,12 +474,6 @@ fail:
 if (mppframe)
 mpp_frame_deinit();
 
-if (framecontextref)
-av_buffer_unref();
-
-if (desc)
-av_free(desc);
-
 return ret;
 }
 
-- 
2.40.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 25/27] avcodec/rkmppdec: Use RefStruct API for references to decoder itself

2024-04-08 Thread Andreas Rheinhardt
Avoids boilerplate code when creating the context
and avoids allocations and therefore whole error paths
when creating references to it. Also avoids an indirection
and improves type-safety.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/rkmppdec.c | 46 +++
 1 file changed, 16 insertions(+), 30 deletions(-)

diff --git a/libavcodec/rkmppdec.c b/libavcodec/rkmppdec.c
index 4e14d09c7c..e137e7e820 100644
--- a/libavcodec/rkmppdec.c
+++ b/libavcodec/rkmppdec.c
@@ -30,6 +30,7 @@
 #include "codec_internal.h"
 #include "decode.h"
 #include "hwconfig.h"
+#include "refstruct.h"
 #include "libavutil/buffer.h"
 #include "libavutil/common.h"
 #include "libavutil/frame.h"
@@ -57,12 +58,12 @@ typedef struct {
 
 typedef struct {
 AVClass *av_class;
-AVBufferRef *decoder_ref;
+RKMPPDecoder *decoder;   ///< RefStruct reference
 } RKMPPDecodeContext;
 
 typedef struct {
 MppFrame frame;
-AVBufferRef *decoder_ref;
+const RKMPPDecoder *decoder_ref; ///< RefStruct reference
 } RKMPPFrameContext;
 
 static MppCodingType rkmpp_get_codingtype(AVCodecContext *avctx)
@@ -90,7 +91,7 @@ static uint32_t rkmpp_get_frameformat(MppFrameFormat 
mppformat)
 static int rkmpp_write_data(AVCodecContext *avctx, uint8_t *buffer, int size, 
int64_t pts)
 {
 RKMPPDecodeContext *rk_context = avctx->priv_data;
-RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data;
+RKMPPDecoder *decoder = rk_context->decoder;
 int ret;
 MppPacket packet;
 
@@ -125,13 +126,13 @@ static int rkmpp_write_data(AVCodecContext *avctx, 
uint8_t *buffer, int size, in
 static int rkmpp_close_decoder(AVCodecContext *avctx)
 {
 RKMPPDecodeContext *rk_context = avctx->priv_data;
-av_buffer_unref(_context->decoder_ref);
+ff_refstruct_unref(_context->decoder);
 return 0;
 }
 
-static void rkmpp_release_decoder(void *opaque, uint8_t *data)
+static void rkmpp_release_decoder(FFRefStructOpaque unused, void *obj)
 {
-RKMPPDecoder *decoder = (RKMPPDecoder *)data;
+RKMPPDecoder *decoder = obj;
 
 if (decoder->mpi) {
 decoder->mpi->reset(decoder->ctx);
@@ -146,8 +147,6 @@ static void rkmpp_release_decoder(void *opaque, uint8_t 
*data)
 
 av_buffer_unref(>frames_ref);
 av_buffer_unref(>device_ref);
-
-av_free(decoder);
 }
 
 static int rkmpp_init_decoder(AVCodecContext *avctx)
@@ -162,19 +161,13 @@ static int rkmpp_init_decoder(AVCodecContext *avctx)
 avctx->pix_fmt = AV_PIX_FMT_DRM_PRIME;
 
 // create a decoder and a ref to it
-decoder = av_mallocz(sizeof(RKMPPDecoder));
+decoder = ff_refstruct_alloc_ext(sizeof(*decoder), 0,
+ NULL, rkmpp_release_decoder);
 if (!decoder) {
 ret = AVERROR(ENOMEM);
 goto fail;
 }
-
-rk_context->decoder_ref = av_buffer_create((uint8_t *)decoder, 
sizeof(*decoder), rkmpp_release_decoder,
-   NULL, AV_BUFFER_FLAG_READONLY);
-if (!rk_context->decoder_ref) {
-av_free(decoder);
-ret = AVERROR(ENOMEM);
-goto fail;
-}
+rk_context->decoder = decoder;
 
 av_log(avctx, AV_LOG_DEBUG, "Initializing RKMPP decoder.\n");
 
@@ -270,7 +263,7 @@ fail:
 static int rkmpp_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
 {
 RKMPPDecodeContext *rk_context = avctx->priv_data;
-RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data;
+RKMPPDecoder *decoder = rk_context->decoder;
 int ret;
 
 // handle EOF
@@ -312,7 +305,7 @@ static void rkmpp_release_frame(void *opaque, uint8_t *data)
 RKMPPFrameContext *framecontext = (RKMPPFrameContext 
*)framecontextref->data;
 
 mpp_frame_deinit(>frame);
-av_buffer_unref(>decoder_ref);
+ff_refstruct_unref(>decoder_ref);
 av_buffer_unref();
 
 av_free(desc);
@@ -321,7 +314,7 @@ static void rkmpp_release_frame(void *opaque, uint8_t *data)
 static int rkmpp_retrieve_frame(AVCodecContext *avctx, AVFrame *frame)
 {
 RKMPPDecodeContext *rk_context = avctx->priv_data;
-RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data;
+RKMPPDecoder *decoder = rk_context->decoder;
 RKMPPFrameContext *framecontext = NULL;
 AVBufferRef *framecontextref = NULL;
 int ret;
@@ -449,11 +442,6 @@ static int rkmpp_retrieve_frame(AVCodecContext *avctx, 
AVFrame *frame)
 
 // MPP decoder needs to be closed only when all frames have been 
released.
 framecontext = (RKMPPFrameContext *)framecontextref->data;
-framecontext->decoder_ref = av_buffer_ref(rk_context->decoder_ref);
-if (!framecontext->decoder_ref) {
-ret = AVERROR(ENOMEM);
-goto fail;
-}
 framecontext->frame = mppframe;
 
 frame->data[0]  = (uint8_t *)desc;
@@ -464,6 +452,7 @@ static int rkmpp_retrieve_frame(AVCodecContext *avctx, 
AVFrame *frame)
 ret = 

[FFmpeg-devel] [PATCH v2 24/27] avcodec/rkmppdec: Check av_buffer_ref()

2024-04-08 Thread Andreas Rheinhardt
Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/rkmppdec.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/libavcodec/rkmppdec.c b/libavcodec/rkmppdec.c
index 6889545b20..4e14d09c7c 100644
--- a/libavcodec/rkmppdec.c
+++ b/libavcodec/rkmppdec.c
@@ -450,6 +450,10 @@ static int rkmpp_retrieve_frame(AVCodecContext *avctx, 
AVFrame *frame)
 // MPP decoder needs to be closed only when all frames have been 
released.
 framecontext = (RKMPPFrameContext *)framecontextref->data;
 framecontext->decoder_ref = av_buffer_ref(rk_context->decoder_ref);
+if (!framecontext->decoder_ref) {
+ret = AVERROR(ENOMEM);
+goto fail;
+}
 framecontext->frame = mppframe;
 
 frame->data[0]  = (uint8_t *)desc;
-- 
2.40.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 23/27] avcodec/rkmppdec: Fix double-free on error

2024-04-08 Thread Andreas Rheinhardt
After having created the AVBuffer that is put into frame->buf[0],
ownership of several objects (namely an AVDRMFrameDescriptor,
an MppFrame and some AVBufferRefs framecontextref and decoder_ref)
has passed to the AVBuffer and therefore to the frame.
Yet it has nevertheless been freed manually on error
afterwards, which would lead to a double-free as soon
as the AVFrame is unreferenced.

Signed-off-by: Andreas Rheinhardt 
---
The rockchip patches are still untested (except for compilation).

 libavcodec/rkmppdec.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/rkmppdec.c b/libavcodec/rkmppdec.c
index 7665098c6a..6889545b20 100644
--- a/libavcodec/rkmppdec.c
+++ b/libavcodec/rkmppdec.c
@@ -463,8 +463,8 @@ static int rkmpp_retrieve_frame(AVCodecContext *avctx, 
AVFrame *frame)
 
 frame->hw_frames_ctx = av_buffer_ref(decoder->frames_ref);
 if (!frame->hw_frames_ctx) {
-ret = AVERROR(ENOMEM);
-goto fail;
+av_frame_unref(frame);
+return AVERROR(ENOMEM);
 }
 
 return 0;
-- 
2.40.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 22/27] avcodec/qsv: Use RefStruct API for memory id (mids) array

2024-04-08 Thread Andreas Rheinhardt
Avoids allocations and therefore error checks and cleanup code;
also avoids indirections.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/qsv.c  | 55 +++
 libavcodec/qsv_internal.h | 11 
 libavcodec/qsvdec.c   |  3 ++-
 libavcodec/qsvenc.c   |  3 ++-
 4 files changed, 31 insertions(+), 41 deletions(-)

diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index d9c81b7158..b07302cdf6 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -35,6 +35,7 @@
 
 #include "avcodec.h"
 #include "qsv_internal.h"
+#include "refstruct.h"
 
 #define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl))
 #define QSV_HAVE_USER_PLUGIN!QSV_ONEVPL
@@ -740,20 +741,19 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, 
QSVSession *qs,
 return 0;
 }
 
-static void mids_buf_free(void *opaque, uint8_t *data)
+static void mids_buf_free(FFRefStructOpaque opaque, void *obj)
 {
-AVBufferRef *hw_frames_ref = opaque;
+AVBufferRef *hw_frames_ref = opaque.nc;
 av_buffer_unref(_frames_ref);
-av_freep();
 }
 
-static AVBufferRef *qsv_create_mids(AVBufferRef *hw_frames_ref)
+static QSVMid *qsv_create_mids(AVBufferRef *hw_frames_ref)
 {
 AVHWFramesContext*frames_ctx = (AVHWFramesContext*)hw_frames_ref->data;
 AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
 int  nb_surfaces = frames_hwctx->nb_surfaces;
 
-AVBufferRef *mids_buf, *hw_frames_ref1;
+AVBufferRef *hw_frames_ref1;
 QSVMid *mids;
 int i;
 
@@ -761,35 +761,27 @@ static AVBufferRef *qsv_create_mids(AVBufferRef 
*hw_frames_ref)
 if (!hw_frames_ref1)
 return NULL;
 
-mids = av_calloc(nb_surfaces, sizeof(*mids));
+mids = ff_refstruct_alloc_ext(nb_surfaces * sizeof(*mids), 0,
+  hw_frames_ref1, mids_buf_free);
 if (!mids) {
 av_buffer_unref(_frames_ref1);
 return NULL;
 }
 
-mids_buf = av_buffer_create((uint8_t*)mids, nb_surfaces * sizeof(*mids),
-mids_buf_free, hw_frames_ref1, 0);
-if (!mids_buf) {
-av_buffer_unref(_frames_ref1);
-av_freep();
-return NULL;
-}
-
 for (i = 0; i < nb_surfaces; i++) {
 QSVMid *mid = [i];
 mid->handle_pair   = (mfxHDLPair*)frames_hwctx->surfaces[i].Data.MemId;
 mid->hw_frames_ref = hw_frames_ref1;
 }
 
-return mids_buf;
+return mids;
 }
 
 static int qsv_setup_mids(mfxFrameAllocResponse *resp, AVBufferRef 
*hw_frames_ref,
-  AVBufferRef *mids_buf)
+  QSVMid *mids)
 {
 AVHWFramesContext*frames_ctx = (AVHWFramesContext*)hw_frames_ref->data;
 AVQSVFramesContext *frames_hwctx = frames_ctx->hwctx;
-QSVMid *mids = (QSVMid*)mids_buf->data;
 int  nb_surfaces = frames_hwctx->nb_surfaces;
 int i;
 
@@ -810,12 +802,7 @@ static int qsv_setup_mids(mfxFrameAllocResponse *resp, 
AVBufferRef *hw_frames_re
 return AVERROR(ENOMEM);
 }
 
-resp->mids[resp->NumFrameActual + 1] = av_buffer_ref(mids_buf);
-if (!resp->mids[resp->NumFrameActual + 1]) {
-av_buffer_unref((AVBufferRef**)>mids[resp->NumFrameActual]);
-av_freep(>mids);
-return AVERROR(ENOMEM);
-}
+resp->mids[resp->NumFrameActual + 1] = ff_refstruct_ref(mids);
 
 return 0;
 }
@@ -849,7 +836,7 @@ static mfxStatus qsv_frame_alloc(mfxHDL pthis, 
mfxFrameAllocRequest *req,
 return MFX_ERR_UNSUPPORTED;
 }
 
-ret = qsv_setup_mids(resp, ctx->hw_frames_ctx, ctx->mids_buf);
+ret = qsv_setup_mids(resp, ctx->hw_frames_ctx, ctx->mids);
 if (ret < 0) {
 av_log(ctx->logctx, AV_LOG_ERROR,
"Error filling an external frame allocation request\n");
@@ -860,7 +847,8 @@ static mfxStatus qsv_frame_alloc(mfxHDL pthis, 
mfxFrameAllocRequest *req,
 AVHWFramesContext *ext_frames_ctx = 
(AVHWFramesContext*)ctx->hw_frames_ctx->data;
 mfxFrameInfo  *i  = >Info;
 
-AVBufferRef *frames_ref, *mids_buf;
+AVBufferRef *frames_ref;
+QSVMid *mids;
 AVHWFramesContext *frames_ctx;
 AVQSVFramesContext *frames_hwctx;
 
@@ -888,14 +876,14 @@ static mfxStatus qsv_frame_alloc(mfxHDL pthis, 
mfxFrameAllocRequest *req,
 return MFX_ERR_MEMORY_ALLOC;
 }
 
-mids_buf = qsv_create_mids(frames_ref);
-if (!mids_buf) {
+mids = qsv_create_mids(frames_ref);
+if (!mids) {
 av_buffer_unref(_ref);
 return MFX_ERR_MEMORY_ALLOC;
 }
 
-ret = qsv_setup_mids(resp, frames_ref, mids_buf);
-av_buffer_unref(_buf);
+ret = qsv_setup_mids(resp, frames_ref, mids);
+ff_refstruct_unref();
 av_buffer_unref(_ref);
 if (ret < 0) {
 av_log(ctx->logctx, AV_LOG_ERROR,
@@ -912,7 +900,7 @@ static mfxStatus qsv_frame_alloc(mfxHDL pthis, 

[FFmpeg-devel] [PATCH v2 21/27] avcodec/ffv1dec: Switch to ProgressFrames

2024-04-08 Thread Andreas Rheinhardt
Avoids implicit av_frame_ref() and therefore allocations
and error checks. It also avoids explicitly allocating
the AVFrames (done implicitly when getting the buffer).

It also fixes a data race: The AVFrame's sample_aspect_ratio
is currently updated after ff_thread_finish_setup()
and this write is unsynchronized with the read in av_frame_ref().
Removing the implicit av_frame_ref() fixed this.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/ffv1.h|  5 ++-
 libavcodec/ffv1dec.c | 81 +++-
 2 files changed, 36 insertions(+), 50 deletions(-)

diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h
index 04869da5c9..acec22e83e 100644
--- a/libavcodec/ffv1.h
+++ b/libavcodec/ffv1.h
@@ -28,13 +28,12 @@
  * FF Video Codec 1 (a lossless codec)
  */
 
-#include "libavutil/imgutils.h"
 #include "avcodec.h"
 #include "get_bits.h"
 #include "mathops.h"
+#include "progressframe.h"
 #include "put_bits.h"
 #include "rangecoder.h"
-#include "threadframe.h"
 
 #ifdef __INTEL_COMPILER
 #undef av_flatten
@@ -87,7 +86,7 @@ typedef struct FFV1Context {
 int flags;
 int64_t picture_number;
 int key_frame;
-ThreadFrame picture, last_picture;
+ProgressFrame picture, last_picture;
 struct FFV1Context *fsrc;
 
 AVFrame *cur;
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index dd594e3f9f..7a0d1909aa 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -37,8 +37,8 @@
 #include "golomb.h"
 #include "mathops.h"
 #include "ffv1.h"
+#include "progressframe.h"
 #include "thread.h"
-#include "threadframe.h"
 
 static inline av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state,
int is_signed)
@@ -264,8 +264,8 @@ static int decode_slice(AVCodecContext *c, void *arg)
 for( si=0; fs != f->slice_context[si]; si ++)
 ;
 
-if(f->fsrc && !(p->flags & AV_FRAME_FLAG_KEY))
-ff_thread_await_progress(>last_picture, si, 0);
+if (f->fsrc && !(p->flags & AV_FRAME_FLAG_KEY) && f->last_picture.f)
+ff_progress_frame_await(>last_picture, si);
 
 if(f->fsrc && !(p->flags & AV_FRAME_FLAG_KEY)) {
 FFV1Context *fssrc = f->fsrc->slice_context[si];
@@ -370,7 +370,7 @@ static int decode_slice(AVCodecContext *c, void *arg)
 }
 }
 
-ff_thread_report_progress(>picture, si, 0);
+ff_progress_frame_report(>picture, si);
 
 return 0;
 }
@@ -858,11 +858,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
 if ((ret = ff_ffv1_common_init(avctx)) < 0)
 return ret;
 
-f->picture.f  = av_frame_alloc();
-f->last_picture.f = av_frame_alloc();
-if (!f->picture.f || !f->last_picture.f)
-return AVERROR(ENOMEM);
-
 if (avctx->extradata_size > 0 && (ret = read_extra_header(f)) < 0)
 return ret;
 
@@ -879,31 +874,21 @@ static int decode_frame(AVCodecContext *avctx, AVFrame 
*rframe,
 int buf_size= avpkt->size;
 FFV1Context *f  = avctx->priv_data;
 RangeCoder *const c = >slice_context[0]->c;
-int i, ret;
+int i, ret, key_frame;
 uint8_t keystate = 128;
 uint8_t *buf_p;
 AVFrame *p;
 
-if (f->last_picture.f)
-ff_thread_release_ext_buffer(>last_picture);
-FFSWAP(ThreadFrame, f->picture, f->last_picture);
-
-f->cur = p = f->picture.f;
+ff_progress_frame_unref(>last_picture);
+FFSWAP(ProgressFrame, f->picture, f->last_picture);
 
-if (f->version < 3 && avctx->field_order > AV_FIELD_PROGRESSIVE) {
-/* we have interlaced material flagged in container */
-p->flags |= AV_FRAME_FLAG_INTERLACED;
-if (avctx->field_order == AV_FIELD_TT || avctx->field_order == 
AV_FIELD_TB)
-p->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
-}
 
 f->avctx = avctx;
 ff_init_range_decoder(c, buf, buf_size);
 ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
 
-p->pict_type = AV_PICTURE_TYPE_I; //FIXME I vs. P
 if (get_rac(c, )) {
-p->flags |= AV_FRAME_FLAG_KEY;
+key_frame = AV_FRAME_FLAG_KEY;
 f->key_frame_ok = 0;
 if ((ret = read_header(f)) < 0)
 return ret;
@@ -914,7 +899,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame 
*rframe,
"Cannot decode non-keyframe without valid keyframe\n");
 return AVERROR_INVALIDDATA;
 }
-p->flags &= ~AV_FRAME_FLAG_KEY;
+key_frame = 0;
 }
 
 if (f->ac != AC_GOLOMB_RICE) {
@@ -932,10 +917,23 @@ static int decode_frame(AVCodecContext *avctx, AVFrame 
*rframe,
 return AVERROR_INVALIDDATA;
 }
 
-ret = ff_thread_get_ext_buffer(avctx, >picture, AV_GET_BUFFER_FLAG_REF);
+ret = ff_progress_frame_get_buffer(avctx, >picture,
+   AV_GET_BUFFER_FLAG_REF);
 if (ret < 0)
 return ret;
 
+f->cur = p = f->picture.f;
+
+p->pict_type = AV_PICTURE_TYPE_I; //FIXME I vs. P
+p->flags = (p->flags & 

[FFmpeg-devel] [PATCH v2 20/27] avcodec/pngdec: Switch to ProgressFrames

2024-04-08 Thread Andreas Rheinhardt
Avoids implicit av_frame_ref() and therefore allocations
and error checks. It also avoids explicitly allocating
the AVFrames (done implicitly when getting the buffer).

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/pngdec.c | 67 ++---
 1 file changed, 27 insertions(+), 40 deletions(-)

diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index 5a99b4a1c4..f7751223b8 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -42,8 +42,8 @@
 #include "apng.h"
 #include "png.h"
 #include "pngdsp.h"
+#include "progressframe.h"
 #include "thread.h"
-#include "threadframe.h"
 #include "zlib_wrapper.h"
 
 #include 
@@ -63,8 +63,8 @@ typedef struct PNGDecContext {
 AVCodecContext *avctx;
 
 GetByteContext gb;
-ThreadFrame last_picture;
-ThreadFrame picture;
+ProgressFrame last_picture;
+ProgressFrame picture;
 
 AVDictionary *frame_metadata;
 
@@ -874,7 +874,7 @@ static int decode_idat_chunk(AVCodecContext *avctx, 
PNGDecContext *s,
 s->bpp += byte_depth;
 }
 
-ff_thread_release_ext_buffer(>picture);
+ff_progress_frame_unref(>picture);
 if (s->dispose_op == APNG_DISPOSE_OP_PREVIOUS) {
 /* We only need a buffer for the current picture. */
 ret = ff_thread_get_buffer(avctx, p, 0);
@@ -883,8 +883,8 @@ static int decode_idat_chunk(AVCodecContext *avctx, 
PNGDecContext *s,
 } else if (s->dispose_op == APNG_DISPOSE_OP_BACKGROUND) {
 /* We need a buffer for the current picture as well as
  * a buffer for the reference to retain. */
-ret = ff_thread_get_ext_buffer(avctx, >picture,
-   AV_GET_BUFFER_FLAG_REF);
+ret = ff_progress_frame_get_buffer(avctx, >picture,
+   AV_GET_BUFFER_FLAG_REF);
 if (ret < 0)
 return ret;
 ret = ff_thread_get_buffer(avctx, p, 0);
@@ -892,8 +892,9 @@ static int decode_idat_chunk(AVCodecContext *avctx, 
PNGDecContext *s,
 return ret;
 } else {
 /* The picture output this time and the reference to retain 
coincide. */
-if ((ret = ff_thread_get_ext_buffer(avctx, >picture,
-AV_GET_BUFFER_FLAG_REF)) < 0)
+ret = ff_progress_frame_get_buffer(avctx, >picture,
+AV_GET_BUFFER_FLAG_REF);
+if (ret < 0)
 return ret;
 ret = av_frame_ref(p, s->picture.f);
 if (ret < 0)
@@ -1254,7 +1255,7 @@ static void handle_p_frame_png(PNGDecContext *s, AVFrame 
*p)
 
 ls = FFMIN(ls, s->width * s->bpp);
 
-ff_thread_await_progress(>last_picture, INT_MAX, 0);
+ff_progress_frame_await(>last_picture, INT_MAX);
 for (j = 0; j < s->height; j++) {
 for (i = 0; i < ls; i++)
 pd[i] += pd_last[i];
@@ -1286,7 +1287,7 @@ static int handle_p_frame_apng(AVCodecContext *avctx, 
PNGDecContext *s,
 return AVERROR_PATCHWELCOME;
 }
 
-ff_thread_await_progress(>last_picture, INT_MAX, 0);
+ff_progress_frame_await(>last_picture, INT_MAX);
 
 // copy unchanged rectangles from the last frame
 for (y = 0; y < s->y_offset; y++)
@@ -1674,7 +1675,7 @@ exit_loop:
 }
 
 /* handle P-frames only if a predecessor frame is available */
-if (s->last_picture.f->data[0]) {
+if (s->last_picture.f) {
 if (   !(avpkt->flags & AV_PKT_FLAG_KEY) && avctx->codec_tag != 
AV_RL32("MPNG")
 && s->last_picture.f->width == p->width
 && s->last_picture.f->height== p->height
@@ -1691,12 +1692,11 @@ exit_loop:
 if (CONFIG_APNG_DECODER && s->dispose_op == APNG_DISPOSE_OP_BACKGROUND)
 apng_reset_background(s, p);
 
-ff_thread_report_progress(>picture, INT_MAX, 0);
-
-return 0;
-
+ret = 0;
 fail:
-ff_thread_report_progress(>picture, INT_MAX, 0);
+if (s->picture.f)
+ff_progress_frame_report(>picture, INT_MAX);
+
 return ret;
 }
 
@@ -1783,8 +1783,8 @@ static int decode_frame_png(AVCodecContext *avctx, 
AVFrame *p,
 goto the_end;
 
 if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
-ff_thread_release_ext_buffer(>last_picture);
-FFSWAP(ThreadFrame, s->picture, s->last_picture);
+ff_progress_frame_unref(>last_picture);
+FFSWAP(ProgressFrame, s->picture, s->last_picture);
 }
 
 *got_frame = 1;
@@ -1835,12 +1835,9 @@ static int decode_frame_apng(AVCodecContext *avctx, 
AVFrame *p,
 return ret;
 
 if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
-if (s->dispose_op == APNG_DISPOSE_OP_PREVIOUS) {
-ff_thread_release_ext_buffer(>picture);
-} else {
-ff_thread_release_ext_buffer(>last_picture);
-FFSWAP(ThreadFrame, s->picture, s->last_picture);
-}
+if (s->dispose_op != 

[FFmpeg-devel] [PATCH v2 18/27] avcodec/codec_internal: Remove FF_CODEC_CAP_ALLOCATE_PROGRESS

2024-04-08 Thread Andreas Rheinhardt
Before commit f025b8e110b36c1cdb4fb56c4cd57aeca1767b5b,
every frame-threaded decoder used ThreadFrames, even when
they did not have any inter-frame dependencies at all.
In order to distinguish those decoders that need the AVBuffer
for progress communication from those that do not (to avoid
the allocation for the latter), the former decoders were marked
with the FF_CODEC_CAP_ALLOCATE_PROGRESS internal codec cap.

Yet distinguishing these two can be done in a more natural way:
Don't use ThreadFrames when not needed and split ff_thread_get_buffer()
into a core function that calls the user's get_buffer2 callback
and a wrapper around it that also allocates the progress AVBuffer.
This has been done in 02220b88fc38ef9dd4f2d519f5d3e4151258b60c
and since that commit the ALLOCATE_PROGRESS cap was nearly redundant.

The only exception was WebP and VP8. WebP can contain VP8
and uses the VP8 decoder directly (i.e. they share the same
AVCodecContext). Both decoders are frame-threaded and VP8
has inter-frame dependencies (in general, not in valid WebP)
and therefore the ALLOCATE_PROGRESS cap. In order to avoid
allocating progress in case of a frame-threaded WebP decoder
the cap and the check for the cap has been kept in place.

Yet now the VP8 decoder has been switched to use ProgressFrames
and therefore there is just no reason any more for this check
and the cap. This commit therefore removes both.

Also change the value of FF_CODEC_CAP_USES_PROGRESSFRAMES
to leave no gaps.

Signed-off-by: Andreas Rheinhardt 
---
 doc/multithreading.txt  | 15 +++
 libavcodec/codec_internal.h |  7 +--
 libavcodec/ffv1dec.c|  3 +--
 libavcodec/h264dec.c|  2 +-
 libavcodec/hevcdec.c|  2 +-
 libavcodec/mpeg4videodec.c  |  3 +--
 libavcodec/pngdec.c |  3 +--
 libavcodec/pthread_frame.c  | 12 +---
 libavcodec/rv30.c   |  1 -
 libavcodec/rv40.c   |  1 -
 libavcodec/tests/avcodec.c  |  5 -
 11 files changed, 18 insertions(+), 36 deletions(-)

diff --git a/doc/multithreading.txt b/doc/multithreading.txt
index 6c65ca9651..842d331e4f 100644
--- a/doc/multithreading.txt
+++ b/doc/multithreading.txt
@@ -36,9 +36,9 @@ Frame threading -
 * Codecs similar to ffv1, whose streams don't reset across frames,
   will not work because their bitstreams cannot be decoded in parallel.
 
-* The contents of buffers must not be read before ff_thread_await_progress()
+* The contents of buffers must not be read before ff_progress_frame_await()
   has been called on them. reget_buffer() and buffer age optimizations no 
longer work.
-* The contents of buffers must not be written to after 
ff_thread_report_progress()
+* The contents of buffers must not be written to after 
ff_progress_frame_report()
   has been called on them. This includes draw_edges().
 
 Porting codecs to frame threading
@@ -53,14 +53,13 @@ thread.
 Add AV_CODEC_CAP_FRAME_THREADS to the codec capabilities. There will be very 
little
 speed gain at this point but it should work.
 
-If there are inter-frame dependencies, so the codec calls
-ff_thread_report/await_progress(), set FF_CODEC_CAP_ALLOCATE_PROGRESS in
-FFCodec.caps_internal and use ff_thread_get_buffer() to allocate frames.
-Otherwise decode directly into the user-supplied frames.
+Use ff_thread_get_buffer() (or ff_progress_frame_get_buffer()
+in case you have inter-frame dependencies and use the ProgressFrame API)
+to allocate frame buffers.
 
-Call ff_thread_report_progress() after some part of the current picture has 
decoded.
+Call ff_progress_frame_report() after some part of the current picture has 
decoded.
 A good place to put this is where draw_horiz_band() is called - add this if it 
isn't
 called anywhere, as it's useful too and the implementation is trivial when 
you're
 doing this. Note that draw_edges() needs to be called before reporting 
progress.
 
-Before accessing a reference frame or its MVs, call ff_thread_await_progress().
+Before accessing a reference frame or its MVs, call ff_progress_frame_await().
diff --git a/libavcodec/codec_internal.h b/libavcodec/codec_internal.h
index 832e6440d7..1cd1f684f9 100644
--- a/libavcodec/codec_internal.h
+++ b/libavcodec/codec_internal.h
@@ -65,12 +65,7 @@
 /**
  * The decoder might make use of the ProgressFrame API.
  */
-#define FF_CODEC_CAP_USES_PROGRESSFRAMES(1 << 11)
-/*
- * The codec supports frame threading and has inter-frame dependencies, so it
- * uses ff_thread_report/await_progress().
- */
-#define FF_CODEC_CAP_ALLOCATE_PROGRESS  (1 << 6)
+#define FF_CODEC_CAP_USES_PROGRESSFRAMES(1 << 6)
 /**
  * Codec handles avctx->thread_count == 0 (auto) internally.
  */
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index ba535e800d..dd594e3f9f 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -1129,6 +1129,5 @@ const FFCodec ff_ffv1_decoder = {
 UPDATE_THREAD_CONTEXT(update_thread_context),
 .p.capabilities = AV_CODEC_CAP_DR1 |
   

[FFmpeg-devel] [PATCH v2 17/27] avcodec/vp8: Mark flushing functions as av_cold

2024-04-08 Thread Andreas Rheinhardt
Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/vp8.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index a1443f6571..f37938ad27 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -128,7 +128,7 @@ static void vp8_release_frame(VP8Frame *f)
 ff_progress_frame_unref(>tf);
 }
 
-static void vp8_decode_flush_impl(AVCodecContext *avctx, int free_mem)
+static av_cold void vp8_decode_flush_impl(AVCodecContext *avctx, int free_mem)
 {
 VP8Context *s = avctx->priv_data;
 int i;
@@ -144,7 +144,7 @@ static void vp8_decode_flush_impl(AVCodecContext *avctx, 
int free_mem)
 FF_HW_SIMPLE_CALL(avctx, flush);
 }
 
-static void vp8_decode_flush(AVCodecContext *avctx)
+static av_cold void vp8_decode_flush(AVCodecContext *avctx)
 {
 vp8_decode_flush_impl(avctx, 0);
 }
-- 
2.40.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 16/27] avcodec/vp8: Convert to ProgressFrame API

2024-04-08 Thread Andreas Rheinhardt
Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/pthread_frame.c |   2 +-
 libavcodec/vp8.c   | 104 -
 libavcodec/vp8.h   |   5 +-
 libavcodec/webp.c  |   3 +-
 4 files changed, 40 insertions(+), 74 deletions(-)

diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index ee571be610..e42a9563cd 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -974,7 +974,7 @@ int ff_thread_get_ext_buffer(AVCodecContext *avctx, 
ThreadFrame *f, int flags)
 /* Hint: It is possible for this function to be called with codecs
  * that don't support frame threading at all, namely in case
  * a frame-threaded decoder shares code with codecs that are not.
- * This currently affects non-MPEG-4 mpegvideo codecs and and VP7.
+ * This currently affects non-MPEG-4 mpegvideo codecs.
  * The following check will always be true for them. */
 if (!(avctx->active_thread_type & FF_THREAD_FRAME))
 return ff_get_buffer(avctx, f->f, flags);
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index 539b5c5395..a1443f6571 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -35,9 +35,9 @@
 #include "hwaccel_internal.h"
 #include "hwconfig.h"
 #include "mathops.h"
+#include "progressframe.h"
 #include "refstruct.h"
 #include "thread.h"
-#include "threadframe.h"
 #include "vp8.h"
 #include "vp89_rac.h"
 #include "vp8data.h"
@@ -103,9 +103,9 @@ static void free_buffers(VP8Context *s)
 
 static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref)
 {
-int ret;
-if ((ret = ff_thread_get_ext_buffer(s->avctx, >tf,
-ref ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
+int ret = ff_progress_frame_get_buffer(s->avctx, >tf,
+   ref ? AV_GET_BUFFER_FLAG_REF : 0);
+if (ret < 0)
 return ret;
 if (!(f->seg_map = ff_refstruct_allocz(s->mb_width * s->mb_height)))
 goto fail;
@@ -117,7 +117,7 @@ static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int 
ref)
 
 fail:
 ff_refstruct_unref(>seg_map);
-ff_thread_release_ext_buffer(>tf);
+ff_progress_frame_unref(>tf);
 return ret;
 }
 
@@ -125,26 +125,9 @@ static void vp8_release_frame(VP8Frame *f)
 {
 ff_refstruct_unref(>seg_map);
 ff_refstruct_unref(>hwaccel_picture_private);
-ff_thread_release_ext_buffer(>tf);
+ff_progress_frame_unref(>tf);
 }
 
-#if CONFIG_VP8_DECODER
-static int vp8_ref_frame(VP8Frame *dst, const VP8Frame *src)
-{
-int ret;
-
-vp8_release_frame(dst);
-
-if ((ret = ff_thread_ref_frame(>tf, >tf)) < 0)
-return ret;
-ff_refstruct_replace(>seg_map, src->seg_map);
-ff_refstruct_replace(>hwaccel_picture_private,
-  src->hwaccel_picture_private);
-
-return 0;
-}
-#endif /* CONFIG_VP8_DECODER */
-
 static void vp8_decode_flush_impl(AVCodecContext *avctx, int free_mem)
 {
 VP8Context *s = avctx->priv_data;
@@ -184,7 +167,7 @@ static VP8Frame *vp8_find_free_buffer(VP8Context *s)
 av_log(s->avctx, AV_LOG_FATAL, "Ran out of free frames!\n");
 abort();
 }
-if (frame->tf.f->buf[0])
+if (frame->tf.f)
 vp8_release_frame(frame);
 
 return frame;
@@ -1830,7 +1813,7 @@ static const uint8_t subpel_idx[3][8] = {
  */
 static av_always_inline
 void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst,
- const ThreadFrame *ref, const VP8mv *mv,
+ const ProgressFrame *ref, const VP8mv *mv,
  int x_off, int y_off, int block_w, int block_h,
  int width, int height, ptrdiff_t linesize,
  vp8_mc_func mc_func[3][3])
@@ -1847,7 +1830,7 @@ void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, 
uint8_t *dst,
 y_off += mv->y >> 2;
 
 // edge emulation
-ff_thread_await_progress(ref, (3 + y_off + block_h + 
subpel_idx[2][my]) >> 4, 0);
+ff_progress_frame_await(ref, (3 + y_off + block_h + subpel_idx[2][my]) 
>> 4);
 src += y_off * linesize + x_off;
 if (x_off < mx_idx || x_off >= width  - block_w - subpel_idx[2][mx] ||
 y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
@@ -1863,7 +1846,7 @@ void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, 
uint8_t *dst,
 }
 mc_func[my_idx][mx_idx](dst, linesize, src, src_linesize, block_h, mx, 
my);
 } else {
-ff_thread_await_progress(ref, (3 + y_off + block_h) >> 4, 0);
+ff_progress_frame_await(ref, (3 + y_off + block_h) >> 4);
 mc_func[0][0](dst, linesize, src + y_off * linesize + x_off,
   linesize, block_h, 0, 0);
 }
@@ -1888,7 +1871,7 @@ void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, 
uint8_t *dst,
  */
 static av_always_inline
 void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1,
-   uint8_t *dst2, const ThreadFrame *ref, const VP8mv *mv,
+   

[FFmpeg-devel] [PATCH v2 15/27] avcodec/wavpack: Move transient variable from context to stack

2024-04-08 Thread Andreas Rheinhardt
Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/wavpack.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 6ab9088213..d4cf489c0f 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -103,7 +103,6 @@ typedef struct WavpackContext {
 WavpackFrameContext **fdec;
 int fdec_num;
 
-int block;
 int samples;
 int ch_offset;
 
@@ -1638,14 +1637,13 @@ static int wavpack_decode_frame(AVCodecContext *avctx, 
AVFrame *frame,
 const uint8_t *buf = avpkt->data;
 int buf_size   = avpkt->size;
 int frame_size, ret, frame_flags;
-int new_progress = 0;
+int block = 0, new_progress = 0;
 
 av_assert1(!s->curr_progress || s->dsdctx);
 
 if (avpkt->size <= WV_HEADER_SIZE)
 return AVERROR_INVALIDDATA;
 
-s->block = 0;
 s->ch_offset = 0;
 
 /* determine number of samples */
@@ -1666,14 +1664,15 @@ static int wavpack_decode_frame(AVCodecContext *avctx, 
AVFrame *frame,
 if (frame_size <= 0 || frame_size > buf_size) {
 av_log(avctx, AV_LOG_ERROR,
"Block %d has invalid size (size %d vs. %d bytes left)\n",
-   s->block, frame_size, buf_size);
+   block, frame_size, buf_size);
 ret = AVERROR_INVALIDDATA;
 goto error;
 }
-ret = wavpack_decode_block(avctx, frame, s->block, buf, frame_size, 
_progress);
+ret = wavpack_decode_block(avctx, frame, block, buf,
+   frame_size, _progress);
 if (ret < 0)
 goto error;
-s->block++;
+block++;
 buf  += frame_size;
 buf_size -= frame_size;
 }
-- 
2.40.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 14/27] avcodec/wavpack: Optimize always-false comparison away

2024-04-08 Thread Andreas Rheinhardt
Also use the correct type limit SIZE_MAX; INT_MAX comes
from a time when this used av_buffer_allocz() which used
an int at the time.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/wavpack.c | 5 -
 libavcodec/wavpack.h | 1 +
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 51ac943fe7..6ab9088213 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -1000,7 +1000,8 @@ static int wv_dsd_reset(WavpackContext *s, int channels)
 if (!channels)
 return 0;
 
-if (channels > INT_MAX / sizeof(*s->dsdctx))
+if (WV_MAX_CHANNELS > SIZE_MAX / sizeof(*s->dsdctx) &&
+channels > SIZE_MAX / sizeof(*s->dsdctx))
 return AVERROR(EINVAL);
 
 s->dsdctx = ff_refstruct_allocz(channels * sizeof(*s->dsdctx));
@@ -1433,6 +1434,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, 
AVFrame *frame, int block
 av_log(avctx, AV_LOG_ERROR, "Invalid channel info size %d\n",
size);
 }
+av_assert1(chan <= WV_MAX_CHANNELS);
 break;
 case WP_ID_SAMPLE_RATE:
 if (size != 3) {
@@ -1524,6 +1526,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, 
AVFrame *frame, int block
 } else {
 av_channel_layout_default(_ch_layout, s->stereo + 1);
 }
+av_assert1(new_ch_layout.nb_channels <= WV_MAX_CHANNELS);
 
 /* clear DSD state if stream properties change */
 if ((wc->dsdctx && !got_dsd) ||
diff --git a/libavcodec/wavpack.h b/libavcodec/wavpack.h
index 9f62f8406d..2efbb1fd06 100644
--- a/libavcodec/wavpack.h
+++ b/libavcodec/wavpack.h
@@ -57,6 +57,7 @@
 #define WV_FLT_ZERO_SENT  0x08
 #define WV_FLT_ZERO_SIGN  0x10
 
+#define WV_MAX_CHANNELS   (1 << 12)
 #define WV_MAX_SAMPLES15
 
 enum WP_ID_Flags {
-- 
2.40.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 13/27] avcodec/wavpack: Only reset DSD context upon parameter change

2024-04-08 Thread Andreas Rheinhardt
The current code resets it all the time unless we are decoding
a DSD frame with identical parameters to the last frame.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/wavpack.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 6fd297a002..51ac943fe7 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -1526,10 +1526,10 @@ static int wavpack_decode_block(AVCodecContext *avctx, 
AVFrame *frame, int block
 }
 
 /* clear DSD state if stream properties change */
-if (new_ch_layout.nb_channels != wc->dsd_channels ||
-av_channel_layout_compare(_ch_layout, >ch_layout) ||
-new_samplerate != avctx->sample_rate||
-!!got_dsd  != !!wc->dsdctx) {
+if ((wc->dsdctx && !got_dsd) ||
+got_dsd && (new_ch_layout.nb_channels != wc->dsd_channels ||
+av_channel_layout_compare(_ch_layout, 
>ch_layout) ||
+new_samplerate != avctx->sample_rate)) {
 ret = wv_dsd_reset(wc, got_dsd ? new_ch_layout.nb_channels : 0);
 if (ret < 0) {
 av_log(avctx, AV_LOG_ERROR, "Error reinitializing the DSD 
context\n");
-- 
2.40.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 12/27] avcodec/wavpack: Move initializing DSD data to a better place

2024-04-08 Thread Andreas Rheinhardt
Namely to code that is only executed if we are indeed
initializing a DSD context.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/wavpack.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 83f42f392d..6fd297a002 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -1011,6 +1011,8 @@ static int wv_dsd_reset(WavpackContext *s, int channels)
 for (i = 0; i < channels; i++)
 memset(s->dsdctx[i].buf, 0x69, sizeof(s->dsdctx[i].buf));
 
+ff_init_dsd_data();
+
 return 0;
 }
 
@@ -1533,7 +1535,6 @@ static int wavpack_decode_block(AVCodecContext *avctx, 
AVFrame *frame, int block
 av_log(avctx, AV_LOG_ERROR, "Error reinitializing the DSD 
context\n");
 return ret;
 }
-ff_init_dsd_data();
 }
 av_channel_layout_copy(>ch_layout, _ch_layout);
 avctx->sample_rate = new_samplerate;
-- 
2.40.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 11/27] avcodec/wavpack: Use ThreadProgress API

2024-04-08 Thread Andreas Rheinhardt
It is more natural given that WavPack doesn't need the data of
the previous frame at all; it just needs the DSD context.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/wavpack.c | 133 ---
 1 file changed, 75 insertions(+), 58 deletions(-)

diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 73d69d66ff..83f42f392d 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -30,7 +30,7 @@
 #include "get_bits.h"
 #include "refstruct.h"
 #include "thread.h"
-#include "threadframe.h"
+#include "threadprogress.h"
 #include "unary.h"
 #include "wavpack.h"
 #include "dsd.h"
@@ -107,11 +107,11 @@ typedef struct WavpackContext {
 int samples;
 int ch_offset;
 
-AVFrame *frame;
-ThreadFrame curr_frame, prev_frame;
 Modulation modulation;
 
 DSDContext *dsdctx; ///< RefStruct reference
+ThreadProgress *curr_progress, *prev_progress; ///< RefStruct references
+FFRefStructPool *progress_pool; ///< RefStruct reference
 int dsd_channels;
 } WavpackContext;
 
@@ -994,6 +994,8 @@ static int wv_dsd_reset(WavpackContext *s, int channels)
 
 s->dsd_channels = 0;
 ff_refstruct_unref(>dsdctx);
+ff_refstruct_unref(>curr_progress);
+ff_refstruct_unref(>prev_progress);
 
 if (!channels)
 return 0;
@@ -1017,22 +1019,31 @@ static int update_thread_context(AVCodecContext *dst, 
const AVCodecContext *src)
 {
 WavpackContext *fsrc = src->priv_data;
 WavpackContext *fdst = dst->priv_data;
-int ret;
-
-if (dst == src)
-return 0;
-
-ff_thread_release_ext_buffer(>curr_frame);
-if (fsrc->curr_frame.f->data[0]) {
-if ((ret = ff_thread_ref_frame(>curr_frame, >curr_frame)) 
< 0)
-return ret;
-}
 
+ff_refstruct_replace(>curr_progress, fsrc->curr_progress);
 ff_refstruct_replace(>dsdctx, fsrc->dsdctx);
 fdst->dsd_channels = fsrc->dsd_channels;
 
 return 0;
 }
+
+static av_cold int progress_pool_init_cb(FFRefStructOpaque opaque, void *obj)
+{
+ThreadProgress *progress = obj;
+return ff_thread_progress_init(progress, 1);
+}
+
+static void progress_pool_reset_cb(FFRefStructOpaque opaque, void *obj)
+{
+ThreadProgress *progress = obj;
+ff_thread_progress_reset(progress);
+}
+
+static av_cold void progress_pool_free_entry_cb(FFRefStructOpaque opaque, void 
*obj)
+{
+ThreadProgress *progress = obj;
+ff_thread_progress_destroy(progress);
+}
 #endif
 
 static av_cold int wavpack_decode_init(AVCodecContext *avctx)
@@ -1043,11 +1054,17 @@ static av_cold int wavpack_decode_init(AVCodecContext 
*avctx)
 
 s->fdec_num = 0;
 
-s->curr_frame.f = av_frame_alloc();
-s->prev_frame.f = av_frame_alloc();
-
-if (!s->curr_frame.f || !s->prev_frame.f)
-return AVERROR(ENOMEM);
+#if HAVE_THREADS
+if (ff_thread_sync_ref(avctx, offsetof(WavpackContext, progress_pool)) == 
FF_THREAD_IS_FIRST_THREAD) {
+s->progress_pool = 
ff_refstruct_pool_alloc_ext(sizeof(*s->curr_progress),
+   
FF_REFSTRUCT_POOL_FLAG_FREE_ON_INIT_ERROR, NULL,
+   progress_pool_init_cb,
+   progress_pool_reset_cb,
+   
progress_pool_free_entry_cb, NULL);
+if (!s->progress_pool)
+return AVERROR(ENOMEM);
+}
+#endif
 
 return 0;
 }
@@ -1061,19 +1078,14 @@ static av_cold int wavpack_decode_end(AVCodecContext 
*avctx)
 av_freep(>fdec);
 s->fdec_num = 0;
 
-ff_thread_release_ext_buffer(>curr_frame);
-av_frame_free(>curr_frame.f);
-
-ff_thread_release_ext_buffer(>prev_frame);
-av_frame_free(>prev_frame.f);
-
-ff_refstruct_unref(>dsdctx);
+ff_refstruct_pool_uninit(>progress_pool);
+wv_dsd_reset(s, 0);
 
 return 0;
 }
 
-static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
-const uint8_t *buf, int buf_size)
+static int wavpack_decode_block(AVCodecContext *avctx, AVFrame *frame, int 
block_no,
+const uint8_t *buf, int buf_size, int 
*new_progress)
 {
 WavpackContext *wc = avctx->priv_data;
 WavpackFrameContext *s;
@@ -1521,7 +1533,6 @@ static int wavpack_decode_block(AVCodecContext *avctx, 
int block_no,
 av_log(avctx, AV_LOG_ERROR, "Error reinitializing the DSD 
context\n");
 return ret;
 }
-ff_thread_release_ext_buffer(>curr_frame);
 ff_init_dsd_data();
 }
 av_channel_layout_copy(>ch_layout, _ch_layout);
@@ -1529,18 +1540,25 @@ static int wavpack_decode_block(AVCodecContext *avctx, 
int block_no,
 avctx->sample_fmt  = sample_fmt;
 avctx->bits_per_raw_sample = orig_bpp;
 
-ff_thread_release_ext_buffer(>prev_frame);
-FFSWAP(ThreadFrame, wc->curr_frame, wc->prev_frame);
-
 /* 

[FFmpeg-devel] [PATCH v2 10/27] avcodec/pthread_frame: Add API to share RefStruct refs just once

2024-04-08 Thread Andreas Rheinhardt
This is useful when the lifetime of the object to be shared
is the whole decoding process as it allows to avoid having
to sync them every time in update_thread_context.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/decode.c|  7 +++
 libavcodec/pthread_frame.c | 20 
 libavcodec/thread.h| 30 ++
 3 files changed, 57 insertions(+)

diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index f18f85c33c..e196c05f11 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -1747,6 +1747,13 @@ void ff_progress_frame_await(const ProgressFrame *f, int 
n)
 ff_thread_progress_await(>progress->progress, n);
 }
 
+#if !HAVE_THREADS
+enum ThreadingStatus ff_thread_sync_ref(AVCodecContext *avctx, size_t offset)
+{
+return FF_THREAD_NO_FRAME_THREADING;
+}
+#endif /* !HAVE_THREADS */
+
 static av_cold int progress_frame_pool_init_cb(FFRefStructOpaque opaque, void 
*obj)
 {
 const AVCodecContext *avctx = opaque.nc;
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index 6b2c4312e0..ee571be610 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -1001,3 +1001,23 @@ void ff_thread_release_ext_buffer(ThreadFrame *f)
 if (f->f)
 av_frame_unref(f->f);
 }
+
+enum ThreadingStatus ff_thread_sync_ref(AVCodecContext *avctx, size_t offset)
+{
+PerThreadContext *p;
+const void *ref;
+
+if (!avctx->internal->is_copy)
+return avctx->active_thread_type & FF_THREAD_FRAME ?
+  FF_THREAD_IS_FIRST_THREAD : FF_THREAD_NO_FRAME_THREADING;
+
+p = avctx->internal->thread_ctx;
+
+av_assert1(memcpy(, (char*)avctx->priv_data + offset, sizeof(ref)) && 
ref == NULL);
+
+memcpy(, (const char*)p->parent->threads[0].avctx->priv_data + offset, 
sizeof(ref));
+av_assert1(ref);
+ff_refstruct_replace((char*)avctx->priv_data + offset, ref);
+
+return FF_THREAD_IS_COPY;
+}
diff --git a/libavcodec/thread.h b/libavcodec/thread.h
index f772d7ff18..5ab12848b4 100644
--- a/libavcodec/thread.h
+++ b/libavcodec/thread.h
@@ -84,4 +84,34 @@ int ff_slice_thread_init_progress(AVCodecContext *avctx);
 void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, 
int n);
 void ff_thread_await_progress2(AVCodecContext *avctx,  int field, int thread, 
int shift);
 
+enum ThreadingStatus {
+FF_THREAD_IS_COPY,
+FF_THREAD_IS_FIRST_THREAD,
+FF_THREAD_NO_FRAME_THREADING,
+};
+
+/**
+ * Allows to synchronize objects whose lifetime is the whole decoding
+ * process among all frame threads.
+ *
+ * When called from a non-copy thread, do nothing.
+ * When called from another thread, place a new RefStruct reference
+ * at the given offset in the calling thread's private data from
+ * the RefStruct reference in the private data of the first decoding thread.
+ * The first thread must have a valid RefStruct reference at the given
+ * offset in its private data; the calling thread must not have
+ * a reference at this offset in its private data (must be NULL).
+ *
+ * @param avctx  an AVCodecContext
+ * @param offset offset of the RefStruct reference in avctx's private data
+ *
+ * @retval FF_THREAD_IS_COPY if frame-threading is in use and the
+ * calling thread is a copy; in this case, the RefStruct reference
+ * will be set.
+ * @retval FF_THREAD_IS_MAIN_THREAD if frame-threading is in use
+ * and the calling thread is the main thread.
+ * @retval FF_THREAD_NO_FRAME_THREADING if frame-threading is not in use.
+ */
+enum ThreadingStatus ff_thread_sync_ref(AVCodecContext *avctx, size_t offset);
+
 #endif /* AVCODEC_THREAD_H */
-- 
2.40.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 09/27] avcodec/vp9: Replace atomic_store() by atomic_init()

2024-04-08 Thread Andreas Rheinhardt
This part of the code is not slice-threaded and they are
semantically an initialization, so use atomic_init()
instead of the potentially expensive atomic_store()
(which uses sequentially consistent memory ordering).

Also remove the initial initialization directly after
allocating this array.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/vp9.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index 443eb74c3c..3adfb98f2d 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -55,7 +55,6 @@ DEFINE_OFFSET_ARRAY(VP9Context, vp9_context, pthread_init_cnt,
 
 static int vp9_alloc_entries(AVCodecContext *avctx, int n) {
 VP9Context *s = avctx->priv_data;
-int i;
 
 if (avctx->active_thread_type & FF_THREAD_SLICE)  {
 if (s->entries)
@@ -64,9 +63,6 @@ static int vp9_alloc_entries(AVCodecContext *avctx, int n) {
 s->entries = av_malloc_array(n, sizeof(atomic_int));
 if (!s->entries)
 return AVERROR(ENOMEM);
-
-for (i  = 0; i < n; i++)
-atomic_init(>entries[i], 0);
 }
 return 0;
 }
@@ -1661,7 +1657,7 @@ static int vp9_decode_frame(AVCodecContext *avctx, 
AVFrame *frame,
 #if HAVE_THREADS
 if (avctx->active_thread_type & FF_THREAD_SLICE) {
 for (i = 0; i < s->sb_rows; i++)
-atomic_store(>entries[i], 0);
+atomic_init(>entries[i], 0);
 }
 #endif
 
-- 
2.40.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 08/27] avcodec/vp9: Simplify replacing VP9Frame

2024-04-08 Thread Andreas Rheinhardt
ff_thread_progress_replace() can handle a blank ProgressFrame
as src (in which case it simply unreferences dst), but not
a NULL one. So add a blank frame to be used as source for
this case, so that we can use the replace functions
to simplify vp9_frame_replace().

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/vp9.c   | 16 +---
 libavcodec/vp9shared.h |  3 ++-
 2 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index bdfa543188..443eb74c3c 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -147,11 +147,11 @@ fail:
 return ret;
 }
 
-static void vp9_frame_ref(VP9Frame *dst, const VP9Frame *src)
+static void vp9_frame_replace(VP9Frame *dst, const VP9Frame *src)
 {
-ff_progress_frame_ref(>tf, >tf);
+ff_progress_frame_replace(>tf, >tf);
 
-dst->extradata = ff_refstruct_ref(src->extradata);
+ff_refstruct_replace(>extradata, src->extradata);
 
 dst->segmentation_map = src->segmentation_map;
 dst->mv = src->mv;
@@ -161,13 +161,6 @@ static void vp9_frame_ref(VP9Frame *dst, const VP9Frame 
*src)
   src->hwaccel_picture_private);
 }
 
-static void vp9_frame_replace(VP9Frame *dst, const VP9Frame *src)
-{
-vp9_frame_unref(dst);
-if (src && src->tf.f)
-vp9_frame_ref(dst, src);
-}
-
 static int update_size(AVCodecContext *avctx, int w, int h)
 {
 #define HWACCEL_MAX (CONFIG_VP9_DXVA2_HWACCEL + \
@@ -1584,7 +1577,8 @@ static int vp9_decode_frame(AVCodecContext *avctx, 
AVFrame *frame,
 data += ret;
 size -= ret;
 
-src = !s->s.h.keyframe && !s->s.h.intraonly && !s->s.h.errorres ? 
>s.frames[CUR_FRAME] : NULL;
+src = !s->s.h.keyframe && !s->s.h.intraonly && !s->s.h.errorres ?
+  >s.frames[CUR_FRAME] : >s.frames[BLANK_FRAME];
 if (!retain_segmap_ref || s->s.h.keyframe || s->s.h.intraonly)
 vp9_frame_replace(>s.frames[REF_FRAME_SEGMAP], src);
 vp9_frame_replace(>s.frames[REF_FRAME_MVPAIR], src);
diff --git a/libavcodec/vp9shared.h b/libavcodec/vp9shared.h
index 805668416f..8a450c26a6 100644
--- a/libavcodec/vp9shared.h
+++ b/libavcodec/vp9shared.h
@@ -168,7 +168,8 @@ typedef struct VP9SharedContext {
 #define CUR_FRAME 0
 #define REF_FRAME_MVPAIR 1
 #define REF_FRAME_SEGMAP 2
-VP9Frame frames[3];
+#define BLANK_FRAME 3
+VP9Frame frames[4];
 } VP9SharedContext;
 
 #endif /* AVCODEC_VP9SHARED_H */
-- 
2.40.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 07/27] avcodec/vp9: Reduce wait times

2024-04-08 Thread Andreas Rheinhardt
Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/vp9.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index e0bc313301..bdfa543188 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -1569,14 +1569,15 @@ static int vp9_decode_frame(AVCodecContext *avctx, 
AVFrame *frame,
 av_log(avctx, AV_LOG_ERROR, "Requested reference %d not 
available\n", ref);
 return AVERROR_INVALIDDATA;
 }
+for (int i = 0; i < 8; i++)
+ff_progress_frame_replace(>next_refs[i], >s.refs[i]);
+ff_thread_finish_setup(avctx);
 ff_progress_frame_await(>s.refs[ref], INT_MAX);
 
 if ((ret = av_frame_ref(frame, s->s.refs[ref].f)) < 0)
 return ret;
 frame->pts = pkt->pts;
 frame->pkt_dts = pkt->dts;
-for (int i = 0; i < 8; i++)
-ff_progress_frame_replace(>next_refs[i], >s.refs[i]);
 *got_frame = 1;
 return pkt->size;
 }
-- 
2.40.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 06/27] avcodec/vp9: Fix race when attaching side-data for show-existing frame

2024-04-08 Thread Andreas Rheinhardt
When outputting a show-existing frame, the VP9 decoder simply
created a reference to said frame and returned it immediately to
the caller, without waiting for it to have finished decoding.
In case of frame-threading it is possible for the frame to
only be decoded while it was waiting to be output.
This is normally benign.

But there is one case where it is not: If the user wants
video encoding parameters to be exported, said side data
will only be attached to the src AVFrame at the end of
decoding the frame that is actually being shown. Without
synchronisation adding said side data in the decoder thread
and the reads in av_frame_ref() in the output thread
constitute a data race. This happens e.g. when using the
venc_data_dump tool with vp90-2-10-show-existing-frame.webm
from the FATE-suite.

Fix this by actually waiting for the frame to be output.

Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/vp9.c | 18 +++---
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index bd52478ce7..e0bc313301 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -1569,6 +1569,8 @@ static int vp9_decode_frame(AVCodecContext *avctx, 
AVFrame *frame,
 av_log(avctx, AV_LOG_ERROR, "Requested reference %d not 
available\n", ref);
 return AVERROR_INVALIDDATA;
 }
+ff_progress_frame_await(>s.refs[ref], INT_MAX);
+
 if ((ret = av_frame_ref(frame, s->s.refs[ref].f)) < 0)
 return ret;
 frame->pts = pkt->pts;
@@ -1715,10 +1717,8 @@ static int vp9_decode_frame(AVCodecContext *avctx, 
AVFrame *frame,
 #endif
 {
 ret = decode_tiles(avctx, data, size);
-if (ret < 0) {
-ff_progress_frame_report(>s.frames[CUR_FRAME].tf, INT_MAX);
-return ret;
-}
+if (ret < 0)
+goto fail;
 }
 
 // Sum all counts fields into td[0].counts for tile threading
@@ -1732,18 +1732,19 @@ static int vp9_decode_frame(AVCodecContext *avctx, 
AVFrame *frame,
 ff_thread_finish_setup(avctx);
 }
 } while (s->pass++ == 1);
-ff_progress_frame_report(>s.frames[CUR_FRAME].tf, INT_MAX);
 
 if (s->td->error_info < 0) {
 av_log(avctx, AV_LOG_ERROR, "Failed to decode tile data\n");
 s->td->error_info = 0;
-return AVERROR_INVALIDDATA;
+ret = AVERROR_INVALIDDATA;
+goto fail;
 }
 if (avctx->export_side_data & AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS) {
 ret = vp9_export_enc_params(s, >s.frames[CUR_FRAME]);
 if (ret < 0)
-return ret;
+goto fail;
 }
+ff_progress_frame_report(>s.frames[CUR_FRAME].tf, INT_MAX);
 
 finish:
 // ref frame setup
@@ -1757,6 +1758,9 @@ finish:
 }
 
 return pkt->size;
+fail:
+ff_progress_frame_report(>s.frames[CUR_FRAME].tf, INT_MAX);
+return ret;
 }
 
 static void vp9_decode_flush(AVCodecContext *avctx)
-- 
2.40.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 05/27] avcodec/vp9: Switch to ProgressFrames

2024-04-08 Thread Andreas Rheinhardt
This already fixes a race in the vp9-encparams test. In this test,
side data is added to the current frame after having been decoded
(and therefore after ff_thread_finish_setup() has been called).
Yet the update_thread_context callback called ff_thread_ref_frame()
and therefore av_frame_ref() with this frame as source frame and
the ensuing read was unsynchronised with adding the side data,
i.e. there was a data race.

By switching to the ProgressFrame API the implicit av_frame_ref()
is removed and the race fixed except if this frame is later reused by
a show-existing-frame which uses an explicit av_frame_ref().
The vp9-encparams test does not cover this, so this commit
already fixes all the races in this test.

This decoder kept multiple references to the same ThreadFrames
in the same context and therefore had lots of implicit av_frame_ref()
even when decoding single-threaded. This incurred lots of small
allocations: When decoding an ordinary 10s video in single-threaded
mode the number of allocations reported by Valgrind went down
from 57,814 to 20,908; for 10 threads it went down from 84,223 to
21,901.

Reviewed-by: Anton Khirnov 
Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/dxva2_vp9.c   |   4 +-
 libavcodec/vaapi_vp9.c   |   2 +-
 libavcodec/vp9.c | 137 +++
 libavcodec/vp9_mc_template.c |   2 +-
 libavcodec/vp9block.c|   5 +-
 libavcodec/vp9dec.h  |   6 +-
 libavcodec/vp9lpf.c  |   1 +
 libavcodec/vp9mvs.c  |   4 +-
 libavcodec/vp9recon.c|  19 ++---
 libavcodec/vp9shared.h   |   6 +-
 10 files changed, 70 insertions(+), 116 deletions(-)

diff --git a/libavcodec/dxva2_vp9.c b/libavcodec/dxva2_vp9.c
index 1498deb3c8..ca8b3b136d 100644
--- a/libavcodec/dxva2_vp9.c
+++ b/libavcodec/dxva2_vp9.c
@@ -79,7 +79,7 @@ int ff_dxva2_vp9_fill_picture_parameters(const AVCodecContext 
*avctx, AVDXVACont
 pp->Reserved8Bits = 0;
 
 for (i = 0; i < 8; i++) {
-if (h->refs[i].f->buf[0]) {
+if (h->refs[i].f) {
 fill_picture_entry(>ref_frame_map[i], 
ff_dxva2_get_surface_index(avctx, ctx, h->refs[i].f, 0), 0);
 pp->ref_frame_coded_width[i]  = h->refs[i].f->width;
 pp->ref_frame_coded_height[i] = h->refs[i].f->height;
@@ -89,7 +89,7 @@ int ff_dxva2_vp9_fill_picture_parameters(const AVCodecContext 
*avctx, AVDXVACont
 
 for (i = 0; i < 3; i++) {
 uint8_t refidx = h->h.refidx[i];
-if (h->refs[refidx].f->buf[0])
+if (h->refs[refidx].f)
 fill_picture_entry(>frame_refs[i], 
ff_dxva2_get_surface_index(avctx, ctx, h->refs[refidx].f, 0), 0);
 else
 pp->frame_refs[i].bPicEntry = 0xFF;
diff --git a/libavcodec/vaapi_vp9.c b/libavcodec/vaapi_vp9.c
index 9dc7d5e72b..b8e760c807 100644
--- a/libavcodec/vaapi_vp9.c
+++ b/libavcodec/vaapi_vp9.c
@@ -100,7 +100,7 @@ static int vaapi_vp9_start_frame(AVCodecContext  
*avctx,
 }
 
 for (i = 0; i < 8; i++) {
-if (h->refs[i].f->buf[0])
+if (h->refs[i].f)
 pic_param.reference_frames[i] = 
ff_vaapi_get_surface_id(h->refs[i].f);
 else
 pic_param.reference_frames[i] = VA_INVALID_ID;
diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index 6bcda8bfff..bd52478ce7 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -30,9 +30,9 @@
 #include "hwaccel_internal.h"
 #include "hwconfig.h"
 #include "profiles.h"
+#include "progressframe.h"
 #include "refstruct.h"
 #include "thread.h"
-#include "threadframe.h"
 #include "pthread_internal.h"
 
 #include "videodsp.h"
@@ -100,7 +100,7 @@ static void vp9_tile_data_free(VP9TileData *td)
 
 static void vp9_frame_unref(VP9Frame *f)
 {
-ff_thread_release_ext_buffer(>tf);
+ff_progress_frame_unref(>tf);
 ff_refstruct_unref(>extradata);
 ff_refstruct_unref(>hwaccel_picture_private);
 f->segmentation_map = NULL;
@@ -111,7 +111,7 @@ static int vp9_frame_alloc(AVCodecContext *avctx, VP9Frame 
*f)
 VP9Context *s = avctx->priv_data;
 int ret, sz;
 
-ret = ff_thread_get_ext_buffer(avctx, >tf, AV_GET_BUFFER_FLAG_REF);
+ret = ff_progress_frame_get_buffer(avctx, >tf, AV_GET_BUFFER_FLAG_REF);
 if (ret < 0)
 return ret;
 
@@ -147,13 +147,9 @@ fail:
 return ret;
 }
 
-static int vp9_frame_ref(VP9Frame *dst, VP9Frame *src)
+static void vp9_frame_ref(VP9Frame *dst, const VP9Frame *src)
 {
-int ret;
-
-ret = ff_thread_ref_frame(>tf, >tf);
-if (ret < 0)
-return ret;
+ff_progress_frame_ref(>tf, >tf);
 
 dst->extradata = ff_refstruct_ref(src->extradata);
 
@@ -163,8 +159,13 @@ static int vp9_frame_ref(VP9Frame *dst, VP9Frame *src)
 
 ff_refstruct_replace(>hwaccel_picture_private,
   src->hwaccel_picture_private);
+}
 
-return 0;
+static void vp9_frame_replace(VP9Frame *dst, const VP9Frame *src)
+{
+vp9_frame_unref(dst);
+if (src && src->tf.f)
+vp9_frame_ref(dst, src);
 }
 
 static 

[FFmpeg-devel] [PATCH v2 04/27] avcodec/vp3: Switch to ProgressFrames

2024-04-08 Thread Andreas Rheinhardt
Avoids implicit av_frame_ref() and therefore allocations
and error checks. It also avoids explicitly allocating
the AVFrames (done implicitly when getting the buffer)
and it also allows to reuse the flushing code for freeing
the ProgressFrames.

Reviewed-by: Anton Khirnov 
Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/vp3.c | 147 +--
 1 file changed, 53 insertions(+), 94 deletions(-)

diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index 201bab0e32..2a5f68dfa8 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -49,9 +49,9 @@
 #include "internal.h"
 #include "jpegquanttables.h"
 #include "mathops.h"
+#include "progressframe.h"
 #include "refstruct.h"
 #include "thread.h"
-#include "threadframe.h"
 #include "videodsp.h"
 #include "vp3data.h"
 #include "vp4data.h"
@@ -201,9 +201,9 @@ typedef struct Vp3DecodeContext {
 int version;
 int width, height;
 int chroma_x_shift, chroma_y_shift;
-ThreadFrame golden_frame;
-ThreadFrame last_frame;
-ThreadFrame current_frame;
+ProgressFrame golden_frame;
+ProgressFrame last_frame;
+ProgressFrame current_frame;
 int keyframe;
 uint8_t idct_permutation[64];
 uint8_t idct_scantable[64];
@@ -353,12 +353,9 @@ static void vp3_decode_flush(AVCodecContext *avctx)
 {
 Vp3DecodeContext *s = avctx->priv_data;
 
-if (s->golden_frame.f)
-ff_thread_release_ext_buffer(>golden_frame);
-if (s->last_frame.f)
-ff_thread_release_ext_buffer(>last_frame);
-if (s->current_frame.f)
-ff_thread_release_ext_buffer(>current_frame);
+ff_progress_frame_unref(>golden_frame);
+ff_progress_frame_unref(>last_frame);
+ff_progress_frame_unref(>current_frame);
 }
 
 static av_cold int vp3_decode_end(AVCodecContext *avctx)
@@ -372,9 +369,6 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx)
 
 /* release all frames */
 vp3_decode_flush(avctx);
-av_frame_free(>current_frame.f);
-av_frame_free(>last_frame.f);
-av_frame_free(>golden_frame.f);
 
 ff_refstruct_unref(>coeff_vlc);
 
@@ -1908,10 +1902,9 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, int 
y)
 /* At the end of the frame, report INT_MAX instead of the height of
  * the frame. This makes the other threads' ff_thread_await_progress()
  * calls cheaper, because they don't have to clip their values. */
-ff_thread_report_progress(>current_frame,
-  y_flipped == s->height ? INT_MAX
- : y_flipped - 1,
-  0);
+ff_progress_frame_report(>current_frame,
+ y_flipped == s->height ? INT_MAX
+: y_flipped - 1);
 }
 
 if (!s->avctx->draw_horiz_band)
@@ -1942,7 +1935,7 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, int 
y)
 static void await_reference_row(Vp3DecodeContext *s, const Vp3Fragment 
*fragment,
 int motion_y, int y)
 {
-const ThreadFrame *ref_frame;
+const ProgressFrame *ref_frame;
 int ref_row;
 int border = motion_y & 1;
 
@@ -1955,7 +1948,7 @@ static void await_reference_row(Vp3DecodeContext *s, 
const Vp3Fragment *fragment
 ref_row = y + (motion_y >> 1);
 ref_row = FFMAX(FFABS(ref_row), ref_row + 8 + border);
 
-ff_thread_await_progress(ref_frame, ref_row, 0);
+ff_progress_frame_await(ref_frame, ref_row);
 }
 
 #if CONFIG_VP4_DECODER
@@ -2066,12 +2059,12 @@ static void render_slice(Vp3DecodeContext *s, int slice)
 int16_t *block = s->block;
 int motion_x = 0xdeadbeef, motion_y = 0xdeadbeef;
 /* When decoding keyframes, the earlier frames may not be available,
- * so to avoid using undefined pointer arithmetic on them we just
- * use the current frame instead. Nothing is ever read from these
- * frames in case of a keyframe. */
-const AVFrame *last_frame   = s->last_frame.f->data[0]   ?
+ * so we just use the current frame in this case instead;
+ * it also avoid using undefined pointer arithmetic. Nothing is
+ * ever read from these frames in case of a keyframe. */
+const AVFrame *last_frame   = s->last_frame.f   ?
   s->last_frame.f   : s->current_frame.f;
-const AVFrame *golden_frame = s->golden_frame.f->data[0] ?
+const AVFrame *golden_frame = s->golden_frame.f ?
   s->golden_frame.f : s->current_frame.f;
 int motion_halfpel_index;
 int first_pixel;
@@ -2353,17 +2346,6 @@ static av_cold int allocate_tables(AVCodecContext *avctx)
 return 0;
 }
 
-static av_cold int init_frames(Vp3DecodeContext *s)
-{
-s->current_frame.f = av_frame_alloc();
-s->last_frame.f= av_frame_alloc();
-s->golden_frame.f  = av_frame_alloc();
-
-if (!s->current_frame.f || !s->last_frame.f || !s->golden_frame.f)
- 

[FFmpeg-devel] [PATCH v2 03/27] avcodec/mimic: Switch to ProgressFrames

2024-04-08 Thread Andreas Rheinhardt
Avoids implicit av_frame_ref() and therefore allocations
and error checks.

Reviewed-by: Anton Khirnov 
Signed-off-by: Andreas Rheinhardt 
---
 libavcodec/mimic.c | 61 +-
 1 file changed, 22 insertions(+), 39 deletions(-)

diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c
index 8928f24022..2925aa50f7 100644
--- a/libavcodec/mimic.c
+++ b/libavcodec/mimic.c
@@ -34,8 +34,8 @@
 #include "bswapdsp.h"
 #include "hpeldsp.h"
 #include "idctdsp.h"
+#include "progressframe.h"
 #include "thread.h"
-#include "threadframe.h"
 
 #define MIMIC_HEADER_SIZE   20
 #define MIMIC_VLC_BITS  11
@@ -52,7 +52,7 @@ typedef struct MimicContext {
 int cur_index;
 int prev_index;
 
-ThreadFrame frames [16];
+ProgressFrame   frames[16];
 
 DECLARE_ALIGNED(32, int16_t, dct_block)[64];
 
@@ -105,16 +105,12 @@ static const uint8_t col_zag[64] = {
 static av_cold int mimic_decode_end(AVCodecContext *avctx)
 {
 MimicContext *ctx = avctx->priv_data;
-int i;
 
 av_freep(>swap_buf);
 ctx->swap_buf_size = 0;
 
-for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
-if (ctx->frames[i].f)
-ff_thread_release_ext_buffer(>frames[i]);
-av_frame_free(>frames[i].f);
-}
+for (int i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++)
+ff_progress_frame_unref(>frames[i]);
 
 return 0;
 }
@@ -130,7 +126,6 @@ static av_cold int mimic_decode_init(AVCodecContext *avctx)
 {
 static AVOnce init_static_once = AV_ONCE_INIT;
 MimicContext *ctx = avctx->priv_data;
-int i;
 
 ctx->prev_index = 0;
 ctx->cur_index  = 15;
@@ -141,12 +136,6 @@ static av_cold int mimic_decode_init(AVCodecContext *avctx)
 ff_idctdsp_init(>idsp, avctx);
 ff_permute_scantable(ctx->permutated_scantable, col_zag, 
ctx->idsp.idct_permutation);
 
-for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
-ctx->frames[i].f = av_frame_alloc();
-if (!ctx->frames[i].f)
-return AVERROR(ENOMEM);
-}
-
 ff_thread_once(_static_once, mimic_init_static);
 
 return 0;
@@ -156,7 +145,6 @@ static av_cold int mimic_decode_init(AVCodecContext *avctx)
 static int mimic_decode_update_thread_context(AVCodecContext *avctx, const 
AVCodecContext *avctx_from)
 {
 MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
-int i, ret;
 
 if (avctx == avctx_from)
 return 0;
@@ -164,13 +152,10 @@ static int 
mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCod
 dst->cur_index  = src->next_cur_index;
 dst->prev_index = src->next_prev_index;
 
-for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
-ff_thread_release_ext_buffer(>frames[i]);
-if (i != src->next_cur_index && src->frames[i].f->data[0]) {
-ret = ff_thread_ref_frame(>frames[i], >frames[i]);
-if (ret < 0)
-return ret;
-}
+for (int i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
+ff_progress_frame_unref(>frames[i]);
+if (i != src->next_cur_index && src->frames[i].f)
+ff_progress_frame_ref(>frames[i], >frames[i]);
 }
 
 return 0;
@@ -293,11 +278,10 @@ static int decode(MimicContext *ctx, int quality, int 
num_coeffs,
 } else {
 unsigned int backref = get_bits(>gb, 4);
 int index= (ctx->cur_index + backref) & 15;
-uint8_t *p   = ctx->frames[index].f->data[0];
 
-if (index != ctx->cur_index && p) {
-ff_thread_await_progress(>frames[index],
- cur_row, 0);
+if (index != ctx->cur_index && ctx->frames[index].f) {
+const uint8_t *p = ctx->frames[index].f->data[0];
+ff_progress_frame_await(>frames[index], 
cur_row);
 p += src -
  ctx->frames[ctx->prev_index].f->data[plane];
 ctx->hdsp.put_pixels_tab[1][0](dst, p, stride, 8);
@@ -307,8 +291,7 @@ static int decode(MimicContext *ctx, int quality, int 
num_coeffs,
 }
 }
 } else {
-ff_thread_await_progress(>frames[ctx->prev_index],
- cur_row, 0);
+ff_progress_frame_await(>frames[ctx->prev_index], 
cur_row);
 ctx->hdsp.put_pixels_tab[1][0](dst, src, stride, 8);
 }
 src += 8;
@@ -317,8 +300,7 @@ static int decode(MimicContext *ctx, int quality, int 
num_coeffs,
 src += (stride - ctx->num_hblocks[plane]) << 3;
 dst += (stride - ctx->num_hblocks[plane]) << 3;
 
-ff_thread_report_progress(>frames[ctx->cur_index],
- 

[FFmpeg-devel] [PATCH v2 02/27] avcodec/decode: Add new ProgressFrame API

2024-04-08 Thread Andreas Rheinhardt
Frame-threaded decoders with inter-frame dependencies
use the ThreadFrame API for syncing. It works as follows:

During init each thread allocates an AVFrame for every
ThreadFrame.

Thread A reads the header of its packet and allocates
a buffer for an AVFrame with ff_thread_get_ext_buffer()
(which also allocates a small structure that is shared
with other references to this frame) and sets its fields,
including side data. Then said thread calls ff_thread_finish_setup().
>From that moment onward it is not allowed to change any
of the AVFrame fields at all any more, but it may change
fields which are an indirection away, like the content of
AVFrame.data or already existing side data.

After thread A has called ff_thread_finish_setup(),
another thread (the user one) calls the codec's update_thread_context
callback which in turn calls ff_thread_ref_frame() which
calls av_frame_ref() which reads every field of A's
AVFrame; hence the above restriction on modifications
of the AVFrame (as any modification of the AVFrame by A after
ff_thread_finish_setup() would be a data race). Of course,
this av_frame_ref() also incurs allocations and therefore
needs to be checked. ff_thread_ref_frame() also references
the small structure used for communicating progress.

This av_frame_ref() makes it awkward to propagate values that
only become known during decoding to later threads (in case of
frame reordering or other mechanisms of delayed output (like
show-existing-frames) it's not the decoding thread, but a later
thread that returns the AVFrame). E.g. for VP9 when exporting video
encoding parameters as side data the number of blocks only
becomes known during decoding, so one can't allocate the side data
before ff_thread_finish_setup(). It is currently being done afterwards
and this leads to a data race in the vp9-encparams test when using
frame-threading. Returning decode_error_flags is also complicated
by this.

To perform this exchange a buffer shared between the references
is needed (notice that simply giving the later threads a pointer
to the original AVFrame does not work, because said AVFrame will
be reused lateron when thread A decodes the next packet given to it).
One could extend the buffer already used for progress for this
or use a new one (requiring yet another allocation), yet both
of these approaches have the drawback of being unnatural, ugly
and requiring quite a lot of ad-hoc code. E.g. in case of the VP9
side data mentioned above one could not simply use the helper
that allocates and adds the side data to an AVFrame in one go.

The ProgressFrame API meanwhile offers a different solution to all
of this. It is based around the idea that the most natural
shared object for sharing information about an AVFrame between
decoding threads is the AVFrame itself. To actually implement this
the AVFrame needs to be reference counted. This is achieved by
putting a (ownership) pointer into a shared (and opaque) structure
that is managed by the RefStruct API and which also contains
the stuff necessary for progress reporting.
The users get a pointer to this AVFrame with the understanding
that the owner may set all the fields until it has indicated
that it has finished decoding this AVFrame; then the users are
allowed to read everything. Every decoder may of course employ
a different contract than the one outlined above.

Given that there is no underlying av_frame_ref(), creating
references to a ProgressFrame can't fail. Only
ff_thread_progress_get_buffer() can fail, but given that
it will replace calls to ff_thread_get_ext_buffer() it is
at places where errors are already expected and properly
taken care of.

The ProgressFrames are empty (i.e. the AVFrame pointer is NULL
and the AVFrames are not allocated during init at all)
while not being in use; ff_thread_progress_get_buffer() both
sets up the actual ProgressFrame and already calls
ff_thread_get_buffer(). So instead of checking for
ThreadFrame.f->data[0] or ThreadFrame.f->buf[0] being NULL
for "this reference frame is non-existing" one should check for
ProgressFrame.f.

This also implies that one can only set AVFrame properties
after having allocated the buffer. This restriction is not deep:
if it becomes onerous for any codec, ff_thread_progress_get_buffer()
can be broken up. The user would then have to get a buffer
himself.

In order to avoid unnecessary allocations, the shared structure
is pooled, so that both the structure as well as the AVFrame
itself are reused. This means that there won't be lots of
unnecessary allocations in case of non-frame-threaded decoding.
It might even turn out to have fewer than the current code
(the current code allocates AVFrames for every DPB slot, but
these are often excessively large and not completely used;
the new code allocates them on demand). Pooling relies on the
reset function of the RefStruct pool API, it would be impossible
to implement with the AVBufferPool API.

Finally, ProgressFrames have no notion of owner; they are built

[FFmpeg-devel] [PATCH v2 01/27] avcodec/threadprogress: Add new API for frame-threaded progress

2024-04-08 Thread Andreas Rheinhardt
The API is similar to the ThreadFrame API, with the exception
that it no longer has an included AVFrame and that it has its
own mutexes and condition variables which makes it more independent
of pthread_frame.c. One can wait on anything via a ThreadProgress.
One just has to ensure that the lifetime of the object containing
the ThreadProgress is long enough. This will typically be solved
by putting a ThreadProgress in a refcounted structure that is
shared between threads.

Signed-off-by: Andreas Rheinhardt 
---
Now including its own mutex and condition variable. Hopefully
no system has constraints on the number of mutexes and condition
variables it supports.

 libavcodec/threadprogress.c | 73 +
 libavcodec/threadprogress.h | 91 +
 2 files changed, 164 insertions(+)
 create mode 100644 libavcodec/threadprogress.c
 create mode 100644 libavcodec/threadprogress.h

diff --git a/libavcodec/threadprogress.c b/libavcodec/threadprogress.c
new file mode 100644
index 00..dd2a4d2336
--- /dev/null
+++ b/libavcodec/threadprogress.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2022 Andreas Rheinhardt 
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include 
+#include 
+
+#include "pthread_internal.h"
+#include "threadprogress.h"
+#include "libavutil/attributes.h"
+
+DEFINE_OFFSET_ARRAY(ThreadProgress, thread_progress, init,
+(offsetof(ThreadProgress, progress_mutex)),
+(offsetof(ThreadProgress, progress_cond)));
+
+av_cold int ff_thread_progress_init(ThreadProgress *pro, int init_mode)
+{
+atomic_init(>progress, init_mode ? -1 : INT_MAX);
+if (!init_mode) {
+pro->init = 0;
+return 0;
+}
+return ff_pthread_init(pro, thread_progress_offsets);
+}
+
+av_cold void ff_thread_progress_destroy(ThreadProgress *pro)
+{
+ff_pthread_free(pro, thread_progress_offsets);
+}
+
+void ff_thread_progress_report(ThreadProgress *pro, int n)
+{
+if (atomic_load_explicit(>progress, memory_order_relaxed) >= n)
+return;
+
+atomic_store_explicit(>progress, n, memory_order_release);
+
+pthread_mutex_lock(>progress_mutex);
+pthread_cond_broadcast(>progress_cond);
+pthread_mutex_unlock(>progress_mutex);
+}
+
+void ff_thread_progress_await(const ThreadProgress *pro_c, int n)
+{
+/* Casting const away here is safe, because we only read from progress
+ * and will leave pro_c in the same state upon leaving the function
+ * as it had at the beginning. */
+ThreadProgress *pro = (ThreadProgress*)pro_c;
+
+if (atomic_load_explicit(>progress, memory_order_acquire) >= n)
+return;
+
+pthread_mutex_lock(>progress_mutex);
+while (atomic_load_explicit(>progress, memory_order_relaxed) < n)
+pthread_cond_wait(>progress_cond, >progress_mutex);
+pthread_mutex_unlock(>progress_mutex);
+}
diff --git a/libavcodec/threadprogress.h b/libavcodec/threadprogress.h
new file mode 100644
index 00..786802cbf1
--- /dev/null
+++ b/libavcodec/threadprogress.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2022 Andreas Rheinhardt 
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_THREADPROGRESS_H
+#define AVCODEC_THREADPROGRESS_H
+
+/**
+ * ThreadProgress is an API to easily notify other threads about progress
+ * of any kind as long as it can be packaged into an int and is consistent
+ * with the natural ordering of integers.
+ *
+ * Each initialized ThreadProgress can be in one of two modes: No-op mode
+ * or 

Re: [FFmpeg-devel] [PATCH v2 1/4] avformat/mov_chan: check channel count of layout tags at compile time

2024-04-08 Thread Marton Balint




On Wed, 3 Apr 2024, Marton Balint wrote:


We can do this by using an X-macro for channel map declaration and doing a
static_assert() in one pass for the check. Thanks for Andreas Rheinhardt for
the suggestion.


Will apply the series.

Regards,
Marton



Signed-off-by: Marton Balint 
---
libavformat/mov_chan.c | 217 -
1 file changed, 108 insertions(+), 109 deletions(-)

diff --git a/libavformat/mov_chan.c b/libavformat/mov_chan.c
index e7d181d71f..4bb0ee7405 100644
--- a/libavformat/mov_chan.c
+++ b/libavformat/mov_chan.c
@@ -23,6 +23,7 @@
 * @author Justin Ruggles
 */

+#include 
#include 

#include "libavutil/avassert.h"
@@ -81,108 +82,114 @@ struct MovChannelLayoutMap {
};
};

-#define TAG(_0)  {.tag = _0}
-#define ID(_0)   {.id = c_##_0}
-#define CHLIST(_0, ...)  TAG(_0), __VA_ARGS__
-#define CHLIST01(_0, _1) CHLIST(_0, ID(_1))
-#define CHLIST02(_0, _1, _2) CHLIST(_0, ID(_1), 
ID(_2))
-#define CHLIST03(_0, _1, _2, _3) CHLIST(_0, ID(_1), 
ID(_2), ID(_3))
-#define CHLIST04(_0, _1, _2, _3, _4) CHLIST(_0, ID(_1), 
ID(_2), ID(_3), ID(_4))
-#define CHLIST05(_0, _1, _2, _3, _4, _5) CHLIST(_0, ID(_1), 
ID(_2), ID(_3), ID(_4), ID(_5))
-#define CHLIST06(_0, _1, _2, _3, _4, _5, _6) CHLIST(_0, ID(_1), 
ID(_2), ID(_3), ID(_4), ID(_5), ID(_6))
-#define CHLIST07(_0, _1, _2, _3, _4, _5, _6, _7) CHLIST(_0, ID(_1), 
ID(_2), ID(_3), ID(_4), ID(_5), ID(_6), ID(_7))
-#define CHLIST08(_0, _1, _2, _3, _4, _5, _6, _7, _8) CHLIST(_0, ID(_1), 
ID(_2), ID(_3), ID(_4), ID(_5), ID(_6), ID(_7), ID(_8))
-#define CHLIST09(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) CHLIST(_0, ID(_1), 
ID(_2), ID(_3), ID(_4), ID(_5), ID(_6), ID(_7), ID(_8), ID(_9))
-#define CHLIST16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, 
_14, _15, _16) \
-CHLIST(_0, ID(_1),  ID(_2),  ID(_3),  ID(_4),  ID(_5),  ID(_6), ID(_7), 
ID(_8), ID(_9), ID(_10), \
-   ID(_11), ID(_12), ID(_13), ID(_14), ID(_15), ID(_16))
-#define CHLIST21(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, 
_14, _15, _16, _17, _18, _19, _20, _21) \
-CHLIST(_0, ID(_1),  ID(_2),  ID(_3),  ID(_4),  ID(_5),  ID(_6),  ID(_7),  
ID(_8),  ID(_9),  ID(_10), \
-   ID(_11), ID(_12), ID(_13), ID(_14), ID(_15), ID(_16), ID(_17), 
ID(_18), ID(_19), ID(_20), ID(_21))
-
+#define TAG(_tag, _cnt){.tag = _tag}
+#define ID(_0) {.id = c_##_0}
+#define CHLIST01(_tag, _1) CHLIST(_tag, 1, 
ID(_1))
+#define CHLIST02(_tag, _1, _2) CHLIST(_tag, 2, 
ID(_1), ID(_2))
+#define CHLIST03(_tag, _1, _2, _3) CHLIST(_tag, 3, 
ID(_1), ID(_2), ID(_3))
+#define CHLIST04(_tag, _1, _2, _3, _4) CHLIST(_tag, 4, 
ID(_1), ID(_2), ID(_3), ID(_4))
+#define CHLIST05(_tag, _1, _2, _3, _4, _5) CHLIST(_tag, 5, 
ID(_1), ID(_2), ID(_3), ID(_4), ID(_5))
+#define CHLIST06(_tag, _1, _2, _3, _4, _5, _6) CHLIST(_tag, 6, 
ID(_1), ID(_2), ID(_3), ID(_4), ID(_5), ID(_6))
+#define CHLIST07(_tag, _1, _2, _3, _4, _5, _6, _7) CHLIST(_tag, 7, 
ID(_1), ID(_2), ID(_3), ID(_4), ID(_5), ID(_6), ID(_7))
+#define CHLIST08(_tag, _1, _2, _3, _4, _5, _6, _7, _8) CHLIST(_tag, 8, 
ID(_1), ID(_2), ID(_3), ID(_4), ID(_5), ID(_6), ID(_7), ID(_8))
+#define CHLIST09(_tag, _1, _2, _3, _4, _5, _6, _7, _8, _9) CHLIST(_tag, 9, 
ID(_1), ID(_2), ID(_3), ID(_4), ID(_5), ID(_6), ID(_7), ID(_8), ID(_9))
+#define CHLIST16(_tag, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, 
_14, _15, _16) \
+CHLIST(_tag, 16, ID(_1),  ID(_2),  ID(_3),  ID(_4),  ID(_5),  ID(_6), 
ID(_7), ID(_8), ID(_9), ID(_10), \
+ ID(_11), ID(_12), ID(_13), ID(_14), ID(_15), ID(_16))
+#define CHLIST21(_tag, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, 
_14, _15, _16, _17, _18, _19, _20, _21) \
+CHLIST(_tag, 21, ID(_1),  ID(_2),  ID(_3),  ID(_4),  ID(_5),  ID(_6),  
ID(_7),  ID(_8),  ID(_9),  ID(_10), \
+ ID(_11), ID(_12), ID(_13), ID(_14), ID(_15), ID(_16), 
ID(_17), ID(_18), ID(_19), ID(_20), ID(_21))
+
+#define MOV_CH_LAYOUT_MAP \
+CHLIST01( MOV_CH_LAYOUT_MONO, C)\
+CHLIST02( MOV_CH_LAYOUT_STEREO,   L,   R)\
+CHLIST02( MOV_CH_LAYOUT_STEREOHEADPHONES, L,   R)\
+CHLIST02( MOV_CH_LAYOUT_BINAURAL, L,   R)\
+CHLIST02( MOV_CH_LAYOUT_MIDSIDE,  L,   R)\
+CHLIST02( MOV_CH_LAYOUT_XY,   L,   R)\
+CHLIST02( MOV_CH_LAYOUT_MATRIXSTEREO, Lt,  Rt   )\
+CHLIST02( MOV_CH_LAYOUT_AC3_1_0_1,C,   LFE  )\
+CHLIST03( MOV_CH_LAYOUT_MPEG_3_0_A,  

Re: [FFmpeg-devel] [PATCH 4/5] avformat/mxfdec: Check index_edit_rate

2024-04-08 Thread Marton Balint



On Mon, 8 Apr 2024, Tomas Härdin wrote:


tor 2024-04-04 klockan 00:51 +0200 skrev Michael Niedermayer:

Fixes: Assertion b >=0 failed at libavutil/mathematics.c:62
Fixes: 67811/clusterfuzz-testcase-minimized-ffmpeg_dem_MXF_fuzzer-
5108429687422976

Found-by: continuous fuzzing process
https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer 
---
 libavformat/mxfdec.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 04de4c1d5e3..233d614f783 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -1264,6 +1264,9 @@ static int mxf_read_index_table_segment(void
*arg, AVIOContext *pb, int tag, int
 case 0x3F0B:
 segment->index_edit_rate.num = avio_rb32(pb);
 segment->index_edit_rate.den = avio_rb32(pb);
+    if (segment->index_edit_rate.num <= 0 ||
+    segment->index_edit_rate.den <= 0)
+    return AVERROR_INVALIDDATA;


mxf_compute_index_tables() has a check for index_edit_rate that you
probably want to remove as well. It was introduced in c6fff3d, but the
files it supposedly fixes aren't in FATE. We shouldn't encourage broken
muxers.


I don't quite get what FATE has to do with it. And the samples mentioned 
in the patch has valid index segment edit rates, only they are different 
from the track edit rate, and the patch was intended to fix that case.


Regards,
Marton
___
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] lavc/vvc_parser: Fix integer overflow calculating framerate

2024-04-08 Thread James Almer

On 4/8/2024 3:20 PM, Frank Plowman wrote:

num_units_in_tick and time_scale are both 32-bit unsigned integers.
Storing them as ints was causing overflows.

Signed-off-by: Frank Plowman 
---
  libavcodec/vvc_parser.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/vvc_parser.c b/libavcodec/vvc_parser.c
index a6a5be27ae..e3501fa139 100644
--- a/libavcodec/vvc_parser.c
+++ b/libavcodec/vvc_parser.c
@@ -191,8 +191,8 @@ static void set_parser_ctx(AVCodecParserContext *s, 
AVCodecContext *avctx,
  
  if (sps->sps_ptl_dpb_hrd_params_present_flag &&

  sps->sps_timing_hrd_params_present_flag) {
-int num = sps->sps_general_timing_hrd_parameters.num_units_in_tick;
-int den = sps->sps_general_timing_hrd_parameters.time_scale;
+uint32_t num = 
sps->sps_general_timing_hrd_parameters.num_units_in_tick;
+uint32_t den = sps->sps_general_timing_hrd_parameters.time_scale;
  
  if (num != 0 && den != 0)

  av_reduce(>framerate.den, >framerate.num,


LGTM.
___
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] lavc/vvc_parser: Fix integer overflow calculating framerate

2024-04-08 Thread Frank Plowman
num_units_in_tick and time_scale are both 32-bit unsigned integers.
Storing them as ints was causing overflows.

Signed-off-by: Frank Plowman 
---
 libavcodec/vvc_parser.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/vvc_parser.c b/libavcodec/vvc_parser.c
index a6a5be27ae..e3501fa139 100644
--- a/libavcodec/vvc_parser.c
+++ b/libavcodec/vvc_parser.c
@@ -191,8 +191,8 @@ static void set_parser_ctx(AVCodecParserContext *s, 
AVCodecContext *avctx,
 
 if (sps->sps_ptl_dpb_hrd_params_present_flag &&
 sps->sps_timing_hrd_params_present_flag) {
-int num = sps->sps_general_timing_hrd_parameters.num_units_in_tick;
-int den = sps->sps_general_timing_hrd_parameters.time_scale;
+uint32_t num = 
sps->sps_general_timing_hrd_parameters.num_units_in_tick;
+uint32_t den = sps->sps_general_timing_hrd_parameters.time_scale;
 
 if (num != 0 && den != 0)
 av_reduce(>framerate.den, >framerate.num,
-- 
2.44.0

___
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] Query from Reuters on XZ, open source, and Microsoft

2024-04-08 Thread Romain Beauxis
On Wed, Apr 3, 2024, 11:39 Kieran Kunhya via ffmpeg-devel <
ffmpeg-devel@ffmpeg.org> wrote:

> Hi Raphael,
>
> I was the author of the tweet and I gave a short talk about this topic at
> Demuxed at a video conference last year:
> https://m.youtube.com/watch?v=OIyOEuQQsCQ=930s
>
> That said this is a community project and it would be best to continue the
> discussion on this mailing list unless agreed otherwise.
>

Thank you for sharing your talk. It's indeed unfortunate that large
companies are not more generous with the projects they depend on _heavily_

I would like to offer a constructive feedback really not intended as
trolling. I believe that supporting a more modern development workflow such
as the GitHub PR or gitlab MR would go very long way in helping onboarding
new developers.

I have been trying to contribute to the project for perhaps 18 months and,
while I think I'm getting better at it, I still find it incredibly complex
and hard to ramp up to.

The other open source community that I am involved with, the OCaml
compiler, moved to GitHub maybe 5/6 years ago and this has really done
wonders bringing in new contributors. And, you know, this is a niche
compiler that is also not getting much attention from AI/Machine Learning
people.


> Regards,
> Kieran Kunhya
>
> On Wed, 3 Apr 2024, 16:52 Satter, Raphael (Reuters) via ffmpeg-devel, <
> ffmpeg-devel@ffmpeg.org> wrote:
>
> > Dear FFMPEG community,
> >
> > This is Raphael Satter, a journalist with Reuters. I saw your thread on X
> > about your experience with Microsoft in the context of the XZ story and
> > would love to follow up with a few questions.
> >
> > Is there a good person to talk to? I’m reachable using the details below
> > or on Signal/WhatsApp at +1 202 430 9389.
> >
> > Raphael
> >
> >  raphael.sat...@tr.com
> >  raphaelsatter.com
> >  reuters.com/authors/raphael-satter
> >
> > Thomson Reuters
> > 1333 H Street NW
> > Washington, DC 20005
> >
> > ☎️ +1 202 843-6302
> >
> > ___
> > 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".


Re: [FFmpeg-devel] [PATCH] avcodec/mpegvideo_enc: Fix 1 line and one column images

2024-04-08 Thread Andreas Rheinhardt
Paul B Mahol:
> On Mon, Apr 8, 2024 at 6:49 PM Michael Niedermayer 
> wrote:
> 
>> Fixes: Ticket10952
>> Fixes: poc21ffmpeg
>> Signed-off-by: Michael Niedermayer 
>> ---
>>  libavcodec/mpegvideo_enc.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
>> index d1b19178247..40844b2f682 100644
>> --- a/libavcodec/mpegvideo_enc.c
>> +++ b/libavcodec/mpegvideo_enc.c
>> @@ -1199,8 +1199,8 @@ static int load_input_picture(MpegEncContext *s,
>> const AVFrame *pic_arg)
>>  ptrdiff_t dst_stride = i ? s->uvlinesize : s->linesize;
>>  int h_shift = i ? s->chroma_x_shift : 0;
>>  int v_shift = i ? s->chroma_y_shift : 0;
>> -int w = s->width  >> h_shift;
>> -int h = s->height >> v_shift;
>> +int w = -((-s->width)  >> h_shift);
>> +int h = -((-s->height) >> v_shift);
>>  const uint8_t *src = pic_arg->data[i];
>>  uint8_t *dst = pic->f->data[i];
>>  int vpad = 16;
>>
> 
> What that does? Its not same as aligned rshift macro?
> 

It is the same, just more complicated. And maybe with more instructions.

- 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/mpegvideo_enc: Fix 1 line and one column images

2024-04-08 Thread Paul B Mahol
On Mon, Apr 8, 2024 at 6:49 PM Michael Niedermayer 
wrote:

> Fixes: Ticket10952
> Fixes: poc21ffmpeg
> Signed-off-by: Michael Niedermayer 
> ---
>  libavcodec/mpegvideo_enc.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
> index d1b19178247..40844b2f682 100644
> --- a/libavcodec/mpegvideo_enc.c
> +++ b/libavcodec/mpegvideo_enc.c
> @@ -1199,8 +1199,8 @@ static int load_input_picture(MpegEncContext *s,
> const AVFrame *pic_arg)
>  ptrdiff_t dst_stride = i ? s->uvlinesize : s->linesize;
>  int h_shift = i ? s->chroma_x_shift : 0;
>  int v_shift = i ? s->chroma_y_shift : 0;
> -int w = s->width  >> h_shift;
> -int h = s->height >> v_shift;
> +int w = -((-s->width)  >> h_shift);
> +int h = -((-s->height) >> v_shift);
>  const uint8_t *src = pic_arg->data[i];
>  uint8_t *dst = pic->f->data[i];
>  int vpad = 16;
>

What that does? Its not same as aligned rshift macro?


> --
> 2.17.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] [EXT] Re: Query from Reuters on XZ, open source, and Microsoft

2024-04-08 Thread Paul B Mahol
On Mon, Apr 8, 2024 at 4:41 PM Nicolas George  wrote:

> Tomas Härdin (12024-04-08):
> > We could always start licensing the project under a less permissive
> > license like the GPL or the AGPL and then charge for exceptions. This
> > tactic goes by the name of license trolling, and was successfully used
> > by FFmbc for a while.
>
> Why do you say that when you know perfectly well than some of the
> developers holding copyright on the core code of the project will never
> let you do it and the project currently does not have the talent to
> rewrite everything?
>
> > We also don't need to support every use case.
>
> This, sadly, your ilk has the power to enforce. I am ancient enough in
> the project to remember the time where supporting every use case was
> almost an official motto, and lucid enough to realise that it was the
> main reason for the success of the project.
>

And the demise of LibAV, history repeats over and over again.


>
> --
>   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".
>
___
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/2] avcodec/mpegvideo_enc: Reject input incompatible with chroma subsampling

2024-04-08 Thread Anton Khirnov
Quoting Michael Niedermayer (2024-04-08 18:07:31)
> Also please dont apply stuff like this with a 1 day warning, i just saw this 
> now
> 
> dropping support for odd resolutions is a major change and not ok

Maybe such things would happen less frequently if your private testsuite
was less private.

-- 
Anton Khirnov
___
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] avcodec/mpegvideo_enc: Fix 1 line and one column images

2024-04-08 Thread Michael Niedermayer
Fixes: Ticket10952
Fixes: poc21ffmpeg
Signed-off-by: Michael Niedermayer 
---
 libavcodec/mpegvideo_enc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index d1b19178247..40844b2f682 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -1199,8 +1199,8 @@ static int load_input_picture(MpegEncContext *s, const 
AVFrame *pic_arg)
 ptrdiff_t dst_stride = i ? s->uvlinesize : s->linesize;
 int h_shift = i ? s->chroma_x_shift : 0;
 int v_shift = i ? s->chroma_y_shift : 0;
-int w = s->width  >> h_shift;
-int h = s->height >> v_shift;
+int w = -((-s->width)  >> h_shift);
+int h = -((-s->height) >> v_shift);
 const uint8_t *src = pic_arg->data[i];
 uint8_t *dst = pic->f->data[i];
 int vpad = 16;
-- 
2.17.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 1/2] avcodec/mpegvideo_enc: Reject input incompatible with chroma subsampling

2024-04-08 Thread Michael Niedermayer
On Mon, Apr 08, 2024 at 12:51:08AM +0200, Andreas Rheinhardt wrote:
> Andreas Rheinhardt:
> > Fixes ticket #10952.
> > 
> > Discovered by: Zeng Yunxiang
> > Signed-off-by: Andreas Rheinhardt 
> > ---
> > I am pretty sure that a lot of other encoders don't handle this well
> > either. Maybe we should handle this more generically in
> > ff_encode_preinit?
> > 
> >  libavcodec/mpegvideo_enc.c | 12 
> >  1 file changed, 12 insertions(+)
> > 
> > diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
> > index d1b1917824..a65ecc6839 100644
> > --- a/libavcodec/mpegvideo_enc.c
> > +++ b/libavcodec/mpegvideo_enc.c
> > @@ -314,6 +314,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
> >  AVCPBProperties *cpb_props;
> >  int i, ret;
> >  int mb_array_size, mv_table_size;
> > +int chroma_h_subsampling = 1, chroma_v_subsampling = 1;
> >  
> >  mpv_encode_defaults(s);
> >  
> > @@ -325,14 +326,25 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
> >  case AV_PIX_FMT_YUVJ422P:
> >  case AV_PIX_FMT_YUV422P:
> >  s->chroma_format = CHROMA_422;
> > +chroma_h_subsampling = 2;
> >  break;
> >  case AV_PIX_FMT_YUVJ420P:
> >  case AV_PIX_FMT_YUV420P:
> >  default:
> >  s->chroma_format = CHROMA_420;
> > +chroma_h_subsampling = 2;
> > +chroma_v_subsampling = 2;
> >  break;
> >  }
> >  
> > +if (avctx->width &  (chroma_h_subsampling - 1) ||
> > +avctx->height & (chroma_v_subsampling - 1)) {
> > +av_log(avctx, AV_LOG_ERROR,
> > +   "Dimensions %dx%d incompatible with chroma subsampling.\n",
> > +   avctx->width, avctx->height);
> > +return AVERROR(EINVAL);
> > +}
> > +
> >  avctx->bits_per_raw_sample = av_clip(avctx->bits_per_raw_sample, 0, 8);
> >  
> >  s->bit_rate = avctx->bit_rate;
> 
> Will apply this patchset tomorrow unless there are objections.

Also please dont apply stuff like this with a 1 day warning, i just saw this now

dropping support for odd resolutions is a major change and not ok

thanks

[...]
-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Elect your leaders based on what they did after the last election, not
based on what they say before an election.



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] [PATCH] lavc/vvc: Fix left shifts of negative values

2024-04-08 Thread Frank Plowman
All these variables lie in the range [-12..12]

Signed-off-by: Frank Plowman 
---
 libavcodec/vvc/ps.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libavcodec/vvc/ps.c b/libavcodec/vvc/ps.c
index 3c71c34bae..1b23675c98 100644
--- a/libavcodec/vvc/ps.c
+++ b/libavcodec/vvc/ps.c
@@ -1196,12 +1196,12 @@ static void sh_deblock_offsets(VVCSH *sh)
 const H266RawSliceHeader *r = sh->r;
 
 if (!r->sh_deblocking_filter_disabled_flag) {
-sh->deblock.beta_offset[LUMA] = r->sh_luma_beta_offset_div2 << 1;
-sh->deblock.tc_offset[LUMA]   = r->sh_luma_tc_offset_div2 << 1;
-sh->deblock.beta_offset[CB]   = r->sh_cb_beta_offset_div2 << 1;
-sh->deblock.tc_offset[CB] = r->sh_cb_tc_offset_div2 << 1;
-sh->deblock.beta_offset[CR]   = r->sh_cr_beta_offset_div2 << 1;
-sh->deblock.tc_offset[CR] = r->sh_cr_tc_offset_div2 << 1;
+sh->deblock.beta_offset[LUMA] = r->sh_luma_beta_offset_div2 * 2;
+sh->deblock.tc_offset[LUMA]   = r->sh_luma_tc_offset_div2 * 2;
+sh->deblock.beta_offset[CB]   = r->sh_cb_beta_offset_div2 * 2;
+sh->deblock.tc_offset[CB] = r->sh_cb_tc_offset_div2 * 2;
+sh->deblock.beta_offset[CR]   = r->sh_cr_beta_offset_div2 * 2;
+sh->deblock.tc_offset[CR] = r->sh_cr_tc_offset_div2 * 2;
 }
 }
 
-- 
2.44.0

___
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/2] avcodec/mpegvideo_enc: Reject input incompatible with chroma subsampling

2024-04-08 Thread Michael Niedermayer
On Mon, Apr 08, 2024 at 12:51:08AM +0200, Andreas Rheinhardt wrote:
> Andreas Rheinhardt:
> > Fixes ticket #10952.
> > 
> > Discovered by: Zeng Yunxiang
> > Signed-off-by: Andreas Rheinhardt 
> > ---
> > I am pretty sure that a lot of other encoders don't handle this well
> > either. Maybe we should handle this more generically in
> > ff_encode_preinit?
> > 
> >  libavcodec/mpegvideo_enc.c | 12 
> >  1 file changed, 12 insertions(+)
> > 
> > diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
> > index d1b1917824..a65ecc6839 100644
> > --- a/libavcodec/mpegvideo_enc.c
> > +++ b/libavcodec/mpegvideo_enc.c
> > @@ -314,6 +314,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
> >  AVCPBProperties *cpb_props;
> >  int i, ret;
> >  int mb_array_size, mv_table_size;
> > +int chroma_h_subsampling = 1, chroma_v_subsampling = 1;
> >  
> >  mpv_encode_defaults(s);
> >  
> > @@ -325,14 +326,25 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx)
> >  case AV_PIX_FMT_YUVJ422P:
> >  case AV_PIX_FMT_YUV422P:
> >  s->chroma_format = CHROMA_422;
> > +chroma_h_subsampling = 2;
> >  break;
> >  case AV_PIX_FMT_YUVJ420P:
> >  case AV_PIX_FMT_YUV420P:
> >  default:
> >  s->chroma_format = CHROMA_420;
> > +chroma_h_subsampling = 2;
> > +chroma_v_subsampling = 2;
> >  break;
> >  }
> >  
> > +if (avctx->width &  (chroma_h_subsampling - 1) ||
> > +avctx->height & (chroma_v_subsampling - 1)) {
> > +av_log(avctx, AV_LOG_ERROR,
> > +   "Dimensions %dx%d incompatible with chroma subsampling.\n",
> > +   avctx->width, avctx->height);
> > +return AVERROR(EINVAL);
> > +}
> > +
> >  avctx->bits_per_raw_sample = av_clip(avctx->bits_per_raw_sample, 0, 8);
> >  
> >  s->bit_rate = avctx->bit_rate;
> 
> Will apply this patchset tomorrow unless there are objections.

this breaks
./ffmpeg -i 
'samples.multimedia.cx/game-formats/sierra-vmd/lastdynasty/HG060808.VMD' -y 
test.avi


[...]

-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

The worst form of inequality is to try to make unequal things equal.
-- Aristotle


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] [PATCH] avutil/hwcontext_d3d12va: wait the texture is used before to free it.

2024-04-08 Thread Renan Lavarec via ffmpeg-devel
From: Renan Lavarec 
124602499+rlavarec-g...@users.noreply.github.com
Date: Mon, 8 Apr 2024 14:38:10 +0200
Subject: [PATCH] avutil/hwcontext_d3d12va: wait the texture is used inside the
GPU before to free it.

fix: ID3D12Resource2::: CORRUPTION: An ID3D12Resource object 
(0x0222D58B5450:'Unnamed Object') is referenced by GPU operations in-flight 
on Command Queue (0x0222EEC87090:'Unnamed ID3D12CommandQueue Object').
 It is not safe to final-release objects that may have GPU operations 
pending.  This can result in application instability. [ EXECUTION ERROR #921: 
OBJECT_DELETED_WHILE_STILL_IN_USE]
---
libavutil/hwcontext_d3d12va.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/libavutil/hwcontext_d3d12va.c b/libavutil/hwcontext_d3d12va.c
index cfc016315d..621a79d257 100644
--- a/libavutil/hwcontext_d3d12va.c
+++ b/libavutil/hwcontext_d3d12va.c
@@ -220,6 +220,9 @@ static void free_texture(void *opaque, uint8_t *data)
{
 AVD3D12VAFrame *frame = (AVD3D12VAFrame *)data;

+// Wait texture to be available
+d3d12va_fence_completion(>sync_ctx);
+
 D3D12_OBJECT_RELEASE(frame->texture);
 D3D12_OBJECT_RELEASE(frame->sync_ctx.fence);
 if (frame->sync_ctx.event)
--
2.44.0.windows.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] avcodec/vvc/ps: reset sps_id_used on PS uninit

2024-04-08 Thread Frank Plowman
On 08/04/2024 15:12, Nuo Mi wrote:
> On Mon, Apr 8, 2024 at 4:37 PM Frank Plowman  wrote:
> 
>> On 07/04/2024 15:48, James Almer wrote:
>>> On 4/7/2024 10:38 AM, Nuo Mi wrote:
 On Sun, Apr 7, 2024 at 11:05 AM James Almer  wrote:

> Signed-off-by: James Almer 
> ---
>   libavcodec/vvc/ps.c | 1 +
>   1 file changed, 1 insertion(+)
>
> diff --git a/libavcodec/vvc/ps.c b/libavcodec/vvc/ps.c
> index 3c71c34bae..83ee75fb62 100644
> --- a/libavcodec/vvc/ps.c
> +++ b/libavcodec/vvc/ps.c
> @@ -912,6 +912,7 @@ void ff_vvc_ps_uninit(VVCParamSets *ps)
>   ff_refstruct_unref(>sps_list[i]);
>   for (int i = 0; i < FF_ARRAY_ELEMS(ps->pps_list); i++)
>   ff_refstruct_unref(>pps_list[i]);
> +ps->sps_id_used = 0;
>
 Hi James,
 thank you for the patch.

 Is this really necessary?
 vvc_ps_uninit will be called by vvc_decode_free,
 We are not supposed to use any member of VVCParamSets after
 vvc_decode_free.
>>>
>>> My bad, i thought it was also called on every flush() call.
>>>
>>> Something like the following:
>>>
 diff --git a/libavcodec/vvc/dec.c b/libavcodec/vvc/dec.c
 index eb447604fe..463536512e 100644
 --- a/libavcodec/vvc/dec.c
 +++ b/libavcodec/vvc/dec.c
 @@ -963,6 +963,8 @@ static av_cold void
 vvc_decode_flush(AVCodecContext *avctx)
  ff_vvc_flush_dpb(last);
  }

 +s->ps->sps_id_used = 0;
 +
  s->eos = 1;
  }
>>>
>>> Should be done on FFCodec.flush() (like when seeking) as the previous
>>> state is no longer valid, right?
>>
>> Yes I agree, I think this is needed.  Cases where the random access
>> point has no leading pictures should be covered by the existing logic as
>> these always fall at the start of a CVS, but I think this is needed to
>> cover the case in which there are leading pictures.
>>
> This patch isn't necessary.
> Leading pictures won't carry SPS.
> IDR, CRA, and GDR will carry SPS, but they will also start a new CVS, which
> will covered by the current logic.
>

I may be misunderstanding the spec, NoOutputBeforeRecoveryFlag is set
for pictures which have no leading pictures, no?  In any case take, for
instance, a CRA picture.  In most cases, CRA pictures have
NoOutputBeforeRecoveryFlag=0, therefore are not CLVSS pictures and
sps_id_used is not reset by the existing logic.  Do we not need to reset
sps_id_used when seeking to a CRA then?
___
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] [EXT] Re: Query from Reuters on XZ, open source, and Microsoft

2024-04-08 Thread Nicolas George
Tomas Härdin (12024-04-08):
> We could always start licensing the project under a less permissive
> license like the GPL or the AGPL and then charge for exceptions. This
> tactic goes by the name of license trolling, and was successfully used
> by FFmbc for a while.

Why do you say that when you know perfectly well than some of the
developers holding copyright on the core code of the project will never
let you do it and the project currently does not have the talent to
rewrite everything?

> We also don't need to support every use case.

This, sadly, your ilk has the power to enforce. I am ancient enough in
the project to remember the time where supporting every use case was
almost an official motto, and lucid enough to realise that it was the
main reason for the success of the project.

-- 
  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] avformat/lc3: Add file format for LC3/LC3plus transport

2024-04-08 Thread Stefano Sabatini
On date Saturday 2024-04-06 21:08:19 +, ffmpeg-devel Mailing List wrote:
> From: Antoine SOULIER 
> 
> A file format is described in Bluetooth SIG LC3 and ETSI TS 103 634, for
> test purpose. This is the format implemented here.
> ---
>  Changelog|   1 +
>  doc/muxers.texi  |   6 ++
>  libavformat/Makefile |   2 +
>  libavformat/allformats.c |   2 +
>  libavformat/lc3dec.c | 173 +++
>  libavformat/lc3enc.c | 114 ++
>  6 files changed, 298 insertions(+)
>  create mode 100644 libavformat/lc3dec.c
>  create mode 100644 libavformat/lc3enc.c
> 
> diff --git a/Changelog b/Changelog
> index 18e83b99a1..02ed7831ec 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -4,6 +4,7 @@ releases are sorted from youngest to oldest.
>  version :
>  - Raw Captions with Time (RCWT) closed caption demuxer
>  - LC3/LC3plus decoding/encoding using external library liblc3
> +- LC3/LC3plus demuxer and muxer
>  
>  
>  version 7.0:
> diff --git a/doc/muxers.texi b/doc/muxers.texi
> index d8a1f83309..ed4144f6d1 100644
> --- a/doc/muxers.texi
> +++ b/doc/muxers.texi
> @@ -2700,6 +2700,12 @@ computer-generated compositions.
>  
>  This muxer accepts a single audio stream containing PCM data.
>  
> +@section lc3
> +Bluetooth SIG Low Complexity Communication Codec audio (LC3), or
> +ETSI TS 103 634 Low Complexity Communication Codec plus (LC3plus).
> +
> +This muxer accepts a single @code{lc3} audio stream.
> +
>  @section matroska
>  
>  Matroska container muxer.
> diff --git a/libavformat/Makefile b/libavformat/Makefile
> index 9981799cc9..027d0cdae5 100644
> --- a/libavformat/Makefile
> +++ b/libavformat/Makefile
> @@ -332,6 +332,8 @@ OBJS-$(CONFIG_KVAG_DEMUXER)  += kvag.o
>  OBJS-$(CONFIG_KVAG_MUXER)+= kvag.o rawenc.o
>  OBJS-$(CONFIG_LAF_DEMUXER)   += lafdec.o
>  OBJS-$(CONFIG_LATM_MUXER)+= latmenc.o rawenc.o
> +OBJS-$(CONFIG_LC3_DEMUXER)   += lc3dec.o
> +OBJS-$(CONFIG_LC3_MUXER) += lc3enc.o
>  OBJS-$(CONFIG_LMLM4_DEMUXER) += lmlm4.o
>  OBJS-$(CONFIG_LOAS_DEMUXER)  += loasdec.o rawdec.o
>  OBJS-$(CONFIG_LUODAT_DEMUXER)+= luodatdec.o
> diff --git a/libavformat/allformats.c b/libavformat/allformats.c
> index ae925dcf60..305fa46532 100644
> --- a/libavformat/allformats.c
> +++ b/libavformat/allformats.c
> @@ -252,6 +252,8 @@ extern const FFInputFormat  ff_kvag_demuxer;
>  extern const FFOutputFormat ff_kvag_muxer;
>  extern const FFInputFormat  ff_laf_demuxer;
>  extern const FFOutputFormat ff_latm_muxer;
> +extern const FFInputFormat  ff_lc3_demuxer;
> +extern const FFOutputFormat ff_lc3_muxer;
>  extern const FFInputFormat  ff_lmlm4_demuxer;
>  extern const FFInputFormat  ff_loas_demuxer;
>  extern const FFInputFormat  ff_luodat_demuxer;
> diff --git a/libavformat/lc3dec.c b/libavformat/lc3dec.c
> new file mode 100644
> index 00..371e9242d5
> --- /dev/null
> +++ b/libavformat/lc3dec.c
> @@ -0,0 +1,173 @@
> +/*
> + * LC3 demuxer
> + * Copyright (C) 2024  Antoine Soulier 
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
> USA
> + */
> +
> +/**
> + * @file
> + * Based on the file format specified by :
> + *
> + * - Bluetooth SIG - Low Complexity Communication Codec Test Suite
> + *   https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=502301
> + *   3.2.8.2 Reference LC3 Codec Bitstream Format
> + *
> + * - ETSI TI 103 634 V1.4.1 - Low Complexity Communication Codec plus
> + *   
> https://www.etsi.org/deliver/etsi_ts/103600_103699/103634/01.04.01_60/ts_103634v010401p.pdf
> + *   LC3plus conformance script package
> + */
> +
> +#include "libavcodec/packet.h"
> +#include "libavutil/intreadwrite.h"
> +
> +#include "avformat.h"
> +#include "avio.h"
> +#include "demux.h"
> +#include "internal.h"
> +
> +typedef struct LC3DemuxContext {
> +int frame_samples;
> +int64_t end_dts;
> +} LC3DemuxContext;
> +
> +static int lc3_read_probe(const AVProbeData *p)
> +{
> +int frame_us, srate_hz;
> +
> +if (p->buf_size < 12)
> +return 0;
> +
> +if (AV_RB16(p->buf + 0) != 0x1ccc ||
> +AV_RL16(p->buf + 2) <  9 * sizeof(uint16_t))
> +

Re: [FFmpeg-devel] FFmpeg TC input needed

2024-04-08 Thread Paul B Mahol
How dare you to question LibAV overlords decisions here!

On Mon, Apr 8, 2024 at 3:12 PM Gyan Doshi  wrote:

> Ping x2.
>
> On 2024-04-02 10:55 am, Gyan Doshi wrote:
> > Ping.
> >
> > As the TC rules matter has been concluded, this should go ahead.
> >
> > Regards,
> > Gyan
> >
> >
> > On 2024-02-17 05:15 pm, Gyan Doshi wrote:
> >> Issue:
> >>
> >> Patch: avcodec/s302m: enable non-PCM decoding
> >> URL:
> >>
> https://patchwork.ffmpeg.org/project/ffmpeg/patch/20240127103854.9971-1-ffm...@gyani.pro/
> >>
> >> The issue needing resolution is whether the patch should be added to
> >> the existing s302m decoder or should that decoder
> >> be removed and all old and new patched features inlined into the
> >> mpeg-ts demuxer.
> >>
> >> Summary:
> >>
> >> SMPTE ST 302 specifies for carriage of LPCM media in MPEG-TS. SMPTE
> >> ST 337 enables this for non-PCM codecs. The payload
> >> has a custom layout so it can't be directly processed hence
> >> lavc/s302m decodes the packet data to yield LPCM media. But
> >> it can only deal at present with LPCM payloads, meaning that non-PCM
> >> payloads need to be exported to a raw bytestream
> >> format and then decoded in a 2nd step, which prohibits direct
> >> transcoding of live/streaming inputs. This patch corrects
> >> the identification process for non-PCM payloads, reformats the
> >> payload and then carries out in-place decoding by calling
> >> a nested decoder similar to the ftr or imm5 decoders in lavc.
> >>
> >> In the v1 patch review, Andreas, in response to the proposed doc
> >> entry describing the feature capability of multiple
> >> or differing payloads in a s302m stream, suggested[1] that s302m
> >> should be a bitstream filter instead, but I did not
> >> see that as an actionable suggestion as he immediately listed the bsf
> >> limitations preventing the possibility. I also
> >> had not seen an actual sample of s302m with multiple embedded
> >> streams. Kieran also observed[2] that he had not seen
> >> such a stream in the wild. So the added features of this patch,
> >> wherever they are ultimately located, shall not yield
> >> more than one media stream. Anton suggested[3] that the decoder
> >> should instead be a demuxer. I saw no other objections
> >> to the architecture of the patch.
> >>
> >> I posted the v2 patch, incorporating some changes suggested by
> >> Andreas, 4 days later. This had gone uncommented for
> >> over two weeks when I posted a notice stating an intention to push.
> >> Anton posted[4] a new objection that "If it
> >> dynamically generates nested decoders, then it's not a proper codec
> >> in our model". This new objection is not connected
> >> to multiple streams but only to a codec 'model' that I don't see
> >> described anywhere and which contradicts the
> >> implementations of multiple decoders with a nested decoder, including
> >> the ftr and imm5 decoders, which are most similar
> >> in design to the patched s302m decoder. Anton later on mentioned[5]
> >> that nested decoders are "a constant source of
> >> issues". However, I didn't find anything on trac reporting an issue
> >> with the nested decoders of ftr and imm5 nor
> >> anything on ffmpeg-devel-ml or ffmpeg-user-ml. Nothing in their
> >> commit history either points to architectural bugs.
> >> These decoders have been around for 6 years among themselves. The
> >> testing of the patched s302m decoder over the past
> >> month by myself, an OTT provider and others shows no issues either.
> >> Finally, Anton speculates[6] that the burden of
> >> fixes will likely fall upon him. In none of his objections, till the
> >> time of writing, did I see specific concerns with
> >> the patch.
> >>
> >> There are some limitations in shifting this decoder wholesale to
> >> inside the MPEG-TS demuxer. A s302m stream may contain
> >> some non-media payload accompanying non-PCM media i.e. S-ADM
> >> metadata. At present, I have neither the samples nor the
> >> specification needed in order to locate and extract or parse this
> >> metadata. Formatting the payload data inside the
> >> demuxer will lead to irrevocable loss of such metadata if present.
> >> However, a decoder patch allows simultaneuous output
> >> of both a decoded stream alongside a copied stream. The end-user can
> >> then do with the raw data whatever they wish.
> >>
> >> Ultimately, s302m is specified an an elementary stream inside a
> >> MPEG-TS container. Its internal handling is better left
> >> to a dedicated module like a decoder. A bitstream filter might be a
> >> better fit if s302m streams with multiple media
> >> payloads ever start appearing - none have, so far - but for single
> >> media payloads, a decoder remains the best place.
> >>
> >> Regards,
> >> Gyan
> >>
> >> [1]: https://ffmpeg.org/pipermail/ffmpeg-devel/2024-January/320119.html
> >> [2]: https://ffmpeg.org/pipermail/ffmpeg-devel/2024-January/320321.html
> >> [3]: https://ffmpeg.org/pipermail/ffmpeg-devel/2024-January/320258.html
> >> [4]:
> 

Re: [FFmpeg-devel] [PATCH] avcodec/vvc/ps: reset sps_id_used on PS uninit

2024-04-08 Thread Nuo Mi
On Mon, Apr 8, 2024 at 4:37 PM Frank Plowman  wrote:

> On 07/04/2024 15:48, James Almer wrote:
> > On 4/7/2024 10:38 AM, Nuo Mi wrote:
> >> On Sun, Apr 7, 2024 at 11:05 AM James Almer  wrote:
> >>
> >>> Signed-off-by: James Almer 
> >>> ---
> >>>   libavcodec/vvc/ps.c | 1 +
> >>>   1 file changed, 1 insertion(+)
> >>>
> >>> diff --git a/libavcodec/vvc/ps.c b/libavcodec/vvc/ps.c
> >>> index 3c71c34bae..83ee75fb62 100644
> >>> --- a/libavcodec/vvc/ps.c
> >>> +++ b/libavcodec/vvc/ps.c
> >>> @@ -912,6 +912,7 @@ void ff_vvc_ps_uninit(VVCParamSets *ps)
> >>>   ff_refstruct_unref(>sps_list[i]);
> >>>   for (int i = 0; i < FF_ARRAY_ELEMS(ps->pps_list); i++)
> >>>   ff_refstruct_unref(>pps_list[i]);
> >>> +ps->sps_id_used = 0;
> >>>
> >> Hi James,
> >> thank you for the patch.
> >>
> >> Is this really necessary?
> >> vvc_ps_uninit will be called by vvc_decode_free,
> >> We are not supposed to use any member of VVCParamSets after
> >> vvc_decode_free.
> >
> > My bad, i thought it was also called on every flush() call.
> >
> > Something like the following:
> >
> >> diff --git a/libavcodec/vvc/dec.c b/libavcodec/vvc/dec.c
> >> index eb447604fe..463536512e 100644
> >> --- a/libavcodec/vvc/dec.c
> >> +++ b/libavcodec/vvc/dec.c
> >> @@ -963,6 +963,8 @@ static av_cold void
> >> vvc_decode_flush(AVCodecContext *avctx)
> >>  ff_vvc_flush_dpb(last);
> >>  }
> >>
> >> +s->ps->sps_id_used = 0;
> >> +
> >>  s->eos = 1;
> >>  }
> >
> > Should be done on FFCodec.flush() (like when seeking) as the previous
> > state is no longer valid, right?
>
> Yes I agree, I think this is needed.  Cases where the random access
> point has no leading pictures should be covered by the existing logic as
> these always fall at the start of a CVS, but I think this is needed to
> cover the case in which there are leading pictures.
>
This patch isn't necessary.
Leading pictures won't carry SPS.
IDR, CRA, and GDR will carry SPS, but they will also start a new CVS, which
will covered by the current logic.


> Thanks,
> --
> Frank
> ___
> 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] avformat/tls_mbedtls: Pass FLAG_NONBLOCK to underlying transport

2024-04-08 Thread Zhao Zhili


> On Apr 8, 2024, at 21:32, Dennis Mungai  wrote:
> 
> On Mon, 8 Apr 2024 at 16:26, Zhao Zhili  wrote:
> 
>> From: Zhao Zhili 
>> 
>> This fix rtmps failure since rtmps requires nonblocking read.
>> 
>> Signed-off-by: Zhao Zhili 
>> ---
>> libavformat/tls_mbedtls.c | 4 
>> 1 file changed, 4 insertions(+)
>> 
>> diff --git a/libavformat/tls_mbedtls.c b/libavformat/tls_mbedtls.c
>> index 8503523b6d..f51cf43b1c 100644
>> --- a/libavformat/tls_mbedtls.c
>> +++ b/libavformat/tls_mbedtls.c
>> @@ -309,6 +309,8 @@ static int tls_read(URLContext *h, uint8_t *buf, int
>> size)
>> TLSContext *tls_ctx = h->priv_data;
>> int ret;
>> 
>> +tls_ctx->tls_shared.tcp->flags &= ~AVIO_FLAG_NONBLOCK;
>> +tls_ctx->tls_shared.tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK;
>> if ((ret = mbedtls_ssl_read(_ctx->ssl_context, buf, size)) > 0) {
>> // return read length
>> return ret;
>> @@ -322,6 +324,8 @@ static int tls_write(URLContext *h, const uint8_t
>> *buf, int size)
>> TLSContext *tls_ctx = h->priv_data;
>> int ret;
>> 
>> +tls_ctx->tls_shared.tcp->flags &= ~AVIO_FLAG_NONBLOCK;
>> +tls_ctx->tls_shared.tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK;
>> if ((ret = mbedtls_ssl_write(_ctx->ssl_context, buf, size)) > 0) {
>> // return written length
>> return ret;
>> --
>> 2.25.1
>> 
> 
> Are other TLS layers affected, say OpenSSL, etc?

openssl and gnutls don’t get affected, since they have done the same operation.
I don’t know about schannel and securetransport.

> ___
> 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] avformat/tls_mbedtls: Pass FLAG_NONBLOCK to underlying transport

2024-04-08 Thread Dennis Mungai
On Mon, 8 Apr 2024 at 16:26, Zhao Zhili  wrote:

> From: Zhao Zhili 
>
> This fix rtmps failure since rtmps requires nonblocking read.
>
> Signed-off-by: Zhao Zhili 
> ---
>  libavformat/tls_mbedtls.c | 4 
>  1 file changed, 4 insertions(+)
>
> diff --git a/libavformat/tls_mbedtls.c b/libavformat/tls_mbedtls.c
> index 8503523b6d..f51cf43b1c 100644
> --- a/libavformat/tls_mbedtls.c
> +++ b/libavformat/tls_mbedtls.c
> @@ -309,6 +309,8 @@ static int tls_read(URLContext *h, uint8_t *buf, int
> size)
>  TLSContext *tls_ctx = h->priv_data;
>  int ret;
>
> +tls_ctx->tls_shared.tcp->flags &= ~AVIO_FLAG_NONBLOCK;
> +tls_ctx->tls_shared.tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK;
>  if ((ret = mbedtls_ssl_read(_ctx->ssl_context, buf, size)) > 0) {
>  // return read length
>  return ret;
> @@ -322,6 +324,8 @@ static int tls_write(URLContext *h, const uint8_t
> *buf, int size)
>  TLSContext *tls_ctx = h->priv_data;
>  int ret;
>
> +tls_ctx->tls_shared.tcp->flags &= ~AVIO_FLAG_NONBLOCK;
> +tls_ctx->tls_shared.tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK;
>  if ((ret = mbedtls_ssl_write(_ctx->ssl_context, buf, size)) > 0) {
>  // return written length
>  return ret;
> --
> 2.25.1
>

Are other TLS layers affected, say OpenSSL, etc?
___
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] avformat/tls_mbedtls: Pass FLAG_NONBLOCK to underlying transport

2024-04-08 Thread Zhao Zhili
From: Zhao Zhili 

This fix rtmps failure since rtmps requires nonblocking read.

Signed-off-by: Zhao Zhili 
---
 libavformat/tls_mbedtls.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/libavformat/tls_mbedtls.c b/libavformat/tls_mbedtls.c
index 8503523b6d..f51cf43b1c 100644
--- a/libavformat/tls_mbedtls.c
+++ b/libavformat/tls_mbedtls.c
@@ -309,6 +309,8 @@ static int tls_read(URLContext *h, uint8_t *buf, int size)
 TLSContext *tls_ctx = h->priv_data;
 int ret;
 
+tls_ctx->tls_shared.tcp->flags &= ~AVIO_FLAG_NONBLOCK;
+tls_ctx->tls_shared.tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK;
 if ((ret = mbedtls_ssl_read(_ctx->ssl_context, buf, size)) > 0) {
 // return read length
 return ret;
@@ -322,6 +324,8 @@ static int tls_write(URLContext *h, const uint8_t *buf, int 
size)
 TLSContext *tls_ctx = h->priv_data;
 int ret;
 
+tls_ctx->tls_shared.tcp->flags &= ~AVIO_FLAG_NONBLOCK;
+tls_ctx->tls_shared.tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK;
 if ((ret = mbedtls_ssl_write(_ctx->ssl_context, buf, size)) > 0) {
 // return written length
 return ret;
-- 
2.25.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/2] configure: simplify bigendian check

2024-04-08 Thread J. Dekker
The preferred way to use LTO is --enable-lto but often times packagers
still end up with -flto in cflags for various reasons. Using grep
on binary object files is brittle and relies on specific object
representation, which in the case of LLVM bitcode, debug-info or other
intermediary formats can fail silently.

This patch changes the check to a more commonly used define for
big-endian systems. More checks may need to be added in the future to
cover legacy machines.

Signed-off-by: J. Dekker 
---
 configure | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/configure b/configure
index 7b6f48e631..e787f13e0b 100755
--- a/configure
+++ b/configure
@@ -6120,11 +6120,7 @@ extern_prefix=${sym%%ff_extern*}
 
 check_cc pragma_deprecated "" '_Pragma("GCC diagnostic push") _Pragma("GCC 
diagnostic ignored \"-Wdeprecated-declarations\"")'
 
-# The global variable ensures the bits appear unchanged in the object file.
-test_cc 

[FFmpeg-devel] [PATCH v2 1/2] configure,etc: unify shebang usage

2024-04-08 Thread J. Dekker
In some cases, these scripts can be called directly by packagers, and
some systems require the interpreter to be explicit.

Signed-off-by: J. Dekker 
---
 configure | 3 ++-
 doc/texidep.pl| 2 +-
 ffbuild/libversion.sh | 1 +
 tests/fate-run.sh | 2 +-
 tests/fate.sh | 2 +-
 5 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/configure b/configure
index f511fbae49..7b6f48e631 100755
--- a/configure
+++ b/configure
@@ -4737,7 +4737,7 @@ chmod +x $TMPE
 
 # make sure we can execute files in $TMPDIR
 cat > $TMPSH 2>> $logfile <> $logfile 2>&1
 if ! $TMPSH >> $logfile 2>&1; then
@@ -8283,6 +8283,7 @@ print_enabled_components libavformat/protocol_list.c 
URLProtocol url_protocols $
 # Settings for pkg-config files
 
 cat > $TMPH <  
diff --git a/ffbuild/libversion.sh b/ffbuild/libversion.sh
index a94ab58057..ecaa90cde6 100755
--- a/ffbuild/libversion.sh
+++ b/ffbuild/libversion.sh
@@ -1,3 +1,4 @@
+#!/bin/sh
 toupper(){
 echo "$@" | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
 }
diff --git a/tests/fate-run.sh b/tests/fate-run.sh
index 9863e4f2d9..6ae0320c60 100755
--- a/tests/fate-run.sh
+++ b/tests/fate-run.sh
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 export LC_ALL=C
 
diff --git a/tests/fate.sh b/tests/fate.sh
index 07908be3a5..c5ee18de80 100755
--- a/tests/fate.sh
+++ b/tests/fate.sh
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/sh
 
 config=$1
 
-- 
2.44.0

___
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] FFmpeg TC input needed

2024-04-08 Thread Gyan Doshi

Ping x2.

On 2024-04-02 10:55 am, Gyan Doshi wrote:

Ping.

As the TC rules matter has been concluded, this should go ahead.

Regards,
Gyan


On 2024-02-17 05:15 pm, Gyan Doshi wrote:

Issue:

Patch: avcodec/s302m: enable non-PCM decoding
URL: 
https://patchwork.ffmpeg.org/project/ffmpeg/patch/20240127103854.9971-1-ffm...@gyani.pro/


The issue needing resolution is whether the patch should be added to 
the existing s302m decoder or should that decoder
be removed and all old and new patched features inlined into the 
mpeg-ts demuxer.


Summary:

SMPTE ST 302 specifies for carriage of LPCM media in MPEG-TS. SMPTE 
ST 337 enables this for non-PCM codecs. The payload
has a custom layout so it can't be directly processed hence 
lavc/s302m decodes the packet data to yield LPCM media. But
it can only deal at present with LPCM payloads, meaning that non-PCM 
payloads need to be exported to a raw bytestream
format and then decoded in a 2nd step, which prohibits direct 
transcoding of live/streaming inputs. This patch corrects
the identification process for non-PCM payloads, reformats the 
payload and then carries out in-place decoding by calling

a nested decoder similar to the ftr or imm5 decoders in lavc.

In the v1 patch review, Andreas, in response to the proposed doc 
entry describing the feature capability of multiple
or differing payloads in a s302m stream, suggested[1] that s302m 
should be a bitstream filter instead, but I did not
see that as an actionable suggestion as he immediately listed the bsf 
limitations preventing the possibility. I also
had not seen an actual sample of s302m with multiple embedded 
streams. Kieran also observed[2] that he had not seen
such a stream in the wild. So the added features of this patch, 
wherever they are ultimately located, shall not yield
more than one media stream. Anton suggested[3] that the decoder 
should instead be a demuxer. I saw no other objections

to the architecture of the patch.

I posted the v2 patch, incorporating some changes suggested by 
Andreas, 4 days later. This had gone uncommented for
over two weeks when I posted a notice stating an intention to push. 
Anton posted[4] a new objection that "If it
dynamically generates nested decoders, then it's not a proper codec 
in our model". This new objection is not connected
to multiple streams but only to a codec 'model' that I don't see 
described anywhere and which contradicts the
implementations of multiple decoders with a nested decoder, including 
the ftr and imm5 decoders, which are most similar
in design to the patched s302m decoder. Anton later on mentioned[5] 
that nested decoders are "a constant source of
issues". However, I didn't find anything on trac reporting an issue 
with the nested decoders of ftr and imm5 nor
anything on ffmpeg-devel-ml or ffmpeg-user-ml. Nothing in their 
commit history either points to architectural bugs.
These decoders have been around for 6 years among themselves. The 
testing of the patched s302m decoder over the past
month by myself, an OTT provider and others shows no issues either. 
Finally, Anton speculates[6] that the burden of
fixes will likely fall upon him. In none of his objections, till the 
time of writing, did I see specific concerns with

the patch.

There are some limitations in shifting this decoder wholesale to 
inside the MPEG-TS demuxer. A s302m stream may contain
some non-media payload accompanying non-PCM media i.e. S-ADM 
metadata. At present, I have neither the samples nor the
specification needed in order to locate and extract or parse this 
metadata. Formatting the payload data inside the
demuxer will lead to irrevocable loss of such metadata if present. 
However, a decoder patch allows simultaneuous output
of both a decoded stream alongside a copied stream. The end-user can 
then do with the raw data whatever they wish.


Ultimately, s302m is specified an an elementary stream inside a 
MPEG-TS container. Its internal handling is better left
to a dedicated module like a decoder. A bitstream filter might be a 
better fit if s302m streams with multiple media
payloads ever start appearing - none have, so far - but for single 
media payloads, a decoder remains the best place.


Regards,
Gyan

[1]: https://ffmpeg.org/pipermail/ffmpeg-devel/2024-January/320119.html
[2]: https://ffmpeg.org/pipermail/ffmpeg-devel/2024-January/320321.html
[3]: https://ffmpeg.org/pipermail/ffmpeg-devel/2024-January/320258.html
[4]: https://ffmpeg.org/pipermail/ffmpeg-devel/2024-February/321514.html
[5]: https://ffmpeg.org/pipermail/ffmpeg-devel/2024-February/321523.html
[6]: https://ffmpeg.org/pipermail/ffmpeg-devel/2024-February/321539.html

___
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] [PATCH v2 11/17] fftools: drop unused/hacky macros

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

Having macros initialize local variables seems strange to me, and there
are no more current users of these macros. (The one that was commented
out was incorrect anyway, since the macro has changed in the meantime)
---
 fftools/cmdutils.h  | 13 -
 fftools/ffmpeg_filter.c |  2 +-
 2 files changed, 1 insertion(+), 14 deletions(-)

diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h
index d0c773663ba..940541b9eaf 100644
--- a/fftools/cmdutils.h
+++ b/fftools/cmdutils.h
@@ -465,19 +465,6 @@ void *allocate_array_elem(void *array, size_t elem_size, 
int *nb_elems);
 #define GROW_ARRAY(array, nb_elems)\
 grow_array((void**), sizeof(*array), _elems, nb_elems + 1)
 
-#define GET_PIX_FMT_NAME(pix_fmt)\
-const char *name = av_get_pix_fmt_name(pix_fmt);
-
-#define GET_CODEC_NAME(id)\
-const char *name = avcodec_descriptor_get(id)->name;
-
-#define GET_SAMPLE_FMT_NAME(sample_fmt)\
-const char *name = av_get_sample_fmt_name(sample_fmt)
-
-#define GET_SAMPLE_RATE_NAME(rate)\
-char name[16];\
-snprintf(name, sizeof(name), "%d", rate);
-
 double get_rotation(const int32_t *displaymatrix);
 
 /* read file contents into a string */
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 2308abf82af..ac04841a16c 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -401,7 +401,7 @@ static void choose_ ## name (OutputFilterPriv *ofp, 
AVBPrint *bprint)  \
 }
 
 //DEF_CHOOSE_FORMAT(pix_fmts, enum AVPixelFormat, format, formats, 
AV_PIX_FMT_NONE,
-//  GET_PIX_FMT_NAME)
+//  av_get_pix_fmt_name)
 
 DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats,
   AV_SAMPLE_FMT_NONE, "%s", av_get_sample_fmt_name)
-- 
2.44.0

___
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 10/17] fftools/opt_common: switch to avcodec_get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

While rewriting this macro, I decided to make it a bit more flexible so
it can work for all of the fields (including future fields) in a more
generic way, and to also print the channel layout using an AVBPrint to
avoid hard-coding the assumption that the length is less than 128
characters.
---
 fftools/opt_common.c | 92 +++-
 1 file changed, 49 insertions(+), 43 deletions(-)

diff --git a/fftools/opt_common.c b/fftools/opt_common.c
index 947a226d8d1..c4d71fbe3c7 100644
--- a/fftools/opt_common.c
+++ b/fftools/opt_common.c
@@ -262,22 +262,35 @@ int show_buildconf(void *optctx, const char *opt, const 
char *arg)
 return 0;
 }
 
-#define PRINT_CODEC_SUPPORTED(codec, field, type, list_name, term, get_name) \
-if (codec->field) {  \
-const type *p = codec->field;\
- \
-printf("Supported " list_name ":");  \
-while (*p != term) { \
-get_name(*p);\
-printf(" %s", name); \
-p++; \
-}\
-printf("\n");\
-}\
+#define PRINT_CODEC_SUPPORTED(codec, config, type, name, elem, cond, fmt, ...) 
 \
+do {   
 \
+const type *elem = NULL;   
 \
+avcodec_get_supported_config(NULL, codec, config, 0,   
 \
+ (const void **) );   
 \
+if (elem) {
 \
+printf("Supported " name ":"); 
 \
+while (cond) { 
 \
+printf(" " fmt, __VA_ARGS__);  
 \
+elem++;
 \
+}  
 \
+printf("\n");  
 \
+}  
 \
+} while (0)
+
+static const char *get_channel_layout_desc(const AVChannelLayout *layout, 
AVBPrint *bp)
+{
+int ret;
+av_bprint_clear(bp);
+ret = av_channel_layout_describe_bprint(layout, bp);
+if (!av_bprint_is_complete(bp) || ret < 0)
+return "unknown/invalid";
+return bp->str;
+}
 
 static void print_codec(const AVCodec *c)
 {
 int encoder = av_codec_is_encoder(c);
+AVBPrint desc;
 
 printf("%s %s [%s]:\n", encoder ? "Encoder" : "Decoder", c->name,
c->long_name ? c->long_name : "");
@@ -343,35 +356,22 @@ static void print_codec(const AVCodec *c)
 printf("\n");
 }
 
-if (c->supported_framerates) {
-const AVRational *fps = c->supported_framerates;
-
-printf("Supported framerates:");
-while (fps->num) {
-printf(" %d/%d", fps->num, fps->den);
-fps++;
-}
-printf("\n");
-}
-PRINT_CODEC_SUPPORTED(c, pix_fmts, enum AVPixelFormat, "pixel formats",
-  AV_PIX_FMT_NONE, GET_PIX_FMT_NAME);
-PRINT_CODEC_SUPPORTED(c, supported_samplerates, int, "sample rates", 0,
-  GET_SAMPLE_RATE_NAME);
-PRINT_CODEC_SUPPORTED(c, sample_fmts, enum AVSampleFormat, "sample 
formats",
-  AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME);
-
-if (c->ch_layouts) {
-const AVChannelLayout *p = c->ch_layouts;
-
-printf("Supported channel layouts:");
-while (p->nb_channels) {
-char name[128];
-av_channel_layout_describe(p, name, sizeof(name));
-printf(" %s", name);
-p++;
-}
-printf("\n");
-}
+PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_FRAME_RATE, AVRational, 
"framerates",
+  fps, fps->num, "%d/%d", fps->num, fps->den);
+PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_PIX_FORMAT, enum AVPixelFormat,
+  "pixel formats", fmt, *fmt != AV_PIX_FMT_NONE,
+  "%s", av_get_pix_fmt_name(*fmt));
+PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_SAMPLE_RATE, int, "sample rates",
+  rate, *rate != 0, "%d", *rate);
+PRINT_CODEC_SUPPORTED(c, 

[FFmpeg-devel] [PATCH v2 09/17] avcodec/codec_internal: nuke init_static_data()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

All hail get_supported_config()
---
 libavcodec/allcodecs.c  | 7 +--
 libavcodec/codec_internal.h | 8 
 2 files changed, 1 insertion(+), 14 deletions(-)

diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index a9f1797930a..1f22e06e710 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -916,13 +916,8 @@ static AVOnce av_codec_static_init = AV_ONCE_INIT;
 static void av_codec_init_static(void)
 {
 for (int i = 0; codec_list[i]; i++) {
-const FFCodec *codec = codec_list[i];
-if (codec->init_static_data) {
-codec->init_static_data((FFCodec*) codec);
-continue;
-}
-
 /* Backward compatibility with deprecated public fields */
+const FFCodec *codec = codec_list[i];
 if (!codec->get_supported_config)
 continue;
 
diff --git a/libavcodec/codec_internal.h b/libavcodec/codec_internal.h
index bac3e30ba2c..d3033db3375 100644
--- a/libavcodec/codec_internal.h
+++ b/libavcodec/codec_internal.h
@@ -174,14 +174,6 @@ typedef struct FFCodec {
  */
 const FFCodecDefault *defaults;
 
-/**
- * Initialize codec static data, called from av_codec_iterate().
- *
- * This is not intended for time consuming operations as it is
- * run for every codec regardless of that codec being used.
- */
-void (*init_static_data)(struct FFCodec *codec);
-
 int (*init)(struct AVCodecContext *);
 
 union {
-- 
2.44.0

___
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 08/17] avcodec/mjpegenc: switch to get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

This codec's capabilities should be set dynamically based on the value
of strict_std_compliance, when available. This will allow us to finally
get rid of the strictness hack in ffmpeg_filter.c.
---
 libavcodec/mjpegenc.c | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 137b68a98db..0473ad132ba 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -640,7 +640,24 @@ static const AVClass mjpeg_class = {
 .version= LIBAVUTIL_VERSION_INT,
 };
 
-const FFCodec ff_mjpeg_encoder = {
+static int mjpeg_get_supported_config(const AVCodecContext *avctx,
+  const AVCodec *codec,
+  enum AVCodecConfig config,
+  unsigned flags, const void **out)
+{
+if (config == AV_CODEC_CONFIG_COLOR_RANGE) {
+static const enum AVColorRange mjpeg_ranges[] = {
+AVCOL_RANGE_MPEG, AVCOL_RANGE_JPEG, AVCOL_RANGE_UNSPECIFIED,
+};
+int strict = avctx ? avctx->strict_std_compliance : 0;
+*out = _ranges[strict > FF_COMPLIANCE_UNOFFICIAL ? 1 : 0];
+return 0;
+}
+
+return ff_default_get_supported_config(avctx, codec, config, flags, out);
+}
+
+FFCodec ff_mjpeg_encoder = {
 .p.name = "mjpeg",
 CODEC_LONG_NAME("MJPEG (Motion JPEG)"),
 .p.type = AVMEDIA_TYPE_VIDEO,
@@ -657,9 +674,9 @@ const FFCodec ff_mjpeg_encoder = {
 AV_PIX_FMT_YUV420P,  AV_PIX_FMT_YUV422P,  AV_PIX_FMT_YUV444P,
 AV_PIX_FMT_NONE
 },
-.color_ranges   = AVCOL_RANGE_MPEG | AVCOL_RANGE_JPEG,
 .p.priv_class   = _class,
 .p.profiles = NULL_IF_CONFIG_SMALL(ff_mjpeg_profiles),
+.get_supported_config = mjpeg_get_supported_config,
 };
 #endif
 
-- 
2.44.0

___
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 07/17] avcodec/libaomenc: switch to get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

---
 libavcodec/libaomenc.c | 28 ++--
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
index 5023d2fda42..0488e5c3c9a 100644
--- a/libavcodec/libaomenc.c
+++ b/libavcodec/libaomenc.c
@@ -1398,16 +1398,24 @@ static const enum AVPixelFormat 
av1_pix_fmts_highbd_with_gray[] = {
 AV_PIX_FMT_NONE
 };
 
-static av_cold void av1_init_static(FFCodec *codec)
+static int av1_get_supported_config(const AVCodecContext *avctx,
+const AVCodec *codec,
+enum AVCodecConfig config,
+unsigned flags, const void **out)
 {
-int supports_monochrome = aom_codec_version() >= 20001;
-aom_codec_caps_t codec_caps = aom_codec_get_caps(aom_codec_av1_cx());
-if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH)
-codec->p.pix_fmts = supports_monochrome ? 
av1_pix_fmts_highbd_with_gray :
-  av1_pix_fmts_highbd;
-else
-codec->p.pix_fmts = supports_monochrome ? av1_pix_fmts_with_gray :
-  av1_pix_fmts;
+if (config == AV_CODEC_CONFIG_PIX_FORMAT) {
+int supports_monochrome = aom_codec_version() >= 20001;
+aom_codec_caps_t codec_caps = aom_codec_get_caps(aom_codec_av1_cx());
+if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH)
+*out = supports_monochrome ? av1_pix_fmts_highbd_with_gray :
+ av1_pix_fmts_highbd;
+else
+*out = supports_monochrome ? av1_pix_fmts_with_gray :
+ av1_pix_fmts;
+return 0;
+}
+
+return ff_default_get_supported_config(avctx, codec, config, flags, out);
 }
 
 static av_cold int av1_init(AVCodecContext *avctx)
@@ -1529,5 +1537,5 @@ FFCodec ff_libaom_av1_encoder = {
   FF_CODEC_CAP_INIT_CLEANUP |
   FF_CODEC_CAP_AUTO_THREADS,
 .defaults   = defaults,
-.init_static_data = av1_init_static,
+.get_supported_config = av1_get_supported_config,
 };
-- 
2.44.0

___
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 06/17] avcodec/libvpxenc: switch to get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

---
 libavcodec/libvpxenc.c | 22 +++---
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index cdb83312614..64dc69f8547 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -2087,13 +2087,21 @@ static const enum AVPixelFormat vp9_pix_fmts_highbd[] = 
{
 AV_PIX_FMT_NONE
 };
 
-static av_cold void vp9_init_static(FFCodec *codec)
+static int vp9_get_supported_config(const AVCodecContext *avctx,
+const AVCodec *codec,
+enum AVCodecConfig config,
+unsigned flags, const void **out)
 {
-vpx_codec_caps_t codec_caps = vpx_codec_get_caps(vpx_codec_vp9_cx());
-if (codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH)
-codec->p.pix_fmts = vp9_pix_fmts_highbd;
-else
-codec->p.pix_fmts = vp9_pix_fmts_highcol;
+if (config == AV_CODEC_CONFIG_PIX_FORMAT) {
+vpx_codec_caps_t codec_caps = vpx_codec_get_caps(vpx_codec_vp9_cx());
+if (codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH)
+*out = vp9_pix_fmts_highbd;
+else
+*out = vp9_pix_fmts_highcol;
+return 0;
+}
+
+return ff_default_get_supported_config(avctx, codec, config, flags, out);
 }
 
 static const AVClass class_vp9 = {
@@ -2122,6 +2130,6 @@ FFCodec ff_libvpx_vp9_encoder = {
 .caps_internal  = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
   FF_CODEC_CAP_AUTO_THREADS,
 .defaults   = defaults,
-.init_static_data = vp9_init_static,
+.get_supported_config = vp9_get_supported_config,
 };
 #endif /* CONFIG_LIBVPX_VP9_ENCODER */
-- 
2.44.0

___
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 05/17] avcodec/libx265: switch to get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

---
 libavcodec/libx265.c | 26 ++
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c
index 3533ac5cc1f..e36a1eb9505 100644
--- a/libavcodec/libx265.c
+++ b/libavcodec/libx265.c
@@ -892,14 +892,24 @@ static const enum AVPixelFormat x265_csp_twelve[] = {
 AV_PIX_FMT_NONE
 };
 
-static av_cold void libx265_encode_init_csp(FFCodec *codec)
+static int libx265_get_supported_config(const AVCodecContext *avctx,
+const AVCodec *codec,
+enum AVCodecConfig config,
+unsigned flags, const void **out)
 {
-if (x265_api_get(12))
-codec->p.pix_fmts = x265_csp_twelve;
-else if (x265_api_get(10))
-codec->p.pix_fmts = x265_csp_ten;
-else if (x265_api_get(8))
-codec->p.pix_fmts = x265_csp_eight;
+if (config == AV_CODEC_CONFIG_PIX_FORMAT) {
+if (x265_api_get(12))
+*out = x265_csp_twelve;
+else if (x265_api_get(10))
+*out = x265_csp_ten;
+else if (x265_api_get(8))
+*out = x265_csp_eight;
+else
+return AVERROR_EXTERNAL;
+return 0;
+}
+
+return ff_default_get_supported_config(avctx, codec, config, flags, out);
 }
 
 #define OFFSET(x) offsetof(libx265Context, x)
@@ -952,7 +962,7 @@ FFCodec ff_libx265_encoder = {
 .p.priv_class = ,
 .p.wrapper_name   = "libx265",
 .init = libx265_encode_init,
-.init_static_data = libx265_encode_init_csp,
+.get_supported_config = libx265_get_supported_config,
 FF_CODEC_ENCODE_CB(libx265_encode_frame),
 .close= libx265_encode_close,
 .priv_data_size   = sizeof(libx265Context),
-- 
2.44.0

___
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 16/17] fftools/ffmpeg_filter: propagate codec yuv metadata to filters

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

To convert between color spaces/ranges, if needed by the codec
properties.
---
 fftools/ffmpeg_filter.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 83259416a68..a40c6f381f2 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -193,6 +193,8 @@ typedef struct OutputFilterPriv {
 int width, height;
 int sample_rate;
 AVChannelLayout ch_layout;
+enum AVColorSpace   color_space;
+enum AVColorRange   color_range;
 
 // time base in which the output is sent to our downstream
 // does not need to match the filtersink's timebase
@@ -208,6 +210,8 @@ typedef struct OutputFilterPriv {
 const int  *formats;
 const AVChannelLayout  *ch_layouts;
 const int  *sample_rates;
+const enum AVColorSpace *color_spaces;
+const enum AVColorRange *color_ranges;
 
 AVRational  enc_timebase;
 // offset for output timestamps, in AV_TIME_BASE_Q
@@ -379,6 +383,12 @@ DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, 
format, formats,
 DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0,
   "%d", )
 
+DEF_CHOOSE_FORMAT(color_spaces, enum AVColorSpace, color_space, color_spaces,
+  AVCOL_SPC_UNSPECIFIED, "%s", av_color_space_name);
+
+DEF_CHOOSE_FORMAT(color_ranges, enum AVColorRange, color_range, color_ranges,
+  AVCOL_RANGE_UNSPECIFIED, "%s", av_color_range_name);
+
 static void choose_channel_layouts(OutputFilterPriv *ofp, AVBPrint *bprint)
 {
 if (av_channel_layout_check(>ch_layout)) {
@@ -607,6 +617,8 @@ static OutputFilter *ofilter_alloc(FilterGraph *fg)
 ofilter->graph= fg;
 ofp->format   = -1;
 ofp->index= fg->nb_outputs - 1;
+ofp->color_space  = AVCOL_SPC_UNSPECIFIED;
+ofp->color_range  = AVCOL_RANGE_UNSPECIFIED;
 
 return ofilter;
 }
@@ -789,6 +801,24 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
 ofp->formats = mjpeg_formats;
 }
 }
+if (ost->enc_ctx->colorspace != AVCOL_SPC_UNSPECIFIED) {
+ofp->color_space = ost->enc_ctx->colorspace;
+} else {
+ret = avcodec_get_supported_config(ost->enc_ctx, NULL,
+   AV_CODEC_CONFIG_COLOR_SPACE, 0,
+   (const void **) 
>color_spaces);
+if (ret < 0)
+return ret;
+}
+if (ost->enc_ctx->color_range != AVCOL_RANGE_UNSPECIFIED) {
+ofp->color_range = ost->enc_ctx->color_range;
+} else {
+ret = avcodec_get_supported_config(ost->enc_ctx, NULL,
+   AV_CODEC_CONFIG_COLOR_RANGE, 0,
+   (const void **) 
>color_ranges);
+if (ret < 0)
+return ret;
+}
 
 fgp->disable_conversions |= ost->keep_pix_fmt;
 
@@ -1347,6 +1377,8 @@ static int configure_output_video_filter(FilterGraph *fg, 
AVFilterGraph *graph,
 av_assert0(!ost->keep_pix_fmt || (!ofp->format && !ofp->formats));
 av_bprint_init(, 0, AV_BPRINT_SIZE_UNLIMITED);
 choose_pix_fmts(ofp, );
+choose_color_spaces(ofp, );
+choose_color_ranges(ofp, );
 if (!av_bprint_is_complete())
 return AVERROR(ENOMEM);
 if (bprint.len) {
@@ -1777,6 +1809,8 @@ static int configure_filtergraph(FilterGraph *fg, 
FilterGraphThread *fgt)
 
 ofp->width  = av_buffersink_get_w(sink);
 ofp->height = av_buffersink_get_h(sink);
+ofp->color_space = av_buffersink_get_colorspace(sink);
+ofp->color_range = av_buffersink_get_color_range(sink);
 
 // If the timing parameters are not locked yet, get the tentative 
values
 // here but don't lock them. They will only be used if no output frames
-- 
2.44.0

___
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 14/17] fftools/ffmpeg_filter: simplify choose_pix_fmts

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

The only meaningful difference between choose_pix_fmts and the default
code was the inclusion of an extra branch for `keep_pix_fmt` being true.

However, in this case, we either:
1. Force the specific `ofp->format` that we inherited from
   ofilter_bind_ost, or if no format was set:
2. Print an empty format list

Both of these goals can be accomplished by simply moving the decision
logic to ofilter_bind_ost, to avoid setting any format list when
keep_pix_fmt is enabled. This is arguably cleaner as it moves format
selection logic to a single function. In the case of branch 1, nothing
else needs to be done as we already force the format provided in
ofp->format, if any is set. Add an assertion to verify this assumption
just in case.

(Side note: The "choose_*" family of functions are arguably misnomers,
as they should really be called "print_*" - their current behavior is to
print the relevant format lists to the `vf/af_format` filter arguments)
---
 fftools/ffmpeg_filter.c | 49 -
 1 file changed, 9 insertions(+), 40 deletions(-)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 9ff064f5f68..945147d6ca1 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -348,36 +348,6 @@ static void sub2video_update(InputFilterPriv *ifp, int64_t 
heartbeat_pts,
 ifp->sub2video.initialize = 0;
 }
 
-/* *dst may return be set to NULL (no pixel format found), a static string or a
- * string backed by the bprint. Nothing has been written to the AVBPrint in 
case
- * NULL is returned. The AVBPrint provided should be clean. */
-static int choose_pix_fmts(OutputFilter *ofilter, AVBPrint *bprint,
-   const char **dst)
-{
-OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
-OutputStream *ost = ofilter->ost;
-
-*dst = NULL;
-
-if (ost->keep_pix_fmt || ofp->format != AV_PIX_FMT_NONE) {
-*dst = ofp->format == AV_PIX_FMT_NONE ? NULL :
-   av_get_pix_fmt_name(ofp->format);
-} else if (ofp->formats) {
-const enum AVPixelFormat *p = ofp->formats;
-
-for (; *p != AV_PIX_FMT_NONE; p++) {
-const char *name = av_get_pix_fmt_name(*p);
-av_bprintf(bprint, "%s%c", name, p[1] == AV_PIX_FMT_NONE ? '\0' : 
'|');
-}
-if (!av_bprint_is_complete(bprint))
-return AVERROR(ENOMEM);
-
-*dst = bprint->str;
-}
-
-return 0;
-}
-
 /* Define a function for appending a list of allowed formats
  * to an AVBPrint. If nonempty, the list will have a header. */
 #define DEF_CHOOSE_FORMAT(name, type, var, supported_list, none, 
printf_format, get_name) \
@@ -400,8 +370,8 @@ static void choose_ ## name (OutputFilterPriv *ofp, 
AVBPrint *bprint)  \
 av_bprint_chars(bprint, ':', 1);   
\
 }
 
-//DEF_CHOOSE_FORMAT(pix_fmts, enum AVPixelFormat, format, formats, 
AV_PIX_FMT_NONE,
-//  av_get_pix_fmt_name)
+DEF_CHOOSE_FORMAT(pix_fmts, enum AVPixelFormat, format, formats,
+  AV_PIX_FMT_NONE, "%s", av_get_pix_fmt_name)
 
 DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats,
   AV_SAMPLE_FMT_NONE, "%s", av_get_sample_fmt_name)
@@ -791,7 +761,7 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
 ofp->height = ost->enc_ctx->height;
 if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
 ofp->format = ost->enc_ctx->pix_fmt;
-} else {
+} else if (!ost->keep_pix_fmt) {
 ofp->formats = c->pix_fmts;
 
 // MJPEG encoder exports a full list of supported pixel formats,
@@ -1307,7 +1277,6 @@ static int configure_output_video_filter(FilterGraph *fg, 
AVFilterGraph *graph,
 AVBPrint bprint;
 int pad_idx = out->pad_idx;
 int ret;
-const char *pix_fmts;
 char name[255];
 
 snprintf(name, sizeof(name), "out_%d_%d", ost->file->index, ost->index);
@@ -1342,17 +1311,17 @@ static int configure_output_video_filter(FilterGraph 
*fg, AVFilterGraph *graph,
 pad_idx = 0;
 }
 
+av_assert0(!ost->keep_pix_fmt || (!ofp->format && !ofp->formats));
 av_bprint_init(, 0, AV_BPRINT_SIZE_UNLIMITED);
-ret = choose_pix_fmts(ofilter, , _fmts);
-if (ret < 0)
-return ret;
-
-if (pix_fmts) {
+choose_pix_fmts(ofp, );
+if (!av_bprint_is_complete())
+return AVERROR(ENOMEM);
+if (bprint.len) {
 AVFilterContext *filter;
 
 ret = avfilter_graph_create_filter(,
avfilter_get_by_name("format"),
-   "format", pix_fmts, NULL, graph);
+   "format", bprint.str, NULL, graph);
 av_bprint_finalize(, NULL);
 if (ret < 0)
 return ret;
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org

[FFmpeg-devel] [PATCH v2 17/17] fftools/ffmpeg_filter: remove YUVJ hack

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

This is no longer needed, since we now correctly negotiate the required
range from the mjpeg encoder via avcodec_get_supported_config().
---
 fftools/ffmpeg_filter.c | 15 ---
 1 file changed, 15 deletions(-)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index a40c6f381f2..461f2b86065 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -785,21 +785,6 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
(const void **) >formats);
 if (ret < 0)
 return ret;
-
-// MJPEG encoder exports a full list of supported pixel formats,
-// but the full-range ones are experimental-only.
-// Restrict the auto-conversion list unless -strict experimental
-// has been specified.
-if (!strcmp(c->name, "mjpeg")) {
-// FIXME: YUV420P etc. are actually supported with full color 
range,
-// yet the latter information isn't available here.
-static const enum AVPixelFormat mjpeg_formats[] =
-{ AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, 
AV_PIX_FMT_YUVJ444P,
-  AV_PIX_FMT_NONE };
-
-if (ost->enc_ctx->strict_std_compliance > 
FF_COMPLIANCE_UNOFFICIAL)
-ofp->formats = mjpeg_formats;
-}
 }
 if (ost->enc_ctx->colorspace != AVCOL_SPC_UNSPECIFIED) {
 ofp->color_space = ost->enc_ctx->colorspace;
-- 
2.44.0

___
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 13/17] fftools/ffmpeg_filter: set strict_std_compliance

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

For avcodec_get_supported_config(), which requires this value be set on
the actual ost->enc_ctx being queried.
---
 fftools/ffmpeg_filter.c | 16 ++--
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index ac04841a16c..9ff064f5f68 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -770,6 +770,7 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
 FilterGraph  *fg = ofilter->graph;
 FilterGraphPriv *fgp = fgp_from_fg(fg);
 const AVCodec *c = ost->enc_ctx->codec;
+const AVDictionaryEntry *strict = av_dict_get(ost->encoder_opts, "strict", 
NULL, 0);
 int ret;
 
 av_assert0(!ofilter->ost);
@@ -780,6 +781,10 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
 ofp->ts_offset = of->start_time == AV_NOPTS_VALUE ? 0 : of->start_time;
 ofp->enc_timebase = ost->enc_timebase;
 
+/* Ensure this is up-to-date for avcodefc_get_supported_config() */
+if (strict)
+av_opt_set(ost->enc_ctx, strict->key, strict->value, 0);
+
 switch (ost->enc_ctx->codec_type) {
 case AVMEDIA_TYPE_VIDEO:
 ofp->width  = ost->enc_ctx->width;
@@ -800,16 +805,7 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
 { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, 
AV_PIX_FMT_YUVJ444P,
   AV_PIX_FMT_NONE };
 
-const AVDictionaryEntry *strict = 
av_dict_get(ost->encoder_opts, "strict", NULL, 0);
-int strict_val = ost->enc_ctx->strict_std_compliance;
-
-if (strict) {
-const AVOption *o = av_opt_find(ost->enc_ctx, strict->key, 
NULL, 0, 0);
-av_assert0(o);
-av_opt_eval_int(ost->enc_ctx, o, strict->value, 
_val);
-}
-
-if (strict_val > FF_COMPLIANCE_UNOFFICIAL)
+if (ost->enc_ctx->strict_std_compliance > 
FF_COMPLIANCE_UNOFFICIAL)
 ofp->formats = mjpeg_formats;
 }
 }
-- 
2.44.0

___
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 15/17] fftools/ffmpeg_filter: switch to avcodec_get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

I preserved the no-op condition on `!ch_layouts`, even though I suspect
it's not actually needed.
---
 fftools/ffmpeg_filter.c | 59 -
 1 file changed, 46 insertions(+), 13 deletions(-)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 945147d6ca1..83259416a68 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -694,7 +694,7 @@ static int ifilter_bind_dec(InputFilterPriv *ifp, Decoder 
*dec)
 
 static int set_channel_layout(OutputFilterPriv *f, OutputStream *ost)
 {
-const AVCodec *c = ost->enc_ctx->codec;
+const AVChannelLayout *ch_layouts;
 int i, err;
 
 if (ost->enc_ctx->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
@@ -705,8 +705,14 @@ static int set_channel_layout(OutputFilterPriv *f, 
OutputStream *ost)
 return 0;
 }
 
+err = avcodec_get_supported_config(ost->enc_ctx, NULL,
+   AV_CODEC_CONFIG_CHANNEL_LAYOUT, 0,
+   (const void **) _layouts);
+if (err < 0)
+return err;
+
 /* Requested layout is of order UNSPEC */
-if (!c->ch_layouts) {
+if (!ch_layouts) {
 /* Use the default native layout for the requested amount of channels 
when the
encoder doesn't have a list of supported layouts */
 av_channel_layout_default(>ch_layout, 
ost->enc_ctx->ch_layout.nb_channels);
@@ -714,13 +720,13 @@ static int set_channel_layout(OutputFilterPriv *f, 
OutputStream *ost)
 }
 /* Encoder has a list of supported layouts. Pick the first layout in it 
with the
same amount of channels as the requested layout */
-for (i = 0; c->ch_layouts[i].nb_channels; i++) {
-if (c->ch_layouts[i].nb_channels == 
ost->enc_ctx->ch_layout.nb_channels)
+for (i = 0; ch_layouts[i].nb_channels; i++) {
+if (ch_layouts[i].nb_channels == ost->enc_ctx->ch_layout.nb_channels)
 break;
 }
-if (c->ch_layouts[i].nb_channels) {
+if (ch_layouts[i].nb_channels) {
 /* Use it if one is found */
-err = av_channel_layout_copy(>ch_layout, >ch_layouts[i]);
+err = av_channel_layout_copy(>ch_layout, _layouts[i]);
 if (err < 0)
 return err;
 return 0;
@@ -762,7 +768,11 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
 if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
 ofp->format = ost->enc_ctx->pix_fmt;
 } else if (!ost->keep_pix_fmt) {
-ofp->formats = c->pix_fmts;
+ret = avcodec_get_supported_config(ost->enc_ctx, NULL,
+   AV_CODEC_CONFIG_PIX_FORMAT, 0,
+   (const void **) >formats);
+if (ret < 0)
+return ret;
 
 // MJPEG encoder exports a full list of supported pixel formats,
 // but the full-range ones are experimental-only.
@@ -788,8 +798,16 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
 
 ofp->fps.framerate   = ost->frame_rate;
 ofp->fps.framerate_max   = ost->max_frame_rate;
-ofp->fps.framerate_supported = ost->force_fps ?
-   NULL : c->supported_framerates;
+
+if (ost->force_fps) {
+ofp->fps.framerate_supported = NULL;
+} else {
+ret = avcodec_get_supported_config(ost->enc_ctx, NULL,
+   AV_CODEC_CONFIG_FRAME_RATE, 0,
+   (const void **) 
>fps.framerate_supported);
+if (ret < 0)
+return ret;
+}
 
 // reduce frame rate for mpeg4 to be within the spec limits
 if (c->id == AV_CODEC_ID_MPEG4)
@@ -802,19 +820,34 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
 if (ost->enc_ctx->sample_fmt != AV_SAMPLE_FMT_NONE) {
 ofp->format = ost->enc_ctx->sample_fmt;
 } else {
-ofp->formats = c->sample_fmts;
+ret = avcodec_get_supported_config(ost->enc_ctx, NULL,
+   AV_CODEC_CONFIG_SAMPLE_FORMAT, 
0,
+   (const void **) >formats);
+if (ret < 0)
+return ret;
 }
 if (ost->enc_ctx->sample_rate) {
 ofp->sample_rate = ost->enc_ctx->sample_rate;
 } else {
-ofp->sample_rates = c->supported_samplerates;
+ret = avcodec_get_supported_config(ost->enc_ctx, NULL,
+   AV_CODEC_CONFIG_SAMPLE_RATE, 0,
+   (const void **) 
>sample_rates);
+if (ret < 0)
+return ret;
 }
 if (ost->enc_ctx->ch_layout.nb_channels) {
 int ret = set_channel_layout(ofp, ost);
 if (ret < 

[FFmpeg-devel] [PATCH v2 12/17] fftools/ffmpeg_mux_init: switch to avcodec_get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

---
 fftools/ffmpeg_mux_init.c | 22 +-
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
index d3d7d022ff6..4f8c81102d3 100644
--- a/fftools/ffmpeg_mux_init.c
+++ b/fftools/ffmpeg_mux_init.c
@@ -511,13 +511,19 @@ static int fmt_in_list(const int *formats, int format)
 }
 
 static enum AVPixelFormat
-choose_pixel_fmt(const AVCodec *codec, enum AVPixelFormat target)
+choose_pixel_fmt(const AVCodecContext *avctx, enum AVPixelFormat target)
 {
-const enum AVPixelFormat *p = codec->pix_fmts;
+const enum AVPixelFormat *p;
 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(target);
 //FIXME: This should check for AV_PIX_FMT_FLAG_ALPHA after PAL8 pixel 
format without alpha is implemented
 int has_alpha = desc ? desc->nb_components % 2 == 0 : 0;
 enum AVPixelFormat best= AV_PIX_FMT_NONE;
+int ret;
+
+ret = avcodec_get_supported_config(avctx, NULL, AV_CODEC_CONFIG_PIX_FORMAT,
+   0, (const void **) );
+if (ret < 0)
+return AV_PIX_FMT_NONE;
 
 for (; *p != AV_PIX_FMT_NONE; p++) {
 best = av_find_best_pix_fmt_of_2(best, *p, target, has_alpha, NULL);
@@ -529,7 +535,7 @@ choose_pixel_fmt(const AVCodec *codec, enum AVPixelFormat 
target)
 av_log(NULL, AV_LOG_WARNING,
"Incompatible pixel format '%s' for codec '%s', 
auto-selecting format '%s'\n",
av_get_pix_fmt_name(target),
-   codec->name,
+   avctx->codec->name,
av_get_pix_fmt_name(best));
 return best;
 }
@@ -538,8 +544,9 @@ choose_pixel_fmt(const AVCodec *codec, enum AVPixelFormat 
target)
 
 static enum AVPixelFormat pix_fmt_parse(OutputStream *ost, const char *name)
 {
-const enum AVPixelFormat *fmts = ost->enc_ctx->codec->pix_fmts;
+const enum AVPixelFormat *fmts;
 enum AVPixelFormat fmt;
+int ret;
 
 fmt = av_get_pix_fmt(name);
 if (fmt == AV_PIX_FMT_NONE) {
@@ -547,6 +554,11 @@ static enum AVPixelFormat pix_fmt_parse(OutputStream *ost, 
const char *name)
 return AV_PIX_FMT_NONE;
 }
 
+ret = avcodec_get_supported_config(ost->enc_ctx, NULL, 
AV_CODEC_CONFIG_PIX_FORMAT,
+   0, (const void **) );
+if (ret < 0)
+return AV_PIX_FMT_NONE;
+
 /* when the user specified-format is an alias for an endianness-specific
  * one (e.g. rgb48 -> rgb48be/le), it gets translated into the native
  * endianness by av_get_pix_fmt();
@@ -574,7 +586,7 @@ static enum AVPixelFormat pix_fmt_parse(OutputStream *ost, 
const char *name)
 }
 
 if (fmts && !fmt_in_list(fmts, fmt))
-fmt = choose_pixel_fmt(ost->enc_ctx->codec, fmt);
+fmt = choose_pixel_fmt(ost->enc_ctx, fmt);
 
 return fmt;
 }
-- 
2.44.0

___
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 04/17] avcodec/allcodecs: add backcompat for new config API

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

In order to avoid breaking older clients not yet using the new API, we
need to add backwards compatibility for codecs which have switched from
init_static() to get_supported_config().

This function can be removed entirely once the deprecated static fields
are removed.
---
 libavcodec/allcodecs.c | 37 +++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index f4705651fb8..a9f1797930a 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -916,8 +916,41 @@ static AVOnce av_codec_static_init = AV_ONCE_INIT;
 static void av_codec_init_static(void)
 {
 for (int i = 0; codec_list[i]; i++) {
-if (codec_list[i]->init_static_data)
-codec_list[i]->init_static_data((FFCodec*)codec_list[i]);
+const FFCodec *codec = codec_list[i];
+if (codec->init_static_data) {
+codec->init_static_data((FFCodec*) codec);
+continue;
+}
+
+/* Backward compatibility with deprecated public fields */
+if (!codec->get_supported_config)
+continue;
+
+FF_DISABLE_DEPRECATION_WARNINGS
+switch (codec->p.type) {
+case AVMEDIA_TYPE_VIDEO:
+codec->get_supported_config(NULL, >p,
+AV_CODEC_CONFIG_PIX_FORMAT, 0,
+(const void **) >p.pix_fmts);
+codec->get_supported_config(NULL, >p,
+AV_CODEC_CONFIG_FRAME_RATE, 0,
+(const void **) 
>p.supported_framerates);
+break;
+case AVMEDIA_TYPE_AUDIO:
+codec->get_supported_config(NULL, >p,
+AV_CODEC_CONFIG_SAMPLE_FORMAT, 0,
+(const void **) >p.sample_fmts);
+codec->get_supported_config(NULL, >p,
+AV_CODEC_CONFIG_SAMPLE_RATE, 0,
+(const void **) 
>p.supported_samplerates);
+codec->get_supported_config(NULL, >p,
+AV_CODEC_CONFIG_CHANNEL_LAYOUT, 0,
+(const void **) >p.ch_layouts);
+break;
+default:
+break;
+}
+FF_ENABLE_DEPRECATION_WARNINGS
 }
 }
 
-- 
2.44.0

___
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 03/17] avcodec/encode: switch to avcodec_get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

---
 libavcodec/encode.c | 88 -
 1 file changed, 55 insertions(+), 33 deletions(-)

diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index 34658d13d0c..d0e79379048 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -563,7 +563,8 @@ static int encode_preinit_video(AVCodecContext *avctx)
 {
 const AVCodec *c = avctx->codec;
 const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(avctx->pix_fmt);
-int i;
+const enum AVPixelFormat *pix_fmts;
+int ret, i;
 
 if (!av_get_pix_fmt_name(avctx->pix_fmt)) {
 av_log(avctx, AV_LOG_ERROR, "Invalid video pixel format: %d\n",
@@ -571,28 +572,33 @@ static int encode_preinit_video(AVCodecContext *avctx)
 return AVERROR(EINVAL);
 }
 
-if (c->pix_fmts) {
-for (i = 0; c->pix_fmts[i] != AV_PIX_FMT_NONE; i++)
-if (avctx->pix_fmt == c->pix_fmts[i])
+ret = avcodec_get_supported_config(avctx, NULL, AV_CODEC_CONFIG_PIX_FORMAT,
+   0, (const void **) _fmts);
+if (ret < 0)
+return ret;
+
+if (pix_fmts) {
+for (i = 0; pix_fmts[i] != AV_PIX_FMT_NONE; i++)
+if (avctx->pix_fmt == pix_fmts[i])
 break;
-if (c->pix_fmts[i] == AV_PIX_FMT_NONE) {
+if (pix_fmts[i] == AV_PIX_FMT_NONE) {
 av_log(avctx, AV_LOG_ERROR,
"Specified pixel format %s is not supported by the %s 
encoder.\n",
av_get_pix_fmt_name(avctx->pix_fmt), c->name);
 
 av_log(avctx, AV_LOG_ERROR, "Supported pixel formats:\n");
-for (int p = 0; c->pix_fmts[p] != AV_PIX_FMT_NONE; p++) {
+for (int p = 0; pix_fmts[p] != AV_PIX_FMT_NONE; p++) {
 av_log(avctx, AV_LOG_ERROR, "  %s\n",
-   av_get_pix_fmt_name(c->pix_fmts[p]));
+   av_get_pix_fmt_name(pix_fmts[p]));
 }
 
 return AVERROR(EINVAL);
 }
-if (c->pix_fmts[i] == AV_PIX_FMT_YUVJ420P ||
-c->pix_fmts[i] == AV_PIX_FMT_YUVJ411P ||
-c->pix_fmts[i] == AV_PIX_FMT_YUVJ422P ||
-c->pix_fmts[i] == AV_PIX_FMT_YUVJ440P ||
-c->pix_fmts[i] == AV_PIX_FMT_YUVJ444P)
+if (pix_fmts[i] == AV_PIX_FMT_YUVJ420P ||
+pix_fmts[i] == AV_PIX_FMT_YUVJ411P ||
+pix_fmts[i] == AV_PIX_FMT_YUVJ422P ||
+pix_fmts[i] == AV_PIX_FMT_YUVJ440P ||
+pix_fmts[i] == AV_PIX_FMT_YUVJ444P)
 avctx->color_range = AVCOL_RANGE_JPEG;
 }
 
@@ -646,7 +652,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
 static int encode_preinit_audio(AVCodecContext *avctx)
 {
 const AVCodec *c = avctx->codec;
-int i;
+const enum AVSampleFormat *sample_fmts;
+const int *supported_samplerates;
+const AVChannelLayout *ch_layouts;
+int ret, i;
 
 if (!av_get_sample_fmt_name(avctx->sample_fmt)) {
 av_log(avctx, AV_LOG_ERROR, "Invalid audio sample format: %d\n",
@@ -659,53 +668,66 @@ static int encode_preinit_audio(AVCodecContext *avctx)
 return AVERROR(EINVAL);
 }
 
-if (c->sample_fmts) {
-for (i = 0; c->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
-if (avctx->sample_fmt == c->sample_fmts[i])
+ret = avcodec_get_supported_config(avctx, NULL, 
AV_CODEC_CONFIG_SAMPLE_FORMAT,
+   0, (const void **) _fmts);
+if (ret < 0)
+return ret;
+if (sample_fmts) {
+for (i = 0; sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
+if (avctx->sample_fmt == sample_fmts[i])
 break;
 if (avctx->ch_layout.nb_channels == 1 &&
 av_get_planar_sample_fmt(avctx->sample_fmt) ==
-av_get_planar_sample_fmt(c->sample_fmts[i])) {
-avctx->sample_fmt = c->sample_fmts[i];
+av_get_planar_sample_fmt(sample_fmts[i])) {
+avctx->sample_fmt = sample_fmts[i];
 break;
 }
 }
-if (c->sample_fmts[i] == AV_SAMPLE_FMT_NONE) {
+if (sample_fmts[i] == AV_SAMPLE_FMT_NONE) {
 av_log(avctx, AV_LOG_ERROR,
"Specified sample format %s is not supported by the %s 
encoder\n",
av_get_sample_fmt_name(avctx->sample_fmt), c->name);
 
 av_log(avctx, AV_LOG_ERROR, "Supported sample formats:\n");
-for (int p = 0; c->sample_fmts[p] != AV_SAMPLE_FMT_NONE; p++) {
+for (int p = 0; sample_fmts[p] != AV_SAMPLE_FMT_NONE; p++) {
 av_log(avctx, AV_LOG_ERROR, "  %s\n",
-   av_get_sample_fmt_name(c->sample_fmts[p]));
+   av_get_sample_fmt_name(sample_fmts[p]));
 }
 
 return AVERROR(EINVAL);
 }
 }
-if (c->supported_samplerates) {
-for (i = 0; c->supported_samplerates[i] != 0; i++)
-if 

[FFmpeg-devel] [PATCH v2 02/17] avcodec: add avcodec_get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

This replaces the myriad of existing lists in AVCodec by a unified API
call, allowing us to (ultimately) trim down the sizeof(AVCodec) quite
substantially, while also making this more trivially extensible.

In addition to the already covered lists, add two new entries for color
space and color range, mirroring the newly added negotiable fields in
libavfilter.

I decided to drop the explicit length field from the API proposed by
Andreas Rheinhardt, because having it in place ended up complicating
both the codec side and the client side implementations, while also
being strictly less flexible (it's trivial to recover a length given
a terminator, but requires allocation to add a terminator given
a length). Using a terminator also presents less of a porting challenge
for existing users of the current API.

Once the deprecation period passes for the existing public fields, the
rough plan is to move the commonly used fields (such as
pix_fmt/sample_fmt) into FFCodec, possibly as a union of audio and video
configuration types, and then implement the rarely used fields with
custom callbacks.
---
 doc/APIchanges  |  5 +++
 libavcodec/avcodec.c| 75 +
 libavcodec/avcodec.h| 27 +
 libavcodec/codec.h  | 19 --
 libavcodec/codec_internal.h | 24 
 libavcodec/version.h|  4 +-
 6 files changed, 148 insertions(+), 6 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 0a39b6d7ab8..fdeae67159d 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,11 @@ The last version increases of all libraries were on 2024-03-07
 
 API changes, most recent first:
 
+2024-04-xx - xx - lavc 59.6.100 - avcodec.h
+  Add avcodec_get_supported_config() and enum AVCodecConfig; deprecate
+  AVCodec.pix_fmts, AVCodec.sample_fmts, AVCodec.supported_framerates,
+  AVCodec.supported_samplerates and AVCodec.ch_layouts.
+
 2024-04-03 - xx - lavu 59.13.100 - pixfmt.h
   Add AVCOL_SPC_IPT_C2, AVCOL_SPC_YCGCO_RE and AVCOL_SPC_YCGCO_RO
   to map new matrix coefficients defined by H.273 v3.
diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
index 525fe516bd2..96728546d6c 100644
--- a/libavcodec/avcodec.c
+++ b/libavcodec/avcodec.c
@@ -700,3 +700,78 @@ int attribute_align_arg 
avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr
 return ff_decode_receive_frame(avctx, frame);
 return ff_encode_receive_frame(avctx, frame);
 }
+
+#define WRAP_CONFIG(allowed_type, field)\
+do {\
+if (codec->type != (allowed_type))  \
+return AVERROR(EINVAL); \
+*out_configs = (field); \
+return 0;   \
+} while (0)
+
+static const enum AVColorRange color_range_jpeg[] = {
+AVCOL_RANGE_JPEG, AVCOL_RANGE_UNSPECIFIED
+};
+
+static const enum AVColorRange color_range_mpeg[] = {
+AVCOL_RANGE_MPEG, AVCOL_RANGE_UNSPECIFIED
+};
+
+static const enum AVColorRange color_range_all[] = {
+AVCOL_RANGE_MPEG, AVCOL_RANGE_JPEG, AVCOL_RANGE_UNSPECIFIED
+};
+
+static const enum AVColorRange *color_range_table[] = {
+[AVCOL_RANGE_MPEG] = color_range_mpeg,
+[AVCOL_RANGE_JPEG] = color_range_jpeg,
+[AVCOL_RANGE_MPEG | AVCOL_RANGE_JPEG] = color_range_all,
+};
+
+int ff_default_get_supported_config(const AVCodecContext *avctx,
+const AVCodec *codec,
+enum AVCodecConfig config,
+unsigned flags,
+const void **out_configs)
+{
+switch (config) {
+FF_DISABLE_DEPRECATION_WARNINGS
+case AV_CODEC_CONFIG_PIX_FORMAT:
+WRAP_CONFIG(AVMEDIA_TYPE_VIDEO, codec->pix_fmts);
+case AV_CODEC_CONFIG_FRAME_RATE:
+WRAP_CONFIG(AVMEDIA_TYPE_VIDEO, codec->supported_framerates);
+case AV_CODEC_CONFIG_SAMPLE_RATE:
+WRAP_CONFIG(AVMEDIA_TYPE_AUDIO, codec->supported_samplerates);
+case AV_CODEC_CONFIG_SAMPLE_FORMAT:
+WRAP_CONFIG(AVMEDIA_TYPE_AUDIO, codec->sample_fmts);
+case AV_CODEC_CONFIG_CHANNEL_LAYOUT:
+WRAP_CONFIG(AVMEDIA_TYPE_AUDIO, codec->ch_layouts);
+FF_ENABLE_DEPRECATION_WARNINGS
+
+case AV_CODEC_CONFIG_COLOR_RANGE:
+if (codec->type != AVMEDIA_TYPE_VIDEO)
+return AVERROR(EINVAL);
+*out_configs = color_range_table[ffcodec(codec)->color_ranges];
+return 0;
+
+case AV_CODEC_CONFIG_COLOR_SPACE:
+*out_configs = NULL;
+return 0;
+default:
+return AVERROR(EINVAL);
+}
+}
+
+int avcodec_get_supported_config(const AVCodecContext *avctx, const AVCodec 
*codec,
+ enum AVCodecConfig config, unsigned flags,
+ const void **out)
+{
+const FFCodec *codec2;
+if (!codec)
+codec = avctx->codec;
+codec2 = ffcodec(codec);
+if 

[FFmpeg-devel] [PATCH v2 01/17] avcodec/internal: add FFCodec.color_ranges

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

I went through all codecs and put them into five basic categories:

1. JPEG range only
2. MPEG range only
3. Explicitly tagged
4. Broken (codec supports both but encoder ignores tags)
5. N/A (headerless or pseudo-formats)

Filters in category 5 remain untouched. The rest gain an explicit
assignment of their supported color ranges, with codecs in category
4 being set to MPEG-only for safety.

It might be considered redundant to distinguish between 0 (category 5)
and MPEG+JPEG (category 3), but in doing so we effectively communicate
that we can guarantee that these tags will be encoded, which is distinct
from the situation where there are some codecs that simply don't have
tagging or implied semantics (e.g. rawvideo).

A full list of codecs follows:

JPEG range only:
 - amv
 - roqvideo

MPEG range only:
 - asv1, asv2
 - avui
 - cfhd
 - cljr
 - dnxhd
 - dvvideo
 - ffv1
 - flv
 - h261, h263, h263p
 - {h263,vp8}_v4l2m2m
 - huffyuv, ffvhuff
 - jpeg2000
 - libopenjpeg
 - libtheora
 - libwebp, libwebp_anim
 - libx262
 - libxavs, libxavs2
 - libxvid
 - mpeg1video, mpeg2video
 - mpeg2_qsv
 - mpeg2_vaapi
 - mpeg4, msmpeg4, msmpeg4v2, wmv1, wmv2
 - mpeg4_omx
 - rv10, rv20
 - snow
 - speedhq
 - svq1
 - tiff
 - utvideo

Explicitly tagged (MPEG/JPEG):
 - {av1,h264,hevc}_nvenc
 - {av1,h264,hevc}_vaapi
 - {av1,h264,hevc,vp8,vp9,mpeg4}_mediacodec
 - {av1,h264,hevc,vp9}_qsv
 - h264_amf
 - {h264,hevc,prores}_videotoolbox
 - libaom-av1
 - libkvazaar
 - libopenh264
 - librav1e
 - libsvtav1
 - libvpx, libvpx-vp9
 - libx264
 - libx265
 - ljpeg
 - mjpeg
 - vc2

Broken (encoder ignores tags):
 - {av1,hevc}_amf
 - {h264,hevc,mpeg4}_v4l2m2m
 - h264_omx
 - libxeve
 - magicyuv
 - {vp8,vp9,mjpeg}_vaapi

N/A:
 - ayuv, yuv4, y41p, v308, v210, v410, v408 (headerless)
 - pgmyuv (headerless)
 - prores, prores_aw, prores_ks (?)
 - rawvideo, bitpacked (headerless)
 - vnull, wrapped_avframe (pseudocodecs)
---
 libavcodec/amfenc_av1.c | 1 +
 libavcodec/amfenc_h264.c| 1 +
 libavcodec/amfenc_hevc.c| 1 +
 libavcodec/asvenc.c | 2 ++
 libavcodec/avuienc.c| 1 +
 libavcodec/cfhdenc.c| 1 +
 libavcodec/cljrenc.c| 1 +
 libavcodec/codec_internal.h | 8 +++-
 libavcodec/dnxhdenc.c   | 1 +
 libavcodec/dvenc.c  | 1 +
 libavcodec/ffv1enc.c| 1 +
 libavcodec/flvenc.c | 1 +
 libavcodec/h261enc.c| 1 +
 libavcodec/huffyuvenc.c | 2 ++
 libavcodec/ituh263enc.c | 2 ++
 libavcodec/j2kenc.c | 1 +
 libavcodec/libaomenc.c  | 1 +
 libavcodec/libkvazaar.c | 1 +
 libavcodec/libopenh264enc.c | 1 +
 libavcodec/libopenjpegenc.c | 1 +
 libavcodec/librav1e.c   | 1 +
 libavcodec/libsvtav1.c  | 1 +
 libavcodec/libtheoraenc.c   | 1 +
 libavcodec/libvpxenc.c  | 2 ++
 libavcodec/libwebpenc.c | 1 +
 libavcodec/libwebpenc_animencoder.c | 1 +
 libavcodec/libx264.c| 2 ++
 libavcodec/libx265.c| 1 +
 libavcodec/libxavs.c| 1 +
 libavcodec/libxavs2.c   | 1 +
 libavcodec/libxeve.c| 1 +
 libavcodec/libxvid.c| 1 +
 libavcodec/ljpegenc.c   | 1 +
 libavcodec/magicyuvenc.c| 1 +
 libavcodec/mediacodecenc.c  | 1 +
 libavcodec/mjpegenc.c   | 2 ++
 libavcodec/mpeg12enc.c  | 2 ++
 libavcodec/mpeg4videoenc.c  | 1 +
 libavcodec/msmpeg4enc.c | 3 +++
 libavcodec/nvenc_av1.c  | 1 +
 libavcodec/nvenc_h264.c | 1 +
 libavcodec/nvenc_hevc.c | 1 +
 libavcodec/omx.c| 2 ++
 libavcodec/qsvenc_av1.c | 1 +
 libavcodec/qsvenc_h264.c| 1 +
 libavcodec/qsvenc_hevc.c| 1 +
 libavcodec/qsvenc_jpeg.c| 1 +
 libavcodec/qsvenc_mpeg2.c   | 1 +
 libavcodec/qsvenc_vp9.c | 1 +
 libavcodec/roqvideoenc.c| 1 +
 libavcodec/rv10enc.c| 1 +
 libavcodec/rv20enc.c| 1 +
 libavcodec/snowenc.c| 1 +
 libavcodec/speedhqenc.c | 1 +
 libavcodec/svq1enc.c| 1 +
 libavcodec/tiffenc.c| 1 +
 libavcodec/utvideoenc.c | 1 +
 libavcodec/v4l2_m2m_enc.c   | 1 +
 libavcodec/vaapi_encode_av1.c   | 1 +
 libavcodec/vaapi_encode_h264.c  | 1 +
 libavcodec/vaapi_encode_h265.c  | 1 +
 libavcodec/vaapi_encode_mjpeg.c | 1 +
 libavcodec/vaapi_encode_mpeg2.c | 1 +
 libavcodec/vaapi_encode_vp8.c   | 1 +
 libavcodec/vaapi_encode_vp9.c   | 1 +
 libavcodec/vc2enc.c | 3 ++-
 libavcodec/videotoolboxenc.c| 2 ++
 libavcodec/wmv2enc.c| 1 +
 68 files changed, 86 insertions(+), 2 deletions(-)

diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index 

[FFmpeg-devel] [PATCH v2 00/17] Add avcodec_get_supported_config()

2024-04-08 Thread Niklas Haas
Changes since v1:
- Add implementation of AV_CODEC_CONFIG_COLOR_RANGE for all codecs
- Use AVBPrint instead of char desc[128] for printing channel
  descriptions
- Implement new constraints inside fftools/ffmpeg_filter.c
- Remove old YUVJ/MJPEG strictness hack

___
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 08/11] fftools/opt_common: switch to avcodec_get_supported_config()

2024-04-08 Thread Niklas Haas
On Sat, 06 Apr 2024 21:10:45 -0300 James Almer  wrote:
> On 4/6/2024 8:38 AM, Niklas Haas wrote:
> > On Fri, 05 Apr 2024 16:36:50 -0300 James Almer  wrote:
> >> On 4/5/2024 3:57 PM, Niklas Haas wrote:
> >>> From: Niklas Haas 
> >>>
> >>> While rewriting this macro, I decided to make it a bit more flexible so
> >>> it can work for all of the fields (including future fields) in a more
> >>> generic way.
> >>> ---
> >>>fftools/opt_common.c | 86 ++--
> >>>1 file changed, 43 insertions(+), 43 deletions(-)
> >>>
> >>> diff --git a/fftools/opt_common.c b/fftools/opt_common.c
> >>> index 947a226d8d1..1bf66580192 100644
> >>> --- a/fftools/opt_common.c
> >>> +++ b/fftools/opt_common.c
> >>> @@ -262,22 +262,32 @@ int show_buildconf(void *optctx, const char *opt, 
> >>> const char *arg)
> >>>return 0;
> >>>}
> >>>
> >>> -#define PRINT_CODEC_SUPPORTED(codec, field, type, list_name, term, 
> >>> get_name) \
> >>> -if (codec->field) {  
> >>> \
> >>> -const type *p = codec->field;
> >>> \
> >>> - 
> >>> \
> >>> -printf("Supported " list_name ":");  
> >>> \
> >>> -while (*p != term) { 
> >>> \
> >>> -get_name(*p);
> >>> \
> >>> -printf(" %s", name); 
> >>> \
> >>> -p++; 
> >>> \
> >>> -}
> >>> \
> >>> -printf("\n");
> >>> \
> >>> -}
> >>> \
> >>> +#define PRINT_CODEC_SUPPORTED(codec, config, type, name, elem, cond, 
> >>> fmt, ...)  \
> >>> +do { 
> >>>\
> >>> +const type *elem = NULL; 
> >>>\
> >>> +avcodec_get_supported_config(NULL, codec, config, 0, 
> >>>\
> >>> + (const void **) ); 
> >>>\
> >>> +if (elem) {  
> >>>\
> >>> +printf("Supported " name ":");   
> >>>\
> >>> +while (cond) {   
> >>>\
> >>> +printf(" " fmt, __VA_ARGS__);
> >>>\
> >>> +elem++;  
> >>>\
> >>> +}
> >>>\
> >>> +printf("\n");
> >>>\
> >>> +}
> >>>\
> >>> +} while (0)
> >>> +
> >>> +static char *get_channel_layout_desc(const AVChannelLayout *layout,
> >>> + char desc[], int desc_size)
> >>> +{
> >>> +av_channel_layout_describe(layout, desc, desc_size);
> >>> +return desc;
> >>> +}
> >>>
> >>>static void print_codec(const AVCodec *c)
> >>>{
> >>>int encoder = av_codec_is_encoder(c);
> >>> +char desc[128];
> >>>
> >>>printf("%s %s [%s]:\n", encoder ? "Encoder" : "Decoder", c->name,
> >>>   c->long_name ? c->long_name : "");
> >>> @@ -343,35 +353,19 @@ static void print_codec(const AVCodec *c)
> >>>printf("\n");
> >>>}
> >>>
> >>> -if (c->supported_framerates) {
> >>> -const AVRational *fps = c->supported_framerates;
> >>> -
> >>> -printf("Supported framerates:");
> >>> -while (fps->num) {
> >>> -printf(" %d/%d", fps->num, fps->den);
> >>> -fps++;
> >>> -}
> >>> -printf("\n");
> >>> -}
> >>> -PRINT_CODEC_SUPPORTED(c, pix_fmts, enum AVPixelFormat, "pixel 
> >>> formats",
> >>> -  AV_PIX_FMT_NONE, GET_PIX_FMT_NAME);
> >>> -PRINT_CODEC_SUPPORTED(c, supported_samplerates, int, "sample rates", 
> >>> 0,
> >>> -  GET_SAMPLE_RATE_NAME);
> >>> -PRINT_CODEC_SUPPORTED(c, sample_fmts, enum AVSampleFormat, "sample 
> >>> formats",
> >>> -  AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME);
> >>> -
> >>> -if (c->ch_layouts) {
> >>> -const AVChannelLayout *p = c->ch_layouts;
> >>> -
> >>> -printf("Supported channel layouts:");
> >>> -while (p->nb_channels) {
> >>> -char name[128];
> 

Re: [FFmpeg-devel] [PATCH 01/11] avcodec: add avcodec_get_supported_config()

2024-04-08 Thread Niklas Haas
On Sun, 07 Apr 2024 01:16:39 +0200 Michael Niedermayer  
wrote:
> On Fri, Apr 05, 2024 at 08:57:11PM +0200, Niklas Haas wrote:
> > From: Niklas Haas 
> > 
> > This replaces the myriad of existing lists in AVCodec by a unified API
> > call, allowing us to (ultimately) trim down the sizeof(AVCodec) quite
> > substantially, while also making this more trivially extensible.
> > 
> > In addition to the already covered lists, add two new entries for color
> > space and color range, mirroring the newly added negotiable fields in
> > libavfilter.
> > 
> > I decided to drop the explicit length field from the API proposed by
> > Andreas Rheinhardt, because having it in place ended up complicating
> > both the codec side and the client side implementations, while also
> > being strictly less flexible (it's trivial to recover a length given
> > a terminator, but requires allocation to add a terminator given
> > a length). Using a terminator also presents less of a porting challenge
> > for existing users of the current API.
> > 
> > Once the deprecation period passes for the existing public fields, the
> > rough plan is to move the commonly used fields (such as
> > pix_fmt/sample_fmt) into FFCodec, possibly as a union of audio and video
> > configuration types, and then implement the rarely used fields with
> > custom callbacks.
> > ---
> >  doc/APIchanges  |  5 
> >  libavcodec/avcodec.c| 51 +
> >  libavcodec/avcodec.h| 27 
> >  libavcodec/codec.h  | 19 +++---
> >  libavcodec/codec_internal.h | 21 +++
> >  libavcodec/version.h|  4 +--
> >  6 files changed, 121 insertions(+), 6 deletions(-)
> 
> If the API is changed, it should be to an API that allows externally
> maintained codecs.
> (it would result in more developers working on codecs)

The only way this could work is by making all of FFCodec public, which
is orthogonal to the API proposed here.

> 
> thx
> 
> [...]
> -- 
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
> 
> it is not once nor twice but times without number that the same ideas make
> their appearance in the world. -- Aristotle
> ___
> 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] avcodec/hevcdec: fix segfault on invalid film grain metadata

2024-04-08 Thread Niklas Haas
On Sat, 06 Apr 2024 13:14:45 +0200 Niklas Haas  wrote:
> From: Niklas Haas 
> 
> Invalid input files may contain film grain metadata which survives
> ff_h274_film_grain_params_supported() but does not pass
> av_film_grain_params_select(), leading to a SIGSEGV on hevc_frame_end().
> 
> Fix this by duplicating the av_film_grain_params_select() check at frame
> init time.
> 
> An alternative solution here would be to defer the incompatibility check
> to hevc_frame_end(), but this has the downside of allocating a film
> grain buffer even when we already know we can't apply film grain.
> 
> Fixes: https://trac.ffmpeg.org/ticket/10951
> ---
>  libavcodec/hevcdec.c | 15 ---
>  1 file changed, 8 insertions(+), 7 deletions(-)
> 
> diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
> index 727b02f0f40..d3b668af00e 100644
> --- a/libavcodec/hevcdec.c
> +++ b/libavcodec/hevcdec.c
> @@ -2893,10 +2893,15 @@ static int hevc_frame_start(HEVCContext *s)
>  !(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) &&
>  !s->avctx->hwaccel;
>  
> +ret = set_side_data(s);
> +if (ret < 0)
> +goto fail;
> +
>  if (s->ref->needs_fg &&
> -s->sei.common.film_grain_characteristics.present &&
> -
> !ff_h274_film_grain_params_supported(s->sei.common.film_grain_characteristics.model_id,
> - s->ref->frame->format)) {
> +( s->sei.common.film_grain_characteristics.present &&
> +  
> !ff_h274_film_grain_params_supported(s->sei.common.film_grain_characteristics.model_id,
> + s->ref->frame->format))
> +  || !av_film_grain_params_select(s->ref->frame)) {
>  av_log_once(s->avctx, AV_LOG_WARNING, AV_LOG_DEBUG, 
> >film_grain_warning_shown,
>  "Unsupported film grain parameters. Ignoring film 
> grain.\n");
>  s->ref->needs_fg = 0;
> @@ -2910,10 +2915,6 @@ static int hevc_frame_start(HEVCContext *s)
>  goto fail;
>  }
>  
> -ret = set_side_data(s);
> -if (ret < 0)
> -goto fail;
> -
>  s->frame->pict_type = 3 - s->sh.slice_type;
>  
>  if (!IS_IRAP(s))
> -- 
> 2.44.0
> 

Will merge very soon if there are no comments, as this fixes a bug
marked important.
___
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] [EXT] Re: Query from Reuters on XZ, open source, and Microsoft

2024-04-08 Thread Tomas Härdin
ons 2024-04-03 klockan 19:26 + skrev Satter, Raphael (Reuters) via
ffmpeg-devel:
>   *   What’s the solution here? Your talk mentioned paying
> developers, getting an SLA, or hiring them as consultants … but why
> would companies bother when they can just free ride? I asked the same
> question to CISA’s Jack Cable when he told me that  companies need to
> “contribute back and help build the sustainable open source ecosystem
> that we get so much value from.” Sure, they “need” to do it, but who
> will punish them if they don’t?

We could always start licensing the project under a less permissive
license like the GPL or the AGPL and then charge for exceptions. This
tactic goes by the name of license trolling, and was successfully used
by FFmbc for a while.

We also don't need to support every use case. I've been making the case
that we should be far more restrictive with what kind of input we
allow, especially for formats mainly used by professionals such as MXF.
Every feature carries with it a maintenance burden.

/Tomas
___
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] aarch64: ac3dsp: Simplify the end of ff_ac3_sum_square_butterfly_float_neon

2024-04-08 Thread Martin Storsjö
Before:   Cortex A53 A72 A78
ac3_sum_square_bufferfly_float_neon:  1005.7   516.5   224.5
After:
ac3_sum_square_bufferfly_float_neon:   981.7   504.5   223.2
---
 libavcodec/aarch64/ac3dsp_neon.S | 16 
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/libavcodec/aarch64/ac3dsp_neon.S b/libavcodec/aarch64/ac3dsp_neon.S
index 20beb6cc50..7e97cc39f7 100644
--- a/libavcodec/aarch64/ac3dsp_neon.S
+++ b/libavcodec/aarch64/ac3dsp_neon.S
@@ -103,17 +103,9 @@ function ff_ac3_sum_square_butterfly_float_neon, export=1
 fmlav3.4s, v17.4s, v17.4s
 subsw3, w3, #4
 b.gt1b
-faddp   v0.4s, v0.4s, v0.4s
-faddp   v0.2s, v0.2s, v0.2s
-st1 {v0.s}[0], [x0], #4
-faddp   v1.4s, v1.4s, v1.4s
-faddp   v1.2s, v1.2s, v1.2s
-st1 {v1.s}[0], [x0], #4
-faddp   v2.4s, v2.4s, v2.4s
-faddp   v2.2s, v2.2s, v2.2s
-st1 {v2.s}[0], [x0], #4
-faddp   v3.4s, v3.4s, v3.4s
-faddp   v3.2s, v3.2s, v3.2s
-st1 {v3.s}[0], [x0]
+faddp   v0.4s, v0.4s, v1.4s
+faddp   v2.4s, v2.4s, v3.4s
+faddp   v0.4s, v0.4s, v2.4s
+st1 {v0.4s}, [x0]
 ret
 endfunc
-- 
2.39.3 (Apple Git-146)

___
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 v4 0/5] avcodec/ac3: Add aarch64 NEON DSP

2024-04-08 Thread Martin Storsjö

On Sat, 6 Apr 2024, Geoff Hill wrote:


Thanks Martin for your review and testing.

Here's v4 with the following changes:

 * Use fmal in sum_square_butterfly_float loop. Faster.

 * Removed redundant loop bound zero checks in extract_exponents,
   sum_square_bufferfly_int32 and sum_square_bufferfly_float.

 * Fixed randomize_int24() to also use negative values.

 * Carry copyright from arm implementation over to aarch64. I
   did use this version as reference.

 * Fix indentation to match existing aarch64 assembly style.

Tested once again on aarch64 and x86.


Thanks, this set looked good, so I pushed it.

I amended the commits a bit, moving the added copyright line from 
checkasm/ac3dsp.c from patch 1 to 2, where that file actually gets 
extended.


Actually, after pushing, I realized another thing that can be done better 
in ff_ac3_sum_square_butterfly_float_neon - I'll send a patch for that.



On AWS Graviton2 (t4g.medium), GCC 12.3:

$ tests/checkasm/checkasm --bench --test=ac3dsp
...
NEON:
- ac3dsp.ac3_exponent_min   [OK]
- ac3dsp.ac3_extract_exponents  [OK]
- ac3dsp.float_to_fixed24   [OK]
- ac3dsp.ac3_sum_square_butterfly_int32 [OK]
- ac3dsp.ac3_sum_square_butterfly_float [OK]
checkasm: all 20 tests passed
float_to_fixed24_c: 2460.5
float_to_fixed24_neon: 561.5


FWIW, it's usually neater to include such numbers in the commit message, 
so it gets brought along into the final git history (to show the benefit 
we got from the optimization at the time), quoting only those functions 
that are added/modified in each patch. But I didn't amend in that in the 
commit messages this time, but you can keep it in mind for the future.


Anyway, thanks for the patches!

// 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 4/5] avformat/mxfdec: Check index_edit_rate

2024-04-08 Thread Tomas Härdin
tor 2024-04-04 klockan 00:51 +0200 skrev Michael Niedermayer:
> Fixes: Assertion b >=0 failed at libavutil/mathematics.c:62
> Fixes: 67811/clusterfuzz-testcase-minimized-ffmpeg_dem_MXF_fuzzer-
> 5108429687422976
> 
> Found-by: continuous fuzzing process
> https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
> Signed-off-by: Michael Niedermayer 
> ---
>  libavformat/mxfdec.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
> index 04de4c1d5e3..233d614f783 100644
> --- a/libavformat/mxfdec.c
> +++ b/libavformat/mxfdec.c
> @@ -1264,6 +1264,9 @@ static int mxf_read_index_table_segment(void
> *arg, AVIOContext *pb, int tag, int
>  case 0x3F0B:
>  segment->index_edit_rate.num = avio_rb32(pb);
>  segment->index_edit_rate.den = avio_rb32(pb);
> +    if (segment->index_edit_rate.num <= 0 ||
> +    segment->index_edit_rate.den <= 0)
> +    return AVERROR_INVALIDDATA;

mxf_compute_index_tables() has a check for index_edit_rate that you
probably want to remove as well. It was introduced in c6fff3d, but the
files it supposedly fixes aren't in FATE. We shouldn't encourage broken
muxers.

/Tomas
___
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/vvc/ps: reset sps_id_used on PS uninit

2024-04-08 Thread Frank Plowman
On 07/04/2024 15:48, James Almer wrote:
> On 4/7/2024 10:38 AM, Nuo Mi wrote:
>> On Sun, Apr 7, 2024 at 11:05 AM James Almer  wrote:
>>
>>> Signed-off-by: James Almer 
>>> ---
>>>   libavcodec/vvc/ps.c | 1 +
>>>   1 file changed, 1 insertion(+)
>>>
>>> diff --git a/libavcodec/vvc/ps.c b/libavcodec/vvc/ps.c
>>> index 3c71c34bae..83ee75fb62 100644
>>> --- a/libavcodec/vvc/ps.c
>>> +++ b/libavcodec/vvc/ps.c
>>> @@ -912,6 +912,7 @@ void ff_vvc_ps_uninit(VVCParamSets *ps)
>>>   ff_refstruct_unref(>sps_list[i]);
>>>   for (int i = 0; i < FF_ARRAY_ELEMS(ps->pps_list); i++)
>>>   ff_refstruct_unref(>pps_list[i]);
>>> +    ps->sps_id_used = 0;
>>>
>> Hi James,
>> thank you for the patch.
>>
>> Is this really necessary?
>> vvc_ps_uninit will be called by vvc_decode_free,
>> We are not supposed to use any member of VVCParamSets after
>> vvc_decode_free.
> 
> My bad, i thought it was also called on every flush() call.
> 
> Something like the following:
> 
>> diff --git a/libavcodec/vvc/dec.c b/libavcodec/vvc/dec.c
>> index eb447604fe..463536512e 100644
>> --- a/libavcodec/vvc/dec.c
>> +++ b/libavcodec/vvc/dec.c
>> @@ -963,6 +963,8 @@ static av_cold void
>> vvc_decode_flush(AVCodecContext *avctx)
>>  ff_vvc_flush_dpb(last);
>>  }
>>
>> +    s->ps->sps_id_used = 0;
>> +
>>  s->eos = 1;
>>  }
> 
> Should be done on FFCodec.flush() (like when seeking) as the previous
> state is no longer valid, right?

Yes I agree, I think this is needed.  Cases where the random access
point has no leading pictures should be covered by the existing logic as
these always fall at the start of a CVS, but I think this is needed to
cover the case in which there are leading pictures.

Thanks,
--
Frank
___
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/2] avcodec/mpegvideo_enc: Reject input incompatible with chroma subsampling

2024-04-08 Thread Anton Khirnov
Quoting Andreas Rheinhardt (2024-04-06 12:23:49)
> Fixes ticket #10952.
> 
> Discovered by: Zeng Yunxiang
> Signed-off-by: Andreas Rheinhardt 
> ---
> I am pretty sure that a lot of other encoders don't handle this well
> either. Maybe we should handle this more generically in
> ff_encode_preinit?

We should.

-- 
Anton Khirnov
___
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".