使用“adder”元素的gstreamer c代码中的内部数据流错误?

时间:2013-11-25 15:22:57

标签: gstreamer

我想将gst-launch命令转换为c代码。我是gstreamer编码的新手。有谁可以帮助我?

命令:gst-launch-0.10 uridecodebin uri = file:///media/afeb7785-7c21-45bf-b1b7-41d3263022f6/gst/bigcity.wav! audioconvert!音量='0.9'! audioconvert!加法器名称= m! autoaudiosink uridecodebin uri = file:///media/afeb7785-7c21-45bf-b1b7-41d3263022f6/gst/tereliya.wav! audioconvert!音量='0.3'! audioconvert!米。

C代码:

#include <gst/gst.h>
#include <glib.h>


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 ("End of 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 ("Error: %s\n", error->message);
      g_error_free (error);

      g_main_loop_quit (loop);
      break;
    }
    default:
      break;
  }

  return TRUE;
}


static void
on_pad_added (GstElement *element,
              GstPad     *pad,
              gpointer    data)
{
  GstPad *sinkpad;
  GstElement *decoder = (GstElement *) data;

  /* We can now link this pad with the vorbis-decoder sink pad */
  g_print ("Dynamic pad created, linking \n");

  sinkpad = gst_element_get_static_pad (decoder, "sink");

  gst_pad_link (pad, sinkpad);

  gst_object_unref (sinkpad);
}



int
main (int   argc,
      char *argv[])
{
  GMainLoop *loop;
  GstElement *pipeline, *source1, *source2, *mixer, *conv, *conv2, *sink;
  GstBus *bus;
  guint bus_watch_id;
  GstPad *adder_sinkpad;
  GstPad *adder_sinkpad2;
  GstPad *conv1_pad;
  GstPad *conv2_pad;
  gchar *pad1name;
  gchar *pad2name;
  /* Initialisation */
  gst_init (&argc, &argv);

  loop = g_main_loop_new (NULL, FALSE);


  /* Check input arguments */
/*  if (argc != 3) {
    g_printerr ("Usage: %s \n", argv[0]);
    return -1;
  }*/


  /* Create gstreamer elements */
  pipeline = gst_pipeline_new ("audio-player");
  source1  = gst_element_factory_make ("uridecodebin",  "uri-source1");
  source2  = gst_element_factory_make ("uridecodebin",  "uri-source2");
  mixer    = gst_element_factory_make ("adder",         "audio-mix");
  conv     = gst_element_factory_make ("audioconvert",  "conv");
  conv2     = gst_element_factory_make ("audioconvert", "conv2");
  sink     = gst_element_factory_make ("alsasink", "audio-output");

  if (!pipeline || !source1 || !source2 || !mixer || !conv || !conv2 || !sink) {
    g_printerr ("One element could not be created. Exiting.\n");
    return -1;
  }

  /* Set up the pipeline */

  /* we set the input filename to the source element */
  g_object_set (G_OBJECT (source1), "uri",  "file:///home/baibhav/gst/shadowoftheday.wav", NULL);
  g_object_set (G_OBJECT (source2), "uri",  "file:///home/baibhav/gst/valentinesday.wav" , NULL);

  g_object_set (G_OBJECT (mixer), "name", "mix", NULL);
  /* we add a message handler */
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  bus_watch_id = gst_bus_add_watch (bus, bus_call, loop);
  gst_object_unref (bus);

  /* we add all elements into the pipeline */
  gst_bin_add_many (GST_BIN (pipeline),
                    source1, conv, mixer, sink, source2, conv2, NULL);


  /* we link the elements together */
  int k,n;
  if((k=gst_element_link (source1, conv)) !=0 ) {
    g_print ("link1 error: %d\n",k);
    g_print ("cannot link source1 with conv\n");
    }
  if((n=gst_element_link (source2, conv2)) != 0) {
    g_print ("link2 error: %d\n",n);
    g_print ("cannot link source2 with conv2\n");
    }

  if(gst_element_link (mixer, sink) != TRUE) {
    g_print ("cannot link sink with mixer\n");
    }

  conv1_pad= gst_element_get_static_pad (conv, "src");
  conv2_pad= gst_element_get_static_pad (conv2, "src");
  adder_sinkpad = gst_element_get_request_pad (mixer, "sink%d");
  pad1name = gst_pad_get_name (adder_sinkpad);
  g_print ("pad1name: %s\n",pad1name );
  adder_sinkpad2 = gst_element_get_request_pad (mixer, "sink%d");
  pad2name = gst_pad_get_name (adder_sinkpad2);
  g_print ("pad2name: %s\n",pad2name );
  int i,j;
  if((i=gst_pad_link (conv1_pad, adder_sinkpad)) != 0) {
    g_print ("pad error: %d\n",i);
    g_print ("cannot link conv1 with adder1\n");
     }

  if((j=gst_pad_link (conv2_pad, adder_sinkpad2))!= 0) {
    g_print ("pad2 error: %d\n",j);
    g_print ("cannot link conv2 with adder2\n");
    }

//  g_signal_connect (conv, "pad-added", G_CALLBACK (on_pad_added), mixer);
//  g_signal_connect (conv2, "pad-added", G_CALLBACK (on_pad_added), mixer);

  /* Set the pipeline to "playing" state*/
  g_print ("Now playing\n");
  gst_element_set_state (pipeline, GST_STATE_PLAYING);


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


  /* Out of the main loop, clean up nicely */
  g_print ("Returned, stopping playback\n");
  gst_element_set_state (pipeline, GST_STATE_NULL);

  g_print ("Deleting pipeline\n");
//  gst_pad_unlink (conv2_pad, adder_sinkpad2);
//  gst_pad_unlink ((conv1_pad, adder_sinkpad);
  gst_object_unref (GST_OBJECT (pipeline));
  g_source_remove (bus_watch_id);
  g_main_loop_unref (loop);

  return 0;
}

