Poate ffmpeg av libs returna un PTS exact?

Lucrez cu un flux MPEG care folosește o secvență IBBP ... GOP. Valorile (DTS, PTS) returnate pentru primele 4 pachete AV sunt următoarele: I = (0,3) B = (1,1) B = (2,2) P =

PTS pe cadrul I pare ca este legit, dar atunci PTS pe cadrele B nu poate fi corect, deoarece cadrele B nu ar trebui sa fie afisate inaintea frame-ului I asa cum indica valorile lor PTS. Am încercat, de asemenea, decodarea pachetelor și folosind valoarea pts în AVFrame rezultată, puneți că PTS este întotdeauna setat la zero.

Există vreo modalitate de a obține un PTS exact din ffmpeg? Dacă nu, care este cel mai bun mod de sincronizare audio atunci?

0

2 răspunsuri

Cred că în cele din urmă mi-am dat seama ce se întâmplă pe baza unui comentariu făcut în http: //www.dranger. com/ffmpeg/tutorial05.html :

ffmpeg rearanjează pachetele astfel încât DTS-ul pachetului care este procesat de avcodec_decode_video() va fi mereu același ca PTS al cadrului pe care îl returnează

Traducere: Dacă eu alimentez un pachet în avcodec_decode_video() care are un PTS de 12, avcodec_decode_video() nu va returna cadrul decodat conținut în acel pachet până când îl voi alimenta un pachet mai târziu care are un DTS de 12. Dacă PTS a pachetului este același cu DTS, atunci pachetul dat este același cu cel returnat. Dacă PTS a pachetului este de 2 cadre mai târziu decât DTS, atunci avcodec_decode_video() va întârzia cadranul și nu-l va returna până când nu am furnizat încă 2 pachete.

Pe baza acestui comportament, presupun că av_read_frame() poate reordona pachetele de la IPBB la IBBP astfel încât avcodec_decode_video() trebuie doar să tamponeze cadrele P pentru 3 cadre în loc de 5. De exemplu, diferența dintre intrarea și ieșirea cadrului P cu această ordonare este 3 (6 - 3):

|                  I B B P B B P
|             DTS: 0 1 2 3 4 5 6
| decode() result:       I B B P

vs. o diferență de 5 cu comanda standard (6 - 1):

|                  I P B B P B B
|             DTS: 0 1 2 3 4 5 6
| decode() result:       I B B P

but that is pure conjecture.

0
adăugat

Sunt destul de sigur că obțineți valori exacte. S-ar putea să vă ajute dacă vă place un flux MPEG ca și un flux. În acest caz, înainte de IBBPBB pe care îl vedeți acolo ar fi în mod normal un alt GOP. Poate ceva de genul acesta (folosind aceeași notație ca și întrebarea originală):

P(-3,-2)  B(-2,-1)  B(-1,0)

În principiu, cadrele B după cadrele I se bazează pe cadrul I și ultimul cadru P din GOP anterior .

Deși este logic ca un videoclip să înceapă cu acest lucru:

Start GOP: IPBBPBBPBB...

Mai târziu, trebuie să fie

Start GOP: IBBPBBPBBPBB
Start GOP: IBBPBBPBBPBB
Start GOP: IBB... 

Amintiți-vă că decodificarea oricărui cadru B necesită un cadru complet înainte și după el. Deci, fiecare pereche de cadre B ar trebui să fie afișată înainte de rama I sau P chiar înainte de a fi în fișier.

FFMPEG poate pur și simplu a pierdut "cazul special" al primului POR.

Deoarece primele două cadre B nu au un cadru anterior de manipulat, ar trebui să le puteți arunca în siguranță. Doar rebasează-ți timestamp-urile de pe primul cadru I și ajustați fluxul audio la aceeași valoare.

Dacă acest lucru va duce la pierderea cadrelor, va depinde de implementarea FFMPEG, dar scenariul mai rău este că pierdeți 83 de milisecunde (2 cadre la 24 cadre/sec).

0
adăugat
Aceste tipuri de hack-uri (acceptând pierderea a 2 cadre) sunt ... hacky :) Documentarea rușinii este atât de plictisitoare încât aproape nimeni nu deranjează.
adăugat autor Roman Starkov, sursa