X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fvf_fieldhint.c;h=a6c0237f02815ec60f85f9cd4d6728276810f7cb;hb=a04ad248a05e7b613abe09b3bb067f555108d794;hp=3cfeb20a382ca5caec40ad221c8dfd8e757bf979;hpb=fbd607dd560afe44c3b90de1e6cbe5265cac8f1e;p=ffmpeg diff --git a/libavfilter/vf_fieldhint.c b/libavfilter/vf_fieldhint.c index 3cfeb20a382..a6c0237f028 100644 --- a/libavfilter/vf_fieldhint.c +++ b/libavfilter/vf_fieldhint.c @@ -65,7 +65,7 @@ static av_cold int init(AVFilterContext *ctx) av_log(ctx, AV_LOG_ERROR, "Hint file must be set.\n"); return AVERROR(EINVAL); } - s->hint = fopen(s->hint_file_str, "r"); + s->hint = av_fopen_utf8(s->hint_file_str, "r"); if (!s->hint) { ret = AVERROR(errno); av_log(ctx, AV_LOG_ERROR, "%s: %s\n", s->hint_file_str, av_err2str(ret)); @@ -77,19 +77,16 @@ static av_cold int init(AVFilterContext *ctx) static int query_formats(AVFilterContext *ctx) { - AVFilterFormats *pix_fmts = NULL; - int fmt, ret; - - for (fmt = 0; av_pix_fmt_desc_get(fmt); fmt++) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); - if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL || - desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_BITSTREAM) && - (ret = ff_add_format(&pix_fmts, fmt)) < 0) - return ret; - } + AVFilterFormats *formats = NULL; + int ret; - return ff_set_common_formats(ctx, pix_fmts); + ret = ff_formats_pixdesc_filter(&formats, 0, + AV_PIX_FMT_FLAG_HWACCEL | + AV_PIX_FMT_FLAG_BITSTREAM | + AV_PIX_FMT_FLAG_PAL); + if (ret < 0) + return ret; + return ff_set_common_formats(ctx, formats); } static int config_input(AVFilterLink *inlink) @@ -117,7 +114,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) AVFrame *out, *top, *bottom; char buf[1024] = { 0 }; int64_t tf, bf; - char hint = '='; + int tfactor = 0, bfactor = 1; + char hint = '=', field = '='; int p; av_frame_free(&s->frame[0]); @@ -137,6 +135,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) s->line++; if (buf[0] == '#' || buf[0] == ';') { continue; + } else if (sscanf(buf, "%"PRId64",%"PRId64" %c %c", &tf, &bf, &hint, &field) == 4) { + ; } else if (sscanf(buf, "%"PRId64",%"PRId64" %c", &tf, &bf, &hint) == 3) { ; } else if (sscanf(buf, "%"PRId64",%"PRId64"", &tf, &bf) == 2) { @@ -185,6 +185,23 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) av_assert0(0); } + switch (field) { + case 'b': + tfactor = 1; + top = bottom; + break; + case 't': + bfactor = 0; + bottom = top; + break; + case '=': + break; + default: + av_log(ctx, AV_LOG_ERROR, "Invalid field: %c.\n", field); + av_frame_free(&out); + return AVERROR(EINVAL); + } + switch (hint) { case '+': out->interlaced_frame = 1; @@ -194,6 +211,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) break; case '=': break; + case 'b': + tfactor = 1; + top = bottom; + break; + case 't': + bfactor = 0; + bottom = top; + break; default: av_log(ctx, AV_LOG_ERROR, "Invalid hint: %c.\n", hint); av_frame_free(&out); @@ -203,13 +228,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) for (p = 0; p < s->nb_planes; p++) { av_image_copy_plane(out->data[p], out->linesize[p] * 2, - top->data[p], + top->data[p] + tfactor * top->linesize[p], top->linesize[p] * 2, s->planewidth[p], (s->planeheight[p] + 1) / 2); av_image_copy_plane(out->data[p] + out->linesize[p], out->linesize[p] * 2, - bottom->data[p] + bottom->linesize[p], + bottom->data[p] + bfactor * bottom->linesize[p], bottom->linesize[p] * 2, s->planewidth[p], (s->planeheight[p] + 1) / 2); @@ -271,7 +296,7 @@ static const AVFilterPad outputs[] = { { NULL } }; -AVFilter ff_vf_fieldhint = { +const AVFilter ff_vf_fieldhint = { .name = "fieldhint", .description = NULL_IF_CONFIG_SMALL("Field matching using hints."), .priv_size = sizeof(FieldHintContext),