+
+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);
+}
+
+void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type)
+{
+ int i;
+
+ for (i = 0; i < frame->nb_side_data; i++) {
+ AVFrameSideData *sd = frame->side_data[i];
+ if (sd->type == type) {
+ free_side_data(&frame->side_data[i]);
+ frame->side_data[i] = frame->side_data[frame->nb_side_data - 1];
+ frame->nb_side_data--;
+ }
+ }
+}