diff mbox series

[FFmpeg-devel,v0,09/14] avcodec: add private side data set to AVCodecInternal

Message ID 20230320233408.134255-10-jeebjp@gmail.com
State New
Headers show
Series encoder AVCodecContext configuration side data | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Jan Ekström March 20, 2023, 11:34 p.m. UTC
This allows configuring an encoder by using AVFrameSideData.
---
 libavcodec/avcodec.c  | 1 +
 libavcodec/internal.h | 7 +++++++
 libavcodec/options.c  | 5 +++++
 3 files changed, 13 insertions(+)

Comments

Anton Khirnov March 24, 2023, 10:50 a.m. UTC | #1
Quoting Jan Ekström (2023-03-21 00:34:03)
> This allows configuring an encoder by using AVFrameSideData.
> ---
>  libavcodec/avcodec.c  | 1 +
>  libavcodec/internal.h | 7 +++++++
>  libavcodec/options.c  | 5 +++++
>  3 files changed, 13 insertions(+)
> 
> diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
> index c110b19e08..3faabe77d1 100644
> --- a/libavcodec/avcodec.c
> +++ b/libavcodec/avcodec.c
> @@ -403,6 +403,7 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
>      avci->nb_draining_errors = 0;
>      av_frame_unref(avci->buffer_frame);
>      av_packet_unref(avci->buffer_pkt);
> +    av_side_data_set_wipe(&avci->side_data_set);
>  
>      if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
>          ff_thread_flush(avctx);
> diff --git a/libavcodec/internal.h b/libavcodec/internal.h
> index f21101752d..c658e97313 100644
> --- a/libavcodec/internal.h
> +++ b/libavcodec/internal.h
> @@ -168,6 +168,13 @@ typedef struct AVCodecInternal {
>       * a boolean to describe whether context is opened or not.
>       */
>      unsigned int ctx_opened;
> +
> +    /**
> +     * Set holding static side data, such as HDR10 CLL / MDCV structures.
> +     * - encoding: set by user
> +     * - decoding: unused
> +     */
> +    AVFrameSideDataSet side_data_set;

Why put it here and not in the public struct? It seems way more natural
there.
Jan Ekström March 24, 2023, 5:34 p.m. UTC | #2
On Fri, Mar 24, 2023 at 12:51 PM Anton Khirnov <anton@khirnov.net> wrote:
>
> Quoting Jan Ekström (2023-03-21 00:34:03)
> > This allows configuring an encoder by using AVFrameSideData.
> > ---
> >  libavcodec/avcodec.c  | 1 +
> >  libavcodec/internal.h | 7 +++++++
> >  libavcodec/options.c  | 5 +++++
> >  3 files changed, 13 insertions(+)
> >
> > diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
> > index c110b19e08..3faabe77d1 100644
> > --- a/libavcodec/avcodec.c
> > +++ b/libavcodec/avcodec.c
> > @@ -403,6 +403,7 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
> >      avci->nb_draining_errors = 0;
> >      av_frame_unref(avci->buffer_frame);
> >      av_packet_unref(avci->buffer_pkt);
> > +    av_side_data_set_wipe(&avci->side_data_set);
> >
> >      if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
> >          ff_thread_flush(avctx);
> > diff --git a/libavcodec/internal.h b/libavcodec/internal.h
> > index f21101752d..c658e97313 100644
> > --- a/libavcodec/internal.h
> > +++ b/libavcodec/internal.h
> > @@ -168,6 +168,13 @@ typedef struct AVCodecInternal {
> >       * a boolean to describe whether context is opened or not.
> >       */
> >      unsigned int ctx_opened;
> > +
> > +    /**
> > +     * Set holding static side data, such as HDR10 CLL / MDCV structures.
> > +     * - encoding: set by user
> > +     * - decoding: unused
> > +     */
> > +    AVFrameSideDataSet side_data_set;
>
> Why put it here and not in the public struct? It seems way more natural
> there.
>

The general idea was that if you want to make people utilize helpers
and not touch entries willy-nilly, you put it outside of the API
client's view. Or in other words, "only making something public when
it's absolutely required means that no unnecessary things are part of
the ABI structs"

Of course looking at the fun times with avci, I might just end up
doing what you note... I just wanted to give it a try to have a
private structure which was available before init() was called :) .

Jan
Anton Khirnov March 26, 2023, 7 p.m. UTC | #3
Quoting Jan Ekström (2023-03-24 18:34:28)
> On Fri, Mar 24, 2023 at 12:51 PM Anton Khirnov <anton@khirnov.net> wrote:
> >
> > Quoting Jan Ekström (2023-03-21 00:34:03)
> > > This allows configuring an encoder by using AVFrameSideData.
> > > ---
> > >  libavcodec/avcodec.c  | 1 +
> > >  libavcodec/internal.h | 7 +++++++
> > >  libavcodec/options.c  | 5 +++++
> > >  3 files changed, 13 insertions(+)
> > >
> > > diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
> > > index c110b19e08..3faabe77d1 100644
> > > --- a/libavcodec/avcodec.c
> > > +++ b/libavcodec/avcodec.c
> > > @@ -403,6 +403,7 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
> > >      avci->nb_draining_errors = 0;
> > >      av_frame_unref(avci->buffer_frame);
> > >      av_packet_unref(avci->buffer_pkt);
> > > +    av_side_data_set_wipe(&avci->side_data_set);
> > >
> > >      if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
> > >          ff_thread_flush(avctx);
> > > diff --git a/libavcodec/internal.h b/libavcodec/internal.h
> > > index f21101752d..c658e97313 100644
> > > --- a/libavcodec/internal.h
> > > +++ b/libavcodec/internal.h
> > > @@ -168,6 +168,13 @@ typedef struct AVCodecInternal {
> > >       * a boolean to describe whether context is opened or not.
> > >       */
> > >      unsigned int ctx_opened;
> > > +
> > > +    /**
> > > +     * Set holding static side data, such as HDR10 CLL / MDCV structures.
> > > +     * - encoding: set by user
> > > +     * - decoding: unused
> > > +     */
> > > +    AVFrameSideDataSet side_data_set;
> >
> > Why put it here and not in the public struct? It seems way more natural
> > there.
> >
> 
> The general idea was that if you want to make people utilize helpers
> and not touch entries willy-nilly,

But do we? Why?

In this case I see no advantage to having a public function over having
two public fields. The function is strictly worse because it cannot be
extended, and enlarges the symbol table.
James Almer March 26, 2023, 7:03 p.m. UTC | #4
On 3/26/2023 4:00 PM, Anton Khirnov wrote:
> Quoting Jan Ekström (2023-03-24 18:34:28)
>> On Fri, Mar 24, 2023 at 12:51 PM Anton Khirnov <anton@khirnov.net> wrote:
>>>
>>> Quoting Jan Ekström (2023-03-21 00:34:03)
>>>> This allows configuring an encoder by using AVFrameSideData.
>>>> ---
>>>>   libavcodec/avcodec.c  | 1 +
>>>>   libavcodec/internal.h | 7 +++++++
>>>>   libavcodec/options.c  | 5 +++++
>>>>   3 files changed, 13 insertions(+)
>>>>
>>>> diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
>>>> index c110b19e08..3faabe77d1 100644
>>>> --- a/libavcodec/avcodec.c
>>>> +++ b/libavcodec/avcodec.c
>>>> @@ -403,6 +403,7 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
>>>>       avci->nb_draining_errors = 0;
>>>>       av_frame_unref(avci->buffer_frame);
>>>>       av_packet_unref(avci->buffer_pkt);
>>>> +    av_side_data_set_wipe(&avci->side_data_set);
>>>>
>>>>       if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
>>>>           ff_thread_flush(avctx);
>>>> diff --git a/libavcodec/internal.h b/libavcodec/internal.h
>>>> index f21101752d..c658e97313 100644
>>>> --- a/libavcodec/internal.h
>>>> +++ b/libavcodec/internal.h
>>>> @@ -168,6 +168,13 @@ typedef struct AVCodecInternal {
>>>>        * a boolean to describe whether context is opened or not.
>>>>        */
>>>>       unsigned int ctx_opened;
>>>> +
>>>> +    /**
>>>> +     * Set holding static side data, such as HDR10 CLL / MDCV structures.
>>>> +     * - encoding: set by user
>>>> +     * - decoding: unused
>>>> +     */
>>>> +    AVFrameSideDataSet side_data_set;
>>>
>>> Why put it here and not in the public struct? It seems way more natural
>>> there.
>>>
>>
>> The general idea was that if you want to make people utilize helpers
>> and not touch entries willy-nilly,
> 
> But do we? Why?
> 
> In this case I see no advantage to having a public function over having
> two public fields. The function is strictly worse because it cannot be
> extended, and enlarges the symbol table.

Also, is this new AVFrameSideDataSet struct necessary? This looks sort 
of like the opposite of coded_side_data.
Jan Ekström March 27, 2023, 6:37 a.m. UTC | #5
On Sun, Mar 26, 2023 at 10:00 PM Anton Khirnov <anton@khirnov.net> wrote:
>
> Quoting Jan Ekström (2023-03-24 18:34:28)
> > On Fri, Mar 24, 2023 at 12:51 PM Anton Khirnov <anton@khirnov.net> wrote:
> > >
> > > Quoting Jan Ekström (2023-03-21 00:34:03)
> > > > This allows configuring an encoder by using AVFrameSideData.
> > > > ---
> > > >  libavcodec/avcodec.c  | 1 +
> > > >  libavcodec/internal.h | 7 +++++++
> > > >  libavcodec/options.c  | 5 +++++
> > > >  3 files changed, 13 insertions(+)
> > > >
> > > > diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
> > > > index c110b19e08..3faabe77d1 100644
> > > > --- a/libavcodec/avcodec.c
> > > > +++ b/libavcodec/avcodec.c
> > > > @@ -403,6 +403,7 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
> > > >      avci->nb_draining_errors = 0;
> > > >      av_frame_unref(avci->buffer_frame);
> > > >      av_packet_unref(avci->buffer_pkt);
> > > > +    av_side_data_set_wipe(&avci->side_data_set);
> > > >
> > > >      if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
> > > >          ff_thread_flush(avctx);
> > > > diff --git a/libavcodec/internal.h b/libavcodec/internal.h
> > > > index f21101752d..c658e97313 100644
> > > > --- a/libavcodec/internal.h
> > > > +++ b/libavcodec/internal.h
> > > > @@ -168,6 +168,13 @@ typedef struct AVCodecInternal {
> > > >       * a boolean to describe whether context is opened or not.
> > > >       */
> > > >      unsigned int ctx_opened;
> > > > +
> > > > +    /**
> > > > +     * Set holding static side data, such as HDR10 CLL / MDCV structures.
> > > > +     * - encoding: set by user
> > > > +     * - decoding: unused
> > > > +     */
> > > > +    AVFrameSideDataSet side_data_set;
> > >
> > > Why put it here and not in the public struct? It seems way more natural
> > > there.
> > >
> >
> > The general idea was that if you want to make people utilize helpers
> > and not touch entries willy-nilly,
>
> But do we? Why?
>
> In this case I see no advantage to having a public function over having
> two public fields. The function is strictly worse because it cannot be
> extended, and enlarges the symbol table.

The overarching idea has been that looking at the recent changes of
adding private internal structs and deprecating previously public
stuff from the public structs was to be careful.

1. Post a patch with things added to the relevant private struct.
2. Allow specific access with a helper
3. See if anyone requires the information to be part of the public
struct. At which point it may be moved there.

Additionally, only having things available via helpers means that you
know how exactly the fields were being poked (instead of "we don't
know how API users utilize them, and thus we cannot do X" (see the
avcodec context related helpers where we still have to support close &
av_freep which popped up in another patch), and given that the
argument is a struct, the function can technically be extended
(although a struct being in the middle of a struct might stop from it
being extended).

I hope this opens up my thoughts and that I'm not a religious zealot
about this selection. Just that I wanted to start where it's not
public, so that hopefully someone would explain why it should be
public if they would wish it to be such.

Jan
Jan Ekström March 27, 2023, 6:40 a.m. UTC | #6
On Sun, Mar 26, 2023 at 10:03 PM James Almer <jamrial@gmail.com> wrote:
>
>
>
> On 3/26/2023 4:00 PM, Anton Khirnov wrote:
> > Quoting Jan Ekström (2023-03-24 18:34:28)
> >> On Fri, Mar 24, 2023 at 12:51 PM Anton Khirnov <anton@khirnov.net> wrote:
> >>>
> >>> Quoting Jan Ekström (2023-03-21 00:34:03)
> >>>> This allows configuring an encoder by using AVFrameSideData.
> >>>> ---
> >>>>   libavcodec/avcodec.c  | 1 +
> >>>>   libavcodec/internal.h | 7 +++++++
> >>>>   libavcodec/options.c  | 5 +++++
> >>>>   3 files changed, 13 insertions(+)
> >>>>
> >>>> diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
> >>>> index c110b19e08..3faabe77d1 100644
> >>>> --- a/libavcodec/avcodec.c
> >>>> +++ b/libavcodec/avcodec.c
> >>>> @@ -403,6 +403,7 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
> >>>>       avci->nb_draining_errors = 0;
> >>>>       av_frame_unref(avci->buffer_frame);
> >>>>       av_packet_unref(avci->buffer_pkt);
> >>>> +    av_side_data_set_wipe(&avci->side_data_set);
> >>>>
> >>>>       if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
> >>>>           ff_thread_flush(avctx);
> >>>> diff --git a/libavcodec/internal.h b/libavcodec/internal.h
> >>>> index f21101752d..c658e97313 100644
> >>>> --- a/libavcodec/internal.h
> >>>> +++ b/libavcodec/internal.h
> >>>> @@ -168,6 +168,13 @@ typedef struct AVCodecInternal {
> >>>>        * a boolean to describe whether context is opened or not.
> >>>>        */
> >>>>       unsigned int ctx_opened;
> >>>> +
> >>>> +    /**
> >>>> +     * Set holding static side data, such as HDR10 CLL / MDCV structures.
> >>>> +     * - encoding: set by user
> >>>> +     * - decoding: unused
> >>>> +     */
> >>>> +    AVFrameSideDataSet side_data_set;
> >>>
> >>> Why put it here and not in the public struct? It seems way more natural
> >>> there.
> >>>
> >>
> >> The general idea was that if you want to make people utilize helpers
> >> and not touch entries willy-nilly,
> >
> > But do we? Why?
> >
> > In this case I see no advantage to having a public function over having
> > two public fields. The function is strictly worse because it cannot be
> > extended, and enlarges the symbol table.
>
> Also, is this new AVFrameSideDataSet struct necessary? This looks sort
> of like the opposite of coded_side_data.

It indeed is the other side of the coded_side_data, which is something
that gets added after avctx init.

And the main reason was because the addition function being a pointer
to a struct, instead of (AVFrameSideData ***sd, int *nb_side_data).

Jan
Anton Khirnov March 27, 2023, 7:08 a.m. UTC | #7
Quoting Jan Ekström (2023-03-27 08:37:07)
> On Sun, Mar 26, 2023 at 10:00 PM Anton Khirnov <anton@khirnov.net> wrote:
> > Quoting Jan Ekström (2023-03-24 18:34:28)
> > > The general idea was that if you want to make people utilize helpers
> > > and not touch entries willy-nilly,
> >
> > But do we? Why?
> >
> > In this case I see no advantage to having a public function over having
> > two public fields. The function is strictly worse because it cannot be
> > extended, and enlarges the symbol table.
> 
> The overarching idea has been that looking at the recent changes of
> adding private internal structs and deprecating previously public
> stuff from the public structs was to be careful.

The fields being removed from public structs are actually private,
that's the only reason they are being hidden.

The thing you are adding is not private, it is public API. Having a
setter for it rather than making it a field in a public struct is merely
a different way of making it public, which
* is inconsistent with other similar APIs
* has the disadvantages I mentioned in the previous email

> 1. Post a patch with things added to the relevant private struct.
> 2. Allow specific access with a helper
> 3. See if anyone requires the information to be part of the public
> struct. At which point it may be moved there.
> 
> Additionally, only having things available via helpers means that you
> know how exactly the fields were being poked (instead of "we don't
> know how API users utilize them, and thus we cannot do X" (see the
> avcodec context related helpers where we still have to support close &
> av_freep which popped up in another patch), and given that the
> argument is a struct, the function can technically be extended
> (although a struct being in the middle of a struct might stop from it
> being extended).

There is no constructor for the struct, so it cannot be extended without
a major bump.
diff mbox series

Patch

diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
index c110b19e08..3faabe77d1 100644
--- a/libavcodec/avcodec.c
+++ b/libavcodec/avcodec.c
@@ -403,6 +403,7 @@  void avcodec_flush_buffers(AVCodecContext *avctx)
     avci->nb_draining_errors = 0;
     av_frame_unref(avci->buffer_frame);
     av_packet_unref(avci->buffer_pkt);
+    av_side_data_set_wipe(&avci->side_data_set);
 
     if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
         ff_thread_flush(avctx);
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index f21101752d..c658e97313 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -168,6 +168,13 @@  typedef struct AVCodecInternal {
      * a boolean to describe whether context is opened or not.
      */
     unsigned int ctx_opened;
+
+    /**
+     * Set holding static side data, such as HDR10 CLL / MDCV structures.
+     * - encoding: set by user
+     * - decoding: unused
+     */
+    AVFrameSideDataSet side_data_set;
 } AVCodecInternal;
 
 /**
diff --git a/libavcodec/options.c b/libavcodec/options.c
index f8fab164fb..acd3472fde 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -184,12 +184,17 @@  AVCodecContext *avcodec_alloc_context3(const AVCodec *codec)
 void avcodec_free_context(AVCodecContext **pavctx)
 {
     AVCodecContext *avctx = *pavctx;
+    AVCodecInternal *avci = NULL;
 
     if (!avctx)
         return;
 
     avcodec_close(avctx);
 
+    avci = avctx->internal;
+    if (avci)
+        av_side_data_set_wipe(&avci->side_data_set);
+
     av_freep(&avctx->internal);
 
     av_freep(&avctx->extradata);