2012-10-15 2 views
1

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(); 
} 

나는 videosink의 싱크 패드 (따라서 건너 뛰는 timeoverlay에 textoverlay의 src 패드를 연결하면), 나는 예상대로 비디오와 부제목을 얻습니다.

코드를 변경하여 mybin의 유령 패드 timeoverlay의 싱크 패드를 만든 다음 timeoverlay의 src 패드를 videosink에 연결합니다 (따라서 textoverlay 건너 뛰기). 예상대로 경과 시간이있는 비디오가 나타납니다.

그러나 텍스트 오버레이와 시간 오버레이를 계단식으로 만들려고하면 비디오가 없습니다. videosink에 의존하지 않습니다 - xvimagesink 및 ximagesink와 동일합니다. 오류는 표시되지 않습니다. gstreamer를 실행하면 제대로 작동하기 때문에 분명히 C에서 뭔가 잘못된 일을하고 있습니다. 무엇이 있는지 파악할 수 없습니다.

도움이 될 것입니다.

답변

0

무엇이 문제는 bin 대신 파이프 라인을 사용하고 있는지를 해결합니다.

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

왜 그런지는 아직 불분명합니다. GStreamer 문서에서는 파이프 라인이 최상위 수준의 저장소라고합니다. 문서에서 bin에서 얼마나 많은 요소가있을 수 있는지 또는 무엇을 할 수 있는지에 대한 제한 사항을 발견하지 못했습니다. 반면에, playbin2는 내부적으로 파이프 라인이므로 mybin은 일반 bin이 될 수 있습니다 (그리고 textoverlay 또는 timeoverlay 만 사용되는 한 일반 bin으로 잘 작동합니다).

0

Textoverlay는 싱크에서 텍스트 스트림을 예상합니다. GST_DEBUG = "* : 2"로 앱을 실행하면 경고가 표시됩니다.

그리고 btw. - char uri [2048]; - sprintf (& uri [0], "file : ///tmp/1.mpg"); + gchar * uri = "file : ///tmp/1.mpg"; :)

+0

더 정확하게, textoverlay 텍스트 싱크를 가지고,하지만 그것은 의무적으로하지 않습니다 sendingtext에. 내 필요 (자막 응용 프로그램) 설정 '텍스트'속성을 잘 작동합니다. 두 번째 제안도 괜찮지 만 문제를 해결하지는 못합니다. –

0

더 단순한 솔루션은 gst_element_link_many 사용하는 것입니다

gst_element_link_many(textoverlay, timeoverlay, videosink); 
관련 문제