Merge branch 'joshdoe:master' into master

This commit is contained in:
yair 2023-04-26 22:45:27 +03:00 committed by GitHub
commit 6f48029c63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 569 additions and 144 deletions

View File

@ -24,15 +24,15 @@ endif ()
set (_Pleora_PATHS PATHS set (_Pleora_PATHS PATHS
"${Pleora_DIR}" "${Pleora_DIR}"
"C:/Program Files/Pleora Technologies Inc/eBUS SDK/Includes" "C:/Program Files/Pleora Technologies Inc/eBUS SDK"
"C:/Program Files (x86)/Pleora Technologies Inc/eBUS SDK/Includes") "C:/Program Files (x86)/Pleora Technologies Inc/eBUS SDK")
find_path (Pleora_INCLUDE_DIR PvBase.h find_path (Pleora_INCLUDE_DIR PvBase.h
PATHS ${_Pleora_PATHS} PATHS ${_Pleora_PATHS}
PATH_SUFFIXES Includes include) PATH_SUFFIXES Includes include)
message (STATUS "Found Pleora include dir in ${Pleora_INCLUDE_DIR}") message (STATUS "Found Pleora include dir in ${Pleora_INCLUDE_DIR}")
find_path (Pleora_LIBRARY_DIR NAMES libPvBase.so "PvBase${_LIB_NAME}" find_path (Pleora_LIBRARY_DIR NAMES libPvBase.so "PvBase${_LIB_SUFFIX}.lib"
PATHS ${_Pleora_PATHS} PATHS ${_Pleora_PATHS}
PATH_SUFFIXES Libraries lib) PATH_SUFFIXES Libraries lib)

View File

