/* GStreamer
 *
 * Copyright (C) 2001-2002 Ronald Bultje <rbultje@ronald.bitfreak.net>
 *               2006 Edgard Lima <edgard.lima@indt.org.br>
 *
 * gstv4l2object.c: base class for V4L2 elements
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Library General Public License as published
 * by the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. This library is distributed in the hope
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU Library General Public License for more details.
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
 * USA.
 */

/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
 * with newer GLib versions (>= 2.31.0) */
#define GLIB_DISABLE_DEPRECATION_WARNINGS

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>

#ifdef HAVE_GUDEV
#include <gudev/gudev.h>
#endif

#include "v4l2_calls.h"
#include "gstv4l2tuner.h"
#include "gstv4l2colorbalance.h"

#include "gst/gst-i18n-plugin.h"

#include <gst/video/video.h>

GST_DEBUG_CATEGORY_EXTERN (v4l2_debug);
#define GST_CAT_DEFAULT v4l2_debug

#define DEFAULT_PROP_DEVICE_NAME        NULL
#define DEFAULT_PROP_DEVICE_FD          -1
#define DEFAULT_PROP_FLAGS              0
#define DEFAULT_PROP_TV_NORM            0
#define DEFAULT_PROP_CHANNEL            NULL
#define DEFAULT_PROP_FREQUENCY          0
#define DEFAULT_PROP_IO_MODE            GST_V4L2_IO_AUTO

#define ENCODED_BUFFER_SIZE             (1 * 1024 * 1024)

enum
{
  PROP_0,
  V4L2_STD_OBJECT_PROPS,
};

/*
 * common format / caps utilities:
 */
typedef enum
{
  GST_V4L2_RAW = 1 << 0,
  GST_V4L2_CODEC = 1 << 1,
  GST_V4L2_TRANSPORT = 1 << 2,
  GST_V4L2_NO_PARSE = 1 << 3,
  GST_V4L2_ALL = 0xffff
} GstV4L2FormatFlags;

typedef struct
{
  guint32 format;
  gboolean dimensions;
  GstV4L2FormatFlags flags;
} GstV4L2FormatDesc;

static const GstV4L2FormatDesc gst_v4l2_formats[] = {
  /* from Linux 2.6.15 videodev2.h */
  {V4L2_PIX_FMT_RGB332, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_RGB555, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_RGB565, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_RGB555X, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_RGB565X, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_BGR24, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_RGB24, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_BGR32, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_RGB32, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_GREY, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_YVU410, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_YVU420, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_YUYV, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_UYVY, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_YUV422P, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_YUV411P, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_Y41P, TRUE, GST_V4L2_RAW},

  /* two planes -- one Y, one Cr + Cb interleaved  */
  {V4L2_PIX_FMT_NV12, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_NV12M, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_NV12MT, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_NV21, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_NV21M, TRUE, GST_V4L2_RAW},

  /*  The following formats are not defined in the V4L2 specification */
  {V4L2_PIX_FMT_YUV410, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_YUV420, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_YYUV, TRUE, GST_V4L2_RAW},
  {V4L2_PIX_FMT_HI240, TRUE, GST_V4L2_RAW},

  /* see http://www.siliconimaging.com/RGB%20Bayer.htm */
  {V4L2_PIX_FMT_SBGGR8, TRUE, GST_V4L2_CODEC},
  {V4L2_PIX_FMT_SGBRG8, TRUE, GST_V4L2_CODEC},
  {V4L2_PIX_FMT_SGRBG8, TRUE, GST_V4L2_CODEC},
  {V4L2_PIX_FMT_SRGGB8, TRUE, GST_V4L2_CODEC},

  /* compressed formats */
  {V4L2_PIX_FMT_MJPEG, FALSE, GST_V4L2_CODEC},
  {V4L2_PIX_FMT_JPEG, FALSE, GST_V4L2_CODEC},
  {V4L2_PIX_FMT_PJPG, FALSE, GST_V4L2_CODEC},
  {V4L2_PIX_FMT_DV, FALSE, GST_V4L2_TRANSPORT},
  {V4L2_PIX_FMT_MPEG, FALSE, GST_V4L2_TRANSPORT},
  {V4L2_PIX_FMT_MPEG1, FALSE, GST_V4L2_CODEC},
  {V4L2_PIX_FMT_MPEG2, FALSE, GST_V4L2_CODEC},
  {V4L2_PIX_FMT_MPEG4, FALSE, GST_V4L2_CODEC},
  {V4L2_PIX_FMT_H263, FALSE, GST_V4L2_CODEC},
  {V4L2_PIX_FMT_H264, FALSE, GST_V4L2_CODEC},
  /* VP8 not parseable */
  {V4L2_PIX_FMT_VP8, FALSE, GST_V4L2_CODEC | GST_V4L2_NO_PARSE},

  /*  Vendor-specific formats   */
  {V4L2_PIX_FMT_WNVA, TRUE, GST_V4L2_CODEC},
  {V4L2_PIX_FMT_SN9C10X, TRUE, GST_V4L2_CODEC},
  {V4L2_PIX_FMT_PWC1, TRUE, GST_V4L2_CODEC},
  {V4L2_PIX_FMT_PWC2, TRUE, GST_V4L2_CODEC},
  {V4L2_PIX_FMT_YVYU, TRUE, GST_V4L2_RAW},
};

#define GST_V4L2_FORMAT_COUNT (G_N_ELEMENTS (gst_v4l2_formats))

static GSList *gst_v4l2_object_get_format_list (GstV4l2Object * v4l2object);


#define GST_TYPE_V4L2_DEVICE_FLAGS (gst_v4l2_device_get_type ())
static GType
gst_v4l2_device_get_type (void)
{
  static GType v4l2_device_type = 0;

  if (v4l2_device_type == 0) {
    static const GFlagsValue values[] = {
      {V4L2_CAP_VIDEO_CAPTURE, "Device supports video capture", "capture"},
      {V4L2_CAP_VIDEO_OUTPUT, "Device supports video playback", "output"},
      {V4L2_CAP_VIDEO_OVERLAY, "Device supports video overlay", "overlay"},

      {V4L2_CAP_VBI_CAPTURE, "Device supports the VBI capture", "vbi-capture"},
      {V4L2_CAP_VBI_OUTPUT, "Device supports the VBI output", "vbi-output"},

      {V4L2_CAP_TUNER, "Device has a tuner or modulator", "tuner"},
      {V4L2_CAP_AUDIO, "Device has audio inputs or outputs", "audio"},

      {0, NULL, NULL}
    };

    v4l2_device_type =
        g_flags_register_static ("GstV4l2DeviceTypeFlags", values);
  }

  return v4l2_device_type;
}

#define GST_TYPE_V4L2_TV_NORM (gst_v4l2_tv_norm_get_type ())
static GType
gst_v4l2_tv_norm_get_type (void)
{
  static GType v4l2_tv_norm = 0;

  if (!v4l2_tv_norm) {
    static const GEnumValue tv_norms[] = {
      {0, "none", "none"},

      {V4L2_STD_NTSC, "NTSC", "NTSC"},
      {V4L2_STD_NTSC_M, "NTSC-M", "NTSC-M"},
      {V4L2_STD_NTSC_M_JP, "NTSC-M-JP", "NTSC-M-JP"},
      {V4L2_STD_NTSC_M_KR, "NTSC-M-KR", "NTSC-M-KR"},
      {V4L2_STD_NTSC_443, "NTSC-443", "NTSC-443"},

      {V4L2_STD_PAL, "PAL", "PAL"},
      {V4L2_STD_PAL_BG, "PAL-BG", "PAL-BG"},
      {V4L2_STD_PAL_B, "PAL-B", "PAL-B"},
      {V4L2_STD_PAL_B1, "PAL-B1", "PAL-B1"},
      {V4L2_STD_PAL_G, "PAL-G", "PAL-G"},
      {V4L2_STD_PAL_H, "PAL-H", "PAL-H"},
      {V4L2_STD_PAL_I, "PAL-I", "PAL-I"},
      {V4L2_STD_PAL_DK, "PAL-DK", "PAL-DK"},
      {V4L2_STD_PAL_D, "PAL-D", "PAL-D"},
      {V4L2_STD_PAL_D1, "PAL-D1", "PAL-D1"},
      {V4L2_STD_PAL_K, "PAL-K", "PAL-K"},
      {V4L2_STD_PAL_M, "PAL-M", "PAL-M"},
      {V4L2_STD_PAL_N, "PAL-N", "PAL-N"},
      {V4L2_STD_PAL_Nc, "PAL-Nc", "PAL-Nc"},
      {V4L2_STD_PAL_60, "PAL-60", "PAL-60"},

      {V4L2_STD_SECAM, "SECAM", "SECAM"},
      {V4L2_STD_SECAM_B, "SECAM-B", "SECAM-B"},
      {V4L2_STD_SECAM_G, "SECAM-G", "SECAM-G"},
      {V4L2_STD_SECAM_H, "SECAM-H", "SECAM-H"},
      {V4L2_STD_SECAM_DK, "SECAM-DK", "SECAM-DK"},
      {V4L2_STD_SECAM_D, "SECAM-D", "SECAM-D"},
      {V4L2_STD_SECAM_K, "SECAM-K", "SECAM-K"},
      {V4L2_STD_SECAM_K1, "SECAM-K1", "SECAM-K1"},
      {V4L2_STD_SECAM_L, "SECAM-L", "SECAM-L"},
      {V4L2_STD_SECAM_LC, "SECAM-Lc", "SECAM-Lc"},

      {0, NULL, NULL}
    };

    v4l2_tv_norm = g_enum_register_static ("V4L2_TV_norms", tv_norms);
  }

  return v4l2_tv_norm;
}

GType
gst_v4l2_io_mode_get_type (void)
{
  static GType v4l2_io_mode = 0;

  if (!v4l2_io_mode) {
    static const GEnumValue io_modes[] = {
      {GST_V4L2_IO_AUTO, "GST_V4L2_IO_AUTO", "auto"},
      {GST_V4L2_IO_RW, "GST_V4L2_IO_RW", "rw"},
      {GST_V4L2_IO_MMAP, "GST_V4L2_IO_MMAP", "mmap"},
      {GST_V4L2_IO_USERPTR, "GST_V4L2_IO_USERPTR", "userptr"},
      {GST_V4L2_IO_DMABUF, "GST_V4L2_IO_DMABUF", "dmabuf"},
      {GST_V4L2_IO_DMABUF_IMPORT, "GST_V4L2_IO_DMABUF_IMPORT",
          "dmabuf-import"},

      {0, NULL, NULL}
    };
    v4l2_io_mode = g_enum_register_static ("GstV4l2IOMode", io_modes);
  }
  return v4l2_io_mode;
}

