[515/906] GstGLDisplay: rework gen_texture and upload

rename functions so that other code can create textures in the GL thread
change upload functions to take a GstVideoFrame
default to GLSL for upload conversion
This commit is contained in:
Matthew Waters 2012-07-06 18:51:02 +10:00 committed by Tim-Philipp Müller
parent ffdc6d496e
commit 6528aba8c9
2 changed files with 64 additions and 154 deletions

View file

@ -62,7 +62,6 @@ static void gst_gl_display_finalize (GObject * object);
gpointer gst_gl_display_thread_create_context (GstGLDisplay * display); gpointer gst_gl_display_thread_create_context (GstGLDisplay * display);
void gst_gl_display_thread_destroy_context (GstGLDisplay * display); void gst_gl_display_thread_destroy_context (GstGLDisplay * display);
void gst_gl_display_thread_run_generic (GstGLDisplay * display); void gst_gl_display_thread_run_generic (GstGLDisplay * display);
void gst_gl_display_thread_gen_texture (GstGLDisplay * display);
#ifdef OPENGL_ES2 #ifdef OPENGL_ES2
void gst_gl_display_thread_init_redisplay (GstGLDisplay * display); void gst_gl_display_thread_init_redisplay (GstGLDisplay * display);
#endif #endif
@ -83,13 +82,8 @@ void gst_gl_display_unlock (GstGLDisplay * display);
void gst_gl_display_on_resize (GstGLDisplay * display, gint width, gint height); void gst_gl_display_on_resize (GstGLDisplay * display, gint width, gint height);
void gst_gl_display_on_draw (GstGLDisplay * display); void gst_gl_display_on_draw (GstGLDisplay * display);
void gst_gl_display_on_close (GstGLDisplay * display); void gst_gl_display_on_close (GstGLDisplay * display);
void gst_gl_display_glgen_texture (GstGLDisplay * display, GLuint * pTexture, void gst_gl_display_del_texture_thread (GstGLDisplay * display,
GLint width, GLint height); GLuint * pTexture);
void gst_gl_display_gldel_texture (GstGLDisplay * display, GLuint * pTexture,
GLint width, GLint height);
gboolean gst_gl_display_texture_pool_func_clean (gpointer key, gpointer value,
gpointer data);
void gst_gl_display_check_framebuffer_status (void);
/* To not make gst_gl_display_thread_do_upload /* To not make gst_gl_display_thread_do_upload
* and gst_gl_display_thread_do_download too big */ * and gst_gl_display_thread_do_download too big */
@ -99,7 +93,7 @@ void gst_gl_display_thread_do_upload_fill (GstGLDisplay * display);
void gst_gl_display_thread_do_upload_draw (GstGLDisplay * display); void gst_gl_display_thread_do_upload_draw (GstGLDisplay * display);
void gst_gl_display_thread_do_download_draw_rgb (GstGLDisplay * display); void gst_gl_display_thread_do_download_draw_rgb (GstGLDisplay * display);
void gst_gl_display_thread_do_download_draw_yuv (GstGLDisplay * display); void gst_gl_display_thread_do_download_draw_yuv (GstGLDisplay * display);
void gst_gl_display_gen_texture_window_cb (GstGLDisplay * display);
//------------------------------------------------------------ //------------------------------------------------------------
//---------------------- For klass GstGLDisplay --------------- //---------------------- For klass GstGLDisplay ---------------
@ -144,6 +138,7 @@ gst_gl_display_init (GstGLDisplay * display)
display->gen_texture = 0; display->gen_texture = 0;
display->gen_texture_width = 0; display->gen_texture_width = 0;
display->gen_texture_height = 0; display->gen_texture_height = 0;
display->gen_texture_video_format = GST_VIDEO_FORMAT_UNKNOWN;
//client callbacks //client callbacks
display->clientReshapeCallback = NULL; display->clientReshapeCallback = NULL;
@ -160,10 +155,10 @@ gst_gl_display_init (GstGLDisplay * display)
display->upload_width = 0; display->upload_width = 0;
display->upload_height = 0; display->upload_height = 0;
display->upload_video_format = GST_VIDEO_FORMAT_RGBx; display->upload_video_format = GST_VIDEO_FORMAT_RGBx;
display->upload_colorspace_conversion = GST_GL_DISPLAY_CONVERSION_MESA; display->upload_colorspace_conversion = GST_GL_DISPLAY_CONVERSION_GLSL;
display->upload_data_width = 0; display->upload_data_width = 0;
display->upload_data_height = 0; display->upload_data_height = 0;
display->upload_data = NULL; display->upload_frame = NULL;
//foreign gl context //foreign gl context
display->external_gl_context = 0; display->external_gl_context = 0;
@ -781,11 +776,11 @@ gst_gl_display_thread_destroy_context (GstGLDisplay * display)
} }
#endif #endif
GST_INFO ("Cleaning texture pool"); /* GST_INFO ("Cleaning texture pool");
//clean up the texture pool //clean up the texture pool
g_hash_table_foreach_remove (display->texture_pool, g_hash_table_foreach_remove (display->texture_pool,
gst_gl_display_texture_pool_func_clean, NULL); gst_gl_display_texture_pool_func_clean, NULL);*/
GST_INFO ("Context destroyed"); GST_INFO ("Context destroyed");
} }
@ -797,17 +792,6 @@ gst_gl_display_thread_run_generic (GstGLDisplay * display)
display->generic_callback (display, display->data); display->generic_callback (display, display->data);
} }
/* Called in the gl thread */
void
gst_gl_display_thread_gen_texture (GstGLDisplay * display)
{
//setup a texture to render to (this one will be in a gl buffer)
gst_gl_display_glgen_texture (display, &display->gen_texture,
display->gen_texture_width, display->gen_texture_height);
}
#ifdef OPENGL_ES2 #ifdef OPENGL_ES2
/* Called in the gl thread */ /* Called in the gl thread */
void void
@ -1131,6 +1115,10 @@ gst_gl_display_thread_init_upload (GstGLDisplay * display)
void void
gst_gl_display_thread_do_upload (GstGLDisplay * display) gst_gl_display_thread_do_upload (GstGLDisplay * display)
{ {
GST_TRACE ("uploading video frame %" GST_PTR_FORMAT " with dimensions: %ix%i",
display->upload_frame, display->upload_data_width,
display->upload_data_height);
gst_gl_display_thread_do_upload_fill (display); gst_gl_display_thread_do_upload_fill (display);
switch (display->upload_video_format) { switch (display->upload_video_format) {
@ -2014,17 +2002,24 @@ gst_gl_display_on_close (GstGLDisplay * display)
gst_gl_display_set_error (display, "Output window was closed"); gst_gl_display_set_error (display, "Output window was closed");
} }
void
gst_gl_display_gen_texture_window_cb (GstGLDisplay * display)
{
gst_gl_display_gen_texture_thread (display, &display->gen_texture,
display->gen_texture_video_format, display->gen_texture_width,
display->gen_texture_height);
}
/* Generate a texture if no one is available in the pool /* Generate a texture if no one is available in the pool
* Called in the gl thread */ * Called in the gl thread */
void void
gst_gl_display_glgen_texture (GstGLDisplay * display, GLuint * pTexture, gst_gl_display_gen_texture_thread (GstGLDisplay * display, GLuint * pTexture,
GLint width, GLint height) GstVideoFormat v_format, GLint width, GLint height)
{ {
glGenTextures (1, pTexture); glGenTextures (1, pTexture);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, *pTexture); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, *pTexture);
switch (display->upload_video_format) { switch (v_format) {
case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR: case GST_VIDEO_FORMAT_BGR:
case GST_VIDEO_FORMAT_RGBx: case GST_VIDEO_FORMAT_RGBx:
@ -2081,72 +2076,12 @@ gst_gl_display_glgen_texture (GstGLDisplay * display, GLuint * pTexture,
GST_LOG ("generated texture id:%d", *pTexture); GST_LOG ("generated texture id:%d", *pTexture);
} }
/* Delete a texture, actually the texture is just added to the pool
* Called in the gl thread */
void void
gst_gl_display_gldel_texture (GstGLDisplay * display, GLuint * pTexture, gst_gl_display_del_texture_thread (GstGLDisplay * display, GLuint * pTexture)
GLint width, GLint height)
{ {
//Each existing texture is destroyed only when the pool is destroyed glDeleteTextures (1, pTexture);
//The pool of textures is deleted in the GstGLDisplay destructor
GQueue *sub_texture_pool = NULL;
GstGLDisplayTex *tex = NULL;
//make a unique key from w and h
//the key cannot be w*h because (4*6 = 6*4 = 2*12 = 12*2)
guint key = (gint) width;
key <<= 16;
key |= (gint) height;
sub_texture_pool =
g_hash_table_lookup (display->texture_pool, GUINT_TO_POINTER (key));
//if the size is known
if (!sub_texture_pool) {
sub_texture_pool = g_queue_new ();
g_hash_table_insert (display->texture_pool, GUINT_TO_POINTER (key),
sub_texture_pool);
GST_INFO ("one more sub texture pool inserted: %d ", key);
GST_INFO ("nb sub texture pools: %d",
g_hash_table_size (display->texture_pool));
}
//contruct a sub texture pool element
tex = g_new0 (GstGLDisplayTex, 1);
tex->texture = *pTexture;
*pTexture = 0;
//add tex to the pool, it makes texture allocation reusable
g_queue_push_tail (sub_texture_pool, tex);
GST_LOG ("texture id:%d added to the sub texture pool: %d",
tex->texture, key);
GST_LOG ("%d texture(s) in the sub texture pool: %d",
g_queue_get_length (sub_texture_pool), key);
} }
/* call when a sub texture pool is removed from the texture pool (ghash table) */
gboolean
gst_gl_display_texture_pool_func_clean (gpointer key, gpointer value,
gpointer data)
{
GQueue *sub_texture_pool = (GQueue *) value;
while (g_queue_get_length (sub_texture_pool) > 0) {
GstGLDisplayTex *tex = g_queue_pop_head (sub_texture_pool);
GST_INFO ("trying to delete texture id: %d deleted", tex->texture);
glDeleteTextures (1, &tex->texture);
GST_INFO ("texture id: %d deleted", tex->texture);
g_free (tex);
}
g_queue_free (sub_texture_pool);
return TRUE;
}
/* called in the gl thread */ /* called in the gl thread */
void void
gst_gl_display_check_framebuffer_status (void) gst_gl_display_check_framebuffer_status (void)
@ -2279,38 +2214,17 @@ gst_gl_display_thread_add (GstGLDisplay * display,
/* Called by gst_gl_buffer_new */ /* Called by gst_gl_buffer_new */
void void
gst_gl_display_gen_texture (GstGLDisplay * display, GLuint * pTexture, gst_gl_display_gen_texture (GstGLDisplay * display, GLuint * pTexture,
GLint width, GLint height) GstVideoFormat v_format, GLint width, GLint height)
{ {
gst_gl_display_lock (display); gst_gl_display_lock (display);
if (display->isAlive) { if (display->isAlive) {
GQueue *sub_texture_pool = NULL; display->gen_texture_width = width;
display->gen_texture_height = height;
//make a unique key from w and h display->gen_texture_video_format = v_format;
//the key cannot be w*h because (4*6 = 6*4 = 2*12 = 12*2) gst_gl_window_send_message (display->gl_window,
guint key = (gint) width; GST_GL_WINDOW_CB (gst_gl_display_gen_texture_window_cb), display);
key <<= 16; *pTexture = display->gen_texture;
key |= (gint) height;
sub_texture_pool =
g_hash_table_lookup (display->texture_pool, GUINT_TO_POINTER (key));
//if there is a sub texture pool associated to the given key
if (sub_texture_pool && g_queue_get_length (sub_texture_pool) > 0) {
//a texture is available in the pool
GstGLDisplayTex *tex = g_queue_pop_head (sub_texture_pool);
*pTexture = tex->texture;
g_free (tex);
GST_LOG ("get texture id:%d from the sub texture pool: %d",
*pTexture, key);
} else {
//only in this case we want to ask a texture from the gl thread
display->gen_texture_width = width;
display->gen_texture_height = height;
gst_gl_window_send_message (display->gl_window,
GST_GL_WINDOW_CB (gst_gl_display_thread_gen_texture), display);
*pTexture = display->gen_texture;
}
} else } else
*pTexture = 0; *pTexture = 0;
@ -2320,12 +2234,11 @@ gst_gl_display_gen_texture (GstGLDisplay * display, GLuint * pTexture,
/* Called by gst_gl_buffer_finalize */ /* Called by gst_gl_buffer_finalize */
void void
gst_gl_display_del_texture (GstGLDisplay * display, GLuint texture, GLint width, gst_gl_display_del_texture (GstGLDisplay * display, GLuint * pTexture)
GLint height)
{ {
gst_gl_display_lock (display); gst_gl_display_lock (display);
if (texture) { if (*pTexture) {
gst_gl_display_gldel_texture (display, &texture, width, height); gst_gl_display_del_texture_thread (display, pTexture);
} }
gst_gl_display_unlock (display); gst_gl_display_unlock (display);
} }
@ -2356,7 +2269,7 @@ gst_gl_display_init_upload (GstGLDisplay * display, GstVideoFormat video_format,
/* Called by the first gl element of a video/x-raw-gl flow */ /* Called by the first gl element of a video/x-raw-gl flow */
gboolean gboolean
gst_gl_display_do_upload (GstGLDisplay * display, GLuint texture, gst_gl_display_do_upload (GstGLDisplay * display, GLuint texture,
gint data_width, gint data_height, gpointer data) GstVideoFrame * frame)
{ {
gboolean isAlive = TRUE; gboolean isAlive = TRUE;
@ -2364,9 +2277,7 @@ gst_gl_display_do_upload (GstGLDisplay * display, GLuint texture,
isAlive = display->isAlive; isAlive = display->isAlive;
if (isAlive) { if (isAlive) {
display->upload_outtex = texture; display->upload_outtex = texture;
display->upload_data_width = data_width; display->upload_frame = frame;
display->upload_data_height = data_height;
display->upload_data = data;
gst_gl_window_send_message (display->gl_window, gst_gl_window_send_message (display->gl_window,
GST_GL_WINDOW_CB (gst_gl_display_thread_do_upload), display); GST_GL_WINDOW_CB (gst_gl_display_thread_do_upload), display);
isAlive = display->isAlive; isAlive = display->isAlive;
@ -2809,13 +2720,12 @@ gst_gl_display_thread_do_upload_fill (GstGLDisplay * display)
{ {
GstVideoInfo vinfo; GstVideoInfo vinfo;
gint width, height; gint width, height;
gpointer data; GstVideoFrame *frame;
width = display->upload_data_width; frame = display->upload_frame;
height = display->upload_data_height; vinfo = frame->info;
data = display->upload_data; width = GST_VIDEO_INFO_WIDTH (&vinfo);
gst_video_info_set_format (&vinfo, display->upload_video_format, width, height = GST_VIDEO_INFO_HEIGHT (&vinfo);
height);
switch (display->upload_video_format) { switch (display->upload_video_format) {
case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_RGB:
@ -2865,48 +2775,48 @@ gst_gl_display_thread_do_upload_fill (GstGLDisplay * display)
switch (display->upload_video_format) { switch (display->upload_video_format) {
case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_RGB:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_RGB, GL_UNSIGNED_BYTE, data); GL_RGB, GL_UNSIGNED_BYTE, frame->data[0]);
break; break;
case GST_VIDEO_FORMAT_BGR: case GST_VIDEO_FORMAT_BGR:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_BGR, GL_UNSIGNED_BYTE, data); GL_BGR, GL_UNSIGNED_BYTE, frame->data[0]);
break; break;
case GST_VIDEO_FORMAT_RGBx: case GST_VIDEO_FORMAT_RGBx:
case GST_VIDEO_FORMAT_RGBA: case GST_VIDEO_FORMAT_RGBA:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_RGBA, GL_UNSIGNED_BYTE, data); GL_RGBA, GL_UNSIGNED_BYTE, frame->data[0]);
break; break;
case GST_VIDEO_FORMAT_BGRx: case GST_VIDEO_FORMAT_BGRx:
case GST_VIDEO_FORMAT_BGRA: case GST_VIDEO_FORMAT_BGRA:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_BGRA, GL_UNSIGNED_BYTE, data); GL_BGRA, GL_UNSIGNED_BYTE, frame->data[0]);
break; break;
case GST_VIDEO_FORMAT_AYUV: case GST_VIDEO_FORMAT_AYUV:
case GST_VIDEO_FORMAT_xRGB: case GST_VIDEO_FORMAT_xRGB:
case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_ARGB:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, data); GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, frame->data[0]);
break; break;
case GST_VIDEO_FORMAT_xBGR: case GST_VIDEO_FORMAT_xBGR:
case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_ABGR:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data); GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, frame->data[0]);
break; break;
case GST_VIDEO_FORMAT_YUY2: case GST_VIDEO_FORMAT_YUY2:
switch (display->upload_colorspace_conversion) { switch (display->upload_colorspace_conversion) {
case GST_GL_DISPLAY_CONVERSION_GLSL: case GST_GL_DISPLAY_CONVERSION_GLSL:
case GST_GL_DISPLAY_CONVERSION_MATRIX: case GST_GL_DISPLAY_CONVERSION_MATRIX:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data); GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, frame->data[0]);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex_u); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex_u);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
GST_ROUND_UP_2 (width) / 2, height, GST_ROUND_UP_2 (width) / 2, height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, frame->data[0]);
break; break;
case GST_GL_DISPLAY_CONVERSION_MESA: case GST_GL_DISPLAY_CONVERSION_MESA:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, data); GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_REV_MESA, frame->data[0]);
break; break;
default: default:
gst_gl_display_set_error (display, "Unknow colorspace conversion %d", gst_gl_display_set_error (display, "Unknow colorspace conversion %d",
@ -2918,16 +2828,16 @@ gst_gl_display_thread_do_upload_fill (GstGLDisplay * display)
case GST_GL_DISPLAY_CONVERSION_GLSL: case GST_GL_DISPLAY_CONVERSION_GLSL:
case GST_GL_DISPLAY_CONVERSION_MATRIX: case GST_GL_DISPLAY_CONVERSION_MATRIX:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data); GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, frame->data[0]);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex_u); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex_u);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
GST_ROUND_UP_2 (width) / 2, height, GST_ROUND_UP_2 (width) / 2, height,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data); GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, frame->data[0]);
break; break;
case GST_GL_DISPLAY_CONVERSION_MESA: case GST_GL_DISPLAY_CONVERSION_MESA:
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, data); GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, frame->data[0]);
break; break;
default: default:
gst_gl_display_set_error (display, "Unknow colorspace conversion %d", gst_gl_display_set_error (display, "Unknow colorspace conversion %d",
@ -2938,19 +2848,17 @@ gst_gl_display_thread_do_upload_fill (GstGLDisplay * display)
case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_YV12:
{ {
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, width, height,
GL_LUMINANCE, GL_UNSIGNED_BYTE, data); GL_LUMINANCE, GL_UNSIGNED_BYTE, frame->data[0]);
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex_u); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex_u);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2, GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2,
GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE, GL_UNSIGNED_BYTE, frame->data[1]);
(guint8 *) data + GST_VIDEO_INFO_COMP_OFFSET (&vinfo, 2));
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex_v); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->upload_intex_v);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, glTexSubImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0,
GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2, GST_ROUND_UP_2 (width) / 2, GST_ROUND_UP_2 (height) / 2,
GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE, GL_UNSIGNED_BYTE, frame->data[2]);
(guint8 *) data + GST_VIDEO_INFO_COMP_OFFSET (&vinfo, 2));
} }
break; break;
default: default:
@ -3249,7 +3157,7 @@ gst_gl_display_thread_do_upload_draw (GstGLDisplay * display)
break; break;
default: default:
gst_gl_display_set_error (display, "Unsupported upload video format %d", GST_ERROR ("Unsupported upload video format %d",
display->upload_video_format); display->upload_video_format);
} //end switch display->currentVideo_format } //end switch display->currentVideo_format

