2011-07-18 4 views
2

J'utilise Ffmpeg pour décoder et lire des fichiers vidéo. J'ai actuellement la lecture de la vidéo et la lecture de l'audio aussi rapidement que le processeur peut les décoder et les afficher. Le problème est que je veux synchroniser la vidéo et l'audio en utilisant l'horloge du système.Synchronisation de la vidéo décodée à l'aide de Ffmpeg

J'ai cherché de l'aide mais je ne trouve rien d'autre que le tutorial 05 du dranger mais je ne comprends pas vraiment ce qu'il fait parce que mon programme n'est pas écrit de la même manière que le sien. J'utilise des fichiers mjpeg et donc le pts semble être récupéré chaque fois qu'une image est décodée, j'ai multiplié les pts par le time_base comme le fait dranger pour obtenir la valeur en secondes mais la résolution semble être seulement secondes et donc je reçois la valeur "6" 25 fois et ensuite "7" 25 fois que la vidéo s'exécute à 25 images par seconde.

N'y a-t-il pas une valeur plus précise? Ou comment obtenir une valeur plus précise et si oui, comment procéder pour la synchronisation avec cette valeur? J'utilise SDL pour afficher la valeur, puis-je simplement utiliser un SDL_Delay() de la valeur obtenue?

Merci pour votre temps,

Infinitifizz

+0

Cochez pour vérifier que vous utilisez le bon type, peut-être que vous faites le calcul 'pts * time_base' comme int au lieu de float. –

+0

Eh bien, la valeur PTS semble être en int64t ne pas flotter ou doubler. –

+0

En regardant le tutoriel du dranger, il utilise fondamentalement les pts du premier paquet qui compose le cadre en tant que pts du cadre ou, si cela n'existe pas, la valeur dts du paquet. Cette valeur est ensuite multipliée par la video time_base (en double) mais est toujours un uint64_t et donc je reçois juste un résultat comme: 0,0,0,0,0,0,1,1,1,1,1,1 , 2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4 etc. plutôt que n'importe quoi en millisecondes ou quoi que ce soit de plus précis que les secondes. –

Répondre

2

Pour convertir ou pts dts en secondes à virgule flottante, utilisez av_q2d() sur time_base appropriée:

// You got the context from open_input: 
AVFormatContext *pFormatCtx; 
avformat_open_input(&pFormatCtx, inputfilename, NULL, &format_opts); 

// Get a stream from the context 
AVStream pStream= pFormatCtx->streams[i]; 

// Convert packet time (here, dts) to seconds with: 
double seconds= (dts - pStream->start_time) * av_q2d(pStream->time_base); 

// Or convert frame number to seconds with the codec context 
AVCodecContext *pCodecCtx= pStream->pVideoStream->codec; 
double seconds= framenumber * av_q2d(pCodecCtx->time_base); 

Cela retourne le temps From- quand-la-vidéo commence en secondes.

+0

Qu'est-ce que "frame" et d'où vous obtenez "dts from"? –

+1

Vous avez probablement mis au point vos problèmes, mais pour les futurs chercheurs: 'framenumber' est obtenu à partir de' pCodecCtx' et 'dts' vient de' AVPacket' que vous obtenez après avoir appelé la fonction de décodage. – Sam

Questions connexes