void
gst_v4l2_object_install_properties_helper (GObjectClass * gobject_class,
    const char *default_device)
{
  g_object_class_install_property (gobject_class, PROP_DEVICE,
      g_param_spec_string ("device", "Device", "Device location",
          default_device, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_DEVICE_NAME,
      g_param_spec_string ("device-name", "Device name",
          "Name of the device", DEFAULT_PROP_DEVICE_NAME,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_DEVICE_FD,
      g_param_spec_int ("device-fd", "File descriptor",
          "File descriptor of the device", -1, G_MAXINT, DEFAULT_PROP_DEVICE_FD,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_FLAGS,
      g_param_spec_flags ("flags", "Flags", "Device type flags",
          GST_TYPE_V4L2_DEVICE_FLAGS, DEFAULT_PROP_FLAGS,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  /**
   * GstV4l2Src:brightness:
   *
   * Picture brightness, or more precisely, the black level
   */
  g_object_class_install_property (gobject_class, PROP_BRIGHTNESS,
      g_param_spec_int ("brightness", "Brightness",
          "Picture brightness, or more precisely, the black level", G_MININT,
          G_MAXINT, 0,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
  /**
   * GstV4l2Src:contrast:
   *
   * Picture contrast or luma gain
   */
  g_object_class_install_property (gobject_class, PROP_CONTRAST,
      g_param_spec_int ("contrast", "Contrast",
          "Picture contrast or luma gain", G_MININT,
          G_MAXINT, 0,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
  /**
   * GstV4l2Src:saturation:
   *
   * Picture color saturation or chroma gain
   */
  g_object_class_install_property (gobject_class, PROP_SATURATION,
      g_param_spec_int ("saturation", "Saturation",
          "Picture color saturation or chroma gain", G_MININT,
          G_MAXINT, 0,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
  /**
   * GstV4l2Src:hue:
   *
   * Hue or color balance
   */
  g_object_class_install_property (gobject_class, PROP_HUE,
      g_param_spec_int ("hue", "Hue",
          "Hue or color balance", G_MININT,
          G_MAXINT, 0,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));

  /**
   * GstV4l2Src:norm:
   *
   * TV norm
   */
  g_object_class_install_property (gobject_class, PROP_TV_NORM,
      g_param_spec_enum ("norm", "TV norm",
          "video standard",
          GST_TYPE_V4L2_TV_NORM, DEFAULT_PROP_TV_NORM,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstV4l2Src:io-mode:
   *
   * IO Mode
   */
  g_object_class_install_property (gobject_class, PROP_IO_MODE,
      g_param_spec_enum ("io-mode", "IO mode",
          "I/O mode",
          GST_TYPE_V4L2_IO_MODE, DEFAULT_PROP_IO_MODE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstV4l2Src:extra-controls:
   *
   * Additional v4l2 controls for the device. The controls are identified
   * by the control name (lowercase with '_' for any non-alphanumeric
   * characters).
   *
   * Since: 1.2
   */
  g_object_class_install_property (gobject_class, PROP_EXTRA_CONTROLS,
      g_param_spec_boxed ("extra-controls", "Extra Controls",
          "Extra v4l2 controls (CIDs) for the device",
          GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstV4l2Src:pixel-aspect-ratio:
   *
   * The pixel aspect ratio of the device. This overwrites the pixel aspect
   * ratio queried from the device.
   *
   * Since: 1.2
   */
  g_object_class_install_property (gobject_class, PROP_PIXEL_ASPECT_RATIO,
      g_param_spec_string ("pixel-aspect-ratio", "Pixel Aspect Ratio",
          "Overwrite the pixel aspect ratio of the device", "1/1",
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstV4l2Src:force-aspect-ratio:
   *
   * When enabled, the pixel aspect ratio queried from the device or set
   * with the pixel-aspect-ratio property will be enforced.
   *
   * Since: 1.2
   */
  g_object_class_install_property (gobject_class, PROP_FORCE_ASPECT_RATIO,
      g_param_spec_boolean ("force-aspect-ratio", "Force aspect ratio",
          "When enabled, the pixel aspect ratio will be enforced", TRUE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

}

void
gst_v4l2_object_install_m2m_properties_helper (GObjectClass * gobject_class)
{
  g_object_class_install_property (gobject_class, PROP_DEVICE,
      g_param_spec_string ("device", "Device", "Device location",
          NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_DEVICE_NAME,
      g_param_spec_string ("device-name", "Device name",
          "Name of the device", DEFAULT_PROP_DEVICE_NAME,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_DEVICE_FD,
      g_param_spec_int ("device-fd", "File descriptor",
          "File descriptor of the device", -1, G_MAXINT, DEFAULT_PROP_DEVICE_FD,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_OUTPUT_IO_MODE,
      g_param_spec_enum ("output-io-mode", "Output IO mode",
          "Output side I/O mode (matches sink pad)",
          GST_TYPE_V4L2_IO_MODE, DEFAULT_PROP_IO_MODE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_CAPTURE_IO_MODE,
      g_param_spec_enum ("capture-io-mode", "Capture IO mode",
          "Capture I/O mode (matches src pad)",
          GST_TYPE_V4L2_IO_MODE, DEFAULT_PROP_IO_MODE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_EXTRA_CONTROLS,
      g_param_spec_boxed ("extra-controls", "Extra Controls",
          "Extra v4l2 controls (CIDs) for the device",
          GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

GstV4l2Object *
gst_v4l2_object_new (GstElement * element,
    enum v4l2_buf_type type,
    const char *default_device,
    GstV4l2GetInOutFunction get_in_out_func,
    GstV4l2SetInOutFunction set_in_out_func,
    GstV4l2UpdateFpsFunction update_fps_func)
{
  GstV4l2Object *v4l2object;

  /*
   * some default values
   */
  v4l2object = g_new0 (GstV4l2Object, 1);

  v4l2object->type = type;
  v4l2object->formats = NULL;

  v4l2object->element = element;
  v4l2object->get_in_out_func = get_in_out_func;
  v4l2object->set_in_out_func = set_in_out_func;
  v4l2object->update_fps_func = update_fps_func;

  v4l2object->video_fd = -1;
  v4l2object->active = FALSE;
  v4l2object->videodev = g_strdup (default_device);

  v4l2object->norms = NULL;
  v4l2object->channels = NULL;
  v4l2object->colors = NULL;

  v4l2object->xwindow_id = 0;

  v4l2object->keep_aspect = TRUE;

  v4l2object->n_v4l2_planes = 0;

  v4l2object->no_initial_format = FALSE;

  return v4l2object;
}

static gboolean gst_v4l2_object_clear_format_list (GstV4l2Object * v4l2object);


void
gst_v4l2_object_destroy (GstV4l2Object * v4l2object)
{
  g_return_if_fail (v4l2object != NULL);

  if (v4l2object->videodev)
    g_free (v4l2object->videodev);

  if (v4l2object->channel)
    g_free (v4l2object->channel);

  if (v4l2object->formats) {
    gst_v4l2_object_clear_format_list (v4l2object);
  }

  if (v4l2object->probed_caps) {
    gst_caps_unref (v4l2object->probed_caps);
  }

  g_free (v4l2object);
}


static gboolean
gst_v4l2_object_clear_format_list (GstV4l2Object * v4l2object)
{
  g_slist_foreach (v4l2object->formats, (GFunc) g_free, NULL);
  g_slist_free (v4l2object->formats);
  v4l2object->formats = NULL;

  return TRUE;
}

static gint
gst_v4l2_object_prop_to_cid (guint prop_id)
{
  gint cid = -1;

  switch (prop_id) {
    case PROP_BRIGHTNESS:
      cid = V4L2_CID_BRIGHTNESS;
      break;
    case PROP_CONTRAST:
      cid = V4L2_CID_CONTRAST;
      break;
    case PROP_SATURATION:
      cid = V4L2_CID_SATURATION;
      break;
    case PROP_HUE:
      cid = V4L2_CID_HUE;
      break;
    default:
      GST_WARNING ("unmapped property id: %d", prop_id);
  }
  return cid;
}


gboolean
gst_v4l2_object_set_property_helper (GstV4l2Object * v4l2object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  switch (prop_id) {
    case PROP_DEVICE:
      g_free (v4l2object->videodev);
      v4l2object->videodev = g_value_dup_string (value);
      break;
    case PROP_BRIGHTNESS:
    case PROP_CONTRAST:
    case PROP_SATURATION:
    case PROP_HUE:
    {
      gint cid = gst_v4l2_object_prop_to_cid (prop_id);

      if (cid != -1) {
        if (GST_V4L2_IS_OPEN (v4l2object)) {
          gst_v4l2_set_attribute (v4l2object, cid, g_value_get_int (value));
        }
      }
      return TRUE;
    }
      break;
    case PROP_TV_NORM:
      v4l2object->tv_norm = g_value_get_enum (value);
      break;
#if 0
    case PROP_CHANNEL:
      if (GST_V4L2_IS_OPEN (v4l2object)) {
        GstTuner *tuner = GST_TUNER (v4l2object->element);
        GstTunerChannel *channel = gst_tuner_find_channel_by_name (tuner,
            (gchar *) g_value_get_string (value));

        if (channel) {
          /* like gst_tuner_set_channel (tuner, channel)
             without g_object_notify */
          gst_v4l2_tuner_set_channel (v4l2object, channel);
        }
      } else {
        g_free (v4l2object->channel);
        v4l2object->channel = g_value_dup_string (value);
      }
      break;
    case PROP_FREQUENCY:
      if (GST_V4L2_IS_OPEN (v4l2object)) {
        GstTuner *tuner = GST_TUNER (v4l2object->element);
        GstTunerChannel *channel = gst_tuner_get_channel (tuner);

        if (channel &&
            GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) {
          /* like
             gst_tuner_set_frequency (tuner, channel, g_value_get_ulong (value))
             without g_object_notify */
          gst_v4l2_tuner_set_frequency (v4l2object, channel,
              g_value_get_ulong (value));
        }
      } else {
        v4l2object->frequency = g_value_get_ulong (value);
      }
      break;
#endif

    case PROP_IO_MODE:
      v4l2object->req_mode = g_value_get_enum (value);
      break;
    case PROP_CAPTURE_IO_MODE:
      g_return_val_if_fail (!V4L2_TYPE_IS_OUTPUT (v4l2object->type), FALSE);
      v4l2object->req_mode = g_value_get_enum (value);
      break;
    case PROP_OUTPUT_IO_MODE:
      g_return_val_if_fail (V4L2_TYPE_IS_OUTPUT (v4l2object->type), FALSE);
      v4l2object->req_mode = g_value_get_enum (value);
      break;
    case PROP_EXTRA_CONTROLS:{
      const GstStructure *s = gst_value_get_structure (value);

      if (v4l2object->extra_controls)
        gst_structure_free (v4l2object->extra_controls);

      v4l2object->extra_controls = s ? gst_structure_copy (s) : NULL;
      if (GST_V4L2_IS_OPEN (v4l2object))
        gst_v4l2_set_controls (v4l2object, v4l2object->extra_controls);
      break;
    }
    case PROP_PIXEL_ASPECT_RATIO:
      g_free (v4l2object->par);
      v4l2object->par = g_new0 (GValue, 1);
      g_value_init (v4l2object->par, GST_TYPE_FRACTION);
      if (!g_value_transform (value, v4l2object->par)) {
        g_warning ("Could not transform string to aspect ratio");
        gst_value_set_fraction (v4l2object->par, 1, 1);
      }
      GST_DEBUG_OBJECT (v4l2object->element, "set PAR to %d/%d",
          gst_value_get_fraction_numerator (v4l2object->par),
          gst_value_get_fraction_denominator (v4l2object->par));
      break;
    case PROP_FORCE_ASPECT_RATIO:
      v4l2object->keep_aspect = g_value_get_boolean (value);
      break;
    default:
      return FALSE;
      break;
  }
  return TRUE;
}


gboolean
gst_v4l2_object_get_property_helper (GstV4l2Object * v4l2object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  switch (prop_id) {
    case PROP_DEVICE:
      g_value_set_string (value, v4l2object->videodev);
      break;
    case PROP_DEVICE_NAME:
    {
      const guchar *new = NULL;

      if (GST_V4L2_IS_OPEN (v4l2object)) {
        new = v4l2object->vcap.card;
      } else if (gst_v4l2_open (v4l2object)) {
        new = v4l2object->vcap.card;
        gst_v4l2_close (v4l2object);
      }
      g_value_set_string (value, (gchar *) new);
      break;
    }
    case PROP_DEVICE_FD:
    {
      if (GST_V4L2_IS_OPEN (v4l2object))
        g_value_set_int (value, v4l2object->video_fd);
      else
        g_value_set_int (value, DEFAULT_PROP_DEVICE_FD);
      break;
    }
    case PROP_FLAGS:
    {
      guint flags = 0;

      if (GST_V4L2_IS_OPEN (v4l2object)) {
        flags |= v4l2object->vcap.capabilities &
            (V4L2_CAP_VIDEO_CAPTURE |
            V4L2_CAP_VIDEO_OUTPUT |
            V4L2_CAP_VIDEO_OVERLAY |
            V4L2_CAP_VBI_CAPTURE |
            V4L2_CAP_VBI_OUTPUT | V4L2_CAP_TUNER | V4L2_CAP_AUDIO);

        if (v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE)
          flags |= V4L2_CAP_VIDEO_CAPTURE;

        if (v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_OUTPUT_MPLANE)
          flags |= V4L2_CAP_VIDEO_OUTPUT;
      }
      g_value_set_flags (value, flags);
      break;
    }
    case PROP_BRIGHTNESS:
    case PROP_CONTRAST:
    case PROP_SATURATION:
    case PROP_HUE:
    {
      gint cid = gst_v4l2_object_prop_to_cid (prop_id);

      if (cid != -1) {
        if (GST_V4L2_IS_OPEN (v4l2object)) {
          gint v;
          if (gst_v4l2_get_attribute (v4l2object, cid, &v)) {
            g_value_set_int (value, v);
          }
        }
      }
      return TRUE;
    }
      break;
    case PROP_TV_NORM:
      g_value_set_enum (value, v4l2object->tv_norm);
      break;
    case PROP_IO_MODE:
      g_value_set_enum (value, v4l2object->req_mode);
      break;
    case PROP_CAPTURE_IO_MODE:
      g_return_val_if_fail (!V4L2_TYPE_IS_OUTPUT (v4l2object->type), FALSE);
      g_value_set_enum (value, v4l2object->req_mode);
      break;
    case PROP_OUTPUT_IO_MODE:
      g_return_val_if_fail (V4L2_TYPE_IS_OUTPUT (v4l2object->type), FALSE);
      g_value_set_enum (value, v4l2object->req_mode);
      break;
    case PROP_EXTRA_CONTROLS:
      gst_value_set_structure (value, v4l2object->extra_controls);
      break;
    case PROP_PIXEL_ASPECT_RATIO:
      if (v4l2object->par)
        g_value_transform (v4l2object->par, value);
      break;
    case PROP_FORCE_ASPECT_RATIO:
      g_value_set_boolean (value, v4l2object->keep_aspect);
      break;
    default:
      return FALSE;
      break;
  }
  return TRUE;
}

static void
gst_v4l2_set_defaults (GstV4l2Object * v4l2object)
{
  GstTunerNorm *norm = NULL;
  GstTunerChannel *channel = NULL;
  GstTuner *tuner;

  if (!GST_IS_TUNER (v4l2object->element))
    return;

  tuner = GST_TUNER (v4l2object->element);

  if (v4l2object->tv_norm)
    norm = gst_v4l2_tuner_get_norm_by_std_id (v4l2object, v4l2object->tv_norm);
  GST_DEBUG_OBJECT (v4l2object->element, "tv_norm=0x%" G_GINT64_MODIFIER "x, "
      "norm=%p", (guint64) v4l2object->tv_norm, norm);
  if (norm) {
    gst_tuner_set_norm (tuner, norm);
  } else {
    norm =
        GST_TUNER_NORM (gst_tuner_get_norm (GST_TUNER (v4l2object->element)));
    if (norm) {
      v4l2object->tv_norm =
          gst_v4l2_tuner_get_std_id_by_norm (v4l2object, norm);
      gst_tuner_norm_changed (tuner, norm);
    }
  }

  if (v4l2object->channel)
    channel = gst_tuner_find_channel_by_name (tuner, v4l2object->channel);
  if (channel) {
    gst_tuner_set_channel (tuner, channel);
  } else {
    channel =
        GST_TUNER_CHANNEL (gst_tuner_get_channel (GST_TUNER
            (v4l2object->element)));
    if (channel) {
      g_free (v4l2object->channel);
      v4l2object->channel = g_strdup (channel->label);
      gst_tuner_channel_changed (tuner, channel);
    }
  }

  if (channel
      && GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) {
    if (v4l2object->frequency != 0) {
      gst_tuner_set_frequency (tuner, channel, v4l2object->frequency);
    } else {
      v4l2object->frequency = gst_tuner_get_frequency (tuner, channel);
      if (v4l2object->frequency == 0) {
        /* guess */
        gst_tuner_set_frequency (tuner, channel, 1000);
      } else {
      }
    }
  }
}

gboolean
gst_v4l2_object_open (GstV4l2Object * v4l2object)
{
  if (gst_v4l2_open (v4l2object))
    gst_v4l2_set_defaults (v4l2object);
  else
    return FALSE;

  return TRUE;
}

gboolean
gst_v4l2_object_open_shared (GstV4l2Object * v4l2object, GstV4l2Object * other)
{
  gboolean ret;

  ret = gst_v4l2_dup (v4l2object, other);

  return ret;
}

gboolean
gst_v4l2_object_close (GstV4l2Object * v4l2object)
{
  if (!gst_v4l2_close (v4l2object))
    return FALSE;

  gst_caps_replace (&v4l2object->probed_caps, NULL);

  if (v4l2object->formats) {
    gst_v4l2_object_clear_format_list (v4l2object);
  }

  return TRUE;
}

static struct v4l2_fmtdesc *
gst_v4l2_object_get_format_from_fourcc (GstV4l2Object * v4l2object,
    guint32 fourcc)
{
  struct v4l2_fmtdesc *fmt;
  GSList *walk;

  if (fourcc == 0)
    return NULL;

  walk = gst_v4l2_object_get_format_list (v4l2object);
  while (walk) {
    fmt = (struct v4l2_fmtdesc *) walk->data;
    if (fmt->pixelformat == fourcc)
      return fmt;
    /* special case for jpeg */
    if (fmt->pixelformat == V4L2_PIX_FMT_MJPEG ||
        fmt->pixelformat == V4L2_PIX_FMT_JPEG ||
        fmt->pixelformat == V4L2_PIX_FMT_PJPG) {
      if (fourcc == V4L2_PIX_FMT_JPEG || fourcc == V4L2_PIX_FMT_MJPEG ||
          fourcc == V4L2_PIX_FMT_PJPG) {
        return fmt;
      }
    }
    walk = g_slist_next (walk);
  }

  return NULL;
}



/* complete made up ranking, the values themselves are meaningless */
/* These ranks MUST be X such that X<<15 fits on a signed int - see
   the comment at the end of gst_v4l2_object_format_get_rank. */
#define YUV_BASE_RANK     1000
#define JPEG_BASE_RANK     500
#define DV_BASE_RANK       200
#define RGB_BASE_RANK      100
#define YUV_ODD_BASE_RANK   50
#define RGB_ODD_BASE_RANK   25
#define BAYER_BASE_RANK     15
#define S910_BASE_RANK      10
#define GREY_BASE_RANK       5
#define PWC_BASE_RANK        1

static gint
gst_v4l2_object_format_get_rank (const struct v4l2_fmtdesc *fmt)
{
  guint32 fourcc = fmt->pixelformat;
  gboolean emulated = ((fmt->flags & V4L2_FMT_FLAG_EMULATED) != 0);
  gint rank = 0;

  switch (fourcc) {
    case V4L2_PIX_FMT_MJPEG:
    case V4L2_PIX_FMT_PJPG:
      rank = JPEG_BASE_RANK;
      break;
    case V4L2_PIX_FMT_JPEG:
      rank = JPEG_BASE_RANK + 1;
      break;
    case V4L2_PIX_FMT_MPEG:    /* MPEG          */
      rank = JPEG_BASE_RANK + 2;
      break;

    case V4L2_PIX_FMT_RGB332:
    case V4L2_PIX_FMT_RGB555:
    case V4L2_PIX_FMT_RGB555X:
    case V4L2_PIX_FMT_RGB565:
    case V4L2_PIX_FMT_RGB565X:
      rank = RGB_ODD_BASE_RANK;
      break;

    case V4L2_PIX_FMT_RGB24:
    case V4L2_PIX_FMT_BGR24:
      rank = RGB_BASE_RANK - 1;
      break;

    case V4L2_PIX_FMT_RGB32:
    case V4L2_PIX_FMT_BGR32:
      rank = RGB_BASE_RANK;
      break;

    case V4L2_PIX_FMT_GREY:    /*  8  Greyscale     */
      rank = GREY_BASE_RANK;
      break;

    case V4L2_PIX_FMT_NV12:    /* 12  Y/CbCr 4:2:0  */
    case V4L2_PIX_FMT_NV12M:   /* Same as NV12      */
    case V4L2_PIX_FMT_NV12MT:  /* NV12 64x32 tile   */
    case V4L2_PIX_FMT_NV21:    /* 12  Y/CrCb 4:2:0  */
    case V4L2_PIX_FMT_NV21M:   /* Same as NV21      */
    case V4L2_PIX_FMT_YYUV:    /* 16  YUV 4:2:2     */
    case V4L2_PIX_FMT_HI240:   /*  8  8-bit color   */
      rank = YUV_ODD_BASE_RANK;
      break;

    case V4L2_PIX_FMT_YVU410:  /* YVU9,  9 bits per pixel */
      rank = YUV_BASE_RANK + 3;
      break;
    case V4L2_PIX_FMT_YUV410:  /* YUV9,  9 bits per pixel */
      rank = YUV_BASE_RANK + 2;
      break;
    case V4L2_PIX_FMT_YUV420:  /* I420, 12 bits per pixel */
      rank = YUV_BASE_RANK + 7;
      break;
    case V4L2_PIX_FMT_YUYV:    /* YUY2, 16 bits per pixel */
      rank = YUV_BASE_RANK + 10;
      break;
    case V4L2_PIX_FMT_YVU420:  /* YV12, 12 bits per pixel */
      rank = YUV_BASE_RANK + 6;
      break;
    case V4L2_PIX_FMT_UYVY:    /* UYVY, 16 bits per pixel */
      rank = YUV_BASE_RANK + 9;
      break;
    case V4L2_PIX_FMT_Y41P:    /* Y41P, 12 bits per pixel */
      rank = YUV_BASE_RANK + 5;
      break;
    case V4L2_PIX_FMT_YUV411P: /* Y41B, 12 bits per pixel */
      rank = YUV_BASE_RANK + 4;
      break;
    case V4L2_PIX_FMT_YUV422P: /* Y42B, 16 bits per pixel */
      rank = YUV_BASE_RANK + 8;
      break;

    case V4L2_PIX_FMT_DV:
      rank = DV_BASE_RANK;
      break;

    case V4L2_PIX_FMT_WNVA:    /* Winnov hw compres */
      rank = 0;
      break;

    case V4L2_PIX_FMT_SBGGR8:
    case V4L2_PIX_FMT_SGBRG8:
    case V4L2_PIX_FMT_SGRBG8:
    case V4L2_PIX_FMT_SRGGB8:
      rank = BAYER_BASE_RANK;
      break;

    case V4L2_PIX_FMT_SN9C10X:
      rank = S910_BASE_RANK;
      break;

    case V4L2_PIX_FMT_PWC1:
      rank = PWC_BASE_RANK;
      break;
    case V4L2_PIX_FMT_PWC2:
      rank = PWC_BASE_RANK;
      break;

    default:
      rank = 0;
      break;
  }

  /* All ranks are below 1<<15 so a shift by 15
   * will a) make all non-emulated formats larger
   * than emulated and b) will not overflow
   */
  if (!emulated)
    rank <<= 15;

  return rank;
}



static gint
format_cmp_func (gconstpointer a, gconstpointer b)
{
  const struct v4l2_fmtdesc *fa = a;
  const struct v4l2_fmtdesc *fb = b;

  if (fa->pixelformat == fb->pixelformat)
    return 0;

  return gst_v4l2_object_format_get_rank (fb) -
      gst_v4l2_object_format_get_rank (fa);
}

/******************************************************
 * gst_v4l2_object_fill_format_list():
 *   create list of supported capture formats
 * return value: TRUE on success, FALSE on error
 ******************************************************/
static gboolean
gst_v4l2_object_fill_format_list (GstV4l2Object * v4l2object,
    enum v4l2_buf_type type)
{
  gint n;
  struct v4l2_fmtdesc *format;

  GST_DEBUG_OBJECT (v4l2object->element, "getting src format enumerations");

  /* format enumeration */
  for (n = 0;; n++) {
    format = g_new0 (struct v4l2_fmtdesc, 1);

    format->index = n;
    format->type = type;

    if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_ENUM_FMT, format) < 0) {
      if (errno == EINVAL) {
        g_free (format);
        break;                  /* end of enumeration */
      } else {
        goto failed;
      }
    }

    GST_LOG_OBJECT (v4l2object->element, "index:       %u", format->index);
    GST_LOG_OBJECT (v4l2object->element, "type:        %d", format->type);
    GST_LOG_OBJECT (v4l2object->element, "flags:       %08x", format->flags);
    GST_LOG_OBJECT (v4l2object->element, "description: '%s'",
        format->description);
    GST_LOG_OBJECT (v4l2object->element, "pixelformat: %" GST_FOURCC_FORMAT,
        GST_FOURCC_ARGS (format->pixelformat));

    /* sort formats according to our preference;  we do this, because caps
     * are probed in the order the formats are in the list, and the order of
     * formats in the final probed caps matters for things like fixation */
    v4l2object->formats = g_slist_insert_sorted (v4l2object->formats, format,
        (GCompareFunc) format_cmp_func);
  }

#ifndef GST_DISABLE_GST_DEBUG
  {
    GSList *l;

    GST_INFO_OBJECT (v4l2object->element, "got %d format(s):", n);
    for (l = v4l2object->formats; l != NULL; l = l->next) {
      format = l->data;

      GST_INFO_OBJECT (v4l2object->element,
          "  %" GST_FOURCC_FORMAT "%s", GST_FOURCC_ARGS (format->pixelformat),
          ((format->flags & V4L2_FMT_FLAG_EMULATED)) ? " (emulated)" : "");
    }
  }
#endif

  return TRUE;

  /* ERRORS */
failed:
  {
    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
        (_("Failed to enumerate possible video formats device '%s' can work with"), v4l2object->videodev), ("Failed to get number %d in pixelformat enumeration for %s. (%d - %s)", n, v4l2object->videodev, errno, g_strerror (errno)));
    g_free (format);
    return FALSE;
  }
}

/*
  * Get the list of supported capture formats, a list of
  * <code>struct v4l2_fmtdesc</code>.
  */
static GSList *
gst_v4l2_object_get_format_list (GstV4l2Object * v4l2object)
{
  if (!v4l2object->formats) {

    /* check usual way */
    gst_v4l2_object_fill_format_list (v4l2object, v4l2object->type);

    /* if our driver supports multi-planar
     * and if formats are still empty then we can workaround driver bug
     * by also looking up formats as if our device was not supporting
     * multiplanar */
    if (!v4l2object->formats) {
      switch (v4l2object->type) {
        case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
          gst_v4l2_object_fill_format_list (v4l2object,
              V4L2_BUF_TYPE_VIDEO_CAPTURE);
          break;

        case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
          gst_v4l2_object_fill_format_list (v4l2object,
              V4L2_BUF_TYPE_VIDEO_OUTPUT);
          break;

        default:
          break;
      }
    }
  }
  return v4l2object->formats;
}

static GstVideoFormat
gst_v4l2_object_v4l2fourcc_to_video_format (guint32 fourcc)
{
  GstVideoFormat format;

  switch (fourcc) {
    case V4L2_PIX_FMT_GREY:    /*  8  Greyscale     */
      format = GST_VIDEO_FORMAT_GRAY8;
      break;
    case V4L2_PIX_FMT_RGB555:
      format = GST_VIDEO_FORMAT_RGB15;
      break;
    case V4L2_PIX_FMT_RGB565:
      format = GST_VIDEO_FORMAT_RGB16;
      break;
    case V4L2_PIX_FMT_RGB24:
      format = GST_VIDEO_FORMAT_RGB;
      break;
    case V4L2_PIX_FMT_BGR24:
      format = GST_VIDEO_FORMAT_BGR;
      break;
    case V4L2_PIX_FMT_RGB32:
      format = GST_VIDEO_FORMAT_xRGB;
      break;
    case V4L2_PIX_FMT_BGR32:
      format = GST_VIDEO_FORMAT_BGRx;
      break;
    case V4L2_PIX_FMT_NV12:
    case V4L2_PIX_FMT_NV12M:
      format = GST_VIDEO_FORMAT_NV12;
      break;
    case V4L2_PIX_FMT_NV12MT:
      format = GST_VIDEO_FORMAT_NV12_64Z32;
      break;
    case V4L2_PIX_FMT_NV21:
    case V4L2_PIX_FMT_NV21M:
      format = GST_VIDEO_FORMAT_NV21;
      break;
    case V4L2_PIX_FMT_YVU410:
      format = GST_VIDEO_FORMAT_YVU9;
      break;
    case V4L2_PIX_FMT_YUV410:
      format = GST_VIDEO_FORMAT_YUV9;
      break;
    case V4L2_PIX_FMT_YUV420:
      format = GST_VIDEO_FORMAT_I420;
      break;
    case V4L2_PIX_FMT_YUYV:
      format = GST_VIDEO_FORMAT_YUY2;
      break;
    case V4L2_PIX_FMT_YVU420:
      format = GST_VIDEO_FORMAT_YV12;
      break;
    case V4L2_PIX_FMT_UYVY:
      format = GST_VIDEO_FORMAT_UYVY;
      break;
#if 0
    case V4L2_PIX_FMT_Y41P:
      format = GST_VIDEO_FORMAT_Y41P;
      break;
#endif
    case V4L2_PIX_FMT_YUV411P:
      format = GST_VIDEO_FORMAT_Y41B;
      break;
    case V4L2_PIX_FMT_YUV422P:
      format = GST_VIDEO_FORMAT_Y42B;
      break;
    case V4L2_PIX_FMT_YVYU:
      format = GST_VIDEO_FORMAT_YVYU;
      break;
    default:
      format = GST_VIDEO_FORMAT_UNKNOWN;
      break;
  }

  return format;
}

static GstStructure *
gst_v4l2_object_v4l2fourcc_to_bare_struct (guint32 fourcc)
{
  GstStructure *structure = NULL;

  switch (fourcc) {
    case V4L2_PIX_FMT_MJPEG:   /* Motion-JPEG */
    case V4L2_PIX_FMT_PJPG:    /* Progressive-JPEG */
    case V4L2_PIX_FMT_JPEG:    /* JFIF JPEG */
      structure = gst_structure_new_empty ("image/jpeg");
      break;
    case V4L2_PIX_FMT_YYUV:    /* 16  YUV 4:2:2     */
    case V4L2_PIX_FMT_HI240:   /*  8  8-bit color   */
      /* FIXME: get correct fourccs here */
      break;
    case V4L2_PIX_FMT_MPEG1:
      structure = gst_structure_new ("video/mpeg",
          "mpegversion", G_TYPE_INT, 2, NULL);
      break;
    case V4L2_PIX_FMT_MPEG2:
      structure = gst_structure_new ("video/mpeg",
          "mpegversion", G_TYPE_INT, 2, NULL);
      break;
    case V4L2_PIX_FMT_MPEG4:
      structure = gst_structure_new ("video/mpeg",
          "mpegversion", G_TYPE_INT, 4, "systemstream",
          G_TYPE_BOOLEAN, FALSE, NULL);
      break;
    case V4L2_PIX_FMT_H263:
      structure = gst_structure_new ("video/x-h263",
          "variant", G_TYPE_STRING, "itu", NULL);
      break;
    case V4L2_PIX_FMT_H264:    /* H.264 */
      structure = gst_structure_new ("video/x-h264",
          "stream-format", G_TYPE_STRING, "byte-stream", "alignment",
          G_TYPE_STRING, "au", NULL);
      break;
    case V4L2_PIX_FMT_VP8:
      structure = gst_structure_new_empty ("video/x-vp8");
      break;
    case V4L2_PIX_FMT_RGB332:
    case V4L2_PIX_FMT_RGB555X:
    case V4L2_PIX_FMT_RGB565X:
      /* FIXME: get correct fourccs here */
      break;
    case V4L2_PIX_FMT_GREY:    /*  8  Greyscale     */
    case V4L2_PIX_FMT_RGB555:
    case V4L2_PIX_FMT_RGB565:
    case V4L2_PIX_FMT_RGB24:
    case V4L2_PIX_FMT_BGR24:
    case V4L2_PIX_FMT_RGB32:
    case V4L2_PIX_FMT_BGR32:
    case V4L2_PIX_FMT_NV12:    /* 12  Y/CbCr 4:2:0  */
    case V4L2_PIX_FMT_NV12M:
    case V4L2_PIX_FMT_NV12MT:
    case V4L2_PIX_FMT_NV21:    /* 12  Y/CrCb 4:2:0  */
    case V4L2_PIX_FMT_NV21M:
    case V4L2_PIX_FMT_YVU410:
    case V4L2_PIX_FMT_YUV410:
    case V4L2_PIX_FMT_YUV420:  /* I420/IYUV */
    case V4L2_PIX_FMT_YUYV:
    case V4L2_PIX_FMT_YVU420:
    case V4L2_PIX_FMT_UYVY:
#if 0
    case V4L2_PIX_FMT_Y41P:
#endif
    case V4L2_PIX_FMT_YUV422P:
    case V4L2_PIX_FMT_YVYU:
    case V4L2_PIX_FMT_YUV411P:{
      GstVideoFormat format;
      format = gst_v4l2_object_v4l2fourcc_to_video_format (fourcc);
      if (format != GST_VIDEO_FORMAT_UNKNOWN)
        structure = gst_structure_new ("video/x-raw",
            "format", G_TYPE_STRING, gst_video_format_to_string (format), NULL);
      break;
    }
    case V4L2_PIX_FMT_DV:
      structure =
          gst_structure_new ("video/x-dv", "systemstream", G_TYPE_BOOLEAN, TRUE,
          NULL);
      break;
    case V4L2_PIX_FMT_MPEG:    /* MPEG          */
      structure = gst_structure_new ("video/mpegts",
          "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
      break;
    case V4L2_PIX_FMT_WNVA:    /* Winnov hw compres */
      break;
    case V4L2_PIX_FMT_SBGGR8:
    case V4L2_PIX_FMT_SGBRG8:
    case V4L2_PIX_FMT_SGRBG8:
    case V4L2_PIX_FMT_SRGGB8:
      structure = gst_structure_new ("video/x-bayer", "format", G_TYPE_STRING,
          fourcc == V4L2_PIX_FMT_SBGGR8 ? "bggr" :
          fourcc == V4L2_PIX_FMT_SGBRG8 ? "gbrg" :
          fourcc == V4L2_PIX_FMT_SGRBG8 ? "grbg" :
          /* fourcc == V4L2_PIX_FMT_SRGGB8 ? */ "rggb", NULL);
      break;
    case V4L2_PIX_FMT_SN9C10X:
      structure = gst_structure_new_empty ("video/x-sonix");
      break;
    case V4L2_PIX_FMT_PWC1:
      structure = gst_structure_new_empty ("video/x-pwc1");
      break;
    case V4L2_PIX_FMT_PWC2:
      structure = gst_structure_new_empty ("video/x-pwc2");
      break;
    default:
      GST_DEBUG ("Unknown fourcc 0x%08x %" GST_FOURCC_FORMAT,
          fourcc, GST_FOURCC_ARGS (fourcc));
      break;
  }

  return structure;
}

GstStructure *
gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc)
{
  GstStructure *template;
  gint i;

  template = gst_v4l2_object_v4l2fourcc_to_bare_struct (fourcc);

  if (template == NULL)
    goto done;

  for (i = 0; i < GST_V4L2_FORMAT_COUNT; i++) {
    if (gst_v4l2_formats[i].format != fourcc)
      continue;

    if (gst_v4l2_formats[i].dimensions) {
      gst_structure_set (template,
          "width", GST_TYPE_INT_RANGE, 1, GST_V4L2_MAX_SIZE,
          "height", GST_TYPE_INT_RANGE, 1, GST_V4L2_MAX_SIZE,
          "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 100, 1, NULL);
    }
    break;
  }

done:
  return template;
}


static GstCaps *
gst_v4l2_object_get_caps_helper (GstV4L2FormatFlags flags)
{
  GstStructure *structure;
  GstCaps *caps;
  guint i;

  caps = gst_caps_new_empty ();
  for (i = 0; i < GST_V4L2_FORMAT_COUNT; i++) {

    if ((gst_v4l2_formats[i].flags & flags) == 0)
      continue;

    structure =
        gst_v4l2_object_v4l2fourcc_to_bare_struct (gst_v4l2_formats[i].format);

    if (structure) {
      GstStructure *alt_s = NULL;

      if (gst_v4l2_formats[i].dimensions) {
        gst_structure_set (structure,
            "width", GST_TYPE_INT_RANGE, 1, GST_V4L2_MAX_SIZE,
            "height", GST_TYPE_INT_RANGE, 1, GST_V4L2_MAX_SIZE,
            "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 100, 1, NULL);
      }

      switch (gst_v4l2_formats[i].format) {
        case V4L2_PIX_FMT_RGB32:
          alt_s = gst_structure_copy (structure);
          gst_structure_set (alt_s, "format", G_TYPE_STRING, "ARGB", NULL);
          break;
        case V4L2_PIX_FMT_BGR32:
          alt_s = gst_structure_copy (structure);
          gst_structure_set (alt_s, "format", G_TYPE_STRING, "BGRA", NULL);
        default:
          break;
      }

      gst_caps_append_structure (caps, structure);

      if (alt_s)
        gst_caps_append_structure (caps, alt_s);
    }
  }

  return gst_caps_simplify (caps);
}

GstCaps *
gst_v4l2_object_get_all_caps (void)
{
  static GstCaps *caps = NULL;

  if (caps == NULL)
    caps = gst_v4l2_object_get_caps_helper (GST_V4L2_ALL);

  return gst_caps_ref (caps);
}

GstCaps *
gst_v4l2_object_get_raw_caps (void)
{
  static GstCaps *caps = NULL;

  if (caps == NULL)
    caps = gst_v4l2_object_get_caps_helper (GST_V4L2_RAW);

  return gst_caps_ref (caps);
}

GstCaps *
gst_v4l2_object_get_codec_caps (void)
{
  static GstCaps *caps = NULL;

  if (caps == NULL)
    caps = gst_v4l2_object_get_caps_helper (GST_V4L2_CODEC);

  return gst_caps_ref (caps);
}

/* collect data for the given caps
 * @caps: given input caps
 * @format: location for the v4l format
 * @w/@h: location for width and height
 * @fps_n/@fps_d: location for framerate
 * @size: location for expected size of the frame or 0 if unknown
 */
static gboolean
gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
    struct v4l2_fmtdesc **format, GstVideoInfo * info)
{
  GstStructure *structure;
  guint32 fourcc = 0, fourcc_nc = 0;
  const gchar *mimetype;
  struct v4l2_fmtdesc *fmt = NULL;

  structure = gst_caps_get_structure (caps, 0);

  mimetype = gst_structure_get_name (structure);

  if (!gst_video_info_from_caps (info, caps))
    goto invalid_format;

  if (g_str_equal (mimetype, "video/x-raw")) {
    switch (GST_VIDEO_INFO_FORMAT (info)) {
      case GST_VIDEO_FORMAT_I420:
        fourcc = V4L2_PIX_FMT_YUV420;
        break;
      case GST_VIDEO_FORMAT_YUY2:
        fourcc = V4L2_PIX_FMT_YUYV;
        break;
#if 0
      case GST_VIDEO_FORMAT_Y41P:
        fourcc = V4L2_PIX_FMT_Y41P;
        break;
#endif
      case GST_VIDEO_FORMAT_UYVY:
        fourcc = V4L2_PIX_FMT_UYVY;
        break;
      case GST_VIDEO_FORMAT_YV12:
        fourcc = V4L2_PIX_FMT_YVU420;
        break;
      case GST_VIDEO_FORMAT_Y41B:
        fourcc = V4L2_PIX_FMT_YUV411P;
        break;
      case GST_VIDEO_FORMAT_Y42B:
        fourcc = V4L2_PIX_FMT_YUV422P;
        break;
      case GST_VIDEO_FORMAT_NV12:
        fourcc = V4L2_PIX_FMT_NV12;
        fourcc_nc = V4L2_PIX_FMT_NV12M;
        break;
      case GST_VIDEO_FORMAT_NV12_64Z32:
        fourcc_nc = V4L2_PIX_FMT_NV12MT;
        break;
      case GST_VIDEO_FORMAT_NV21:
        fourcc = V4L2_PIX_FMT_NV21;
        fourcc_nc = V4L2_PIX_FMT_NV21M;
        break;
      case GST_VIDEO_FORMAT_YVYU:
        fourcc = V4L2_PIX_FMT_YVYU;
        break;
      case GST_VIDEO_FORMAT_RGB15:
        fourcc = V4L2_PIX_FMT_RGB555;
        break;
      case GST_VIDEO_FORMAT_RGB16:
        fourcc = V4L2_PIX_FMT_RGB565;
        break;
      case GST_VIDEO_FORMAT_RGB:
        fourcc = V4L2_PIX_FMT_RGB24;
        break;
      case GST_VIDEO_FORMAT_BGR:
        fourcc = V4L2_PIX_FMT_BGR24;
        break;
      case GST_VIDEO_FORMAT_xRGB:
      case GST_VIDEO_FORMAT_ARGB:
        fourcc = V4L2_PIX_FMT_RGB32;
        break;
      case GST_VIDEO_FORMAT_BGRx:
      case GST_VIDEO_FORMAT_BGRA:
        fourcc = V4L2_PIX_FMT_BGR32;
        break;
      case GST_VIDEO_FORMAT_GRAY8:
        fourcc = V4L2_PIX_FMT_GREY;
      default:
        break;
    }
  } else {
    if (g_str_equal (mimetype, "video/mpegts")) {
      fourcc = V4L2_PIX_FMT_MPEG;
    } else if (g_str_equal (mimetype, "video/x-dv")) {
      fourcc = V4L2_PIX_FMT_DV;
    } else if (g_str_equal (mimetype, "image/jpeg")) {
      fourcc = V4L2_PIX_FMT_JPEG;
    } else if (g_str_equal (mimetype, "video/mpeg")) {
      gint version;
      if (gst_structure_get_int (structure, "mpegversion", &version)) {
        switch (version) {
          case 1:
            fourcc = V4L2_PIX_FMT_MPEG1;
            break;
          case 2:
            fourcc = V4L2_PIX_FMT_MPEG2;
            break;
          case 4:
            fourcc = V4L2_PIX_FMT_MPEG4;
            break;
          default:
            break;
        }
      }
    } else if (g_str_equal (mimetype, "video/x-h263")) {
      fourcc = V4L2_PIX_FMT_H263;
    } else if (g_str_equal (mimetype, "video/x-h264")) {
      fourcc = V4L2_PIX_FMT_H264;
    } else if (g_str_equal (mimetype, "video/x-vp8")) {
      fourcc = V4L2_PIX_FMT_VP8;
    } else if (g_str_equal (mimetype, "video/x-bayer")) {
      fourcc = V4L2_PIX_FMT_SBGGR8;
    } else if (g_str_equal (mimetype, "video/x-sonix")) {
      fourcc = V4L2_PIX_FMT_SN9C10X;
    } else if (g_str_equal (mimetype, "video/x-pwc1")) {
      fourcc = V4L2_PIX_FMT_PWC1;
    } else if (g_str_equal (mimetype, "video/x-pwc2")) {
      fourcc = V4L2_PIX_FMT_PWC2;
    }
  }


  /* Prefer the non-contiguous if supported */
  v4l2object->prefered_non_contiguous = TRUE;

  if (fourcc_nc)
    fmt = gst_v4l2_object_get_format_from_fourcc (v4l2object, fourcc_nc);
  else if (fourcc == 0)
    goto unhandled_format;

  if (fmt == NULL) {
    fmt = gst_v4l2_object_get_format_from_fourcc (v4l2object, fourcc);
    v4l2object->prefered_non_contiguous = FALSE;
  }

  if (fmt == NULL)
    goto unsupported_format;

  *format = fmt;

  return TRUE;

  /* ERRORS */
invalid_format:
  {
    GST_DEBUG_OBJECT (v4l2object, "invalid format");
    return FALSE;
  }
unhandled_format:
  {
    GST_DEBUG_OBJECT (v4l2object, "unhandled format");
    return FALSE;
  }
unsupported_format:
  {
    GST_DEBUG_OBJECT (v4l2object, "unsupported format");
    return FALSE;
  }
}

static gboolean
gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
    guint32 pixelformat, gint * width, gint * height);

static void
gst_v4l2_object_add_aspect_ratio (GstV4l2Object * v4l2object, GstStructure * s)
{
  struct v4l2_cropcap cropcap;
  int num = 1, den = 1;

  if (!v4l2object->keep_aspect)
    return;

  if (v4l2object->par) {
    num = gst_value_get_fraction_numerator (v4l2object->par);
    den = gst_value_get_fraction_denominator (v4l2object->par);
    goto done;
  }

  memset (&cropcap, 0, sizeof (cropcap));

  cropcap.type = v4l2object->type;
  if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_CROPCAP, &cropcap) < 0)
    goto cropcap_failed;

  num = cropcap.pixelaspect.numerator;
  den = cropcap.pixelaspect.denominator;

  /* Ignore PAR that are 0/0 */
  if (den == 0)
    return;

done:
  gst_structure_set (s, "pixel-aspect-ratio", GST_TYPE_FRACTION, num, den,
      NULL);
  return;

cropcap_failed:
  if (errno != ENOTTY)
    GST_WARNING_OBJECT (v4l2object->element,
        "Failed to probe pixel aspect ratio with VIDIOC_CROPCAP: %s",
        g_strerror (errno));
  goto done;
}

/* returns TRUE if the value was changed in place, otherwise FALSE */
static gboolean
gst_v4l2src_value_simplify (GValue * val)
{
  /* simplify list of one value to one value */
  if (GST_VALUE_HOLDS_LIST (val) && gst_value_list_get_size (val) == 1) {
    const GValue *list_val;
    GValue new_val = G_VALUE_INIT;

    list_val = gst_value_list_get_value (val, 0);
    g_value_init (&new_val, G_VALUE_TYPE (list_val));
    g_value_copy (list_val, &new_val);
    g_value_unset (val);
    *val = new_val;
    return TRUE;
  }

  return FALSE;
}

static gboolean
gst_v4l2_object_get_interlace_mode (enum v4l2_field field,
    GstVideoInterlaceMode * interlace_mode)
{
  /* NB: If you add new return values, please fix mode_strings in
   * gst_v4l2_object_add_interlace_mode */
  switch (field) {
    case V4L2_FIELD_ANY:
      GST_ERROR
          ("Driver bug detected - check driver with v4l2-compliance from http://git.linuxtv.org/v4l-utils.git\n");
      /* fallthrough */
    case V4L2_FIELD_NONE:
      *interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
      return TRUE;
    case V4L2_FIELD_INTERLACED:
    case V4L2_FIELD_INTERLACED_TB:
    case V4L2_FIELD_INTERLACED_BT:
      *interlace_mode = GST_VIDEO_INTERLACE_MODE_INTERLEAVED;
      return TRUE;
    default:
      GST_ERROR ("Unknown enum v4l2_field %d", field);
      return FALSE;
  }
}

static gboolean
gst_v4l2_object_get_colorspace (enum v4l2_colorspace colorspace,
    GstVideoColorimetry * cinfo)
{
  gboolean ret = FALSE;

  switch (colorspace) {
    case V4L2_COLORSPACE_SMPTE170M:
      ret = gst_video_colorimetry_from_string (cinfo,
          GST_VIDEO_COLORIMETRY_BT601);
      break;
    case V4L2_COLORSPACE_REC709:
      ret = gst_video_colorimetry_from_string (cinfo,
          GST_VIDEO_COLORIMETRY_BT709);
      break;
    case V4L2_COLORSPACE_SMPTE240M:
      ret = gst_video_colorimetry_from_string (cinfo,
          GST_VIDEO_COLORIMETRY_SMPTE240M);
      break;
    case V4L2_COLORSPACE_SRGB:
      ret = gst_video_colorimetry_from_string (cinfo,
          GST_VIDEO_COLORIMETRY_SRGB);
      break;
    default:
      GST_DEBUG ("Unknown enum v4l2_colorspace %d", colorspace);
      ret = FALSE;
      break;
  }
  return ret;
}

static int
gst_v4l2_object_try_fmt (GstV4l2Object * v4l2object,
    struct v4l2_format *try_fmt)
{
  int fd = v4l2object->video_fd;
  struct v4l2_format fmt;
  int r;

  memcpy (&fmt, try_fmt, sizeof (fmt));
  r = v4l2_ioctl (fd, VIDIOC_TRY_FMT, &fmt);

  if (r < 0 && errno == ENOTTY) {
    /* The driver might not implement TRY_FMT, in which case we will try
       S_FMT to probe */
    if (GST_V4L2_IS_ACTIVE (v4l2object))
      goto error;

    memcpy (&fmt, try_fmt, sizeof (fmt));
    r = v4l2_ioctl (fd, VIDIOC_S_FMT, &fmt);
  }
  memcpy (try_fmt, &fmt, sizeof (fmt));
  return r;

error:
  memcpy (try_fmt, &fmt, sizeof (fmt));
  GST_WARNING_OBJECT (v4l2object->element,
      "Unable to try format: %s", g_strerror (errno));
  return r;
}


static void
gst_v4l2_object_add_interlace_mode (GstV4l2Object * v4l2object,
    GstStructure * s, guint32 width, guint32 height, guint32 pixelformat)
{
  struct v4l2_format fmt;
  GValue interlace_formats = { 0, };
  GstVideoInterlaceMode interlace_mode;

  const gchar *mode_strings[] = { "progressive",
    "interleaved",
    "mixed"
  };

  if (!g_str_equal (gst_structure_get_name (s), "video/x-raw"))
    return;

  if (v4l2object->never_interlaced) {
    gst_structure_set (s, "interlace-mode", G_TYPE_STRING, "progressive", NULL);
    return;
  }

  g_value_init (&interlace_formats, GST_TYPE_LIST);

  /* Try twice - once for NONE, once for INTERLACED. */
  memset (&fmt, 0, sizeof (fmt));
  fmt.type = v4l2object->type;
  fmt.fmt.pix.width = width;
  fmt.fmt.pix.height = height;
  fmt.fmt.pix.pixelformat = pixelformat;
  fmt.fmt.pix.field = V4L2_FIELD_NONE;

  if (gst_v4l2_object_try_fmt (v4l2object, &fmt) == 0 &&
      gst_v4l2_object_get_interlace_mode (fmt.fmt.pix.field, &interlace_mode)) {
    GValue interlace_enum = { 0, };
    g_value_init (&interlace_enum, G_TYPE_STRING);
    g_value_set_string (&interlace_enum, mode_strings[interlace_mode]);
    gst_value_list_append_and_take_value (&interlace_formats, &interlace_enum);
  }

  memset (&fmt, 0, sizeof (fmt));
  fmt.type = v4l2object->type;
  fmt.fmt.pix.width = width;
  fmt.fmt.pix.height = height;
  fmt.fmt.pix.pixelformat = pixelformat;
  fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;

  if (gst_v4l2_object_try_fmt (v4l2object, &fmt) == 0 &&
      gst_v4l2_object_get_interlace_mode (fmt.fmt.pix.field, &interlace_mode)) {
    GValue interlace_enum = { 0, };
    g_value_init (&interlace_enum, G_TYPE_STRING);
    g_value_set_string (&interlace_enum, mode_strings[interlace_mode]);
    gst_value_list_append_and_take_value (&interlace_formats, &interlace_enum);
  }

  gst_v4l2src_value_simplify (&interlace_formats);
  gst_structure_take_value (s, "interlace-mode", &interlace_formats);
  return;
}

static void
gst_v4l2_object_add_colorspace (GstV4l2Object * v4l2object, GstStructure * s,
    guint32 width, guint32 height, guint32 pixelformat)
{
  struct v4l2_format fmt;
  GValue colorimetry = G_VALUE_INIT;
  GstVideoColorimetry cinfo;

  memset (&fmt, 0, sizeof (fmt));
  fmt.type = v4l2object->type;
  fmt.fmt.pix.width = width;
  fmt.fmt.pix.height = height;
  fmt.fmt.pix.pixelformat = pixelformat;

  if (gst_v4l2_object_try_fmt (v4l2object, &fmt) == 0) {
    enum v4l2_colorspace colorspace;

    if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type))
      colorspace = fmt.fmt.pix_mp.colorspace;
    else
      colorspace = fmt.fmt.pix.colorspace;

    if (gst_v4l2_object_get_colorspace (colorspace, &cinfo)) {
      g_value_init (&colorimetry, G_TYPE_STRING);
      g_value_take_string (&colorimetry,
          gst_video_colorimetry_to_string (&cinfo));
      gst_structure_take_value (s, "colorimetry", &colorimetry);
    }
  }

  return;
}

/* The frame interval enumeration code first appeared in Linux 2.6.19. */
static GstStructure *
gst_v4l2_object_probe_caps_for_format_and_size (GstV4l2Object * v4l2object,
    guint32 pixelformat,
    guint32 width, guint32 height, const GstStructure * template)
{
  gint fd = v4l2object->video_fd;
  struct v4l2_frmivalenum ival;
  guint32 num, denom;
  GstStructure *s;
  GValue rates = { 0, };

  memset (&ival, 0, sizeof (struct v4l2_frmivalenum));
  ival.index = 0;
  ival.pixel_format = pixelformat;
  ival.width = width;
  ival.height = height;

  GST_LOG_OBJECT (v4l2object->element,
      "get frame interval for %ux%u, %" GST_FOURCC_FORMAT, width, height,
      GST_FOURCC_ARGS (pixelformat));

  /* keep in mind that v4l2 gives us frame intervals (durations); we invert the
   * fraction to get framerate */
  if (v4l2_ioctl (fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) < 0)
    goto enum_frameintervals_failed;

  if (ival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
    GValue rate = { 0, };

    g_value_init (&rates, GST_TYPE_LIST);
    g_value_init (&rate, GST_TYPE_FRACTION);

    do {
      num = ival.discrete.numerator;
      denom = ival.discrete.denominator;

      if (num > G_MAXINT || denom > G_MAXINT) {
        /* let us hope we don't get here... */
        num >>= 1;
        denom >>= 1;
      }

      GST_LOG_OBJECT (v4l2object->element, "adding discrete framerate: %d/%d",
          denom, num);

      /* swap to get the framerate */
      gst_value_set_fraction (&rate, denom, num);
      gst_value_list_append_value (&rates, &rate);

      ival.index++;
    } while (v4l2_ioctl (fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) >= 0);
  } else if (ival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
    GValue min = { 0, };
    GValue step = { 0, };
    GValue max = { 0, };
    gboolean added = FALSE;
    guint32 minnum, mindenom;
    guint32 maxnum, maxdenom;

    g_value_init (&rates, GST_TYPE_LIST);

    g_value_init (&min, GST_TYPE_FRACTION);
    g_value_init (&step, GST_TYPE_FRACTION);
    g_value_init (&max, GST_TYPE_FRACTION);

    /* get the min */
    minnum = ival.stepwise.min.numerator;
    mindenom = ival.stepwise.min.denominator;
    if (minnum > G_MAXINT || mindenom > G_MAXINT) {
      minnum >>= 1;
      mindenom >>= 1;
    }
    GST_LOG_OBJECT (v4l2object->element, "stepwise min frame interval: %d/%d",
        minnum, mindenom);
    gst_value_set_fraction (&min, minnum, mindenom);

    /* get the max */
    maxnum = ival.stepwise.max.numerator;
    maxdenom = ival.stepwise.max.denominator;
    if (maxnum > G_MAXINT || maxdenom > G_MAXINT) {
      maxnum >>= 1;
      maxdenom >>= 1;
    }

    GST_LOG_OBJECT (v4l2object->element, "stepwise max frame interval: %d/%d",
        maxnum, maxdenom);
    gst_value_set_fraction (&max, maxnum, maxdenom);

    /* get the step */
    num = ival.stepwise.step.numerator;
    denom = ival.stepwise.step.denominator;
    if (num > G_MAXINT || denom > G_MAXINT) {
      num >>= 1;
      denom >>= 1;
    }

    if (num == 0 || denom == 0) {
      /* in this case we have a wrong fraction or no step, set the step to max
       * so that we only add the min value in the loop below */
      num = maxnum;
      denom = maxdenom;
    }

    /* since we only have gst_value_fraction_subtract and not add, negate the
     * numerator */
    GST_LOG_OBJECT (v4l2object->element, "stepwise step frame interval: %d/%d",
        num, denom);
    gst_value_set_fraction (&step, -num, denom);

    while (gst_value_compare (&min, &max) != GST_VALUE_GREATER_THAN) {
      GValue rate = { 0, };

      num = gst_value_get_fraction_numerator (&min);
      denom = gst_value_get_fraction_denominator (&min);
      GST_LOG_OBJECT (v4l2object->element, "adding stepwise framerate: %d/%d",
          denom, num);

      /* invert to get the framerate */
      g_value_init (&rate, GST_TYPE_FRACTION);
      gst_value_set_fraction (&rate, denom, num);
      gst_value_list_append_value (&rates, &rate);
      added = TRUE;

      /* we're actually adding because step was negated above. This is because
       * there is no _add function... */
      if (!gst_value_fraction_subtract (&min, &min, &step)) {
        GST_WARNING_OBJECT (v4l2object->element, "could not step fraction!");
        break;
      }
    }
    if (!added) {
      /* no range was added, leave the default range from the template */
      GST_WARNING_OBJECT (v4l2object->element,
          "no range added, leaving default");
      g_value_unset (&rates);
    }
  } else if (ival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) {
    guint32 maxnum, maxdenom;

    g_value_init (&rates, GST_TYPE_FRACTION_RANGE);

    num = ival.stepwise.min.numerator;
    denom = ival.stepwise.min.denominator;
    if (num > G_MAXINT || denom > G_MAXINT) {
      num >>= 1;
      denom >>= 1;
    }

    maxnum = ival.stepwise.max.numerator;
    maxdenom = ival.stepwise.max.denominator;
    if (maxnum > G_MAXINT || maxdenom > G_MAXINT) {
      maxnum >>= 1;
      maxdenom >>= 1;
    }

    GST_LOG_OBJECT (v4l2object->element,
        "continuous frame interval %d/%d to %d/%d", maxdenom, maxnum, denom,
        num);

    gst_value_set_fraction_range_full (&rates, maxdenom, maxnum, denom, num);
  } else {
    goto unknown_type;
  }

return_data:
  s = gst_structure_copy (template);
  gst_structure_set (s, "width", G_TYPE_INT, (gint) width,
      "height", G_TYPE_INT, (gint) height, NULL);
  gst_v4l2_object_add_aspect_ratio (v4l2object, s);
  gst_v4l2_object_add_interlace_mode (v4l2object, s, width, height,
      pixelformat);
  gst_v4l2_object_add_colorspace (v4l2object, s, width, height, pixelformat);

  if (G_IS_VALUE (&rates)) {
    gst_v4l2src_value_simplify (&rates);
    /* only change the framerate on the template when we have a valid probed new
     * value */
    gst_structure_take_value (s, "framerate", &rates);
  } else if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
      v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
    gst_structure_set (s, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 100, 1,
        NULL);
  }
  return s;

  /* ERRORS */
enum_frameintervals_failed:
  {
    GST_DEBUG_OBJECT (v4l2object->element,
        "Unable to enumerate intervals for %" GST_FOURCC_FORMAT "@%ux%u",
        GST_FOURCC_ARGS (pixelformat), width, height);
    goto return_data;
  }
unknown_type:
  {
    /* I don't see how this is actually an error, we ignore the format then */
    GST_WARNING_OBJECT (v4l2object->element,
        "Unknown frame interval type at %" GST_FOURCC_FORMAT "@%ux%u: %u",
        GST_FOURCC_ARGS (pixelformat), width, height, ival.type);
    return NULL;
  }
}

static gint
sort_by_frame_size (GstStructure * s1, GstStructure * s2)
{
  int w1, h1, w2, h2;

  gst_structure_get_int (s1, "width", &w1);
  gst_structure_get_int (s1, "height", &h1);
  gst_structure_get_int (s2, "width", &w2);
  gst_structure_get_int (s2, "height", &h2);

  /* I think it's safe to assume that this won't overflow for a while */
  return ((w2 * h2) - (w1 * h1));
}

static void
gst_v4l2_object_update_and_append (GstV4l2Object * v4l2object,
    guint32 format, GstCaps * caps, GstStructure * s)
{
  GstStructure *alt_s = NULL;

  /* Encoded stream on output buffer need to be parsed */
  if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT ||
      v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
    gint i = 0;

    for (; i < GST_V4L2_FORMAT_COUNT; i++) {
      if (format == gst_v4l2_formats[i].format &&
          gst_v4l2_formats[i].flags & GST_V4L2_CODEC &&
          !(gst_v4l2_formats[i].flags & GST_V4L2_NO_PARSE)) {
        gst_structure_set (s, "parsed", G_TYPE_BOOLEAN, TRUE, NULL);
        break;
      }
    }
  }

  if (v4l2object->has_alpha_component &&
      (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
          v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) {
    switch (format) {
      case V4L2_PIX_FMT_RGB32:
        alt_s = gst_structure_copy (s);
        gst_structure_set (alt_s, "format", G_TYPE_STRING, "ARGB", NULL);
        break;
      case V4L2_PIX_FMT_BGR32:
        alt_s = gst_structure_copy (s);
        gst_structure_set (alt_s, "format", G_TYPE_STRING, "BGRA", NULL);
        break;
      default:
        break;
    }
  }

  gst_caps_append_structure (caps, s);

  if (alt_s)
    gst_caps_append_structure (caps, alt_s);
}

static GstCaps *
gst_v4l2_object_probe_caps_for_format (GstV4l2Object * v4l2object,
    guint32 pixelformat, const GstStructure * template)
{
  GstCaps *ret = gst_caps_new_empty ();
  GstStructure *tmp;
  gint fd = v4l2object->video_fd;
  struct v4l2_frmsizeenum size;
  GList *results = NULL;
  guint32 w, h;

  if (pixelformat == GST_MAKE_FOURCC ('M', 'P', 'E', 'G')) {
    gst_caps_append_structure (ret, gst_structure_copy (template));
    return ret;
  }

  memset (&size, 0, sizeof (struct v4l2_frmsizeenum));
  size.index = 0;
  size.pixel_format = pixelformat;

  GST_DEBUG_OBJECT (v4l2object->element,
      "Enumerating frame sizes for %" GST_FOURCC_FORMAT,
      GST_FOURCC_ARGS (pixelformat));

  if (v4l2_ioctl (fd, VIDIOC_ENUM_FRAMESIZES, &size) < 0)
    goto enum_framesizes_failed;

  if (size.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
    do {
      GST_LOG_OBJECT (v4l2object->element, "got discrete frame size %dx%d",
          size.discrete.width, size.discrete.height);

      w = MIN (size.discrete.width, G_MAXINT);
      h = MIN (size.discrete.height, G_MAXINT);

      if (w && h) {
        tmp =
            gst_v4l2_object_probe_caps_for_format_and_size (v4l2object,
            pixelformat, w, h, template);

        if (tmp)
          results = g_list_prepend (results, tmp);
      }

      size.index++;
    } while (v4l2_ioctl (fd, VIDIOC_ENUM_FRAMESIZES, &size) >= 0);
    GST_DEBUG_OBJECT (v4l2object->element,
        "done iterating discrete frame sizes");
  } else if (size.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
    guint32 maxw, maxh, step_w, step_h;

    GST_DEBUG_OBJECT (v4l2object->element, "we have stepwise frame sizes:");
    GST_DEBUG_OBJECT (v4l2object->element, "min width:   %d",
        size.stepwise.min_width);
    GST_DEBUG_OBJECT (v4l2object->element, "min height:  %d",
        size.stepwise.min_height);
    GST_DEBUG_OBJECT (v4l2object->element, "max width:   %d",
        size.stepwise.max_width);
    GST_DEBUG_OBJECT (v4l2object->element, "min height:  %d",
        size.stepwise.max_height);
    GST_DEBUG_OBJECT (v4l2object->element, "step width:  %d",
        size.stepwise.step_width);
    GST_DEBUG_OBJECT (v4l2object->element, "step height: %d",
        size.stepwise.step_height);

    w = MAX (size.stepwise.min_width, 1);
    h = MAX (size.stepwise.min_height, 1);
    maxw = MIN (size.stepwise.max_width, G_MAXINT);
    maxh = MIN (size.stepwise.max_height, G_MAXINT);

    step_w = MAX (size.stepwise.step_width, 1);
    step_h = MAX (size.stepwise.step_height, 1);

    /* FIXME: check for sanity and that min/max are multiples of the steps */

    /* we only query details for the max width/height since it's likely the
     * most restricted if there are any resolution-dependent restrictions */
    tmp = gst_v4l2_object_probe_caps_for_format_and_size (v4l2object,
        pixelformat, maxw, maxh, template);

    if (tmp) {
      GValue step_range = G_VALUE_INIT;

      g_value_init (&step_range, GST_TYPE_INT_RANGE);
      gst_value_set_int_range_step (&step_range, w, maxw, step_w);
      gst_structure_set_value (tmp, "width", &step_range);

      gst_value_set_int_range_step (&step_range, h, maxh, step_h);
      gst_structure_take_value (tmp, "height", &step_range);

      /* no point using the results list here, since there's only one struct */
      gst_v4l2_object_update_and_append (v4l2object, pixelformat, ret, tmp);
    }
  } else if (size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) {
    guint32 maxw, maxh;

    GST_DEBUG_OBJECT (v4l2object->element, "we have continuous frame sizes:");
    GST_DEBUG_OBJECT (v4l2object->element, "min width:   %d",
        size.stepwise.min_width);
    GST_DEBUG_OBJECT (v4l2object->element, "min height:  %d",
        size.stepwise.min_height);
    GST_DEBUG_OBJECT (v4l2object->element, "max width:   %d",
        size.stepwise.max_width);
    GST_DEBUG_OBJECT (v4l2object->element, "min height:  %d",
        size.stepwise.max_height);

    w = MAX (size.stepwise.min_width, 1);
    h = MAX (size.stepwise.min_height, 1);
    maxw = MIN (size.stepwise.max_width, G_MAXINT);
    maxh = MIN (size.stepwise.max_height, G_MAXINT);

    tmp =
        gst_v4l2_object_probe_caps_for_format_and_size (v4l2object, pixelformat,
        w, h, template);
    if (tmp) {
      gst_structure_set (tmp, "width", GST_TYPE_INT_RANGE, (gint) w,
          (gint) maxw, "height", GST_TYPE_INT_RANGE, (gint) h, (gint) maxh,
          NULL);

      /* no point using the results list here, since there's only one struct */
      gst_v4l2_object_update_and_append (v4l2object, pixelformat, ret, tmp);
    }
  } else {
    goto unknown_type;
  }

  /* we use an intermediary list to store and then sort the results of the
   * probing because we can't make any assumptions about the order in which
   * the driver will give us the sizes, but we want the final caps to contain
   * the results starting with the highest resolution and having the lowest
   * resolution last, since order in caps matters for things like fixation. */
  results = g_list_sort (results, (GCompareFunc) sort_by_frame_size);
  while (results != NULL) {
    gst_v4l2_object_update_and_append (v4l2object, pixelformat, ret,
        results->data);
    results = g_list_delete_link (results, results);
  }

  if (gst_caps_is_empty (ret))
    goto enum_framesizes_no_results;

  return ret;

  /* ERRORS */
enum_framesizes_failed:
  {
    /* I don't see how this is actually an error */
    GST_DEBUG_OBJECT (v4l2object->element,
        "Failed to enumerate frame sizes for pixelformat %" GST_FOURCC_FORMAT
        " (%s)", GST_FOURCC_ARGS (pixelformat), g_strerror (errno));
    goto default_frame_sizes;
  }
enum_framesizes_no_results:
  {
    /* it's possible that VIDIOC_ENUM_FRAMESIZES is defined but the driver in
     * question doesn't actually support it yet */
    GST_DEBUG_OBJECT (v4l2object->element,
        "No results for pixelformat %" GST_FOURCC_FORMAT
        " enumerating frame sizes, trying fallback",
        GST_FOURCC_ARGS (pixelformat));
    goto default_frame_sizes;
  }
unknown_type:
  {
    GST_WARNING_OBJECT (v4l2object->element,
        "Unknown frame sizeenum type for pixelformat %" GST_FOURCC_FORMAT
        ": %u", GST_FOURCC_ARGS (pixelformat), size.type);
    goto default_frame_sizes;
  }

default_frame_sizes:
  {
    gint min_w, max_w, min_h, max_h, fix_num = 0, fix_denom = 0;

    /* This code is for Linux < 2.6.19 */
    min_w = min_h = 1;
    max_w = max_h = GST_V4L2_MAX_SIZE;
    if (!gst_v4l2_object_get_nearest_size (v4l2object, pixelformat, &min_w,
            &min_h)) {
      GST_WARNING_OBJECT (v4l2object->element,
          "Could not probe minimum capture size for pixelformat %"
          GST_FOURCC_FORMAT, GST_FOURCC_ARGS (pixelformat));
    }
    if (!gst_v4l2_object_get_nearest_size (v4l2object, pixelformat, &max_w,
            &max_h)) {
      GST_WARNING_OBJECT (v4l2object->element,
          "Could not probe maximum capture size for pixelformat %"
          GST_FOURCC_FORMAT, GST_FOURCC_ARGS (pixelformat));
    }

    /* Since we can't get framerate directly, try to use the current norm */
    if (v4l2object->tv_norm && v4l2object->norms) {
      GList *norms;
      GstTunerNorm *norm = NULL;
      GstTunerNorm *current =
          gst_v4l2_tuner_get_norm_by_std_id (v4l2object, v4l2object->tv_norm);

      for (norms = v4l2object->norms; norms != NULL; norms = norms->next) {
        norm = (GstTunerNorm *) norms->data;
        if (!strcmp (norm->label, current->label))
          break;
      }
      /* If it's possible, set framerate to that (discrete) value */
      if (norm) {
        fix_num = gst_value_get_fraction_numerator (&norm->framerate);
        fix_denom = gst_value_get_fraction_denominator (&norm->framerate);
      }
    }

    tmp = gst_structure_copy (template);
    if (fix_num) {
      gst_structure_set (tmp, "framerate", GST_TYPE_FRACTION, fix_num,
          fix_denom, NULL);
    } else if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
        v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
      /* if norm can't be used, copy the template framerate */
      gst_structure_set (tmp, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
          100, 1, NULL);
    }

    if (min_w == max_w)
      gst_structure_set (tmp, "width", G_TYPE_INT, max_w, NULL);
    else
      gst_structure_set (tmp, "width", GST_TYPE_INT_RANGE, min_w, max_w, NULL);

    if (min_h == max_h)
      gst_structure_set (tmp, "height", G_TYPE_INT, max_h, NULL);
    else
      gst_structure_set (tmp, "height", GST_TYPE_INT_RANGE, min_h, max_h, NULL);

    /* We could consider setting interlace mode from min and max. */
    gst_v4l2_object_add_interlace_mode (v4l2object, tmp, max_w, max_h,
        pixelformat);
    gst_v4l2_object_add_aspect_ratio (v4l2object, tmp);
    /* We could consider to check colorspace for min too, in case it depends on
     * the size. But in this case, min and max could not be enough */
    gst_v4l2_object_add_colorspace (v4l2object, tmp, max_w, max_h, pixelformat);

    gst_v4l2_object_update_and_append (v4l2object, pixelformat, ret, tmp);
    return ret;
  }
}

static gboolean
gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
    guint32 pixelformat, gint * width, gint * height)
{
  struct v4l2_format fmt;
  gboolean ret = FALSE;
  GstVideoInterlaceMode interlace_mode;

  g_return_val_if_fail (width != NULL, FALSE);
  g_return_val_if_fail (height != NULL, FALSE);

  GST_LOG_OBJECT (v4l2object->element,
      "getting nearest size to %dx%d with format %" GST_FOURCC_FORMAT,
      *width, *height, GST_FOURCC_ARGS (pixelformat));

  memset (&fmt, 0, sizeof (struct v4l2_format));

  /* get size delimiters */
  memset (&fmt, 0, sizeof (fmt));
  fmt.type = v4l2object->type;
  fmt.fmt.pix.width = *width;
  fmt.fmt.pix.height = *height;
  fmt.fmt.pix.pixelformat = pixelformat;
  fmt.fmt.pix.field = V4L2_FIELD_ANY;

  if (gst_v4l2_object_try_fmt (v4l2object, &fmt) < 0)
    goto error;

  GST_LOG_OBJECT (v4l2object->element,
      "got nearest size %dx%d", fmt.fmt.pix.width, fmt.fmt.pix.height);

  *width = fmt.fmt.pix.width;
  *height = fmt.fmt.pix.height;

  if (!gst_v4l2_object_get_interlace_mode (fmt.fmt.pix.field, &interlace_mode)) {
    GST_WARNING_OBJECT (v4l2object->element,
        "Unsupported field type for %" GST_FOURCC_FORMAT "@%ux%u: %u",
        GST_FOURCC_ARGS (pixelformat), *width, *height, fmt.fmt.pix.field);
    goto error;
  }

  ret = TRUE;

error:
  if (!ret) {
    GST_WARNING_OBJECT (v4l2object->element,
        "Unable to try format: %s", g_strerror (errno));
  }

  return ret;
}

static gboolean
gst_v4l2_object_setup_pool (GstV4l2Object * v4l2object, GstCaps * caps)
{
  GstV4l2IOMode mode;

  GST_DEBUG_OBJECT (v4l2object->element, "initializing the %s system",
      V4L2_TYPE_IS_OUTPUT (v4l2object->type) ? "output" : "capture");

  GST_V4L2_CHECK_OPEN (v4l2object);
  GST_V4L2_CHECK_NOT_ACTIVE (v4l2object);

  /* find transport */
  mode = v4l2object->req_mode;

  if (v4l2object->vcap.capabilities & V4L2_CAP_READWRITE) {
    if (v4l2object->req_mode == GST_V4L2_IO_AUTO)
      mode = GST_V4L2_IO_RW;
  } else if (v4l2object->req_mode == GST_V4L2_IO_RW)
    goto method_not_supported;

  if (v4l2object->vcap.capabilities & V4L2_CAP_STREAMING) {
    if (v4l2object->req_mode == GST_V4L2_IO_AUTO)
      mode = GST_V4L2_IO_MMAP;
  } else if (v4l2object->req_mode == GST_V4L2_IO_MMAP)
    goto method_not_supported;

  /* if still no transport selected, error out */
  if (mode == GST_V4L2_IO_AUTO)
    goto no_supported_capture_method;

  GST_INFO_OBJECT (v4l2object->element, "accessing buffers via mode %d", mode);
  v4l2object->mode = mode;

  /* Map the buffers */
  GST_LOG_OBJECT (v4l2object->element, "initiating buffer pool");

  if (!(v4l2object->pool = gst_v4l2_buffer_pool_new (v4l2object, caps)))
    goto buffer_pool_new_failed;

  GST_V4L2_SET_ACTIVE (v4l2object);

  return TRUE;

  /* ERRORS */
buffer_pool_new_failed:
  {
    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, READ,
        (_("Could not map buffers from device '%s'"),
            v4l2object->videodev),
        ("Failed to create buffer pool: %s", g_strerror (errno)));
    return FALSE;
  }
method_not_supported:
  {
    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, READ,
        (_("The driver of device '%s' does not support the IO method %d"),
            v4l2object->videodev, mode), (NULL));
    return FALSE;
  }
no_supported_capture_method:
  {
    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, READ,
        (_("The driver of device '%s' does not support any known IO "
                "method."), v4l2object->videodev), (NULL));
    return FALSE;
  }
}

static void
gst_v4l2_object_set_stride (GstVideoInfo * info, GstVideoAlignment * align,
    gint plane, gint stride)
{
  const GstVideoFormatInfo *finfo = info->finfo;

  if (GST_VIDEO_FORMAT_INFO_IS_TILED (finfo)) {
    gint x_tiles, y_tiles, ws, hs, tile_height, padded_height;


    ws = GST_VIDEO_FORMAT_INFO_TILE_WS (finfo);
    hs = GST_VIDEO_FORMAT_INFO_TILE_HS (finfo);
    tile_height = 1 << hs;

    padded_height = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (finfo, plane,
        info->height + align->padding_top + align->padding_bottom);
    padded_height = GST_ROUND_UP_N (padded_height, tile_height);

    x_tiles = stride >> ws;
    y_tiles = padded_height >> hs;
    info->stride[plane] = GST_VIDEO_TILE_MAKE_STRIDE (x_tiles, y_tiles);
  } else {
    info->stride[plane] = stride;
  }
}

static void
gst_v4l2_object_extrapolate_info (GstV4l2Object * v4l2object,
    GstVideoInfo * info, GstVideoAlignment * align, gint stride)
{
  const GstVideoFormatInfo *finfo = info->finfo;
  gint i, estride, padded_height;
  gsize offs = 0;

  g_return_if_fail (v4l2object->n_v4l2_planes == 1);

  padded_height = info->height + align->padding_top + align->padding_bottom;

  for (i = 0; i < finfo->n_planes; i++) {
    estride = gst_v4l2_object_extrapolate_stride (finfo, i, stride);

    gst_v4l2_object_set_stride (info, align, i, estride);

    info->offset[i] = offs;
    offs += estride *
        GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (finfo, i, padded_height);

    GST_DEBUG_OBJECT (v4l2object->element,
        "Extrapolated for plane %d with base stride %d: "
        "stride %d, offset %" G_GSIZE_FORMAT, i, stride, info->stride[i],
        info->offset[i]);
  }
}

static void
gst_v4l2_object_save_format (GstV4l2Object * v4l2object,
    struct v4l2_fmtdesc *fmtdesc, struct v4l2_format *format,
    GstVideoInfo * info, GstVideoAlignment * align)
{
  const GstVideoFormatInfo *finfo = info->finfo;
  gboolean standard_stride = TRUE;
  gint stride, padded_width, padded_height, i;

  if (GST_VIDEO_INFO_FORMAT (info) == GST_VIDEO_FORMAT_ENCODED) {
    v4l2object->n_v4l2_planes = 1;
    info->size = format->fmt.pix.sizeimage;
    goto store_info;
  }

  /* adjust right padding */
  if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type))
    stride = format->fmt.pix_mp.plane_fmt[0].bytesperline;
  else
    stride = format->fmt.pix.bytesperline;

  padded_width = stride / GST_VIDEO_FORMAT_INFO_PSTRIDE (finfo, 0);

  if (padded_width < format->fmt.pix.width)
    GST_WARNING_OBJECT (v4l2object->element,
        "Driver bug detected, stride is too small for the width");

  align->padding_right = padded_width - info->width - align->padding_left;

  /* adjust bottom padding */
  padded_height = format->fmt.pix.height;

  if (GST_VIDEO_FORMAT_INFO_IS_TILED (finfo)) {
    guint hs, tile_height;

    hs = GST_VIDEO_FORMAT_INFO_TILE_HS (finfo);
    tile_height = 1 << hs;

    padded_height = GST_ROUND_UP_N (padded_height, tile_height);
  }

  align->padding_bottom = padded_height - info->height - align->padding_top;

  /* setup the strides and offset */
  if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type)) {
    struct v4l2_pix_format_mplane *pix_mp = &format->fmt.pix_mp;

    /* figure out the frame layout */
    v4l2object->n_v4l2_planes = MAX (1, pix_mp->num_planes);
    info->size = 0;
    for (i = 0; i < v4l2object->n_v4l2_planes; i++) {
      stride = pix_mp->plane_fmt[i].bytesperline;

      if (info->stride[i] != stride)
        standard_stride = FALSE;

      gst_v4l2_object_set_stride (info, align, i, stride);
      info->offset[i] = info->size;
      info->size += pix_mp->plane_fmt[i].sizeimage;
    }

    /* Extrapolate stride if planar format are being set in 1 v4l2 plane */
    if (v4l2object->n_v4l2_planes < finfo->n_planes) {
      stride = format->fmt.pix_mp.plane_fmt[0].bytesperline;
      gst_v4l2_object_extrapolate_info (v4l2object, info, align, stride);
    }
  } else {
    /* only one plane in non-MPLANE mode */
    v4l2object->n_v4l2_planes = 1;
    info->size = format->fmt.pix.sizeimage;
    stride = format->fmt.pix.bytesperline;

    if (info->stride[0] != stride)
      standard_stride = FALSE;

    gst_v4l2_object_extrapolate_info (v4l2object, info, align, stride);
  }

  /* adjust the offset to take into account left and top */
  if (GST_VIDEO_FORMAT_INFO_IS_TILED (finfo)) {
    if ((align->padding_left + align->padding_top) > 0)
      GST_WARNING_OBJECT (v4l2object->element,
          "Left and top padding is not permitted for tiled formats");
  } else {
    for (i = 0; i < finfo->n_planes; i++) {
      gint vedge, hedge;

      /* FIXME we assume plane as component as this is true for all supported
       * format we support. */

      hedge = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (finfo, i, align->padding_left);
      vedge = GST_VIDEO_FORMAT_INFO_SCALE_HEIGHT (finfo, i, align->padding_top);

      info->offset[i] += (vedge * info->stride[i]) +
          (hedge * GST_VIDEO_INFO_COMP_PSTRIDE (info, i));
    }
  }

store_info:
  GST_DEBUG_OBJECT (v4l2object->element, "Got sizeimage %" G_GSIZE_FORMAT,
      info->size);

  /* to avoid copies we need video meta if top or left padding */
  v4l2object->need_video_meta =
      ((align->padding_top + align->padding_left) != 0);

  /* ... or if stride is non "standard" */
  if (!standard_stride)
    v4l2object->need_video_meta = TRUE;

  /* ... or also video meta if we use multiple, non-contiguous, planes */
  if (v4l2object->n_v4l2_planes > 1)
    v4l2object->need_video_meta = TRUE;

  v4l2object->info = *info;
  v4l2object->align = *align;
  v4l2object->format = *format;
  v4l2object->fmtdesc = fmtdesc;

  /* if we have a framerate pre-calculate duration */
  if (info->fps_n > 0 && info->fps_d > 0) {
    v4l2object->duration = gst_util_uint64_scale_int (GST_SECOND, info->fps_d,
        info->fps_n);
  } else {
    v4l2object->duration = GST_CLOCK_TIME_NONE;
  }
}

gint
gst_v4l2_object_extrapolate_stride (const GstVideoFormatInfo * finfo,
    gint plane, gint stride)
{
  gint estride;

  switch (finfo->format) {
    case GST_VIDEO_FORMAT_NV12:
    case GST_VIDEO_FORMAT_NV12_64Z32:
    case GST_VIDEO_FORMAT_NV21:
    case GST_VIDEO_FORMAT_NV16:
    case GST_VIDEO_FORMAT_NV24:
      estride = (plane == 0 ? 1 : 2) *
          GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (finfo, plane, stride);
      break;
    default:
      estride = GST_VIDEO_FORMAT_INFO_SCALE_WIDTH (finfo, plane, stride);
      break;
  }

  return estride;
}

static gboolean
gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
    gboolean try_only)
{
  gint fd = v4l2object->video_fd;
  struct v4l2_format format;
  struct v4l2_streamparm streamparm;
  enum v4l2_field field;
  guint32 pixelformat;
  struct v4l2_fmtdesc *fmtdesc;
  GstVideoInfo info;
  GstVideoAlignment align;
  gint width, height, fps_n, fps_d;
  gint n_v4l_planes;
  gint i = 0;
  gboolean is_mplane;
  enum v4l2_colorspace colorspace = 0;

  GST_V4L2_CHECK_OPEN (v4l2object);
  if (!try_only)
    GST_V4L2_CHECK_NOT_ACTIVE (v4l2object);

  is_mplane = V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type);

  gst_video_info_init (&info);
  gst_video_alignment_reset (&align);

  if (!gst_v4l2_object_get_caps_info (v4l2object, caps, &fmtdesc, &info))
    goto invalid_caps;

  pixelformat = fmtdesc->pixelformat;
  width = GST_VIDEO_INFO_WIDTH (&info);
  height = GST_VIDEO_INFO_HEIGHT (&info);
  fps_n = GST_VIDEO_INFO_FPS_N (&info);
  fps_d = GST_VIDEO_INFO_FPS_D (&info);

  /* if encoded format (GST_VIDEO_INFO_N_PLANES return 0)
   * or if contiguous is prefered */
  n_v4l_planes = GST_VIDEO_INFO_N_PLANES (&info);
  if (!n_v4l_planes || !v4l2object->prefered_non_contiguous)
    n_v4l_planes = 1;

  if (GST_VIDEO_INFO_IS_INTERLACED (&info)) {
    GST_DEBUG_OBJECT (v4l2object->element, "interlaced video");
    /* ideally we would differentiate between types of interlaced video
     * but there is not sufficient information in the caps..
     */
    field = V4L2_FIELD_INTERLACED;
  } else {
    GST_DEBUG_OBJECT (v4l2object->element, "progressive video");
    field = V4L2_FIELD_NONE;
  }

  if (V4L2_TYPE_IS_OUTPUT (v4l2object->type)) {
    /* We should set colorspace if we have it */
    if (gst_video_colorimetry_matches (&info.colorimetry, "bt601")) {
      colorspace = V4L2_COLORSPACE_SMPTE170M;
    } else if (gst_video_colorimetry_matches (&info.colorimetry, "bt709")) {
      colorspace = V4L2_COLORSPACE_REC709;
    } else if (gst_video_colorimetry_matches (&info.colorimetry, "smpte240m")) {
      colorspace = V4L2_COLORSPACE_SMPTE240M;
    } else {
      /* Try to guess colorspace according to pixelformat and size */
      if (GST_VIDEO_INFO_IS_YUV (&info)) {
        /* SD streams likely use SMPTE170M and HD streams REC709 */
        if (width <= 720 && height <= 576)
          colorspace = V4L2_COLORSPACE_SMPTE170M;
        else
          colorspace = V4L2_COLORSPACE_REC709;
      } else if (GST_VIDEO_INFO_IS_RGB (&info)) {
        colorspace = V4L2_COLORSPACE_SRGB;
      }
    }
  }

  GST_DEBUG_OBJECT (v4l2object->element, "Desired format %dx%d, format "
      "%" GST_FOURCC_FORMAT " stride: %d", width, height,
      GST_FOURCC_ARGS (pixelformat), GST_VIDEO_INFO_PLANE_STRIDE (&info, 0));

  memset (&format, 0x00, sizeof (struct v4l2_format));
  format.type = v4l2object->type;

  if (is_mplane) {
    format.type = v4l2object->type;
    format.fmt.pix_mp.pixelformat = pixelformat;
    format.fmt.pix_mp.width = width;
    format.fmt.pix_mp.height = height;
    format.fmt.pix_mp.field = field;
    format.fmt.pix_mp.num_planes = n_v4l_planes;

    /* try to ask our prefered stride but it's not a failure if not
     * accepted */
    for (i = 0; i < n_v4l_planes; i++) {
      gint stride = GST_VIDEO_INFO_PLANE_STRIDE (&info, i);

      if (GST_VIDEO_FORMAT_INFO_IS_TILED (info.finfo))
        stride = GST_VIDEO_TILE_X_TILES (stride) <<
            GST_VIDEO_FORMAT_INFO_TILE_WS (info.finfo);

      format.fmt.pix_mp.plane_fmt[i].bytesperline = stride;
    }

    if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_ENCODED)
      format.fmt.pix_mp.plane_fmt[0].sizeimage = ENCODED_BUFFER_SIZE;
  } else {
    gint stride = GST_VIDEO_INFO_PLANE_STRIDE (&info, 0);

    format.type = v4l2object->type;
    format.fmt.pix.width = width;
    format.fmt.pix.height = height;
    format.fmt.pix.pixelformat = pixelformat;
    format.fmt.pix.field = field;

    if (GST_VIDEO_FORMAT_INFO_IS_TILED (info.finfo))
      stride = GST_VIDEO_TILE_X_TILES (stride) <<
          GST_VIDEO_FORMAT_INFO_TILE_WS (info.finfo);

    /* try to ask our prefered stride */
    format.fmt.pix.bytesperline = stride;

    if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_ENCODED)
      format.fmt.pix.sizeimage = ENCODED_BUFFER_SIZE;
  }

  GST_DEBUG_OBJECT (v4l2object->element, "Desired format is %dx%d, format "
      "%" GST_FOURCC_FORMAT ", nb planes %d", format.fmt.pix.width,
      format.fmt.pix_mp.height,
      GST_FOURCC_ARGS (format.fmt.pix.pixelformat),
      is_mplane ? format.fmt.pix_mp.num_planes : 1);

#ifndef GST_DISABLE_GST_DEBUG
  if (is_mplane) {
    for (i = 0; i < format.fmt.pix_mp.num_planes; i++)
      GST_DEBUG_OBJECT (v4l2object->element, "  stride %d",
          format.fmt.pix_mp.plane_fmt[i].bytesperline);
  } else {
    GST_DEBUG_OBJECT (v4l2object->element, "  stride %d",
        format.fmt.pix.bytesperline);
  }
#endif

  if (V4L2_TYPE_IS_OUTPUT (v4l2object->type)) {
    if (is_mplane)
      format.fmt.pix_mp.colorspace = colorspace;
    else
      format.fmt.pix.colorspace = colorspace;

    GST_DEBUG_OBJECT (v4l2object->element, "Desired colorspace is %d",
        colorspace);
  }

  if (try_only) {
    if (v4l2_ioctl (fd, VIDIOC_TRY_FMT, &format) < 0)
      goto try_fmt_failed;
  } else {
    if (v4l2_ioctl (fd, VIDIOC_S_FMT, &format) < 0)
      goto set_fmt_failed;
  }

  GST_DEBUG_OBJECT (v4l2object->element, "Got format of %dx%d, format "
      "%" GST_FOURCC_FORMAT ", nb planes %d, colorspace %d",
      format.fmt.pix.width, format.fmt.pix_mp.height,
      GST_FOURCC_ARGS (format.fmt.pix.pixelformat),
      is_mplane ? format.fmt.pix_mp.num_planes : 1,
      is_mplane ? format.fmt.pix_mp.colorspace : format.fmt.pix.colorspace);

#ifndef GST_DISABLE_GST_DEBUG
  if (is_mplane) {
    for (i = 0; i < format.fmt.pix_mp.num_planes; i++)
      GST_DEBUG_OBJECT (v4l2object->element, "  stride %d, sizeimage %d",
          format.fmt.pix_mp.plane_fmt[i].bytesperline,
          format.fmt.pix_mp.plane_fmt[i].sizeimage);
  } else {
    GST_DEBUG_OBJECT (v4l2object->element, "  stride %d, sizeimage %d",
        format.fmt.pix.bytesperline, format.fmt.pix.sizeimage);
  }
#endif

  if (format.fmt.pix.pixelformat != pixelformat)
    goto invalid_pixelformat;

  /* Only negotiate size with raw data.
   * For some codecs the dimensions are *not* in the bitstream, IIRC VC1
   * in ASF mode for example, there is also not reason for a driver to
   * change the size. */
  if (info.finfo->format != GST_VIDEO_FORMAT_ENCODED) {
    /* We can crop larger images */
    if (format.fmt.pix.width < width || format.fmt.pix.height < height)
      goto invalid_dimensions;

    /* Note, this will be adjusted if upstream has non-centered cropping. */
    align.padding_top = 0;
    align.padding_bottom = format.fmt.pix.height - height;
    align.padding_left = 0;
    align.padding_right = format.fmt.pix.width - width;
  }

  if (is_mplane && format.fmt.pix_mp.num_planes != n_v4l_planes)
    goto invalid_planes;

  if (try_only)                 /* good enough for trying only */
    return TRUE;

  if (GST_VIDEO_INFO_HAS_ALPHA (&info)) {
    struct v4l2_control ctl = { 0, };
    ctl.id = V4L2_CID_ALPHA_COMPONENT;
    ctl.value = 0xff;

    if (v4l2_ioctl (fd, VIDIOC_S_CTRL, &ctl) < 0)
      GST_WARNING_OBJECT (v4l2object->element,
          "Failed to set alpha component value");
  }

  /* Is there a reason we require the caller to always specify a framerate? */
  GST_DEBUG_OBJECT (v4l2object->element, "Desired framerate: %u/%u", fps_n,
      fps_d);

  memset (&streamparm, 0x00, sizeof (struct v4l2_streamparm));
  streamparm.type = v4l2object->type;

  if (v4l2_ioctl (fd, VIDIOC_G_PARM, &streamparm) < 0)
    goto get_parm_failed;

  GST_VIDEO_INFO_FPS_N (&info) =
      streamparm.parm.capture.timeperframe.denominator;
  GST_VIDEO_INFO_FPS_D (&info) = streamparm.parm.capture.timeperframe.numerator;

  if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE
      || v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
    GST_DEBUG_OBJECT (v4l2object->element, "Got framerate: %u/%u",
        streamparm.parm.capture.timeperframe.denominator,
        streamparm.parm.capture.timeperframe.numerator);

    /* We used to skip frame rate setup if the camera was already setup
     * with the requested frame rate. This breaks some cameras though,
     * causing them to not output data (several models of Thinkpad cameras
     * have this problem at least).
     * So, don't skip. */
    GST_LOG_OBJECT (v4l2object->element, "Setting framerate to %u/%u", fps_n,
        fps_d);
    /* We want to change the frame rate, so check whether we can. Some cheap USB
     * cameras don't have the capability */
    if ((streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) == 0) {
      GST_DEBUG_OBJECT (v4l2object->element,
          "Not setting framerate (not supported)");
      goto done;
    }

    /* Note: V4L2 wants the frame interval, we have the frame rate */
    streamparm.parm.capture.timeperframe.numerator = fps_d;
    streamparm.parm.capture.timeperframe.denominator = fps_n;

    /* some cheap USB cam's won't accept any change */
    if (v4l2_ioctl (fd, VIDIOC_S_PARM, &streamparm) < 0)
      goto set_parm_failed;

    if (streamparm.parm.capture.timeperframe.numerator > 0 &&
        streamparm.parm.capture.timeperframe.denominator > 0) {
      /* get new values */
      fps_d = streamparm.parm.capture.timeperframe.numerator;
      fps_n = streamparm.parm.capture.timeperframe.denominator;

      GST_INFO_OBJECT (v4l2object->element, "Set framerate to %u/%u", fps_n,
          fps_d);
    } else {
      /* fix v4l2 capture driver to provide framerate values */
      GST_WARNING_OBJECT (v4l2object->element,
          "Reuse caps framerate %u/%u - fix v4l2 capture driver", fps_n, fps_d);
    }

    GST_VIDEO_INFO_FPS_N (&info) = fps_n;
    GST_VIDEO_INFO_FPS_D (&info) = fps_d;
  }

done:
  /* add boolean return, so we can fail on drivers bugs */
  gst_v4l2_object_save_format (v4l2object, fmtdesc, &format, &info, &align);

  /* now configure the pool */
  if (!gst_v4l2_object_setup_pool (v4l2object, caps))
    goto pool_failed;

  return TRUE;

  /* ERRORS */
invalid_caps:
  {
    GST_DEBUG_OBJECT (v4l2object->element, "can't parse caps %" GST_PTR_FORMAT,
        caps);
    return FALSE;
  }
try_fmt_failed:
  {
    if (errno == EBUSY) {
      GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, BUSY,
          (_("Device '%s' is busy"), v4l2object->videodev),
          ("Call to TRY_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
              GST_FOURCC_ARGS (pixelformat), width, height,
              g_strerror (errno)));
    }
    return FALSE;
  }
set_fmt_failed:
  {
    if (errno == EBUSY) {
      GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, BUSY,
          (_("Device '%s' is busy"), v4l2object->videodev),
          ("Call to S_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
              GST_FOURCC_ARGS (pixelformat), width, height,
              g_strerror (errno)));
    } else {
      GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
          (_("Device '%s' cannot capture at %dx%d"),
              v4l2object->videodev, width, height),
          ("Call to S_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
              GST_FOURCC_ARGS (pixelformat), width, height,
              g_strerror (errno)));
    }
    return FALSE;
  }
invalid_dimensions:
  {
    if (!try_only) {
      GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
          (_("Device '%s' cannot capture at %dx%d"),
              v4l2object->videodev, width, height),
          ("Tried to capture at %dx%d, but device returned size %dx%d",
              width, height, format.fmt.pix.width, format.fmt.pix.height));
    }
    return FALSE;
  }
invalid_pixelformat:
  {
    if (!try_only) {
      GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
          (_("Device '%s' cannot capture in the specified format"),
              v4l2object->videodev),
          ("Tried to capture in %" GST_FOURCC_FORMAT
              ", but device returned format" " %" GST_FOURCC_FORMAT,
              GST_FOURCC_ARGS (pixelformat),
              GST_FOURCC_ARGS (format.fmt.pix.pixelformat)));
    }
    return FALSE;
  }
invalid_planes:
  {
    if (!try_only) {
      GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
          (_("Device '%s' does support non-contiguous planes"),
              v4l2object->videodev),
          ("Device wants %d planes", format.fmt.pix_mp.num_planes));
    }
    return FALSE;
  }
get_parm_failed:
  {
    /* it's possible that this call is not supported */
    if (errno != EINVAL && errno != ENOTTY) {
      GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS,
          (_("Could not get parameters on device '%s'"),
              v4l2object->videodev), GST_ERROR_SYSTEM);
    }
    goto done;
  }
set_parm_failed:
  {
    GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS,
        (_("Video device did not accept new frame rate setting.")),
        GST_ERROR_SYSTEM);
    goto done;
  }
