2009-02-02 23 views
15

Estoy intentando buscar en una película usando el método av_seek_frame de ffmpeg, pero estoy teniendo más problemas para determinar cómo generar un sello de tiempo para buscar. Asumiendo que quiero buscar x cantidad de fotogramas hacia adelante o hacia atrás y sé en qué fotograma está actualmente la película, ¿cómo voy a hacer esto?ffmpeg av_seek_frame

+0

¿No pudo calcular la compensación de tiempo utilizando la velocidad de cuadro? –

+0

Por lo que entiendo, el desplazamiento de tiempo debe estar en unidades de base de tiempo pero no estoy exactamente seguro de cómo convertirlo a esas unidades (o incluso si eso es lo que tengo que hacer). Si eso es lo que tengo que hacer, no estoy seguro de en qué se encuentran las unidades de time_base (segundos, cuadros, cuadros por segundo). –

Respuesta

8

Respuesta simple: Debería tener un objeto AVFormatContext por ahí. Su propiedad duration le dice cuánto tiempo es su archivo en términos de la marca de tiempo multiplicada por 1000 que se puede usar en av_seek_frame, así que trátela como 100%. Luego puede calcular qué tan lejos en el video desea buscar.

si quiere avanzar un cuadro, simplemente llame a av_read_frame y avcodec_decode_video hasta que llene el got_picture_ptr con un valor distinto de cero. Antes de llamar avcodec_decode_video, asegúrese de que el paquete de av_read_frame proviene de la transmisión de video. avcodec_decode_video completará la estructura AVFrame que puede usar para hacer cualquier cosa.

13

Aquí es cómo lo hice:

// Duration of one frame in AV_TIME_BASE units 
int64_t timeBase; 

void open(const char* fpath){ 
    ... 
    timeBase = (int64_t(pCodecCtx->time_base.num) * AV_TIME_BASE)/int64_t(pCodecCtx->time_base.den); 
    ... 
} 

bool seek(int frameIndex){ 

    if(!pFormatCtx) 
     return false; 

    int64_t seekTarget = int64_t(frameIndex) * timeBase; 

    if(av_seek_frame(pFormatCtx, -1, seekTarget, AVSEEK_FLAG_ANY) < 0) 
     mexErrMsgTxt("av_seek_frame failed."); 

} 

El AVSEEK_FLAG_ANY permite tratar de cada cuadro y no sólo los fotogramas clave.

+0

+1 para señalar lo que 'AVSEEK_FLAG_ANY' hace – puk