diff mbox series

[FFmpeg-devel,3/3,v2] avcodec/bsf: add av_bsf_close()

Message ID 20200810185530.5306-1-jamrial@gmail.com
State New
Headers show
Series Untitled series #1973
Related show

Commit Message

James Almer Aug. 10, 2020, 6:55 p.m. UTC
This function lets the API user reuse an AVBSFContext in case of stream
parameter changes.

Signed-off-by: James Almer <jamrial@gmail.com>
---
 libavcodec/bsf.c | 26 ++++++++++++++++++++++++++
 libavcodec/bsf.h | 14 ++++++++++++++
 2 files changed, 40 insertions(+)

Comments

Andreas Rheinhardt Aug. 10, 2020, 11:26 p.m. UTC | #1
James Almer:
> This function lets the API user reuse an AVBSFContext in case of stream
> parameter changes.
> 
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
>  libavcodec/bsf.c | 26 ++++++++++++++++++++++++++
>  libavcodec/bsf.h | 14 ++++++++++++++
>  2 files changed, 40 insertions(+)
> 
> diff --git a/libavcodec/bsf.c b/libavcodec/bsf.c
> index d71bc32584..c8acd40ec0 100644
> --- a/libavcodec/bsf.c
> +++ b/libavcodec/bsf.c
> @@ -29,6 +29,7 @@
>  #include "bsf_internal.h"
>  #include "codec_desc.h"
>  #include "codec_par.h"
> +#include "internal.h"
>  
>  #define IS_EMPTY(pkt) (!(pkt)->data && !(pkt)->side_data_elems)
>  
> @@ -197,6 +198,31 @@ void av_bsf_flush(AVBSFContext *ctx)
>          ctx->filter->flush(ctx);
>  }
>  
> +void av_bsf_close(AVBSFContext *ctx)
> +{
> +    AVBSFInternal *bsfi = ctx->internal;
> +
> +    if (ctx->filter->close)
> +        ctx->filter->close(ctx);
> +    if (ctx->priv_data) {
> +        if (ctx->filter->priv_class)
> +            av_opt_free(ctx->priv_data);
> +        memset(ctx->priv_data, 0, ctx->filter->priv_data_size);
> +        if (ctx->filter->priv_class) {
> +            *(const AVClass **)ctx->priv_data = ctx->filter->priv_class;
> +            av_opt_set_defaults(ctx->priv_data);
> +        }
> +    }
> +
> +    bsfi->eof = 0;
> +    av_packet_unref(bsfi->buffer_pkt);
> +
> +    ctx->time_base_out = ctx->time_base_in = (AVRational){ 0, 0 };
> +
> +    ff_codec_parameters_reset(ctx->par_in);
> +    ff_codec_parameters_reset(ctx->par_out);
> +}
> +
>  int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
>  {
>      AVBSFInternal *bsfi = ctx->internal;
> diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
> index 3b5faa85cb..f72c45f7e5 100644
> --- a/libavcodec/bsf.h
> +++ b/libavcodec/bsf.h
> @@ -216,12 +216,26 @@ int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt);
>  
>  /**
>   * Reset the internal bitstream filter state. Should be called e.g. when seeking.
> + *
> + * @see av_bsf_close().
>   */
>  void av_bsf_flush(AVBSFContext *ctx);
>  
> +/**
> + * Close a bitstream filter context, leaving it in the same state as when it was
> + * freshly allocated. May be called e.g. to reuse the context in case of stream
> + * parameter changes.
> + *
> + * @see av_bsf_flush().
> + * @see av_bsf_free().
> + */
> +void av_bsf_close(AVBSFContext *ctx);
> +
>  /**
>   * Free a bitstream filter context and everything associated with it; write NULL
>   * into the supplied pointer.
> + *
> + * @see av_bsf_close().
>   */
>  void av_bsf_free(AVBSFContext **ctx);
>  
> 
I just had a thought about this: What to do with a BSF of type bsf_list?
av_bsf_close() will close and free all of the bsf in the internal list,
leaving the thing completely unusable: It just passes through any
packets unmodified. One would need to resurrect/adapt Marton's patch
from a few months ago that allows to add a bsf to an already existing
bsf list to make av_bsf_close() usable with these bsf lists.

