rippletv: clean up the rendering code a bit

This is corrrupts the memoy when resizing. Add a FIXME to make it resizeable
once that is solved.
This commit is contained in:
Stefan Sauer 2011-11-25 10:15:35 +01:00
parent b6de7baeb6
commit f0fe717cd9

View file

@ -312,9 +312,9 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in,
guint32 *src, *dest; guint32 *src, *dest;
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
gint x, y, i; gint x, y, i;
gint dx, dy; gint dx, dy, o_dx;
gint h, v; gint h, v;
gint width, height; gint m_w, m_h, v_w, v_h;
gint *p, *q, *r; gint *p, *q, *r;
gint8 *vp; gint8 *vp;
GstClockTime timestamp, stream_time; GstClockTime timestamp, stream_time;
@ -339,22 +339,24 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in,
else else
motiondetect (filter, src); motiondetect (filter, src);
m_w = filter->map_w;
m_h = filter->map_h;
v_w = filter->width;
v_h = filter->height;
/* simulate surface wave */ /* simulate surface wave */
width = filter->map_w;
height = filter->map_h;
/* This function is called only 30 times per second. To increase a speed /* This function is called only 30 times per second. To increase a speed
* of wave, iterates this loop several times. */ * of wave, iterates this loop several times. */
for (i = loopnum; i > 0; i--) { for (i = loopnum; i > 0; i--) {
/* wave simulation */ /* wave simulation */
p = filter->map1 + width + 1; p = filter->map1 + m_w + 1;
q = filter->map2 + width + 1; q = filter->map2 + m_w + 1;
r = filter->map3 + width + 1; r = filter->map3 + m_w + 1;
for (y = height - 2; y > 0; y--) { for (y = m_h - 2; y > 0; y--) {
for (x = width - 2; x > 0; x--) { for (x = m_w - 2; x > 0; x--) {
h = *(p - width - 1) + *(p - width + 1) + *(p + width - 1) + *(p + h = *(p - m_w - 1) + *(p - m_w + 1) + *(p + m_w - 1) + *(p + m_w + 1)
width + 1) + *(p - m_w) + *(p - 1) + *(p + 1) + *(p + m_w) - (*p) * 9;
+ *(p - width) + *(p - 1) + *(p + 1) + *(p + width) - (*p) * 9;
h = h >> 3; h = h >> 3;
v = *p - *q; v = *p - *q;
v += h - (v >> decay); v += h - (v >> decay);
@ -369,11 +371,11 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in,
} }
/* low pass filter */ /* low pass filter */
p = filter->map3 + width + 1; p = filter->map3 + m_w + 1;
q = filter->map2 + width + 1; q = filter->map2 + m_w + 1;
for (y = height - 2; y > 0; y--) { for (y = m_h - 2; y > 0; y--) {
for (x = width - 2; x > 0; x--) { for (x = m_w - 2; x > 0; x--) {
h = *(p - width) + *(p - 1) + *(p + 1) + *(p + width) + (*p) * 60; h = *(p - m_w) + *(p - 1) + *(p + 1) + *(p + m_w) + (*p) * 60;
*q = h >> 6; *q = h >> 6;
p++; p++;
q++; q++;
@ -389,12 +391,12 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in,
vp = filter->vtable; vp = filter->vtable;
p = filter->map1; p = filter->map1;
for (y = height - 1; y > 0; y--) { for (y = m_h - 1; y > 0; y--) {
for (x = width - 1; x > 0; x--) { for (x = m_w - 1; x > 0; x--) {
/* difference of the height between two voxel. They are twiced to /* difference of the height between two voxel. They are twiced to
* emphasise the wave. */ * emphasise the wave. */
vp[0] = sqrtable[((p[0] - p[1]) >> (point - 1)) & 0xff]; 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++; p++;
vp += 2; vp += 2;
} }
@ -402,48 +404,34 @@ gst_rippletv_transform (GstBaseTransform * trans, GstBuffer * in,
vp += 2; vp += 2;
} }
height = filter->height;
width = filter->width;
vp = filter->vtable; vp = filter->vtable;
/* draw refracted image. The vector table is stretched. */ /* draw refracted image. The vector table is stretched. */
for (y = 0; y < height; y += 2) { for (y = 0; y < v_h; y += 2) {
for (x = 0; x < width; x += 2) { for (x = 0; x < v_w; x += 2) {
h = (gint) vp[0]; h = (gint) vp[0];
v = (gint) vp[1]; v = (gint) vp[1];
dx = x + h; dx = x + h;
dy = y + v; dy = y + v;
if (dx < 0) dx = CLAMP (dx, 0, (v_w - 1));
dx = 0; dy = CLAMP (dy, 0, (v_h - 1));
if (dy < 0) dest[0] = src[dy * v_w + dx];
dy = 0;
if (dx >= width)
dx = width - 1;
if (dy >= height)
dy = height - 1;
dest[0] = src[dy * width + dx];
i = dx; o_dx = dx;
dx = x + 1 + (h + (gint) vp[2]) / 2; dx = x + 1 + (h + (gint) vp[2]) / 2;
if (dx < 0) dx = CLAMP (dx, 0, (v_w - 1));
dx = 0; dest[1] = src[dy * v_w + dx];
if (dx >= width)
dx = width - 1;
dest[1] = src[dy * width + dx];
dy = y + 1 + (v + (gint) vp[filter->map_w * 2 + 1]) / 2; dy = y + 1 + (v + (gint) vp[m_w * 2 + 1]) / 2;
if (dy < 0) dy = CLAMP (dy, 0, (v_h - 1));
dy = 0; dest[v_w] = src[dy * v_w + o_dx];
if (dy >= height)
dy = height - 1;
dest[width] = src[dy * width + i];
dest[width + 1] = src[dy * width + dx]; dest[v_w + 1] = src[dy * v_w + dx];
dest += 2; dest += 2;
vp += 2; vp += 2;
} }
dest += filter->width; dest += v_w;
vp += 2; vp += 2;
} }
GST_OBJECT_UNLOCK (filter); GST_OBJECT_UNLOCK (filter);
@ -468,9 +456,11 @@ gst_rippletv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
filter->map_h = filter->height / 2 + 1; filter->map_h = filter->height / 2 + 1;
filter->map_w = filter->width / 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) if (filter->map)
g_free (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->map1 = filter->map;
filter->map2 = filter->map + filter->map_w * filter->map_h; filter->map2 = filter->map + filter->map_w * filter->map_h;
@ -478,15 +468,15 @@ gst_rippletv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
if (filter->vtable) if (filter->vtable)
g_free (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) if (filter->background)
g_free (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) if (filter->diff)
g_free (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; ret = TRUE;
} }
@ -626,6 +616,7 @@ gst_rippletv_init (GstRippleTV * filter, GstRippleTVClass * klass)
{ {
filter->mode = DEFAULT_MODE; 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_SRC_PAD (filter));
gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (filter)); gst_pad_use_fixed_caps (GST_BASE_TRANSFORM_SINK_PAD (filter));
} }