pool_failed:
  {
    /* setup_pool already send the error */
    return FALSE;
  }
}

gboolean
gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps)
{
  return gst_v4l2_object_set_format_full (v4l2object, caps, FALSE);
}

gboolean
gst_v4l2_object_try_format (GstV4l2Object * v4l2object, GstCaps * caps)
{
  return gst_v4l2_object_set_format_full (v4l2object, caps, TRUE);
}

/**
 * gst_v4l2_object_acquire_format:
 * @v4l2object the object
 * @info a GstVideoInfo to be filled
 *
 * Acquire the driver choosen format. This is useful in decoder or encoder elements where
 * the output format is choosen by the HW.
 *
 * Returns: %TRUE on success, %FALSE on failure.
 */
gboolean
gst_v4l2_object_acquire_format (GstV4l2Object * v4l2object, GstVideoInfo * info)
{
  struct v4l2_fmtdesc *fmtdesc;
  struct v4l2_format fmt;
  struct v4l2_crop crop;
  GstVideoFormat format;
  guint width, height;
  GstVideoAlignment align;

  gst_video_info_init (info);
  gst_video_alignment_reset (&align);

  memset (&fmt, 0x00, sizeof (struct v4l2_format));
  fmt.type = v4l2object->type;
  if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_FMT, &fmt) < 0)
    goto get_fmt_failed;

  fmtdesc = gst_v4l2_object_get_format_from_fourcc (v4l2object,
      fmt.fmt.pix.pixelformat);
  if (fmtdesc == NULL)
    goto unsupported_format;

  /* No need to care about mplane, the four first params are the same */
  format = gst_v4l2_object_v4l2fourcc_to_video_format (fmt.fmt.pix.pixelformat);

  /* fails if we do no translate the fmt.pix.pixelformat to GstVideoFormat */
  if (format == GST_VIDEO_FORMAT_UNKNOWN)
    goto unsupported_format;

  if (fmt.fmt.pix.width == 0 || fmt.fmt.pix.height == 0)
    goto invalid_dimensions;

  width = fmt.fmt.pix.width;
  height = fmt.fmt.pix.height;

  memset (&crop, 0, sizeof (struct v4l2_crop));
  crop.type = v4l2object->type;
  if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_G_CROP, &crop) >= 0) {
    align.padding_left = crop.c.left;
    align.padding_top = crop.c.top;
    align.padding_right = width - crop.c.width - crop.c.left;
    align.padding_bottom = height - crop.c.height - crop.c.top;
    width = crop.c.width;
    height = crop.c.height;
  }

  gst_video_info_set_format (info, format, width, height);

  switch (fmt.fmt.pix.field) {
    case V4L2_FIELD_ANY:
    case V4L2_FIELD_NONE:
      info->interlace_mode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
      break;
    case V4L2_FIELD_INTERLACED:
    case V4L2_FIELD_INTERLACED_TB:
    case V4L2_FIELD_INTERLACED_BT:
      info->interlace_mode = GST_VIDEO_INTERLACE_MODE_INTERLEAVED;
      break;
    default:
      goto unsupported_field;
  }

  gst_v4l2_object_save_format (v4l2object, fmtdesc, &fmt, info, &align);

  /* Shall we setup the pool ? */

  return TRUE;

