Remove glimagesink, as it's been moved to gst-plugins-gl.

Original commit message from CVS:
* configure.ac:
* docs/plugins/Makefile.am:
* docs/plugins/gst-plugins-bad-plugins-docs.sgml:
* docs/plugins/inspect/plugin-glimagesink.xml:
* sys/Makefile.am:
* sys/glsink/BUGS:
* sys/glsink/Makefile.am:
* sys/glsink/color_matrix.c:
* sys/glsink/glextensions.c:
* sys/glsink/glextensions.h:
* sys/glsink/glimagesink.c:
* sys/glsink/glimagesink.h:
* sys/glsink/gltestsrc.c:
* sys/glsink/gltestsrc.h:
* sys/glsink/gstglbuffer.c:
* sys/glsink/gstglbuffer.h:
* sys/glsink/gstglconvert.c:
* sys/glsink/gstgldisplay.c:
* sys/glsink/gstgldisplay.h:
* sys/glsink/gstgldownload.c:
* sys/glsink/gstglfilter.c:
* sys/glsink/gstglfilter.h:
* sys/glsink/gstglfilterexample.c:
* sys/glsink/gstgltestsrc.c:
* sys/glsink/gstgltestsrc.h:
* sys/glsink/gstglupload.c:
* sys/glsink/gstopengl.c:
Remove glimagesink, as it's been moved to gst-plugins-gl.
Fixes #516094.
This commit is contained in:
David Schleef 2008-02-12 21:01:17 +00:00
parent fe7d133879
commit 1a74d7922a
28 changed files with 35 additions and 5796 deletions

View File

@ -1,3 +1,35 @@
2008-02-12 David Schleef <ds@schleef.org>
* configure.ac:
* docs/plugins/Makefile.am:
* docs/plugins/gst-plugins-bad-plugins-docs.sgml:
* docs/plugins/inspect/plugin-glimagesink.xml:
* sys/Makefile.am:
* sys/glsink/BUGS:
* sys/glsink/Makefile.am:
* sys/glsink/color_matrix.c:
* sys/glsink/glextensions.c:
* sys/glsink/glextensions.h:
* sys/glsink/glimagesink.c:
* sys/glsink/glimagesink.h:
* sys/glsink/gltestsrc.c:
* sys/glsink/gltestsrc.h:
* sys/glsink/gstglbuffer.c:
* sys/glsink/gstglbuffer.h:
* sys/glsink/gstglconvert.c:
* sys/glsink/gstgldisplay.c:
* sys/glsink/gstgldisplay.h:
* sys/glsink/gstgldownload.c:
* sys/glsink/gstglfilter.c:
* sys/glsink/gstglfilter.h:
* sys/glsink/gstglfilterexample.c:
* sys/glsink/gstgltestsrc.c:
* sys/glsink/gstgltestsrc.h:
* sys/glsink/gstglupload.c:
* sys/glsink/gstopengl.c:
Remove glimagesink, as it's been moved to gst-plugins-gl.
Fixes #516094.
2008-02-12 Wim Taymans <wim.taymans@collabora.co.uk> 2008-02-12 Wim Taymans <wim.taymans@collabora.co.uk>
Patch by: Josep Torra Valles <josep@fluendo.com> Patch by: Josep Torra Valles <josep@fluendo.com>

View File

@ -289,19 +289,6 @@ AC_SUBST(GST_PLUGINS_SELECTED)
dnl *** sys plug-ins *** dnl *** sys plug-ins ***
dnl OpenGL
translit(dnm, m, l) AM_CONDITIONAL(USE_OPENGL, true)
AG_GST_CHECK_FEATURE(OPENGL, [Open GL], glsink, [
PKG_CHECK_MODULES(GL, gl >= 7.1.0, [
HAVE_OPENGL="yes"
AC_SUBST(GL_CFLAGS)
AC_SUBST(GL_LIBS)
],[
HAVE_OPENGL=no
AC_MSG_RESULT(no)
])
])
dnl check for QuickTime dnl check for QuickTime
translit(dnm, m, l) AM_CONDITIONAL(USE_QUICKTIME, true) translit(dnm, m, l) AM_CONDITIONAL(USE_QUICKTIME, true)
AG_GST_CHECK_FEATURE(QUICKTIME, [QuickTime wrapper], qtwrapper, [ AG_GST_CHECK_FEATURE(QUICKTIME, [QuickTime wrapper], qtwrapper, [
@ -943,7 +930,6 @@ else
dnl not building plugins with external dependencies, dnl not building plugins with external dependencies,
dnl but we still need to set the conditionals dnl but we still need to set the conditionals
AM_CONDITIONAL(USE_OPENGL, false)
AM_CONDITIONAL(USE_QUICKTIME, false) AM_CONDITIONAL(USE_QUICKTIME, false)
AM_CONDITIONAL(USE_VCD, false) AM_CONDITIONAL(USE_VCD, false)
AM_CONDITIONAL(USE_ALSA, false) AM_CONDITIONAL(USE_ALSA, false)
@ -1075,7 +1061,6 @@ gst-libs/gst/Makefile
gst-libs/gst/app/Makefile gst-libs/gst/app/Makefile
sys/Makefile sys/Makefile
sys/fbdev/Makefile sys/fbdev/Makefile
sys/glsink/Makefile
sys/dvb/Makefile sys/dvb/Makefile
sys/qtwrapper/Makefile sys/qtwrapper/Makefile
sys/vcd/Makefile sys/vcd/Makefile

View File

@ -135,8 +135,7 @@ EXTRA_HFILES = \
$(top_srcdir)/gst/videosignal/gstvideoanalyse.h \ $(top_srcdir)/gst/videosignal/gstvideoanalyse.h \
$(top_srcdir)/gst/videosignal/gstvideodetect.h \ $(top_srcdir)/gst/videosignal/gstvideodetect.h \
$(top_srcdir)/gst/videosignal/gstvideomark.h \ $(top_srcdir)/gst/videosignal/gstvideomark.h \
$(top_srcdir)/sys/dvb/gstdvbsrc.h \ $(top_srcdir)/sys/dvb/gstdvbsrc.h
$(top_srcdir)/sys/glsink/gstgltestsrc.h
# Images to copy into HTML directory. # Images to copy into HTML directory.
HTML_IMAGES = HTML_IMAGES =

View File

@ -77,7 +77,6 @@
<xi:include href="xml/plugin-flvdemux.xml" /> <xi:include href="xml/plugin-flvdemux.xml" />
<xi:include href="xml/plugin-freeze.xml" /> <xi:include href="xml/plugin-freeze.xml" />
<xi:include href="xml/plugin-gdp.xml" /> <xi:include href="xml/plugin-gdp.xml" />
<xi:include href="xml/plugin-glimagesink.xml" />
<xi:include href="xml/plugin-gsm.xml" /> <xi:include href="xml/plugin-gsm.xml" />
<xi:include href="xml/plugin-gstinterlace.xml" /> <xi:include href="xml/plugin-gstinterlace.xml" />
<xi:include href="xml/plugin-gstrtpmanager.xml" /> <xi:include href="xml/plugin-gstrtpmanager.xml" />

View File

@ -1,127 +0,0 @@
<plugin>
<name>glimagesink</name>
<description>OpenGL video output plugin</description>
<filename>../../sys/glsink/.libs/libgstglimagesink.so</filename>
<basename>libgstglimagesink.so</basename>
<version>0.10.5.1</version>
<license>LGPL</license>
<source>gst-plugins-bad</source>
<package>GStreamer Bad Plug-ins CVS/prerelease</package>
<origin>Unknown package origin</origin>
<elements>
<element>
<name>glconvert</name>
<longname>FIXME</longname>
<class>Filter/Effect</class>
<description>FIXME GL conversion filter</description>
<author>FIXME &lt;fixme@fixme.com&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>video/x-raw-gl, format=(int)1, is_yuv=(boolean)false, width=(int)[ 1, 2048 ], height=(int)[ 1, 2048 ], pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)[ 0/1, 100/1 ]</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>video/x-raw-gl, format=(int)1, is_yuv=(boolean)false, width=(int)[ 1, 2048 ], height=(int)[ 1, 2048 ], pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)[ 0/1, 100/1 ]</details>
</caps>
</pads>
</element>
<element>
<name>gldownload</name>
<longname>FIXME</longname>
<class>Filter/Effect</class>
<description>FIXME example filter</description>
<author>FIXME &lt;fixme@fixme.com&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>video/x-raw-gl, format=(int)1, is_yuv=(boolean)false, width=(int)[ 1, 2048 ], height=(int)[ 1, 2048 ], pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)[ 0/1, 100/1 ]</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)16711680, green_mask=(int)65280, blue_mask=(int)255, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)-16777216, green_mask=(int)16711680, blue_mask=(int)65280, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
</caps>
</pads>
</element>
<element>
<name>glfilterexample</name>
<longname>FIXME</longname>
<class>Filter/Effect</class>
<description>FIXME example filter</description>
<author>FIXME &lt;fixme@fixme.com&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>video/x-raw-gl, format=(int)1, is_yuv=(boolean)false, width=(int)[ 1, 2048 ], height=(int)[ 1, 2048 ], pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)[ 0/1, 100/1 ]</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>video/x-raw-gl, format=(int)1, is_yuv=(boolean)false, width=(int)[ 1, 2048 ], height=(int)[ 1, 2048 ], pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)[ 0/1, 100/1 ]</details>
</caps>
</pads>
</element>
<element>
<name>glimagesink</name>
<longname>OpenGL video sink</longname>
<class>Sink/Video</class>
<description>A videosink based on OpenGL</description>
<author>David Schleef &lt;ds@schleef.org&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>video/x-raw-gl, format=(int)1, is_yuv=(boolean)false, width=(int)[ 1, 2048 ], height=(int)[ 1, 2048 ], pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)[ 0/1, 100/1 ]</details>
</caps>
</pads>
</element>
<element>
<name>gltestsrc</name>
<longname>Video test source</longname>
<class>Source/Video</class>
<description>Creates a test video stream</description>
<author>David A. Schleef &lt;ds@schleef.org&gt;</author>
<pads>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>video/x-raw-gl, format=(int)1, is_yuv=(boolean)false, width=(int)[ 1, 2048 ], height=(int)[ 1, 2048 ], pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)[ 0/1, 100/1 ]</details>
</caps>
</pads>
</element>
<element>
<name>glupload</name>
<longname>FIXME</longname>
<class>Filter/Effect</class>
<description>FIXME example filter</description>
<author>FIXME &lt;fixme@fixme.com&gt;</author>
<pads>
<caps>
<name>sink</name>
<direction>sink</direction>
<presence>always</presence>
<details>video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)-16777216, green_mask=(int)16711680, blue_mask=(int)65280, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)65280, green_mask=(int)16711680, blue_mask=(int)-16777216, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)16711680, green_mask=(int)65280, blue_mask=(int)255, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-rgb, bpp=(int)32, depth=(int)24, endianness=(int)4321, red_mask=(int)255, green_mask=(int)65280, blue_mask=(int)16711680, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]; video/x-raw-yuv, format=(fourcc){ YUY2, UYVY, AYUV, YV12, I420 }, width=(int)[ 1, 2147483647 ], height=(int)[ 1, 2147483647 ], framerate=(fraction)[ 0/1, 2147483647/1 ]</details>
</caps>
<caps>
<name>src</name>
<direction>source</direction>
<presence>always</presence>
<details>video/x-raw-gl, format=(int)1, is_yuv=(boolean)false, width=(int)[ 1, 2048 ], height=(int)[ 1, 2048 ], pixel-aspect-ratio=(fraction)1/1, framerate=(fraction)[ 0/1, 100/1 ]</details>
</caps>
</pads>
</element>
</elements>
</plugin>

View File

@ -28,12 +28,6 @@ else
FBDEV_DIR= FBDEV_DIR=
endif endif
if USE_OPENGL
GL_DIR=glsink
else
GL_DIR=
endif
if USE_DVB if USE_DVB
DVB_DIR=dvb DVB_DIR=dvb
else else
@ -46,6 +40,6 @@ else
QT_DIR= QT_DIR=
endif endif
SUBDIRS = $(FBDEV_DIR) $(GL_DIR) $(DVB_DIR) $(VCD_DIR) $(QT_DIR) SUBDIRS = $(FBDEV_DIR) $(DVB_DIR) $(VCD_DIR) $(QT_DIR)
DIST_SUBDIRS = fbdev glsink dvb vcd qtwrapper DIST_SUBDIRS = fbdev dvb vcd qtwrapper

View File

@ -1,19 +0,0 @@
known issues:
- negotiation is shite. I don't want to know about any failed
negotiations or failed prerolls.
- teardown sometimes fails.
- sharing a GL context among a bunch of elements that stomp all
over it is potential fail.
intel driver:
- rendering to texture ignores the color matrix. This causes any
YUV->RGB conversion to fail.
- YUY2 and UYVY conversions in the driver use the wrong matrix.

View File

@ -1,36 +0,0 @@
plugin_LTLIBRARIES = libgstglimagesink.la
noinst_PROGRAMS = color_matrix
AM_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS)
AM_LIBS = $(GST_BASE_LIBS)
libgstglimagesink_la_SOURCES = \
glimagesink.c \
gstgldisplay.c \
gstopengl.c \
glextensions.c \
gstglbuffer.c \
gstglupload.c \
gstgldownload.c \
gstgltestsrc.c \
gltestsrc.c \
gstglfilter.c \
gstglfilterexample.c \
gstglconvert.c
libgstglimagesink_la_CFLAGS = $(GST_CFLAGS) $(X_CFLAGS) $(GST_BASE_CFLAGS) \
$(GST_PLUGINS_BASE_CFLAGS) $(GL_CFLAGS)
libgstglimagesink_la_LIBADD = $(GL_LIBS) \
$(GST_BASE_LIBS) -lgstvideo-$(GST_MAJORMINOR) \
$(GST_PLUGINS_BASE_LIBS) -lgstinterfaces-$(GST_MAJORMINOR)
libgstglimagesink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
noinst_HEADERS = \
glimagesink.h \
gstgldisplay.h \
glextensions.h \
gstgltestsrc.h \
gltestsrc.h \
gstglbuffer.h \
gstglfilter.h

View File

