]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/vf_fieldhint.c
avfilter/vf_scale: store the offset in a local variable before adding it
[ffmpeg] / libavfilter / vf_fieldhint.c
index 3cfeb20a382ca5caec40ad221c8dfd8e757bf979..a6c0237f02815ec60f85f9cd4d6728276810f7cb 100644 (file)
@@ -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),