mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
v4l2: De-duplicate caps probing between src and sink
This commit is contained in:
parent
dd5d93f0f6
commit
48caa1712a
6 changed files with 62 additions and 129 deletions
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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) \
|
||||||
\
|
\
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue