我正在尝试使用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文件?
感谢