mirror of
https://github.com/mpv-player/mpv
synced 2025-03-11 08:37:59 +00:00
mp_image: pass through unknown AVFrame side data
Useful for libavfilter. Somewhat risky, because we can't ensure the consistency of the unknown side data (but this is a general problem with side data, and libavfilter filters will usually get it wrong too _if_ there are conflict cases). Fixes #5569.
This commit is contained in:
parent
9daa842b5f
commit
55c88fdb8f
@ -209,6 +209,9 @@ static void mp_image_destructor(void *ptr)
|
|||||||
av_buffer_unref(&mpi->hwctx);
|
av_buffer_unref(&mpi->hwctx);
|
||||||
av_buffer_unref(&mpi->icc_profile);
|
av_buffer_unref(&mpi->icc_profile);
|
||||||
av_buffer_unref(&mpi->a53_cc);
|
av_buffer_unref(&mpi->a53_cc);
|
||||||
|
for (int n = 0; n < mpi->num_ff_side_data; n++)
|
||||||
|
av_buffer_unref(&mpi->ff_side_data[n].buf);
|
||||||
|
talloc_free(mpi->ff_side_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mp_chroma_div_up(int size, int shift)
|
int mp_chroma_div_up(int size, int shift)
|
||||||
@ -329,6 +332,10 @@ struct mp_image *mp_image_new_ref(struct mp_image *img)
|
|||||||
fail |= !ref_buffer(&new->icc_profile);
|
fail |= !ref_buffer(&new->icc_profile);
|
||||||
fail |= !ref_buffer(&new->a53_cc);
|
fail |= !ref_buffer(&new->a53_cc);
|
||||||
|
|
||||||
|
new->ff_side_data = talloc_memdup(NULL, new->ff_side_data,
|
||||||
|
new->num_ff_side_data * sizeof(new->ff_side_data[0]));
|
||||||
|
for (int n = 0; n < new->num_ff_side_data; n++)
|
||||||
|
fail |= !ref_buffer(&new->ff_side_data[n].buf);
|
||||||
|
|
||||||
if (!fail)
|
if (!fail)
|
||||||
return new;
|
return new;
|
||||||
@ -897,6 +904,15 @@ struct mp_image *mp_image_from_av_frame(struct AVFrame *src)
|
|||||||
sd = av_frame_get_side_data(src, AV_FRAME_DATA_A53_CC);
|
sd = av_frame_get_side_data(src, AV_FRAME_DATA_A53_CC);
|
||||||
if (sd)
|
if (sd)
|
||||||
dst->a53_cc = sd->buf;
|
dst->a53_cc = sd->buf;
|
||||||
|
|
||||||
|
for (int n = 0; n < src->nb_side_data; n++) {
|
||||||
|
sd = src->side_data[n];
|
||||||
|
struct mp_ff_side_data mpsd = {
|
||||||
|
.type = sd->type,
|
||||||
|
.buf = sd->buf,
|
||||||
|
};
|
||||||
|
MP_TARRAY_APPEND(NULL, dst->ff_side_data, dst->num_ff_side_data, mpsd);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (dst->hwctx) {
|
if (dst->hwctx) {
|
||||||
@ -908,7 +924,12 @@ struct mp_image *mp_image_from_av_frame(struct AVFrame *src)
|
|||||||
fns->complete_image_params(dst);
|
fns->complete_image_params(dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mp_image_new_ref(dst);
|
struct mp_image *res = mp_image_new_ref(dst);
|
||||||
|
|
||||||
|
// Allocated, but non-refcounted data.
|
||||||
|
talloc_free(dst->ff_side_data);
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -981,6 +1002,18 @@ struct AVFrame *mp_image_to_av_frame(struct mp_image *src)
|
|||||||
abort();
|
abort();
|
||||||
clm->MaxCLL = src->params.color.sig_peak * MP_REF_WHITE;
|
clm->MaxCLL = src->params.color.sig_peak * MP_REF_WHITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add back side data, but only for types which are not specially handled
|
||||||
|
// above. Keep in mind that the types above will be out of sync anyway.
|
||||||
|
for (int n = 0; n < new_ref->num_ff_side_data; n++) {
|
||||||
|
struct mp_ff_side_data *mpsd = &new_ref->ff_side_data[n];
|
||||||
|
if (!av_frame_get_side_data(dst, mpsd->type)) {
|
||||||
|
AVFrameSideData *sd = ffmpeg_garbage(dst, mpsd->type, mpsd->buf);
|
||||||
|
if (!sd)
|
||||||
|
abort();
|
||||||
|
mpsd->buf = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
talloc_free(new_ref);
|
talloc_free(new_ref);
|
||||||
|
@ -121,8 +121,16 @@ typedef struct mp_image {
|
|||||||
struct AVBufferRef *icc_profile;
|
struct AVBufferRef *icc_profile;
|
||||||
// Closed captions packet, if any (only after decoder)
|
// Closed captions packet, if any (only after decoder)
|
||||||
struct AVBufferRef *a53_cc;
|
struct AVBufferRef *a53_cc;
|
||||||
|
// Other side data we don't care about.
|
||||||
|
struct mp_ff_side_data *ff_side_data;
|
||||||
|
int num_ff_side_data;
|
||||||
} mp_image_t;
|
} mp_image_t;
|
||||||
|
|
||||||
|
struct mp_ff_side_data {
|
||||||
|
int type;
|
||||||
|
struct AVBufferRef *buf;
|
||||||
|
};
|
||||||
|
|
||||||
int mp_chroma_div_up(int size, int shift);
|
int mp_chroma_div_up(int size, int shift);
|
||||||
|
|
||||||
int mp_image_get_alloc_size(int imgfmt, int w, int h, int stride_align);
|
int mp_image_get_alloc_size(int imgfmt, int w, int h, int stride_align);
|
||||||
|
Loading…
Reference in New Issue
Block a user