geometer
24th December 2015, 02:53
To me it seems, that convolution is rarely mentioned, but I found it remarkably powerful for my needs, when I archive DVDs in h264 format.
I would like to share a case study here, to make customized convolution more popular. The GeneralConvolution filter runs in AviSynth, therefor I post it here.
Source material: DVD, NTSC 720x480, mostly interlaced 29.97 fps. Video, not film.
Target: h264 mp4, optionally upsampled to 960x640.
Main technique in this topic is convolution, the primary filtering chain runs in AviSynth.
I will share some asymmetric matrices (kernels) in the script below.
(I also included a code example, for to try out a short sequence of the source with various different kernels.
Probably, only one or two of those will work well, when we are interested in subtle quality.)
This is then embedded in a secondary filtering chain in AviDemux, for its simplicity to adjust parameters.
The chain is constructed so, that it becomes easy to correct typical flaws, plus - which is important part of the case study -
in the complete chain, there is a complex attempt to achieve some synergy with the encoder.
------
In the secondary chain, AviDemux, the following techniques have been added:
- Upsampling, at first to a ~1600x960, on that level we do
-- general sharpening and color sharpening (effectively, we get a smaller sharpening radius, doing it here.)
-- color shift corrections on subpixel level
-- color and contrast corrections
- Final upsampling domain is 960x640, to mitigate influence by the brickwalling filters of the various players, that may not be optimals for CPU speed reasons.
- A final convolutional sharpener (preset of AviDemux), but it should obviously be deleted in case the result looks oversharpened.
- A preset for the x264 encoder is included here, that has been adapted to this project.
Naturally, we can omit the secondary chain and just crop (as the asymmetric matrix will shift the picture and there are borders added for this), and encode directly.
But I recommend to check the special synergies with the full chain.
Result discusson:
I found that without additional work, a direct transcode seems to look a bit blurred, even though a high bitrate is allocated.
There is a convolutional sharpener in AviDemux that is used additionally, but it can't be customized.
What the customized matrix does, is a combined set of adjustments, that were checked out heuristically with hundreds of trial/error attempts.
- we use the 5x5 matrix in an asymmetric way, so this yields us 4 coefficient taps in the filtering, which is a lot more precision than the usual 3x3 symmetric kernel.
- obviously, it does some sharpening
- "deconvolution"; in quotes, as it is done from experience, not with proper math (for we don't have the modeling data).
-- it should mitigate influences starting from the camera lense to postprocessing to encoding and reencoding steps.
- some attempts to soften deinterlacing artifacts, this combines well with the upsampling.
The encoder is being slammed with enhanced detail range, in a way that it should better recognize small structures in the picture, and treat these as moving blocks, further enhancing clarity by averaging those sharp details down to a "normal" level. Otherwise it seems, that the encoder often cannot recognize the structures from noise, as they carry mpeg2 artefacts, and it will blur them.
For the sensitivity of the analyzer on these details, plus for preserving textures, a certain optimization in the x264 encoder is being turned off.
The sum of these techniques makes the video look "different".
It will get extra clarity, smoothness, and a particular shine and gloom, that resembles pop music videos, which even works with sources that may look a bit blurred and pale.
The fine-tuning of course has influence on that "pop look".
(But to completely remove the different looks, I recommend to delete the extra color sharpener, perhaps all color and contrast filters, or even the whole secondary chain.)
So, there are two aspects in the result:
Crisp sharpness, and the smooth "pop look".
Artifacts:
Halo and ringing already in the source might increase, but quite little of such would be added, with the correct choice of the matrix, and avoiding oversharpening (controlled by the optional final sharpener at the end of the secondary chain.)
Sometimes the kernel can even cancel out certain ringing.
Please, note that in linear processing, tuned deconvolution can remove ringing, because the ringing is actually the "Gibb" phenomenon, that comes from non-ideal (finite) filtering of a rectangular signal. If we transmit a digital rectangular signal, its bandwidth must be limited beforehand, i.e. it becomes "rounded". If we don't do this, hoping that things will look sharper, then mathematics will prove us wrong and punish the results with "ringing".
Ugly pixel artifacts on 720px level will disappear, as we are using 960px density, and the resizers will round off anything such.
The "running ants" artifact of the Yadif tends to run with smaller and softer pixels, which is quite a pleasant improvement.
This article does not deal with any other techniques to remove artifacts, as it wants to use only fully linear filters.
When the postprocessing already has used too much of nonlinear filtering, that might create trouble, and need further,
nonlinear removal with techniques mentioned in the many other threads.
Scripts
Here is the AviSynth script:
(plz adjust the file paths to your needs)
LoadPlugin("F:\programs\AviSynth+\plugins\dgdecode.dll")
MPEG2Source ("F:\workdir\MyProject.d2v",cpu=0,info=2)
# delete this if source is not interlaced. caution - there are sources declared interlaced, that are not. visual check required.
Load_Stdcall_plugin("F:\programs\AviSynth+\plugins\yadif.dll")
Yadif(mode=1)
AddBorders(4,0,4,4,$7F7F7F)
#AddBorders(clip clip, int left, int top, int right, int bottom [, int color])
ConvertToRGB32(matrix="PC.709",interlaced=false,chromaresample="lanczos4")
#ConvertToRGB(clip [, string matrix] [, bool interlaced] [, string ChromaInPlacement] [, string chromaresample])
# Remarks: default in this project is PC.709 (= HDTV)
# Though DVD = PC.601 or Rec601, I use 709 always, and correct the colors in the filtering chain.
# The reason is, that too often the decoded video ends up with flawed color space anyway.
# "Rec601" : Use 601 coefficients, scaled to TV range [16,235].
# "PC.601" : Use 601 coefficients, keep full range [0,255].
# please, activate only one of the following matrices:
# roughly said, intensity and radius are increasing. differences are still subtle.
GeneralConvolution(0, "3 -4 8 -10 112 0 0 -0 -4 -15 0 0 -6 -0 15 0 0 0 0 -5 0 0 0 0 0") #C3.1
#GeneralConvolution(0, "3 -3 9 -13 112 0 0 -0 -4 -15 0 0 -6 -0 15 0 0 0 0 -5 0 0 0 0 0") #C3.2
#GeneralConvolution(0, "3 -3 10 -15 112 0 0 -0 -4 -12 0 0 -6 -0 14 0 0 0 0 -4 0 0 0 0 0") #C3.3
#GeneralConvolution(0, "2 -5 12 -20 112 0 0 -0 -4 -10 0 0 -6 -0 12 0 0 0 0 -4 0 0 0 0 0") #C3.4
#GeneralConvolution(0, "5 -13 15 -20 120 0 0 -0 -4 -10 0 0 -6 -0 12 0 0 0 0 -4 0 0 0 0 0") #a3
#GeneralConvolution(0, "5 -13 18 -21 103 0 0 -0 -4 -10 0 0 -6 -0 12 0 0 0 0 -4 0 0 0 0 0") #a2'
#GeneralConvolution(0, "2 -5 15 -20 96 0 0 -0 -6 -12 0 0 -6 -0 12 0 0 0 0 -4 0 0 0 0 0") # X7
#GeneralConvolution(0, "2 -6 15 -20 96 0 0 -0 -4 -12 0 0 -6 -0 15 0 0 0 0 -4 0 0 0 0 0") # X8
#--------------convolution tuning----
#---test start time = minutes*60 + ss.ddd #(seconds)
tpos=0*60+13
rff=29.97*2
fpos=int(tpos*rff)
#--test slice length:
tsl=int(40*rff)
/*
Trim(fpos, -tsl) + blankclip(last,5) \
+Trim(fpos, -tsl).GeneralConvolution(0, "2 -6 15 -20 96 0 0 -0 -4 -12 0 0 -6 -0 15 0 0 0 0 -4 0 0 0 0 0").subtitle("x8") + blankclip(last,15)\
+Trim(fpos, -tsl).GeneralConvolution(0, "3 -4 8 -10 112 0 0 -0 -4 -15 0 0 -6 -0 15 0 0 0 0 -5 0 0 0 0 0").subtitle("C3.1") + blankclip(last,15)\
+Trim(fpos, -tsl).GeneralConvolution(0, "3 -3 9 -13 112 0 0 -0 -4 -15 0 0 -6 -0 15 0 0 0 0 -5 0 0 0 0 0").subtitle("C3.2") + blankclip(last,15)\
+Trim(fpos, -tsl).GeneralConvolution(0, "3 -3 10 -15 112 0 0 -0 -4 -12 0 0 -6 -0 14 0 0 0 0 -4 0 0 0 0 0").subtitle("C3.3") + blankclip(last,15)\
+Trim(fpos, -tsl).GeneralConvolution(0, "2 -5 12 -20 112 0 0 -0 -4 -10 0 0 -6 -0 12 0 0 0 0 -4 0 0 0 0 0").subtitle("C3.4") + blankclip(last,15)\
+Trim(fpos, -tsl).GeneralConvolution(0, "5 -13 18 -21 103 0 0 -0 -4 -10 0 0 -6 -0 12 0 0 0 0 -4 0 0 0 0 0").subtitle("a2'") + blankclip(last,15)
*/
#Crop(clip clip, int left, int top, int -right, int -bottom, bool align)
Crop(0,2,-2,-2) # not checking this, cropping will be adjusted in the final step.
ConvertToYV12(matrix="PC.709",interlaced=false,chromaresample="lanczos4")
# this will go to AviDemux with a particular filtering chain.
Here is the AviDemux script (save as MyProject.py)
Open the AVS-Proxy channel first, then run this script.
I hope the line breaks will come out correctly..
#PY <- Needed to identify #
#--automatically built--
adm = Avidemux()
adm.loadVideo("::ADM_AVS_PROXY::")
adm.clearSegments()
adm.addSegment(0, 0, 12000000000)
adm.markerA = 0
adm.markerB = 4827930624
adm.videoCodec("x264", "useAdvancedConfiguration=True", "general.params=AQ=22", "general.threads=0"
, "general.preset=ultrafast", "general.tuning=film", "general.profile=baseline", "general.fast_decode=False", "general.zero_latency=False"
, "general.fast_first_pass=True", "level=-1", "vui.sar_height=27", "vui.sar_width=32"
, "MaxRefFrames=5", "MinIdr=25", "MaxIdr=250", "i_scenecut_threshold=40", "intra_refresh=False", "MaxBFrame=5", "i_bframe_adaptive=2"
, "i_bframe_bias=0", "i_bframe_pyramid=2", "b_deblocking_filter=True", "i_deblocking_filter_alphac0=-1"
, "i_deblocking_filter_beta=0", "cabac=True", "interlaced=False", "constrained_intra=False", "tff=True"
, "fake_interlaced=False", "analyze.b_8x8=True", "analyze.b_i4x4=True", "analyze.b_i8x8=True", "analyze.b_p8x8=False"
, "analyze.b_p16x16=True", "analyze.b_b16x16=True", "analyze.weighted_pred=2", "analyze.weighted_bipred=True"
, "analyze.direct_mv_pred=3", "analyze.chroma_offset=1", "analyze.me_method=2", "analyze.me_range=17"
, "analyze.mv_range=-1", "analyze.mv_range_thread=-1", "analyze.subpel_refine=9", "analyze.chroma_me=True"
, "analyze.mixed_references=True", "analyze.trellis=2", "analyze.psy_rd=1.100000", "analyze.psy_trellis=0.000000"
, "analyze.fast_pskip=True", "analyze.dct_decimate=True", "analyze.noise_reduction=0", "analyze.psy=True"
, "analyze.intra_luma=0", "analyze.inter_luma=0", "ratecontrol.rc_method=0", "ratecontrol.qp_constant=0"
, "ratecontrol.qp_min=4", "ratecontrol.qp_max=58", "ratecontrol.qp_step=8", "ratecontrol.bitrate=0"
, "ratecontrol.rate_tolerance=1.000000", "ratecontrol.vbv_max_bitrate=0", "ratecontrol.vbv_buffer_size=0"
, "ratecontrol.vbv_buffer_init=0", "ratecontrol.ip_factor=1.400000", "ratecontrol.pb_factor=1.400000"
, "ratecontrol.aq_mode=1", "ratecontrol.aq_strength=1.400000", "ratecontrol.mb_tree=True", "ratecontrol.lookahead=40")
adm.addVideoFilter("fluxsmooth", "temporal_threshold=17", "spatial_threshold=0")
adm.addVideoFilter("addBorder", "left=0", "right=2", "top=2", "bottom=2")
adm.addVideoFilter("swscale", "width=1600", "height=968", "algo=2", "sourceAR=2", "targetAR=2")
adm.addVideoFilter("chromashift", "u=-1", "v=-1")
adm.addVideoFilter("Sharpen", "luma=True", "chroma=True")
adm.addVideoFilter("contrast", "coef=0.900000", "offset=40", "doLuma=False", "doChromaU=False", "doChromaV=True")
adm.addVideoFilter("colorYuv", "y_gain=0.000000", "y_bright=0.000000", "y_gamma=1.900000"
, "y_contrast=15.000000", "u_gain=0.000000", "u_bright=0.000000", "u_gamma=0.000000"
, "u_contrast=12.000000", "v_gain=0.000000", "v_bright=0.000000"
, "v_gamma=0.000000", "v_contrast=0.000000", "matrix=0", "levels=0", "opt=False"
, "colorbars=0", "analyze=1", "autowhite=False", "autogain=False")
adm.addVideoFilter("Sharpen", "luma=False", "chroma=True")
adm.addVideoFilter("swscale", "width=970", "height=646", "algo=2", "sourceAR=1", "targetAR=1")
adm.addVideoFilter("rotate", "angle=90")
adm.addVideoFilter("chromashift", "u=-1", "v=-1")
adm.addVideoFilter("rotate", "angle=270")
adm.addVideoFilter("crop", "top=4", "bottom=2", "left=6", "right=8")
adm.addVideoFilter("Sharpen", "luma=True", "chroma=True")
adm.audioClearTracks()
adm.setContainer("MP4V2", "optimize=0", "add_itunes_metadata=1")
Crop and resizing width need to be nudged. Check Aspect in the Output section, when there is a 4:3 video. Check video length with the rightmost [>>] button, then set [B].
Compression value recommended as 22-24. File size: 30fps uses > 12MB per minute, 60fps may use up to 20MB/min.
Audio is not covered here. I use DGIndex to create a WAV, and add this as a final step (convert to mp3), when video encoding is complete.
Please, enjoy, and comment about results..
Perhaps someone can figure out additional matrix specimen.
Thanks much for reading and checking out.
I would like to share a case study here, to make customized convolution more popular. The GeneralConvolution filter runs in AviSynth, therefor I post it here.
Source material: DVD, NTSC 720x480, mostly interlaced 29.97 fps. Video, not film.
Target: h264 mp4, optionally upsampled to 960x640.
Main technique in this topic is convolution, the primary filtering chain runs in AviSynth.
I will share some asymmetric matrices (kernels) in the script below.
(I also included a code example, for to try out a short sequence of the source with various different kernels.
Probably, only one or two of those will work well, when we are interested in subtle quality.)
This is then embedded in a secondary filtering chain in AviDemux, for its simplicity to adjust parameters.
The chain is constructed so, that it becomes easy to correct typical flaws, plus - which is important part of the case study -
in the complete chain, there is a complex attempt to achieve some synergy with the encoder.
------
In the secondary chain, AviDemux, the following techniques have been added:
- Upsampling, at first to a ~1600x960, on that level we do
-- general sharpening and color sharpening (effectively, we get a smaller sharpening radius, doing it here.)
-- color shift corrections on subpixel level
-- color and contrast corrections
- Final upsampling domain is 960x640, to mitigate influence by the brickwalling filters of the various players, that may not be optimals for CPU speed reasons.
- A final convolutional sharpener (preset of AviDemux), but it should obviously be deleted in case the result looks oversharpened.
- A preset for the x264 encoder is included here, that has been adapted to this project.
Naturally, we can omit the secondary chain and just crop (as the asymmetric matrix will shift the picture and there are borders added for this), and encode directly.
But I recommend to check the special synergies with the full chain.
Result discusson:
I found that without additional work, a direct transcode seems to look a bit blurred, even though a high bitrate is allocated.
There is a convolutional sharpener in AviDemux that is used additionally, but it can't be customized.
What the customized matrix does, is a combined set of adjustments, that were checked out heuristically with hundreds of trial/error attempts.
- we use the 5x5 matrix in an asymmetric way, so this yields us 4 coefficient taps in the filtering, which is a lot more precision than the usual 3x3 symmetric kernel.
- obviously, it does some sharpening
- "deconvolution"; in quotes, as it is done from experience, not with proper math (for we don't have the modeling data).
-- it should mitigate influences starting from the camera lense to postprocessing to encoding and reencoding steps.
- some attempts to soften deinterlacing artifacts, this combines well with the upsampling.
The encoder is being slammed with enhanced detail range, in a way that it should better recognize small structures in the picture, and treat these as moving blocks, further enhancing clarity by averaging those sharp details down to a "normal" level. Otherwise it seems, that the encoder often cannot recognize the structures from noise, as they carry mpeg2 artefacts, and it will blur them.
For the sensitivity of the analyzer on these details, plus for preserving textures, a certain optimization in the x264 encoder is being turned off.
The sum of these techniques makes the video look "different".
It will get extra clarity, smoothness, and a particular shine and gloom, that resembles pop music videos, which even works with sources that may look a bit blurred and pale.
The fine-tuning of course has influence on that "pop look".
(But to completely remove the different looks, I recommend to delete the extra color sharpener, perhaps all color and contrast filters, or even the whole secondary chain.)
So, there are two aspects in the result:
Crisp sharpness, and the smooth "pop look".
Artifacts:
Halo and ringing already in the source might increase, but quite little of such would be added, with the correct choice of the matrix, and avoiding oversharpening (controlled by the optional final sharpener at the end of the secondary chain.)
Sometimes the kernel can even cancel out certain ringing.
Please, note that in linear processing, tuned deconvolution can remove ringing, because the ringing is actually the "Gibb" phenomenon, that comes from non-ideal (finite) filtering of a rectangular signal. If we transmit a digital rectangular signal, its bandwidth must be limited beforehand, i.e. it becomes "rounded". If we don't do this, hoping that things will look sharper, then mathematics will prove us wrong and punish the results with "ringing".
Ugly pixel artifacts on 720px level will disappear, as we are using 960px density, and the resizers will round off anything such.
The "running ants" artifact of the Yadif tends to run with smaller and softer pixels, which is quite a pleasant improvement.
This article does not deal with any other techniques to remove artifacts, as it wants to use only fully linear filters.
When the postprocessing already has used too much of nonlinear filtering, that might create trouble, and need further,
nonlinear removal with techniques mentioned in the many other threads.
Scripts
Here is the AviSynth script:
(plz adjust the file paths to your needs)
LoadPlugin("F:\programs\AviSynth+\plugins\dgdecode.dll")
MPEG2Source ("F:\workdir\MyProject.d2v",cpu=0,info=2)
# delete this if source is not interlaced. caution - there are sources declared interlaced, that are not. visual check required.
Load_Stdcall_plugin("F:\programs\AviSynth+\plugins\yadif.dll")
Yadif(mode=1)
AddBorders(4,0,4,4,$7F7F7F)
#AddBorders(clip clip, int left, int top, int right, int bottom [, int color])
ConvertToRGB32(matrix="PC.709",interlaced=false,chromaresample="lanczos4")
#ConvertToRGB(clip [, string matrix] [, bool interlaced] [, string ChromaInPlacement] [, string chromaresample])
# Remarks: default in this project is PC.709 (= HDTV)
# Though DVD = PC.601 or Rec601, I use 709 always, and correct the colors in the filtering chain.
# The reason is, that too often the decoded video ends up with flawed color space anyway.
# "Rec601" : Use 601 coefficients, scaled to TV range [16,235].
# "PC.601" : Use 601 coefficients, keep full range [0,255].
# please, activate only one of the following matrices:
# roughly said, intensity and radius are increasing. differences are still subtle.
GeneralConvolution(0, "3 -4 8 -10 112 0 0 -0 -4 -15 0 0 -6 -0 15 0 0 0 0 -5 0 0 0 0 0") #C3.1
#GeneralConvolution(0, "3 -3 9 -13 112 0 0 -0 -4 -15 0 0 -6 -0 15 0 0 0 0 -5 0 0 0 0 0") #C3.2
#GeneralConvolution(0, "3 -3 10 -15 112 0 0 -0 -4 -12 0 0 -6 -0 14 0 0 0 0 -4 0 0 0 0 0") #C3.3
#GeneralConvolution(0, "2 -5 12 -20 112 0 0 -0 -4 -10 0 0 -6 -0 12 0 0 0 0 -4 0 0 0 0 0") #C3.4
#GeneralConvolution(0, "5 -13 15 -20 120 0 0 -0 -4 -10 0 0 -6 -0 12 0 0 0 0 -4 0 0 0 0 0") #a3
#GeneralConvolution(0, "5 -13 18 -21 103 0 0 -0 -4 -10 0 0 -6 -0 12 0 0 0 0 -4 0 0 0 0 0") #a2'
#GeneralConvolution(0, "2 -5 15 -20 96 0 0 -0 -6 -12 0 0 -6 -0 12 0 0 0 0 -4 0 0 0 0 0") # X7
#GeneralConvolution(0, "2 -6 15 -20 96 0 0 -0 -4 -12 0 0 -6 -0 15 0 0 0 0 -4 0 0 0 0 0") # X8
#--------------convolution tuning----
#---test start time = minutes*60 + ss.ddd #(seconds)
tpos=0*60+13
rff=29.97*2
fpos=int(tpos*rff)
#--test slice length:
tsl=int(40*rff)
/*
Trim(fpos, -tsl) + blankclip(last,5) \
+Trim(fpos, -tsl).GeneralConvolution(0, "2 -6 15 -20 96 0 0 -0 -4 -12 0 0 -6 -0 15 0 0 0 0 -4 0 0 0 0 0").subtitle("x8") + blankclip(last,15)\
+Trim(fpos, -tsl).GeneralConvolution(0, "3 -4 8 -10 112 0 0 -0 -4 -15 0 0 -6 -0 15 0 0 0 0 -5 0 0 0 0 0").subtitle("C3.1") + blankclip(last,15)\
+Trim(fpos, -tsl).GeneralConvolution(0, "3 -3 9 -13 112 0 0 -0 -4 -15 0 0 -6 -0 15 0 0 0 0 -5 0 0 0 0 0").subtitle("C3.2") + blankclip(last,15)\
+Trim(fpos, -tsl).GeneralConvolution(0, "3 -3 10 -15 112 0 0 -0 -4 -12 0 0 -6 -0 14 0 0 0 0 -4 0 0 0 0 0").subtitle("C3.3") + blankclip(last,15)\
+Trim(fpos, -tsl).GeneralConvolution(0, "2 -5 12 -20 112 0 0 -0 -4 -10 0 0 -6 -0 12 0 0 0 0 -4 0 0 0 0 0").subtitle("C3.4") + blankclip(last,15)\
+Trim(fpos, -tsl).GeneralConvolution(0, "5 -13 18 -21 103 0 0 -0 -4 -10 0 0 -6 -0 12 0 0 0 0 -4 0 0 0 0 0").subtitle("a2'") + blankclip(last,15)
*/
#Crop(clip clip, int left, int top, int -right, int -bottom, bool align)
Crop(0,2,-2,-2) # not checking this, cropping will be adjusted in the final step.
ConvertToYV12(matrix="PC.709",interlaced=false,chromaresample="lanczos4")
# this will go to AviDemux with a particular filtering chain.
Here is the AviDemux script (save as MyProject.py)
Open the AVS-Proxy channel first, then run this script.
I hope the line breaks will come out correctly..
#PY <- Needed to identify #
#--automatically built--
adm = Avidemux()
adm.loadVideo("::ADM_AVS_PROXY::")
adm.clearSegments()
adm.addSegment(0, 0, 12000000000)
adm.markerA = 0
adm.markerB = 4827930624
adm.videoCodec("x264", "useAdvancedConfiguration=True", "general.params=AQ=22", "general.threads=0"
, "general.preset=ultrafast", "general.tuning=film", "general.profile=baseline", "general.fast_decode=False", "general.zero_latency=False"
, "general.fast_first_pass=True", "level=-1", "vui.sar_height=27", "vui.sar_width=32"
, "MaxRefFrames=5", "MinIdr=25", "MaxIdr=250", "i_scenecut_threshold=40", "intra_refresh=False", "MaxBFrame=5", "i_bframe_adaptive=2"
, "i_bframe_bias=0", "i_bframe_pyramid=2", "b_deblocking_filter=True", "i_deblocking_filter_alphac0=-1"
, "i_deblocking_filter_beta=0", "cabac=True", "interlaced=False", "constrained_intra=False", "tff=True"
, "fake_interlaced=False", "analyze.b_8x8=True", "analyze.b_i4x4=True", "analyze.b_i8x8=True", "analyze.b_p8x8=False"
, "analyze.b_p16x16=True", "analyze.b_b16x16=True", "analyze.weighted_pred=2", "analyze.weighted_bipred=True"
, "analyze.direct_mv_pred=3", "analyze.chroma_offset=1", "analyze.me_method=2", "analyze.me_range=17"
, "analyze.mv_range=-1", "analyze.mv_range_thread=-1", "analyze.subpel_refine=9", "analyze.chroma_me=True"
, "analyze.mixed_references=True", "analyze.trellis=2", "analyze.psy_rd=1.100000", "analyze.psy_trellis=0.000000"
, "analyze.fast_pskip=True", "analyze.dct_decimate=True", "analyze.noise_reduction=0", "analyze.psy=True"
, "analyze.intra_luma=0", "analyze.inter_luma=0", "ratecontrol.rc_method=0", "ratecontrol.qp_constant=0"
, "ratecontrol.qp_min=4", "ratecontrol.qp_max=58", "ratecontrol.qp_step=8", "ratecontrol.bitrate=0"
, "ratecontrol.rate_tolerance=1.000000", "ratecontrol.vbv_max_bitrate=0", "ratecontrol.vbv_buffer_size=0"
, "ratecontrol.vbv_buffer_init=0", "ratecontrol.ip_factor=1.400000", "ratecontrol.pb_factor=1.400000"
, "ratecontrol.aq_mode=1", "ratecontrol.aq_strength=1.400000", "ratecontrol.mb_tree=True", "ratecontrol.lookahead=40")
adm.addVideoFilter("fluxsmooth", "temporal_threshold=17", "spatial_threshold=0")
adm.addVideoFilter("addBorder", "left=0", "right=2", "top=2", "bottom=2")
adm.addVideoFilter("swscale", "width=1600", "height=968", "algo=2", "sourceAR=2", "targetAR=2")
adm.addVideoFilter("chromashift", "u=-1", "v=-1")
adm.addVideoFilter("Sharpen", "luma=True", "chroma=True")
adm.addVideoFilter("contrast", "coef=0.900000", "offset=40", "doLuma=False", "doChromaU=False", "doChromaV=True")
adm.addVideoFilter("colorYuv", "y_gain=0.000000", "y_bright=0.000000", "y_gamma=1.900000"
, "y_contrast=15.000000", "u_gain=0.000000", "u_bright=0.000000", "u_gamma=0.000000"
, "u_contrast=12.000000", "v_gain=0.000000", "v_bright=0.000000"
, "v_gamma=0.000000", "v_contrast=0.000000", "matrix=0", "levels=0", "opt=False"
, "colorbars=0", "analyze=1", "autowhite=False", "autogain=False")
adm.addVideoFilter("Sharpen", "luma=False", "chroma=True")
adm.addVideoFilter("swscale", "width=970", "height=646", "algo=2", "sourceAR=1", "targetAR=1")
adm.addVideoFilter("rotate", "angle=90")
adm.addVideoFilter("chromashift", "u=-1", "v=-1")
adm.addVideoFilter("rotate", "angle=270")
adm.addVideoFilter("crop", "top=4", "bottom=2", "left=6", "right=8")
adm.addVideoFilter("Sharpen", "luma=True", "chroma=True")
adm.audioClearTracks()
adm.setContainer("MP4V2", "optimize=0", "add_itunes_metadata=1")
Crop and resizing width need to be nudged. Check Aspect in the Output section, when there is a 4:3 video. Check video length with the rightmost [>>] button, then set [B].
Compression value recommended as 22-24. File size: 30fps uses > 12MB per minute, 60fps may use up to 20MB/min.
Audio is not covered here. I use DGIndex to create a WAV, and add this as a final step (convert to mp3), when video encoding is complete.
Please, enjoy, and comment about results..
Perhaps someone can figure out additional matrix specimen.
Thanks much for reading and checking out.