[FFmpeg-devel] [PATCH v2] lavu/opt: Discuss AV_OPT_FLAG_RUNTIME_PARAM more explicitly

2024-06-06 Thread Andrew Sayers
After a struct is initialized, only options with the
AV_OPT_FLAG_RUNTIME_PARAM flag can be modified.

Make that clearer, for the sake of readers who would otherwise
assume all options can be modified at any time.
---
 libavutil/opt.h | 26 +-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/libavutil/opt.h b/libavutil/opt.h
index 07e27a9208..d23c10bcf5 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -53,6 +53,9 @@
  * question is allowed to access the field. This allows us to extend the
  * semantics of those fields without breaking API compatibility.
  *
+ * Note: only options with the AV_OPT_FLAG_RUNTIME_PARAM flag can be
+ * modified after the struct is initialized.
+ *
  * @section avoptions_scope Scope of AVOptions
  *
  * AVOptions is designed to support any set of multimedia configuration options
@@ -300,7 +303,7 @@ enum AVOptionType{
 #define AV_OPT_FLAG_BSF_PARAM   (1 << 8)
 
 /**
- * A generic parameter which can be set by the user at runtime.
+ * A generic parameter which can be set by the user after initialization.
  */
 #define AV_OPT_FLAG_RUNTIME_PARAM   (1 << 15)
 /**
@@ -483,6 +486,9 @@ typedef struct AVOptionRanges {
 /**
  * Set the values of all AVOption fields to their default values.
  *
+ * Note: after a struct is initialized, only options with the
+ * AV_OPT_FLAG_RUNTIME_PARAM flag can be modified.
+ *
  * @param s an AVOption-enabled struct (its first member must be a pointer to 
AVClass)
  */
 void av_opt_set_defaults(void *s);
@@ -492,6 +498,9 @@ void av_opt_set_defaults(void *s);
  * AVOption fields for which (opt->flags & mask) == flags will have their
  * default applied to s.
  *
+ * Note: after a struct is initialized, only options with the
+ * AV_OPT_FLAG_RUNTIME_PARAM flag can be modified.
+ *
  * @param s an AVOption-enabled struct (its first member must be a pointer to 
AVClass)
  * @param mask combination of AV_OPT_FLAG_*
  * @param flags combination of AV_OPT_FLAG_*
@@ -661,6 +670,9 @@ enum {
  * key. ctx must be an AVClass context, storing is done using
  * AVOptions.
  *
+ * Note: after a struct is initialized, only options with the
+ * AV_OPT_FLAG_RUNTIME_PARAM flag can be modified.
+ *
  * @param opts options string to parse, may be NULL
  * @param key_val_sep a 0-terminated list of characters used to
  * separate key from value
@@ -679,6 +691,9 @@ int av_set_options_string(void *ctx, const char *opts,
  * Parse the key-value pairs list in opts. For each key=value pair found,
  * set the value of the corresponding option in ctx.
  *
+ * Note: after a struct is initialized, only options with the
+ * AV_OPT_FLAG_RUNTIME_PARAM flag can be modified.
+ *
  * @param ctx  the AVClass object to set options on
  * @param opts the options string, key-value pairs separated by a
  * delimiter
@@ -709,6 +724,9 @@ int av_opt_set_from_string(void *ctx, const char *opts,
 /**
  * Set all the options from a given dictionary on an object.
  *
+ * Note: after a struct is initialized, only options with the
+ * AV_OPT_FLAG_RUNTIME_PARAM flag can be modified.
+ *
  * @param obj a struct whose first element is a pointer to AVClass
  * @param options options to process. This dictionary will be freed and 
replaced
  *by a new one containing all options not found in obj.
@@ -726,6 +744,9 @@ int av_opt_set_dict(void *obj, struct AVDictionary 
**options);
 /**
  * Set all the options from a given dictionary on an object.
  *
+ * Note: after a struct is initialized, only options with the
+ * AV_OPT_FLAG_RUNTIME_PARAM flag can be modified.
+ *
  * @param obj a struct whose first element is a pointer to AVClass
  * @param options options to process. This dictionary will be freed and 
replaced
  *by a new one containing all options not found in obj.
@@ -764,6 +785,9 @@ int av_opt_copy(void *dest, const void *src);
  * @{
  * Those functions set the field of obj with the given name to value.
  *
+ * Note: after a struct is initialized, only options with the
+ * AV_OPT_FLAG_RUNTIME_PARAM flag can be modified.
+ *
  * @param[in] obj A struct whose first element is a pointer to an AVClass.
  * @param[in] name the name of the field to set
  * @param[in] val The value to set. In case of av_opt_set() if the field is not
-- 
2.45.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] lavu/opt: Mention that AVOptions is not reentrant

2024-06-06 Thread Andrew Sayers
On Thu, Jun 06, 2024 at 05:21:00PM +0200, Andreas Rheinhardt wrote:
> Andrew Sayers:
> > On Thu, Jun 06, 2024 at 04:24:11PM +0200, Michael Niedermayer wrote:
> >> On Thu, Jun 06, 2024 at 09:29:24AM +0100, Andrew Sayers wrote:
> >>> On Thu, Jun 06, 2024 at 01:17:48AM +0200, Michael Niedermayer wrote:
> >>> [...]
> >>>> AVOption simply provides light weight access to the struct fields.
> >>>> Calling AVOption non re-entrant in modifying a field you arent even 
> >>>> allowed
> >>>> to modify from 2 threads is confusing
> >>>
> >>> I think you're saying there's already a rule about modifying AVOptions 
> >>> from
> >>> 2 threads.  Could you explain that in more detail?
> >>
> >> Well, one way this can be argued is this:
> >> Latest C draft: (but i doubt this is different) ISO/IEC 9899:2017   C17 
> >> ballot N2176
> >>
> >> "Two expression evaluations conflict if one of them modifies a memory 
> >> location and the other one
> >>  reads or modifies the same memory location"
> >>
> >> so if you have 2 threads and one writes into a int and another reads it at 
> >> the
> >> same time, the code is broken.
> >> The code doing said act through some API doesnt become less broken
> >>
> >> Calling AVOption non re-rentrant because of that is false thats as if one 
> >> executed
> >> strtok_r(a,b,c) with the VERY same a,b,c from 2 threads and then said
> >> its not thread safe
> >>
> >> strtok_r() is thread safe and reentrant if its used correctly, so is 
> >> AVOption
> > [...]
> > 
> > Ok, how about if the patch avoided the word "reentrant" and just said:
> > 
> > + * Note: AVOptions values should not be modified after a struct is 
> > initialized.
> 
> This is wrong either. As Paul has already pointed out to you, some
> options are allowed to be modified lateron.

Ah, I'd interpreted "runtime" to be the opposite of "compile-time", not
"initialization-time".  I'll propose a new patch that should be clearer.
___
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] lavu/opt: Mention that AVOptions is not reentrant

2024-06-06 Thread Andrew Sayers
On Thu, Jun 06, 2024 at 04:24:11PM +0200, Michael Niedermayer wrote:
> On Thu, Jun 06, 2024 at 09:29:24AM +0100, Andrew Sayers wrote:
> > On Thu, Jun 06, 2024 at 01:17:48AM +0200, Michael Niedermayer wrote:
> > [...]
> > > AVOption simply provides light weight access to the struct fields.
> > > Calling AVOption non re-entrant in modifying a field you arent even 
> > > allowed
> > > to modify from 2 threads is confusing
> > 
> > I think you're saying there's already a rule about modifying AVOptions from
> > 2 threads.  Could you explain that in more detail?
> 
> Well, one way this can be argued is this:
> Latest C draft: (but i doubt this is different) ISO/IEC 9899:2017   C17 
> ballot N2176
> 
> "Two expression evaluations conflict if one of them modifies a memory 
> location and the other one
>  reads or modifies the same memory location"
> 
> so if you have 2 threads and one writes into a int and another reads it at the
> same time, the code is broken.
> The code doing said act through some API doesnt become less broken
> 
> Calling AVOption non re-rentrant because of that is false thats as if one 
> executed
> strtok_r(a,b,c) with the VERY same a,b,c from 2 threads and then said
> its not thread safe
> 
> strtok_r() is thread safe and reentrant if its used correctly, so is AVOption
[...]

Ok, how about if the patch avoided the word "reentrant" and just said:

+ * Note: AVOptions values should not be modified after a struct is initialized.
___
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] lavu/opt: Mention that AVOptions is not reentrant

2024-06-06 Thread Andrew Sayers
On Thu, Jun 06, 2024 at 01:17:48AM +0200, Michael Niedermayer wrote:
[...]
> AVOption simply provides light weight access to the struct fields.
> Calling AVOption non re-entrant in modifying a field you arent even allowed
> to modify from 2 threads is confusing

I think you're saying there's already a rule about modifying AVOptions from
2 threads.  Could you explain that in more detail?

> If you want to modify a field from 2 threads that field could be some sort
> of atomic type. This can then easily be added to AVOption

Doing that for a single option would involve publicly guaranteeing its
representation for at least one major version.  At that point, you might as well
just tell people to access it as a member of a public struct.

To be clear - this isn't a programming problem, it's a design problem.
The interface currently allows external developers to assume something will
always work when it's actually just something that could be supported some day.
Writing up the current behaviour as a guarantee lets them avoid writing code
that will generate hard-to-reproduce bugs, at the cost of making it slightly
harder for us to do something we've never needed to do in the past.
___
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] lavu/opt: Mention that AVOptions is not reentrant

2024-06-05 Thread Andrew Sayers
On Wed, Jun 05, 2024 at 09:46:16AM -0400, Ronald S. Bultje wrote:
> Hi,
> 
> On Wed, Jun 5, 2024 at 9:44 AM Andrew Sayers 
> wrote:
> 
> > On Wed, Jun 05, 2024 at 03:34:50PM +0200, Paul B Mahol wrote:
> > > On Wed, Jun 5, 2024 at 3:18 PM Andrew Sayers <
> > ffmpeg-de...@pileofstuff.org>
> > > wrote:
> > >
> > > > An external API developer might think they can use AVOptions to modify
> > > > values
> > > > during playback (e.g. putting a playback quality slider next to the
> > volume
> > > > slider).  Make it clear that behaviour is not recommended.
> > > >
> > >
> > > There are options that can be changed at runtime,
> > > And it works just fine.
> >
> > How would an external developer know which options can be safely changed
> > (preferably including in future versions of FFmpeg) vs. ones where their
> > tests
> > got lucky and happened not to trigger a read during a non-atomic write?
> >
> 
> If you see that happening, it would be good to submit a bug report. Right
> now it's very abstract.

I think we might be talking past each other - here's a concrete example:

The private struct "SetTSContext" includes an AVOptions-accessible member
"time_base", currently implemented as an AVRational (i.e. a pair of ints).
write_number() in libavutil/opt.c sets options of type AV_OPT_TYPE_RATIONAL
in such a way that a poorly-timed read could see the new numerator
and old denominator (or the other way around).

If I wrote a program that let users dynamically change the time base,
and someone switched their timebase from 1/30 to 100/3000, one unlucky user
might have a few frames encoded with a timebase of 100/30.  Is that something
the AVOptions API is supposed to support?  If yes, the bug is that
AVOptions access isn't guarded by a mutex.  If no, there's no bug, just an
edge case worth mentioning in the docs.
___
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] lavu/opt: Mention that AVOptions is not reentrant

2024-06-05 Thread Andrew Sayers
On Wed, Jun 05, 2024 at 03:34:50PM +0200, Paul B Mahol wrote:
> On Wed, Jun 5, 2024 at 3:18 PM Andrew Sayers 
> wrote:
> 
> > An external API developer might think they can use AVOptions to modify
> > values
> > during playback (e.g. putting a playback quality slider next to the volume
> > slider).  Make it clear that behaviour is not recommended.
> >
> 
> There are options that can be changed at runtime,
> And it works just fine.

How would an external developer know which options can be safely changed
(preferably including in future versions of FFmpeg) vs. ones where their tests
got lucky and happened not to trigger a read during a non-atomic write?
___
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] lavu/opt: Mention that AVOptions is not reentrant

2024-06-05 Thread Andrew Sayers
An external API developer might think they can use AVOptions to modify values
during playback (e.g. putting a playback quality slider next to the volume
slider).  Make it clear that behaviour is not recommended.

Include the warning in the group description and the text for every function
that sets options, but leave it implicit in functions that get options.
This reflects the fact that *modifying* options is likely to cause weird bugs,
while *reading* options isn't guaranteed but is likely to be safe.
---
 libavutil/opt.h | 30 --
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/libavutil/opt.h b/libavutil/opt.h
index 07e27a9208..13292c6473 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -53,11 +53,16 @@
  * question is allowed to access the field. This allows us to extend the
  * semantics of those fields without breaking API compatibility.
  *
+ * Note that AVOptions functions are not reentrant, and options may be accessed
+ * from internal FFmpeg threads.  Unless otherwise noted, it is best to avoid
+ * modifying options once a struct has been initialized.
+ *
  * @section avoptions_scope Scope of AVOptions
  *
  * AVOptions is designed to support any set of multimedia configuration options
- * that can be defined at compile-time.  Although it is mainly used to expose
- * FFmpeg options, you are welcome to adapt it to your own use case.
+ * that can be defined at compile-time and set at object creation time.  
Although
+ * it is mainly used to expose FFmpeg options, you are welcome to adapt it
+ * to your own use case.
  *
  * No single approach can ever fully solve the problem of configuration,
  * but please submit a patch if you believe you have found a problem
@@ -483,6 +488,9 @@ typedef struct AVOptionRanges {
 /**
  * Set the values of all AVOption fields to their default values.
  *
+ * Note: like all AVOptions functions, this is not reentrant.  Unless
+ * otherwise noted, it should only be used before initializing the struct.
+ *
  * @param s an AVOption-enabled struct (its first member must be a pointer to 
AVClass)
  */
 void av_opt_set_defaults(void *s);
@@ -492,6 +500,9 @@ void av_opt_set_defaults(void *s);
  * AVOption fields for which (opt->flags & mask) == flags will have their
  * default applied to s.
  *
+ * Note: like all AVOptions functions, this is not reentrant.  Unless
+ * otherwise noted, it should only be used before initializing the struct.
+ *
  * @param s an AVOption-enabled struct (its first member must be a pointer to 
AVClass)
  * @param mask combination of AV_OPT_FLAG_*
  * @param flags combination of AV_OPT_FLAG_*
@@ -661,6 +672,9 @@ enum {
  * key. ctx must be an AVClass context, storing is done using
  * AVOptions.
  *
+ * Note: like all AVOptions functions, this is not reentrant.  Unless
+ * otherwise noted, it should only be used before initializing the struct.
+ *
  * @param opts options string to parse, may be NULL
  * @param key_val_sep a 0-terminated list of characters used to
  * separate key from value
@@ -679,6 +693,9 @@ int av_set_options_string(void *ctx, const char *opts,
  * Parse the key-value pairs list in opts. For each key=value pair found,
  * set the value of the corresponding option in ctx.
  *
+ * Note: like all AVOptions functions, this is not reentrant.  Unless
+ * otherwise noted, it should only be used before initializing the struct.
+ *
  * @param ctx  the AVClass object to set options on
  * @param opts the options string, key-value pairs separated by a
  * delimiter
@@ -709,6 +726,9 @@ int av_opt_set_from_string(void *ctx, const char *opts,
 /**
  * Set all the options from a given dictionary on an object.
  *
+ * Note: like all AVOptions functions, this is not reentrant.  Unless
+ * otherwise noted, it should only be used before initializing the struct.
+ *
  * @param obj a struct whose first element is a pointer to AVClass
  * @param options options to process. This dictionary will be freed and 
replaced
  *by a new one containing all options not found in obj.
@@ -726,6 +746,9 @@ int av_opt_set_dict(void *obj, struct AVDictionary 
**options);
 /**
  * Set all the options from a given dictionary on an object.
  *
+ * Note: like all AVOptions functions, this is not reentrant.  Unless
+ * otherwise noted, it should only be used before initializing the struct.
+ *
  * @param obj a struct whose first element is a pointer to AVClass
  * @param options options to process. This dictionary will be freed and 
replaced
  *by a new one containing all options not found in obj.
@@ -764,6 +787,9 @@ int av_opt_copy(void *dest, const void *src);
  * @{
  * Those functions set the field of obj with the given name to value.
  *
+ * Note: like all AVOptions functions, these are not reentrant.  Unless
+ * otherwise noted, they should only be used before initializing the struct.
+ *
  * @param[in] obj A struct whose first element is a pointer to 

Re: [FFmpeg-devel] [PATCH v6 3/4] all: Link to "context" from all public contexts with documentation

2024-06-05 Thread Andrew Sayers
Note: I somehow managed to send this message directly to Anton before - sorry
Anton for the message spam, please reply to this one if you want the list to
see it!

On Wed, Jun 05, 2024 at 10:12:47AM +0200, Anton Khirnov wrote:
> Quoting Andrew Sayers (2024-06-04 16:47:23)
> > The goal of putting these links in "@see" blocks is to provide hooks
> > for future developers to add links to other useful parts of the codebase.
> > ---
> >  libavcodec/avcodec.h | 3 +++
> >  libavcodec/bsf.h | 3 +++
> >  libavcodec/d3d11va.h | 3 +++
> >  libavcodec/mediacodec.h  | 2 ++
> >  libavcodec/qsv.h | 3 +++
> >  libavcodec/vdpau.h   | 3 +++
> >  libavcodec/videotoolbox.h| 3 +++
> >  libavfilter/avfilter.h   | 7 ++-
> >  libavformat/avformat.h   | 3 +++
> >  libavformat/avio.h   | 3 +++
> >  libavutil/audio_fifo.h   | 3 +++
> >  libavutil/hwcontext.h| 6 ++
> >  libavutil/hwcontext_cuda.h   | 3 +++
> >  libavutil/hwcontext_d3d11va.h| 6 ++
> >  libavutil/hwcontext_d3d12va.h| 6 ++
> >  libavutil/hwcontext_drm.h| 3 +++
> >  libavutil/hwcontext_dxva2.h  | 6 ++
> >  libavutil/hwcontext_mediacodec.h | 3 +++
> >  libavutil/hwcontext_opencl.h | 6 ++
> >  libavutil/hwcontext_qsv.h| 6 ++
> >  libavutil/hwcontext_vaapi.h  | 6 ++
> >  libavutil/hwcontext_vdpau.h  | 3 +++
> >  libavutil/hwcontext_vulkan.h | 6 ++
> >  libavutil/lfg.h  | 3 +++
> >  24 files changed, 98 insertions(+), 1 deletion(-)
> 
> IMO this is pointless churn.

That's like saying caches are pointless bloat - it's not about correctness,
it's about performance.  Actually, I've been talking about "performance" a lot
round here, but not really explained what I mean...

Imagine a smart young developer who learned C at university and is now dipping
their toe in the world of actual C development.  They've come up with an idea
for a little app that's different enough from the examples to force themselves
not to just copy/paste example code.  It's simple enough that an experienced
developer like you would only need half a day for the whole project, so they
allow themselves a weekend to get it done.   "Performance" in this case means
"can they finish the project in their ~16 hour time budget?"

Assuming they're half as productive as you would be, 8 of their 16 hours go on
programming, leaving 8 hours to learn FFmpeg.

They've never written real-world C before, so they don't know what a context is.
And they only have a narrow understanding of OOP, so as soon as they see words
like "object" and "class", they assume you're referring to the precise version
of OOP their Java lecturer taught them about.  So the longer they spend poking
round looking for information, the more misconceptions they're going to develop.
Even if we assume they find the context document after one hour of searching,
they fully understand the document with no reading time, and only need one
extra hour to unlearn the misconceptions they developed, that's still cost
a quarter of their remaining time budget.

To an expert, these links are unnecessary verbiage pointing to a document
that explains things that are blindingly obvious.  But to a newbie, they're
an important optimisation that can make the difference between finishing
a project or having to give up on FFmpeg altogether.
___
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 v6 2/4] lavu: Clarify relationship between AVClass, AVOption and context

2024-06-05 Thread Andrew Sayers
On Wed, Jun 05, 2024 at 12:34:48PM +0200, Stefano Sabatini wrote:
> On date Tuesday 2024-06-04 15:47:22 +0100, Andrew Sayers wrote:

> > + * Structs that only use logging facilities are often referred to as
> > + * "AVClass context structures", while those that provide configuration
> > + * options are called "AVOptions-enabled structs".
> 
> A struct with an AVClass as its first member can be used for both
> logging and options management, there is no difference between the
> two. My take:
> |Structs that use AVClass might be referred to as AVClass
> |contexts/structures, those that in addition define options might be
> |called AVOptions contexts/structures.

I think you were away when this came up, and anyway this thread is getting
quite unwieldy.  See [1] and [2] for the full version, but in short, defining
AVClass by layout leads to conclusions that are at best unintuitive.


> > + * Note that AVOptions is not reentrant, and that many FFmpeg functions 
> > access
> 
> ... AVOptions access is not reeentrant ...
> 
> > + * options from separate threads.  Unless otherwise indicated, it is best 
> > to
> > + * avoid modifying options once a struct has been initialized.
> 
> But this note is not relevant to the change, and should probably be
> discussed separately

Short version: I'll make a separate patch now, let's come back to this after

Long version...

If you assume options can be set at any time, they broadly resemble a reflection
mechanism.  If you assume they can only be set during the configuration stage,
they broadly resemble an OOP constructor.  The document needs to address the one
they resemble (even if just to say "this is why they're different"), and needs
to steer clear of any possible comparison with the one they don't resemble.
So it would be too risky to bump this to the upcoming omnibus patchset,
but it's fine to apply this *before* the context document.

[1] https://ffmpeg.org/pipermail/ffmpeg-devel/2024-May/328058.html
[2] https://ffmpeg.org/pipermail/ffmpeg-devel/2024-May/328087.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".


Re: [FFmpeg-devel] [RFC] STF 2025

2024-06-04 Thread Andrew Sayers
On Fri, May 17, 2024 at 03:49:58PM +0200, Michael Niedermayer wrote:
> Hi all
> 
> Before this is forgotten again, better start some dicsussion too early than 
> too late

Unless there's a better place to put these, I plan to reply to this message
whenever I notice someone bring up something that seems relevant.
Hopefully it will be a good reference if and when the time comes.

Sebastian Ramacher recently said this in another thread[1]:

> Maintainers and developers of reverse dependencies repeatedly ask for
> upgrade guides that go beyond "use this function instead"

This strikes me as an excellent bit of boring-but-important STF work.
The bug reports in that e-mail make it relatively easy to quantify impact -
measure the number of breakages in each revision, make a chart of numbers
over time, agree a target number for next time.

[1] https://ffmpeg.org/pipermail/ffmpeg-devel/2024-June/328852.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] [PATCH v6 4/4] all: Rewrite documentation for contexts

2024-06-04 Thread Andrew Sayers
Make their documentation more readable and similar to each other,
(hopefully) without changing the meaning.
---
 libavcodec/aac/aacdec.h  |  2 +-
 libavcodec/aacenc.h  |  2 +-
 libavcodec/ac3enc.h  |  2 +-
 libavcodec/amfenc.h  |  2 +-
 libavcodec/atrac.h   |  2 +-
 libavcodec/avcodec.h |  3 ++-
 libavcodec/bsf.h |  2 +-
 libavcodec/cbs.h |  2 +-
 libavcodec/d3d11va.h |  3 +--
 libavcodec/mediacodec.h  |  4 ++--
 libavcodec/pthread_frame.c   |  4 ++--
 libavcodec/qsv.h |  6 --
 libavcodec/sbr.h |  2 +-
 libavcodec/vdpau.h   |  5 +++--
 libavcodec/videotoolbox.h|  5 +++--
 libavfilter/avfilter.h   |  2 +-
 libavformat/avformat.h   |  3 ++-
 libavformat/avio.h   |  3 ++-
 libavutil/audio_fifo.h   |  2 +-
 libavutil/hwcontext.h| 21 -
 libavutil/hwcontext_cuda.h   |  2 +-
 libavutil/hwcontext_d3d11va.h|  4 ++--
 libavutil/hwcontext_d3d12va.h|  6 +++---
 libavutil/hwcontext_drm.h|  2 +-
 libavutil/hwcontext_dxva2.h  |  4 ++--
 libavutil/hwcontext_mediacodec.h |  2 +-
 libavutil/hwcontext_opencl.h |  4 ++--
 libavutil/hwcontext_qsv.h|  4 ++--
 libavutil/hwcontext_vaapi.h  |  4 ++--
 libavutil/hwcontext_vdpau.h  |  2 +-
 libavutil/hwcontext_vulkan.h |  5 +++--
 libavutil/lfg.h  |  3 ++-
 32 files changed, 65 insertions(+), 54 deletions(-)

diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h
index ee21a94007..f0d613afd9 100644
--- a/libavcodec/aac/aacdec.h
+++ b/libavcodec/aac/aacdec.h
@@ -441,7 +441,7 @@ typedef struct AACDecDSP {
 } AACDecDSP;
 
 /**
- * main AAC decoding context
+ * Context for decoding AAC
  */
 struct AACDecContext {
 const struct AVClass  *class;
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index d07960620e..3e710c7fac 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -207,7 +207,7 @@ typedef struct AACPCEInfo {
 } AACPCEInfo;
 
 /**
- * AAC encoder context
+ * Context for encoding AAC
  */
 typedef struct AACEncContext {
 AVClass *av_class;
diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
index 5e98ad188b..e5abe0a856 100644
--- a/libavcodec/ac3enc.h
+++ b/libavcodec/ac3enc.h
@@ -153,7 +153,7 @@ typedef struct AC3Block {
 struct PutBitContext;
 
 /**
- * AC-3 encoder private context.
+ * Private context for encoding AC-3
  */
 typedef struct AC3EncodeContext {
 AVClass *av_class;  ///< AVClass used for AVOption
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 2dbd378ef8..184897beeb 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -43,7 +43,7 @@ typedef struct AmfTraceWriter {
 } AmfTraceWriter;
 
 /**
-* AMF encoder context
+* Context for encoding AMF
 */
 
 typedef struct AmfContext {
diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
index 05208bbee6..e760f0384d 100644
--- a/libavcodec/atrac.h
+++ b/libavcodec/atrac.h
@@ -39,7 +39,7 @@ typedef struct AtracGainInfo {
 } AtracGainInfo;
 
 /**
- *  Gain compensation context structure.
+ *  Context for gain compensation
  */
 typedef struct AtracGCContext {
 float   gain_tab1[16];  ///< gain compensation level table
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index abc00ab394..2fed4757ed 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -430,7 +430,8 @@ typedef struct RcOverride{
 #define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0)
 
 /**
- * main external API structure.
+ * Context for an encode or decode session
+ *
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
index ee5fdd48d2..fadcfc5d47 100644
--- a/libavcodec/bsf.h
+++ b/libavcodec/bsf.h
@@ -56,7 +56,7 @@
  */
 
 /**
- * The bitstream filter state.
+ * Context for bitstream filtering
  *
  * This struct must be allocated with av_bsf_alloc() and freed with
  * av_bsf_free().
diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h
index d479b1ac2d..c074dd11ec 100644
--- a/libavcodec/cbs.h
+++ b/libavcodec/cbs.h
@@ -214,7 +214,7 @@ typedef void (*CBSTraceWriteCallback)(void *trace_context,
   int64_t value);
 
 /**
- * Context structure for coded bitstream operations.
+ * Context for coded bitstream operations
  */
 typedef struct CodedBitstreamContext {
 /**
diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
index 686974b083..5ffee2b3be 100644
--- a/libavcodec/d3d11va.h
+++ b/libavcodec/d3d11va.h
@@ -46,8 +46,7 @@
  */
 
 /**
- * This structure is used to provides the necessary configurations and data
- * to the Direct3D11 FFmpeg HWAccel implementation.
+ * Context for the Direct3D11 FFmpeg HWAccel implementation
  *
  * The application must make it available as 

[FFmpeg-devel] [PATCH v6 3/4] all: Link to "context" from all public contexts with documentation

2024-06-04 Thread Andrew Sayers
The goal of putting these links in "@see" blocks is to provide hooks
for future developers to add links to other useful parts of the codebase.
---
 libavcodec/avcodec.h | 3 +++
 libavcodec/bsf.h | 3 +++
 libavcodec/d3d11va.h | 3 +++
 libavcodec/mediacodec.h  | 2 ++
 libavcodec/qsv.h | 3 +++
 libavcodec/vdpau.h   | 3 +++
 libavcodec/videotoolbox.h| 3 +++
 libavfilter/avfilter.h   | 7 ++-
 libavformat/avformat.h   | 3 +++
 libavformat/avio.h   | 3 +++
 libavutil/audio_fifo.h   | 3 +++
 libavutil/hwcontext.h| 6 ++
 libavutil/hwcontext_cuda.h   | 3 +++
 libavutil/hwcontext_d3d11va.h| 6 ++
 libavutil/hwcontext_d3d12va.h| 6 ++
 libavutil/hwcontext_drm.h| 3 +++
 libavutil/hwcontext_dxva2.h  | 6 ++
 libavutil/hwcontext_mediacodec.h | 3 +++
 libavutil/hwcontext_opencl.h | 6 ++
 libavutil/hwcontext_qsv.h| 6 ++
 libavutil/hwcontext_vaapi.h  | 6 ++
 libavutil/hwcontext_vdpau.h  | 3 +++
 libavutil/hwcontext_vulkan.h | 6 ++
 libavutil/lfg.h  | 3 +++
 24 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 2da63c87ea..abc00ab394 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -441,6 +441,9 @@ typedef struct RcOverride{
  * The AVOption/command line parameter names differ in some cases from the C
  * structure field names for historic reasons or brevity.
  * sizeof(AVCodecContext) must not be used outside libav*.
+ *
+ * @see
+ * - @ref Context
  */
 typedef struct AVCodecContext {
 /**
diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
index a09c69f242..ee5fdd48d2 100644
--- a/libavcodec/bsf.h
+++ b/libavcodec/bsf.h
@@ -64,6 +64,9 @@
  * The fields in the struct will only be changed (by the caller or by the
  * filter) as described in their documentation, and are to be considered
  * immutable otherwise.
+ *
+ * @see
+ * - @ref Context
  */
 typedef struct AVBSFContext {
 /**
diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
index 27f40e5519..686974b083 100644
--- a/libavcodec/d3d11va.h
+++ b/libavcodec/d3d11va.h
@@ -52,6 +52,9 @@
  * The application must make it available as AVCodecContext.hwaccel_context.
  *
  * Use av_d3d11va_alloc_context() exclusively to allocate an AVD3D11VAContext.
+ *
+ * @see
+ * - @ref Context
  */
 typedef struct AVD3D11VAContext {
 /**
diff --git a/libavcodec/mediacodec.h b/libavcodec/mediacodec.h
index 4e9b56a618..43f049a609 100644
--- a/libavcodec/mediacodec.h
+++ b/libavcodec/mediacodec.h
@@ -29,6 +29,8 @@
  * This structure holds a reference to a android/view/Surface object that will
  * be used as output by the decoder.
  *
+ * @see
+ * - @ref Context
  */
 typedef struct AVMediaCodecContext {
 
diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h
index c156b08d07..8ab93af6b6 100644
--- a/libavcodec/qsv.h
+++ b/libavcodec/qsv.h
@@ -32,6 +32,9 @@
  * - decoding: hwaccel_context must be set on return from the get_format()
  * callback
  * - encoding: hwaccel_context must be set before avcodec_open2()
+ *
+ * @see
+ * - @ref Context
  */
 typedef struct AVQSVContext {
 /**
diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
index 8021c25761..934c96b88c 100644
--- a/libavcodec/vdpau.h
+++ b/libavcodec/vdpau.h
@@ -74,6 +74,9 @@ typedef int (*AVVDPAU_Render2)(struct AVCodecContext *, 
struct AVFrame *,
  *
  * The size of this structure is not a part of the public ABI and must not
  * be used outside of libavcodec.
+ *
+ * @see
+ * - @ref Context
  */
 typedef struct AVVDPAUContext {
 /**
diff --git a/libavcodec/videotoolbox.h b/libavcodec/videotoolbox.h
index d68d76e400..81d90d63b6 100644
--- a/libavcodec/videotoolbox.h
+++ b/libavcodec/videotoolbox.h
@@ -53,6 +53,9 @@
  * between the caller and libavcodec for initializing Videotoolbox decoding.
  * Its size is not a part of the public ABI, it must be allocated with
  * av_videotoolbox_alloc_context() and freed with av_free().
+ *
+ * @see
+ * - @ref Context
  */
 typedef struct AVVideotoolboxContext {
 /**
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index a34e61f23c..25ccd80433 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -403,7 +403,12 @@ unsigned avfilter_filter_pad_count(const AVFilter *filter, 
int is_output);
  */
 #define AVFILTER_THREAD_SLICE (1 << 0)
 
-/** An instance of a filter */
+/**
+ * An instance of a filter
+ *
+ * @see
+ * - @ref Context
+ */
 struct AVFilterContext {
 const AVClass *av_class;///< needed for av_log() and filters 
common options
 
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 8afdcd9fd0..18f20f0bb0 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1253,6 +1253,9 @@ enum AVDurationEstimationMethod {
  * can be found in libavformat/options_table.h.
  * The AVOption/command line 

[FFmpeg-devel] [PATCH v6 2/4] lavu: Clarify relationship between AVClass, AVOption and context

2024-06-04 Thread Andrew Sayers
---
 libavutil/log.h | 16 +---
 libavutil/opt.h | 26 +-
 2 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/libavutil/log.h b/libavutil/log.h
index ab7ceabe22..88b35897c6 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -59,9 +59,19 @@ typedef enum {
 struct AVOptionRanges;
 
 /**
- * Describe the class of an AVClass context structure. That is an
- * arbitrary struct of which the first field is a pointer to an
- * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.).
+ * Generic Logging facilities and configuration options
+ *
+ * Logging and AVOptions functions expect to be passed structs
+ * whose first member is a pointer-to-@ref AVClass.
+ *
+ * Structs that only use logging facilities are often referred to as
+ * "AVClass context structures", while those that provide configuration
+ * options are called "AVOptions-enabled structs".
+ *
+ * @see
+ * * @ref lavu_log
+ * * @ref avoptions
+ * * @ref Context
  */
 typedef struct AVClass {
 /**
diff --git a/libavutil/opt.h b/libavutil/opt.h
index 07e27a9208..cdee8f7d28 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -39,9 +39,16 @@
  * @defgroup avoptions AVOptions
  * @ingroup lavu_data
  * @{
- * AVOptions provide a generic system to declare options on arbitrary structs
- * ("objects"). An option can have a help text, a type and a range of possible
- * values. Options may then be enumerated, read and written to.
+ *
+ * Inspection and configuration for AVClass context structures
+ *
+ * Provides a generic API to declare and manage options on any struct
+ * whose first member is a pointer-to-@ref AVClass.  Structs with private
+ * contexts can use that AVClass to return further @ref AVClass "AVClass"es
+ * that allow access to options in the private structs.
+ *
+ * Each option can have a help text, a type and a range of possible values.
+ * Options may be enumerated, read and written to.
  *
  * There are two modes of access to members of AVOption and its child structs.
  * One is called 'native access', and refers to access from the code that
@@ -53,11 +60,20 @@
  * question is allowed to access the field. This allows us to extend the
  * semantics of those fields without breaking API compatibility.
  *
+ * Note that AVOptions is not reentrant, and that many FFmpeg functions access
+ * options from separate threads.  Unless otherwise indicated, it is best to
+ * avoid modifying options once a struct has been initialized.
+ *
+ * @see
+ * * @ref lavu_log
+ * * @ref Context
+ *
  * @section avoptions_scope Scope of AVOptions
  *
  * AVOptions is designed to support any set of multimedia configuration options
- * that can be defined at compile-time.  Although it is mainly used to expose
- * FFmpeg options, you are welcome to adapt it to your own use case.
+ * that can be defined at compile-time and set at object creation time.  
Although
+ * it is mainly used to expose FFmpeg options, you are welcome to adapt it
+ * to your own use case.
  *
  * No single approach can ever fully solve the problem of configuration,
  * but please submit a patch if you believe you have found a problem
-- 
2.45.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 v6 1/4] doc: Explain what "context" means

2024-06-04 Thread Andrew Sayers
Derived from explanations kindly provided by Stefano Sabatini and others:
https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325903.html
---
 doc/context.md | 430 +
 1 file changed, 430 insertions(+)
 create mode 100644 doc/context.md

diff --git a/doc/context.md b/doc/context.md
new file mode 100644
index 00..bd8cb58696
--- /dev/null
+++ b/doc/context.md
@@ -0,0 +1,430 @@
+@page Context Introduction to contexts
+
+@tableofcontents
+
+FFmpeg uses the term “context” to refer to an idiom
+you have probably used before:
+
+```c
+// C structs often share context between functions:
+
+FILE *my_file; // my_file stores information about a filehandle
+
+printf(my_file, "hello "); // my_file provides context to this function,
+printf(my_file, "world!"); // and also to this function
+```
+
+```python
+# Python classes provide context for the methods they contain:
+
+class MyClass:
+def print(self,message):
+if self.prev_message != message:
+self.prev_message = message
+print(message)
+```
+
+
+```c
+// Many JavaScript callbacks accept an optional context argument:
+
+const my_object = {};
+
+my_array.forEach(function_1, my_object);
+my_array.forEach(function_2, my_object);
+```
+
+Be careful comparing FFmpeg contexts to things you're already familiar with -
+FFmpeg may sometimes happen to reuse words you recognise, but mean something
+completely different.  For example, the AVClass struct has nothing to do with
+[object-oriented 
classes](https://en.wikipedia.org/wiki/Class_(computer_programming)).
+
+If you've used contexts in other C projects, you may want to read
+@ref Context_comparison before the rest of the document.
+
+@section Context_general “Context” as a general concept
+
+@par
+A context is any data structure used by several functions
+(or several instances of the same function) that all operate on the same 
entity.
+
+In the broadest sense, “context” is just a way to think about code.
+You can even use it to think about code written by people who have never
+heard the term, or who would disagree with you about what it means.
+Consider the following snippet:
+
+```c
+struct DualWriter {
+int fd1, fd2;
+};
+
+ssize_t write_to_two_files(
+struct DualWriter *my_writer,
+uint8_t *buf,
+int buf_size
+) {
+
+ssize_t bytes_written_1 = write(my_writer->fd1, buf, buf_size);
+ssize_t bytes_written_2 = write(my_writer->fd2, buf, buf_size);
+
+if ( bytes_written_1 != bytes_written_2 ) {
+// ... handle this edge case ...
+}
+
+return bytes_written_1;
+
+}
+
+int main() {
+
+struct DualWriter my_writer;
+my_writer.fd1 = open("file1", 0644, "wb");
+my_writer.fd2 = open("file2", 0644, "wb");
+
+write_to_two_files(_writer, "hello ", sizeof("hello "));
+write_to_two_files(_writer, "world!", sizeof("world!"));
+
+close( my_writer.fd1 );
+close( my_writer.fd2 );
+
+}
+```
+
+The term “context” doesn't appear anywhere in the snippet.  But `DualWriter`
+is passed to several instances of `write_to_two_files()` that operate on
+the same entity, so it fits the definition of a context.
+
+When reading code that isn't explicitly described in terms of contexts,
+remember that your interpretation may differ from other people's.
+For example, FFmpeg's avio_alloc_context() accepts a set of callback functions
+and an `opaque` argument - even though this function guarantees to *return*
+a context, it does not require `opaque` to *provide* context for the callback
+functions.  So you could choose to pass a struct like `DualWriter` as the
+`opaque` argument, or you could pass callbacks that use `stdin` and `stdout`
+and just pass a `NULL` argument for `opaque`.
+
+When reading code that *is* explicitly described in terms of contexts,
+remember that the term's meaning is guaranteed by *the project's community*,
+not *the language it's written in*.  That means guarantees may be more flexible
+and change more over time.  For example, programming languages that use
+[encapsulation](https://en.wikipedia.org/wiki/Encapsulation_(computer_programming))
+will simply refuse to compile code that violates its rules about access,
+while communities can put up with special cases if they improve code quality.
+
+The next section will discuss what specific conventions FFmpeg developers mean
+when they describe parts of their code as using “contexts”.
+
+@section Context_ffmpeg FFmpeg contexts
+
+This section discusses specific context-related conventions used in FFmpeg.
+Some of these are used in other projects, others are unique to this project.
+
+@subsection Context_indicating Indicating context: “Context”, “ctx” etc.
+
+```c
+// Context struct names usually end with `Context`:
+struct AVSomeContext {
+  ...
+};
+
+// Functions are usually named after their context,
+// context parameters usually come first and are often called `ctx`:
+void av_some_function(AVSomeContext *ctx, ...);
+```

[FFmpeg-devel] [PATCH v6 0/4] doc: Explain what "context" means

2024-06-04 Thread Andrew Sayers
I'm making a list of little documentation patches to submit as a set once this
patchset is done.  I've put Sw{r,s}Context on the list, and will think about
their relationship to other opaque AVOptions-enabled structs as part of that.
I don't see anything in that discussion that affects this patchset,
so let's park that discussion for now.

One thing we haven't talked about before, but is worth stating explicitly -
smart people tend to conflate "I can't think of anything complex about X"
with "there are no complex things about X", so this document needs to sell
people on the complexity of each problem before laying out the solution.
The AVOptions section is a particularly good example, tackling the implicit
question "can't you just use `getopt`?" first then moving on to describe how
it solves that problem.  Some parts of the document function as responses to 
questions an FFmpeg developer would never think to ask, because why would you 
even think to compare AVOptions with getopt?

This version emphasises how AVOptions should only be set during configuration.
It avoids the words "reflection" and "introspection" altogether, because IMHO
they imply an API that can be used in any stage of a struct's lifetime.

Aside: this is the latest in a series of issues where it initially seemed like
I was adding unnecessary terminology in places where it was confusing,
but turned out to be a symptom of a fundamental misunderstanding on my part.
If there's any such language remaining in this version, we should probably
look for those misunderstandings first and worry about language second.

___
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 7.0 blocking issues

2024-06-04 Thread Andrew Sayers
On Mon, Jun 03, 2024 at 11:32:37PM +0200, Michael Niedermayer wrote:
> On Sun, Jun 02, 2024 at 03:49:42PM +0200, Sebastian Ramacher wrote:
[...]
> > Just as a FYI: ffmpeg 7.0 breaks close to 70 reverse dependencies in
> > Debian. The list is available at [1]. So if you want ffmpeg X to be in
> > Debian Y or Ubuntu Z, X needs to be released at least half a year before
> > Y or Z freeze.
> 
> Is there something that ffmpeg can do to reduce this breakage ?
> (i know its a bit of a lame question as its API brekages but i mean
> can the policy we have about deprecating API/ABI be amended in some way
> to make this easier ?

A quick look through Sebastian's list suggests two main groups of issues:

* channel layout migration
* things that didn't have attribute_deprecated before being removed

There are probably ways to reduce migration issues (e.g. Anton's point about
frequent small changes), but the quick win is to use attribute_deprecated more.

To be clear - attribute_deprecated is already used a lot.  If those messages
were being ignored, we would expect to see more bugs reported for those things.
The fact that channel layout is the only deprecated functionality to get this
far suggests that attribute_deprecated is a good way to notify people about
all but the largest changes.

> Also am i correct that it should be easier if a X.1 with same API/ABI that is
> released 6 month after X.0 is targetet for the release ? Thats in fact kind
> of what i would have preferred anyway as the .1 likely has also fewer bugs
> 
> And last but not least, someone needs to write down when .0 and .1 releases 
> should
> be made so I dont forget it :)

Whatever decision is made about this, it would be good to update the
attribute_deprecated macro to point to a URL that lays out the policy.
Something like:

#define attribute_deprecated __attribute__((deprecated("see  for 
details")))
___
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 v5 0/6] avformat/network: improve ff_neterrno()

2024-05-31 Thread Andrew Sayers
On Thu, May 16, 2024 at 12:59:05PM +0100, Andrew Sayers wrote:
> On Thu, May 16, 2024 at 01:42:23PM +0300, Rémi Denis-Courmont wrote:
> > Err, please. Keep this to the Windows back-end. Nothing good is going to 
> > happen with a function that does nothing (on other platforms) and has a 
> > nondescript numbered name.
> 
> I have no strong opinion either way, and it feels rather bikesheddable.
> Here's a version with the offending part moved to its own patch -
> I'm happy for whoever applies this to decide whether they want to
> keep or chuck patch 4/6 :)

Ping?
___
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] git problems

2024-05-30 Thread Andrew Sayers
On Thu, May 30, 2024 at 01:30:09AM +0200, Michael Niedermayer wrote:
> Hi all
> 
> It seems the security update (https://ubuntu.com/security/notices/USN-6793-1)
> broke public git
> 
> We use gitolite that runs under its own user and serve git through apache
> which runs under a different user.
> Apache has only read access to the repositories
> 
> Since the security update that stoped working, the logs are full of messages
> telling that we need to add the repositories to safe.directory
> (the commands suggested dont work and seem to mix up \t with a tab but thats 
> besides the point)
> once the repository is added to safe.directory, which ive done with 
> https://git.ffmpeg.org/michael.git
> the error is gone and everything looks fine in the logs on the server but it 
> still
> doesnt work. (i have not touched ffmpeg.git config as i first wanted to test 
> this)
> 
> So like i just said on IRC. i hope some of the other root admins will have
> some more insight here. Or if you (yes YOU!) want to help or know something
> please speak up.
> 
> This is totally not my area and i think other people could find the issue
> with less effort in less time and it would be more efficient if i work
> on FFmpeg instead where the return per hour of my time should be much greater.
> 
> Also gitweb and git over ssh seem uneffected and theres github
> 
> If people want i could downgrade git OR
> upgrade git to latest git ignoring official ubuntu packages
> otherwise, i intend to leave this for someone else to investigate and rather
> work on FFmpeg which just seems like a much better use of my time

You've talked recently about looking for STF money to upgrade the servers.
You might want to write up a postmortem when the bug is fixed, focussing on
improvements that are unlikely to happen without money.  Then you can say
"we had X hours of downtime, we think Y jobs will reduce that by Z%".

One thing for the postmortem - I don't know enough about these specific
programs to do much with the description provided.  And even if I did, I could
only offer prose hints at a solution.  But containerising these services would
let me replicate the server locally, and suggest solutions as normal patches
on the mailing list.
___
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 1/4] doc: Explain what "context" means

2024-05-29 Thread Andrew Sayers
On Wed, May 29, 2024 at 01:06:30PM +0200, Paul B Mahol wrote:
> On Wed, May 29, 2024 at 12:50 PM Andrew Sayers 
> wrote:
> 
[...]
> > *Are AVOptions just command-line options?*
> >
> > I have trouble with statements like "AVOptions is a framework for options",
> > both because it's circular and because the term "option" is too broad to be
> > meaningful.
> >
> > I've previously pushed the word "reflection" on the assumption that options
> > can be used anywhere variables are used.  For example, imagine a decoder
> > that
> > could be reconfigured on-the-fly to reduce CPU usage at the cost of
> > displaying
> > blurier images.  That can't be part of the public interface because it's
> > codec-specific, but I could imagine updating some kind of "output_quality"
> > AVOption as a user slides a slider up and down.
> >
> > But the CLI tools are largely non-interactive, so have I just
> > misunderstood?
> >
> > How about saying "AVOptions is a framework for command-line options"?
> >
> 
> ffmpeg is cli tool
> 
> libavfilter is library
> 
> AVOptions is certainly and primarily not framework for command-line options.

"Command-line option" might be the wrong word, but I've just checked
write_number() in libavutil/opt.c, and it seems to do non-atomic updates
without locking anything.  That suggests I was indeed wrong to think it could
be used on-the-fly - maybe "initial configuration options" would be a better
term?  Possibly with a warning somewhere about how AVOptions is not reentrant?
___
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 1/4] doc: Explain what "context" means

2024-05-29 Thread Andrew Sayers
Posting this separately, as these are practical "how does FFmpeg work" issues
vaguely inspired by recent discussions.


*How do namespaces work in FFmpeg?*

We've talked a bit about function namespaces recently.  One reason I've
suggested they're a weak signal is because they aren't really addressed in the
documentation.  How about adding something like this to the context doc:

Most FFmpeg functions are grouped into namespaces, usually indicated by
prefixes (e.g. `av_format_*`) but sometimes indicated by infixes
(e.g. av_alloc_format_context()).  Namespaces group functions by *topic*,
which doesn't always correlate with *context*.  For example, `av_find_*`
functions search for information across various contexts.


*Should external API devs treat Sw{r,s}Context as AVClass context structures?*

This is probably an uninteresting edge case, but just to be sure...

The website says Sw{r,s}Context start with AVClass[1], they have _get_class
functions, are shown in `ffmpeg -h full`, and I haven't found anything that says
to treat them differently to e.g. AVCodecContext.  So I'm pretty sure these
are AVClass context structures, at least as far as internal devs are concerned.

But their definitions are only in the private interface, so the layout is just
an implementation detail that can change without even a major version bump.
AVFrame used to have a _get_class function despite never having an actual
AVClass member, so that's not a signal to external API devs.  And `URLContext`
appears in `ffmpeg -h full` despite having being made private long ago,
so that's not much of a signal either.

My guess is that the above should be addressed with a patch like:

+/**
+ * @brief Context for SWResampler
+ *
+ * @note The public ABI only guarantees this is an AVOptions-enabled struct.
+ * Its size and other members are not a part of the public ABI.
+ *
+ * @see
+ * - @ref Context
+ */
 struct SwrContext {

Let me know if the above is on the right track.  If so, I'll queue up a patch
for after the context document is done.


*Are AVOptions just command-line options?*

I have trouble with statements like "AVOptions is a framework for options",
both because it's circular and because the term "option" is too broad to be
meaningful.

I've previously pushed the word "reflection" on the assumption that options
can be used anywhere variables are used.  For example, imagine a decoder that
could be reconfigured on-the-fly to reduce CPU usage at the cost of displaying
blurier images.  That can't be part of the public interface because it's
codec-specific, but I could imagine updating some kind of "output_quality"
AVOption as a user slides a slider up and down.

But the CLI tools are largely non-interactive, so have I just misunderstood?

How about saying "AVOptions is a framework for command-line options"?

[1] https://ffmpeg.org/doxygen/trunk/structSwrContext.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".


Re: [FFmpeg-devel] [PATCH v4 1/4] doc: Explain what "context" means

2024-05-29 Thread Andrew Sayers
On Tue, May 28, 2024 at 07:24:55PM +0200, Stefano Sabatini wrote:
> 
> I think we start with different assumptions: you assume that most of
> the readers are familiar with OOP jargon, and that they will leverage
> the OOP jargon to understand the FFmpeg API. I think this is

Not exactly.  I'm saying the document has two equally valid use cases:

1. non-OOP developers, who need us to add new information to their brains
2. OOP developers, who need us to replace existing information in their brains

So it's not a matter of "leveraging OOP" jargon so much as "calling out
OOP assumptions".  For example, I originally assumed AVClass was to FFmpeg
as the Object struct[1] is to GObject, and struggled to take anything onboard
until that been explicitly debunked.  You may even be able to see that
opinion gradually eroding in each rewrite of the context document.

But actually, two groups is probably over-simplifying.  Another group would be
people coming from other C projects, who have incompatible ideas about contexts
that would never occur to us.  Or Fortran developers, who (according to the
first link on Google[2]) can be expected to understand modules but not objects.

> misleading: historically what defined FFmpeg is its minimalistic
> approach, in this case we don't want the user, familiar with C, to be
> familiar with OOP in order to use and understand the FFmpeg API, as
> this is simply not necessary as FFmpeg is plain C language.
> 
> In fact, if this might help with some users, this will probably
> confuse all the others. Even more, if we adopt the FFmpeg jargon to
> OOP (using "context") we are adding more confusion, as now the OOP
> reader will have to adopt the FFmpeg jargon applied to OOP.
> 
> My advice is to move all the content to OOP to a dedicated section, or
> to make the references to OOP jargon as less as possible, to not get
> in the way with the non-OOP reader.

Earlier versions of the document probably drew too strong an analogy with OOP,
but I suspect the problem may be simpler in the latest draft.  The majority of
OOP references explain how things are different to OOP - it might be possible
to make these more readable, but they can't be moved or removed, because
replacing information involves calling out the old information first.  Only the
first few OOP references draw the analogy in the positive, aiming to show OOP
devs how this is similar but different.

Given the OOP vs. non-OOP distinction is too simplistic, the solution might be
to start the document with a collection of code samples - a generic C function,
a Python object, a JavaScript event listener, and an FFmpeg sample.  That would
show how "context" is a name for a broad concept you've probably used before,
without singling out OOP.  It would also reinforce the idea of the document as
a buffet of concepts - don't like the OOP example?  Never mind, here are some
procedural ones for you to enjoy.

> 
> > Aside: if FFmpeg had a blog, I could turn this discussion into a great post
> > called something like "reflections on object- vs. context-oriented 
> > development".
> > But the project's voice is more objective than that, so this document is 
> > limited
> > to discussing the subset of issues that relate specifically to the FFmpeg 
> > API.
> 
> One option would be the wiki:
> http://trac.ffmpeg.org/
> 
> but probably a personal blog entry would be better, given that this
> would not be reference material but more as an article (since the API
> and its own philosophy is a moving target).
> 
> > 
> > On Sat, May 25, 2024 at 01:00:14PM +0200, Stefano Sabatini wrote:
> > > > +Some functions fit awkwardly within FFmpeg's context idiom.  For 
> > > > example,
> > > > +av_ambient_viewing_environment_create_side_data() creates an
> > > > +AVAmbientViewingEnvironment context, then adds it to the side-data of 
> > > > an
> > > > +AVFrame context.
> > > 
> > > To go back to this unfitting example, can you state what would be
> > > fitting in this case?
> > 
> > "Awkwardly" probably isn't the right word to use, but that's a language 
> > choice
> > we can come back to.
> > 
> > The problem with FFmpeg's interface isn't that any one part is illogical,
> > it's that different parts of the interface follow incompatible logic.
> > 
> > It's hard to give specific examples, because any given learner's journey 
> > looks
> > like a random walk through the API, and you can always say "well nobody else
> > would have that problem".  But if everyone has a different problem, that 
> > means
> > everyone has *a* problem, even though there's no localised code fix.
> 
> Fine, but can you propose the signature of the functions that you
> would consider optimal in this case?

I think we largely agree on this, but since you ask -

The code solution would be to pick a rule and rewrite the entire codebase to
fit that rule.  I don't have a strong opinion about what the rule is, but one
example might be "the first context parameter to a function must be that

Re: [FFmpeg-devel] [PATCH] avcodec/mediacodec: Add support of dynamic bitrate

2024-05-28 Thread Andrew Sayers
On Mon, May 27, 2024 at 01:49:47PM +0100, Dmitrii Okunev wrote:
> MediaCodec supports parameter "video-bitrate" to change the bitrate
> on fly. This commit add possibility to use it.
> 
> It adds option -bitrate_ctrl_socket to the encoder which makes
> the encoder to create an UNIX socket and listen for messages
> to change the bitrate.
> 
> An example of ffmpeg execution:
> 
> ffmpeg -listen 1 -i rtmp://0.0.0.0:1935/live/myStream -c:v 
> hevc_mediacodec -bitrate_ctrl_socket /run/bitrate.sock -b:v 8M -f rtsp 
> rtsp://127.0.0.1:1935/live/reEncoded
> 
> An example of changing the bitrate to 1000 BPS:
> 
> printf '%016X' 1000 | xxd -r -p | socat -u STDIN UNIX:/run/bitrate.sock

Nitpick: please do s/\* / \*/g on the following lines:

> +const FFAMediaFormat* format_ctx)
> +static int mediacodec_ndk_setParameters(FFAMediaCodec* ctx,
> +const FFAMediaFormat* format_ctx)
> +int (*setParameters)(FFAMediaCodec* codec, const FFAMediaFormat* format);

(found by an in-progress review bot)
___
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 v3 2/3] avfilter/af_volumedetect.c: Add 32bit float audio support

2024-05-28 Thread Andrew Sayers
On Mon, May 20, 2024 at 11:16:05PM +0300, Yigithan Yigit wrote:
> ---
>  libavfilter/af_volumedetect.c | 159 --
>  1 file changed, 133 insertions(+), 26 deletions(-)
> 
> diff --git a/libavfilter/af_volumedetect.c b/libavfilter/af_volumedetect.c
> index 327801a7f9..dbbcd037a5 100644
> --- a/libavfilter/af_volumedetect.c
> +++ b/libavfilter/af_volumedetect.c
> @@ -20,27 +20,51 @@
>  
>  #include "libavutil/channel_layout.h"
>  #include "libavutil/avassert.h"
> +#include "libavutil/mem.h"
>  #include "audio.h"
>  #include "avfilter.h"
>  #include "internal.h"
>  
> +#define MAX_DB_FLT 1024
>  #define MAX_DB 91
> +#define HISTOGRAM_SIZE 0x1
> +#define HISTOGRAM_SIZE_FLT (MAX_DB_FLT*2)
>  
>  typedef struct VolDetectContext {
> -/**
> - * Number of samples at each PCM value.
> - * histogram[0x8000 + i] is the number of samples at value i.
> - * The extra element is there for symmetry.
> - */
> -uint64_t histogram[0x10001];
> +uint64_t* histogram; ///< for integer number of samples at each PCM 
> value, for float number of samples at each dB

Nitpick (from an in-progress review bot): s/\* / \*/
___
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] [RFC 00/13] flvdec/flvenc: add support for enhanced rtmp codecs and multitrack/multichannel

2024-05-28 Thread Andrew Sayers
On Tue, May 21, 2024 at 11:02:09AM +0200, Timo Rothenpieler wrote:
> This is based on the preliminary spec for enhanced rtmp v2:
> https://veovera.org/docs/enhanced/enhanced-rtmp-v2
> 
> The spec is not final, and can still undergo breaking changes, hence this set 
> is purely for comments and review, and not ready to be merged until the final 
> v2 spec is published.
> 
> There are no samples out in the wild yet, so testing interoperability with 
> other software has not happened yet either.
> Specially the two other multitrack modes, where multiple tracks are in the 
> same packet, have not been tested at all, since no software can write such 
> files.
> 
> The set can also be found on GitHub, where ignoring whitespaces makes 
> specially the last patch a lot more readable:
> https://github.com/BtbN/FFmpeg/tree/enhanced-flv
> 

I ran this against a little review bot I'm working on.
Please do s/\* / \*/g on the following:


avformat/flvenc: add support for writing multi track audio

> +static void flv_write_multichannel_header(AVFormatContext* s, 
> AVCodecParameters* par, int64_t ts, int stream_index)


avformat/flvenc: write enhanced rtmp multichannel info for audio with more than 
two channels

> +static void flv_write_multichannel_body(AVFormatContext* s, 
> AVCodecParameters* par)
> +static int flv_get_multichannel_body_size(AVCodecParameters* par)
> +static void flv_write_multichannel_header(AVFormatContext* s, 
> AVCodecParameters* par, int64_t ts)


avformat/flvenc: add enhanced audio codecs

> +static void flv_write_aac_header(AVFormatContext* s, AVCodecParameters* par)


avformat/flvenc: Implement support for multi-track video

> +static void flv_write_codec_header(AVFormatContext* s, AVCodecParameters* 
> par, int64_t ts, int stream_index) {
___
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 v10 12/13] avcodec: add D3D12VA hardware HEVC encoder

2024-05-28 Thread Andrew Sayers
On Wed, May 22, 2024 at 09:26:25AM +0800, tong1.wu-at-intel@ffmpeg.org 
wrote:
> +static int d3d12va_create_encoder_heap(AVCodecContext* avctx)

Nitpick: s/\* / \*/

I'm trying to write typo-detection bot.  This is the only problem it noticed in
this patchset, but more nits incoming elsewhere.
___
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 1/4] doc: Explain what "context" means

2024-05-26 Thread Andrew Sayers
It feels like we've got through most of the mid-level "how FFmpeg works" stuff,
and now we're left with language choices (e.g "options" vs. "introspection")
and philosophical discussions (e.g. the relationship between contexts and OOP).
It's probably best to philosophise first, then come back to language.

This message has been sent as a reply to one specific message, but is actually
springboarding off messages from two sub-threads.  Hopefully that will keep
the big questions contained in one place.

On Sat, May 25, 2024 at 11:49:48AM +0200, Stefano Sabatini wrote:
> What perplexes me is that "context" is not part of the standard OOP
> jargon, so this is probably adding more to the confusion.

This actually speaks to a more fundamental issue about how we learn.
To be clear, everything I'm about to describe applies every human that ever
lived, but starting with this message makes it easier to explain
(for reasons that will hopefully become obvious).

When you ask why "context" is not part of OOP jargon, one could equally ask
why "object" isn't part of FFmpeg jargon.  The document hints at some arguments:
their lifetime stages are different, their rules are enforced at the
language vs. community level, OOP encourages homogenous interfaces while FFmpeg
embraces unique interfaces that precisely suit each use case, and so on.
But the honest answer is much simpler - humans are lazy, and we want the things
we learn today to resemble the things we learnt yesterday.

Put another way - if we had infinite time every day, we could probably write an
object-oriented interface to FFmpeg.  But our time is sadly finite so we stick
with the thing that's proven to work.  Similarly, if our readers had infinite
free time every day, they could probably learn a completely new approach to
programming.  But their time is finite, so they stick to what they know.

That means people reading this document aren't just passively soaking up
information, they're looking for shortcuts that fit their assumptions.
And as anyone that's ever seen a political discussion can tell you,
humans are *really good* at finding shortcuts that fit their assumptions.
For example, when an OOP developer sees the words "alloc" and "init",
they will assume these map precisely to OOP allocators and initializers.  One
reason for the long section about context lifetimes is because it needs to
meet them where they are, then walk them step-by-step to a better place.

Aside: if FFmpeg had a blog, I could turn this discussion into a great post
called something like "reflections on object- vs. context-oriented development".
But the project's voice is more objective than that, so this document is limited
to discussing the subset of issues that relate specifically to the FFmpeg API.


On Sat, May 25, 2024 at 01:00:14PM +0200, Stefano Sabatini wrote:
> > +Some functions fit awkwardly within FFmpeg's context idiom.  For example,
> > +av_ambient_viewing_environment_create_side_data() creates an
> > +AVAmbientViewingEnvironment context, then adds it to the side-data of an
> > +AVFrame context.
> 
> To go back to this unfitting example, can you state what would be
> fitting in this case?

"Awkwardly" probably isn't the right word to use, but that's a language choice
we can come back to.

The problem with FFmpeg's interface isn't that any one part is illogical,
it's that different parts of the interface follow incompatible logic.

It's hard to give specific examples, because any given learner's journey looks
like a random walk through the API, and you can always say "well nobody else
would have that problem".  But if everyone has a different problem, that means
everyone has *a* problem, even though there's no localised code fix.

For sake of argument, let's imagine a user who was a world-leading expert in
Microsoft QBasic in the eighties, then fell into a forty-year coma and woke up
in front of the FFmpeg documentation.  In other words, a highly adept
programmer with zero knowledge of programming conventions more recent than
"a function is a special type of subroutine for returning a value".
Their journey might look like...

1. there's this thing called "context", and some functions "have" contexts
2. sws_init_context() says "Initialize the swscaler context sws_context",
   and `sws_context` is a `SwsContext *`, so I think it has a SwsContext context
3. sws_alloc_context() says "Allocate an empty SwsContext",
   and it returns a `SwsContext *`, so I think it has the same context
   as sws_init_context()
4. avio_alloc_context() and avio_open2() are both variations on this theme,
   so I should look for creative ways to interpret things as "having" contexts
5. av_alloc_format_context() puts the type in the middle of the function name,
   so I should only treat prefixes as a weak signal
6. av_ambient_viewing_environment_create_side_data() allocates like an alloc,
   so I think the return value is the context; but it also operates on AVFrame
   in a way that affects related 

Re: [FFmpeg-devel] [RFC] STF 2025

2024-05-24 Thread Andrew Sayers
On Fri, May 17, 2024 at 03:49:58PM +0200, Michael Niedermayer wrote:
> Hi all
> 
> Before this is forgotten again, better start some dicsussion too early than 
> too late

This comment is inspired by the other subthread, but not directly in reply to 
it.
I'm replying to this post rather than get in the middle of all that...

What happens if someone is hired to do a job that requires access to the ML,
then gets involved in a situation where there's talk of a ban?

If they're banned, does that translate to suspension without pay?  With pay?

Banning such a person would jeopardise future funding - if they aren't banned,
will people be concerned about the apparent conflict of interest?

In a wider sense, hiring a single person to do a job we come to rely on (like
code review) gives the project a bus number of 1.  How would the STF react to
a proposal like "we plan to do XYZ in 2025, but if we don't get funding for
2026, we'll drop Z and spend the time on a transition plan instead"?
___
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 v5 0/4] Explain what "context" means

2024-05-24 Thread Andrew Sayers
On Fri, May 24, 2024 at 03:50:52AM +0200, Michael Niedermayer wrote:
> On Thu, May 23, 2024 at 09:00:39PM +0100, Andrew Sayers wrote:

> > Imagine you wanted to write a system that nudged people to try new codecs.
> > It might say e.g. "you seem to be using H.264, would you like to try H.265?"
> > Implementing that would probably involve a struct like:
> > 
> > struct AVOldNew {
> >   AVClass* old;
> >   AVClass* new;
> > };
> 
> AVClass would describe the internal decoder structures. This would not be
> correct at all in this example.
> Thats like handing a man 2 CAD documents about 2 engines of 2 cars
> 
> If you wanted to suggest to get a tesla instead of a ford. One would have to
> describe the 2 cars and their differences
> thats 2 AVCodecDescriptor maybe

Hmm, yes fair point.  A better example might be a simple linked list:

struct AVClassList {
AVClass* cur;
AVClassList* next;
};

Again, that clearly is a struct that begins with AVClass*, but clearly isn't an
AVClass context structure.

I realise it's a bit of an academic distinction, but IMHO these hypotheticals
suggest it's more accurate to define the term "AVClass context structure"
in terms of usage rather than layout.
___
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 v5 4/4] all: Rewrite documentation for contexts

2024-05-23 Thread Andrew Sayers
Make their documentation more readable and similar to each other,
(hopefully) without changing the meaning.
---
 libavcodec/aac/aacdec.h  |  2 +-
 libavcodec/aacenc.h  |  2 +-
 libavcodec/ac3enc.h  |  2 +-
 libavcodec/amfenc.h  |  2 +-
 libavcodec/atrac.h   |  2 +-
 libavcodec/avcodec.h |  3 ++-
 libavcodec/bsf.h |  2 +-
 libavcodec/cbs.h |  2 +-
 libavcodec/d3d11va.h |  3 +--
 libavcodec/mediacodec.h  |  4 ++--
 libavcodec/pthread_frame.c   |  4 ++--
 libavcodec/qsv.h |  6 --
 libavcodec/sbr.h |  2 +-
 libavcodec/vdpau.h   |  5 +++--
 libavcodec/videotoolbox.h|  5 +++--
 libavfilter/avfilter.h   |  2 +-
 libavformat/avformat.h   |  3 ++-
 libavformat/avio.h   |  3 ++-
 libavutil/audio_fifo.h   |  2 +-
 libavutil/hwcontext.h| 21 -
 libavutil/hwcontext_cuda.h   |  2 +-
 libavutil/hwcontext_d3d11va.h|  4 ++--
 libavutil/hwcontext_d3d12va.h|  6 +++---
 libavutil/hwcontext_drm.h|  2 +-
 libavutil/hwcontext_dxva2.h  |  4 ++--
 libavutil/hwcontext_mediacodec.h |  2 +-
 libavutil/hwcontext_opencl.h |  4 ++--
 libavutil/hwcontext_qsv.h|  4 ++--
 libavutil/hwcontext_vaapi.h  |  4 ++--
 libavutil/hwcontext_vdpau.h  |  2 +-
 libavutil/hwcontext_vulkan.h |  5 +++--
 libavutil/lfg.h  |  3 ++-
 32 files changed, 65 insertions(+), 54 deletions(-)

diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h
index eed53c6c96..87a834797d 100644
--- a/libavcodec/aac/aacdec.h
+++ b/libavcodec/aac/aacdec.h
@@ -253,7 +253,7 @@ typedef struct AACDecDSP {
 } AACDecDSP;
 
 /**
- * main AAC decoding context
+ * Context for decoding AAC
  */
 struct AACDecContext {
 const struct AVClass  *class;
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index d07960620e..3e710c7fac 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -207,7 +207,7 @@ typedef struct AACPCEInfo {
 } AACPCEInfo;
 
 /**
- * AAC encoder context
+ * Context for encoding AAC
  */
 typedef struct AACEncContext {
 AVClass *av_class;
diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
index 5e98ad188b..e5abe0a856 100644
--- a/libavcodec/ac3enc.h
+++ b/libavcodec/ac3enc.h
@@ -153,7 +153,7 @@ typedef struct AC3Block {
 struct PutBitContext;
 
 /**
- * AC-3 encoder private context.
+ * Private context for encoding AC-3
  */
 typedef struct AC3EncodeContext {
 AVClass *av_class;  ///< AVClass used for AVOption
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 2dbd378ef8..184897beeb 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -43,7 +43,7 @@ typedef struct AmfTraceWriter {
 } AmfTraceWriter;
 
 /**
-* AMF encoder context
+* Context for encoding AMF
 */
 
 typedef struct AmfContext {
diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
index 05208bbee6..e760f0384d 100644
--- a/libavcodec/atrac.h
+++ b/libavcodec/atrac.h
@@ -39,7 +39,7 @@ typedef struct AtracGainInfo {
 } AtracGainInfo;
 
 /**
- *  Gain compensation context structure.
+ *  Context for gain compensation
  */
 typedef struct AtracGCContext {
 float   gain_tab1[16];  ///< gain compensation level table
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index abc00ab394..2fed4757ed 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -430,7 +430,8 @@ typedef struct RcOverride{
 #define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0)
 
 /**
- * main external API structure.
+ * Context for an encode or decode session
+ *
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
index ee5fdd48d2..fadcfc5d47 100644
--- a/libavcodec/bsf.h
+++ b/libavcodec/bsf.h
@@ -56,7 +56,7 @@
  */
 
 /**
- * The bitstream filter state.
+ * Context for bitstream filtering
  *
  * This struct must be allocated with av_bsf_alloc() and freed with
  * av_bsf_free().
diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h
index d479b1ac2d..c074dd11ec 100644
--- a/libavcodec/cbs.h
+++ b/libavcodec/cbs.h
@@ -214,7 +214,7 @@ typedef void (*CBSTraceWriteCallback)(void *trace_context,
   int64_t value);
 
 /**
- * Context structure for coded bitstream operations.
+ * Context for coded bitstream operations
  */
 typedef struct CodedBitstreamContext {
 /**
diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
index 686974b083..5ffee2b3be 100644
--- a/libavcodec/d3d11va.h
+++ b/libavcodec/d3d11va.h
@@ -46,8 +46,7 @@
  */
 
 /**
- * This structure is used to provides the necessary configurations and data
- * to the Direct3D11 FFmpeg HWAccel implementation.
+ * Context for the Direct3D11 FFmpeg HWAccel implementation
  *
  * The application must make it available as 

[FFmpeg-devel] [PATCH v5 3/4] all: Link to "context" from all public contexts with documentation

2024-05-23 Thread Andrew Sayers
The goal of putting these links in "@see" blocks is to provide hooks
for future developers to add links to other useful parts of the codebase.
---
 libavcodec/avcodec.h | 3 +++
 libavcodec/bsf.h | 3 +++
 libavcodec/d3d11va.h | 3 +++
 libavcodec/mediacodec.h  | 2 ++
 libavcodec/qsv.h | 3 +++
 libavcodec/vdpau.h   | 3 +++
 libavcodec/videotoolbox.h| 3 +++
 libavfilter/avfilter.h   | 7 ++-
 libavformat/avformat.h   | 3 +++
 libavformat/avio.h   | 3 +++
 libavutil/audio_fifo.h   | 3 +++
 libavutil/hwcontext.h| 6 ++
 libavutil/hwcontext_cuda.h   | 3 +++
 libavutil/hwcontext_d3d11va.h| 6 ++
 libavutil/hwcontext_d3d12va.h| 6 ++
 libavutil/hwcontext_drm.h| 3 +++
 libavutil/hwcontext_dxva2.h  | 6 ++
 libavutil/hwcontext_mediacodec.h | 3 +++
 libavutil/hwcontext_opencl.h | 6 ++
 libavutil/hwcontext_qsv.h| 6 ++
 libavutil/hwcontext_vaapi.h  | 6 ++
 libavutil/hwcontext_vdpau.h  | 3 +++
 libavutil/hwcontext_vulkan.h | 6 ++
 libavutil/lfg.h  | 3 +++
 24 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 2da63c87ea..abc00ab394 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -441,6 +441,9 @@ typedef struct RcOverride{
  * The AVOption/command line parameter names differ in some cases from the C
  * structure field names for historic reasons or brevity.
  * sizeof(AVCodecContext) must not be used outside libav*.
+ *
+ * @see
+ * - @ref Context
  */
 typedef struct AVCodecContext {
 /**
diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
index a09c69f242..ee5fdd48d2 100644
--- a/libavcodec/bsf.h
+++ b/libavcodec/bsf.h
@@ -64,6 +64,9 @@
  * The fields in the struct will only be changed (by the caller or by the
  * filter) as described in their documentation, and are to be considered
  * immutable otherwise.
+ *
+ * @see
+ * - @ref Context
  */
 typedef struct AVBSFContext {
 /**
diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
index 27f40e5519..686974b083 100644
--- a/libavcodec/d3d11va.h
+++ b/libavcodec/d3d11va.h
@@ -52,6 +52,9 @@
  * The application must make it available as AVCodecContext.hwaccel_context.
  *
  * Use av_d3d11va_alloc_context() exclusively to allocate an AVD3D11VAContext.
+ *
+ * @see
+ * - @ref Context
  */
 typedef struct AVD3D11VAContext {
 /**
diff --git a/libavcodec/mediacodec.h b/libavcodec/mediacodec.h
index 4e9b56a618..43f049a609 100644
--- a/libavcodec/mediacodec.h
+++ b/libavcodec/mediacodec.h
@@ -29,6 +29,8 @@
  * This structure holds a reference to a android/view/Surface object that will
  * be used as output by the decoder.
  *
+ * @see
+ * - @ref Context
  */
 typedef struct AVMediaCodecContext {
 
diff --git a/libavcodec/qsv.h b/libavcodec/qsv.h
index c156b08d07..8ab93af6b6 100644
--- a/libavcodec/qsv.h
+++ b/libavcodec/qsv.h
@@ -32,6 +32,9 @@
  * - decoding: hwaccel_context must be set on return from the get_format()
  * callback
  * - encoding: hwaccel_context must be set before avcodec_open2()
+ *
+ * @see
+ * - @ref Context
  */
 typedef struct AVQSVContext {
 /**
diff --git a/libavcodec/vdpau.h b/libavcodec/vdpau.h
index 8021c25761..934c96b88c 100644
--- a/libavcodec/vdpau.h
+++ b/libavcodec/vdpau.h
@@ -74,6 +74,9 @@ typedef int (*AVVDPAU_Render2)(struct AVCodecContext *, 
struct AVFrame *,
  *
  * The size of this structure is not a part of the public ABI and must not
  * be used outside of libavcodec.
+ *
+ * @see
+ * - @ref Context
  */
 typedef struct AVVDPAUContext {
 /**
diff --git a/libavcodec/videotoolbox.h b/libavcodec/videotoolbox.h
index d68d76e400..81d90d63b6 100644
--- a/libavcodec/videotoolbox.h
+++ b/libavcodec/videotoolbox.h
@@ -53,6 +53,9 @@
  * between the caller and libavcodec for initializing Videotoolbox decoding.
  * Its size is not a part of the public ABI, it must be allocated with
  * av_videotoolbox_alloc_context() and freed with av_free().
+ *
+ * @see
+ * - @ref Context
  */
 typedef struct AVVideotoolboxContext {
 /**
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index a34e61f23c..25ccd80433 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -403,7 +403,12 @@ unsigned avfilter_filter_pad_count(const AVFilter *filter, 
int is_output);
  */
 #define AVFILTER_THREAD_SLICE (1 << 0)
 
-/** An instance of a filter */
+/**
+ * An instance of a filter
+ *
+ * @see
+ * - @ref Context
+ */
 struct AVFilterContext {
 const AVClass *av_class;///< needed for av_log() and filters 
common options
 
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 8afdcd9fd0..18f20f0bb0 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1253,6 +1253,9 @@ enum AVDurationEstimationMethod {
  * can be found in libavformat/options_table.h.
  * The AVOption/command line 

[FFmpeg-devel] [PATCH v5 2/4] lavu: Clarify relationship between AVClass, AVOption and context

2024-05-23 Thread Andrew Sayers
---
 libavutil/log.h | 16 +---
 libavutil/opt.h | 17 ++---
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/libavutil/log.h b/libavutil/log.h
index ab7ceabe22..d599ab506e 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -59,9 +59,19 @@ typedef enum {
 struct AVOptionRanges;
 
 /**
- * Describe the class of an AVClass context structure. That is an
- * arbitrary struct of which the first field is a pointer to an
- * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.).
+ * Generic Logging and introspection facilities
+ *
+ * Logging and introspection functions expect to be passed structs
+ * whose first member is a pointer-to-@ref AVClass.
+ *
+ * Structs that only use the logging facilities are often referred to as
+ * "AVClass context structures", while those that use introspection facilities
+ * are called "AVOptions-enabled structs".
+ *
+ * @see
+ * * @ref lavu_log
+ * * @ref avoptions
+ * * @ref Context
  */
 typedef struct AVClass {
 /**
diff --git a/libavutil/opt.h b/libavutil/opt.h
index 07e27a9208..b14c120e36 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -39,9 +39,16 @@
  * @defgroup avoptions AVOptions
  * @ingroup lavu_data
  * @{
- * AVOptions provide a generic system to declare options on arbitrary structs
- * ("objects"). An option can have a help text, a type and a range of possible
- * values. Options may then be enumerated, read and written to.
+ *
+ * Generic introspection facilities for AVClass context structures
+ *
+ * Provides a generic system to declare and manage options on any struct
+ * whose first member is a pointer-to-@ref AVClass.  Structs with private
+ * contexts can use that AVClass to return further @ref AVClass "AVClass"es
+ * that enable introspection of the private structs.
+ *
+ * Each option can have a help text, a type and a range of possible values.
+ * Options may be enumerated, read and written to.
  *
  * There are two modes of access to members of AVOption and its child structs.
  * One is called 'native access', and refers to access from the code that
@@ -53,6 +60,10 @@
  * question is allowed to access the field. This allows us to extend the
  * semantics of those fields without breaking API compatibility.
  *
+ * @see
+ * * @ref lavu_log
+ * * @ref Context
+ *
  * @section avoptions_scope Scope of AVOptions
  *
  * AVOptions is designed to support any set of multimedia configuration options
-- 
2.43.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 v5 1/4] doc: Explain what "context" means

2024-05-23 Thread Andrew Sayers
Derived from explanations kindly provided by Stefano Sabatini and others:
https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325903.html
---
 doc/context.md | 439 +
 1 file changed, 439 insertions(+)
 create mode 100644 doc/context.md

diff --git a/doc/context.md b/doc/context.md
new file mode 100644
index 00..21469a6e58
--- /dev/null
+++ b/doc/context.md
@@ -0,0 +1,439 @@
+@page Context Introduction to contexts
+
+@tableofcontents
+
+“Context” is a name for a widely-used programming idiom.
+This document explains the general idiom and some conventions used by FFmpeg.
+
+This document uses object-oriented analogies for readers familiar with
+[object-oriented 
programming](https://en.wikipedia.org/wiki/Object-oriented_programming).
+But contexts can also be used outside of OOP, and even in situations where OOP
+isn't helpful.  So these analogies should only be used as a rough guide.
+
+@section Context_general “Context” as a general concept
+
+Many projects use some kind of “context” idiom.  You can safely skip this
+section if you have used contexts in another project.  You might also prefer to
+read @ref Context_comparison before continuing with the rest of the document.
+
+@subsection Context_think “Context” as a way to think about code
+
+A context is any data structure that is passed to several functions
+(or several instances of the same function) that all operate on the same 
entity.
+For example, [object-oriented 
programming](https://en.wikipedia.org/wiki/Object-oriented_programming)
+languages usually provide member functions with a `this` or `self` value:
+
+```python
+# Python methods (functions within classes) must start with an object argument,
+# which does a similar job to a context:
+class MyClass:
+def my_func(self):
+...
+```
+
+Contexts can also be used in C-style procedural code.  If you have ever written
+a callback function, you have probably used a context:
+
+```c
+struct FileReader {
+FILE* file;
+};
+
+int my_callback(void *my_var_, uint8_t* buf, int buf_size) {
+
+// my_var provides context for the callback function:
+struct FileReader *my_var = (struct FileReader *)my_var_;
+
+return read(my_var->file, sizeof(*buf), buf_size);
+}
+
+void init() {
+
+struct FileReader my_var;
+my_var->file = fopen("my-file", "rb");
+
+register_callback(my_callback, _var);
+
+...
+
+fclose( my_var->file );
+
+}
+```
+
+In the broadest sense, a context is just a way to think about some code.
+You can even use it to think about code written by people who have never
+heard the term, or who would disagree with you about what it means.
+But when FFmpeg developers say “context”, they're usually talking about
+a more specific set of conventions.
+
+@subsection Context_communication “Context” as a tool of communication
+
+“Context“ can just be a word to understand code in your own head,
+but it can also be a term you use to explain your interfaces.
+Here is a version of the callback example that makes the context explicit:
+
+```c
+struct FileReaderContext {
+FILE *file;
+};
+
+int my_callback(void *ctx_, uint8_t *buf, int buf_size) {
+
+// ctx provides context for the callback function:
+struct FileReaderContext *ctx = (struct FileReaderContext *)ctx_;
+
+return read(ctx->file, sizeof(*buf), buf_size);
+}
+
+void init() {
+
+struct FileReader ctx;
+ctx->file = fopen("my-file", "rb");
+
+register_callback(my_callback, );
+
+...
+
+fclose( ctx->file );
+
+}
+```
+
+The difference here is subtle, but important.  If a piece of code
+*appears compatible with contexts*, then you are *allowed to think
+that way*, but if a piece of code *explicitly states it uses
+contexts*, then you are *required to follow that approach*.
+
+For example, take a look at avio_alloc_context().
+The function name and return value both state it uses contexts,
+so failing to follow that approach is a bug you can report.
+But its arguments are a set of callbacks that merely appear compatible with
+contexts, so it's fine to write a `read_packet` function that just reads
+from standard input.
+
+When a programmer says their code is "a context", they're guaranteeing
+to follow a set of conventions enforced by their community - for example,
+the FFmpeg community enforces that contexts have separate allocation,
+configuration, and initialization steps.  That's different from saying
+their code is "an object", which normally guarantees to follow conventions
+enforced by their programming language (e.g. using a constructor function).
+
+@section Context_ffmpeg FFmpeg contexts
+
+This section discusses specific context-related conventions used in FFmpeg.
+Some of these are used in other projects, others are unique to this project.
+
+@subsection Context_naming Naming: “Context” and “ctx”
+
+```c
+// Context struct names usually end with `Context`:
+struct AVSomeContext {
+  ...
+};
+
+// Functions are 

[FFmpeg-devel] [PATCH v5 0/4] Explain what "context" means

2024-05-23 Thread Andrew Sayers
NOTE: this patchset depends on [1], and should not be applied before that.

I think it's important to guide readers between parts of FFmpeg, because
learning how the pieces of the puzzle fit together is a big part of the
newbie experience.  So this patchset replaces the "@ref Context for foo"
statements in public structs with "@see" blocks, giving us a hook we can
hang more links on in future.

That said, there's a rule against internal links from private structs,
so I've removed the @ref's from them.  By the way, is this rule written
somewhere?  If not, where would be a good place to write it?
And either way, it would be good to link to this as part of [2].

Previous patches had to change the language for many structs, but "@see" blocks
avoid the need to include those changes in this patchset.  Rather than waste
that work, I've temporarily moved those changes to the final patch in this set.
My feelings about that last patch aren't strong, but I guess I'll propose them
in a separate thread unless anyone wants them here or chucked altogether.


I've rewritten AVOptions and AVClass based on feedback.  The new version
reflects a hypothetical that's been going round my head all week...

Imagine you wanted to write a system that nudged people to try new codecs.
It might say e.g. "you seem to be using H.264, would you like to try H.265?"
Implementing that would probably involve a struct like:

struct AVOldNew {
  AVClass* old;
  AVClass* new;
};

That's a struct that begins with an AVClass*, but is clearly not an AVClass
context structure.  So the new version defines "AVClass context structure" and
"AVOptions-enabled struct" in terms of the way the structs are used instead of
their layout, which should be more useful and accurate to current practice,
while remaining compatible(ish) with the way the words are used in conversation.


I mentioned hwaccels in a previous message.  From another look around the code,
I think these are supposed to be completely invisible to an external API dev.
If not, please point me in the direction of any documentation I missed.

[1] https://ffmpeg.org/pipermail/ffmpeg-devel/2024-May/327958.html
[2] https://ffmpeg.org/pipermail/ffmpeg-devel/2024-May/327624.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".


Re: [FFmpeg-devel] [PATCH v4 4/4] lavf: Add documentation for private "Context" classes

2024-05-22 Thread Andrew Sayers
On Wed, May 22, 2024 at 05:24:36PM +0200, Andreas Rheinhardt wrote:
> These structures should be renamed instead of adding these comments
> (which are pointless for internal developers). I just sent a patch for that.
> Thanks for pointing out the issue.

Oh, great!  So the next version of this patchset will skip this patch,
and will reduce links like this:

> + * @brief @ref md_doc_2context "Context" for a cache

down to:

> + * @brief @ref Context for a cache

I don't see a way of removing the "@ref" without doing something nasty,
like making a fake "Context" struct and shoving the documentation in there.

Also, if someone does something strange like this:

> + * @brief @ref Context "structure" (actually an enum)

doxygen won't render it the way the author expects.  I don't expect that to
happen much in the real world though.
___
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 1/4] doc: Explain what "context" means

2024-05-22 Thread Andrew Sayers
On Wed, May 22, 2024 at 11:31:52AM +0200, Stefano Sabatini wrote:
> Sorry for the slow reply.

Welcome back :)

I've gathered some critiques of my own over the past week, which I'll pepper
throughout the reply.  Starting with...

The document assumes (or is at least designed to be secure against) readers
starting at the top and reading through to the bottom.  I found doxygen's
@tableofcontents command while writing this e-mail, which I will definitely
use in the next version, and which might provoke a rewrite aimed at people
jumping around the document looking for answers to specific questions.

> 
> On date Wednesday 2024-05-15 16:54:19 +0100, Andrew Sayers wrote:
> > Derived from detailed explanations kindly provided by Stefano Sabatini:
> > https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325903.html
> > ---
> >  doc/context.md | 394 +
> >  1 file changed, 394 insertions(+)
> >  create mode 100644 doc/context.md
> > 
> > diff --git a/doc/context.md b/doc/context.md
> > new file mode 100644
> > index 00..fb85b3f366
> > --- /dev/null
> > +++ b/doc/context.md
> > @@ -0,0 +1,394 @@
> > +# Introduction to contexts
> > +
> > +%Context
> 
> Is this style of quoting needed? Especially I'd avoid special markup
> to simplify unredendered text reading (which is the point of markdown
> afterall).

Short answer: I'll change it in the next patch and see what happens.

Long answer: HTML quotes are ugly for everyone, UTF-8 is great until someone
turns up complaining we broke their Latin-1 workflow.  I've always preferred
ASCII-only representations for that reason, but happy to try the other way
and see if anyone still cares.

> 
> > is a name for a widely-used programming idiom.
> 
> > +This document explains the general idiom and the conventions FFmpeg has 
> > built around it.
> > +
> > +This document uses object-oriented analogies to help readers familiar with
> > +[object-oriented 
> > programming](https://en.wikipedia.org/wiki/Object-oriented_programming)
> > +learn about contexts.  But contexts can also be used outside of OOP,
> > +and even in situations where OOP isn't helpful.  So these analogies
> > +should only be used as a first step towards understanding contexts.
> > +
> > +## Context as a way to think about code
> > +
> > +A context is any data structure that is passed to several functions
> > +(or several instances of the same function) that all operate on the same 
> > entity.
> > +For example, [object-oriented 
> > programming](https://en.wikipedia.org/wiki/Object-oriented_programming)
> > +languages usually provide member functions with a `this` or `self` value:
> > +
> 
> > +```c
> > +class my_cxx_class {
> > +  void my_member_function() {
> > +// the implicit object parameter provides context for the member 
> > function:
> > +std::cout << this;
> > +  }
> > +};
> > +```
> 
> I'm not convinced this is really useful: if you know C++ this is
> redundant, if you don't this is confusing and don't add much information.

The example is there to break up a wall of text (syntax-highlighted in the
rendered output), and to let the reader know that this is going to be one of
those documents that alternates between text and code, so they're ready for the
more substantive examples later on.  I take the point about C++ though -
would this Python example be more readable?

class MyClass:
def my_func(self):
# If a Python function is part of a class,
# its first parameter must be an instance of that class

> 
> > +
> > +Contexts are a fundamental building block of OOP, but can also be used in 
> > procedural code.
> 
> I'd drop this line, and drop the anchor on OOP at the same time since
> it's adding no much information.

Fundamentally, this document addresses two audiences:

1. people coming from a non-OOP background, who want to learn contexts
   from first principles, and at best see OOP stuff as background information

2. people coming from an OOP background.  There's no polite way to say this -
   their incentive is to write FFmpeg off as a failed attempt at OOP, so they
   don't have to learn a new way of working that's just different enough to
   make them feel dumb

I think a good way to evaluate the document might be to read it through twice,
stopping after each paragraph to ask two unfair questions...

1. what has this told me about FFmpeg itself, as opposed to some other thing
   you wish I cared about?

2. couldn't you have just done this the standard OOP way?

The earlier paragraph acknowledged that contexts resemble OOP (telling the OOP
audience we g

Re: [FFmpeg-devel] [PATCH v4 4/4] lavf: Add documentation for private "Context" classes

2024-05-22 Thread Andrew Sayers
On Wed, May 22, 2024 at 12:08:29PM +0200, Stefano Sabatini wrote:
> On date Wednesday 2024-05-15 16:54:22 +0100, Andrew Sayers wrote:
> > Doxygen thinks any text like "Context for foo" is a link to a struct called 
> > "Context".
> > Add a description and a better link, to avoid confusing readers.
> > ---
> >  libavformat/async.c | 3 +++
> >  libavformat/cache.c | 3 +++
> >  2 files changed, 6 insertions(+)
> > 
> > diff --git a/libavformat/async.c b/libavformat/async.c
> > index e096b0bc6f..3c28d418ae 100644
> > --- a/libavformat/async.c
> > +++ b/libavformat/async.c
> > @@ -53,6 +53,9 @@ typedef struct RingBuffer
> >  int   read_pos;
> >  } RingBuffer;
> >  
> > +/**
> > + * @brief @ref md_doc_2context "Context" for testing async
> > + */
> >  typedef struct Context {
> >  AVClass*class;
> >  URLContext *inner;
> > diff --git a/libavformat/cache.c b/libavformat/cache.c
> > index 5f78adba9d..3cc0edec82 100644
> > --- a/libavformat/cache.c
> > +++ b/libavformat/cache.c
> > @@ -52,6 +52,9 @@ typedef struct CacheEntry {
> >  int size;
> >  } CacheEntry;
> >  
> > +/**
> > + * @brief @ref md_doc_2context "Context" for a cache
> > + */
> >  typedef struct Context {
> >  AVClass *class;
> >  int fd;
> 
> Not sure, these are private structs and we enforce no use of internal
> markup for those, and we can assume internals developers are already
> acquainted with contexts and such so this is probably adding no value.

Ah, yeah the use case isn't obvious if you haven't tripped over it...

Imagine you're a new user trying to learn FFmpeg, and you find yourself at
https://ffmpeg.org/doxygen/trunk/structAVAudioFifo.html - the first word
appears to be a link for this "context" thing you've been hearing about[1],
so you drop what you're doing to investigate.  It links you to a struct that
looks promisingly general, but eventually turns out to be some random internal
struct with a misleading name.  Now you've wasted a bunch of time and forgotten
what you were doing.

The other patch fixes the examples I've found in the code, but doxygen links
all instances of the word "Context" to this struct, confusing newbies.  This
patch ensures that when future developers say "Context" in a comment, the page
doxygen links them to will point them in the right direction.

I had previously assumed it was a deliberate decision to include private files
in the documentation, so I didn't look that carefully into workarounds that
would break links to these private structures.  But you've implied elsewhere
that's not the case, so is it worth looking into solutions that made "Context"
link to the context document, at the cost of making it impossible to link to
these private structs at all?

[1] to be clear, this is the current behaviour of the page on the live site
___
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 v3 1/3] doc: Explain what "context" means

2024-05-22 Thread Andrew Sayers
On Wed, May 22, 2024 at 12:37:37PM +0200, Stefano Sabatini wrote:
> On date Sunday 2024-05-05 22:04:36 +0100, Andrew Sayers wrote:
> > I'm still travelling, so the following thoughts might be a bit
> > half-formed.  But I wanted to get some feedback before sitting down
> > for a proper think.
> [...]
> > > > I've also gone through the code looking for edge cases we haven't 
> > > > covered.
> > > > Here are some questions trying to prompt an "oh yeah I forgot to mention
> > > > that"-type answer.  Anything where the answer is more like "that should
> > > > probably be rewritten to be clearer", let me know and I'll avoid 
> > > > confusing
> > > > newbies with it.
> > > > 
> > > 
> > > > av_ambient_viewing_environment_create_side_data() takes an AVFrame as 
> > > > its
> > > > first argument, and returns a new AVAmbientViewingEnvironment.  What is 
> > > > the
> > > > context object for that function - AVFrame or 
> > > > AVAmbientViewingEnvironment?
> > > 
> > > But this should be clear from the doxy:
> > > 
> > > /**
> > >  * Allocate and add an AVAmbientViewingEnvironment structure to an 
> > > existing
> > >  * AVFrame as side data.
> > >  *
> > >  * @return the newly allocated struct, or NULL on failure
> > >  */
> > > AVAmbientViewingEnvironment 
> > > *av_ambient_viewing_environment_create_side_data(AVFrame *frame);
> > 
> > I'm afraid it's not clear, at least to me.  I think you're saying the
> > AVFrame is the context because a "create" function can't have a
> > context any more than a C++ "new" can be called as a member.  But the
> > function's prefix points to the other conclusion, and neither signal
> > is clear enough on its own.
> 
> No, what I'm saying is that in some cases you don't need to think in
> terms of contexts, in this case there is no context at all, the
> function takes a frame and modify it, and returns the ambient
> environment to be used by the following functions. This should be very
> clear by reading the doxy. There is no rule dictating the first param
> of each FFmpeg function should be a "context".

I'm still writing up a reply to your longer feedback, but on this topic...

This function is in the "av_ambient_viewing_environment" namespace, and returns
an object that is clearly used as a context for other functions.  So saying
"stop thinking about contexts" just leaves a negative space and a bad thing
to fill it with (confusion in my case).

I've found it useful to think about "receiving" vs. "producing" a context:

* avcodec_alloc_context3() produces a context, but does not receive one
* sws_init_context() receives a context, but does not produce one
* av_ambient_viewing_environment_create_side_data() receives one context,
  and produces another

How about if the document mostly talks about functions as having contexts,
then follows it up with something like:

There are some edge cases where this doesn't work.  .
If you find contexts a useful metaphor in these cases, you might
prefer to think about them as "receiving" and "producing" contexts.

... or something similar that acknowledges contexts are unnecessary here,
but provides a solution for people that want to use them anyway.
___
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 v9 11/13] avutil/hwcontext_d3d12va: add Flags for resource creation

2024-05-21 Thread Andrew Sayers
(Only reviewing documentation, not code)

On Mon, May 20, 2024 at 10:52:20PM +0800, tong1.wu-at-intel@ffmpeg.org 
wrote:
> From: Tong Wu 
> 
> Flags field is added to support diffferent resource creation.
> 
> Signed-off-by: Tong Wu 
> ---
>  doc/APIchanges| 3 +++
>  libavutil/hwcontext_d3d12va.c | 2 +-
>  libavutil/hwcontext_d3d12va.h | 8 
>  libavutil/version.h   | 2 +-
>  4 files changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/doc/APIchanges b/doc/APIchanges
> index 269fd36559..808ba02f2d 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2024-03-07
>  
>  API changes, most recent first:
>  
> +2024-01-xx - xx - lavu 59.20.100 - hwcontext_d3d12va.h
> + Add AVD3D12VAFramesContext.flags
> +
>  2024-05-xx - xx - lavu 59.19.100 - hwcontext_qsv.h
>Add AVQSVFramesContext.info
>  
> diff --git a/libavutil/hwcontext_d3d12va.c b/libavutil/hwcontext_d3d12va.c
> index cfc016315d..6507cf69c1 100644
> --- a/libavutil/hwcontext_d3d12va.c
> +++ b/libavutil/hwcontext_d3d12va.c
> @@ -247,7 +247,7 @@ static AVBufferRef *d3d12va_pool_alloc(void *opaque, 
> size_t size)
>  .Format   = hwctx->format,
>  .SampleDesc   = {.Count = 1, .Quality = 0 },
>  .Layout   = D3D12_TEXTURE_LAYOUT_UNKNOWN,
> -.Flags= D3D12_RESOURCE_FLAG_NONE,
> +.Flags= hwctx->flags,
>  };
>  
>  frame = av_mallocz(sizeof(AVD3D12VAFrame));
> diff --git a/libavutil/hwcontext_d3d12va.h b/libavutil/hwcontext_d3d12va.h
> index ff06e6f2ef..608dbac97f 100644
> --- a/libavutil/hwcontext_d3d12va.h
> +++ b/libavutil/hwcontext_d3d12va.h
> @@ -129,6 +129,14 @@ typedef struct AVD3D12VAFramesContext {
>   * If unset, will be automatically set.
>   */
>  DXGI_FORMAT format;
> +
> +/**
> + * This field is used to specify options for working with resources.
> + * If unset, this will be D3D12_RESOURCE_FLAG_NONE.
> + *
> + * @see: 
> https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_resource_flags.
> + */
> +D3D12_RESOURCE_FLAGS flags;

Some nitpicks:

* "This field is used to specify" is redundant, you can save the reader
  a few seconds by starting the sentence with just "Options..."
* "@see" starts a paragraph, so the rendered documentation will look better
  without the ":"
* the full stop after the URL makes it harder to copy/paste the text -
  remove the full stop or use a [markdown link](...)
___
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] [RFC] STF 2025

2024-05-19 Thread Andrew Sayers
On Sun, May 19, 2024 at 01:29:43PM +0200, Thilo Borgmann via ffmpeg-devel wrote:
> 
> [...]
> > > * Fund administrative / maintainance work (one example is the mailman 
> > > upgrade that is needed
> > >   with the next OS upgrade on one of our servers (this is not as trivial 
> > > as one might
> > >   expect). Another example here may be some git related tools if we find 
> > > something that
> > >   theres a broad consensus about.
> > 
> > I agree that this should be paid but I would expect that STF would not be 
> > too keen on it, not that I'd know really.
> 
> We should absolutely pay for such activity and STF is very well willing to
> fund such things.
> 
> 
> > > * Fund maintaince on the bug tracker, try to reproduce bugs, ask users to 
> > > provide
> > >   reproduceable cases, close bugs still unreproduceable, ...
> > >   ATM we have over 2000 "new" bugs that are not even marked as open
> > 
> > This is a double-edged sword. If somebody gets paid to do that, then that 
> > is one more reason for others not to do it.
> > 
> > And again, it is completely reasonable to be paid for that, and also for 
> > code reviews and writing test cases (if we want to complete the menial task 
> > list), but I am perplexed as to STF's stance on that.
> 
> Same as above about that we should and STF would. Especially since no
> corporate interest usually pays anyone for these tasks (in case of reviews
> it might of course be considered a good thing).
> 
> The one problem to solve here AFAICT is we don't know exactly what quantity
> of bugs, reviewable code submissions and other maintenance work will come up
> in the next 12 months.
> So it renders impossible to define in prior the workload, milestones and
> compensation per contributor interested as we did this year for well-defined
> tasks.
> 
> What we should consider IMO is defining the tasks (patch review, bug review
> & fix, FATE extensions, checkasm extensions, etc. as well such things for
> the administrative tasks from above) and defining a budget for these tasks.
> Then, allow 'everyone interested' (aka git push access?) to claim a part of
> that budget every N-months, depending what the corresponding contributor
> actually did and can somehow be determined.

Another solution would be to have a variable-sized primary task, with a
secondary task that can absorb leftover time.  For example, if your primary
task was reviewing patches, your secondary task might be improving the patch
review process.  So when you get to the point where you'd rather let someone
else claim a bounty than say "fix your indentation" one more time, your
incentive is instead to write a tutorial, or a review bot, or otherwise get to
the root cause.
___
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] doc/developer: add examples to clarify code style

2024-05-18 Thread Andrew Sayers
I would have found this very helpful!

On Sat, May 18, 2024 at 07:00:50PM +0200, Marvin Scholz wrote:
> Given the frequency that new developers, myself included, get the
> code style wrong, it is useful to add some examples to clarify how
> things should be done.
> ---
>  doc/developer.texi | 57 +-
>  1 file changed, 56 insertions(+), 1 deletion(-)
> 
> diff --git a/doc/developer.texi b/doc/developer.texi
> index 63835dfa06..d7bf3f9cb8 100644
> --- a/doc/developer.texi
> +++ b/doc/developer.texi
> @@ -115,7 +115,7 @@ Objective-C where required for interacting with 
> macOS-specific interfaces.
>  
>  @section Code formatting conventions
>  
> -There are the following guidelines regarding the indentation in files:
> +There are the following guidelines regarding the code style in files:
>  
>  @itemize @bullet
>  @item
> @@ -135,6 +135,61 @@ K coding style is used.
>  @end itemize
>  The presentation is one inspired by 'indent -i4 -kr -nut'.
>  
> +@subsection Examples
> +Some notable examples to illustrate common code style in FFmpeg:
> +
> +@itemize @bullet
> +
> +@item
> +Spaces around @code{if}/@code{do}/@code{while}/@code{for} conditions and 
> assigments:

s/assigments/assignments/

Also, this might be more readable as "Space around assignments and after
@code{if}... keywords"?  On first pass, I assumed this was telling me
`( condition )` is correct, then had to re-read when the example showed
it wasn't.

> +
> +@example c
> +if (condition)

`condition` here differs from `cond` below, despite conveying the same meaning.
Either word is fine so long as it's the same word in both places.

> +av_foo();
> +@end example
> +
> +@example c
> +for (size_t i = 0; i < len; i++)

This lightly implies we prefer `i < len` over `i != len` and `i++` over `++i`.
Is that something people round here have strong opinions about?  Maybe iterate
over a linked list if this is a controversial question?

> +av_bar(i);
> +@end example
> +
> +@example c
> +size_t size = 0;
> +@end example
> +
> +However no spaces between the parentheses and condition, unless it helps
> +readability of complex conditions, so the following should not be done:
> +
> +@example c
> +// Wrong:

Nitpick: if you're going to say "// Wrong" here, it might be better to introduce
the mechanism with some "// Good"s or something above.  The consistency reduces
cognitive load on the learner, and it's a good excuse to add a little positivity
to a nerve-wracking experience.

> +if ( cond )
> +av_foo();
> +@end example
> +
> +@item
> +No unnecessary parentheses, unless it helps readability:
> +
> +@example c
> +flags = s->mb_x ? RIGHT_EDGE : LEFT_EDGE | RIGHT_EDGE;
> +@end example

Can the example use "+" or "*" instead of "|"?  I've had so many bugs where
I got the precedence wrong, I'm not sure whether this is supposed to be a good
or bad example of readability.

> +
> +@item
> +No braces around single-line blocks:
> +
> +@example c
> +if (bits_pixel == 24)
> +avctx->pix_fmt = AV_PIX_FMT_BGR24;
> +else if (bits_pixel == 8)
> +avctx->pix_fmt = AV_PIX_FMT_GRAY8;
> +else @{
> +av_log(avctx, AV_LOG_ERROR, "Invalid pixel format.\n");
> +return AVERROR_INVALIDDATA;
> +@}
> +@end example
> +
> +@end itemize
> +
> +
>  @subsection Vim configuration
>  In order to configure Vim to follow FFmpeg formatting conventions, paste
>  the following snippet into your @file{.vimrc}:

Some other things that could help (in decreasing order of importance)...

* if you find a piece of code that looks wrong, should you...
  a) ignore the guide and match your style to the surroundings?
  b) follow the guide and accept the file will look inconsistent?
  c) add an extra patch to fix the formatting?

(I suspect the answer is (b), but could well be wrong)

* example of brace style for both functions and structs
  (as a newbie you don't know if you're about to meet one of those people
  who get all bent out of shape when they see a bracket on a line on its own
  )

* prefer `foo=bar; if (foo)` over `if ((foo=bar))`
  (the latter is sadly used in the code, but is a speedbump for reviewers)

* `foo *bar`, not `foo* bar`
  (I always forget this, not important if it's just me)

Also, way outside the scope of this patch, but a linter that checks these things
would be very much appreciated.  There's a lot to get wrong with your first 
patch,
and a program that just said "yep that's formatted correctly" might save a 
newbie
enough time to learn git-send-email instead.
___
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] [RFC] STF 2025

2024-05-17 Thread Andrew Sayers
On Fri, May 17, 2024 at 03:49:58PM +0200, Michael Niedermayer wrote:
> Hi all
> 
> Before this is forgotten again, better start some dicsussion too early than 
> too late
> 
> I propose that if we have the oppertunity again next year to receive a grant
> from STF. That we use it to fund:
> 
> * Paul to work on FFmpeg full time. My idea here is that he can work on 
> whatever
>   he likes in FFmpeg (so its not full time employment for specific work but
>   simply full time employment for him to work on whatever he likes in FFmpeg 
> any
>   way he likes) Paul is the 2nd largest contributor to FFmpeg (git shortlog 
> -s -n)

Instead of one person creating code five days a week, how about paying five
people to review code one day a week each?  As well as being less divisive
among maintainers, a public list of people who are obliged to do reviews would
make us peripheral developers feel less like we're shouting into a void.
___
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/6] lavf/tls_mbedtls: handle more error codes for human-readable message

2024-05-17 Thread Andrew Sayers
On Fri, May 17, 2024 at 10:34:26AM +0200, Sfan5 wrote:
> Signed-off-by: sfan5 
> ---
>  libavformat/tls_mbedtls.c | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/libavformat/tls_mbedtls.c b/libavformat/tls_mbedtls.c
> index 1a182e735e..fd6ba0b1f5 100644
> --- a/libavformat/tls_mbedtls.c
> +++ b/libavformat/tls_mbedtls.c
> @@ -138,6 +138,9 @@ static void handle_handshake_error(URLContext *h, int
> ret)
>  case MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE:
>  av_log(h, AV_LOG_ERROR, "TLS handshake failed.\n");
>  break;
> +case MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION:
> +av_log(h, AV_LOG_ERROR, "TLS protocol version mismatches.\n");

"... mismatch" or "... does not match" would be more readable than "mismatches".

The word "matches" can mean either "does match" or "plural of match".
It's technically valid to use "mismatches" to mean "does not match",
but in practice the word is only ever used to mean "plural of mismatch".
___
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] [RFC] Value analysis with Frama-C's Eva plugin (and an UB fix)

2024-05-16 Thread Andrew Sayers
On Thu, May 16, 2024 at 02:31:31PM +0200, Tomas Härdin wrote:
> tor 2024-05-16 klockan 13:12 +0100 skrev Andrew Sayers:
> > On Wed, May 15, 2024 at 09:39:43PM +0200, Tomas Härdin wrote:
> > > Hi
> > > 
> > > So as I said in the coverity thread it would be good if we could
> > > get at
> > > least part of the codebase covered using formal tools. To this
> > > effect I
> > > sat down for an hour just now and gave libavutil/common.h a go with
> > > Frama-C's Eva plugin [1;2]. This plugin performs value analysis,
> > > which
> > > is a much simpler analysis compared to say the weakest predicate
> > > (WP)
> > > plugin.
> > > 
> > > Going through the functions from top to bottom it only took until
> > > av_clipl_int32_c() to find my first UB, a patch for which is
> > > attached.
> > > Thus my harping on this has born at least some fruit.
> > > 
> > > To run the analysis implemented in this set of patches (all of
> > > which
> > > I've attached here because I don't want to bother writing six
> > > follow-up
> > > email), first install frama-c using opam. I'm using 28.0~beta
> > > (Nickel).
> > > Then run "make verify" in libavutil/ and Eva should tell you that
> > > 33%
> > > of functions are covered and 100% of statements in those functions
> > > are
> > > covered, with zero alarms.
> > > 
> > > If the project isn't interested in this then I'll probably continue
> > > fiddling with it on my own mostly as exercise. But I suspect it
> > > will
> > > bear even more fruit in time.
> > > 
> > > /Tomas
> > > 
> > > [1] https://frama-c.com/
> > > [2] https://frama-c.com/fc-plugins/eva.html
> > 
> > I'm all for automated checks, but in my experience they're only
> > worthwhile
> > if two conditions are met:
> > 
> > * they run automatically on a regular basis
> 
> They could easily be incorporated into FATE or a post-commit hook

FATE is a good idea, but post-commit hooks break some workflows.
For example, I like to start a test in one window, then put together a commit
in another window.  I can always amend the commit if there's a problem.

The documentation suggests there are some hooks around e-mailing[1],
but I haven't tried them.

> 
> > * their output doesn't get boring
> 
> The output of Frama-C in general tends to be quite chatty. I've asked a
> couple of time for them to add exit codes, for example returning with
> zero only if there are no alarms and no unproven proof obligations.
> With Eva grepping for " 0 alarms generated by the analysis." is one
> way, but that's also quite ugly

Yeah, IMHO the refusal to listen to such reasonable requests is the standard
way for these projects to sabotage themselves.

Diffing against the previous run tends to work a little better than grepping
for a magic word, but still ugly, and you end up having to get rid of line
numbers with `sed` or something.

I find it's easier to put up with such hacks by constantly reminding myself:
No code solution can ever be as ugly as having to do it all by hand.

[1] https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#_email_hooks
___
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/opt: Say more often that AV_OPT_SEARCH_CHILDREN searches children first

2024-05-16 Thread Andrew Sayers
This behaviour is already mentioned in the documentation for
AV_OPT_SEARCH_CHILDREN itself, but that's quite easy to miss.

Knowing that child options *override* parent ones is useful for users,
so it's worth mentioning in all the places they would look.

av_opt_find() had a note that av_opt_find2() was missing.
Assume that wasn't deliberate, and copy it over.
---
 libavutil/opt.h | 20 ++--
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/libavutil/opt.h b/libavutil/opt.h
index 07e27a9208..24b807ec66 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -211,7 +211,7 @@
  *
  * The situation is more complicated with nesting. An AVOptions-enabled struct
  * may have AVOptions-enabled children. Passing the AV_OPT_SEARCH_CHILDREN flag
- * to av_opt_find() will make the function search children recursively.
+ * to av_opt_find() will make the function recursively search children first.
  *
  * For enumerating there are basically two cases. The first is when you want to
  * get all options that may potentially exist on the struct and its children
@@ -570,10 +570,11 @@ const AVClass *av_opt_child_class_iterate(const AVClass 
*parent, void **iter);
  * @return A pointer to the option found, or NULL if no option
  * was found.
  *
- * @note Options found with AV_OPT_SEARCH_CHILDREN flag may not be settable
- * directly with av_opt_set(). Use special calls which take an options
- * AVDictionary (e.g. avformat_open_input()) to set options found with this
- * flag.
+ * @note If AV_OPT_SEARCH_CHILDREN is set, this function will return an
+ * option from the first matching child class, or the specified class if
+ * no child matches.  Options from child classes may not be settable directly
+ * with av_opt_set(), so use special calls which take an options AVDictionary
+ * (e.g. avformat_open_input()) to set options found with this flag.
  */
 const AVOption *av_opt_find(void *obj, const char *name, const char *unit,
 int opt_flags, int search_flags);
@@ -598,6 +599,12 @@ const AVOption *av_opt_find(void *obj, const char *name, 
const char *unit,
  *
  * @return A pointer to the option found, or NULL if no option
  * was found.
+ *
+ * @note If AV_OPT_SEARCH_CHILDREN is set, this function will return an
+ * option from the first matching child class, or the specified class if
+ * no child matches.  Options from child classes may not be settable directly
+ * with av_opt_set(), so use special calls which take an options AVDictionary
+ * (e.g. avformat_open_input()) to set options found with this flag.
  */
 const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
  int opt_flags, int search_flags, void 
**target_obj);
@@ -780,7 +787,8 @@ int av_opt_copy(void *dest, const void *src);
  * key=value parameters. Values containing ':' special characters must be
  * escaped.
  * @param search_flags flags passed to av_opt_find2. I.e. if 
AV_OPT_SEARCH_CHILDREN
- * is passed here, then the option may be set on a child of obj.
+ * is passed here, av_opt_set() will set the first matching child if possible,
+ * or obj if no child matches.
  *
  * @return 0 if the value has been set, or an AVERROR code in case of
  * error:
-- 
2.43.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] all: s/Open/Allocate and initialize/ in comments

2024-05-16 Thread Andrew Sayers
Comments for a few prominent functions claim to "open" something, when they
actually "allocate and initialize" that thing.

Using a different word misleads users into thinking it's doing a different
thing, making the interface more time-consuming to learn.

Replace "open" with the more standard "allocate and initialize".
---
 libavformat/avformat.h | 4 ++--
 libavformat/avio.h | 4 ++--
 libavutil/hwcontext.h  | 3 ++-
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 8afdcd9fd0..2fb89807a1 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -2235,8 +2235,8 @@ int av_probe_input_buffer(AVIOContext *pb, const 
AVInputFormat **fmt,
   unsigned int offset, unsigned int max_probe_size);
 
 /**
- * Open an input stream and read the header. The codecs are not opened.
- * The stream must be closed with avformat_close_input().
+ * Allocate and initialize an input stream, then read the header.
+ * The codecs are not opened. The stream must be closed with 
avformat_close_input().
  *
  * @param ps   Pointer to user-supplied AVFormatContext (allocated by
  * avformat_alloc_context). May be a pointer to NULL, in
diff --git a/libavformat/avio.h b/libavformat/avio.h
index ebf611187d..1f56c58f9a 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -330,7 +330,7 @@ const char *avio_find_protocol_name(const char *url);
 int avio_check(const char *url, int flags);
 
 /**
- * Open directory for reading.
+ * Allocate and initialize a directory for reading.
  *
  * @param s   directory read context. Pointer to a NULL pointer must be 
passed.
  * @param url directory to be listed.
@@ -707,7 +707,7 @@ int avio_closep(AVIOContext **s);
 
 
 /**
- * Open a write only memory stream.
+ * Allocate and initialize a write only memory stream.
  *
  * @param s new IO context
  * @return zero if no error.
diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h
index bac30debae..be03f565f2 100644
--- a/libavutil/hwcontext.h
+++ b/libavutil/hwcontext.h
@@ -264,7 +264,8 @@ AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType 
type);
 int av_hwdevice_ctx_init(AVBufferRef *ref);
 
 /**
- * Open a device of the specified type and create an AVHWDeviceContext for it.
+ * Allocate and initialize a device of the specified type,
+ * and create an AVHWDeviceContext for it.
  *
  * This is a convenience function intended to cover the simple cases. Callers
  * who need to fine-tune device creation/management should open the device
-- 
2.43.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] [RFC] Value analysis with Frama-C's Eva plugin (and an UB fix)

2024-05-16 Thread Andrew Sayers
On Wed, May 15, 2024 at 09:39:43PM +0200, Tomas Härdin wrote:
> Hi
> 
> So as I said in the coverity thread it would be good if we could get at
> least part of the codebase covered using formal tools. To this effect I
> sat down for an hour just now and gave libavutil/common.h a go with
> Frama-C's Eva plugin [1;2]. This plugin performs value analysis, which
> is a much simpler analysis compared to say the weakest predicate (WP)
> plugin.
> 
> Going through the functions from top to bottom it only took until
> av_clipl_int32_c() to find my first UB, a patch for which is attached.
> Thus my harping on this has born at least some fruit.
> 
> To run the analysis implemented in this set of patches (all of which
> I've attached here because I don't want to bother writing six follow-up
> email), first install frama-c using opam. I'm using 28.0~beta (Nickel).
> Then run "make verify" in libavutil/ and Eva should tell you that 33%
> of functions are covered and 100% of statements in those functions are
> covered, with zero alarms.
> 
> If the project isn't interested in this then I'll probably continue
> fiddling with it on my own mostly as exercise. But I suspect it will
> bear even more fruit in time.
> 
> /Tomas
> 
> [1] https://frama-c.com/
> [2] https://frama-c.com/fc-plugins/eva.html

I'm all for automated checks, but in my experience they're only worthwhile
if two conditions are met:

* they run automatically on a regular basis
* their output doesn't get boring

One simple way to meet both criteria would be a cron job that runs overnight,
and messages the ML with just the issues that didn't exist in yesterday's run.

Plenty of other ways to do it, but something like that would be a great start.
___
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 v5 6/6] avformat/avformat: Document return codes for av_format_(de)init

2024-05-16 Thread Andrew Sayers
---
 libavformat/avformat.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 8afdcd9fd0..f624fb1e2e 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1944,12 +1944,16 @@ const char *avformat_license(void);
  * This function will be deprecated once support for older GnuTLS and
  * OpenSSL libraries is removed, and this function has no purpose
  * anymore.
+ *
+ * @return 0 for success or AVERROR code
  */
 int avformat_network_init(void);
 
 /**
  * Undo the initialization done by avformat_network_init. Call it only
  * once for each time you called avformat_network_init.
+ *
+ * @return 0 for success or AVERROR code
  */
 int avformat_network_deinit(void);
 
-- 
2.43.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 v5 5/6] avformat/network: Return 0/AVERROR from ff_network_init()

2024-05-16 Thread Andrew Sayers
---
 libavformat/avio.c|  7 +--
 libavformat/network.c |  7 +++
 libavformat/rtsp.c| 14 --
 libavformat/rtspdec.c |  5 +++--
 libavformat/sapdec.c  |  5 +++--
 libavformat/sapenc.c  |  5 +++--
 6 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/libavformat/avio.c b/libavformat/avio.c
index d109f3adff..8c94bfeb14 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -123,8 +123,11 @@ static int url_alloc_for_protocol(URLContext **puc, const 
URLProtocol *up,
 int err;
 
 #if CONFIG_NETWORK
-if (up->flags & URL_PROTOCOL_FLAG_NETWORK && !ff_network_init())
-return AVERROR(EIO);
+if (up->flags & URL_PROTOCOL_FLAG_NETWORK) {
+err = ff_network_init();
+if (err<0)
+return err;
+}
 #endif
 if ((flags & AVIO_FLAG_READ) && !up->url_read) {
 av_log(NULL, AV_LOG_ERROR,
diff --git a/libavformat/network.c b/libavformat/network.c
index 351dc34bb6..643294efe4 100644
--- a/libavformat/network.c
+++ b/libavformat/network.c
@@ -59,11 +59,10 @@ int ff_network_init(void)
 {
 #if HAVE_WINSOCK2_H
 WSADATA wsaData;
-
-if (WSAStartup(MAKEWORD(1,1), ))
-return 0;
+return ff_neterror2(WSAStartup(MAKEWORD(1,1), ));
+#else
+return 0;
 #endif
-return 1;
 }
 
 int ff_network_wait_fd(int fd, int write)
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index b0c61ee00a..d50d0b7fc0 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -1740,8 +1740,9 @@ int ff_rtsp_connect(AVFormatContext *s)
 return AVERROR(EINVAL);
 }
 
-if (!ff_network_init())
-return AVERROR(EIO);
+err = ff_network_init();
+if (err<0)
+return err;
 
 if (s->max_delay < 0) /* Not set by the caller */
 s->max_delay = s->iformat ? DEFAULT_REORDERING_DELAY : 0;
@@ -2395,8 +2396,9 @@ static int sdp_read_header(AVFormatContext *s)
 char url[MAX_URL_SIZE];
 AVBPrint bp;
 
-if (!ff_network_init())
-return AVERROR(EIO);
+err = ff_network_init();
+if (err<0)
+return err;
 
 if (s->max_delay < 0) /* Not set by the caller */
 s->max_delay = DEFAULT_REORDERING_DELAY;
@@ -2522,8 +2524,8 @@ static int rtp_read_header(AVFormatContext *s)
 AVBPrint sdp;
 AVDictionary *opts = NULL;
 
-if (!ff_network_init())
-return AVERROR(EIO);
+if ((ret = ff_network_init())<0)
+return ret;
 
 opts = map_to_opts(rt);
 ret = ffurl_open_whitelist(, s->url, AVIO_FLAG_READ,
diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index 10078ce2fa..1b4b478170 100644
--- a/libavformat/rtspdec.c
+++ b/libavformat/rtspdec.c
@@ -663,8 +663,9 @@ static int rtsp_listen(AVFormatContext *s)
 int ret;
 enum RTSPMethod methodcode;
 
-if (!ff_network_init())
-return AVERROR(EIO);
+ret = ff_network_init();
+if (ret<0)
+return ret;
 
 /* extract hostname and port */
 av_url_split(proto, sizeof(proto), auth, sizeof(auth), host, sizeof(host),
diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c
index 357c0dd514..393e544556 100644
--- a/libavformat/sapdec.c
+++ b/libavformat/sapdec.c
@@ -70,8 +70,9 @@ static int sap_read_header(AVFormatContext *s)
 int port;
 int ret, i;
 
-if (!ff_network_init())
-return AVERROR(EIO);
+ret = ff_network_init();
+if (ret<0)
+return ret;
 
 av_url_split(NULL, 0, NULL, 0, host, sizeof(host), ,
  path, sizeof(path), s->url);
diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c
index 87a834a8d8..5760e3a0c2 100644
--- a/libavformat/sapenc.c
+++ b/libavformat/sapenc.c
@@ -80,8 +80,9 @@ static int sap_write_header(AVFormatContext *s)
 int udp_fd;
 AVDictionaryEntry* title = av_dict_get(s->metadata, "title", NULL, 0);
 
-if (!ff_network_init())
-return AVERROR(EIO);
+ret = ff_network_init();
+if (ret<0)
+return ret;
 
 /* extract hostname and port */
 av_url_split(NULL, 0, NULL, 0, host, sizeof(host), _port,
-- 
2.43.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 v5 4/6] avformat/network: add ff_neterror2() for compatibility with Windows

2024-05-16 Thread Andrew Sayers
This is not currently used anywhere, but included to avoid
potential future surprises.
---
 libavformat/network.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/libavformat/network.h b/libavformat/network.h
index 1ac067f09f..7c8f81a050 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -82,6 +82,12 @@ int ff_neterror2(int err);
  * @note Error is based on WSAGetLastError() (Windows) or `errno` (otherwise)
  */
 #define ff_neterror() AVERROR(errno)
+/*
+ * @brief ff_neterror()-style AVERROR
+ * @param err error code (usually an errno or Windows Sockets Error Code)
+ * @note Windows Sockets Error Codes are only supported in Windows
+ */
+#define ff_neterror2(ERRNO) AVERROR(ERRNO)
 #endif /* HAVE_WINSOCK2_H */
 
 #if HAVE_ARPA_INET_H
-- 
2.43.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 v5 3/6] avformat/network: add ff_neterror2() for cases that don't use WSAGetLastError

2024-05-16 Thread Andrew Sayers
For example, WSAStartup()'s documentation says:

"A call to the WSAGetLastError function is not needed and should not be 
used"
---
 libavformat/network.c | 5 -
 libavformat/network.h | 6 ++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/libavformat/network.c b/libavformat/network.c
index 5d0d05c5f1..351dc34bb6 100644
--- a/libavformat/network.c
+++ b/libavformat/network.c
@@ -123,7 +123,10 @@ void ff_network_close(void)
 #if HAVE_WINSOCK2_H
 int ff_neterror(void)
 {
-int err = WSAGetLastError();
+return ff_neterror2(WSAGetLastError());
+}
+int ff_neterror2(int err)
+{
 switch (err) {
 case WSAEWOULDBLOCK:
 return AVERROR(EAGAIN);
diff --git a/libavformat/network.h b/libavformat/network.h
index f338694212..1ac067f09f 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -63,6 +63,12 @@
  * @note Error is based on WSAGetLastError() (Windows) or `errno` (otherwise)
  */
 int ff_neterror(void);
+/*
+ * @brief ff_neterror()-style AVERROR
+ * @param err error code (usually an errno or Windows Sockets Error Code)
+ * @note Windows Sockets Error Codes are only supported in Windows
+ */
+int ff_neterror2(int err);
 #else
 #include 
 #include 
-- 
2.43.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 v5 2/6] Rename "ff_neterrno()" to "ff_neterror()"

2024-05-16 Thread Andrew Sayers
This function does not check errno on Windows, so the old name was misleading.

Actual command:

sed -i -e 's/ff_neterrno/ff_neterror/g' $( git grep -l ff_neterrno )
---
 libavformat/network.c  | 24 
 libavformat/network.h  |  4 ++--
 libavformat/rtpproto.c |  8 
 libavformat/sctp.c | 10 +-
 libavformat/tcp.c  |  8 
 libavformat/udp.c  | 32 
 libavformat/unix.c |  6 +++---
 libavformat/url.h  |  2 +-
 8 files changed, 47 insertions(+), 47 deletions(-)

diff --git a/libavformat/network.c b/libavformat/network.c
index f752efc411..5d0d05c5f1 100644
--- a/libavformat/network.c
+++ b/libavformat/network.c
@@ -72,7 +72,7 @@ int ff_network_wait_fd(int fd, int write)
 struct pollfd p = { .fd = fd, .events = ev, .revents = 0 };
 int ret;
 ret = poll(, 1, POLLING_TIME);
-return ret < 0 ? ff_neterrno() : p.revents & (ev | POLLERR | POLLHUP) ? 0 
: AVERROR(EAGAIN);
+return ret < 0 ? ff_neterror() : p.revents & (ev | POLLERR | POLLHUP) ? 0 
: AVERROR(EAGAIN);
 }
 
 int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, 
AVIOInterruptCB *int_cb)
@@ -121,7 +121,7 @@ void ff_network_close(void)
 }
 
 #if HAVE_WINSOCK2_H
-int ff_neterrno(void)
+int ff_neterror(void)
 {
 int err = WSAGetLastError();
 switch (err) {
@@ -168,7 +168,7 @@ static int ff_poll_interrupt(struct pollfd *p, nfds_t nfds, 
int timeout,
 ret = poll(p, nfds, POLLING_TIME);
 if (ret != 0) {
 if (ret < 0)
-ret = ff_neterrno();
+ret = ff_neterror();
 if (ret == AVERROR(EINTR))
 continue;
 break;
@@ -217,11 +217,11 @@ int ff_listen(int fd, const struct sockaddr *addr,
 }
 ret = bind(fd, addr, addrlen);
 if (ret)
-return ff_neterrno();
+return ff_neterror();
 
 ret = listen(fd, 1);
 if (ret)
-return ff_neterrno();
+return ff_neterror();
 return ret;
 }
 
@@ -236,7 +236,7 @@ int ff_accept(int fd, int timeout, URLContext *h)
 
 ret = accept(fd, NULL, NULL);
 if (ret < 0)
-return ff_neterrno();
+return ff_neterror();
 if (ff_socket_nonblock(ret, 1) < 0)
 av_log(h, AV_LOG_DEBUG, "ff_socket_nonblock failed\n");
 
@@ -267,7 +267,7 @@ int ff_listen_connect(int fd, const struct sockaddr *addr,
 av_log(h, AV_LOG_DEBUG, "ff_socket_nonblock failed\n");
 
 while ((ret = connect(fd, addr, addrlen))) {
-ret = ff_neterrno();
+ret = ff_neterror();
 switch (ret) {
 case AVERROR(EINTR):
 if (ff_check_interrupt(>interrupt_callback))
@@ -280,7 +280,7 @@ int ff_listen_connect(int fd, const struct sockaddr *addr,
 return ret;
 optlen = sizeof(ret);
 if (getsockopt (fd, SOL_SOCKET, SO_ERROR, , ))
-ret = AVUNERROR(ff_neterrno());
+ret = AVUNERROR(ff_neterror());
 if (ret != 0) {
 char errbuf[100];
 ret = AVERROR(ret);
@@ -365,7 +365,7 @@ static int start_connect_attempt(struct ConnectionAttempt 
*attempt,
 
 attempt->fd = ff_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol, 
h);
 if (attempt->fd < 0)
-return ff_neterrno();
+return ff_neterror();
 attempt->deadline_us = av_gettime_relative() + timeout_ms * 1000;
 attempt->addr = ai;
 
@@ -381,7 +381,7 @@ static int start_connect_attempt(struct ConnectionAttempt 
*attempt,
 }
 
 while ((ret = connect(attempt->fd, ai->ai_addr, ai->ai_addrlen))) {
-ret = ff_neterrno();
+ret = ff_neterror();
 switch (ret) {
 case AVERROR(EINTR):
 if (ff_check_interrupt(>interrupt_callback)) {
@@ -478,7 +478,7 @@ int ff_connect_parallel(struct addrinfo *addrs, int 
timeout_ms_per_address,
 // a successful connection or an error).
 optlen = sizeof(last_err);
 if (getsockopt(attempts[i].fd, SOL_SOCKET, SO_ERROR, 
_err, ))
-last_err = ff_neterrno();
+last_err = ff_neterror();
 else if (last_err != 0)
 last_err = AVERROR(last_err);
 if (last_err == 0) {
@@ -587,6 +587,6 @@ int ff_http_match_no_proxy(const char *no_proxy, const char 
*hostname)
 void ff_log_net_error(void *ctx, int level, const char* prefix)
 {
 char errbuf[100];
-av_strerror(ff_neterrno(), errbuf, sizeof(errbuf));
+av_strerror(ff_neterror(), errbuf, sizeof(errbuf));
 av_log(ctx, level, "%s: %s\n", prefix, errbuf);
 }
diff --git a/libavformat/network.h b/libavformat/network.h
index 728c20c9bb..f338694212 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -62,7 +62,7 @@
  * @return platform-specific AVERROR value
  * @note Error is based on WSAGetLastError() (Windows) or `errno` (otherwise)
  */
-int ff_neterrno(void);
+int 

[FFmpeg-devel] [PATCH v5 0/6] avformat/network: improve ff_neterrno()

2024-05-16 Thread Andrew Sayers
On Thu, May 16, 2024 at 01:42:23PM +0300, Rémi Denis-Courmont wrote:
> Err, please. Keep this to the Windows back-end. Nothing good is going to 
> happen with a function that does nothing (on other platforms) and has a 
> nondescript numbered name.

I have no strong opinion either way, and it feels rather bikesheddable.
Here's a version with the offending part moved to its own patch -
I'm happy for whoever applies this to decide whether they want to
keep or chuck patch 4/6 :)

___
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 v5 1/6] Add documentation for ff_neterrno()

2024-05-16 Thread Andrew Sayers
---
 libavformat/network.h | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/libavformat/network.h b/libavformat/network.h
index ca214087fc..728c20c9bb 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -57,6 +57,11 @@
 #define getsockopt(a, b, c, d, e) getsockopt(a, b, c, (char*) d, e)
 #define setsockopt(a, b, c, d, e) setsockopt(a, b, c, (const char*) d, e)
 
+/*
+ * @brief AVERROR for the latest network function
+ * @return platform-specific AVERROR value
+ * @note Error is based on WSAGetLastError() (Windows) or `errno` (otherwise)
+ */
 int ff_neterrno(void);
 #else
 #include 
@@ -65,6 +70,11 @@ int ff_neterrno(void);
 #include 
 #include 
 
+/*
+ * @brief AVERROR for the latest network function
+ * @return platform-specific AVERROR value
+ * @note Error is based on WSAGetLastError() (Windows) or `errno` (otherwise)
+ */
 #define ff_neterrno() AVERROR(errno)
 #endif /* HAVE_WINSOCK2_H */
 
-- 
2.43.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 v4 3/4] all: Link to "context" from all contexts with documentation

2024-05-16 Thread Andrew Sayers
On Wed, May 15, 2024 at 06:46:19PM +0200, Lynne via ffmpeg-devel wrote:
> On 15/05/2024 17:54, Andrew Sayers wrote:
> > Some headings needed to be rewritten to accomodate the text,
> > (hopefully) without changing the meaning.
> > ---
> >   libavcodec/aac/aacdec.h|  2 +-
> >   libavcodec/aacenc.h|  2 +-
> >   libavcodec/ac3enc.h|  2 +-
> >   libavcodec/amfenc.h|  2 +-
> >   libavcodec/atrac.h |  2 +-
> >   libavcodec/avcodec.h   |  3 ++-
> >   libavcodec/bsf.h   |  2 +-
> >   libavcodec/cbs.h   |  2 +-
> >   libavcodec/d3d11va.h   |  3 +--
> >   libavcodec/h264dsp.h   |  2 +-
> >   libavcodec/h264pred.h  |  2 +-
> >   libavcodec/mediacodec.h|  2 +-
> >   libavcodec/mpegaudiodec_template.c |  2 +-
> >   libavcodec/pthread_frame.c |  4 ++--
> >   libavcodec/qsv.h   |  6 --
> >   libavcodec/sbr.h   |  2 +-
> >   libavcodec/smacker.c   |  2 +-
> >   libavcodec/vdpau.h |  3 ++-
> >   libavcodec/videotoolbox.h  |  5 +++--
> >   libavfilter/avfilter.h |  2 +-
> >   libavformat/avformat.h |  3 ++-
> >   libavformat/avio.h |  3 ++-
> >   libavutil/audio_fifo.h |  2 +-
> >   libavutil/hwcontext.h  | 21 -
> >   libavutil/hwcontext_cuda.h |  2 +-
> >   libavutil/hwcontext_d3d11va.h  |  4 ++--
> >   libavutil/hwcontext_d3d12va.h  |  6 +++---
> >   libavutil/hwcontext_drm.h  |  2 +-
> >   libavutil/hwcontext_dxva2.h|  4 ++--
> >   libavutil/hwcontext_mediacodec.h   |  2 +-
> >   libavutil/hwcontext_opencl.h   |  4 ++--
> >   libavutil/hwcontext_qsv.h  |  4 ++--
> >   libavutil/hwcontext_vaapi.h|  6 +++---
> >   libavutil/hwcontext_vdpau.h|  2 +-
> >   libavutil/hwcontext_vulkan.h   |  4 ++--
> >   libavutil/lfg.h|  2 +-
> >   36 files changed, 66 insertions(+), 57 deletions(-)
> 
> I still don't like this part. There's no reason to link this everywhere when
> no one will be bothered to. The document alone is enough IMO.

Readers who don't already know the word "context" need a sign that it's a word
they need to pay attention to.  For example, I come from an OOP background
where the word "object" is used so widely, it simply never comes up.

In fact, I'm probably not the only person who followed the link to AVClass
instead, which just makes FFmpeg look like a failed attempt at OOP if you don't
know about contexts.

Linking widely lets an attentive reader see this *before* they get the wrong
end of the stick, and gives an overwhelmed newbie enough hints that this is a
word they need to pay attention to.

To underline the previous point - an attentive reader could probably make do
with e.g. just links from AVClass and a handful of the most popular contexts.
But newbies are often inefficient learners who need many reminders before
they stop paying attention to random things.  So linking as widely as possible
makes the project more accessible to people with less experience.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v4 5/5] avformat/avformat: Document return codes for av_format_(de)init

2024-05-16 Thread Andrew Sayers
---
 libavformat/avformat.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 8afdcd9fd0..f624fb1e2e 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1944,12 +1944,16 @@ const char *avformat_license(void);
  * This function will be deprecated once support for older GnuTLS and
  * OpenSSL libraries is removed, and this function has no purpose
  * anymore.
+ *
+ * @return 0 for success or AVERROR code
  */
 int avformat_network_init(void);
 
 /**
  * Undo the initialization done by avformat_network_init. Call it only
  * once for each time you called avformat_network_init.
+ *
+ * @return 0 for success or AVERROR code
  */
 int avformat_network_deinit(void);
 
-- 
2.43.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 v4 4/5] avformat/network: Return 0/AVERROR from ff_network_init()

2024-05-16 Thread Andrew Sayers
---
 libavformat/avio.c|  7 +--
 libavformat/network.c |  7 +++
 libavformat/rtsp.c| 14 --
 libavformat/rtspdec.c |  5 +++--
 libavformat/sapdec.c  |  5 +++--
 libavformat/sapenc.c  |  5 +++--
 6 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/libavformat/avio.c b/libavformat/avio.c
index d109f3adff..8c94bfeb14 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -123,8 +123,11 @@ static int url_alloc_for_protocol(URLContext **puc, const 
URLProtocol *up,
 int err;
 
 #if CONFIG_NETWORK
-if (up->flags & URL_PROTOCOL_FLAG_NETWORK && !ff_network_init())
-return AVERROR(EIO);
+if (up->flags & URL_PROTOCOL_FLAG_NETWORK) {
+err = ff_network_init();
+if (err<0)
+return err;
+}
 #endif
 if ((flags & AVIO_FLAG_READ) && !up->url_read) {
 av_log(NULL, AV_LOG_ERROR,
diff --git a/libavformat/network.c b/libavformat/network.c
index 351dc34bb6..643294efe4 100644
--- a/libavformat/network.c
+++ b/libavformat/network.c
@@ -59,11 +59,10 @@ int ff_network_init(void)
 {
 #if HAVE_WINSOCK2_H
 WSADATA wsaData;
-
-if (WSAStartup(MAKEWORD(1,1), ))
-return 0;
+return ff_neterror2(WSAStartup(MAKEWORD(1,1), ));
+#else
+return 0;
 #endif
-return 1;
 }
 
 int ff_network_wait_fd(int fd, int write)
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index b0c61ee00a..d50d0b7fc0 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -1740,8 +1740,9 @@ int ff_rtsp_connect(AVFormatContext *s)
 return AVERROR(EINVAL);
 }
 
-if (!ff_network_init())
-return AVERROR(EIO);
+err = ff_network_init();
+if (err<0)
+return err;
 
 if (s->max_delay < 0) /* Not set by the caller */
 s->max_delay = s->iformat ? DEFAULT_REORDERING_DELAY : 0;
@@ -2395,8 +2396,9 @@ static int sdp_read_header(AVFormatContext *s)
 char url[MAX_URL_SIZE];
 AVBPrint bp;
 
-if (!ff_network_init())
-return AVERROR(EIO);
+err = ff_network_init();
+if (err<0)
+return err;
 
 if (s->max_delay < 0) /* Not set by the caller */
 s->max_delay = DEFAULT_REORDERING_DELAY;
@@ -2522,8 +2524,8 @@ static int rtp_read_header(AVFormatContext *s)
 AVBPrint sdp;
 AVDictionary *opts = NULL;
 
-if (!ff_network_init())
-return AVERROR(EIO);
+if ((ret = ff_network_init())<0)
+return ret;
 
 opts = map_to_opts(rt);
 ret = ffurl_open_whitelist(, s->url, AVIO_FLAG_READ,
diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index 10078ce2fa..1b4b478170 100644
--- a/libavformat/rtspdec.c
+++ b/libavformat/rtspdec.c
@@ -663,8 +663,9 @@ static int rtsp_listen(AVFormatContext *s)
 int ret;
 enum RTSPMethod methodcode;
 
-if (!ff_network_init())
-return AVERROR(EIO);
+ret = ff_network_init();
+if (ret<0)
+return ret;
 
 /* extract hostname and port */
 av_url_split(proto, sizeof(proto), auth, sizeof(auth), host, sizeof(host),
diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c
index 357c0dd514..393e544556 100644
--- a/libavformat/sapdec.c
+++ b/libavformat/sapdec.c
@@ -70,8 +70,9 @@ static int sap_read_header(AVFormatContext *s)
 int port;
 int ret, i;
 
-if (!ff_network_init())
-return AVERROR(EIO);
+ret = ff_network_init();
+if (ret<0)
+return ret;
 
 av_url_split(NULL, 0, NULL, 0, host, sizeof(host), ,
  path, sizeof(path), s->url);
diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c
index 87a834a8d8..5760e3a0c2 100644
--- a/libavformat/sapenc.c
+++ b/libavformat/sapenc.c
@@ -80,8 +80,9 @@ static int sap_write_header(AVFormatContext *s)
 int udp_fd;
 AVDictionaryEntry* title = av_dict_get(s->metadata, "title", NULL, 0);
 
-if (!ff_network_init())
-return AVERROR(EIO);
+ret = ff_network_init();
+if (ret<0)
+return ret;
 
 /* extract hostname and port */
 av_url_split(NULL, 0, NULL, 0, host, sizeof(host), _port,
-- 
2.43.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 v4 3/5] avformat/network: add ff_neterror2() for cases where we already have an error

2024-05-16 Thread Andrew Sayers
For example, WSAStartup()'s documentation says:

"A call to the WSAGetLastError function is not needed and should not be 
used"
---
 libavformat/network.c |  5 -
 libavformat/network.h | 12 
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/libavformat/network.c b/libavformat/network.c
index 5d0d05c5f1..351dc34bb6 100644
--- a/libavformat/network.c
+++ b/libavformat/network.c
@@ -123,7 +123,10 @@ void ff_network_close(void)
 #if HAVE_WINSOCK2_H
 int ff_neterror(void)
 {
-int err = WSAGetLastError();
+return ff_neterror2(WSAGetLastError());
+}
+int ff_neterror2(int err)
+{
 switch (err) {
 case WSAEWOULDBLOCK:
 return AVERROR(EAGAIN);
diff --git a/libavformat/network.h b/libavformat/network.h
index f338694212..7c8f81a050 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -63,6 +63,12 @@
  * @note Error is based on WSAGetLastError() (Windows) or `errno` (otherwise)
  */
 int ff_neterror(void);
+/*
+ * @brief ff_neterror()-style AVERROR
+ * @param err error code (usually an errno or Windows Sockets Error Code)
+ * @note Windows Sockets Error Codes are only supported in Windows
+ */
+int ff_neterror2(int err);
 #else
 #include 
 #include 
@@ -76,6 +82,12 @@ int ff_neterror(void);
  * @note Error is based on WSAGetLastError() (Windows) or `errno` (otherwise)
  */
 #define ff_neterror() AVERROR(errno)
+/*
+ * @brief ff_neterror()-style AVERROR
+ * @param err error code (usually an errno or Windows Sockets Error Code)
+ * @note Windows Sockets Error Codes are only supported in Windows
+ */
+#define ff_neterror2(ERRNO) AVERROR(ERRNO)
 #endif /* HAVE_WINSOCK2_H */
 
 #if HAVE_ARPA_INET_H
-- 
2.43.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 v4 2/5] Rename "ff_neterrno()" to "ff_neterror()"

2024-05-16 Thread Andrew Sayers
This function does not check errno on Windows, so the old name was misleading.

Actual command:

sed -i -e 's/ff_neterrno/ff_neterror/g' $( git grep -l ff_neterrno )
---
 libavformat/network.c  | 24 
 libavformat/network.h  |  4 ++--
 libavformat/rtpproto.c |  8 
 libavformat/sctp.c | 10 +-
 libavformat/tcp.c  |  8 
 libavformat/udp.c  | 32 
 libavformat/unix.c |  6 +++---
 libavformat/url.h  |  2 +-
 8 files changed, 47 insertions(+), 47 deletions(-)

diff --git a/libavformat/network.c b/libavformat/network.c
index f752efc411..5d0d05c5f1 100644
--- a/libavformat/network.c
+++ b/libavformat/network.c
@@ -72,7 +72,7 @@ int ff_network_wait_fd(int fd, int write)
 struct pollfd p = { .fd = fd, .events = ev, .revents = 0 };
 int ret;
 ret = poll(, 1, POLLING_TIME);
-return ret < 0 ? ff_neterrno() : p.revents & (ev | POLLERR | POLLHUP) ? 0 
: AVERROR(EAGAIN);
+return ret < 0 ? ff_neterror() : p.revents & (ev | POLLERR | POLLHUP) ? 0 
: AVERROR(EAGAIN);
 }
 
 int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, 
AVIOInterruptCB *int_cb)
@@ -121,7 +121,7 @@ void ff_network_close(void)
 }
 
 #if HAVE_WINSOCK2_H
-int ff_neterrno(void)
+int ff_neterror(void)
 {
 int err = WSAGetLastError();
 switch (err) {
@@ -168,7 +168,7 @@ static int ff_poll_interrupt(struct pollfd *p, nfds_t nfds, 
int timeout,
 ret = poll(p, nfds, POLLING_TIME);
 if (ret != 0) {
 if (ret < 0)
-ret = ff_neterrno();
+ret = ff_neterror();
 if (ret == AVERROR(EINTR))
 continue;
 break;
@@ -217,11 +217,11 @@ int ff_listen(int fd, const struct sockaddr *addr,
 }
 ret = bind(fd, addr, addrlen);
 if (ret)
-return ff_neterrno();
+return ff_neterror();
 
 ret = listen(fd, 1);
 if (ret)
-return ff_neterrno();
+return ff_neterror();
 return ret;
 }
 
@@ -236,7 +236,7 @@ int ff_accept(int fd, int timeout, URLContext *h)
 
 ret = accept(fd, NULL, NULL);
 if (ret < 0)
-return ff_neterrno();
+return ff_neterror();
 if (ff_socket_nonblock(ret, 1) < 0)
 av_log(h, AV_LOG_DEBUG, "ff_socket_nonblock failed\n");
 
@@ -267,7 +267,7 @@ int ff_listen_connect(int fd, const struct sockaddr *addr,
 av_log(h, AV_LOG_DEBUG, "ff_socket_nonblock failed\n");
 
 while ((ret = connect(fd, addr, addrlen))) {
-ret = ff_neterrno();
+ret = ff_neterror();
 switch (ret) {
 case AVERROR(EINTR):
 if (ff_check_interrupt(>interrupt_callback))
@@ -280,7 +280,7 @@ int ff_listen_connect(int fd, const struct sockaddr *addr,
 return ret;
 optlen = sizeof(ret);
 if (getsockopt (fd, SOL_SOCKET, SO_ERROR, , ))
-ret = AVUNERROR(ff_neterrno());
+ret = AVUNERROR(ff_neterror());
 if (ret != 0) {
 char errbuf[100];
 ret = AVERROR(ret);
@@ -365,7 +365,7 @@ static int start_connect_attempt(struct ConnectionAttempt 
*attempt,
 
 attempt->fd = ff_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol, 
h);
 if (attempt->fd < 0)
-return ff_neterrno();
+return ff_neterror();
 attempt->deadline_us = av_gettime_relative() + timeout_ms * 1000;
 attempt->addr = ai;
 
@@ -381,7 +381,7 @@ static int start_connect_attempt(struct ConnectionAttempt 
*attempt,
 }
 
 while ((ret = connect(attempt->fd, ai->ai_addr, ai->ai_addrlen))) {
-ret = ff_neterrno();
+ret = ff_neterror();
 switch (ret) {
 case AVERROR(EINTR):
 if (ff_check_interrupt(>interrupt_callback)) {
@@ -478,7 +478,7 @@ int ff_connect_parallel(struct addrinfo *addrs, int 
timeout_ms_per_address,
 // a successful connection or an error).
 optlen = sizeof(last_err);
 if (getsockopt(attempts[i].fd, SOL_SOCKET, SO_ERROR, 
_err, ))
-last_err = ff_neterrno();
+last_err = ff_neterror();
 else if (last_err != 0)
 last_err = AVERROR(last_err);
 if (last_err == 0) {
@@ -587,6 +587,6 @@ int ff_http_match_no_proxy(const char *no_proxy, const char 
*hostname)
 void ff_log_net_error(void *ctx, int level, const char* prefix)
 {
 char errbuf[100];
-av_strerror(ff_neterrno(), errbuf, sizeof(errbuf));
+av_strerror(ff_neterror(), errbuf, sizeof(errbuf));
 av_log(ctx, level, "%s: %s\n", prefix, errbuf);
 }
diff --git a/libavformat/network.h b/libavformat/network.h
index 728c20c9bb..f338694212 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -62,7 +62,7 @@
  * @return platform-specific AVERROR value
  * @note Error is based on WSAGetLastError() (Windows) or `errno` (otherwise)
  */
-int ff_neterrno(void);
+int 

[FFmpeg-devel] [PATCH v4 1/5] Add documentation for ff_neterrno()

2024-05-16 Thread Andrew Sayers
---
 libavformat/network.h | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/libavformat/network.h b/libavformat/network.h
index ca214087fc..728c20c9bb 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -57,6 +57,11 @@
 #define getsockopt(a, b, c, d, e) getsockopt(a, b, c, (char*) d, e)
 #define setsockopt(a, b, c, d, e) setsockopt(a, b, c, (const char*) d, e)
 
+/*
+ * @brief AVERROR for the latest network function
+ * @return platform-specific AVERROR value
+ * @note Error is based on WSAGetLastError() (Windows) or `errno` (otherwise)
+ */
 int ff_neterrno(void);
 #else
 #include 
@@ -65,6 +70,11 @@ int ff_neterrno(void);
 #include 
 #include 
 
+/*
+ * @brief AVERROR for the latest network function
+ * @return platform-specific AVERROR value
+ * @note Error is based on WSAGetLastError() (Windows) or `errno` (otherwise)
+ */
 #define ff_neterrno() AVERROR(errno)
 #endif /* HAVE_WINSOCK2_H */
 
-- 
2.43.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 v4 0/5] avformat/network: improve ff_neterrno()

2024-05-16 Thread Andrew Sayers
I've prepended two patches - one with just the documentation,
the other with just the code.  The latter was generated automatically
with the command specified in the commit message, so e.g. rebase conflicts
can be resolved by throwing away the old commit and rerunning the command.

As discussed, this also fixes the assigns in if-statements.

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v4 4/4] lavf: Add documentation for private "Context" classes

2024-05-15 Thread Andrew Sayers
Doxygen thinks any text like "Context for foo" is a link to a struct called 
"Context".
Add a description and a better link, to avoid confusing readers.
---
 libavformat/async.c | 3 +++
 libavformat/cache.c | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/libavformat/async.c b/libavformat/async.c
index e096b0bc6f..3c28d418ae 100644
--- a/libavformat/async.c
+++ b/libavformat/async.c
@@ -53,6 +53,9 @@ typedef struct RingBuffer
 int   read_pos;
 } RingBuffer;
 
+/**
+ * @brief @ref md_doc_2context "Context" for testing async
+ */
 typedef struct Context {
 AVClass*class;
 URLContext *inner;
diff --git a/libavformat/cache.c b/libavformat/cache.c
index 5f78adba9d..3cc0edec82 100644
--- a/libavformat/cache.c
+++ b/libavformat/cache.c
@@ -52,6 +52,9 @@ typedef struct CacheEntry {
 int size;
 } CacheEntry;
 
+/**
+ * @brief @ref md_doc_2context "Context" for a cache
+ */
 typedef struct Context {
 AVClass *class;
 int fd;
-- 
2.43.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 v4 3/4] all: Link to "context" from all contexts with documentation

2024-05-15 Thread Andrew Sayers
Some headings needed to be rewritten to accomodate the text,
(hopefully) without changing the meaning.
---
 libavcodec/aac/aacdec.h|  2 +-
 libavcodec/aacenc.h|  2 +-
 libavcodec/ac3enc.h|  2 +-
 libavcodec/amfenc.h|  2 +-
 libavcodec/atrac.h |  2 +-
 libavcodec/avcodec.h   |  3 ++-
 libavcodec/bsf.h   |  2 +-
 libavcodec/cbs.h   |  2 +-
 libavcodec/d3d11va.h   |  3 +--
 libavcodec/h264dsp.h   |  2 +-
 libavcodec/h264pred.h  |  2 +-
 libavcodec/mediacodec.h|  2 +-
 libavcodec/mpegaudiodec_template.c |  2 +-
 libavcodec/pthread_frame.c |  4 ++--
 libavcodec/qsv.h   |  6 --
 libavcodec/sbr.h   |  2 +-
 libavcodec/smacker.c   |  2 +-
 libavcodec/vdpau.h |  3 ++-
 libavcodec/videotoolbox.h  |  5 +++--
 libavfilter/avfilter.h |  2 +-
 libavformat/avformat.h |  3 ++-
 libavformat/avio.h |  3 ++-
 libavutil/audio_fifo.h |  2 +-
 libavutil/hwcontext.h  | 21 -
 libavutil/hwcontext_cuda.h |  2 +-
 libavutil/hwcontext_d3d11va.h  |  4 ++--
 libavutil/hwcontext_d3d12va.h  |  6 +++---
 libavutil/hwcontext_drm.h  |  2 +-
 libavutil/hwcontext_dxva2.h|  4 ++--
 libavutil/hwcontext_mediacodec.h   |  2 +-
 libavutil/hwcontext_opencl.h   |  4 ++--
 libavutil/hwcontext_qsv.h  |  4 ++--
 libavutil/hwcontext_vaapi.h|  6 +++---
 libavutil/hwcontext_vdpau.h|  2 +-
 libavutil/hwcontext_vulkan.h   |  4 ++--
 libavutil/lfg.h|  2 +-
 36 files changed, 66 insertions(+), 57 deletions(-)

diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h
index eed53c6c96..1d991a3c63 100644
--- a/libavcodec/aac/aacdec.h
+++ b/libavcodec/aac/aacdec.h
@@ -253,7 +253,7 @@ typedef struct AACDecDSP {
 } AACDecDSP;
 
 /**
- * main AAC decoding context
+ * main AAC decoding @ref md_doc_2context "context"
  */
 struct AACDecContext {
 const struct AVClass  *class;
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index d07960620e..1a645f4719 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -207,7 +207,7 @@ typedef struct AACPCEInfo {
 } AACPCEInfo;
 
 /**
- * AAC encoder context
+ * AAC encoder @ref md_doc_2context "context"
  */
 typedef struct AACEncContext {
 AVClass *av_class;
diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
index 30812617cc..c725007077 100644
--- a/libavcodec/ac3enc.h
+++ b/libavcodec/ac3enc.h
@@ -152,7 +152,7 @@ typedef struct AC3Block {
 } AC3Block;
 
 /**
- * AC-3 encoder private context.
+ * AC-3 encoder private @ref md_doc_2context "context"
  */
 typedef struct AC3EncodeContext {
 AVClass *av_class;  ///< AVClass used for AVOption
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 2dbd378ef8..f142ede63a 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -43,7 +43,7 @@ typedef struct AmfTraceWriter {
 } AmfTraceWriter;
 
 /**
-* AMF encoder context
+* AMF encoder @ref md_doc_2context "context"
 */
 
 typedef struct AmfContext {
diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
index 05208bbee6..1527e376a9 100644
--- a/libavcodec/atrac.h
+++ b/libavcodec/atrac.h
@@ -39,7 +39,7 @@ typedef struct AtracGainInfo {
 } AtracGainInfo;
 
 /**
- *  Gain compensation context structure.
+ *  Gain compensation @ref md_doc_2context "context"
  */
 typedef struct AtracGCContext {
 float   gain_tab1[16];  ///< gain compensation level table
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 2da63c87ea..4f7a5aa80d 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -430,7 +430,8 @@ typedef struct RcOverride{
 #define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0)
 
 /**
- * main external API structure.
+ * @ref md_doc_2context "Context" for an encode or decode session
+ *
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
index a09c69f242..bf79afa7cc 100644
--- a/libavcodec/bsf.h
+++ b/libavcodec/bsf.h
@@ -56,7 +56,7 @@
  */
 
 /**
- * The bitstream filter state.
+ * Bitstream filter @ref md_doc_2context "context"
  *
  * This struct must be allocated with av_bsf_alloc() and freed with
  * av_bsf_free().
diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h
index d479b1ac2d..0ff64d2fef 100644
--- a/libavcodec/cbs.h
+++ b/libavcodec/cbs.h
@@ -214,7 +214,7 @@ typedef void (*CBSTraceWriteCallback)(void *trace_context,
   int64_t value);
 
 /**
- * Context structure for coded bitstream operations.
+ * @ref md_doc_2context "Context" structure for coded bitstream operations.
  */
 typedef struct CodedBitstreamContext {
 /**
diff --git a/libavcodec/d3d11va.h 

[FFmpeg-devel] [PATCH v4 2/4] lavu: Clarify relationship between AVClass, AVOption and context

2024-05-15 Thread Andrew Sayers
---
 libavutil/log.h | 11 ---
 libavutil/opt.h |  7 ---
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/libavutil/log.h b/libavutil/log.h
index ab7ceabe22..cfbf416679 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -59,9 +59,14 @@ typedef enum {
 struct AVOptionRanges;
 
 /**
- * Describe the class of an AVClass context structure. That is an
- * arbitrary struct of which the first field is a pointer to an
- * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.).
+ * Metadata about an arbitrary data structure
+ *
+ * A @ref md_doc_2context "context struct" whose first member is a pointer
+ * to an AVClass object is called an "AVClass context structure"
+ * (e.g. AVCodecContext, AVFormatContext etc.).
+ *
+ * AVClass is often combined with @ref avoptions "AVOptions" to create
+ * "AVOptions-enabled structs" that can be easily configured by users.
  */
 typedef struct AVClass {
 /**
diff --git a/libavutil/opt.h b/libavutil/opt.h
index 07e27a9208..e314e134c2 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -39,9 +39,10 @@
  * @defgroup avoptions AVOptions
  * @ingroup lavu_data
  * @{
- * AVOptions provide a generic system to declare options on arbitrary structs
- * ("objects"). An option can have a help text, a type and a range of possible
- * values. Options may then be enumerated, read and written to.
+ * Builds on AVClass, adding a generic system to declare options.
+ *
+ * An option can have a help text, a type and a range of possible values.
+ * Options may then be enumerated, read and written to.
  *
  * There are two modes of access to members of AVOption and its child structs.
  * One is called 'native access', and refers to access from the code that
-- 
2.43.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 v4 1/4] doc: Explain what "context" means

2024-05-15 Thread Andrew Sayers
Derived from detailed explanations kindly provided by Stefano Sabatini:
https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325903.html
---
 doc/context.md | 394 +
 1 file changed, 394 insertions(+)
 create mode 100644 doc/context.md

diff --git a/doc/context.md b/doc/context.md
new file mode 100644
index 00..fb85b3f366
--- /dev/null
+++ b/doc/context.md
@@ -0,0 +1,394 @@
+# Introduction to contexts
+
+%Context is a name for a widely-used programming idiom.
+This document explains the general idiom and the conventions FFmpeg has built 
around it.
+
+This document uses object-oriented analogies to help readers familiar with
+[object-oriented 
programming](https://en.wikipedia.org/wiki/Object-oriented_programming)
+learn about contexts.  But contexts can also be used outside of OOP,
+and even in situations where OOP isn't helpful.  So these analogies
+should only be used as a first step towards understanding contexts.
+
+## Context as a way to think about code
+
+A context is any data structure that is passed to several functions
+(or several instances of the same function) that all operate on the same 
entity.
+For example, [object-oriented 
programming](https://en.wikipedia.org/wiki/Object-oriented_programming)
+languages usually provide member functions with a `this` or `self` value:
+
+```c
+class my_cxx_class {
+  void my_member_function() {
+// the implicit object parameter provides context for the member function:
+std::cout << this;
+  }
+};
+```
+
+Contexts are a fundamental building block of OOP, but can also be used in 
procedural code.
+For example, most callback functions can be understood to use contexts:
+
+```c
+struct MyStruct {
+  int counter;
+};
+
+void my_callback( void *my_var_ ) {
+  // my_var provides context for the callback function:
+  struct MyStruct *my_var = (struct MyStruct *)my_var_;
+  printf("Called %d time(s)", ++my_var->counter);
+}
+
+void init() {
+  struct MyStruct my_var;
+  my_var.counter = 0;
+  register_callback( my_callback, _var );
+}
+```
+
+In the broadest sense, context is just a way to think about code.
+You can even use it to think about code written by people who have never
+heard the term, or who would disagree with you about what it means.
+
+## Context as a tool of communication
+
+%Context can just be a word to understand code in your own head,
+but it can also be a term you use to explain your interfaces.
+Here is a version of the callback example that makes the context explicit:
+
+```c
+struct CallbackContext {
+  int counter;
+};
+
+void my_callback( void *ctx_ ) {
+  // ctx provides context for the callback function:
+  struct CallbackContext *ctx = (struct CallbackContext *)ctx_;
+  printf("Called %d time(s)", ++ctx->counter);
+}
+
+void init() {
+  struct CallbackContext ctx;
+  ctx.counter = 0;
+  register_callback( my_callback,  );
+}
+```
+
+The difference here is subtle, but important.  If a piece of code
+*appears compatible with contexts*, then you are *allowed to think
+that way*, but if a piece of code *explicitly states it uses
+contexts*, then you are *required to follow that approach*.
+
+For example, imagine someone modified `MyStruct` in the earlier example
+to count several unrelated events across the whole program.  That would mean
+it contained information about multiple entities, so was not a context.
+But nobody ever *said* it was a context, so that isn't necessarily wrong.
+However, proposing the same change to the `CallbackContext` in the later 
example
+would violate a guarantee, and should be pointed out in a code review.
+
+@warning Guaranteeing to use contexts does not mean guaranteeing to use
+object-oriented programming.  For example, FFmpeg creates its contexts
+procedurally instead of with constructors.
+
+## Contexts in the real world
+
+To understand how contexts are used in the real world, it might be
+useful to compare [curl's MD5 hash 
context](https://github.com/curl/curl/blob/bbeeccdea8507ff50efca70a0b33d28aef720267/lib/curl_md5.h#L48)
+with @ref AVMD5 "FFmpeg's equivalent context".
+
+The [MD5 algorithm](https://en.wikipedia.org/wiki/MD5) produces
+a fixed-length digest from arbitrary-length data.  It does this by calculating
+the digest for a prefix of the data, then loading the next part and adding it
+to the previous digest, and so on.  Projects that use MD5 generally use some
+kind of context, so comparing them can reveal differences between projects.
+
+```c
+// Curl's MD5 context looks like this:
+struct MD5_context {
+  const struct MD5_params *md5_hash;/* Hash function definition */
+  void  *md5_hashctx;   /* Hash function context */
+};
+
+// FFmpeg's MD5 context looks like this:
+typedef struct AVMD5 {
+uint64_t len;
+uint8_t  block[64];
+uint32_t ABCD[4];
+} AVMD5;
+```
+
+Curl's struct name ends with `_context`, guaranteeing contexts are the correct
+interpretation.  FFmpeg's struct does not explicitly 

[FFmpeg-devel] [PATCH v4 0/4] Explain what "context" means

2024-05-15 Thread Andrew Sayers
This version strongly implies AVClass is only used alongside AVOption.
I'm not sure when or if e.g. AVClass::category would be used by an external
API developer, but happy to change the text if anyone has a use case.

I accept the argument that the previous version was linked more widely
than it was useful, but instead of reducing links I've tried to widen
its usefulness.  The new version discusses how e.g. FFmpeg contexts differ
from curl, which could be useful to developers coming from other projects.
And it goes into more detail about e.g. context lifetime, which could
be useful for even an intermediate developer.

___
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] libavfilter: add PipeWire-based grab

2024-05-11 Thread Andrew Sayers
(only reviewing the documentation, not the code itself)

On Fri, May 10, 2024 at 05:12:19PM -0400, François-Simon Fauteux-Chapleau wrote:
> This is a revised version of the "pipewiregrab" patch submitted by
> Abhishek Ojha a few months ago:
> https://patchwork.ffmpeg.org/project/ffmpeg/patch/20231227162504.690730-1-abhishek.o...@savoirfairelinux.com/
> https://patchwork.ffmpeg.org/project/ffmpeg/patch/20231227162504.690730-2-abhishek.o...@savoirfairelinux.com/
> 
> The main change is that the patch is now implemented as a libavfilter
> source filter instead of a libavdevice input device, as was requested in
> a comment on the previous version. This version also adds support for
> DMA buffer sharing and uses sd-bus instead of GDBus.
> 
> There are also several small changes meant to fix bugs or simplify the
> code, but the overall structure remains the same as before: we use the
> ScreenCast interface provided by XDG Desktop Portal to obtain a file
> descriptor, which is then used to create a PipeWire stream. The data from
> that stream can then be used to generate frames for FFmpeg.
> 
> Example usage:
> ffmpeg -f lavfi -i pipewiregrab \
>-vf 'hwmap=derive_device=vaapi,scale_vaapi=format=nv12' \
>-c:v h264_vaapi -t 10 output.mp4
> 
> Signed-off-by: François-Simon Fauteux-Chapleau 
> 
> ---
>  configure   |   16 +
>  libavfilter/Makefile|1 +
>  libavfilter/allfilters.c|1 +
>  libavfilter/vsrc_pipewiregrab.c | 1433 +++
>  4 files changed, 1451 insertions(+)
>  create mode 100644 libavfilter/vsrc_pipewiregrab.c
> 
> diff --git a/configure b/configure
> index beb1fa6d3c..028020455e 100755
> --- a/configure
> +++ b/configure
> @@ -304,6 +304,7 @@ External library support:
>--enable-libxcb-shm  enable X11 grabbing shm communication [autodetect]
>--enable-libxcb-xfixes   enable X11 grabbing mouse rendering [autodetect]
>--enable-libxcb-shapeenable X11 grabbing shape rendering [autodetect]
> +  --enable-libpipewire enable screen grabbing using PipeWire [autodetect]
>--enable-libxvid enable Xvid encoding via xvidcore,
> native MPEG-4/Xvid encoder exists [no]
>--enable-libxml2 enable XML parsing using the C library libxml2, 
> needed
> @@ -1845,6 +1846,8 @@ EXTERNAL_AUTODETECT_LIBRARY_LIST="
>  libxcb_shm
>  libxcb_shape
>  libxcb_xfixes
> +libpipewire
> +libsystemd
>  lzma
>  mediafoundation
>  metal
> @@ -3895,6 +3898,7 @@ pad_opencl_filter_deps="opencl"
>  pan_filter_deps="swresample"
>  perspective_filter_deps="gpl"
>  phase_filter_deps="gpl"
> +pipewiregrab_filter_deps="libpipewire libsystemd pthreads"
>  pp7_filter_deps="gpl"
>  pp_filter_deps="gpl postproc"
>  prewitt_opencl_filter_deps="opencl"
> @@ -7230,6 +7234,18 @@ if enabled libxcb; then
>  enabled libxcb_xfixes && check_pkg_config libxcb_xfixes xcb-xfixes 
> xcb/xfixes.h xcb_xfixes_get_cursor_image
>  fi
>  
> +# Starting with version 0.3.52, PipeWire's spa library uses the 
> __LOCALE_C_ONLY macro to determine
> +# whether the locale_t type (introduced in POSIX.1-2008) and some related 
> functions are available (see
> +# https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/2390 for more 
> information).
> +# Unfortunately, this macro is specific to uclibc, which can cause build 
> issues on systems that use a
> +# different implementation of libc if POSIX 2008 support isn't enabled 
> (which is the case for FFmpeg currently).
> +# As a workaround for this problem, we add a compilation flag to ensure that 
> __LOCALE_C_ONLY is always defined.
> +add_cppflags -D__LOCALE_C_ONLY
> +enabled libpipewire && check_pkg_config libpipewire "libpipewire-0.3 >= 
> 0.3.40" pipewire/pipewire.h pw_init
> +if enabled libpipewire; then
> +enabled libsystemd  && check_pkg_config libsystemd "libsystemd >= 246" 
> systemd/sd-bus.h sd_bus_call_method
> +fi
> +
>  check_func_headers "windows.h" CreateDIBSection "$gdigrab_indev_extralibs"
>  
>  # check if building for desktop or uwp
> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> index 5992fd161f..6352e91586 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -603,6 +603,7 @@ OBJS-$(CONFIG_NULLSRC_FILTER)+= 
> vsrc_testsrc.o
>  OBJS-$(CONFIG_OPENCLSRC_FILTER)  += vf_program_opencl.o opencl.o
>  OBJS-$(CONFIG_PAL75BARS_FILTER)  += vsrc_testsrc.o
>  OBJS-$(CONFIG_PAL100BARS_FILTER) += vsrc_testsrc.o
> +OBJS-$(CONFIG_PIPEWIREGRAB_FILTER)   += vsrc_pipewiregrab.o
>  OBJS-$(CONFIG_QRENCODE_FILTER)   += qrencode.o textutils.o
>  OBJS-$(CONFIG_QRENCODESRC_FILTER)+= qrencode.o textutils.o
>  OBJS-$(CONFIG_RGBTESTSRC_FILTER) += vsrc_testsrc.o
> diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
> index c532682fc2..3670a6d7e7 100644
> --- a/libavfilter/allfilters.c
> +++ 

Re: [FFmpeg-devel] [PATCH 2/4] avcodec/aac_ac3_parser: Untangle AAC and AC3 parsing error codes

2024-05-11 Thread Andrew Sayers
On Fri, May 10, 2024 at 06:56:25PM +0200, Andreas Rheinhardt wrote:
> Also remove the (unused) AAC_AC3_PARSE_ERROR_CHANNEL_CFG while at it;
> furthermore, fix the documentation of ff_ac3_parse_header()
> and (ff|avpriv)_adts_header_parse().
> 
> Signed-off-by: Andreas Rheinhardt 
> ---
>  libavcodec/aac_ac3_parser.h  | 10 --
>  libavcodec/ac3_parser.c  | 14 +++---
>  libavcodec/ac3_parser_internal.h | 13 ++---
>  libavcodec/ac3dec.c  | 18 --
>  libavcodec/adts_header.c |  7 +++
>  libavcodec/adts_header.h | 16 ++--
>  libavcodec/eac3dec.c |  6 +++---
>  7 files changed, 41 insertions(+), 43 deletions(-)
> 
> diff --git a/libavcodec/aac_ac3_parser.h b/libavcodec/aac_ac3_parser.h
> index bc16181a19..e3259d1841 100644
> --- a/libavcodec/aac_ac3_parser.h
> +++ b/libavcodec/aac_ac3_parser.h
> @@ -28,16 +28,6 @@
>  #include "avcodec.h"
>  #include "parser.h"
>  
> -typedef enum {
> -AAC_AC3_PARSE_ERROR_SYNC= -0x1030c0a,
> -AAC_AC3_PARSE_ERROR_BSID= -0x2030c0a,
> -AAC_AC3_PARSE_ERROR_SAMPLE_RATE = -0x3030c0a,
> -AAC_AC3_PARSE_ERROR_FRAME_SIZE  = -0x4030c0a,
> -AAC_AC3_PARSE_ERROR_FRAME_TYPE  = -0x5030c0a,
> -AAC_AC3_PARSE_ERROR_CRC = -0x6030c0a,
> -AAC_AC3_PARSE_ERROR_CHANNEL_CFG = -0x7030c0a,
> -} AACAC3ParseError;
> -
>  typedef struct AACAC3ParseContext {
>  ParseContext pc;
>  int header_size;
> diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c
> index 4e0ba73481..69989690dd 100644
> --- a/libavcodec/ac3_parser.c
> +++ b/libavcodec/ac3_parser.c
> @@ -81,12 +81,12 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo 
> *hdr)
>  
>  hdr->sync_word = get_bits(gbc, 16);
>  if(hdr->sync_word != 0x0B77)
> -return AAC_AC3_PARSE_ERROR_SYNC;
> +return AC3_PARSE_ERROR_SYNC;
>  
>  /* read ahead to bsid to distinguish between AC-3 and E-AC-3 */
>  hdr->bitstream_id = show_bits_long(gbc, 29) & 0x1F;
>  if(hdr->bitstream_id > 16)
> -return AAC_AC3_PARSE_ERROR_BSID;
> +return AC3_PARSE_ERROR_BSID;
>  
>  hdr->num_blocks = 6;
>  hdr->ac3_bit_rate_code = -1;
> @@ -103,11 +103,11 @@ int ff_ac3_parse_header(GetBitContext *gbc, 
> AC3HeaderInfo *hdr)
>  hdr->crc1 = get_bits(gbc, 16);
>  hdr->sr_code = get_bits(gbc, 2);
>  if(hdr->sr_code == 3)
> -return AAC_AC3_PARSE_ERROR_SAMPLE_RATE;
> +return AC3_PARSE_ERROR_SAMPLE_RATE;
>  
>  frame_size_code = get_bits(gbc, 6);
>  if(frame_size_code > 37)
> -return AAC_AC3_PARSE_ERROR_FRAME_SIZE;
> +return AC3_PARSE_ERROR_FRAME_SIZE;
>  
>  hdr->ac3_bit_rate_code = (frame_size_code >> 1);
>  
> @@ -138,19 +138,19 @@ int ff_ac3_parse_header(GetBitContext *gbc, 
> AC3HeaderInfo *hdr)
>  hdr->crc1 = 0;
>  hdr->frame_type = get_bits(gbc, 2);
>  if(hdr->frame_type == EAC3_FRAME_TYPE_RESERVED)
> -return AAC_AC3_PARSE_ERROR_FRAME_TYPE;
> +return AC3_PARSE_ERROR_FRAME_TYPE;
>  
>  hdr->substreamid = get_bits(gbc, 3);
>  
>  hdr->frame_size = (get_bits(gbc, 11) + 1) << 1;
>  if(hdr->frame_size < AC3_HEADER_SIZE)
> -return AAC_AC3_PARSE_ERROR_FRAME_SIZE;
> +return AC3_PARSE_ERROR_FRAME_SIZE;
>  
>  hdr->sr_code = get_bits(gbc, 2);
>  if (hdr->sr_code == 3) {
>  int sr_code2 = get_bits(gbc, 2);
>  if(sr_code2 == 3)
> -return AAC_AC3_PARSE_ERROR_SAMPLE_RATE;
> +return AC3_PARSE_ERROR_SAMPLE_RATE;
>  hdr->sample_rate = ff_ac3_sample_rate_tab[sr_code2] / 2;
>  hdr->sr_shift = 1;
>  } else {
> diff --git a/libavcodec/ac3_parser_internal.h 
> b/libavcodec/ac3_parser_internal.h
> index 2ac0e67ec2..2c4eb546e5 100644
> --- a/libavcodec/ac3_parser_internal.h
> +++ b/libavcodec/ac3_parser_internal.h
> @@ -64,15 +64,22 @@ typedef struct AC3HeaderInfo {
>  /** @} */
>  } AC3HeaderInfo;
>  
> +typedef enum {
> +AC3_PARSE_ERROR_SYNC= -0x1030c0a,
> +AC3_PARSE_ERROR_BSID= -0x2030c0a,
> +AC3_PARSE_ERROR_SAMPLE_RATE = -0x3030c0a,
> +AC3_PARSE_ERROR_FRAME_SIZE  = -0x4030c0a,
> +AC3_PARSE_ERROR_FRAME_TYPE  = -0x5030c0a,
> +AC3_PARSE_ERROR_CRC = -0x6030c0a,
> +} AC3ParseError;
> +
>  /**
>   * Parse AC-3 frame header.
>   * Parse the header up to the lfeon element, which is the first 52 or 54 bits
>   * depending on the audio coding mode.
>   * @param[in]  gbc BitContext containing the first 54 bits of the frame.
>   * @param[out] hdr Pointer to struct where header info is written.
> - * @return Returns 0 on success, -1 if there is a sync word mismatch,
> - * -2 if the bsid (version) element is invalid, -3 if the fscod (sample rate)
> - * element is invalid, or -4 if the frmsizecod (bit rate) element is invalid.
> + * @return Returns 

Re: [FFmpeg-devel] [PATCH v3 1/3] avformat/network: add ff_neterrno2() for cases where we already have an errno

2024-05-07 Thread Andrew Sayers
On Sun, May 05, 2024 at 09:59:28PM +0200, Marton Balint wrote:
> 
> 
> On Fri, 19 Apr 2024, Andrew Sayers wrote:
> 
> > For example, WSAStartup()'s documentation says:
> > 
> >"A call to the WSAGetLastError function is not needed and should not be 
> > used"
> > ---
> > libavformat/network.c | 7 ++-
> > 1 file changed, 6 insertions(+), 1 deletion(-)
> > 
> > diff --git a/libavformat/network.c b/libavformat/network.c
> > index f752efc411..fb70f9cafc 100644
> > --- a/libavformat/network.c
> > +++ b/libavformat/network.c
> > @@ -121,9 +121,14 @@ void ff_network_close(void)
> > }
> > 
> > #if HAVE_WINSOCK2_H
> > +
> > +}
> > int ff_neterrno(void)
> > {
> > -int err = WSAGetLastError();
> > +return ff_neterrno2(WSAGetLastError());
> > +}
> > +int ff_neterrno2(int err)
> 
> ff_neterror(int err) would be a better name, since it has nothing to do with
> errno.
> 
> Regards.
> Marton

Not sure which one you're proposing to rename, but if the original
ff_neterrno() was documented, I think it would say something like:

/*
 * @brief AVERROR for the latest network function
 * @return AVERROR based on `WSAGetLastError()` (Windows) or `errno` (otherwise)
 */

... and neterrno2 would be something like:

/*
 * @brief ff_neterrno()-style AVERROR
 * @param err error code (usually an errno or Windows Sockets Error Code)
 * @return AVERROR equivalent to err
 */

So neither necessarily have anything to do with errno.  How about adding the
above documentation then doing s/ff_neterrno(2?)/ff_neterror\1/g ?

Note: this was supposed to be a quick patch documenting the existing behaviour
of a single function, and has now scope-crept up to a fairly sizeable refactor
of a barely-related function.  I don't mind working on this sort of thing in
principle, but would like to land this particular patch before things get too
much further out of hand.
___
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 2/3] avformat/network: Return 0/AVERROR from ff_network_init()

2024-05-07 Thread Andrew Sayers
On Sun, May 05, 2024 at 10:05:36PM +0200, Marton Balint wrote:
> 
> 
> On Sat, 20 Apr 2024, Andrew Sayers wrote:
> 
> > ---
> > libavformat/avio.c|  4 ++--
> > libavformat/network.c |  7 +++
> > libavformat/rtsp.c| 12 ++--
> > libavformat/rtspdec.c |  4 ++--
> > libavformat/sapdec.c  |  4 ++--
> > libavformat/sapenc.c  |  4 ++--
> > 6 files changed, 17 insertions(+), 18 deletions(-)
> > 
> > diff --git a/libavformat/avio.c b/libavformat/avio.c
> > index d109f3adff..f82edec779 100644
> > --- a/libavformat/avio.c
> > +++ b/libavformat/avio.c
> > @@ -123,8 +123,8 @@ static int url_alloc_for_protocol(URLContext **puc, 
> > const URLProtocol *up,
> > int err;
> > 
> > #if CONFIG_NETWORK
> > -if (up->flags & URL_PROTOCOL_FLAG_NETWORK && !ff_network_init())
> > -return AVERROR(EIO);
> > +if (up->flags & URL_PROTOCOL_FLAG_NETWORK && (err=ff_network_init())<0)
> > +return err;
> > #endif
> > if ((flags & AVIO_FLAG_READ) && !up->url_read) {
> > av_log(NULL, AV_LOG_ERROR,
> > diff --git a/libavformat/network.c b/libavformat/network.c
> > index f295957aa5..c1b0e69362 100644
> > --- a/libavformat/network.c
> > +++ b/libavformat/network.c
> > @@ -59,11 +59,10 @@ int ff_network_init(void)
> > {
> > #if HAVE_WINSOCK2_H
> > WSADATA wsaData;
> > -
> > -if (WSAStartup(MAKEWORD(1,1), ))
> > -return 0;
> > +return ff_neterrno2(WSAStartup(MAKEWORD(1,1), ));
> > +#else
> > +return 0;
> > #endif
> > -return 1;
> > }
> > 
> > int ff_network_wait_fd(int fd, int write)
> > diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
> > index b0c61ee00a..3db4ed11c2 100644
> > --- a/libavformat/rtsp.c
> > +++ b/libavformat/rtsp.c
> > @@ -1740,8 +1740,8 @@ int ff_rtsp_connect(AVFormatContext *s)
> > return AVERROR(EINVAL);
> > }
> > 
> > -if (!ff_network_init())
> > -return AVERROR(EIO);
> > +if ((err = ff_network_init())<0)
> > +return err;
> 
> Assignments in if conditions should be avoided. So this should be expanded
> to:
> 
> err = ff_network_init();
> if (err < 0)
>return err;
> 
> Same for the rest of the checks later.
> 
> Thanks,
> Marton

Assignments in if conditions seem to be the standard in that file, so I figured
it was better to have one ugly standard than two competing ones.  But I agree
they're not good, so I'll propose a new patch in a few days if nobody objects.
___
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 v3 1/3] doc: Explain what "context" means

2024-05-05 Thread Andrew Sayers
I'm still travelling, so the following thoughts might be a bit
half-formed.  But I wanted to get some feedback before sitting down
for a proper think.

On Sun, May 05, 2024 at 09:29:10AM +0200, Stefano Sabatini wrote:
> On date Monday 2024-04-29 10:10:35 +0100, Andrew Sayers wrote:
> > On Mon, Apr 22, 2024 at 07:05:12PM +0200, Stefano Sabatini wrote:
> [...]
> > > I don't have a strong opinion, but I'd probably focus on providing a
> > > typical example of a common API (check doc/examples). Also I see here
> > > there is a strong focus on OOP, this might be counter-productive in
> > > case the reader is not familiar with OOP terminology.
> > > 
> > > OTOH the content might be useful for readers coming from an OOP
> > > background and terminology. I wonder if this content might be isolated
> > > in a dedicated section, so that non-OOP readers can simply skip it.
> > > 
> > > But this is not a strong objection, and can be possibly reworked in a
> > > later step.
> > > 
> > 
> > This is really a document for FFmpeg newbies, so we need to assume as
> > little prior knowledge as possible.  After a few days to think it
> > over, I think we should avoid assuming...
> > 
> > Knowledge of object-oriented programming.  For example, this should be
> > useful to a research mathematician with a project that involves codec
> > algorithms.  So the next draft should feel less like "FFmpeg for OOP
> > devs" and more like "FFmpeg for newbies (with some optional OOP
> > background reading)".
> > 
> > Knowing that programming doesn't *have* to be object-oriented.
> > OOP has become so ubiquitous nowadays, there are plenty of programmers
> > who will insist everything is OOP if you just speak loudly and slowly.
> > This is a harder problem in some ways, because someone who doesn't
> > understand can always re-read until they do, while someone who jumps
> > to the wrong conclusion will just keep reading and try to make things
> > fit their assumption (e.g. my earlier messages in this thread!).
> > So the "how it differs from OOP" stuff needs to stay fairly prominent.
> > 
> 
> > Knowing anything about FFmpeg (or multimedia in general).  I like the
> > idea of tweaking `doc/examples` to better introduce FFmpeg
> > fundamentals, but explaining "context" is a steep enough learning
> > curve on its own - introducing concepts like "stream" and "codec" at
> > the same time seems like too much.
> 
> But even if you show the API that does not mean you need to explain
> it entirely, you only need to highligth the structural relationships:
> 
> // create an instance context, whatever it is
> c = avcodec_alloc_context3(codec);
> if (!c) {
> fprintf(stderr, "Could not allocate video codec context\n");
> exit(1);
> }
> 
> // set context parametres directly
> c->bit_rate = 40;
> /* resolution must be a multiple of two */
> c->width = 352;
> c->height = 288;
> /* frames per second */
> c->time_base = (AVRational){1, 25};
> c->framerate = (AVRational){25, 1};
> 
> // use av_opt API to set the options?
> ...
> 
> // open the codec context provided a codec
> ret = avcodec_open2(c, codec, NULL);
> if (ret < 0) {
> fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));
> exit(1);
> }
> 
> You might even replace avcodec_ with fooblargh_ and get the same
> effect, with the addition that with avcodec_ you are already
> familiarizing the user with the concrete API rather than with an
> hypotetical one.
> 
> [...]
> 
> > I've also gone through the code looking for edge cases we haven't covered.
> > Here are some questions trying to prompt an "oh yeah I forgot to mention
> > that"-type answer.  Anything where the answer is more like "that should
> > probably be rewritten to be clearer", let me know and I'll avoid confusing
> > newbies with it.
> > 
> 
> > av_ambient_viewing_environment_create_side_data() takes an AVFrame as its
> > first argument, and returns a new AVAmbientViewingEnvironment.  What is the
> > context object for that function - AVFrame or AVAmbientViewingEnvironment?
> 
> But this should be clear from the doxy:
> 
> /**
>  * Allocate and add an AVAmbientViewingEnvironment structure to an existing
>  * AVFrame as side data.
>  *
>  * @return the newly allocated struct, or NULL on failure
>  */
> AVAmbientViewingEnvironment 
> *av_a

Re: [FFmpeg-devel] [PATCH v4 1/4] doc: Explain what "context" means

2024-05-05 Thread Andrew Sayers
On Sun, May 05, 2024 at 10:31:18AM +0200, Andreas Rheinhardt wrote:
> Andrew Sayers:
> > Derived from detailed explanations kindly provided by Stefano Sabatini:
> > https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325903.html
> > ---
> >  doc/context.md | 308 +
> >  1 file changed, 308 insertions(+)
> >  create mode 100644 doc/context.md
> > 
> 
> Who is the intended audience of this file? (Aspiring) internal
> developers or external API users?

External API users.  This needs to say e.g. "ignore anything called
`internal` or `priv_data`", whereas a document for new internal devs
would say which one to prefer in new code.  That would be very
useful, but well beyond my current abilities.

(I'm still travelling so have low mental and typing bandwidth, but am
thinking through other responses and should have time to respond in
the coming days)
___
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] [RFC] 5 year plan & Inovation

2024-05-04 Thread Andrew Sayers
On Sat, May 04, 2024 at 09:28:03PM +0200, Michael Niedermayer wrote:
> Hi
> 
> On Fri, May 03, 2024 at 03:45:20PM +, Cosmin Stejerean via ffmpeg-devel 
> wrote:
> [...]
> > What doesn't exist (yet) is a way to keep people on the exact email based 
> > workflow 
> > we currently have, and have bi-directional sync with something like github 
> > or gitlab.
> > Such a thing could probably be built, but it might be worth first trying to 
> > see if those
> > that insist on sticking with the CLI can use one of the existing CLI based 
> > workflows.
> 
> Such a thing could be quite useful to many more projects than just ffmpeg.
> There are many older projects that use ML based workflows.
> 
> I imagine STF might be willing to fund such a thing if it is technically
> feasable. As the goal of STF is about maintainance. And bridging the gap
> between old ML and new browser based workflows allowing developers who
> prefer to work through their web browser to do so.
> 
> also, we need to find maintaince related projects worth minimum 150k €
> for 2025 for STF.
> We cant do many of the things we do in 2024 for STF again as they where
> one time things and STF doesnt like sponsoring adding new features.
> 
> thx

It seems like the strongest argument for sticking with the ML is from
experienced maintainers who don't want to jeopardise their existing
workflow; while the strongest argument for switching is from people
itching to try out new workflows.  So how about this for a plan...

Make a repo on SourceHut, not necessarily for FFmpeg itself but for
automated review tools (running fate tests, checking C11 compliance
etc.).  Their CI/CD system automatically runs those tests on every
patch, then we manually forward genuine issues to the ML.  That would
let experimenters show off new things, and would let maintainers
think through what their workflow would look like in a mixed
environment.  Then when we've got enough evidence to make a long-term
plan, we can wind the repo down without too much fuss.
___
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 3/4] all: Link to "context" from all contexts with documentation

2024-05-02 Thread Andrew Sayers
On Thu, May 02, 2024 at 09:00:42PM +0800, Zhao Zhili wrote:
> 
> 
> > On May 2, 2024, at 19:01, Lynne  wrote:
> > 
> > Apr 29, 2024, 11:24 by ffmpeg-de...@pileofstuff.org:
> > 
> >> Some headings needed to be rewritten to accomodate the text,
> >> (hopefully) without changing the meaning.
> >> ---
> >> libavcodec/aac/aacdec.h|  2 +-
> >> libavcodec/aacenc.h|  2 +-
> >> libavcodec/ac3enc.h|  2 +-
> >> libavcodec/amfenc.h|  2 +-
> >> libavcodec/atrac.h |  2 +-
> >> libavcodec/avcodec.h   |  3 ++-
> >> libavcodec/bsf.h   |  2 +-
> >> libavcodec/cbs.h   |  2 +-
> >> libavcodec/d3d11va.h   |  3 +--
> >> libavcodec/h264dsp.h   |  2 +-
> >> libavcodec/h264pred.h  |  2 +-
> >> libavcodec/mediacodec.h|  2 +-
> >> libavcodec/mpegaudiodec_template.c |  2 +-
> >> libavcodec/pthread_frame.c |  4 ++--
> >> libavcodec/qsv.h   |  6 --
> >> libavcodec/sbr.h   |  2 +-
> >> libavcodec/smacker.c   |  2 +-
> >> libavcodec/vdpau.h |  3 ++-
> >> libavcodec/videotoolbox.h  |  5 +++--
> >> libavfilter/avfilter.h |  2 +-
> >> libavformat/avformat.h |  3 ++-
> >> libavformat/avio.h |  3 ++-
> >> libavutil/audio_fifo.h |  2 +-
> >> libavutil/hwcontext.h  | 21 -
> >> libavutil/hwcontext_cuda.h |  2 +-
> >> libavutil/hwcontext_d3d11va.h  |  4 ++--
> >> libavutil/hwcontext_d3d12va.h  |  6 +++---
> >> libavutil/hwcontext_drm.h  |  2 +-
> >> libavutil/hwcontext_dxva2.h|  4 ++--
> >> libavutil/hwcontext_mediacodec.h   |  2 +-
> >> libavutil/hwcontext_opencl.h   |  4 ++--
> >> libavutil/hwcontext_qsv.h  |  4 ++--
> >> libavutil/hwcontext_vaapi.h|  6 +++---
> >> libavutil/hwcontext_vdpau.h|  2 +-
> >> libavutil/hwcontext_vulkan.h   |  4 ++--
> >> libavutil/lfg.h|  2 +-
> >> 36 files changed, 66 insertions(+), 57 deletions(-)
> >> 
> >> diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h
> >> index 4cf764e2e9..71d61813f4 100644
> >> --- a/libavcodec/aac/aacdec.h
> >> +++ b/libavcodec/aac/aacdec.h
> >> @@ -248,7 +248,7 @@ typedef struct AACDecDSP {
> >> } AACDecDSP;
> >> 
> >> /**
> >> - * main AAC decoding context
> >> + * main AAC decoding @ref md_doc_2context "context"
> >> */
> >> struct AACDecContext {
> >> const struct AVClass  *class;
> >> diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
> >> index d07960620e..1a645f4719 100644
> >> --- a/libavcodec/aacenc.h
> >> +++ b/libavcodec/aacenc.h
> >> @@ -207,7 +207,7 @@ typedef struct AACPCEInfo {
> >> } AACPCEInfo;
> >> 
> >> /**
> >> - * AAC encoder context
> >> + * AAC encoder @ref md_doc_2context "context"
> >> */
> >> typedef struct AACEncContext {
> >> AVClass *av_class;
> >> diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
> >> index 30812617cc..c725007077 100644
> >> --- a/libavcodec/ac3enc.h
> >> +++ b/libavcodec/ac3enc.h
> >> @@ -152,7 +152,7 @@ typedef struct AC3Block {
> >> } AC3Block;
> >> 
> >> /**
> >> - * AC-3 encoder private context.
> >> + * AC-3 encoder private @ref md_doc_2context "context"
> >> */
> >> typedef struct AC3EncodeContext {
> >> AVClass *av_class;  ///< AVClass used for AVOption
> >> diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
> >> index 2dbd378ef8..f142ede63a 100644
> >> --- a/libavcodec/amfenc.h
> >> +++ b/libavcodec/amfenc.h
> >> @@ -43,7 +43,7 @@ typedef struct AmfTraceWriter {
> >> } AmfTraceWriter;
> >> 
> >> /**
> >> -* AMF encoder context
> >> +* AMF encoder @ref md_doc_2context "context"
> >> */
> >> 
> >> typedef struct AmfContext {
> >> diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
> >> index 05208bbee6..1527e376a9 100644
> >> --- a/libavcodec/atrac.h
> >> +++ b/libavcodec/atrac.h
> >> @@ -39,7 +39,7 @@ typedef struct AtracGainInfo {
> >> } AtracGainInfo;
> >> 
> >> /**
> >> - *  Gain compensation context structure.
> >> + *  Gain compensation @ref md_doc_2context "context"
> >> */
> >> typedef struct AtracGCContext {
> >> float   gain_tab1[16];  ///< gain compensation level table
> >> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> >> index 968009a192..9180fedca7 100644
> >> --- a/libavcodec/avcodec.h
> >> +++ b/libavcodec/avcodec.h
> >> @@ -430,7 +430,8 @@ typedef struct RcOverride{
> >> #define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0)
> >> 
> >> /**
> >> - * main external API structure.
> >> + * @ref md_doc_2context "Context" for an encode or decode session
> >> + *
> >> * New fields can be added to the end with minor version bumps.
> >> * Removal, reordering and changes to existing fields require a major
> >> * version bump.
> >> diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
> >> index a09c69f242..bf79afa7cc 100644
> >> --- a/libavcodec/bsf.h
> >> +++ 

Re: [FFmpeg-devel] [PATCH v4 3/4] all: Link to "context" from all contexts with documentation

2024-05-02 Thread Andrew Sayers
On Thu, May 02, 2024 at 01:01:43PM +0200, Lynne wrote:
> Apr 29, 2024, 11:24 by ffmpeg-de...@pileofstuff.org:
> 
> > Some headings needed to be rewritten to accomodate the text,
> > (hopefully) without changing the meaning.
> > ---
> >  libavcodec/aac/aacdec.h|  2 +-
> >  libavcodec/aacenc.h|  2 +-
> >  libavcodec/ac3enc.h|  2 +-
> >  libavcodec/amfenc.h|  2 +-
> >  libavcodec/atrac.h |  2 +-
> >  libavcodec/avcodec.h   |  3 ++-
> >  libavcodec/bsf.h   |  2 +-
> >  libavcodec/cbs.h   |  2 +-
> >  libavcodec/d3d11va.h   |  3 +--
> >  libavcodec/h264dsp.h   |  2 +-
> >  libavcodec/h264pred.h  |  2 +-
> >  libavcodec/mediacodec.h|  2 +-
> >  libavcodec/mpegaudiodec_template.c |  2 +-
> >  libavcodec/pthread_frame.c |  4 ++--
> >  libavcodec/qsv.h   |  6 --
> >  libavcodec/sbr.h   |  2 +-
> >  libavcodec/smacker.c   |  2 +-
> >  libavcodec/vdpau.h |  3 ++-
> >  libavcodec/videotoolbox.h  |  5 +++--
> >  libavfilter/avfilter.h |  2 +-
> >  libavformat/avformat.h |  3 ++-
> >  libavformat/avio.h |  3 ++-
> >  libavutil/audio_fifo.h |  2 +-
> >  libavutil/hwcontext.h  | 21 -
> >  libavutil/hwcontext_cuda.h |  2 +-
> >  libavutil/hwcontext_d3d11va.h  |  4 ++--
> >  libavutil/hwcontext_d3d12va.h  |  6 +++---
> >  libavutil/hwcontext_drm.h  |  2 +-
> >  libavutil/hwcontext_dxva2.h|  4 ++--
> >  libavutil/hwcontext_mediacodec.h   |  2 +-
> >  libavutil/hwcontext_opencl.h   |  4 ++--
> >  libavutil/hwcontext_qsv.h  |  4 ++--
> >  libavutil/hwcontext_vaapi.h|  6 +++---
> >  libavutil/hwcontext_vdpau.h|  2 +-
> >  libavutil/hwcontext_vulkan.h   |  4 ++--
> >  libavutil/lfg.h|  2 +-
> >  36 files changed, 66 insertions(+), 57 deletions(-)
> >
> > diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h
> > index 4cf764e2e9..71d61813f4 100644
> > --- a/libavcodec/aac/aacdec.h
> > +++ b/libavcodec/aac/aacdec.h
> > @@ -248,7 +248,7 @@ typedef struct AACDecDSP {
> >  } AACDecDSP;
> >  
> >  /**
> > - * main AAC decoding context
> > + * main AAC decoding @ref md_doc_2context "context"
> >  */
> >  struct AACDecContext {
> >  const struct AVClass  *class;
> > diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
> > index d07960620e..1a645f4719 100644
> > --- a/libavcodec/aacenc.h
> > +++ b/libavcodec/aacenc.h
> > @@ -207,7 +207,7 @@ typedef struct AACPCEInfo {
> >  } AACPCEInfo;
> >  
> >  /**
> > - * AAC encoder context
> > + * AAC encoder @ref md_doc_2context "context"
> >  */
> >  typedef struct AACEncContext {
> >  AVClass *av_class;
> > diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
> > index 30812617cc..c725007077 100644
> > --- a/libavcodec/ac3enc.h
> > +++ b/libavcodec/ac3enc.h
> > @@ -152,7 +152,7 @@ typedef struct AC3Block {
> >  } AC3Block;
> >  
> >  /**
> > - * AC-3 encoder private context.
> > + * AC-3 encoder private @ref md_doc_2context "context"
> >  */
> >  typedef struct AC3EncodeContext {
> >  AVClass *av_class;  ///< AVClass used for AVOption
> > diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
> > index 2dbd378ef8..f142ede63a 100644
> > --- a/libavcodec/amfenc.h
> > +++ b/libavcodec/amfenc.h
> > @@ -43,7 +43,7 @@ typedef struct AmfTraceWriter {
> >  } AmfTraceWriter;
> >  
> >  /**
> > -* AMF encoder context
> > +* AMF encoder @ref md_doc_2context "context"
> >  */
> >  
> >  typedef struct AmfContext {
> > diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
> > index 05208bbee6..1527e376a9 100644
> > --- a/libavcodec/atrac.h
> > +++ b/libavcodec/atrac.h
> > @@ -39,7 +39,7 @@ typedef struct AtracGainInfo {
> >  } AtracGainInfo;
> >  
> >  /**
> > - *  Gain compensation context structure.
> > + *  Gain compensation @ref md_doc_2context "context"
> >  */
> >  typedef struct AtracGCContext {
> >  float   gain_tab1[16];  ///< gain compensation level table
> > diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> > index 968009a192..9180fedca7 100644
> > --- a/libavcodec/avcodec.h
> > +++ b/libavcodec/avcodec.h
> > @@ -430,7 +430,8 @@ typedef struct RcOverride{
> >  #define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0)
> >  
> >  /**
> > - * main external API structure.
> > + * @ref md_doc_2context "Context" for an encode or decode session
> > + *
> >  * New fields can be added to the end with minor version bumps.
> >  * Removal, reordering and changes to existing fields require a major
> >  * version bump.
> > diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
> > index a09c69f242..bf79afa7cc 100644
> > --- a/libavcodec/bsf.h
> > +++ b/libavcodec/bsf.h
> > @@ -56,7 +56,7 @@
> >  */
> >  
> >  /**
> > - * The bitstream filter state.
> > + * Bitstream filter @ref 

Re: [FFmpeg-devel] [PATCH v3 1/3] doc: Explain what "context" means

2024-05-02 Thread Andrew Sayers
On Mon, Apr 29, 2024 at 10:10:35AM +0100, Andrew Sayers wrote:
> 
> I've also gone through the code looking for edge cases we haven't covered.
> Here are some questions trying to prompt an "oh yeah I forgot to mention
> that"-type answer.  Anything where the answer is more like "that should
> probably be rewritten to be clearer", let me know and I'll avoid confusing
> newbies with it.
> 
> av_ambient_viewing_environment_create_side_data() takes an AVFrame as its
> first argument, and returns a new AVAmbientViewingEnvironment.  What is the
> context object for that function - AVFrame or AVAmbientViewingEnvironment?
> 
> av_register_bitstream_filter() (deprecated 4.0, removed 5.0) took an
> `AVBitStreamFilter *` as its first argument, but I don't think you'd say
> the argument provided "context" for the function.  So would I be right in
> saying `AVBitStreamFilter *` is not a context, despite looking like one?
> 
> av_buffersink_*() all take a `const AVFilterContext *` argument.
> What does the difference between av_buffersink prefix and AVFilter type mean?
> 
> av_channel_description_bprint() takes a `struct AVBPrint *` as its first
> argument, then `enum AVChannel`.  Is the context AVBPrint, AVChannel,
> or both?  Does it make sense for a function to have two contexts?
> 
> Related to the previous question, does `av_cmp_q()` count as a function
> with two contexts?  Or no contexts?
> 
> Finally, a general question - functions of the form "avfoo" seem like they
> are more consistent than "av_foo".  Does the underscore mean anything?

One extra question I hadn't thought to ask before - when, if at all, would an
ordinary user be expected to access the contents of AVClass directly?  Or
AVOption for that matter?  For example, it's not clear to me how people are
supposed to use AVClass.category - is this an important use case we haven't
covered?  Either way, happy to propose an AVClass patch to make it clearer.

It's my turn to be off for a few days, so will pick up any responses next week.
___
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] doc/Doxfyile: Refactor for maintainability

2024-04-30 Thread Andrew Sayers
On Tue, Apr 30, 2024 at 07:26:39PM +0200, Michael Niedermayer wrote:
> On Mon, Apr 29, 2024 at 09:53:13AM +0100, Andrew Sayers wrote:
> > On Sun, Apr 28, 2024 at 11:46:18PM +0200, Michael Niedermayer wrote:
> > > Hi
> > > 
> > > On Sun, Apr 28, 2024 at 11:10:22AM +0100, Andrew Sayers wrote:
> > > [...]
> > > > Ping ?
> > > > 
> > > > Michael, this is in response to your request[0].  I've queued up some 
> > > > more
> > > > patches that depend on this and would help attract and retain 
> > > > developers (e.g.
> > > > warning when you're looking at old documentation).  What would be 
> > > > involved in
> > > > getting this sort of thing on the website itself?
> > > 
> > > I dont have the time to review this
> > > 
> > > if you split the patch between updates to to comments and updates to teh 
> > > actual
> > > configuration this may make it easier to review to whoever does review it
> > 
> > Thanks for letting me know.
> > 
> > For anyone who does pick this up - this patch does not contain any changes
> > to the configuration.  I've attached a default 1.8.2 configuration file in 
> > case
> > you want to use them for a review, but it's a real timesink so I'd recommend
> > the build-and-diff approach in the patch description.
> > 
> > My interest in this patch was about getting the website itself updated.
> > My understanding is that can't happen without Michael's involvement,
> > so I'm planning to focus my attention elsewhere.
> 
> I can update the file on the server but i cannot currently review a 200+k doxy
> configuration diff someone else needs to review whatever needs review for the 
> doxy config
> 
> thx

Reading the patch again, I don't think the patch body is the problem.
The problem is that the message doesn't properly explain what it does.

The repo configuration (doc/Doxyfile) and website configuration[0] have spent
a decade drifting apart, and now behave in ways that are too different to knit
back together in a single patch.  So this patch avoids any attempt to analyse
the logic, and simply provides a collection of files that produce byte-for-byte
identical output while being easier to maintain in future.

doc/Doxyfile-1.8.17 is literally just the 1.8.17 output of `doxygen -g`.

doc/Doxyfile-website contains configuration that existed in the file you
provided, but not in the stock 1.8.17 configuration or doc/Doxyfile.

doc/Doxyfile contains configuration that existed in the old doc/Doxyfile,
but not in the stock 1.8.17 configuration or your file.

doc/Doxyfile-FFmpeg contains configuration that was in both your file and the
old doc/Doxyfile, but not the stock 1.8.17 configuration.

So each file represents at least a three-way diff, arguably four or five
if you include the older stock configuration files they were originally based
on.  Trying to present that as a series of two-way diffs will always be
confusing, so it's best not to read the diff itself, and instead concentrate
on the contents of the new files.

Reviewing doc/Doxyfile-1.8.17 just means doing `doxygen -g` with the version of
doxygen on the server, then diffing them to confirm they're the same.

doc/Doxyfile looks like a huge diff because 99% of the configuration is now in
doc/Doxyfile-1.8.17.  The diff is particularly un-human-readable for this file,
so I've attached a copy of the new file for reference.  Would it be better if
the attached file was called doc/Doxyfile-repo, and the old doc/Doxyfile
was changed to just "@INCLUDE = doc/Doxyfile-repo" and a recommendation to
update any scripts that pointed there?

doc/Doxyfile{,-FFmpeg,-website} are only about 200 lines between them.
Running doxygen with old and new configuration should confirm they don't
change behaviour, so reviewing them beyond that just means skimming through
to make sure I haven't snuck in an `rm -rf /` or something.  You can review
these files for logic if you like, and if I've done my job right you should 
feel a strong temptation to fix them.  But doing so is a problem for another
patch, so explicitly out-of-scope for this review.

[0] https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/326010.html
# Local doxygen configuration
#
# This configuration is optimised to produce pleasant documentation,
# but its output may change at any time.
#
# Only put configuration here if it breaks compatibility with older versions.
# For example, if a new version of doxygen adds a new option,
# enable it here.  Put "safe" improvements in Doxyfile-FFmpeg,
# and compatibility changes in Doxyfile-website

@INCLUDE = doc/Doxyfile-1.8.17
@INCLUDE = doc/Doxyfile-FFmpeg

#---

Re: [FFmpeg-devel] [RFC] 5 year plan & Inovation

2024-04-30 Thread Andrew Sayers
On Tue, Apr 30, 2024 at 09:05:05PM +0200, Ondřej Fiala wrote:
> On Mon Apr 29, 2024 at 9:04 PM CEST, Davy Durham wrote:
> > Presently do you not have to create an account on the devel mailing list to
> > contribute to ffmpeg?
> >
> > So on the flip side, I (actually) find it just as annoying to have to
> > create such accounts at every project rather than my having one account at
> > GitHub (or a relatively few for other hosting sites) and can then
> > contribute to literally thousands of projects without any friction.
> I would disagree on the "friction" part. To contribute, you have to "fork"
> the project, add your "fork" as a new git remote, push to it, and only then
> can you create a pull request. In comparison, contributing using email is
> literally just two simple git commands without ever having to leave the
> terminal.

IMHO, GitHub have improved that user experience significantly in recent years.
Yes you're still making a fork and pushing it, but the experience is more like
click the edit button -> make changes (in an admittedly clunky web editor) ->
save and push.  The rest is just kinda presented as implementation details.

That's a bit of a nitpick, but the wider point is interesting -
GitHub etc. are fast-moving targets, so today's friction points become
tomorrow's selling points, then the next day's lock-in opportunities.
That makes it hard to compare to a mailing list, which is unlikely to be
better or worse ten years from now.

> > Moreover now being subscribed to that list I get 50 emails a day that I
> > have to wait through. Just so long as I want to contribute. Sure I can
> > create rules but it is pretty obnoxious.
> >
> > As a casual contributor, I much prefer getting notifications about my
> > occasion contributions.  But one can opt to get notified of everything by
> > subscribing to the whole project.
> I actually agree that the mailing list can be somewhat annoying as well,
> which is why I like that on SourceHut you can send a patch to their mailing
> lists without being subscribed and it's standard practice that people Cc you
> on the replies. I really feel like this should be standard practice;
> subscribing to the mailing list makes no sense if you only want to send in a
> single patch, and it increases the effort required by flooding you with emails
> which aren't relevant to you, as you say.
> 
> I personally find the mailing list much less annoying than using GitHub even
> when subscription is required, but I feel like without having to subscribe
> it's the most straight-forward way really.

I haven't properly tried this, and it's an ugly hack if it works at all, but it
might be possible to support logged-out comments with a web-based trigger.

Triggers are designed to let you e.g. ping a URL on github.com when some
third-party dependency is updated, and have code on their servers automatically
pull in that dependency and rebuild your package without manual intervention.
But you could equally ping "my-web-hook?name=...=..." then have your
bot turn that into a comment.

This isn't unique to GitHub - a quick look suggests GitLab can do the same,
and I wouldn't be surprised if SourceHut can too.  And a self-hosted solution
could presumably use this as the basis for a general anonymous comment thing.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v4 4/4] lavf: Add documentation for private "Context" classes

2024-04-29 Thread Andrew Sayers
Doxygen thinks any text like "Context for foo" is a link to a struct called 
"Context".
Add a description and a better link, to avoid confusing readers.
---
 libavformat/async.c | 3 +++
 libavformat/cache.c | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/libavformat/async.c b/libavformat/async.c
index e096b0bc6f..3c28d418ae 100644
--- a/libavformat/async.c
+++ b/libavformat/async.c
@@ -53,6 +53,9 @@ typedef struct RingBuffer
 int   read_pos;
 } RingBuffer;
 
+/**
+ * @brief @ref md_doc_2context "Context" for testing async
+ */
 typedef struct Context {
 AVClass*class;
 URLContext *inner;
diff --git a/libavformat/cache.c b/libavformat/cache.c
index 5f78adba9d..3cc0edec82 100644
--- a/libavformat/cache.c
+++ b/libavformat/cache.c
@@ -52,6 +52,9 @@ typedef struct CacheEntry {
 int size;
 } CacheEntry;
 
+/**
+ * @brief @ref md_doc_2context "Context" for a cache
+ */
 typedef struct Context {
 AVClass *class;
 int fd;
-- 
2.43.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 v4 3/4] all: Link to "context" from all contexts with documentation

2024-04-29 Thread Andrew Sayers
Some headings needed to be rewritten to accomodate the text,
(hopefully) without changing the meaning.
---
 libavcodec/aac/aacdec.h|  2 +-
 libavcodec/aacenc.h|  2 +-
 libavcodec/ac3enc.h|  2 +-
 libavcodec/amfenc.h|  2 +-
 libavcodec/atrac.h |  2 +-
 libavcodec/avcodec.h   |  3 ++-
 libavcodec/bsf.h   |  2 +-
 libavcodec/cbs.h   |  2 +-
 libavcodec/d3d11va.h   |  3 +--
 libavcodec/h264dsp.h   |  2 +-
 libavcodec/h264pred.h  |  2 +-
 libavcodec/mediacodec.h|  2 +-
 libavcodec/mpegaudiodec_template.c |  2 +-
 libavcodec/pthread_frame.c |  4 ++--
 libavcodec/qsv.h   |  6 --
 libavcodec/sbr.h   |  2 +-
 libavcodec/smacker.c   |  2 +-
 libavcodec/vdpau.h |  3 ++-
 libavcodec/videotoolbox.h  |  5 +++--
 libavfilter/avfilter.h |  2 +-
 libavformat/avformat.h |  3 ++-
 libavformat/avio.h |  3 ++-
 libavutil/audio_fifo.h |  2 +-
 libavutil/hwcontext.h  | 21 -
 libavutil/hwcontext_cuda.h |  2 +-
 libavutil/hwcontext_d3d11va.h  |  4 ++--
 libavutil/hwcontext_d3d12va.h  |  6 +++---
 libavutil/hwcontext_drm.h  |  2 +-
 libavutil/hwcontext_dxva2.h|  4 ++--
 libavutil/hwcontext_mediacodec.h   |  2 +-
 libavutil/hwcontext_opencl.h   |  4 ++--
 libavutil/hwcontext_qsv.h  |  4 ++--
 libavutil/hwcontext_vaapi.h|  6 +++---
 libavutil/hwcontext_vdpau.h|  2 +-
 libavutil/hwcontext_vulkan.h   |  4 ++--
 libavutil/lfg.h|  2 +-
 36 files changed, 66 insertions(+), 57 deletions(-)

diff --git a/libavcodec/aac/aacdec.h b/libavcodec/aac/aacdec.h
index 4cf764e2e9..71d61813f4 100644
--- a/libavcodec/aac/aacdec.h
+++ b/libavcodec/aac/aacdec.h
@@ -248,7 +248,7 @@ typedef struct AACDecDSP {
 } AACDecDSP;
 
 /**
- * main AAC decoding context
+ * main AAC decoding @ref md_doc_2context "context"
  */
 struct AACDecContext {
 const struct AVClass  *class;
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index d07960620e..1a645f4719 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -207,7 +207,7 @@ typedef struct AACPCEInfo {
 } AACPCEInfo;
 
 /**
- * AAC encoder context
+ * AAC encoder @ref md_doc_2context "context"
  */
 typedef struct AACEncContext {
 AVClass *av_class;
diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
index 30812617cc..c725007077 100644
--- a/libavcodec/ac3enc.h
+++ b/libavcodec/ac3enc.h
@@ -152,7 +152,7 @@ typedef struct AC3Block {
 } AC3Block;
 
 /**
- * AC-3 encoder private context.
+ * AC-3 encoder private @ref md_doc_2context "context"
  */
 typedef struct AC3EncodeContext {
 AVClass *av_class;  ///< AVClass used for AVOption
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 2dbd378ef8..f142ede63a 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -43,7 +43,7 @@ typedef struct AmfTraceWriter {
 } AmfTraceWriter;
 
 /**
-* AMF encoder context
+* AMF encoder @ref md_doc_2context "context"
 */
 
 typedef struct AmfContext {
diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
index 05208bbee6..1527e376a9 100644
--- a/libavcodec/atrac.h
+++ b/libavcodec/atrac.h
@@ -39,7 +39,7 @@ typedef struct AtracGainInfo {
 } AtracGainInfo;
 
 /**
- *  Gain compensation context structure.
+ *  Gain compensation @ref md_doc_2context "context"
  */
 typedef struct AtracGCContext {
 float   gain_tab1[16];  ///< gain compensation level table
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 968009a192..9180fedca7 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -430,7 +430,8 @@ typedef struct RcOverride{
 #define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0)
 
 /**
- * main external API structure.
+ * @ref md_doc_2context "Context" for an encode or decode session
+ *
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
index a09c69f242..bf79afa7cc 100644
--- a/libavcodec/bsf.h
+++ b/libavcodec/bsf.h
@@ -56,7 +56,7 @@
  */
 
 /**
- * The bitstream filter state.
+ * Bitstream filter @ref md_doc_2context "context"
  *
  * This struct must be allocated with av_bsf_alloc() and freed with
  * av_bsf_free().
diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h
index d479b1ac2d..0ff64d2fef 100644
--- a/libavcodec/cbs.h
+++ b/libavcodec/cbs.h
@@ -214,7 +214,7 @@ typedef void (*CBSTraceWriteCallback)(void *trace_context,
   int64_t value);
 
 /**
- * Context structure for coded bitstream operations.
+ * @ref md_doc_2context "Context" structure for coded bitstream operations.
  */
 typedef struct CodedBitstreamContext {
 /**
diff --git a/libavcodec/d3d11va.h 

[FFmpeg-devel] [PATCH v4 2/4] lavu: Clarify relationship between AVClass, AVOption and context

2024-04-29 Thread Andrew Sayers
---
 libavutil/log.h | 11 ---
 libavutil/opt.h |  7 ---
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/libavutil/log.h b/libavutil/log.h
index ab7ceabe22..cfbf416679 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -59,9 +59,14 @@ typedef enum {
 struct AVOptionRanges;
 
 /**
- * Describe the class of an AVClass context structure. That is an
- * arbitrary struct of which the first field is a pointer to an
- * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.).
+ * Metadata about an arbitrary data structure
+ *
+ * A @ref md_doc_2context "context struct" whose first member is a pointer
+ * to an AVClass object is called an "AVClass context structure"
+ * (e.g. AVCodecContext, AVFormatContext etc.).
+ *
+ * AVClass is often combined with @ref avoptions "AVOptions" to create
+ * "AVOptions-enabled structs" that can be easily configured by users.
  */
 typedef struct AVClass {
 /**
diff --git a/libavutil/opt.h b/libavutil/opt.h
index 855e363091..82ac933a2a 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -39,9 +39,10 @@
  * @defgroup avoptions AVOptions
  * @ingroup lavu_data
  * @{
- * AVOptions provide a generic system to declare options on arbitrary structs
- * ("objects"). An option can have a help text, a type and a range of possible
- * values. Options may then be enumerated, read and written to.
+ * Builds on AVClass, adding a generic system to declare options.
+ *
+ * An option can have a help text, a type and a range of possible values.
+ * Options may then be enumerated, read and written to.
  *
  * There are two modes of access to members of AVOption and its child structs.
  * One is called 'native access', and refers to access from the code that
-- 
2.43.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 v4 1/4] doc: Explain what "context" means

2024-04-29 Thread Andrew Sayers
Derived from detailed explanations kindly provided by Stefano Sabatini:
https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325903.html
---
 doc/context.md | 308 +
 1 file changed, 308 insertions(+)
 create mode 100644 doc/context.md

diff --git a/doc/context.md b/doc/context.md
new file mode 100644
index 00..73297f53aa
--- /dev/null
+++ b/doc/context.md
@@ -0,0 +1,308 @@
+# Introduction to contexts
+
+Like many C projects, FFmpeg has adopted the subset of
+[object-oriented 
programming](https://en.wikipedia.org/wiki/Object-oriented_programming)
+techniques that help solve its problems.  Object-like structures are called 
"contexts",
+and this document provides a general introduction to how they work.
+
+Object-oriented programming tends to focus on
+[access](https://en.wikipedia.org/wiki/Access_modifiers) as a primary concern.
+For example, members of a class are often designated "private" to indicate
+they are only accessible to code that's part of the class.  Less focus is put 
on
+[reflection](https://en.wikipedia.org/wiki/Reflection_(computer_programming)),
+where it is provided at all.  For example, C++ has no built-in way to serialize
+the state of an arbitrary object.
+
+Reflection is extremely important for FFmpeg, because user-facing
+options are implemented by reflecting the state of contexts.  Limiting
+access is a secondary concern, mainly important for ensuring
+implementation details can change between versions.
+
+Knowledge of object-oriented programming concepts can help when learning 
FFmpeg,
+but it's important not to fixate on FFmpeg's access control features,
+nor to overlook its reflection capabilities.  This document compares
+FFmpeg and OOP techniques where relevant, but does not require an understanding
+of object-oriented programming.
+
+## Example: modify text then print it
+
+The example below shows a context structure that receives input strings,
+modifies them in some context-dependant way, then prints them to a specified
+filehandle.
+
+```c
+/**
+ * Type information, accessible at runtime.
+ *
+ * Useful when configuring objects.
+ */
+enum ModifyThenPrintDialect {
+MODIFY_THEN_PRINT_DIALECT_PLAIN_TEXT = 0,
+MODIFY_THEN_PRINT_DIALECT_REGEX  = 1,
+MODIFY_THEN_PRINT_DIALECT_REGEX_PCRE = 2
+};
+
+/**
+ * User-facing information about types
+ *
+ * Useful for describing contexts to the user.
+ */
+static const char *ModifyThenPrintDialectName[] = {
+"plain text",
+"regular expression",
+"Perl-compatible regular expression"
+};
+
+/**
+ * Context for functions that modify strings before printing them
+ */
+struct ModifyThenPrintContext {
+
+/**
+ * Information about the type of this particular instance
+ *
+ * Object-oriented programs would probably replace this with "sub-classes",
+ * where each class extends the base class to implement one dialect.
+ * But information about a type can also work more like "mixins",
+ * where several pieces of unrelated functionality are blended together
+ * to create an interface for a specific purpose.
+ */
+enum ModifyThenPrintDialect dialect;
+
+/**
+ * Internal context
+ *
+ * Contains anything that isn't part of the public interface.
+ * The most obvious OOP analogy is to "private" members that are only
+ * accessible to code that's part of the class.  But it could also contain
+ * information about "virtual functions" - functions that every sub-class
+ * guarantees to implement, but in their own class-specific way.
+ */
+void *priv_data;
+
+/**
+ * User-configurable options
+ *
+ * Best set through an API, but can be set directly if necessary
+ *
+ * Data from users needs to be validated before it's set, and the API
+ * might e.g. want to update some internal buffer for performance reasons.
+ * Setting these directly is always less robust than using an API,
+ * but might be worthwhile if you're willing to spend the time checking
+ * for edge cases, and don't mind your code misbehaving if future
+ * versions change the API but not the structure.
+ *
+ * Object-oriented programs would likely make these "protected" members,
+ * initialised in a constructor and accessed with getters and setters.
+ * That means code *related* to this class can access them directly,
+ * while unrelated code accesses them indirectly by calling functions.
+ *
+ * But the "protected access" analogy is quite limited. In particular,
+ * protected members don't have any special reflective properties,
+ * whereas FFmpeg options are usually configurable by end users.
+ */
+char *replace_this;
+char *with_this;
+
+/**
+ * Programmer-configurable variable
+ *
+ * Object-oriented programs would represent this as a public member.
+ */
+FILE *out;
+
+};
+
+/**
+ * Allocate and initialize a 

Re: [FFmpeg-devel] [PATCH v3 1/3] doc: Explain what "context" means

2024-04-29 Thread Andrew Sayers
On Mon, Apr 22, 2024 at 07:05:12PM +0200, Stefano Sabatini wrote:
> On date Monday 2024-04-22 16:56:48 +0100, Andrew Sayers wrote:
> > Derived from detailed explanations kindly provided by Stefano Sabatini:
> > https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325903.html
> > ---
> >  doc/context.md | 276 +
> >  1 file changed, 276 insertions(+)
> >  create mode 100644 doc/context.md
> > 
> > diff --git a/doc/context.md b/doc/context.md
> > new file mode 100644
> > index 00..73caacf54f
> > --- /dev/null
> > +++ b/doc/context.md
> > @@ -0,0 +1,276 @@
> > +# Context-oriented programming
> > +
> > +Like many C projects, FFmpeg has adopted the subset of object-oriented 
> > techniques
> > +that help solve its problems.  Object-like structures are called 
> > "contexts",
> > +and this document provides a general introduction to how they work.
> > +
> > +Object-oriented programming usually focusses on *access* as a primary 
> > concern.
> > +For example, members of an object are visibly designated "private", 
> > "constant"
> > +etc. to control how they are accessed.  *Reflection* is a secondary 
> > concern,
> > +where it is provided at all.  For example, C++ has no built-in way to get a
> > +string containing the name of a variable.
> > +
> > +Reflection is extremely important for FFmpeg, because user-facing options 
> > are
> > +implemented by reflecting state at runtime. Limiting access is a secondary
> > +concern, mainly important for ensuring implementation details can change
> > +between versions.
> > +
> > +An object-oriented programmer learning FFmpeg should be careful not to 
> > fixate on
> > +FFmpeg's access control features, nor to overlook its reflection 
> > capabilities.
> > +Both are present, but have been given the level of focus appropriate for 
> > the task.
> > +
> > +## Example: modify text then print it
> > +
> > +The example below shows a context structure that receives input strings,
> > +modifies them in some context-dependant way, then prints them to a 
> > specified
> > +filehandle.
> > +
> > +```c
> > +/**
> > + * Type information, accessible at runtime.
> > + *
> > + * Useful when configuring objects.
> > + */
> > +enum ModifyThenPrintDialect {
> > +MODIFY_THEN_PRINT_PLAIN_TEXT = 0,
> > +MODIFY_THEN_PRINT_REGEX  = 1,
> > +MODIFY_THEN_PRINT_REGEX_PCRE = 2
> > +};
> > +
> > +/**
> > + * User-facing information about types
> > + *
> > + * Useful for describing contexts to the user.
> > + */
> > +static const char* ModifyThenPrintDialectName[] = {
> > +"plain text",
> > +"regular expression",
> > +"Perl-compatible regular expression"
> > +};
> > +
> > +/**
> > + * Context for functions that modify strings before printing them
> > + */
> > +struct ModifyThenPrintContext {
> > +
> > +/**
> > + * Information about the type of this particular instance
> > + *
> > + * Object-oriented programs would probably represent this example
> > + * as a sub-class, but some instance-specific functionality
> > + * behaves more like a mixin.
> > + */
> > +enum ModifyThenPrintDialect dialect;
> > +
> > +/**
> > + * Internal context
> > + *
> > + * Object-oriented programs would put private members in here,
> > + * but could also use it to store a virtual function table
> > + * or other "invisible" information.
> > + */
> 
> > +void* priv_data;
> 
> style:
> type *name;
> 
> here and below
> 
> 
> > +
> > +/**
> > + * User-configurable options
> > + *
> > + * Best set through an API, but can be set directly if necessary
> > + *
> > + * Data from users needs to be validated before it's set, and the API
> > + * might e.g. want to update some internal buffer when these change.
> > + * Setting this directly is always less robust than using an API,
> > + * but might be worthwhile if you're willing to spend the time checking
> > + * for edge cases, and don't mind your code misbehaving if future
> > + * versions change the API but not the structure.
> > + *
> > + * Object-oriented programs would likely make these protected members,
> > + * initialised in a constru

Re: [FFmpeg-devel] [PATCH] doc/Doxfyile: Refactor for maintainability

2024-04-29 Thread Andrew Sayers
On Sun, Apr 28, 2024 at 11:46:18PM +0200, Michael Niedermayer wrote:
> Hi
> 
> On Sun, Apr 28, 2024 at 11:10:22AM +0100, Andrew Sayers wrote:
> [...]
> > Ping ?
> > 
> > Michael, this is in response to your request[0].  I've queued up some more
> > patches that depend on this and would help attract and retain developers 
> > (e.g.
> > warning when you're looking at old documentation).  What would be involved 
> > in
> > getting this sort of thing on the website itself?
> 
> I dont have the time to review this
> 
> if you split the patch between updates to to comments and updates to teh 
> actual
> configuration this may make it easier to review to whoever does review it

Thanks for letting me know.

For anyone who does pick this up - this patch does not contain any changes
to the configuration.  I've attached a default 1.8.2 configuration file in case
you want to use them for a review, but it's a real timesink so I'd recommend
the build-and-diff approach in the patch description.

My interest in this patch was about getting the website itself updated.
My understanding is that can't happen without Michael's involvement,
so I'm planning to focus my attention elsewhere.
# Doxyfile 1.8.2

# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
#
# All text after a hash (#) is considered a comment and will be ignored.
# The format is:
#   TAG = value [value, ...]
# For lists items can also be appended using:
#   TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (" ").

#---
# Project related configuration options
#---

# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
# iconv built into libc) for the transcoding. See
# http://www.gnu.org/software/libiconv for the list of possible encodings.

DOXYFILE_ENCODING  = UTF-8

# The PROJECT_NAME tag is a single word (or sequence of words) that should
# identify the project. Note that if you do not use Doxywizard you need
# to put quotes around the project name if it contains spaces.

PROJECT_NAME   = "My Project"

# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.

PROJECT_NUMBER =

# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer
# a quick idea about the purpose of the project. Keep the description short.

PROJECT_BRIEF  =

# With the PROJECT_LOGO tag one can specify an logo or icon that is
# included in the documentation. The maximum height of the logo should not
# exceed 55 pixels and the maximum width should not exceed 200 pixels.
# Doxygen will copy the logo to the output directory.

PROJECT_LOGO   =

# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.

OUTPUT_DIRECTORY   =

# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output
# format and will distribute the generated files over these directories.
# Enabling this option can be useful when feeding doxygen a huge amount of
# source files, where putting all generated files in the same directory would
# otherwise cause performance problems for the file system.

CREATE_SUBDIRS = NO

# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# The default language is English, other supported languages are:
# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.

OUTPUT_LANGUAGE= English

# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
# the file and class documentation (similar 

Re: [FFmpeg-devel] [PATCH v4 1/3] avformat/network: add ff_neterrno2() for cases where we already have an errno

2024-04-27 Thread Andrew Sayers
On Sat, Apr 20, 2024 at 02:24:59PM +0100, Andrew Sayers wrote:
> For example, WSAStartup()'s documentation says:
> 
> "A call to the WSAGetLastError function is not needed and should not be 
> used"
> ---
>  libavformat/network.c | 5 -
>  libavformat/network.h | 2 ++
>  2 files changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/libavformat/network.c b/libavformat/network.c
> index f752efc411..f295957aa5 100644
> --- a/libavformat/network.c
> +++ b/libavformat/network.c
> @@ -123,7 +123,10 @@ void ff_network_close(void)
>  #if HAVE_WINSOCK2_H
>  int ff_neterrno(void)
>  {
> -int err = WSAGetLastError();
> +return ff_neterrno2(WSAGetLastError());
> +}
> +int ff_neterrno2(int err)
> +{
>  switch (err) {
>  case WSAEWOULDBLOCK:
>  return AVERROR(EAGAIN);
> diff --git a/libavformat/network.h b/libavformat/network.h
> index ca214087fc..84348f52a4 100644
> --- a/libavformat/network.h
> +++ b/libavformat/network.h
> @@ -58,6 +58,7 @@
>  #define setsockopt(a, b, c, d, e) setsockopt(a, b, c, (const char*) d, e)
>  
>  int ff_neterrno(void);
> +int ff_neterrno2(int err);
>  #else
>  #include 
>  #include 
> @@ -66,6 +67,7 @@ int ff_neterrno(void);
>  #include 
>  
>  #define ff_neterrno() AVERROR(errno)
> +#define ff_neterrno2(ERRNO) AVERROR(ERRNO)
>  #endif /* HAVE_WINSOCK2_H */
>  
>  #if HAVE_ARPA_INET_H

Ping?  Still applies, and I'm not aware of any further changes needed.
___
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] [RFC] 5 year plan & Inovation

2024-04-25 Thread Andrew Sayers
On Sun, Apr 21, 2024 at 01:05:13AM +0200, Michael Niedermayer wrote:
> On Fri, Apr 19, 2024 at 08:00:28PM +0200, Diederick C. Niehorster wrote:
> > On Fri, Apr 19, 2024, 19:35 Zhao Zhili  wrote:
> > 
> > >
> > > > -Original Message-
> > > > From: ffmpeg-devel  On Behalf Of
> > > Niklas Haas
> > > > Sent: 2024年4月19日 22:50
> > > > To: FFmpeg development discussions and patches 
> > > > Subject: Re: [FFmpeg-devel] [RFC] 5 year plan & Inovation
> > > >
> > > > On Thu, 18 Apr 2024 22:53:51 +0200 Michael Niedermayer <
> > > mich...@niedermayer.cc> wrote:
> > > > > A plugin system moves this patch-management to people who actually
> > > > > care, that is the authors of the codecs and (de)muxers.
> > > >
> > > > A plugin system will only solve this insomuch as plugin authors will
> > > > just host their plugin code on GitHub instead of bothering with the
> > > > mailing list.
> > > >
> > > > I think it runs a good risk of basically killing the project.
> > >
> > > VLC is plugin based, gstreamer is plugin based too (which went t far
> > > ),
> > > I don't think plugin is that dangerous.
> > >
> > > Firstly, we can enable plugin interface only with enable-gpl.
> > >
> > > Secondly, we can have a less stable plugin interface than public API, for
> > > our
> > > development convenience, and encourage plugin authors to contribute to
> > > upstream.
> > >
> > > >
> > > > > Our productivity as is, is not good, many patches are ignored.
> > > > > The people caring about these patches are their Authors and yet they
> > > > > are powerless as they must sometimes wait many months for reviews
> > > >
> > > > So, rather than all of the above, what I think we should do is contract
> > > > somebody to set up, manage, host and maintain a GitLab instance for us.
> > > >
> > > > This would probably be the single most cost effective boost to both
> > > > community growth and innovation I can think of, as it will remove
> > > > several of the major grievances and barriers to entry with the
> > > > ML+pingspam model.
> > >
> > > +1.
> > >
> > > I can't remember how many patches I have ping. It's really frustration.
> > > I ask for permission to commit mostly due to this.
> > >
> > > Now I can keep track of my own patches, but it's still not easy to filter
> > > out
> > > patches I'm interested to review (I can blame the email client, but blame
> > > it
> > > doesn't help). I'm sure I can review more patches with a new workflow.
> > >
> > 
> > If i recall correctly, there was a conversation not too long ago about what
> > to do with all the SPI money. This seems to be a perfect use for it.
> 
> > 1. Set up and manage a gitlab instance
> 
> I think we first need to understand what exact problem there is with the
> ML/Patchwork workflow. Write this down. See if we all agree on that
> 
> Look at what workflow* people use
> Look at what alternatives to ML/Patchwork there are
> I think others than gitlab where suggested like gittea and forgejo
> 
> And then carefully evaluate each for cost vs benefit.
> 
> If we agree on one then its probably best to setup a small test environment
> and have the whole team try to use that before we consider a switch
> 
> 
> > 2. Move tickets from trac to there (possibly)
> 
> why ?
> 
> 
> > 3. Move fate running to there
> 
> why ?
> 
> 
> workflow*
> For example, i go through patches on the ML with mutt and i have one key
> to apply a patch and another to open an editor and write a reply. Also i 
> have
> my muttrc setup so it colorizes diffs nicely so patches are easy to review
> I do test close to every patch posted on ffmpeg-devel, so being able
> to quickly apply patches matters. If i had to use a GUI based browser
> and click around with the mouse it would probably mean an end for me
> testing all patches, simply as it would be too inconvenient and slow.

It seems like this is splitting into two slightly different questions:

One is "there's a bunch of jobs that could be interesting to someone, but
nobody here wants to do.  How do we attract people who'd want to do them?".
For example, bindings in other languages are only interesting to people who use
those languages, and people here are generally happy with C.

The other is "there's a bunch of jobs nobody will ever want to do, how do we
automate them away?".  For example, it sounds like keeping the website updated
is a boring routine you've found yourself stuck with.

Moving away from the ML has to mean answering the first question with a
trade-off.  For example, I've got several patches outstanding, and I would
*love* an interface that said "assigned: so-and-so" for the ones that just need
a ping, and "unassigned" for the ones I shouldn't waste my limited energy on.
But from your point-of-view, that would mean being chased through your day by a
page of jobs people expect you to get done.

On the other hand, there are many win/win answers to the automation question.
For example, most platforms have some kind 

[FFmpeg-devel] [PATCH v3] lavu/opt: Clarify the scope of AVOptions

2024-04-24 Thread Andrew Sayers
See discussion on the mailing list:
https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/326054.html
---
 libavutil/opt.h | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/libavutil/opt.h b/libavutil/opt.h
index e6013662f6..6cf2b39a63 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -53,6 +53,16 @@
  * question is allowed to access the field. This allows us to extend the
  * semantics of those fields without breaking API compatibility.
  *
+ * @section avoptions_scope Scope of AVOptions
+ *
+ * AVOptions is designed to support any set of multimedia configuration options
+ * that can be defined at compile-time.  Although it is mainly used to expose
+ * FFmpeg options, you are welcome to adapt it to your own use case.
+ *
+ * No single approach can ever fully solve the problem of configuration,
+ * but please submit a patch if you believe you have found a problem
+ * that is best solved by extending AVOptions.
+ *
  * @section avoptions_implement Implementing AVOptions
  * This section describes how to add AVOptions capabilities to a struct.
  *
-- 
2.43.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 v2] lavu/opt: Clarify that AVOptions is not indended for general use

2024-04-23 Thread Andrew Sayers
On Tue, Apr 23, 2024 at 07:52:49PM +0100, Andrew Sayers wrote:
> On Tue, Apr 23, 2024 at 10:28:38AM -0700, Vittorio Giovara wrote:
> > On Tue, Apr 23, 2024 at 4:55 AM Andrew Sayers 
> > wrote:
> > 
> > > The hypothetical me wants not to throw away a week's work
> > > because he did everything through AVOptions then came across some edge 
> > > case
> > > that doesn't fit into the AVOptions model.
> > 
> > 
> > Out of curiosity, what are those edge cases?
> 
> It's really more a question of how to recover from the thing you didn't think
> of, which makes it hard to think of good examples ;)
> 
> But since you ask, it might be worth looking at SANE option descriptors[0].
> They perform a very similar function to AVOptions (providing a flexible
> configuration API for a C codebase), and have a 90% overlap in features.  But
> for example, SANE doesn't have an equivalent of AVRational, while AVOptions
> doesn't have an equivalent of option groups.  More importantly, some things 
> are
> technically compatible but perform unobviously different jobs, like how SANE's
> "description" text seems to do the same as FFmpeg's "help" text, but if memory
> serves descriptions are usually several paragraphs while help is usually a
> sentence or two.  It would waste a lot of time if I coded up a whole program
> only to discover the SANE config screen had nicely-grouped options with
> novel-length tooltips, while the FFmpeg config screen had a flat list of
> well-described options that would have looked good if I'd picked an interface
> with a search bar.
> 
> In a situation like that, it would be very helpful to know that FFmpeg's
> position is "have a go and send us a patch if it works" rather than e.g. "we
> never got round to making that private" or "we're in the middle of spinning
> that off as a standalone library".  I'll have a think overnight and submit an
> updated patch tomorrow based on everyone's feedback (thanks!).
> 
> [0] http://www.sane-project.org/html/doc011.html#s4.2.9

At the risk of further complicating a conversation that's already drifting
off-topic, a better example might be Video4Linux2 configuration.  Not only does
it have data types unsupported by AVOptions (like "menu"), but also does things
like making some options constant depending on the value of others (e.g. you
can't change the frame rate if you've selected "automatic frame rate").  A
quick look at v4l2_m2m_enc.c suggests that FFmpeg has decided to just put up
with limited configurability, rather than do something crazy like dynamically
allocate new AVClasses at runtime.  That's a limitation I'd need to know about
if I made a chat app, but also a guarantee that helps me understand how
AVOptions works.

Looping back to a point from before, I can work with either answer, the value
is simply in *having* an answer.
___
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] lavu/opt: Clarify that AVOptions is not indended for general use

2024-04-23 Thread Andrew Sayers
On Tue, Apr 23, 2024 at 10:28:38AM -0700, Vittorio Giovara wrote:
> On Tue, Apr 23, 2024 at 4:55 AM Andrew Sayers 
> wrote:
> 
> > The hypothetical me wants not to throw away a week's work
> > because he did everything through AVOptions then came across some edge case
> > that doesn't fit into the AVOptions model.
> 
> 
> Out of curiosity, what are those edge cases?

It's really more a question of how to recover from the thing you didn't think
of, which makes it hard to think of good examples ;)

But since you ask, it might be worth looking at SANE option descriptors[0].
They perform a very similar function to AVOptions (providing a flexible
configuration API for a C codebase), and have a 90% overlap in features.  But
for example, SANE doesn't have an equivalent of AVRational, while AVOptions
doesn't have an equivalent of option groups.  More importantly, some things are
technically compatible but perform unobviously different jobs, like how SANE's
"description" text seems to do the same as FFmpeg's "help" text, but if memory
serves descriptions are usually several paragraphs while help is usually a
sentence or two.  It would waste a lot of time if I coded up a whole program
only to discover the SANE config screen had nicely-grouped options with
novel-length tooltips, while the FFmpeg config screen had a flat list of
well-described options that would have looked good if I'd picked an interface
with a search bar.

In a situation like that, it would be very helpful to know that FFmpeg's
position is "have a go and send us a patch if it works" rather than e.g. "we
never got round to making that private" or "we're in the middle of spinning
that off as a standalone library".  I'll have a think overnight and submit an
updated patch tomorrow based on everyone's feedback (thanks!).

[0] http://www.sane-project.org/html/doc011.html#s4.2.9
___
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] lavu/opt: Clarify that AVOptions is not indended for general use

2024-04-23 Thread Andrew Sayers
On Tue, Apr 23, 2024 at 01:18:28PM +0200, Michael Niedermayer wrote:
> On Tue, Apr 23, 2024 at 01:15:52PM +0200, Michael Niedermayer wrote:
> > On Tue, Apr 23, 2024 at 11:10:43AM +0100, Andrew Sayers wrote:
> > > On Tue, Apr 23, 2024 at 12:04:34PM +0200, Anton Khirnov wrote:
> > > > Quoting Andrew Sayers (2024-04-23 11:51:00)
> > > > > On Tue, Apr 23, 2024 at 11:21:27AM +0200, Anton Khirnov wrote:
> > > > > > > lavu/opt: Clarify that AVOptions is not indended for general use
> > > > > > 
> > > > > > They _are_ intended for general use though.
> > > > > 
> > > > > In that case I'm confused...
> > > > > 
> > > > > Let's say I make a desktop app to transcode videos.  Obviously I 
> > > > > would use
> > > > > AVOptions to display configuration options for different encoders.  
> > > > > And it's
> > > > > possible to create AVOptions objects for my UI.  But how strongly is 
> > > > > that use
> > > > > case recommended?
> > > > > 
> > > > > To provide a particularly difficult example - let's say I want to let 
> > > > > the user
> > > > > choose between interface themes, and I want to show both some text 
> > > > > and a
> > > > > picture of the theme.  AVOption doesn't include a "text + picture" 
> > > > > option,
> > > > > so how would I extend it to meet my needs?
> > > > 
> > > > If they fit your use case, then use them, otherwise don't - that's true
> > > > for pretty much all APIs we provide.
> > > 
> > > Ah ok, so how about if I changed "intended" to "optimized" in the subject?
> > 
> > If FFmpeg which is a multimedia tool in no place needs or wants to store
> > pictures through its option API in a way not curently supported.
> > I would say thats not going to qualify as "general use" outside specialized
> > software thats already dealing with a lot of pictures
> > 
> > still you certainly can handle binary data (like a bitmap picture) through
> > AVOption
> 
> And if you disagree, which you probably do :)
> send a patch to improve AVOption to cover more general use

Not sure if that's aimed at the real me, or the hypothetical me that wants to
make a desktop app.  The hypothetical me wants not to throw away a week's work
because he did everything through AVOptions then came across some edge case
that doesn't fit into the AVOptions model.  The real me doesn't want to throw
away a week's work because I avoided AVOptions then found some bit of interface
that needs me to express my program in an AVOptions-compatible way.  Neither of
us mind what the answer is, so long as it's written down somewhere we would
spot during the design stage.

It sounds like the consensus is that people are *allowed* to implement their
own AVOption interfaces if they want to, but that there's no expectation for
them to do so unless they're working on FFmpeg itself.  That suggests the body
of the patch is fine, but the subject needs improvement?

How about 'Clarify that "Implementing AVOptions" is addressed to people working
on FFmpeg itself'?
___
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] lavu/opt: Clarify that AVOptions is not indended for general use

2024-04-23 Thread Andrew Sayers
On Tue, Apr 23, 2024 at 12:04:34PM +0200, Anton Khirnov wrote:
> Quoting Andrew Sayers (2024-04-23 11:51:00)
> > On Tue, Apr 23, 2024 at 11:21:27AM +0200, Anton Khirnov wrote:
> > > > lavu/opt: Clarify that AVOptions is not indended for general use
> > > 
> > > They _are_ intended for general use though.
> > 
> > In that case I'm confused...
> > 
> > Let's say I make a desktop app to transcode videos.  Obviously I would use
> > AVOptions to display configuration options for different encoders.  And it's
> > possible to create AVOptions objects for my UI.  But how strongly is that 
> > use
> > case recommended?
> > 
> > To provide a particularly difficult example - let's say I want to let the 
> > user
> > choose between interface themes, and I want to show both some text and a
> > picture of the theme.  AVOption doesn't include a "text + picture" option,
> > so how would I extend it to meet my needs?
> 
> If they fit your use case, then use them, otherwise don't - that's true
> for pretty much all APIs we provide.

Ah ok, so how about if I changed "intended" to "optimized" in the subject?
___
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] lavu/opt: Clarify that AVOptions is not indended for general use

2024-04-23 Thread Andrew Sayers
On Tue, Apr 23, 2024 at 11:21:27AM +0200, Anton Khirnov wrote:
> > lavu/opt: Clarify that AVOptions is not indended for general use
> 
> They _are_ intended for general use though.

In that case I'm confused...

Let's say I make a desktop app to transcode videos.  Obviously I would use
AVOptions to display configuration options for different encoders.  And it's
possible to create AVOptions objects for my UI.  But how strongly is that use
case recommended?

To provide a particularly difficult example - let's say I want to let the user
choose between interface themes, and I want to show both some text and a
picture of the theme.  AVOption doesn't include a "text + picture" option,
so how would I extend it to meet my needs?
___
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] [RFC] 5 year plan & Inovation

2024-04-23 Thread Andrew Sayers
On Tue, Apr 23, 2024 at 10:02:58AM +0200, Lynne wrote:
> Apr 23, 2024, 09:47 by ffmpeg-de...@pileofstuff.org:
> 
> > On Tue, Apr 23, 2024 at 02:20:51AM +0200, Michael Niedermayer wrote:
> >
> >> On Thu, Apr 18, 2024 at 10:46:35AM +0200, Stefano Sabatini wrote:
> >> > On date Wednesday 2024-04-17 15:58:32 +0200, Michael Niedermayer wrote:
> >> > > Hi all
> >> > > 
> >> > > The pace of inovation in FFmpeg has been slowing down.
> >> > > Most work is concentarted nowadays on code refactoring, and adding
> >> > > support for new codecs and formats.
> >> > > 
> >> > > Should we
> >> > > * make a list of longer term goals
> >> > > * vote on them
> >> > > * and then together work towards implementing them
> >> > > ?
> >> > > 
> >> > > (The idea here is to increase the success of larger efforts
> >> > >  than adding codecs and refactoring code)
> >> > > It would then also not be possible for individuals to object
> >> > > to a previously agreed goal.
> >> > > And it would add ideas for which we can try to get funding/grants for
> >> > > 
> >> > > (larger scale changes need consensus first that we as a whole want
> >> > >  them before we would be able to ask for funding/grants for them)
> >> > > 
> >> > > Some ideas and why they would help FFmpeg:
> >> > > 
> >> > [...]
> >> > > * client side / in browser support
> >> > > (expand towards webapps, webpages using ffmpeg client side in the 
> >> > > browser)
> >> > > bring in more users and developers, and it will be costly for us
> >> > > if we let others take this area as its important and significant
> >> > 
> >> > There are already several projects on github, the most prominent one:
> >> > https://github.com/ffmpegwasm/ffmpeg.wasm/
> >> > 
> >> > In general it would be useful to provide libav* bindings to other
> >> > languages, for example:
> >> > https://github.com/PyAV-Org/PyAV
> >> > https://github.com/zmwangx/rust-ffmpeg
> >> > 
> >> > Not sure these should be really moved to FFmpeg though.
> >>
> >> From a user PoV it would be nice if there was a official
> >> python, rust and wasm binding
> >>
> >> It also would draw in more developers and users to FFmpeg.
> >> test coverage might also improve
> >>
> >> I think the 2 questions are.
> >>  1. is there a binding for some language that wants to become the official
> >>  FFmpeg binding for that language ?
> >>  2. does the FFmpeg community want that too ?
> >>
> >> thx
> >>
> >
> > I've thought about this a lot while trying to learn FFmpeg.
> > IMHO there are two big hurdles to good other-language bindings:
> >
> > First, FFmpeg's interface is full of C idioms that are unintuitive to
> > programmers from other languages.  For example, Stefano Sabatini is
> > patiently explaining to me in anoher thread how contexts are a central
> > concept in FFmpeg's design.  Even where I understood the code on a
> > mechanical level, I had drastically underestimated their importance
> > because I didn't have a mental model to understand them.  Binding
> > FFmpeg functionality in another language is only half the problem -
> > the interface needs to be explained in terms they can understand,
> > or rewritten in terms they already know.
> >
> > Second, the interface is full of special cases that make translation
> > to other languages burdensome.  For example, C errors are based on
> > returning a value and requiring the caller to check it explicitly;
> > whereas most other languages throw an error and allow the caller to
> > catch it or not.  A translator needs to convert every one of those,
> > but FFmpeg functions don't have a standard mechanism to signal the
> > correct behaviour for a given function.  Even the documentation isn't
> > reliably helpful, sometimes saying a variant of "returns an AVERROR",
> > sometimes "returns a negative number", and sometimes it just
> > returns an int and expects the reader to dig through the source.
> > That eats up a huge amount of programmer time, and has to be done for
> > every language that wants a binding.
> >
> > Solving those problems would make it far more practical for translators
> > to make bindings in other languages, and for new people to learn FFmpeg
> > even in C.  For example, creating an `enum AVERROR` and rewriting
> > functions to return it would make the code easier to read and drastically
> > cut translator time.
> >
> 
> We always return a negative number for error. 

This is going to be a lot of detail for a specific example, but I think it
illuminates the general point...

Signalling an error with "a negative number" vs. "an AVERROR" is all-but
synonymous in C - in both cases, you just do `if ( ret < 0 ) return ret;`.  But
the equivalent idiom in most languages involves throwing different data types.
For example, a Python programmer would likely expect the former to throw an
"Exception", but the latter to throw some library-specific "AVErrorException"
type.  A function that "returns a negative number on error" might return `-1`
in all cases, or a 

Re: [FFmpeg-devel] [RFC] 5 year plan & Inovation

2024-04-23 Thread Andrew Sayers
On Tue, Apr 23, 2024 at 02:20:51AM +0200, Michael Niedermayer wrote:
> On Thu, Apr 18, 2024 at 10:46:35AM +0200, Stefano Sabatini wrote:
> > On date Wednesday 2024-04-17 15:58:32 +0200, Michael Niedermayer wrote:
> > > Hi all
> > > 
> > > The pace of inovation in FFmpeg has been slowing down.
> > > Most work is concentarted nowadays on code refactoring, and adding
> > > support for new codecs and formats.
> > > 
> > > Should we
> > > * make a list of longer term goals
> > > * vote on them
> > > * and then together work towards implementing them
> > > ?
> > > 
> > > (The idea here is to increase the success of larger efforts
> > >  than adding codecs and refactoring code)
> > > It would then also not be possible for individuals to object
> > > to a previously agreed goal.
> > > And it would add ideas for which we can try to get funding/grants for
> > > 
> > > (larger scale changes need consensus first that we as a whole want
> > >  them before we would be able to ask for funding/grants for them)
> > > 
> > > Some ideas and why they would help FFmpeg:
> > > 
> > [...]
> > > * client side / in browser support
> > > (expand towards webapps, webpages using ffmpeg client side in the 
> > > browser)
> > > bring in more users and developers, and it will be costly for us
> > > if we let others take this area as its important and significant
> > 
> > There are already several projects on github, the most prominent one:
> > https://github.com/ffmpegwasm/ffmpeg.wasm/
> > 
> > In general it would be useful to provide libav* bindings to other
> > languages, for example:
> > https://github.com/PyAV-Org/PyAV
> > https://github.com/zmwangx/rust-ffmpeg
> > 
> > Not sure these should be really moved to FFmpeg though.
> 
> From a user PoV it would be nice if there was a official
> python, rust and wasm binding
> 
> It also would draw in more developers and users to FFmpeg.
> test coverage might also improve
> 
> I think the 2 questions are.
>  1. is there a binding for some language that wants to become the official
> FFmpeg binding for that language ?
>  2. does the FFmpeg community want that too ?
> 
> thx

I've thought about this a lot while trying to learn FFmpeg.
IMHO there are two big hurdles to good other-language bindings:

First, FFmpeg's interface is full of C idioms that are unintuitive to
programmers from other languages.  For example, Stefano Sabatini is
patiently explaining to me in anoher thread how contexts are a central
concept in FFmpeg's design.  Even where I understood the code on a
mechanical level, I had drastically underestimated their importance
because I didn't have a mental model to understand them.  Binding
FFmpeg functionality in another language is only half the problem -
the interface needs to be explained in terms they can understand,
or rewritten in terms they already know.

Second, the interface is full of special cases that make translation
to other languages burdensome.  For example, C errors are based on
returning a value and requiring the caller to check it explicitly;
whereas most other languages throw an error and allow the caller to
catch it or not.  A translator needs to convert every one of those,
but FFmpeg functions don't have a standard mechanism to signal the
correct behaviour for a given function.  Even the documentation isn't
reliably helpful, sometimes saying a variant of "returns an AVERROR",
sometimes "returns a negative number", and sometimes it just
returns an int and expects the reader to dig through the source.
That eats up a huge amount of programmer time, and has to be done for
every language that wants a binding.

Solving those problems would make it far more practical for translators
to make bindings in other languages, and for new people to learn FFmpeg
even in C.  For example, creating an `enum AVERROR` and rewriting
functions to return it would make the code easier to read and drastically
cut translator time.

- Andrew Sayers
___
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 v3 3/3] all: Link to "context" from all contexts with documentation

2024-04-22 Thread Andrew Sayers
Some headings needed to be rewritten to accomodate the text,
(hopefully) without changing the meaning.
---
 libavcodec/aacdec.h  |  2 +-
 libavcodec/aacenc.h  |  2 +-
 libavcodec/ac3enc.h  |  2 +-
 libavcodec/amfenc.h  |  2 +-
 libavcodec/atrac.h   |  2 +-
 libavcodec/avcodec.h |  3 ++-
 libavcodec/bsf.h |  2 +-
 libavcodec/d3d11va.h |  3 +--
 libavcodec/mediacodec.h  |  2 +-
 libavcodec/qsv.h |  6 --
 libavcodec/sbr.h |  2 +-
 libavcodec/vdpau.h   |  3 ++-
 libavcodec/videotoolbox.h|  5 +++--
 libavfilter/avfilter.h   |  2 +-
 libavformat/avformat.h   |  3 ++-
 libavformat/avio.h   |  3 ++-
 libavutil/hwcontext.h| 21 -
 libavutil/hwcontext_cuda.h   |  2 +-
 libavutil/hwcontext_d3d11va.h|  4 ++--
 libavutil/hwcontext_d3d12va.h|  6 +++---
 libavutil/hwcontext_drm.h|  2 +-
 libavutil/hwcontext_dxva2.h  |  4 ++--
 libavutil/hwcontext_mediacodec.h |  2 +-
 libavutil/hwcontext_opencl.h |  4 ++--
 libavutil/hwcontext_qsv.h|  4 ++--
 libavutil/hwcontext_vaapi.h  |  6 +++---
 libavutil/hwcontext_vdpau.h  |  2 +-
 libavutil/hwcontext_vulkan.h |  4 ++--
 28 files changed, 57 insertions(+), 48 deletions(-)

diff --git a/libavcodec/aacdec.h b/libavcodec/aacdec.h
index 1b245f9258..715886ae07 100644
--- a/libavcodec/aacdec.h
+++ b/libavcodec/aacdec.h
@@ -181,7 +181,7 @@ typedef struct DynamicRangeControl {
 } DynamicRangeControl;
 
 /**
- * main AAC decoding context
+ * main AAC decoding @ref md_doc_2context "context"
  */
 typedef struct AACDecContext {
 const struct AVClass  *class;
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index 8899f90ac7..755f0495a2 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -193,7 +193,7 @@ typedef struct AACPCEInfo {
 } AACPCEInfo;
 
 /**
- * AAC encoder context
+ * AAC encoder @ref md_doc_2context "context"
  */
 typedef struct AACEncContext {
 AVClass *av_class;
diff --git a/libavcodec/ac3enc.h b/libavcodec/ac3enc.h
index 30812617cc..c725007077 100644
--- a/libavcodec/ac3enc.h
+++ b/libavcodec/ac3enc.h
@@ -152,7 +152,7 @@ typedef struct AC3Block {
 } AC3Block;
 
 /**
- * AC-3 encoder private context.
+ * AC-3 encoder private @ref md_doc_2context "context"
  */
 typedef struct AC3EncodeContext {
 AVClass *av_class;  ///< AVClass used for AVOption
diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h
index 2dbd378ef8..f142ede63a 100644
--- a/libavcodec/amfenc.h
+++ b/libavcodec/amfenc.h
@@ -43,7 +43,7 @@ typedef struct AmfTraceWriter {
 } AmfTraceWriter;
 
 /**
-* AMF encoder context
+* AMF encoder @ref md_doc_2context "context"
 */
 
 typedef struct AmfContext {
diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
index 05208bbee6..1527e376a9 100644
--- a/libavcodec/atrac.h
+++ b/libavcodec/atrac.h
@@ -39,7 +39,7 @@ typedef struct AtracGainInfo {
 } AtracGainInfo;
 
 /**
- *  Gain compensation context structure.
+ *  Gain compensation @ref md_doc_2context "context"
  */
 typedef struct AtracGCContext {
 float   gain_tab1[16];  ///< gain compensation level table
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 968009a192..9180fedca7 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -430,7 +430,8 @@ typedef struct RcOverride{
 #define AV_GET_ENCODE_BUFFER_FLAG_REF (1 << 0)
 
 /**
- * main external API structure.
+ * @ref md_doc_2context "Context" for an encode or decode session
+ *
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
index a09c69f242..bf79afa7cc 100644
--- a/libavcodec/bsf.h
+++ b/libavcodec/bsf.h
@@ -56,7 +56,7 @@
  */
 
 /**
- * The bitstream filter state.
+ * Bitstream filter @ref md_doc_2context "context"
  *
  * This struct must be allocated with av_bsf_alloc() and freed with
  * av_bsf_free().
diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
index 27f40e5519..ec0c472ab9 100644
--- a/libavcodec/d3d11va.h
+++ b/libavcodec/d3d11va.h
@@ -46,8 +46,7 @@
  */
 
 /**
- * This structure is used to provides the necessary configurations and data
- * to the Direct3D11 FFmpeg HWAccel implementation.
+ * @ref md_doc_2context "Context" for the Direct3D11 FFmpeg HWAccel 
implementation
  *
  * The application must make it available as AVCodecContext.hwaccel_context.
  *
diff --git a/libavcodec/mediacodec.h b/libavcodec/mediacodec.h
index 4e9b56a618..9967a7cfb3 100644
--- a/libavcodec/mediacodec.h
+++ b/libavcodec/mediacodec.h
@@ -26,7 +26,7 @@
 #include "libavcodec/avcodec.h"
 
 /**
- * This structure holds a reference to a android/view/Surface object that will
+ * @ref md_doc_2context "Context" for the android/view/Surface object that will
  * be used as output by the 

[FFmpeg-devel] [PATCH v3 2/3] lavu: Clarify relationship between AVClass, AVOption and context

2024-04-22 Thread Andrew Sayers
---
 libavutil/log.h | 11 ---
 libavutil/opt.h |  7 ---
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/libavutil/log.h b/libavutil/log.h
index ab7ceabe22..cfbf416679 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -59,9 +59,14 @@ typedef enum {
 struct AVOptionRanges;
 
 /**
- * Describe the class of an AVClass context structure. That is an
- * arbitrary struct of which the first field is a pointer to an
- * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.).
+ * Metadata about an arbitrary data structure
+ *
+ * A @ref md_doc_2context "context struct" whose first member is a pointer
+ * to an AVClass object is called an "AVClass context structure"
+ * (e.g. AVCodecContext, AVFormatContext etc.).
+ *
+ * AVClass is often combined with @ref avoptions "AVOptions" to create
+ * "AVOptions-enabled structs" that can be easily configured by users.
  */
 typedef struct AVClass {
 /**
diff --git a/libavutil/opt.h b/libavutil/opt.h
index e6013662f6..b817d15554 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -39,9 +39,10 @@
  * @defgroup avoptions AVOptions
  * @ingroup lavu_data
  * @{
- * AVOptions provide a generic system to declare options on arbitrary structs
- * ("objects"). An option can have a help text, a type and a range of possible
- * values. Options may then be enumerated, read and written to.
+ * Builds on AVClass, adding a generic system to declare options.
+ *
+ * An option can have a help text, a type and a range of possible values.
+ * Options may then be enumerated, read and written to.
  *
  * There are two modes of access to members of AVOption and its child structs.
  * One is called 'native access', and refers to access from the code that
-- 
2.43.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 v3 1/3] doc: Explain what "context" means

2024-04-22 Thread Andrew Sayers
Derived from detailed explanations kindly provided by Stefano Sabatini:
https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325903.html
---
 doc/context.md | 276 +
 1 file changed, 276 insertions(+)
 create mode 100644 doc/context.md

diff --git a/doc/context.md b/doc/context.md
new file mode 100644
index 00..73caacf54f
--- /dev/null
+++ b/doc/context.md
@@ -0,0 +1,276 @@
+# Context-oriented programming
+
+Like many C projects, FFmpeg has adopted the subset of object-oriented 
techniques
+that help solve its problems.  Object-like structures are called "contexts",
+and this document provides a general introduction to how they work.
+
+Object-oriented programming usually focusses on *access* as a primary concern.
+For example, members of an object are visibly designated "private", "constant"
+etc. to control how they are accessed.  *Reflection* is a secondary concern,
+where it is provided at all.  For example, C++ has no built-in way to get a
+string containing the name of a variable.
+
+Reflection is extremely important for FFmpeg, because user-facing options are
+implemented by reflecting state at runtime.  Limiting access is a secondary
+concern, mainly important for ensuring implementation details can change
+between versions.
+
+An object-oriented programmer learning FFmpeg should be careful not to fixate 
on
+FFmpeg's access control features, nor to overlook its reflection capabilities.
+Both are present, but have been given the level of focus appropriate for the 
task.
+
+## Example: modify text then print it
+
+The example below shows a context structure that receives input strings,
+modifies them in some context-dependant way, then prints them to a specified
+filehandle.
+
+```c
+/**
+ * Type information, accessible at runtime.
+ *
+ * Useful when configuring objects.
+ */
+enum ModifyThenPrintDialect {
+MODIFY_THEN_PRINT_PLAIN_TEXT = 0,
+MODIFY_THEN_PRINT_REGEX  = 1,
+MODIFY_THEN_PRINT_REGEX_PCRE = 2
+};
+
+/**
+ * User-facing information about types
+ *
+ * Useful for describing contexts to the user.
+ */
+static const char* ModifyThenPrintDialectName[] = {
+"plain text",
+"regular expression",
+"Perl-compatible regular expression"
+};
+
+/**
+ * Context for functions that modify strings before printing them
+ */
+struct ModifyThenPrintContext {
+
+/**
+ * Information about the type of this particular instance
+ *
+ * Object-oriented programs would probably represent this example
+ * as a sub-class, but some instance-specific functionality
+ * behaves more like a mixin.
+ */
+enum ModifyThenPrintDialect dialect;
+
+/**
+ * Internal context
+ *
+ * Object-oriented programs would put private members in here,
+ * but could also use it to store a virtual function table
+ * or other "invisible" information.
+ */
+void* priv_data;
+
+/**
+ * User-configurable options
+ *
+ * Best set through an API, but can be set directly if necessary
+ *
+ * Data from users needs to be validated before it's set, and the API
+ * might e.g. want to update some internal buffer when these change.
+ * Setting this directly is always less robust than using an API,
+ * but might be worthwhile if you're willing to spend the time checking
+ * for edge cases, and don't mind your code misbehaving if future
+ * versions change the API but not the structure.
+ *
+ * Object-oriented programs would likely make these protected members,
+ * initialised in a constructor and accessed with getters and setters.
+ * Making them user-configurable would be left to the programmer.
+ */
+char *replace_this;
+char *with_this;
+
+/**
+ * Programmer-configurable variable
+ *
+ * Object-oriented programs would represent this as a public member.
+ */
+FILE *out;
+
+};
+
+/**
+ * Allocate and initialize a ModifyThenPrintContext
+ *
+ * This creates a new pointer, then fills in some sensible defaults.
+ *
+ * We can reasonably assume this function will initialise `priv_data`
+ * with a dialect-specific object, but shouldn't make any assumptions
+ * about what that object is.
+ *
+ * Object-oriented programs would likely represent this as an
+ * allocator function and a constructor.
+ */
+int ModifyThenPrintContext_alloc_context(struct ModifyThenPrintContext **ctx,
+ enum ModifyThenPrintDialect dialect,
+ FILE *out);
+
+/**
+ * Uninitialize and deallocate a ModifyThenPrintContext
+ *
+ * This does any work required by the internal context (e.g. deallocating
+ * `priv_data`), then deallocates the main context itself.
+ *
+ * Object-oriented programs would likely represent this as a
+ * destructor and a deallocator.
+ */
+int ModifyThenPrintContext_free(struct ModifyThenPrintContext *ctx);
+
+/**
+ * Configure a 

[FFmpeg-devel] [PATCH v3 0/3] all: Link to "context" from all contexts with documentation

2024-04-22 Thread Andrew Sayers
I've updated the link in patch 1 to point to this thread instead of your
original post.

I've heavily rewritten "jargon.md" and renamed it to "context.md", reflecting
how it's more important than I previously realised.  I think it's safe to leave
it in markdown format in doc/ now - it shouldn't open the floodgates to more
files, and that seems like a safe enough bridge to cross when we come to it.

The links in patches 2 and 3 have been updated to point to the new file, but
are otherwise unchanged.

___
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] lavu/opt: Clarify that AVOptions is not indended for general use

2024-04-22 Thread Andrew Sayers
---
 libavutil/opt.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libavutil/opt.h b/libavutil/opt.h
index e6013662f6..4c0e7d9223 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -54,7 +54,10 @@
  * semantics of those fields without breaking API compatibility.
  *
  * @section avoptions_implement Implementing AVOptions
+ *
  * This section describes how to add AVOptions capabilities to a struct.
+ * It is aimed at people adding new interfaces to internal FFmpeg 
functionality,
+ * but may also be of interest to programs that depend on FFmpeg.
  *
  * All AVOptions-related information is stored in an AVClass. Therefore
  * the first member of the struct should be a pointer to an AVClass describing 
it.
-- 
2.43.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] lavu/opt: Clarify that AVOptions is not indended for general use

2024-04-22 Thread Andrew Sayers
---
 libavutil/opt.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/libavutil/opt.h b/libavutil/opt.h
index e6013662f6..795accb363 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -54,7 +54,11 @@
  * semantics of those fields without breaking API compatibility.
  *
  * @section avoptions_implement Implementing AVOptions
+ *
  * This section describes how to add AVOptions capabilities to a struct.
+ * It is intended for developers of FFmpeg itself - AVOptions can technically
+ * be used as a more general toolkit, but is neither intended nor expected
+ * to be good fit for other use cases.
  *
  * All AVOptions-related information is stored in an AVClass. Therefore
  * the first member of the struct should be a pointer to an AVClass describing 
it.
-- 
2.43.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 v2 1/3] doc: Explain what "context" means

2024-04-20 Thread Andrew Sayers
On Sat, Apr 20, 2024 at 06:48:32PM +0200, Stefano Sabatini wrote:
> On date Saturday 2024-04-20 13:19:41 +0100, Andrew Sayers wrote:
> > Based largely on the explanation by Stefano Sabatini:
> > https://ffmpeg.org/pipermail/ffmpeg-devel/2024-April/325854.html
> > ---
> >  doc/jargon.md | 169 ++
> >  1 file changed, 169 insertions(+)
> >  create mode 100644 doc/jargon.md
> > 
> > diff --git a/doc/jargon.md b/doc/jargon.md
> > new file mode 100644
> > index 00..f967b5c8bc
> > --- /dev/null
> > +++ b/doc/jargon.md
> > @@ -0,0 +1,169 @@
> > +# Jargon
> > +
> > +Terms used throughout the code that developers may need to know.
> > +
> > +@anchor context
> > +
> 
> > +## Context
> > +
> 
> > +A design pattern that stores the context (e.g. configuration) for a series
> > +of operations in a "context" structure, and moves other information with
> > +a longer or shorter lifetime elsewhere.
> 
> I'd skip the mention of a design pattern since this is about the
> jargon.
> 
> So a simplified variant would be:
> 
> A "context" is a a structure used to store information
> (e.g. configuration and/or internal state) for a series of operations
> working on the same data.

I think there's a pattern to the problems I'm having in this thread -
*anchoring effects*.

If you ask someone "is 5 a big number?" then "is 5 thousand a big number?",
they'll probably say "yes" to the second question.  But if you ask them
"is 5 billian a big number?" then "is 5 thousand a big number?", they'll
probably say "no".  In each case, their concept of "bigness" has been
anchored by the first question you asked.

When I originally tried to learn FFmpeg back in the day, I got nowhere with my
default OOP mindset.  It wasn't until I thought to read the examples with a
procedural mindset that it started making any sense, and I think that has
*anchored* my mental model of FFmpeg to a mindset that made it hard to think
deeply about its object-oriented bits.

Yesterday I would have agreed this was just one piece of jargon that needed
pinning down.  But if other people have similarly mis-anchored themselves,
this question might need to be a bit easier for them to find.

> 
> > +
> > +Consider a code snippet to modify text then print it:
> > +
> > +```c
> > +/**
> > + * Contextual information about printing a series of messages
> > + */
> > +struct ModifyThenPrintContext {
> > +
> > +/**
> > + * Members of the context usually are usually part of its public API...
> > + */
> > +FILE *out;
> > +
> > +/**
> > + * ... but check the documentation just in case
> > + */
> > +[[deprecated]]
> > +int no_longer_part_of_the_public_api;
> > +
> > +/**
> > + * The "internal context" is private to the context itself.
> > + *
> > + * Unlike the members above, the private context is not guaranteed
> > + * and can change arbitrarily between versions.
> > + */
> > +void* priv_data;
> > +};
> > +
> > +/**
> > + * Long-lifetime information, reused by many contexts
> > + */
> > +enum ModifyThenPrintDialect {
> > +MODIFY_THEN_PRINT_PLAIN_TEXT,
> > +MODIFY_THEN_PRINT_REGEX,
> > +MODIFY_THEN_PRINT_REGEX_PCRE
> > +};
> > +
> > +/**
> > + * Short-lifetime information, used repeatedly in a single context
> > + */
> > +struct ModifyThenPrintMessage {
> > +char *str;
> > +char *replace_this;
> > +char *with_this;
> > +};
> > +
> > +/**
> > + * Allocate and initialize a ModifyThenPrintContext
> > + *
> > + * This creates a new pointer, then fills in some sensible defaults.
> > + *
> > + * We can reasonably assume this function will initialise `priv_data`
> > + * with a dialect-specific object, but shouldn't make any assumptions
> > + * about what that object is.
> > + *
> > + */
> > +int ModifyThenPrintContext_alloc_context(struct ModifyThenPrintContext 
> > **ctx,
> > + FILE *out,
> > + enum ModifyThenPrintDialect 
> > dialect);
> > +
> > +/**
> > + * Uninitialize and deallocate a ModifyThenPrintContext
> > + *
> > + * This does any work required by the private context in `priv_data`
> > + * (e.g. deallocating it), then deallocates the main context itself.
> > + *
&

  1   2   >