get_fmt_failed:
  {
    GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS,
        (_("Video device did not provide output format.")), GST_ERROR_SYSTEM);
    return FALSE;
  }
invalid_dimensions:
  {
    GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, SETTINGS,
        (_("Video device returned invalid dimensions.")),
        ("Expected non 0 dimensions, got %dx%d", fmt.fmt.pix.width,
            fmt.fmt.pix.height));
    return FALSE;
  }
unsupported_field:
  {
    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
        (_("Video devices uses an unsupported interlacing method.")),
        ("V4L2 field type %d not supported", fmt.fmt.pix.field));
    return FALSE;
  }
unsupported_format:
  {
    GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
        (_("Video devices uses an unsupported pixel format.")),
        ("V4L2 format %" GST_FOURCC_FORMAT " not supported",
            GST_FOURCC_ARGS (fmt.fmt.pix.pixelformat)));
    return FALSE;
  }
}

gboolean
gst_v4l2_object_set_crop (GstV4l2Object * obj)
{
  struct v4l2_crop crop = { 0 };

  crop.type = obj->type;
  crop.c.left = obj->align.padding_left;
  crop.c.top = obj->align.padding_top;
  crop.c.width = obj->info.width;
  crop.c.height = obj->info.height;

  if (obj->align.padding_left + obj->align.padding_top +
      obj->align.padding_right + obj->align.padding_bottom == 0) {
    GST_DEBUG_OBJECT (obj->element, "no cropping needed");
    return TRUE;
  }

  GST_DEBUG_OBJECT (obj->element,
      "Desired cropping left %u, top %u, size %ux%u", crop.c.left, crop.c.top,
      crop.c.width, crop.c.height);

  if (v4l2_ioctl (obj->video_fd, VIDIOC_S_CROP, &crop) < 0) {
    GST_WARNING_OBJECT (obj->element, "VIDIOC_S_CROP failed");
    return FALSE;
  }

  if (v4l2_ioctl (obj->video_fd, VIDIOC_G_CROP, &crop) < 0) {
    GST_WARNING_OBJECT (obj->element, "VIDIOC_G_CROP failed");
    return FALSE;
  }

  GST_DEBUG_OBJECT (obj->element,
      "Got cropping left %u, top %u, size %ux%u", crop.c.left, crop.c.top,
      crop.c.width, crop.c.height);

  return TRUE;
}

