geometrictransform: Make map precalculation optional

Adds a variable to be set to allow subclasses to enable
or disable precalculation of the pixels mapping
This commit is contained in:
Thiago Santos 2010-06-05 19:20:06 -03:00
parent 370a5049ba
commit e7d417f4fc
2 changed files with 38 additions and 13 deletions

View file

@ -92,10 +92,6 @@ gst_geometric_transform_generate_map (GstGeometricTransform * gt)
/* subclass must have defined the map_func */ /* subclass must have defined the map_func */
g_return_val_if_fail (klass->map_func, FALSE); g_return_val_if_fail (klass->map_func, FALSE);
if (klass->prepare_func)
if (!klass->prepare_func (gt))
return FALSE;
/* /*
* (x,y) pairs of the inverse mapping * (x,y) pairs of the inverse mapping
*/ */
@ -130,8 +126,10 @@ gst_geometric_transform_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
gboolean ret; gboolean ret;
gint old_width; gint old_width;
gint old_height; gint old_height;
GstGeometricTransformClass *klass;
gt = GST_GEOMETRIC_TRANSFORM (btrans); gt = GST_GEOMETRIC_TRANSFORM (btrans);
klass = GST_GEOMETRIC_TRANSFORM_GET_CLASS (gt);
old_width = gt->width; old_width = gt->width;
old_height = gt->height; old_height = gt->height;
@ -145,7 +143,11 @@ gst_geometric_transform_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
/* regenerate the map */ /* regenerate the map */
if (old_width == 0 || old_height == 0 || gt->width != old_width || if (old_width == 0 || old_height == 0 || gt->width != old_width ||
gt->height != old_height) { gt->height != old_height) {
gst_geometric_transform_generate_map (gt); if (klass->prepare_func)
if (!klass->prepare_func (gt))
return FALSE;
if (gt->precalc_map)
gst_geometric_transform_generate_map (gt);
} }
} }
return ret; return ret;
@ -199,22 +201,38 @@ gst_geometric_transform_transform (GstBaseTransform * trans, GstBuffer * buf,
GstBuffer * outbuf) GstBuffer * outbuf)
{ {
GstGeometricTransform *gt; GstGeometricTransform *gt;
GstGeometricTransformClass *klass;
gint x, y; gint x, y;
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
gdouble *ptr; gdouble *ptr;
gt = GST_GEOMETRIC_TRANSFORM (trans); gt = GST_GEOMETRIC_TRANSFORM (trans);
klass = GST_GEOMETRIC_TRANSFORM_GET_CLASS (gt);
g_return_val_if_fail (gt->map, GST_FLOW_ERROR);
memset (GST_BUFFER_DATA (outbuf), 0, GST_BUFFER_SIZE (outbuf)); memset (GST_BUFFER_DATA (outbuf), 0, GST_BUFFER_SIZE (outbuf));
ptr = gt->map; if (gt->precalc_map) {
for (y = 0; y < gt->height; y++) { g_return_val_if_fail (gt->map, GST_FLOW_ERROR);
for (x = 0; x < gt->width; x++) { ptr = gt->map;
/* do the mapping */ for (y = 0; y < gt->height; y++) {
gst_geometric_transform_do_map (gt, buf, outbuf, x, y, ptr[0], ptr[1]); for (x = 0; x < gt->width; x++) {
ptr += 2; /* do the mapping */
gst_geometric_transform_do_map (gt, buf, outbuf, x, y, ptr[0], ptr[1]);
ptr += 2;
}
}
} else {
for (y = 0; y < gt->height; y++) {
for (x = 0; x < gt->width; x++) {
gdouble in_x, in_y;
if (klass->map_func (gt, x, y, &in_x, &in_y)) {
gst_geometric_transform_do_map (gt, buf, outbuf, x, y, in_x, in_y);
} else {
GST_WARNING_OBJECT (gt, "Failed to do mapping for %d %d", x, y);
return GST_FLOW_ERROR;
}
}
} }
} }
return ret; return ret;
@ -312,6 +330,7 @@ gst_geometric_transform_init (GTypeInstance * instance, gpointer g_class)
GstGeometricTransform *gt = GST_GEOMETRIC_TRANSFORM (instance); GstGeometricTransform *gt = GST_GEOMETRIC_TRANSFORM (instance);
gt->off_edge_pixels = DEFAULT_OFF_EDGE_PIXELS; gt->off_edge_pixels = DEFAULT_OFF_EDGE_PIXELS;
gt->precalc_map = TRUE;
} }
GType GType

View file

@ -87,6 +87,12 @@ struct _GstGeometricTransform {
gint pixel_stride; gint pixel_stride;
gint row_stride; gint row_stride;
/* Must be set on NULL state.
* Useful for subclasses that use don't want to use a fixed precalculated
* pixel mapping table. Like 'diffuse' that uses random values for each pic.
*/
gboolean precalc_map;
/* properties */ /* properties */
gint off_edge_pixels; gint off_edge_pixels;