static gboolean gst_shagadelictv_set_caps (GstBaseTransform * btrans, GstCaps * incaps, GstCaps * outcaps) { GstShagadelicTV *filter = GST_SHAGADELICTV (btrans); GstStructure *structure; gboolean ret = FALSE; structure = gst_caps_get_structure (incaps, 0); GST_OBJECT_LOCK (filter); if (gst_structure_get_int (structure, "width", &filter->width) && gst_structure_get_int (structure, "height", &filter->height)) { gint area = filter->width * filter->height; g_free (filter->ripple); g_free (filter->spiral); filter->ripple = (guint8 *) g_malloc (area * 4); filter->spiral = (guint8 *) g_malloc (area); gst_shagadelic_initialize (filter); ret = TRUE; } GST_OBJECT_UNLOCK (filter); return ret; }
static GstFlowReturn gst_shagadelictv_transform (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out) { GstShagadelicTV *filter = GST_SHAGADELICTV (trans); guint32 *src, *dest; gint x, y; guint32 v; guint8 r, g, b; gint width, height; GstFlowReturn ret = GST_FLOW_OK; src = (guint32 *) GST_BUFFER_DATA (in); dest = (guint32 *) GST_BUFFER_DATA (out); GST_OBJECT_LOCK (filter); width = filter->width; height = filter->height; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { v = *src++ | 0x1010100; v = (v - 0x707060) & 0x1010100; v -= v >> 8; /* Try another Babe! * v = *src++; * *dest++ = v & ((r<<16)|(g<<8)|b); */ r = ((gint8) (filter->ripple[(filter->ry + y) * width * 2 + filter->rx + x] + filter->phase * 2)) >> 7; g = ((gint8) (filter->spiral[y * width + x] + filter->phase * 3)) >> 7; b = ((gint8) (filter->ripple[(filter->by + y) * width * 2 + filter->bx + x] - filter->phase)) >> 7; *dest++ = v & ((r << 16) | (g << 8) | b); } } filter->phase -= 8; if ((filter->rx + filter->rvx) < 0 || (filter->rx + filter->rvx) >= width) filter->rvx = -filter->rvx; if ((filter->ry + filter->rvy) < 0 || (filter->ry + filter->rvy) >= height) filter->rvy = -filter->rvy; if ((filter->bx + filter->bvx) < 0 || (filter->bx + filter->bvx) >= width) filter->bvx = -filter->bvx; if ((filter->by + filter->bvy) < 0 || (filter->by + filter->bvy) >= height) filter->bvy = -filter->bvy; filter->rx += filter->rvx; filter->ry += filter->rvy; filter->bx += filter->bvx; filter->by += filter->bvy; GST_OBJECT_UNLOCK (filter); return ret; }
static GstFlowReturn gst_shagadelictv_transform_frame (GstVideoFilter * vfilter, GstVideoFrame * in_frame, GstVideoFrame * out_frame) { GstShagadelicTV *filter = GST_SHAGADELICTV (vfilter); guint32 *src, *dest; gint x, y; guint32 v; guint8 r, g, b; gint width, height; src = GST_VIDEO_FRAME_PLANE_DATA (in_frame, 0); dest = GST_VIDEO_FRAME_PLANE_DATA (out_frame, 0); width = GST_VIDEO_FRAME_WIDTH (in_frame); height = GST_VIDEO_FRAME_HEIGHT (in_frame); for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { v = *src++ | 0x1010100; v = (v - 0x707060) & 0x1010100; v -= v >> 8; /* Try another Babe! * v = *src++; * *dest++ = v & ((r<<16)|(g<<8)|b); */ r = ((gint8) (filter->ripple[(filter->ry + y) * width * 2 + filter->rx + x] + filter->phase * 2)) >> 7; g = ((gint8) (filter->spiral[y * width + x] + filter->phase * 3)) >> 7; b = ((gint8) (filter->ripple[(filter->by + y) * width * 2 + filter->bx + x] - filter->phase)) >> 7; *dest++ = v & ((r << 16) | (g << 8) | b); } } filter->phase -= 8; if ((filter->rx + filter->rvx) < 0 || (filter->rx + filter->rvx) >= width) filter->rvx = -filter->rvx; if ((filter->ry + filter->rvy) < 0 || (filter->ry + filter->rvy) >= height) filter->rvy = -filter->rvy; if ((filter->bx + filter->bvx) < 0 || (filter->bx + filter->bvx) >= width) filter->bvx = -filter->bvx; if ((filter->by + filter->bvy) < 0 || (filter->by + filter->bvy) >= height) filter->bvy = -filter->bvy; filter->rx += filter->rvx; filter->ry += filter->rvy; filter->bx += filter->bvx; filter->by += filter->bvy; return GST_FLOW_OK; }
static void gst_shagadelictv_finalize (GObject * object) { GstShagadelicTV *filter = GST_SHAGADELICTV (object); if (filter->ripple) g_free (filter->ripple); filter->ripple = NULL; if (filter->spiral) g_free (filter->spiral); filter->spiral = NULL; G_OBJECT_CLASS (parent_class)->finalize (object); }
static gboolean gst_shagadelictv_set_info (GstVideoFilter * vfilter, GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps, GstVideoInfo * out_info) { GstShagadelicTV *filter = GST_SHAGADELICTV (vfilter); gint width, height, area; width = GST_VIDEO_INFO_WIDTH (in_info); height = GST_VIDEO_INFO_HEIGHT (in_info); area = width * height; g_free (filter->ripple); g_free (filter->spiral); filter->ripple = (guint8 *) g_malloc (area * 4); filter->spiral = (guint8 *) g_malloc (area); gst_shagadelic_initialize (filter, in_info); return TRUE; }