2013-03-17 17 views
5

Seguendo le exmaples di ffmpeg: decoding_encoding.c e filtering_video.c, elaborerò un file video preso da iPhone. Il file video: .mov, dimensioni del video; 480x272, codec video: H.264/AVC, 30 fotogrammi al secondo, bitrate: 605 kbps.Perché frame-> pts aumenta di 20 anziché di 1?

Estrarre prima ogni frame, che è YUV. Converto YUV in RGB24 ed elabora l'RGB24, quindi scrive RGB24 in un file .ppm. Mostra il file .ppm è corretto.

Quindi ho intenzione di codificare i frame RGB24 elaborati in un file video. Poiché MPEG non supporta il formato di immagine RGB24, ho utilizzato AV_CODEC_ID_HUFFYUV. Ma il file di output video (che mostra 18,5 MB) non viene riprodotto. Movie Player su Ubuntu afferma un errore: Impossibile determinare il tipo di flusso. L'ho provato anche su VCL. Semplicemente non funziona, senza alcuna informazione di errore.

mie seconda questione è: Per ogni Fram estratto dal file di ingresso, ricevo i suoi punti come segue in base alla filtering_video.c:

frame->pts = av_frame_get_best_effort_timestamp(frame);

stampo fuori pts di ogni fotogramma, e scoprire che aumenta di 20, come di seguito:

pFrameRGB_count: 0, frame->pts: 0 
pFrameRGB_count: 1, frame->pts: 20 
pFrameRGB_count: 2, frame->pts: 40 
pFrameRGB_count: 3, frame->pts: 60 

Dove telaio è il fotogramma estratto dal video di ingresso, e pFrameRGB_count è il conteggio per telaio trasformati in forma RGB24.

Perché si sbagliano?

risposta

5

I video H.264 utilizzano 90 kHz clock per la codifica timestamps. Poiché il tuo video è 30 fps, il delta PTS tra 2 frame successivi deve essere 3000 anziché 20.

Un valore di 20 indica una o entrambe le seguenti operazioni:

  • L'orologio codifica (cioè velocità di campionamento) è configurato in modo errato (a 600 Hz) per il dato frame rate di 30 fps

  • I frame al secondo sono configurati in modo errato (a 4500fps).

La formula generale per calcolare PTS delta è:

PTS delta = (1/fps) * Encoder sampling rate 
0

ho debug per ottenere contesto codec del file di ingresso, dec_ctx-> time_base.den = 1200; Conosco il fps, 30, facendo clic con il tasto destro del mouse sul file video di input per controllarne le proprietà (Ubuntu 12.04) Quindi sembra che la durata del frame debba essere 1200/30 = 40 unità di base. Ma è 20 usando frame-> pts = av_frame_get_best_effort_timestamp (frame);

il pacchetto di lettura del video in ingresso ha la durata = 20.

ho trovato dec_ctx-> ticks_per_frame = 2. Credo ticks_per_frame rende 40 a 20. forse c'è qualche formula interna, come: durata della trama in unità di base = durata del frame x ticks_per_frame (ma sembra che sia diverso da ciò che viene detto nel documento ffmpeg, ad esempio time_base è uguale a 1/frame rate.)

0

Penso di trovare la risposta. A causa della mancanza di documentazione dettagliata di ffmpeg, gli utenti potrebbero essere fuorviati. trovo che, per ottenere punti corretti, si dovrebbe sempre usare: video_st-> time_base NON video_st-> codec-> time_base

(a) Tempo assoluto di un telaio:

di pacchetto> dts * (1/video_st-> time_base.den)

(b) tempo assoluto tra il telaio e il suo frame successivo:

cornice-> repeat_pict * (1/video_st-> time_base.den)

Problemi correlati