@ -1,243 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <string.h>
typedef struct
{
double comp[3];
} Color;
typedef struct
{
Color pre_offset;
double matrix[3][3];
Color post_offset;
} ColorMatrix;
/* convert uint8 RGB values to float */
ColorMatrix rgb255_to_rgb = {
{{0, 0, 0}},
{{(1 / 255.0), 0, 0},
{0, (1 / 255.0), 0},
{0, 0, (1 / 255.0)}},
{{0, 0, 0}}
};
ColorMatrix rgb_to_rgb255;
/* convert uint8 YUV values to float as per ITU-R.601
* technically, Y, Cr, Cb to E_Y, E_C_B, E_C_R */
ColorMatrix ycbcr601_to_yuv = {
{{-16, -128, -128}},
{{(1 / 219.0), 0, 0},
{0, (1 / 224.0), 0},
{0, 0, (1 / 224.0)}},
{{0, 0, 0}}
};
ColorMatrix yuv_to_ycbcr601;
/* convert RGB to YUV as per ITU-R.601
* technically, E_R, E_G, E_B to E_Y, E_C_B, E_C_R */
ColorMatrix rgb_to_yuv = {
{{0, 0, 0}},
{{0.299, 0.587, 0.114},
{0.500, -0.419, -0.081},
{-0.169, -0.331, 0.500}},
{{0, 0, 0}}
};
ColorMatrix yuv_to_rgb;
ColorMatrix compress = {
{{0, 0, 0}},
{{0.50, 0, 0},
{0, 0.5, 0},
{0, 0, 0.500}},
{{0.25, 0.25, 0.25}}
};
/* red mask */
ColorMatrix red_mask = {
{{0, 0, 0}},
{{1, 1, 1},
{0, 0, 0},
{0, 0, 0}},
{{0, 0, 0}}
};
double colors[][3] = {
{0, 0, 0},
{255, 0, 0},
{0, 255, 0},
{0, 0, 255}
};
void
color_dump (const double *a)
{
printf (" %g, %g, %g\n", a[0], a[1], a[2]);
}
void
color_matrix_dump (ColorMatrix * m)
{
printf ("pre: %g, %g, %g\n",
m->pre_offset.comp[0], m->pre_offset.comp[1], m->pre_offset.comp[2]);
printf (" %g, %g, %g\n", m->matrix[0][0], m->matrix[0][1], m->matrix[0][2]);
printf (" %g, %g, %g\n", m->matrix[1][0], m->matrix[1][1], m->matrix[1][2]);
printf (" %g, %g, %g\n", m->matrix[2][0], m->matrix[2][1], m->matrix[2][2]);
printf ("post: %g, %g, %g\n",
m->post_offset.comp[0], m->post_offset.comp[1], m->post_offset.comp[2]);
}
void
color_matrix_apply_color (Color * a, const ColorMatrix * b)
{
Color d;
int i;
a->comp[0] += b->pre_offset.comp[0];
a->comp[1] += b->pre_offset.comp[1];
a->comp[2] += b->pre_offset.comp[2];
for (i = 0; i < 3; i++) {
d.comp[i] = a->comp[0] * b->matrix[i][0];
d.comp[i] += a->comp[1] * b->matrix[i][1];
d.comp[i] += a->comp[2] * b->matrix[i][2];
}
d.comp[0] += b->post_offset.comp[0];
d.comp[1] += b->post_offset.comp[1];
d.comp[2] += b->post_offset.comp[2];
*a = d;
}
void
color_matrix_init (ColorMatrix * a)
{
memset (a, 0, sizeof (*a));
a->matrix[0][0] = 1.0;
a->matrix[1][1] = 1.0;
a->matrix[2][2] = 1.0;
}
void
color_matrix_apply (ColorMatrix * a, ColorMatrix * b)
{
ColorMatrix d;
int i, j;
d.pre_offset = a->pre_offset;
d.post_offset = a->post_offset;
color_matrix_apply_color (&d.post_offset, b);
for (j = 0; j < 3; j++) {
for (i = 0; i < 3; i++) {
d.matrix[i][j] =
a->matrix[i][0] * b->matrix[0][j] +
a->matrix[i][1] * b->matrix[1][j] + a->matrix[i][2] * b->matrix[2][j];
}
}
*a = d;
}
void
color_matrix_invert (ColorMatrix * a, ColorMatrix * b)
{
int i, j;
double det;
a->post_offset.comp[0] = -b->pre_offset.comp[0];
a->post_offset.comp[1] = -b->pre_offset.comp[1];
a->post_offset.comp[2] = -b->pre_offset.comp[2];
for (j = 0; j < 3; j++) {
for (i = 0; i < 3; i++) {
a->matrix[j][i] =
b->matrix[(i + 1) % 3][(j + 1) % 3] * b->matrix[(i + 2) % 3][(j +
2) % 3] - b->matrix[(i + 1) % 3][(j + 2) % 3] * b->matrix[(i +
2) % 3][(j + 1) % 3];
}
}
det = a->matrix[0][0] * b->matrix[0][0];
det += a->matrix[0][1] * b->matrix[1][0];
det += a->matrix[0][2] * b->matrix[2][0];
for (j = 0; j < 3; j++) {
for (i = 0; i < 3; i++) {
a->matrix[j][i] /= det;
}
}
a->pre_offset.comp[0] = -b->post_offset.comp[0];
a->pre_offset.comp[1] = -b->post_offset.comp[1];
a->pre_offset.comp[2] = -b->post_offset.comp[2];
}
void
init (void)
{
color_matrix_invert (&yuv_to_rgb, &rgb_to_yuv);
color_matrix_invert (&yuv_to_ycbcr601, &ycbcr601_to_yuv);
color_matrix_invert (&rgb_to_rgb255, &rgb255_to_rgb);
#if 0
color_matrix_dump (&yuv_to_rgb);
color_matrix_dump (&yuv_to_ycbcr601);
color_matrix_dump (&rgb_to_rgb255);
#endif
}
int
main (int argc, char *argv[])
{
ColorMatrix want;
ColorMatrix actual;
ColorMatrix actual_inv;
ColorMatrix a;
init ();
#if 0
int i;
for (i = 0; i < 4; i++) {
double color[3];
printf ("%d:\n", i);
color_copy (color, colors[i]);
color_matrix_apply_color (color, &rgb255_to_rgb);
color_matrix_apply_color (color, &rgb_to_yuv);
color_dump (color);
}
#endif
color_matrix_init (&want);
color_matrix_apply (&want, &ycbcr601_to_yuv);
color_matrix_apply (&want, &yuv_to_rgb);
color_matrix_apply (&want, &compress);
color_matrix_apply (&want, &compress);
//color_matrix_apply (&want, &compress);
color_matrix_init (&actual);
color_matrix_apply (&actual, &rgb255_to_rgb);
/* calc X such that actual * X = want */
color_matrix_invert (&actual_inv, &actual);
a = actual_inv;
color_matrix_apply (&a, &want);
color_matrix_dump (&a);
return 0;
}

View File

