aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/codec_par.c
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2023-07-16 13:18:35 -0300
committerJames Almer <jamrial@gmail.com>2023-10-06 09:56:41 -0300
commit21d7cc6fa9a26e94965fa71b25655d07568450fe (patch)
tree47ccff66a822b05de25af3a0875b53db39f11936 /libavcodec/codec_par.c
parent74279227dd28d01b447edb8e617a545982171c2c (diff)
downloadffmpeg-21d7cc6fa9a26e94965fa71b25655d07568450fe.tar.gz
avcodec/codec_par: add side data to AVCodecParameters
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>
Diffstat (limited to 'libavcodec/codec_par.c')
-rw-r--r--libavcodec/codec_par.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/libavcodec/codec_par.c b/libavcodec/codec_par.c
index e4e4cd48d3..abaac63841 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->coded_side_data, &par->nb_coded_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->coded_side_data = NULL;
+ dst->nb_coded_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->coded_side_data, &dst->nb_coded_side_data,
+ src->coded_side_data, src->nb_coded_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->coded_side_data, &par->nb_coded_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->coded_side_data, par->nb_coded_side_data);
+ if (ret < 0)
+ return ret;
+
return 0;
}