[gst-devel] pause problem

Paulo Benatto benatto at gmail.com
Thu Aug 20 19:05:24 CEST 2009


i created a pipe filesrc ! decodebin ! appsink and set the appsink to dont
emit signals and block when reaches a maximum number of buffers, my problem
is that with this behaviour after pausing the pipeline i cant set it to
playing again, the stream seens to be locked. Before setting to play again
if i perform a seek (to any position) them the playing will occur. Im using
a separated thread to pull the data from the appsink, i dont now if this is
a bug of appsink, i cant see what im doing wrong (i used gst-debug=5 and the
pipe seens to get blocked when i set it back to playing state). I would
apreciate if someone could help, here is the source code:



#include <stdio.h>
#include <glib.h>
#include <gst/gst.h>
#include <gst/app/gstappsink.h>

static const int SLEEP_TIME_US = 5000;
static gboolean run_thread = TRUE;

static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
{
   GMainLoop *loop = (GMainLoop *) data;

   switch (GST_MESSAGE_TYPE (msg))
   {

       case GST_MESSAGE_EOS:
       {
       g_print ("Fim da stream\n");
       g_main_loop_quit (loop);
       break;
       }

       case GST_MESSAGE_ERROR:
       {
       gchar  *debug;
       GError *error;

       gst_message_parse_error (msg, &error, &debug);
       g_free (debug);

       g_printerr ("Erro: %s\n", error->message);
       g_error_free (error);

       g_main_loop_quit (loop);

       break;
       }

       default:
       g_print("Tipo da mensagem [%d], Nome da mensagem [%s]\n",
GST_MESSAGE_TYPE (msg), GST_MESSAGE_TYPE_NAME(msg));
       break;
   }       return TRUE;
}

// ------------------ START PADS - ELEMENTS GENERIC FUNCTIONS
--------------- //

static int connect_pads(GstPad* src, GstPad* sink)
{
   gchar* src_name = NULL;
   gchar* sink_name = NULL;
   if(gst_pad_link(src, sink) != GST_PAD_LINK_OK){
       src_name = gst_pad_get_name(src);
       sink_name = gst_pad_get_name(sink);
       g_debug("Error linking [%s] to [%s]", src_name, sink_name);
       g_free(src_name);
       g_free(sink_name);
       return FALSE;
   }
   return TRUE;
}

// ------------------ END PADS - ELEMENTS GENERIC FUNCTIONS ---------------
//

