gstreamer - 在运行时更换音频接收器

时间:2017-09-15 20:16:32

标签: gstreamer alsa

我想删除alsa接收器并在运行时创建新接收器。 旧元素和新元素都已删除并成功创建。 我尝试恢复音频,但音频没有播放。 请告知哪部分是错误的。

#include <stdio.h>
#include <unistd.h>
#include <glib.h>
#include <gst/gst.h>
#include <pthread.h>

GstElement *pipeline, *src_, *conv_, *alsaaudiosink, *volume_, *fake_sink_;
gint64 pos, len;
GstPad *src_pad;
GstFormat fmt = GST_FORMAT_TIME;
GstSeekFlags gst_flags = (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT);

void OnNewPadAdded (GstElement* src, GstPad* new_pad, gpointer data);
GstBusSyncReply GstreamerMessageHandler(GstBus* gst_bus, GstMessage* message, gpointer data);


GstBusSyncReply GstreamerMessageHandler(GstBus* gst_bus, GstMessage* message, gpointer data) {
  printf("GstreamerMessageHandler\n");
  switch(GST_MESSAGE_TYPE(message)) {
    case GST_MESSAGE_EOS:
      break;
    case GST_MESSAGE_BUFFERING:
      break;
    case GST_MESSAGE_DURATION:
      break;
    case GST_MESSAGE_ERROR:
      break;
    case GST_MESSAGE_STATE_CHANGED:
      break;
    case GST_MESSAGE_STREAM_STATUS:
    default:
      break;
  } 
    return GST_BUS_DROP; 
}

void OnNewPadAdded (GstElement* src, GstPad* new_pad, gpointer data) {
  GstPad *sink_pad_audio = gst_element_get_static_pad (conv_, "sink");

  if (GST_PAD_IS_LINKED (sink_pad_audio)) {
    g_object_unref (sink_pad_audio);
    return;
  }

  gst_pad_link (new_pad, sink_pad_audio);
  g_object_unref (sink_pad_audio);
}

void reset_fake_sink() {
 //remove fakesink
  gst_element_unlink(conv_, fake_sink_);     
  gst_bin_remove (GST_BIN (pipeline), fake_sink_);
  gst_element_set_state (fake_sink_, GST_STATE_NULL);
  gst_object_unref (GST_OBJECT (fake_sink_));    
}

void create_alsa_sink() {
  printf("create alsa\n");
  alsaaudiosink = gst_element_factory_make ("alsasink", "sink");
  // g_object_set(alsaaudiosink, "device", "AdevWebMainOut", NULL);
  gst_bin_add (GST_BIN (pipeline), alsaaudiosink);
  gst_element_link(conv_, alsaaudiosink);
  gst_element_sync_state_with_parent (alsaaudiosink);
  gst_element_sync_state_with_parent (conv_);
}

void remove_alsa_sink() {
  printf("remove alsa\n");
  gst_element_unlink(conv_, alsaaudiosink);     
  gst_bin_remove (GST_BIN (pipeline), alsaaudiosink);
  gst_element_set_state (alsaaudiosink, GST_STATE_NULL);
  gst_object_unref (GST_OBJECT (alsaaudiosink));       
  gst_element_sync_state_with_parent (conv_);
}

int main (int argc, char *argv[]) {

  gst_init(&argc, &argv);

  if (argc != 2) {
    printf("%s <mp3 filename>\n", __FUNCTION__, argv[0]);
    exit (-1);
  }

  src_ = gst_element_factory_make ("uridecodebin", "source");
  conv_ = gst_element_factory_make ("audioconvert", "convert");
  fake_sink_ = gst_element_factory_make ("fakesink", NULL);

  pipeline = gst_pipeline_new ("pipeline");

  if (!pipeline || !src_ || !conv_ || !fake_sink_) {
    return -1;
  }

  gst_bin_add_many (GST_BIN (pipeline), src_, conv_, fake_sink_, NULL);

  if (!gst_element_link (conv_, fake_sink_)) {
      gst_object_unref(pipeline);
      return -1;
  }

// Bus - Sync.
  GstBus* gst_bus;
  gst_bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));

  gst_bus_set_sync_handler(gst_bus, GstreamerMessageHandler, NULL);
  gst_object_unref(gst_bus);
  g_signal_connect (src_, "pad-added", G_CALLBACK (OnNewPadAdded), NULL);

  g_object_set (src_, "uri", argv[1], NULL);

  gst_element_set_state(pipeline, GST_STATE_PAUSED);

  //remove fakesink
  reset_fake_sink();

  //create new sink
  create_alsa_sink(); 

  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  static int is_quiting = 0;

  while (1) {
    if(!(gst_bin_iterate_elements (GST_BIN (pipeline)))) break;
    printf(" q:Quit, press'c' : Pause -> remove sink -> create sink -> Play\n");
    char ch =0 ;
    ch=getchar();
    switch (ch) {
    case 'c':
        /* pause */
        gst_element_set_state (pipeline, GST_STATE_PAUSED);
        remove_alsa_sink();
        create_alsa_sink(); 
        gst_element_set_state (pipeline, GST_STATE_PLAYING);
    break;
    case 'q':
      is_quiting = 1;
    break;

    default:

    break;

    }

    if(is_quiting) break;
  }
  /* stop the pipeline */
  gst_element_set_state (pipeline, GST_STATE_NULL);
  /* we don't need a reference to these objects anymore */
  gst_object_unref (GST_OBJECT (pipeline));
  /* unreffing the pipeline unrefs the contained elements as well */
  exit (0);
}

如果音频不响,请按以下方式播放。

  

gst_element_seek_simple(管道,GST_FORMAT_TIME,gst_flags,0);
  gst_element_set_state(管道,GST_STATE_PLAYING);

我不知道具体原因。

1 个答案:

答案 0 :(得分:0)