v4l2: De-duplicate caps probing between src and sink

This commit is contained in:
Olivier Crête 2012-10-22 17:58:07 -04:00
parent dd5d93f0f6
commit 48caa1712a
6 changed files with 62 additions and 129 deletions

View file

@ -593,6 +593,10 @@ gst_v4l2_object_destroy (GstV4l2Object * v4l2object)
gst_v4l2_object_clear_format_list (v4l2object); gst_v4l2_object_clear_format_list (v4l2object);
} }
if (v4l2object->probed_caps) {
gst_caps_unref (v4l2object->probed_caps);
}
g_free (v4l2object); g_free (v4l2object);
} }
@ -1263,7 +1267,7 @@ failed:
* Get the list of supported capture formats, a list of * Get the list of supported capture formats, a list of
* <code>struct v4l2_fmtdesc</code>. * <code>struct v4l2_fmtdesc</code>.
*/ */
GSList * static GSList *
gst_v4l2_object_get_format_list (GstV4l2Object * v4l2object) gst_v4l2_object_get_format_list (GstV4l2Object * v4l2object)
{ {
if (!v4l2object->formats) if (!v4l2object->formats)
@ -1913,7 +1917,7 @@ sort_by_frame_size (GstStructure * s1, GstStructure * s2)
} }
#endif #endif
GstCaps * static GstCaps *
gst_v4l2_object_probe_caps_for_format (GstV4l2Object * v4l2object, gst_v4l2_object_probe_caps_for_format (GstV4l2Object * v4l2object,
guint32 pixelformat, const GstStructure * template) guint32 pixelformat, const GstStructure * template)
{ {
@ -2663,3 +2667,53 @@ invalid_buffer:
return FALSE; return FALSE;
} }
} }
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_structure (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: %p", ret);
LOG_CAPS (v4l2object->element, ret);
return ret;
}

View file

@ -139,6 +139,7 @@ struct _GstV4l2Object {
/* lists... */ /* lists... */
GSList *formats; /* list of available capture formats */ GSList *formats; /* list of available capture formats */
GstCaps *probed_caps;
GList *colors; GList *colors;
GList *norms; GList *norms;
@ -223,11 +224,6 @@ GValueArray* gst_v4l2_probe_get_values (GstPropertyProbe * probe, guint pro
GList ** klass_devices); GList ** klass_devices);
#endif #endif
GstCaps* gst_v4l2_object_probe_caps_for_format (GstV4l2Object *v4l2object, guint32 pixelformat,
const GstStructure * template);
GSList* gst_v4l2_object_get_format_list (GstV4l2Object *v4l2object);
GstCaps* gst_v4l2_object_get_all_caps (void); GstCaps* gst_v4l2_object_get_all_caps (void);
GstStructure* gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc); GstStructure* gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc);
@ -245,6 +241,9 @@ gboolean gst_v4l2_object_stop (GstV4l2Object *v4l2object);
gboolean gst_v4l2_object_copy (GstV4l2Object * v4l2object, gboolean gst_v4l2_object_copy (GstV4l2Object * v4l2object,
GstBuffer * dest, GstBuffer *src); GstBuffer * dest, GstBuffer *src);
GstCaps * gst_v4l2_object_get_caps (GstV4l2Object * v4l2object,
GstCaps * filter);
#define GST_IMPLEMENT_V4L2_PROBE_METHODS(Type_Class, interface_as_function) \ #define GST_IMPLEMENT_V4L2_PROBE_METHODS(Type_Class, interface_as_function) \
\ \

View file

