Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@overt.org>2018-10-24 21:52:42 +0300
committerPhilip Langdale <philipl@overt.org>2018-11-02 21:24:05 +0300
commit598f0f39271d6033588b4d8ccc672c5bdc85fec7 (patch)
tree4450a872e639537fab7432d7f4d7c73c3da58ed1 /libavfilter/vf_yadif.c
parentef1aadffc785b48ed62c45d954289e754f43ef46 (diff)
libavfilter/vf_yadif: Make frame management logic and options shareable
I'm writing a cuda implementation of yadif, and while this obviously has a very different implementation of the actual filtering, all the frame management is unchanged. To avoid duplicating that logic, let's make it shareable. From the perspective of the existing filter, the only real change is introducing a function pointer for the filter() function so it can be specified for the specific filter.
Diffstat (limited to 'libavfilter/vf_yadif.c')
-rw-r--r--libavfilter/vf_yadif.c196
1 files changed, 9 insertions, 187 deletions
diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c
index f58d8ac2bc..3107924932 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;
@@ -492,6 +331,7 @@ static int config_props(AVFilterLink *link)
}
s->csp = av_pix_fmt_desc_get(link->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 +347,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,7 +368,7 @@ static const AVFilterPad avfilter_vf_yadif_outputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
- .request_frame = request_frame,
+ .request_frame = ff_yadif_request_frame,
.config_props = config_props,
},
{ NULL }