#include "libavutil/imgutils.h"
#include "avfilter.h"
+#include "filters.h"
#include "internal.h"
+#include "video.h"
typedef struct RepeatFieldsContext {
const AVClass *class;
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)) {
+ if ((state == 0 && !(in->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST)) ||
+ (state == 1 && (in->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST))) {
av_log(ctx, AV_LOG_WARNING, "Unexpected field flags: "
"state=%d top_field_first=%d repeat_first_field=%d\n",
- state, in->top_field_first, in->repeat_pict);
+ state, !!(in->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST),
+ in->repeat_pict);
state ^= 1;
}
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);
}
}
} 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);
}
},
};
-static const AVFilterPad repeatfields_outputs[] = {
- {
- .name = "default",
- .type = AVMEDIA_TYPE_VIDEO,
- },
-};
-
const AVFilter ff_vf_repeatfields = {
.name = "repeatfields",
.description = NULL_IF_CONFIG_SMALL("Hard repeat fields based on MPEG repeat field flag."),
.priv_size = sizeof(RepeatFieldsContext),
.uninit = uninit,
FILTER_INPUTS(repeatfields_inputs),
- FILTER_OUTPUTS(repeatfields_outputs),
+ FILTER_OUTPUTS(ff_video_default_filterpad),
FILTER_PIXFMTS_ARRAY(pixel_fmts_eq),
};