gboolean
gst_v4l2_object_caps_equal (GstV4l2Object * v4l2object, GstCaps * caps)
{
  GstStructure *config;
  GstCaps *oldcaps;
  gboolean ret;

  if (!v4l2object->pool)
    return FALSE;

  config = gst_buffer_pool_get_config (v4l2object->pool);
  gst_buffer_pool_config_get_params (config, &oldcaps, NULL, NULL, NULL);

  ret = oldcaps && gst_caps_is_equal (caps, oldcaps);

  gst_structure_free (config);

  return ret;
}

gboolean
gst_v4l2_object_unlock (GstV4l2Object * v4l2object)
{
  gboolean ret = TRUE;

  GST_LOG_OBJECT (v4l2object->element, "start flushing");

  if (v4l2object->pool && gst_buffer_pool_is_active (v4l2object->pool))
    gst_buffer_pool_set_flushing (v4l2object->pool, TRUE);

  return ret;
}

gboolean
gst_v4l2_object_unlock_stop (GstV4l2Object * v4l2object)
{
  gboolean ret = TRUE;

  GST_LOG_OBJECT (v4l2object->element, "stop flushing");

  if (v4l2object->pool && gst_buffer_pool_is_active (v4l2object->pool))
    gst_buffer_pool_set_flushing (v4l2object->pool, FALSE);

  return ret;
}

