From: Niklas Haas <g...@haasn.dev> The signature of ff_frame_new_side_data got more complicated due to a need to distinguish between "failed allocating side data" and "side data was already present".
We could do something similar to ff_frame_new_side_data_from_buf, but most callers ignore the OOM condition on this function, which is merely re-allocating the side data array. So preserve the return signature to make it slightly less of a pain to use. Signed-off-by: Anton Khirnov <an...@khirnov.net> --- libavcodec/decode.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ libavcodec/decode.h | 20 +++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 5524e229c2..10946f208a 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -1857,6 +1857,53 @@ int ff_decode_preinit(AVCodecContext *avctx) return 0; } +/** + * Check side data preference and clear existing side data from frame + * if needed. + * + * @retval 0 side data of this type can be added to frame + * @retval 1 side data of this type should not be added to frame + */ +static int side_data_pref(const AVCodecContext *avctx, AVFrame *frame, + enum AVFrameSideDataType type) +{ + DecodeContext *dc = decode_ctx(avctx->internal); + + // Note: could be skipped for `type` without corresponding packet sd + if (av_frame_get_side_data(frame, type)) { + if (dc->side_data_pref_mask & (1ULL << type)) + return 1; + av_frame_remove_side_data(frame, type); + } + + return 0; +} + + +int ff_frame_new_side_data(const AVCodecContext *avctx, AVFrame *frame, + enum AVFrameSideDataType type, size_t size, + AVFrameSideData **sd) +{ + if (side_data_pref(avctx, frame, type)) { + *sd = NULL; + return 0; + } + + *sd = av_frame_new_side_data(frame, type, size); + return *sd ? 0 : AVERROR(ENOMEM); +} + +AVFrameSideData *ff_frame_new_side_data_from_buf(const AVCodecContext *avctx, + AVFrame *frame, + enum AVFrameSideDataType type, + AVBufferRef *buf) +{ + if (side_data_pref(avctx, frame, type)) + return NULL; + + return av_frame_new_side_data_from_buf(frame, type, buf); +} + int ff_copy_palette(void *dst, const AVPacket *src, void *logctx) { size_t size; diff --git a/libavcodec/decode.h b/libavcodec/decode.h index daf1a67444..a131b9940a 100644 --- a/libavcodec/decode.h +++ b/libavcodec/decode.h @@ -155,4 +155,24 @@ int ff_hwaccel_frame_priv_alloc(AVCodecContext *avctx, void **hwaccel_picture_pr const AVPacketSideData *ff_get_coded_side_data(const AVCodecContext *avctx, enum AVPacketSideDataType type); +/** + * Wrapper around av_frame_new_side_data, which rejects side data overridden by + * the demuxer. Returns 0 on success, and a negative error code otherwise. + * If successful, *sd may either be a pointer to the new side data, or NULL + * in case the side data was already present. + */ +int ff_frame_new_side_data(const AVCodecContext *avctx, AVFrame *frame, + enum AVFrameSideDataType type, size_t size, + AVFrameSideData **sd); + +/** + * Similar to `ff_frame_new_side_data`, but using an existing buffer ref. + * On success, returns the newly added side data, and passes ownership + * of `buf` to the frame. + */ +AVFrameSideData *ff_frame_new_side_data_from_buf(const AVCodecContext *avctx, + AVFrame *frame, + enum AVFrameSideDataType type, + AVBufferRef *buf); + #endif /* AVCODEC_DECODE_H */ -- 2.42.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".