@ -1,190 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <GL/glx.h>
#include <GL/glxext.h>
#include <string.h>
#include <glib.h>
#include "glextensions.h"
int
gl_have_extension (const char *name)
{
const char *s;
s = (const char *) glGetString (GL_EXTENSIONS);
if (s == NULL)
return FALSE;
if (strstr (s, name))
return TRUE;
return FALSE;
}
extern __GLXextFuncPtr glXGetProcAddressARB (const GLubyte *);
#define DEFINE_FUNC_RET(name,return_type,prototype,args) \
return_type name prototype \
{ \
static return_type (*func) prototype; \
if (func == NULL) { \
func = (void *) glXGetProcAddressARB ((unsigned char *) #name); \
} \
return func args; \
}
#define DEFINE_FUNC(name,prototype,args) \
void name prototype \
{ \
static void (*func) prototype; \
if (func == NULL) { \
func = (void *) glXGetProcAddressARB ((unsigned char *) #name); \
} \
func args; \
}
DEFINE_FUNC_RET (glCreateShaderObjectARB, GLhandleARB,
(GLenum shaderType), (shaderType));
#if 0
typedef GLhandleARB type_glCreateShaderObjectARB (GLenum shaderType);
GLhandleARB
glCreateShaderObjectARB (GLenum shaderType)
{
type_glCreateShaderObjectARB *func;
if (func == NULL) {
func = (type_glCreateShaderObjectARB *)
glXGetProcAddress ((unsigned char *) "glCreateShaderObjectARB");
}
return (*func) (shaderType);
}
#endif
DEFINE_FUNC (glShaderSourceARB,
(GLhandleARB shaderObj, GLsizei count, const GLcharARB ** string,
const GLint * length), (shaderObj, count, string, length));
DEFINE_FUNC (glUniform2fARB,
(GLint location, GLfloat val1, GLfloat val2), (location, val1, val2));
DEFINE_FUNC_RET (glGetUniformLocationARB, GLint,
(GLhandleARB programObj, const GLcharARB * name), (programObj, name));
DEFINE_FUNC (glUniform1iARB, (GLint location, GLint val), (location, val));
DEFINE_FUNC (glGetObjectParameterivARB, (GLhandleARB object, GLenum pname,
GLint * params), (object, pname, params));
DEFINE_FUNC (glCompileShaderARB, (GLhandleARB shader), (shader));
DEFINE_FUNC (glGetInfoLogARB, (GLhandleARB object, GLsizei maxLength,
GLsizei * length, GLcharARB * infoLog), (object, maxLength, length,
infoLog));
DEFINE_FUNC_RET (glCreateProgramObjectARB, GLhandleARB, (void), ());
DEFINE_FUNC (glAttachObjectARB, (GLhandleARB program, GLhandleARB shader),
(program, shader));
DEFINE_FUNC (glLinkProgramARB, (GLhandleARB program), (program));
DEFINE_FUNC (glUseProgramObjectARB, (GLhandleARB program), (program));
DEFINE_FUNC (glPixelDataRangeNV, (GLenum target, GLsizei length, void *pointer),
(target, length, pointer));
DEFINE_FUNC_RET (glXGetSyncValuesOML, Bool,
(Display * display, GLXDrawable drawable, int64_t * ust, int64_t * msc,
int64_t * sbc), (display, drawable, ust, msc, sbc));
DEFINE_FUNC_RET (glXGetMscRateOML, Bool,
(Display * display, GLXDrawable drawable, int32_t * numerator,
int32_t * denominator), (display, drawable, numerator, denominator));
DEFINE_FUNC_RET (glXSwapBuffersMscOML, int64_t,
(Display * display, GLXDrawable drawable, int64_t target_msc,
int64_t divisor, int64_t remainder), (display, drawable, target_msc,
divisor, remainder));
DEFINE_FUNC_RET (glXWaitForMscOML, Bool,
(Display * display, GLXDrawable drawable, int64_t target_msc,
int64_t divisor, int64_t remainder, int64_t * ust, int64_t * msc,
int64_t * sbc), (display, drawable, target_msc, divisor, remainder, ust,
msc, sbc));
DEFINE_FUNC_RET (glXWaitForSbcOML, Bool,
(Display * display, GLXDrawable drawable, int64_t target_sbc, int64_t * ust,
int64_t * msc, int64_t * sbc), (display, drawable, target_sbc, ust, msc,
sbc));
DEFINE_FUNC_RET (glXSwapIntervalSGI, int, (int interval), (interval));
DEFINE_FUNC_RET (glXSwapIntervalMESA, int, (unsigned int interval), (interval));
#if 0
DEFINE_FUNC (glBindFramebufferEXT, (int target, uint framebuffer),
(target, framebuffer));
DEFINE_FUNC (glDeleteRenderbuffersEXT, (int n, unsigned int *renderbuffers),
(n, renderbuffers));
DEFINE_FUNC (glGenRenderbuffersEXT, (int n, unsigned int *renderbuffers),
(n, renderbuffers));
DEFINE_FUNC (glRenderbufferStorageEXT, (int target, int internalformat,
int width, int height), (target, internalformat, width, height));
DEFINE_FUNC (glBindRenderbufferEXT, (int target, unsigned int renderbuffer),
(target, renderbuffer));
DEFINE_FUNC (glFramebufferRenderbufferEXT,
(int target, int attachment, int renderbuffertarget,
unsigned int renderbuffer), (target, attachment, renderbuffertarget,
renderbuffer));
#endif
/* EXT_framebuffer_object */
DEFINE_FUNC_RET (glIsRenderbufferEXT, Bool,
(GLuint renderbuffer), (renderbuffer));
DEFINE_FUNC (glBindRenderbufferEXT,
(GLenum target, GLuint renderbuffer), (target, renderbuffer));
DEFINE_FUNC (glDeleteRenderbuffersEXT,
(GLsizei n, GLuint * renderbuffers), (n, renderbuffers));
DEFINE_FUNC (glGenRenderbuffersEXT,
(GLsizei n, GLuint * renderbuffers), (n, renderbuffers));
DEFINE_FUNC (glRenderbufferStorageEXT,
(GLenum target, GLenum internalformat, GLsizei width, GLsizei height),
(target, internalformat, width, height));
DEFINE_FUNC (glGetRenderbufferParameterivEXT,
(GLenum target, GLenum pname, GLint * params), (target, pname, params));
DEFINE_FUNC_RET (glIsFramebufferEXT, Bool, (GLuint framebuffer), (framebuffer));
DEFINE_FUNC (glBindFramebufferEXT,
(GLenum target, GLuint framebuffer), (target, framebuffer));
DEFINE_FUNC (glDeleteFramebuffersEXT,
(GLsizei n, GLuint * framebuffers), (n, framebuffers));
DEFINE_FUNC (glGenFramebuffersEXT,
(GLsizei n, GLuint * framebuffers), (n, framebuffers));
DEFINE_FUNC_RET (glCheckFramebufferStatusEXT, GLenum,
(GLenum target), (target));
DEFINE_FUNC (glFramebufferTexture1DEXT,
(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
GLint level), (target, attachment, textarget, texture, level));
DEFINE_FUNC (glFramebufferTexture2DEXT, (GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level), (target, attachment,
textarget, texture, level));
DEFINE_FUNC (glFramebufferTexture3DEXT, (GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level, GLint zoffset), (target,
attachment, textarget, texture, level, zoffset));
DEFINE_FUNC (glFramebufferRenderbufferEXT, (GLenum target, GLenum attachment,
GLenum renderbuffertarget, GLuint renderbuffer), (target, attachment,
renderbuffertarget, renderbuffer));
DEFINE_FUNC (glGetFramebufferAttachmentParameterivEXT, (GLenum target,
GLenum pname, GLint * params), (target, pname, params));
DEFINE_FUNC (glGenerateMipmapEXT, (GLenum target), (target));
DEFINE_FUNC (glWindowPos2iARB, (GLint x, GLint y), (x, y));
DEFINE_FUNC (glGenProgramsARB, (GLsizei a, GLuint * b), (a, b));
DEFINE_FUNC (glBindProgramARB, (GLenum a, GLuint b), (a, b));
DEFINE_FUNC (glProgramStringARB,
(GLenum a, GLenum b, GLsizei c, const GLvoid * d), (a, b, c, d));

View File

@ -1,64 +0,0 @@
#ifndef __GST_GLEXTENSIONS_H__
#define __GST_GLEXTENSIONS_H__
#include <GL/gl.h>
//#include <glib.h>
int gl_have_extension (const char *name);
GLhandleARB glCreateShaderObjectARB (GLenum shaderType);
void glShaderSourceARB (GLhandleARB shaderObj, GLsizei count, const GLcharARB ** string, const GLint *length);
void glUniform2fARB (GLint location, GLfloat val1, GLfloat val2);
GLint glGetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name);
void glUniform1iARB (GLint location, GLint val);
void glCompileShaderARB (GLhandleARB shader);
void glGetObjectParameterivARB (GLhandleARB object, GLenum pname, GLint *params);
void glGetInfoLogARB (GLhandleARB object, GLsizei maxLength, GLsizei *length,
GLcharARB *infoLog);
GLhandleARB glCreateProgramObjectARB (void);
void glAttachObjectARB (GLhandleARB program, GLhandleARB shader);
void glLinkProgramARB (GLhandleARB program);
void glUseProgramObjectARB (GLhandleARB program);
void glPixelDataRangeNV(GLenum target, GLsizei length, void *pointer);
void glActiveTexture(GLenum target);
Bool glXGetSyncValuesOML (Display *, GLXDrawable, int64_t *, int64_t *, int64_t *);
Bool glXGetMscRateOML (Display *, GLXDrawable, int32_t *, int32_t *);
int64_t glXSwapBuffersMscOML (Display *, GLXDrawable, int64_t, int64_t, int64_t);
Bool glXWaitForMscOML (Display *, GLXDrawable, int64_t, int64_t, int64_t, int64_t *, int64_t *, int64_t *);
Bool glXWaitForSbcOML (Display *, GLXDrawable, int64_t, int64_t *, int64_t *, int64_t *);
int glXSwapIntervalSGI (int);
int glXSwapIntervalMESA (unsigned int);
/* EXT_framebuffer_object */
Bool glIsRenderbufferEXT (GLuint renderbuffer);
void glBindRenderbufferEXT (GLenum target, GLuint renderbuffer);
void glDeleteRenderbuffersEXT (GLsizei n, GLuint *renderbuffers);
void glGenRenderbuffersEXT (GLsizei n, GLuint *renderbuffers);
void glRenderbufferStorageEXT (GLenum target, GLenum internalformat,
GLsizei width, GLsizei height);
void glGetRenderbufferParameterivEXT (GLenum target, GLenum pname, GLint *params);
Bool glIsFramebufferEXT (GLuint framebuffer);
void glBindFramebufferEXT (GLenum target, GLuint framebuffer);
void glDeleteFramebuffersEXT (GLsizei n, GLuint *framebuffers);
void glGenFramebuffersEXT (GLsizei n, GLuint *framebuffers);
GLenum glCheckFramebufferStatusEXT (GLenum target);
void glFramebufferTexture1DEXT (GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level);
void glFramebufferTexture2DEXT (GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level);
void glFramebufferTexture3DEXT (GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level, GLint zoffset);
void glFramebufferRenderbufferEXT (GLenum target, GLenum attachment,
GLenum renderbuffertarget, GLuint renderbuffer);
void glGetFramebufferAttachmentParameterivEXT (GLenum target, GLenum pname,
GLint *params);
void glGenerateMipmapEXT (GLenum target);
void glWindowPos2iARB (GLint x, GLint y);
void glGenProgramsARB (GLsizei, GLuint *);
void glBindProgramARB (GLenum, GLuint);
void glProgramStringARB (GLenum, GLenum, GLsizei, const GLvoid *);
#endif

View File

@ -1,557 +0,0 @@
/* GStreamer
* Copyright (C) 2003 Julien Moutte <julien@moutte.net>
* Copyright (C) 2005,2006,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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include <gst/interfaces/xoverlay.h>
#include <gst/video/gstvideosink.h>
#include <gst/video/video.h>
#include "gstglbuffer.h"
#include <string.h>
#include <glimagesink.h>
GST_DEBUG_CATEGORY (gst_debug_glimage_sink);
#define GST_CAT_DEFAULT gst_debug_glimage_sink
static void gst_glimage_sink_init_interfaces (GType type);
static void gst_glimage_sink_finalize (GObject * object);
static void gst_glimage_sink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * param_spec);
static void gst_glimage_sink_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * param_spec);
static GstStateChangeReturn
gst_glimage_sink_change_state (GstElement * element, GstStateChange transition);
static void gst_glimage_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
GstClockTime * start, GstClockTime * end);
static GstCaps *gst_glimage_sink_get_caps (GstBaseSink * bsink);
static gboolean gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
static GstFlowReturn gst_glimage_sink_render (GstBaseSink * bsink,
GstBuffer * buf);
static gboolean gst_glimage_sink_start (GstBaseSink * bsink);
static gboolean gst_glimage_sink_stop (GstBaseSink * bsink);
static gboolean gst_glimage_sink_unlock (GstBaseSink * bsink);
static void gst_glimage_sink_xoverlay_init (GstXOverlayClass * iface);
static void gst_glimage_sink_set_xwindow_id (GstXOverlay * overlay,
XID window_id);
static void gst_glimage_sink_expose (GstXOverlay * overlay);
static void gst_glimage_sink_set_event_handling (GstXOverlay * overlay,
gboolean handle_events);
static gboolean gst_glimage_sink_interface_supported (GstImplementsInterface *
iface, GType type);
static void gst_glimage_sink_implements_init (GstImplementsInterfaceClass *
klass);
//static void gst_glimage_sink_update_caps (GstGLImageSink * glimage_sink);
static const GstElementDetails gst_glimage_sink_details =
GST_ELEMENT_DETAILS ("OpenGL video sink",
"Sink/Video",
"A videosink based on OpenGL",
"David Schleef <ds@schleef.org>");
#ifdef GL_YCBCR_MESA
#define YUV_CAPS ";" GST_VIDEO_CAPS_YUV ("{ AYUV, UYVY, YUY2 }")
#else
#define YUV_CAPS
#endif
static GstStaticPadTemplate gst_glimage_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_GL_VIDEO_CAPS ";"
GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";"
GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_xBGR ";"
GST_VIDEO_CAPS_YUV ("{ AYUV, UYVY, YUY2 }"))
);
enum
{
ARG_0,
ARG_DISPLAY
};
GST_BOILERPLATE_FULL (GstGLImageSink, gst_glimage_sink, GstVideoSink,
GST_TYPE_VIDEO_SINK, gst_glimage_sink_init_interfaces);
static void
gst_glimage_sink_init_interfaces (GType type)
{
static const GInterfaceInfo overlay_info = {
(GInterfaceInitFunc) gst_glimage_sink_xoverlay_init,
NULL,
NULL
};
static const GInterfaceInfo implements_info = {
(GInterfaceInitFunc) gst_glimage_sink_implements_init,
NULL,
NULL
};
g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE,
&implements_info);
g_type_add_interface_static (type, GST_TYPE_X_OVERLAY, &overlay_info);
}
static void
gst_glimage_sink_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details (element_class, &gst_glimage_sink_details);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_glimage_sink_template));
}
static void
gst_glimage_sink_class_init (GstGLImageSinkClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
GstBaseSinkClass *gstbasesink_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
gstbasesink_class = (GstBaseSinkClass *) klass;
gobject_class->set_property = gst_glimage_sink_set_property;
gobject_class->get_property = gst_glimage_sink_get_property;
g_object_class_install_property (gobject_class, ARG_DISPLAY,
g_param_spec_string ("display", "Display", "X Display name",
NULL, G_PARAM_READWRITE));
gobject_class->finalize = gst_glimage_sink_finalize;
gstelement_class->change_state = gst_glimage_sink_change_state;
if (0)
gstbasesink_class->get_caps = gst_glimage_sink_get_caps;
gstbasesink_class->set_caps = gst_glimage_sink_set_caps;
gstbasesink_class->get_times = gst_glimage_sink_get_times;
gstbasesink_class->preroll = gst_glimage_sink_render;
gstbasesink_class->render = gst_glimage_sink_render;
gstbasesink_class->start = gst_glimage_sink_start;
gstbasesink_class->stop = gst_glimage_sink_stop;
gstbasesink_class->unlock = gst_glimage_sink_unlock;
}
static void
gst_glimage_sink_init (GstGLImageSink * glimage_sink,
GstGLImageSinkClass * glimage_sink_class)
{
glimage_sink->display_name = NULL;
//gst_glimage_sink_update_caps (glimage_sink);
}
static void
gst_glimage_sink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstGLImageSink *glimage_sink;
g_return_if_fail (GST_IS_GLIMAGE_SINK (object));
glimage_sink = GST_GLIMAGE_SINK (object);
switch (prop_id) {
case ARG_DISPLAY:
g_free (glimage_sink->display_name);
glimage_sink->display_name = g_strdup (g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_glimage_sink_finalize (GObject * object)
{
GstGLImageSink *glimage_sink;
g_return_if_fail (GST_IS_GLIMAGE_SINK (object));
glimage_sink = GST_GLIMAGE_SINK (object);
if (glimage_sink->caps) {
gst_caps_unref (glimage_sink->caps);
}
g_free (glimage_sink->display_name);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gst_glimage_sink_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstGLImageSink *glimage_sink;
g_return_if_fail (GST_IS_GLIMAGE_SINK (object));
glimage_sink = GST_GLIMAGE_SINK (object);
switch (prop_id) {
case ARG_DISPLAY:
g_value_set_string (value, glimage_sink->display_name);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/*
* GstElement methods
*/
static GstStateChangeReturn
gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
{
GstGLImageSink *glimage_sink;
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
GST_DEBUG ("change state");
glimage_sink = GST_GLIMAGE_SINK (element);
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
break;
default:
break;
}
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
if (ret == GST_STATE_CHANGE_FAILURE)
return ret;
switch (transition) {
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
/* FIXME clear window */
glimage_sink->fps_n = 0;
glimage_sink->fps_d = 1;
GST_VIDEO_SINK_WIDTH (glimage_sink) = 0;
GST_VIDEO_SINK_HEIGHT (glimage_sink) = 0;
break;
case GST_STATE_CHANGE_READY_TO_NULL:
/* FIXME dispose of window */
break;
default:
break;
}
return ret;
}
/*
* GstBaseSink methods
*/
static gboolean
gst_glimage_sink_start (GstBaseSink * bsink)
{
GstGLImageSink *glimage_sink;
GST_DEBUG ("start");
glimage_sink = GST_GLIMAGE_SINK (bsink);
if (glimage_sink->display && glimage_sink->window_id) {
gst_gl_display_set_window (glimage_sink->display, glimage_sink->window_id);
gst_gl_display_set_visible (glimage_sink->display, TRUE);
}
GST_DEBUG ("start done");
return TRUE;
}
static gboolean
gst_glimage_sink_stop (GstBaseSink * bsink)
{
GstGLImageSink *glimage_sink;
GST_DEBUG ("stop");
glimage_sink = GST_GLIMAGE_SINK (bsink);
if (glimage_sink->stored_buffer) {
gst_buffer_unref (glimage_sink->stored_buffer);
glimage_sink->stored_buffer = NULL;
}
if (glimage_sink->display) {
gst_gl_display_set_visible (glimage_sink->display, FALSE);
g_object_unref (glimage_sink->display);
glimage_sink->display = NULL;
}
return TRUE;
}
static gboolean
gst_glimage_sink_unlock (GstBaseSink * bsink)
{
//GstGLImageSink *glimage_sink;
GST_DEBUG ("unlock");
//glimage_sink = GST_GLIMAGE_SINK (bsink);
/* FIXME */
return TRUE;
}
static void
gst_glimage_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
GstClockTime * start, GstClockTime * end)
{
GstGLImageSink *glimagesink;
glimagesink = GST_GLIMAGE_SINK (bsink);
if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
*start = GST_BUFFER_TIMESTAMP (buf);
if (GST_BUFFER_DURATION_IS_VALID (buf)) {
*end = *start + GST_BUFFER_DURATION (buf);
} else {
if (glimagesink->fps_n > 0) {
*end = *start +
gst_util_uint64_scale_int (GST_SECOND, glimagesink->fps_d,
glimagesink->fps_n);
}
}
}
}
static GstCaps *
gst_glimage_sink_get_caps (GstBaseSink * bsink)
{
GstGLImageSink *glimage_sink;
glimage_sink = GST_GLIMAGE_SINK (bsink);
GST_DEBUG ("get caps returning %" GST_PTR_FORMAT, glimage_sink->caps);
return gst_caps_ref (glimage_sink->caps);
}
static gboolean
gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
{
GstGLImageSink *glimage_sink;
int width;
int height;
gboolean ok;
int fps_n, fps_d;
int par_n, par_d;
GstVideoFormat format;
GstStructure *structure;
gboolean is_gl;
GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps);
glimage_sink = GST_GLIMAGE_SINK (bsink);
structure = gst_caps_get_structure (caps, 0);
if (gst_structure_has_name (structure, "video/x-raw-gl")) {
is_gl = TRUE;
format = GST_VIDEO_FORMAT_UNKNOWN;
ok = gst_structure_get_int (structure, "width", &width);
ok &= gst_structure_get_int (structure, "height", &height);
} else {
is_gl = FALSE;
ok = gst_video_format_parse_caps (caps, &format, &width, &height);
}
ok &= gst_video_parse_caps_framerate (caps, &fps_n, &fps_d);
ok &= gst_video_parse_caps_pixel_aspect_ratio (caps, &par_n, &par_d);
if (!ok)
return FALSE;
GST_VIDEO_SINK_WIDTH (glimage_sink) = width;
GST_VIDEO_SINK_HEIGHT (glimage_sink) = height;
glimage_sink->is_gl = is_gl;
glimage_sink->format = format;
glimage_sink->width = width;
glimage_sink->height = height;
glimage_sink->fps_n = fps_n;
glimage_sink->fps_d = fps_d;
glimage_sink->par_n = par_n;
glimage_sink->par_d = par_d;
return TRUE;
}
static GstFlowReturn
gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf)
{
GstGLImageSink *glimage_sink;
GstGLBuffer *gl_buffer;
GstGLDisplay *display;
glimage_sink = GST_GLIMAGE_SINK (bsink);
if (glimage_sink->stored_buffer) {
gst_buffer_unref (glimage_sink->stored_buffer);
glimage_sink->stored_buffer = NULL;
}
if (glimage_sink->is_gl) {
gl_buffer = GST_GL_BUFFER (gst_buffer_ref (buf));
if (glimage_sink->display == NULL) {
glimage_sink->display = g_object_ref (gl_buffer->display);
if (glimage_sink->window_id) {
gst_gl_display_set_window (glimage_sink->display,
glimage_sink->window_id);
}
} else {
g_assert (gl_buffer->display == glimage_sink->display);
}
display = gl_buffer->display;
} else {
if (glimage_sink->display == NULL) {
gboolean ret;
glimage_sink->display = gst_gl_display_new ();
ret = gst_gl_display_connect (glimage_sink->display, NULL);
if (!ret) {
g_object_unref (glimage_sink->display);
return GST_FLOW_ERROR;
}
if (glimage_sink->window_id) {
gst_gl_display_set_window (glimage_sink->display,
glimage_sink->window_id);
}
gst_gl_display_set_visible (glimage_sink->display, TRUE);
}
display = glimage_sink->display;
gl_buffer = gst_gl_buffer_new_from_video_format (display,
glimage_sink->format, glimage_sink->width, glimage_sink->height);
gst_gl_buffer_upload (gl_buffer, glimage_sink->format,
GST_BUFFER_DATA (buf));
}
glimage_sink->stored_buffer = gst_gl_buffer_ref (gl_buffer);
gst_gl_display_draw_texture (display, gl_buffer->texture,
gl_buffer->width, gl_buffer->height, TRUE);
gst_buffer_unref (GST_BUFFER (gl_buffer));
return GST_FLOW_OK;
}
/*
* XOverlay
*/
static void
gst_glimage_sink_xoverlay_init (GstXOverlayClass * iface)
{
iface->set_xwindow_id = gst_glimage_sink_set_xwindow_id;
iface->expose = gst_glimage_sink_expose;
iface->handle_events = gst_glimage_sink_set_event_handling;
}
static void
gst_glimage_sink_set_xwindow_id (GstXOverlay * overlay, XID window_id)
{
GstGLImageSink *glimage_sink;
g_return_if_fail (GST_IS_GLIMAGE_SINK (overlay));
GST_DEBUG ("set_xwindow_id %ld", window_id);
glimage_sink = GST_GLIMAGE_SINK (overlay);
if (glimage_sink->window_id == window_id) {
return;
}
glimage_sink->window_id = window_id;
if (glimage_sink->display) {
gst_gl_display_set_window (glimage_sink->display, glimage_sink->window_id);
}
}
static void
gst_glimage_sink_expose (GstXOverlay * overlay)
{
GstGLImageSink *glimagesink = GST_GLIMAGE_SINK (overlay);
GST_DEBUG ("expose");
if (glimagesink->display) {
gst_gl_display_update_window (glimagesink->display);
}
if (glimagesink->stored_buffer) {
GstGLBuffer *gl_buffer = glimagesink->stored_buffer;
gst_gl_display_draw_texture (gl_buffer->display, gl_buffer->texture,
gl_buffer->width, gl_buffer->height, FALSE);
}
}
static void
gst_glimage_sink_set_event_handling (GstXOverlay * overlay,
gboolean handle_events)
{
/* FIXME */
GST_DEBUG ("handle_events %d", handle_events);
}
/*
* GstImplementsInterface
*/
static gboolean
gst_glimage_sink_interface_supported (GstImplementsInterface * iface,
GType type)
{
return TRUE;
}
static void
gst_glimage_sink_implements_init (GstImplementsInterfaceClass * klass)
{
klass->supported = gst_glimage_sink_interface_supported;
}

View File

@ -1,79 +0,0 @@
/* GStreamer
* Copyright (C) 2003 Julien Moutte <julien@moutte.net>
* Copyright (C) 2005,2006,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.
*/
#ifndef _GLIMAGESINK_H_
#define _GLIMAGESINK_H_
#include <gst/gst.h>
#include <gst/interfaces/xoverlay.h>
#include <gst/video/gstvideosink.h>
#include <gst/video/video.h>
#include "gstgldisplay.h"
#include "gstglbuffer.h"
GST_DEBUG_CATEGORY_EXTERN (gst_debug_glimage_sink);
#define GST_TYPE_GLIMAGE_SINK \
(gst_glimage_sink_get_type())
#define GST_GLIMAGE_SINK(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GLIMAGE_SINK,GstGLImageSink))
#define GST_GLIMAGE_SINK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GLIMAGE_SINK,GstGLImageSinkClass))
#define GST_IS_GLIMAGE_SINK(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GLIMAGE_SINK))
#define GST_IS_GLIMAGE_SINK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GLIMAGE_SINK))
typedef struct _GstGLImageSink GstGLImageSink;
typedef struct _GstGLImageSinkClass GstGLImageSinkClass;
struct _GstGLImageSink
{
GstVideoSink video_sink;
/* properties */
char *display_name;
/* caps */
GstCaps *caps;
GstVideoFormat format;
int width;
int height;
gboolean is_gl;
int fps_n, fps_d;
int par_n, par_d;
GstGLDisplay *display;
GstGLBuffer *stored_buffer;
XID window_id;
};
struct _GstGLImageSinkClass
{
GstVideoSinkClass video_sink_class;
};
GType gst_glimage_sink_get_type(void);
#endif

