我正在使用gstreamer-1.0在Qt中构建一个简单的视频播放器。当我从我的电脑中的Qt或.exe运行它时,一切运行正常。但是当我从另一台电脑上试用它时,它会播放几秒钟,它会跳过几秒钟/分钟,依此类推。我想问题是同步,我试过设置d3dvidesink属性:sync = false,但是是一样的。我读过许多类似的线程,但似乎都没有帮助。
正在删除大量缓冲区。 其他调试信息: gstbasesink.c(2846):gst_base_sink_is_too_late(): 可能存在时间戳问题,或者此计算机速度太慢。
我尝试过设置不同的属性,但都没有帮助。我见过以下线程,但仍然存在同样的问题:
在线程3上有一个建议设置" do-timestamp" appsrc上的属性为TRUE,但我使用uridecodebin作为没有" do-timestamp"属性。
我的管道如下:
uridecodebin! audioconvert!量! autoaudiosink!视频转换!伽玛! d3dvideosink
提前致谢!
以下是元素创建/链接的一些代码。如果您需要任何其他代码,请发表评论。
// Create the elements
data.source = gst_element_factory_make ( "uridecodebin", "source" );
data.audio_convert = gst_element_factory_make ( "audioconvert", "audio_convert" );
data.volume = gst_element_factory_make ( "volume", "volume");
data.audio_sink = gst_element_factory_make ( "autoaudiosink", "audio_sink" );
data.video_convert = gst_element_factory_make ( "videoconvert", "video_convert" );
data.filter = gst_element_factory_make ( "gamma", "filter");
data.video_sink = gst_element_factory_make ( "d3dvideosink", "video_sink" );
// Create the empty pipeline
data.pipeline = gst_pipeline_new ("test-pipeline");
if (!data.pipeline || !data.source || !data.audio_convert || !data.volume || !data.audio_sink
|| !data.video_convert || !data.filter || !data.video_sink ) {
g_printerr ("Not all elements could be created.\n");}
return ;
}
// Build the pipeline. Note that we are NOT linking the source at this point. We will do it later.
gst_bin_add_many (GST_BIN (data.pipeline), data.source, data.audio_convert , data.volume, data.audio_sink,
data.video_convert, data.filter, data.video_sink, NULL);
if (!gst_element_link (data.audio_convert, data.volume)) {
g_printerr ("Elements AUDIO_CONVERT - VOLUME could not be linked.\n");
gst_object_unref (data.pipeline);
return ;
}
if (!gst_element_link (data.volume, data.audio_sink)) {
g_printerr ("Elements VOLUME - AUDIO_SINK could not be linked.\n");
gst_object_unref (data.pipeline);
return ;
}
if (!gst_element_link(data.video_convert, data.filter)) {
g_printerr("Elements VIDEO_CONVERT - FILTER could not be linked.\n");
gst_object_unref(data.pipeline);
return ;
}
if (!gst_element_link(data.filter, data.video_sink)) {
g_printerr("Elements FILTER - VIDEO_SINK could not be linked.\n");
gst_object_unref(data.pipeline);
return ;
}
当我打开视频时:
// Set the URI to play
QString filePath = "file:///"+filename;
QByteArray ba = filePath.toLatin1();
const char *c_filePath = ba.data();
ret = gst_element_set_state (data.pipeline, GST_STATE_NULL);
gint64 max_lateness = 2000000; //2 milli sec
g_object_set (data.source, "uri", c_filePath, NULL);
// I have tried setting the following properties, but none helped
// g_object_set (data.source, "do-timestamp", true, NULL);
// g_object_set( data.video_sink, "sync", false, NULL);
// g_object_set( data.video_sink, "max-lateness", max_lateness, NULL);
qDebug() << &c_filePath;
// Link video_sink with playingWidget->winId()
gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (data.video_sink), xwinid);
// Connect to the pad-added signal
g_signal_connect (data.source, "pad-added", G_CALLBACK (pad_added_handler), &data) ;
// Start playing
ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE) {
gst_element_set_state (data.pipeline, GST_STATE_NULL);
gst_object_unref (data.pipeline);
// Exit application
QTimer::singleShot(0, QApplication::activeWindow(), SLOT(quit()));}
data.playing = TRUE;
data.rate = 1.0;
// Iterate - gets the position and length every 200 msec
g_print ("Running...\n");
emit setMsg( "Running...\n" );
currFileName = filename;
timer->start(500);
Pad_added_handler:
void gst_pipeline::pad_added_handler(GstElement *src, GstPad *new_pad, CustomData *data)
{
GstPadLinkReturn ret;
GstCaps *new_pad_caps = NULL;
GstStructure *new_pad_struct = NULL;
const gchar *new_pad_type = NULL;
GstPad *sink_pad_audio = gst_element_get_static_pad (data->audio_queue, "sink");
GstPad *sink_pad_video = gst_element_get_static_pad (data->video_queue, "sink");
g_print ("Received new pad '%s' from '%s':\n", GST_PAD_NAME (new_pad), GST_ELEMENT_NAME (src));
// If our audio converter is already linked, we have nothing to do here
if (gst_pad_is_linked (sink_pad_audio))
{
g_print (" We have already linked sink_pad_audio. Ignoring.\n");
// goto exit;
}
// If our video converter is already linked, we have nothing to do here
if (gst_pad_is_linked (sink_pad_video))
{
g_print (" We have already linked sink_pad_video. Ignoring.\n");
// goto exit;
}
// Check the new pad's type
new_pad_caps = gst_pad_get_current_caps (new_pad); //gst_pad_get_caps
new_pad_struct = gst_caps_get_structure (new_pad_caps, 0);
new_pad_type = gst_structure_get_name (new_pad_struct);
if (g_str_has_prefix (new_pad_type, "audio/x-raw"))
{
// Attempt the link
ret = gst_pad_link (new_pad, sink_pad_audio);
if (GST_PAD_LINK_FAILED (ret))
{ g_print (" Type is '%s' but link failed.\n", new_pad_type); }
else
{ g_print (" Link succeeded (type '%s').\n", new_pad_type); }
}
else if (g_str_has_prefix (new_pad_type, "video/x-raw"))
{
// Attempt the link
ret = gst_pad_link (new_pad, sink_pad_video);
if (GST_PAD_LINK_FAILED (ret))
{ g_print (" Type is '%s' but link failed.\n", new_pad_type); }
else
{ g_print (" Link succeeded (type '%s').\n", new_pad_type); }
}
else
{
g_print (" It has type '%s' which is not audio/x-raw OR video/x-raw. Ignoring.\n", new_pad_type);
goto exit;
}
exit:
// Unreference the new pad's caps, if we got them
if (new_pad_caps != NULL)
{ gst_caps_unref (new_pad_caps); g_print("EXIT"); msg_STRING2 += "EXIT\n" ; }
// Unreference the sink pad
gst_object_unref (sink_pad_audio);
gst_object_unref (sink_pad_video);
}