Alexander Sackett
Alexander Sackett

Reputation: 1

Gtk/Gstreamer application freezes on first frame

I'm trying to make an application that streams video through a gtk draw area. The pipeline I'm currently trying to run is videotestsrc ! ximagesink. My problem is, when I try to run my program, it displays videotestsrc, but only as a still image. This is different from running "gst-launch-1.0 videotestsrc ! ximagesink" through a terminal, where the static in the bottom right moves.

Any ideas on what I'm doing wrong?

int main(int argc, char* argv[])
{
        Gst::init(argc, argv);
        auto app = Gtk::Application::create(argc, argv, "gtkmm.video.sunshine.test");
        Program_Window window;
        return app->run(window);
}

    
class Program_Window : public Gtk::Window
{
    
public:
        Program_Window();
        virtual ~Program_Window();

protected:
        Gtk::DrawingArea* display;
        Glib::RefPtr<Gst::Pipeline> playbin;
        gulong window_handler;
        GstVideoOverlay* overlay;
        void on_display_realize();
};


Program_Window::Program_Window()
{

        //initialize variables
        display = new Gtk::DrawingArea();
        window_handler = 0;

        //connect realize callback
        display->signal_realize().connect( sigc::mem_fun( *this, &Program_Window::on_display_realize ));

        //create playbin
        playbin = Gst::PlayBin::create("playbin");

        //prepare elements for the pipeline
        Glib::RefPtr<Gst::Element> source = Gst::ElementFactory::create_element("videotestsrc", "src");
        Glib::RefPtr<Gst::Element> sink = Gst::ElementFactory::create_element("ximagesink", "sink");

        //add elements to the pipeline
        playbin->add(source)->add(sink);

        //link elements
        source->link(sink);

        //prep video overlay interface
        overlay = (GstVideoOverlay*) sink->gobj();

        //add drawing area to main window
        add(*display);
        show_all_children();
}


void Program_Window::on_display_realize()
{
    
            //acquire an xwindow pointer to our draw area   
            window_handler = GDK_WINDOW_XID( display->get_window()->gobj() );
    
            //give xwindow pointer to our pipeline via video overlay interface
            gst_video_overlay_set_window_handle(overlay, window_handler);
    
            //start video
            playbin->set_state(Gst::STATE_PLAYING);
}

Upvotes: 0

Views: 637

Answers (2)

Alexander Sackett
Alexander Sackett

Reputation: 1

Fixed it. For whatever reason, the program didn't like the way I used playbin. Changing it to a normal Gst::pipeline worked.

    //create playbin                             //in the above code
    //playbin = Gst::PlayBin::create("playbin"); //change this
    playbin = Gst::Pipeline::create("pipeline"); //to this

Upvotes: 0

Florian Zwoch
Florian Zwoch

Reputation: 7373

Could be that in the app it is a tad slower causing following frames to miss their clock times and get discarded. Try setting the sync=false option for the video sink and check if it changes anything. Else use GST_DEBUG to get some logs from the pipeline about what is happening.

P.S. When using Gtk consider using gtksink and gtkglsink to make you life easier.

Upvotes: 0

Related Questions