documentation: fixed a heap o' typos
[platform/upstream/gstreamer.git] / sys / winks / ksvideohelpers.c
index 69b4311..a5b53c1 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007 Haakon Sporsheim <hakon.sporsheim@tandberg.com>
- *               2008 Ole André Vadla Ravnås <ole.andre.ravnas@tandberg.com>
+ *               2008 Ole André Vadla Ravnås <ole.andre.ravnas@tandberg.com>
  *               2009 Knut Inge Hvidsten <knut.inge.hvidsten@tandberg.com>
  *
  * This library is free software; you can redistribute it and/or
  *
  * You should have received a copy of the GNU Library General Public
  * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
  */
 
 #include "ksvideohelpers.h"
 
+#include <math.h>
 #include <uuids.h>
 #include "kshelpers.h"
 
@@ -32,11 +33,6 @@ static const GUID MEDIASUBTYPE_FOURCC =
     0x38, 0x9B, 0x71}
 };
 
-extern const GUID MEDIASUBTYPE_I420 =
-    { 0x30323449, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B,
-    0x71}
-};
-
 typedef struct _KsVideoDeviceEntry KsVideoDeviceEntry;
 
 struct _KsVideoDeviceEntry
@@ -129,95 +125,56 @@ ks_video_device_list_sort_cameras_first (GList * devices)
 }
 
 static GstStructure *
-ks_video_format_to_structure (GUID subtype_guid, GUID format_guid)
+ks_video_format_to_structure (GUID subtype_guid, GUID format_guid,
+    gboolean * p_is_rgb)
 {
   GstStructure *structure = NULL;
+  const gchar *media_type = NULL, *format = NULL;
+  /* RGB formats can be bottom-up (upside down) DIB */
+  gboolean is_rgb = FALSE;
 
   if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_MJPG) || IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_TVMJ) ||     /* FIXME: NOT tested */
       IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_WAKE) ||        /* FIXME: NOT tested */
       IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_CFCC) ||        /* FIXME: NOT tested */
       IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_IJPG)) {        /* FIXME: NOT tested */
-    structure = gst_structure_new ("image/jpeg", NULL);
-  } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB555) ||       /* FIXME: NOT tested */
-      IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB565) ||      /* FIXME: NOT tested */
-      IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB24) || IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB32) ||   /* FIXME: NOT tested */
-      IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB1555) ||    /* FIXME: NOT tested */
-      IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB32) ||      /* FIXME: NOT tested */
-      IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB4444)) {    /* FIXME: NOT tested */
-    guint depth = 0, bpp = 0;
-    gint endianness = 0;
-    guint32 r_mask = 0, b_mask = 0, g_mask = 0;
-
-    if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB555)) {
-      bpp = 16;
-      depth = 15;
-      endianness = G_BIG_ENDIAN;
-      r_mask = 0x7c00;
-      g_mask = 0x03e0;
-      b_mask = 0x001f;
-    } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB565)) {
-      bpp = depth = 16;
-      endianness = G_BIG_ENDIAN;
-      r_mask = 0xf800;
-      g_mask = 0x07e0;
-      b_mask = 0x001f;
-    } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB24)) {
-      bpp = depth = 24;
-      endianness = G_BIG_ENDIAN;
-      r_mask = 0x0000ff;
-      g_mask = 0x00ff00;
-      b_mask = 0xff0000;
-    } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB32)) {
-      bpp = 32;
-      depth = 24;
-      endianness = G_BIG_ENDIAN;
-      r_mask = 0x000000ff;
-      g_mask = 0x0000ff00;
-      b_mask = 0x00ff0000;
-      /* FIXME: check
-       *r_mask = 0xff000000;
-       *g_mask = 0x00ff0000;
-       *b_mask = 0x0000ff00;
-       */
-    } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB1555)) {
-      bpp = 16;
-      depth = 15;
-      endianness = G_BIG_ENDIAN;
-      r_mask = 0x7c00;
-      g_mask = 0x03e0;
-      b_mask = 0x001f;
-    } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB32)) {
-      bpp = depth = 32;
-      endianness = G_BIG_ENDIAN;
-      r_mask = 0x000000ff;
-      g_mask = 0x0000ff00;
-      b_mask = 0x00ff0000;
-      /* FIXME: check
-       *r_mask = 0xff000000;
-       *g_mask = 0x00ff0000;
-       *b_mask = 0x0000ff00;
-       */
-    } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB4444)) {
-      bpp = 16;
-      depth = 12;
-      endianness = G_BIG_ENDIAN;
-      r_mask = 0x0f00;
-      g_mask = 0x00f0;
-      b_mask = 0x000f;
-      //r_mask = 0x000f;
-      //g_mask = 0x00f0;
-      //b_mask = 0x0f00;
+    media_type = "image/jpeg";
+  } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB555)) {
+    media_type = "video/x-raw";
+    format = "RGB15";
+    is_rgb = TRUE;
+  } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB565)) {
+    media_type = "video/x-raw";
+    format = "RGB16";
+    is_rgb = TRUE;
+  } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB24)) {
+    media_type = "video/x-raw";
+    format = "BGR";
+    is_rgb = TRUE;
+  } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB32)) {
+    media_type = "video/x-raw";
+    format = "BGRx";
+    is_rgb = TRUE;
+  } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB32)) {
+    media_type = "video/x-raw";
+    format = "BGRA";
+    is_rgb = TRUE;
+  } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB1555)) {
+    GST_WARNING ("Unsupported video format ARGB15555");
+  } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB4444)) {
+    GST_WARNING ("Unsupported video format ARGB4444");
+  } else if (memcmp (&subtype_guid.Data2, &MEDIASUBTYPE_FOURCC.Data2,
+          sizeof (subtype_guid) - sizeof (subtype_guid.Data1)) == 0) {
+    guint32 fourcc = subtype_guid.Data1;
+    gchar *format =
+        g_strdup_printf ("%" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc));
+    if (GST_STR_FOURCC (format) == GST_MAKE_FOURCC ('Y', '1', '6', ' ')) {
+      structure = gst_structure_new ("video/x-raw", "format",
+          G_TYPE_STRING, "GRAY16_LE", NULL);
     } else {
-      g_assert_not_reached ();
+      structure = gst_structure_new ("video/x-raw", "format",
+          G_TYPE_STRING, format, NULL);
     }
