diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-02-24 09:37:14 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-02-24 09:38:32 +0100 |
commit | fff526230148b3a67c04c328eecb16efac654e68 (patch) | |
tree | 90dd02d5a13abc983cb8a6ac465ab5340b421f13 /libavutil | |
parent | cc6cc84bc4e009b08ae2f4c2206920e2963adc52 (diff) | |
parent | 1155fd02ae7bac215acab316e847c6bb25f74fc3 (diff) | |
download | ffmpeg-fff526230148b3a67c04c328eecb16efac654e68.tar.gz |
Merge commit '1155fd02ae7bac215acab316e847c6bb25f74fc3'
* commit '1155fd02ae7bac215acab316e847c6bb25f74fc3':
frame: add a convenience function for copying AVFrame data
Conflicts:
doc/APIchanges
libavutil/frame.c
libavutil/version.h
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavutil')
-rw-r--r-- | libavutil/frame.c | 85 | ||||
-rw-r--r-- | libavutil/frame.h | 13 | ||||
-rw-r--r-- | libavutil/version.h | 2 |
3 files changed, 81 insertions, 19 deletions
diff --git a/libavutil/frame.c b/libavutil/frame.c index 75a1c28347..9b4ecfcc0f 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -271,16 +271,11 @@ int av_frame_ref(AVFrame *dst, const AVFrame *src) if (ret < 0) return ret; - if (src->nb_samples) { - int ch = src->channels; - CHECK_CHANNELS_CONSISTENCY(src); - 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 */ @@ -424,14 +419,10 @@ int av_frame_make_writable(AVFrame *frame) if (ret < 0) return ret; - if (tmp.nb_samples) { - int ch = tmp.channels; - CHECK_CHANNELS_CONSISTENCY(&tmp); - 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); @@ -592,3 +583,61 @@ 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 = dst->channels; + int planes = planar ? channels : 1; + int i; + + if (dst->nb_samples != src->nb_samples || + dst->channel_layout != src->channel_layout) + return AVERROR(EINVAL); + + CHECK_CHANNELS_CONSISTENCY(src); + + 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); +} diff --git a/libavutil/frame.h b/libavutil/frame.h index b423f67996..0cb5fb72ae 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -674,6 +674,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. * * Metadata for the purpose of this function are those fields that do not affect diff --git a/libavutil/version.h b/libavutil/version.h index e3b822c01f..7f093cd583 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -56,7 +56,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 52 -#define LIBAVUTIL_VERSION_MINOR 65 +#define LIBAVUTIL_VERSION_MINOR 66 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ |