2017-08-08 1 views
1

J'utilise avcodec (C++) api pour décoder les trames de fichiers vidéo et les traiter. J'ai remarqué que le nombre de trames décodées est inférieur au nombre réel attendu de trames. La différence est de 16 images. Alors que les images x ont été décodées avec ffmpeg, VirtualDub dit que le même fichier a x + 16 images. En utilisant ffprobe, j'ai vu que le fichier contient des cadres de x:Le décodeur ffmpeg semble perdre des trames

$ ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 inputFile.avi 
10875 

De plus, quand j'ai essayé d'extraire le cadre x + 1 en utilisant l'utilitaire ffmpeg, je suis un échec:

$ ffmpeg -i inputFile.avi -vf "select=eq(n\,10875)" -vframes 1 outPic.jpg 
ffmpeg version N-80801-gc0cb53c Copyright (c) 2000-2016 the FFmpeg developers 
    built with gcc 5.4.0 (GCC) 
    configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-dxva2 --enable-libmfx --enable-nvenc --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-decklink --enable-zlib 
    libavutil  55. 27.100/55. 27.100 
    libavcodec  57. 48.101/57. 48.101 
    libavformat 57. 40.101/57. 40.101 
    libavdevice 57. 0.102/57. 0.102 
    libavfilter  6. 46.102/6. 46.102 
    libswscale  4. 1.100/4. 1.100 
    libswresample 2. 1.100/2. 1.100 
    libpostproc 54. 0.100/54. 0.100 
Input #0, avi, from 'inputFile.avi': 
    Metadata: 
    comment   : Recorder-v2 
    encoder   : Lavf57.40.101 
    Duration: 00:18:09.10, start: 0.000000, bitrate: 3421 kb/s 
    Stream #0:0: Video: mpeg4 (Simple Profile) (xvid/0x64697678), yuv420p, 1280x960 [SAR 1:1 DAR 4:3], 3420 kb/s, 10 fps, 10 tbr, 10 tbn, 10 tbc 
[swscaler @ 00000000021100a0] deprecated pixel format used, make sure you did set range correctly 
[image2 @ 0000000001f10540] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead. 
Output #0, image2, to 'outPic.jpg': 
    Metadata: 
    comment   : Recorder-v2 
    encoder   : Lavf57.40.101 
    Stream #0:0: Video: mjpeg, yuvj420p(pc), 1280x960 [SAR 1:1 DAR 4:3], q=2-31, 200 kb/s, 10 fps, 10 tbn, 10 tbc 
    Metadata: 
     encoder   : Lavc57.48.101 mjpeg 
    Side data: 
     cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1 
Stream mapping: 
    Stream #0:0 -> #0:0 (mpeg4 (native) -> mjpeg (native)) 
Press [q] to stop, [?] for help 
frame= 0 fps=0.0 q=0.0 Lsize=N/A time=00:00:00.00 bitrate=N/A speed= 0x 
video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown 
Output file is empty, nothing was encoded (check -ss/-t/-frames parameters if used) 

L'intéressant et une partie étrange est que sauver toutes les images de ce film dans une séquence produite x + 16 fichiers (même nombre de revendications cadre VirutalDub):

$ ffmpeg -i inputFile.avi "frames/out-%03d.jpg" 
ffmpeg version N-80801-gc0cb53c Copyright (c) 2000-2016 the FFmpeg developers 
    built with gcc 5.4.0 (GCC) 
    configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-dxva2 --enable-libmfx --enable-nvenc --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-decklink --enable-zlib 
    libavutil  55. 27.100/55. 27.100 
    libavcodec  57. 48.101/57. 48.101 
    libavformat 57. 40.101/57. 40.101 
    libavdevice 57. 0.102/57. 0.102 
    libavfilter  6. 46.102/6. 46.102 
    libswscale  4. 1.100/4. 1.100 
    libswresample 2. 1.100/2. 1.100 
    libpostproc 54. 0.100/54. 0.100 
Input #0, avi, from 'inputFile.avi': 
    Metadata: 
    comment   : Recorder-v2 
    encoder   : Lavf57.40.101 
    Duration: 00:18:09.10, start: 0.000000, bitrate: 3421 kb/s 
    Stream #0:0: Video: mpeg4 (Simple Profile) (xvid/0x64697678), yuv420p, 1280x960 [SAR 1:1 DAR 4:3], 3420 kb/s, 10 fps, 10 tbr, 10 tbn, 10 tbc 
[swscaler @ 00000000020600a0] deprecated pixel format used, make sure you did set range correctly 
[image2 @ 0000000001d20540] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead. 
Output #0, image2, to 'frames/out-%03d.jpg': 
    Metadata: 
    comment   : Recorder-v2 
    encoder   : Lavf57.40.101 
    Stream #0:0: Video: mjpeg, yuvj420p(pc), 1280x960 [SAR 1:1 DAR 4:3], q=2-31, 200 kb/s, 10 fps, 10 tbn, 10 tbc 
    Metadata: 
     encoder   : Lavc57.48.101 mjpeg 
    Side data: 
     cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1 
Stream mapping: 
    Stream #0:0 -> #0:0 (mpeg4 (native) -> mjpeg (native)) 
Press [q] to stop, [?] for help 
frame=10891 fps=120 q=24.8 Lsize=N/A time=00:18:09.10 bitrate=N/A dup=16 drop=0 speed= 12x 
video:384325kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown 

nombre compté de fichiers/images:

$ ls -l frames/* | wc -l 
    10891 

Je suis à peu près perdu ici. Toute idée de pourquoi avcodec décode x images et non x + 16? Est-ce que ffmpeg manque des cadres? Est-ce que VirtualDub peut dupliquer (16) images?

Merci

+0

Cette vidéo a-t-elle des cadres noirs purs? – VTT

+0

Pas que je sache –

Répondre

0

Cause possible est "cadres de chute", vous pouvez vérifier avec VirtualDub raccourcis clavier "Go -> drop frame suivante". FFmpeg ne les considère pas comme des images indépendantes, mais vous pouvez remarquer des sauts dans le code temporel.

+0

Oui, c'est ça! On dirait que Vdub "complétant" une image perdue, en remplissant une copie de la dernière image. En outre, ffmpeg peut imiter ce comportement lorsque le dumping toutes les images: ffmpeg -i inFile.avi « % 03d.jpg » –

+0

Est-ce que quelqu'un connait un moyen de dire ffmpeg en utilisant avcodec (C++) api pour remplir les cadres dupliqués où il y a des ' trous », comme VirtualDub? Dans l'utilitaire ffmpeg, par exemple, il peut être fait avec le commutateur '-vsync cfr' Mais je dois le faire dans mon code de décodage C++ Merci –

+0

afaik il n'y a pas de commutateur simple. Vous pouvez regarder les lacunes dans les points et insérer des doublons vous-même. btw, ceci est implémenté dans mon pilote ffmpeg pour virtualdub https://sourceforge.net/p/vdfiltermod/cch_input/ci/master/tree/ – shekh