-
-    structure = gst_structure_new ("video/x-raw-rgb",
-        "bpp", G_TYPE_INT, bpp,
-        "depth", G_TYPE_INT, depth,
-        "red_mask", G_TYPE_INT, r_mask,
-        "green_mask", G_TYPE_INT, g_mask,
-        "blue_mask", G_TYPE_INT, b_mask,
-        "endianness", G_TYPE_INT, endianness, NULL);
+    g_free (format);
   } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_dvsd)) {
     if (IsEqualGUID (&format_guid, &FORMAT_DvInfo)) {
       structure = gst_structure_new ("video/x-dv",
@@ -225,23 +182,27 @@ ks_video_format_to_structure (GUID subtype_guid, GUID format_guid)
     } else if (IsEqualGUID (&format_guid, &FORMAT_VideoInfo)) {
       structure = gst_structure_new ("video/x-dv",
           "systemstream", G_TYPE_BOOLEAN, FALSE,
-          "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('d', 'v', 's', 'd'),
-          NULL);
+          "format", G_TYPE_STRING, "dvsd", NULL);
     }
-  } else if (memcmp (&subtype_guid.Data2, &MEDIASUBTYPE_FOURCC.Data2,
-          sizeof (subtype_guid) - sizeof (subtype_guid.Data1)) == 0) {
-    guint8 *p = (guint8 *) & subtype_guid.Data1;
+  }
 