@ -118,7 +118,6 @@ G_DEFINE_TYPE_WITH_CODE (GstV4l2Sink, gst_v4l2sink, GST_TYPE_VIDEO_SINK,
gst_v4l2sink_video_orientation_interface_init)); gst_v4l2sink_video_orientation_interface_init));
static void gst_v4l2sink_dispose (GObject * object);
static void gst_v4l2sink_finalize (GstV4l2Sink * v4l2sink); static void gst_v4l2sink_finalize (GstV4l2Sink * v4l2sink);
/* GObject methods: */ /* GObject methods: */
@ -154,7 +153,6 @@ gst_v4l2sink_class_init (GstV4l2SinkClass * klass)
element_class = GST_ELEMENT_CLASS (klass); element_class = GST_ELEMENT_CLASS (klass);
basesink_class = GST_BASE_SINK_CLASS (klass); basesink_class = GST_BASE_SINK_CLASS (klass);
gobject_class->dispose = gst_v4l2sink_dispose;
gobject_class->finalize = (GObjectFinalizeFunc) gst_v4l2sink_finalize; gobject_class->finalize = (GObjectFinalizeFunc) gst_v4l2sink_finalize;
gobject_class->set_property = gst_v4l2sink_set_property; gobject_class->set_property = gst_v4l2sink_set_property;
gobject_class->get_property = gst_v4l2sink_get_property; gobject_class->get_property = gst_v4l2sink_get_property;
@ -232,26 +230,11 @@ gst_v4l2sink_init (GstV4l2Sink * v4l2sink)
*/ */
g_object_set (v4l2sink, "device", "/dev/video1", NULL); g_object_set (v4l2sink, "device", "/dev/video1", NULL);
v4l2sink->probed_caps = NULL;
v4l2sink->overlay_fields_set = 0; v4l2sink->overlay_fields_set = 0;
v4l2sink->crop_fields_set = 0; v4l2sink->crop_fields_set = 0;
} }
static void
gst_v4l2sink_dispose (GObject * object)
{
GstV4l2Sink *v4l2sink = GST_V4L2SINK (object);
if (v4l2sink->probed_caps) {
gst_caps_unref (v4l2sink->probed_caps);
}
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void static void
gst_v4l2sink_finalize (GstV4l2Sink * v4l2sink) gst_v4l2sink_finalize (GstV4l2Sink * v4l2sink)
{ {
@ -506,9 +489,6 @@ static GstCaps *
gst_v4l2sink_get_caps (GstBaseSink * bsink, GstCaps * filter) gst_v4l2sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
{ {
GstV4l2Sink *v4l2sink = GST_V4L2SINK (bsink); GstV4l2Sink *v4l2sink = GST_V4L2SINK (bsink);
GstCaps *ret;
GSList *walk;
GSList *formats;
if (!GST_V4L2_IS_OPEN (v4l2sink->v4l2object)) { if (!GST_V4L2_IS_OPEN (v4l2sink->v4l2object)) {
/* FIXME: copy? */ /* FIXME: copy? */
@ -516,49 +496,8 @@ gst_v4l2sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
return gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD (v4l2sink)); return gst_pad_get_pad_template_caps (GST_BASE_SINK_PAD (v4l2sink));
} }
if (v4l2sink->probed_caps == NULL) {
formats = gst_v4l2_object_get_format_list (v4l2sink->v4l2object);
ret = gst_caps_new_empty (); return gst_v4l2_object_get_caps (v4l2sink->v4l2object, filter);
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_structure (format->pixelformat);
if (template) {
GstCaps *tmp;
tmp =
gst_v4l2_object_probe_caps_for_format (v4l2sink->v4l2object,
format->pixelformat, template);
if (tmp)
gst_caps_append (ret, tmp);
gst_structure_free (template);
} else {
GST_DEBUG_OBJECT (v4l2sink, "unknown format %u", format->pixelformat);
}
}
v4l2sink->probed_caps = ret;
}
if (filter) {
ret =
gst_caps_intersect_full (filter, v4l2sink->probed_caps,
GST_CAPS_INTERSECT_FIRST);
} else {
ret = gst_caps_ref (v4l2sink->probed_caps);
}
GST_INFO_OBJECT (v4l2sink, "probed caps: %p", ret);
LOG_CAPS (v4l2sink, ret);
return ret;
} }
static gboolean static gboolean

View file

@ -54,7 +54,6 @@ struct _GstV4l2Sink {
/*< private >*/ /*< private >*/
GstV4l2Object * v4l2object; GstV4l2Object * v4l2object;
GstCaps *probed_caps; /* all supported caps of underlying v4l2 device */
gint video_width, video_height; /* original (unscaled) video w/h */ gint video_width, video_height; /* original (unscaled) video w/h */

View file

@ -109,7 +109,6 @@ G_DEFINE_TYPE_WITH_CODE (GstV4l2Src, gst_v4l2src, GST_TYPE_PUSH_SRC,
G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_ORIENTATION, G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_ORIENTATION,
gst_v4l2src_video_orientation_interface_init)); gst_v4l2src_video_orientation_interface_init));
static void gst_v4l2src_dispose (GObject * object);
static void gst_v4l2src_finalize (GstV4l2Src * v4l2src); static void gst_v4l2src_finalize (GstV4l2Src * v4l2src);
/* element methods */ /* element methods */
@ -148,7 +147,6 @@ gst_v4l2src_class_init (GstV4l2SrcClass * klass)
basesrc_class = GST_BASE_SRC_CLASS (klass); basesrc_class = GST_BASE_SRC_CLASS (klass);
pushsrc_class = GST_PUSH_SRC_CLASS (klass); pushsrc_class = GST_PUSH_SRC_CLASS (klass);
gobject_class->dispose = gst_v4l2src_dispose;
gobject_class->finalize = (GObjectFinalizeFunc) gst_v4l2src_finalize; gobject_class->finalize = (GObjectFinalizeFunc) gst_v4l2src_finalize;
gobject_class->set_property = gst_v4l2src_set_property; gobject_class->set_property = gst_v4l2src_set_property;
gobject_class->get_property = gst_v4l2src_get_property; gobject_class->get_property = gst_v4l2src_get_property;
@ -219,18 +217,6 @@ gst_v4l2src_init (GstV4l2Src * v4l2src)
gst_base_src_set_live (GST_BASE_SRC (v4l2src), TRUE); gst_base_src_set_live (GST_BASE_SRC (v4l2src), TRUE);
} }
static void
gst_v4l2src_dispose (GObject * object)
{
GstV4l2Src *v4l2src = GST_V4L2SRC (object);
if (v4l2src->probed_caps) {
gst_caps_unref (v4l2src->probed_caps);
}
G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void static void
gst_v4l2src_finalize (GstV4l2Src * v4l2src) gst_v4l2src_finalize (GstV4l2Src * v4l2src)
@ -437,9 +423,6 @@ gst_v4l2src_get_caps (GstBaseSrc * src, GstCaps * filter)
{ {
GstV4l2Src *v4l2src; GstV4l2Src *v4l2src;
GstV4l2Object *obj; GstV4l2Object *obj;
GstCaps *ret;
GSList *walk;
GSList *formats;
v4l2src = GST_V4L2SRC (src); v4l2src = GST_V4L2SRC (src);
obj = v4l2src->v4l2object; obj = v4l2src->v4l2object;
@ -448,41 +431,7 @@ gst_v4l2src_get_caps (GstBaseSrc * src, GstCaps * filter)
return gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (v4l2src)); return gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (v4l2src));
} }
if (v4l2src->probed_caps) return gst_v4l2_object_get_caps (obj, filter);
return gst_caps_ref (v4l2src->probed_caps);
formats = gst_v4l2_object_get_format_list (obj);
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_structure (format->pixelformat);
if (template) {
GstCaps *tmp;
tmp =
gst_v4l2_object_probe_caps_for_format (obj,
format->pixelformat, template);
if (tmp)
gst_caps_append (ret, tmp);
gst_structure_free (template);
} else {
GST_DEBUG_OBJECT (v4l2src, "unknown format %u", format->pixelformat);
}
}
v4l2src->probed_caps = gst_caps_ref (ret);
GST_INFO_OBJECT (v4l2src, "probed caps: %" GST_PTR_FORMAT, ret);
return ret;
} }
static gboolean static gboolean
@ -741,10 +690,6 @@ gst_v4l2src_change_state (GstElement * element, GstStateChange transition)
if (!gst_v4l2_object_close (obj)) if (!gst_v4l2_object_close (obj))
return GST_STATE_CHANGE_FAILURE; return GST_STATE_CHANGE_FAILURE;
if (v4l2src->probed_caps) {
gst_caps_unref (v4l2src->probed_caps);
v4l2src->probed_caps = NULL;
}
break; break;
default: default:
break; break;

View file

@ -57,9 +57,6 @@ struct _GstV4l2Src
/*< private >*/ /*< private >*/
GstV4l2Object * v4l2object; GstV4l2Object * v4l2object;
/* pads */
GstCaps *probed_caps;
guint64 offset; guint64 offset;
GstClockTime ctrl_time; GstClockTime ctrl_time;