@ -64,6 +64,7 @@ initialize_evt_addresses (GstGenTlProducer * producer)
producer->cti_path = producer->cti_path =
g_strdup ("C:\\Program Files\\EVT\\eSDK\\bin\\EmergentGenTL.cti"); g_strdup ("C:\\Program Files\\EVT\\eSDK\\bin\\EmergentGenTL.cti");
producer->acquisition_mode_value = 0; producer->acquisition_mode_value = 0;
producer->timestamp_control_latch_value = 2;
producer->width = 0xA000; producer->width = 0xA000;
producer->height = 0xA004; producer->height = 0xA004;
producer->pixel_format = 0xA008; producer->pixel_format = 0xA008;
@ -76,6 +77,7 @@ initialize_evt_addresses (GstGenTlProducer * producer)
producer->timestamp_control_latch = 0x944; producer->timestamp_control_latch = 0x944;
producer->timestamp_low = 0x094C; producer->timestamp_low = 0x094C;
producer->timestamp_high = 0x0948; producer->timestamp_high = 0x0948;
producer->port_endianness = G_BIG_ENDIAN;
} }
static void static void
@ -93,8 +95,31 @@ initialize_basler_addresses (GstGenTlProducer * producer)
producer->acquisition_mode = 0x40004; producer->acquisition_mode = 0x40004;
producer->acquisition_start = 0x40024; producer->acquisition_start = 0x40024;
producer->acquisition_stop = 0x40044; producer->acquisition_stop = 0x40044;
producer->port_endianness = G_BIG_ENDIAN;
} }
static void
initialize_flir_addresses (GstGenTlProducer * producer)
{
memset (producer, 0, sizeof (producer));
producer->cti_path =
g_strdup
("C:\\Program Files\\FLIR Systems\\Spinnaker\\cti64\\vs2015\\FLIR_GenTL_v140.cti");
producer->acquisition_mode_value = 0;
producer->timestamp_control_latch_value = 1;
producer->width = 0x00081084;
producer->height = 0x00081064;
producer->pixel_format = 0x00086008;
producer->payload_size = 0x20002008;
producer->acquisition_mode = 0x000C00C8;
producer->acquisition_start = 0x000C0004;
producer->acquisition_stop = 0x000C0024;
producer->timestamp_control_latch = 0x1F8;
producer->timestamp = 0x1F0;
producer->port_endianness = G_LITTLE_ENDIAN;
}
#define GST_TYPE_GENTLSRC_PRODUCER (gst_gentlsrc_producer_get_type()) #define GST_TYPE_GENTLSRC_PRODUCER (gst_gentlsrc_producer_get_type())
static GType static GType
gst_gentlsrc_producer_get_type (void) gst_gentlsrc_producer_get_type (void)
@ -103,6 +128,7 @@ gst_gentlsrc_producer_get_type (void)
static const GEnumValue gentlsrc_producer[] = { static const GEnumValue gentlsrc_producer[] = {
{GST_GENTLSRC_PRODUCER_BASLER, "Basler producer", "basler"}, {GST_GENTLSRC_PRODUCER_BASLER, "Basler producer", "basler"},
{GST_GENTLSRC_PRODUCER_EVT, "EVT producer", "evt"}, {GST_GENTLSRC_PRODUCER_EVT, "EVT producer", "evt"},
{GST_GENTLSRC_PRODUCER_FLIR, "FLIR producer", "flir"},
{0, NULL, NULL}, {0, NULL, NULL},
}; };
@ -135,6 +161,7 @@ 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); static void gst_gentlsrc_cleanup_tl (GstGenTlSrc * src);
static gboolean gst_gentlsrc_src_latch_timestamps (GstGenTlSrc * src);
enum enum
{ {
@ -144,6 +171,7 @@ enum
PROP_INTERFACE_ID, PROP_INTERFACE_ID,
PROP_DEVICE_INDEX, PROP_DEVICE_INDEX,
PROP_DEVICE_ID, PROP_DEVICE_ID,
PROP_DEVICE_USER_ID,
PROP_STREAM_INDEX, PROP_STREAM_INDEX,
PROP_STREAM_ID, PROP_STREAM_ID,
PROP_NUM_CAPTURE_BUFFERS, PROP_NUM_CAPTURE_BUFFERS,
@ -156,6 +184,7 @@ enum
#define DEFAULT_PROP_INTERFACE_ID "" #define DEFAULT_PROP_INTERFACE_ID ""
#define DEFAULT_PROP_DEVICE_INDEX 0 #define DEFAULT_PROP_DEVICE_INDEX 0
#define DEFAULT_PROP_DEVICE_ID "" #define DEFAULT_PROP_DEVICE_ID ""
#define DEFAULT_PROP_DEVICE_USER_ID ""
#define DEFAULT_PROP_STREAM_INDEX 0 #define DEFAULT_PROP_STREAM_INDEX 0
#define DEFAULT_PROP_STREAM_ID "" #define DEFAULT_PROP_STREAM_ID ""
#define DEFAULT_PROP_NUM_CAPTURE_BUFFERS 3 #define DEFAULT_PROP_NUM_CAPTURE_BUFFERS 3
@ -382,6 +411,12 @@ gst_gentlsrc_class_init (GstGenTlSrcClass * klass)
DEFAULT_PROP_DEVICE_ID, DEFAULT_PROP_DEVICE_ID,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY))); GST_PARAM_MUTABLE_READY)));
g_object_class_install_property (gobject_class, PROP_DEVICE_USER_ID,
g_param_spec_string ("device-user-id", "Device User ID",
"Device User ID, overrides all other interface/device properties",
DEFAULT_PROP_DEVICE_USER_ID,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
GST_PARAM_MUTABLE_READY)));
g_object_class_install_property (gobject_class, PROP_STREAM_INDEX, g_object_class_install_property (gobject_class, PROP_STREAM_INDEX,
g_param_spec_uint ("stream-index", "Stream index", g_param_spec_uint ("stream-index", "Stream index",
"Stream index number, zero-based, overridden by stream-id", "Stream index number, zero-based, overridden by stream-id",
@ -417,8 +452,8 @@ gst_gentlsrc_class_init (GstGenTlSrcClass * klass)
static void static void
gst_gentlsrc_reset (GstGenTlSrc * src) gst_gentlsrc_reset (GstGenTlSrc * src)
{ {
src->gentl_latched_ticks = 0; src->gentl_latched_ns = 0;
src->unix_latched_time = 0; src->unix_latched_ns = 0;
src->error_string[0] = 0; src->error_string[0] = 0;
src->last_frame_count = 0; src->last_frame_count = 0;
@ -484,6 +519,10 @@ gst_gentlsrc_set_property (GObject * object, guint property_id,
g_free (src->device_id); g_free (src->device_id);
src->device_id = g_strdup (g_value_get_string (value)); src->device_id = g_strdup (g_value_get_string (value));
break; break;
case PROP_DEVICE_USER_ID:
g_free (src->device_user_id);
src->device_user_id = g_strdup (g_value_get_string (value));
break;
case PROP_STREAM_INDEX: case PROP_STREAM_INDEX:
src->stream_index = g_value_get_uint (value); src->stream_index = g_value_get_uint (value);
break; break;
@ -533,6 +572,9 @@ gst_gentlsrc_get_property (GObject * object, guint property_id,
case PROP_DEVICE_ID: case PROP_DEVICE_ID:
g_value_set_string (value, src->device_id); g_value_set_string (value, src->device_id);
break; break;
case PROP_DEVICE_USER_ID:
g_value_set_string (value, src->device_user_id);
break;
case PROP_STREAM_INDEX: case PROP_STREAM_INDEX:
g_value_set_uint (value, src->stream_index); g_value_set_uint (value, src->stream_index);
break; break;
@ -704,9 +746,11 @@ gst_gentl_print_device_info (GstGenTlSrc * src, uint32_t index)
char model[GTL_MAX_STR_SIZE]; char model[GTL_MAX_STR_SIZE];
char tl_type[GTL_MAX_STR_SIZE]; char tl_type[GTL_MAX_STR_SIZE];
char display_name[GTL_MAX_STR_SIZE]; char display_name[GTL_MAX_STR_SIZE];
char user_defined_name[GTL_MAX_STR_SIZE];
gint32 access_status; gint32 access_status;
INFO_DATATYPE datatype; INFO_DATATYPE datatype;
str_size = GTL_MAX_STR_SIZE;
ret = GTL_IFGetDeviceID (src->hIF, index, dev_id, &str_size); ret = GTL_IFGetDeviceID (src->hIF, index, dev_id, &str_size);
if (ret != GC_ERR_SUCCESS) { if (ret != GC_ERR_SUCCESS) {
GST_WARNING_OBJECT (src, "Failed to get device id: %s", GST_WARNING_OBJECT (src, "Failed to get device id: %s",
@ -729,13 +773,17 @@ gst_gentl_print_device_info (GstGenTlSrc * src, uint32_t index)
str_size = GTL_MAX_STR_SIZE; str_size = GTL_MAX_STR_SIZE;
GTL_IFGetDeviceInfo (src->hIF, dev_id, DEVICE_INFO_DISPLAYNAME, &datatype, GTL_IFGetDeviceInfo (src->hIF, dev_id, DEVICE_INFO_DISPLAYNAME, &datatype,
display_name, &str_size); display_name, &str_size);
str_size = GTL_MAX_STR_SIZE;
GTL_IFGetDeviceInfo (src->hIF, dev_id, DEVICE_INFO_USER_DEFINED_NAME,
&datatype, user_defined_name, &str_size);
str_size = sizeof (access_status); str_size = sizeof (access_status);
GTL_IFGetDeviceInfo (src->hIF, dev_id, DEVICE_INFO_ACCESS_STATUS, &datatype, GTL_IFGetDeviceInfo (src->hIF, dev_id, DEVICE_INFO_ACCESS_STATUS, &datatype,
&access_status, &str_size); &access_status, &str_size);
GST_DEBUG_OBJECT (src, GST_DEBUG_OBJECT (src,
"Device %d: ID=%s, Vendor=%s, Model=%s, TL_Type=%s, Display_Name=%s, Access_Status=%d", "Device %d: ID=%s, Vendor=%s, Model=%s, TL_Type=%s, Display_Name=%s, User_Name=%s, Access_Status=%d",
index, id, vendor, model, tl_type, display_name, access_status); index, id, vendor, model, tl_type, display_name, user_defined_name,
access_status);
} }
//void gst_gentl_print_stream_info (GstGenTlSrc * src) //void gst_gentl_print_stream_info (GstGenTlSrc * src)
@ -775,6 +823,111 @@ gst_gentl_print_device_info (GstGenTlSrc * src, uint32_t index)
//} //}
static guint32
read_uint32 (GstGenTlSrc * src, guint64 addr, GC_ERROR * ret)
{
guint32 value;
size_t datasize = 4;
*ret = GTL_GCReadPort (src->hDevPort, addr, &value, &datasize);
if (*ret != GC_ERR_SUCCESS) {
GST_ELEMENT_ERROR (src, LIBRARY, FAILED,
("Failed to read address: %s", gst_gentlsrc_get_error_string (src)),
(NULL));
goto error;
}
if (src->producer.port_endianness == G_BIG_ENDIAN)
value = GUINT32_FROM_BE (value);
else
value = GUINT32_FROM_LE (value);
return value;
error:
return 0;
}
static gboolean
write_uint32 (GstGenTlSrc * src, guint64 addr, guint32 value)
{
GC_ERROR ret;
size_t datasize = 4;
if (src->producer.port_endianness == G_BIG_ENDIAN)
value = GUINT32_TO_BE (value);
else
value = GUINT32_TO_LE (value);
ret = GTL_GCWritePort (src->hDevPort, addr, &value, &datasize);
HANDLE_GTL_ERROR ("Failed to write address");
return ret;
error:
return ret;
}
static guint64
read_uint64_single (GstGenTlSrc * src, guint64 addr, GC_ERROR * ret)
{
guint64 value;
size_t datasize = 8;
*ret = GTL_GCReadPort (src->hDevPort, addr, &value, &datasize);
if (*ret != GC_ERR_SUCCESS) {
GST_ELEMENT_ERROR (src, LIBRARY, FAILED,
("Failed to read address: %s", gst_gentlsrc_get_error_string (src)),
(NULL));
goto error;
}
if (src->producer.port_endianness == G_BIG_ENDIAN)
value = GUINT64_FROM_BE (value);
else
value = GUINT64_FROM_LE (value);
return value;
error:
return 0;
}
static guint64
read_uint64 (GstGenTlSrc * src, guint64 low_addr, guint64 high_addr,
GC_ERROR * ret)
{
guint32 low, high;
size_t datasize = 4;
guint64 value;
*ret = GTL_GCReadPort (src->hDevPort, low_addr, &low, &datasize);
if (*ret != GC_ERR_SUCCESS) {
GST_ELEMENT_ERROR (src, LIBRARY, FAILED,
("Failed to read lower address: %s",
gst_gentlsrc_get_error_string (src)), (NULL));
goto error;
}
*ret = GTL_GCReadPort (src->hDevPort, high_addr, &high, &datasize);
if (*ret != GC_ERR_SUCCESS) {
GST_ELEMENT_ERROR (src, LIBRARY, FAILED,
("Failed to read upper address: %s",
gst_gentlsrc_get_error_string (src)), (NULL));
goto error;
}
if (src->producer.port_endianness == G_BIG_ENDIAN)
value = GUINT64_FROM_BE ((guint64) low << 32 | high);
else
value = GUINT64_FROM_LE ((guint64) low << 32 | high);
return value;
error:
return 0;
}
static size_t static size_t
gst_gentlsrc_get_payload_size (GstGenTlSrc * src) gst_gentlsrc_get_payload_size (GstGenTlSrc * src)
{ {
@ -798,13 +951,9 @@ gst_gentlsrc_get_payload_size (GstGenTlSrc * src)
payload_size); payload_size);
} else { } else {
guint32 val = 0; guint32 val = 0;
size_t datasize = 4;
// TODO: use node map // TODO: use node map
ret = payload_size = read_uint32 (src, src->producer.payload_size, &ret);
GTL_GCReadPort (src->hDevPort, src->producer.payload_size, &val,
&datasize);
HANDLE_GTL_ERROR ("Failed to get payload size"); HANDLE_GTL_ERROR ("Failed to get payload size");
payload_size = GUINT32_FROM_BE (val);
GST_DEBUG_OBJECT (src, "Payload size defined by node map: %d", GST_DEBUG_OBJECT (src, "Payload size defined by node map: %d",
payload_size); payload_size);
@ -860,65 +1009,79 @@ gst_gentlsrc_get_gev_tick_frequency (GstGenTlSrc * src)
{ {
GC_ERROR ret; GC_ERROR ret;
if (!src->producer.tick_frequency_high || !src->producer.tick_frequency_low) if (!src->producer.tick_frequency_high || !src->producer.tick_frequency_low) {
// latch timestamps once
if (gst_gentlsrc_src_latch_timestamps (src)) {
GST_DEBUG_OBJECT (src, "Assuming timestamps are in nanoseconds");
return GST_SECOND;
} else {
GST_ERROR_OBJECT (src, "Tick frequency addresses aren't defined");
return 0; return 0;
}
}
guint32 freq_low, freq_high; guint64 tick_frequency = read_uint64 (src, src->producer.tick_frequency_low,
size_t datasize = 4; src->producer.tick_frequency_high, &ret);
ret = GTL_GCReadPort (src->hDevPort, src->producer.tick_frequency_low, &freq_low, &datasize); // GevTimestampTickFrequencyLow
HANDLE_GTL_ERROR ("Failed to get GevTimestampTickFrequencyLow");
ret = GTL_GCReadPort (src->hDevPort, src->producer.tick_frequency_high, &freq_high, &datasize); // GevTimestampTickFrequencyHigh
HANDLE_GTL_ERROR ("Failed to get GevTimestampTickFrequencyHigh");
guint64 tick_frequency =
GUINT64_FROM_BE ((guint64) freq_low << 32 | freq_high);
GST_DEBUG_OBJECT (src, "GEV Timestamp tick frequency is %llu", GST_DEBUG_OBJECT (src, "GEV Timestamp tick frequency is %llu",
tick_frequency); tick_frequency);
return tick_frequency; return tick_frequency;
error:
return 0;
} }
static guint64 static guint64
gst_gentlsrc_get_gev_timestamp_ticks (GstGenTlSrc * src) gst_gentlsrc_get_gev_timestamp_ns (GstGenTlSrc * src)
{ {
GC_ERROR ret; GC_ERROR ret;
size_t datasize = 4; guint64 timestamp_ns;
guint32 val, ts_low, ts_high;
val = GUINT32_TO_BE (2); ret =
datasize = sizeof (val); write_uint32 (src, src->producer.timestamp_control_latch,
ret = GTL_GCWritePort (src->hDevPort, src->producer.timestamp_control_latch, &val, &datasize); // GevTimestampControlLatch src->producer.timestamp_control_latch_value);
HANDLE_GTL_WARNING ("Failed to latch timestamp GevTimestampControlLatch"); HANDLE_GTL_WARNING ("Failed to latch timestamp GevTimestampControlLatch");
ret = GTL_GCReadPort (src->hDevPort, src->producer.timestamp_low, &ts_low, &datasize); // GevTimestampValueLow if (src->producer.timestamp) {
HANDLE_GTL_WARNING ("Failed to get GevTimestampValueLow"); timestamp_ns = read_uint64_single (src, src->producer.timestamp, &ret);
ret = GTL_GCReadPort (src->hDevPort, src->producer.timestamp_high, &ts_high, &datasize); // GevTimestampValueHigh HANDLE_GTL_WARNING ("Failed to read device timestamp");
HANDLE_GTL_WARNING ("Failed to get GevTimestampValueHigh"); } else {
guint64 ticks = GUINT64_FROM_BE ((guint64) ts_low << 32 | ts_high); guint64 ticks = read_uint64 (src, src->producer.timestamp_low,
src->producer.timestamp_high, &ret);
HANDLE_GTL_WARNING ("Failed to read timestamp ticks");
GST_LOG_OBJECT (src, "Timestamp ticks are %llu", ticks); GST_LOG_OBJECT (src, "Timestamp ticks are %llu", ticks);
return ticks; if (src->tick_frequency == 0) {
GST_WARNING_OBJECT (src,
"Tick frequency undefined, can't timestamp accurately");
goto error;
}
timestamp_ns = ((guint64)
(ticks * ((double) GST_SECOND / src->tick_frequency)));;
}
GST_LOG_OBJECT (src, "Device timestamp in ns is %llu", timestamp_ns);
return timestamp_ns;
error: error:
return 0; return 0;
} }
static void static gboolean
gst_gentlsrc_src_latch_timestamps (GstGenTlSrc * src) gst_gentlsrc_src_latch_timestamps (GstGenTlSrc * src)
{ {
guint64 unix_ts, gev_ts; guint64 unix_ts, gev_ts;
unix_ts = get_unix_ns (); unix_ts = get_unix_ns ();
gev_ts = gst_gentlsrc_get_gev_timestamp_ticks (src); gev_ts = gst_gentlsrc_get_gev_timestamp_ns (src);
if (gev_ts != 0) { if (gev_ts != 0) {
src->unix_latched_time = unix_ts; src->unix_latched_ns = unix_ts;
src->gentl_latched_ticks = gev_ts; src->gentl_latched_ns = gev_ts;
GST_LOG_OBJECT (src, "Latched system time: %llu", src->unix_latched_ns);
GST_LOG_OBJECT (src, "Latched GenTL time : %llu", src->gentl_latched_ns);
return TRUE;
} else { } else {
GST_WARNING_OBJECT (src, "Failed to latch GEV time, using old latch value"); GST_WARNING_OBJECT (src, "Failed to latch GEV time, using old latch value");
return FALSE;
} }
} }
@ -927,8 +1090,6 @@ gst_gentlsrc_set_attributes (GstGenTlSrc * src)
{ {
gchar **pairs; gchar **pairs;
int i; int i;
guint32 val;
size_t datasize;
GC_ERROR ret; GC_ERROR ret;
if (!src->attributes || src->attributes == 0) { if (!src->attributes || src->attributes == 0) {
@ -955,11 +1116,7 @@ gst_gentlsrc_set_attributes (GstGenTlSrc * src)
GST_DEBUG_OBJECT (src, "Setting attribute, '%s'='%s'", pair[0], pair[1]); GST_DEBUG_OBJECT (src, "Setting attribute, '%s'='%s'", pair[0], pair[1]);
val = GUINT32_TO_BE (atoi (pair[1])); ret = write_uint32 (src, strtol (pair[0], NULL, 16), atoi (pair[1]));
datasize = sizeof (val);
ret =
GTL_GCWritePort (src->hDevPort, strtol (pair[0], NULL, 16), &val,
&datasize);
if (ret != GC_ERR_SUCCESS) { if (ret != GC_ERR_SUCCESS) {
GST_WARNING_OBJECT (src, "Failed to set attribute: %s", GST_WARNING_OBJECT (src, "Failed to set attribute: %s",
gst_gentlsrc_get_error_string (src)); gst_gentlsrc_get_error_string (src));
@ -1059,6 +1216,104 @@ error:
return FALSE; return FALSE;
} }
static void
gst_gentlsrc_close_interface (GstGenTlSrc * src)
{
if (src->hIF) {
GTL_IFClose (src->hIF);
src->hIF = NULL;
}
}
static void
get_gentlsrc_select_user_id (GstGenTlSrc * src)
{
GstGenTlSrcClass *klass = GST_GENTL_SRC_GET_CLASS (src);
GC_ERROR ret;
uint32_t num_ifaces, num_devs;
char dev_id[GTL_MAX_STR_SIZE];
ret = GTL_TLGetNumInterfaces (src->hTL, &num_ifaces);
HANDLE_GTL_ERROR ("Failed to get number of interfaces");
GST_DEBUG_OBJECT (src,
"Trying to find device-user-id='%s' on all %d interfaces",
src->device_user_id, num_ifaces);
for (src->interface_index = 0; src->interface_index < num_ifaces;
src->interface_index++) {
size_t id_size;
GST_DEBUG_OBJECT (src, "Trying to find interface ID at index %d",
src->interface_index);
ret = GTL_TLGetInterfaceID (src->hTL, src->interface_index, NULL, &id_size);
HANDLE_GTL_ERROR ("Failed to get interface ID at specified index");
if (src->interface_id) {
g_free (src->interface_id);
}
src->interface_id = (gchar *) g_malloc (id_size);
ret =
GTL_TLGetInterfaceID (src->hTL, src->interface_index, src->interface_id,
&id_size);
HANDLE_GTL_ERROR ("Failed to get interface ID at specified index");
GST_DEBUG_OBJECT (src, "Trying to open interface '%s'", src->interface_id);
ret = GTL_TLOpenInterface (src->hTL, src->interface_id, &src->hIF);
if (ret != GC_ERR_SUCCESS) {
GST_WARNING_OBJECT (src, "Interface failed to open");
continue;
}
ret = GTL_IFUpdateDeviceList (src->hIF, NULL, src->timeout);
HANDLE_GTL_ERROR ("Failed to update device list within timeout");
ret = GTL_IFGetNumDevices (src->hIF, &num_devs);
HANDLE_GTL_ERROR ("Failed to get number of devices");
if (num_devs == 0) {
gst_gentlsrc_close_interface (src);
continue;
}
GST_DEBUG_OBJECT (src, "Found %d devices on interface", num_devs);
for (src->device_index = 0; src->device_index < num_devs;
++src->device_index) {
size_t str_size;
char user_defined_name[GTL_MAX_STR_SIZE];
INFO_DATATYPE datatype;
str_size = GTL_MAX_STR_SIZE;
ret = GTL_IFGetDeviceID (src->hIF, src->device_index, dev_id, &str_size);
if (ret != GC_ERR_SUCCESS) {
GST_WARNING_OBJECT (src, "Failed to get device id: %s",
gst_gentlsrc_get_error_string (src));
return;
}
str_size = GTL_MAX_STR_SIZE;
GTL_IFGetDeviceInfo (src->hIF, dev_id, DEVICE_INFO_USER_DEFINED_NAME,
&datatype, user_defined_name, &str_size);
GST_DEBUG_OBJECT (src, "Comparing specified user ID='%s', to '%s'",
src->device_user_id, user_defined_name);
if (g_strcmp0 (src->device_user_id, user_defined_name) == 0) {
GST_DEBUG_OBJECT (src, "Device matches!");
gst_gentlsrc_close_interface (src);
return;
} else {
GST_DEBUG_OBJECT (src, "Device doesn't match, continuing");
}
} // looping over devices
gst_gentlsrc_close_interface (src);
} // looping over interfaces
GST_ELEMENT_ERROR (src, RESOURCE, TOO_LAZY,
("Failed to find device using device-user-id='%s'", src->device_user_id),
(NULL));
return;
error:
return;
}
static gboolean static gboolean
gst_gentlsrc_start (GstBaseSrc * bsrc) gst_gentlsrc_start (GstBaseSrc * bsrc)
{ {
@ -1066,8 +1321,7 @@ gst_gentlsrc_start (GstBaseSrc * bsrc)
GstGenTlSrcClass *klass = GST_GENTL_SRC_GET_CLASS (src); GstGenTlSrcClass *klass = GST_GENTL_SRC_GET_CLASS (src);
GC_ERROR ret; GC_ERROR ret;
uint32_t i, num_devs; uint32_t i, num_devs;
guint32 width, height, stride; guint32 width, height;
GstVideoInfo vinfo;
GST_DEBUG_OBJECT (src, "start"); GST_DEBUG_OBJECT (src, "start");
@ -1075,6 +1329,8 @@ gst_gentlsrc_start (GstBaseSrc * bsrc)
initialize_basler_addresses (&src->producer); initialize_basler_addresses (&src->producer);
} else if (src->producer_prop == GST_GENTLSRC_PRODUCER_EVT) { } else if (src->producer_prop == GST_GENTLSRC_PRODUCER_EVT) {
initialize_evt_addresses (&src->producer); initialize_evt_addresses (&src->producer);
} else if (src->producer_prop == GST_GENTLSRC_PRODUCER_FLIR) {
initialize_flir_addresses (&src->producer);
} else { } else {
g_assert_not_reached (); g_assert_not_reached ();
} }
@ -1094,6 +1350,10 @@ gst_gentlsrc_start (GstBaseSrc * bsrc)
goto error; goto error;
} }
if (src->device_user_id && src->device_user_id[0] != 0) {
get_gentlsrc_select_user_id (src);
}
if (!gst_gentlsrc_open_interface (src)) { if (!gst_gentlsrc_open_interface (src)) {
g_mutex_unlock (&klass->tl_mutex); g_mutex_unlock (&klass->tl_mutex);
goto error; goto error;
@ -1108,6 +1368,7 @@ gst_gentlsrc_start (GstBaseSrc * bsrc)
ret = GTL_IFGetNumDevices (src->hIF, &num_devs); ret = GTL_IFGetNumDevices (src->hIF, &num_devs);
HANDLE_GTL_ERROR ("Failed to get number of devices"); HANDLE_GTL_ERROR ("Failed to get number of devices");
if (num_devs > 0) { if (num_devs > 0) {
GST_DEBUG_OBJECT (src, "Found %d devices on interface", num_devs);
for (i = 0; i < num_devs; ++i) { for (i = 0; i < num_devs; ++i) {
gst_gentl_print_device_info (src, i); gst_gentl_print_device_info (src, i);
} }
@ -1308,28 +1569,19 @@ gst_gentlsrc_start (GstBaseSrc * bsrc)
} }
} }
src->tick_frequency = gst_gentlsrc_get_gev_tick_frequency (src);
gst_gentlsrc_set_attributes (src); gst_gentlsrc_set_attributes (src);
{ {
// TODO: use GenTl node map for this // TODO: use GenTl node map for this
guint32 val = 0; width = read_uint32 (src, src->producer.width, &ret);
size_t datasize = 4;
ret = GTL_GCReadPort (src->hDevPort, src->producer.width, &val, &datasize);
HANDLE_GTL_ERROR ("Failed to get width"); HANDLE_GTL_ERROR ("Failed to get width");
width = GUINT32_FROM_BE (val); height = read_uint32 (src, src->producer.height, &ret);
ret = GTL_GCReadPort (src->hDevPort, src->producer.height, &val, &datasize);
HANDLE_GTL_ERROR ("Failed to get height"); HANDLE_GTL_ERROR ("Failed to get height");
height = GUINT32_FROM_BE (val);
GST_DEBUG_OBJECT (src, "Width and height %dx%d", width, height); GST_DEBUG_OBJECT (src, "Width and height %dx%d", width, height);
ret = guint32 pixfmt_enum = read_uint32 (src, src->producer.pixel_format, &ret);
GTL_GCReadPort (src->hDevPort, src->producer.pixel_format, &val, HANDLE_GTL_ERROR ("Failed to get pixel format");
&datasize);
HANDLE_GTL_ERROR ("Failed to get height");
const char *genicam_pixfmt; const char *genicam_pixfmt;
guint32 pixfmt_enum = GUINT32_FROM_BE (val);
switch (pixfmt_enum) { switch (pixfmt_enum) {
case 0x1: // Basler Ace case 0x1: // Basler Ace
case 0x01080001: case 0x01080001:
@ -1339,6 +1591,9 @@ gst_gentlsrc_start (GstBaseSrc * bsrc)
case 0x01100005: case 0x01100005:
genicam_pixfmt = "Mono12"; genicam_pixfmt = "Mono12";
break; break;
case 0x1100007:
genicam_pixfmt = "Mono16";
break;
case 0x1100010: // Basler Ace case 0x1100010: // Basler Ace
genicam_pixfmt = "BayerGR12"; genicam_pixfmt = "BayerGR12";
break; break;
@ -1348,6 +1603,12 @@ gst_gentlsrc_start (GstBaseSrc * bsrc)
case 0x01100011: case 0x01100011:
genicam_pixfmt = "BayerRG12"; genicam_pixfmt = "BayerRG12";
break; break;
case 0x0110002E:
genicam_pixfmt = "BayerGR16";
break;
case 0x0110002F:
genicam_pixfmt = "BayerRG16";
break;
case 0x02180014: case 0x02180014:
genicam_pixfmt = "RGB8Packed"; genicam_pixfmt = "RGB8Packed";
break; break;
@ -1362,7 +1623,7 @@ gst_gentlsrc_start (GstBaseSrc * bsrc)
break; break;
default: default:
GST_ELEMENT_ERROR (src, RESOURCE, TOO_LAZY, GST_ELEMENT_ERROR (src, RESOURCE, TOO_LAZY,
("Unrecognized PixelFormat enum value: %d", pixfmt_enum), (NULL)); ("Unrecognized PixelFormat enum value: 0x%x", pixfmt_enum), (NULL));
goto error; goto error;
} }
@ -1375,7 +1636,6 @@ gst_gentlsrc_start (GstBaseSrc * bsrc)
src->caps = src->caps =
gst_genicam_pixel_format_caps_from_pixel_format (genicam_pixfmt, gst_genicam_pixel_format_caps_from_pixel_format (genicam_pixfmt,
G_LITTLE_ENDIAN, width, height, 30, 1, 1, 1); G_LITTLE_ENDIAN, width, height, 30, 1, 1, 1);
gst_video_info_from_caps (&vinfo, src->caps);
if (!src->caps) { if (!src->caps) {
GST_ELEMENT_ERROR (src, STREAM, WRONG_TYPE, GST_ELEMENT_ERROR (src, STREAM, WRONG_TYPE,
("Unknown or unsupported pixel format (%s).", genicam_pixfmt), ("Unknown or unsupported pixel format (%s).", genicam_pixfmt),
@ -1383,8 +1643,12 @@ gst_gentlsrc_start (GstBaseSrc * bsrc)
goto error; goto error;
} }
src->height = vinfo.height; src->height = height;
src->gst_stride = GST_VIDEO_INFO_COMP_STRIDE (&vinfo, 0); src->gst_stride =
gst_genicam_pixel_format_get_stride (genicam_pixfmt, G_LITTLE_ENDIAN,
width);
GST_DEBUG_OBJECT (src, "Height=%d, stride=%d", src->height,
src->gst_stride);
} }
if (!gst_gentlsrc_prepare_buffers (src)) { if (!gst_gentlsrc_prepare_buffers (src)) {
@ -1406,25 +1670,17 @@ gst_gentlsrc_start (GstBaseSrc * bsrc)
{ {
// TODO: use GenTl node map for this // TODO: use GenTl node map for this
guint32 val;
size_t datasize;
/* set AcquisitionMode to Continuous */ /* set AcquisitionMode to Continuous */
// TODO: "Continuous" value can have different integer values, we need // TODO: "Continuous" value can have different integer values, we need
// to look it up in the node map (EVT is 0, Basler is 2) // to look it up in the node map (EVT is 0, Basler is 2)
val = GUINT32_TO_BE (src->producer.acquisition_mode_value);
datasize = sizeof (val);
ret = ret =
GTL_GCWritePort (src->hDevPort, src->producer.acquisition_mode, &val, write_uint32 (src, src->producer.acquisition_mode,
&datasize); src->producer.acquisition_mode_value);
HANDLE_GTL_ERROR ("Failed to start device acquisition"); HANDLE_GTL_ERROR ("Failed to start device acquisition");
/* send AcquisitionStart command */ /* send AcquisitionStart command */
val = GUINT32_TO_BE (1); ret = write_uint32 (src, src->producer.acquisition_start, 1);
datasize = sizeof (val);
ret =
GTL_GCWritePort (src->hDevPort, src->producer.acquisition_start, &val,
&datasize);
HANDLE_GTL_ERROR ("Failed to start device acquisition"); HANDLE_GTL_ERROR ("Failed to start device acquisition");
} }
@ -1435,6 +1691,8 @@ gst_gentlsrc_start (GstBaseSrc * bsrc)
src->acq_start_time = src->acq_start_time =
gst_clock_get_time (gst_element_get_clock (GST_ELEMENT (src))); gst_clock_get_time (gst_element_get_clock (GST_ELEMENT (src)));
src->tick_frequency = gst_gentlsrc_get_gev_tick_frequency (src);
return TRUE; return TRUE;
error: error:
@ -1448,10 +1706,7 @@ error:
src->hDEV = NULL; src->hDEV = NULL;
} }
if (src->hIF) { gst_gentlsrc_close_interface (src);
GTL_IFClose (src->hIF);
src->hIF = NULL;
}
gst_gentlsrc_cleanup_tl (src); gst_gentlsrc_cleanup_tl (src);
@ -1489,11 +1744,8 @@ gst_gentlsrc_stop (GstBaseSrc * bsrc)
if (src->hDS) { if (src->hDS) {
/* command AcquisitionStop */ /* command AcquisitionStop */
guint32 val = GUINT32_TO_BE (1); GC_ERROR ret;
gsize datasize = sizeof (val); ret = write_uint32 (src, src->producer.acquisition_stop, 1);
GC_ERROR ret =
GTL_GCWritePort (src->hDevPort, src->producer.acquisition_stop, &val,
&datasize);
GTL_DSStopAcquisition (src->hDS, ACQ_STOP_FLAGS_DEFAULT); GTL_DSStopAcquisition (src->hDS, ACQ_STOP_FLAGS_DEFAULT);
GTL_DSFlushQueue (src->hDS, ACQ_QUEUE_INPUT_TO_OUTPUT); GTL_DSFlushQueue (src->hDS, ACQ_QUEUE_INPUT_TO_OUTPUT);
@ -1556,10 +1808,22 @@ gst_gentlsrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
GST_DEBUG_OBJECT (src, "The caps being set are %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (src, "The caps being set are %" GST_PTR_FORMAT, caps);
GST_ERROR ("Stride is %d", src->gst_stride);
gst_video_info_from_caps (&vinfo, caps); gst_video_info_from_caps (&vinfo, caps);
if (GST_VIDEO_INFO_FORMAT (&vinfo) != GST_VIDEO_FORMAT_UNKNOWN) { if (GST_VIDEO_INFO_FORMAT (&vinfo) != GST_VIDEO_FORMAT_UNKNOWN) {
src->gst_stride = GST_VIDEO_INFO_COMP_STRIDE (&vinfo, 0); int endianness;
const char *genicam_pixfmt =
gst_genicam_pixel_format_from_caps (caps, &endianness);
GST_ERROR ("Format is %s, Stride is %d", genicam_pixfmt, src->gst_stride);
if (genicam_pixfmt)
src->gst_stride =
gst_genicam_pixel_format_get_stride (genicam_pixfmt, G_LITTLE_ENDIAN,
vinfo.width);
else
goto unsupported_caps;
GST_ERROR ("Format is %s, Stride is %d", genicam_pixfmt, src->gst_stride);
} else { } else {
goto unsupported_caps; goto unsupported_caps;
} }
@ -1611,7 +1875,7 @@ gst_gentlsrc_get_buffer (GstGenTlSrc * src)
guint8 *data_ptr; guint8 *data_ptr;
GstMapInfo minfo; GstMapInfo minfo;
GstClockTime unix_ts; GstClockTime unix_ts;
uint64_t buf_timestamp_ticks; uint64_t buf_timestamp_ticks, buf_timestamp_ns;
/* sometimes we get non-image payloads, try several times for an image */ /* sometimes we get non-image payloads, try several times for an image */
@ -1641,12 +1905,22 @@ gst_gentlsrc_get_buffer (GstGenTlSrc * src)
goto error; goto error;
} }
datasize = sizeof (buf_timestamp_ticks); datasize = sizeof (buf_timestamp_ns);
ret =
GTL_DSGetBufferInfo (src->hDS, new_buffer_data.BufferHandle,
BUFFER_INFO_TIMESTAMP_NS, &datatype, &buf_timestamp_ns, &datasize);
if (ret == GC_ERR_SUCCESS) {
GST_LOG_OBJECT (src, "Buffer GentTL timestamp: %llu ns", buf_timestamp_ns);
} else {
ret = ret =
GTL_DSGetBufferInfo (src->hDS, new_buffer_data.BufferHandle, GTL_DSGetBufferInfo (src->hDS, new_buffer_data.BufferHandle,
BUFFER_INFO_TIMESTAMP, &datatype, &buf_timestamp_ticks, &datasize); BUFFER_INFO_TIMESTAMP, &datatype, &buf_timestamp_ticks, &datasize);
HANDLE_GTL_ERROR ("Failed to get buffer timestamp"); HANDLE_GTL_ERROR ("Failed to get buffer timestamp");
GST_LOG_OBJECT (src, "Buffer GentTL timestamp: %llu", buf_timestamp_ticks); buf_timestamp_ns = (gint64)
(buf_timestamp_ticks * ((double) GST_SECOND / src->tick_frequency));
GST_LOG_OBJECT (src, "Buffer GentTL timestamp: %llu ticks, %llu ns",
buf_timestamp_ticks, buf_timestamp_ns);
}
datasize = sizeof (frame_id); datasize = sizeof (frame_id);
ret = ret =
@ -1677,7 +1951,15 @@ gst_gentlsrc_get_buffer (GstGenTlSrc * src)
// TODO: what if strides aren't same? // TODO: what if strides aren't same?
buf = gst_buffer_new_allocate (NULL, buffer_size, NULL); guint64 image_size = (size_t) src->height * src->gst_stride;
if (buffer_size < image_size) {
GST_ELEMENT_ERROR (src, STREAM, TOO_LAZY,
("Buffer size (%d) is smaller than expected image size (%llu)",
buffer_size, image_size), (NULL));
goto error;
}
buf = gst_buffer_new_allocate (NULL, image_size, NULL);
if (!buf) { if (!buf) {
GST_ELEMENT_ERROR (src, STREAM, TOO_LAZY, GST_ELEMENT_ERROR (src, STREAM, TOO_LAZY,
("Failed to allocate buffer"), (NULL)); ("Failed to allocate buffer"), (NULL));
@ -1695,17 +1977,14 @@ gst_gentlsrc_get_buffer (GstGenTlSrc * src)
if (src->tick_frequency) { if (src->tick_frequency) {
gint64 nanoseconds_after_latch; gint64 nanoseconds_after_latch;
gint64 ticks_after_latch;
/* resync system clock and buffer clock periodically */ /* resync system clock and buffer clock periodically */
if (GST_CLOCK_DIFF (src->unix_latched_time, get_unix_ns ()) > GST_SECOND) { if (GST_CLOCK_DIFF (src->unix_latched_ns, get_unix_ns ()) > GST_SECOND) {
gst_gentlsrc_src_latch_timestamps (src); gst_gentlsrc_src_latch_timestamps (src);
} }
ticks_after_latch = buf_timestamp_ticks - src->gentl_latched_ticks; nanoseconds_after_latch = buf_timestamp_ns - src->gentl_latched_ns;
nanoseconds_after_latch = (gint64) unix_ts = src->unix_latched_ns + nanoseconds_after_latch;
(ticks_after_latch * ((double) GST_SECOND / src->tick_frequency));
unix_ts = src->unix_latched_time + nanoseconds_after_latch;
GST_LOG_OBJECT (src, "Adding Unix timestamp: %llu", unix_ts); GST_LOG_OBJECT (src, "Adding Unix timestamp: %llu", unix_ts);
gst_buffer_add_reference_timestamp_meta (buf, gst_buffer_add_reference_timestamp_meta (buf,
gst_static_caps_get (&unix_reference), unix_ts, GST_CLOCK_TIME_NONE); gst_static_caps_get (&unix_reference), unix_ts, GST_CLOCK_TIME_NONE);
@ -1780,9 +2059,6 @@ gst_gentlsrc_create (GstPushSrc * psrc, GstBuffer ** buf)
} }
return GST_FLOW_OK; return GST_FLOW_OK;
error:
return GST_FLOW_ERROR;
} }
gchar * gchar *

View File

@ -45,6 +45,7 @@ struct _GstGenTlProducer
{ {
gchar* cti_path; gchar* cti_path;
guint32 acquisition_mode_value; guint32 acquisition_mode_value;
guint32 timestamp_control_latch_value;
guint64 width; guint64 width;
guint64 height; guint64 height;
@ -55,9 +56,11 @@ struct _GstGenTlProducer
guint64 acquisition_stop; guint64 acquisition_stop;
guint64 tick_frequency_low; guint64 tick_frequency_low;
guint64 tick_frequency_high; guint64 tick_frequency_high;
guint64 timestamp_control_latch; guint64 timestamp_control_latch; // GevTimestampControlLatch
guint64 timestamp_low; guint64 timestamp; // TimestampLatchValue
guint64 timestamp_high; guint64 timestamp_low; // GevTimestampValueLow
guint64 timestamp_high; // GevTimestampValueHigh
guint16 port_endianness;
}; };
@ -71,6 +74,7 @@ struct _GstGenTlProducer
typedef enum { typedef enum {
GST_GENTLSRC_PRODUCER_BASLER, GST_GENTLSRC_PRODUCER_BASLER,
GST_GENTLSRC_PRODUCER_EVT, GST_GENTLSRC_PRODUCER_EVT,
GST_GENTLSRC_PRODUCER_FLIR,
} GstGenTlSrcProducer; } GstGenTlSrcProducer;
@ -94,6 +98,7 @@ struct _GstGenTlSrc
gchar *interface_id; gchar *interface_id;
guint device_index; guint device_index;
gchar *device_id; gchar *device_id;
gchar *device_user_id;
guint stream_index; guint stream_index;
gchar *stream_id; gchar *stream_id;
guint num_capture_buffers; guint num_capture_buffers;
@ -105,8 +110,8 @@ struct _GstGenTlSrc
guint32 total_dropped_frames; guint32 total_dropped_frames;
guint64 tick_frequency; guint64 tick_frequency;
guint64 unix_latched_time; guint64 unix_latched_ns;
guint64 gentl_latched_ticks; guint64 gentl_latched_ns;
GstCaps *caps; GstCaps *caps;
gint height; gint height;

View File

@ -446,7 +446,7 @@ char_to_ids_unicode (const char *str)
void * void *
char_to_ids_unicode (const char *str) char_to_ids_unicode (const char *str)
{ {
return g_utf8_to_ucs4 (src->config_file, -1, NULL, NULL, NULL); return g_utf8_to_ucs4 (str, -1, NULL, NULL, NULL);
} }
#endif #endif
@ -504,7 +504,7 @@ gst_idsueyesrc_start (GstBaseSrc * bsrc)
if (!g_file_test (src->config_file, G_FILE_TEST_EXISTS)) { if (!g_file_test (src->config_file, G_FILE_TEST_EXISTS)) {
GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,
("Camera file does not exist: %s", src->config_file), (NULL)); ("Camera file does not exist: %s", src->config_file), (NULL));
return FALSE; goto error;
} }
/* function requires Unicode */ /* function requires Unicode */
@ -533,7 +533,7 @@ gst_idsueyesrc_start (GstBaseSrc * bsrc)
} }
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
("Failed to load parameter file: %s", src->config_file), (NULL)); ("Failed to load parameter file: %s", src->config_file), (NULL));
return FALSE; goto error;
} }
} else { } else {
ret = ret =
@ -542,37 +542,42 @@ gst_idsueyesrc_start (GstBaseSrc * bsrc)
if (ret != IS_SUCCESS) { if (ret != IS_SUCCESS) {
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
("Failed to load parameters from EEPROM"), (NULL)); ("Failed to load parameters from EEPROM"), (NULL));
return FALSE; goto error;
} }
} }
gst_idsueyesrc_set_caps_from_camera (src); gst_idsueyesrc_set_caps_from_camera (src);
if (!src->caps) { if (!src->caps) {
return FALSE; goto error;
} }
if (!gst_idsueyesrc_alloc_memory (src)) { if (!gst_idsueyesrc_alloc_memory (src)) {
/* element error already sent */ /* element error already sent */
return FALSE; goto error;
} }
ret = is_SetDisplayMode (src->hCam, IS_SET_DM_DIB); ret = is_SetDisplayMode (src->hCam, IS_SET_DM_DIB);
if (ret != IS_SUCCESS) { if (ret != IS_SUCCESS) {
GST_ELEMENT_ERROR (src, STREAM, WRONG_TYPE, GST_ELEMENT_ERROR (src, STREAM, WRONG_TYPE,
("Failed to set display mode"), (NULL)); ("Failed to set display mode"), (NULL));
return FALSE; goto error;
} }
ret = is_InitImageQueue (src->hCam, 0); ret = is_InitImageQueue (src->hCam, 0);
if (ret != IS_SUCCESS) { if (ret != IS_SUCCESS) {
GST_ELEMENT_ERROR (src, STREAM, WRONG_TYPE, GST_ELEMENT_ERROR (src, STREAM, WRONG_TYPE,
("Failed to init image queue"), (NULL)); ("Failed to init image queue"), (NULL));
return FALSE; goto error;
} }
gst_idsueyesrc_set_framerate_exposure (src); gst_idsueyesrc_set_framerate_exposure (src);
return TRUE; return TRUE;
error:
ret = is_ExitCamera (src->hCam);
return FALSE;
} }
static gboolean static gboolean

View File

@ -41,6 +41,7 @@
#include <gst/base/gstpushsrc.h> #include <gst/base/gstpushsrc.h>
#include <gst/video/video.h> #include <gst/video/video.h>
#include "get_unix_ns.h"
#include "gstkayasrc.h" #include "gstkayasrc.h"
#include "genicampixelformat.h" #include "genicampixelformat.h"
@ -223,6 +224,7 @@ gst_kayasrc_cleanup (GstKayaSrc * src)
src->stop_requested = FALSE; src->stop_requested = FALSE;
src->acquisition_started = FALSE; src->acquisition_started = FALSE;
src->kaya_base = GST_CLOCK_TIME_NONE; src->kaya_base = GST_CLOCK_TIME_NONE;
src->unix_base = 0;
if (src->caps) { if (src->caps) {
gst_caps_unref (src->caps); gst_caps_unref (src->caps);
@ -799,11 +801,13 @@ gst_kayasrc_stream_buffer_callback (STREAM_BUFFER_HANDLE buffer_handle,
GST_BUFFER_OFFSET (buf) = src->frame_count; GST_BUFFER_OFFSET (buf) = src->frame_count;
src->frame_count++; src->frame_count++;
//if (src->kaya_base == GST_CLOCK_TIME_NONE) { guint64 cur_time = get_unix_ns();
// assume delay between these two calls is negligible if (cur_time - src->unix_base > GST_SECOND) {
// assume delay between these two calls is negligible (one measurement showed <100ns)
src->kaya_base = KYFG_GetGrabberValueInt (src->cam_handle, "Timestamp"); src->kaya_base = KYFG_GetGrabberValueInt (src->cam_handle, "Timestamp");
src->unix_base = g_get_real_time () * 1000; src->unix_base = get_unix_ns ();
//} }
#if GST_CHECK_VERSION(1,14,0) #if GST_CHECK_VERSION(1,14,0)
{ {
GstClockTime unix_ts = src->unix_base + (timestamp - src->kaya_base); GstClockTime unix_ts = src->unix_base + (timestamp - src->kaya_base);

View File

@ -510,8 +510,10 @@ gst_matroxsrc_start (GstBaseSrc * bsrc)
&src->MilDigitizer); &src->MilDigitizer);
} }
if (ret == M_NULL) { if (ret == M_NULL) {
MIL_TEXT_CHAR err_msg[M_ERROR_MESSAGE_SIZE];
MappGetError (M_DEFAULT, M_CURRENT | M_MESSAGE, err_msg);
GST_ELEMENT_ERROR (src, RESOURCE, FAILED, GST_ELEMENT_ERROR (src, RESOURCE, FAILED,
("Failed to allocate a MIL digitizer"), (NULL)); ("Failed to allocate a MIL digitizer: %s", err_msg), (NULL));
goto error; goto error;
} }

View File

@ -93,6 +93,19 @@ static gboolean gst_niimaqdxsrc_close_interface (GstNiImaqDxSrc * src);
static void gst_niimaqdxsrc_reset (GstNiImaqDxSrc * src); static void gst_niimaqdxsrc_reset (GstNiImaqDxSrc * src);
static void gst_niimaqdxsrc_set_dx_attributes (GstNiImaqDxSrc * src); static void gst_niimaqdxsrc_set_dx_attributes (GstNiImaqDxSrc * src);
const char *
gst_niimaqdxsrc_get_imaq_error_str (IMAQdxError code)
{
static char imaqdx_error_string[IMAQDX_MAX_API_STRING_LENGTH];
if (code) {
IMAQdxGetErrorString (code, imaqdx_error_string,
IMAQDX_MAX_API_STRING_LENGTH);
return imaqdx_error_string;
} else {
return "No IMAQdx error";
}
}
IMAQdxError IMAQdxError
gst_niimaqdxsrc_report_imaq_error (IMAQdxError code) gst_niimaqdxsrc_report_imaq_error (IMAQdxError code)
{ {
@ -153,17 +166,31 @@ static GstStaticCaps unix_reference = GST_STATIC_CAPS ("timestamp/x-unix");
"framerate = " GST_VIDEO_FPS_RANGE "framerate = " GST_VIDEO_FPS_RANGE
/* TODO: handle the format mappings more intelligently */ /* TODO: handle the format mappings more intelligently */
/* All pixel format names below have no spaces, as when comparing spaces
will be removed */
ImaqDxCapsInfo imaq_dx_caps_infos[] = { ImaqDxCapsInfo imaq_dx_caps_infos[] = {
{"Mono8", 0, GST_VIDEO_CAPS_MAKE ("GRAY8"), 8, 8, 4} {"Mono8", 0, GST_VIDEO_CAPS_MAKE ("GRAY8"), 8, 8, 4}
, ,
{"8BitMonochrome", 0, GST_VIDEO_CAPS_MAKE ("GRAY8"), 8, 8, 4}
,
{"Mono10", G_LITTLE_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_LE"), 10, 16, 4} {"Mono10", G_LITTLE_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_LE"), 10, 16, 4}
, ,
{"10BitMonochrome", G_LITTLE_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_LE"), 10,
16, 4}
,
{"Mono10", G_BIG_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_BE"), 10, 16, 4} {"Mono10", G_BIG_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_BE"), 10, 16, 4}
, ,
{"10BitMonochrome", G_BIG_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_BE"), 10, 16, 4}
,
{"Mono12", G_LITTLE_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_LE"), 12, 16, 4} {"Mono12", G_LITTLE_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_LE"), 12, 16, 4}
, ,
{"12BitMonochrome", G_LITTLE_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_LE"), 12,
16, 4}
,
{"Mono12", G_BIG_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_BE"), 12, 16, 4} {"Mono12", G_BIG_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_BE"), 12, 16, 4}
, ,
{"12BitMonochrome", G_BIG_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_BE"), 12, 16, 4}
,
{"Mono14", G_LITTLE_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_LE"), 14, 16, 4} {"Mono14", G_LITTLE_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_LE"), 14, 16, 4}
, ,
{"Mono14", G_BIG_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_BE"), 14, 16, 4} {"Mono14", G_BIG_ENDIAN, GST_VIDEO_CAPS_MAKE ("GRAY16_BE"), 14, 16, 4}
@ -687,7 +714,7 @@ gst_niimaqdxsrc_fill (GstPushSrc * psrc, GstBuffer * buf)
if (!gst_niimaqdxsrc_start_acquisition (src)) { if (!gst_niimaqdxsrc_start_acquisition (src)) {
GST_ELEMENT_ERROR (src, RESOURCE, FAILED, GST_ELEMENT_ERROR (src, RESOURCE, FAILED,
("Unable to start acquisition."), (NULL)); ("Unable to start acquisition"), (NULL));
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
@ -728,7 +755,8 @@ gst_niimaqdxsrc_fill (GstPushSrc * psrc, GstBuffer * buf)
if (rval) { if (rval) {
gst_niimaqdxsrc_report_imaq_error (rval); gst_niimaqdxsrc_report_imaq_error (rval);
GST_ELEMENT_ERROR (src, RESOURCE, FAILED, GST_ELEMENT_ERROR (src, RESOURCE, FAILED,
("failed to copy buffer %d", src->cumbufnum), (NULL)); ("failed to copy buffer %d: %s", src->cumbufnum,
gst_niimaqdxsrc_get_imaq_error_str (rval)), (NULL));
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
@ -938,7 +966,8 @@ gst_niimaqdxsrc_get_cam_caps (GstNiImaqDxSrc * src)
if (rval) { if (rval) {
GST_ELEMENT_ERROR (src, STREAM, FAILED, GST_ELEMENT_ERROR (src, STREAM, FAILED,
("attempt to read attributes failed"), ("attempt to read attributes failed: %s",
gst_niimaqdxsrc_get_imaq_error_str (rval)),
("attempt to read attributes failed")); ("attempt to read attributes failed"));
goto error; goto error;
} }
@ -1071,7 +1100,8 @@ gst_niimaqdxsrc_start (GstBaseSrc * bsrc)
if (rval != IMAQdxErrorSuccess) { if (rval != IMAQdxErrorSuccess) {
gst_niimaqdxsrc_report_imaq_error (rval); gst_niimaqdxsrc_report_imaq_error (rval);
GST_ELEMENT_ERROR (src, RESOURCE, FAILED, GST_ELEMENT_ERROR (src, RESOURCE, FAILED,
("Failed to open IMAQdx interface"), ("Failed to open IMAQdx interface %s: %s", src->device_name,
gst_niimaqdxsrc_get_imaq_error_str (rval)),
("Failed to open camera interface %s", src->device_name)); ("Failed to open camera interface %s", src->device_name));
goto error; goto error;
} }
@ -1085,7 +1115,8 @@ gst_niimaqdxsrc_start (GstBaseSrc * bsrc)
if (rval) { if (rval) {
gst_niimaqdxsrc_report_imaq_error (rval); gst_niimaqdxsrc_report_imaq_error (rval);
GST_ELEMENT_ERROR (src, RESOURCE, FAILED, GST_ELEMENT_ERROR (src, RESOURCE, FAILED,
("Failed to create ring buffer"), ("Failed to create ring buffer: %s",
gst_niimaqdxsrc_get_imaq_error_str (rval)),
("Failed to create ring buffer with %d buffers", ("Failed to create ring buffer with %d buffers",
src->ringbuffer_count)); src->ringbuffer_count));
goto error; goto error;
@ -1101,7 +1132,8 @@ gst_niimaqdxsrc_start (GstBaseSrc * bsrc)
if (rval) { if (rval) {
gst_niimaqdxsrc_report_imaq_error (rval); gst_niimaqdxsrc_report_imaq_error (rval);
GST_ELEMENT_ERROR (src, RESOURCE, FAILED, GST_ELEMENT_ERROR (src, RESOURCE, FAILED,
("Failed to register callback(s)"), (NULL)); ("Failed to register callback(s): %s",
gst_niimaqdxsrc_get_imaq_error_str (rval)), (NULL));
goto error; goto error;
} }
} }
@ -1138,7 +1170,8 @@ gst_niimaqdxsrc_stop (GstBaseSrc * bsrc)
if (rval != IMAQdxErrorSuccess) { if (rval != IMAQdxErrorSuccess) {
gst_niimaqdxsrc_report_imaq_error (rval); gst_niimaqdxsrc_report_imaq_error (rval);
GST_ELEMENT_ERROR (src, RESOURCE, FAILED, GST_ELEMENT_ERROR (src, RESOURCE, FAILED,
("Unable to stop acquisition"), (NULL)); ("Unable to stop acquisition: %s",
gst_niimaqdxsrc_get_imaq_error_str (rval)), (NULL));
result = FALSE; result = FALSE;
} }
src->session_started = FALSE; src->session_started = FALSE;

View File

@ -39,8 +39,10 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <glib.h> #include <glib.h>
#include "genapic/GenApiC.h"
#include "common/genicampixelformat.h" #include "common/genicampixelformat.h"
static int plugin_counter = 0; static int plugin_counter = 0;
int int
@ -142,6 +144,7 @@ typedef enum _GST_PYLONSRC_PROP
PROP_GAMMA, PROP_GAMMA,
PROP_RESET, PROP_RESET,
PROP_TESTIMAGE, PROP_TESTIMAGE,
PROP_TESTIMAGESOURCE,
PROP_CONTINUOUSMODE, PROP_CONTINUOUSMODE,
PROP_PIXEL_FORMAT, PROP_PIXEL_FORMAT,
PROP_USERID, PROP_USERID,
@ -177,6 +180,7 @@ typedef enum _GST_PYLONSRC_PROP
PROP_FRAMETRANSDELAY, PROP_FRAMETRANSDELAY,
PROP_BANDWIDTHRESERVE, PROP_BANDWIDTHRESERVE,
PROP_BANDWIDTHRESERVEACC, PROP_BANDWIDTHRESERVEACC,
PROP_MAXTRANSFERSIZE,
PROP_CONFIGFILE, PROP_CONFIGFILE,
PROP_IGNOREDEFAULTS, PROP_IGNOREDEFAULTS,
@ -337,6 +341,7 @@ ascii_strdown (gchar * *str, gssize len)
#define DEFAULT_PROP_GAMMA 1.0 #define DEFAULT_PROP_GAMMA 1.0
#define DEFAULT_PROP_RESET "off" #define DEFAULT_PROP_RESET "off"
#define DEFAULT_PROP_TESTIMAGE 0 #define DEFAULT_PROP_TESTIMAGE 0
#define DEFAULT_PROP_TESTIMAGESOURCE ""
#define DEFAULT_PROP_CONTINUOUSMODE TRUE #define DEFAULT_PROP_CONTINUOUSMODE TRUE
#define DEFAULT_PROP_PIXEL_FORMAT "auto" #define DEFAULT_PROP_PIXEL_FORMAT "auto"
#define DEFAULT_PROP_USERID "" #define DEFAULT_PROP_USERID ""
@ -363,6 +368,7 @@ ascii_strdown (gchar * *str, gssize len)
#define DEFAULT_PROP_FRAMETRANSDELAY 0 #define DEFAULT_PROP_FRAMETRANSDELAY 0
#define DEFAULT_PROP_BANDWIDTHRESERVE 10 #define DEFAULT_PROP_BANDWIDTHRESERVE 10
#define DEFAULT_PROP_BANDWIDTHRESERVEACC 10 #define DEFAULT_PROP_BANDWIDTHRESERVEACC 10
#define DEFAULT_PROP_MAXTRANSFERSIZE 262144
/* pad templates */ /* pad templates */
static GstStaticPadTemplate gst_pylonsrc_src_template = static GstStaticPadTemplate gst_pylonsrc_src_template =
@ -584,6 +590,11 @@ gst_pylonsrc_class_init (GstPylonSrcClass * klass)
"(1-6) Specifies a test image to show instead of a video stream. Useful for debugging. Will be disabled by default.", "(1-6) Specifies a test image to show instead of a video stream. Useful for debugging. Will be disabled by default.",
0, 6, DEFAULT_PROP_TESTIMAGE, 0, 6, DEFAULT_PROP_TESTIMAGE,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class, PROP_TESTIMAGESOURCE,
g_param_spec_string ("testimagesource", "Test image source",
"Specifies a test image (or image directory) to show instead of a video stream. Useful for debugging. Will be disabled by default.",
DEFAULT_PROP_TESTIMAGESOURCE,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class, PROP_CONTINUOUSMODE, g_object_class_install_property (gobject_class, PROP_CONTINUOUSMODE,
g_param_spec_boolean ("continuous", "Continuous mode", g_param_spec_boolean ("continuous", "Continuous mode",
"(true/false) Used to switch between triggered and continuous mode. To switch to triggered mode this parameter has to be switched to false.", "(true/false) Used to switch between triggered and continuous mode. To switch to triggered mode this parameter has to be switched to false.",
@ -748,35 +759,46 @@ gst_pylonsrc_class_init (GstPylonSrcClass * klass)
"Specifies the number of miiliseconds to wait for frame to be grabed from the camera.", "Specifies the number of miiliseconds to wait for frame to be grabed from the camera.",
0, 60000, DEFAULT_PROP_GRABTIMEOUT, 0, 60000, DEFAULT_PROP_GRABTIMEOUT,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
//TODO: Limits may be co-dependent on other transport layer parameters.
g_object_class_install_property (gobject_class, PROP_PACKETSIZE, g_object_class_install_property (gobject_class, PROP_PACKETSIZE,
g_param_spec_int ("packet-size", "Maximum size of data packet", g_param_spec_int ("packet-size", "Maximum size of data packet",
"The packetsize parameter specifies the maximum size of a data packet transmitted via Ethernet. The value is in bytes.", "The packetsize parameter specifies the maximum size of a data packet transmitted via Ethernet. The value is in bytes.",
0, 16000, DEFAULT_PROP_PACKETSIZE, 0, 16000, DEFAULT_PROP_PACKETSIZE,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); //TODO: Limits may be co-dependent on other transport layer parameters. (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
//TODO: Limits may be co-dependent on other transport layer parameters.
g_object_class_install_property (gobject_class, PROP_INTERPACKETDELAY, g_object_class_install_property (gobject_class, PROP_INTERPACKETDELAY,
g_param_spec_int ("inter-packet-delay", g_param_spec_int ("inter-packet-delay",
"Inter-Packet Delay between packet transmissions", "Inter-Packet Delay between packet transmissions",
"If your network hardware can't handle the incoming packet rate, it is useful to increase the delay between packet transmissions.", "If your network hardware can't handle the incoming packet rate, it is useful to increase the delay between packet transmissions.",
0, 3435, DEFAULT_PROP_INTERPACKETDELAY, 0, 3435, DEFAULT_PROP_INTERPACKETDELAY,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); //TODO: Limits may be co-dependent on other transport layer parameters. (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
//TODO: Limits may be co-dependent on other transport layer parameters.
g_object_class_install_property (gobject_class, PROP_FRAMETRANSDELAY, g_object_class_install_property (gobject_class, PROP_FRAMETRANSDELAY,
g_param_spec_int ("frame-trans-delay", g_param_spec_int ("frame-trans-delay",
"Delay for begin transmitting frame.", "Delay for begin transmitting frame.",
"Sets a delay in ticks between when camera begisn transmitting frame afther acquiring it. By default, one tick equals 8 ns. With PTP enabled, one tick equals 1 ns.", "Sets a delay in ticks between when camera begisn transmitting frame afther acquiring it. By default, one tick equals 8 ns. With PTP enabled, one tick equals 1 ns.",
0, 50000000, DEFAULT_PROP_FRAMETRANSDELAY, 0, 50000000, DEFAULT_PROP_FRAMETRANSDELAY,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); //TODO: Limits may be co-dependent on other transport layer parameters. (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
//TODO: Limits may be co-dependent on other transport layer parameters.
g_object_class_install_property (gobject_class, PROP_BANDWIDTHRESERVE, g_object_class_install_property (gobject_class, PROP_BANDWIDTHRESERVE,
g_param_spec_int ("bandwidth-reserve", g_param_spec_int ("bandwidth-reserve",
"Portion of bandwidth reserved for packet resends.", "Portion of bandwidth reserved for packet resends.",
"The setting is expressed as a percentage of the assigned bandwidth.", "The setting is expressed as a percentage of the assigned bandwidth.",
0, 26, DEFAULT_PROP_BANDWIDTHRESERVE, 0, 26, DEFAULT_PROP_BANDWIDTHRESERVE,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); //TODO: Limits may be co-dependent on other transport layer parameters. (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
//TODO: Limits may be co-dependent on other transport layer parameters.
g_object_class_install_property (gobject_class, PROP_BANDWIDTHRESERVEACC, g_object_class_install_property (gobject_class, PROP_BANDWIDTHRESERVEACC,
g_param_spec_int ("bandwidth-reserve-acc", g_param_spec_int ("bandwidth-reserve-acc",
"Pool of resends for unusual situations", "Pool of resends for unusual situations",
"For situations when the network connection becomes unstable. A larger number of packet resends may be needed to transmit an image", "For situations when the network connection becomes unstable. A larger number of packet resends may be needed to transmit an image",
1, 32, DEFAULT_PROP_BANDWIDTHRESERVEACC, 1, 32, DEFAULT_PROP_BANDWIDTHRESERVEACC,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); //TODO: Limits may be co-dependent on other transport layer parameters. (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class, PROP_MAXTRANSFERSIZE,
g_param_spec_int ("max-transfer-size",
"Maximum USB data transfer size in bytes",
"Use the MaxTransferSize parameter to specify the maximum USB data transfer size in bytes. The default value is appropriate for most applications. Increase the value to lower the CPU load. USB host adapter drivers may require decreasing the value if the application fails to receive the image stream. The maximum value depends on the operating system.",
0x400, 0x400000, DEFAULT_PROP_MAXTRANSFERSIZE,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
} }
static gboolean static gboolean
@ -814,6 +836,7 @@ gst_pylonsrc_init (GstPylonSrc * src)
src->cameraId = DEFAULT_PROP_CAMERA; src->cameraId = DEFAULT_PROP_CAMERA;
src->maxBandwidth = DEFAULT_PROP_MAXBANDWIDTH; src->maxBandwidth = DEFAULT_PROP_MAXBANDWIDTH;
src->testImage = DEFAULT_PROP_TESTIMAGE; src->testImage = DEFAULT_PROP_TESTIMAGE;
src->testImageSource = g_strdup (DEFAULT_PROP_TESTIMAGESOURCE);
src->sensorMode = g_strdup (DEFAULT_PROP_SENSORREADOUTMODE); src->sensorMode = g_strdup (DEFAULT_PROP_SENSORREADOUTMODE);
src->lightsource = g_strdup (DEFAULT_PROP_LIGHTSOURCE); src->lightsource = g_strdup (DEFAULT_PROP_LIGHTSOURCE);
@ -872,6 +895,7 @@ gst_pylonsrc_init (GstPylonSrc * src)
src->frameTransDelay = DEFAULT_PROP_FRAMETRANSDELAY; src->frameTransDelay = DEFAULT_PROP_FRAMETRANSDELAY;
src->bandwidthReserve = DEFAULT_PROP_BANDWIDTHRESERVE; src->bandwidthReserve = DEFAULT_PROP_BANDWIDTHRESERVE;
src->bandwidthReserveAcc = DEFAULT_PROP_BANDWIDTHRESERVEACC; src->bandwidthReserveAcc = DEFAULT_PROP_BANDWIDTHRESERVEACC;
src->maxTransferSize = DEFAULT_PROP_MAXTRANSFERSIZE;
for (int i = 0; i < PROP_NUM_PROPERTIES; i++) { for (int i = 0; i < PROP_NUM_PROPERTIES; i++) {
src->propFlags[i] = GST_PYLONSRC_PROPST_DEFAULT; src->propFlags[i] = GST_PYLONSRC_PROPST_DEFAULT;
@ -982,6 +1006,10 @@ gst_pylonsrc_set_property (GObject * object, guint property_id,
case PROP_TESTIMAGE: case PROP_TESTIMAGE:
src->testImage = g_value_get_int (value); src->testImage = g_value_get_int (value);
break; break;
case PROP_TESTIMAGESOURCE:
g_free (src->testImageSource);
src->testImageSource = g_value_dup_string (value);
break;
case PROP_SENSORREADOUTMODE: case PROP_SENSORREADOUTMODE:
g_free (src->sensorMode); g_free (src->sensorMode);
src->sensorMode = g_value_dup_string (value); src->sensorMode = g_value_dup_string (value);
@ -1214,6 +1242,9 @@ gst_pylonsrc_set_property (GObject * object, guint property_id,
case PROP_BANDWIDTHRESERVEACC: case PROP_BANDWIDTHRESERVEACC:
src->bandwidthReserveAcc = g_value_get_int (value); src->bandwidthReserveAcc = g_value_get_int (value);
break; break;
case PROP_MAXTRANSFERSIZE:
src->maxTransferSize = g_value_get_int (value);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
return; return;
@ -1254,6 +1285,9 @@ gst_pylonsrc_get_property (GObject * object, guint property_id,
case PROP_TESTIMAGE: case PROP_TESTIMAGE:
g_value_set_int (value, src->testImage); g_value_set_int (value, src->testImage);
break; break;
case PROP_TESTIMAGESOURCE:
g_value_set_string (value, src->testImageSource);
break;
case PROP_SENSORREADOUTMODE: case PROP_SENSORREADOUTMODE:
g_value_set_string (value, src->sensorMode); g_value_set_string (value, src->sensorMode);
break; break;
@ -1449,6 +1483,9 @@ gst_pylonsrc_get_property (GObject * object, guint property_id,
case PROP_BANDWIDTHRESERVEACC: case PROP_BANDWIDTHRESERVEACC:
g_value_set_int (value, src->bandwidthReserveAcc); g_value_set_int (value, src->bandwidthReserveAcc);
break; break;
case PROP_MAXTRANSFERSIZE:
g_value_set_int (value, src->maxTransferSize);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; break;
@ -2134,6 +2171,32 @@ error:
return FALSE; return FALSE;
} }
static gboolean
gst_pylonsrc_set_test_image_source (GstPylonSrc * src)
{
if (is_prop_implicit (src, PROP_TESTIMAGESOURCE) &&
!(is_prop_default (src, PROP_TESTIMAGESOURCE))) {
// Set whether test image will be shown
if (feature_supported (src, "ImageFilename")) {
GENAPIC_RESULT res;
res = PylonDeviceFeatureFromString(src->deviceHandle, "TestImageSelector", "Off");
PYLONC_CHECK_ERROR(src, res);
/* Enable custom test images */
res = PylonDeviceFeatureFromString(src->deviceHandle, "ImageFileMode", "On");
PYLONC_CHECK_ERROR(src, res);
GST_DEBUG_OBJECT (src, "Test image source enabled and set to %s", src->testImageSource);
res = PylonDeviceFeatureFromString(src->deviceHandle, "ImageFilename", src->testImageSource);
PYLONC_CHECK_ERROR (src, res);
}
reset_prop (src, PROP_TESTIMAGESOURCE);
}
return TRUE;
error:
return FALSE;
}
static gboolean static gboolean
gst_pylonsrc_set_readout (GstPylonSrc * src) gst_pylonsrc_set_readout (GstPylonSrc * src)
{ {
@ -3050,6 +3113,39 @@ error:
return FALSE; return FALSE;
} }
static gboolean
gst_pylonsrc_set_maxTransferSize (GstPylonSrc * src)
{
GENAPIC_RESULT res;
if (is_prop_implicit (src, PROP_MAXTRANSFERSIZE)) {
if (is_prop_set (src, PROP_MAXTRANSFERSIZE)) {
NODE_HANDLE phNode = 0;
NODEMAP_HANDLE phStreamGrabberNodeMap = 0;
PylonStreamGrabberGetNodeMap (src->streamGrabber,
&phStreamGrabberNodeMap);
if (!phStreamGrabberNodeMap)
goto error;
GenApiNodeMapGetNode (phStreamGrabberNodeMap, "MaxTransferSize", &phNode);
if (phNode) {
_Bool isWritable = 0;
GenApiNodeIsWritable (phNode, &isWritable);
if (isWritable) {
GST_DEBUG_OBJECT (src, "Setting max transfer size to %d",
src->maxTransferSize);
res = GenApiIntegerSetValue (phNode, src->maxTransferSize);
PYLONC_CHECK_ERROR (src, res);
}
}
}
reset_prop (src, PROP_MAXTRANSFERSIZE);
}
return TRUE;
error:
return FALSE;
}
static gboolean static gboolean
gst_pylonsrc_configure_start_acquisition (GstPylonSrc * src) gst_pylonsrc_configure_start_acquisition (GstPylonSrc * src)
{ {
@ -3074,6 +3170,9 @@ gst_pylonsrc_configure_start_acquisition (GstPylonSrc * src)
res = PylonStreamGrabberOpen (src->streamGrabber); res = PylonStreamGrabberOpen (src->streamGrabber);
PYLONC_CHECK_ERROR (src, res); PYLONC_CHECK_ERROR (src, res);
// set the max transfer size in case of USB
gst_pylonsrc_set_maxTransferSize (src);
// Get the wait object // Get the wait object
res = PylonStreamGrabberGetWaitObject (src->streamGrabber, &src->waitObject); res = PylonStreamGrabberGetWaitObject (src->streamGrabber, &src->waitObject);
PYLONC_CHECK_ERROR (src, res); PYLONC_CHECK_ERROR (src, res);
@ -3998,6 +4097,7 @@ gst_pylonsrc_set_properties (GstPylonSrc * src)
gst_pylonsrc_set_reverse (src) && gst_pylonsrc_set_reverse (src) &&
gst_pylonsrc_set_pixel_format (src) && gst_pylonsrc_set_pixel_format (src) &&
gst_pylonsrc_set_test_image (src) && gst_pylonsrc_set_test_image (src) &&
gst_pylonsrc_set_test_image_source (src) &&
gst_pylonsrc_set_packetsize (src) && gst_pylonsrc_set_packetsize (src) &&
gst_pylonsrc_set_interPacketDelay (src) && gst_pylonsrc_set_interPacketDelay (src) &&
gst_pylonsrc_set_frameTransDelay (src) && gst_pylonsrc_set_frameTransDelay (src) &&
@ -4132,13 +4232,13 @@ gst_pylonsrc_create (GstPushSrc * psrc, GstBuffer ** buf)
if (grabResult.Status != Grabbed) { if (grabResult.Status != Grabbed) {
src->failedFrames += 1; src->failedFrames += 1;
GST_WARNING_OBJECT (src, GST_WARNING_OBJECT (src,
"Failed capture count=%d. Status=%d, ErrorCode=%d", src->failedFrames, "Failed capture count=%d. Status=%d, ErrorCode=0x%.8X", src->failedFrames,
grabResult.Status, grabResult.ErrorCode); grabResult.Status, grabResult.ErrorCode);
} else } else
src->failedFrames = 0; src->failedFrames = 0;
} else { } else {
GST_ERROR_OBJECT (src, GST_ERROR_OBJECT (src,
"Error in the image processing loop. Status=%d, ErrorCode=%d", "Error in the image processing loop. Status=%d, ErrorCode=0x%.8X",
grabResult.Status, grabResult.ErrorCode); grabResult.Status, grabResult.ErrorCode);
goto error; goto error;
} }
@ -4264,8 +4364,7 @@ pylonc_print_camera_info (GstPylonSrc * src, PYLON_DEVICE_HANDLE deviceHandle,
size_t siz = 0; size_t siz = 0;
GENAPIC_RESULT res; GENAPIC_RESULT res;
if (PylonDeviceFeatureIsReadable (deviceHandle, "DeviceModelName") if (PylonDeviceFeatureIsAvailable (deviceHandle, "DeviceModelName")) {
&& PylonDeviceFeatureIsReadable (deviceHandle, "DeviceSerialNumber")) {
siz = sizeof (name); siz = sizeof (name);
res = res =
PylonDeviceFeatureToString (deviceHandle, "DeviceModelName", name, PylonDeviceFeatureToString (deviceHandle, "DeviceModelName", name,

View File

@ -39,7 +39,7 @@ enum
GST_PYLONSRC_NUM_CAPTURE_BUFFERS = 10, GST_PYLONSRC_NUM_CAPTURE_BUFFERS = 10,
GST_PYLONSRC_NUM_AUTO_FEATURES = 3, GST_PYLONSRC_NUM_AUTO_FEATURES = 3,
GST_PYLONSRC_NUM_LIMITED_FEATURES = 2, GST_PYLONSRC_NUM_LIMITED_FEATURES = 2,
GST_PYLONSRC_NUM_PROPS = 74 GST_PYLONSRC_NUM_PROPS = 75
}; };
typedef enum _GST_PYLONSRC_PROPERTY_STATE typedef enum _GST_PYLONSRC_PROPERTY_STATE
@ -101,13 +101,14 @@ struct _GstPylonSrc
GstPylonSrcLimitedFeature limitedFeature[GST_PYLONSRC_NUM_LIMITED_FEATURES]; GstPylonSrcLimitedFeature limitedFeature[GST_PYLONSRC_NUM_LIMITED_FEATURES];
gint maxBandwidth, testImage, frameDropLimit, grabtimeout, packetSize, gint maxBandwidth, testImage, frameDropLimit, grabtimeout, packetSize,
interPacketDelay, frameTransDelay, bandwidthReserve, bandwidthReserveAcc; interPacketDelay, frameTransDelay, bandwidthReserve, bandwidthReserveAcc,
maxTransferSize;
gint size[2]; gint size[2];
gint binning[2]; gint binning[2];
gint maxSize[2]; gint maxSize[2];
gint offset[2]; gint offset[2];
gchar *pixel_format, *sensorMode, *lightsource, *reset, *autoprofile, gchar *pixel_format, *sensorMode, *lightsource, *reset, *autoprofile,
*transformationselector, *userid; *transformationselector, *userid, *testImageSource;
gchar *autoFeature[GST_PYLONSRC_NUM_AUTO_FEATURES]; gchar *autoFeature[GST_PYLONSRC_NUM_AUTO_FEATURES];
gchar *configFile; gchar *configFile;
GST_PYLONSRC_PROPERTY_STATE propFlags[GST_PYLONSRC_NUM_PROPS]; GST_PYLONSRC_PROPERTY_STATE propFlags[GST_PYLONSRC_NUM_PROPS];