filter: fix semantics of deinterlacing flags.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Thu, 21 Nov 2013 17:44:46 +0000 (18:44 +0100)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Thu, 21 Nov 2013 22:08:02 +0000 (23:08 +0100)
Fix deinterlacing flags to make more sense. The TFF (top-field-first)
flag is meant to specify the organization of reference frames used in
advanced deinterlacing modes. Introduce the more explicit flag TOPFIELD
to specify that the top-field of the supplied input surface is to be
used for deinterlacing. Conversely, if not set, this means that the
bottom field of the supplied input surface will be used instead.

gst-libs/gst/vaapi/gstvaapifilter.c
gst-libs/gst/vaapi/gstvaapifilter.h
gst-libs/gst/vaapi/gstvaapiutils.c
gst/vaapi/gstvaapipostproc.c
tests/test-filter.c

index b6e9073..697b8a1 100755 (executable)
@@ -112,6 +112,8 @@ gst_vaapi_deinterlace_flags_get_type(void)
           "Top-field first", "top-field-first" },
         { GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD,
           "One field", "one-field" },
+        { GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD,
+          "Top field", "top-field" },
         { 0, NULL, NULL }
     };
 
index 5d9ec65..85bbe28 100755 (executable)
@@ -109,16 +109,23 @@ typedef enum {
 /**
  * GstVaapiDeinterlaceFlags:
  * @GST_VAAPI_DEINTERLACE_FLAG_TFF: Top-field first. If this flag is
- *   not set, then bottom-field first order is assumed.
+ *   not set, then bottom-field first order is assumed. Note: this
+ *   only affects the way reference frames are organized for advanced
+ *   deinterlacing modes.
  * @GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD: The input frame represents a
  *   single field. If this flag is not set, then the whole frame holds
- *   two fields.
+ *   two interleaved fields.
+ * @GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD: The top field of the input
+ *   frame is to be used for deinterlacing. Otherwise, if this flag is
+ *   not set, then the bottom field of the input frame will be used
+ *   for deinterlacing.
  *
  * The set of gst_vaapi_filter_set_deinterlacing() flags.
  */
 typedef enum {
     GST_VAAPI_DEINTERLACE_FLAG_TFF      = 1 << 31,
     GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD = 1 << 30,
+    GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD = 1 << 29,
 } GstVaapiDeinterlaceFlags;
 
 #define GST_VAAPI_TYPE_DEINTERLACE_METHOD \
index a0b0d0a..9fc4c68 100644 (file)
@@ -471,11 +471,11 @@ from_GstVaapiDeinterlaceFlags(guint flags)
     if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TFF))
         va_flags |= VA_DEINTERLACING_BOTTOM_FIELD_FIRST;
 
-    if (flags & GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD) {
+    if (flags & GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD)
         va_flags |= VA_DEINTERLACING_ONE_FIELD;
-        if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TFF))
-            va_flags |= VA_DEINTERLACING_BOTTOM_FIELD;
-    }
+
+    if (!(flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD))
+        va_flags |= VA_DEINTERLACING_BOTTOM_FIELD;
 #endif
     return va_flags;
 }
index 99b400c..69cfa11 100755 (executable)
@@ -449,7 +449,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf,
 
         if (deint) {
             GstVaapiDeinterlaceMethod deint_method;
-            deint_flags = (tff ? GST_VAAPI_DEINTERLACE_FLAG_TFF : 0);
+            deint_flags = (tff ? GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD : 0);
             if (!set_best_deint_method(postproc, flags, &deint_method))
                 goto error_op_deinterlace;
             if (deint_method != postproc->deinterlace_method) {
@@ -482,7 +482,7 @@ gst_vaapipostproc_process_vpp(GstBaseTransform *trans, GstBuffer *inbuf,
     outbuf_surface = gst_vaapi_video_meta_get_surface(outbuf_meta);
 
     if (deint) {
-        deint_flags = (tff ? 0 : GST_VAAPI_DEINTERLACE_FLAG_TFF);
+        deint_flags = (tff ? 0 : GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD);
         if (!gst_vaapi_filter_set_deinterlacing(postproc->filter,
                 postproc->deinterlace_method, deint_flags))
             goto error_op_deinterlace;
index a96c033..7bb6219 100755 (executable)
@@ -291,7 +291,9 @@ end:
 static inline gboolean
 parse_deinterlace(const gchar *str, GstVaapiDeinterlaceMethod *deinterlace_ptr)
 {
-    return parse_enum(str, GST_VAAPI_TYPE_DEINTERLACE_METHOD,
+    g_return_val_if_fail(deinterlace_ptr != NULL, FALSE);
+
+    return str && parse_enum(str, GST_VAAPI_TYPE_DEINTERLACE_METHOD,
         GST_VAAPI_DEINTERLACE_METHOD_NONE, (gint *)deinterlace_ptr);
 }
 
@@ -390,7 +392,7 @@ main(int argc, char *argv[])
             g_error("failed to set deinterlacing method");
     }
     else if (deinterlace_flags) {
-        if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TFF)
+        if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD)
             filter_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
         else
             filter_flags = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
@@ -401,7 +403,7 @@ main(int argc, char *argv[])
         if (!(deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_ONEFIELD))
             surface_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD |
                 GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
-        else if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TFF)
+        else if (deinterlace_flags & GST_VAAPI_DEINTERLACE_FLAG_TOPFIELD)
             surface_flags = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
         else
             surface_flags = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;