View File

@ -1,495 +0,0 @@
/* 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);
glDisable (GL_CULL_FACE);
glDisable (GL_TEXTURE_RECTANGLE_ARB);
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
}

View File

@ -1,57 +0,0 @@
/* 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

View File

@ -1,451 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gstglbuffer.h>
#include <gstgldisplay.h>
#include <GL/glext.h>
#include <unistd.h>
#include "glextensions.h"
#include <string.h>
static GObjectClass *gst_gl_buffer_parent_class;
static void
gst_gl_buffer_finalize (GstGLBuffer * buffer)
{
gst_gl_display_lock (buffer->display);
glDeleteTextures (1, &buffer->texture);
if (buffer->texture_u) {
glDeleteTextures (1, &buffer->texture_u);
}
if (buffer->texture_v) {
glDeleteTextures (1, &buffer->texture_v);
}
gst_gl_display_unlock (buffer->display);
g_object_unref (buffer->display);
GST_MINI_OBJECT_CLASS (gst_gl_buffer_parent_class)->
finalize (GST_MINI_OBJECT (buffer));
}
static void
gst_gl_buffer_init (GstGLBuffer * buffer, gpointer g_class)
{
}
static void
gst_gl_buffer_class_init (gpointer g_class, gpointer class_data)
{
GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class);
gst_gl_buffer_parent_class = g_type_class_peek_parent (g_class);
mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
gst_gl_buffer_finalize;
}
GType
gst_gl_buffer_get_type (void)
{
static GType _gst_gl_buffer_type;
if (G_UNLIKELY (_gst_gl_buffer_type == 0)) {
static const GTypeInfo info = {
sizeof (GstBufferClass),
NULL,
NULL,
gst_gl_buffer_class_init,
NULL,
NULL,
sizeof (GstGLBuffer),
0,
(GInstanceInitFunc) gst_gl_buffer_init,
NULL
};
_gst_gl_buffer_type = g_type_register_static (GST_TYPE_BUFFER,
"GstGLBuffer", &info, 0);
}
return _gst_gl_buffer_type;
}
GstGLBuffer *
gst_gl_buffer_new (GstGLDisplay * display, int width, int height)
{
g_return_val_if_fail (display != NULL, NULL);
g_return_val_if_fail (width > 0, NULL);
g_return_val_if_fail (height > 0, NULL);
return gst_gl_buffer_new_with_format (display, GST_GL_BUFFER_FORMAT_RGBA,
width, height);
}
GstGLBuffer *
gst_gl_buffer_new_with_format (GstGLDisplay * display,
GstGLBufferFormat format, int width, int height)
{
GstGLBuffer *buffer;
g_return_val_if_fail (format != GST_GL_BUFFER_FORMAT_UNKNOWN, NULL);
g_return_val_if_fail (display != NULL, NULL);
g_return_val_if_fail (width > 0, NULL);
g_return_val_if_fail (height > 0, NULL);
buffer = (GstGLBuffer *) gst_mini_object_new (GST_TYPE_GL_BUFFER);
buffer->display = g_object_ref (display);
buffer->width = width;
buffer->height = height;
buffer->format = format;
GST_BUFFER_SIZE (buffer) = gst_gl_buffer_format_get_size (format, width,
height);
gst_gl_display_lock (buffer->display);
glGenTextures (1, &buffer->texture);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture);
switch (format) {
case GST_GL_BUFFER_FORMAT_RGBA:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
buffer->width, buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
break;
case GST_GL_BUFFER_FORMAT_RGB:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB,
buffer->width, buffer->height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
break;
case GST_GL_BUFFER_FORMAT_YUYV:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA,
buffer->width, buffer->height,
0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL);
break;
case GST_GL_BUFFER_FORMAT_PLANAR444:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
buffer->width, buffer->height,
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
glGenTextures (1, &buffer->texture_u);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_u);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
buffer->width, buffer->height,
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
glGenTextures (1, &buffer->texture_v);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_v);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
buffer->width, buffer->height,
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
break;
case GST_GL_BUFFER_FORMAT_PLANAR422:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
buffer->width, buffer->height,
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
glGenTextures (1, &buffer->texture_u);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_u);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
GST_ROUND_UP_2 (buffer->width) / 2, buffer->height,
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
glGenTextures (1, &buffer->texture_v);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_v);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
GST_ROUND_UP_2 (buffer->width) / 2, buffer->height,
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
break;
case GST_GL_BUFFER_FORMAT_PLANAR420:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
buffer->width, buffer->height,
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
glGenTextures (1, &buffer->texture_u);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_u);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
GST_ROUND_UP_2 (buffer->width) / 2,
GST_ROUND_UP_2 (buffer->height) / 2,
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
glGenTextures (1, &buffer->texture_v);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_v);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE,
GST_ROUND_UP_2 (buffer->width) / 2,
GST_ROUND_UP_2 (buffer->height) / 2,
0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
break;
default:
g_warning ("GL buffer format not handled");
}
gst_gl_display_unlock (buffer->display);
return buffer;
}
GstGLBuffer *
gst_gl_buffer_new_from_video_format (GstGLDisplay * display,
GstVideoFormat video_format, int width, int height)
{
GstGLBuffer *buffer;
g_return_val_if_fail (width > 0, NULL);
g_return_val_if_fail (height > 0, NULL);
buffer = gst_gl_buffer_new_with_format (display,
gst_gl_buffer_format_from_video_format (video_format), width, height);
switch (video_format) {
case GST_VIDEO_FORMAT_RGBx:
case GST_VIDEO_FORMAT_BGRx:
case GST_VIDEO_FORMAT_xRGB:
case GST_VIDEO_FORMAT_xBGR:
buffer->is_yuv = FALSE;
break;
case GST_VIDEO_FORMAT_YUY2:
case GST_VIDEO_FORMAT_UYVY:
/* counterintuitive: when you use a GL_YCBCR_MESA texture, the
* colorspace is automatically converted, so it's referred to
* as RGB */
buffer->is_yuv = FALSE;
break;
case GST_VIDEO_FORMAT_AYUV:
case GST_VIDEO_FORMAT_I420:
case GST_VIDEO_FORMAT_YV12:
buffer->is_yuv = TRUE;
break;
default:
g_assert_not_reached ();
}
return buffer;
}
void
gst_gl_buffer_upload (GstGLBuffer * buffer, GstVideoFormat video_format,
void *data)
{
int width = buffer->width;
int height = buffer->height;
GST_DEBUG ("uploading %p %dx%d", data, width, height);
g_return_if_fail (buffer->format ==
gst_gl_buffer_format_from_video_format (video_format));
gst_gl_display_lock (buffer->display);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture);
switch (video_format) {
case GST_VIDEO_FORMAT_RGBx:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_RGBA, GL_UNSIGNED_BYTE, data);
break;
case GST_VIDEO_FORMAT_BGRx:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_BGRA, GL_UNSIGNED_BYTE, data);
break;
case GST_VIDEO_FORMAT_AYUV:
case GST_VIDEO_FORMAT_xRGB:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data);
break;
case GST_VIDEO_FORMAT_xBGR:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data);
break;
case GST_VIDEO_FORMAT_YUY2:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, data);
break;
case GST_VIDEO_FORMAT_UYVY:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, data);
break;
case GST_VIDEO_FORMAT_I420:
case GST_VIDEO_FORMAT_YV12:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_u);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
GST_ROUND_UP_2 (buffer->width) / 2,
GST_ROUND_UP_2 (buffer->height) / 2,
GL_LUMINANCE, GL_UNSIGNED_BYTE,
(guint8 *) data +
gst_video_format_get_component_offset (video_format, 1, width,
height));
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, buffer->texture_v);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
GST_ROUND_UP_2 (buffer->width) / 2,
GST_ROUND_UP_2 (buffer->height) / 2,
GL_LUMINANCE, GL_UNSIGNED_BYTE,
(guint8 *) data +
gst_video_format_get_component_offset (video_format, 2, width,
height));
break;
default:
g_assert_not_reached ();
}
gst_gl_display_unlock (buffer->display);
}
void
gst_gl_buffer_download (GstGLBuffer * buffer, GstVideoFormat video_format,
void *data)
{
GLuint fbo;
g_return_if_fail (buffer->format ==
gst_gl_buffer_format_from_video_format (video_format));
GST_DEBUG ("downloading");
gst_gl_display_lock (buffer->display);
/* we need a reset function */
glMatrixMode (GL_COLOR);
glLoadIdentity ();
glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, 0);
glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, 0);
glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, 0);
glGenFramebuffersEXT (1, &fbo);
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo);
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, buffer->texture, 0);
glDrawBuffer (GL_COLOR_ATTACHMENT1_EXT);
glReadBuffer (GL_COLOR_ATTACHMENT1_EXT);
g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) ==
GL_FRAMEBUFFER_COMPLETE_EXT);
switch (video_format) {
case GST_VIDEO_FORMAT_RGBx:
glReadPixels (0, 0, buffer->width, buffer->height, GL_RGBA,
GL_UNSIGNED_BYTE, data);
break;
case GST_VIDEO_FORMAT_BGRx:
glReadPixels (0, 0, buffer->width, buffer->height, GL_BGRA,
GL_UNSIGNED_BYTE, data);
break;
case GST_VIDEO_FORMAT_xBGR:
glReadPixels (0, 0, buffer->width, buffer->height, GL_RGBA,
GL_UNSIGNED_INT_8_8_8_8, data);
break;
case GST_VIDEO_FORMAT_AYUV:
case GST_VIDEO_FORMAT_xRGB:
glReadPixels (0, 0, buffer->width, buffer->height, GL_BGRA,
GL_UNSIGNED_INT_8_8_8_8, data);
break;
case GST_VIDEO_FORMAT_YUY2:
case GST_VIDEO_FORMAT_UYVY:
g_warning ("video format not supported for download from GL texture");
break;
case GST_VIDEO_FORMAT_I420:
case GST_VIDEO_FORMAT_YV12:
glReadPixels (0, 0, buffer->width, buffer->height,
GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB,
buffer->texture_u, 0);
glReadPixels (0, 0,
GST_ROUND_UP_2 (buffer->width) / 2,
GST_ROUND_UP_2 (buffer->height) / 2,
GL_LUMINANCE, GL_UNSIGNED_BYTE,
(guint8 *) data +
gst_video_format_get_component_offset (video_format, 1, buffer->width,
buffer->height));
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB,
buffer->texture_v, 0);
glReadPixels (0, 0,
GST_ROUND_UP_2 (buffer->width) / 2,
GST_ROUND_UP_2 (buffer->height) / 2,
GL_LUMINANCE, GL_UNSIGNED_BYTE,
(guint8 *) data +
gst_video_format_get_component_offset (video_format, 2, buffer->width,
buffer->height));
break;
default:
g_assert_not_reached ();
}
glDeleteFramebuffersEXT (1, &fbo);
gst_gl_display_unlock (buffer->display);
}
/* buffer format */
GstGLBufferFormat
gst_gl_buffer_format_from_video_format (GstVideoFormat format)
{
switch (format) {
case GST_VIDEO_FORMAT_RGBx:
case GST_VIDEO_FORMAT_BGRx:
case GST_VIDEO_FORMAT_xRGB:
case GST_VIDEO_FORMAT_xBGR:
case GST_VIDEO_FORMAT_RGBA:
case GST_VIDEO_FORMAT_BGRA:
case GST_VIDEO_FORMAT_ARGB:
case GST_VIDEO_FORMAT_ABGR:
case GST_VIDEO_FORMAT_AYUV:
return GST_GL_BUFFER_FORMAT_RGBA;
case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR:
return GST_GL_BUFFER_FORMAT_RGB;
case GST_VIDEO_FORMAT_YUY2:
case GST_VIDEO_FORMAT_UYVY:
return GST_GL_BUFFER_FORMAT_YUYV;
case GST_VIDEO_FORMAT_I420:
case GST_VIDEO_FORMAT_YV12:
return GST_GL_BUFFER_FORMAT_PLANAR420;
case GST_VIDEO_FORMAT_UNKNOWN:
return GST_GL_BUFFER_FORMAT_UNKNOWN;
}
g_return_val_if_reached (GST_GL_BUFFER_FORMAT_UNKNOWN);
}
int
gst_gl_buffer_format_get_size (GstGLBufferFormat format, int width, int height)
{
/* this is not strictly true, but it's used for compatibility with
* queue and BaseTransform */
return width * height * 4;
}
gboolean
gst_gl_buffer_format_parse_caps (GstCaps * caps, GstGLBufferFormat * format,
int *width, int *height)
{
GstStructure *structure;
int format_as_int;
gboolean ret;
structure = gst_caps_get_structure (caps, 0);
if (!gst_structure_has_name (structure, "video/x-raw-gl")) {
return FALSE;
}
ret = gst_structure_get_int (structure, "format", &format_as_int);
*format = format_as_int;
ret &= gst_structure_get_int (structure, "width", width);
ret &= gst_structure_get_int (structure, "height", height);
return ret;
}

View File

@ -1,76 +0,0 @@
#ifndef _GST_GL_BUFFER_H_
#define _GST_GL_BUFFER_H_
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gstgldisplay.h>
typedef struct _GstGLBuffer GstGLBuffer;
#define GST_TYPE_GL_BUFFER (gst_gl_buffer_get_type())
#define GST_IS_GL_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_GL_BUFFER))
#define GST_GL_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_GL_BUFFER, GstGLBuffer))
typedef enum {
GST_GL_BUFFER_FORMAT_UNKNOWN,
GST_GL_BUFFER_FORMAT_RGBA,
GST_GL_BUFFER_FORMAT_RGB,
GST_GL_BUFFER_FORMAT_YUYV,
GST_GL_BUFFER_FORMAT_PLANAR444,
GST_GL_BUFFER_FORMAT_PLANAR422,
GST_GL_BUFFER_FORMAT_PLANAR420
} GstGLBufferFormat;
struct _GstGLBuffer {
GstBuffer buffer;
GstGLDisplay *display;
GstGLBufferFormat format;
gboolean is_yuv;
GLuint texture;
GLuint texture_u;
GLuint texture_v;
int width;
int height;
};
GType gst_gl_buffer_get_type (void);
#define gst_gl_buffer_ref(x) ((GstGLBuffer *)(gst_buffer_ref((GstBuffer *)(x))))
#define gst_gl_buffer_unref(x) (gst_buffer_unref((GstBuffer *)(x)))
GstGLBuffer * gst_gl_buffer_new (GstGLDisplay *display,
int width, int height);
GstGLBuffer * gst_gl_buffer_new_with_format (GstGLDisplay *display,
GstGLBufferFormat format, int width, int height);
GstGLBuffer * gst_gl_buffer_new_from_video_format (GstGLDisplay *display,
GstVideoFormat format, int width, int height);
void gst_gl_buffer_upload (GstGLBuffer *buffer,
GstVideoFormat format, void *data);
void gst_gl_buffer_download (GstGLBuffer *buffer, GstVideoFormat format,
void *data);
#define GST_GL_VIDEO_CAPS \
"video/x-raw-gl," \
"format=(int)1," \
"is_yuv=(boolean)FALSE," \
"width=(int)[1,2048]," \
"height=(int)[1,2048]," \
"pixel-aspect-ratio=(fraction)1/1," \
"framerate=(fraction)[0/1,100/1]"
GstGLBufferFormat gst_gl_buffer_format_from_video_format (GstVideoFormat format);
int gst_gl_buffer_format_get_size (GstGLBufferFormat format, int width,
int height);
gboolean gst_gl_buffer_format_parse_caps (GstCaps *caps, GstGLBufferFormat *format,
int *width, int *height);
#endif