-    structure = gst_structure_new ("video/x-raw-yuv",
-        "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC (p[0], p[1], p[2], p[3]),
-        NULL);
+  if (media_type) {
+    structure = gst_structure_new_empty (media_type);
+    if (format) {
+      gst_structure_set (structure, "format", G_TYPE_STRING, format, NULL);
+    }
+    if (p_is_rgb) {
+      *p_is_rgb = is_rgb;
+    }
   }
 
   if (!structure) {
-    GST_DEBUG ("Unknown DirectShow Video GUID %08x-%04x-%04x-%04x-%08x%04x",
-        subtype_guid.Data1, subtype_guid.Data2, subtype_guid.Data3,
-        *(WORD *) subtype_guid.Data4, *(DWORD *) & subtype_guid.Data4[2],
-        *(WORD *) & subtype_guid.Data4[6]);
+    GST_DEBUG ("Unknown DirectShow Video GUID "
+        "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+        (guint) subtype_guid.Data1, subtype_guid.Data2, subtype_guid.Data3,
+        subtype_guid.Data4[0], subtype_guid.Data4[1], subtype_guid.Data4[2],
+        subtype_guid.Data4[3], subtype_guid.Data4[4], subtype_guid.Data4[5],
+        subtype_guid.Data4[6], subtype_guid.Data4[7]);
   }
 
   return structure;
@@ -251,7 +212,7 @@ static void
 guess_aspect (gint width, gint height, gint * par_width, gint * par_height)
 {
   /*
-   * As we dont have access to the actual pixel aspect, we will try to do a
+   * As we don't have access to the actual pixel aspect, we will try to do a
    * best-effort guess. The guess is based on most sensors being either 4/3
    * or 16/9, and most pixel aspects being close to 1/1.
    */
@@ -269,10 +230,48 @@ guess_aspect (gint width, gint height, gint * par_width, gint * par_height)
   }
 }
 
