This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

A cookie will be stored in your browser regardless of choice to prevent you being asked this question again. You will be able to change your cookie settings at any time using the link in the footer.

[HELP] FFmpeg x264 not fully utilizing the CPU
#1
Hello!

I use FFmpeg to create videos from one image and an Opus audio file. The expected outcome is a video that contains the given image at a rate of 4-6 FPS (manually selected) and the audio file; of course, the video should be as long as the audio track is - not longer, not shorter (as far as possible).

My workload sometimes requires me to process up to 100 audio files at once, so, since my CPU has 12 threads, I'd like all of them to be utilized, so I could finish the queue faster. Only problem is FFmpeg does not utilize more than 2 threads and cannot render faster than 12-18 FPS (~3x faster than real-time, no matter the settings).

At some point, I needed Hybrid for some workload, so I gave that a try. Importing the pre-rendered by FFmpeg video into Hybrid and re-encoding it yields 25x real-time encoding times and the CPU being utilized to 90%. Seeing this, I tried using Hybrid's FFmpeg version to process my workload, but the thread count did not rise.

My command is:
ffmpeg -loop 1 -i image -threads 18 -i audio.opus -c:v libx264 -crf:v 23 -preset ultrafast -strict -2 -r 6 -c:a copy -shortest audio_name.mkv

Any help would be appreciated!

P.S.: I have a program that applies the command to a batch of files, hence the simple command.
Reply
#2
Why not simply use a mkv with a cover instead of the video stream?
Why the 6 fps, i mean when using just one image the fps should matter?
Why are you using crf ?
Why the '-scrict -2' ?
Also your encoding will probably be (a lot) faster if you specify the '-r 6' before the "-i image".
How fast is:
ffmpeg -y -loop 1 -r 6 -i <path to image> -i <path to audio> -c:v libx264 -q:v 23 -preset ultrafast -c:a copy -shortest <path to output>
for you?
(Also if you have an nvida cpu or intel cpu with a graphic processor you might want to use nvenc or qsvenc instead of x264)

Cu Selur

Ps.: your goal shouldn't be a higher cpu utilization, but higher speed. Since you basically tell the encoder to do nothing it's to be expected that the cpu utilization isn't high.
Reply
#3
(28.05.2021, 23:07)Selur Wrote: Why not simply use a mkv with a cover instead of the video stream?

Not sure what you mean by that. I believe an mkv with a cover would mean an empty video inside the mkv, just some cover and the audio? Well, the video needs to have the picture displayed constantly while the video is played back, so just a cover won't do.

(28.05.2021, 23:07)Selur Wrote: Why the 6 fps, i mean when using just one image the fps should matter?

Because I don't want the videos taking a lot of space and by letting FFmpeg render at 25 FPS it really increases the video size, especially when working with hundreds of videos at a time.

(28.05.2021, 23:07)Selur Wrote: Why are you using crf ?

Seeing as you replaced it with "q", I guess I've never seen it used in FFmpeg commands before. I read this and tested the answer. It was true: the argument "q" gets ignored in libx264.

(28.05.2021, 23:07)Selur Wrote: Why the '-scrict -2' ?

I think it was necessary for muxing Opus in .mp4 format. I used to use .mp4, but have since changed to .mkv, but the -strict -2 argument remained.

(28.05.2021, 23:07)Selur Wrote: Also your encoding will probably be (a lot) faster if you specify the '-r 6' before the "-i image".
How fast is:
ffmpeg -y -loop 1 -r 6 -i <path to image> -i <path to audio> -c:v libx264 -q:v 23 -preset ultrafast -c:a copy -shortest <path to output>
for you?

It is up to 13x faster than real-time, considerably faster than the max 3.5x I had before. The threads are still not used, not sure if that's such a problem anymore. If possible, I'd still like them used.

(28.05.2021, 23:07)Selur Wrote: (Also if you have an nvida cpu or intel cpu with a graphic processor you might want to use nvenc or qsvenc instead of x264)

