Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > General > Newbies

Reply
 
Thread Tools Search this Thread Display Modes
Old 9th December 2023, 17:55   #1  |  Link
hellgauss
Registered User
 
hellgauss's Avatar
 
Join Date: Sep 2002
Location: Italy
Posts: 108
Using ffmpeg to capture frame by number

I need to capture several video frames as .png from .mkv files in an automated way, starting from the frame numbers.

I use the following .bat file (windows) which extracts e.g. 4 frames from a .mkv with yuv video.

Code:
set "f1=12345"
set "f2=55555"
set "f3=111111"
set "f4=141414"

ffmpeg -y -bitexact -i "myvideo.mkv" -map 0:v -vf "select='eq(n,%f1%)+eq(n,%f2%)+eq(n,%f3%)+eq(n,%f4%)'" -fps_mode passthrough -sws_flags accurate_rnd+full_chroma_int -bitexact "im_%%d.png"
The output seems to be ok for me. The problem is that ffmpeg parse (re-encode?) the whole video and it takes *a lot* of time, especially if I use the -sws_flags which I need for precision.

Is there a way to do that in a fast way without calculating the exact timestamp of the frames?

If needed I can also switch to another command-line windows utility, as long as it is well tested and the yuv-->rgb conversion is accurate.

Thanks
HG
hellgauss is offline   Reply With Quote
Old 10th December 2023, 23:43   #2  |  Link
Emulgator
Big Bit Savings Now !
 
Emulgator's Avatar
 
Join Date: Feb 2007
Location: close to the wall
Posts: 1,738
You want precisely that frame you are specifying decoded, and bitexact, so ffmpeg needs to precisely parse the unknown .mkv, which can only mean indexing, searching, decoding.
Given the complexity of codecs in ffmpeg toolbox I can not imagine any fast way hoping to take shortcuts and assuming a hopefully correct frame.
Any other software would have to perform the same.
__________________
"To bypass shortcuts and find suffering...is called QUALity" (Die toten Augen von Friedrichshain)
"Data reduction ? Yep, Sir. We're that issue working on. Synce invntoin uf lingöage..."
Emulgator is offline   Reply With Quote
Old 11th December 2023, 22:07   #3  |  Link
hellgauss
Registered User
 
hellgauss's Avatar
 
Join Date: Sep 2002
Location: Italy
Posts: 108
It is not true. Virtualdub2 opens a .mkv in less than a second, and can jump immediately to a given frame by number (just click on the "Frame" label at bottom). This is the standard way I take screenshots when I have to compare two same frames of different encodings, but I also have to copy the frame to clipboard, open an Image utility, paste and save, then open a new file in VD2. If I can do it automatically it is better, especially if I have several different files to compare.

PS: the 'bitexact' option, as a general ffmpeg flag and outside the -sws_flags parameter, is only for deterministic output (and input/decoding). It allows me to check if an option has any effect by hash, and remove any unwanted and potentially personal information from the output, such as timestamps.

Last edited by hellgauss; 11th December 2023 at 22:10. Reason: typo
hellgauss is offline   Reply With Quote
Old 12th December 2023, 20:15   #4  |  Link
Emulgator
Big Bit Savings Now !
 
Emulgator's Avatar
 
Join Date: Feb 2007
Location: close to the wall
Posts: 1,738
Well, VD2 uses avlib-1.vdplugin as decoder, and behind that sits: The very same mother ffmpeg, what else. ;-)
https://forum.doom9.org/showthread.p...89#post1994989
Just no lengthy indexing, rather trusting the container- if that hits the correct frame, one may use that.
(Here it was not, BTW. DGDecoders are the gold standard here, and they do need indexing.)
BTW, if one prefers VD: no image utility needed.
VD can export frames: single, sequences, and this can be scripted.
And AvsPmod can do that too, with Macros.
__________________
"To bypass shortcuts and find suffering...is called QUALity" (Die toten Augen von Friedrichshain)
"Data reduction ? Yep, Sir. We're that issue working on. Synce invntoin uf lingöage..."

Last edited by Emulgator; 12th December 2023 at 20:29.
Emulgator is offline   Reply With Quote
Old 13th December 2023, 21:04   #5  |  Link
hellgauss
Registered User
 
hellgauss's Avatar
 
Join Date: Sep 2002
Location: Italy
Posts: 108
Thanks a lot for info and tips!

I cannot find the way to script single image export with VD2, bit i managed it with export image sequence. The following script seems to do a good job. Perhaps it needs some tweak with strange characters in file name.

It needs Virtualdub2 folder in windows PATH

Code:
set "f1=12345"
set "f2=55555"
set "f3=111111"
set "f4=141414"
set "input=test_(test)\myvideo.mkv"

call :vdgrab %input%, %f1%, 1
call :vdgrab %input%, %f2%, 2
call :vdgrab %input%, %f3%, 3
call :vdgrab %input%, %f4%, 4

pause
exit

:vdgrab
rem usage (3 params): vdgrab input_video frame_number output
rem virtualdub2 folder must be in windows PATH
rem output is without .png extension

SETLOCAL
set "input=%1"
set "input=%input:\=\\%"

set /A n1=%2
set /A n2=n1+1

(
echo VirtualDub.Open^("%input%","",0^);
echo VirtualDub.audio.SetSource^(1^);
echo VirtualDub.audio.SetMode^(0^);
echo VirtualDub.audio.SetInterleave^(1,500,1,0,0^);
echo VirtualDub.audio.SetClipMode^(1,1^);
echo VirtualDub.audio.SetEditMode^(1^);
echo VirtualDub.audio.SetConversion^(0,0,0,0,0^);
echo VirtualDub.audio.SetVolume^(^);
echo VirtualDub.audio.SetCompression^(^);
echo VirtualDub.audio.EnableFilterGraph^(0^);
echo VirtualDub.video.SetInputFormat^(0^);
echo VirtualDub.video.SetOutputFormat^(7^);
echo VirtualDub.video.SetMode^(3^);
echo VirtualDub.video.SetSmartRendering^(0^);
echo VirtualDub.video.SetPreserveEmptyFrames^(0^);
echo VirtualDub.video.SetFrameRate2^(0,0,1^);
echo VirtualDub.video.SetIVTC^(0, 0, 0, 0^);
echo VirtualDub.video.SetCompression^(^);
echo VirtualDub.SaveFormatAVI^(^);
echo VirtualDub.SaveAudioFormat^(""^);
echo VirtualDub.video.filters.BeginUpdate^(^);
echo VirtualDub.video.filters.Clear^(^);
echo VirtualDub.video.filters.EndUpdate^(^);
echo VirtualDub.audio.filters.Clear^(^);
echo VirtualDub.video.SetRangeFrames^(%n1%,%n2%^);
echo VirtualDub.project.ClearTextInfo^(^);
echo VirtualDub.SaveImageSequence2^("%3_", ".png", 1, 0, 3, 100^);
echo VirtualDub.Close^(^);
) > %1_%2_%3.tmp

start /min /wait virtualdub64.exe /x /s %1_%2_%3.tmp
rename "%3_0.png" "%3.png"
del %1_%2_%3.tmp
ENDLOCAL
exit /B 0
hellgauss is offline   Reply With Quote
Reply

Tags
ffmpeg, frames

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 09:46.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.