avfilter: use ff_inlink_make_frame_writable()

This commit is contained in:
Paul B Mahol
2023-02-06 14:57:50 +01:00
parent 78f46065d8
commit e506ea3ce1
20 changed files with 152 additions and 48 deletions

View File

@@ -20,6 +20,7 @@
#include "libavutil/imgutils.h"
#include "avfilter.h"
#include "filters.h"
#include "internal.h"
typedef struct RepeatFieldsContext {
@@ -75,23 +76,23 @@ static void update_pts(AVFilterLink *link, AVFrame *f, int64_t pts, int fields)
f->pts = AV_NOPTS_VALUE;
}
static int filter_frame(AVFilterLink *inlink, AVFrame *in) {
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = inlink->dst->outputs[0];
RepeatFieldsContext *s = ctx->priv;
AVFrame *out;
int ret, i;
int state = s->state;
if (!s->frame) {
s->frame = av_frame_clone(in);
if (!s->frame)
if (!s->frame) {
av_frame_free(&in);
return AVERROR(ENOMEM);
}
s->frame->pts = AV_NOPTS_VALUE;
}
out = s->frame;
if ((state == 0 && !in->top_field_first) ||
(state == 1 && in->top_field_first)) {
av_log(ctx, AV_LOG_WARNING, "Unexpected field flags: "
@@ -104,16 +105,22 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) {
AVFrame *new;
new = av_frame_clone(in);
if (!new)
if (!new) {
av_frame_free(&in);
return AVERROR(ENOMEM);
}
ret = ff_filter_frame(outlink, new);
if (in->repeat_pict) {
av_frame_make_writable(out);
update_pts(outlink, out, in->pts, 2);
ret = ff_inlink_make_frame_writable(inlink, &s->frame);
if (ret < 0) {
av_frame_free(&in);
return ret;
}
update_pts(outlink, s->frame, in->pts, 2);
for (i = 0; i < s->nb_planes; i++) {
av_image_copy_plane(out->data[i], out->linesize[i] * 2,
av_image_copy_plane(s->frame->data[i], s->frame->linesize[i] * 2,
in->data[i], in->linesize[i] * 2,
s->linesize[i], s->planeheight[i] / 2);
}
@@ -121,28 +128,38 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) {
}
} else {
for (i = 0; i < s->nb_planes; i++) {
av_frame_make_writable(out);
av_image_copy_plane(out->data[i] + out->linesize[i], out->linesize[i] * 2,
ret = ff_inlink_make_frame_writable(inlink, &s->frame);
if (ret < 0) {
av_frame_free(&in);
return ret;
}
av_image_copy_plane(s->frame->data[i] + s->frame->linesize[i], s->frame->linesize[i] * 2,
in->data[i] + in->linesize[i], in->linesize[i] * 2,
s->linesize[i], s->planeheight[i] / 2);
}
ret = ff_filter_frame(outlink, av_frame_clone(out));
ret = ff_filter_frame(outlink, av_frame_clone(s->frame));
if (in->repeat_pict) {
AVFrame *new;
new = av_frame_clone(in);
if (!new)
if (!new) {
av_frame_free(&in);
return AVERROR(ENOMEM);
}
ret = ff_filter_frame(outlink, new);
state = 0;
} else {
av_frame_make_writable(out);
update_pts(outlink, out, in->pts, 1);
ret = ff_inlink_make_frame_writable(inlink, &s->frame);
if (ret < 0) {
av_frame_free(&in);
return ret;
}
update_pts(outlink, s->frame, in->pts, 1);
for (i = 0; i < s->nb_planes; i++) {
av_image_copy_plane(out->data[i], out->linesize[i] * 2,
av_image_copy_plane(s->frame->data[i], s->frame->linesize[i] * 2,
in->data[i], in->linesize[i] * 2,
s->linesize[i], s->planeheight[i] / 2);
}