Browse Source

frame: add a convenience function for copying AVFrame data

tags/n2.2-rc1
Anton Khirnov 11 years ago
parent
commit
1155fd02ae
4 changed files with 82 additions and 17 deletions
  1. +3
    -0
      doc/APIchanges
  2. +65
    -16
      libavutil/frame.c
  3. +13
    -0
      libavutil/frame.h
  4. +1
    -1
      libavutil/version.h

+ 3
- 0
doc/APIchanges View File

@@ -13,6 +13,9 @@ libavutil: 2013-12-xx

API changes, most recent first:

2014-xx-xx - xxxxxxx - lavu 53.05.0 - frame.h
Add av_frame_copy() for copying the frame data.

2014-02-xx - xxxxxxx - lavr 1.2.0 - avresample.h
Add avresample_is_open() for checking whether a resample context is open.



+ 65
- 16
libavutil/frame.c View File

@@ -191,15 +191,11 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src)
if (ret < 0)
return ret;

if (src->nb_samples) {
int ch = av_get_channel_layout_nb_channels(src->channel_layout);
av_samples_copy(dst->extended_data, src->extended_data, 0, 0,
dst->nb_samples, ch, dst->format);
} else {
av_image_copy(dst->data, dst->linesize, src->data, src->linesize,
dst->format, dst->width, dst->height);
}
return 0;
ret = av_frame_copy(dst, src);
if (ret < 0)
av_frame_unref(dst);

return ret;
}

/* ref the buffers */
@@ -335,13 +331,10 @@ int av_frame_make_writable(AVFrame *frame)
if (ret < 0)
return ret;

if (tmp.nb_samples) {
int ch = av_get_channel_layout_nb_channels(tmp.channel_layout);
av_samples_copy(tmp.extended_data, frame->extended_data, 0, 0,
frame->nb_samples, ch, frame->format);
} else {
av_image_copy(tmp.data, tmp.linesize, frame->data, frame->linesize,
frame->format, frame->width, frame->height);
ret = av_frame_copy(&tmp, frame);
if (ret < 0) {
av_frame_unref(&tmp);
return ret;
}

ret = av_frame_copy_props(&tmp, frame);
@@ -477,3 +470,59 @@ AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
}
return NULL;
}

static int frame_copy_video(AVFrame *dst, const AVFrame *src)
{
const uint8_t *src_data[4];
int i, planes;

if (dst->width != src->width ||
dst->height != src->height)
return AVERROR(EINVAL);

planes = av_pix_fmt_count_planes(dst->format);
for (i = 0; i < planes; i++)
if (!dst->data[i] || !src->data[i])
return AVERROR(EINVAL);

memcpy(src_data, src->data, sizeof(src_data));
av_image_copy(dst->data, dst->linesize,
src_data, src->linesize,
dst->format, dst->width, dst->height);

return 0;
}

static int frame_copy_audio(AVFrame *dst, const AVFrame *src)
{
int planar = av_sample_fmt_is_planar(dst->format);
int channels = av_get_channel_layout_nb_channels(dst->channel_layout);
int planes = planar ? channels : 1;
int i;

if (dst->nb_samples != src->nb_samples ||
dst->channel_layout != src->channel_layout)
return AVERROR(EINVAL);

for (i = 0; i < planes; i++)
if (!dst->extended_data[i] || !src->extended_data[i])
return AVERROR(EINVAL);

av_samples_copy(dst->extended_data, src->extended_data, 0, 0,
dst->nb_samples, channels, dst->format);

return 0;
}

int av_frame_copy(AVFrame *dst, const AVFrame *src)
{
if (dst->format != src->format || dst->format < 0)
return AVERROR(EINVAL);

if (dst->width > 0 && dst->height > 0)
return frame_copy_video(dst, src);
else if (dst->nb_samples > 0 && dst->channel_layout)
return frame_copy_audio(dst, src);

return AVERROR(EINVAL);
}

+ 13
- 0
libavutil/frame.h View File

@@ -505,6 +505,19 @@ int av_frame_is_writable(AVFrame *frame);
*/
int av_frame_make_writable(AVFrame *frame);

/**
* Copy the frame data from src to dst.
*
* This function does not allocate anything, dst must be already initialized and
* allocated with the same parameters as src.
*
* This function only copies the frame data (i.e. the contents of the data /
* extended data arrays), not any other properties.
*
* @return >= 0 on success, a negative AVERROR on error.
*/
int av_frame_copy(AVFrame *dst, const AVFrame *src);

/**
* Copy only "metadata" fields from src to dst.
*


+ 1
- 1
libavutil/version.h View File

@@ -54,7 +54,7 @@
*/

#define LIBAVUTIL_VERSION_MAJOR 53
#define LIBAVUTIL_VERSION_MINOR 4
#define LIBAVUTIL_VERSION_MINOR 5
#define LIBAVUTIL_VERSION_MICRO 0

#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \


Loading…
Cancel
Save