I'm trying to perform a real-time encoding of a video using HEVC with ffmpeg. I'm able to achieve the required performance when running the x265 encoder separately without the support of ffmpeg. This way the my system can perform the encoding at 30 frames per second. However, my requirement is to create a MPEG-TS stream with the encoded content and therefore, the video is encoded with the ffmpeg as follows:
ffmpeg -s:v 1280x720 -i input.yuv -c:v libx265 -x265-params crf=20:keyint=25:fps=25:preset=ultrafast -f mpegts out.ts
Strangely, the performance of the encoding is reduced drastically and I'm only able to achieve an encoding performance of just 10 frames per second.
Is this a problem of the multiplexing process within ffmpeg?. Could someone please help me to resolve this issue.
Thanks.
This is can be a reason q factor in FFmpeg. You need to compare q value of FFmpeg and x265 bin. This is my guess.
Related
I tried to encode a series of png files into a HEVC codec video with ffmpeg (version modern enough) in these parameters:
ffmpeg -hwaccel cuda -r 60000/1001 -f image2 -i output%05d.png -c:v hevc_nvenc -preset slow -profile:v main10 -level 6.2 -pix_fmt yuv444p16le output.mkv
Then I got a mkv video file and I found that it cannot be decoded with DXV2 but with LAV Decoder, which takes up really lot of my CPU. However, I also found that the other HEVC codec video file, which has similar property of my video, can be decoded with DXV2 Decoder using my GPU. Could anyone help me find a way that, make a HEVC codec video can be decoded using GPU? Thanks a lot.
I'm going to guess your issue is with -pix_fmt yuv444p16le. I don't know what format your PNG is, but it's typically 8-bits/component RGB. You're upsampling it to 16-bits/component 4:4:4 YUV and then using that as input to the HEVC encoder at whatever is its closest-supported neighbour (10-bits/component YUV-4:4:4, according to comments in the source code).
4:4:4 is sometimes not supported by hardware decoders (see here). Also see this quote from here:
Many existing end-client devices/GPUs/SoC support hardware decode 4:2:0 but not 4:4:4 and whilst newer hardware and GPUs are introducing 4:4:4 decoders many existing devices only support 4:2:0 decode.
I would try -pix_fmt p010le, which should result in YUV-4:2:0 10-bits/component, which should work fine with all hardware decoders.
Whenever I use the ffmpeg commands, the video is larger and the seeking/keyframe inteval is not the same as the video rendered from Blender. How can I convert the following Blender settings to ffmpeg please?
Blender Settings:
Frame rate: 30
Codec: h.264
Output .mp4
Keyframe interval: 1
Output quality: Medium
Encoding speed: Good
Here's my current command however the seeking and file size is different:
ffmpeg -framerate 30 -i %04d.jpg -g 1 -vcodec libx264 video.mp4
ffmpeg -r 30 -i %04d.jpg -vcodec libx264 -crf 25 -x264-params keyint=30:scenecut=0 -preset veryslow video.mp4
Explanation:
-r 30 befor input pictures will say ffmpeg to use 30 pictures per second
-vcodec libx264 will let ffmpeg encode in plain old H.264
-crf 25 will let the encoder decide on the bitrate for a medium quality (lower it for better quality / higher file size, increase it for worse quality / lower file size. Need to find your right setting there through testing)
-x264-params keyint=30:scenecut=0 will tell the x264 encoder to set a keyframe every 30s frames (here 1s) and to disable scene detection. Be aware that this increases the file size a lot, you should not use a keyframe every second, except for livestreaming. Modern video encoders like AV1 will at most times set a keyframe every 10-20s based on scene detection.
-preset veryslow will use the best libx264 preset available to make the file as small as possible with H.264 (however needs more time to encode). If you want a faster encode but a larger file set it to slow.
Some general opinions from me:
If you don't need compatibility to very old devices rather encode with libx265 or 2-pass libvpx-vp9. This will save you a lot of space without quality loss. libx265 slow is even faster then libx264 veryslow for me.
I'm using FFmpeg with Directshow input. The output is a series of single JPEG images. FFmpeg itself maps the stream to mjpeg and uses image2 for the output.
Is it possible to increase performance by using the Intel QuickSync Video (QSV) hardware acceleration for this process? The FFmpeg QuickSync Wiki actually lists JPEG encoding since Braswell.
This is what I tried so far:
ffmpeg -init_hw_device qsv=hw -filter_hw_device hw -f dshow -video_size 3840x2160 -framerate 25 -i "video=My Webcam" -vf hwupload=extra_hw_frames=64,format=qsv -vcodec mjpeg_qsv "C:\out\%d.jpg"
The command works, images are generated - but the GPU load seems to be the same as without any qsv options..?
Thanks!
I compared it for a h264 encoded video. First with the QSV jpeg encoder:
ffmpeg -c:v h264_qsv -i myvideo.mkv -vcodec mjpeg_qsv images/%06d.jpg
and afterwards without mjpeg_qsv:
ffmpeg -c:v h264_qsv -i myvideo.mkv images/%06d.jpg
The example is minimalistic and can be improved in many ways. In the picture you can see the load of the GPU. In the red box with mjpeg_qsv and the blue box without mjpeg_qsv. The execution time was also better with mjpeg_qsv, speed=3.34x vs speed=1.84x. Since you are using your webcam as an source, your pipeline is limited by the frame rate of the live video. So, your hardware will only process 25 frames per second (-framerate 25). Depending on the resolution and your hardware, this might be an easy job for your GPU, in both cases. Also, make sure you look for the Intel GPU and not your Nvidia/AMD GPU. If you still have the impression that you can't see a performance gain, please let us know both of your commands for comparison.
I have a series of JPEG images named 0000.jpg 0001.jpg 0002.jpg...
I used the following command to turn these into a slideshow video, each frame playing for 1 second.
ffmpeg -framerate 1 -i %04d.jpg -c:v libx264 -vf fps=1 -pix_fmt yuv420p out.mp4
This works fine except that the resulting video is 6x larger than what I get if I encode the exact same frames at normal framerate (e.g. 25 FPS)
I'm looking for a way to effectively get the same efficient encoding as when encoding 25fps but with each frame showing for 1 second.
H.264 is a video codec that is inter-coded i.e. frames rely on other frames in order to get decoded. What x264, a H.264 encoder, does, at a basic level, is observe the changes in the picture content between frames and then save only that difference.
In the CRF ratecontrol mode, which is what's used by default when no rate control mode is expressly specified (-b:v, -crf, -x264opts qp), x264 is sensitive to framerate. When given an input at 25 fps, each frame is displayed for 40 milliseconds, so the viewer isn't that sensitive to image quality of each individual frame, so x264 compresses it quite a bit. But when that input is encoded at 1 fps, each output frame will be on display for a whole second, so x264 is much less aggressive with its compression.
The workaround is to encode at 25 fps and then remux at the lower fps.
#1
ffmpeg -framerate 25 -i %04d.jpg -c:v libx264 -pix_fmt yuv420p out.264
#2 Using mp4box*, part of GPAC, remux with the lower rate:
mp4box -add out.264:fps=1 -new out.mp4
*normally, this would be possible using ffmpeg, but it does not correctly remux H.264 raw streams with out-of-order frame storage i.e. those with B-frames.
I need convert MP4 to webm with ffmpeg.
So, i use :
ffmpeg -i input.mp4 -c:v libvpx -crf 10 -b:v 1M -c:a libvorbis output.webm
But it's very long.
Is there faster ?
libvpx is a relatively slow encoder. According to the VP8 Encode Parameter Guide: Encode Quality vs. Speed, you can use the -cpu-used option to increase encoding speed. A higher value results in faster encoding but lower quality:
Setting a value of 0 will give the best quality output but is
extremely slow. Using 1 (default) or 2 will give further significant
boosts to encode speed, but will start to have a more noticeable
impact on quality and may also start to effect the accuracy of the
data rate control. Setting a value of 4 or 5 will turn off "rate
distortion optimisation" which has a big impact on quality, but also
greatly speeds up the encoder.
Alternatively, it appears that VA-API can be utilized for hardware accelerated VP8 encoding, but I have no experience with this.