? path Index: Makefile.am =================================================================== RCS file: /cvs/gstreamer/gst-plugins-good/sys/osxvideo/Makefile.am,v retrieving revision 1.3 diff -u -r1.3 Makefile.am --- Makefile.am 23 Sep 2005 04:23:00 -0000 1.3 +++ Makefile.am 17 Dec 2006 04:57:27 -0000 @@ -5,10 +5,16 @@ plugin_LTLIBRARIES = libgstosxvideosink.la libgstosxvideosink_la_SOURCES = osxvideosink.m cocoawindow.m -libgstosxvideosink_la_CFLAGS = $(GST_CFLAGS) +libgstosxvideosink_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) libgstosxvideosink_la_LIBADD = \ - $(top_builddir)/gst-libs/gst/libgstinterfaces-$(GST_MAJORMINOR).la \ - $(GST_LIBS) + $(GST_PLUGINS_BASE_LIBS) \ + -lgstvideo-0.10 + $(GST_LIBS) \ + $(GST_BASE_LIBS) + +# -lgstinterfaces-$(GST_MAJORMINOR).la +# -libgstvideo-$(GST_MAJORMINOR).la + LIBS = -Wl,-framework -Wl,Cocoa -Wl,-framework -Wl,QuickTime -Wl,-framework -Wl,OpenGL libgstosxvideosink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -framework Cocoa -framework QuickTime -framework OpenGL Index: osxvideosink.h =================================================================== RCS file: /cvs/gstreamer/gst-plugins-good/sys/osxvideo/osxvideosink.h,v retrieving revision 1.4 diff -u -r1.4 osxvideosink.h --- osxvideosink.h 1 Jun 2006 21:07:26 -0000 1.4 +++ osxvideosink.h 17 Dec 2006 04:57:27 -0000 @@ -20,7 +20,9 @@ #ifndef __GST_OSXVIDEOSINK_H__ #define __GST_OSXVIDEOSINK_H__ -#include + +#include +#include #include #include Index: osxvideosink.m =================================================================== RCS file: /cvs/gstreamer/gst-plugins-good/sys/osxvideo/osxvideosink.m,v retrieving revision 1.5 diff -u -r1.5 osxvideosink.m --- osxvideosink.m 23 Nov 2005 14:22:18 -0000 1.5 +++ osxvideosink.m 17 Dec 2006 04:57:28 -0000 @@ -27,6 +27,7 @@ /* Debugging category */ #include +#include GST_DEBUG_CATEGORY_STATIC (gst_debug_osxvideosink); #define GST_CAT_DEFAULT gst_debug_osxvideosink @@ -40,7 +41,7 @@ "Zaheer Abbas Merali "); /* Default template - initiated with class struct to allow gst-register to work - without X running */ + without X running static GstStaticPadTemplate gst_osxvideosink_sink_template_factory = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, @@ -52,6 +53,15 @@ ) ); +*/ + static GstStaticPadTemplate gst_osxvideosink_sink_template_factory = + GST_STATIC_PAD_TEMPLATE ("sink", + GST_PAD_SINK, + GST_PAD_ALWAYS, + GST_STATIC_CAPS ("video/x-raw-yuv") + ); + + enum { ARG_0, @@ -232,8 +242,8 @@ return; - if (GST_VIDEOSINK_WIDTH (osxvideosink) != osxvideosink->osxwindow->width || - GST_VIDEOSINK_HEIGHT (osxvideosink) != osxvideosink->osxwindow->height) { + if (GST_VIDEO_SINK_WIDTH (osxvideosink) != osxvideosink->osxwindow->width || + GST_VIDEO_SINK_HEIGHT (osxvideosink) != osxvideosink->osxwindow->height) { GstPadLinkReturn r; r = gst_pad_try_set_caps (GST_VIDEOSINK_PAD (osxvideosink), @@ -244,18 +254,18 @@ "framerate", G_TYPE_DOUBLE, osxvideosink->framerate, NULL)); if ((r == GST_PAD_LINK_OK) || (r == GST_PAD_LINK_DONE)) { - GST_VIDEOSINK_WIDTH (osxvideosink) = osxvideosink->osxwindow->width; - GST_VIDEOSINK_HEIGHT (osxvideosink) = osxvideosink->osxwindow->height; + GST_VIDEO_SINK_WIDTH (osxvideosink) = osxvideosink->osxwindow->width; + GST_VIDEO_SINK_HEIGHT (osxvideosink) = osxvideosink->osxwindow->height; if ((osxvideosink->osximage) && - ((GST_VIDEOSINK_WIDTH (osxvideosink) != osxvideosink->osximage->width) || - (GST_VIDEOSINK_HEIGHT (osxvideosink) != + ((GST_VIDEO_SINK_WIDTH (osxvideosink) != osxvideosink->osximage->width) || + (GST_VIDEO_SINK_HEIGHT (osxvideosink) != osxvideosink->osximage->height))) { gst_osxvideosink_osximage_destroy (osxvideosink, osxvideosink->osximage); osxvideosink->osximage = gst_osxvideosink_osximage_new (osxvideosink, - GST_VIDEOSINK_WIDTH (osxvideosink), - GST_VIDEOSINK_HEIGHT (osxvideosink)); + GST_VIDEO_SINK_WIDTH (osxvideosink), + GST_VIDEO_SINK_HEIGHT (osxvideosink)); } } else { osxvideosink->sw_scaling_failed = TRUE; @@ -282,36 +292,50 @@ /* Element stuff */ -static GstCaps * -gst_osxvideosink_fixate (GstPad * pad, const GstCaps * caps) +static void +gst_osxvideosink_fixate (GstPad * pad, GstCaps * caps) { GstStructure *structure; GstCaps *newcaps; GValue target_fps = { 0 }; if (gst_caps_get_size (caps) > 1) - return NULL; + return; newcaps = gst_caps_copy (caps); structure = gst_caps_get_structure (newcaps, 0); if (gst_structure_fixate_field_nearest_int (structure, "width", 320)) { - return newcaps; + return; } if (gst_structure_fixate_field_nearest_int (structure, "height", 240)) { - return newcaps; + return; } g_value_init (&target_fps, GST_TYPE_FRACTION); gst_value_set_fraction (&target_fps, 25, 1); - gst_structure_fixate_field_nearest_fraction (s, "framerate", &target_fps); + + /* + gst_structure_fixate_field_nearest_fraction (structure, "framerate", &target_fps); if (gst_structure_fixate_field_nearest_fraction (structure, "framerate", &target_fps)) { return newcaps; } + */ + gst_structure_fixate_field_nearest_fraction (structure, + "framerate", + gst_value_get_fraction_numerator(&target_fps), + gst_value_get_fraction_denominator(&target_fps)); + + if (gst_structure_fixate_field_nearest_fraction (structure, "framerate", + gst_value_get_fraction_numerator(&target_fps), + gst_value_get_fraction_denominator(&target_fps) )) { + return; + } - gst_caps_free (newcaps); - return NULL; + gst_caps_unref (newcaps); + +return; } static GstCaps * @@ -343,9 +367,9 @@ structure = gst_caps_get_structure (caps, 0); ret = gst_structure_get_int (structure, "width", - &(GST_VIDEOSINK_WIDTH (osxvideosink))); + &(GST_VIDEO_SINK_WIDTH (osxvideosink))); ret &= gst_structure_get_int (structure, "height", - &(GST_VIDEOSINK_HEIGHT (osxvideosink))); + &(GST_VIDEO_SINK_HEIGHT (osxvideosink))); fps = gst_structure_get_value (structure, "framerate"); ret &= (fps != NULL && GST_VALUE_HOLDS_FRACTION (fps)); @@ -364,54 +388,55 @@ /* Creating our window and our image */ if (!osxvideosink->osxwindow) { osxvideosink->osxwindow = gst_osxvideosink_osxwindow_new (osxvideosink, - GST_VIDEOSINK_WIDTH (osxvideosink), GST_VIDEOSINK_HEIGHT (osxvideosink)); + GST_VIDEO_SINK_WIDTH (osxvideosink), GST_VIDEO_SINK_HEIGHT (osxvideosink)); gst_osxvideosink_osxwindow_clear (osxvideosink, osxvideosink->osxwindow); } else { if (osxvideosink->osxwindow->internal) gst_osxvideosink_osxwindow_resize (osxvideosink, osxvideosink->osxwindow, - GST_VIDEOSINK_WIDTH (osxvideosink), GST_VIDEOSINK_HEIGHT (osxvideosink)); + GST_VIDEO_SINK_WIDTH (osxvideosink), GST_VIDEO_SINK_HEIGHT (osxvideosink)); } - if ((osxvideosink->osximage) && ((GST_VIDEOSINK_WIDTH (osxvideosink) != osxvideosink->osximage->width) || (GST_VIDEOSINK_HEIGHT (osxvideosink) != osxvideosink->osximage->height))) { /* We renew our ximage only if size changed */ + if ((osxvideosink->osximage) && ((GST_VIDEO_SINK_WIDTH (osxvideosink) != osxvideosink->osximage->width) || (GST_VIDEO_SINK_HEIGHT (osxvideosink) != osxvideosink->osximage->height))) { /* We renew our ximage only if size changed */ gst_osxvideosink_osximage_destroy (osxvideosink, osxvideosink->osximage); osxvideosink->osximage = gst_osxvideosink_osximage_new (osxvideosink, - GST_VIDEOSINK_WIDTH (osxvideosink), GST_VIDEOSINK_HEIGHT (osxvideosink)); + GST_VIDEO_SINK_WIDTH (osxvideosink), GST_VIDEO_SINK_HEIGHT (osxvideosink)); } else if (!osxvideosink->osximage) /* If no ximage, creating one */ osxvideosink->osximage = gst_osxvideosink_osximage_new (osxvideosink, - GST_VIDEOSINK_WIDTH (osxvideosink), GST_VIDEOSINK_HEIGHT (osxvideosink)); + GST_VIDEO_SINK_WIDTH (osxvideosink), GST_VIDEO_SINK_HEIGHT (osxvideosink)); return GST_PAD_LINK_OK; } -static GstElementStateReturn -gst_osxvideosink_change_state (GstElement * element) +//static GstElementStateReturn +static GstStateChangeReturn +gst_osxvideosink_change_state (GstElement * element, GstStateChange transition) { GstOSXVideoSink *osxvideosink; osxvideosink = GST_OSXVIDEOSINK (element); - switch (GST_STATE_TRANSITION (element)) { - case GST_STATE_NULL_TO_READY: + switch (transition) { + case GST_STATE_CHANGE_NULL_TO_READY: break; - case GST_STATE_READY_TO_PAUSED: + case GST_STATE_CHANGE_READY_TO_PAUSED: if (osxvideosink->osxwindow) gst_osxvideosink_osxwindow_clear (osxvideosink, osxvideosink->osxwindow); osxvideosink->time = 0; break; - case GST_STATE_PAUSED_TO_PLAYING: + case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; - case GST_STATE_PLAYING_TO_PAUSED: + case GST_STATE_CHANGE_PLAYING_TO_PAUSED: break; - case GST_STATE_PAUSED_TO_READY: + case GST_STATE_CHANGE_PAUSED_TO_READY: osxvideosink->fps_n = 0; osxvideosink->fps_d = 0; osxvideosink->sw_scaling_failed = FALSE; - GST_VIDEOSINK_WIDTH (osxvideosink) = 0; - GST_VIDEOSINK_HEIGHT (osxvideosink) = 0; + GST_VIDEO_SINK_WIDTH (osxvideosink) = 0; + GST_VIDEO_SINK_HEIGHT (osxvideosink) = 0; break; - case GST_STATE_READY_TO_NULL: + case GST_STATE_CHANGE_READY_TO_NULL: if (osxvideosink->osximage) { gst_osxvideosink_osximage_destroy (osxvideosink, osxvideosink->osximage); osxvideosink->osximage = NULL; @@ -425,18 +450,93 @@ osxvideosink->osxwindow = NULL; } break; + + default: + break; + } + + if (GST_ELEMENT_CLASS (parent_class)->change_state) { + return GST_ELEMENT_CLASS(parent_class)->change_state(element,transition); + } + + return GST_STATE_CHANGE_SUCCESS; +} + +static GstFlowReturn +gst_osxvideosink_chain (GstPad * pad, GstBuffer * buffer) +{ + + /*GstBuffer *buf = GST_BUFFER(data); */ + GstFlowReturn ret = GST_FLOW_OK; + GstOSXVideoSink *osxvideosink; + + if (buffer==NULL) { + return GST_FLOW_ERROR; + } + + if (GST_IS_PAD(pad)) { + return GST_FLOW_ERROR; + } + + /* + g_return_if_fail (GST_IS_PAD (pad)); + g_return_if_fail (buffer != NULL); + */ + osxvideosink = GST_OSXVIDEOSINK (gst_pad_get_parent (pad)); + + if (GST_IS_EVENT (GST_BUFFER_DATA(buffer))) { + gst_pad_event_default (pad, GST_EVENT(GST_BUFFER_DATA(buffer))); + return GST_FLOW_ERROR; + } + + /* update time */ + if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) { + osxvideosink->time = GST_BUFFER_TIMESTAMP (buffer); + } + GST_DEBUG ("clock wait: %" GST_TIME_FORMAT, GST_TIME_ARGS (osxvideosink->time)); + + /* + if (GST_VIDEO_SINK_CLOCK (osxvideosink)) { + gst_element_wait (GST_ELEMENT (osxvideosink), osxvideosink->time); + } + */ + + /* If this buffer has been allocated using our buffer management we simply + put the ximage which is in the PRIVATE pointer */ + char* viewdata = [osxvideosink->osxwindow->gstview getTextureBuffer]; + memcpy(viewdata, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE(buffer)); + [osxvideosink->osxwindow->gstview displayTexture]; + + /*if (GST_BUFFER_FREE_DATA_FUNC (buffer) != gst_osxvideosink_buffer_free) { + */ + if (!osxvideosink->osximage) { + /* + No image available. Something went wrong during capsnego ! + */ + + gst_buffer_unref (buffer); + GST_ELEMENT_ERROR (osxvideosink, CORE, NEGOTIATION, (NULL), + ("no format defined before chain function")); + return GST_FLOW_ERROR; + } + /*}*/ + + /* set correct time for next buffer */ + if (!GST_BUFFER_TIMESTAMP_IS_VALID (buffer) && osxvideosink->fps_n > 0) { + osxvideosink->time += gst_util_uint64_scale_int (GST_SECOND, + osxvideosink->fps_d, osxvideosink->fps_n); } - if (GST_ELEMENT_CLASS (parent_class)->change_state) - return GST_ELEMENT_CLASS (parent_class)->change_state (element); + gst_buffer_unref (buffer); - return GST_STATE_SUCCESS; + return ret; } +/* static void gst_osxvideosink_chain (GstPad * pad, GstData * data) { - GstBuffer *buf = GST_BUFFER (data); + GstBuffer *buf = GST_BUFFER(data); GstOSXVideoSink *osxvideosink; g_return_if_fail (GST_IS_PAD (pad)); @@ -450,25 +550,25 @@ } buf = GST_BUFFER (data); - /* update time */ + // update time if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) { osxvideosink->time = GST_BUFFER_TIMESTAMP (buf); } GST_DEBUG ("clock wait: %" GST_TIME_FORMAT, GST_TIME_ARGS (osxvideosink->time)); - if (GST_VIDEOSINK_CLOCK (osxvideosink)) { + if (GST_VIDEO_SINK_CLOCK (osxvideosink)) { gst_element_wait (GST_ELEMENT (osxvideosink), osxvideosink->time); } - /* If this buffer has been allocated using our buffer management we simply - put the ximage which is in the PRIVATE pointer */ + If this buffer has been allocated using our buffer management we simply + put the ximage which is in the PRIVATE pointer char* viewdata = [osxvideosink->osxwindow->gstview getTextureBuffer]; memcpy(viewdata, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE(buf)); [osxvideosink->osxwindow->gstview displayTexture]; if (GST_BUFFER_FREE_DATA_FUNC (buf) != gst_osxvideosink_buffer_free) { if (!osxvideosink->osximage) { - /* No image available. Something went wrong during capsnego ! */ + No image available. Something went wrong during capsnego ! gst_buffer_unref (buf); GST_ELEMENT_ERROR (osxvideosink, CORE, NEGOTIATION, (NULL), @@ -477,7 +577,7 @@ } } - /* set correct time for next buffer */ + set correct time for next buffer if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf) && osxvideosink->fps_n > 0) { osxvideosink->time += gst_util_uint64_scale_int (GST_SECOND, osxvideosink->fps_d, osxvideosink->fps_n); @@ -486,6 +586,9 @@ gst_buffer_unref (buf); } +*/ + + /* Buffer management */ @@ -501,8 +604,8 @@ osxvideosink = osximage->osxvideosink; /* If our geometry changed we can't reuse that image. */ - if ((osximage->width != GST_VIDEOSINK_WIDTH (osxvideosink)) || - (osximage->height != GST_VIDEOSINK_HEIGHT (osxvideosink))) + if ((osximage->width != GST_VIDEO_SINK_WIDTH (osxvideosink)) || + (osximage->height != GST_VIDEO_SINK_HEIGHT (osxvideosink))) gst_osxvideosink_osximage_destroy (osxvideosink, osximage); else { /* In that case we can reuse the image and add it to our image pool. */ @@ -511,20 +614,34 @@ g_mutex_unlock (osxvideosink->pool_lock); } } - +/* + change signature to include reverse negotiation see ximagesink in base , gstpad.h + add rev neg. with caps/buffer size + add dynamic destruction + return proper values +*/ +/* static GstBuffer * gst_osxvideosink_buffer_alloc (GstPad * pad, guint64 offset, guint size) +*/ +static GstFlowReturn +gst_osxvideosink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size, + GstCaps * caps, GstBuffer ** buf) { GstOSXVideoSink *osxvideosink; GstBuffer *buffer; GstOSXImage *osximage = NULL; gboolean not_found = TRUE; + GstCaps *alloc_caps; + gboolean alloc_unref = FALSE; + GstFlowReturn ret = GST_FLOW_OK; - osxvideosink = GST_OSXVIDEOSINK (gst_pad_get_parent (pad)); + /* get this sink */ + osxvideosink = GST_OSXVIDEOSINK (bsink); g_mutex_lock (osxvideosink->pool_lock); - /* Walking through the pool cleaning unsuable images and searching for a + /* Walking through the pool cleaning unusable images and searching for a suitable one */ while (not_found && osxvideosink->image_pool) { osximage = osxvideosink->image_pool->data; @@ -534,7 +651,7 @@ osxvideosink->image_pool = g_slist_delete_link (osxvideosink->image_pool, osxvideosink->image_pool); - if ((osximage->width != GST_VIDEOSINK_WIDTH (osxvideosink)) || (osximage->height != GST_VIDEOSINK_HEIGHT (osxvideosink))) { /* This image is unusable. Destroying... */ + if ((osximage->width != GST_VIDEO_SINK_WIDTH (osxvideosink)) || (osximage->height != GST_VIDEO_SINK_HEIGHT (osxvideosink))) { /* This image is unusable. Destroying... */ gst_osxvideosink_osximage_destroy (osxvideosink, osximage); osximage = NULL; } else { /* We found a suitable image */ @@ -548,21 +665,27 @@ if (!osximage) { /* We found no suitable image in the pool. Creating... */ osximage = gst_osxvideosink_osximage_new (osxvideosink, - GST_VIDEOSINK_WIDTH (osxvideosink), GST_VIDEOSINK_HEIGHT (osxvideosink)); + GST_VIDEO_SINK_WIDTH (osxvideosink), GST_VIDEO_SINK_HEIGHT (osxvideosink)); } if (osximage) { buffer = gst_buffer_new (); - /* Storing some pointers in the buffer */ + /* Storing some pointers in the buffer GST_BUFFER_PRIVATE (buffer) = osximage; - +*/ GST_BUFFER_DATA (buffer) = osximage->data; +/* GST_BUFFER_FREE_DATA_FUNC (buffer) = gst_osxvideosink_buffer_free; +*/ GST_BUFFER_SIZE (buffer) = osximage->size; - return buffer; - } else - return NULL; + + *buf = GST_BUFFER_CAST (osximage); + return ret; + + } else { + return GST_FLOW_ERROR; + } } /* =========================================== */ @@ -632,22 +755,25 @@ static void gst_osxvideosink_init (GstOSXVideoSink * osxvideosink) { - GST_VIDEOSINK_PAD (osxvideosink) = + /* + GST_VIDEO_SINK_PAD (osxvideosink) = gst_pad_new_from_template (gst_static_pad_template_get (&gst_osxvideosink_sink_template_factory), "sink"); - + + gst_element_add_pad (GST_ELEMENT (osxvideosink), - GST_VIDEOSINK_PAD (osxvideosink)); + GST_VIDEO_SINK_PAD (osxvideosink)); + */ - gst_pad_set_chain_function (GST_VIDEOSINK_PAD (osxvideosink), + gst_pad_set_chain_function (GST_VIDEO_SINK_PAD (osxvideosink), gst_osxvideosink_chain); - gst_pad_set_link_function (GST_VIDEOSINK_PAD (osxvideosink), + gst_pad_set_link_function (GST_VIDEO_SINK_PAD (osxvideosink), gst_osxvideosink_sink_link); - gst_pad_set_getcaps_function (GST_VIDEOSINK_PAD (osxvideosink), + gst_pad_set_getcaps_function (GST_VIDEO_SINK_PAD (osxvideosink), gst_osxvideosink_getcaps); - gst_pad_set_fixate_function (GST_VIDEOSINK_PAD (osxvideosink), - gst_osxvideosink_fixate); - gst_pad_set_bufferalloc_function (GST_VIDEOSINK_PAD (osxvideosink), + gst_pad_set_fixatecaps_function(GST_VIDEO_SINK_PAD(osxvideosink), + gst_osxvideosink_fixate); + gst_pad_set_bufferalloc_function (GST_VIDEO_SINK_PAD (osxvideosink), gst_osxvideosink_buffer_alloc); osxvideosink->osxwindow = NULL; @@ -664,8 +790,6 @@ osxvideosink->sw_scaling_failed = FALSE; osxvideosink->embed = FALSE; osxvideosink->fullscreen = FALSE; - GST_FLAG_SET (osxvideosink, GST_ELEMENT_THREAD_SUGGESTED); - GST_FLAG_SET (osxvideosink, GST_ELEMENT_EVENT_AWARE); } @@ -689,7 +813,7 @@ gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; - parent_class = g_type_class_ref (GST_TYPE_VIDEOSINK); + parent_class = g_type_class_ref (GST_TYPE_VIDEO_SINK); gobject_class->dispose = gst_osxvideosink_dispose; gobject_class->set_property = gst_osxvideosink_set_property; @@ -739,7 +863,7 @@ (GInstanceInitFunc) gst_osxvideosink_init, }; - osxvideosink_type = g_type_register_static (GST_TYPE_VIDEOSINK, + osxvideosink_type = g_type_register_static (GST_TYPE_VIDEO_SINK, "GstOSXVideoSink", &osxvideosink_info, 0); } @@ -750,9 +874,11 @@ static gboolean plugin_init (GstPlugin * plugin) { - /* Loading the library containing GstVideoSink, our parent object */ + + /* Loading the library containing GstVideoSink, our parent object if (!gst_library_load ("gstvideo")) return FALSE; +*/ if (!gst_element_register (plugin, "osxvideosink", GST_RANK_PRIMARY, GST_TYPE_OSXVIDEOSINK)) @@ -768,4 +894,4 @@ GST_VERSION_MINOR, "osxvideo", "OSX native video output plugin", - plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN) + plugin_init, VERSION, GST_LICENSE, "GStreamer", "http://gstreamer.freedesktop.org/")