gentlsrc: allow two interfaces of the same producer to be opened in one process
Need to make it producer specific, and allow for multiple devices on the same interface
This commit is contained in:
parent
766d2de7e5
commit
63731a3b6f
@ -137,6 +137,7 @@ static gboolean gst_gentlsrc_unlock_stop (GstBaseSrc * src);
|
|||||||
static GstFlowReturn gst_gentlsrc_create (GstPushSrc * src, GstBuffer ** buf);
|
static GstFlowReturn gst_gentlsrc_create (GstPushSrc * src, GstBuffer ** buf);
|
||||||
|
|
||||||
static gchar *gst_gentlsrc_get_error_string (GstGenTlSrc * src);
|
static gchar *gst_gentlsrc_get_error_string (GstGenTlSrc * src);
|
||||||
|
static void gst_gentlsrc_cleanup_tl (GstGenTlSrc * src);
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -404,6 +405,9 @@ gst_gentlsrc_class_init (GstGenTlSrcClass * klass)
|
|||||||
"Attributes", "Attributes to change, comma separated key=value pairs",
|
"Attributes", "Attributes to change, comma separated key=value pairs",
|
||||||
DEFAULT_PROP_ATTRIBUTES, G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
|
DEFAULT_PROP_ATTRIBUTES, G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
|
||||||
|
|
||||||
|
klass->hTL = NULL;
|
||||||
|
g_mutex_init (&klass->tl_mutex);
|
||||||
|
klass->tl_refcount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -967,60 +971,63 @@ gst_gentlsrc_set_attributes (GstGenTlSrc * src)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_gentlsrc_start (GstBaseSrc * bsrc)
|
gst_gentlsrc_open_tl (GstGenTlSrc * src)
|
||||||
{
|
{
|
||||||
GstGenTlSrc *src = GST_GENTL_SRC (bsrc);
|
GstGenTlSrcClass *klass = GST_GENTL_SRC_GET_CLASS (src);
|
||||||
GC_ERROR ret;
|
GC_ERROR ret;
|
||||||
uint32_t i, num_ifaces, num_devs;
|
uint32_t i, num_ifaces;
|
||||||
guint32 width, height, stride;
|
|
||||||
GstVideoInfo vinfo;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (src, "start");
|
/* open framegrabber if it isn't already opened */
|
||||||
|
if (klass->tl_refcount > 0) {
|
||||||
if (src->producer_prop == GST_GENTLSRC_PRODUCER_BASLER) {
|
GST_DEBUG_OBJECT (src,
|
||||||
initialize_basler_addresses (&src->producer);
|
"Framegrabber interface already opened in this process, reusing");
|
||||||
} else if (src->producer_prop == GST_GENTLSRC_PRODUCER_EVT) {
|
src->hTL = klass->hTL;
|
||||||
initialize_evt_addresses (&src->producer);
|
klass->tl_refcount++;
|
||||||
} else {
|
} else {
|
||||||
g_assert_not_reached ();
|
/* initialize library and print info */
|
||||||
}
|
ret = GTL_GCInitLib ();
|
||||||
|
//HANDLE_GTL_ERROR ("GenTL Producer library could not be initialized");
|
||||||
|
|
||||||
/* bind functions from CTI */
|
gst_gentl_print_gentl_impl_info (src);
|
||||||
/* TODO: Enumerate CTI files in env var GENTL_GENTL64_PATH */
|
|
||||||
if (!gst_gentlsrc_bind_functions (src)) {
|
|
||||||
GST_ELEMENT_ERROR (src, LIBRARY, INIT,
|
|
||||||
("GenTL CTI could not be opened: %s", g_module_error ()), (NULL));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize library and print info */
|
/* open GenTL, print info, and update interface list */
|
||||||
ret = GTL_GCInitLib ();
|
ret = GTL_TLOpen (&src->hTL);
|
||||||
HANDLE_GTL_ERROR ("GenTL Producer library could not be initialized");
|
HANDLE_GTL_ERROR ("System module failed to open");
|
||||||
|
|
||||||
gst_gentl_print_gentl_impl_info (src);
|
gst_gentl_print_system_info (src);
|
||||||
|
|
||||||
/* open GenTL, print info, and update interface list */
|
ret = GTL_TLUpdateInterfaceList (src->hTL, NULL, src->timeout);
|
||||||
ret = GTL_TLOpen (&src->hTL);
|
HANDLE_GTL_ERROR ("Failed to update interface list within timeout");
|
||||||
HANDLE_GTL_ERROR ("System module failed to open");
|
|
||||||
|
|
||||||
gst_gentl_print_system_info (src);
|
/* print info for all interfaces and open specified interface */
|
||||||
|
ret = GTL_TLGetNumInterfaces (src->hTL, &num_ifaces);
|
||||||
ret = GTL_TLUpdateInterfaceList (src->hTL, NULL, src->timeout);
|
HANDLE_GTL_ERROR ("Failed to get number of interfaces");
|
||||||
HANDLE_GTL_ERROR ("Failed to update interface list within timeout");
|
if (num_ifaces > 0) {
|
||||||
|
GST_DEBUG_OBJECT (src, "Found %d GenTL interfaces", num_ifaces);
|
||||||
/* print info for all interfaces and open specified interface */
|
for (i = 0; i < num_ifaces; ++i) {
|
||||||
ret = GTL_TLGetNumInterfaces (src->hTL, &num_ifaces);
|
gst_gentl_print_interface_info (src, i);
|
||||||
HANDLE_GTL_ERROR ("Failed to get number of interfaces");
|
}
|
||||||
if (num_ifaces > 0) {
|
} else {
|
||||||
GST_DEBUG_OBJECT (src, "Found %d GenTL interfaces", num_ifaces);
|
GST_ELEMENT_ERROR (src, LIBRARY, FAILED, ("No interfaces found"), (NULL));
|
||||||
for (i = 0; i < num_ifaces; ++i) {
|
goto error;
|
||||||
gst_gentl_print_interface_info (src, i);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
GST_ELEMENT_ERROR (src, LIBRARY, FAILED, ("No interfaces found"), (NULL));
|
klass->hTL = src->hTL;
|
||||||
goto error;
|
klass->tl_refcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
error:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_gentlsrc_open_interface (GstGenTlSrc * src)
|
||||||
|
{
|
||||||
|
GstGenTlSrcClass *klass = GST_GENTL_SRC_GET_CLASS (src);
|
||||||
|
GC_ERROR ret;
|
||||||
|
|
||||||
if (!src->interface_id || src->interface_id[0] == 0) {
|
if (!src->interface_id || src->interface_id[0] == 0) {
|
||||||
size_t id_size;
|
size_t id_size;
|
||||||
GST_DEBUG_OBJECT (src, "Trying to find interface ID at index %d",
|
GST_DEBUG_OBJECT (src, "Trying to find interface ID at index %d",
|
||||||
@ -1042,6 +1049,54 @@ gst_gentlsrc_start (GstBaseSrc * bsrc)
|
|||||||
ret = GTL_TLOpenInterface (src->hTL, src->interface_id, &src->hIF);
|
ret = GTL_TLOpenInterface (src->hTL, src->interface_id, &src->hIF);
|
||||||
HANDLE_GTL_ERROR ("Interface module failed to open");
|
HANDLE_GTL_ERROR ("Interface module failed to open");
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
error:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_gentlsrc_start (GstBaseSrc * bsrc)
|
||||||
|
{
|
||||||
|
GstGenTlSrc *src = GST_GENTL_SRC (bsrc);
|
||||||
|
GstGenTlSrcClass *klass = GST_GENTL_SRC_GET_CLASS (src);
|
||||||
|
GC_ERROR ret;
|
||||||
|
uint32_t i, num_devs;
|
||||||
|
guint32 width, height, stride;
|
||||||
|
GstVideoInfo vinfo;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (src, "start");
|
||||||
|
|
||||||
|
if (src->producer_prop == GST_GENTLSRC_PRODUCER_BASLER) {
|
||||||
|
initialize_basler_addresses (&src->producer);
|
||||||
|
} else if (src->producer_prop == GST_GENTLSRC_PRODUCER_EVT) {
|
||||||
|
initialize_evt_addresses (&src->producer);
|
||||||
|
} else {
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bind functions from CTI */
|
||||||
|
/* TODO: Enumerate CTI files in env var GENTL_GENTL64_PATH */
|
||||||
|
if (!gst_gentlsrc_bind_functions (src)) {
|
||||||
|
GST_ELEMENT_ERROR (src, LIBRARY, INIT,
|
||||||
|
("GenTL CTI could not be opened: %s", g_module_error ()), (NULL));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_mutex_lock (&klass->tl_mutex);
|
||||||
|
|
||||||
|
if (!gst_gentlsrc_open_tl (src)) {
|
||||||
|
g_mutex_unlock (&klass->tl_mutex);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gst_gentlsrc_open_interface (src)) {
|
||||||
|
g_mutex_unlock (&klass->tl_mutex);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_mutex_unlock (&klass->tl_mutex);
|
||||||
|
|
||||||
ret = GTL_IFUpdateDeviceList (src->hIF, NULL, src->timeout);
|
ret = GTL_IFUpdateDeviceList (src->hIF, NULL, src->timeout);
|
||||||
HANDLE_GTL_ERROR ("Failed to update device list within timeout");
|
HANDLE_GTL_ERROR ("Failed to update device list within timeout");
|
||||||
|
|
||||||
@ -1392,16 +1447,32 @@ error:
|
|||||||
src->hIF = NULL;
|
src->hIF = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src->hTL) {
|
gst_gentlsrc_cleanup_tl (src);
|
||||||
GTL_TLClose (src->hTL);
|
|
||||||
src->hTL = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
GTL_GCCloseLib ();
|
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_gentlsrc_cleanup_tl (GstGenTlSrc * src)
|
||||||
|
{
|
||||||
|
GstGenTlSrcClass *klass = GST_GENTL_SRC_GET_CLASS (src);
|
||||||
|
if (src->hTL) {
|
||||||
|
g_mutex_lock (&klass->tl_mutex);
|
||||||
|
GST_DEBUG_OBJECT (src, "Framegrabber open with refcount=%d",
|
||||||
|
klass->tl_refcount);
|
||||||
|
klass->tl_refcount--;
|
||||||
|
if (klass->tl_refcount == 0) {
|
||||||
|
GST_DEBUG_OBJECT (src, "Framegrabber ref dropped to 0, closing");
|
||||||
|
GTL_TLClose (src->hTL);
|
||||||
|
src->hTL = NULL;
|
||||||
|
}
|
||||||
|
g_mutex_unlock (&klass->tl_mutex);
|
||||||
|
src->hTL = NULL;
|
||||||
|
|
||||||
|
GTL_GCCloseLib ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_gentlsrc_stop (GstBaseSrc * bsrc)
|
gst_gentlsrc_stop (GstBaseSrc * bsrc)
|
||||||
{
|
{
|
||||||
@ -1434,12 +1505,7 @@ gst_gentlsrc_stop (GstBaseSrc * bsrc)
|
|||||||
src->hIF = NULL;
|
src->hIF = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src->hTL) {
|
gst_gentlsrc_cleanup_tl (src);
|
||||||
GTL_TLClose (src->hTL);
|
|
||||||
src->hTL = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
GTL_GCCloseLib ();
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (src, "Closed data stream, device, interface, and library");
|
GST_DEBUG_OBJECT (src, "Closed data stream, device, interface, and library");
|
||||||
|
|
||||||
|
|||||||
@ -34,6 +34,8 @@ G_BEGIN_DECLS
|
|||||||
#define GST_GENTL_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GENTL_SRC,GstGenTlSrcClass))
|
#define GST_GENTL_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GENTL_SRC,GstGenTlSrcClass))
|
||||||
#define GST_IS_GENTL_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GENTL_SRC))
|
#define GST_IS_GENTL_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GENTL_SRC))
|
||||||
#define GST_IS_GENTL_SRC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GENTL_SRC))
|
#define GST_IS_GENTL_SRC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GENTL_SRC))
|
||||||
|
#define GST_GENTL_SRC_GET_CLASS(klass) \
|
||||||
|
(G_TYPE_INSTANCE_GET_CLASS ((klass), GST_TYPE_GENTL_SRC, GstGenTlSrcClass))
|
||||||
|
|
||||||
typedef struct _GstGenTlSrc GstGenTlSrc;
|
typedef struct _GstGenTlSrc GstGenTlSrc;
|
||||||
typedef struct _GstGenTlSrcClass GstGenTlSrcClass;
|
typedef struct _GstGenTlSrcClass GstGenTlSrcClass;
|
||||||
@ -116,6 +118,9 @@ struct _GstGenTlSrc
|
|||||||
struct _GstGenTlSrcClass
|
struct _GstGenTlSrcClass
|
||||||
{
|
{
|
||||||
GstPushSrcClass base_gentlsrc_class;
|
GstPushSrcClass base_gentlsrc_class;
|
||||||
|
TL_HANDLE hTL;
|
||||||
|
GMutex tl_mutex;
|
||||||
|
guint tl_refcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_gentlsrc_get_type (void);
|
GType gst_gentlsrc_get_type (void);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user