FFmpeg VP9 - Different Quantisation Parameters but same output files - encoding

I want to encode a video with vp9 with different quantisation parameters (qp=[16,20,24,28,32]). Unfortunately the output files have the same data rate after encoding and don't show any quality differences.
This is my code for qp=20:
ffmpeg -s:v 3840x1920 -framerate 30 -i video_3840x1920_30fps_8bit_420_erp.yuv -c:v libvpx-vp9 -qp 20 -f avi out.avi
Many thanks for any pointers you can give me.

-qp only works for internal mpegvideoenc-derived encoders, such as FFmpeg's built-in MPEG-1/2/4 encoders. Libvpx, like x264/5, uses -crf to do this instead. See the Wiki for more details. You can also type ffmpeg -h encoder=libvpx-vp9:
$ ffmpeg -h encoder=libvpx-vp9
[..]
-crf <int> E..V.... Select the quality for constant quality mode (from -1 to 63) (default -1)
So for qp=20, you would use ffmpeg -s:v 3840x1920 -framerate 30 -i video_3840x1920_30fps_8bit_420_erp.yuv -c:v libvpx-vp9 -crf 20 -b:v 0 out.avi.

Related

ffmpeg monochrome rawvideo

I am trying to generate a raw video stream with luma only (monochrome, YUV400) 8bit pixel data using the following command:
ffmpeg -i input.mp4 -vcodec rawvideo -pix_fmt raw.yuv
After that I want to h.264 encode the raw stream with the profiles that support monochrome pixel data (eg: high)
ffmpeg -f rawvideo -vcodec rawvideo -pix_fmt gray -s 640x512 -r 60 -i raw.yuv -codec:v libx264 -profile:v high -c:a copy out.mp4
However, i always get the following error, which indicates that the raw stream is not in the monochrome format that I expected:
x264 [error]: high profile doesn't support 4:4:4
I am new to ffmpeg and video formats in general. Can somebody please point out what I am missing?
Thank you!
Edit:
I also tried to use the following filter to extract only the luma channel. Unfortunately, the end result was the same.
ffmpeg -i input.mp4 -vcodec rawvideo -pix_fmt gray -filter_complex 'extractplanes=y[y]' -map '[y]' raw.yuv
The ffmpeg version installed was quite old (3.4.7). After installing 4.2.3 everything worked fine.

Streaming from Icecast to Facebook Live with ffmpeg on Ubuntu 16.04

I have a webradio streamed by Liquidsoap+Icecast on a DigitalOcean droplet (Ubuntu 16.04), and I want to combine this audio stream with a simple jpeg image with ffmpeg, transform it to a video stream and send it to Facebook live.
Facebook Live specifications :
Video Format :
We accept video in maximum 720p (1280 x 720) resolution, at 30 frames
per second. (or 1 key frame every 2 seconds). You must send an I-frame
(keyframe) at least once every two seconds throughout the stream..
Recommended max bit rate is 4000 Kbps. Titles must be less than 255
characters otherwise the stream will fail. The Live API accepts H264
encoded video and AAC encoded audio only.
Video Length :
240 minute maximum length, with the exception of continuous live (see
above). 240 minute maximum length for preview streams (either through
Live dialog or publisher tools). After 240 minutes, a new stream key
must be generated.
Advanced Settings :
Pixel Aspect Ratio: Square. Frame Types: Progressive Scan. Audio
Sample Rate: 44.1 KHz. Audio Bitrate: 128 Kbps stereo. Bitrate
Encoding: CBR.
And the ffmpeg command I tried :
ffmpeg -loop 1 -i radio-background.jpg -thread_queue_size 20480 -i http://localhost:8000/radio -framerate 30 -r 30 -acodec aac -strict -2 -c:v libx264 -strict experimental -b:a 128k -pix_fmt yuvj444p -x264-params keyint=60 -b:v 256k -minrate 128k -maxrate 512k -bufsize 768k -f flv 'rtmp://rtmp-api.facebook.com:80/rtmp/<fb-streaming-key>'
This is actually working, as Facebook receives the live video and allows me to publish it. But I can't figured out why there is a lag almost every 2 or 3 seconds. I asked different people to watch the test video, and everyone gets the same problem : every 2 or 3 seconds the playing "freezes" for half a second and seems to load the video, I even can see the loading icon spinning on the screen.
I tried different combinations of values for the following options : -thread_queue_size / -b:v / -minrate / -maxrate / -bufsize. Nothing seems to produce any change.
Video streaming is new for me, I'm not really confortable with the options listed before, so I think I'm missing something here...
Also, note that the icecast audio stream perfectly works, and according to DigitalOcean graphs, the server is not overloaded. So I think my ffmpeg command is wrong.
What ffmpeg parameters would be working for that case?
specify a frame rate for the image. this would go before the input item.
-r 30 -loop 1 -i radio-background.jpg
if your radio stream is is already aac you can just stream copy, there is no need to re-encode the audio. you can use -c:a copy.
-c:a copy
if you still want to use aac you should switch to using libfdk_aac. ffmpeg by default uses 128k bitrate for audio so there is no need to specify -b:a
-c:a libfdk_aac
ffmpeg will use the input framerate of the first item for the output by default so you dont need to specify anymore frame rates. (you have the output frame rate specified twice. -framerate 30 and -r 30 are the same)
ultrafast preset for better CPU performance, tune, and pixel format. you can also use -g for the keyent.
-c:v h264 -preset ultrafast -tune stillimage -pix_fmt yuvj444p -g 60
set the profile and profile level, bframes
-profile:v high444 -level 4.2
use either -b:v or -minrate -maxrate -bufsize but not both.
-b:v 768k
and out we go
-f flv rtmp://rtmp-api.facebook.com:80/rtmp/streamkey
now to put it all together
ffmpeg -r 30 -loop 1 -i radio-background.jpg \
-i http://localhost:port/mount -c:a libfdk_aac -c:v h264 -b:v 768k \
-preset ultrafast -tune stillimage -pix_fmt yuvj444p -g 60 \
-profile:v high444 -level 4.2 -f flv rtmp://rtmp-api.facebook.com:80/rtmp/streamkey