2 个答案:

答案 0 :(得分:0)

对于您的应用,不需要为添加焊盘的信号添加信号处理程序。您可以按如下方式编写应用程序:

#include <gst/gst.h>
#include <glib.h>


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 ("End of 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 ("Error: %s\n", error->message);
                    g_error_free (error);

                    g_main_loop_quit (loop);
                    break;
                }
    default:
                break;
}

return TRUE;
    }



int main (int   argc,
    char *argv[])
    {
GMainLoop *loop;
GstElement *pipeline, *source1, *source2, *mixer, *conv, *conv2, *sink;
GstBus *bus;
guint bus_watch_id;
GstPad *adder_sinkpad;
GstPad *adder_sinkpad2;
GstPad *conv1_pad;
GstPad *conv2_pad;
gchar *pad1name;
gchar *pad2name;
/* Initialisation */
gst_init (&argc, &argv);

loop = g_main_loop_new (NULL, FALSE);


/* Check input arguments */
/*  if (argc != 3) {
 *      g_printerr ("Usage: %s \n", argv[0]);
 *          return -1;
 *            }*/


/* Create gstreamer elements */
pipeline = gst_pipeline_new ("audio-player");
source1  = gst_element_factory_make ("audiotestsrc",  "uri-source1");
source2  = gst_element_factory_make ("audiotestsrc",  "uri-source2");
mixer    = gst_element_factory_make ("adder",         "audio-mix");
conv     = gst_element_factory_make ("audioconvert",  "conv");
conv2     = gst_element_factory_make ("audioconvert", "conv2");
sink     = gst_element_factory_make ("alsasink", "audio-output");

if (!pipeline || !source1 || !source2 || !mixer || !conv || !conv2 || !sink) {
    g_printerr ("One element could not be created. Exiting.\n");
    return -1;
}

/* Set up the pipeline */

/* we set the input filename to the source element */
g_object_set (G_OBJECT (source1), "uri",  "file:///home/baibhav/gst/shadowoftheday.wav", NULL);
g_object_set (G_OBJECT (source2), "uri",  "file:///home/baibhav/gst/valentinesday.wav" , NULL);

g_object_set (G_OBJECT (mixer), "name", "mix", NULL);
/* we add a message handler */
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
bus_watch_id = gst_bus_add_watch (bus, bus_call, loop);
gst_object_unref (bus);

/* we add all elements into the pipeline */
gst_bin_add_many (GST_BIN (pipeline),
        source1, conv, mixer, sink, source2, conv2, NULL);


/* we link the elements together */
int k,n;
if((k=gst_element_link_many (source1, conv,mixer,NULL)== 0) ) {
    g_print ("link1 error: %d\n",k);
    g_print ("cannot link source1 with conv\n");
}
if((n=gst_element_link_many (source2, conv2,mixer,NULL))== 0 ) {
    g_print ("link2 error: %d\n",n);
    g_print ("cannot link source2 with conv2\n");
}

if(gst_element_link (mixer, sink) == 0 ) {
    g_print ("cannot link sink with mixer\n");
}


//    /* Set the pipeline to "playing" state*/
g_print ("Now playing\n");
gst_element_set_state (pipeline, GST_STATE_PLAYING);
//
//
//          /* Iterate */
g_print ("Running...\n");
g_main_loop_run (loop);

//
//                /* Out of the main loop, clean up nicely */
g_print ("Returned, stopping playback\n");
gst_element_set_state (pipeline, GST_STATE_NULL);

g_print ("Deleting pipeline\n");
//  gst_pad_unlink (conv2_pad, adder_sinkpad2);
//  gst_pad_unlink ((conv1_pad, adder_sinkpad);
gst_object_unref (GST_OBJECT (pipeline));
g_source_remove (bus_watch_id);
g_main_loop_unref (loop);

return 0;

}

