2009-02-02 16 views
15

Ich versuche in einem Film zu suchen, indem ich die av_seek_frame-Methode von ffmpeg benutze, aber ich habe die größten Schwierigkeiten damit, zu bestimmen, wie man einen Zeitstempel erzeugt, um zu suchen. Angenommen, ich möchte die Anzahl der Bilder entweder vorwärts oder rückwärts suchen und weiß, in welchem ​​Bild der Film gerade läuft, wie würde ich das machen?ffmpeg av_seek_frame

+0

Konnten Sie den Zeitversatz nicht mit der Bildrate berechnen? –

+0

Von dem, was ich verstehe, muss der Zeitversatz in time_base-Einheiten sein, aber ich bin nicht genau sicher, wie man es in diese Einheiten umwandelt (oder sogar, wenn es das ist, was ich tun muss). Wenn das das ist, was ich tun muss, bin ich nicht sicher, was die Einheiten von time_base sind (Sekunden, Frames, Frames pro Sekunde). –

Antwort

8

Einfache Antwort: Sie sollten ein AVFormatContext-Objekt herumliegen haben. Seine duration Eigenschaft sagt Ihnen, wie lange Ihre Datei in Bezug auf den Zeitstempel multipliziert mit 1000 ist, die in av_seek_frame verwendet werden kann, also behandeln Sie sie als 100%. Dann kannst du berechnen, wie weit du in das Video hineinsehen möchtest.

Wenn Sie einen Frame vorwärts gehen möchten, rufen Sie einfach av_read_frame und avcodec_decode_video auf, bis der Wert von got_picture_ptr mit einem Wert ungleich Null gefüllt ist. Stellen Sie vor dem Aufruf von avcodec_decode_video sicher, dass das Paket von av_read_frame aus dem Videostream stammt. avcodec_decode_video füllt dann die AVFrame-Struktur aus, mit der Sie alles machen können.

13

Hier ist, wie ich es tat:

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

} 

Die AVSEEK_FLAG_ANY ermöglicht jedem Frame sucht und nicht nur Keyframes.

+0

+1 für den Hinweis, was 'AVSEEK_FLAG_ANY' tut – puk