我的目标是使用刻录字幕转码视频(使用textoverlay)。 我参考Gstreamer教程并编写一个小程序来测试2 管道
管道1(没有字幕):
multiqueue max-size-buffers = 10000 max-size-bytes = 0 max-size-time = 0 name = mq splitfilesrc location =“/ share / Multimedia / debug / harry / Harry.Potter.and.the.Deathly .Hallows.Part.1.2010.BluRay.1080p.AAC.4Audio.x264-CHD.mkv“! matroskademux name = dmx dmx。 !排队! identity sync = false! h264parse! omxh264dec! omxh264enc force-keyframe-period = 40 scaling-width = 1920 scaling-height = 800! h264parse! mq.sink_0 mq.src_0! mpegtsmux name = mux! filesink location =“/ share / Public / aaa.ts”dmx。 ! aacparse!排队! identity sync = false! faad name = adec! audioconvert!听觉样本! audio / x-raw,channels = 2,rate = 44100!排队! voaacenc! audio / mpeg,mpegversion = 4,stream-format = raw! aacparse! mq.sink_1 mq.src_1! audio / mpeg,mpegversion = 4,stream-format = raw!多路复用器。
管道2(带副标题):
multiqueue max-size-buffers = 10000 max-size-bytes = 0 max-size-time = 0 name = mq textoverlay wait-text = false name = txo splitfilesrc location =“/ share / Multimedia / debug / harry / Harry.Potter.and.the.Deathly.Hallows.Part.1.2010.BluRay.1080p.AAC.4Audio.x264-CHD.mkv“! matroskademux name = dmx dmx。 !排队! identity sync = false! h264parse! omxh264dec! txo.video_sink txo.src! omxh264enc force-keyframe-period = 40 scaling-width = 1920 scaling-height = 800! h264parse! mq.sink_0 mq.src_0! mpegtsmux name = mux!文件接收位置= “/共享/公共/ aaa.ts” filesrc位置=“/共享/多媒体/调试/哈里/ Harry.Potter.and.the.Deathly.Hallows.Part.1.2010.BluRay.1080p.AAC.4Audio。 x264-CHD.zh-TW.srt“! subparse subtitle-encoding = UTF-8! txo.text_sink dmx。 ! aacparse!排队! identity sync = false! faad name = adec! audioconvert!听觉样本! audio / x-raw,channels = 2,rate = 44100!排队! voaacenc! audio / mpeg,mpegversion = 4,stream-format = raw! aacparse! mq.sink_1 mq.src_1! audio / mpeg,mpegversion = 4,stream-format = raw! MUX。
无论是否执行搜索事件,管道1都能正常工作。 管道2也正常工作,没有寻求,但有问题 寻求执行。 它将阻止
ret = gst_element_seek_simple (pipeline, GST_FORMAT_TIME,
GST_SEEK_FLAG_KEY_UNIT, 7280 * GST_SECOND);
永远不会回来。
我能做些什么吗?以下是我的测试代码
的问候, Tany
#include <gst/gst.h>
int main(int argc, char *argv[]) {
GstElement *pipeline;
GstBus *bus;
GstMessage *msg;
gboolean ret;
int isSeek=0;
/* Initialize GStreamer */
gst_init (&argc, &argv);
/* Build the pipeline */
#if 1 // with subtitle
pipeline = gst_parse_launch("multiqueue max-size-buffers=10000 max-size-bytes=0 max-size-time=0 name=mq textoverlay wait-text=false name=txo splitfilesrc location=\"/share/Multimedia/debug/harry/Harry.Potter.and.the.Deathly.Hallows.Part.1.2010.BluRay.1080p.AAC.4Audio.x264-CHD.mkv\" ! matroskademux name=dmx dmx. ! queue ! identity sync=false ! h264parse ! omxh264dec ! txo.video_sink txo.src ! omxh264enc force-keyframe-period=40 scaling-width=1920 scaling-height=800 ! h264parse ! mq.sink_0 mq.src_0 ! mpegtsmux name=mux ! filesink location=\"/share/Public/aaa.ts\" filesrc location=\"/share/Multimedia/debug/harry/Harry.Potter.and.the.Deathly.Hallows.Part.1.2010.BluRay.1080p.AAC.4Audio.x264-CHD.zh-TW.srt\" ! subparse subtitle-encoding=UTF-8 ! txo.text_sink dmx. ! aacparse ! queue ! identity sync=false ! faad name=adec ! audioconvert ! audioresample ! audio/x-raw,channels=2,rate=44100 ! queue ! voaacenc ! audio/mpeg,mpegversion=4,stream-format=raw ! aacparse ! mq.sink_1 mq.src_1 ! audio/mpeg,mpegversion=4,stream-format=raw ! mux.", NULL);
#else // constantine without subtitle
pipeline = gst_parse_launch("multiqueue max-size-buffers=10000 max-size-bytes=0 max-size-time=0 name=mq splitfilesrc location=\"/share/Multimedia/debug/harry/Harry.Potter.and.the.Deathly.Hallows.Part.1.2010.BluRay.1080p.AAC.4Audio.x264-CHD.mkv\" ! matroskademux name=dmx dmx. ! queue ! identity sync=false ! h264parse ! omxh264dec ! omxh264enc force-keyframe-period=40 scaling-width=1920 scaling-height=800 ! h264parse ! mq.sink_0 mq.src_0 ! mpegtsmux name=mux ! filesink location=\"/share/Public/aaa.ts\" dmx. ! aacparse ! queue ! identity sync=false ! faad name=adec ! audioconvert ! audioresample ! audio/x-raw,channels=2,rate=44100 ! queue ! voaacenc ! audio/mpeg,mpegversion=4,stream-format=raw ! aacparse ! mq.sink_1 mq.src_1 ! audio/mpeg,mpegversion=4,stream-format=raw ! mux.", NULL);
#endif
/* Start playing */
//gst_element_set_state (pipeline, GST_STATE_PLAYING);
gst_element_set_state (pipeline, GST_STATE_PAUSED);
bus = gst_element_get_bus (pipeline);
do{
msg = gst_bus_timed_pop_filtered (bus, 1 * GST_SECOND,
GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_DURATION);
if(msg != NULL){
GError *err;
gchar *debug_info;
switch(GST_MESSAGE_TYPE(msg)){
case GST_MESSAGE_ERROR:
gst_message_parse_error (msg, &err, &debug_info);
g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
g_clear_error (&err);
g_free (debug_info);
break;
case GST_MESSAGE_EOS:
g_print ("End-Of-Stream reached.\n");
goto _exit;
break;
case GST_MESSAGE_DURATION:
g_print ("The duration has changed.\n");
break;
case GST_MESSAGE_STATE_CHANGED:{
GstState old_state, new_state, pending_state;
gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);
if (GST_MESSAGE_SRC (msg) == GST_OBJECT (pipeline)) {
g_print ("Pipeline state changed from %s to %s:\n",
gst_element_state_get_name (old_state), gst_element_state_get_name (new_state));
if (new_state == GST_STATE_PLAYING) {
g_printerr("[%s:%d]: do nothing now.\n", __FILE__, __LINE__);
}else if (new_state == GST_STATE_PAUSED){
// do seek
if(isSeek == 0){
// show seek info
GstQuery *query;
gint64 start, end;
gboolean seek_enabled;
query = gst_query_new_seeking (GST_FORMAT_TIME);
if (gst_element_query (pipeline, query)) {
gst_query_parse_seeking (query, NULL, &seek_enabled, &start, &end);
if (seek_enabled) {
g_print ("Seeking is ENABLED from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT "\n",
GST_TIME_ARGS (start), GST_TIME_ARGS (end));
} else {
g_print ("Seeking is DISABLED for this stream.\n");
}
}else {
g_printerr ("Seeking query failed.");
}
gst_query_unref (query);
// do seek
isSeek = 1;
g_printerr("[%s:%d]start to seek \n", __FILE__, __LINE__);
ret = gst_element_seek_simple (pipeline, GST_FORMAT_TIME,
//GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT,
GST_SEEK_FLAG_KEY_UNIT,
//GST_SEEK_FLAG_ACCURATE,
//GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
//GST_SEEK_FLAG_FLUSH,
//GST_SEEK_FLAG_NONE,
7280 * GST_SECOND);
g_printerr("[%s:%d]end to seek \n", __FILE__, __LINE__);
if(ret == TRUE){
g_printerr("[%s:%d]ret=true\n", __FILE__, __LINE__);
}else{
g_printerr("[%s:%d]ret=false\n", __FILE__, __LINE__);
}
gst_element_set_state (pipeline, GST_STATE_PLAYING);
}
}
}
}
default:
//g_printerr ("Unexpected message received.\n");
break;
}
gst_message_unref (msg);
}else{
GstFormat fmt = GST_FORMAT_TIME;
gint64 current = -1;
gint64 duration;
if (!gst_element_query_position (pipeline, fmt, ¤t)) {
g_printerr ("Could not query current position.\n");
}
if (!GST_CLOCK_TIME_IS_VALID (duration)) {
if (!gst_element_query_duration (pipeline, fmt, &duration)) {
g_printerr ("Could not query current duration.\n");
}
}
g_print ("Position %" GST_TIME_FORMAT " / %" GST_TIME_FORMAT "\n",
GST_TIME_ARGS (current), GST_TIME_ARGS (duration));
}
}while(1);
_exit:
/* Free resources */
if (msg != NULL)
gst_message_unref (msg);
gst_object_unref (bus);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
return 0;
}