first i'll explain the purpose of the encodes... making x264/AAC video inside MP4 container with target video bitrate of minimum 1000, using 1280x720 JPG image and MP3 audio as sources. this is so when uploaded to youtube i get the "watch in HD" link under the player.
first, i take JPG/MP3 files and combine the two with avisynth:
then, i need to pass the resulting avisynth scrip through x264 encoder, in a way that resulting video has max quality, video bitrate of 1,000Kbps, but keyframe interval to be the adjusted accordingly to fit the set-quality/set-bitrate tradeoff... in other words - known quality, known bitrate, but unknown keyframe interval.Code:audio = directshowsource("source.mp3").SSRC(44100) duration = audio.AudioLength / audio.AudioRate * 30 video = ImageSource("source.jpg", 1, duration, 30) AudioDub(audio, video).ConvertToYV12()
currently i'm using the following command, encoding multiple times and modifying "--keyint" to match 1000Kbps as close as possible:
Code:x264 --qp 10 --keyint 30 --scenecut -1 --nf --subme 1 --partitions p8x8,b8x8,i4x4 --merange 12 --threads auto --thread-input --aud --progress --no-psnr --no-ssim --output output.mp4 source.avs *** --qp 10 is good enough as far as quality concerned
guessing the best "--keyint" manually is simply too time consuming. is x264 encoder flexible enough to figure out the best matching keyframe interval automatically? if not, what would i need to do in order to automate the process?
thanks for the help!
+ Reply to Thread
Results 1 to 7 of 7
There is no way you will be able to automate this. Every video is different. The size of the keyframes will vary depending on the image content. All the B and P frames will be nearly zero in size because the picture isn't changing in a slideshow. You'll probably have to switch to bitrate based encoding if you have to guaranty the video bitrate is over 1000 kbps.
as i usually say, nothing is impossible
after some experimenting on my own, there is a correlation between bitrate and keyinterval... inverse square correlation to be exact. after doing 3 tests i was able to write and equations that would give me the best keyinterval depending on the video bitrate i get after encoding at keyinterval of 30.
currently, this is where i'm at. encode the video at keyint = 30:
x264 --qp 10 --keyint 30 --scenecut -1 --nf --subme 1 --partitions p8x8,b8x8,i4x4 --merange 12 --threads auto --thread-input --aud --progress --no-psnr --no-ssim --output NUL source.avs
with that function above i can guess the best keyint with final ranging from 1,000 to 1,100 which is pretty darn good. there is still an unknown factor which is responsible for that variance in Kbps and i'm pretty sure i got it figured out, just have to make few more tests to gather data and incorporate it in the equation.
i guess if x264 doesnt do it by itself, i can achieve what i want by doing with a my own versions of "2 pass" encoding
And now try a different video. You'll get different numbers. Try an all black video.
yep, thats the unknown factor i'll need to figure out... the -.96229 exponent seems to depend on the complexity of the picture. for very simple to very complex it ranges from -.92 to -.99 respectively. just gotta figure out the type of correlation and account for it in the final equation.
not sure if anybody else is interested in such 2-pass encoding but i'll still report back once i got it all figured out to the perfection
after many more tests, i figured it out.
final equation for finding out the keyinterval i should use is:
z = keyinterval used in the 1st pass k = final Kbps of 1st pass video t = target bitrate b = variable exponent. varies from “-.80” to “-.99”, but I found that ”-1” does the job just fine
0.03 * k
here's the command used in the 1st pass,
ffmpeg -loop_input -i source.jpg -vframes 30 -pix_fmt yuv420p -f rawvideo - | x264 --keyint 30 --fps 30 --qp 10 --scenecut -1 --nf --subme 1 --partitions p8x8,b8x8,i4x4 --merange 12 --threads auto --thread-input --aud --progress --no-psnr --no-ssim --output NUL - 1280x720