Search code examples
wxwidgetsgstreamer-1.0

Have the information that GstPadProbeReturn have been called by my main


When my source is grabbing the stream, the callback function is called and I have the wxMessageBox("Got buffer"); which display the text Got Buffer. But At this point I don't know how to have the information in my main code that my stream is actually grabing something and so I can display it (I want to sure that my pipeline is grabbing something before asking for display). For example, changing my toolbar icon that indicate the user that the pipeline is actually grabbing something and he can display it. you can find my code bellow :

#include "MainWindow.h"


wxBEGIN_EVENT_TABLE(MainWindow, wxFrame)
    EVT_TOOL(10001, LoadVideo)
wxEND_EVENT_TABLE()

MainWindow::MainWindow(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxPoint(30, 30), wxSize(1224, 1024))
{
    wxInitAllImageHandlers();
    wxBitmap load(wxT("bitmap.png"), wxBITMAP_TYPE_PNG);

    wxPanel* bg = new wxPanel(this, wxID_ANY);
    bg->SetBackgroundColour(wxColor(230, 230, 230));

    m_renderWindow = new wxWindow(bg, wxID_ANY);
    m_renderWindow->SetBackgroundColour(*wxBLACK);

    // Layout the UI.
    wxBoxSizer* szr1 = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer* szr2 = new wxBoxSizer(wxHORIZONTAL);

    szr1->Add(m_renderWindow, wxSizerFlags(1).Expand().Border(wxBOTTOM));
    szr1->Add(szr2, wxSizerFlags(0));

    bg->SetSizer(szr1);
    toolbar->AddTool(10001, _T("ContinuousShot"), load);
    toolbar->Realize();
    Layout();

    // Set up the event handlers.
#ifdef __WXGTK__
    m_renderWindow->Bind(wxEVT_CREATE, &MainWindow::OnRendererWinCreated, this);
#endif
    // Initialize GStreamer.
    m_xid = 0;
    m_pipeline = NULL;
    gst_init(NULL, NULL);
}

        
GstPadProbeReturn buffer_out_cb(GstPad* pad, GstPadProbeInfo* info, gpointer user_data)
    {
    
        GstElement* pipe = (GstElement*)user_data;
    
        //toolbar->SetToolNormalBitmap(10001, wxBitmap(wxT(icon-open-device.png), wxBITMAP_TYPE_PNG));

        wxMessageBox("Got buffer");
        gst_element_set_state(pipe, GST_STATE_PAUSED);
    
        
        //remove the probe if you don't need it anymore, otherwise return GST_PAD_PROBE_OK
        return GST_PAD_PROBE_REMOVE;
    }

void MainWindow::LoadVideo(wxWindowCreateEvent&)
    {
        GstPad* pad;
        GError* error = NULL;
        //GstElement* pipeline;
        GstElement* source;
    
        GstCaps* caps = gst_caps_new_simple("application/x-rtp",
            "media", G_TYPE_STRING, "video",
            "payload", G_TYPE_INT, 96,
            "encoding-name", G_TYPE_STRING, "H264",
            NULL);
    
        m_pipeline = gst_parse_launch("udpsrc name=source !rtpjitterbuffer !rtph264depay !h264parse !avdec_h264 !autovideoconvert !d3dvideosink name=mysink sync=false ", &error);
        if (!m_pipeline) {
            g_print("Parse error: %s\n", error->message);
            exit(1);
        }
    
        source = gst_bin_get_by_name(GST_BIN(m_pipeline), "source");
        g_object_set(G_OBJECT(source), "caps", caps, NULL);
        g_object_set(G_OBJECT(source), "port", m_port, NULL);
    
        pad = gst_element_get_static_pad(source, "src");
        gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, (GstPadProbeCallback)buffer_out_cb, m_pipeline, NULL);
        gst_object_unref(pad);
    
    #ifdef __WXGTK__
        GstElement* sink = gst_bin_get_by_name((GstBin*)m_pipeline, "mysink");
        gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(sink), m_xid);
    #elif defined __WXMSW__
        GstElement* sink = gst_bin_get_by_name((GstBin*)m_pipeline, "mysink");
        WXWidget hwnd = m_renderWindow->GetHandle();
        gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(sink),
            reinterpret_cast<guintptr>(hwnd));
    #endif
    
        gst_element_set_state(m_pipeline, GST_STATE_PLAYING);
    
    }

Solution

  • The solution :

    pass a pointer in the callback function (gpointer user_data), for example a int that is at 0 if the callback is not called and at 1 if it is called