View File

@ -1,198 +0,0 @@
/*
* GStreamer
* Copyright (C) 2007 David 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gstglbuffer.h>
#include <gstglfilter.h>
#include "glextensions.h"
#define GST_CAT_DEFAULT gst_gl_convert_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_TYPE_GL_CONVERT (gst_gl_convert_get_type())
#define GST_GL_CONVERT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_CONVERT,GstGLConvert))
#define GST_IS_GL_CONVERT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_CONVERT))
#define GST_GL_CONVERT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_GL_CONVERT,GstGLConvertClass))
#define GST_IS_GL_CONVERT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_GL_CONVERT))
#define GST_GL_CONVERT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_GL_CONVERT,GstGLConvertClass))
typedef struct _GstGLConvert GstGLConvert;
typedef struct _GstGLConvertClass GstGLConvertClass;
struct _GstGLConvert
{
GstGLFilter filter;
/* < private > */
};
struct _GstGLConvertClass
{
GstGLFilterClass filter_class;
};
static const GstElementDetails element_details = GST_ELEMENT_DETAILS ("FIXME",
"Filter/Effect",
"FIXME GL conversion filter",
"FIXME <fixme@fixme.com>");
enum
{
PROP_0
};
#define DEBUG_INIT(bla) \
GST_DEBUG_CATEGORY_INIT (gst_gl_convert_debug, "glconvert", 0, "glconvert element");
GST_BOILERPLATE_FULL (GstGLConvert, gst_gl_convert, GstGLFilter,
GST_TYPE_GL_FILTER, DEBUG_INIT);
static void gst_gl_convert_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_gl_convert_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static gboolean gst_gl_convert_filter (GstGLFilter * filter,
GstGLBuffer * inbuf, GstGLBuffer * outbuf);
static void
gst_gl_convert_base_init (gpointer klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_set_details (element_class, &element_details);
}
static void
gst_gl_convert_class_init (GstGLConvertClass * klass)
{
GObjectClass *gobject_class;
gobject_class = (GObjectClass *) klass;
gobject_class->set_property = gst_gl_convert_set_property;
gobject_class->get_property = gst_gl_convert_get_property;
GST_GL_FILTER_CLASS (klass)->filter = gst_gl_convert_filter;
}
static void
gst_gl_convert_init (GstGLConvert * filter, GstGLConvertClass * klass)
{
}
static void
gst_gl_convert_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
//GstGLConvert *filter = GST_GL_CONVERT (object);
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_gl_convert_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
//GstGLConvert *filter = GST_GL_CONVERT (object);
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static gboolean
gst_gl_convert_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
GstGLBuffer * outbuf)
{
//GstGLConvert *convert = GST_GL_CONVERT(filter);
glDisable (GL_CULL_FACE);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
if (inbuf->is_yuv) {
#ifdef GL_POST_COLOR_MATRIX_RED_BIAS
const double matrix[16] = {
1.16438, 1.6321, -0.00107909, 0,
1.13839, -0.813005, -0.39126, 0,
1.13839, 0.00112726, 2.01741, 0,
0, 0, 0, 1
};
GST_DEBUG ("applying YUV->RGB conversion");
glMatrixMode (GL_COLOR);
glLoadMatrixd (matrix);
/* same */
glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, -0.873494);
glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, 0.531435);
glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, -1.08629);
#else
g_assert_not_reached ();
#endif
}
glColor4f (1, 0, 1, 1);
glBegin (GL_QUADS);
glNormal3f (0, 0, -1);
glTexCoord2f (inbuf->width, 0);
glVertex3f (1.0, -1.0, 0);
glTexCoord2f (0, 0);
glVertex3f (-1.0, -1.0, 0);
glTexCoord2f (0, inbuf->height);
glVertex3f (-1.0, 1.0, 0);
glTexCoord2f (inbuf->width, inbuf->height);
glVertex3f (1.0, 1.0, 0);
glEnd ();
if (inbuf->is_yuv) {
#ifdef GL_POST_COLOR_MATRIX_RED_BIAS
glMatrixMode (GL_COLOR);
glLoadIdentity ();
glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, 0);
glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, 0);
glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, 0);
#else
g_assert_not_reached ();
#endif
}
return TRUE;
}

View File