I do have both of those, but NVENC has really poor quality at the beggining of the video, from what I have tested. I have not tested qsvenc, not sure what that codec is for or how it's used.

(28.05.2021, 23:07)Selur Wrote: Ps.: your goal shouldn't be a higher cpu utilization, but higher speed. Since you basically tell the encoder to do nothing it's to be expected that the cpu utilization isn't high.

Well, that's pretty much my final goal, but the fact that the cores were not utilized at full potential really struck me, even after the -threads argument.


Are there any consequences to using the command like this? I, for one, didn't notice them, but I must say I didn't analyze the output files very thoroughly. All I saw was the files were small and the quality was not terrible.


Also, sorry for the late reply. I must have not subscribed correctly to the thread.
Reply
#4
Quote:Seeing as you replaced it with "q", I guess I've never seen it used in FFmpeg commands before. I read this and tested the answer. It was true: the argument "q" gets ignored in libx264.
Needs to be probably cq or qp then.
Quote:Not sure what you mean by that. I believe an mkv with a cover would mean an empty video inside the mkv, just some cover and the audio? Well, the video needs to have the picture displayed constantly while the video is played back, so just a cover won't do.
Confused. Why is there a delay if you only use one image?
Quote:If possible, I'd still like them used.
try changing the threads in the x264 options, but my guess is that there is simply not much to do for motion estimation etc. if the input doesn't change.
Probably better simply run multiple encodes in parallel.

Cu Selur
Reply
#5
(01.06.2021, 05:46)Selur Wrote: Needs to be probably cq or qp then.

Yeah, I just searched for it online. It is indeed "qp" and in this case we're talking about constant quantizer. I also found out that CRF is just motion variable QP - interesting stuff.

I tried a command with -qp 23 and it got up to 15x faster than real-time.

(01.06.2021, 05:46)Selur Wrote: Confused. Why is there a delay if you only use one image?

Uhh... I wasn't talking about a delay, I was just not sure what you meant by "cover". Please explain more thoroughly, as I'm not familiar with the concept you're talking about.

Do you mean 1 frame throughout the whole video? If that's what it is, that would be great; but I do not know how to do that.

(01.06.2021, 05:46)Selur Wrote: try changing the threads in the x264 options, but my guess is that there is simply not much to do for motion estimation etc. if the input doesn't change.

Not exactly sure what you mean by "x264 options", but if you mean something like "libx264 -threads 18", that doesn't work.

(01.06.2021, 05:46)Selur Wrote: Probably better simply run multiple encodes in parallel.

Yeah, that would also be a solution. Only thing is my program cannot run encodes in parallel and running multiple instances of that program is a pain.

So I'd have to implement some kind of parallel processing in this case.
Reply
#6
mkv with cover = mkv file which container an image that most players will display if there isn't a video stream.
see: https://www.matroska.org/technical/attachments.html

Quote:I tried a command with -qp 23 and it got up to 15x faster than real-time.
If there's no motion crf is the wrong choice. Smile

Quote:Not exactly sure what you mean by "x264 options", but if you mean something like "libx264 -threads 18", that doesn't work.
-c:v libx264 -x264opts  ....
https://ffmpeg.org/ffmpeg-codecs.html#Options-31

Cu Selur
Reply
#7
(01.06.2021, 19:39)Selur Wrote: mkv with cover = mkv file which container an image that most players will display if there isn't a video stream.
see: https://www.matroska.org/technical/attachments.html

Tried it and it is indeed a very efficient way of doing this. It's not accepted, however, by YouTube, where these videos would get uploaded to.

(01.06.2021, 19:39)Selur Wrote:
-c:v libx264 -x264optsĀ  ....
https://ffmpeg.org/ffmpeg-codecs.html#Options-31

Didn't work. Also tried using "-x264-params"; that didn't work either. So it's probably the lack of things to process in my case.

Thank you for helping me speed up the process! It will definitely improve the time taken for the workloads to finish by quite a margin, even without the threads.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)