lieff / minih264

Minimalistic H264/SVC encoder single header library
Creative Commons Zero v1.0 Universal
536 stars 53 forks source link

Filesize #9

Open mattdesl opened 3 years ago

mattdesl commented 3 years ago

Hey Lieff, thanks for this library and minimp4, I'm compiling them to WASM for the web here using Emscripten and it's working well.

Something that came up is a filesize concern. I did a quick test with 30 1920x1080 frames of Big Buck Bunny and the resulting MP4 is 11MB (gop=20, speed=0, qp_min=10, qp_max=10). But, using that output MP4, running default ffmpeg -i vid.mp4 vid2.mp4 produces a 181KB file. Is there something I might be doing wrong in minih264 that would produce such high file sizes compared to ffmpeg's default encoders?

lieff commented 3 years ago

Hi)

May be it's just bit-rate setting issue. Can you attach sample 11MB file? I will check the compression ratio of ffmpeg result and the original.

mattdesl commented 3 years ago

Here's a link to the file: https://drive.google.com/file/d/14LsSdtVxrxzvc09oNo74OcZutMCcJI7D/view?usp=sharing

I think you are right, I'm just testing a few more options (changing qp_min and qp_max, and desired_frame_bytes, vbv_size_bytes) and I'm able to get it down to ~2 MB with your libraries without a huge quality loss. I'm not entirely sure how to go about setting these flags though, do you have any suggestions that might be sorta similar to "fast" / "slow" profiles?

lieff commented 3 years ago

Yep, looks like it.

ffmpeg -i minih264-output.mp4 minih264-ffmpeg.mp4 gives 770kb on my side or 6849 kbps.

With h264enc_x64 -kbps6849 minih264_1920x1080.yuv out.264 I'm able to produce comparable size. But quality is much worse. Issue here is vbv buffer size, rate control gives much less bits for intra frame than ffmpeg.

So I adjust vbv buffer size to 2 seconds based on kbps:

    create_param.vbv_size_bytes = cmdline->kbps*1000/8*2; // 2 seconds vbv buffer for quality, so rate control can allocate more bits for intra frame

And now quality is comparable.

Other things to adjust for performance/quality is run_param.encode_speed and create_param.temporal_denoise_flag. qp_min-qp_max range 10-51 is max supported range, so rate control can set any possible quantizer (lower is better). You can also adjust this range to change minimum and maximum quality, but then not all values available to rate control. And vbv overflow or underflow can happen in more scenarios.