将元素状态设置为NULL时,程序挂起

时间:2014-04-11 03:48:12

标签: c linux gstreamer

我正在尝试使用gstreamer将AVI文件转换为两个MP4文件,gstreamer是0.10版本。 我的管道包含以下元素:

filesrc -> avidemux -> tee --> fakesink
                           |
                           --> h264parse -> mp4mux -> filesink

h264parse, mp4mux, filesink are in a custom bin.

在发送块的srcpad之后,我将一个EOS事件发送到h264parse,然后我尝试删除bin并替换一个新的bin以生成第二个MP4文件。 我的代码如下:

typedef enum {
  NO_NEW_FILE,  // Keep current file destination
  NEW_FILE,     // Switch file destination
} NewFileStatus;
static NewFileStatus newfile = NO_NEW_FILE; // Switch File Flag

struct PipeData {
  GstElement * pipeline;
  GstPad * vsrcpad;  // tee srcpad
};

static struct PipeData pipedata;

static void recording_bin_handle_message (GstBin * bin, GstMessage * message)
{
  RecordingBin *recording = (RecordingBin *)(bin);

  switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_EOS:
        g_print ("Got EOS in the recording bin\n");
        build_new_file_bin();
        break;
    default:
        break;
  }

  GST_BIN_CLASS (parent_class)->handle_message (bin, message);
}

static void build_new_file_bin ()
{
  char ele_name[16];
  GstState state;

  g_message("TEST setting NULL state");
  gst_element_set_state(file_bin_old, GST_STATE_NULL);

  // remove old file bin from pipeline
  g_message("TEST remove file bin");
  gst_bin_remove (GST_BIN (pipeline), file_bin_old);

  // build new file bin
  g_message("TEST build new file bin");
  g_snprintf(ele_name, sizeof(ele_name), "file_bin%d", counter);
  file_bin_new = GST_BIN(g_object_new (GST_TYPE_RECORDING_BIN, "name", ele_name, NULL));

  ....blah blah.....

}

static void pad_blocked_cb(GstPad * pad, gboolean blocked, gpointer userdata)
{
  g_message("TEST pad_blocked_cb");
  if (blocked)
  {
    GstPad * peer = gst_pad_get_peer (pad);

    file_bin_old = file_bin_new;
    gst_pad_unlink (pad, peer);

    g_message("send EOS to old file bin");
    gst_pad_send_event (peer, gst_event_new_eos ());
  }
  else
  {
    g_message("UNBLOCKED");
  }
}

// Block source and launch EOS to bin to achieve a full muxed file
static gboolean pad_probe_cb (GstPad * pad, GstBuffer * buffer, gpointer user_data)
{
  ....blah blah....    
  g_message ("TEST pad_probe_cb");
  gst_pad_remove_buffer_probe (pad, probe_id);

  g_message ("TEST block");
  gst_pad_set_blocked_async(pipedata.vsrcpad, TRUE, pad_blocked_cb, NULL);

  g_message ("TEST pad_probe_cb END");

  return TRUE;
}

// this timeout is periodically run as part of the mainloop
static gboolean timeout_cb (gpointer user_data)
{
  g_print ("TIMEOUT\n");
  if (!playing)
    return FALSE;

  newfile = NEW_FILE;
  /* install new probe for Keyframe and New File */
  probe_id = gst_pad_add_buffer_probe (pipedata.vsrcpad, G_CALLBACK(pad_probe_cb), pipeline);
  return TRUE;
}

当我运行程序时,我发现当将bin的状态更改为NULL时它会挂起。 无法生成第二个MP4文件。

** Message: TEST pad_probe_cb
** Message: TEST block
** Message: TEST pad_probe_cb END
** Message: TEST pad_blocked_cb
** Message: send EOS to old file bin
Got EOS in the recording bin
** Message: TEST setting NULL state
TIMEOUT
TIMEOUT
TIMEOUT

如何正确生成第二个MP4文件?

感谢

0 个答案:

没有答案