Message ID | 20240229164307.3535613-8-jeebjp@gmail.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,v7,01/14] avutil/frame: split side data list wiping out to non-AVFrame function | expand |
Context | Check | Description |
---|---|---|
yinshiyou/make_loongarch64 | success | Make finished |
yinshiyou/make_fate_loongarch64 | success | Make fate finished |
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
Quoting Jan Ekström (2024-02-29 17:42:54) > diff --git a/libavutil/frame.h b/libavutil/frame.h > index 47d0096bc4..908fd4a90d 100644 > --- a/libavutil/frame.h > +++ b/libavutil/frame.h > @@ -1081,6 +1081,26 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd, > enum AVFrameSideDataType type, > size_t size, unsigned int flags); > > +/** > + * Add a new side data entry to a set from an existing AVBufferRef. > + * > + * @param sd pointer to array of side data to which to add another entry. > + * @param nb_sd pointer to an integer containing the number of entries in > + * the array. > + * @param type type of the added side data > + * @param buf AVBufferRef for which a new reference will be made This seems inconsistent with av_frame_new_side_data_from_buf(), which takes ownership of the buffer reference passed to it. Is there a strong reason to do it differently here?
On 3/1/2024 3:19 PM, Anton Khirnov wrote: > Quoting Jan Ekström (2024-02-29 17:42:54) >> diff --git a/libavutil/frame.h b/libavutil/frame.h >> index 47d0096bc4..908fd4a90d 100644 >> --- a/libavutil/frame.h >> +++ b/libavutil/frame.h >> @@ -1081,6 +1081,26 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd, >> enum AVFrameSideDataType type, >> size_t size, unsigned int flags); >> >> +/** >> + * Add a new side data entry to a set from an existing AVBufferRef. >> + * >> + * @param sd pointer to array of side data to which to add another entry. >> + * @param nb_sd pointer to an integer containing the number of entries in >> + * the array. >> + * @param type type of the added side data >> + * @param buf AVBufferRef for which a new reference will be made > > This seems inconsistent with av_frame_new_side_data_from_buf(), which > takes ownership of the buffer reference passed to it. > Is there a strong reason to do it differently here? I asked for it. Taking ownership of the AVBufferRef and then expecting the caller to discard the pointer to it is awkward, and unlike any other function using AVBufferRef we have in the tree. The alternative, to keep the behavior of taking ownership of the passed on reference, is to have this function take a pointer to pointer, and clearing it on success.
Quoting James Almer (2024-03-01 21:42:28) > On 3/1/2024 3:19 PM, Anton Khirnov wrote: > > Quoting Jan Ekström (2024-02-29 17:42:54) > >> diff --git a/libavutil/frame.h b/libavutil/frame.h > >> index 47d0096bc4..908fd4a90d 100644 > >> --- a/libavutil/frame.h > >> +++ b/libavutil/frame.h > >> @@ -1081,6 +1081,26 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd, > >> enum AVFrameSideDataType type, > >> size_t size, unsigned int flags); > >> > >> +/** > >> + * Add a new side data entry to a set from an existing AVBufferRef. > >> + * > >> + * @param sd pointer to array of side data to which to add another entry. > >> + * @param nb_sd pointer to an integer containing the number of entries in > >> + * the array. > >> + * @param type type of the added side data > >> + * @param buf AVBufferRef for which a new reference will be made > > > > This seems inconsistent with av_frame_new_side_data_from_buf(), which > > takes ownership of the buffer reference passed to it. > > Is there a strong reason to do it differently here? > > I asked for it. Taking ownership of the AVBufferRef and then expecting > the caller to discard the pointer to it is awkward, and unlike any other > function using AVBufferRef we have in the tree. > > The alternative, to keep the behavior of taking ownership of the passed > on reference, is to have this function take a pointer to pointer, and > clearing it on success. That seems preferable to me, in most cases the caller does not want to keep a reference.
diff --git a/libavutil/frame.c b/libavutil/frame.c index 99c9ce4119..3a2084d1ca 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -889,36 +889,55 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd, return ret; } -int av_frame_side_data_from_sd(AVFrameSideData ***sd, int *nb_sd, - const AVFrameSideData *src, - unsigned int flags) +AVFrameSideData *av_frame_side_data_from_buf(AVFrameSideData ***sd, int *nb_sd, + enum AVFrameSideDataType type, + const AVBufferRef *buf, + unsigned int flags) { - if (!sd || !src || !nb_sd || (*nb_sd && !*sd)) - return AVERROR(EINVAL); + if (!sd || !buf || !nb_sd || (*nb_sd && !*sd)) + return NULL; + + if (flags & AV_FRAME_SIDE_DATA_SET_FLAG_NO_DUPLICATES) + remove_side_data(sd, nb_sd, type); { - AVBufferRef *buf = av_buffer_ref(src->buf); - AVFrameSideData *sd_dst = NULL; + AVBufferRef *new_buf = av_buffer_ref(buf); + AVFrameSideData *sd_dst = NULL; if (flags & AV_FRAME_SIDE_DATA_SET_FLAG_NO_DUPLICATES) - remove_side_data(sd, nb_sd, src->type); + remove_side_data(sd, nb_sd, type); - sd_dst = add_side_data_to_set_from_buf(sd, nb_sd, src->type, buf); + sd_dst = add_side_data_to_set_from_buf(sd, nb_sd, type, new_buf); if (!sd_dst) { - av_buffer_unref(&buf); - return AVERROR(ENOMEM); + av_buffer_unref(&new_buf); + return NULL; } - { - int ret = av_dict_copy(&sd_dst->metadata, src->metadata, 0); - if (ret < 0) { - remove_side_data_by_entry(sd, nb_sd, sd_dst); - return ret; - } - } + return sd_dst; + } +} - return 0; +int av_frame_side_data_from_sd(AVFrameSideData ***sd, int *nb_sd, + const AVFrameSideData *src, + unsigned int flags) +{ + AVFrameSideData *sd_dst = NULL; + int ret = AVERROR_BUG; + if (!src) + return AVERROR(EINVAL); + + sd_dst = + av_frame_side_data_from_buf(sd, nb_sd, src->type, src->buf, flags); + if (!sd_dst) + return AVERROR(ENOMEM); + + ret = av_dict_copy(&sd_dst->metadata, src->metadata, 0); + if (ret < 0) { + remove_side_data_by_entry(sd, nb_sd, sd_dst); + return ret; } + + return 0; } AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, diff --git a/libavutil/frame.h b/libavutil/frame.h index 47d0096bc4..908fd4a90d 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -1081,6 +1081,26 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd, enum AVFrameSideDataType type, size_t size, unsigned int flags); +/** + * Add a new side data entry to a set from an existing AVBufferRef. + * + * @param sd pointer to array of side data to which to add another entry. + * @param nb_sd pointer to an integer containing the number of entries in + * the array. + * @param type type of the added side data + * @param buf AVBufferRef for which a new reference will be made + * @param flags Some combination of AV_FRAME_SIDE_DATA_SET_FLAG_* flags, or 0. + * + * @return newly added side data on success, NULL on error. In case of + * AV_FRAME_SIDE_DATA_SET_FLAG_NO_DUPLICATES being set, entries + * of matching AVFrameSideDataType will be removed before the + * addition is attempted. + */ +AVFrameSideData *av_frame_side_data_from_buf(AVFrameSideData ***sd, int *nb_sd, + enum AVFrameSideDataType type, + const AVBufferRef *buf, + unsigned int flags); + /** * Add a new side data entry to a set based on existing side data, taking * a reference towards the contained AVBufferRef.