aboutsummaryrefslogtreecommitdiffstats
path: root/libavutil
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2014-02-24 09:37:14 +0100
committerMichael Niedermayer <michaelni@gmx.at>2014-02-24 09:38:32 +0100
commitfff526230148b3a67c04c328eecb16efac654e68 (patch)
tree90dd02d5a13abc983cb8a6ac465ab5340b421f13 /libavutil
parentcc6cc84bc4e009b08ae2f4c2206920e2963adc52 (diff)
parent1155fd02ae7bac215acab316e847c6bb25f74fc3 (diff)
downloadffmpeg-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.c85
-rw-r--r--libavutil/frame.h13
-rw-r--r--libavutil/version.h2
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, \