Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 23/09/2008, à 14:07

sebv78

gstreamer pipeline audio video, pas d'audio

Bonjour,

j'essaie de coder une application permettant de lire un fichier A/V avec gstreamer, et je rencontre des problèmes d'absence d'audio.
J'ai créé un pipeline qui avec des queue sépare l'audio et la vidéo.
J'ai :
                              | -> queue -> dec -> audioconvert -> autoaudiosink
filesrc -> mpegdemux
                              | -> queue -> dec -> ffmpegcolorspace -> autovideosink

J'ai l'impression de ne pas pouvoir avoir l'A/V en simultanée avec ce pipeline. Au moment où je l'active, j'ai quelques secondes d'audio, et dès que la vidéo est correcte, je n'ai plus l'audio. J'entends quelques glichs dès que la vidéo devient macroblockée.

J'utilise un seul pipeline pour l'audio et la vidéo afin d'avoir une synchronisation des 2. J'avais commencé an faisant 2 pipelines différents, mais l'audio et la vidéo étaient alors désynchronisées.

J'ai fait des g_signal_connect sur les underrun et overrun des queues audio et video, et je vois que l'audio est en underrun permanent alors que la vidéo est en overrun permanent, bien qu'elle soit fluide.

Si quelqu'un a une idée du problème, merci.
Voici le code utilisé :

/**********************************************************/
        gst_init(NULL, NULL);   // gstreamer init
        // we have to create the gstreamer pipeline
        gst_loop    =   g_main_loop_new(NULL, FALSE);

        /* create gstreamer elements    */
        pipeline    =   gst_pipeline_new("pipeline");

        source      =   gst_element_factory_make("fakesrc", "file-source");
        demuxer     =   gst_element_factory_make("flutsdemux", "stream-demuxer" );

        if(!pipeline || !source || !demuxer )
        {
            g_printerr("DMX gstreamer init : One element could not be created. Exiting. \n");
            return;
        }

/* audio queue elements */
        audio_queue     =   gst_element_factory_make("queue", "queue-audio");
        audiodecoder    =   gst_element_factory_make("flump3dec",  "audio-mpeg-decoder");    //SV
        audioconv       =   gst_element_factory_make("audioconvert", "audioconverter");
        audioresample   =   gst_element_factory_make("audioresample", "audioresampler");
        audiosink       =   gst_element_factory_make("autoaudiosink", "audio-output");                       

        if(!audio_queue || !audiodecoder || !audioresample || !audioconv || !audiosink)
        {
            g_printerr("AUDIO gstreamer : One element could not be created. Exiting. \n");
            return;
        }       

/* video queue elements */
        video_queue     =   gst_element_factory_make("queue", "queue-video");
        // Source video   
        videodecoder    = gst_element_factory_make ("mpeg2dec","video-mpeg-decoder");
        videoconv       = gst_element_factory_make ("ffmpegcolorspace", "videoconverter");

        // Video output
        videosink       = gst_element_factory_make ("fbdevsink", "video-output");
     

        // Trace   
        if (  !video_queue || !videodecoder || !videoconv || !videosink  )
        {
            g_print ("VIDEO : One element could not be created\n");
            return;
        }

        gst_bin_add_many (GST_BIN (pipeline), source, demuxer, video_queue, videodecoder, videoconv, videosink,audio_queue, audiodecoder, audioconv,
                audioresample, audiosink, NULL);
       
        if(!gst_element_link(source, demuxer))
            printf("AUDIO1 gst element link error !\n");

        if(!gst_element_link_many (video_queue, videodecoder, videoconv, videosink, NULL))       
            printf("VIDEO1 gst element link error !\n");

        if(!gst_element_link_many (audio_queue, audiodecoder, audioconv, audioresample, audiosink, NULL))
            printf("AUDIO2 gst element link error !\n");
       
        bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
        gst_bus_add_watch(bus, (GstBusFunc)bus_callback, gst_loop);
        gst_object_unref(GST_OBJECT(bus));   

        gst_element_set_state (pipeline, GST_STATE_PAUSED);

        g_object_set(G_OBJECT (source), "signal-handoffs", TRUE, "sizemax", 1600, "sizetype", 2, NULL);
        g_signal_connect(source, "handoff", G_CALLBACK (Source_handoff), NULL);

        g_signal_connect(G_OBJECT(demuxer), "pad-added", G_CALLBACK (add_video_pad), gst_element_get_pad(video_queue, "sink"));
        g_signal_connect(G_OBJECT(demuxer), "pad-added", G_CALLBACK (add_audio_pad), gst_element_get_pad(audio_queue, "sink"));

        g_signal_connect(audio_queue, "underrun", G_CALLBACK(underrun_handler), NULL);
        g_signal_connect(audio_queue, "overrun", G_CALLBACK(underrun_handler), NULL);       
        g_signal_connect(audio_queue, "running", G_CALLBACK(running_handler), NULL);               
        g_signal_connect(video_queue, "overrun", G_CALLBACK(v_overrun_handler), NULL);       
        g_signal_connect(video_queue, "underrun", G_CALLBACK(v_overrun_handler), NULL);               
        g_signal_connect(video_queue, "running", G_CALLBACK(v_running_handler), NULL);               

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

static  void    running_handler(GstElement *queue, gpointer user_data)
{
   g_print("audio running\n");
}   
/**********************************************/
static  void    v_running_handler(GstElement *queue, gpointer user_data)
{
   g_print("video running\n");
}   
/**********************************************/
static  void    underrun_handler(GstElement *queue, gpointer user_data)
{
   g_print("audio underrun\n");
}   
/**********************************************/
static  void    overrun_handler(GstElement *queue, gpointer user_data)
{
   g_print("audio overrun\n");
}   
/**********************************************/
static  void    v_underrun_handler(GstElement *queue, gpointer user_data)
{
   g_print("video underrun\n");
}   
/**********************************************/
static  void    v_overrun_handler(GstElement *queue, gpointer user_data)
{
   g_print("video overrun\n");
}   
/**********************************************/

Hors ligne

#2 Le 23/09/2008, à 15:43

janot_40

Re : gstreamer pipeline audio video, pas d'audio

Bonjour,
Tu peux peut-être jouer sur les propriétés de l'élément de sortie autoaudiosink.
Tu peux aussi essayer de remplacer autoaudiosink par alsasink ou osssink.
J'avais eu un problème similaire et l'avais résolu en mettant la propriété sync de l'élément alsasink à false.

Hors ligne

#3 Le 23/09/2008, à 16:39

sebv78

Re : gstreamer pipeline audio video, pas d'audio

bonjour,

merci, ça marche comme ça (alsasink). Par contre, sais tu comment rajouter un délai avant de lancer l'audio ?
Là, je fais un
        g_object_set (G_OBJECT (audiosink), "latency-time", 2000000, NULL);

et j'ai un segmentation fault quand je fais cet appel.
Je souhaite rajouter un délai car je voudrais synchroniser l'audio avec la vidéo et là, j'ai 2 secondes de décalage.

Hors ligne

#4 Le 24/09/2008, à 08:28

janot_40

Re : gstreamer pipeline audio video, pas d'audio

C'est bizarre même avec un pipeline tout simple la propriété latency-time n'ajoute aucun retard:
gst-launch -v audiotestsrc ! alsasink latency-time=200000

Par contre tu peux ajouter un retard en augmentant le nombre de buffers d'alsasink:
gst-launch -v audiotestsrc ! alsasink preroll-queue-len=20000
Vu que les données transitent de buffer en buffer, plus t'en met plus il y a de retard. Mais bon c'est pas terrible. Le mieux serait de trouver un élement avec une propriété delay ou quelque chose dans le genre.

Hors ligne