FFMPEG fast quality video encoding without quality loss & less storage occupancy (maybe using GPU)

52 Views Asked by At

I Have written a go code but it is slow and the video compression rate is also not that impressive. I am new to FFMPEG and my entire project depends on FFMPEG. I have tried different video codecs like vp9, h264, h265, NVENC, AV1, etc. All of them were too slow (maybe I am not good enough to optimize it). My project is based on Go and the current codec that I am using is libx264. Can anyone help me optimize the video encoding part of my project.

Libx264:

func encodeVideo(fileName, bitrate, crf, preset, resolution string) *exec.Cmd {
    return exec.Command("C:\\ffmpeg-6.1-full_build\\bin\\ffmpeg",
        "-i", "./userUploadDatas/videos/"+fileName,
        "-c:v", "libx264",
        "-b:v", bitrate,
        "-crf", crf,
        "-preset", preset,
        "-vf", "scale="+resolution,
        "./userUploadDatas/videos/"+fileName+"_encoded"+".mp4")
}

Please provide static value of each parameters. Any codec will work for me as long as it is fast, occupies less space & doesn't loose spaces.

The problems I have faces with different codecs are:

  1. NVENC: Fast but the size of video is doubled & loss of video quality.
  2. libx264: Best I can find currently, but is slow.
  3. h264, h265: Occupies more space
  4. Av1 & vp9: Was too slow and wasn't able to encode 30sec video in 1hrs.

The specs of hardware that I am using is Ryzen7 5000 series CPU, NVIDIA RTX 3050 Ti Laptop GPU.

1

There are 1 best solutions below

0
galabov On

How much a video can be compressed while preserving quality depends highly on the target video's compression, codec, pixel format, etc. You can measure the bit rate against a video quality metric to determine if the transcoded videos meet your expectation.

  • in order to measure the perceived quality of the video, you can use Netflix's VMAF that also supports PSNR and SSIM, and is available for ffmpeg through the libvmaf lib (CUDA implementation is also available).
  • in my experience, 95% and above VMAF score is perceptually lossless

As an example you can see in the graph a showcase of the relation: bit rate to quality for transcoding an H.264, YUV420, 8bit video to AV1 with av1_nvenc. The used script executed on Nvidia RTX 4090, Architecture: Ada Lovelace is:

for cq in {0..50}; do ffmpeg -y -hwaccel cuda -hwaccel_output_format cuda -i xyz.mkv -c:a copy -c:v av1_nvenc -preset p7 -tune hq -cq:v $cq -rc-lookahead 53 xyz.cq${cq}.mp4; done
  • always define a target quality level (in this case -cq, my personal preference for this script is 30), otherwise the results are unpredictable
  • use a high quality preset as you want to preserve quality
  • you can also set -qmin and -qmax to the same value as -cq, but the file might get larger with little benefit for quality
  • some videos will get nicely compressed to a smaller file size, some will get bigger than the original video, guessing does not work, so it's better to run the transcoder and see the results.
  • H.264, H.265 and AV1 have both software and hardware implementations/integrations for ffmpeg, and always a hardware transcoder will be faster than it's software counterpart.
  • if you run VMAF, always specify the frame rate -r for the original and distorted video, otherwise you may have a mismatch (frames that have a rating of 0), therefore you'll get way worse results than they actually are