Blame tests/examples/app/appsink-src.c

Packit 971217
/* GStreamer
Packit 971217
 *
Packit 971217
 * appsink-src.c: example for using appsink and appsrc.
Packit 971217
 *
Packit 971217
 * Copyright (C) 2008 Wim Taymans <wim.taymans@gmail.com>
Packit 971217
 *
Packit 971217
 * This library is free software; you can redistribute it and/or
Packit 971217
 * modify it under the terms of the GNU Library General Public
Packit 971217
 * License as published by the Free Software Foundation; either
Packit 971217
 * version 2 of the License, or (at your option) any later version.
Packit 971217
 *
Packit 971217
 * This library is distributed in the hope that it will be useful,
Packit 971217
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 971217
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 971217
 * Library General Public License for more details.
Packit 971217
 *
Packit 971217
 * You should have received a copy of the GNU Library General Public
Packit 971217
 * License along with this library; if not, write to the
Packit 971217
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Packit 971217
 * Boston, MA 02110-1301, USA.
Packit 971217
 */
Packit 971217
Packit 971217
#include <gst/gst.h>
Packit 971217
Packit 971217
#include <string.h>
Packit 971217
Packit 971217
#include <gst/app/gstappsrc.h>
Packit 971217
#include <gst/app/gstappsink.h>
Packit 971217
Packit 971217
/* these are the caps we are going to pass through the appsink and appsrc */
Packit 971217
const gchar *audio_caps =
Packit 971217
    "audio/x-raw,format=S16LE,channels=1,rate=8000, layout=interleaved";
Packit 971217
Packit 971217
typedef struct
Packit 971217
{
Packit 971217
  GMainLoop *loop;
Packit 971217
  GstElement *source;
Packit 971217
  GstElement *sink;
Packit 971217
} ProgramData;
Packit 971217
Packit 971217
/* called when the appsink notifies us that there is a new buffer ready for
Packit 971217
 * processing */
Packit 971217
static GstFlowReturn
Packit 971217
on_new_sample_from_sink (GstElement * elt, ProgramData * data)
Packit 971217
{
Packit 971217
  GstSample *sample;
Packit 971217
  GstBuffer *app_buffer, *buffer;
Packit 971217
  GstElement *source;
Packit 971217
  GstFlowReturn ret;
Packit 971217
Packit 971217
  /* get the sample from appsink */
Packit 971217
  sample = gst_app_sink_pull_sample (GST_APP_SINK (elt));
Packit 971217
  buffer = gst_sample_get_buffer (sample);
Packit 971217
Packit 971217
  /* make a copy */
Packit 971217
  app_buffer = gst_buffer_copy (buffer);
Packit 971217
Packit 971217
  /* we don't need the appsink sample anymore */
Packit 971217
  gst_sample_unref (sample);
Packit 971217
Packit 971217
  /* get source an push new buffer */
Packit 971217
  source = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
Packit 971217
  ret = gst_app_src_push_buffer (GST_APP_SRC (source), app_buffer);
Packit 971217
  gst_object_unref (source);
Packit 971217
Packit 971217
  return ret;
Packit 971217
}
Packit 971217
Packit 971217
/* called when we get a GstMessage from the source pipeline when we get EOS, we
Packit 971217
 * notify the appsrc of it. */
Packit 971217
static gboolean
Packit 971217
on_source_message (GstBus * bus, GstMessage * message, ProgramData * data)
Packit 971217
{
Packit 971217
  GstElement *source;
Packit 971217
Packit 971217
  switch (GST_MESSAGE_TYPE (message)) {
Packit 971217
    case GST_MESSAGE_EOS:
Packit 971217
      g_print ("The source got dry\n");
Packit 971217
      source = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
Packit 971217
      gst_app_src_end_of_stream (GST_APP_SRC (source));
Packit 971217
      gst_object_unref (source);
Packit 971217
      break;
Packit 971217
    case GST_MESSAGE_ERROR:
Packit 971217
      g_print ("Received error\n");
Packit 971217
      g_main_loop_quit (data->loop);
Packit 971217
      break;
Packit 971217
    default:
Packit 971217
      break;
Packit 971217
  }
Packit 971217
  return TRUE;
Packit 971217
}
Packit 971217
Packit 971217
/* called when we get a GstMessage from the sink pipeline when we get EOS, we
Packit 971217
 * exit the mainloop and this testapp. */
Packit 971217
static gboolean
Packit 971217
on_sink_message (GstBus * bus, GstMessage * message, ProgramData * data)
Packit 971217
{
Packit 971217
  /* nil */
Packit 971217
  switch (GST_MESSAGE_TYPE (message)) {
Packit 971217
    case GST_MESSAGE_EOS:
Packit 971217
      g_print ("Finished playback\n");
Packit 971217
      g_main_loop_quit (data->loop);
Packit 971217
      break;
Packit 971217
    case GST_MESSAGE_ERROR:
Packit 971217
      g_print ("Received error\n");
Packit 971217
      g_main_loop_quit (data->loop);
Packit 971217
      break;
Packit 971217
    default:
Packit 971217
      break;
Packit 971217
  }
Packit 971217
  return TRUE;
Packit 971217
}
Packit 971217
Packit 971217
int
Packit 971217
main (int argc, char *argv[])
Packit 971217
{
Packit 971217
  gchar *filename = NULL;
Packit 971217
  ProgramData *data = NULL;
Packit 971217
  gchar *string = NULL;
Packit 971217
  GstBus *bus = NULL;
Packit 971217
  GstElement *testsink = NULL;
Packit 971217
  GstElement *testsource = NULL;
Packit 971217
Packit 971217
  gst_init (&argc, &argv);
Packit 971217
Packit 971217
  if (argc == 2)
Packit 971217
    filename = g_strdup (argv[1]);
Packit 971217
  else
Packit 971217
    filename = g_strdup ("/usr/share/sounds/ekiga/ring.wav");
Packit 971217
Packit 971217
  if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
Packit 971217
    g_print ("File %s does not exist\n", filename);
Packit 971217
    g_free (filename);
Packit 971217
    return -1;
Packit 971217
  }