答案 1 :(得分:0)

下面的代码可以使用。

#include <gst/gst.h>
#include <glib.h>


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 ("End of 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 ("Error: %s\n", error->message);
      g_error_free (error);

      g_main_loop_quit (loop);
      break;
    }
    default:
      break;
  }

  return TRUE;
}


static void
on_pad_added (GstElement *element,
              GstPad     *pad,
              gpointer    data)
{
  GstPad *sinkpad;
  GstElement *decoder = (GstElement *) data;

  /* We can now link this pad with the vorbis-decoder sink pad */
  g_print ("Dynamic pad created, linking \n");

  sinkpad = gst_element_get_static_pad (decoder, "sink");

  gst_pad_link (pad, sinkpad);

  gst_object_unref (sinkpad);
}



int
main (int   argc,
      char *argv[])
{
  GMainLoop *loop;
  GstElement *pipeline, *source1, *source2, *mixer, *conv1, *conv2, *sink;
  GstBus *bus;
  guint bus_watch_id;
  GstPad *adder_sinkpad1;
  GstPad *adder_sinkpad2;
  GstPad *vol1_pad, *vol2_pad;
  gchar *pad1name;
  gchar *pad2name;
  GstElement *vol1, *vol2;
  int n;

  /* Initialisation */
  gst_init (&argc, &argv);

  loop = g_main_loop_new (NULL, FALSE);


  /* Check input arguments */
  if (argc != 3) {
    g_printerr ("Usage: %s file1 file2\n", argv[0]);
    return -1;
  }


  /* Create gstreamer elements */
  pipeline = gst_pipeline_new ("audio-player");
  source1  = gst_element_factory_make ("uridecodebin",  "uri-source1");
  source2  = gst_element_factory_make ("uridecodebin",  "uri-source2");
  mixer    = gst_element_factory_make ("adder",         "audio-mix");
  conv1     = gst_element_factory_make ("audioconvert",  "conv1");
  conv2     = gst_element_factory_make ("audioconvert", "conv2");
  vol1 = gst_element_factory_make("volume", "vol1");
  vol2 = gst_element_factory_make("volume", "vol2");
  sink     = gst_element_factory_make ("alsasink", "audio-output");

  if (!pipeline || !source1 || !source2 || !mixer || !conv1 || !conv2 || !vol1 || !vol2 || !sink) {
    g_printerr ("One element could not be created. Exiting.\n");
    return -1;
  }

  /* Set up the pipeline */

  /* we set the input filename to the source element */

  g_object_set (G_OBJECT (source1), "uri",  argv[1], NULL);
  g_object_set (G_OBJECT (source2), "uri",  argv[2], NULL);

  g_object_set (G_OBJECT (mixer), "name", "mix", NULL);

  g_object_set(G_OBJECT (vol1), "volume", 0.9, NULL);
  g_object_set(G_OBJECT (vol2), "volume", 0.3, NULL);

  /* we add a message handler */
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  bus_watch_id = gst_bus_add_watch (bus, bus_call, loop);
  gst_object_unref (bus);

  /* we add all elements into the pipeline */
  gst_bin_add_many (GST_BIN (pipeline),
                    source1, conv1, vol1, mixer, sink, source2, conv2, vol2, NULL);


  /* we link the elements together */
#if 0 //Doesnt work directly linking elements
  g_print("link elements directly \n");
  if((n=gst_element_link (source1, conv1)) == 0 ) {
    g_print ("link1 error: %d\n",n);
    g_print ("cannot link source1 with conv1\n");
  }

  if((n=gst_element_link (source2, conv2)) == 0) {
    g_print ("link2 error: %d\n",n);
    g_print ("cannot link source2 with conv2\n");
  }
#else
  g_print("use dynamic pads to link elements \n");
  g_signal_connect (source1, "pad-added", G_CALLBACK (on_pad_added), conv1);
  g_signal_connect (source2, "pad-added", G_CALLBACK (on_pad_added), conv2);
#endif

  if((n=gst_element_link (conv1, vol1)) == 0) {
    g_print ("link2 error: %d\n",n);
    g_print ("cannot link conv with vol1\n");
  }

  if((n=gst_element_link (conv2, vol2)) == 0) {
    g_print ("link2 error: %d\n",n);
    g_print ("cannot link conv2 with conv2\n");
  }

  if((n = gst_element_link (mixer, sink)) == 0) {
    g_print ("cannot link sink with mixer\n");
  }
  vol1_pad= gst_element_get_static_pad (vol1, "src");
  vol2_pad= gst_element_get_static_pad (vol2, "src");

  adder_sinkpad1 = gst_element_get_request_pad (mixer, "sink_%u");
  pad1name = gst_pad_get_name (adder_sinkpad1);
  g_print ("pad1name: %s\n",pad1name );
  adder_sinkpad2 = gst_element_get_request_pad (mixer, "sink_%u");
  pad2name = gst_pad_get_name (adder_sinkpad2);
  g_print ("pad2name: %s\n",pad2name );

  int i,j;
  if((i=gst_pad_link (vol1_pad, adder_sinkpad1)) != 0) {
    g_print ("pad error: %d\n",i);
    g_print ("cannot link conv1 with adder1\n");
     }

  if((j=gst_pad_link (vol2_pad, adder_sinkpad2))!= 0) {
    g_print ("pad2 error: %d\n",j);
    g_print ("cannot link conv2 with adder2\n");
    }

  /* Set the pipeline to "playing" state*/
  g_print ("Now playing\n");
  gst_element_set_state (pipeline, GST_STATE_PLAYING);


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


  /* Out of the main loop, clean up nicely */
  g_print ("Returned, stopping playback\n");
  gst_element_set_state (pipeline, GST_STATE_NULL);

  g_print ("Deleting pipeline\n");

  gst_object_unref (GST_OBJECT (pipeline));
  g_source_remove (bus_watch_id);
  g_main_loop_unref (loop);

  return 0;
}