X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fvf_yadif.c;h=a6942a2aa2d1d4b2e861ffed9495d4639e3b1c31;hb=a04ad248a05e7b613abe09b3bb067f555108d794;hp=f58d8ac2bce32e200ad12d0c4571c1f8146ab7cb;hpb=9a88a47be4da9cd25a582feec7cc36790500b481;p=ffmpeg diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index f58d8ac2bce..a6942a2aa2d 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -22,7 +22,6 @@ #include "libavutil/avassert.h" #include "libavutil/cpu.h" #include "libavutil/common.h" -#include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "libavutil/imgutils.h" #include "avfilter.h" @@ -254,166 +253,6 @@ static void filter(AVFilterContext *ctx, AVFrame *dstpic, emms_c(); } -static int return_frame(AVFilterContext *ctx, int is_second) -{ - YADIFContext *yadif = ctx->priv; - AVFilterLink *link = ctx->outputs[0]; - int tff, ret; - - if (yadif->parity == -1) { - tff = yadif->cur->interlaced_frame ? - yadif->cur->top_field_first : 1; - } else { - tff = yadif->parity ^ 1; - } - - if (is_second) { - yadif->out = ff_get_video_buffer(link, link->w, link->h); - if (!yadif->out) - return AVERROR(ENOMEM); - - av_frame_copy_props(yadif->out, yadif->cur); - yadif->out->interlaced_frame = 0; - } - - filter(ctx, yadif->out, tff ^ !is_second, tff); - - if (is_second) { - int64_t cur_pts = yadif->cur->pts; - int64_t next_pts = yadif->next->pts; - - if (next_pts != AV_NOPTS_VALUE && cur_pts != AV_NOPTS_VALUE) { - yadif->out->pts = cur_pts + next_pts; - } else { - yadif->out->pts = AV_NOPTS_VALUE; - } - } - ret = ff_filter_frame(ctx->outputs[0], yadif->out); - - yadif->frame_pending = (yadif->mode&1) && !is_second; - return ret; -} - -static int checkstride(YADIFContext *yadif, const AVFrame *a, const AVFrame *b) -{ - int i; - for (i = 0; i < yadif->csp->nb_components; i++) - if (a->linesize[i] != b->linesize[i]) - return 1; - return 0; -} - -static void fixstride(AVFilterLink *link, AVFrame *f) -{ - AVFrame *dst = ff_default_get_video_buffer(link, f->width, f->height); - if(!dst) - return; - av_frame_copy_props(dst, f); - av_image_copy(dst->data, dst->linesize, - (const uint8_t **)f->data, f->linesize, - dst->format, dst->width, dst->height); - av_frame_unref(f); - av_frame_move_ref(f, dst); - av_frame_free(&dst); -} - -static int filter_frame(AVFilterLink *link, AVFrame *frame) -{ - AVFilterContext *ctx = link->dst; - YADIFContext *yadif = ctx->priv; - - av_assert0(frame); - - if (yadif->frame_pending) - return_frame(ctx, 1); - - if (yadif->prev) - av_frame_free(&yadif->prev); - yadif->prev = yadif->cur; - yadif->cur = yadif->next; - yadif->next = frame; - - if (!yadif->cur && - !(yadif->cur = av_frame_clone(yadif->next))) - return AVERROR(ENOMEM); - - if (checkstride(yadif, yadif->next, yadif->cur)) { - av_log(ctx, AV_LOG_VERBOSE, "Reallocating frame due to differing stride\n"); - fixstride(link, yadif->next); - } - if (checkstride(yadif, yadif->next, yadif->cur)) - fixstride(link, yadif->cur); - if (yadif->prev && checkstride(yadif, yadif->next, yadif->prev)) - fixstride(link, yadif->prev); - if (checkstride(yadif, yadif->next, yadif->cur) || (yadif->prev && checkstride(yadif, yadif->next, yadif->prev))) { - av_log(ctx, AV_LOG_ERROR, "Failed to reallocate frame\n"); - return -1; - } - - if (!yadif->prev) - return 0; - - if ((yadif->deint && !yadif->cur->interlaced_frame) || - ctx->is_disabled || - (yadif->deint && !yadif->prev->interlaced_frame && yadif->prev->repeat_pict) || - (yadif->deint && !yadif->next->interlaced_frame && yadif->next->repeat_pict) - ) { - yadif->out = av_frame_clone(yadif->cur); - if (!yadif->out) - return AVERROR(ENOMEM); - - av_frame_free(&yadif->prev); - if (yadif->out->pts != AV_NOPTS_VALUE) - yadif->out->pts *= 2; - return ff_filter_frame(ctx->outputs[0], yadif->out); - } - - yadif->out = ff_get_video_buffer(ctx->outputs[0], link->w, link->h); - if (!yadif->out) - return AVERROR(ENOMEM); - - av_frame_copy_props(yadif->out, yadif->cur); - yadif->out->interlaced_frame = 0; - - if (yadif->out->pts != AV_NOPTS_VALUE) - yadif->out->pts *= 2; - - return return_frame(ctx, 0); -} - -static int request_frame(AVFilterLink *link) -{ - AVFilterContext *ctx = link->src; - YADIFContext *yadif = ctx->priv; - int ret; - - if (yadif->frame_pending) { - return_frame(ctx, 1); - return 0; - } - - if (yadif->eof) - return AVERROR_EOF; - - ret = ff_request_frame(ctx->inputs[0]); - - if (ret == AVERROR_EOF && yadif->cur) { - AVFrame *next = av_frame_clone(yadif->next); - - if (!next) - return AVERROR(ENOMEM); - - next->pts = yadif->next->pts * 2 - yadif->cur->pts; - - filter_frame(ctx->inputs[0], next); - yadif->eof = 1; - } else if (ret < 0) { - return ret; - } - - return 0; -} - static av_cold void uninit(AVFilterContext *ctx) { YADIFContext *yadif = ctx->priv; @@ -426,42 +265,19 @@ static av_cold void uninit(AVFilterContext *ctx) static int query_formats(AVFilterContext *ctx) { static const enum AVPixelFormat pix_fmts[] = { - AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV422P, - AV_PIX_FMT_YUV444P, - AV_PIX_FMT_YUV410P, - AV_PIX_FMT_YUV411P, - AV_PIX_FMT_GRAY8, - AV_PIX_FMT_YUVJ420P, - AV_PIX_FMT_YUVJ422P, - AV_PIX_FMT_YUVJ444P, - AV_PIX_FMT_GRAY16, - AV_PIX_FMT_YUV440P, + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV440P, + AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16, + AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P, - AV_PIX_FMT_YUV420P9, - AV_PIX_FMT_YUV422P9, - AV_PIX_FMT_YUV444P9, - AV_PIX_FMT_YUV420P10, - AV_PIX_FMT_YUV422P10, - AV_PIX_FMT_YUV444P10, - AV_PIX_FMT_YUV420P12, - AV_PIX_FMT_YUV422P12, - AV_PIX_FMT_YUV444P12, - AV_PIX_FMT_YUV420P14, - AV_PIX_FMT_YUV422P14, - AV_PIX_FMT_YUV444P14, - AV_PIX_FMT_YUV420P16, - AV_PIX_FMT_YUV422P16, - AV_PIX_FMT_YUV444P16, - AV_PIX_FMT_YUVA420P, - AV_PIX_FMT_YUVA422P, - AV_PIX_FMT_YUVA444P, - AV_PIX_FMT_GBRP, - AV_PIX_FMT_GBRP9, - AV_PIX_FMT_GBRP10, - AV_PIX_FMT_GBRP12, - AV_PIX_FMT_GBRP14, - AV_PIX_FMT_GBRP16, + AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9, + AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, + AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12, + AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14, + AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, + AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P, + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10, + AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14, AV_PIX_FMT_GBRP16, AV_PIX_FMT_GBRAP, AV_PIX_FMT_NONE }; @@ -472,26 +288,27 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, fmts_list); } -static int config_props(AVFilterLink *link) +static int config_output(AVFilterLink *outlink) { - AVFilterContext *ctx = link->src; + AVFilterContext *ctx = outlink->src; YADIFContext *s = ctx->priv; - link->time_base.num = ctx->inputs[0]->time_base.num; - link->time_base.den = ctx->inputs[0]->time_base.den * 2; - link->w = ctx->inputs[0]->w; - link->h = ctx->inputs[0]->h; + outlink->time_base.num = ctx->inputs[0]->time_base.num; + outlink->time_base.den = ctx->inputs[0]->time_base.den * 2; + outlink->w = ctx->inputs[0]->w; + outlink->h = ctx->inputs[0]->h; if(s->mode & 1) - link->frame_rate = av_mul_q(ctx->inputs[0]->frame_rate, + outlink->frame_rate = av_mul_q(ctx->inputs[0]->frame_rate, (AVRational){2, 1}); - if (link->w < 3 || link->h < 3) { + if (outlink->w < 3 || outlink->h < 3) { av_log(ctx, AV_LOG_ERROR, "Video of less than 3 columns or lines is not supported\n"); return AVERROR(EINVAL); } - s->csp = av_pix_fmt_desc_get(link->format); + s->csp = av_pix_fmt_desc_get(outlink->format); + s->filter = filter; if (s->csp->comp[0].depth > 8) { s->filter_line = filter_line_c_16bit; s->filter_edges = filter_edges_16bit; @@ -507,37 +324,19 @@ static int config_props(AVFilterLink *link) } -#define OFFSET(x) offsetof(YADIFContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM - -#define CONST(name, help, val, unit) { name, help, 0, AV_OPT_TYPE_CONST, {.i64=val}, INT_MIN, INT_MAX, FLAGS, unit } - -static const AVOption yadif_options[] = { - { "mode", "specify the interlacing mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=YADIF_MODE_SEND_FRAME}, 0, 3, FLAGS, "mode"}, - CONST("send_frame", "send one frame for each frame", YADIF_MODE_SEND_FRAME, "mode"), - CONST("send_field", "send one frame for each field", YADIF_MODE_SEND_FIELD, "mode"), - CONST("send_frame_nospatial", "send one frame for each frame, but skip spatial interlacing check", YADIF_MODE_SEND_FRAME_NOSPATIAL, "mode"), - CONST("send_field_nospatial", "send one frame for each field, but skip spatial interlacing check", YADIF_MODE_SEND_FIELD_NOSPATIAL, "mode"), - - { "parity", "specify the assumed picture field parity", OFFSET(parity), AV_OPT_TYPE_INT, {.i64=YADIF_PARITY_AUTO}, -1, 1, FLAGS, "parity" }, - CONST("tff", "assume top field first", YADIF_PARITY_TFF, "parity"), - CONST("bff", "assume bottom field first", YADIF_PARITY_BFF, "parity"), - CONST("auto", "auto detect parity", YADIF_PARITY_AUTO, "parity"), - - { "deint", "specify which frames to deinterlace", OFFSET(deint), AV_OPT_TYPE_INT, {.i64=YADIF_DEINT_ALL}, 0, 1, FLAGS, "deint" }, - CONST("all", "deinterlace all frames", YADIF_DEINT_ALL, "deint"), - CONST("interlaced", "only deinterlace frames marked as interlaced", YADIF_DEINT_INTERLACED, "deint"), - - { NULL } +static const AVClass yadif_class = { + .class_name = "yadif", + .item_name = av_default_item_name, + .option = ff_yadif_options, + .version = LIBAVUTIL_VERSION_INT, + .category = AV_CLASS_CATEGORY_FILTER, }; -AVFILTER_DEFINE_CLASS(yadif); - static const AVFilterPad avfilter_vf_yadif_inputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .filter_frame = filter_frame, + .filter_frame = ff_yadif_filter_frame, }, { NULL } }; @@ -546,13 +345,13 @@ static const AVFilterPad avfilter_vf_yadif_outputs[] = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .config_props = config_props, + .request_frame = ff_yadif_request_frame, + .config_props = config_output, }, { NULL } }; -AVFilter ff_vf_yadif = { +const AVFilter ff_vf_yadif = { .name = "yadif", .description = NULL_IF_CONFIG_SMALL("Deinterlace the input image."), .priv_size = sizeof(YADIFContext),