From 07b37e4c6d55bd2d23001abeb4a31f2c0b6b6985 Mon Sep 17 00:00:00 2001 From: Julien Moutte Date: Wed, 7 Jan 2004 15:33:42 +0000 Subject: [PATCH] examples/gstplay/player.c: Adding some new lines in g_print calls. Original commit message from CVS: * examples/gstplay/player.c: (got_time_tick), (got_stream_length), (got_video_size): Adding some new lines in g_print calls. * sys/ximage/ximagesink.c: (gst_ximagesink_xwindow_new), (gst_ximagesink_xwindow_destroy), (gst_ximagesink_xwindow_resize), (gst_ximagesink_handle_xevents), (gst_ximagesink_fixate), (gst_ximagesink_sinkconnect), (gst_ximagesink_change_state), (gst_ximagesink_chain), (gst_ximagesink_buffer_new), (gst_ximagesink_set_xwindow_id), (gst_ximagesink_get_desired_size): Complete code review, reverting some stuff i disagree with, adding some fixes : time synchronization on invalid timestamps, renegotiation of private window. * sys/ximage/ximagesink.h: * sys/xvimage/xvimagesink.c: (gst_xvimagesink_xwindow_destroy), (gst_xvimagesink_xwindow_resize), (gst_xvimagesink_handle_xevents), (gst_xvimagesink_get_xv_support), (gst_xvimagesink_xcontext_get), (gst_xvimagesink_fixate), (gst_xvimagesink_sinkconnect), (gst_xvimagesink_change_state), (gst_xvimagesink_chain), (gst_xvimagesink_buffer_new), (gst_xvimagesink_navigation_send_event), (gst_xvimagesink_set_xwindow_id), (gst_xvimagesink_get_desired_size), (gst_xvimagesink_xoverlay_init): Complete code review, reverting some stuff i disagree with, adding some fixes : Renegotiation of private window, implementing get_desired_size. --- ChangeLog | 27 ++++ examples/gstplay/player.c | 6 +- sys/ximage/ximagesink.c | 204 +++++++++++++++++----------- sys/ximage/ximagesink.h | 5 +- sys/xvimage/xvimagesink.c | 192 +++++++++++++++++--------- tests/old/examples/gstplay/player.c | 6 +- 6 files changed, 283 insertions(+), 157 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3cc50467a53..1d586cfd517 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2004-01-07 Julien MOUTTE,,, + + * examples/gstplay/player.c: (got_time_tick), (got_stream_length), + (got_video_size): Adding some new lines in g_print calls. + * sys/ximage/ximagesink.c: (gst_ximagesink_xwindow_new), + (gst_ximagesink_xwindow_destroy), (gst_ximagesink_xwindow_resize), + (gst_ximagesink_handle_xevents), (gst_ximagesink_fixate), + (gst_ximagesink_sinkconnect), (gst_ximagesink_change_state), + (gst_ximagesink_chain), (gst_ximagesink_buffer_new), + (gst_ximagesink_set_xwindow_id), (gst_ximagesink_get_desired_size): + Complete code review, reverting some stuff i disagree with, adding + some fixes : time synchronization on invalid timestamps, renegotiation + of private window. + * sys/ximage/ximagesink.h: + * sys/xvimage/xvimagesink.c: (gst_xvimagesink_xwindow_destroy), + (gst_xvimagesink_xwindow_resize), (gst_xvimagesink_handle_xevents), + (gst_xvimagesink_get_xv_support), (gst_xvimagesink_xcontext_get), + (gst_xvimagesink_fixate), (gst_xvimagesink_sinkconnect), + (gst_xvimagesink_change_state), (gst_xvimagesink_chain), + (gst_xvimagesink_buffer_new), + (gst_xvimagesink_navigation_send_event), + (gst_xvimagesink_set_xwindow_id), + (gst_xvimagesink_get_desired_size), + (gst_xvimagesink_xoverlay_init): Complete code review, reverting some + stuff i disagree with, adding some fixes : Renegotiation of private + window, implementing get_desired_size. + 2004-01-07 Ronald Bultje * ext/audiofile/gstafsink.c: (gst_afsink_init), (gst_afsink_chain), diff --git a/examples/gstplay/player.c b/examples/gstplay/player.c index 76a735fc9c9..5d4f2466389 100644 --- a/examples/gstplay/player.c +++ b/examples/gstplay/player.c @@ -58,20 +58,20 @@ got_found_tag (GstPlay *play,GstElement *source, GstTagList *tag_list) static void got_time_tick (GstPlay *play, gint64 time_nanos) { - g_print ("time tick %llu", time_nanos); + g_print ("time tick %llu\n", time_nanos); } static void got_stream_length (GstPlay *play, gint64 length_nanos) { - g_print ("got length %llu", length_nanos); + g_print ("got length %llu\n", length_nanos); length = length_nanos; } static void got_video_size (GstPlay *play, gint width, gint height) { - g_print ("got video size %d, %d", width, height); + g_print ("got video size %d, %d\n", width, height); } static void diff --git a/sys/ximage/ximagesink.c b/sys/ximage/ximagesink.c index e0dc80cbce2..25a7b964802 100644 --- a/sys/ximage/ximagesink.c +++ b/sys/ximage/ximagesink.c @@ -216,27 +216,24 @@ gst_ximagesink_xwindow_new (GstXImageSink *ximagesink, gint width, gint height) xwindow->width = width; xwindow->height = height; + xwindow->internal = TRUE; g_mutex_lock (ximagesink->x_lock); - if (ximagesink->embed_into == 0) { - xwindow->win = XCreateSimpleWindow (ximagesink->xcontext->disp, - ximagesink->xcontext->root, - 0, 0, xwindow->width, xwindow->height, - 0, 0, ximagesink->xcontext->black); + xwindow->win = XCreateSimpleWindow (ximagesink->xcontext->disp, + ximagesink->xcontext->root, + 0, 0, xwindow->width, xwindow->height, + 0, 0, ximagesink->xcontext->black); - XMapRaised (ximagesink->xcontext->disp, xwindow->win); - } else { - xwindow->win = ximagesink->embed_into; - } + XMapRaised (ximagesink->xcontext->disp, xwindow->win); + XSelectInput (ximagesink->xcontext->disp, xwindow->win, ExposureMask | StructureNotifyMask | PointerMotionMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask); xwindow->gc = XCreateGC (ximagesink->xcontext->disp, xwindow->win, 0, NULL); - - + g_mutex_unlock (ximagesink->x_lock); return xwindow; @@ -253,11 +250,10 @@ gst_ximagesink_xwindow_destroy (GstXImageSink *ximagesink, GstXWindow *xwindow) g_mutex_lock (ximagesink->x_lock); /* If we did not create that window we just free the GC and let it live */ - if (ximagesink->embed_into == 0) { + if (xwindow->internal) XDestroyWindow (ximagesink->xcontext->disp, xwindow->win); - } else { + else XSelectInput (ximagesink->xcontext->disp, xwindow->win, 0); - } XFreeGC (ximagesink->xcontext->disp, xwindow->gc); @@ -266,6 +262,26 @@ gst_ximagesink_xwindow_destroy (GstXImageSink *ximagesink, GstXWindow *xwindow) g_free (xwindow); } +/* This function resizes a GstXWindow */ +static void +gst_ximagesink_xwindow_resize (GstXImageSink *ximagesink, GstXWindow *xwindow, + guint width, guint height) +{ + g_return_if_fail (xwindow != NULL); + g_return_if_fail (ximagesink != NULL); + g_return_if_fail (GST_IS_XIMAGESINK (ximagesink)); + + g_mutex_lock (ximagesink->x_lock); + + xwindow->width = width; + xwindow->height = height; + + XResizeWindow (ximagesink->xcontext->disp, xwindow->win, + xwindow->width, xwindow->height); + + g_mutex_unlock (ximagesink->x_lock); +} + /* This function handles XEvents that might be in the queue. It generates GstEvent that will be sent upstream in the pipeline to handle interactivity and navigation. It will also listen for configure events on the window to @@ -309,17 +325,17 @@ gst_ximagesink_handle_xevents (GstXImageSink *ximagesink, GstPad *pad) ximagesink->xwindow->height = e.xconfigure.height; r = gst_pad_try_set_caps (GST_VIDEOSINK_PAD (ximagesink), - gst_caps_new_simple ("video/x-raw-rgb", - "bpp", G_TYPE_INT, ximagesink->xcontext->bpp, - "depth", G_TYPE_INT, ximagesink->xcontext->depth, - "endianness", G_TYPE_INT, ximagesink->xcontext->endianness, - "red_mask", G_TYPE_INT, ximagesink->xcontext->visual->red_mask, - "green_mask", G_TYPE_INT, ximagesink->xcontext->visual->green_mask, - "blue_mask", G_TYPE_INT, ximagesink->xcontext->visual->blue_mask, - "width", G_TYPE_INT, e.xconfigure.width & ~3, - "height", G_TYPE_INT, e.xconfigure.height & ~3, - "framerate", G_TYPE_DOUBLE, ximagesink->framerate, - NULL)); + gst_caps_new_simple ("video/x-raw-rgb", + "bpp", G_TYPE_INT, ximagesink->xcontext->bpp, + "depth", G_TYPE_INT, ximagesink->xcontext->depth, + "endianness", G_TYPE_INT, ximagesink->xcontext->endianness, + "red_mask", G_TYPE_INT, ximagesink->xcontext->visual->red_mask, + "green_mask", G_TYPE_INT, ximagesink->xcontext->visual->green_mask, + "blue_mask", G_TYPE_INT, ximagesink->xcontext->visual->blue_mask, + "width", G_TYPE_INT, e.xconfigure.width & ~3, + "height", G_TYPE_INT, e.xconfigure.height & ~3, + "framerate", G_TYPE_DOUBLE, ximagesink->framerate, + NULL)); if ( (r == GST_PAD_LINK_OK) || (r == GST_PAD_LINK_DONE) ) { @@ -352,26 +368,25 @@ gst_ximagesink_handle_xevents (GstXImageSink *ximagesink, GstPad *pad) GST_DEBUG ("ximagesink pointer moved over window at %d,%d", e.xmotion.x, e.xmotion.y); gst_navigation_send_mouse_event (GST_NAVIGATION (ximagesink), - "mouse-move", - 0, + "mouse-move", 0, e.xmotion.x, e.xmotion.y); break; case ButtonPress: + /* Mouse button pressed/released over our window. We send upstream + events for interactivity/navigation */ GST_DEBUG ("ximagesink button %d pressed over window at %d,%d", e.xbutton.button, e.xbutton.x, e.xbutton.x); gst_navigation_send_mouse_event (GST_NAVIGATION (ximagesink), "mouse-button-press", - e.xbutton.button, + e.xbutton.button, e.xbutton.x, e.xbutton.y); - break; + break; case ButtonRelease: - /* Mouse button pressed/released over our window. We send upstream - events for interactivity/navigation */ GST_DEBUG ("ximagesink button %d release over window at %d,%d", e.xbutton.button, e.xbutton.x, e.xbutton.x); gst_navigation_send_mouse_event (GST_NAVIGATION (ximagesink), - "mouse-button-release", - e.xbutton.button, + "mouse-button-release", + e.xbutton.button, e.xbutton.x, e.xbutton.y); break; case KeyPress: @@ -382,19 +397,18 @@ gst_ximagesink_handle_xevents (GstXImageSink *ximagesink, GstPad *pad) e.xkey.keycode, e.xkey.x, e.xkey.x); keysym = XKeycodeToKeysym (ximagesink->xcontext->disp, e.xkey.keycode, 0); - if (keysym != NoSymbol) { - gst_navigation_send_key_event (GST_NAVIGATION (ximagesink), - e.type == KeyPress ? - "key-press" : "key-release", - XKeysymToString (keysym)); - } - else { - /* FIXME : What's that ? */ - gst_navigation_send_key_event (GST_NAVIGATION (ximagesink), - e.type == KeyPress ? - "key-press" : "key-release", - "unknown"); - } + if (keysym != NoSymbol) { + gst_navigation_send_key_event (GST_NAVIGATION (ximagesink), + e.type == KeyPress ? + "key-press" : "key-release", + XKeysymToString (keysym)); + } + else { + gst_navigation_send_key_event (GST_NAVIGATION (ximagesink), + e.type == KeyPress ? + "key-press" : "key-release", + "unknown"); + } break; default: GST_DEBUG ("ximagesink unhandled X event (%d)", e.type); @@ -546,7 +560,7 @@ gst_ximagesink_fixate (GstPad *pad, const GstCaps *caps) return newcaps; } if (gst_caps_structure_fixate_field_nearest_double (structure, "framerate", - 30.0)) { + 30.0)) { return newcaps; } @@ -593,20 +607,20 @@ gst_ximagesink_sinkconnect (GstPad *pad, const GstCaps *caps) structure = gst_caps_get_structure (caps, 0); ret = gst_structure_get_int (structure, "width", - &(GST_VIDEOSINK_WIDTH (ximagesink))); + &(GST_VIDEOSINK_WIDTH (ximagesink))); ret &= gst_structure_get_int (structure, "height", - &(GST_VIDEOSINK_HEIGHT (ximagesink))); + &(GST_VIDEOSINK_HEIGHT (ximagesink))); ret &= gst_structure_get_double (structure, - "framerate", &ximagesink->framerate); + "framerate", &ximagesink->framerate); if (!ret) return GST_PAD_LINK_REFUSED; ximagesink->pixel_width = 1; gst_structure_get_int (structure, "pixel_width", - &ximagesink->pixel_width); + &ximagesink->pixel_width); ximagesink->pixel_height = 1; gst_structure_get_int (structure, "pixel_height", - &ximagesink->pixel_height); + &ximagesink->pixel_height); /* Creating our window and our image */ if (!ximagesink->xwindow) @@ -614,10 +628,12 @@ gst_ximagesink_sinkconnect (GstPad *pad, const GstCaps *caps) GST_VIDEOSINK_WIDTH (ximagesink), GST_VIDEOSINK_HEIGHT (ximagesink)); else - XResizeWindow (ximagesink->xcontext->disp, - ximagesink->xwindow->win, - GST_VIDEOSINK_WIDTH (ximagesink), - GST_VIDEOSINK_HEIGHT (ximagesink)); + { + if (ximagesink->xwindow->internal) + gst_ximagesink_xwindow_resize (ximagesink, ximagesink->xwindow, + GST_VIDEOSINK_WIDTH (ximagesink), + GST_VIDEOSINK_HEIGHT (ximagesink)); + } if ( (ximagesink->ximage) && ( (GST_VIDEOSINK_WIDTH (ximagesink) != ximagesink->ximage->width) || @@ -635,8 +651,8 @@ gst_ximagesink_sinkconnect (GstPad *pad, const GstCaps *caps) GST_VIDEOSINK_HEIGHT (ximagesink)); gst_x_overlay_got_desired_size (GST_X_OVERLAY (ximagesink), - GST_VIDEOSINK_WIDTH (ximagesink), - GST_VIDEOSINK_HEIGHT (ximagesink)); + GST_VIDEOSINK_WIDTH (ximagesink), + GST_VIDEOSINK_HEIGHT (ximagesink)); gst_video_sink_got_video_size (GST_VIDEOSINK (ximagesink), GST_VIDEOSINK_WIDTH (ximagesink), GST_VIDEOSINK_HEIGHT (ximagesink)); @@ -660,12 +676,14 @@ gst_ximagesink_change_state (GstElement *element) return GST_STATE_FAILURE; break; case GST_STATE_READY_TO_PAUSED: + ximagesink->time = 0; break; case GST_STATE_PAUSED_TO_PLAYING: break; case GST_STATE_PLAYING_TO_PAUSED: break; case GST_STATE_PAUSED_TO_READY: + ximagesink->framerate = 0; GST_VIDEOSINK_WIDTH (ximagesink) = 0; GST_VIDEOSINK_HEIGHT (ximagesink) = 0; break; @@ -680,10 +698,9 @@ gst_ximagesink_change_state (GstElement *element) } static void -gst_ximagesink_chain (GstPad *pad, GstData *_data) +gst_ximagesink_chain (GstPad *pad, GstData *data) { - GstBuffer *buf = GST_BUFFER (_data); - GstClockTime time = GST_BUFFER_TIMESTAMP (buf); + GstBuffer *buf = GST_BUFFER (data); GstXImageSink *ximagesink; g_return_if_fail (pad != NULL); @@ -692,30 +709,36 @@ gst_ximagesink_chain (GstPad *pad, GstData *_data) ximagesink = GST_XIMAGESINK (gst_pad_get_parent (pad)); - if (GST_IS_EVENT (buf)) + if (GST_IS_EVENT (data)) { - GstEvent *event = GST_EVENT (buf); + GstEvent *event = GST_EVENT (data); gint64 offset; switch (GST_EVENT_TYPE (event)) { case GST_EVENT_DISCONTINUOUS: - offset = GST_EVENT_DISCONT_OFFSET (event, 0).value; - GST_DEBUG ("ximage discont %" G_GINT64_FORMAT "\n", offset); - break; + offset = GST_EVENT_DISCONT_OFFSET (event, 0).value; + GST_DEBUG ("ximage discont %" G_GINT64_FORMAT "\n", offset); + break; default: - gst_pad_event_default (pad, event); - return; + gst_pad_event_default (pad, event); + return; } gst_event_unref (event); return; } - GST_DEBUG ("videosink: clock wait: %" G_GUINT64_FORMAT, time); + buf = GST_BUFFER (data); + /* update time */ + if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) { + ximagesink->time = GST_BUFFER_TIMESTAMP (buf); + } + GST_DEBUG ("videosink: clock wait: %" G_GUINT64_FORMAT, ximagesink->time); if (GST_VIDEOSINK_CLOCK (ximagesink)) { GstClockID id; - id = gst_clock_new_single_shot_id (GST_VIDEOSINK_CLOCK (ximagesink), time); + id = gst_clock_new_single_shot_id (GST_VIDEOSINK_CLOCK (ximagesink), + ximagesink->time); gst_element_clock_wait (GST_ELEMENT (ximagesink), id, NULL); gst_clock_id_free (id); } @@ -744,6 +767,10 @@ gst_ximagesink_chain (GstPad *pad, GstData *_data) #if 0 } #endif + /* set correct time for next buffer */ + if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf) && ximagesink->framerate > 0) { + ximagesink->time += GST_SECOND / ximagesink->framerate; + } gst_buffer_unref (buf); @@ -753,7 +780,7 @@ gst_ximagesink_chain (GstPad *pad, GstData *_data) #if 0 static GstBuffer* gst_ximagesink_buffer_new (GstBufferPool *pool, - gint64 location, guint size, gpointer user_data) + gint64 location, guint size, gpointer user_data) { GstXImageSink *ximagesink; GstBuffer *buffer; @@ -910,17 +937,14 @@ static void gst_ximagesink_set_xwindow_id (GstXOverlay *overlay, XID xwindow_id) { GstXImageSink *ximagesink = GST_XIMAGESINK (overlay); + GstXWindow *xwindow = NULL; + XWindowAttributes attr; g_return_if_fail (ximagesink != NULL); g_return_if_fail (GST_IS_XIMAGESINK (ximagesink)); - if (ximagesink->embed_into == xwindow_id) - return; - if (!ximagesink->xcontext) - { - ximagesink->xcontext = gst_ximagesink_xcontext_get (ximagesink); - } + ximagesink->xcontext = gst_ximagesink_xcontext_get (ximagesink); if ( (ximagesink->xwindow) && (ximagesink->ximage) ) { /* If we are replacing a window we destroy pictures and window as they @@ -930,16 +954,30 @@ gst_ximagesink_set_xwindow_id (GstXOverlay *overlay, XID xwindow_id) gst_ximagesink_xwindow_destroy (ximagesink, ximagesink->xwindow); } - ximagesink->embed_into = xwindow_id; + xwindow = g_new0 (GstXWindow, 1); - ximagesink->xwindow = gst_ximagesink_xwindow_new (ximagesink, GST_VIDEOSINK_WIDTH (ximagesink), GST_VIDEOSINK_HEIGHT (ximagesink)); - ximagesink->ximage = gst_ximagesink_ximage_new (ximagesink, - GST_VIDEOSINK_WIDTH (ximagesink), GST_VIDEOSINK_HEIGHT (ximagesink)); - gst_x_overlay_got_xwindow_id (overlay, xwindow_id); + xwindow->win = xwindow_id; + + /* We get window geometry, set the event we want to receive, and create a GC */ + g_mutex_lock (ximagesink->x_lock); + XGetWindowAttributes (ximagesink->xcontext->disp, xwindow->win, &attr); + xwindow->width = attr.width; + xwindow->height = attr.height; + xwindow->internal = FALSE; + XSelectInput (ximagesink->xcontext->disp, xwindow->win, ExposureMask | + StructureNotifyMask | PointerMotionMask | KeyPressMask | + KeyReleaseMask); + + xwindow->gc = XCreateGC (ximagesink->xcontext->disp, + xwindow->win, 0, NULL); + g_mutex_unlock (ximagesink->x_lock); + + ximagesink->xwindow = xwindow; } static void -gst_ximagesink_get_desired_size (GstXOverlay *overlay, guint *width, guint *height) +gst_ximagesink_get_desired_size (GstXOverlay *overlay, + guint *width, guint *height) { GstXImageSink *ximagesink = GST_XIMAGESINK (overlay); diff --git a/sys/ximage/ximagesink.h b/sys/ximage/ximagesink.h index ad292a93261..74fe93ed622 100644 --- a/sys/ximage/ximagesink.h +++ b/sys/ximage/ximagesink.h @@ -83,6 +83,7 @@ struct _GstXContext { struct _GstXWindow { Window win; gint width, height; + gboolean internal; GC gc; }; @@ -102,8 +103,6 @@ struct _GstXImageSink { /* Our element stuff */ GstVideoSink videosink; - XID embed_into; - GstXContext *xcontext; GstXWindow *xwindow; GstXImage *ximage; @@ -114,6 +113,8 @@ struct _GstXImageSink { /* Unused */ gint pixel_width, pixel_height; + GstClockTime time; + GMutex *pool_lock; GSList *image_pool; }; diff --git a/sys/xvimage/xvimagesink.c b/sys/xvimage/xvimagesink.c index 7c3da91ef28..6f1ab4b439a 100644 --- a/sys/xvimage/xvimagesink.c +++ b/sys/xvimage/xvimagesink.c @@ -263,6 +263,8 @@ gst_xvimagesink_xwindow_destroy (GstXvImageSink *xvimagesink, GstXWindow *xwindo /* If we did not create that window we just free the GC and let it live */ if (xwindow->internal) XDestroyWindow (xvimagesink->xcontext->disp, xwindow->win); + else + XSelectInput (xvimagesink->xcontext->disp, xwindow->win, 0); XFreeGC (xvimagesink->xcontext->disp, xwindow->gc); @@ -271,6 +273,26 @@ gst_xvimagesink_xwindow_destroy (GstXvImageSink *xvimagesink, GstXWindow *xwindo g_free (xwindow); } +/* This function resizes a GstXWindow */ +static void +gst_xvimagesink_xwindow_resize (GstXvImageSink *xvimagesink, + GstXWindow *xwindow, guint width, guint height) +{ + g_return_if_fail (xwindow != NULL); + g_return_if_fail (xvimagesink != NULL); + g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink)); + + g_mutex_lock (xvimagesink->x_lock); + + xwindow->width = width; + xwindow->height = height; + + XResizeWindow (xvimagesink->xcontext->disp, xwindow->win, + xwindow->width, xwindow->height); + + g_mutex_unlock (xvimagesink->x_lock); +} + /* This function handles XEvents that might be in the queue. It generates GstEvent that will be sent upstream in the pipeline to handle interactivity and navigation. It will also listen for configure events on the window to @@ -301,7 +323,7 @@ gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad) { case ConfigureNotify: /* Window got resized or moved. We update our data. */ - GST_DEBUG ("ximagesink window is at %d, %d with geometry : %d,%d", + GST_DEBUG ("xvimagesink window is at %d, %d with geometry : %d,%d", e.xconfigure.x, e.xconfigure.y, e.xconfigure.width, e.xconfigure.height); xvimagesink->xwindow->width = e.xconfigure.width; @@ -313,7 +335,7 @@ gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad) GST_DEBUG ("xvimagesink pointer moved over window at %d,%d", e.xmotion.x, e.xmotion.y); gst_navigation_send_mouse_event (GST_NAVIGATION (xvimagesink), - "mouse-move", 0, + "mouse-move", 0, e.xmotion.x, e.xmotion.y); break; case ButtonPress: @@ -322,8 +344,8 @@ gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad) GST_DEBUG ("xvimagesink button %d pressed over window at %d,%d", e.xbutton.button, e.xbutton.x, e.xbutton.y); gst_navigation_send_mouse_event (GST_NAVIGATION (xvimagesink), - "mouse-button-press", - e.xbutton.button, + "mouse-button-press", + e.xbutton.button, e.xbutton.x, e.xbutton.y); break; case ButtonRelease: @@ -332,8 +354,8 @@ gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad) GST_DEBUG ("xvimagesink button %d released over window at %d,%d", e.xbutton.button, e.xbutton.x, e.xbutton.y); gst_navigation_send_mouse_event (GST_NAVIGATION (xvimagesink), - "mouse-button-release", - e.xbutton.button, + "mouse-button-release", + e.xbutton.button, e.xbutton.x, e.xbutton.y); break; case KeyPress: @@ -344,18 +366,18 @@ gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad) e.xkey.keycode, e.xkey.x, e.xkey.y); keysym = XKeycodeToKeysym (xvimagesink->xcontext->disp, e.xkey.keycode, 0); - if (keysym != NoSymbol) { - gst_navigation_send_key_event (GST_NAVIGATION (xvimagesink), - e.type == KeyPress ? - "key-press" : "key-release", - XKeysymToString (keysym)); - } - else { - gst_navigation_send_key_event (GST_NAVIGATION (xvimagesink), - e.type == KeyPress ? - "key-press" : "key-release", - "unknown"); - } + if (keysym != NoSymbol) { + gst_navigation_send_key_event (GST_NAVIGATION (xvimagesink), + e.type == KeyPress ? + "key-press" : "key-release", + XKeysymToString (keysym)); + } + else { + gst_navigation_send_key_event (GST_NAVIGATION (xvimagesink), + e.type == KeyPress ? + "key-press" : "key-release", + "unknown"); + } break; default: GST_DEBUG ("xvimagesink unhandled X event (%d)", e.type); @@ -366,6 +388,9 @@ gst_xvimagesink_handle_xevents (GstXvImageSink *xvimagesink, GstPad *pad) g_mutex_unlock (xvimagesink->x_lock); } +/* This function generates a caps with all supported format by the first + Xv grabable port we find. We store each one of the supported formats in a + format list and append the format to a newly created caps that we return */ static GstCaps * gst_xvimagesink_get_xv_support (GstXContext *xcontext) { @@ -437,21 +462,21 @@ gst_xvimagesink_get_xv_support (GstXContext *xcontext) case XvRGB: { format_caps = gst_caps_new_simple ("video/x-raw-rgb", - "endianness", G_TYPE_INT, xcontext->endianness, - "depth", G_TYPE_INT, xcontext->depth, - "bpp", G_TYPE_INT, xcontext->bpp, - "blue_mask", G_TYPE_INT, formats[i].red_mask, - "green_mask", G_TYPE_INT, formats[i].green_mask, - "red_mask", G_TYPE_INT, formats[i].blue_mask, - "width", GST_TYPE_INT_RANGE, 0, G_MAXINT, - "height", GST_TYPE_INT_RANGE, 0, G_MAXINT, - "framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE, - NULL); + "endianness", G_TYPE_INT, xcontext->endianness, + "depth", G_TYPE_INT, xcontext->depth, + "bpp", G_TYPE_INT, xcontext->bpp, + "blue_mask", G_TYPE_INT, formats[i].red_mask, + "green_mask", G_TYPE_INT, formats[i].green_mask, + "red_mask", G_TYPE_INT, formats[i].blue_mask, + "width", GST_TYPE_INT_RANGE, 0, G_MAXINT, + "height", GST_TYPE_INT_RANGE, 0, G_MAXINT, + "framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE, + NULL); /* For RGB caps we store them and the image - format so that we can get back the format - when sinkconnect will give us a caps without - format property */ + format so that we can get back the format + when sinkconnect will give us a caps without + format property */ if (format_caps) { GstXvImageFormat *format = NULL; @@ -467,16 +492,16 @@ gst_xvimagesink_get_xv_support (GstXContext *xcontext) break; } case XvYUV: - format_caps = gst_caps_new_simple ("video/x-raw-yuv", - "format", GST_TYPE_FOURCC,formats[i].id, - "width", GST_TYPE_INT_RANGE, 0, G_MAXINT, - "height", GST_TYPE_INT_RANGE, 0, G_MAXINT, - "framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE, - NULL); + format_caps = gst_caps_new_simple ("video/x-raw-yuv", + "format", GST_TYPE_FOURCC,formats[i].id, + "width", GST_TYPE_INT_RANGE, 0, G_MAXINT, + "height", GST_TYPE_INT_RANGE, 0, G_MAXINT, + "framerate", GST_TYPE_DOUBLE_RANGE, 0.0, G_MAXDOUBLE, + NULL); + break; + default: + g_assert_not_reached(); break; - default: - g_assert_not_reached(); - break; } gst_caps_append (caps, format_caps); @@ -564,13 +589,19 @@ gst_xvimagesink_xcontext_get (GstXvImageSink *xvimagesink) } #endif /* HAVE_XSHM */ - if (xcontext->endianness == G_LITTLE_ENDIAN && xcontext->depth == 24) - { - xcontext->endianness = G_BIG_ENDIAN; - xcontext->visual->red_mask = GUINT32_SWAP_LE_BE (xcontext->visual->red_mask); - xcontext->visual->green_mask = GUINT32_SWAP_LE_BE (xcontext->visual->green_mask); - xcontext->visual->blue_mask = GUINT32_SWAP_LE_BE (xcontext->visual->blue_mask); + /* our caps system handles 24/32bpp RGB as big-endian. */ + if ((xcontext->bpp == 24 || xcontext->bpp == 32) && + xcontext->endianness == G_LITTLE_ENDIAN) { + xcontext->endianness = G_BIG_ENDIAN; + xcontext->visual->red_mask = GUINT32_TO_BE (xcontext->visual->red_mask); + xcontext->visual->green_mask = GUINT32_TO_BE (xcontext->visual->green_mask); + xcontext->visual->blue_mask = GUINT32_TO_BE (xcontext->visual->blue_mask); + if (xcontext->bpp == 24) { + xcontext->visual->red_mask >>= 8; + xcontext->visual->green_mask >>= 8; + xcontext->visual->blue_mask >>= 8; } + } xcontext->caps = gst_xvimagesink_get_xv_support (xcontext); @@ -644,7 +675,7 @@ gst_xvimagesink_fixate (GstPad *pad, const GstCaps *caps) return newcaps; } if (gst_caps_structure_fixate_field_nearest_double (structure, "framerate", - 30.0)) { + 30.0)) { return newcaps; } @@ -652,6 +683,8 @@ gst_xvimagesink_fixate (GstPad *pad, const GstCaps *caps) return NULL; } +/* This function tries to get a format matching with a given caps in the + supported list of formats we generated in gst_xvimagesink_get_xv_support */ static gint gst_xvimagesink_get_fourcc_from_caps (GstXvImageSink *xvimagesink, GstCaps *caps) @@ -713,23 +746,26 @@ gst_xvimagesink_sinkconnect (GstPad *pad, const GstCaps *caps) caps_str1 = gst_caps_to_string (xvimagesink->xcontext->caps); caps_str2 = gst_caps_to_string (caps); - + GST_DEBUG ("sinkconnect %s with %s", caps_str1, caps_str2); - + g_free (caps_str1); g_free (caps_str2); structure = gst_caps_get_structure (caps, 0); - ret = gst_structure_get_int (structure, "width", &(GST_VIDEOSINK_WIDTH (xvimagesink))); - ret &= gst_structure_get_int (structure, "height", &(GST_VIDEOSINK_HEIGHT (xvimagesink))); - ret &= gst_structure_get_double (structure, "framerate", &xvimagesink->framerate); + ret = gst_structure_get_int (structure, "width", + &(GST_VIDEOSINK_WIDTH (xvimagesink))); + ret &= gst_structure_get_int (structure, "height", + &(GST_VIDEOSINK_HEIGHT (xvimagesink))); + ret &= gst_structure_get_double (structure, "framerate", + &xvimagesink->framerate); if (!ret) return GST_PAD_LINK_REFUSED; xvimagesink->xcontext->im_format = 0; if (!gst_structure_get_fourcc (structure, "format", - &xvimagesink->xcontext->im_format)) { + &xvimagesink->xcontext->im_format)) { xvimagesink->xcontext->im_format = gst_xvimagesink_get_fourcc_from_caps ( - xvimagesink, gst_caps_copy(caps)); + xvimagesink, gst_caps_copy(caps)); } if (xvimagesink->xcontext->im_format == 0) { return GST_PAD_LINK_REFUSED; @@ -739,13 +775,21 @@ gst_xvimagesink_sinkconnect (GstPad *pad, const GstCaps *caps) gst_structure_get_int (structure, "pixel_width", &xvimagesink->pixel_width); xvimagesink->pixel_height = 1; - gst_structure_get_int (structure, "pixel_height", &xvimagesink->pixel_height); + gst_structure_get_int (structure, "pixel_height", + &xvimagesink->pixel_height); /* Creating our window and our image */ if (!xvimagesink->xwindow) xvimagesink->xwindow = gst_xvimagesink_xwindow_new (xvimagesink, GST_VIDEOSINK_WIDTH (xvimagesink), GST_VIDEOSINK_HEIGHT (xvimagesink)); + else + { + if (xvimagesink->xwindow->internal) + gst_xvimagesink_xwindow_resize (xvimagesink, xvimagesink->xwindow, + GST_VIDEOSINK_WIDTH (xvimagesink), + GST_VIDEOSINK_HEIGHT (xvimagesink)); + } if ( (xvimagesink->xvimage) && ( (GST_VIDEOSINK_WIDTH (xvimagesink) != xvimagesink->xvimage->width) || @@ -762,6 +806,9 @@ gst_xvimagesink_sinkconnect (GstPad *pad, const GstCaps *caps) GST_VIDEOSINK_WIDTH (xvimagesink), GST_VIDEOSINK_HEIGHT (xvimagesink)); + gst_x_overlay_got_desired_size (GST_X_OVERLAY (xvimagesink), + GST_VIDEOSINK_WIDTH (xvimagesink), + GST_VIDEOSINK_HEIGHT (xvimagesink)); gst_video_sink_got_video_size (GST_VIDEOSINK (xvimagesink), GST_VIDEOSINK_WIDTH (xvimagesink), GST_VIDEOSINK_HEIGHT (xvimagesink)); @@ -793,6 +840,8 @@ gst_xvimagesink_change_state (GstElement *element) break; case GST_STATE_PAUSED_TO_READY: xvimagesink->framerate = 0; + GST_VIDEOSINK_WIDTH (xvimagesink) = 0; + GST_VIDEOSINK_HEIGHT (xvimagesink) = 0; break; case GST_STATE_READY_TO_NULL: break; @@ -824,12 +873,12 @@ gst_xvimagesink_chain (GstPad *pad, GstData *data) switch (GST_EVENT_TYPE (event)) { case GST_EVENT_DISCONTINUOUS: - offset = GST_EVENT_DISCONT_OFFSET (event, 0).value; - GST_DEBUG ("xvimage discont %" G_GINT64_FORMAT "\n", offset); - break; + offset = GST_EVENT_DISCONT_OFFSET (event, 0).value; + GST_DEBUG ("xvimage discont %" G_GINT64_FORMAT "\n", offset); + break; default: - gst_pad_event_default (pad, event); - return; + gst_pad_event_default (pad, event); + return; } gst_event_unref (event); return; @@ -844,7 +893,8 @@ gst_xvimagesink_chain (GstPad *pad, GstData *data) if (GST_VIDEOSINK_CLOCK (xvimagesink)) { GstClockID id; - id = gst_clock_new_single_shot_id (GST_VIDEOSINK_CLOCK (xvimagesink), xvimagesink->time); + id = gst_clock_new_single_shot_id (GST_VIDEOSINK_CLOCK (xvimagesink), + xvimagesink->time); gst_element_clock_wait (GST_ELEMENT (xvimagesink), id, NULL); gst_clock_id_free (id); } @@ -886,7 +936,7 @@ gst_xvimagesink_chain (GstPad *pad, GstData *data) #if 0 static GstBuffer* gst_xvimagesink_buffer_new (GstBufferPool *pool, - gint64 location, guint size, gpointer user_data) + gint64 location, guint size, gpointer user_data) { GstXvImageSink *xvimagesink; GstBuffer *buffer; @@ -1024,7 +1074,8 @@ gst_xvimagesink_navigation_send_event (GstNavigation *navigation, gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL); } - gst_pad_send_event (gst_pad_get_peer (GST_VIDEOSINK_PAD (xvimagesink)), event); + gst_pad_send_event (gst_pad_get_peer (GST_VIDEOSINK_PAD (xvimagesink)), + event); } static void @@ -1044,9 +1095,7 @@ gst_xvimagesink_set_xwindow_id (GstXOverlay *overlay, XID xwindow_id) g_return_if_fail (GST_IS_XVIMAGESINK (xvimagesink)); if (!xvimagesink->xcontext) - { - xvimagesink->xcontext = gst_xvimagesink_xcontext_get (xvimagesink); - } + xvimagesink->xcontext = gst_xvimagesink_xcontext_get (xvimagesink); if ( (xvimagesink->xwindow) && (xvimagesink->xvimage) ) { /* If we are replacing a window we destroy pictures and window as they @@ -1077,10 +1126,21 @@ gst_xvimagesink_set_xwindow_id (GstXOverlay *overlay, XID xwindow_id) xvimagesink->xwindow = xwindow; } +static void +gst_xvimagesink_get_desired_size (GstXOverlay *overlay, + guint *width, guint *height) +{ + GstXvImageSink *xvimagesink = GST_XVIMAGESINK (overlay); + + *width = GST_VIDEOSINK_WIDTH (xvimagesink); + *height = GST_VIDEOSINK_HEIGHT (xvimagesink); +} + static void gst_xvimagesink_xoverlay_init (GstXOverlayClass *iface) { iface->set_xwindow_id = gst_xvimagesink_set_xwindow_id; + iface->get_desired_size = gst_xvimagesink_get_desired_size; } /* =========================================== */ diff --git a/tests/old/examples/gstplay/player.c b/tests/old/examples/gstplay/player.c index 76a735fc9c9..5d4f2466389 100644 --- a/tests/old/examples/gstplay/player.c +++ b/tests/old/examples/gstplay/player.c @@ -58,20 +58,20 @@ got_found_tag (GstPlay *play,GstElement *source, GstTagList *tag_list) static void got_time_tick (GstPlay *play, gint64 time_nanos) { - g_print ("time tick %llu", time_nanos); + g_print ("time tick %llu\n", time_nanos); } static void got_stream_length (GstPlay *play, gint64 length_nanos) { - g_print ("got length %llu", length_nanos); + g_print ("got length %llu\n", length_nanos); length = length_nanos; } static void got_video_size (GstPlay *play, gint width, gint height) { - g_print ("got video size %d, %d", width, height); + g_print ("got video size %d, %d\n", width, height); } static void