gboolean
gst_v4l2_object_stop (GstV4l2Object * v4l2object)
{
  GST_DEBUG_OBJECT (v4l2object->element, "stopping");

  if (!GST_V4L2_IS_OPEN (v4l2object))
    goto done;
  if (!GST_V4L2_IS_ACTIVE (v4l2object))
    goto done;

  if (v4l2object->pool) {
    GST_DEBUG_OBJECT (v4l2object->element, "deactivating pool");
    gst_buffer_pool_set_active (v4l2object->pool, FALSE);
    gst_object_unref (v4l2object->pool);
    v4l2object->pool = NULL;
  }

  GST_V4L2_SET_INACTIVE (v4l2object);

done:
  return TRUE;
}

GstCaps *
gst_v4l2_object_get_caps (GstV4l2Object * v4l2object, GstCaps * filter)
{
  GstCaps *ret;
  GSList *walk;
  GSList *formats;

  if (v4l2object->probed_caps == NULL) {
    formats = gst_v4l2_object_get_format_list (v4l2object);

    ret = gst_caps_new_empty ();

    for (walk = formats; walk; walk = walk->next) {
      struct v4l2_fmtdesc *format;
      GstStructure *template;

      format = (struct v4l2_fmtdesc *) walk->data;

      template =
          gst_v4l2_object_v4l2fourcc_to_bare_struct (format->pixelformat);

      if (template) {
        GstCaps *tmp;

        tmp = gst_v4l2_object_probe_caps_for_format (v4l2object,
            format->pixelformat, template);
        if (tmp)
          gst_caps_append (ret, tmp);

        gst_structure_free (template);
      } else {
        GST_DEBUG_OBJECT (v4l2object->element, "unknown format %u",
            format->pixelformat);
      }
    }
    v4l2object->probed_caps = ret;
  }

  if (filter) {
    ret = gst_caps_intersect_full (filter, v4l2object->probed_caps,
        GST_CAPS_INTERSECT_FIRST);
  } else {
    ret = gst_caps_ref (v4l2object->probed_caps);
  }

  GST_INFO_OBJECT (v4l2object->element, "probed caps: %" GST_PTR_FORMAT, ret);
  LOG_CAPS (v4l2object->element, ret);

  return ret;
}