@ -1,875 +0,0 @@
/* gstgldisplay.c
* Copyright (C) 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstgldisplay.h"
#include "glextensions.h"
#include <gst/gst.h>
#include <string.h>
static void gst_gl_display_finalize (GObject * object);
static void gst_gl_display_init_tmp_window (GstGLDisplay * display);
GST_BOILERPLATE (GstGLDisplay, gst_gl_display, GObject, G_TYPE_OBJECT);
static void
gst_gl_display_base_init (gpointer g_class)
{
}
static void
gst_gl_display_class_init (GstGLDisplayClass * klass)
{
G_OBJECT_CLASS (klass)->finalize = gst_gl_display_finalize;
}
static void
gst_gl_display_init (GstGLDisplay * display, GstGLDisplayClass * klass)
{
display->lock = g_mutex_new ();
}
static void
gst_gl_display_finalize (GObject * object)
{
GstGLDisplay *display = GST_GL_DISPLAY (object);
GST_DEBUG ("finalize %p", object);
if (display->window != None) {
XDestroyWindow (display->display, display->window);
}
if (display->context) {
glXDestroyContext (display->display, display->context);
}
//if (display->visinfo) {
// XFree (display->visinfo);
//}
if (display->display) {
XCloseDisplay (display->display);
}
if (display->lock) {
g_mutex_free (display->lock);
}
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static gboolean gst_gl_display_check_features (GstGLDisplay * display);
GstGLDisplay *
gst_gl_display_new (void)
{
return g_object_new (GST_TYPE_GL_DISPLAY, NULL);
}
//#define HANDLE_X_ERRORS
#ifdef HANDLE_X_ERRORS
static int
x_error_handler (Display * display, XErrorEvent * event)
{
g_assert_not_reached ();
}
#endif
gboolean
gst_gl_display_connect (GstGLDisplay * display, const char *display_name)
{
gboolean usable;
XGCValues values;
XPixmapFormatValues *px_formats;
int n_formats;
int i;
display->display = XOpenDisplay (display_name);
if (display->display == NULL) {
return FALSE;
}
#ifdef HANDLE_X_ERRORS
XSynchronize (display->display, True);
XSetErrorHandler (x_error_handler);
#endif
usable = gst_gl_display_check_features (display);
if (!usable) {
return FALSE;
}
display->screen = DefaultScreenOfDisplay (display->display);
display->screen_num = DefaultScreen (display->display);
display->visual = DefaultVisual (display->display, display->screen_num);
display->root = DefaultRootWindow (display->display);
display->white = XWhitePixel (display->display, display->screen_num);
display->black = XBlackPixel (display->display, display->screen_num);
display->depth = DefaultDepthOfScreen (display->screen);
display->gc = XCreateGC (display->display,
DefaultRootWindow (display->display), 0, &values);
px_formats = XListPixmapFormats (display->display, &n_formats);
for (i = 0; i < n_formats; i++) {
GST_DEBUG ("%d: depth %d bpp %d pad %d", i,
px_formats[i].depth,
px_formats[i].bits_per_pixel, px_formats[i].scanline_pad);
}
gst_gl_display_init_tmp_window (display);
return TRUE;
}
static gboolean
gst_gl_display_check_features (GstGLDisplay * display)
{
gboolean ret;
XVisualInfo *visinfo;
Screen *screen;
Window root;
int scrnum;
int attrib[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, None
};
XSetWindowAttributes attr;
int error_base;
int event_base;
int mask;
const char *extstring;
Window window;
screen = XDefaultScreenOfDisplay (display->display);
scrnum = XScreenNumberOfScreen (screen);
root = XRootWindow (display->display, scrnum);
ret = glXQueryExtension (display->display, &error_base, &event_base);
if (!ret) {
GST_DEBUG ("No GLX extension");
return FALSE;
}
visinfo = glXChooseVisual (display->display, scrnum, attrib);
if (visinfo == NULL) {
GST_DEBUG ("No usable visual");
return FALSE;
}
display->visinfo = visinfo;
display->context = glXCreateContext (display->display, visinfo, NULL, True);
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap (display->display, root,
visinfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask;
attr.override_redirect = True;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect;
GST_DEBUG ("creating window with visual %ld", visinfo->visualid);
window = XCreateWindow (display->display, root, 0, 0,
100, 100, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr);
XSync (display->display, FALSE);
glXMakeCurrent (display->display, window, display->context);
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &display->max_texture_size);
extstring = (const char *) glGetString (GL_EXTENSIONS);
display->have_ycbcr_texture = FALSE;
#ifdef GL_YCBCR_MESA
if (strstr (extstring, "GL_MESA_ycbcr_texture")) {
display->have_ycbcr_texture = TRUE;
}
#endif
display->have_color_matrix = FALSE;
#ifdef GL_POST_COLOR_MATRIX_RED_BIAS
if (strstr (extstring, "GL_SGI_color_matrix")) {
display->have_color_matrix = TRUE;
}
#endif
display->have_texture_rectangle = FALSE;
#ifdef GL_TEXTURE_RECTANGLE_ARB
if (strstr (extstring, "GL_ARB_texture_rectangle")) {
display->have_texture_rectangle = TRUE;
}
#endif
glXMakeCurrent (display->display, None, NULL);
XDestroyWindow (display->display, window);
return TRUE;
}
gboolean
gst_gl_display_can_handle_type (GstGLDisplay * display, GstVideoFormat type)
{
switch (type) {
case GST_VIDEO_FORMAT_RGBx:
case GST_VIDEO_FORMAT_BGRx:
case GST_VIDEO_FORMAT_xRGB:
case GST_VIDEO_FORMAT_xBGR:
return TRUE;
case GST_VIDEO_FORMAT_YUY2:
case GST_VIDEO_FORMAT_UYVY:
return display->have_ycbcr_texture;
case GST_VIDEO_FORMAT_AYUV:
return display->have_color_matrix;
default:
return FALSE;
}
}
void
gst_gl_display_lock (GstGLDisplay * display)
{
gboolean ret;
g_assert (display->window != None);
g_assert (display->context != NULL);
g_mutex_lock (display->lock);
ret = glXMakeCurrent (display->display, display->window, display->context);
if (!ret) {
g_warning ("glxMakeCurrent failed");
}
gst_gl_display_check_error (display, __LINE__);
}
void
gst_gl_display_unlock (GstGLDisplay * display)
{
gst_gl_display_check_error (display, __LINE__);
glXMakeCurrent (display->display, None, NULL);
g_mutex_unlock (display->lock);
}
static void
gst_gl_display_init_tmp_window (GstGLDisplay * display)
{
XSetWindowAttributes attr = { 0 };
int scrnum;
int mask;
Window root;
Window parent_window;
Screen *screen;
int width;
int height;
GST_DEBUG ("creating temp window");
screen = XDefaultScreenOfDisplay (display->display);
scrnum = XScreenNumberOfScreen (screen);
root = XRootWindow (display->display, scrnum);
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap (display->display, root,
display->visinfo->visual, AllocNone);
if (display->parent_window != None) {
XWindowAttributes parent_attr;
attr.override_redirect = True;
parent_window = display->parent_window;
XGetWindowAttributes (display->display, parent_window, &parent_attr);
width = parent_attr.width;
height = parent_attr.height;
} else {
attr.override_redirect = False;
parent_window = root;
width = 100;
height = 100;
}
mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect;
display->window = XCreateWindow (display->display,
parent_window, 0, 0, width, height,
0, display->visinfo->depth, InputOutput,
display->visinfo->visual, mask, &attr);
if (display->visible) {
XMapWindow (display->display, display->window);
}
XSync (display->display, FALSE);
}
static void
gst_gl_display_destroy_tmp_window (GstGLDisplay * display)
{
XDestroyWindow (display->display, display->window);
}
void
gst_gl_display_set_visible (GstGLDisplay * display, gboolean visible)
{
if (display->visible == visible)
return;
display->visible = visible;
if (display->visible) {
XMapWindow (display->display, display->window);
} else {
XUnmapWindow (display->display, display->window);
}
XSync (display->display, FALSE);
}
void
gst_gl_display_set_window (GstGLDisplay * display, Window window)
{
g_mutex_lock (display->lock);
if (display->display == NULL) {
display->parent_window = window;
} else {
if (window != display->parent_window) {
XSync (display->display, False);
gst_gl_display_destroy_tmp_window (display);
display->parent_window = window;
gst_gl_display_init_tmp_window (display);
}
}
g_mutex_unlock (display->lock);
}
void
gst_gl_display_update_window (GstGLDisplay * display)
{
XWindowAttributes attr;
g_return_if_fail (display != NULL);
g_mutex_lock (display->lock);
if (display->window != None && display->parent_window != None) {
XSync (display->display, False);
XGetWindowAttributes (display->display, display->parent_window, &attr);
GST_DEBUG ("new size %d %d", attr.width, attr.height);
if (display->win_width != attr.width || display->win_height != attr.height) {
XResizeWindow (display->display, display->window,
attr.width, attr.height);
//XSync (display->display, False);
}
display->win_width = attr.width;
display->win_height = attr.height;
}
g_mutex_unlock (display->lock);
}
void
gst_gl_display_update_attributes (GstGLDisplay * display)
{
XWindowAttributes attr;
if (display->window != None) {
XGetWindowAttributes (display->display, display->window, &attr);
GST_DEBUG ("window visual %ld display visual %ld",
attr.visual->visualid, display->visinfo->visual->visualid);
display->win_width = attr.width;
display->win_height = attr.height;
} else {
display->win_width = 0;
display->win_height = 0;
}
}
void
gst_gl_display_set_window_size (GstGLDisplay * display, int width, int height)
{
if (display->win_width != width || display->win_height != height) {
display->win_width = width;
display->win_height = height;
XResizeWindow (display->display, display->window, width, height);
XSync (display->display, False);
}
}
void
gst_gl_display_clear (GstGLDisplay * display)
{
gst_gl_display_lock (display);
glDepthFunc (GL_LESS);
glEnable (GL_DEPTH_TEST);
glClearColor (0.2, 0.2, 0.2, 1.0);
glViewport (0, 0, display->win_width, display->win_height);
gst_gl_display_unlock (display);
}
void
gst_gl_display_check_error (GstGLDisplay * display, int line)
{
GLenum err = glGetError ();
if (err) {
GST_ERROR ("GL Error 0x%x at line %d", (int) err, line);
g_assert (0);
}
}
GLuint
gst_gl_display_upload_texture_rectangle (GstGLDisplay * display,
GstVideoFormat type, void *data, int width, int height)
{
GLuint texture;
glGenTextures (1, &texture);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
switch (type) {
case GST_VIDEO_FORMAT_RGBx:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_RGBA, GL_UNSIGNED_BYTE, data);
break;
case GST_VIDEO_FORMAT_BGRx:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_BGRA, GL_UNSIGNED_BYTE, data);
break;
case GST_VIDEO_FORMAT_xRGB:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data);
break;
case GST_VIDEO_FORMAT_xBGR:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data);
break;
case GST_VIDEO_FORMAT_YUY2:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height,
0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, data);
break;
case GST_VIDEO_FORMAT_UYVY:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height,
0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, data);
break;
case GST_VIDEO_FORMAT_AYUV:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data);
break;
default:
g_assert_not_reached ();
}
return texture;
}
#if 0
static void
draw_rect_texture (GstGLDisplay * display, GstVideoFormat type,
void *data, int width, int height)
{
GLuint texture;
GST_DEBUG ("using rectangular texture");
#ifdef GL_TEXTURE_RECTANGLE_ARB
glEnable (GL_TEXTURE_RECTANGLE_ARB);
texture = gst_gl_display_upload_texture_rectangle (display, type,
data, width, height);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
#if 0
switch (type) {
case GST_VIDEO_FORMAT_RGBx:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_RGBA, GL_UNSIGNED_BYTE, data);
break;
case GST_VIDEO_FORMAT_BGRx:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_BGRA, GL_UNSIGNED_BYTE, data);
break;
case GST_VIDEO_FORMAT_xRGB:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data);
break;
case GST_VIDEO_FORMAT_xBGR:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data);
break;
case GST_VIDEO_FORMAT_YUY2:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height,
0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, data);
break;
case GST_VIDEO_FORMAT_UYVY:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA, width, height,
0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, data);
break;
case GST_VIDEO_FORMAT_AYUV:
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data);
break;
default:
g_assert_not_reached ();
}
#ifdef GL_POST_COLOR_MATRIX_RED_BIAS
if (type == GST_VIDEO_FORMAT_AYUV) {
const double matrix[16] = {
1, 1, 1, 0,
0, -0.344 * 1, 1.770 * 1, 0,
1.403 * 1, -0.714 * 1, 0, 0,
0, 0, 0, 1
};
glMatrixMode (GL_COLOR);
glLoadMatrixd (matrix);
glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, -1.403 / 2);
glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, (0.344 + 0.714) / 2);
glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, -1.770 / 2);
}
#endif
#endif
glColor4f (1, 0, 1, 1);
glBegin (GL_QUADS);
glNormal3f (0, 0, -1);
glTexCoord2f (width, 0);
glVertex3f (1.0, 1.0, 0);
glTexCoord2f (0, 0);
glVertex3f (-1.0, 1.0, 0);
glTexCoord2f (0, height);
glVertex3f (-1.0, -1.0, 0);
glTexCoord2f (width, height);
glVertex3f (1.0, -1.0, 0);
glEnd ();
glDeleteTextures (1, &texture);
#else
g_assert_not_reached ();
#endif
}
static void
draw_pow2_texture (GstGLDisplay * display, GstVideoFormat type,
void *data, int width, int height)
{
int pow2_width;
int pow2_height;
double x, y;
GLuint texture;
GST_DEBUG ("using power-of-2 texture");
for (pow2_height = 64;
pow2_height < height && pow2_height > 0; pow2_height <<= 1);
for (pow2_width = 64; pow2_width < width && pow2_width > 0; pow2_width <<= 1);
glEnable (GL_TEXTURE_2D);
glGenTextures (1, &texture);
glBindTexture (GL_TEXTURE_2D, texture);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
switch (type) {
case GST_VIDEO_FORMAT_RGBx:
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height,
GL_RGBA, GL_UNSIGNED_BYTE, data);
break;
case GST_VIDEO_FORMAT_BGRx:
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height,
GL_BGRA, GL_UNSIGNED_BYTE, data);
break;
case GST_VIDEO_FORMAT_xRGB:
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data);
break;
case GST_VIDEO_FORMAT_xBGR:
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height,
GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data);
break;
case GST_VIDEO_FORMAT_YUY2:
glTexImage2D (GL_TEXTURE_2D, 0, GL_YCBCR_MESA, pow2_width, pow2_height,
0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL);
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height,
GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, data);
break;
case GST_VIDEO_FORMAT_UYVY:
glTexImage2D (GL_TEXTURE_2D, 0, GL_YCBCR_MESA, pow2_width, pow2_height,
0, GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, NULL);
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height,
GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, data);
break;
case GST_VIDEO_FORMAT_AYUV:
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, pow2_width, pow2_height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, width, height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data);
break;
default:
g_assert_not_reached ();
}
#ifdef GL_POST_COLOR_MATRIX_RED_BIAS
if (type == GST_VIDEO_FORMAT_AYUV) {
const double matrix[16] = {
1, 1, 1, 0,
0, -0.344 * 1, 1.770 * 1, 0,
1.403 * 1, -0.714 * 1, 0, 0,
0, 0, 0, 1
};
glMatrixMode (GL_COLOR);
glLoadMatrixd (matrix);
glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, -1.403 / 2);
glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, (0.344 + 0.714) / 2);
glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, -1.770 / 2);
}
#endif
glColor4f (1, 0, 1, 1);
glBegin (GL_QUADS);
glNormal3f (0, 0, -1);
x = (double) width / pow2_width;
y = (double) height / pow2_height;
glTexCoord2f (x, 0);
glVertex3f (1.0, 1.0, 0);
glTexCoord2f (0, 0);
glVertex3f (-1.0, 1.0, 0);
glTexCoord2f (0, y);
glVertex3f (-1.0, -1.0, 0);
glTexCoord2f (x, y);
glVertex3f (1.0, -1.0, 0);
glEnd ();
glDeleteTextures (1, &texture);
}
#endif
#if 0
void
gst_gl_display_draw_image (GstGLDisplay * display, GstVideoFormat type,
void *data, int width, int height)
{
g_return_if_fail (data != NULL);
g_return_if_fail (width > 0);
g_return_if_fail (height > 0);
gst_gl_display_lock (display);
#if 0
/* Doesn't work */
{
int64_t ust = 1234;
int64_t mst = 1234;
int64_t sbc = 1234;
gboolean ret;
ret = glXGetSyncValuesOML (display->display, display->window,
&ust, &mst, &sbc);
GST_ERROR ("sync values %d %lld %lld %lld", ret, ust, mst, sbc);
}
#endif
#if 0
/* Does work, but is not relevant */
{
int32_t num = 1234;
int32_t den = 1234;
gboolean ret;
ret = glXGetMscRateOML (display->display, display->window, &num, &den);
GST_DEBUG ("rate %d %d %d", ret, num, den);
}
#endif
gst_gl_display_update_attributes (display);
glXSwapIntervalSGI (1);
glViewport (0, 0, display->win_width, display->win_height);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glDisable (GL_CULL_FACE);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glColor4f (1, 1, 1, 1);
if (display->have_texture_rectangle) {
draw_rect_texture (display, type, data, width, height);
} else {
draw_pow2_texture (display, type, data, width, height);
}
glXSwapBuffers (display->display, display->window);
#if 0
/* Doesn't work */
{
ret = glXSwapBuffersMscOML (display->display, display->window, 0, 1, 0);
if (ret == 0) {
GST_DEBUG ("glXSwapBuffersMscOML failed");
}
}
#endif
gst_gl_display_unlock (display);
}
#endif
void
gst_gl_display_draw_texture (GstGLDisplay * display, GLuint texture,
int width, int height, gboolean sync)
{
g_return_if_fail (width > 0);
g_return_if_fail (height > 0);
g_return_if_fail (texture != None);
gst_gl_display_lock (display);
g_assert (display->window != None);
g_assert (display->context != NULL);
//gst_gl_display_update_attributes (display);
#if 0
/* Doesn't work */
{
int64_t ust = 1234;
int64_t mst = 1234;
int64_t sbc = 1234;
gboolean ret;
ret = glXGetSyncValuesOML (display->display, display->window,
&ust, &mst, &sbc);
GST_ERROR ("sync values %d %lld %lld %lld", ret, ust, mst, sbc);
}
#endif
if (sync) {
glXSwapIntervalSGI (1);
} else {
glXSwapIntervalSGI (0);
}
glViewport (0, 0, display->win_width, display->win_height);
glClearColor (0.3, 0.3, 0.3, 1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glDisable (GL_CULL_FACE);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glColor4f (1, 1, 1, 1);
glEnable (GL_TEXTURE_RECTANGLE_ARB);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glColor4f (1, 0, 1, 1);
gst_gl_display_check_error (display, __LINE__);
glBegin (GL_QUADS);
glNormal3f (0, 0, -1);
glTexCoord2f (width, 0);
glVertex3f (1.0, 1.0, 0);
glTexCoord2f (0, 0);
glVertex3f (-1.0, 1.0, 0);
glTexCoord2f (0, height);
glVertex3f (-1.0, -1.0, 0);
glTexCoord2f (width, height);
glVertex3f (1.0, -1.0, 0);
glEnd ();
gst_gl_display_check_error (display, __LINE__);
glXSwapBuffers (display->display, display->window);
gst_gl_display_unlock (display);
}

View File

@ -1,85 +0,0 @@
#ifndef __GST_GL_H__
#define __GST_GL_H__
#include <GL/glx.h>
#include <GL/gl.h>
#include <gst/gst.h>
#include <gst/video/video.h>
typedef struct _GstGLDisplay GstGLDisplay;
typedef struct _GstGLDisplayClass GstGLDisplayClass;
#define GST_TYPE_GL_DISPLAY \
(gst_gl_display_get_type())
#define GST_GL_DISPLAY(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_DISPLAY,GstGLDisplay))
#define GST_GL_DISPLAY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GL_DISPLAY,GstGLDisplayClass))
#define GST_IS_GL_DISPLAY(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_DISPLAY))
#define GST_IS_GL_DISPLAY_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GL_DISPLAY))
struct _GstGLDisplay {
GObject object;
Display *display;
GC gc;
XVisualInfo *visinfo;
GLXContext context;
GMutex *lock;
Screen *screen;
int screen_num;
Visual *visual;
Window root;
guint32 white;
guint32 black;
int depth;
int max_texture_size;
gboolean have_ycbcr_texture;
gboolean have_texture_rectangle;
gboolean have_color_matrix;
Window window;
gboolean visible;
Window parent_window;
int win_width;
int win_height;
};
struct _GstGLDisplayClass {
GObjectClass object_class;
};
GType gst_gl_display_get_type (void);
GstGLDisplay *gst_gl_display_new (void);
gboolean gst_gl_display_connect (GstGLDisplay *display,
const char *display_name);
gboolean gst_gl_display_can_handle_type (GstGLDisplay *display,
GstVideoFormat type);
void gst_gl_display_lock (GstGLDisplay *display);
void gst_gl_display_unlock (GstGLDisplay *display);
void gst_gl_display_set_window (GstGLDisplay *display, Window window);
void gst_gl_display_update_attributes (GstGLDisplay *display);
void gst_gl_display_clear (GstGLDisplay *display);
void gst_gl_display_draw_texture (GstGLDisplay * display, GLuint texture,
int width, int height, gboolean sync);
void gst_gl_display_check_error (GstGLDisplay *display, int line);
GLuint gst_gl_display_upload_texture_rectangle (GstGLDisplay *display,
GstVideoFormat type, void *data, int width, int height);
void gst_gl_display_set_visible (GstGLDisplay *display, gboolean visible);
void gst_gl_display_set_window_size (GstGLDisplay *display, int width,
int height);
void gst_gl_display_update_window (GstGLDisplay * display);
#endif

View File

@ -1,323 +0,0 @@
/*
* GStreamer
* Copyright (C) 2007 David 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include <gst/base/gstbasetransform.h>
#include <gst/video/video.h>
#include <gstglbuffer.h>
#define GST_CAT_DEFAULT gst_gl_download_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_TYPE_GL_DOWNLOAD (gst_gl_download_get_type())
#define GST_GL_DOWNLOAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_DOWNLOAD,GstGLDownload))
#define GST_IS_GL_DOWNLOAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_DOWNLOAD))
#define GST_GL_DOWNLOAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_GL_DOWNLOAD,GstGLDownloadClass))
#define GST_IS_GL_DOWNLOAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_GL_DOWNLOAD))
#define GST_GL_DOWNLOAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_GL_DOWNLOAD,GstGLDownloadClass))
typedef struct _GstGLDownload GstGLDownload;
typedef struct _GstGLDownloadClass GstGLDownloadClass;
typedef void (*GstGLDownloadProcessFunc) (GstGLDownload *, guint8 *, guint);
struct _GstGLDownload
{
GstBaseTransform base_transform;
/* < private > */
GstGLDisplay *display;
GstVideoFormat format;
int width;
int height;
};
struct _GstGLDownloadClass
{
GstBaseTransformClass base_transform_class;
};
static const GstElementDetails element_details = GST_ELEMENT_DETAILS ("FIXME",
"Filter/Effect",
"FIXME example filter",
"FIXME <fixme@fixme.com>");
static GstStaticPadTemplate gst_gl_download_src_pad_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_xRGB ";"
GST_VIDEO_CAPS_RGBx ";" GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_xBGR)
);
static GstStaticPadTemplate gst_gl_download_sink_pad_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_GL_VIDEO_CAPS)
);
enum
{
PROP_0
};
#define DEBUG_INIT(bla) \
GST_DEBUG_CATEGORY_INIT (gst_gl_download_debug, "gldownload", 0, "gldownload element");
GST_BOILERPLATE_FULL (GstGLDownload, gst_gl_download, GstBaseTransform,
GST_TYPE_BASE_TRANSFORM, DEBUG_INIT);
static void gst_gl_download_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_gl_download_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_gl_download_reset (GstGLDownload * download);
static gboolean gst_gl_download_set_caps (GstBaseTransform * bt,
GstCaps * incaps, GstCaps * outcaps);
static GstCaps *gst_gl_download_transform_caps (GstBaseTransform * bt,
GstPadDirection direction, GstCaps * caps);
static gboolean gst_gl_download_start (GstBaseTransform * bt);
static gboolean gst_gl_download_stop (GstBaseTransform * bt);
static GstFlowReturn gst_gl_download_transform (GstBaseTransform * trans,
GstBuffer * inbuf, GstBuffer * outbuf);
static gboolean
gst_gl_download_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
guint * size);
static void
gst_gl_download_base_init (gpointer klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_set_details (element_class, &element_details);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_gl_download_src_pad_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_gl_download_sink_pad_template));
}
static void
gst_gl_download_class_init (GstGLDownloadClass * klass)
{
GObjectClass *gobject_class;
gobject_class = (GObjectClass *) klass;
gobject_class->set_property = gst_gl_download_set_property;
gobject_class->get_property = gst_gl_download_get_property;
GST_BASE_TRANSFORM_CLASS (klass)->transform_caps =
gst_gl_download_transform_caps;
GST_BASE_TRANSFORM_CLASS (klass)->transform = gst_gl_download_transform;
GST_BASE_TRANSFORM_CLASS (klass)->start = gst_gl_download_start;
GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_download_stop;
GST_BASE_TRANSFORM_CLASS (klass)->set_caps = gst_gl_download_set_caps;
GST_BASE_TRANSFORM_CLASS (klass)->get_unit_size =
gst_gl_download_get_unit_size;
}
static void
gst_gl_download_init (GstGLDownload * download, GstGLDownloadClass * klass)
{
gst_gl_download_reset (download);
}
static void
gst_gl_download_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
//GstGLDownload *download = GST_GL_DOWNLOAD (object);
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_gl_download_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
//GstGLDownload *download = GST_GL_DOWNLOAD (object);
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_gl_download_reset (GstGLDownload * download)
{
if (download->display) {
g_object_unref (download->display);
download->display = NULL;
}
download->format = GST_VIDEO_FORMAT_RGBx;
}
static gboolean
gst_gl_download_start (GstBaseTransform * bt)
{
GstGLDownload *download = GST_GL_DOWNLOAD (bt);
download->format = GST_VIDEO_FORMAT_RGBx;
return TRUE;
}
static gboolean
gst_gl_download_stop (GstBaseTransform * bt)
{
GstGLDownload *download = GST_GL_DOWNLOAD (bt);
gst_gl_download_reset (download);
return TRUE;
}
static GstCaps *
gst_gl_download_transform_caps (GstBaseTransform * bt,
GstPadDirection direction, GstCaps * caps)
{
GstGLDownload *download;
GstStructure *structure;
GstCaps *newcaps;
GstStructure *newstruct;
const GValue *width_value;
const GValue *height_value;
const GValue *framerate_value;
const GValue *par_value;
download = GST_GL_DOWNLOAD (bt);
GST_ERROR ("transform caps %" GST_PTR_FORMAT, caps);
structure = gst_caps_get_structure (caps, 0);
width_value = gst_structure_get_value (structure, "width");
height_value = gst_structure_get_value (structure, "height");
framerate_value = gst_structure_get_value (structure, "framerate");
par_value = gst_structure_get_value (structure, "pixel-aspect-ratio");
if (direction == GST_PAD_SINK) {
newcaps = gst_caps_new_simple ("video/x-raw-rgb", NULL);
} else {
newcaps = gst_caps_new_simple ("video/x-raw-gl",
"format", G_TYPE_INT, GST_GL_BUFFER_FORMAT_RGBA,
"is_yuv", G_TYPE_BOOLEAN, FALSE, NULL);
}
newstruct = gst_caps_get_structure (newcaps, 0);
gst_structure_set_value (newstruct, "width", width_value);
gst_structure_set_value (newstruct, "height", height_value);
gst_structure_set_value (newstruct, "framerate", framerate_value);
if (par_value) {
gst_structure_set_value (newstruct, "pixel-aspect-ratio", par_value);
} else {
gst_structure_set (newstruct, "pixel-aspect-ratio", GST_TYPE_FRACTION,
1, 1, NULL);
}
GST_ERROR ("new caps %" GST_PTR_FORMAT, newcaps);
return newcaps;
}
static gboolean
gst_gl_download_set_caps (GstBaseTransform * bt, GstCaps * incaps,
GstCaps * outcaps)
{
GstGLDownload *download;
gboolean ret;
download = GST_GL_DOWNLOAD (bt);
GST_DEBUG ("called with %" GST_PTR_FORMAT, incaps);
ret = gst_video_format_parse_caps (outcaps, &download->format,
&download->width, &download->height);
if (!ret) {
GST_ERROR ("bad caps");
return FALSE;
}
return ret;
}
static gboolean
gst_gl_download_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
guint * size)
{
gboolean ret;
GstStructure *structure;
int width;
int height;
structure = gst_caps_get_structure (caps, 0);
if (gst_structure_has_name (structure, "video/x-raw-gl")) {
GstGLBufferFormat format;
ret = gst_gl_buffer_format_parse_caps (caps, &format, &width, &height);
if (ret) {
*size = gst_gl_buffer_format_get_size (format, width, height);
}
} else {
GstVideoFormat format;
ret = gst_video_format_parse_caps (caps, &format, &width, &height);
if (ret) {
*size = gst_video_format_get_size (format, width, height);
}
}
return ret;
}
static GstFlowReturn
gst_gl_download_transform (GstBaseTransform * trans, GstBuffer * inbuf,
GstBuffer * outbuf)
{
GstGLDownload *download;
GstGLBuffer *gl_inbuf = GST_GL_BUFFER (inbuf);
download = GST_GL_DOWNLOAD (trans);
if (download->display == NULL) {
download->display = g_object_ref (gl_inbuf->display);
} else {
g_assert (download->display == gl_inbuf->display);
}
GST_DEBUG ("downloading %p size %d",
GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf));
gst_gl_buffer_download (gl_inbuf, download->format, GST_BUFFER_DATA (outbuf));
return GST_FLOW_OK;
}

