[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 */ /* Called in the gl thread, protected by lock and unlock */
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_change_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); void gst_gl_display_thread_gen_texture (GstGLDisplay* display);
void gst_gl_display_thread_del_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 //gl context
display->gl_thread = NULL; display->gl_thread = NULL;
display->gl_window = NULL; display->gl_window = NULL;
display->winId = 0;
display->visible = FALSE; display->visible = FALSE;
display->isAlive = TRUE; display->isAlive = TRUE;
display->texture_pool = g_hash_table_new (g_direct_hash, g_direct_equal); 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_width = 0;
display->redisplay_texture_height = 0; display->redisplay_texture_height = 0;
//action resize
display->resize_width = 0;
display->resize_height = 0;
//action gen and del texture //action gen and del texture
display->gen_texture = 0; display->gen_texture = 0;
display->gen_texture_width = 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 */ /* Called in the gl thread */
@ -1399,7 +1393,7 @@ gst_gl_display_glgen_texture (GstGLDisplay* display, GLuint* pTexture, GLint wid
guint key = (gint)width; guint key = (gint)width;
key <<= 16; key <<= 16;
key |= (gint)height; 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 there is a sub texture pool associated to th given key
if (sub_texture_pool && g_queue_get_length(sub_texture_pool) > 0) 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; guint key = (gint)width;
key <<= 16; key <<= 16;
key |= (gint)height; 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 the size is known
if (!sub_texture_pool) if (!sub_texture_pool)
{ {
sub_texture_pool = g_queue_new (); 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 ("one more sub texture pool inserted: %d ", key);
GST_INFO ("nb sub texture pools: %d", g_hash_table_size (display->texture_pool)); 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 */ * Called by the first gl element of a video/x-raw-gl flow */
void void
gst_gl_display_create_context (GstGLDisplay *display, gst_gl_display_create_context (GstGLDisplay *display,
GLint width, GLint height, GLint width, GLint height)
gulong winId)
{ {
gst_gl_display_lock (display); gst_gl_display_lock (display);
display->winId = winId;
display->upload_width = width; display->upload_width = width;
display->upload_height = height; 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 */ /* Called by the glimagesink element */
gboolean gboolean
gst_gl_display_redisplay (GstGLDisplay* display, GLuint texture, gint width, gint height) 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_width = width;
display->redisplay_texture_height = height; 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); gst_gl_display_unlock (display);
@ -1878,13 +1859,10 @@ gst_gl_display_del_shader (GstGLDisplay* display, GstGLShader* shader)
/* Called by the glimagesink */ /* Called by the glimagesink */
void 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); gst_gl_display_lock (display);
display->winId = winId; gst_gl_window_set_external_window_id (display->gl_window, window_id);
gst_gl_window_set_external_window_id (display->gl_window, display->winId);
gst_gl_display_unlock (display); gst_gl_display_unlock (display);
} }

View File

@ -80,7 +80,6 @@ struct _GstGLDisplay {
//gl context //gl context
GThread* gl_thread; GThread* gl_thread;
GstGLWindow* gl_window; GstGLWindow* gl_window;
gulong winId;
gboolean visible; gboolean visible;
gboolean isAlive; gboolean isAlive;
GHashTable* texture_pool; GHashTable* texture_pool;
@ -97,10 +96,6 @@ struct _GstGLDisplay {
GLuint redisplay_texture_width; GLuint redisplay_texture_width;
GLuint redisplay_texture_height; GLuint redisplay_texture_height;
//action resize
gint resize_width;
gint resize_height;
//action gen and del texture //action gen and del texture
GLuint gen_texture; GLuint gen_texture;
GLuint gen_texture_width; GLuint gen_texture_width;
@ -213,10 +208,8 @@ GType gst_gl_display_get_type (void);
GstGLDisplay* gst_gl_display_new (void); GstGLDisplay* gst_gl_display_new (void);
void gst_gl_display_create_context (GstGLDisplay* display, void gst_gl_display_create_context (GstGLDisplay* display,
GLint width, GLint height, GLint width, GLint height);
gulong winId);
void gst_gl_display_set_visible_context (GstGLDisplay* display, gboolean visible); 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); gboolean gst_gl_display_redisplay (GstGLDisplay* display, GLuint texture, gint width, gint height);
void gst_gl_display_thread_add (GstGLDisplay *display, void gst_gl_display_thread_add (GstGLDisplay *display,
@ -254,7 +247,7 @@ void gst_gl_display_gen_shader (GstGLDisplay* display,
GstGLShader** shader); GstGLShader** shader);
void gst_gl_display_del_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_reshape_callback (GstGLDisplay* display, CRCB cb);
void gst_gl_display_set_client_draw_callback (GstGLDisplay* display, CDCB 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_resize_callback (GstGLWindow *window, GstGLWindowCB2 callback, gpointer data);
void gst_gl_window_set_close_callback (GstGLWindow *window, GstGLWindowCB 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_external_window_id (GstGLWindow *window);
gboolean gst_gl_window_has_internal_gl_context (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_window_id (GstGLWindow *window);
guint64 gst_gl_window_get_gl_context (GstGLWindow *window); guint64 gst_gl_window_get_gl_context (GstGLWindow *window);
void gst_gl_window_visible (GstGLWindow *window, gboolean visible); void gst_gl_window_visible (GstGLWindow *window, gboolean visible);
void gst_gl_window_draw (GstGLWindow *window); 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_run_loop (GstGLWindow *window);
void gst_gl_window_quit_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); void gst_gl_window_set_pixel_format (GstGLWindow *window);
LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 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) \ #define GST_GL_WINDOW_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_WINDOW, GstGLWindowPrivate)) (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; gboolean _gst_gl_window_debug = FALSE;
HHOOK hHook;
/* Must be called in the gl thread */ /* Must be called in the gl thread */
static void static void
gst_gl_window_finalize (GObject * object) 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 //device is set in the window_proc
g_assert (priv->device); g_assert (priv->device);
UpdateWindow (priv->internal_win_id);
ShowCursor (TRUE); ShowCursor (TRUE);
return window; return window;
@ -208,7 +210,20 @@ gst_gl_window_error_quark (void)
void void
gst_gl_window_set_external_window_id (GstGLWindow *window, guint64 id) 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 void
@ -253,24 +268,18 @@ gst_gl_window_has_external_window_id (GstGLWindow *window)
{ {
gboolean has_internal_window_id = TRUE; gboolean has_internal_window_id = TRUE;
GstGLWindowPrivate *priv = window->priv; 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 */ /* Must be called in the gl thread */
gboolean 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; gboolean has_external_gl_context = TRUE;
GstGLWindowPrivate *priv = window->priv; 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 */ /* 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); g_debug ("set visible %d\n", priv->internal_win_id);
if (visible) if (visible)
ret = ShowWindow (priv->internal_win_id, SW_SHOW); ret = ShowWindowAsync (priv->internal_win_id, SW_SHOW);
else else
ret = ShowWindow (priv->internal_win_id, SW_HIDE); ret = ShowWindowAsync (priv->internal_win_id, SW_HIDE);
} }
/* Thread safe */ /* Thread safe */
@ -310,60 +319,8 @@ void
gst_gl_window_draw (GstGLWindow *window) gst_gl_window_draw (GstGLWindow *window)
{ {
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
RedrawWindow (priv->internal_win_id, NULL, NULL,
if (!priv->has_external_window_id) RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE);
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);
} }
void void
@ -515,7 +472,11 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
case WM_SIZE: case WM_SIZE:
{ {
if (priv->resize_cb) 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)); priv->resize_cb (priv->resize_data, LOWORD(lParam), HIWORD(lParam));
}
break; break;
} }
@ -589,3 +550,17 @@ LRESULT CALLBACK window_proc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
else else
return DefWindowProc( hWnd, uMsg, wParam, lParam ); 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 //init unvisible opengl context
gst_gl_display_create_context (colorscale->display, gst_gl_display_create_context (colorscale->display,
colorscale->output_video_width, colorscale->output_video_height, colorscale->output_video_width, colorscale->output_video_height);
0);
//blocking call, init colorspace conversion if needed //blocking call, init colorspace conversion if needed
gst_gl_display_init_upload (colorscale->display, colorscale->input_video_format, 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, gst_gl_display_set_client_draw_callback (glimage_sink->display,
glimage_sink->clientDrawCallback); 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);
} }
} }
@ -524,8 +522,10 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf)
//init opengl context //init opengl context
gst_gl_display_create_context (glimage_sink->display, gst_gl_display_create_context (glimage_sink->display,
glimage_sink->width, glimage_sink->height, glimage_sink->width, glimage_sink->height);
glimage_sink->window_id);
if (glimage_sink->window_id)
gst_gl_display_set_window_id (glimage_sink->display, glimage_sink->window_id);
//init colorspace conversion if needed //init colorspace conversion if needed
gst_gl_display_init_upload (glimage_sink->display, glimage_sink->format, 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, gst_gl_display_set_client_draw_callback (glimage_sink->display,
glimage_sink->clientDrawCallback); 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 //blocking call

View File

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

View File

@ -446,7 +446,7 @@ gst_gl_upload_set_caps (GstBaseTransform* bt, GstCaps* incaps,
//init unvisible opengl context //init unvisible opengl context
gst_gl_display_create_context (upload->display, 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 //init colorspace conversion if needed
gst_gl_display_init_upload (upload->display, upload->video_format, gst_gl_display_init_upload (upload->display, upload->video_format,