static void gst_gldisplay_glutGenerateOutputVideoFBO (GstGLDisplay *display);
static void gst_gl_display_glutGenerateFBO (GstGLDisplay *display);
static void gst_gl_display_glutUseFBO (GstGLDisplay *display);
+static void gst_gl_display_glutUseFBO2 (GstGLDisplay *display);
static void gst_gl_display_glutDestroyFBO (GstGLDisplay *display);
static void gst_gl_display_glutDestroyWindow (GstGLDisplay* display);
static void gst_gl_display_glutSetVisibleWindow (GstGLDisplay* display);
display->cond_video = g_cond_new ();
display->cond_generateFBO = g_cond_new ();
display->cond_useFBO = g_cond_new ();
+ display->cond_useFBO2 = g_cond_new ();
display->cond_destroyFBO = g_cond_new ();
display->cond_create = g_cond_new ();
display->cond_destroy = g_cond_new ();
display->usedTextureFBOWidth = 0;
display->usedTextureFBOHeight = 0;
display->glsceneFBO_cb = NULL;
+ display->glsceneFBO_cb2 = NULL;
+ display->p1 = NULL;
+ display->p2 = NULL;
display->inputTextureWidth = 0;
display->inputTextureHeight = 0;
display->inputTexture = 0;
g_cond_free (display->cond_useFBO);
display->cond_useFBO = NULL;
}
+ if (display->cond_useFBO2) {
+ g_cond_free (display->cond_useFBO2);
+ display->cond_useFBO2 = NULL;
+ }
if (display->cond_destroyFBO) {
g_cond_free (display->cond_destroyFBO);
display->cond_destroyFBO = NULL;
display->clientDrawCallback = NULL;
if (display->glsceneFBO_cb)
display->glsceneFBO_cb = NULL;
+ if (display->glsceneFBO_cb2)
+ display->glsceneFBO_cb2 = NULL;
+ if (display->p1)
+ display->p1 = NULL;
+ if (display->p2)
+ display->p2 = NULL;
//at this step, the next condition imply that the last display has been pushed
if (g_hash_table_size (gst_gl_display_map) == 0)
/* Called by the idle funtion */
static void
+gst_gl_display_glutUseFBO2 (GstGLDisplay *display)
+{
+ glutSetWindow (display->glutWinId);
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, display->usedFBO);
+
+ glPushAttrib(GL_VIEWPORT_BIT);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ //gluPerspective(45, (gfloat)display->usedTextureFBOWidth/(gfloat)display->usedTextureFBOHeight, 0.1, 100);
+ gluOrtho2D(0.0, display->usedTextureFBOWidth, 0.0, display->usedTextureFBOHeight);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glViewport(0, 0, display->usedTextureFBOWidth, display->usedTextureFBOHeight);
+
+ glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ //the opengl scene
+ display->glsceneFBO_cb2 (display->p1, display->p2, display->usedTextureFBOWidth, display->usedTextureFBOHeight);
+
+ glDrawBuffer(GL_NONE);
+
+ glUseProgramObjectARB (0);
+
+ glDisable(GL_TEXTURE_RECTANGLE_ARB);
+
+ glPopMatrix();
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopAttrib();
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+ g_cond_signal (display->cond_useFBO2);
+}
+
+
+/* Called by the idle funtion */
+static void
gst_gl_display_glutDestroyFBO (GstGLDisplay *display)
{
case GST_GL_DISPLAY_ACTION_USEFBO:
gst_gl_display_glutUseFBO (msg->display);
break;
+ case GST_GL_DISPLAY_ACTION_USEFBO2:
+ gst_gl_display_glutUseFBO2 (msg->display);
+ break;
case GST_GL_DISPLAY_ACTION_OVFBO:
gst_gldisplay_glutGenerateOutputVideoFBO (msg->display);
break;
case GST_GL_DISPLAY_ACTION_GENFBO:
case GST_GL_DISPLAY_ACTION_DELFBO:
case GST_GL_DISPLAY_ACTION_USEFBO:
+ case GST_GL_DISPLAY_ACTION_USEFBO2:
case GST_GL_DISPLAY_ACTION_OVFBO:
//msg is out of date if the associated display is not in the map
if (!g_hash_table_lookup (gst_gl_display_map, GINT_TO_POINTER (msg->glutWinId)))
/* Called by gst_gl elements */
void
+gst_gl_display_useFBO2 (GstGLDisplay* display, gint textureFBOWidth, gint textureFBOheight,
+ guint fbo, guint depthbuffer, guint textureFBO, GLCB2 cb2,
+ gpointer* p1, gpointer* p2)
+{
+ gst_gl_display_lock (display);
+ display->usedFBO = fbo;
+ display->usedDepthBuffer = depthbuffer;
+ display->usedTextureFBO = textureFBO;
+ display->usedTextureFBOWidth = textureFBOWidth;
+ display->usedTextureFBOHeight = textureFBOheight;
+ display->glsceneFBO_cb2 = cb2;
+ gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_USEFBO2, display);
+ g_cond_wait (display->cond_useFBO2, display->mutex);
+ gst_gl_display_unlock (display);
+}
+
+
+/* Called by gst_gl elements */
+void
gst_gl_display_rejectFBO (GstGLDisplay* display, guint fbo,
guint depthbuffer, guint texture)
{
gst_gl_display_lock (display);
//check if video format has been setup
- if (!display->currentVideo_format)
+ if (!display->displayedTexture)
{
gst_gl_display_unlock (display);
return;
GST_GL_DISPLAY_ACTION_GENFBO,
GST_GL_DISPLAY_ACTION_DELFBO,
GST_GL_DISPLAY_ACTION_USEFBO,
+ GST_GL_DISPLAY_ACTION_USEFBO2,
GST_GL_DISPLAY_ACTION_OVFBO
} GstGLDisplayAction;
//opengl scene callback
typedef void (* GLCB) ( GLuint, GLuint, GLuint);
+typedef void (* GLCB2) ( gpointer* p1, gpointer* p2, gint w, gint h);
struct _GstGLDisplay {
GObject object;
GCond* cond_video;
GCond* cond_generateFBO;
GCond* cond_useFBO;
+ GCond* cond_useFBO2;
GCond* cond_destroyFBO;
GCond* cond_download;
GLuint usedTextureFBOWidth;
GLuint usedTextureFBOHeight;
GLCB glsceneFBO_cb;
+ GLCB2 glsceneFBO_cb2;
+ gpointer* p1;
+ gpointer* p2;
GLuint inputTextureWidth;
GLuint inputTextureHeight;
GLuint inputTexture;
void gst_gl_display_useFBO (GstGLDisplay* display, gint textureFBOWidth, gint textureFBOheight,
guint fbo, guint depthbuffer, guint textureFBO, GLCB cb,
guint inputTextureWidth, guint inputTextureHeight, guint inputTexture);
+void gst_gl_display_useFBO2 (GstGLDisplay* display, gint textureFBOWidth, gint textureFBOheight,
+ guint fbo, guint depthbuffer, guint textureFBO, GLCB2 cb,
+ gpointer* p1, gpointer* p2);
void gst_gl_display_rejectFBO (GstGLDisplay* display, guint fbo,
guint depthbuffer, guint texture);
void gst_gl_display_initDonwloadFBO (GstGLDisplay* display, gint width, gint height);
gboolean res;
gint width, height, rate_denominator, rate_numerator;
GstGLTestSrc* gltestsrc;
+ static gint y = 0;
gltestsrc = GST_GL_TEST_SRC (bsrc);
GST_DEBUG_OBJECT (gltestsrc, "size %dx%d, %d/%d fps",
gltestsrc->width, gltestsrc->height,
gltestsrc->rate_numerator, gltestsrc->rate_denominator);
+
+ gltestsrc->display = gst_gl_display_new ();
+
+ gst_gl_display_initGLContext (gltestsrc->display,
+ 50, y++ * (gltestsrc->height+50) + 50,
+ gltestsrc->width, gltestsrc->height,
+ gltestsrc->width, gltestsrc->height, 0, FALSE);
+
+ gst_gl_display_requestFBO (gltestsrc->display, gltestsrc->width, gltestsrc->height,
+ &gltestsrc->fbo, &gltestsrc->depthbuffer, &gltestsrc->texture);
}
return res;
}
gst_buffer_set_caps (GST_BUFFER (outbuf),
GST_PAD_CAPS (GST_BASE_SRC_PAD (psrc)));
+
+ if (src->pattern_type == GST_GL_TEST_SRC_BLINK)
+ {
+ if (src->n_frames & 0x1)
+ src->make_image = gst_gl_test_src_white;
+ else
+ src->make_image = gst_gl_test_src_black;
+ }
//blocking call, generate a FBO
- gst_gl_display_useFBO (src->display, src->width, src->height,
- src->fbo, src->depthbuffer, src->texture, NULL,
- 0, 0, 0);
+ gst_gl_display_useFBO2 (src->display, src->width, src->height,
+ src->fbo, src->depthbuffer, src->texture, (GLCB2)src->make_image,
+ (gpointer*)src, (gpointer*)outbuf);
outbuf->textureGL = src->texture;
- /*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);
+ 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;
}
- } else {
- src->make_image (src, outbuf, src->width, src->height);
- }*/
-
- 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;
+ src->running_time = next_time;
- *buffer = GST_BUFFER (outbuf);
+ *buffer = GST_BUFFER (outbuf);
- return GST_FLOW_OK;
+ return GST_FLOW_OK;
not_negotiated:
{
static gboolean
gst_gl_test_src_start (GstBaseSrc* basesrc)
{
- GstGLTestSrc* src = GST_GL_TEST_SRC (basesrc);
- static gint y = 0;
-
- src->running_time = 0;
- src->n_frames = 0;
- src->negotiated = FALSE;
- src->display = gst_gl_display_new ();
-
- gst_gl_display_initGLContext (src->display,
- 50, y++ * (src->height+50) + 50,
- src->width, src->height,
- src->width, src->height, 0, FALSE);
+ GstGLTestSrc* src = GST_GL_TEST_SRC (basesrc);
- gst_gl_display_requestFBO (src->display, src->width, src->height,
- &src->fbo, &src->depthbuffer, &src->texture);
+ src->running_time = 0;
+ src->n_frames = 0;
+ src->negotiated = FALSE;
- return TRUE;
+ return TRUE;
}
static gboolean
{
GstGLTestSrc* src = GST_GL_TEST_SRC (basesrc);
- g_object_unref (src->display);
+ if (src->display)
+ {
+ //blocking call, delete the FBO
+ gst_gl_display_rejectFBO (src->display, src->fbo,
+ src->depthbuffer, src->texture);
+ g_object_unref (src->display);
+ src->display = NULL;
+ }
return TRUE;
}