diff mbox series

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

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

Checks

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

Commit Message

James Almer Sept. 27, 2023, 1:12 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 | 48 ++++++++++++++++++++++++++++++++++++++++++
 libavcodec/codec_par.h | 11 ++++++++++
 2 files changed, 59 insertions(+)

Comments

Anton Khirnov Oct. 3, 2023, 11:23 a.m. UTC | #1
Quoting James Almer (2023-09-27 15:12:33)
> 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 | 48 ++++++++++++++++++++++++++++++++++++++++++
>  libavcodec/codec_par.h | 11 ++++++++++
>  2 files changed, 59 insertions(+)

LGTM
diff mbox series

Patch

diff --git a/libavcodec/codec_par.c b/libavcodec/codec_par.c
index e4e4cd48d3..364569c0e6 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_free(&par->side_data, &par->nb_side_data);
 
     memset(par, 0, sizeof(*par));
 
@@ -72,6 +74,35 @@  void avcodec_parameters_free(AVCodecParameters **ppar)
     av_freep(ppar);
 }
 
+static int codec_parameters_copy_side_data(AVPacketSideData **pdst, int *pnb_dst,
+                                           const AVPacketSideData *src, int nb_src)
+{
+    AVPacketSideData *dst;
+    int nb_dst = *pnb_dst;
+
+    if (!src)
+        return 0;
+
+    *pdst = dst = av_calloc(nb_src, sizeof(*dst));
+    if (!dst)
+        return AVERROR(ENOMEM);
+
+    for (int i = 0; i < nb_src; i++) {
+        const AVPacketSideData *src_sd = &src[i];
+        AVPacketSideData *dst_sd = &dst[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;
+        *pnb_dst = ++nb_dst;
+    }
+
+    return 0;
+}
+
 int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
 {
     int ret;
@@ -82,6 +113,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      = NULL;
+    dst->nb_side_data   = 0;
     if (src->extradata) {
         dst->extradata = av_mallocz(src->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
         if (!dst->extradata)
@@ -89,6 +122,10 @@  int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src
         memcpy(dst->extradata, src->extradata, src->extradata_size);
         dst->extradata_size = src->extradata_size;
     }
+    ret = codec_parameters_copy_side_data(&dst->side_data, &dst->nb_side_data,
+                                           src->side_data,  src->nb_side_data);
+    if (ret < 0)
+        return ret;
 
     ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
     if (ret < 0)
@@ -178,6 +215,11 @@  FF_ENABLE_DEPRECATION_WARNINGS
         par->extradata_size = codec->extradata_size;
     }
 
+    ret = codec_parameters_copy_side_data(&par->side_data, &par->nb_side_data,
+                                          codec->coded_side_data, codec->nb_coded_side_data);
+    if (ret < 0)
+        return ret;
+
     return 0;
 }
 
@@ -262,5 +304,11 @@  FF_ENABLE_DEPRECATION_WARNINGS
         codec->extradata_size = par->extradata_size;
     }
 
+    av_packet_side_data_free(&codec->coded_side_data, &codec->nb_coded_side_data);
+    ret = codec_parameters_copy_side_data(&codec->coded_side_data, &codec->nb_coded_side_data,
+                                          par->side_data, par->nb_side_data);
+    if (ret < 0)
+        return ret;
+
     return 0;
 }
diff --git a/libavcodec/codec_par.h b/libavcodec/codec_par.h
index add90fdb1e..85017ec76e 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,16 @@  typedef struct AVCodecParameters {
      * when no higher-level timing information is available.
      */
     AVRational framerate;
+
+    /**
+     * Additional data associated with the entire stream.
+     */
+    AVPacketSideData *side_data;
+
+    /**
+     * Amount of entries in @ref side_data.
+     */
+    int nb_side_data;
 } AVCodecParameters;
 
 /**