Skip to content

Commit

Permalink
cache dimension settings in PAUSED state
Browse files Browse the repository at this point in the history
Allow to set offsetx/y early in construction.
Move the validation of offset vs width/height
to set_configuration
  • Loading branch information
thiesmoeller committed May 8, 2023
1 parent 18a476e commit 5de4664
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 22 deletions.
61 changes: 60 additions & 1 deletion ext/pylon/gstpylon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#include "gstpylonsysmembufferfactory.h"

#include <map>
#include <vector>

/* retry open camera limits in case of collision with other
* process
Expand Down Expand Up @@ -862,6 +863,65 @@ gboolean gst_pylon_set_configuration(GstPylon *self, const GstCaps *conf,
height.SetValue(gst_height, Pylon::IntegerValueCorrection_None);
GST_INFO("Set Feature Height: %d", gst_height);

/* set the cached offsetx/y values
* respect the rounding value adjustment rules
* -> offset will be adjusted to keep dimensions
*/

GstPylonObjectPrivate *cam_properties =
(GstPylonObjectPrivate *)gst_pylon_object_get_instance_private(
reinterpret_cast<GstPylonObject *>(self->gcamera));

auto &offsetx_cache = cam_properties->dimension_cache.offsetx;
auto &offsety_cache = cam_properties->dimension_cache.offsety;
auto enable_correction = cam_properties->enable_correction;

bool value_corrected = false;
if (offsetx_cache >= 0) {
Pylon::CIntegerParameter offsetx(nodemap, "OffsetX");
if (enable_correction) {
try {
offsetx.SetValue(
offsetx_cache,
Pylon::EIntegerValueCorrection::IntegerValueCorrection_None);
} catch (GenICam::OutOfRangeException &) {
offsetx.SetValue(
offsetx_cache,
Pylon::EIntegerValueCorrection::IntegerValueCorrection_Nearest);
value_corrected = true;
}
} else {
offsetx.SetValue(offsetx_cache);
}
GST_INFO("Set Feature OffsetX: %d %s",
static_cast<gint>(offsetx.GetValue()),
value_corrected ? " [corrected]" : "");
offsetx_cache = -1;
}

value_corrected = false;
if (offsety_cache >= 0) {
Pylon::CIntegerParameter offsety(nodemap, "OffsetY");
if (enable_correction) {
try {
offsety.SetValue(
offsety_cache,
Pylon::EIntegerValueCorrection::IntegerValueCorrection_None);
} catch (GenICam::OutOfRangeException &) {
offsety.SetValue(
offsety_cache,
Pylon::EIntegerValueCorrection::IntegerValueCorrection_Nearest);
value_corrected = true;
}
} else {
offsety.SetValue(offsety_cache);
}
GST_INFO("Set Feature Offsety: %d %s",
static_cast<gint>(offsety.GetValue()),
value_corrected ? " [corrected]" : "");
offsety_cache = -1;
}

Pylon::CBooleanParameter framerate_enable(nodemap,
"AcquisitionFrameRateEnable");

