Increase bit rate while converting FFMPEG - ffmpeg

I am trying to convert an .mp4 to .mpeg using:
ffmpeg -i "01_b.wmv" -an -c:v mpeg1video -b:v 20M "intro.mpeg"
My source video is 20MB/s but the converted .mpeg file doesn't ever go that high (usually ends up being around 12MB/s).
Is there something I am missing? I am relatively inexperienced with FFMPEG, so any help is appreciated.

The bit rate is calculated to an average at output versus being a simple duration/file size calculation. 100MB file, 10s = 10Mb/s, even though 40Mb/s could be the two seconds, and the rest is a lower bit rate.

Related

How can I avoid an ffmpeg out of memory error

I use ffmpeg with complex filtering. Input are different sets of FULLHD surveilance camera videos each 10 to 15 seconds long. Set size (number of videos per set) varies. To remove unchanged frames I apply mpdecimate. To avoid being triggered by moving bushes but still keep objects I want to remain, I apply a complex filter:
split the video (the original and a dummy to detect motion/stills)
scale the dummy down (so the 8x8-block-metric of mpdecimate matches the size of moving objects I want to keep)
add white boxes to dummy to mask unintendedly moving objects
apply mpdecimate to dummy to remove non-changing frames
scale dummy back to original size
overlay the remaining frames of dummy with matching frames of original
All this works fine if the number of input videos is small (less than 100). The memory consupmtion of the ffmpeg process varies somewhere between 2GiB and 5GiB.
If the number of input files gets larger (say 200), the memory consumption suddenly jumps to insane numbers until memory (32GiB plus 33GiB swap) runs out and ffmpeg gets killed. I can not predict if and why this happens. I have one example, where a set of 340 videos worked using 6GiB. Any other set above 100 videos I tried eats all RAM in under two minutes and dies.
There is no particular error message from ffmpeg.
dmesg says:
Out of memory: Kill process 29173 (ffmpeg)
Killed process 29173 (ffmpeg) total-vm:66707800kB
My ffmpeg command:
ffmpeg -f concat -safe 0 -i vidlist -vf 'split=2[full][masked];[masked]scale=w=iw/4:h=ih/4,drawbox=w=51:h=153:x=101:y=0:t=fill:c=white,drawbox=w=74:h=67:x=86:y=49:t=fill:c=white,drawbox=w=51:h=149:x=258:y=0:t=fill:c=white,drawbox=w=13:h=20:x=214:y=103:t=fill:c=white,drawbox=w=29:h=54:x=429:y=40:t=fill:c=white,drawbox=w=35:h=49:x=360:y=111:t=fill:c=white,drawbox=w=26:h=54:x=304:y=92:t=fill:c=white,drawbox=w=48:h=27:x=356:y=105:t=fill:c=white,drawbox=w=30:h=27:x=188:y=124:t=fill:c=white,drawbox=w=50:h=54:x=371:y=7:t=fill:c=white,drawbox=w=18:h=38:x=248:y=107:t=fill:c=white,drawbox=w=21:h=51:x=242:y=33:t=fill:c=white,mpdecimate=hi=64*80:lo=64*40:frac=0.001,scale=w=iw*4:h=ih*4[deduped];[deduped][full]overlay=shortest=1,setpts=N/(15*TB),mpdecimate=hi=64*80:lo=64*50:frac=0.001,setpts=N/(15*TB)' -r 15 -c:v libx265 -preset slower -crf 37 -pix_fmt yuv420p -an result.mkv
ffmpeg version 4.1.6
Debian 4.19.171-2
I hope that my filter can be tuned in some way that achieves the same result but doesn't eat RAM that much - but I have no clue how. Within reasonable limits, I wouldn't mind if processing time suffers. Any hints appreciated.
It seems the memory issue can be avoided by removing the split filter. Instead of spliting one input into two streams (that ffmpeg has to store in memory) the same input can be loaded twice.
So instead of using "full" and "dummy" as below
ffmpeg -i source -vf 'split=2[full][dummy];...;[dummy][full]overlay...
one would use "0:v" and "1:v" as in
ffmpeg -i source -i scource -filter_complex '.....;[0:v][1:v]overlay...
I get this to work with input videos, but so far I fail to do this with the concat demuxer as input.
Any hints very welcome.