- Andreas
James Almer Aug. 10, 2020, 11:42 p.m. UTC | #2
On 8/10/2020 8:26 PM, Andreas Rheinhardt wrote:
> James Almer:
>> This function lets the API user reuse an AVBSFContext in case of stream
>> parameter changes.
>>
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>>  libavcodec/bsf.c | 26 ++++++++++++++++++++++++++
>>  libavcodec/bsf.h | 14 ++++++++++++++
>>  2 files changed, 40 insertions(+)
>>
>> diff --git a/libavcodec/bsf.c b/libavcodec/bsf.c
>> index d71bc32584..c8acd40ec0 100644
>> --- a/libavcodec/bsf.c
>> +++ b/libavcodec/bsf.c
>> @@ -29,6 +29,7 @@
>>  #include "bsf_internal.h"
>>  #include "codec_desc.h"
>>  #include "codec_par.h"
>> +#include "internal.h"
>>  
>>  #define IS_EMPTY(pkt) (!(pkt)->data && !(pkt)->side_data_elems)
>>  
>> @@ -197,6 +198,31 @@ void av_bsf_flush(AVBSFContext *ctx)
>>          ctx->filter->flush(ctx);
>>  }
>>  
>> +void av_bsf_close(AVBSFContext *ctx)
>> +{
>> +    AVBSFInternal *bsfi = ctx->internal;
>> +
>> +    if (ctx->filter->close)
>> +        ctx->filter->close(ctx);
>> +    if (ctx->priv_data) {
>> +        if (ctx->filter->priv_class)
>> +            av_opt_free(ctx->priv_data);
>> +        memset(ctx->priv_data, 0, ctx->filter->priv_data_size);
>> +        if (ctx->filter->priv_class) {
>> +            *(const AVClass **)ctx->priv_data = ctx->filter->priv_class;
>> +            av_opt_set_defaults(ctx->priv_data);
>> +        }
>> +    }
>> +
>> +    bsfi->eof = 0;
>> +    av_packet_unref(bsfi->buffer_pkt);
>> +
>> +    ctx->time_base_out = ctx->time_base_in = (AVRational){ 0, 0 };
>> +
>> +    ff_codec_parameters_reset(ctx->par_in);
>> +    ff_codec_parameters_reset(ctx->par_out);
>> +}
>> +
>>  int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
>>  {
>>      AVBSFInternal *bsfi = ctx->internal;
>> diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
>> index 3b5faa85cb..f72c45f7e5 100644
>> --- a/libavcodec/bsf.h
>> +++ b/libavcodec/bsf.h
>> @@ -216,12 +216,26 @@ int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt);
>>  
>>  /**
>>   * Reset the internal bitstream filter state. Should be called e.g. when seeking.
>> + *
>> + * @see av_bsf_close().
>>   */
>>  void av_bsf_flush(AVBSFContext *ctx);
>>  
>> +/**
>> + * Close a bitstream filter context, leaving it in the same state as when it was
>> + * freshly allocated. May be called e.g. to reuse the context in case of stream
>> + * parameter changes.
>> + *
>> + * @see av_bsf_flush().
>> + * @see av_bsf_free().
>> + */
>> +void av_bsf_close(AVBSFContext *ctx);
>> +
>>  /**
>>   * Free a bitstream filter context and everything associated with it; write NULL
>>   * into the supplied pointer.
>> + *
>> + * @see av_bsf_close().
>>   */
>>  void av_bsf_free(AVBSFContext **ctx);
>>  
>>
> I just had a thought about this: What to do with a BSF of type bsf_list?
> av_bsf_close() will close and free all of the bsf in the internal list,
> leaving the thing completely unusable: It just passes through any
> packets unmodified.

You're right, calling filter->close() will free all the underlying bsfs,
which is not created during filter->init() but rather by the bsf list
specific alloc API.

> One would need to resurrect/adapt Marton's patch
> from a few months ago that allows to add a bsf to an already existing
> bsf list to make av_bsf_close() usable with these bsf lists.

It may not be worth bothering with it. As you well said, the benefits
from this function for API users are small.

> 
> - Andreas
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
diff mbox series

Patch

diff --git a/libavcodec/bsf.c b/libavcodec/bsf.c
index d71bc32584..c8acd40ec0 100644
--- a/libavcodec/bsf.c
+++ b/libavcodec/bsf.c
@@ -29,6 +29,7 @@ 
 #include "bsf_internal.h"
 #include "codec_desc.h"
 #include "codec_par.h"
+#include "internal.h"
 
 #define IS_EMPTY(pkt) (!(pkt)->data && !(pkt)->side_data_elems)
 
@@ -197,6 +198,31 @@  void av_bsf_flush(AVBSFContext *ctx)
         ctx->filter->flush(ctx);
 }
 
+void av_bsf_close(AVBSFContext *ctx)
+{
+    AVBSFInternal *bsfi = ctx->internal;
+
+    if (ctx->filter->close)
+        ctx->filter->close(ctx);
+    if (ctx->priv_data) {
+        if (ctx->filter->priv_class)
+            av_opt_free(ctx->priv_data);
+        memset(ctx->priv_data, 0, ctx->filter->priv_data_size);
+        if (ctx->filter->priv_class) {
+            *(const AVClass **)ctx->priv_data = ctx->filter->priv_class;
+            av_opt_set_defaults(ctx->priv_data);
+        }
+    }
+
+    bsfi->eof = 0;
+    av_packet_unref(bsfi->buffer_pkt);
+
+    ctx->time_base_out = ctx->time_base_in = (AVRational){ 0, 0 };
+
+    ff_codec_parameters_reset(ctx->par_in);
+    ff_codec_parameters_reset(ctx->par_out);
+}
+
 int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
 {
     AVBSFInternal *bsfi = ctx->internal;
diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
index 3b5faa85cb..f72c45f7e5 100644
--- a/libavcodec/bsf.h
+++ b/libavcodec/bsf.h
@@ -216,12 +216,26 @@  int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt);
 
 /**
  * Reset the internal bitstream filter state. Should be called e.g. when seeking.
+ *
+ * @see av_bsf_close().
  */
 void av_bsf_flush(AVBSFContext *ctx);
 
+/**
+ * Close a bitstream filter context, leaving it in the same state as when it was
+ * freshly allocated. May be called e.g. to reuse the context in case of stream
+ * parameter changes.
+ *
+ * @see av_bsf_flush().
+ * @see av_bsf_free().
+ */
+void av_bsf_close(AVBSFContext *ctx);
+
 /**
  * Free a bitstream filter context and everything associated with it; write NULL
  * into the supplied pointer.
+ *
+ * @see av_bsf_close().
  */
 void av_bsf_free(AVBSFContext **ctx);