+/* NOTE: would probably be better to use a continued fractions approach here */
+static void
+compress_fraction (gint64 in_num, gint64 in_den, gint64 * out_num,
+    gint64 * out_den)
+{
+  gdouble on, od, orig;
+  guint denominators[] = { 1, 2, 3, 5, 7 }, i;
+  const gdouble max_loss = 0.1;
+
+  on = in_num;
+  od = in_den;
+  orig = on / od;
+
+  for (i = 0; i < G_N_ELEMENTS (denominators); i++) {
+    gint64 cur_n, cur_d;
+    gdouble cur, loss;
+
+    cur_n = floor ((on / (od / (gdouble) denominators[i])) + 0.5);
+    cur_d = denominators[i];
+    cur = (gdouble) cur_n / (gdouble) cur_d;
+    loss = fabs (cur - orig);
+
+    if (loss <= max_loss) {
+      *out_num = cur_n;
+      *out_den = cur_d;
+
+      return;
+    }
+  }
+
+  *out_num = in_num;
+  *out_den = in_den;
+}
+
 static gboolean
 ks_video_append_video_stream_cfg_fields (GstStructure * structure,
     const KS_VIDEO_STREAM_CONFIG_CAPS * vscc)
 {
+  GValue val = { 0, };
+  gint64 min_n, min_d;
+  gint64 max_n, max_d;
+
   g_return_val_if_fail (structure, FALSE);
   g_return_val_if_fail (vscc, FALSE);
 
@@ -297,17 +296,20 @@ ks_video_append_video_stream_cfg_fields (GstStructure * structure,
   }
 
   /* framerate */
-  if (vscc->MinFrameInterval == vscc->MaxFrameInterval) {
-    gst_structure_set (structure,
-        "framerate", GST_TYPE_FRACTION,
-        (gint) (10000000 / vscc->MaxFrameInterval), 1, NULL);
+  compress_fraction (NANOSECONDS, vscc->MinFrameInterval, &min_n, &min_d);
+  compress_fraction (NANOSECONDS, vscc->MaxFrameInterval, &max_n, &max_d);
+
+  if (min_n == max_n && min_d == max_d) {
+    g_value_init (&val, GST_TYPE_FRACTION);
+    gst_value_set_fraction (&val, max_n, max_d);
   } else {
-    gst_structure_set (structure,
-        "framerate", GST_TYPE_FRACTION_RANGE,
-        (gint) (10000000 / vscc->MaxFrameInterval), 1,
-        (gint) (10000000 / vscc->MinFrameInterval), 1, NULL);
+    g_value_init (&val, GST_TYPE_FRACTION_RANGE);
+    gst_value_set_fraction_range_full (&val, max_n, max_d, min_n, min_d);
   }
 
+  gst_structure_set_value (structure, "framerate", &val);
+  g_value_unset (&val);
+
   {
     gint par_width, par_height;
 
@@ -430,7 +432,7 @@ ks_video_probe_filter_for_caps (HANDLE filter_handle)
           KSPROPERTY_PIN_CTYPES, &pin_count, sizeof (pin_count), NULL))
     goto beach;
 
-  GST_DEBUG ("pin_count = %d", pin_count);
+  GST_DEBUG ("pin_count = %lu", pin_count);
 
   for (pin_id = 0; pin_id < pin_count; pin_id++) {
     KSPIN_COMMUNICATION pin_comm;
@@ -461,9 +463,10 @@ ks_video_probe_filter_for_caps (HANDLE filter_handle)
         guint i;
 
         for (i = 0; i < items->Count; i++) {
-          if (IsEqualGUID (&range->MajorFormat, &KSDATAFORMAT_TYPE_VIDEO)) {
+          if (IsEqualGUID (&range->MajorFormat, &MEDIATYPE_Video)
+              || IsEqualGUID (&range->MajorFormat, &MEDIATYPE_Interleaved)) {
             KsVideoMediaType *entry;
-            gpointer src_vscc, src_format;
+            gpointer src_vscc = NULL, src_format = NULL;
             GstStructure *media_structure;
 
             entry = g_new0 (KsVideoMediaType, 1);
@@ -500,16 +503,22 @@ ks_video_probe_filter_for_caps (HANDLE filter_handle)
               entry->sample_size =
                   vr->VideoInfoHeader.hdr.bmiHeader.biSizeImage;
             } else if (IsEqualGUID (&range->Specifier, &FORMAT_MPEG2Video)) {
-              /* Untested and probably wrong... */
               KS_DATARANGE_MPEG2_VIDEO *vr =
                   (KS_DATARANGE_MPEG2_VIDEO *) entry->range;
-
               src_vscc = &vr->ConfigCaps;
               src_format = &vr->VideoInfoHeader;
 
               entry->format_size = sizeof (vr->VideoInfoHeader);
               entry->sample_size =
                   vr->VideoInfoHeader.hdr.bmiHeader.biSizeImage;
+            } else if (IsEqualGUID (&range->Specifier, &FORMAT_DvInfo)) {
+              KS_DATARANGE_DVVIDEO *vr = (KS_DATARANGE_DVVIDEO *) entry->range;
+
+              src_vscc = NULL;
+              src_format = &vr->DVVideoInfo;
+
+              entry->format_size = sizeof (vr->DVVideoInfo);
+              entry->sample_size = vr->DataRange.SampleSize;
             } else {
               gchar *guid_str;
 
@@ -525,19 +534,26 @@ ks_video_probe_filter_for_caps (HANDLE filter_handle)
             if (entry != NULL) {
               g_assert (entry->sample_size != 0);
 
-              memcpy ((gpointer) & entry->vscc, src_vscc, sizeof (entry->vscc));
+              if (src_vscc != NULL) {
+                memcpy ((gpointer) & entry->vscc, src_vscc,
+                    sizeof (entry->vscc));
+              }
 
               entry->format = g_malloc (entry->format_size);
               memcpy (entry->format, src_format, entry->format_size);
 
               media_structure =
                   ks_video_format_to_structure (range->SubFormat,
-                  range->MajorFormat);
+                  range->Specifier, &entry->is_rgb);
 
               if (media_structure == NULL) {
                 g_warning ("ks_video_format_to_structure returned NULL");
                 ks_video_media_type_free (entry);
                 entry = NULL;
+              } else if (src_vscc == NULL) {
+                entry->translated_caps = gst_caps_new_empty ();
+                gst_caps_append_structure (entry->translated_caps,
+                    media_structure);
               } else if (ks_video_append_video_stream_cfg_fields
                   (media_structure, &entry->vscc)) {
                 entry->translated_caps = gst_caps_new_empty ();
@@ -593,7 +609,7 @@ ks_video_create_pin_conn_from_media_type (KsVideoMediaType * media_type)
   conn->PinId = media_type->pin_id;
   conn->PinToHandle = NULL;
   conn->Priority.PriorityClass = KSPRIORITY_NORMAL;
-  conn->Priority.PrioritySubClass = 1;
+  conn->Priority.PrioritySubClass = KSPRIORITY_NORMAL;
 
   format = (KSDATAFORMAT *) (conn + 1);
   memcpy (format, media_type->range, sizeof (KSDATAFORMAT));
@@ -609,58 +625,47 @@ gboolean
 ks_video_fixate_media_type (const KSDATARANGE * range,
     guint8 * format, gint width, gint height, gint fps_n, gint fps_d)
 {
-  DWORD dwRate = (width * height * fps_n) / fps_d;
+  KS_DATARANGE_VIDEO *vr;
+  KS_VIDEOINFOHEADER *vih;
+  KS_BITMAPINFOHEADER *bih;
+  DWORD dwRate;
 
   g_return_val_if_fail (format != NULL, FALSE);
 
   if (IsEqualGUID (&range->Specifier, &FORMAT_VideoInfo)) {
-    KS_VIDEOINFOHEADER *vih = (KS_VIDEOINFOHEADER *) format;
-
-    /* FIXME: Need to figure out how to properly handle ranges */
-    if (vih->bmiHeader.biWidth != width || vih->bmiHeader.biHeight != height)
-      return FALSE;
-
-    vih->AvgTimePerFrame = gst_util_uint64_scale_int (10000000, fps_d, fps_n);
-    vih->dwBitRate = dwRate * vih->bmiHeader.biBitCount;
+    bih = &((KS_VIDEOINFOHEADER *) format)->bmiHeader;
   } else if (IsEqualGUID (&range->Specifier, &FORMAT_VideoInfo2)) {
-    KS_VIDEOINFOHEADER2 *vih = (KS_VIDEOINFOHEADER2 *) format;
-
-    /* FIXME: see above */
-    if (vih->bmiHeader.biWidth != width || vih->bmiHeader.biHeight != height)
-      return FALSE;
-
-    vih->AvgTimePerFrame = gst_util_uint64_scale_int (10000000, fps_d, fps_n);
-    vih->dwBitRate = dwRate * vih->bmiHeader.biBitCount;
+    bih = &((KS_VIDEOINFOHEADER2 *) format)->bmiHeader;
   } else if (IsEqualGUID (&range->Specifier, &FORMAT_MPEGVideo)) {
-    KS_MPEG1VIDEOINFO *vih = (KS_MPEG1VIDEOINFO *) format;
-
-    /* FIXME: see above */
-    if (vih->hdr.bmiHeader.biWidth != width ||
-        vih->hdr.bmiHeader.biHeight != height)
-    {
-      return FALSE;
-    }
-
-    vih->hdr.AvgTimePerFrame =
-        gst_util_uint64_scale_int (10000000, fps_d, fps_n);
-    vih->hdr.dwBitRate = dwRate * vih->hdr.bmiHeader.biBitCount;
+    bih = &((KS_MPEG1VIDEOINFO *) format)->hdr.bmiHeader;
   } else if (IsEqualGUID (&range->Specifier, &FORMAT_MPEG2Video)) {
-    KS_MPEGVIDEOINFO2 *vih = (KS_MPEGVIDEOINFO2 *) format;
-
-    /* FIXME: see above */
-    if (vih->hdr.bmiHeader.biWidth != width ||
-        vih->hdr.bmiHeader.biHeight != height)
-    {
-      return FALSE;
-    }
-
-    vih->hdr.AvgTimePerFrame =
-        gst_util_uint64_scale_int (10000000, fps_d, fps_n);
-    vih->hdr.dwBitRate = dwRate * vih->hdr.bmiHeader.biBitCount;
+    bih = &((KS_MPEGVIDEOINFO2 *) format)->hdr.bmiHeader;
   } else {
     return FALSE;
   }
 
+  /* These formats' structures share the most basic stuff */
+  vr = (KS_DATARANGE_VIDEO *) range;
+  vih = (KS_VIDEOINFOHEADER *) format;
+
+  /* FIXME: Need to figure out how to properly handle ranges */
+  if (bih->biWidth != width || bih->biHeight != height)
+    return FALSE;
+
+  /* Framerate, clamped because of fraction conversion rounding errors */
+  vih->AvgTimePerFrame =
+      gst_util_uint64_scale_int_round (NANOSECONDS, fps_d, fps_n);
+  vih->AvgTimePerFrame =
+      MAX (vih->AvgTimePerFrame, vr->ConfigCaps.MinFrameInterval);
+  vih->AvgTimePerFrame =
+      MIN (vih->AvgTimePerFrame, vr->ConfigCaps.MaxFrameInterval);
+
+  /* Bitrate, clamped for the same reason as framerate */
+  dwRate = (width * height * fps_n) / fps_d;
+  vih->dwBitRate = dwRate * bih->biBitCount;
+  vih->dwBitRate = MAX (vih->dwBitRate, vr->ConfigCaps.MinBitsPerSecond);
+  vih->dwBitRate = MIN (vih->dwBitRate, vr->ConfigCaps.MaxBitsPerSecond);
+
   return TRUE;
 }
 
@@ -690,43 +695,43 @@ ks_video_get_all_caps (void)
     /* RGB formats */
     structure =
         ks_video_append_var_video_fields (ks_video_format_to_structure
-        (MEDIASUBTYPE_RGB555, FORMAT_VideoInfo));
+        (MEDIASUBTYPE_RGB555, FORMAT_VideoInfo, NULL));
     gst_caps_append_structure (caps, structure);
 
     structure =
         ks_video_append_var_video_fields (ks_video_format_to_structure
-        (MEDIASUBTYPE_RGB565, FORMAT_VideoInfo));
+        (MEDIASUBTYPE_RGB565, FORMAT_VideoInfo, NULL));
     gst_caps_append_structure (caps, structure);
 
     structure =
         ks_video_append_var_video_fields (ks_video_format_to_structure
-        (MEDIASUBTYPE_RGB24, FORMAT_VideoInfo));
+        (MEDIASUBTYPE_RGB24, FORMAT_VideoInfo, NULL));
     gst_caps_append_structure (caps, structure);
 
     structure =
         ks_video_append_var_video_fields (ks_video_format_to_structure
-        (MEDIASUBTYPE_RGB32, FORMAT_VideoInfo));
+        (MEDIASUBTYPE_RGB32, FORMAT_VideoInfo, NULL));
     gst_caps_append_structure (caps, structure);
 
     /* YUV formats */
     structure =
-        ks_video_append_var_video_fields (gst_structure_new ("video/x-raw-yuv",
-            NULL));
+        ks_video_append_var_video_fields (gst_structure_new_empty
+        ("video/x-raw"));
     gst_caps_append_structure (caps, structure);
 
     /* Other formats */
     structure =
         ks_video_append_var_video_fields (ks_video_format_to_structure
-        (MEDIASUBTYPE_MJPG, FORMAT_VideoInfo));
+        (MEDIASUBTYPE_MJPG, FORMAT_VideoInfo, NULL));
     gst_caps_append_structure (caps, structure);
 
     structure =
         ks_video_append_var_video_fields (ks_video_format_to_structure
-        (MEDIASUBTYPE_dvsd, FORMAT_VideoInfo));
+        (MEDIASUBTYPE_dvsd, FORMAT_VideoInfo, NULL));
     gst_caps_append_structure (caps, structure);
 
     structure =                 /* no variable video fields (width, height, framerate) */
-        ks_video_format_to_structure (MEDIASUBTYPE_dvsd, FORMAT_DvInfo);
+        ks_video_format_to_structure (MEDIASUBTYPE_dvsd, FORMAT_DvInfo, NULL);
     gst_caps_append_structure (caps, structure);
   }