我在GStreamer库上有一个C ++包装程序,它为我的应用程序显示各种文件类型。我目前正在实现对图像的支持,尽管我使jpgs / pngs正常工作没有任何问题,但我在使用GIF时遇到了麻烦。该文件显示正确,正在制作动画,尽管我似乎找不到任何无缝循环GIF的方法,因此它显示的方式与浏览器相同。我正在使用Waylandsink开发Linux。 GStreamer版本1.14.4。
我尝试了许多不同的方法:
gst_element_seek
下以gst_element_seek_simple
或GST_MESSAGE_EOS
进行搜索。这样会将显示屏挂在最后,并产生无限的状态变化循环(从PAUSED-> PLAYING后跟GST_MESSAGE_EOS
)NULL
,然后在PLAYING
下设置为GST_MESSAGE_EOS
。这项工作有效,但是在重新加载之间产生了一个黑缝,这让我不满意,因为我希望gif无缝循环。PLAYING
状态时寻求第一段,然后在GST_MESSAGE_SEGMENT_DONE
下寻找。在第一帧时直接跳到EOS。这是我建立管道的方式:
m_pipeline = gst_parse_launch("playbin uri=file:///home/user/test.gif video-sink=waylandsink");
这是我的循环:
m_ret = gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
if (m_ret == GST_STATE_CHANGE_FAILURE) {
g_printerr("Unable to set the pipeline to the playing state.\n");
gst_object_unref(m_pipeline);
exit(0);
}
m_bus = gst_element_get_bus(m_pipeline);
m_terminate = FALSE;
GError *err;
gchar *debug_info;
bool seekOnce = false;
do {
m_msg =
gst_bus_timed_pop_filtered(m_bus, GST_CLOCK_TIME_NONE, (GstMessageType)(GST_MESSAGE_EOS | GST_MESSAGE_ERROR | GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_SEGMENT_DONE));
/* Parse message */
if (m_msg != NULL) {
switch (GST_MESSAGE_TYPE(m_msg)) {
case GST_MESSAGE_ERROR:
gst_message_parse_error(m_msg, &err, &debug_info);
g_printerr("Error received from element %s: %s\n",
GST_OBJECT_NAME(m_msg->src), err->message);
g_printerr("Debugging information: %s\n",
debug_info ? debug_info : "none");
g_clear_error(&err);
g_free(debug_info);
m_terminate = TRUE;
break;
case GST_MESSAGE_EOS:
g_print("Received EOS!\n");
// This produces no errors but loops PAUSED->PLAYING->EOS
if(gst_element_seek(m_pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) {
g_print("SEEK FAILED!\n");
}
// this loops, but since it's re-starting the entire pipeline the loop is not seamless
//gst_element_set_state(m_pipeline, GST_STATE_NULL);
//gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
break;
case GST_MESSAGE_STATE_CHANGED:
if (GST_MESSAGE_SRC(m_msg) == GST_OBJECT(m_pipeline)) {
GstState old_state, new_state, pending_state;
gst_message_parse_state_changed(m_msg, &old_state, &new_state,
&pending_state);
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 == GstState::GST_STATE_PLAYING) {
// this jumps straight to EOS on the first frame, GST_MESSAGE_SEGMENT_DONE is not received at all
if(!seekOnce)
// gst_element_seek_simple(m_pipeline, GST_FORMAT_TIME, (GstSeekFlags)(GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_FLUSH), 0);
seekOnce = true;
}
}
}
break;
case GST_MESSAGE_SEGMENT_DONE:
//gst_element_seek_simple(m_pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_SEGMENT, 0);
break;
default:
/* We should not reach here */
g_printerr("Unexpected message received.\n");
break;
}
gst_message_unref(m_msg);
}
} while (!m_terminate);
如何像使用GIF循环一样使循环无缝?