View File

@ -1,323 +0,0 @@
/*
* GStreamer
* Copyright (C) 2007 David 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gstglbuffer.h>
#include <gstglfilter.h>
#include "glextensions.h"
#define GST_CAT_DEFAULT gst_gl_filter_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
static GstStaticPadTemplate gst_gl_filter_src_pad_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_GL_VIDEO_CAPS)
);
static GstStaticPadTemplate gst_gl_filter_sink_pad_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_GL_VIDEO_CAPS)
);
#define DEBUG_INIT(bla) \
GST_DEBUG_CATEGORY_INIT (gst_gl_filter_debug, "glfilter", 0, "glfilter element");
GST_BOILERPLATE_FULL (GstGLFilter, gst_gl_filter, GstBaseTransform,
GST_TYPE_BASE_TRANSFORM, DEBUG_INIT);
static void gst_gl_filter_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_gl_filter_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_gl_filter_reset (GstGLFilter * filter);
static gboolean gst_gl_filter_start (GstBaseTransform * bt);
static gboolean gst_gl_filter_stop (GstBaseTransform * bt);
static gboolean gst_gl_filter_get_unit_size (GstBaseTransform * trans,
GstCaps * caps, guint * size);
static GstFlowReturn gst_gl_filter_transform (GstBaseTransform * bt,
GstBuffer * inbuf, GstBuffer * outbuf);
static GstFlowReturn gst_gl_filter_prepare_output_buffer (GstBaseTransform *
trans, GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf);
static gboolean gst_gl_filter_set_caps (GstBaseTransform * bt, GstCaps * incaps,
GstCaps * outcaps);
static gboolean gst_gl_filter_do_transform (GstGLFilter * filter,
GstGLBuffer * inbuf, GstGLBuffer * outbuf);
static void
gst_gl_filter_base_init (gpointer klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_gl_filter_src_pad_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_gl_filter_sink_pad_template));
}
static void
gst_gl_filter_class_init (GstGLFilterClass * klass)
{
GObjectClass *gobject_class;
gobject_class = (GObjectClass *) klass;
gobject_class->set_property = gst_gl_filter_set_property;
gobject_class->get_property = gst_gl_filter_get_property;
GST_BASE_TRANSFORM_CLASS (klass)->transform = gst_gl_filter_transform;
GST_BASE_TRANSFORM_CLASS (klass)->start = gst_gl_filter_start;
GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_filter_stop;
GST_BASE_TRANSFORM_CLASS (klass)->set_caps = gst_gl_filter_set_caps;
GST_BASE_TRANSFORM_CLASS (klass)->get_unit_size = gst_gl_filter_get_unit_size;
GST_BASE_TRANSFORM_CLASS (klass)->prepare_output_buffer =
gst_gl_filter_prepare_output_buffer;
}
static void
gst_gl_filter_init (GstGLFilter * filter, GstGLFilterClass * klass)
{
//gst_element_create_all_pads (GST_ELEMENT (filter));
filter->sinkpad = gst_element_get_static_pad (GST_ELEMENT (filter), "sink");
filter->srcpad = gst_element_get_static_pad (GST_ELEMENT (filter), "src");
gst_gl_filter_reset (filter);
}
static void
gst_gl_filter_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
//GstGLFilter *filter = GST_GL_FILTER (object);
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_gl_filter_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
//GstGLFilter *filter = GST_GL_FILTER (object);
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_gl_filter_reset (GstGLFilter * filter)
{
if (filter->display) {
g_object_unref (filter->display);
filter->display = NULL;
}
filter->format = GST_GL_BUFFER_FORMAT_UNKNOWN;
filter->width = 0;
filter->height = 0;
}
static gboolean
gst_gl_filter_start (GstBaseTransform * bt)
{
return TRUE;
}
static gboolean
gst_gl_filter_stop (GstBaseTransform * bt)
{
GstGLFilter *filter = GST_GL_FILTER (bt);
gst_gl_filter_reset (filter);
return TRUE;
}
static gboolean
gst_gl_filter_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
guint * size)
{
gboolean ret;
GstGLBufferFormat format;
int width;
int height;
ret = gst_gl_buffer_format_parse_caps (caps, &format, &width, &height);
if (ret) {
*size = gst_gl_buffer_format_get_size (format, width, height);
}
return TRUE;
}
static GstFlowReturn
gst_gl_filter_prepare_output_buffer (GstBaseTransform * trans,
GstBuffer * inbuf, gint size, GstCaps * caps, GstBuffer ** buf)
{
GstGLFilter *filter;
GstGLBuffer *gl_inbuf = GST_GL_BUFFER (inbuf);
GstGLBuffer *gl_outbuf;
filter = GST_GL_FILTER (trans);
if (filter->display == NULL) {
filter->display = gl_inbuf->display;
}
gl_outbuf = gst_gl_buffer_new_with_format (filter->display,
filter->format, filter->width, filter->height);
*buf = GST_BUFFER (gl_outbuf);
gst_buffer_set_caps (*buf, caps);
return GST_FLOW_OK;
}
static gboolean
gst_gl_filter_set_caps (GstBaseTransform * bt, GstCaps * incaps,
GstCaps * outcaps)
{
GstGLFilter *filter;
gboolean ret;
filter = GST_GL_FILTER (bt);
ret = gst_gl_buffer_format_parse_caps (incaps, &filter->format,
&filter->width, &filter->height);
if (!ret) {
GST_DEBUG ("bad caps");
return FALSE;
}
GST_ERROR ("set_caps %d %d", filter->width, filter->height);
return ret;
}
static GstFlowReturn
gst_gl_filter_transform (GstBaseTransform * bt, GstBuffer * inbuf,
GstBuffer * outbuf)
{
GstGLFilter *filter;
GstGLBuffer *gl_inbuf = GST_GL_BUFFER (inbuf);
GstGLBuffer *gl_outbuf = GST_GL_BUFFER (outbuf);
filter = GST_GL_FILTER (bt);
gst_gl_filter_do_transform (filter, gl_inbuf, gl_outbuf);
return GST_FLOW_OK;
}
static gboolean
gst_gl_filter_do_transform (GstGLFilter * filter,
GstGLBuffer * inbuf, GstGLBuffer * outbuf)
{
GstGLDisplay *display = inbuf->display;
GstGLFilterClass *filter_class;
unsigned int fbo;
filter_class = GST_GL_FILTER_GET_CLASS (filter);
gst_gl_display_lock (display);
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);
glClearColor (0.3, 0.3, 0.3, 1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glDisable (GL_CULL_FACE);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glColor4f (1, 1, 1, 1);
glEnable (GL_TEXTURE_RECTANGLE_ARB);
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, inbuf->texture);
filter_class->filter (filter, inbuf, outbuf);
#if 0
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glColor4f (1, 0, 1, 1);
glBegin (GL_QUADS);
glNormal3f (0, 0, -1);
glTexCoord2f (inbuf->width, 0);
glVertex3f (0.9, -0.9, 0);
glTexCoord2f (0, 0);
glVertex3f (-1.0, -1.0, 0);
glTexCoord2f (0, inbuf->height);
glVertex3f (-1.0, 1.0, 0);
glTexCoord2f (inbuf->width, inbuf->height);
glVertex3f (1.0, 1.0, 0);
glEnd ();
#endif
glFlush ();
glDeleteFramebuffersEXT (1, &fbo);
gst_gl_display_unlock (display);
return TRUE;
}

View File

@ -1,65 +0,0 @@
/*
* GStreamer
* Copyright (C) 2007 David 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 _GST_GL_FILTER_H_
#define _GST_GL_FILTER_H_
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/base/gstbasetransform.h>
#include <gstglbuffer.h>
#define GST_TYPE_GL_FILTER (gst_gl_filter_get_type())
#define GST_GL_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_FILTER,GstGLFilter))
#define GST_IS_GL_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_FILTER))
#define GST_GL_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_GL_FILTER,GstGLFilterClass))
#define GST_IS_GL_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_GL_FILTER))
#define GST_GL_FILTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_GL_FILTER,GstGLFilterClass))
typedef struct _GstGLFilter GstGLFilter;
typedef struct _GstGLFilterClass GstGLFilterClass;
typedef gboolean (*GstGLFilterProcessFunc) (GstGLFilter *filter,
GstGLBuffer *inbuf, GstGLBuffer *outbuf);
struct _GstGLFilter
{
GstBaseTransform base_transform;
GstPad *srcpad;
GstPad *sinkpad;
/* < private > */
GstGLDisplay *display;
GstGLBufferFormat format;
int width;
int height;
};
struct _GstGLFilterClass
{
GstBaseTransformClass base_transform_class;
GstGLFilterProcessFunc filter;
};
GType gst_gl_filter_get_type(void);
#endif

View File

@ -1,243 +0,0 @@
/*
* GStreamer
* Copyright (C) 2007 David 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gstglbuffer.h>
#include <gstglfilter.h>
#include "glextensions.h"
#include <string.h>
#define GST_CAT_DEFAULT gst_gl_filter_example_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_TYPE_GL_FILTER_EXAMPLE (gst_gl_filter_example_get_type())
#define GST_GL_FILTER_EXAMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_FILTER_EXAMPLE,GstGLFilterExample))
#define GST_IS_GL_FILTER_EXAMPLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_FILTER_EXAMPLE))
#define GST_GL_FILTER_EXAMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_GL_FILTER_EXAMPLE,GstGLFilterExampleClass))
#define GST_IS_GL_FILTER_EXAMPLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_GL_FILTER_EXAMPLE))
#define GST_GL_FILTER_EXAMPLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_GL_FILTER_EXAMPLE,GstGLFilterExampleClass))
typedef struct _GstGLFilterExample GstGLFilterExample;
typedef struct _GstGLFilterExampleClass GstGLFilterExampleClass;
struct _GstGLFilterExample
{
GstGLFilter filter;
/* < private > */
};
struct _GstGLFilterExampleClass
{
GstGLFilterClass filter_class;
};
static const GstElementDetails element_details = GST_ELEMENT_DETAILS ("FIXME",
"Filter/Effect",
"FIXME example filter",
"FIXME <fixme@fixme.com>");
enum
{
PROP_0
};
#define DEBUG_INIT(bla) \
GST_DEBUG_CATEGORY_INIT (gst_gl_filter_example_debug, "glfilterexample", 0, "glfilterexample element");
GST_BOILERPLATE_FULL (GstGLFilterExample, gst_gl_filter_example, GstGLFilter,
GST_TYPE_GL_FILTER, DEBUG_INIT);
static void gst_gl_filter_example_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_gl_filter_example_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static gboolean gst_gl_filter_example_filter (GstGLFilter * filter,
GstGLBuffer * inbuf, GstGLBuffer * outbuf);
static void
gst_gl_filter_example_base_init (gpointer klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_set_details (element_class, &element_details);
}
static void
gst_gl_filter_example_class_init (GstGLFilterExampleClass * klass)
{
GObjectClass *gobject_class;
gobject_class = (GObjectClass *) klass;
gobject_class->set_property = gst_gl_filter_example_set_property;
gobject_class->get_property = gst_gl_filter_example_get_property;
GST_GL_FILTER_CLASS (klass)->filter = gst_gl_filter_example_filter;
}
static void
gst_gl_filter_example_init (GstGLFilterExample * filter,
GstGLFilterExampleClass * klass)
{
}
static void
gst_gl_filter_example_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
//GstGLFilterExample *filter = GST_GL_FILTER_EXAMPLE (object);
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_gl_filter_example_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
//GstGLFilterExample *filter = GST_GL_FILTER_EXAMPLE (object);
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static gboolean
gst_gl_filter_example_filter (GstGLFilter * filter, GstGLBuffer * inbuf,
GstGLBuffer * outbuf)
{
//GstGLFilterExample *example = GST_GL_FILTER_EXAMPLE(filter);
int i, j;
double *vertex_x, *vertex_y;
glDisable (GL_CULL_FACE);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glColor4f (1, 0, 1, 1);
#define GAIN 0.5
/* just for fun. swap red and blue components. Doesn't work on my
* driver. */
{
const double matrix[16] = {
0, 0, 1.0, 0,
0, 1.0, 0, 0,
1.0, 0, 0, 0,
0, 0, 0, 1
};
glMatrixMode (GL_COLOR);
glLoadMatrixd (matrix);
glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, (1 - GAIN) / 2);
glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, (1 - GAIN) / 2);
glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, (1 - GAIN) / 2);
}
/* load raster-scanning matrix */
{
const double matrix[16] = {
2.0, 0, 0, 0,
0, 2.0, 0, 0,
0, 0, 1, 0,
-1, -1, 0, 1
};
glMatrixMode (GL_MODELVIEW);
glLoadMatrixd (matrix);
}
/* load texture raster-scanning matrix */
{
double matrix[16] = {
1.0, 0, 0, 0,
0, 1.0, 0, 0,
0, 0, 1, 0,
-1, -1, 0, 1
};
matrix[0] = inbuf->width;
matrix[5] = inbuf->height;
glMatrixMode (GL_TEXTURE);
glLoadMatrixd (matrix);
}
#define N 10
#define SCALE (1.0/N)
#define NOISE() (0.1*SCALE*g_random_double_range(-1,1))
vertex_x = malloc (sizeof (double) * (N + 1) * (N + 1));
vertex_y = malloc (sizeof (double) * (N + 1) * (N + 1));
for (j = 0; j < N + 1; j++) {
for (i = 0; i < N + 1; i++) {
vertex_x[j * (N + 1) + i] = i * SCALE + NOISE ();
vertex_y[j * (N + 1) + i] = j * SCALE + NOISE ();
}
}
for (j = 0; j < N; j++) {
for (i = 0; i < N; i++) {
glBegin (GL_QUADS);
glNormal3f (0, 0, -1);
glTexCoord2f (i * SCALE, j * SCALE);
glVertex3f (vertex_x[j * (N + 1) + i], vertex_y[j * (N + 1) + i], 0);
glTexCoord2f ((i + 1) * SCALE, j * SCALE);
glVertex3f (vertex_x[j * (N + 1) + (i + 1)],
vertex_y[j * (N + 1) + (i + 1)], 0);
glTexCoord2f ((i + 1) * SCALE, (j + 1) * SCALE);
glVertex3f (vertex_x[(j + 1) * (N + 1) + (i + 1)],
vertex_y[(j + 1) * (N + 1) + (i + 1)], 0);
glTexCoord2f (i * SCALE, (j + 1) * SCALE);
glVertex3f (vertex_x[(j + 1) * (N + 1) + i],
vertex_y[(j + 1) * (N + 1) + i], 0);
glEnd ();
}
}
free (vertex_x);
free (vertex_y);
glFlush ();
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glMatrixMode (GL_TEXTURE);
glLoadIdentity ();
glMatrixMode (GL_COLOR);
glLoadIdentity ();
glPixelTransferf (GL_POST_COLOR_MATRIX_RED_SCALE, 1.0);
glPixelTransferf (GL_POST_COLOR_MATRIX_RED_BIAS, 0);
glPixelTransferf (GL_POST_COLOR_MATRIX_GREEN_BIAS, 0);
glPixelTransferf (GL_POST_COLOR_MATRIX_BLUE_BIAS, 0);
return TRUE;
}

