2011-11-04 13 views
6

Sto tentando di utilizzare GStreamer per riprodurre video MP4 da un file. Sono riuscito a riprodurre il file utilizzando playbin2 e dal prompt dei comandi utilizzando:GStreamer: come collegare i pad dinamici

gst-launch filesrc location=bbb.mp4 ! decodebin2 ! autovideosink 

mi aspetto che in futuro avrò bisogno per creare pipeline più complessi e quindi il motivo per cui sto cercando di 'programma' il pipeline. Nel mio programma sto tentando di replicare la pipeline sopra, tuttavia ho un problema che sospetto sia legato al collegamento del pad sorgente dinamico o "a volte" di decodebin2 al sink autovideo. Sto usando questi elementi solo per mantenere le cose il più semplice possibile.

static void on_new_decoded_pad(GstElement* object, 
          GstPad* arg0, 
          gboolean arg1, 
          gpointer user_data) 
{ 
    // dynamically connect decoderbin2 src pad to autovideosink sink pad 
} 

static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data) 
{ 
    // handle bus messages 
} 

int main(int argc, char *argv[]) 
{ 
    GMainLoop *loop; 
    GstElement *pipeline, *source, *decodebin, *videosink; 
    GstBus *bus; 

    gst_init (&argc, &argv); 
    loop = g_main_loop_new (NULL, FALSE); 

    pipeline = gst_pipeline_new ("pipeline"); 
    source = gst_element_factory_make("filesrc",  "source"); 
    decodebin = gst_element_factory_make("decodebin2", "decodebin"); 
    videosink = gst_element_factory_make("autovideosink", "videosink"); 

    /* check elements were created successfully */ 
    if (!pipeline || !source || !decodebin || !videosink) { 
     // Failed to create element. Exit Program 
     return -1; 
    } 

    /* apply properties to elements before adding to pipeline */ 
    gchar * filename = "bbb.mp4"; 
    g_object_set(G_OBJECT(source), "location", filename, NULL); 

    /* add a message handler */ 
    bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); 
    gst_bus_add_watch (bus, bus_call, loop); 
    gst_object_unref (bus); 

    /* add elements to pipeline (and bin if necessary) before linking them */ 
    gst_bin_add_many(GST_BIN (pipeline), 
        source, 
        decodebin, 
        videosink, 
        NULL); 

    gst_element_link_pads(source, "src", decodebin, "sink"); 

    /* decodebins src pad is a sometimes pad - it gets created dynamically */ 
    g_signal_connect(decodebin, "new-decoded-pad", G_CALLBACK(on_new_decoded_pad), videosink); 

    /* run pipeline */ 
    gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING); 

    g_main_loop_run(loop); 

    gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL); 
    gst_object_unref (pipeline); 

    return 0; 
} 

Quello che mi aspetto che accada quando si esegue questo programma, è per l'on_new_decoded_pad per ottenere chiamato tramite una funzione chiamata indietro, che si trova in prima linea:

g_signal_connect(decodebin, "new-decoded-pad", G_CALLBACK(on_new_decoded_pad), videosink); 

e mi permettesse di collegare i pad in modo appropriato. Ma non viene mai chiamato. In effetti il ​​programma sembra passare interamente e quindi solo uscire (il ciclo principale non fa nulla).

Apprezzerei molto se qualcuno potesse indicare cosa ho sbagliato riguardo alla richiamata o spiegare cos'altro deve essere fatto affinché questo esempio riproduca mp4 usando gli elementi forniti.

Saluti.

risposta

3

Vedi il mio esempio RTP telefono [here]. Rtpbin è usato lì. Spero che questo ti aiuti.

+0

obalex, grazie per la tua risposta anche se è un po 'tardi (avrei potuto farlo con 6 mesi fa: P) Tuttavia, ho dato un'occhiata veloce al tuo codice e sembra scritto abbastanza bene. Penso che sarà utile per gli altri, quindi +1. – user975326