It is well worth running a deinterlacing video filter during your video encode and this may very well lessen some of the odd screen effects that you are seeing in your output video. A second thought, unrelated to motion artefact but well worth adding in, is the use of a de-noising filter.
1. Deinterlacing:
For FFmpeg the best and fastest choice is yadif
which in the usual quirky geek fashion simply stands for 'Yet Another DeInterlacing Filter'!
yadif
can be used with no options or you can specify an option for each of 3 fields:
- mode: The basic interlacing mode to adopt
- parity: The picture field parity assumed for the input interlaced video
- deint: Specify which frames to deinterlace
The safe defaults can be specified on the FFmpeg command line as:
-vf yadif=0:-1:0
If you wish to alter these all of the deeper detail is contained here:
FFmpeg Filter Documentation: yadif
https://ffmpeg.org/ffmpeg-filters.html#yadif-1
A further deinterlacing filter called mcdeint
(motion-compensation deinterlacing) can also be applied but you may find this painfully slow. A typical command line for use of this filter would be:
-vf yadif=1:-1:0,mcdeint=2:1:10
And again the fine detail of the mcdeint
options can be seen in the FFmpeg documentation:
FFmpeg Filter Documentation: mcdeint
https://ffmpeg.org/ffmpeg-filters.html#mcdeint
2. Denoising:
A final though that may well be worth some experimentation is the use of a denoising filter, although this should not effect motion artefact it is still a well worth addition. Under FFmpeg there are a few choices but one well worth looking at is nlmeans
(denoise frames using Non-Local Means algorithm). You will need the very latest FFmpeg for this one.
To use this in the easiest command line try the following:
-vf yadif=0:-1:0,nlmeans
There is a hit with nlmeans
in terms of encoding time, not as severe a penalty as is seen with mcdeint
but still a consideration...
If you have an older copy of FFmpeg with no access to this newest filter there is an older denoise filter that can safely be used with trust in the sane defaults:
-vf yadif=0:-1:0,hqdn3d
I note on my own system that hqdn3d
is very, very much faster than the newer nlmeans
. Better? Well I suspect that is a debate for another forum :)
And hopefully a combination of any of these thoughts will solve your problem...
References:
If you have an appropriately configured modern version of FFmpeg and x265, (the repository FFmpeg under Zesty Zapus 17.04 falls into this category), you should find encoding with 8, 10 and 12bit fairly straightforward.
I illustrate a sample command line for each below:
1. 8bit HEVC encoding with FFmpeg...
Check the capability of your installed version of x265 for 8bit encoding as follows:
andrew@illium~$ x265 -V
x265 [info]: HEVC encoder version 2.4
x265 [info]: build info [Linux][GCC 7.1.0][64 bit] 8bit+10bit+12bit
x265 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX XOP FMA4 FMA3 LZCNT BMI1
andrew@illium~$
Here you will see that my own copy has capabilities for 8|10|12 bit encoding. An installation of FFmpeg compiled against this version of x265 can produce a decent 8bit encode with the following command:
ffmpeg -i input.mp4 \
-c:v libx265 -preset medium -crf 28 -pix_fmt yuv420p \
-c:a aac -b:a 128k \
output_8bit.mp4
You can of course vary any of these settings to suit your specific needs...
2. 10bit HEVC encoding with FFmpeg...
Check the capability of your installed version of x265 for 10bit encoding as follows:
andrew@illium~$ x265 -V -D10
x265 [info]: HEVC encoder version 2.4
x265 [info]: build info [Linux][GCC 7.1.0][64 bit] 10bit
x265 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX XOP FMA4 FMA3 LZCNT BMI1
andrew@illium~$
Here you will see that my own copy has capabilities for 10 bit encoding. An installation of FFmpeg compiled against this version of x265 can produce a decent 10bit encode with the following command:
ffmpeg -i input.mp4 \
-c:v libx265 -preset medium -crf 28 -pix_fmt yuv420p10le \
-c:a aac -b:a 128k \
output_10bit.mp4
And this should see you through...
3. 12bit HEVC encoding with FFmpeg...
Check the capability of your installed version of x265 for 12bit encoding as follows:
andrew@illium~$ x265 -V -D12
x265 [info]: HEVC encoder version 2.4
x265 [info]: build info [Linux][GCC 7.1.0][64 bit] 12bit
x265 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX XOP FMA4 FMA3 LZCNT BMI1
andrew@illium~$
Here you will see that my own copy has capabilities for 12bit encoding. An installation of FFmpeg compiled against this version of x265 can produce a decent 12bit encode with the following command:
ffmpeg -i input.mp4 \
-c:v libx265 -preset medium -crf 28 -pix_fmt yuv420p12le \
-c:a aac -b:a 128k \
output_12bit.mp4
Once again experimentation with some of the ancillary parameters should give you exactly the results you are after...
Notes:
If you are unsure of which pixel formats (for the vital -pix_fmt
FFmpeg setting) are supported by your copy of FFmpeg and libx265 the following command will show the details:
ffmpeg -h encoder=libx265 2>/dev/null | grep pixel
FFmpeg and H.265 Encoding Guide: Base information on HEVC encoding with FFmpeg, nothing on 8|10|12 bit encoding though...
Zesty Zapus (17.04) has a slightly older but fully configured x265:
andrew@ilium:~$ x265 -V
x265 [info]: HEVC encoder version 2.3
x265 [info]: build info [Linux][GCC 6.3.0][64 bit] 8bit+10bit+12bit
x265 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX LZCNT
andrew@ilium:~$
and thus can encode to all 3 possible bit depths...
Best Answer
Thanks for the info about order of options @bodhi.zazen and @LordNeckbeard. Apparently the libvpx encoder is a little more picky about that. When I added -threads option after -c:v libvpx, it visibly uses more cores according to top.
-threads 0 only uses 1 core, -threads 8 uses 2 cores, and -threads 16 uses 4 cores. I've tried using a higher number, but the encoder says more than 16 threads is not recommended, and doesn't use any more CPU. Encoding speed itself is about twice as fast now. Thanks again for the help!