mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 17:18:15 +00:00
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.
This commit is contained in:
parent
37ee652c46
commit
07b37e4c6d
6 changed files with 283 additions and 157 deletions
27
ChangeLog
27
ChangeLog
|
@ -1,3 +1,30 @@
|
|||
2004-01-07 Julien MOUTTE,,, <julien@moutte.net>
|
||||
|
||||
* 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 <rbultje@ronald.bitfreak.net>
|
||||
|
||||
* ext/audiofile/gstafsink.c: (gst_afsink_init), (gst_afsink_chain),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/* =========================================== */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue