From 80da1d408ba64b724f8dd5264604e1dd5d6d6701 Mon Sep 17 00:00:00 2001 From: Nils Hasler Date: Sat, 23 Apr 2011 21:24:41 +0000 Subject: [PATCH] removed private copy of gstappsink because appsink is now part of gstreamer base. --- CMakeLists.txt | 2 +- cvconfig.h.cmake | 3 - modules/highgui/CMakeLists.txt | 4 - modules/highgui/src/cap_gstreamer.cpp | 80 +--- modules/highgui/src/gstappsink.cpp | 765 ---------------------------------- modules/highgui/src/gstappsink.h | 89 ---- 6 files changed, 13 insertions(+), 930 deletions(-) delete mode 100644 modules/highgui/src/gstappsink.cpp delete mode 100644 modules/highgui/src/gstappsink.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2fb2fb3..ea39edf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -372,7 +372,7 @@ if(UNIX) endif() if(WITH_GSTREAMER) CHECK_MODULE(gstreamer-base-0.10 HAVE_GSTREAMER) - CHECK_MODULE(gstreamer-app-0.10 HAVE_GSTREAMER_APP) + CHECK_MODULE(gstreamer-app-0.10 HAVE_GSTREAMER) CHECK_MODULE(gstreamer-video-0.10 HAVE_GSTREAMER) else() set(HAVE_GSTREAMER FALSE) diff --git a/cvconfig.h.cmake b/cvconfig.h.cmake index e805082..287fa9b 100644 --- a/cvconfig.h.cmake +++ b/cvconfig.h.cmake @@ -43,9 +43,6 @@ /* GStreamer multimedia framework */ #cmakedefine HAVE_GSTREAMER -/* GStreamer with gstappsink & gstappsrc */ -#cmakedefine HAVE_GSTREAMER_APP - /* GTK+ 2.0 Thread support */ #cmakedefine HAVE_GTHREAD diff --git a/modules/highgui/CMakeLists.txt b/modules/highgui/CMakeLists.txt index f4d9458..1a268bf 100644 --- a/modules/highgui/CMakeLists.txt +++ b/modules/highgui/CMakeLists.txt @@ -132,10 +132,6 @@ if(UNIX) if(HAVE_GSTREAMER) set(highgui_srcs ${highgui_srcs} src/cap_gstreamer.cpp) - if(NOT HAVE_GSTREAMER_APP) - set(highgui_srcs ${highgui_srcs} src/gstappsink.cpp) - set(highgui_hdrs ${highgui_hdrs} src/gstappsink.h) - endif() endif() if(HAVE_UNICAP) diff --git a/modules/highgui/src/cap_gstreamer.cpp b/modules/highgui/src/cap_gstreamer.cpp index d931405..c11a635 100644 --- a/modules/highgui/src/cap_gstreamer.cpp +++ b/modules/highgui/src/cap_gstreamer.cpp @@ -10,7 +10,7 @@ // Intel License Agreement // For Open Source Computer Vision Library // -// Copyright (C) 2008, Nils Hasler, all rights reserved. +// Copyright (C) 2008, 2011, Nils Hasler, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, @@ -55,15 +55,10 @@ #include #include #include -#ifdef HAVE_GSTREAMER_APP #include #include #include -#else -#include "gstappsink.h" -#endif - #ifdef NDEBUG #define CV_WARN(message) #else @@ -168,28 +163,14 @@ bool CvCapture_GStreamer::grabFrame() if(!pipeline) return false; - if(gst_app_sink_is_eos(GST_APP_SINK(sink))) { - //printf("end of stream\n"); + if(gst_app_sink_is_eos(GST_APP_SINK(sink))) return false; - } if(buffer) gst_buffer_unref(buffer); handleMessage(); -#ifndef HAVE_GSTREAMER_APP - if(gst_app_sink_get_queue_length(GST_APP_SINK(sink))) - { -// printf("peeking buffer, %d buffers in queue\n", - buffer = gst_app_sink_peek_buffer(GST_APP_SINK(sink)); - } - else -#endif - { -// printf("pulling buffer\n"); - buffer = gst_app_sink_pull_buffer(GST_APP_SINK(sink)); -// printf("pulled buffer %p\n", GST_BUFFER_DATA(buffer)); - } + buffer = gst_app_sink_pull_buffer(GST_APP_SINK(sink)); if(!buffer) return false; @@ -204,8 +185,6 @@ IplImage * CvCapture_GStreamer::retrieveFrame(int) if(!buffer) return false; -// printf("retrieving buffer %p\n", GST_BUFFER_DATA(buffer)); - if(!frame) { gint height, width; GstCaps *buff_caps = gst_buffer_get_caps(buffer); @@ -220,9 +199,9 @@ IplImage * CvCapture_GStreamer::retrieveFrame(int) gst_caps_unref(buff_caps); } + // no need to memcpy, just use gstreamer's buffer :-) frame->imageData = (char *)GST_BUFFER_DATA(buffer); //memcpy (frame->imageData, GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE (buffer)); - //gst_data_copy_into (frame->imageData,GST_BUFFER_DATA(buffer)); //gst_buffer_unref(buffer); //buffer = 0; return frame; @@ -270,7 +249,7 @@ void CvCapture_GStreamer::setFilter(const char *property, int type, int v1, int else caps = gst_caps_new_simple("video/x-raw-rgb", property, type, v1, v2, NULL); } else { - printf("caps before setting %s\n", gst_caps_to_string(caps)); + //printf("caps before setting %s\n", gst_caps_to_string(caps)); if(type == G_TYPE_INT) gst_caps_set_simple(caps, "video/x-raw-rgb", property, type, v1, NULL); else @@ -312,14 +291,6 @@ void CvCapture_GStreamer::newPad(GstElement *uridecodebin, gst_object_unref (sinkpad); } -// static int buffernum = 0; -// static GstFlowReturn newbuffer(GstAppSink *sink, gpointer data) -// { - // printf("new buffer %d\n", buffernum); - // buffernum++; - // return GST_FLOW_OK; -// } - bool CvCapture_GStreamer::open( int type, const char* filename ) { close(); @@ -347,11 +318,9 @@ bool CvCapture_GStreamer::open( int type, const char* filename ) } if(!gst_uri_is_valid(filename)) { -// printf("file '%s' is not uri\n", filename); uri = realpath(filename, NULL); stream=false; if(uri) { -// printf("is file... ? %s\n", uri); uri = g_filename_to_uri(uri, NULL, NULL); if(!uri) { CV_WARN("GStreamer: Error opening file\n"); @@ -367,18 +336,14 @@ bool CvCapture_GStreamer::open( int type, const char* filename ) return false; } stream = true; -// printf("created custom bin\n"); manualpipeline = true; } - } - else { -// printf("file '%s' is uri\n", filename); + } else { stream = true; uri = g_strdup(filename); } if(!uridecodebin) { -// printf("creating uridecodebin\n"); uridecodebin = gst_element_factory_make ("uridecodebin", NULL); g_object_set(G_OBJECT(uridecodebin),"uri",uri, NULL); } @@ -387,22 +352,12 @@ bool CvCapture_GStreamer::open( int type, const char* filename ) close(); return false; } -// printf("Trying to connect to stream \n"); color = gst_element_factory_make("ffmpegcolorspace", NULL); - //printf("%sstreaming\n", stream ? "" : "not "); - -#ifdef HAVE_GSTREAMER_APP sink = gst_element_factory_make("appsink", NULL); - gst_app_sink_set_max_buffers (GST_APP_SINK(sink),1); - if (stream) { - gst_app_sink_set_drop (GST_APP_SINK(sink),true); - } -// GstAppSinkCallbacks cb = {0, 0, newbuffer, 0}; -// gst_app_sink_set_callbacks(GST_APP_SINK(sink), &cb, 0, 0); -#else - sink = gst_element_factory_make("opencv-appsink", NULL); -#endif + gst_app_sink_set_max_buffers (GST_APP_SINK(sink), 1); + if(stream) + gst_app_sink_set_drop (GST_APP_SINK(sink), true); GstCaps* caps= gst_caps_new_simple("video/x-raw-rgb", "red_mask", G_TYPE_INT, 255, "green_mask", G_TYPE_INT, 65280, @@ -413,14 +368,12 @@ bool CvCapture_GStreamer::open( int type, const char* filename ) pipeline = gst_pipeline_new (NULL); - //printf("adding stuff to pipeline\n"); if(manualpipeline) { // it is easier to link elements inside the same bin gst_bin_add_many(GST_BIN(uridecodebin), color, sink, NULL); // need the pipeline around the bin because bins don't know about timing gst_bin_add(GST_BIN(pipeline), uridecodebin); - } - else { + } else { gst_bin_add_many(GST_BIN(pipeline), uridecodebin, color, sink, NULL); } @@ -428,11 +381,8 @@ bool CvCapture_GStreamer::open( int type, const char* filename ) GstElement *e = gst_bin_get_by_name(GST_BIN(uridecodebin), "to-opencv"); if(e) { if(!gst_element_link(e, color)) { - //printf("catching 'pad-added' for element 'to-opencv'\n"); g_signal_connect(e, "pad-added", G_CALLBACK(newPad), color); - }/* else { - printf("linked to-opencv -> color\n"); - }*/ + } gst_object_unref(e); } else { CV_WARN("GStreamer: no element with 'name=to-opencv'\n"); @@ -475,7 +425,7 @@ bool CvCapture_GStreamer::open( int type, const char* filename ) return true; } -#ifdef HAVE_GSTREAMER_APP + // // // gstreamer image sequence writer @@ -638,13 +588,7 @@ CvVideoWriter* cvCreateVideoWriter_GStreamer(const char* filename, int fourcc, d delete wrt; return false; } -#else -CvVideoWriter* cvCreateVideoWriter_GStreamer(const char*, int, double, CvSize, int ) -{ - return false; -} -#endif void CvCapture_GStreamer::close() { if(pipeline) { diff --git a/modules/highgui/src/gstappsink.cpp b/modules/highgui/src/gstappsink.cpp deleted file mode 100644 index 4dff240..0000000 --- a/modules/highgui/src/gstappsink.cpp +++ /dev/null @@ -1,765 +0,0 @@ -/* GStreamer - * Copyright (C) 2007 David Schleef - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -#if 1 -#include "precomp.hpp" -#include -#include -#include - -#include - -#include "gstappsink.h" - -GST_DEBUG_CATEGORY (app_sink_debug); -#define GST_CAT_DEFAULT app_sink_debug - -static const GstElementDetails app_sink_details = -GST_ELEMENT_DETAILS ((gchar*)"AppSink", - (gchar*)"Generic/Sink", - (gchar*)"Allow the application to get access to raw buffer", - (gchar*)"David Schleef , Wim Taymans data; - data2 = g_value_peek_pointer (param_values + 0); - } else { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = - (GMarshalFunc_OBJECT__VOID) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, data2); - - gst_value_take_buffer (return_value, v_return); -} - -static void -gst_app_sink_base_init (gpointer g_class) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); - - //printf("appsinkbaseinit\n"); - - GST_DEBUG_CATEGORY_INIT (app_sink_debug, "appsink", 0, "appsink element"); - - gst_element_class_set_details (element_class, &app_sink_details); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&gst_app_sink_template)); -} - -static void -gst_app_sink_class_init (GstAppSinkClass * klass) -{ - GObjectClass *gobject_class = (GObjectClass *) klass; - GstBaseSinkClass *basesink_class = (GstBaseSinkClass *) klass; - - //printf("appsinkclassinit\n"); - - gobject_class->dispose = gst_app_sink_dispose; - gobject_class->finalize = gst_app_sink_finalize; - - gobject_class->set_property = gst_app_sink_set_property; - gobject_class->get_property = gst_app_sink_get_property; - - g_object_class_install_property (gobject_class, PROP_CAPS, - g_param_spec_boxed ("caps", "Caps", - "The caps of the sink pad", GST_TYPE_CAPS, (GParamFlags)G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, PROP_EOS, - g_param_spec_boolean ("eos", "EOS", - "Check if the sink is EOS", TRUE, G_PARAM_READABLE)); - - /** - * GstAppSink::eos: - * @appsink: the appsink element that emitted the signal - * - * Signal that the end-of-stream has been reached. - */ - gst_app_sink_signals[SIGNAL_EOS] = - g_signal_new ("eos", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GstAppSinkClass, eos), - NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); - /** - * GstAppSink::new-preroll: - * @appsink: the appsink element that emitted the signal - * @buffer: the buffer that caused the preroll - * - * Signal that a new preroll buffer is available. - */ - gst_app_sink_signals[SIGNAL_NEW_PREROLL] = - g_signal_new ("new-preroll", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GstAppSinkClass, new_preroll), - NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, - GST_TYPE_BUFFER); - /** - * GstAppSink::new-buffer: - * @appsink: the appsink element that emitted the signal - * @buffer: the buffer that is available - * - * Signal that a new buffer is available. - */ - gst_app_sink_signals[SIGNAL_NEW_BUFFER] = - g_signal_new ("new-buffer", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GstAppSinkClass, new_buffer), - NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, - G_TYPE_UINT); - - /** - * GstAppSink::pull-preroll: - * @appsink: the appsink element to emit this signal on - * - * Get the last preroll buffer on @appsink. - */ - gst_app_sink_signals[SIGNAL_PULL_PREROLL] = - g_signal_new ("pull-preroll", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstAppSinkClass, pull_preroll), NULL, - NULL, gst_app_marshal_OBJECT__VOID, GST_TYPE_BUFFER, 0, G_TYPE_NONE); - /** - * GstAppSink::pull-buffer: - * @appsink: the appsink element to emit this signal on - * - * Get the next buffer buffer on @appsink. - */ - gst_app_sink_signals[SIGNAL_PULL_PREROLL] = - g_signal_new ("pull-buffer", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GstAppSinkClass, pull_buffer), - NULL, NULL, gst_app_marshal_OBJECT__VOID, GST_TYPE_BUFFER, 0, - G_TYPE_NONE); - - basesink_class->start = gst_app_sink_start; - basesink_class->stop = gst_app_sink_stop; - basesink_class->event = gst_app_sink_event; - basesink_class->preroll = gst_app_sink_preroll; - basesink_class->render = gst_app_sink_render; - basesink_class->get_caps = gst_app_sink_getcaps; - - klass->pull_preroll = gst_app_sink_pull_preroll; - klass->pull_buffer = gst_app_sink_pull_buffer; -} - -static void -gst_app_sink_init (GstAppSink * appsink, GstAppSinkClass * klass) -{ - appsink->mutex = g_mutex_new (); - appsink->cond = g_cond_new (); - appsink->queue = g_queue_new (); -} - -static void -gst_app_sink_dispose (GObject * obj) -{ - GstAppSink *appsink = GST_APP_SINK (obj); - GstBuffer *buffer; - - //printf("appsinkdispose\n"); - - if (appsink->caps) { - gst_caps_unref (appsink->caps); - appsink->caps = NULL; - } - if (appsink->preroll) { - gst_buffer_unref (appsink->preroll); - appsink->preroll = NULL; - } - g_mutex_lock (appsink->mutex); - while ((buffer = (GstBuffer*)g_queue_pop_head (appsink->queue))) - gst_buffer_unref (buffer); - g_mutex_unlock (appsink->mutex); - - G_OBJECT_CLASS (parent_class)->dispose (obj); -} - -static void -gst_app_sink_finalize (GObject * obj) -{ - GstAppSink *appsink = GST_APP_SINK (obj); - - g_mutex_free (appsink->mutex); - g_cond_free (appsink->cond); - g_queue_free (appsink->queue); - - G_OBJECT_CLASS (parent_class)->finalize (obj); -} - -static void -gst_app_sink_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstAppSink *appsink = GST_APP_SINK (object); - - //printf("appsinksetproperty\n"); - - switch (prop_id) { - case PROP_CAPS: - gst_app_sink_set_caps (appsink, gst_value_get_caps (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_app_sink_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - GstAppSink *appsink = GST_APP_SINK (object); - - //printf("appsinkgetproperty\n"); - - switch (prop_id) { - case PROP_CAPS: - { - GstCaps *caps; - - caps = gst_app_sink_get_caps (appsink); - gst_value_set_caps (value, caps); - if (caps) - gst_caps_unref (caps); - break; - } - case PROP_EOS: - g_value_set_boolean (value, gst_app_sink_is_eos (appsink)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_app_sink_flush_unlocked (GstAppSink * appsink) -{ - GstBuffer *buffer; - - //printf("appsinkflushunlocked\n"); - - GST_DEBUG_OBJECT (appsink, "flushing appsink"); - appsink->is_eos = FALSE; - gst_buffer_replace (&appsink->preroll, NULL); - while ((buffer = (GstBuffer*)g_queue_pop_head (appsink->queue))) - gst_buffer_unref (buffer); - g_cond_signal (appsink->cond); -} - -static gboolean -gst_app_sink_start (GstBaseSink * psink) -{ - GstAppSink *appsink = GST_APP_SINK (psink); - - //printf("appsinkstart\n"); - - g_mutex_lock (appsink->mutex); - appsink->is_eos = FALSE; - appsink->started = TRUE; - GST_DEBUG_OBJECT (appsink, "starting"); - g_mutex_unlock (appsink->mutex); - - return TRUE; -} - -static gboolean -gst_app_sink_stop (GstBaseSink * psink) -{ - GstAppSink *appsink = GST_APP_SINK (psink); - - //printf("appsinkstop\n"); - - g_mutex_lock (appsink->mutex); - GST_DEBUG_OBJECT (appsink, "stopping"); - appsink->started = FALSE; - gst_app_sink_flush_unlocked (appsink); - g_mutex_unlock (appsink->mutex); - - return TRUE; -} - -static gboolean -gst_app_sink_event (GstBaseSink * sink, GstEvent * event) -{ - GstAppSink *appsink = GST_APP_SINK (sink); - - //printf("appsinkevent\n"); - - switch (event->type) { - case GST_EVENT_EOS: - g_mutex_lock (appsink->mutex); - GST_DEBUG_OBJECT (appsink, "receiving EOS"); - appsink->is_eos = TRUE; - g_cond_signal (appsink->cond); - g_mutex_unlock (appsink->mutex); - break; - case GST_EVENT_FLUSH_START: - break; - case GST_EVENT_FLUSH_STOP: - g_mutex_lock (appsink->mutex); - GST_DEBUG_OBJECT (appsink, "received FLUSH_STOP"); - gst_app_sink_flush_unlocked (appsink); - g_mutex_unlock (appsink->mutex); - break; - default: - break; - } - return TRUE; -} - -static GstFlowReturn -gst_app_sink_preroll (GstBaseSink * psink, GstBuffer * buffer) -{ - GstAppSink *appsink = GST_APP_SINK (psink); - - //printf("appsinkpreroll\n"); - - g_mutex_lock (appsink->mutex); - GST_DEBUG_OBJECT (appsink, "setting preroll buffer %p", buffer); - gst_buffer_replace (&appsink->preroll, buffer); - g_cond_signal (appsink->cond); - g_mutex_unlock (appsink->mutex); - - g_signal_emit(psink, gst_app_sink_signals[SIGNAL_NEW_PREROLL], 0, buffer); - - return GST_FLOW_OK; -} - -static GstFlowReturn -gst_app_sink_render (GstBaseSink * psink, GstBuffer * buffer) -{ - GstAppSink *appsink = GST_APP_SINK (psink); - - g_mutex_lock (appsink->mutex); - GST_DEBUG_OBJECT (appsink, "pushing render buffer %p on queue", buffer); - g_queue_push_tail (appsink->queue, gst_buffer_ref (buffer)); - g_cond_signal (appsink->cond); -// printf("appsinkrender, have %d buffers\n", g_queue_get_length(appsink->queue)); - g_mutex_unlock (appsink->mutex); - g_signal_emit(psink, gst_app_sink_signals[SIGNAL_NEW_BUFFER], 0, - g_queue_get_length(appsink->queue)); - - return GST_FLOW_OK; -} - -static GstCaps * -gst_app_sink_getcaps (GstBaseSink * psink) -{ - GstCaps *caps; - - //printf("appsinkgetcaps\n"); - - GstAppSink *appsink = GST_APP_SINK (psink); - - GST_OBJECT_LOCK (appsink); - if ((caps = appsink->caps)) - gst_caps_ref (caps); - GST_DEBUG_OBJECT (appsink, "got caps %" GST_PTR_FORMAT, caps); - GST_OBJECT_UNLOCK (appsink); - - return caps; -} - -/* external API */ - -/** - * gst_app_sink_set_caps: - * @appsink: a #GstAppSink - * @caps: caps to set - * - * Set the capabilities on the appsink element. This function takes - * a copy of the caps structure. After calling this method, the sink will only - * accept caps that match @caps. If @caps is non-fixed, you must check the caps - * on the buffers to get the actual used caps. - */ -void -gst_app_sink_set_caps (GstAppSink * appsink, const GstCaps * caps) -{ - GstCaps *old; - - g_return_if_fail (appsink != NULL); - g_return_if_fail (GST_IS_APP_SINK (appsink)); - - GST_OBJECT_LOCK (appsink); - GST_DEBUG_OBJECT (appsink, "setting caps to %" GST_PTR_FORMAT, caps); - old = appsink->caps; - if (caps) - appsink->caps = gst_caps_copy (caps); - else - appsink->caps = NULL; - if (old) - gst_caps_unref (old); - GST_OBJECT_UNLOCK (appsink); -} - -/** - * gst_app_sink_get_caps: - * @appsink: a #GstAppSink - * - * Get the configured caps on @appsink. - * - * Returns: the #GstCaps accepted by the sink. gst_caps_unref() after usage. - */ -GstCaps * -gst_app_sink_get_caps (GstAppSink * appsink) -{ - GstCaps *caps; - - g_return_val_if_fail (appsink != NULL, NULL); - g_return_val_if_fail (GST_IS_APP_SINK (appsink), NULL); - - GST_OBJECT_LOCK (appsink); - if ((caps = appsink->caps)) - gst_caps_ref (caps); - GST_DEBUG_OBJECT (appsink, "getting caps of %" GST_PTR_FORMAT, caps); - GST_OBJECT_UNLOCK (appsink); - - return caps; -} - -/** - * gst_app_sink_is_eos: - * @appsink: a #GstAppSink - * - * Check if @appsink is EOS, which is when no more buffers can be pulled because - * an EOS event was received. - * - * This function also returns %TRUE when the appsink is not in the PAUSED or - * PLAYING state. - * - * Returns: %TRUE if no more buffers can be pulled and the appsink is EOS. - */ -gboolean -gst_app_sink_is_eos (GstAppSink * appsink) -{ - gboolean ret; - - g_return_val_if_fail (appsink != NULL, FALSE); - g_return_val_if_fail (GST_IS_APP_SINK (appsink), FALSE); - - g_mutex_lock (appsink->mutex); - if (!appsink->started) - goto not_started; - - if (appsink->is_eos && g_queue_is_empty (appsink->queue)) { - GST_DEBUG_OBJECT (appsink, "we are EOS and the queue is empty"); - ret = TRUE; - } else { - GST_DEBUG_OBJECT (appsink, "we are not yet EOS"); - ret = FALSE; - } - g_mutex_unlock (appsink->mutex); - - return ret; - -not_started: - { - GST_DEBUG_OBJECT (appsink, "we are stopped, return TRUE"); - g_mutex_unlock (appsink->mutex); - return TRUE; - } -} - -/** - * gst_app_sink_pull_preroll: - * @appsink: a #GstAppSink - * - * Get the last preroll buffer in @appsink. This was the buffer that caused the - * appsink to preroll in the PAUSED state. This buffer can be pulled many times - * and remains available to the application even after EOS. - * - * This function is typically used when dealing with a pipeline in the PAUSED - * state. Calling this function after doing a seek will give the buffer right - * after the seek position. - * - * Note that the preroll buffer will also be returned as the first buffer - * when calling gst_app_sink_pull_buffer(). - * - * If an EOS event was received before any buffers, this function returns - * %NULL. Use gst_app_sink_is_eos () to check for the EOS condition. - * - * This function blocks until a preroll buffer or EOS is received or the appsink - * element is set to the READY/NULL state. - * - * Returns: a #GstBuffer or NULL when the appsink is stopped or EOS. - */ -GstBuffer * -gst_app_sink_pull_preroll (GstAppSink * appsink) -{ - GstBuffer *buf = NULL; - - //printf("pull_preroll\n"); - - g_return_val_if_fail (appsink != NULL, NULL); - g_return_val_if_fail (GST_IS_APP_SINK (appsink), NULL); - - g_mutex_lock (appsink->mutex); - - while (TRUE) { - GST_DEBUG_OBJECT (appsink, "trying to grab a buffer"); - if (!appsink->started) - goto not_started; - - if (appsink->preroll != NULL) - break; - - if (appsink->is_eos) - goto eos; - - /* nothing to return, wait */ - GST_DEBUG_OBJECT (appsink, "waiting for the preroll buffer"); - g_cond_wait (appsink->cond, appsink->mutex); - } - buf = gst_buffer_ref (appsink->preroll); - GST_DEBUG_OBJECT (appsink, "we have the preroll buffer %p", buf); - g_mutex_unlock (appsink->mutex); - - return buf; - - /* special conditions */ -eos: - { - GST_DEBUG_OBJECT (appsink, "we are EOS, return NULL"); - g_mutex_unlock (appsink->mutex); - return NULL; - } -not_started: - { - GST_DEBUG_OBJECT (appsink, "we are stopped, return NULL"); - g_mutex_unlock (appsink->mutex); - return NULL; - } -} - -/** - * gst_app_sink_pull_buffer: - * @appsink: a #GstAppSink - * - * This function blocks until a buffer or EOS becomes available or the appsink - * element is set to the READY/NULL state. - * - * This function will only return buffers when the appsink is in the PLAYING - * state. All rendered buffers will be put in a queue so that the application - * can pull buffers at its own rate. Note that when the application does not - * pull buffers fast enough, the queued buffers could consume a lot of memory, - * especially when dealing with raw video frames. - * - * If an EOS event was received before any buffers, this function returns - * %NULL. Use gst_app_sink_is_eos () to check for the EOS condition. - * - * Returns: a #GstBuffer or NULL when the appsink is stopped or EOS. - */ -GstBuffer * -gst_app_sink_pull_buffer (GstAppSink * appsink) -{ - GstBuffer *buf = NULL; - - //printf("pull_buffer\n"); - - g_return_val_if_fail (appsink != NULL, NULL); - g_return_val_if_fail (GST_IS_APP_SINK (appsink), NULL); - - g_mutex_lock (appsink->mutex); - - while (TRUE) { - GST_DEBUG_OBJECT (appsink, "trying to grab a buffer"); - if (!appsink->started) - goto not_started; - - if (!g_queue_is_empty (appsink->queue)) - break; - - if (appsink->is_eos) - goto eos; - - /* nothing to return, wait */ - GST_DEBUG_OBJECT (appsink, "waiting for a buffer"); - g_cond_wait (appsink->cond, appsink->mutex); - } - buf = (GstBuffer*)g_queue_pop_head (appsink->queue); - GST_DEBUG_OBJECT (appsink, "we have a buffer %p", buf); - g_mutex_unlock (appsink->mutex); - - return buf; - - /* special conditions */ -eos: - { - GST_DEBUG_OBJECT (appsink, "we are EOS, return NULL"); - g_mutex_unlock (appsink->mutex); - return NULL; - } -not_started: - { - GST_DEBUG_OBJECT (appsink, "we are stopped, return NULL"); - g_mutex_unlock (appsink->mutex); - return NULL; - } -} - -/** - * gst_app_sink_peek_buffer: - * @appsink: a #GstAppSink - * - * This function returns a buffer if there is one queued but does not block. - * - * This function will only return buffers when the appsink is in the PLAYING - * state. All rendered buffers will be put in a queue so that the application - * can pull buffers at its own rate. Note that when the application does not - * pull buffers fast enough, the queued buffers could consume a lot of memory, - * especially when dealing with raw video frames. - * - * If an EOS event was received before any buffers, this function returns - * %NULL. Use gst_app_sink_is_eos () to check for the EOS condition. - * - * Returns: a #GstBuffer or NULL when the appsink is stopped or EOS. - */ -GstBuffer * -gst_app_sink_peek_buffer (GstAppSink * appsink) -{ - GstBuffer *buf = NULL; - - //printf("pull_buffer\n"); - - g_return_val_if_fail (appsink != NULL, NULL); - g_return_val_if_fail (GST_IS_APP_SINK (appsink), NULL); - - g_mutex_lock (appsink->mutex); - - GST_DEBUG_OBJECT (appsink, "trying to grab a buffer"); - if (!appsink->started) - goto not_started; - - if (g_queue_is_empty (appsink->queue)) - return NULL; - - if (appsink->is_eos) - goto eos; - - /* nothing to return, wait */ - buf = (GstBuffer*)g_queue_pop_head (appsink->queue); - GST_DEBUG_OBJECT (appsink, "we have a buffer %p", buf); - g_mutex_unlock (appsink->mutex); - - return buf; - - /* special conditions */ -eos: - { - GST_DEBUG_OBJECT (appsink, "we are EOS, return NULL"); - g_mutex_unlock (appsink->mutex); - return NULL; - } -not_started: - { - GST_DEBUG_OBJECT (appsink, "we are stopped, return NULL"); - g_mutex_unlock (appsink->mutex); - return NULL; - } -} - -guint -gst_app_sink_get_queue_length (GstAppSink * appsink) -{ - return g_queue_get_length (appsink->queue); -} -#endif diff --git a/modules/highgui/src/gstappsink.h b/modules/highgui/src/gstappsink.h deleted file mode 100644 index 5437285..0000000 --- a/modules/highgui/src/gstappsink.h +++ /dev/null @@ -1,89 +0,0 @@ -/* GStreamer - * Copyright (C) 2007 David Schleef - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _GST_APP_SINK_H_ -#define _GST_APP_SINK_H_ - -#include -#include - -G_BEGIN_DECLS - -#define GST_TYPE_APP_SINK \ - (gst_app_sink_get_type()) -#define GST_APP_SINK(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_APP_SINK,GstAppSink)) -#define GST_APP_SINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_APP_SINK,GstAppSinkClass)) -#define GST_IS_APP_SINK(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_APP_SINK)) -#define GST_IS_APP_SINK_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_APP_SINK)) - -typedef struct _GstAppSink GstAppSink; -typedef struct _GstAppSinkClass GstAppSinkClass; - -struct _GstAppSink -{ - GstBaseSink basesink; - - /*< private >*/ - GstCaps *caps; - - GCond *cond; - GMutex *mutex; - GQueue *queue; - GstBuffer *preroll; - gboolean started; - gboolean is_eos; -}; - -struct _GstAppSinkClass -{ - GstBaseSinkClass basesink_class; - - /* signals */ - gboolean (*eos) (GstAppSink *sink); - gboolean (*new_preroll) (GstAppSink *sink); - gboolean (*new_buffer) (GstAppSink *sink); - - /* actions */ - GstBuffer * (*pull_preroll) (GstAppSink *sink); - GstBuffer * (*pull_buffer) (GstAppSink *sink); -}; - -GType gst_app_sink_get_type(void); - -GST_DEBUG_CATEGORY_EXTERN (app_sink_debug); - -void gst_app_sink_set_caps (GstAppSink *appsink, const GstCaps *caps); -GstCaps * gst_app_sink_get_caps (GstAppSink *appsink); - -gboolean gst_app_sink_is_eos (GstAppSink *appsink); - -GstBuffer * gst_app_sink_pull_preroll (GstAppSink *appsink); -GstBuffer * gst_app_sink_pull_buffer (GstAppSink *appsink); -GstBuffer * gst_app_sink_peek_buffer (GstAppSink *appsink); - -guint gst_app_sink_get_queue_length (GstAppSink *appsink); - -G_END_DECLS - -#endif - -- 2.7.4