2

GStreamerを使用する小さなCプロジェクトがあります。ビデオをロードして、字幕(textoverlay)と経過時間(timeoverlay)と一緒に表示したい。

私のアイデアは次のようになります。

- create a textoverlay and set a sample subtitle
- create a timeoverlay
- create a videosink
- put the three elements in a new bin and link them: 
  textoverlay -> timeoverlay -> videosink
- use playbin2 for playback and send the video from playbin2 to the new bin 

これが私のテスト用スタンドアロンアプリケーションです。

// Save as "test.c". Compile with: 
// gcc -o test `pkg-config --cflags --libs gtk+-2.0 gstreamer-0.10 gstreamer-interfaces-0.10` test.c
#include <gst/gst.h>
#include <gtk/gtk.h>

int main(int argc, char **argv) {
    // Init - GTK is only used here as a GUI hook
    gtk_init (&argc, &argv);
    gst_init(0, NULL);

    // Path to file - juts a simple demo file
    char uri[2048];
    sprintf(&uri[0], "file:///tmp/1.mpg");

    // Playbin and URI
    GstElement *playbin2 = gst_element_factory_make ("playbin2", "playbin2");
    g_object_set (G_OBJECT (playbin2), "uri", &uri[0], NULL);

    // Elements - videosink, textoverlay, timeoverlay
    GstElement *videosink = gst_element_factory_make ("sdlvideosink", "videosink");
    GstElement *textoverlay = gst_element_factory_make("textoverlay", "textoverlay");
    GstElement *timeoverlay = gst_element_factory_make("timeoverlay", "timeoverlay");

    // Set sample text in textoverlay
    g_object_set(G_OBJECT(textoverlay), "text", "Test Subtitle", NULL);

    // Create bin, add elements
    GstElement *mybin = gst_bin_new("mybin");
    gst_bin_add (GST_BIN (mybin), videosink);
    gst_bin_add (GST_BIN (mybin), textoverlay);
    gst_bin_add (GST_BIN (mybin), timeoverlay);

    // Get sink pad for textoverlay and make it a ghostpad for bin
    GstPad *pad_textoverlay_sink = gst_element_get_pad(textoverlay, "video_sink");
    gst_element_add_pad(mybin, gst_ghost_pad_new("sink", pad_textoverlay_sink));

    // Link elements: textoverlay -> timeoverlay -> videosink
    gst_element_link_pads(textoverlay, "src", timeoverlay, "sink");
    gst_element_link_pads(timeoverlay, "src", videosink, "sink");

    // Conect the bin to the playbin
    g_object_set (G_OBJECT (playbin2), "video-sink", mybin, NULL);

    // Play video
    gst_element_set_state (playbin2, GST_STATE_PLAYING);

    // GTK Main loop
    gtk_main ();
}

textoverlayのsrcパッドをvideosinkのシンクパッドにリンクすると(したがって、timeoverlayをスキップして)、期待どおりにビデオと字幕が表示されます。

コードを変更して、timeoverlayのシンクパッドをmybinのゴーストパッドにした後、timeoverlayのsrcパッドをvideosinkにリンクします(したがって、textoverlayをスキップします)-期待どおり、経過時間のあるビデオを取得します。

ただし、textoverlayとtimeoverlayをカスケードしようとすると、ビデオがありません。それはvideosinkに依存しません-xvimagesinkとximagesinkと同じです。エラーは表示されません。gstreamer-launchを使用すると正常に動作するので、明らかにCで何か間違ったことをしています-何がわからないのです。

どんな助けでもありがたいです。

4

3 に答える 3

1

より簡単な解決策は、gst_element_link_manyを使用することです。

gst_element_link_many(textoverlay, timeoverlay, videosink);
于 2013-08-11T11:30:26.833 に答える
0

Textoverlayは、シンク上のテキストのストリームも想定しています。GST_DEBUG = "*:2"を使用してアプリを実行すると、警告が表示されます。

そしてところで。--char uri [2048]; --sprintf(&uri [0]、 "file:///tmp/1.mpg"); + gchar * uri = "file:///tmp/1.mpg"; :)

于 2012-10-16T10:00:07.123 に答える
0

問題を解決するのは、binの代わりにパイプラインを使用することです。

GstElement *mybin = gst_pipeline_new ("my-pipeline");

しかし、なぜそうなるのかはまだ私にはわかりません。GStreamerのドキュメントによると、パイプラインは単なるトップレベルのビンです。ビンに含めることができる要素の数や、それらが実行できることについてのドキュメントに制限はありませんでした。一方、playbin2は内部的にパイプラインであるため、mybinは通常のbinにすることができます(textoverlayまたはtimeoverlayのみが使用されている限り、通常のbinとして正常に機能します)。

于 2012-10-16T13:53:55.117 に答える