summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Schleef <ds@schleef.org>2007-12-25 00:34:13 +0000
committerDavid Schleef <ds@schleef.org>2007-12-25 00:34:13 +0000
commit9bf35b8a06c2b9dc42ebdf5fac4c5d6b317fbe38 (patch)
treebacdab4ed48444610afb4ab9b322731b0b66df26
parent1e2a8da0b76638bddbc0599a07a0ad73f47546e6 (diff)
* sys/glsink/Makefile.am:
* sys/glsink/gltestsrc.c: * sys/glsink/gltestsrc.h: * sys/glsink/gstgldisplay.c: * sys/glsink/gstgldownload.c: * sys/glsink/gstglfilter.c: * sys/glsink/gstgltestsrc.c: * sys/glsink/gstgltestsrc.h: * sys/glsink/gstglupload.c: * sys/glsink/gstopengl.c: Add gltestsrc element, a duplicate of videotestsrc that uses GL rendering to create images. More cleanup.
-rw-r--r--gst-libs/gst/gl/gstgldisplay.c4
-rw-r--r--gst/gl/Makefile.am4
-rw-r--r--gst/gl/gltestsrc.c492
-rw-r--r--gst/gl/gltestsrc.h57
-rw-r--r--gst/gl/gstgldownload.c6
-rw-r--r--gst/gl/gstgltestsrc.c637
-rw-r--r--gst/gl/gstgltestsrc.h116
-rw-r--r--gst/gl/gstglupload.c2
-rw-r--r--gst/gl/gstopengl.c5
9 files changed, 1317 insertions, 6 deletions
diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c
index 7b1c39b..4378c04 100644
--- a/gst-libs/gst/gl/gstgldisplay.c
+++ b/gst-libs/gst/gl/gstgldisplay.c
@@ -267,7 +267,7 @@ gst_gl_display_init_tmp_window (GstGLDisplay * display)
Window root;
Screen *screen;
- GST_ERROR ("creating temp window");
+ GST_DEBUG ("creating temp window");
screen = XDefaultScreenOfDisplay (display->display);
scrnum = XScreenNumberOfScreen (screen);
@@ -290,7 +290,7 @@ gst_gl_display_init_tmp_window (GstGLDisplay * display)
root, 0, 0, 100, 100,
0, display->visinfo->depth, InputOutput,
display->visinfo->visual, mask, &attr);
- XMapWindow (display->display, display->window);
+ //XMapWindow (display->display, display->window);
XSync (display->display, FALSE);
}
diff --git a/gst/gl/Makefile.am b/gst/gl/Makefile.am
index ab1a653..b4f72c9 100644
--- a/gst/gl/Makefile.am
+++ b/gst/gl/Makefile.am
@@ -9,6 +9,8 @@ libgstglimagesink_la_SOURCES = \
gstglbuffer.c \
gstglupload.c \
gstgldownload.c \
+ gstgltestsrc.c \
+ gltestsrc.c \
gstglfilter.c
libgstglimagesink_la_CFLAGS = $(GST_CFLAGS) $(X_CFLAGS) $(GST_BASE_CFLAGS) \
$(GST_PLUGINS_BASE_CFLAGS)
@@ -21,4 +23,6 @@ noinst_HEADERS = \
glimagesink.h \
gstgldisplay.h \
glextensions.h \
+ gstgltestsrc.h \
+ gltestsrc.h \
gstglbuffer.h
diff --git a/gst/gl/gltestsrc.c b/gst/gl/gltestsrc.c
new file mode 100644
index 0000000..c6e7961
--- /dev/null
+++ b/gst/gl/gltestsrc.c
@@ -0,0 +1,492 @@
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* non-GST-specific stuff */
+
+#include "gstgltestsrc.h"
+#include "gltestsrc.h"
+#include "gstglbuffer.h"
+
+
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+enum
+{
+ COLOR_WHITE = 0,
+ COLOR_YELLOW,
+ COLOR_CYAN,
+ COLOR_GREEN,
+ COLOR_MAGENTA,
+ COLOR_RED,
+ COLOR_BLUE,
+ COLOR_BLACK,
+ COLOR_NEG_I,
+ COLOR_POS_Q,
+ COLOR_SUPER_BLACK,
+ COLOR_DARK_GREY
+};
+
+static const struct vts_color_struct vts_colors[] = {
+ /* 100% white */
+ {255, 128, 128, 255, 255, 255, 255},
+ /* yellow */
+ {226, 0, 155, 255, 255, 0, 255},
+ /* cyan */
+ {179, 170, 0, 0, 255, 255, 255},
+ /* green */
+ {150, 46, 21, 0, 255, 0, 255},
+ /* magenta */
+ {105, 212, 235, 255, 0, 255, 255},
+ /* red */
+ {76, 85, 255, 255, 0, 0, 255},
+ /* blue */
+ {29, 255, 107, 0, 0, 255, 255},
+ /* black */
+ {16, 128, 128, 0, 0, 0, 255},
+ /* -I */
+ {16, 198, 21, 0, 0, 128, 255},
+ /* +Q */
+ {16, 235, 198, 0, 128, 255, 255},
+ /* superblack */
+ {0, 128, 128, 0, 0, 0, 255},
+ /* 5% grey */
+ {32, 128, 128, 32, 32, 32, 255},
+};
+
+static void
+gst_gl_test_src_unicolor (GstGLTestSrc * v, GstGLBuffer * buffer, int w,
+ int h, const struct vts_color_struct *color);
+
+void
+gst_gl_test_src_smpte (GstGLTestSrc * v, GstGLBuffer * buffer, int w, int h)
+{
+ int i;
+
+ glClearColor (0.0, 0.0, 0.0, 1.0);
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+
+ for (i = 0; i < 7; i++) {
+ glColor4f (vts_colors[i].R * (1 / 255.0), vts_colors[i].G * (1 / 255.0),
+ vts_colors[i].B * (1 / 255.0), 1.0);
+ glBegin (GL_QUADS);
+ glVertex3f (-1.0 + i * (2.0 / 7.0), -1.0 + 2.0 * (2.0 / 3.0), 0);
+ glVertex3f (-1.0 + (i + 1) * (2.0 / 7.0), -1.0 + 2.0 * (2.0 / 3.0), 0);
+ glVertex3f (-1.0 + (i + 1) * (2.0 / 7.0), -1.0, 0);
+ glVertex3f (-1.0 + i * (2.0 / 7.0), -1.0, 0);
+ glEnd ();
+ }
+
+ for (i = 0; i < 7; i++) {
+ int k;
+
+ if (i & 1) {
+ k = 7;
+ } else {
+ k = 6 - i;
+ }
+
+ glColor4f (vts_colors[k].R * (1 / 255.0), vts_colors[k].G * (1 / 255.0),
+ vts_colors[k].B * (1 / 255.0), 1.0);
+ glBegin (GL_QUADS);
+ glVertex3f (-1.0 + i * (2.0 / 7.0), -1.0 + 2.0 * (3.0 / 4.0), 0);
+ glVertex3f (-1.0 + (i + 1) * (2.0 / 7.0), -1.0 + 2.0 * (3.0 / 4.0), 0);
+ glVertex3f (-1.0 + (i + 1) * (2.0 / 7.0), -1.0 + 2.0 * (2.0 / 3.0), 0);
+ glVertex3f (-1.0 + i * (2.0 / 7.0), -1.0 + 2.0 * (2.0 / 3.0), 0);
+ glEnd ();
+ }
+
+ for (i = 0; i < 3; i++) {
+ int k;
+
+ if (i == 0) {
+ k = 8;
+ } else if (i == 1) {
+ k = 0;
+ } else {
+ k = 9;
+ }
+
+ glColor4f (vts_colors[k].R * (1 / 255.0), vts_colors[k].G * (1 / 255.0),
+ vts_colors[k].B * (1 / 255.0), 1.0);
+ glBegin (GL_QUADS);
+ glVertex3f (-1.0 + i * (2.0 / 6.0), -1.0 + 2.0 * 1, 0);
+ glVertex3f (-1.0 + (i + 1) * (2.0 / 6.0), -1.0 + 2.0 * 1, 0);
+ glVertex3f (-1.0 + (i + 1) * (2.0 / 6.0), -1.0 + 2.0 * (3.0 / 4.0), 0);
+ glVertex3f (-1.0 + i * (2.0 / 6.0), -1.0 + 2.0 * (3.0 / 4.0), 0);
+ glEnd ();
+ }
+
+ for (i = 0; i < 3; i++) {
+ int k;
+
+ if (i == 0) {
+ k = COLOR_SUPER_BLACK;
+ } else if (i == 1) {
+ k = COLOR_BLACK;
+ } else {
+ k = COLOR_DARK_GREY;
+ }
+
+ glColor4f (vts_colors[k].R * (1 / 255.0), vts_colors[k].G * (1 / 255.0),
+ vts_colors[k].B * (1 / 255.0), 1.0);
+ glBegin (GL_QUADS);
+ glVertex3f (-1.0 + 2.0 * (0.5 + i * (1.0 / 12.0)), -1.0 + 2.0 * 1, 0);
+ glVertex3f (-1.0 + 2.0 * (0.5 + (i + 1) * (1.0 / 12.0)), -1.0 + 2.0 * 1, 0);
+ glVertex3f (-1.0 + 2.0 * (0.5 + (i + 1) * (1.0 / 12.0)),
+ -1.0 + 2.0 * (3.0 / 4.0), 0);
+ glVertex3f (-1.0 + 2.0 * (0.5 + i * (1.0 / 12.0)), -1.0 + 2.0 * (3.0 / 4.0),
+ 0);
+ glEnd ();
+ }
+
+ glColor4f (0.5, 0.5, 0.5, 1.0);
+ glBegin (GL_QUADS);
+ glVertex3f (-1.0 + 2.0 * (0.75), -1.0 + 2.0 * 1, 0);
+ glVertex3f (-1.0 + 2.0 * (1.0), -1.0 + 2.0 * 1, 0);
+ glVertex3f (-1.0 + 2.0 * (1.0), -1.0 + 2.0 * (3.0 / 4.0), 0);
+ glVertex3f (-1.0 + 2.0 * (0.75), -1.0 + 2.0 * (3.0 / 4.0), 0);
+ glEnd ();
+
+}
+
+void
+gst_gl_test_src_snow (GstGLTestSrc * v, GstGLBuffer * buffer, int w, int h)
+{
+ glClearColor (0.0, 0.0, 0.0, 1.0);
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+
+ /* FIXME snow requires a fragment shader. Please write. */
+ glColor4f (0.5, 0.5, 0.5, 1.0);
+ glBegin (GL_QUADS);
+ glVertex3f (-1.0 + 2.0 * (0.0), -1.0 + 2.0 * 1, 0);
+ glVertex3f (-1.0 + 2.0 * (1.0), -1.0 + 2.0 * 1, 0);
+ glVertex3f (-1.0 + 2.0 * (1.0), -1.0 + 2.0 * (0.0), 0);
+ glVertex3f (-1.0 + 2.0 * (0.0), -1.0 + 2.0 * (0.0), 0);
+ glEnd ();
+}
+
+static void
+gst_gl_test_src_unicolor (GstGLTestSrc * v, GstGLBuffer * buffer, int w,
+ int h, const struct vts_color_struct *color)
+{
+ glClearColor (color->R * (1 / 255.0), color->G * (1 / 255.0),
+ color->B * (1 / 255.0), 1.0);
+ glClear (GL_COLOR_BUFFER_BIT);
+}
+
+void
+gst_gl_test_src_black (GstGLTestSrc * v, GstGLBuffer * buffer, int w, int h)
+{
+ gst_gl_test_src_unicolor (v, buffer, w, h, vts_colors + COLOR_BLACK);
+}
+
+void
+gst_gl_test_src_white (GstGLTestSrc * v, GstGLBuffer * buffer, int w, int h)
+{
+ gst_gl_test_src_unicolor (v, buffer, w, h, vts_colors + COLOR_WHITE);
+}
+
+void
+gst_gl_test_src_red (GstGLTestSrc * v, GstGLBuffer * buffer, int w, int h)
+{
+ gst_gl_test_src_unicolor (v, buffer, w, h, vts_colors + COLOR_RED);
+}
+
+void
+gst_gl_test_src_green (GstGLTestSrc * v, GstGLBuffer * buffer, int w, int h)
+{
+ gst_gl_test_src_unicolor (v, buffer, w, h, vts_colors + COLOR_GREEN);
+}
+
+void
+gst_gl_test_src_blue (GstGLTestSrc * v, GstGLBuffer * buffer, int w, int h)
+{
+ gst_gl_test_src_unicolor (v, buffer, w, h, vts_colors + COLOR_BLUE);
+}
+
+void
+gst_gl_test_src_checkers1 (GstGLTestSrc * v, GstGLBuffer * buffer, int w, int h)
+{
+#if 0
+ int x, y;
+ paintinfo pi = { NULL, };
+ paintinfo *p = &pi;
+ struct fourcc_list_struct *fourcc;
+
+ p->width = w;
+ p->height = h;
+ fourcc = v->fourcc;
+ if (fourcc == NULL)
+ return;
+
+ fourcc->paint_setup (p, dest);
+ p->paint_hline = fourcc->paint_hline;
+
+ for (y = 0; y < h; y++) {
+ p->color = vts_colors + COLOR_GREEN;
+ p->paint_hline (p, 0, y, w);
+ for (x = (y % 2); x < w; x += 2) {
+ p->color = vts_colors + COLOR_RED;
+ p->paint_hline (p, x, y, 1);
+ }
+ }
+#endif
+}
+
+void
+gst_gl_test_src_checkers2 (GstGLTestSrc * v, GstGLBuffer * buffer, int w, int h)
+{
+#if 0
+ int x, y;
+ paintinfo pi = { NULL, };
+ paintinfo *p = &pi;
+ struct fourcc_list_struct *fourcc;
+
+ p->width = w;
+ p->height = h;
+ fourcc = v->fourcc;
+ if (fourcc == NULL)
+ return;
+
+ fourcc->paint_setup (p, dest);
+ p->paint_hline = fourcc->paint_hline;
+
+ p->color = vts_colors + COLOR_GREEN;
+ for (y = 0; y < h; y++) {
+ p->paint_hline (p, 0, y, w);
+ }
+
+ for (y = 0; y < h; y += 2) {
+ for (x = ((y % 4) == 0) ? 0 : 2; x < w; x += 4) {
+ guint len = (x < (w - 1)) ? 2 : (w - x);
+
+ p->color = vts_colors + COLOR_RED;
+ p->paint_hline (p, x, y + 0, len);
+ if (G_LIKELY ((y + 1) < h)) {
+ p->paint_hline (p, x, y + 1, len);
+ }
+ }
+ }
+#endif
+}
+
+void
+gst_gl_test_src_checkers4 (GstGLTestSrc * v, GstGLBuffer * buffer, int w, int h)
+{
+#if 0
+ int x, y;
+ paintinfo pi = { NULL, };
+ paintinfo *p = &pi;
+ struct fourcc_list_struct *fourcc;
+
+ p->width = w;
+ p->height = h;
+ fourcc = v->fourcc;
+ if (fourcc == NULL)
+ return;
+
+ fourcc->paint_setup (p, dest);
+ p->paint_hline = fourcc->paint_hline;
+
+ p->color = vts_colors + COLOR_GREEN;
+ for (y = 0; y < h; y++) {
+ p->paint_hline (p, 0, y, w);
+ }
+
+ for (y = 0; y < h; y += 4) {
+ for (x = ((y % 8) == 0) ? 0 : 4; x < w; x += 8) {
+ guint len = (x < (w - 3)) ? 4 : (w - x);
+
+ p->color = vts_colors + COLOR_RED;
+ p->paint_hline (p, x, y + 0, len);
+ if (G_LIKELY ((y + 1) < h)) {
+ p->paint_hline (p, x, y + 1, len);
+ if (G_LIKELY ((y + 2) < h)) {
+ p->paint_hline (p, x, y + 2, len);
+ if (G_LIKELY ((y + 3) < h)) {
+ p->paint_hline (p, x, y + 3, len);
+ }
+ }
+ }
+ }
+ }
+#endif
+}
+
+void
+gst_gl_test_src_checkers8 (GstGLTestSrc * v, GstGLBuffer * buffer, int w, int h)
+{
+#if 0
+ int x, y;
+ paintinfo pi = { NULL, };
+ paintinfo *p = &pi;
+ struct fourcc_list_struct *fourcc;
+
+ p->width = w;
+ p->height = h;
+ fourcc = v->fourcc;
+ if (fourcc == NULL)
+ return;
+
+ fourcc->paint_setup (p, dest);
+ p->paint_hline = fourcc->paint_hline;
+
+ p->color = vts_colors + COLOR_GREEN;
+ for (y = 0; y < h; y++) {
+ p->paint_hline (p, 0, y, w);
+ }
+
+ for (y = 0; y < h; y += 8) {
+ for (x = ((GST_ROUND_UP_8 (y) % 16) == 0) ? 0 : 8; x < w; x += 16) {
+ guint len = (x < (w - 7)) ? 8 : (w - x);
+
+ p->color = vts_colors + COLOR_RED;
+ p->paint_hline (p, x, y + 0, len);
+ if (G_LIKELY ((y + 1) < h)) {
+ p->paint_hline (p, x, y + 1, len);
+ if (G_LIKELY ((y + 2) < h)) {
+ p->paint_hline (p, x, y + 2, len);
+ if (G_LIKELY ((y + 3) < h)) {
+ p->paint_hline (p, x, y + 3, len);
+ if (G_LIKELY ((y + 4) < h)) {
+ p->paint_hline (p, x, y + 4, len);
+ if (G_LIKELY ((y + 5) < h)) {
+ p->paint_hline (p, x, y + 5, len);
+ if (G_LIKELY ((y + 6) < h)) {
+ p->paint_hline (p, x, y + 6, len);
+ if (G_LIKELY ((y + 7) < h)) {
+ p->paint_hline (p, x, y + 7, len);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
+}
+
+void
+gst_gl_test_src_circular (GstGLTestSrc * v, GstGLBuffer * buffer, int w, int h)
+{
+#if 0
+ int i;
+ int j;
+ paintinfo pi = { NULL, };
+ paintinfo *p = &pi;
+ struct fourcc_list_struct *fourcc;
+ struct vts_color_struct color;
+ static uint8_t sine_array[256];
+ static int sine_array_inited = FALSE;
+ double freq[8];
+
+#ifdef SCALE_AMPLITUDE
+ double ampl[8];
+#endif
+ int d;
+
+ if (!sine_array_inited) {
+ for (i = 0; i < 256; i++) {
+ sine_array[i] =
+ floor (255 * (0.5 + 0.5 * sin (i * 2 * M_PI / 256)) + 0.5);
+ }
+ sine_array_inited = TRUE;
+ }
+
+ p->width = w;
+ p->height = h;
+ fourcc = v->fourcc;
+ if (fourcc == NULL)
+ return;
+
+ fourcc->paint_setup (p, dest);
+ p->paint_hline = fourcc->paint_hline;
+
+ color = vts_colors[COLOR_BLACK];
+ p->color = &color;
+
+ for (i = 1; i < 8; i++) {
+ freq[i] = 200 * pow (2.0, -(i - 1) / 4.0);
+#ifdef SCALE_AMPLITUDE
+ {
+ double x;
+
+ x = 2 * M_PI * freq[i] / w;
+ ampl[i] = sin (x) / x;
+ }
+#endif
+ }
+
+ for (i = 0; i < w; i++) {
+ for (j = 0; j < h; j++) {
+ double dist;
+ int seg;
+
+ dist =
+ sqrt ((2 * i - w) * (2 * i - w) + (2 * j - h) * (2 * j -
+ h)) / (2 * w);
+ seg = floor (dist * 16);
+ if (seg == 0 || seg >= 8) {
+ color.Y = 255;
+ } else {
+#ifdef SCALE_AMPLITUDE
+ double a;
+#endif
+ d = floor (256 * dist * freq[seg] + 0.5);
+#ifdef SCALE_AMPLITUDE
+ a = ampl[seg];
+ if (a < 0)
+ a = 0;
+ color.Y = 128 + a * (sine_array[d & 0xff] - 128);
+#else
+ color.Y = sine_array[d & 0xff];
+#endif
+ }
+ color.R = color.Y;
+ color.G = color.Y;
+ color.B = color.Y;
+ p->paint_hline (p, i, j, 1);
+ }
+ }
+#endif
+}
diff --git a/gst/gl/gltestsrc.h b/gst/gl/gltestsrc.h
new file mode 100644
index 0000000..345b9b1
--- /dev/null
+++ b/gst/gl/gltestsrc.h
@@ -0,0 +1,57 @@
+/* GStreamer
+ * Copyright (C) <2003> David A. Schleef <ds@schleef.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GL_TEST_SRC_H__
+#define __GL_TEST_SRC_H__
+
+#include <glib.h>
+#include "gstglbuffer.h"
+
+struct vts_color_struct {
+ guint8 Y, U, V;
+ guint8 R, G, B;
+ guint8 A;
+};
+
+void gst_gl_test_src_smpte (GstGLTestSrc * v,
+ GstGLBuffer *buffer, int w, int h);
+void gst_gl_test_src_snow (GstGLTestSrc * v,
+ GstGLBuffer *buffer, int w, int h);
+void gst_gl_test_src_black (GstGLTestSrc * v,
+ GstGLBuffer *buffer, int w, int h);
+void gst_gl_test_src_white (GstGLTestSrc * v,
+ GstGLBuffer *buffer, int w, int h);
+void gst_gl_test_src_red (GstGLTestSrc * v,
+ GstGLBuffer *buffer, int w, int h);
+void gst_gl_test_src_green (GstGLTestSrc * v,
+ GstGLBuffer *buffer, int w, int h);
+void gst_gl_test_src_blue (GstGLTestSrc * v,
+ GstGLBuffer *buffer, int w, int h);
+void gst_gl_test_src_checkers1 (GstGLTestSrc * v,
+ GstGLBuffer *buffer, int w, int h);
+void gst_gl_test_src_checkers2 (GstGLTestSrc * v,
+ GstGLBuffer *buffer, int w, int h);
+void gst_gl_test_src_checkers4 (GstGLTestSrc * v,
+ GstGLBuffer *buffer, int w, int h);
+void gst_gl_test_src_checkers8 (GstGLTestSrc * v,
+ GstGLBuffer *buffer, int w, int h);
+void gst_gl_test_src_circular (GstGLTestSrc * v,
+ GstGLBuffer *buffer, int w, int h);
+
+#endif
diff --git a/gst/gl/gstgldownload.c b/gst/gl/gstgldownload.c
index 23b4513..bc50f45 100644
--- a/gst/gl/gstgldownload.c
+++ b/gst/gl/gstgldownload.c
@@ -207,20 +207,20 @@ gst_gl_download_sink_setcaps (GstPad * pad, GstCaps * caps)
download = GST_GL_DOWNLOAD (gst_pad_get_parent (pad));
- GST_ERROR ("called with %" GST_PTR_FORMAT, caps);
+ GST_DEBUG ("called with %" GST_PTR_FORMAT, caps);
structure = gst_caps_get_structure (caps, 0);
ret = gst_structure_get_int (structure, "width", &download->width);
ret &= gst_structure_get_int (structure, "height", &download->height);
if (!ret) {
- GST_ERROR ("bad caps");
+ GST_DEBUG ("bad caps");
return FALSE;
}
srccaps = gst_video_format_new_caps (download->format,
download->width, download->height, 30, 1, 1, 1);
- GST_ERROR ("srccaps %" GST_PTR_FORMAT, srccaps);
+ GST_DEBUG ("srccaps %" GST_PTR_FORMAT, srccaps);
ret = gst_pad_set_caps (download->srcpad, srccaps);
gst_caps_unref (srccaps);
diff --git a/gst/gl/gstgltestsrc.c b/gst/gl/gstgltestsrc.c
new file mode 100644
index 0000000..66d32f6
--- /dev/null
+++ b/gst/gl/gstgltestsrc.c
@@ -0,0 +1,637 @@
+/* GStreamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ * Copyright (C) 2002,2007 David A. Schleef <ds@schleef.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:element-gltestsrc
+ *
+ * <refsect2>
+ * <para>
+ * The gltestsrc element is used to produce test video data in a wide variaty
+ * of formats. The video test data produced can be controlled with the "pattern"
+ * property.
+ * </para>
+ * <title>Example launch line</title>
+ * <para>
+ * <programlisting>
+ * gst-launch -v gltestsrc pattern=snow ! ximagesink
+ * </programlisting>
+ * Shows random noise in an X window.
+ * </para>
+ * </refsect2>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "gstgltestsrc.h"
+#include "gltestsrc.h"
+#include "gstglbuffer.h"
+#include "glextensions.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#define USE_PEER_BUFFERALLOC
+
+GST_DEBUG_CATEGORY_STATIC (gl_test_src_debug);
+#define GST_CAT_DEFAULT gl_test_src_debug
+
+#define GST_GL_VIDEO_CAPS "video/x-raw-gl,width=(int)[1,2048],height=(int)[1,2048],framerate=(fraction)[0/1,100/1],pixel_aspect_ratio=(fraction)[0/1,100/1]"
+
+static const GstElementDetails gl_test_src_details =
+GST_ELEMENT_DETAILS ("Video test source",
+ "Source/Video",
+ "Creates a test video stream",
+ "David A. Schleef <ds@schleef.org>");
+
+
+enum
+{
+ PROP_0,
+ PROP_PATTERN,
+ PROP_TIMESTAMP_OFFSET,
+ PROP_IS_LIVE
+ /* FILL ME */
+};
+
+
+GST_BOILERPLATE (GstGLTestSrc, gst_gl_test_src, GstPushSrc, GST_TYPE_PUSH_SRC);
+
+
+static void gst_gl_test_src_set_pattern (GstGLTestSrc * gltestsrc,
+ int pattern_type);
+static void gst_gl_test_src_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+static void gst_gl_test_src_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+static gboolean gst_gl_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps);
+static void gst_gl_test_src_src_fixate (GstPad * pad, GstCaps * caps);
+
+static gboolean gst_gl_test_src_is_seekable (GstBaseSrc * psrc);
+static gboolean gst_gl_test_src_do_seek (GstBaseSrc * bsrc,
+ GstSegment * segment);
+static gboolean gst_gl_test_src_query (GstBaseSrc * bsrc, GstQuery * query);
+
+static void gst_gl_test_src_get_times (GstBaseSrc * basesrc,
+ GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
+static GstFlowReturn gst_gl_test_src_create (GstPushSrc * psrc,
+ GstBuffer ** buffer);
+static gboolean gst_gl_test_src_start (GstBaseSrc * basesrc);
+static gboolean gst_gl_test_src_stop (GstBaseSrc * basesrc);
+
+#define GST_TYPE_GL_TEST_SRC_PATTERN (gst_gl_test_src_pattern_get_type ())
+static GType
+gst_gl_test_src_pattern_get_type (void)
+{
+ static GType gl_test_src_pattern_type = 0;
+ static const GEnumValue pattern_types[] = {
+ {GST_GL_TEST_SRC_SMPTE, "SMPTE 100% color bars", "smpte"},
+ {GST_GL_TEST_SRC_SNOW, "Random (television snow)", "snow"},
+ {GST_GL_TEST_SRC_BLACK, "100% Black", "black"},
+ {GST_GL_TEST_SRC_WHITE, "100% White", "white"},
+ {GST_GL_TEST_SRC_RED, "Red", "red"},
+ {GST_GL_TEST_SRC_GREEN, "Green", "green"},
+ {GST_GL_TEST_SRC_BLUE, "Blue", "blue"},
+ {GST_GL_TEST_SRC_CHECKERS1, "Checkers 1px", "checkers-1"},
+ {GST_GL_TEST_SRC_CHECKERS2, "Checkers 2px", "checkers-2"},
+ {GST_GL_TEST_SRC_CHECKERS4, "Checkers 4px", "checkers-4"},
+ {GST_GL_TEST_SRC_CHECKERS8, "Checkers 8px", "checkers-8"},
+ {GST_GL_TEST_SRC_CIRCULAR, "Circular", "circular"},
+ {GST_GL_TEST_SRC_BLINK, "Blink", "blink"},
+ {0, NULL, NULL}
+ };
+
+ if (!gl_test_src_pattern_type) {
+ gl_test_src_pattern_type =
+ g_enum_register_static ("GstGLTestSrcPattern", pattern_types);
+ }
+ return gl_test_src_pattern_type;
+}
+
+static void
+gst_gl_test_src_base_init (gpointer g_class)
+{
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+
+ gst_element_class_set_details (element_class, &gl_test_src_details);
+
+ gst_element_class_add_pad_template (element_class,
+ gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
+ gst_caps_from_string (GST_GL_VIDEO_CAPS)));
+}
+
+static void
+gst_gl_test_src_class_init (GstGLTestSrcClass * klass)
+{
+ GObjectClass *gobject_class;
+ GstBaseSrcClass *gstbasesrc_class;
+ GstPushSrcClass *gstpushsrc_class;
+
+ GST_DEBUG_CATEGORY_INIT (gl_test_src_debug, "gltestsrc", 0,
+ "Video Test Source");
+
+ gobject_class = (GObjectClass *) klass;
+ gstbasesrc_class = (GstBaseSrcClass *) klass;
+ gstpushsrc_class = (GstPushSrcClass *) klass;
+
+ gobject_class->set_property = gst_gl_test_src_set_property;
+ gobject_class->get_property = gst_gl_test_src_get_property;
+
+ g_object_class_install_property (gobject_class, PROP_PATTERN,
+ g_param_spec_enum ("pattern", "Pattern",
+ "Type of test pattern to generate", GST_TYPE_GL_TEST_SRC_PATTERN,
+ GST_GL_TEST_SRC_SMPTE, G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_TIMESTAMP_OFFSET, g_param_spec_int64 ("timestamp-offset",
+ "Timestamp offset",
+ "An offset added to timestamps set on buffers (in ns)", G_MININT64,
+ G_MAXINT64, 0, G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, PROP_IS_LIVE,
+ g_param_spec_boolean ("is-live", "Is Live",
+ "Whether to act as a live source", FALSE, G_PARAM_READWRITE));
+
+ gstbasesrc_class->set_caps = gst_gl_test_src_setcaps;
+ gstbasesrc_class->is_seekable = gst_gl_test_src_is_seekable;
+ gstbasesrc_class->do_seek = gst_gl_test_src_do_seek;
+ gstbasesrc_class->query = gst_gl_test_src_query;
+ gstbasesrc_class->get_times = gst_gl_test_src_get_times;
+ gstbasesrc_class->start = gst_gl_test_src_start;
+ gstbasesrc_class->stop = gst_gl_test_src_stop;
+
+ gstpushsrc_class->create = gst_gl_test_src_create;
+}
+
+static void
+gst_gl_test_src_init (GstGLTestSrc * src, GstGLTestSrcClass * g_class)
+{
+ GstPad *pad = GST_BASE_SRC_PAD (src);
+
+ gst_pad_set_fixatecaps_function (pad, gst_gl_test_src_src_fixate);
+
+ gst_gl_test_src_set_pattern (src, GST_GL_TEST_SRC_SMPTE);
+
+ src->timestamp_offset = 0;
+
+ /* we operate in time */
+ gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
+ gst_base_src_set_live (GST_BASE_SRC (src), FALSE);
+}
+
+static void
+gst_gl_test_src_src_fixate (GstPad * pad, GstCaps * caps)
+{
+ GstStructure *structure;
+
+ GST_DEBUG ("fixate");
+
+ structure = gst_caps_get_structure (caps, 0);
+
+ gst_structure_fixate_field_nearest_int (structure, "width", 320);
+ gst_structure_fixate_field_nearest_int (structure, "height", 240);
+ gst_structure_fixate_field_nearest_fraction (structure, "framerate", 30, 1);
+}
+
+static void
+gst_gl_test_src_set_pattern (GstGLTestSrc * gltestsrc, int pattern_type)
+{
+ gltestsrc->pattern_type = pattern_type;
+
+ GST_DEBUG_OBJECT (gltestsrc, "setting pattern to %d", pattern_type);
+
+ switch (pattern_type) {
+ case GST_GL_TEST_SRC_SMPTE:
+ gltestsrc->make_image = gst_gl_test_src_smpte;
+ break;
+ case GST_GL_TEST_SRC_SNOW:
+ gltestsrc->make_image = gst_gl_test_src_snow;
+ break;
+ case GST_GL_TEST_SRC_BLACK:
+ gltestsrc->make_image = gst_gl_test_src_black;
+ break;
+ case GST_GL_TEST_SRC_WHITE:
+ gltestsrc->make_image = gst_gl_test_src_white;
+ break;
+ case GST_GL_TEST_SRC_RED:
+ gltestsrc->make_image = gst_gl_test_src_red;
+ break;
+ case GST_GL_TEST_SRC_GREEN:
+ gltestsrc->make_image = gst_gl_test_src_green;
+ break;
+ case GST_GL_TEST_SRC_BLUE:
+ gltestsrc->make_image = gst_gl_test_src_blue;
+ break;
+ case GST_GL_TEST_SRC_CHECKERS1:
+ gltestsrc->make_image = gst_gl_test_src_checkers1;
+ break;
+ case GST_GL_TEST_SRC_CHECKERS2:
+ gltestsrc->make_image = gst_gl_test_src_checkers2;
+ break;
+ case GST_GL_TEST_SRC_CHECKERS4:
+ gltestsrc->make_image = gst_gl_test_src_checkers4;
+ break;
+ case GST_GL_TEST_SRC_CHECKERS8:
+ gltestsrc->make_image = gst_gl_test_src_checkers8;
+ break;
+ case GST_GL_TEST_SRC_CIRCULAR:
+ gltestsrc->make_image = gst_gl_test_src_circular;
+ break;
+ case GST_GL_TEST_SRC_BLINK:
+ gltestsrc->make_image = gst_gl_test_src_black;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static void
+gst_gl_test_src_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstGLTestSrc *src = GST_GL_TEST_SRC (object);
+
+ switch (prop_id) {
+ case PROP_PATTERN:
+ gst_gl_test_src_set_pattern (src, g_value_get_enum (value));
+ break;
+ case PROP_TIMESTAMP_OFFSET:
+ src->timestamp_offset = g_value_get_int64 (value);
+ break;
+ case PROP_IS_LIVE:
+ gst_base_src_set_live (GST_BASE_SRC (src), g_value_get_boolean (value));
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+gst_gl_test_src_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ GstGLTestSrc *src = GST_GL_TEST_SRC (object);
+
+ switch (prop_id) {
+ case PROP_PATTERN:
+ g_value_set_enum (value, src->pattern_type);
+ break;
+ case PROP_TIMESTAMP_OFFSET:
+ g_value_set_int64 (value, src->timestamp_offset);
+ break;
+ case PROP_IS_LIVE:
+ g_value_set_boolean (value, gst_base_src_is_live (GST_BASE_SRC (src)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static gboolean
+gst_gl_test_src_parse_caps (const GstCaps * caps,
+ gint * width, gint * height, gint * rate_numerator, gint * rate_denominator)
+{
+ const GstStructure *structure;
+ GstPadLinkReturn ret;
+ const GValue *framerate;
+
+ GST_DEBUG ("parsing caps");
+
+ if (gst_caps_get_size (caps) < 1)
+ return FALSE;
+
+ structure = gst_caps_get_structure (caps, 0);
+
+ ret = gst_structure_get_int (structure, "width", width);
+ ret &= gst_structure_get_int (structure, "height", height);
+ framerate = gst_structure_get_value (structure, "framerate");
+
+ if (framerate) {
+ *rate_numerator = gst_value_get_fraction_numerator (framerate);
+ *rate_denominator = gst_value_get_fraction_denominator (framerate);
+ } else
+ goto no_framerate;
+
+ return ret;
+
+ /* ERRORS */
+no_framerate:
+ {
+ GST_DEBUG ("gltestsrc no framerate given");
+ return FALSE;
+ }
+}
+
+static gboolean
+gst_gl_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
+{
+ gboolean res;
+ gint width, height, rate_denominator, rate_numerator;
+ GstGLTestSrc *gltestsrc;
+
+ gltestsrc = GST_GL_TEST_SRC (bsrc);
+
+ GST_DEBUG ("setcaps");
+
+ res = gst_gl_test_src_parse_caps (caps, &width, &height,
+ &rate_numerator, &rate_denominator);
+ if (res) {
+ /* looks ok here */
+ gltestsrc->width = width;
+ gltestsrc->height = height;
+ gltestsrc->rate_numerator = rate_numerator;
+ gltestsrc->rate_denominator = rate_denominator;
+ gltestsrc->negotiated = TRUE;
+
+ GST_DEBUG_OBJECT (gltestsrc, "size %dx%d, %d/%d fps",
+ gltestsrc->width, gltestsrc->height,
+ gltestsrc->rate_numerator, gltestsrc->rate_denominator);
+ }
+ return res;
+}
+
+static gboolean
+gst_gl_test_src_query (GstBaseSrc * bsrc, GstQuery * query)
+{
+ gboolean res;
+ GstGLTestSrc *src;
+
+ src = GST_GL_TEST_SRC (bsrc);
+
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_CONVERT:
+ {
+ GstFormat src_fmt, dest_fmt;
+ gint64 src_val, dest_val;
+
+ gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
+ if (src_fmt == dest_fmt) {
+ dest_val = src_val;
+ goto done;
+ }
+
+ switch (src_fmt) {
+ case GST_FORMAT_DEFAULT:
+ switch (dest_fmt) {
+ case GST_FORMAT_TIME:
+ /* frames to time */
+ if (src->rate_numerator) {
+ dest_val = gst_util_uint64_scale (src_val,
+ src->rate_denominator * GST_SECOND, src->rate_numerator);
+ } else {
+ dest_val = 0;
+ }
+ break;
+ default:
+ goto error;
+ }
+ break;
+ case GST_FORMAT_TIME:
+ switch (dest_fmt) {
+ case GST_FORMAT_DEFAULT:
+ /* time to frames */
+ if (src->rate_numerator) {
+ dest_val = gst_util_uint64_scale (src_val,
+ src->rate_numerator, src->rate_denominator * GST_SECOND);
+ } else {
+ dest_val = 0;
+ }
+ break;
+ default:
+ goto error;
+ }
+ break;
+ default:
+ goto error;
+ }
+ done:
+ gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
+ res = TRUE;
+ break;
+ }
+ default:
+ res = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query);
+ }
+ return res;
+
+ /* ERROR */
+error:
+ {
+ GST_DEBUG_OBJECT (src, "query failed");
+ return FALSE;
+ }
+}
+
+static void
+gst_gl_test_src_get_times (GstBaseSrc * basesrc, GstBuffer * buffer,
+ GstClockTime * start, GstClockTime * end)
+{
+ /* for live sources, sync on the timestamp of the buffer */
+ if (gst_base_src_is_live (basesrc)) {
+ GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);
+
+ if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
+ /* get duration to calculate end time */
+ GstClockTime duration = GST_BUFFER_DURATION (buffer);
+
+ if (GST_CLOCK_TIME_IS_VALID (duration)) {
+ *end = timestamp + duration;
+ }
+ *start = timestamp;
+ }
+ } else {
+ *start = -1;
+ *end = -1;
+ }
+}
+
+static gboolean
+gst_gl_test_src_do_seek (GstBaseSrc * bsrc, GstSegment * segment)
+{
+ GstClockTime time;
+ GstGLTestSrc *src;
+
+ src = GST_GL_TEST_SRC (bsrc);
+
+ segment->time = segment->start;
+ time = segment->last_stop;
+
+ /* now move to the time indicated */
+ if (src->rate_numerator) {
+ src->n_frames = gst_util_uint64_scale (time,
+ src->rate_numerator, src->rate_denominator * GST_SECOND);
+ } else {
+ src->n_frames = 0;
+ }
+ if (src->rate_numerator) {
+ src->running_time = gst_util_uint64_scale (src->n_frames,
+ src->rate_denominator * GST_SECOND, src->rate_numerator);
+ } else {
+ /* FIXME : Not sure what to set here */
+ src->running_time = 0;
+ }
+
+ g_assert (src->running_time <= time);
+
+ return TRUE;
+}
+
+static gboolean
+gst_gl_test_src_is_seekable (GstBaseSrc * psrc)
+{
+ /* we're seekable... */
+ return TRUE;
+}
+
+static GstFlowReturn
+gst_gl_test_src_create (GstPushSrc * psrc, GstBuffer ** buffer)
+{
+ GstGLTestSrc *src;
+ GstGLBuffer *outbuf;
+
+ //GstFlowReturn res;
+ GstClockTime next_time;
+ GLuint fbo;
+
+ src = GST_GL_TEST_SRC (psrc);
+
+ if (G_UNLIKELY (!src->negotiated))
+ goto not_negotiated;
+
+ /* 0 framerate and we are at the second frame, eos */
+ if (G_UNLIKELY (src->rate_numerator == 0 && src->n_frames == 1))
+ goto eos;
+
+ GST_LOG_OBJECT (src, "creating buffer %dx%d image for frame %d",
+ src->width, src->height, (gint) src->n_frames);
+
+ outbuf = gst_gl_buffer_new (src->display, GST_VIDEO_FORMAT_RGBx,
+ src->width, src->height);
+ gst_buffer_set_caps (GST_BUFFER (outbuf),
+ GST_PAD_CAPS (GST_BASE_SRC_PAD (psrc)));
+
+ gst_gl_display_lock (outbuf->display);
+
+ /* FIXME: This should be part of buffer creation */
+ glGenTextures (1, &outbuf->texture);
+ glBindTexture (GL_TEXTURE_RECTANGLE_ARB, outbuf->texture);
+ glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
+ outbuf->width, outbuf->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+
+ glGenFramebuffersEXT (1, &fbo);
+ glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo);
+
+ glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB, outbuf->texture, 0);
+
+ glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
+ glReadBuffer (GL_COLOR_ATTACHMENT0_EXT);
+
+ g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) ==
+ GL_FRAMEBUFFER_COMPLETE_EXT);
+
+ glViewport (0, 0, outbuf->width, outbuf->height);
+
+#if 0
+ glClearColor (0.3, 0.3, 0.3, 1.0);
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+#endif
+ if (src->pattern_type == GST_GL_TEST_SRC_BLINK) {
+ if (src->n_frames & 0x1) {
+ gst_gl_test_src_white (src, outbuf, src->width, src->height);
+ } else {
+ gst_gl_test_src_black (src, outbuf, src->width, src->height);
+ }
+ } else {
+ src->make_image (src, outbuf, src->width, src->height);
+ }
+
+ glFlush ();
+
+ glDeleteFramebuffersEXT (1, &fbo);
+
+ gst_gl_display_unlock (outbuf->display);
+
+ GST_BUFFER_TIMESTAMP (GST_BUFFER (outbuf)) =
+ src->timestamp_offset + src->running_time;
+ GST_BUFFER_OFFSET (GST_BUFFER (outbuf)) = src->n_frames;
+ src->n_frames++;
+ GST_BUFFER_OFFSET_END (GST_BUFFER (outbuf)) = src->n_frames;
+ if (src->rate_numerator) {
+ next_time = gst_util_uint64_scale_int (src->n_frames * GST_SECOND,
+ src->rate_denominator, src->rate_numerator);
+ GST_BUFFER_DURATION (GST_BUFFER (outbuf)) = next_time - src->running_time;
+ } else {
+ next_time = src->timestamp_offset;
+ /* NONE means forever */
+ GST_BUFFER_DURATION (GST_BUFFER (outbuf)) = GST_CLOCK_TIME_NONE;
+ }
+
+ src->running_time = next_time;
+
+ *buffer = GST_BUFFER (outbuf);
+
+ return GST_FLOW_OK;
+
+not_negotiated:
+ {
+ GST_ELEMENT_ERROR (src, CORE, NEGOTIATION, (NULL),
+ ("format wasn't negotiated before get function"));
+ return GST_FLOW_NOT_NEGOTIATED;
+ }
+eos:
+ {
+ GST_DEBUG_OBJECT (src, "eos: 0 framerate, frame %d", (gint) src->n_frames);
+ return GST_FLOW_UNEXPECTED;
+ }
+#if 0
+no_buffer:
+ {
+ GST_DEBUG_OBJECT (src, "could not allocate buffer, reason %s",
+ gst_flow_get_name (res));
+ return res;
+ }
+#endif
+}
+
+static gboolean
+gst_gl_test_src_start (GstBaseSrc * basesrc)
+{
+ GstGLTestSrc *src = GST_GL_TEST_SRC (basesrc);
+ gboolean ret;
+
+ src->running_time = 0;
+ src->n_frames = 0;
+ src->negotiated = FALSE;
+ src->display = gst_gl_display_new ();
+ ret = gst_gl_display_connect (src->display, NULL);
+
+ return ret;
+}
+
+static gboolean
+gst_gl_test_src_stop (GstBaseSrc * basesrc)
+{
+ GstGLTestSrc *src = GST_GL_TEST_SRC (basesrc);
+
+ g_object_unref (src->display);
+
+ return TRUE;
+}
diff --git a/gst/gl/gstgltestsrc.h b/gst/gl/gstgltestsrc.h
new file mode 100644
index 0000000..5d1f51b
--- /dev/null
+++ b/gst/gl/gstgltestsrc.h
@@ -0,0 +1,116 @@
+/* GStreamer
+ * Copyright (C) 2002,2007 David A. Schleef <ds@schleef.org>
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_GL_TEST_SRC_H__
+#define __GST_GL_TEST_SRC_H__
+
+#include <gst/gst.h>
+#include <gst/base/gstpushsrc.h>
+#include "gstglbuffer.h"
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_GL_TEST_SRC \
+ (gst_gl_test_src_get_type())
+#define GST_GL_TEST_SRC(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_TEST_SRC,GstGLTestSrc))
+#define GST_GL_TEST_SRC_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GL_TEST_SRC,GstGLTestSrcClass))
+#define GST_IS_GL_TEST_SRC(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_TEST_SRC))
+#define GST_IS_GL_TEST_SRC_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GL_TEST_SRC))
+
+/**
+ * GstGLTestSrcPattern:
+ * @GST_GL_TEST_SRC_SMPTE: A standard SMPTE test pattern
+ * @GST_GL_TEST_SRC_SNOW: Random noise
+ * @GST_GL_TEST_SRC_BLACK: A black image
+ * @GST_GL_TEST_SRC_WHITE: A white image
+ * @GST_GL_TEST_SRC_RED: A red image
+ * @GST_GL_TEST_SRC_GREEN: A green image
+ * @GST_GL_TEST_SRC_BLUE: A blue image
+ * @GST_GL_TEST_SRC_CHECKERS1: Checkers pattern (1px)
+ * @GST_GL_TEST_SRC_CHECKERS2: Checkers pattern (2px)
+ * @GST_GL_TEST_SRC_CHECKERS4: Checkers pattern (4px)
+ * @GST_GL_TEST_SRC_CHECKERS8: Checkers pattern (8px)
+ * @GST_GL_TEST_SRC_CIRCULAR: Circular pattern
+ * @GST_GL_TEST_SRC_BLINK: Alternate between black and white
+ *
+ * The test pattern to produce.
+ */
+typedef enum {
+ GST_GL_TEST_SRC_SMPTE,
+ GST_GL_TEST_SRC_SNOW,
+ GST_GL_TEST_SRC_BLACK,
+ GST_GL_TEST_SRC_WHITE,
+ GST_GL_TEST_SRC_RED,
+ GST_GL_TEST_SRC_GREEN,
+ GST_GL_TEST_SRC_BLUE,
+ GST_GL_TEST_SRC_CHECKERS1,
+ GST_GL_TEST_SRC_CHECKERS2,
+ GST_GL_TEST_SRC_CHECKERS4,
+ GST_GL_TEST_SRC_CHECKERS8,
+ GST_GL_TEST_SRC_CIRCULAR,
+ GST_GL_TEST_SRC_BLINK
+} GstGLTestSrcPattern;
+
+typedef struct _GstGLTestSrc GstGLTestSrc;
+typedef struct _GstGLTestSrcClass GstGLTestSrcClass;
+
+/**
+ * GstGLTestSrc:
+ *
+ * Opaque data structure.
+ */
+struct _GstGLTestSrc {
+ GstPushSrc element;
+
+ /*< private >*/
+
+ /* type of output */
+ GstGLTestSrcPattern pattern_type;
+
+ /* video state */
+ char *format_name;
+ gint width;
+ gint height;
+ gint rate_numerator;
+ gint rate_denominator;
+
+ /* private */
+ GstGLDisplay *display;
+ gint64 timestamp_offset; /* base offset */
+ GstClockTime running_time; /* total running time */
+ gint64 n_frames; /* total frames sent */
+ gboolean negotiated;
+
+ void (*make_image) (GstGLTestSrc *v, GstGLBuffer *buffer, int w, int h);
+};
+
+struct _GstGLTestSrcClass {
+ GstPushSrcClass parent_class;
+};
+
+GType gst_gl_test_src_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_GL_TEST_SRC_H__ */
diff --git a/gst/gl/gstglupload.c b/gst/gl/gstglupload.c
index 5f9ffa7..90f7dc2 100644
--- a/gst/gl/gstglupload.c
+++ b/gst/gl/gstglupload.c
@@ -179,7 +179,7 @@ gst_gl_upload_reset (GstGLUpload * upload)
upload->display = NULL;
}
upload->format = GST_VIDEO_FORMAT_RGBx;
- upload->peek = TRUE;
+ upload->peek = FALSE;
}
static gboolean
diff --git a/gst/gl/gstopengl.c b/gst/gl/gstopengl.c
index 4889e0a..d44ed9f 100644
--- a/gst/gl/gstopengl.c
+++ b/gst/gl/gstopengl.c
@@ -35,6 +35,7 @@
GType gst_gl_upload_get_type (void);
GType gst_gl_download_get_type (void);
GType gst_gl_filter_get_type (void);
+GType gst_gl_test_src_get_type (void);
static gboolean
@@ -59,6 +60,10 @@ plugin_init (GstPlugin * plugin)
GST_RANK_NONE, gst_gl_filter_get_type ())) {
return FALSE;
}
+ if (!gst_element_register (plugin, "gltestsrc",
+ GST_RANK_NONE, gst_gl_test_src_get_type ())) {
+ return FALSE;
+ }
return TRUE;
}