5

我尝试使用 phonon 播放视频,但未能成功。Off-late 通过 Qt 论坛得知,即使是最新版本的 Qt 也不支持 phonon。那是我开始使用 Gstreamer 的时候。关于如何将 Gstreamer 窗口与 Qt 小部件连接的任何建议?我的目标是在 Qt 小部件上使用 Gstreamer 播放视频。那么如何链接 Gstreamer 窗口和 Qt 小部件呢?

我成功Id通过winid(). 在 Gregory Pakosz 的帮助下,我在我的应用程序中添加了以下两行代码 -

QApplication::syncX();
gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(sink), widget->winId());

但是无法将 Qt 小部件与 gstreamer 视频窗口链接。

这就是我的示例代码的样子:-

int main(int argc, char *argv[])
{
printf("winid=%d\n", w.winId());
    gst_init (NULL,NULL);
    /* create a new bin to hold the elements */
    bin = gst_pipeline_new ("pipeline");

      /* create a disk reader */
  filesrc = gst_element_factory_make ("filesrc", "disk_source");
  g_assert (filesrc);



  g_object_set (G_OBJECT (filesrc), "location", "PATH_TO_THE_EXECUTABLE", NULL);

  demux = gst_element_factory_make ("mpegtsdemux", "demuxer");
  if (!demux) {
    g_print ("could not find plugin \"mpegtsmux\"");
    return -1;
  }

  vdecoder = gst_element_factory_make ("mpeg2dec", "decode");
  if (!vdecoder) {
    g_print ("could not find plugin \"mpeg2dec\"");
    return -1;
  }

  videosink = gst_element_factory_make ("xvimagesink", "play_video");
  g_assert (videosink);


  /* add objects to the main pipeline */

  gst_bin_add_many (GST_BIN (bin), filesrc, demux, vdecoder, videosink, NULL);


  /* link the elements */
  gst_element_link_many (filesrc, demux, vdecoder, videosink, NULL);

    gst_element_set_state(videosink, GST_STATE_READY);

    QApplication::syncX();
    gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(videosink), w.winId());



  /* start playing */
  gst_element_set_state (bin, GST_STATE_PLAYING);

}

您能否在我的上下文中更详细地解释 gst_x_overlay_set_xwindow_id() 的用法?

我能得到任何关于如何在 Qt 下集成 gstreamer 的提示吗?请帮我解决这个问题。

4

4 回答 4

1

http://cgit.freedesktop.org/gstreamer/gst-plugins-base/tree/tests/examples/overlay

有一个最小的 Qt 示例。

在您的代码中,您可能应该在将状态更改为就绪之前设置窗口 ID(尽管我不是 100% 确定这是问题所在)。

对于播放,您最好使用 playbin2 元素,如下所示(完全未经测试):

GstElement *playbin, *videosink;
gchar *uri;

 playbin = gst_element_factory_make ("playbin2", "myplaybin");
 videosink = gst_element_factory_make ("xvimagesink", NULL);

 g_object_set (playbin, "video-sink", videosink, NULL);

 uri = g_filename_to_uri ("/path/to/file", NULL, NULL);
 g_object_set (playbin, "uri", uri, NULL);
 g_free (uri);

 /* NOTE: at this point your main window needs to be realized,
  * ie visible on the screen, and you might need to make sure
  * that your widget w indeed has a 'native window' (just some
  * things to check for if it doesn't work; there should be Qt
  * API for this kind of thing if needed) */
 QApplication::syncX();
 gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(videosink), w.winId());

 gst_element_set_state (playbin, GST_STATE_PLAYING);

.. 检查管道/playbin 总线上的错误/状态更改/标签/eos 等消息

于 2010-03-26T19:26:44.593 回答
1

我只是用python做了同样的事情。我必须做的是连接到总线上的“sync-message::element”并监听在视频接收器已设置。它会在该消息中向您发送接收器,这就是您将窗口 ID 传递给它的地方。

于 2010-03-30T04:12:23.620 回答
1

如果元素正确链接,上面给出的示例代码会将 GStreamer 视频窗口链接到 QtWidget。

  • filesrc应该链接到解复用器
  • 解码器应该链接到文件接收器
  • 最后,解复用器应该在运行时链接到解码器
// link filesrc to demuxer
gst_element_link(filesrc,demux)

// link vdecoder to filesink
gst_element_link_many(vdecoder,filesink,NULL)

/*
  The demuxer will be linked to the decoder dynamically.
  The source pad(s) will be created at run time,
  by the demuxer when it detects the amount and nature of streams.
  Connect a callback function which will be executed
  when the "pad-added" is emitted.
*/

g_signal_connect(demux,"pad-added",G_CALLBACK(on_pad_added),vdecoder);

// callback definition
static void on_pad_added(GstElement* element,GstPad* pad,gpointer* data)
{
  GstPad* sinkpad;
  GstElement * decoder = (GstElement*)data;
  GstCaps* caps;
  GstStructure* str;
  gchar* tex;

  caps = gst_pad_get_caps(pad);
  str = gst_caps_get_structure(caps,0);
  tex = (gchar*)gst_structure_get_name(str);

  if(g_strrstr(tex,"video"))
  {
    sinkpad = gst_element_get_static_pad(decoder,"sink");
    gst_pad_link(pad,sinkpad);
    gst_object_unref(sinkpad);
  }
}
于 2010-11-03T13:00:51.297 回答
0

将 gstreamer 包装成可用的 C++/Qt 类的项目,包括示例代码: http ://code.google.com/p/qbtgstreamer/

我不知道直接方法,因为我不熟悉 gstreamer 本身。

于 2010-02-14T16:08:17.437 回答