From 796dec59209445cd9a19f1bd5844bb3b5e419d60 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 7 Sep 2009 18:28:51 +0200 Subject: v4l2src: add support for mpeg formats --- sys/v4l2/gstv4l2object.c | 112 ++++++++++++++++++++++++++++------------------- sys/v4l2/v4l2_calls.c | 20 ++++++--- sys/v4l2/v4l2src_calls.c | 3 ++ 3 files changed, 84 insertions(+), 51 deletions(-) (limited to 'sys') 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 */ -- cgit