5

フォノンを使用してビデオを再生しようとしましたが、成功しませんでした。Off-late は Qt フォーラムを通じて、Qt の最新バージョンでさえ phonon をサポートしていないことを知りました。それが私がGstreamerを使い始めたときです。Gstreamer ウィンドウを Qt ウィジェットに接続する方法について何か提案はありますか? 私の目的は、Qt ウィジェットで Gstreamer を使用してビデオを再生することです。では、Gstreamer ウィンドウと Qt ウィジェットをリンクするにはどうすればよいでしょうか?

Idを介してウィジェットの取得に成功しましたwinid()。さらに、Gregory Pakosz の助けを借りて、アプリケーションに以下の 2 行のコードを追加しました -

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の例があります。

コードでは、状態をreadyに変更する前にウィンドウ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);

..パイプライン/プレイビンバス上のエラー/状態変更/タグ/eosなどのメッセージを確認します

于 2010-03-26T19:26:44.593 に答える
1

私はpythonを使ってこれと同じことをしました。私がしなければならなかったことは、バス上の 'sync-message::element' に接続し、'prepare-xwindow-id' (X11 だけでなくすべてのプラットフォームで機能するため、名前は無視してください) というメッセージをリッスンすることでした。ビデオシンクがセットアップされます。そのメッセージ内のシンクを送信し、そこにウィンドウ 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 に答える