gboolean
gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
{
  GstCaps *caps;
  GstBufferPool *pool = NULL, *other_pool = NULL;
  GstStructure *config;
  guint size, min, max, own_min = 0;
  gboolean update;
  gboolean has_video_meta;
  gboolean can_share_own_pool, pushing_from_our_pool = FALSE;
  struct v4l2_control ctl = { 0, };
  GstAllocator *allocator = NULL;
  GstAllocationParams params = { 0 };

  GST_DEBUG_OBJECT (obj->element, "decide allocation");

  g_return_val_if_fail (obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
      obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, FALSE);

  gst_query_parse_allocation (query, &caps, NULL);

  if (obj->pool == NULL) {
    if (!gst_v4l2_object_setup_pool (obj, caps))
      goto pool_failed;
  }

  if (gst_query_get_n_allocation_params (query) > 0)
    gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);

  if (gst_query_get_n_allocation_pools (query) > 0) {
    gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
    update = TRUE;
  } else {
    pool = NULL;
    min = max = 0;
    size = 0;
    update = FALSE;
  }

  GST_DEBUG_OBJECT (obj->element, "allocation: size:%u min:%u max:%u pool:%"
      GST_PTR_FORMAT, size, min, max, pool);

  has_video_meta =
      gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);

  can_share_own_pool = (has_video_meta || !obj->need_video_meta);

  /* Certain driver may expose a minimum through controls */
  ctl.id = V4L2_CID_MIN_BUFFERS_FOR_CAPTURE;
  if (v4l2_ioctl (obj->video_fd, VIDIOC_G_CTRL, &ctl) >= 0) {
    GST_DEBUG_OBJECT (obj->element, "driver require a minimum of %d buffers",
        ctl.value);
    obj->min_buffers = ctl.value;
  } else {
    obj->min_buffers = 0;
  }

  /* We can't share our own pool, if it exceed V4L2 capacity */
  if (min + obj->min_buffers + 1 > VIDEO_MAX_FRAME)
    can_share_own_pool = FALSE;

  /* select a pool */
  switch (obj->mode) {
    case GST_V4L2_IO_RW:
      if (pool) {
        /* in READ/WRITE mode, prefer a downstream pool because our own pool
         * doesn't help much, we have to write to it as well */
        GST_DEBUG_OBJECT (obj->element,
            "read/write mode: using downstream pool");
        /* use the bigest size, when we use our own pool we can't really do any
         * other size than what the hardware gives us but for downstream pools
         * we can try */
        size = MAX (size, obj->info.size);
      } else if (can_share_own_pool) {
        /* no downstream pool, use our own then */
        GST_DEBUG_OBJECT (obj->element,
            "read/write mode: no downstream pool, using our own");
        pool = gst_object_ref (obj->pool);
        size = obj->info.size;
        pushing_from_our_pool = TRUE;
      }
      break;

    case GST_V4L2_IO_USERPTR:
    case GST_V4L2_IO_DMABUF_IMPORT:
      /* in importing mode, prefer our own pool, and pass the other pool to
       * our own, so it can serve itself */
      if (pool == NULL)
        goto no_downstream_pool;
      gst_v4l2_buffer_pool_set_other_pool (GST_V4L2_BUFFER_POOL (obj->pool),
          pool);
      other_pool = pool;
      gst_object_unref (pool);
      pool = gst_object_ref (obj->pool);
      size = obj->info.size;
      break;

    case GST_V4L2_IO_MMAP:
    case GST_V4L2_IO_DMABUF:
      /* in streaming mode, prefer our own pool */
      /* Check if we can use it ... */
      if (can_share_own_pool) {
        if (pool)
          gst_object_unref (pool);
        pool = gst_object_ref (obj->pool);
        size = obj->info.size;
        GST_DEBUG_OBJECT (obj->element,
            "streaming mode: using our own pool %" GST_PTR_FORMAT, pool);
        pushing_from_our_pool = TRUE;
      } else if (pool) {
        GST_DEBUG_OBJECT (obj->element,
            "streaming mode: copying to downstream pool %" GST_PTR_FORMAT,
            pool);
      } else {
        GST_DEBUG_OBJECT (obj->element,
            "streaming mode: no usable pool, copying to generic pool");
        size = MAX (size, obj->info.size);
      }
      break;
    case GST_V4L2_IO_AUTO:
    default:
      GST_WARNING_OBJECT (obj->element, "unhandled mode");
      break;
  }

  if (size == 0)
    goto no_size;

  /* If pushing from our own pool, configure it with queried minimum,
   * otherwise use the minimum required */
  if (pushing_from_our_pool) {
    /* When pushing from our own pool, we need what downstream one, to be able
     * to fill the pipeline, the minimum required to decoder according to the
     * driver and 1 more, so we don't endup up with everything downstream or
     * held by the decoder. */
    own_min = min + obj->min_buffers + 1;

    /* If no allocation parameters where provided, allow for a little more
     * buffers and enable copy threshold */
    if (!update) {
      own_min += 3;
      gst_v4l2_buffer_pool_copy_at_threshold (GST_V4L2_BUFFER_POOL (pool),
          TRUE);
    } else {
      gst_v4l2_buffer_pool_copy_at_threshold (GST_V4L2_BUFFER_POOL (pool),
          FALSE);
    }

  } else {
    /* In this case we'll have to configure two buffer pool. For our buffer
     * pool, we'll need what the driver one, and one more, so we can dequeu */
    own_min = obj->min_buffers + 1;
    own_min = MAX (own_min, GST_V4L2_MIN_BUFFERS);

    /* for the downstream pool, we keep what downstream wants, though ensure
     * at least a minimum if downstream didn't suggest anything (we are
     * expecting the base class to create a default one for the context) */
    min = MAX (min, GST_V4L2_MIN_BUFFERS);

    /* To import we need the other pool to hold at least own_min */
    if (obj->pool == pool)
      min += own_min;
  }

  /* Request a bigger max, if one was suggested but it's too small */
  if (max != 0)
    max = MAX (min, max);

  /* First step, configure our own pool */
  config = gst_buffer_pool_get_config (obj->pool);

  if (obj->need_video_meta || has_video_meta) {
    GST_DEBUG_OBJECT (obj->element, "activate Video Meta");
    gst_buffer_pool_config_add_option (config,
        GST_BUFFER_POOL_OPTION_VIDEO_META);
  }

  gst_buffer_pool_config_set_allocator (config, allocator, &params);
  gst_buffer_pool_config_set_params (config, caps, size, own_min, 0);

  GST_DEBUG_OBJECT (obj->element, "setting own pool config to %"
      GST_PTR_FORMAT, config);

  /* Our pool often need to adjust the value */
  if (!gst_buffer_pool_set_config (obj->pool, config)) {
    config = gst_buffer_pool_get_config (obj->pool);

    GST_DEBUG_OBJECT (obj->element, "own pool config changed to %"
        GST_PTR_FORMAT, config);

    /* our pool will adjust the maximum buffer, which we are fine with */
    if (!gst_buffer_pool_set_config (obj->pool, config))
      goto config_failed;
  }

  /* Now configure the other pool if different */
  if (obj->pool != pool)
    other_pool = pool;

  if (other_pool) {
    config = gst_buffer_pool_get_config (other_pool);
    gst_buffer_pool_config_set_allocator (config, allocator, &params);
    gst_buffer_pool_config_set_params (config, caps, size, min, max);

    GST_DEBUG_OBJECT (obj->element, "setting other pool config to %"
        GST_PTR_FORMAT, config);

    /* if downstream supports video metadata, add this to the pool config */
    if (has_video_meta) {
      GST_DEBUG_OBJECT (obj->element, "activate Video Meta");
      gst_buffer_pool_config_add_option (config,
          GST_BUFFER_POOL_OPTION_VIDEO_META);
    }

    if (!gst_buffer_pool_set_config (other_pool, config)) {
      config = gst_buffer_pool_get_config (other_pool);

      if (!gst_buffer_pool_config_validate_params (config, caps, size, min,
              max)) {
        gst_structure_free (config);
        goto config_failed;
      }

      if (!gst_buffer_pool_set_config (other_pool, config))
        goto config_failed;
    }
  }

  if (pool) {
    /* For simplicity, simply read back the active configuration, so our base
     * class get the right information */
    config = gst_buffer_pool_get_config (pool);
    gst_buffer_pool_config_get_params (config, NULL, &size, &min, &max);
    gst_structure_free (config);
  }

  if (update)
    gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
  else
    gst_query_add_allocation_pool (query, pool, size, min, max);

  if (allocator)
    gst_object_unref (allocator);

  if (pool)
    gst_object_unref (pool);

  return TRUE;