// ------------------ START DECODEBIN FUNCTIONS --------------------- //
static void callback_type_found(GstElement *decodebin, GstPad *srcpad,
gboolean last, gpointer output)
{
   GstElement* output_element = (GstElement*)output;
   GstPad* sinkpad = NULL;
      if(output_element == NULL) {
       g_debug("callback_type_found: Error casting gpointer to GstElement");

       return;
   }

   sinkpad = gst_element_get_static_pad(output_element, "sink");
if(sinkpad == NULL) {
       g_debug("callback_type_found: Error getting output_element sink
pad");
       return;
   }

   if(!connect_pads(srcpad, sinkpad)) {
       g_debug("callback_type_found: Cannot connect decodebin "
                                               "srcpad to output_element
sinkpad");
       g_object_unref (sinkpad);
       return;
   }

   g_debug("callback_type_found: Ended successfully");
   g_object_unref(sinkpad);
}

static void build_decodebin(GstElement* pipeline, GstElement* src,
GstElement* output, const gchar* caps)
{
   GstElement* decoder = gst_element_factory_make ("decodebin", "decoder");
   g_debug("Trying to use decodebin to find type and decode media!");
   if(!decoder) {
       g_debug("build_decodebin: Error creating decodebin");
       return;
   }

   if(caps != NULL) {
       GstCaps* caps_obj = gst_caps_from_string(caps);
       if(caps_obj == NULL){
           g_debug("build_decodebin: Error creating caps[%s]", caps);
           return;
       }
       g_object_set(G_OBJECT (decoder), "sink-caps", caps_obj, NULL);
   }

   if(!gst_bin_add(GST_BIN (pipeline), decoder)) {
       g_debug("build_decodebin: Error inserting the decodebin on the
pipeline");
       return;
   }

   if(!gst_element_link(src, decoder)) {
       g_debug("build_decodebin: Error linking the source element to the
decoder");
       return;
   }
      g_signal_connect (decoder, "new-decoded-pad",
G_CALLBACK(callback_type_found), output);
}

// ------------------ END DECODEBIN FUNCTIONS --------------------- //


static gpointer pull_func(gpointer data)
{
   GstAppSink* appsink = (GstAppSink*) data;
   GstBuffer* buffer = NULL;
      while(run_thread){
       g_usleep(SLEEP_TIME_US);
       if(appsink){
           buffer = gst_app_sink_pull_buffer(appsink);
           if(buffer){
               g_debug("appsink: buffer timestamp(%lli) size(%d)",
               GST_BUFFER_TIMESTAMP(buffer),
               GST_BUFFER_SIZE(buffer));
               gst_buffer_unref(buffer);
           }else{
               g_warning("NULL BUFFER PULLED !!");
           }
       }else{
           g_warning("NULL APPSINK !!!");
       }
   }

   return NULL;
}

gboolean resume_time(gpointer data)
{
   /* IF I DO THIS THE PLAYING WORKS AND APPSINK GIVES ME BUFFERS
   gint64 cur;
   GstFormat format =
gst_format_get_by_nick(gst_format_get_name(GST_FORMAT_TIME));
   gst_element_query_position(GST_ELEMENT (data), &format, &cur);

   if (!gst_element_seek_simple(GST_ELEMENT(data),
                                GST_FORMAT_TIME,
                                GST_SEEK_FLAG_FLUSH |
GST_SEEK_FLAG_KEY_UNIT, cur)) {
       g_print ("Seek failed!\n");
       return FALSE;
   }*/

   g_debug("PLAY \n");
   gst_element_set_state(GST_ELEMENT(data), GST_STATE_PLAYING);

   return FALSE;
}

gboolean pause_time(gpointer data)
{
   g_debug("PAUSE \n");
   gst_element_set_state (GST_ELEMENT(data), GST_STATE_PAUSED);
   return FALSE;
}

int main(int argc, char *argv[])
{
   GstElement *pipeline = NULL;
   GstElement *source = NULL;
   GstElement *appsink = NULL;
   GstBus *bus = NULL;
   GMainLoop *loop = NULL;
   GThread * pull_thread = NULL;

   if(argc < 2){
       g_debug("Usage [%s] [uri]", argv[0]);
       return -1;
   }
   gst_init (&argc, &argv);
   loop = g_main_loop_new (NULL, FALSE);
      pipeline      = gst_pipeline_new ("pause-block-pipe");
   source        = gst_element_factory_make ("filesrc", "sourceFile");
   g_object_set (G_OBJECT(source), "location", argv[1], NULL);
   appsink       = gst_element_factory_make ("appsink", "asink");

   if (!pipeline || !source || !appsink) {
       g_printerr ("Erro na criacao de um dos elementos do pipe.\n");
       return -1;
   }
   bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
   gst_bus_add_watch (bus, bus_call, loop);
   gst_object_unref (bus);

   gst_bin_add_many (GST_BIN(pipeline), source, appsink, NULL);
   build_decodebin(pipeline, source, appsink, NULL);

   gst_app_sink_set_max_buffers((GstAppSink*)appsink, 10);
   g_object_set (G_OBJECT(appsink), "sync", FALSE, NULL);

   pull_thread =  g_thread_create(pull_func, appsink, TRUE, NULL);
   if(!pull_thread){
       g_debug("Error creating thread!!");
       return -1;
   }
   gst_element_set_state (pipeline, GST_STATE_PLAYING);
   g_timeout_add_seconds(2, pause_time, pipeline);
   g_timeout_add_seconds(6, resume_time, pipeline);

   /* Iterate */
   g_print ("Executando...\n");
   g_main_loop_run (loop);

   /* Out of the main loop, clean up nicely */
   g_print ("Terminando...\n");
   run_thread = FALSE;
   gst_element_set_state (pipeline, GST_STATE_NULL);

   g_print ("Deletando pipeline...\n");
   gst_object_unref (GST_OBJECT (pipeline));
      return 1;    }



-- 
Paulo Leonardo Benatto, patito
"the fear of being free makes you proud of being a slave"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20090820/ca93411b/attachment.htm>


More information about the gstreamer-devel mailing list