Does converting .mp4 to .mkv change data fidelity?

I am wondering when I convert a .mp4 to .mkv using the following command if the quality changes.
ffmpeg -i in.mp4 out.mkv
The input file, in.mp4 has a file size of 297 megabytes, while the out.mkv file has a size of 249 megabytes, ~15% lower. Upon manual inspection, the resolution, video, and audio streams are the same before/after (as I would have expected given my (limited) knowledge of ffmpeg).
Is the 15% size decrease by simply converting to mkv actually not affect the quality of the video? If so this seems like a very reasonable way of freeing up some space on my computer.
The quality gets worse
This is due to generation loss because you are re-encoding the video and audio to lossy formats. But you may not notice the difference.
The output file size will vary depending on the input format, if it was encoded well or badly, your output format, and the settings you use.
MP4 to MKV without quality loss
You can just re-mux and avoid re-encoding by using stream copy mode:
ffmpeg -i input.mp4 -c copy output.mkv
You can think of it like a copy and paste. The video and audio is untouched and just put into a new container.

How can I make sure trimming in ffmpeg with -c:v copy is accurate

I looked at many things online and I understand it's better to re-encode if you want precision.
But for instance, I have the following command:
-ss 00:00:09 -i "input.mp4" -c:v copy -c:a copy -vframes 600 "output.mp4
Where 600 is calculated using the video's FPS and duration, in this case 10 seconds from an 60FPS video. Can I expect to get something accurate with this all the time? I tested many variants but this seems to be doing ok for the couple videos I tested for.. And if not, can I really ever get complete ACCURACY with copying, or must I stick to H264 for instance?
Question: can I really ever get complete ACCURACY with copying
No. Copying requires you cut on key frames.

ffmpeg to change video from 30 to 60fps to double speed without re-encoding

First, I have looked at the older questions asking the same, but the responses do not work.
Adding -r 30 or 60 to the input file does not impact the output, nor does setting it for the output, which remains unchanged.
I am handling a very large number of files from 1 to 22 gigs recorded (with audio) in 30fps that need to be re-posted as 60pfs, with the corresponding speed increase.
I toyed with ffmpeg a bit and came up with this..
-filter_complex "[0:v]setpts=0.50*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" -vcodec:v libx264
It works fine, but to have to wait out a complete re-encoding of the video and audio to produce the same video with the fps changed seems like an insane waste of time.
Am I missing something simple? Is there not a way to -c copy with a new fps playback rate on the resulting file?
(if it still has to recode the audio to maintain sync that's fine, audio is quick enough it doesn't much matter)

What codec/format to use for fastest possible decoding?

I'm using an ffmpeg script (in Windows) that extracts all the keyframes from a video and pastes them into a folder. I've made sure that my drive speed, CPU, and RAM are not causing a bottleneck.
The quality of the video is actually not important at all in this case. I need to encode the video that the script extracts frames from so that it has the fastest possible decoding speed. File size and quality are not important, only read speed. The video does not have audio. What would work best for me?
If it matters, here's the script I'm working with:
ffmpeg -i input.mp4 -vf "select=eq(pict_type\,I)" -vsync 1 %%3d.bmp
Sorry if sound like I don't know what I'm talking about, this is not a topic I am super familiar with. I appreciate your help!
The below will be much faster for a codec like H.264
ffmpeg -discard nokey -i input.mp4 -vsync 0 %%3d.bmp
Your present approach decodes all frames and then the select filter gets to do gating, but the above command discards everything but keyframes at the demuxer level. It only works with MP4/MOV like containers.

Resources