[253/906] win32: re-implement supports for gst xoverlay interface, on this branch

This commit is contained in:
Julien Isorce 2008-10-28 00:22:27 +01:00 committed by Matthew Waters
parent 5a84fd49a9
commit f4bfade861
8 changed files with 63 additions and 121 deletions

View file

@ -47,7 +47,6 @@ static void gst_gl_display_finalize (GObject* object);
/* Called in the gl thread, protected by lock and unlock */
gpointer gst_gl_display_thread_create_context (GstGLDisplay* display);
void gst_gl_display_thread_destroy_context (GstGLDisplay* display);
void gst_gl_display_thread_change_context (GstGLDisplay* display);
void gst_gl_display_thread_run_generic (GstGLDisplay *display);
void gst_gl_display_thread_gen_texture (GstGLDisplay* display);
void gst_gl_display_thread_del_texture (GstGLDisplay* display);
@ -107,7 +106,6 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
//gl context
display->gl_thread = NULL;
display->gl_window = NULL;
display->winId = 0;
display->visible = FALSE;
display->isAlive = TRUE;
display->texture_pool = g_hash_table_new (g_direct_hash, g_direct_equal);
@ -120,10 +118,6 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
display->redisplay_texture_width = 0;
display->redisplay_texture_height = 0;
//action resize
display->resize_width = 0;
display->resize_height = 0;
//action gen and del texture
display->gen_texture = 0;
display->gen_texture_width = 0;
@ -385,7 +379,7 @@ gst_gl_display_finalize (GObject* object)
//------------------------------------------------------------
//------------------ BEGIN GL THREAD ACTIONS -----------------
//------------------ BEGIN GL THREAD PROCS -------------------
//------------------------------------------------------------
/* Called in the gl thread */
@ -1399,7 +1393,7 @@ gst_gl_display_glgen_texture (GstGLDisplay* display, GLuint* pTexture, GLint wid
guint key = (gint)width;
key <<= 16;
key |= (gint)height;
sub_texture_pool = g_hash_table_lookup (display->texture_pool, GUINT_TO_POINTER(key));
sub_texture_pool = g_hash_table_lookup (display->texture_pool, GUINT_TO_POINTER((guint64)key));
//if there is a sub texture pool associated to th given key
if (sub_texture_pool && g_queue_get_length(sub_texture_pool) > 0)
@ -1494,13 +1488,13 @@ gst_gl_display_gldel_texture (GstGLDisplay* display, GLuint* pTexture, GLint wid
guint key = (gint)width;
key <<= 16;
key |= (gint)height;
sub_texture_pool = g_hash_table_lookup (display->texture_pool, GUINT_TO_POINTER(key));
sub_texture_pool = g_hash_table_lookup (display->texture_pool, GUINT_TO_POINTER((guint64)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);
g_hash_table_insert (display->texture_pool, GUINT_TO_POINTER((guint64)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));
@ -1582,12 +1576,10 @@ gst_gl_display_new (void)
* Called by the first gl element of a video/x-raw-gl flow */
void
gst_gl_display_create_context (GstGLDisplay *display,
GLint width, GLint height,
gulong winId)
GLint width, GLint height)
{
gst_gl_display_lock (display);
display->winId = winId;
display->upload_width = width;
display->upload_height = height;
@ -1614,18 +1606,6 @@ gst_gl_display_set_visible_context (GstGLDisplay* display, gboolean visible)
}
/* Called by the glimagesink element */
void
gst_gl_display_resize_context (GstGLDisplay* display, gint width, gint height)
{
gst_gl_display_lock (display);
display->resize_width = width;
display->resize_height = height;
gst_gl_window_resize (display->gl_window, display->resize_width, display->resize_height);
gst_gl_display_unlock (display);
}
/* Called by the glimagesink element */
gboolean
gst_gl_display_redisplay (GstGLDisplay* display, GLuint texture, gint width, gint height)
@ -1642,7 +1622,8 @@ gst_gl_display_redisplay (GstGLDisplay* display, GLuint texture, gint width, gin
display->redisplay_texture_width = width;
display->redisplay_texture_height = height;
}
gst_gl_window_draw (display->gl_window);
if (display->gl_window)
gst_gl_window_draw (display->gl_window);
}
gst_gl_display_unlock (display);
@ -1878,13 +1859,10 @@ gst_gl_display_del_shader (GstGLDisplay* display, GstGLShader* shader)
/* Called by the glimagesink */
void
gst_gl_display_set_window_id (GstGLDisplay* display, gulong winId)
gst_gl_display_set_window_id (GstGLDisplay* display, gulong window_id)
{
//used only when glimagesink is connected to a gl flow
//otehrwise it can directly create the gl context using the winId
gst_gl_display_lock (display);
display->winId = winId;
gst_gl_window_set_external_window_id (display->gl_window, display->winId);
gst_gl_window_set_external_window_id (display->gl_window, window_id);
gst_gl_display_unlock (display);
}

View file

@ -80,7 +80,6 @@ struct _GstGLDisplay {
//gl context
GThread* gl_thread;
GstGLWindow* gl_window;
gulong winId;
gboolean visible;
gboolean isAlive;
GHashTable* texture_pool;
@ -97,10 +96,6 @@ struct _GstGLDisplay {
GLuint redisplay_texture_width;
GLuint redisplay_texture_height;
//action resize
gint resize_width;
gint resize_height;
//action gen and del texture
GLuint gen_texture;
GLuint gen_texture_width;
@ -213,10 +208,8 @@ GType gst_gl_display_get_type (void);
GstGLDisplay* gst_gl_display_new (void);
void gst_gl_display_create_context (GstGLDisplay* display,
GLint width, GLint height,
gulong winId);
GLint width, GLint height);
void gst_gl_display_set_visible_context (GstGLDisplay* display, gboolean visible);
void gst_gl_display_resize_context (GstGLDisplay* display, gint width, gint height);
gboolean gst_gl_display_redisplay (GstGLDisplay* display, GLuint texture, gint width, gint height);
void gst_gl_display_thread_add (GstGLDisplay *display,
@ -254,7 +247,7 @@ void gst_gl_display_gen_shader (GstGLDisplay* display,
GstGLShader** shader);
void gst_gl_display_del_shader (GstGLDisplay* display, GstGLShader* shader);
void gst_gl_display_set_window_id (GstGLDisplay* display, gulong winId);
void gst_gl_display_set_window_id (GstGLDisplay* display, gulong window_id);
void gst_gl_display_set_client_reshape_callback (GstGLDisplay* display, CRCB cb);
void gst_gl_display_set_client_draw_callback (GstGLDisplay* display, CDCB cb);

View file

@ -68,15 +68,14 @@ void gst_gl_window_set_draw_callback (GstGLWindow *window, GstGLWindowCB callbac
void gst_gl_window_set_resize_callback (GstGLWindow *window, GstGLWindowCB2 callback, gpointer data);
void gst_gl_window_set_close_callback (GstGLWindow *window, GstGLWindowCB callback, gpointer data);
gboolean gst_gl_window_has_internal_window_id (GstGLWindow *window);
gboolean gst_gl_window_has_internal_gl_context (GstGLWindow *window);
gboolean gst_gl_window_has_external_window_id (GstGLWindow *window);
gboolean gst_gl_window_has_external_gl_context (GstGLWindow *window);
guint64 gst_gl_window_get_window_id (GstGLWindow *window);
guint64 gst_gl_window_get_gl_context (GstGLWindow *window);
void gst_gl_window_visible (GstGLWindow *window, gboolean visible);
void gst_gl_window_draw (GstGLWindow *window);
void gst_gl_window_resize (GstGLWindow *window, gint width, gint height);
void gst_gl_window_run_loop (GstGLWindow *window);
void gst_gl_window_quit_loop (GstGLWindow *window);

View file

@ -33,6 +33,7 @@
void gst_gl_window_set_pixel_format (GstGLWindow *window);
LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT FAR PASCAL sub_class_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
#define GST_GL_WINDOW_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_WINDOW, GstGLWindowPrivate))
@ -66,6 +67,8 @@ G_DEFINE_TYPE (GstGLWindow, gst_gl_window, G_TYPE_OBJECT);
gboolean _gst_gl_window_debug = FALSE;
HHOOK hHook;
/* Must be called in the gl thread */
static void
gst_gl_window_finalize (GObject * object)
@ -193,7 +196,6 @@ gst_gl_window_new (gint width, gint height)
//device is set in the window_proc
g_assert (priv->device);
UpdateWindow (priv->internal_win_id);
ShowCursor (TRUE);
return window;
@ -208,7 +210,20 @@ gst_gl_window_error_quark (void)
void
gst_gl_window_set_external_window_id (GstGLWindow *window, guint64 id)
{
g_warning ("gst_gl_window_set_external_window_id: not implemented\n");
GstGLWindowPrivate *priv = window->priv;
WNDPROC window_parent_proc = (WNDPROC) (guint64) SetWindowLongPtr ((HWND)id, GWL_WNDPROC, (DWORD) (guint64) sub_class_proc);
RECT rect;
GetClientRect ((HWND)id, &rect);
SetWindowLongPtr (priv->internal_win_id, GWL_STYLE, WS_CHILD | WS_MAXIMIZE);
SetParent (priv->internal_win_id, (HWND)id);
SetProp ((HWND)id, "gl_window_parent_proc", (WNDPROC) window_parent_proc);
SetProp ((HWND)id, "gl_window_id", priv->internal_win_id);
priv->has_external_window_id = TRUE;
//take changes into account: SWP_FRAMECHANGED
SetWindowPos (priv->internal_win_id, HWND_TOP, rect.left, rect.top, rect.right, rect.bottom,
SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE);
MoveWindow (priv->internal_win_id, rect.left, rect.top, rect.right, rect.bottom, FALSE);
}
void
@ -253,24 +268,18 @@ gst_gl_window_has_external_window_id (GstGLWindow *window)
{
gboolean has_internal_window_id = TRUE;
GstGLWindowPrivate *priv = window->priv;
has_internal_window_id = priv->has_external_window_id;
return has_internal_window_id;
return priv->has_external_window_id;
}
/* Must be called in the gl thread */
gboolean
gst_gl_window_has_internal_gl_context (GstGLWindow *window)
gst_gl_window_has_external_gl_context (GstGLWindow *window)
{
gboolean has_external_gl_context = TRUE;
GstGLWindowPrivate *priv = window->priv;
has_external_gl_context = priv->has_external_gl_context;
return has_external_gl_context;
return priv->has_external_gl_context;
}
/* Must be called in the gl thread */
@ -300,9 +309,9 @@ gst_gl_window_visible (GstGLWindow *window, gboolean visible)
g_debug ("set visible %d\n", priv->internal_win_id);
if (visible)
ret = ShowWindow (priv->internal_win_id, SW_SHOW);
ret = ShowWindowAsync (priv->internal_win_id, SW_SHOW);
else
ret = ShowWindow (priv->internal_win_id, SW_HIDE);
ret = ShowWindowAsync (priv->internal_win_id, SW_HIDE);
}
/* Thread safe */
@ -310,60 +319,8 @@ void
gst_gl_window_draw (GstGLWindow *window)
{
GstGLWindowPrivate *priv = window->priv;
if (!priv->has_external_window_id)
RedrawWindow (priv->internal_win_id, NULL, NULL,
RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE);
else
{
PAINTSTRUCT ps;
/*RECT destsurf_rect;
POINT dest_surf_point;
dest_surf_point.x = 0;
dest_surf_point.y = 0;
ClientToScreen (priv->external_win_id, &dest_surf_point);
GetClientRect (priv->external_win_id, &destsurf_rect);
OffsetRect (&destsurf_rect, dest_surf_point.x, dest_surf_point.y);
if (window->State.Width != (destsurf_rect.right - destsurf_rect.left) ||
window->State.Height != (destsurf_rect.bottom - destsurf_rect.top))
{
window->State.Width = destsurf_rect.right - destsurf_rect.left;
window->State.Height = destsurf_rect.bottom - destsurf_rect.top;
window->State.NeedToResize = GL_FALSE;
if( FETCH_WCB( *window, Reshape ) )
INVOKE_WCB( *window, Reshape, ( window->State.Width, window->State.Height ) );
glViewport( 0, 0, window->State.Width, window->State.Height );
}*/
BeginPaint (priv->external_win_id, &ps);
priv->draw_cb (priv->draw_data); //FIXME: wrong thread caller
glFlush();
SwapBuffers (priv->device);
EndPaint (priv->external_win_id, &ps);
}
}
/* Thread safe */
void
gst_gl_window_resize (GstGLWindow *window, gint width, gint height)
{
GstGLWindowPrivate *priv = window->priv;
gint x = 0;
gint y = 0;
RECT winRect;
GetWindowRect (priv->internal_win_id, &winRect);
x = winRect.left;
y = winRect.top;
width += 2 * GetSystemMetrics (SM_CXSIZEFRAME);
height += 2 * GetSystemMetrics (SM_CYSIZEFRAME) + GetSystemMetrics (SM_CYCAPTION);
SetWindowPos (priv->internal_win_id, HWND_TOP, x, y, width, height,
SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOZORDER);
RedrawWindow (priv->internal_win_id, NULL, NULL,
RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE);
}
void
@ -515,7 +472,11 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
case WM_SIZE:
{
if (priv->resize_cb)
{
if (priv->has_external_window_id)
MoveWindow (hWnd, 0, 0, LOWORD(lParam), HIWORD(lParam), FALSE);
priv->resize_cb (priv->resize_data, LOWORD(lParam), HIWORD(lParam));
}
break;
}
@ -589,3 +550,17 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
else
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
LRESULT FAR PASCAL sub_class_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
WNDPROC window_parent_proc = GetProp (hWnd, "gl_window_parent_proc");
if (uMsg == WM_SIZE)
{
HWND gl_window_id = GetProp (hWnd, "gl_window_id");
PostMessage (gl_window_id, WM_SIZE, wParam, lParam);
}
return CallWindowProc (window_parent_proc, hWnd, uMsg, wParam, lParam);
}

View file

@ -414,8 +414,7 @@ gst_gl_colorscale_set_caps (GstBaseTransform* bt, GstCaps* incaps,
//init unvisible opengl context
gst_gl_display_create_context (colorscale->display,
colorscale->output_video_width, colorscale->output_video_height,
0);
colorscale->output_video_width, colorscale->output_video_height);
//blocking call, init colorspace conversion if needed
gst_gl_display_init_upload (colorscale->display, colorscale->input_video_format,

View file

@ -508,8 +508,6 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf)
gst_gl_display_set_client_draw_callback (glimage_sink->display,
glimage_sink->clientDrawCallback);
gst_gl_display_resize_context (glimage_sink->display, glimage_sink->width, glimage_sink->height);
gst_gl_display_set_visible_context (glimage_sink->display, TRUE);
}
}
@ -524,8 +522,10 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf)
//init opengl context
gst_gl_display_create_context (glimage_sink->display,
glimage_sink->width, glimage_sink->height,
glimage_sink->window_id);
glimage_sink->width, glimage_sink->height);
if (glimage_sink->window_id)
gst_gl_display_set_window_id (glimage_sink->display, glimage_sink->window_id);
//init colorspace conversion if needed
gst_gl_display_init_upload (glimage_sink->display, glimage_sink->format,
@ -538,9 +538,7 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf)
gst_gl_display_set_client_draw_callback (glimage_sink->display,
glimage_sink->clientDrawCallback);
gst_gl_display_resize_context (glimage_sink->display, glimage_sink->width, glimage_sink->height);
gst_gl_display_set_visible_context (glimage_sink->display, TRUE);
gst_gl_display_set_visible_context (glimage_sink->display, TRUE);
}
//blocking call

View file

@ -368,7 +368,7 @@ gst_gl_test_src_setcaps (GstBaseSrc* bsrc, GstCaps* caps)
gltestsrc->display = gst_gl_display_new ();
gst_gl_display_create_context (gltestsrc->display,
gltestsrc->width, gltestsrc->height, 0);
gltestsrc->width, gltestsrc->height);
gst_gl_display_gen_fbo (gltestsrc->display, gltestsrc->width, gltestsrc->height,
&gltestsrc->fbo, &gltestsrc->depthbuffer);

View file

@ -446,7 +446,7 @@ gst_gl_upload_set_caps (GstBaseTransform* bt, GstCaps* incaps,
//init unvisible opengl context
gst_gl_display_create_context (upload->display,
upload->gl_width, upload->gl_height, 0);
upload->gl_width, upload->gl_height);
//init colorspace conversion if needed
gst_gl_display_init_upload (upload->display, upload->video_format,