fftools: pass global side data through using a separate array

This keeps global and per frame side data clearly separated, and actually
propagates the former as it comes out from the buffersink filter.

Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
James Almer 2025-10-18 20:38:39 -03:00
parent 7ac1b410e1
commit 7b18beb477
4 changed files with 36 additions and 19 deletions

View File

@ -400,6 +400,7 @@ static void frame_data_free(void *opaque, uint8_t *data)
{
FrameData *fd = (FrameData *)data;
av_frame_side_data_free(&fd->side_data, &fd->nb_side_data);
avcodec_parameters_free(&fd->par_enc);
av_free(data);
@ -429,6 +430,8 @@ static int frame_data_ensure(AVBufferRef **dst, int writable)
memcpy(fd, fd_src, sizeof(*fd));
fd->par_enc = NULL;
fd->side_data = NULL;
fd->nb_side_data = 0;
if (fd_src->par_enc) {
int ret = 0;
@ -444,6 +447,16 @@ static int frame_data_ensure(AVBufferRef **dst, int writable)
}
}
if (fd_src->nb_side_data) {
int ret = clone_side_data(&fd->side_data, &fd->nb_side_data,
fd_src->side_data, fd_src->nb_side_data, 0);
if (ret < 0) {
av_buffer_unref(dst);
av_buffer_unref(&src);
return ret;
}
}
av_buffer_unref(&src);
} else {
fd->dec.frame_num = UINT64_MAX;

View File

@ -698,6 +698,9 @@ typedef struct FrameData {
int64_t wallclock[LATENCY_PROBE_NB];
AVCodecParameters *par_enc;
AVFrameSideData **side_data;
int nb_side_data;
} FrameData;
extern InputFile **input_files;

View File

@ -205,19 +205,10 @@ int enc_open(void *opaque, const AVFrame *frame)
av_assert0(frame->opaque_ref);
fd = (FrameData*)frame->opaque_ref->data;
for (int i = 0; i < frame->nb_side_data; i++) {
const AVSideDataDescriptor *desc = av_frame_side_data_desc(frame->side_data[i]->type);
if (!(desc->props & AV_SIDE_DATA_PROP_GLOBAL))
continue;
ret = av_frame_side_data_clone(&enc_ctx->decoded_side_data,
&enc_ctx->nb_decoded_side_data,
frame->side_data[i],
AV_FRAME_SIDE_DATA_FLAG_UNIQUE);
if (ret < 0)
return ret;
}
ret = clone_side_data(&enc_ctx->decoded_side_data, &enc_ctx->nb_decoded_side_data,
fd->side_data, fd->nb_side_data, AV_FRAME_SIDE_DATA_FLAG_UNIQUE);
if (ret < 0)
return ret;
}
if (ist)

View File

@ -2129,7 +2129,8 @@ static int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *fr
for (int i = 0; i < frame->nb_side_data; i++) {
const AVSideDataDescriptor *desc = av_frame_side_data_desc(frame->side_data[i]->type);
if (!(desc->props & AV_SIDE_DATA_PROP_GLOBAL))
if (!(desc->props & AV_SIDE_DATA_PROP_GLOBAL) ||
frame->side_data[i]->type == AV_FRAME_DATA_DISPLAYMATRIX)
continue;
ret = av_frame_side_data_clone(&ifp->side_data,
@ -2502,16 +2503,17 @@ static int close_output(OutputFilterPriv *ofp, FilterGraphThread *fgt)
if (ret < 0)
return ret;
}
av_frame_side_data_free(&frame->side_data, &frame->nb_side_data);
ret = clone_side_data(&frame->side_data, &frame->nb_side_data,
ofp->side_data, ofp->nb_side_data, 0);
if (ret < 0)
return ret;
fd = frame_data(frame);
if (!fd)
return AVERROR(ENOMEM);
av_frame_side_data_free(&fd->side_data, &fd->nb_side_data);
ret = clone_side_data(&fd->side_data, &fd->nb_side_data,
ofp->side_data, ofp->nb_side_data, 0);
if (ret < 0)
return ret;
fd->frame_rate_filter = ofp->fps.framerate;
av_assert0(!frame->buf[0]);
@ -2666,6 +2668,14 @@ static int fg_output_step(OutputFilterPriv *ofp, FilterGraphThread *fgt,
return AVERROR(ENOMEM);
}
av_frame_side_data_free(&fd->side_data, &fd->nb_side_data);
if (!fgt->got_frame) {
ret = clone_side_data(&fd->side_data, &fd->nb_side_data,
ofp->side_data, ofp->nb_side_data, 0);
if (ret < 0)
return ret;
}
fd->wallclock[LATENCY_PROBE_FILTER_POST] = av_gettime_relative();
// only use bits_per_raw_sample passed through from the decoder