diff options
| author | Wim Taymans <wim.taymans@collabora.co.uk> | 2009-09-07 18:28:51 +0200 | 
|---|---|---|
| committer | Wim Taymans <wim.taymans@collabora.co.uk> | 2009-09-07 18:28:51 +0200 | 
| commit | 796dec59209445cd9a19f1bd5844bb3b5e419d60 (patch) | |
| tree | e90cfa251981fc6d228242382a181ff5d8c896e4 | |
| parent | c6b2dff77e47e4fe9665aeb22bf6a65c23b6f35e (diff) | |
v4l2src: add support for mpeg formats
| -rw-r--r-- | sys/v4l2/gstv4l2object.c | 112 | ||||
| -rw-r--r-- | sys/v4l2/v4l2_calls.c | 20 | ||||
| -rw-r--r-- | sys/v4l2/v4l2src_calls.c | 3 | 
3 files changed, 84 insertions, 51 deletions
| diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c index 81fabfd8..8f8097d6 100644 --- a/sys/v4l2/gstv4l2object.c +++ b/sys/v4l2/gstv4l2object.c @@ -615,63 +615,67 @@ gst_v4l2_object_stop (GstV4l2Object * v4l2object)  /*   * common format / caps utilities:   */ +typedef struct +{ +  guint32 format; +  gboolean dimensions; +} GstV4L2FormatDesc; - -static const guint32 gst_v4l2_formats[] = { +static const GstV4L2FormatDesc gst_v4l2_formats[] = {    /* from Linux 2.6.15 videodev2.h */ -  V4L2_PIX_FMT_RGB332, -  V4L2_PIX_FMT_RGB555, -  V4L2_PIX_FMT_RGB565, -  V4L2_PIX_FMT_RGB555X, -  V4L2_PIX_FMT_RGB565X, -  V4L2_PIX_FMT_BGR24, -  V4L2_PIX_FMT_RGB24, -  V4L2_PIX_FMT_BGR32, -  V4L2_PIX_FMT_RGB32, -  V4L2_PIX_FMT_GREY, -  V4L2_PIX_FMT_YVU410, -  V4L2_PIX_FMT_YVU420, -  V4L2_PIX_FMT_YUYV, -  V4L2_PIX_FMT_UYVY, -  V4L2_PIX_FMT_YUV422P, -  V4L2_PIX_FMT_YUV411P, -  V4L2_PIX_FMT_Y41P, +  {V4L2_PIX_FMT_RGB332, TRUE}, +  {V4L2_PIX_FMT_RGB555, TRUE}, +  {V4L2_PIX_FMT_RGB565, TRUE}, +  {V4L2_PIX_FMT_RGB555X, TRUE}, +  {V4L2_PIX_FMT_RGB565X, TRUE}, +  {V4L2_PIX_FMT_BGR24, TRUE}, +  {V4L2_PIX_FMT_RGB24, TRUE}, +  {V4L2_PIX_FMT_BGR32, TRUE}, +  {V4L2_PIX_FMT_RGB32, TRUE}, +  {V4L2_PIX_FMT_GREY, TRUE}, +  {V4L2_PIX_FMT_YVU410, TRUE}, +  {V4L2_PIX_FMT_YVU420, TRUE}, +  {V4L2_PIX_FMT_YUYV, TRUE}, +  {V4L2_PIX_FMT_UYVY, TRUE}, +  {V4L2_PIX_FMT_YUV422P, TRUE}, +  {V4L2_PIX_FMT_YUV411P, TRUE}, +  {V4L2_PIX_FMT_Y41P, TRUE},    /* two planes -- one Y, one Cr + Cb interleaved  */ -  V4L2_PIX_FMT_NV12, -  V4L2_PIX_FMT_NV21, +  {V4L2_PIX_FMT_NV12, TRUE}, +  {V4L2_PIX_FMT_NV21, TRUE},    /*  The following formats are not defined in the V4L2 specification */ -  V4L2_PIX_FMT_YUV410, -  V4L2_PIX_FMT_YUV420, -  V4L2_PIX_FMT_YYUV, -  V4L2_PIX_FMT_HI240, +  {V4L2_PIX_FMT_YUV410, TRUE}, +  {V4L2_PIX_FMT_YUV420, TRUE}, +  {V4L2_PIX_FMT_YYUV, TRUE}, +  {V4L2_PIX_FMT_HI240, TRUE},    /* see http://www.siliconimaging.com/RGB%20Bayer.htm */  #ifdef V4L2_PIX_FMT_SBGGR8 -  V4L2_PIX_FMT_SBGGR8, +  {V4L2_PIX_FMT_SBGGR8, TRUE},  #endif    /* compressed formats */ -  V4L2_PIX_FMT_MJPEG, -  V4L2_PIX_FMT_JPEG, -  V4L2_PIX_FMT_DV, -  V4L2_PIX_FMT_MPEG, +  {V4L2_PIX_FMT_MJPEG, TRUE}, +  {V4L2_PIX_FMT_JPEG, TRUE}, +  {V4L2_PIX_FMT_DV, TRUE}, +  {V4L2_PIX_FMT_MPEG, FALSE},    /*  Vendor-specific formats   */ -  V4L2_PIX_FMT_WNVA, +  {V4L2_PIX_FMT_WNVA, TRUE},  #ifdef V4L2_PIX_FMT_SN9C10X -  V4L2_PIX_FMT_SN9C10X, +  {V4L2_PIX_FMT_SN9C10X, TRUE},  #endif  #ifdef V4L2_PIX_FMT_PWC1 -  V4L2_PIX_FMT_PWC1, +  {V4L2_PIX_FMT_PWC1, TRUE},  #endif  #ifdef V4L2_PIX_FMT_PWC2 -  V4L2_PIX_FMT_PWC2, +  {V4L2_PIX_FMT_PWC2, TRUE},  #endif  #ifdef V4L2_PIX_FMT_YVYU -  V4L2_PIX_FMT_YVYU, +  {V4L2_PIX_FMT_YVYU, TRUE},  #endif  }; @@ -740,6 +744,9 @@ gst_v4l2_object_format_get_rank (const struct v4l2_fmtdesc *fmt)      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: @@ -802,7 +809,6 @@ gst_v4l2_object_format_get_rank (const struct v4l2_fmtdesc *fmt)        rank = DV_BASE_RANK;        break; -    case V4L2_PIX_FMT_MPEG:    /* MPEG          */      case V4L2_PIX_FMT_WNVA:    /* Winnov hw compres */        rank = 0;        break; @@ -1101,7 +1107,7 @@ gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc)            NULL);        break;      case V4L2_PIX_FMT_MPEG:    /* MPEG          */ -      /* someone figure out the MPEG format used... */ +      structure = gst_structure_new ("video/mpegts", NULL);        break;      case V4L2_PIX_FMT_WNVA:    /* Winnov hw compres */        break; @@ -1148,12 +1154,15 @@ gst_v4l2_object_get_all_caps (void)      caps = gst_caps_new_empty ();      for (i = 0; i < GST_V4L2_FORMAT_COUNT; i++) { -      structure = gst_v4l2_object_v4l2fourcc_to_structure (gst_v4l2_formats[i]); +      structure = +          gst_v4l2_object_v4l2fourcc_to_structure (gst_v4l2_formats[i].format);        if (structure) { -        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); +        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); +        }          gst_caps_append_structure (caps, structure);        }      } @@ -1187,6 +1196,16 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,    structure = gst_caps_get_structure (caps, 0); +  mimetype = gst_structure_get_name (structure); + +  if (strcmp (mimetype, "video/mpegts") == 0) { +    fourcc = V4L2_PIX_FMT_MPEG; +    outsize = 8192; +    *fps_n = 0; +    *fps_d = 1; +    goto done; +  } +    if (!gst_structure_get_int (structure, "width", w))      return FALSE; @@ -1200,8 +1219,6 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,    *fps_n = gst_value_get_fraction_numerator (framerate);    *fps_d = gst_value_get_fraction_denominator (framerate); -  mimetype = gst_structure_get_name (structure); -    if (!strcmp (mimetype, "video/x-raw-yuv")) {      gst_structure_get_fourcc (structure, "format", &fourcc); @@ -1309,6 +1326,7 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,    if (fourcc == 0)      return FALSE; +done:    *format = gst_v4l2_object_get_format_from_fourcc (v4l2object, fourcc);    *size = outsize; @@ -1551,6 +1569,9 @@ gst_v4l2_object_probe_caps_for_format (GstV4l2Object * v4l2object,    GList *results = NULL;    guint32 w, h; +  if (pixelformat == GST_MAKE_FOURCC ('M', 'P', 'E', 'G')) +    return gst_caps_new_simple ("video/mpegts", NULL); +    memset (&size, 0, sizeof (struct v4l2_frmsizeenum));    size.index = 0;    size.pixel_format = pixelformat; @@ -1842,6 +1863,9 @@ gst_v4l2_object_set_format (GstV4l2Object * v4l2object, guint32 pixelformat,    memset (&format, 0x00, sizeof (struct v4l2_format));    format.type = v4l2object->type; +  if (pixelformat == GST_MAKE_FOURCC ('M', 'P', 'E', 'G')) +    return TRUE; +    if (v4l2_ioctl (fd, VIDIOC_G_FMT, &format) < 0)      goto get_fmt_failed; diff --git a/sys/v4l2/v4l2_calls.c b/sys/v4l2/v4l2_calls.c index 5f6261ea..e61381c2 100644 --- a/sys/v4l2/v4l2_calls.c +++ b/sys/v4l2/v4l2_calls.c @@ -231,30 +231,31 @@ gst_v4l2_fill_lists (GstV4l2Object * v4l2object)    v4l2object->norms = g_list_reverse (v4l2object->norms);    GST_DEBUG_OBJECT (e, "  controls+menus"); +    /* and lastly, controls+menus (if appropriate) */    for (n = V4L2_CID_BASE;; n++) {      struct v4l2_queryctrl control = { 0, };      GstV4l2ColorBalanceChannel *v4l2channel; -      GstColorBalanceChannel *channel;      /* when we reached the last official CID, continue with private CIDs */      if (n == V4L2_CID_LASTP1) {        GST_DEBUG_OBJECT (e, "checking private CIDs");        n = V4L2_CID_PRIVATE_BASE; -      /* FIXME: We are still not handling private controls. We need a new GstInterface -         to export those controls */ -      break;      } +    GST_DEBUG_OBJECT (e, "checking control %08x", n);      control.id = n;      if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_QUERYCTRL, &control) < 0) {        if (errno == EINVAL) { -        if (n < V4L2_CID_PRIVATE_BASE) +        if (n < V4L2_CID_PRIVATE_BASE) { +          GST_DEBUG_OBJECT (e, "skipping control %08x", n);            /* continue so that we also check private controls */            continue; -        else +        } else { +          GST_DEBUG_OBJECT (e, "controls finished");            break; +        }        } else {          GST_ELEMENT_ERROR (e, RESOURCE, SETTINGS,              (_("Failed getting controls attributes on device '%s'."), @@ -264,8 +265,10 @@ gst_v4l2_fill_lists (GstV4l2Object * v4l2object)          return FALSE;        }      } -    if (control.flags & V4L2_CTRL_FLAG_DISABLED) +    if (control.flags & V4L2_CTRL_FLAG_DISABLED) { +      GST_DEBUG_OBJECT (e, "skipping disabled control");        continue; +    }      switch (n) {        case V4L2_CID_BRIGHTNESS: @@ -281,6 +284,9 @@ gst_v4l2_fill_lists (GstV4l2Object * v4l2object)        case V4L2_CID_EXPOSURE:        case V4L2_CID_AUTOGAIN:        case V4L2_CID_GAIN: +#ifdef V4L2_CID_SHARPNESS +      case V4L2_CID_SHARPNESS: +#endif          /* we only handle these for now (why?) */          break;        case V4L2_CID_HFLIP: diff --git a/sys/v4l2/v4l2src_calls.c b/sys/v4l2/v4l2src_calls.c index d8e365f9..9142ac47 100644 --- a/sys/v4l2/v4l2src_calls.c +++ b/sys/v4l2/v4l2src_calls.c @@ -208,6 +208,9 @@ gst_v4l2src_set_capture (GstV4l2Src * v4l2src, guint32 pixelformat,    gint fd = v4l2src->v4l2object->video_fd;    struct v4l2_streamparm stream; +  if (pixelformat == GST_MAKE_FOURCC ('M', 'P', 'E', 'G')) +    return TRUE; +    if (!gst_v4l2_object_set_format (v4l2src->v4l2object, pixelformat, width,            height)) {      /* error already reported */ | 