View file

@ -118,6 +118,7 @@ struct _GstGLDisplay
GLuint gen_texture; GLuint gen_texture;
GLuint gen_texture_width; GLuint gen_texture_width;
GLuint gen_texture_height; GLuint gen_texture_height;
GstVideoFormat gen_texture_video_format;
//client callbacks //client callbacks
CRCB clientReshapeCallback; CRCB clientReshapeCallback;
@ -137,7 +138,7 @@ struct _GstGLDisplay
GstGLDisplayConversion upload_colorspace_conversion; GstGLDisplayConversion upload_colorspace_conversion;
gint upload_data_width; gint upload_data_width;
gint upload_data_height; gint upload_data_height;
gpointer upload_data; GstVideoFrame *upload_frame;
//foreign gl context //foreign gl context
gulong external_gl_context; gulong external_gl_context;
@ -255,15 +256,16 @@ void gst_gl_display_thread_add (GstGLDisplay * display,
GstGLDisplayThreadFunc func, gpointer data); GstGLDisplayThreadFunc func, gpointer data);
void gst_gl_display_gen_texture (GstGLDisplay * display, GLuint * pTexture, void gst_gl_display_gen_texture (GstGLDisplay * display, GLuint * pTexture,
GLint width, GLint height); GstVideoFormat v_format, GLint width, GLint height);
void gst_gl_display_del_texture (GstGLDisplay * display, GLuint texture, void gst_gl_display_gen_texture_thread (GstGLDisplay * display, GLuint * pTexture,
GLint width, GLint height); GstVideoFormat v_format, GLint width, GLint height);
void gst_gl_display_del_texture (GstGLDisplay * display, GLuint * pTexture);
gboolean gst_gl_display_init_upload (GstGLDisplay * display, gboolean gst_gl_display_init_upload (GstGLDisplay * display,
GstVideoFormat video_format, guint gl_width, guint gl_height, GstVideoFormat video_format, guint gl_width, guint gl_height,
gint video_width, gint video_height); gint video_width, gint video_height);
gboolean gst_gl_display_do_upload (GstGLDisplay * display, GLuint texture, gboolean gst_gl_display_do_upload (GstGLDisplay * display, GLuint texture,
gint data_width, gint data_height, gpointer data); GstVideoFrame * frame);
gboolean gst_gl_display_init_download (GstGLDisplay * display, gboolean gst_gl_display_init_download (GstGLDisplay * display,
GstVideoFormat video_format, gint width, gint height); GstVideoFormat video_format, gint width, gint height);
gboolean gst_gl_display_do_download (GstGLDisplay * display, GLuint texture, gboolean gst_gl_display_do_download (GstGLDisplay * display, GLuint texture,