Encoding 25mp video

I have a 25MP uncompressed video file of 100 frames.
I tried to encode it with ffmpeg and h264 encoder into a .mp4 file, but the encoding got stuck around the 10th frame.
This is the script:
avconv -y -i input.avi -c:v libx264 -preset medium -b:v 5000K -pass 1 -c:a libfdk_aac -b:a 5000K -f mp4 /dev/null && \
avconv -i input.avi -c:v libx264 -preset medium -b:v 5000K -pass 2 -c:a libfdk_aac -b:a 5000K output.mp4
I am running it on a jetson TK1 with nvidia gpu, is there any way to use an accelarating encoding in order to make the encoding possible?
Please, if you can, give me a sampler script of something that might work.
Right now, I dont care how much time the encoding take, as long as it will work.
Thank you in advance! :)

Dividing, processing and merging files with ffmpeg

I am trying to build an application that will divide an input video file (usually mp4) into chunks so that I can apply some processing to them concurrently and then merge them back into a single file.
To do this, I have outlined 4 steps:
Forcing keyframes at specific intervals so to make sure that each
chunk can be played on its own. For this I am using the following
command:
ffmpeg -i input.mp4 -force_key_frames
"expr:gte(t,n_forced*chunk_length)" keyframed.mp4
where chunk_length is the duration of each chunk.
Dividing keyframed.mp4 into multiple chunks.
Here is where I have my problem. I am using the following command:
`ffmpeg -i keyframed.mp4 -ss 00:00:00 -t chunk_length -vcodec copy -acodec copy test1.mp4`
to get the first chunk from my keyframed file but it isn't capturing
the output correctly, since it appears to miss the first keyframe.
On other chunks, the duration of the output is also sometimes
slightly less than chunk_length, even though I am always using the
same -t chunk_length option
Processing each chunk For this task, I am using the following
commands:
ffmpeg -y -i INPUT_FILE -threads 1 -pass 1 -s 1280x720 -preset
medium -vprofile baseline -c:v libx264 -level 3.0 -vf
"format=yuv420p" -b:v 2000k -maxrate:v 2688k -bufsize:v 2688k -r 25
-g 25 -keyint_min 50 -x264opts "keyint=50:min-keyint=50:no-scenecut" -an -f mp4 -movflags faststart /dev/null
ffmpeg -y -i INPUT_FILE -threads 1 -pass 2 -s 1280x720 -preset
medium -vprofile baseline -c:v libx264 -level 3.0 -vf
"format=yuv420p" -b:v 2000k -maxrate:v 2688k -bufsize:v 2688k -r 25
-g 25 -keyint_min 50 -x264opts "keyint=50:min-keyint=50:no-scenecut" -acodec libfaac -ac 2 -ar 48000 -ab 128k -f mp4 -movflags faststart OUTPUT_FILE.mp4
This commands are not allowed to be modified, since my goal here is
to parallelize this process.
Finally, to merge the files I am using concat and a list of the
outputs of the 2nd step, as follows:
ffmpeg -f concat -i mylist.txt -c copy final.mp4
In conclusion, I am trying to find out a way to solve the problem with step 2 and also get some opinions if there is a better way to do this.
I found a solution with the following code, which segments the file without the need to force keyframes (it cuts on the nearest keyframe) and multiple commands.
ffmpeg -i test.mp4 -f segment -segment_time chunk_length -reset_timestamps 1 -c copy test%02d.mp4

ffmpeg apply filters without rencoding?

I want to rotate a video using ffmpeg, but I don't want to lose quality by re-encoding.
If I try
ffmpeg -i in.mp4 -vf 'vflip,hflip' -ss 120 -t 200 -c:v copy -c:a copy out.mp4
No rotation gets preformed. If I instead specify the encoding by using, say -c:v h264, I'm afraid I'll lose some quality. Is there a "losssless" (relative to the original encoding) way of applying a filter?
Use a lossless encoder
Use of filters requires re-encoding. You can use a lossless encoder if quality is the most important factor:
ffmpeg -i in.mp4 -vf 'vflip,hflip' -ss 120 -t 200 -c:v libx264 -preset veryslow \
-crf 0 -c:a copy out.mp4
Using -crf 0 when using libx264 will create a lossless output but the file size may be very large.
Rotate upon playback
Rotating during playback will of course preserve the quality:
ffplay input.mp4 -vf hflip,vflip
Also see
FFmpeg and x264 Encoding Guide
How to flip a video 180° (vertical/upside down) with FFmpeg?