2011-11-04 26 views
6

Estoy tratando de usar GStreamer para reproducir video MP4 desde un archivo. He conseguido reproducir el archivo usando playbin2 y desde la línea de comandos usando:GStreamer: cómo conectar pads dinámicos

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

Estoy esperando en el futuro que tendrá que crear tuberías más complicados y por lo tanto por qué estoy tratando de 'programa' del tubería. En mi programa, estoy intentando replicar la canalización anterior, sin embargo, tengo un problema que sospecho que está relacionado con la conexión de la fuente dinámica o "a veces" de Decodebin2 al receptor automático de video. Estoy usando estos elementos solo para mantener las cosas lo más simples posible.

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

Lo que espero que suceda cuando corro este programa, es para el on_new_decoded_pad a ser llamado a través de una llamada de función, que se encuentra en la línea:

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

y que me permitirá conecta las almohadillas apropiadamente. Pero nunca se llama. De hecho, el programa parece pasar por completo y luego simplemente salir (el ciclo principal no hace nada).

Realmente agradecería que alguien pudiera señalar lo que he hecho mal con respecto a la devolución de llamada o explicar qué más hay que hacer para que este ejemplo reproduzca mp4 utilizando los elementos proporcionados.

Atentamente.

Respuesta

3

Ver mi ejemplo RTP teléfono [here]. Rtpbin se usa allí. Espero que esto ayude.

+0

obalex, gracias por su respuesta incluso si es un poco tarde (realmente podría haberlo hecho hace 6 meses: P) Sin embargo, eché un vistazo rápido a su código y se ve bastante bien escrito. Creo que será útil para otros, así que +1. – user975326