Expand All @@ -878,7 +938,6 @@ gboolean gst_pylon_set_configuration(GstPylon *self, const GstCaps *conf,
framerate.TrySetValue(div, Pylon::FloatValueCorrection_None);
GST_INFO("Set Feature AcquisitionFrameRateAbs: %f", div);
}

} catch (const Pylon::GenericException &e) {
g_set_error(err, GST_LIBRARY_ERROR, GST_LIBRARY_ERROR_FAILED, "%s",
e.GetDescription());
Expand Down
90 changes: 72 additions & 18 deletions gst-libs/gst/pylon/gstpylonobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,6 @@

#include <utility>

typedef struct _GstPylonObjectPrivate GstPylonObjectPrivate;
struct _GstPylonObjectPrivate {
std::shared_ptr<Pylon::CBaslerUniversalInstantCamera> camera;
GenApi::INodeMap* nodemap;
gboolean enable_correction;
};

typedef struct _GstPylonObjectDeviceMembers GstPylonObjectDeviceMembers;
struct _GstPylonObjectDeviceMembers {
const std::string& device_name;
GstPylonCache& feature_cache;
GenApi::INodeMap& nodemap;
};

/************************************************************
* Start of GObject definition
***********************************************************/
Expand All @@ -71,10 +57,6 @@ static void gst_pylon_object_class_intern_init(
g_type_class_adjust_private_offset(klass, &GstPylonObject_private_offset);
gst_pylon_object_class_init((GstPylonObjectClass*)klass, device_members);
}
static inline gpointer gst_pylon_object_get_instance_private(
GstPylonObject* self) {
return (G_STRUCT_MEMBER_P(self, GstPylonObject_private_offset));
}

GType gst_pylon_object_register(const std::string& device_name,
GstPylonCache& feature_cache,
Expand Down Expand Up @@ -114,6 +96,10 @@ GType gst_pylon_object_register(const std::string& device_name,
* End of GObject definition
***********************************************************/

gpointer gst_pylon_object_get_instance_private(GstPylonObject* self) {
return (G_STRUCT_MEMBER_P(self, GstPylonObject_private_offset));
}

/* prototypes */
static void gst_pylon_object_install_properties(GstPylonObjectClass* klass,
GenApi::INodeMap& nodemap,
Expand Down Expand Up @@ -389,6 +375,36 @@ static void gst_pylon_object_set_property(GObject* object, guint property_id,
selector_data = gst_pylon_param_spec_selector_get_data(pspec);
}

/* check if property is from dimension list
* and set before streaming
*/
if (!priv->camera->IsGrabbing()) {
bool is_cached = false;
if (std::string(pspec->name) == "OffsetX") {
priv->dimension_cache.offsetx = g_value_get_int64(value);
is_cached = true;
} else if (std::string(pspec->name) == "OffsetY") {
priv->dimension_cache.offsety = g_value_get_int64(value);
is_cached = true;
} else if (std::string(pspec->name) == "Width") {
priv->dimension_cache.width = g_value_get_int64(value);
is_cached = true;
} else if (std::string(pspec->name) == "Height") {
priv->dimension_cache.height = g_value_get_int64(value);
is_cached = true;
}
if (is_cached) {
GST_INFO("Caching property \"%s\". Value is checked during caps fixation",
pspec->name);

/* skip to set the camera property value
* any value in the gst property range of this feature is accepted in this
* phase
*/
return;
}
}

try {
switch (value_type) {
case G_TYPE_INT64:
Expand Down Expand Up @@ -436,6 +452,39 @@ static void gst_pylon_object_get_property(GObject* object, guint property_id,
selector_data = gst_pylon_param_spec_selector_get_data(pspec);
}

/* check if property is from dimension list
* and get from cache if not streaming
*/
if (!priv->camera->IsGrabbing()) {
bool is_cached = false;
if (std::string(pspec->name) == "OffsetX" &&
priv->dimension_cache.offsetx >= 0) {
is_cached = true;
g_value_set_int64(value, priv->dimension_cache.offsetx);
} else if (std::string(pspec->name) == "OffsetY" &&
priv->dimension_cache.offsety >= 0) {
is_cached = true;
g_value_set_int64(value, priv->dimension_cache.offsety);
} else if (std::string(pspec->name) == "Width" &&
priv->dimension_cache.width >= 0) {
is_cached = true;
g_value_set_int64(value, priv->dimension_cache.width);
} else if (std::string(pspec->name) == "Height" &&
priv->dimension_cache.height >= 0) {
is_cached = true;
g_value_set_int64(value, priv->dimension_cache.height);
}

if (is_cached) {
GST_INFO(
"Read cached property \"%s\". Value might be adjusted during caps "
"fixation",
pspec->name);

return;
}
}

try {
switch (g_type_fundamental(pspec->value_type)) {
case G_TYPE_INT64:
Expand Down Expand Up @@ -499,6 +548,11 @@ GObject* gst_pylon_object_new(
priv->nodemap = nodemap;
priv->enable_correction = enable_correction;

/* setup dimension cache
* -1 -> not activly set
*/
priv->dimension_cache = {-1, -1, -1, -1};

return obj;
}

Expand Down
29 changes: 26 additions & 3 deletions gst-libs/gst/pylon/gstpylonobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,26 @@ struct _GstPylonObjectClass {
GstObjectClass parent_class;
};

typedef struct {
gint width;
gint height;
gint offsetx;
gint offsety;
} dimension_t;

typedef struct {
std::shared_ptr<Pylon::CBaslerUniversalInstantCamera> camera;
GenApi::INodeMap* nodemap;
gboolean enable_correction;
dimension_t dimension_cache;
} GstPylonObjectPrivate;

typedef struct {
const std::string& device_name;
GstPylonCache& feature_cache;
GenApi::INodeMap& nodemap;
} GstPylonObjectDeviceMembers;

EXT_PYLONSRC_API GType gst_pylon_object_register(const std::string& device_name,
GstPylonCache& feature_cache,
GenApi::INodeMap& nodemap);
Expand All @@ -52,8 +72,11 @@ EXT_PYLONSRC_API GObject* gst_pylon_object_new(
const std::string& device_name, GenApi::INodeMap* nodemap,
gboolean enable_correction);

void gst_pylon_object_set_pylon_selector(GenApi::INodeMap& nodemap,
const gchar* selector_name,
gint64& selector_value);
EXT_PYLONSRC_API void gst_pylon_object_set_pylon_selector(
GenApi::INodeMap& nodemap, const gchar* selector_name,
gint64& selector_value);

EXT_PYLONSRC_API gpointer
gst_pylon_object_get_instance_private(GstPylonObject* self);

#endif

0 comments on commit 5de4664

Please sign in to comment.