diff mbox series

[FFmpeg-devel,02/10] avcodec/codec_par: add side data to AVCodecParameters

Message ID 20230906174431.45558-3-jamrial@gmail.com
State New
Headers show
Series AVCodecContext and AVCodecParameters side data | expand

Commit Message

James Almer Sept. 6, 2023, 5:44 p.m. UTC
This will simplify the propagation of side data to decoders and from encoders.
Global side data will now reside in the AVCodecContext, thus be available
during init(), removing the need to propagate it inside packets.

Global and frame specific side data will therefore be distinct.

Signed-off-by: James Almer <jamrial@gmail.com>
---
 libavcodec/codec_par.c | 81 ++++++++++++++++++++++++++++++++++++++++++
 libavcodec/codec_par.h |  6 ++++
 2 files changed, 87 insertions(+)

Comments

Andreas Rheinhardt Sept. 11, 2023, 5:45 p.m. UTC | #1
James Almer:
> This will simplify the propagation of side data to decoders and from encoders.
> Global side data will now reside in the AVCodecContext, thus be available
> during init(), removing the need to propagate it inside packets.
> 
> Global and frame specific side data will therefore be distinct.
> 
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
>  libavcodec/codec_par.c | 81 ++++++++++++++++++++++++++++++++++++++++++
>  libavcodec/codec_par.h |  6 ++++
>  2 files changed, 87 insertions(+)
> 
> diff --git a/libavcodec/codec_par.c b/libavcodec/codec_par.c
> index a38a475dc7..c0c941c2b6 100644
> --- a/libavcodec/codec_par.c
> +++ b/libavcodec/codec_par.c
> @@ -27,11 +27,13 @@
>  #include "libavutil/mem.h"
>  #include "avcodec.h"
>  #include "codec_par.h"
> +#include "packet.h"
>  
>  static void codec_parameters_reset(AVCodecParameters *par)
>  {
>      av_freep(&par->extradata);
>      av_channel_layout_uninit(&par->ch_layout);
> +    av_packet_side_data_set_free(&par->side_data);
>  
>      memset(par, 0, sizeof(*par));
>  
> @@ -82,6 +84,8 @@ int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src
>      dst->ch_layout      = (AVChannelLayout){0};
>      dst->extradata      = NULL;
>      dst->extradata_size = 0;
> +    dst->side_data.sd    = NULL;
> +    dst->side_data.nb_sd = 0;
>      if (src->extradata) {
>          dst->extradata = av_mallocz(src->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
>          if (!dst->extradata)
> @@ -89,6 +93,32 @@ int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src
>          memcpy(dst->extradata, src->extradata, src->extradata_size);
>          dst->extradata_size = src->extradata_size;
>      }
> +    if (src->side_data.nb_sd) {
> +        const AVPacketSideDataSet *src_set = &src->side_data;
> +        AVPacketSideDataSet *dst_set = &dst->side_data;
> +
> +        dst_set->sd = av_calloc(src_set->nb_sd, sizeof(*dst_set->sd));
> +        if (!dst_set->sd)
> +            return AVERROR(ENOMEM);
> +
> +        for (int i = 0; i < src_set->nb_sd; i++) {
> +            const AVPacketSideData *src_sd = src_set->sd[i];
> +            AVPacketSideData *dst_sd = av_mallocz(sizeof(*dst_sd));
> +
> +            if (!dst_sd)
> +                return AVERROR(ENOMEM);
> +
> +            dst_sd->data = av_memdup(src_sd->data, src_sd->size);
> +            if (!dst_sd->data) {
> +                return AVERROR(ENOMEM);
> +                av_free(dst_sd);
> +            }
> +
> +            dst_sd->type = src_sd->type;
> +            dst_sd->size = src_sd->size;
> +            dst_set->sd[dst_set->nb_sd++] = dst_sd;
> +        }
> +    }
>  
>      ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
>      if (ret < 0)
> @@ -178,6 +208,32 @@ FF_ENABLE_DEPRECATION_WARNINGS
>          par->extradata_size = codec->extradata_size;
>      }
>  
> +    if (codec->nb_coded_side_data) {
> +        AVPacketSideDataSet *dst_set = &par->side_data;
> +
> +        dst_set->sd = av_calloc(codec->nb_coded_side_data, sizeof(*dst_set->sd));
> +        if (!dst_set->sd)
> +            return AVERROR(ENOMEM);
> +
> +        for (int i = 0; i < codec->nb_coded_side_data; i++) {
> +            const AVPacketSideData *src_sd = &codec->coded_side_data[i];
> +            AVPacketSideData *dst_sd = av_mallocz(sizeof(*dst_sd));
> +
> +            if (!dst_sd)
> +                return AVERROR(ENOMEM);
> +
> +            dst_sd->data = av_memdup(src_sd->data, src_sd->size);
> +            if (!dst_sd->data) {
> +                return AVERROR(ENOMEM);
> +                av_free(dst_sd);

No compiler warning for this?

> +            }
> +
> +            dst_sd->type = src_sd->type;
> +            dst_sd->size = src_sd->size;
> +            dst_set->sd[dst_set->nb_sd++] = dst_sd;
> +        }
> +    }
> +
>      return 0;
>  }
>  
> @@ -262,5 +318,30 @@ FF_ENABLE_DEPRECATION_WARNINGS
>          codec->extradata_size = par->extradata_size;
>      }
>  
> +    for (int i = 0; i < codec->nb_coded_side_data; i++)
> +        av_free(codec->coded_side_data[i].data);
> +    av_freep(&codec->coded_side_data);
> +    codec->nb_coded_side_data = 0;
> +    if (par->side_data.nb_sd) {
> +        const AVPacketSideDataSet *src_set = &par->side_data;
> +
> +        codec->coded_side_data = av_calloc(src_set->nb_sd, sizeof(*codec->coded_side_data));
> +        if (!codec->coded_side_data)
> +            return AVERROR(ENOMEM);
> +
> +        for (int i = 0; i < src_set->nb_sd; i++) {
> +            const AVPacketSideData *src_sd = src_set->sd[i];
> +            AVPacketSideData *dst_sd = &codec->coded_side_data[i];
> +
> +            dst_sd->data = av_memdup(src_sd->data, src_sd->size);
> +            if (!dst_sd->data)
> +                return AVERROR(ENOMEM);
> +
> +            dst_sd->type = src_sd->type;
> +            dst_sd->size = src_sd->size;
> +            codec->nb_coded_side_data++;
> +        }
> +    }
> +
>      return 0;
>  }
> diff --git a/libavcodec/codec_par.h b/libavcodec/codec_par.h
> index add90fdb1e..169e595b7c 100644
> --- a/libavcodec/codec_par.h
> +++ b/libavcodec/codec_par.h
> @@ -29,6 +29,7 @@
>  #include "libavutil/pixfmt.h"
>  
>  #include "codec_id.h"
> +#include "packet.h"
>  
>  /**
>   * @addtogroup lavc_core
> @@ -223,6 +224,11 @@ typedef struct AVCodecParameters {
>       * when no higher-level timing information is available.
>       */
>      AVRational framerate;
> +
> +    /**
> +     * Additional data associated with the entire stream.
> +     */
> +    AVPacketSideDataSet side_data;
>  } AVCodecParameters;
>  
>  /**
James Almer Sept. 12, 2023, 4:34 p.m. UTC | #2
On 9/11/2023 2:45 PM, Andreas Rheinhardt wrote:
> James Almer:
>> This will simplify the propagation of side data to decoders and from encoders.
>> Global side data will now reside in the AVCodecContext, thus be available
>> during init(), removing the need to propagate it inside packets.
>>
>> Global and frame specific side data will therefore be distinct.
>>
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>>   libavcodec/codec_par.c | 81 ++++++++++++++++++++++++++++++++++++++++++
>>   libavcodec/codec_par.h |  6 ++++
>>   2 files changed, 87 insertions(+)
>>
>> diff --git a/libavcodec/codec_par.c b/libavcodec/codec_par.c
>> index a38a475dc7..c0c941c2b6 100644
>> --- a/libavcodec/codec_par.c
>> +++ b/libavcodec/codec_par.c
>> @@ -27,11 +27,13 @@
>>   #include "libavutil/mem.h"
>>   #include "avcodec.h"
>>   #include "codec_par.h"
>> +#include "packet.h"
>>   
>>   static void codec_parameters_reset(AVCodecParameters *par)
>>   {
>>       av_freep(&par->extradata);
>>       av_channel_layout_uninit(&par->ch_layout);
>> +    av_packet_side_data_set_free(&par->side_data);
>>   
>>       memset(par, 0, sizeof(*par));
>>   
>> @@ -82,6 +84,8 @@ int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src
>>       dst->ch_layout      = (AVChannelLayout){0};
>>       dst->extradata      = NULL;
>>       dst->extradata_size = 0;
>> +    dst->side_data.sd    = NULL;
>> +    dst->side_data.nb_sd = 0;
>>       if (src->extradata) {
>>           dst->extradata = av_mallocz(src->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
>>           if (!dst->extradata)
>> @@ -89,6 +93,32 @@ int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src
>>           memcpy(dst->extradata, src->extradata, src->extradata_size);
>>           dst->extradata_size = src->extradata_size;
>>       }
>> +    if (src->side_data.nb_sd) {
>> +        const AVPacketSideDataSet *src_set = &src->side_data;
>> +        AVPacketSideDataSet *dst_set = &dst->side_data;
>> +
>> +        dst_set->sd = av_calloc(src_set->nb_sd, sizeof(*dst_set->sd));
>> +        if (!dst_set->sd)
>> +            return AVERROR(ENOMEM);
>> +
>> +        for (int i = 0; i < src_set->nb_sd; i++) {
>> +            const AVPacketSideData *src_sd = src_set->sd[i];
>> +            AVPacketSideData *dst_sd = av_mallocz(sizeof(*dst_sd));
>> +
>> +            if (!dst_sd)
>> +                return AVERROR(ENOMEM);
>> +
>> +            dst_sd->data = av_memdup(src_sd->data, src_sd->size);
>> +            if (!dst_sd->data) {
>> +                return AVERROR(ENOMEM);
>> +                av_free(dst_sd);
>> +            }
>> +
>> +            dst_sd->type = src_sd->type;
>> +            dst_sd->size = src_sd->size;
>> +            dst_set->sd[dst_set->nb_sd++] = dst_sd;
>> +        }
>> +    }
>>   
>>       ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
>>       if (ret < 0)
>> @@ -178,6 +208,32 @@ FF_ENABLE_DEPRECATION_WARNINGS
>>           par->extradata_size = codec->extradata_size;
>>       }
>>   
>> +    if (codec->nb_coded_side_data) {
>> +        AVPacketSideDataSet *dst_set = &par->side_data;
>> +
>> +        dst_set->sd = av_calloc(codec->nb_coded_side_data, sizeof(*dst_set->sd));
>> +        if (!dst_set->sd)
>> +            return AVERROR(ENOMEM);
>> +
>> +        for (int i = 0; i < codec->nb_coded_side_data; i++) {
>> +            const AVPacketSideData *src_sd = &codec->coded_side_data[i];
>> +            AVPacketSideData *dst_sd = av_mallocz(sizeof(*dst_sd));
>> +
>> +            if (!dst_sd)
>> +                return AVERROR(ENOMEM);
>> +
>> +            dst_sd->data = av_memdup(src_sd->data, src_sd->size);
>> +            if (!dst_sd->data) {
>> +                return AVERROR(ENOMEM);
>> +                av_free(dst_sd);
> 
> No compiler warning for this?

Good catch. And no, i don't get one with GCC 13.

> 
>> +            }
>> +
>> +            dst_sd->type = src_sd->type;
>> +            dst_sd->size = src_sd->size;
>> +            dst_set->sd[dst_set->nb_sd++] = dst_sd;
>> +        }
>> +    }
>> +
>>       return 0;
>>   }
>>   
>> @@ -262,5 +318,30 @@ FF_ENABLE_DEPRECATION_WARNINGS
>>           codec->extradata_size = par->extradata_size;
>>       }
>>   
>> +    for (int i = 0; i < codec->nb_coded_side_data; i++)
>> +        av_free(codec->coded_side_data[i].data);
>> +    av_freep(&codec->coded_side_data);
>> +    codec->nb_coded_side_data = 0;
>> +    if (par->side_data.nb_sd) {
>> +        const AVPacketSideDataSet *src_set = &par->side_data;
>> +
>> +        codec->coded_side_data = av_calloc(src_set->nb_sd, sizeof(*codec->coded_side_data));
>> +        if (!codec->coded_side_data)
>> +            return AVERROR(ENOMEM);
>> +
>> +        for (int i = 0; i < src_set->nb_sd; i++) {
>> +            const AVPacketSideData *src_sd = src_set->sd[i];
>> +            AVPacketSideData *dst_sd = &codec->coded_side_data[i];
>> +
>> +            dst_sd->data = av_memdup(src_sd->data, src_sd->size);
>> +            if (!dst_sd->data)
>> +                return AVERROR(ENOMEM);
>> +
>> +            dst_sd->type = src_sd->type;
>> +            dst_sd->size = src_sd->size;
>> +            codec->nb_coded_side_data++;
>> +        }
>> +    }
>> +
>>       return 0;
>>   }
>> diff --git a/libavcodec/codec_par.h b/libavcodec/codec_par.h
>> index add90fdb1e..169e595b7c 100644
>> --- a/libavcodec/codec_par.h
>> +++ b/libavcodec/codec_par.h
>> @@ -29,6 +29,7 @@
>>   #include "libavutil/pixfmt.h"
>>   
>>   #include "codec_id.h"
>> +#include "packet.h"
>>   
>>   /**
>>    * @addtogroup lavc_core
>> @@ -223,6 +224,11 @@ typedef struct AVCodecParameters {
>>        * when no higher-level timing information is available.
>>        */
>>       AVRational framerate;
>> +
>> +    /**
>> +     * Additional data associated with the entire stream.
>> +     */
>> +    AVPacketSideDataSet side_data;
>>   } AVCodecParameters;
>>   
>>   /**
> 
> _______________________________________________
> 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/codec_par.c b/libavcodec/codec_par.c
index a38a475dc7..c0c941c2b6 100644
--- a/libavcodec/codec_par.c
+++ b/libavcodec/codec_par.c
@@ -27,11 +27,13 @@ 
 #include "libavutil/mem.h"
 #include "avcodec.h"
 #include "codec_par.h"
+#include "packet.h"
 
 static void codec_parameters_reset(AVCodecParameters *par)
 {
     av_freep(&par->extradata);
     av_channel_layout_uninit(&par->ch_layout);
+    av_packet_side_data_set_free(&par->side_data);
 
     memset(par, 0, sizeof(*par));
 
@@ -82,6 +84,8 @@  int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src
     dst->ch_layout      = (AVChannelLayout){0};
     dst->extradata      = NULL;
     dst->extradata_size = 0;
+    dst->side_data.sd    = NULL;
+    dst->side_data.nb_sd = 0;
     if (src->extradata) {
         dst->extradata = av_mallocz(src->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
         if (!dst->extradata)
@@ -89,6 +93,32 @@  int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src
         memcpy(dst->extradata, src->extradata, src->extradata_size);
         dst->extradata_size = src->extradata_size;
     }
+    if (src->side_data.nb_sd) {
+        const AVPacketSideDataSet *src_set = &src->side_data;
+        AVPacketSideDataSet *dst_set = &dst->side_data;
+
+        dst_set->sd = av_calloc(src_set->nb_sd, sizeof(*dst_set->sd));
+        if (!dst_set->sd)
+            return AVERROR(ENOMEM);
+
+        for (int i = 0; i < src_set->nb_sd; i++) {
+            const AVPacketSideData *src_sd = src_set->sd[i];
+            AVPacketSideData *dst_sd = av_mallocz(sizeof(*dst_sd));
+
+            if (!dst_sd)
+                return AVERROR(ENOMEM);
+
+            dst_sd->data = av_memdup(src_sd->data, src_sd->size);
+            if (!dst_sd->data) {
+                return AVERROR(ENOMEM);
+                av_free(dst_sd);
+            }
+
+            dst_sd->type = src_sd->type;
+            dst_sd->size = src_sd->size;
+            dst_set->sd[dst_set->nb_sd++] = dst_sd;
+        }
+    }
 
     ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
     if (ret < 0)
@@ -178,6 +208,32 @@  FF_ENABLE_DEPRECATION_WARNINGS
         par->extradata_size = codec->extradata_size;
     }
 
+    if (codec->nb_coded_side_data) {
+        AVPacketSideDataSet *dst_set = &par->side_data;
+
+        dst_set->sd = av_calloc(codec->nb_coded_side_data, sizeof(*dst_set->sd));
+        if (!dst_set->sd)
+            return AVERROR(ENOMEM);
+
+        for (int i = 0; i < codec->nb_coded_side_data; i++) {
+            const AVPacketSideData *src_sd = &codec->coded_side_data[i];
+            AVPacketSideData *dst_sd = av_mallocz(sizeof(*dst_sd));
+
+            if (!dst_sd)
+                return AVERROR(ENOMEM);
+
+            dst_sd->data = av_memdup(src_sd->data, src_sd->size);
+            if (!dst_sd->data) {
+                return AVERROR(ENOMEM);
+                av_free(dst_sd);
+            }
+
+            dst_sd->type = src_sd->type;
+            dst_sd->size = src_sd->size;
+            dst_set->sd[dst_set->nb_sd++] = dst_sd;
+        }
+    }
+
     return 0;
 }
 
@@ -262,5 +318,30 @@  FF_ENABLE_DEPRECATION_WARNINGS
         codec->extradata_size = par->extradata_size;
     }
 
+    for (int i = 0; i < codec->nb_coded_side_data; i++)
+        av_free(codec->coded_side_data[i].data);
+    av_freep(&codec->coded_side_data);
+    codec->nb_coded_side_data = 0;
+    if (par->side_data.nb_sd) {
+        const AVPacketSideDataSet *src_set = &par->side_data;
+
+        codec->coded_side_data = av_calloc(src_set->nb_sd, sizeof(*codec->coded_side_data));
+        if (!codec->coded_side_data)
+            return AVERROR(ENOMEM);
+
+        for (int i = 0; i < src_set->nb_sd; i++) {
+            const AVPacketSideData *src_sd = src_set->sd[i];
+            AVPacketSideData *dst_sd = &codec->coded_side_data[i];
+
+            dst_sd->data = av_memdup(src_sd->data, src_sd->size);
+            if (!dst_sd->data)
+                return AVERROR(ENOMEM);
+
+            dst_sd->type = src_sd->type;
+            dst_sd->size = src_sd->size;
+            codec->nb_coded_side_data++;
+        }
+    }
+
     return 0;
 }
diff --git a/libavcodec/codec_par.h b/libavcodec/codec_par.h
index add90fdb1e..169e595b7c 100644
--- a/libavcodec/codec_par.h
+++ b/libavcodec/codec_par.h
@@ -29,6 +29,7 @@ 
 #include "libavutil/pixfmt.h"
 
 #include "codec_id.h"
+#include "packet.h"
 
 /**
  * @addtogroup lavc_core
@@ -223,6 +224,11 @@  typedef struct AVCodecParameters {
      * when no higher-level timing information is available.
      */
     AVRational framerate;
+
+    /**
+     * Additional data associated with the entire stream.
+     */
+    AVPacketSideDataSet side_data;
 } AVCodecParameters;
 
 /**