Packit 971217
Packit 971217
  data = g_new0 (ProgramData, 1);
Packit 971217
Packit 971217
  data->loop = g_main_loop_new (NULL, FALSE);
Packit 971217
Packit 971217
  /* setting up source pipeline, we read from a file and convert to our desired
Packit 971217
   * caps. */
Packit 971217
  string =
Packit 971217
      g_strdup_printf
Packit 971217
      ("filesrc location=\"%s\" ! wavparse ! audioconvert ! audioresample ! appsink caps=\"%s\" name=testsink",
Packit 971217
      filename, audio_caps);
Packit 971217
  g_free (filename);
Packit 971217
  data->source = gst_parse_launch (string, NULL);
Packit 971217
  g_free (string);
Packit 971217
Packit 971217
  if (data->source == NULL) {
Packit 971217
    g_print ("Bad source\n");
Packit 971217
    g_main_loop_unref (data->loop);
Packit 971217
    g_free (data);
Packit 971217
    return -1;
Packit 971217
  }
Packit 971217
Packit 971217
  /* to be notified of messages from this pipeline, mostly EOS */
Packit 971217
  bus = gst_element_get_bus (data->source);
Packit 971217
  gst_bus_add_watch (bus, (GstBusFunc) on_source_message, data);
Packit 971217
  gst_object_unref (bus);
Packit 971217
Packit 971217
  /* we use appsink in push mode, it sends us a signal when data is available
Packit 971217
   * and we pull out the data in the signal callback. We want the appsink to
Packit 971217
   * push as fast as it can, hence the sync=false */
Packit 971217
  testsink = gst_bin_get_by_name (GST_BIN (data->source), "testsink");
Packit 971217
  g_object_set (G_OBJECT (testsink), "emit-signals", TRUE, "sync", FALSE, NULL);
Packit 971217
  g_signal_connect (testsink, "new-sample",
Packit 971217
      G_CALLBACK (on_new_sample_from_sink), data);
Packit 971217
  gst_object_unref (testsink);
Packit 971217
Packit 971217
  /* setting up sink pipeline, we push audio data into this pipeline that will
Packit 971217
   * then play it back using the default audio sink. We have no blocking
Packit 971217
   * behaviour on the src which means that we will push the entire file into
Packit 971217
   * memory. */
Packit 971217
  string =
Packit 971217
      g_strdup_printf ("appsrc name=testsource caps=\"%s\" ! autoaudiosink",
Packit 971217
      audio_caps);
Packit 971217
  data->sink = gst_parse_launch (string, NULL);
Packit 971217
  g_free (string);
Packit 971217
Packit 971217
  if (data->sink == NULL) {
Packit 971217
    g_print ("Bad sink\n");
Packit 971217
    gst_object_unref (data->source);
Packit 971217
    g_main_loop_unref (data->loop);
Packit 971217
    g_free (data);
Packit 971217
    return -1;
Packit 971217
  }
Packit 971217
Packit 971217
  testsource = gst_bin_get_by_name (GST_BIN (data->sink), "testsource");
Packit 971217
  /* configure for time-based format */
Packit 971217
  g_object_set (testsource, "format", GST_FORMAT_TIME, NULL);
Packit 971217
  /* uncomment the next line to block when appsrc has buffered enough */
Packit 971217
  /* g_object_set (testsource, "block", TRUE, NULL); */
Packit 971217
  gst_object_unref (testsource);
Packit 971217
Packit 971217
  bus = gst_element_get_bus (data->sink);
Packit 971217
  gst_bus_add_watch (bus, (GstBusFunc) on_sink_message, data);
Packit 971217
  gst_object_unref (bus);
Packit 971217
Packit 971217
  /* launching things */
Packit 971217
  gst_element_set_state (data->sink, GST_STATE_PLAYING);
Packit 971217
  gst_element_set_state (data->source, GST_STATE_PLAYING);
Packit 971217
Packit 971217
  /* let's run !, this loop will quit when the sink pipeline goes EOS or when an
Packit 971217
   * error occurs in the source or sink pipelines. */
Packit 971217
  g_print ("Let's run!\n");
Packit 971217
  g_main_loop_run (data->loop);
Packit 971217
  g_print ("Going out\n");
Packit 971217
Packit 971217
  gst_element_set_state (data->source, GST_STATE_NULL);
Packit 971217
  gst_element_set_state (data->sink, GST_STATE_NULL);
Packit 971217
Packit 971217
  gst_object_unref (data->source);
Packit 971217
  gst_object_unref (data->sink);
Packit 971217
  g_main_loop_unref (data->loop);
Packit 971217
  g_free (data);
Packit 971217
Packit 971217
  return 0;
Packit 971217
}