View File

@ -1,631 +0,0 @@
/* 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
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, 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);
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);
gst_gl_display_check_error (outbuf->display, __LINE__);
#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 ();
gst_gl_display_check_error (outbuf->display, __LINE__);
glDeleteFramebuffersEXT (1, &fbo);
gst_gl_display_check_error (outbuf->display, __LINE__);
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;
}

View File

@ -1,116 +0,0 @@
/* 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__ */

View File

@ -1,437 +0,0 @@
/*
* GStreamer
* Copyright (C) 2007 David 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include <gst/base/gstbasetransform.h>
#include <gst/video/video.h>
#include <gstglbuffer.h>
#define GST_CAT_DEFAULT gst_gl_upload_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_TYPE_GL_UPLOAD (gst_gl_upload_get_type())
#define GST_GL_UPLOAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GL_UPLOAD,GstGLUpload))
#define GST_IS_GL_UPLOAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GL_UPLOAD))
#define GST_GL_UPLOAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass) ,GST_TYPE_GL_UPLOAD,GstGLUploadClass))
#define GST_IS_GL_UPLOAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass) ,GST_TYPE_GL_UPLOAD))
#define GST_GL_UPLOAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj) ,GST_TYPE_GL_UPLOAD,GstGLUploadClass))
typedef struct _GstGLUpload GstGLUpload;
typedef struct _GstGLUploadClass GstGLUploadClass;
typedef void (*GstGLUploadProcessFunc) (GstGLUpload *, guint8 *, guint);
struct _GstGLUpload
{
GstBaseTransform base_transform;
GstPad *srcpad;
GstPad *sinkpad;
/* < private > */
GstGLDisplay *display;
GstVideoFormat video_format;
GstGLBufferFormat format;
int width;
int height;
gboolean peek;
};
struct _GstGLUploadClass
{
GstBaseTransformClass base_transform_class;
};
static const GstElementDetails element_details = GST_ELEMENT_DETAILS ("FIXME",
"Filter/Effect",
"FIXME example filter",
"FIXME <fixme@fixme.com>");
static GstStaticPadTemplate gst_gl_upload_src_pad_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_GL_VIDEO_CAPS)
);
static GstStaticPadTemplate gst_gl_upload_sink_pad_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBx ";"
GST_VIDEO_CAPS_BGRx ";"
GST_VIDEO_CAPS_xRGB ";"
GST_VIDEO_CAPS_xBGR ";"
GST_VIDEO_CAPS_YUV ("{ YUY2, UYVY, AYUV, YV12, I420 }"))
);
enum
{
PROP_0
};
#define DEBUG_INIT(bla) \
GST_DEBUG_CATEGORY_INIT (gst_gl_upload_debug, "glupload", 0, "glupload element");
GST_BOILERPLATE_FULL (GstGLUpload, gst_gl_upload, GstBaseTransform,
GST_TYPE_BASE_TRANSFORM, DEBUG_INIT);
static void gst_gl_upload_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_gl_upload_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_gl_upload_reset (GstGLUpload * upload);
static void gst_gl_upload_reset (GstGLUpload * upload);
static gboolean gst_gl_upload_set_caps (GstBaseTransform * bt,
GstCaps * incaps, GstCaps * outcaps);
static GstCaps *gst_gl_upload_transform_caps (GstBaseTransform * bt,
GstPadDirection direction, GstCaps * caps);
static gboolean gst_gl_upload_start (GstBaseTransform * bt);
static gboolean gst_gl_upload_stop (GstBaseTransform * bt);
static GstFlowReturn gst_gl_upload_prepare_output_buffer (GstBaseTransform *
trans, GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf);
static GstFlowReturn gst_gl_upload_transform (GstBaseTransform * trans,
GstBuffer * inbuf, GstBuffer * outbuf);
static gboolean gst_gl_upload_get_unit_size (GstBaseTransform * trans,
GstCaps * caps, guint * size);
static void
gst_gl_upload_base_init (gpointer klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_set_details (element_class, &element_details);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_gl_upload_src_pad_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&gst_gl_upload_sink_pad_template));
}
static void
gst_gl_upload_class_init (GstGLUploadClass * klass)
{
GObjectClass *gobject_class;
gobject_class = (GObjectClass *) klass;
gobject_class->set_property = gst_gl_upload_set_property;
gobject_class->get_property = gst_gl_upload_get_property;
GST_BASE_TRANSFORM_CLASS (klass)->transform_caps =
gst_gl_upload_transform_caps;
GST_BASE_TRANSFORM_CLASS (klass)->transform = gst_gl_upload_transform;
GST_BASE_TRANSFORM_CLASS (klass)->start = gst_gl_upload_start;
GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_upload_stop;
GST_BASE_TRANSFORM_CLASS (klass)->set_caps = gst_gl_upload_set_caps;
GST_BASE_TRANSFORM_CLASS (klass)->get_unit_size = gst_gl_upload_get_unit_size;
GST_BASE_TRANSFORM_CLASS (klass)->prepare_output_buffer =
gst_gl_upload_prepare_output_buffer;
}
static void
gst_gl_upload_init (GstGLUpload * upload, GstGLUploadClass * klass)
{
gst_gl_upload_reset (upload);
}
static void
gst_gl_upload_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
//GstGLUpload *upload = GST_GL_UPLOAD (object);
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_gl_upload_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
//GstGLUpload *upload = GST_GL_UPLOAD (object);
switch (prop_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_gl_upload_reset (GstGLUpload * upload)
{
if (upload->display) {
g_object_unref (upload->display);
upload->display = NULL;
}
upload->format = GST_GL_BUFFER_FORMAT_RGB;
upload->peek = FALSE;
}
static gboolean
gst_gl_upload_start (GstBaseTransform * bt)
{
GstGLUpload *upload = GST_GL_UPLOAD (bt);
gboolean ret;
upload->format = GST_GL_BUFFER_FORMAT_RGB;
upload->display = gst_gl_display_new ();
ret = gst_gl_display_connect (upload->display, NULL);
//upload->format = GST_VIDEO_FORMAT_RGBx;
return TRUE;
}
static gboolean
gst_gl_upload_stop (GstBaseTransform * bt)
{
GstGLUpload *upload = GST_GL_UPLOAD (bt);
gst_gl_upload_reset (upload);
return TRUE;
}
#if 0
static gboolean
gst_gl_upload_sink_setcaps (GstPad * pad, GstCaps * caps)
{
GstGLUpload *upload;
GstVideoFormat video_format;
int height;
int width;
gboolean ret;
GstCaps *srccaps;
int fps_n, fps_d;
int par_n, par_d;
upload = GST_GL_UPLOAD (gst_pad_get_parent (pad));
ret = gst_video_format_parse_caps (caps, &video_format, &width, &height);
ret &= gst_video_parse_caps_framerate (caps, &fps_n, &fps_d);
if (!ret)
return FALSE;
upload->video_format = video_format;
upload->width = width;
upload->height = height;
GST_DEBUG ("setcaps %d %d %d", video_format, width, height);
par_n = 1;
par_d = 1;
gst_video_parse_caps_pixel_aspect_ratio (caps, &par_n, &par_d);
srccaps = gst_caps_new_simple ("video/x-raw-gl",
"format", G_TYPE_INT, 0,
"width", G_TYPE_INT, width, "height", G_TYPE_INT, height,
"framerate", GST_TYPE_FRACTION, fps_n, fps_d,
"pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL);
ret = gst_pad_set_caps (upload->srcpad, srccaps);
gst_caps_unref (srccaps);
return ret;
}
#endif
#if 0
static GstFlowReturn
gst_gl_upload_chain (GstPad * pad, GstBuffer * buf)
{
GstGLUpload *upload;
GstGLBuffer *outbuf;
upload = GST_GL_UPLOAD (gst_pad_get_parent (pad));
outbuf = gst_gl_buffer_new_from_data (upload->display,
upload->video_format, upload->width, upload->height,
GST_BUFFER_DATA (buf));
gst_buffer_copy_metadata (GST_BUFFER (outbuf), buf,
GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_FLAGS);
gst_buffer_set_caps (GST_BUFFER (outbuf), GST_PAD_CAPS (upload->srcpad));
GST_DEBUG ("uploading %p size %d", GST_BUFFER_DATA (buf),
GST_BUFFER_SIZE (buf));
gst_buffer_unref (buf);
if (upload->peek) {
gst_gl_display_draw_texture (outbuf->display, outbuf->texture,
outbuf->width, outbuf->height);
}
gst_pad_push (upload->srcpad, GST_BUFFER (outbuf));
gst_object_unref (upload);
return GST_FLOW_OK;
}
#endif
static GstCaps *
gst_gl_upload_transform_caps (GstBaseTransform * bt,
GstPadDirection direction, GstCaps * caps)
{
GstGLUpload *upload;
GstStructure *structure;
GstCaps *newcaps;
GstStructure *newstruct;
const GValue *width_value;
const GValue *height_value;
const GValue *framerate_value;
const GValue *par_value;
upload = GST_GL_UPLOAD (bt);
GST_ERROR ("transform caps %" GST_PTR_FORMAT, caps);
structure = gst_caps_get_structure (caps, 0);
width_value = gst_structure_get_value (structure, "width");
height_value = gst_structure_get_value (structure, "height");
framerate_value = gst_structure_get_value (structure, "framerate");
par_value = gst_structure_get_value (structure, "pixel-aspect-ratio");
if (direction == GST_PAD_SRC) {
newcaps = gst_caps_new_simple ("video/x-raw-rgb", NULL);
} else {
newcaps = gst_caps_new_simple ("video/x-raw-gl",
"format", G_TYPE_INT, GST_GL_BUFFER_FORMAT_RGBA,
"is_yuv", G_TYPE_BOOLEAN, FALSE, NULL);
}
newstruct = gst_caps_get_structure (newcaps, 0);
gst_structure_set_value (newstruct, "width", width_value);
gst_structure_set_value (newstruct, "height", height_value);
gst_structure_set_value (newstruct, "framerate", framerate_value);
if (par_value) {
gst_structure_set_value (newstruct, "pixel-aspect-ratio", par_value);
} else {
gst_structure_set (newstruct, "pixel-aspect-ratio", GST_TYPE_FRACTION,
1, 1, NULL);
}
GST_ERROR ("new caps %" GST_PTR_FORMAT, newcaps);
return newcaps;
}
static gboolean
gst_gl_upload_set_caps (GstBaseTransform * bt, GstCaps * incaps,
GstCaps * outcaps)
{
GstGLUpload *upload;
gboolean ret;
upload = GST_GL_UPLOAD (bt);
GST_DEBUG ("called with %" GST_PTR_FORMAT, incaps);
ret = gst_video_format_parse_caps (incaps, &upload->video_format,
&upload->width, &upload->height);
if (!ret) {
GST_DEBUG ("bad caps");
return FALSE;
}
return ret;
}
static gboolean
gst_gl_upload_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
guint * size)
{
gboolean ret;
GstStructure *structure;
int width;
int height;
structure = gst_caps_get_structure (caps, 0);
if (gst_structure_has_name (structure, "video/x-raw-gl")) {
GstGLBufferFormat format;
ret = gst_gl_buffer_format_parse_caps (caps, &format, &width, &height);
if (ret) {
*size = gst_gl_buffer_format_get_size (format, width, height);
}
} else {
GstVideoFormat format;
ret = gst_video_format_parse_caps (caps, &format, &width, &height);
if (ret) {
*size = gst_video_format_get_size (format, width, height);
}
}
return TRUE;
}
static GstFlowReturn
gst_gl_upload_prepare_output_buffer (GstBaseTransform * trans,
GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf)
{
GstGLUpload *upload;
GstGLBuffer *gl_outbuf;
upload = GST_GL_UPLOAD (trans);
gl_outbuf = gst_gl_buffer_new_from_video_format (upload->display,
upload->video_format, upload->width, upload->height);
*buf = GST_BUFFER (gl_outbuf);
gst_buffer_set_caps (*buf, caps);
return GST_FLOW_OK;
}
static GstFlowReturn
gst_gl_upload_transform (GstBaseTransform * trans, GstBuffer * inbuf,
GstBuffer * outbuf)
{
GstGLUpload *upload;
GstGLBuffer *gl_outbuf = GST_GL_BUFFER (outbuf);
upload = GST_GL_UPLOAD (trans);
GST_DEBUG ("uploading %p size %d",
GST_BUFFER_DATA (inbuf), GST_BUFFER_SIZE (inbuf));
gst_gl_buffer_upload (gl_outbuf, upload->video_format,
GST_BUFFER_DATA (inbuf));
if (upload->peek) {
gst_gl_display_draw_texture (gl_outbuf->display, gl_outbuf->texture,
gl_outbuf->width, gl_outbuf->height, FALSE);
}
return GST_FLOW_OK;
}

View File

@ -1,80 +0,0 @@
/* GStreamer
* Copyright (C) 2003 Julien Moutte <julien@moutte.net>
* Copyright (C) 2005,2006,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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gst.h>
#include <gst/interfaces/xoverlay.h>
#include <gst/video/gstvideosink.h>
#include <gst/video/video.h>
#include <string.h>
#include <glimagesink.h>
GType gst_gl_upload_get_type (void);
GType gst_gl_download_get_type (void);
GType gst_gl_filter_example_get_type (void);
GType gst_gl_convert_get_type (void);
GType gst_gl_test_src_get_type (void);
static gboolean
plugin_init (GstPlugin * plugin)
{
GST_DEBUG_CATEGORY_INIT (gst_debug_glimage_sink, "glimagesink", 0,
"glimagesink element");
if (!gst_element_register (plugin, "glimagesink",
GST_RANK_SECONDARY, GST_TYPE_GLIMAGE_SINK)) {
return FALSE;
}
if (!gst_element_register (plugin, "glupload",
GST_RANK_NONE, gst_gl_upload_get_type ())) {
return FALSE;
}
if (!gst_element_register (plugin, "gldownload",
GST_RANK_NONE, gst_gl_download_get_type ())) {
return FALSE;
}
if (!gst_element_register (plugin, "glfilterexample",
GST_RANK_NONE, gst_gl_filter_example_get_type ())) {
return FALSE;
}
if (!gst_element_register (plugin, "glconvert",
GST_RANK_NONE, gst_gl_convert_get_type ())) {
return FALSE;
}
if (!gst_element_register (plugin, "gltestsrc",
GST_RANK_NONE, gst_gl_test_src_get_type ())) {
return FALSE;
}
return TRUE;
}
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"glimagesink",
"OpenGL video output plugin",
plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)