PROP_IS_LIVE,
PROP_PEER_ALLOC,
PROP_COLOR_SPEC,
+ PROP_K0,
+ PROP_KX,
+ PROP_KY,
+ PROP_KT,
+ PROP_KXT,
+ PROP_KYT,
+ PROP_KXY,
+ PROP_KX2,
+ PROP_KY2,
+ PROP_KT2,
+ PROP_XOFFSET,
+ PROP_YOFFSET,
PROP_LAST
};
{GST_VIDEO_TEST_SRC_CIRCULAR, "Circular", "circular"},
{GST_VIDEO_TEST_SRC_BLINK, "Blink", "blink"},
{GST_VIDEO_TEST_SRC_SMPTE75, "SMPTE 75% color bars", "smpte75"},
+ {GST_VIDEO_TEST_SRC_ZONE_PLATE, "Zone plate", "zone-plate"},
{0, NULL, NULL}
};
"Generate video in the given color specification",
GST_TYPE_VIDEO_TEST_SRC_COLOR_SPEC,
DEFAULT_COLOR_SPEC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_K0,
+ g_param_spec_int ("k0", "Zoneplate zero order phase",
+ "Zoneplate zero order phase, for generating plain fields or phase offsets",
+ G_MININT32, G_MAXINT32, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_KX,
+ g_param_spec_int ("kx", "Zoneplate 1st order x phase",
+ "Zoneplate 1st order x phase, for generating constant horizontal frequencies",
+ G_MININT32, G_MAXINT32, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_KY,
+ g_param_spec_int ("ky", "Zoneplate 1st order y phase",
+ "Zoneplate 1st order y phase, for generating contant vertical frequencies",
+ G_MININT32, G_MAXINT32, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_KT,
+ g_param_spec_int ("kt", "Zoneplate 1st order t phase",
+ "Zoneplate 1st order t phase, for generating phase rotation as a function of time",
+ G_MININT32, G_MAXINT32, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_KXT,
+ g_param_spec_int ("kxt", "Zoneplate x*t product phase",
+ "Zoneplate x*t product phase, normalised to kxy/256 cycles per vertical pixel at width/2 from origin",
+ G_MININT32, G_MAXINT32, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_KYT,
+ g_param_spec_int ("kyt", "Zoneplate y*t product phase",
+ "Zoneplate y*t product phase", G_MININT32, G_MAXINT32, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_KXY,
+ g_param_spec_int ("kxy", "Zoneplate x*y product phase",
+ "Zoneplate x*t product phase", G_MININT32, G_MAXINT32, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_KX2,
+ g_param_spec_int ("kx2", "Zoneplate 2nd order x phase",
+ "Zoneplate 2nd order x phase, normalised to kx2/256 cycles per horizontal pixel at width/2 from origin",
+ G_MININT32, G_MAXINT32, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_KY2,
+ g_param_spec_int ("ky2", "Zoneplate 2nd order y phase",
+ "Zoneplate 2nd order y phase, normailsed to ky2/256 cycles per vertical pixel at height/2 from origin",
+ G_MININT32, G_MAXINT32, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_KT2,
+ g_param_spec_int ("kt2", "Zoneplate 2nd order t phase",
+ "Zoneplate 2nd order t phase, t*t/256 cycles per picture", G_MININT32,
+ G_MAXINT32, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_XOFFSET,
+ g_param_spec_int ("xoffset", "Zoneplate 2nd order products x offset",
+ "Zoneplate 2nd order products x offset", G_MININT32, G_MAXINT32, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_YOFFSET,
+ g_param_spec_int ("yoffset", "Zoneplate 2nd order products y offset",
+ "Zoneplate 2nd order products y offset", G_MININT32, G_MAXINT32, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gstbasesrc_class->get_caps = gst_video_test_src_getcaps;
gstbasesrc_class->set_caps = gst_video_test_src_setcaps;
case GST_VIDEO_TEST_SRC_SMPTE75:
videotestsrc->make_image = gst_video_test_src_smpte75;
break;
+ case GST_VIDEO_TEST_SRC_ZONE_PLATE:
+ videotestsrc->make_image = gst_video_test_src_zoneplate;
+ break;
default:
g_assert_not_reached ();
}
case PROP_COLOR_SPEC:
src->color_spec = g_value_get_enum (value);
break;
+ case PROP_K0:
+ src->k0 = g_value_get_int (value);
+ break;
+ case PROP_KX:
+ src->kx = g_value_get_int (value);
+ break;
+ case PROP_KY:
+ src->ky = g_value_get_int (value);
+ break;
+ case PROP_KT:
+ src->kt = g_value_get_int (value);
+ break;
+ case PROP_KXT:
+ src->kxt = g_value_get_int (value);
+ break;
+ case PROP_KYT:
+ src->kyt = g_value_get_int (value);
+ break;
+ case PROP_KXY:
+ src->kxy = g_value_get_int (value);
+ break;
+ case PROP_KX2:
+ src->kx2 = g_value_get_int (value);
+ break;
+ case PROP_KY2:
+ src->ky2 = g_value_get_int (value);
+ break;
+ case PROP_KT2:
+ src->kt2 = g_value_get_int (value);
+ break;
+ case PROP_XOFFSET:
+ src->xoffset = g_value_get_int (value);
+ break;
+ case PROP_YOFFSET:
+ src->yoffset = g_value_get_int (value);
+ break;
default:
break;
}
case PROP_COLOR_SPEC:
g_value_set_enum (value, src->color_spec);
break;
+ case PROP_K0:
+ g_value_set_int (value, src->k0);
+ break;
+ case PROP_KX:
+ g_value_set_int (value, src->kx);
+ break;
+ case PROP_KY:
+ g_value_set_int (value, src->ky);
+ break;
+ case PROP_KT:
+ g_value_set_int (value, src->kt);
+ break;
+ case PROP_KXT:
+ g_value_set_int (value, src->kxt);
+ break;
+ case PROP_KYT:
+ g_value_set_int (value, src->kyt);
+ break;
+ case PROP_KXY:
+ g_value_set_int (value, src->kxy);
+ break;
+ case PROP_KX2:
+ g_value_set_int (value, src->kx2);
+ break;
+ case PROP_KY2:
+ g_value_set_int (value, src->ky2);
+ break;
+ case PROP_KT2:
+ g_value_set_int (value, src->kt2);
+ break;
+ case PROP_XOFFSET:
+ g_value_set_int (value, src->xoffset);
+ break;
+ case PROP_YOFFSET:
+ g_value_set_int (value, src->yoffset);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
+void
+gst_video_test_src_zoneplate (GstVideoTestSrc * v, unsigned char *dest,
+ int w, int h)
+{
+ int i;
+ int j;
+ paintinfo pi = { NULL, };
+ paintinfo *p = π
+ struct fourcc_list_struct *fourcc;
+ struct vts_color_struct_rgb rgb_color;
+ struct vts_color_struct_yuv yuv_color;
+ static uint8_t sine_array[256];
+ static int sine_array_inited = FALSE;
+
+ static int t = 0; /* time - increment phase vs time by 1 for each generated frame */
+ /* this may not fit with the correct gstreamer notion of time, so maybe FIXME? */
+
+ int xreset = -(w / 2) - v->xoffset; /* starting values for x^2 and y^2, centering the ellipse */
+ int yreset = -(h / 2) - v->yoffset;
+
+ int x, y;
+ int accum_kx;
+ int accum_kxt;
+ int accum_ky;
+ int accum_kyt;
+ int accum_kxy;
+ int kt;
+ int kt2;
+ int ky2;
+ int delta_kxt = v->kxt * t;
+ int delta_kxy;
+ int scale_kxy = 0xffff / (w / 2);
+ int scale_kx2 = 0xffff / w;
+
+ if (!sine_array_inited) {
+ int black = 16;
+ int white = 235;
+ int range = white - black;
+ for (i = 0; i < 256; i++) {
+ sine_array[i] =
+ floor (range * (0.5 + 0.5 * sin (i * 2 * M_PI / 256)) + 0.5 + black);
+ }
+ sine_array_inited = TRUE;
+ }
+
+ p->rgb_colors = vts_colors_rgb;
+ if (v->color_spec == GST_VIDEO_TEST_SRC_BT601) {
+ p->yuv_colors = vts_colors_bt601_ycbcr_100;
+ } else {
+ p->yuv_colors = vts_colors_bt709_ycbcr_100;
+ }
+ p->width = w;
+ p->height = h;
+ fourcc = v->fourcc;
+ if (fourcc == NULL)
+ return;
+
+ fourcc->paint_setup (p, dest);
+ p->paint_hline = fourcc->paint_hline;
+
+ rgb_color = p->rgb_colors[COLOR_BLACK];
+ yuv_color = p->yuv_colors[COLOR_BLACK];
+ p->rgb_color = &rgb_color;
+ p->yuv_color = &yuv_color;
+
+ /* Zoneplate equation:
+ *
+ * phase = k0 + kx*x + ky*y + kt*t
+ * + kxt*x*t + kyt*y*t + kxy*x*y
+ * + kx2*x*x + ky2*y*y + Kt2*t*t
+ */
+
+#if 0
+ for (j = 0, y = yreset; j < h; j++, y++) {
+ for (i = 0, x = xreset; i < w; i++, x++) {
+
+ //zero order
+ int phase = v->k0;
+
+ //first order
+ phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t);
+
+ //cross term
+ //phase = phase + (v->kxt * i * t) + (v->kyt * j * t);
+ //phase = phase + (v->kxy * x * y) / (w/2);
+
+ /*second order */
+ /*normalise x/y terms to rate of change of phase at the picture edge */
+ phase =
+ phase + ((v->kx2 * x * x) / w) + ((v->ky2 * y * y) / h) +
+ ((v->kt2 * t * t) >> 1);
+
+ color.Y = sine_array[phase & 0xff];
+
+ color.R = color.Y;
+ color.G = color.Y;
+ color.B = color.Y;
+ p->paint_hline (p, i, j, 1);
+ }
+ }
+#endif
+
+ /* optimised version, with original code shown in comments */
+ accum_ky = 0;
+ accum_kyt = 0;
+ kt = v->kt * t;
+ kt2 = v->kt2 * t * t;
+ for (j = 0, y = yreset; j < h; j++, y++) {
+ accum_kx = 0;
+ accum_kxt = 0;
+ accum_ky += v->ky;
+ accum_kyt += v->kyt * t;
+ delta_kxy = v->kxy * y * scale_kxy;
+ accum_kxy = delta_kxy * xreset;
+ ky2 = (v->ky2 * y * y) / h;
+ for (i = 0, x = xreset; i < w; i++, x++) {
+
+ //zero order
+ int phase = v->k0;
+
+ //first order
+ accum_kx += v->kx;
+ //phase = phase + (v->kx * i) + (v->ky * j) + (v->kt * t);
+ phase = phase + accum_kx + accum_ky + kt;
+
+ //cross term
+ accum_kxt += delta_kxt;
+ accum_kxy += delta_kxy;
+ //phase = phase + (v->kxt * i * t) + (v->kyt * j * t);
+ phase = phase + accum_kxt + accum_kyt;
+
+ //phase = phase + (v->kxy * x * y) / (w/2);
+ //phase = phase + accum_kxy / (w/2) ;
+ phase = phase + (accum_kxy >> 16);
+
+ /*second order */
+ /*normalise x/y terms to rate of change of phase at the picture edge */
+ //phase = phase + ((v->kx2 * x * x)/w) + ((v->ky2 * y * y)/h) + ((v->kt2 * t * t)>>1);
+ phase = phase + ((v->kx2 * x * x * scale_kx2) >> 16) + ky2 + (kt2 >> 1);
+
+ yuv_color.Y = sine_array[phase & 0xff];
+
+ rgb_color.R = yuv_color.Y;
+ rgb_color.G = yuv_color.Y;
+ rgb_color.B = yuv_color.Y;
+ p->paint_hline (p, i, j, 1);
+ }
+ }
+
+ t++;
+}
+
#undef SCALE_AMPLITUDE
void
gst_video_test_src_circular (GstVideoTestSrc * v, unsigned char *dest,
}
}
+
+
static void
paint_setup_I420 (paintinfo * p, unsigned char *dest)
{