mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 13:41:48 +00:00
v4l2: simplify setting the capture format
Pass the caps to the set_format function and make _set_format parse the caps. Also keep the parsed values in the v4l2object so that we can refer to them when we want.
This commit is contained in:
parent
b7ad28ba53
commit
e8ae00f5fc
6 changed files with 46 additions and 65 deletions
|
@ -1331,9 +1331,9 @@ gst_v4l2_object_get_all_caps (void)
|
|||
* @fps_n/@fps_d: location for framerate
|
||||
* @size: location for expected size of the frame or 0 if unknown
|
||||
*/
|
||||
gboolean
|
||||
static gboolean
|
||||
gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
|
||||
struct v4l2_fmtdesc ** format, gint * w, gint * h,
|
||||
struct v4l2_fmtdesc **format, gint * w, gint * h,
|
||||
gboolean * interlaced, guint * fps_n, guint * fps_d, guint * size)
|
||||
{
|
||||
GstStructure *structure;
|
||||
|
@ -2060,12 +2060,30 @@ gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
|
|||
|
||||
|
||||
gboolean
|
||||
gst_v4l2_object_set_format (GstV4l2Object * v4l2object, guint32 pixelformat,
|
||||
guint32 width, guint32 height, gboolean interlaced)
|
||||
gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps)
|
||||
{
|
||||
gint fd = v4l2object->video_fd;
|
||||
struct v4l2_format *format;
|
||||
enum v4l2_field field;
|
||||
guint32 pixelformat;
|
||||
gint width;
|
||||
gint height;
|
||||
gboolean interlaced;
|
||||
struct v4l2_fmtdesc *fmtdesc;
|
||||
guint fps_n, fps_d;
|
||||
guint size;
|
||||
|
||||
if (!gst_v4l2_object_get_caps_info (v4l2object, caps,
|
||||
&fmtdesc, &width, &height, &interlaced, &fps_n, &fps_d, &size))
|
||||
goto invalid_caps;
|
||||
|
||||
v4l2object->fps_n = fps_n;
|
||||
v4l2object->fps_d = fps_d;
|
||||
v4l2object->size = size;
|
||||
v4l2object->width = width;
|
||||
v4l2object->height = height;
|
||||
|
||||
pixelformat = fmtdesc->pixelformat;
|
||||
|
||||
if (interlaced) {
|
||||
GST_DEBUG_OBJECT (v4l2object->element, "interlaced video");
|
||||
|
@ -2146,6 +2164,12 @@ gst_v4l2_object_set_format (GstV4l2Object * v4l2object, guint32 pixelformat,
|
|||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
invalid_caps:
|
||||
{
|
||||
GST_DEBUG_OBJECT (v4l2object->element, "can't parse caps %" GST_PTR_FORMAT,
|
||||
caps);
|
||||
return FALSE;
|
||||
}
|
||||
get_fmt_failed:
|
||||
{
|
||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
|
||||
|
|
|
@ -93,6 +93,9 @@ struct _GstV4l2Object {
|
|||
|
||||
/* the current format */
|
||||
struct v4l2_format format;
|
||||
guint width, height;
|
||||
guint fps_n, fps_d;
|
||||
guint size;
|
||||
|
||||
/* the video device's capabilities */
|
||||
struct v4l2_capability vcap;
|
||||
|
@ -182,18 +185,13 @@ GValueArray* gst_v4l2_probe_get_values (GstPropertyProbe * probe, guint pro
|
|||
GstCaps* gst_v4l2_object_probe_caps_for_format (GstV4l2Object *v4l2object, guint32 pixelformat,
|
||||
const GstStructure * template);
|
||||
|
||||
gboolean gst_v4l2_object_get_caps_info (GstV4l2Object *v4l2object, GstCaps *caps,
|
||||
struct v4l2_fmtdesc **format, gint *w, gint *h,
|
||||
gboolean * interlaced, guint *fps_n, guint *fps_d, guint *size);
|
||||
|
||||
|
||||
GSList* gst_v4l2_object_get_format_list (GstV4l2Object *v4l2object);
|
||||
|
||||
GstCaps* gst_v4l2_object_get_all_caps (void);
|
||||
|
||||
GstStructure* gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc);
|
||||
|
||||
gboolean gst_v4l2_object_set_format (GstV4l2Object *v4l2object, guint32 pixelformat, guint32 width, guint32 height, gboolean interlaced);
|
||||
gboolean gst_v4l2_object_set_format (GstV4l2Object *v4l2object, GstCaps * caps);
|
||||
|
||||
gboolean gst_v4l2_object_start_streaming (GstV4l2Object *v4l2object);
|
||||
gboolean gst_v4l2_object_stop_streaming (GstV4l2Object *v4l2object);
|
||||
|
|
|
@ -617,11 +617,6 @@ static gboolean
|
|||
gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
||||
{
|
||||
GstV4l2Sink *v4l2sink = GST_V4L2SINK (bsink);
|
||||
gint w = 0, h = 0;
|
||||
gboolean interlaced;
|
||||
struct v4l2_fmtdesc *format;
|
||||
guint fps_n, fps_d;
|
||||
guint size;
|
||||
GstV4l2BufferPool *newpool;
|
||||
|
||||
LOG_CAPS (v4l2sink, caps);
|
||||
|
@ -641,11 +636,6 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
|||
GST_DEBUG_OBJECT (v4l2sink, "no they aren't!");
|
||||
}
|
||||
|
||||
/* we want our own v4l2 type of fourcc codes */
|
||||
if (!gst_v4l2_object_get_caps_info (v4l2sink->v4l2object, caps,
|
||||
&format, &w, &h, &interlaced, &fps_n, &fps_d, &size))
|
||||
goto invalid_caps;
|
||||
|
||||
if (v4l2sink->pool) {
|
||||
/* we have a pool already, stop and destroy the old pool */
|
||||
if (v4l2sink->state == STATE_STREAMING) {
|
||||
|
@ -658,8 +648,7 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
|||
v4l2sink->pool = NULL;
|
||||
}
|
||||
|
||||
if (!gst_v4l2_object_set_format (v4l2sink->v4l2object, format->pixelformat,
|
||||
w, h, interlaced))
|
||||
if (!gst_v4l2_object_set_format (v4l2sink->v4l2object, caps))
|
||||
goto invalid_format;
|
||||
|
||||
if (!(v4l2sink->v4l2object->vcap.capabilities & V4L2_CAP_STREAMING))
|
||||
|
@ -688,26 +677,20 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
|||
g_object_notify (G_OBJECT (v4l2sink), "queue-size");
|
||||
}
|
||||
|
||||
v4l2sink->video_width = w;
|
||||
v4l2sink->video_height = h;
|
||||
v4l2sink->video_width = v4l2sink->v4l2object->width;
|
||||
v4l2sink->video_height = v4l2sink->v4l2object->height;
|
||||
|
||||
/* TODO: videosink width/height should be scaled according to
|
||||
* pixel-aspect-ratio
|
||||
*/
|
||||
GST_VIDEO_SINK_WIDTH (v4l2sink) = w;
|
||||
GST_VIDEO_SINK_HEIGHT (v4l2sink) = h;
|
||||
GST_VIDEO_SINK_WIDTH (v4l2sink) = v4l2sink->video_width;
|
||||
GST_VIDEO_SINK_HEIGHT (v4l2sink) = v4l2sink->video_height;
|
||||
|
||||
v4l2sink->current_caps = gst_caps_ref (caps);
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
invalid_caps:
|
||||
{
|
||||
GST_DEBUG_OBJECT (v4l2sink,
|
||||
"can't get capture format from caps %" GST_PTR_FORMAT, caps);
|
||||
return FALSE;
|
||||
}
|
||||
stop_failed:
|
||||
{
|
||||
GST_DEBUG_OBJECT (v4l2sink, "failed to stop streaming");
|
||||
|
|
|
@ -515,11 +515,6 @@ static gboolean
|
|||
gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
|
||||
{
|
||||
GstV4l2Src *v4l2src;
|
||||
gint w = 0, h = 0;
|
||||
gboolean interlaced;
|
||||
struct v4l2_fmtdesc *format;
|
||||
guint fps_n, fps_d;
|
||||
guint size;
|
||||
|
||||
v4l2src = GST_V4L2SRC (src);
|
||||
|
||||
|
@ -536,19 +531,7 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* we want our own v4l2 type of fourcc codes */
|
||||
if (!gst_v4l2_object_get_caps_info (v4l2src->v4l2object, caps, &format, &w,
|
||||
&h, &interlaced, &fps_n, &fps_d, &size)) {
|
||||
GST_INFO_OBJECT (v4l2src,
|
||||
"can't get capture format from caps %" GST_PTR_FORMAT, caps);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (v4l2src, "trying to set_capture %dx%d at %d/%d fps, "
|
||||
"format %s", w, h, fps_n, fps_d, format->description);
|
||||
|
||||
if (!gst_v4l2src_set_capture (v4l2src, format->pixelformat, w, h,
|
||||
interlaced, fps_n, fps_d))
|
||||
if (!gst_v4l2src_set_capture (v4l2src, caps))
|
||||
/* error already posted */
|
||||
return FALSE;
|
||||
|
||||
|
@ -565,7 +548,7 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
|
|||
return FALSE;
|
||||
|
||||
/* now store the expected output size */
|
||||
v4l2src->frame_byte_size = size;
|
||||
v4l2src->frame_byte_size = v4l2src->v4l2object->size;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -213,21 +213,18 @@ too_many_trials:
|
|||
* return value: TRUE on success, FALSE on error
|
||||
******************************************************/
|
||||
gboolean
|
||||
gst_v4l2src_set_capture (GstV4l2Src * v4l2src, guint32 pixelformat,
|
||||
guint32 width, guint32 height, gboolean interlaced,
|
||||
guint fps_n, guint fps_d)
|
||||
gst_v4l2src_set_capture (GstV4l2Src * v4l2src, GstCaps * caps)
|
||||
{
|
||||
gint fd = v4l2src->v4l2object->video_fd;
|
||||
struct v4l2_streamparm stream;
|
||||
guint fps_n, fps_d;
|
||||
|
||||
if (pixelformat == GST_MAKE_FOURCC ('M', 'P', 'E', 'G'))
|
||||
return TRUE;
|
||||
|
||||
if (!gst_v4l2_object_set_format (v4l2src->v4l2object, pixelformat, width,
|
||||
height, interlaced)) {
|
||||
if (!gst_v4l2_object_set_format (v4l2src->v4l2object, caps))
|
||||
/* error already reported */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fps_n = v4l2src->v4l2object->fps_n;
|
||||
fps_d = v4l2src->v4l2object->fps_d;
|
||||
|
||||
/* Is there a reason we require the caller to always specify a framerate? */
|
||||
GST_DEBUG_OBJECT (v4l2src, "Desired framerate: %u/%u", fps_n, fps_d);
|
||||
|
|
|
@ -27,11 +27,7 @@
|
|||
#include "gstv4l2src.h"
|
||||
#include "v4l2_calls.h"
|
||||
|
||||
gboolean gst_v4l2src_set_capture (GstV4l2Src * v4l2src,
|
||||
guint32 pixelformat,
|
||||
guint32 width, guint32 height,
|
||||
gboolean interlaced,
|
||||
guint32 fps_n, guint32 fps_d);
|
||||
gboolean gst_v4l2src_set_capture (GstV4l2Src * v4l2src, GstCaps *caps);
|
||||
|
||||
gboolean gst_v4l2src_capture_init (GstV4l2Src * v4l2src);
|
||||
gboolean gst_v4l2src_capture_start (GstV4l2Src * v4l2src);
|
||||
|
|
Loading…
Reference in a new issue