Skip to content

Commit

Permalink
avutil/frame: Add av_frame_copy_side_data() and av_frame_remove_all_s…
Browse files Browse the repository at this point in the history
…ide_data()

Signed-off-by: softworkz <[email protected]>
Signed-off-by: Anton Khirnov <[email protected]>
  • Loading branch information
softworkz committed Oct 24, 2022
1 parent 882a170 commit 28c4b9e
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 28 deletions.
4 changes: 4 additions & 0 deletions doc/APIchanges
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ libavutil: 2021-04-27

API changes, most recent first:

2022-05-26 - xxxxxxxxx - lavu 57.40.100 - frame.h
Add av_frame_remove_all_side_data(), av_frame_copy_side_data(),
AV_FRAME_TRANSFER_SD_COPY, and AV_FRAME_TRANSFER_SD_FILTER.

2022-10-11 - xxxxxxxxxx - lavu 57.39.101 - pixfmt.h
Add AV_PIX_FMT_RGBF32 and AV_PIX_FMT_RGBAF32.

Expand Down
67 changes: 41 additions & 26 deletions libavutil/frame.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,45 @@ FF_ENABLE_DEPRECATION_WARNINGS
return AVERROR(EINVAL);
}

void av_frame_remove_all_side_data(AVFrame *frame)
{
wipe_side_data(frame);
}

int av_frame_copy_side_data(AVFrame* dst, const AVFrame* src, int flags)
{
for (unsigned i = 0; i < src->nb_side_data; i++) {
const AVFrameSideData *sd_src = src->side_data[i];
AVFrameSideData *sd_dst;
if ((flags & AV_FRAME_TRANSFER_SD_FILTER) &&
sd_src->type == AV_FRAME_DATA_PANSCAN &&
(src->width != dst->width || src->height != dst->height))
continue;
if (flags & AV_FRAME_TRANSFER_SD_COPY) {
sd_dst = av_frame_new_side_data(dst, sd_src->type,
sd_src->size);
if (!sd_dst) {
wipe_side_data(dst);
return AVERROR(ENOMEM);
}
memcpy(sd_dst->data, sd_src->data, sd_src->size);
} else {
AVBufferRef *ref = av_buffer_ref(sd_src->buf);
sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref);
if (!sd_dst) {
av_buffer_unref(&ref);
wipe_side_data(dst);
return AVERROR(ENOMEM);
}
}
av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0);
}
return 0;
}

static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy)
{
int ret, i;
int ret;

dst->key_frame = src->key_frame;
dst->pict_type = src->pict_type;
Expand Down Expand Up @@ -319,31 +355,10 @@ FF_ENABLE_DEPRECATION_WARNINGS

av_dict_copy(&dst->metadata, src->metadata, 0);

for (i = 0; i < src->nb_side_data; i++) {
const AVFrameSideData *sd_src = src->side_data[i];
AVFrameSideData *sd_dst;
if ( sd_src->type == AV_FRAME_DATA_PANSCAN
&& (src->width != dst->width || src->height != dst->height))
continue;
if (force_copy) {
sd_dst = av_frame_new_side_data(dst, sd_src->type,
sd_src->size);
if (!sd_dst) {
wipe_side_data(dst);
return AVERROR(ENOMEM);
}
memcpy(sd_dst->data, sd_src->data, sd_src->size);
} else {
AVBufferRef *ref = av_buffer_ref(sd_src->buf);
sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref);
if (!sd_dst) {
av_buffer_unref(&ref);
wipe_side_data(dst);
return AVERROR(ENOMEM);
}
}
av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0);
}
if ((ret = av_frame_copy_side_data(dst, src,
(force_copy ? AV_FRAME_TRANSFER_SD_COPY : 0) |
AV_FRAME_TRANSFER_SD_FILTER) < 0))
return ret;

ret = av_buffer_replace(&dst->opaque_ref, src->opaque_ref);
ret |= av_buffer_replace(&dst->private_ref, src->private_ref);
Expand Down
32 changes: 32 additions & 0 deletions libavutil/frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,30 @@ int av_frame_copy(AVFrame *dst, const AVFrame *src);
*/
int av_frame_copy_props(AVFrame *dst, const AVFrame *src);


/**
* Copy side data, rather than creating new references.
*/
#define AV_FRAME_TRANSFER_SD_COPY (1 << 0)
/**
* Filter out side data that does not match dst properties.
*/
#define AV_FRAME_TRANSFER_SD_FILTER (1 << 1)

/**
* Copy all side-data from src to dst.
*
* @param dst a frame to which the side data should be copied.
* @param src a frame from which to copy the side data.
* @param flags a combination of AV_FRAME_TRANSFER_SD_*
*
* @return 0 on success, a negative AVERROR on error.
*
* @note This function will create new references to side data buffers in src,
* unless the AV_FRAME_TRANSFER_SD_COPY flag is passed.
*/
int av_frame_copy_side_data(AVFrame* dst, const AVFrame* src, int flags);

/**
* Get the buffer reference a given data plane is stored in.
*
Expand Down Expand Up @@ -913,6 +937,14 @@ AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
*/
void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type);

/**
* Remove and free all side data instances.
*
* @param frame from which to remove all side data.
*/
void av_frame_remove_all_side_data(AVFrame *frame);



/**
* Flags for frame cropping.
Expand Down
4 changes: 2 additions & 2 deletions libavutil/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@
*/

#define LIBAVUTIL_VERSION_MAJOR 57
#define LIBAVUTIL_VERSION_MINOR 39
#define LIBAVUTIL_VERSION_MICRO 101
#define LIBAVUTIL_VERSION_MINOR 40
#define LIBAVUTIL_VERSION_MICRO 100

#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
LIBAVUTIL_VERSION_MINOR, \
Expand Down

0 comments on commit 28c4b9e

Please sign in to comment.