pool_failed:
  {
    /* setup_pool already send the error */
    goto cleanup;
  }
config_failed:
  {
    GST_ELEMENT_ERROR (obj->element, RESOURCE, SETTINGS,
        (_("Failed to configure internal buffer pool.")), (NULL));
    goto cleanup;
  }
no_size:
  {
    GST_ELEMENT_ERROR (obj->element, RESOURCE, SETTINGS,
        (_("Video device did not suggest any buffer size.")), (NULL));
    goto cleanup;
  }
cleanup:
  {
    if (allocator)
      gst_object_unref (allocator);

    if (pool)
      gst_object_unref (pool);
    return FALSE;
  }
no_downstream_pool:
  {
    GST_ELEMENT_ERROR (obj->element, RESOURCE, SETTINGS,
        (_("No downstream pool to import from.")),
        ("When importing DMABUF or USERPTR, we need a pool to import from"));
    return FALSE;
  }
}

gboolean
gst_v4l2_object_propose_allocation (GstV4l2Object * obj, GstQuery * query)
{
  GstBufferPool *pool;
  /* we need at least 2 buffers to operate */
  guint size, min, max;
  GstCaps *caps;
  gboolean need_pool;
  struct v4l2_control ctl = { 0, };

  /* Set defaults allocation parameters */
  size = obj->info.size;
  min = GST_V4L2_MIN_BUFFERS;
  max = VIDEO_MAX_FRAME;

  gst_query_parse_allocation (query, &caps, &need_pool);

  if (caps == NULL)
    goto no_caps;

  if ((pool = obj->pool))
    gst_object_ref (pool);

  if (pool != NULL) {
    GstCaps *pcaps;
    GstStructure *config;

    /* we had a pool, check caps */
    config = gst_buffer_pool_get_config (pool);
    gst_buffer_pool_config_get_params (config, &pcaps, NULL, NULL, NULL);

    GST_DEBUG_OBJECT (obj->element,
        "we had a pool with caps %" GST_PTR_FORMAT, pcaps);
    if (!gst_caps_is_equal (caps, pcaps)) {
      gst_structure_free (config);
      gst_object_unref (pool);
      goto different_caps;
    }
    gst_structure_free (config);
  }

  /* Some devices may expose a minimum */
  ctl.id = V4L2_CID_MIN_BUFFERS_FOR_OUTPUT;
  if (v4l2_ioctl (obj->video_fd, VIDIOC_G_CTRL, &ctl) >= 0) {
    GST_DEBUG_OBJECT (obj->element, "driver require a miminum of %d buffers",
        ctl.value);
    obj->min_buffers = ctl.value;
  } else {
    obj->min_buffers = 0;
  }

  min = MAX (obj->min_buffers, GST_V4L2_MIN_BUFFERS);

  gst_query_add_allocation_pool (query, pool, size, min, max);

  /* we also support various metadata */
  gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);

  if (pool)
    gst_object_unref (pool);

  return TRUE;

  /* ERRORS */
no_caps:
  {
    GST_DEBUG_OBJECT (obj->element, "no caps specified");
    return FALSE;
  }
different_caps:
  {
    /* different caps, we can't use this pool */
    GST_DEBUG_OBJECT (obj->element, "pool has different caps");
    return FALSE;
  }
}
