guint32 *src, *dest;
GstFlowReturn ret = GST_FLOW_OK;
gint x, y, i;
- gint dx, dy;
+ gint dx, dy, o_dx;
gint h, v;
- gint width, height;
+ gint m_w, m_h, v_w, v_h;
gint *p, *q, *r;
gint8 *vp;
GstClockTime timestamp, stream_time;
else
motiondetect (filter, src);
+ m_w = filter->map_w;
+ m_h = filter->map_h;
+ v_w = filter->width;
+ v_h = filter->height;
+
/* simulate surface wave */
- width = filter->map_w;
- height = filter->map_h;
/* This function is called only 30 times per second. To increase a speed
* of wave, iterates this loop several times. */
for (i = loopnum; i > 0; i--) {
/* wave simulation */
- p = filter->map1 + width + 1;
- q = filter->map2 + width + 1;
- r = filter->map3 + width + 1;
- for (y = height - 2; y > 0; y--) {
- for (x = width - 2; x > 0; x--) {
- h = *(p - width - 1) + *(p - width + 1) + *(p + width - 1) + *(p +
- width + 1)
- + *(p - width) + *(p - 1) + *(p + 1) + *(p + width) - (*p) * 9;
+ p = filter->map1 + m_w + 1;
+ q = filter->map2 + m_w + 1;
+ r = filter->map3 + m_w + 1;
+ for (y = m_h - 2; y > 0; y--) {
+ for (x = m_w - 2; x > 0; x--) {
+ h = *(p - m_w - 1) + *(p - m_w + 1) + *(p + m_w - 1) + *(p + m_w + 1)
+ + *(p - m_w) + *(p - 1) + *(p + 1) + *(p + m_w) - (*p) * 9;
h = h >> 3;
v = *p - *q;
v += h - (v >> decay);
}
/* low pass filter */
- p = filter->map3 + width + 1;
- q = filter->map2 + width + 1;
- for (y = height - 2; y > 0; y--) {
- for (x = width - 2; x > 0; x--) {
- h = *(p - width) + *(p - 1) + *(p + 1) + *(p + width) + (*p) * 60;
+ p = filter->map3 + m_w + 1;
+ q = filter->map2 + m_w + 1;
+ for (y = m_h - 2; y > 0; y--) {
+ for (x = m_w - 2; x > 0; x--) {
+ h = *(p - m_w) + *(p - 1) + *(p + 1) + *(p + m_w) + (*p) * 60;
*q = h >> 6;
p++;
q++;
vp = filter->vtable;
p = filter->map1;
- for (y = height - 1; y > 0; y--) {
- for (x = width - 1; x > 0; x--) {
+ for (y = m_h - 1; y > 0; y--) {
+ for (x = m_w - 1; x > 0; x--) {
/* difference of the height between two voxel. They are twiced to
* emphasise the wave. */
vp[0] = sqrtable[((p[0] - p[1]) >> (point - 1)) & 0xff];
- vp[1] = sqrtable[((p[0] - p[width]) >> (point - 1)) & 0xff];
+ vp[1] = sqrtable[((p[0] - p[m_w]) >> (point - 1)) & 0xff];
p++;
vp += 2;
}
vp += 2;
}
- height = filter->height;
- width = filter->width;
vp = filter->vtable;
/* draw refracted image. The vector table is stretched. */
- for (y = 0; y < height; y += 2) {
- for (x = 0; x < width; x += 2) {
+ for (y = 0; y < v_h; y += 2) {
+ for (x = 0; x < v_w; x += 2) {
h = (gint) vp[0];
v = (gint) vp[1];
dx = x + h;
dy = y + v;
- if (dx < 0)
- dx = 0;
- if (dy < 0)
- dy = 0;
- if (dx >= width)
- dx = width - 1;
- if (dy >= height)
- dy = height - 1;
- dest[0] = src[dy * width + dx];
-
- i = dx;
+ dx = CLAMP (dx, 0, (v_w - 1));
+ dy = CLAMP (dy, 0, (v_h - 1));
+ dest[0] = src[dy * v_w + dx];
+
+ o_dx = dx;
dx = x + 1 + (h + (gint) vp[2]) / 2;
- if (dx < 0)
- dx = 0;
- if (dx >= width)
- dx = width - 1;
- dest[1] = src[dy * width + dx];
-
- dy = y + 1 + (v + (gint) vp[filter->map_w * 2 + 1]) / 2;
- if (dy < 0)
- dy = 0;
- if (dy >= height)
- dy = height - 1;
- dest[width] = src[dy * width + i];
-
- dest[width + 1] = src[dy * width + dx];
+ dx = CLAMP (dx, 0, (v_w - 1));
+ dest[1] = src[dy * v_w + dx];
+
+ dy = y + 1 + (v + (gint) vp[m_w * 2 + 1]) / 2;
+ dy = CLAMP (dy, 0, (v_h - 1));
+ dest[v_w] = src[dy * v_w + o_dx];
+
+ dest[v_w + 1] = src[dy * v_w + dx];
dest += 2;
vp += 2;
}
- dest += filter->width;
+ dest += v_w;
vp += 2;
}
GST_OBJECT_UNLOCK (filter);
filter->map_h = filter->height / 2 + 1;
filter->map_w = filter->width / 2 + 1;
+ /* we over allocate the buffers, as the render code does not handle clipping
+ * very well */
if (filter->map)
g_free (filter->map);
- filter->map = g_new0 (gint, filter->map_h * filter->map_w * 3);
+ filter->map = g_new0 (gint, (1 + filter->map_h) * filter->map_w * 3);
filter->map1 = filter->map;
filter->map2 = filter->map + filter->map_w * filter->map_h;
if (filter->vtable)
g_free (filter->vtable);
- filter->vtable = g_new0 (gint8, filter->map_h * filter->map_w * 2);
+ filter->vtable = g_new0 (gint8, (1 + filter->map_h) * filter->map_w * 2);
if (filter->background)
g_free (filter->background);
- filter->background = g_new0 (gint16, filter->width * filter->height);
+ filter->background = g_new0 (gint16, filter->width * (filter->height + 1));
if (filter->diff)
g_free (filter->diff);
- filter->diff = g_new0 (guint8, filter->width * filter->height);
+ filter->diff = g_new0 (guint8, filter->width * (filter->height + 1));
ret = TRUE;
}
{
filter->mode = DEFAULT_MODE;
+ /* FIXME: remove this when memory corruption after resizes are fixed */
gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SRC_PAD (filter));
gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (filter));
}