2009-02-02 7 views
15

Próbuję szukać w filmie za pomocą metody av_seek_frame ffmpeg, ale mam najwięcej problemów z określeniem, jak wygenerować znacznik czasu do wyszukiwania. Zakładając, że chcę wyszukać x ilość klatek w przód lub w tył i wiem, w jakiej klatce jest obecnie film, w jaki sposób chciałbym to zrobić?ffmpeg av_seek_frame

+0

Nie można obliczyć przesunięcia czasu za pomocą liczby klatek na sekundę? –

+0

Z tego co rozumiem, przesunięcie czasowe musi znajdować się w jednostkach time_base, ale nie jestem do końca pewien, jak przekonwertować go na te jednostki (lub nawet, jeśli to właśnie muszę zrobić). Jeśli to jest to, co muszę zrobić, nie jestem pewien, czym są jednostki time_base (sekundy, klatki, klatki na sekundę). –

Odpowiedz

8

Prosta odpowiedź: Powinieneś kłaść obiekt AVFormatContext. Jego właściwość duration informuje, jak długo twój plik jest pod względem znacznika czasu pomnożonego przez 1000, który może być użyty w av_seek_frame, więc traktuj go jako 100%. Następnie możesz obliczyć odległość do filmu, do którego chcesz dążyć.

Jeśli chcesz przejść do następnej ramki, po prostu wywołaj av_read_frame i avcodec_decode_video, dopóki nie wypełni on got_picture_ptr z niezerową wartością. Przed wywołaniem avcodec_decode_video upewnij się, że pakiet z av_read_frame pochodzi ze strumienia wideo. avcodec_decode_video następnie wypełni strukturę AVFrame, której możesz użyć do zrobienia czegokolwiek.

13

Oto jak to zrobiłem:

// 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."); 

} 

AVSEEK_FLAG_ANY umożliwia dążenie do każdej klatki i nie tylko klatki kluczowe.

+0

+1 za wskazanie, co robi "AVSEEK_FLAG_ANY" – puk