【问题标题】:Internal data flow error in gstreamer c code that uses "adder" element?使用“加法器”元素的 gstreamer c 代码中的内部数据流错误?
【发布时间】:2013-11-25 15:22:57
【问题描述】:

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

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

代码:

#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;
}

【问题讨论】:

    标签: gstreamer


    【解决方案1】:

    对于您的应用程序,不需要为填充信号添加信号处理程序。您可以简单地编写您的应用程序如下:

    #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;
    

    }

    【讨论】:

      【解决方案2】:

      以下代码有效。

      #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;
      }
      

      【讨论】:

        猜你喜欢
        • 2020-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-16
        • 1970-01-01
        相关资源
        最近更新 更多