mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-12 02:15:31 +00:00
[253/906] win32: re-implement supports for gst xoverlay interface, on this branch
This commit is contained in:
parent
5a84fd49a9
commit
f4bfade861
8 changed files with 63 additions and 121 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue