mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +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);
|
||||
}
|
||||
|
||||
if (v4l2object->probed_caps) {
|
||||
gst_caps_unref (v4l2object->probed_caps);
|
||||
}
|
||||
|
||||
g_free (v4l2object);
|
||||
}
|
||||
|
||||
|
@ -1263,7 +1267,7 @@ failed:
|
|||
* Get the list of supported capture formats, a list of
|
||||
* <code>struct v4l2_fmtdesc</code>.
|
||||
*/
|
||||
GSList *
|
||||
static GSList *
|
||||
gst_v4l2_object_get_format_list (GstV4l2Object * v4l2object)
|
||||
{
|
||||
if (!v4l2object->formats)
|
||||
|
@ -1913,7 +1917,7 @@ sort_by_frame_size (GstStructure * s1, GstStructure * s2)
|
|||
}
|
||||
#endif
|
||||
|
||||
GstCaps *
|
||||
static GstCaps *
|
||||
gst_v4l2_object_probe_caps_for_format (GstV4l2Object * v4l2object,
|
||||
guint32 pixelformat, const GstStructure * template)
|
||||
{
|
||||
|
@ -2663,3 +2667,53 @@ invalid_buffer:
|
|||
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... */
|
||||
GSList *formats; /* list of available capture formats */
|
||||
GstCaps *probed_caps;
|
||||
|
||||
GList *colors;
|
||||
GList *norms;
|
||||
|
@ -223,11 +224,6 @@ GValueArray* gst_v4l2_probe_get_values (GstPropertyProbe * probe, guint pro
|
|||
GList ** klass_devices);
|
||||
#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);
|
||||
|
||||
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,
|
||||
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) \
|
||||
\
|
||||
|
|
|
@ -118,7 +118,6 @@ G_DEFINE_TYPE_WITH_CODE (GstV4l2Sink, gst_v4l2sink, GST_TYPE_VIDEO_SINK,
|
|||
gst_v4l2sink_video_orientation_interface_init));
|
||||
|
||||
|
||||
static void gst_v4l2sink_dispose (GObject * object);
|
||||
static void gst_v4l2sink_finalize (GstV4l2Sink * v4l2sink);
|
||||
|
||||
/* GObject methods: */
|
||||
|
@ -154,7 +153,6 @@ gst_v4l2sink_class_init (GstV4l2SinkClass * klass)
|
|||
element_class = GST_ELEMENT_CLASS (klass);
|
||||
basesink_class = GST_BASE_SINK_CLASS (klass);
|
||||
|
||||
gobject_class->dispose = gst_v4l2sink_dispose;
|
||||
gobject_class->finalize = (GObjectFinalizeFunc) gst_v4l2sink_finalize;
|
||||
gobject_class->set_property = gst_v4l2sink_set_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);
|
||||
|
||||
v4l2sink->probed_caps = NULL;
|
||||
|
||||
v4l2sink->overlay_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
|
||||
gst_v4l2sink_finalize (GstV4l2Sink * v4l2sink)
|
||||
{
|
||||
|
@ -506,9 +489,6 @@ static GstCaps *
|
|||
gst_v4l2sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
|
||||
{
|
||||
GstV4l2Sink *v4l2sink = GST_V4L2SINK (bsink);
|
||||
GstCaps *ret;
|
||||
GSList *walk;
|
||||
GSList *formats;
|
||||
|
||||
if (!GST_V4L2_IS_OPEN (v4l2sink->v4l2object)) {
|
||||
/* 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));
|
||||
}
|
||||
|
||||
if (v4l2sink->probed_caps == NULL) {
|
||||
formats = gst_v4l2_object_get_format_list (v4l2sink->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 (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;
|
||||
return gst_v4l2_object_get_caps (v4l2sink->v4l2object, filter);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
|
@ -54,7 +54,6 @@ struct _GstV4l2Sink {
|
|||
|
||||
/*< private >*/
|
||||
GstV4l2Object * v4l2object;
|
||||
GstCaps *probed_caps; /* all supported caps of underlying v4l2 device */
|
||||
|
||||
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,
|
||||
gst_v4l2src_video_orientation_interface_init));
|
||||
|
||||
static void gst_v4l2src_dispose (GObject * object);
|
||||
static void gst_v4l2src_finalize (GstV4l2Src * v4l2src);
|
||||
|
||||
/* element methods */
|
||||
|
@ -148,7 +147,6 @@ gst_v4l2src_class_init (GstV4l2SrcClass * klass)
|
|||
basesrc_class = GST_BASE_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->set_property = gst_v4l2src_set_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);
|
||||
}
|
||||
|
||||
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
|
||||
gst_v4l2src_finalize (GstV4l2Src * v4l2src)
|
||||
|
@ -437,9 +423,6 @@ gst_v4l2src_get_caps (GstBaseSrc * src, GstCaps * filter)
|
|||
{
|
||||
GstV4l2Src *v4l2src;
|
||||
GstV4l2Object *obj;
|
||||
GstCaps *ret;
|
||||
GSList *walk;
|
||||
GSList *formats;
|
||||
|
||||
v4l2src = GST_V4L2SRC (src);
|
||||
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));
|
||||
}
|
||||
|
||||
if (v4l2src->probed_caps)
|
||||
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;
|
||||
return gst_v4l2_object_get_caps (obj, filter);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -741,10 +690,6 @@ gst_v4l2src_change_state (GstElement * element, GstStateChange transition)
|
|||
if (!gst_v4l2_object_close (obj))
|
||||
return GST_STATE_CHANGE_FAILURE;
|
||||
|
||||
if (v4l2src->probed_caps) {
|
||||
gst_caps_unref (v4l2src->probed_caps);
|
||||
v4l2src->probed_caps = NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -57,9 +57,6 @@ struct _GstV4l2Src
|
|||
/*< private >*/
|
||||
GstV4l2Object * v4l2object;
|
||||
|
||||
/* pads */
|
||||
GstCaps *probed_caps;
|
||||
|
||||
guint64 offset;
|
||||
|
||||
GstClockTime ctrl_time;
|
||||
|
|
Loading…
Reference in a new issue