VapourSynth Plugin API¶
The low-level VapourSynth plugin is registered under the analog namespace.
It can be called directly from VapourSynth scripts without the Python wrapper.
Decoding¶
- core.analog.decode_4fsc_video(composite_or_luma_source [, chroma_or_pb_source] [, pr_source] [, decoder] [, color_family] [, color_difference_precision] [, broadcast_scaling_precision] [, model_path] [, onnx_provider] [, model_precision] [, model_chroma_bandpass=1] [, model_input_scale=1.0] [, reverse_fields=0] [, chroma_gain=1.0] [, chroma_phase=0.0] [, chroma_nr=0.0] [, luma_nr=0.0] [, phase_compensation=1] [, first_active_sample] [, last_active_sample] [, first_active_line] [, last_active_line] [, dropout_correct=0] [, dropout_overcorrect=0] [, dropout_intra=0] [, dropout_composite_or_luma_extra_sources] [, dropout_chroma_extra_sources] [, annotate_dropouts=0])¶
Decodes 4𝑓𝑠𝑐 (four times subcarrier frequency) sampled analog video signals to a digital video clip. The signal data must be orthogonal video system lines with well-formed blanking and syncing structure at a stable time base, such as those produced by ld-decode and vhs-decode. These files normally have a
.tbcextension indicating they are time-base-corrected and must have a metadata sidecar file in JSON or SQLite format. The newer CVBS format is also read, detected by extension:.cvbs, or.cvbsy/.cvbscfor separated luma/chroma (the pre-1.5.0.compositeand.y/.cspellings are still accepted). RAW CVBS encodings are rejected.Returns a 32-bit float clip:
YUV444PS(default),RGBS,GRAYS, orYUV440PSfor SECAM, percolor_family.Note: this is the low-level interface. Neural-network
decodervalues need an explicitmodel_path; the Python wrapper resolves bundled models bymodel_versionfor you. The concepts the parameters below lean on — metadata sidecars, the decoder table, output geometry, dropout correction and annotation — are documented once, on the Python API page, and apply to this interface unchanged.- Parameters:
composite_or_luma_source (str) – Path to the composite or luma-only capture (
.tbc/.cvbs).chroma_or_pb_source (str) – Path to a separate chroma
.tbcfile, for Y/C-separated sources such as S-Video or VHS color-under.pr_source (str) – Path to the Pr component
.tbcfile (component video, not yet supported).decoder (str) – Chroma decoder to use. See Decoder Options. When not specified, the decoder is chosen automatically based on the video system in TBC metadata. When
chroma_or_pb_sourceis supplied, this decoder applies to the chroma TBC only; the luma TBC is read with themonodecoder so it isn’t run through Y/C separation a second time. Add"secam"and the neural-network decoders ("nntransform3d","ldzeug2_color_cnn","ldzeug2_luma_sep","ldzeug2_luma_sep_frame", all NTSC only).color_family (str) – Output family:
"yuv"(default),"rgb", or"gray". RGB is rejected for SECAM.color_difference_precision (str) –
"classic"or"modern".broadcast_scaling_precision (str) –
"classic","modern"or"scientific".model_path (str) – Path to NN model weights (
.onnx, or.mlpackageon macOS). Required for a neural-networkdecoder.onnx_provider (str) – Execution provider:
auto,cpu,tensorrt/trt,cuda/gpu,migraphx,directml,coreml.autopicks the accelerator available (TensorRT ahead of CUDA on the Nvidia wheels); falls back to CPU when unavailable.model_precision (str) – Compute precision the backend may use:
fp32(default) orfp16. Only a backend that compiles the model into a device engine acts on it — TensorRT, which then builds mixed fp16/fp32 kernels and caches those engines separately. Setfp16only for weights whose input contract keeps every tensor in fp16 range; the Python wrapper knows which bundled models qualify and sets this for you.model_chroma_bandpass (int) – I/Q low-pass toggle for
ldzeug2_luma_sep/ldzeug2_luma_sep_frame(default1).model_input_scale (float) – Input magnitude divisor for
nntransform3d(default1.0).reverse_fields (int) – Set to 1 to swap field order.
chroma_gain (float) – Chroma gain multiplier for saturation adjustment. Default
1.0.chroma_phase (float) – Chroma phase adjustment in degrees. Default
0.0.chroma_nr (float) – Chroma noise-reduction level. Only applies to NTSC decoders. Default
0.0.luma_nr (float) – Luma noise-reduction level. Default
0.0.phase_compensation (int) – Burst-locked NTSC chroma demodulation, recovering the subcarrier phase from each line’s colorburst instead of assuming it’s locked to the 4𝑓𝑠𝑐 sample grid. Set to 0 to force fixed-phase demodulation. Default
1. The PAL decoders are burst-locked by design and ignore this.first_active_sample (int)
last_active_sample (int) – Inclusive horizontal crop, in the sample numbering of the 4𝑓𝑠𝑐 interface standards: sample 0 is the first sample of the digital active line, and negative numbers reach back into the line blanking ahead of it (see Active Window). Defaults to the whole digital active line.
first_active_line (int)
last_active_line (int) – Inclusive vertical crop, in the standards’ field-sequential signal line numbers.
first_active_lineis the window’s topmost line. Defaults to the video system’s standard active picture.dropout_correct (int) – Set to 1 to enable dropout correction using metadata-identified dropouts. See Correction. Default
0.dropout_overcorrect (int) – Set to 1 to extend dropout boundaries by +/-24 samples. For heavily damaged sources. Default
0.dropout_intra (int) – Set to 1 to force intra-field-only correction, avoiding inter-field borrowing artifacts on high-motion content. Default
0.dropout_composite_or_luma_extra_sources (str[]) – Additional composite or luma
.tbcfiles for multi-source dropout correction.dropout_chroma_extra_sources (str[]) – Additional chroma
.tbcfiles for multi-source dropout correction (for color-under formats).annotate_dropouts (int) – Set to 1 to record each frame’s dropout regions in the
AnalogDropoutSpansframe property, for use with create_dropouts_mask. Independent ofdropout_correct. See Annotation. Default0.
Examples:
from vapoursynth import core
# Basic composite decode:
clip = core.analog.decode_4fsc_video("/path/to/capture.tbc")
# Y/C-separated decode:
clip = core.analog.decode_4fsc_video("luma.tbc", "chroma.tbc")
Dropouts¶
- core.analog.create_dropouts_mask(clip[, origins])¶
Rasterises a clip’s annotated dropout regions into a mask clip.
clipmust have been decoded withannotate_dropouts=1; a clip without theAnalogDropoutSpansproperty is an error. The result is a single-plane clip matchingclip’s dimensions and precision —0for clean samples, full scale (1.0, or2**bits - 1) for dropped ones — which drops straight intocore.std.MaskedMergeand the otherstdmask functions.The mask is full-size even for subsampled clips, which is what
MaskedMergerequires: it resamples the mask for the chroma planes itself, honouring the clip’s_ChromaLocation. For SECAM’s 4:4:0 output that resampling is bilinear, so a one-line dropout softens across two chroma rows.Because the regions travel as frame properties, they survive
std.Trim,std.Interleaveand splicing — build the mask before or after editing the decoded clip and it stays aligned either way.- Parameters:
clip (vnode) – An annotated clip, 8-16 bit integer or 32-bit float.
origins (int[]) – Restrict the mask to regions of particular origin:
0for regions flagged in the source metadata,8for decoder concealment. Defaults to every origin. Maskingorigins=[8]alone shows exactly which chroma samples SECAM click concealment replaced.
Examples:
import vapoursynth as vs
core = vs.core
# Locate the dropouts without concealing them, then repair them elsewhere.
clip = core.analog.decode_4fsc_video(
"capture.tbc", dropout_correct=0, annotate_dropouts=1)
mask = core.analog.create_dropouts_mask(clip)
repaired = core.std.MaskedMerge(clip, inpainted, mask)
# Grow the mask a little to cover the ringing at a dropout's edges.
grown = core.std.Maximum(mask).std.Inflate()
Colorimetry¶
- core.analog.modernize_chromaticity(clip [, primaries_in_s] [, transfer_in_s] [, matrix_in_s] [, primaries_s] [, transfer_s] [, matrix_s] [, output_preset] [, resample_filter_uv] [, filter_param_a_uv] [, filter_param_b_uv] [, chromatic_adaptation=0] [, nominal_luminance=100.0] [, contrast_in=1.0] [, brightness_in=0.0] [, contrast=1.0] [, brightness=0.0])¶
Converts analog-era colorimetry and photometry to a modern target, intended downstream of
decode_4fsc_videoor of a source plugin (such as BestSource) reading previously captured video. Color only — no geometry conversions and no dithering. Input is YUV or RGB (integer up to 16 bits, or 32-bit float). The color math always runs at 4:4:4: subsampled Y’CbCr input is upsampled through the resize plugin (seeresample_filter_uv), converted, and returned to its original subsampling on Y’CbCr output — the same round trip theresizefunctions perform for colorimetry changes.Parameters share names with VapourSynth’s
resizefunctions where the meaning is similar, with one deliberate difference: the*_inparameters here override frame properties. When an*_inparameter is omitted, the value is inferred from the matching frame property (_Primaries,_Transfer,_Matrix), and frame requests fail if the property is absent,unspecified, or has no supported equivalent.Because there is no dithering, prefer high-bit-depth input and output — ideally the 32-bit float that
decode_4fsc_videoproduces — and leave quantization to a proper dithering step at the end of the pipeline. There are likewise norange/range_inparameters: input range comes from the_ColorRangeframe property (defaulting to studio range for Y’CbCr and full range for RGB), and output range follows the output matrix’s convention the same way.To switch color family (YUV to RGB or the reverse), specify
matrix_sor anoutput_preset; RGB input without either yields RGB output.- Parameters:
clip (vnode) – Input clip: YUV 4:4:4 or RGB, constant format.
primaries_in_s (str) –
Input chromaticity (CIE 1931 primaries + white point). Options sharing a line are equivalent:
ntsc-1953,bt470m,470m,fcc— the 1953 NTSC chromaticity (Illuminant C white)bt470-japan,470m93,ntscj— NTSC-1953 primaries with the Japanese “D93” whitebt1700-japan,170j— SMPTE C primaries with the Japanese whitepal,ebu,bbc,470bg— the 625-line EBU chromaticitysmpte-c,st170,170m— SMPTE RP 145 / ST 170code-point-22— the mystery IEC/ITU primaries code point 22 (neither JEDEC P22 nor EBU Tech 3213)ecia-xxa,p22…ecia-xxg— the seven registered phosphor sets of ECIA/TEPAC/JEDEC group XX (“P22”), in registration order;xxais RCA’s 1954 originalrca-sulfide-8500k,rca-sulfide-9300k-27mpcd,rca-sulfide-c— RCA’s all-sulfide commercial mix under three assumed white points (never published)rca-p22-4-67,rca-p22-5-61,rca-p22-9-65— phosphor sets from RCA’s own P22 taxonomysony-p22— Sony’s CRT phosphor set (Japanese white; never a JEDEC/TEPAC/ECIA registration)studio-japan— ARIB TR-B9 pre-1996 Japanese studio practicenederland-proposal— the CCIR Doc. XI/194 compromise primaries
All Japanese entries use ITU-R BT.2035’s reference D93 white point. Inferred from
_Primariesvalues 4, 5, 6/7 and 22 when omitted.transfer_in_s (str) –
Input transfer characteristics:
linearntsc-1953,bt470m,470m,fcc,gamma22— assumed 2.2-gamma displaybt470bg,470bg,tube,gamma28— assumed 2.8-gamma displayst170-scene,st170-oetf,bt601,601— scene-referred inverse of the ST 170 / BT.601 camera OETFst170-display,st170-eotf— ST 170’s reference reproducer EOTF (§5.2). This is the exact inverse of the camera OETF, so it linearizes identically tost170-scene; the two names exist to document intent.bt1886-annex-1,1886,lcd,gamma24— the BT.1886 reference EOTF; honourscontrast_in/brightness_inbt1886-appendix-1,1886a,crt— BT.1886’s informative CRT-matching EOTF; honourscontrast_in/brightness_insrgb,iec-61966-2-1
Inferred from
_Transferwhen omitted: 1 and 6 →bt1886-annex-1, 4 → 2.2 gamma, 5 → 2.8 gamma, 8 →linear, 13 →srgb. BT.709’s reference EOTF is BT.1886, and_Transfer=6(SMPTE ST 170) deliberately gets the same reading rather thanst170-display: ST 170’s idealized inverse-OETF reproducer was rarely what displays actually did — the era’s displays were CRTs, the response BT.1886’s Annex 1 EOTF was later written to approximate so that flat-panel displays with digital processing could emulate it. This matches howresize/zimg linearize code 6 (equivalent to code 1, display-referred BT.1886). Settransfer_in_s="st170-display"explicitly for a literal §5.2 display, or"crt"(BT.1886 Appendix 1) for a closer CRT match.matrix_in_s (str) –
Input Y’CbCr matrix (Y’CbCr input only):
analog-classic,ntsc-1953,fcc— the 0.30/0.11 luma weights of NTSC-1953analog-modern,bt470,bt1700,st170,170m,bt601,601— the 0.299/0.114 weights
Inferred from
_Matrixwhen omitted: 4 → classic, 5/6 → modern.primaries_s (str) – Output chromaticity:
bt709/709,bt2020/2020,p3dci/st431-2,p3d65/st432-1, orxyz/st428(CIE XYZ tristimulus output; requiresmatrix_s="rgb").transfer_s (str) – Output transfer characteristics:
linear;bt1886-annex-1/1886/lcd/gamma24(honourscontrast/brightness);srgb/iec-61966-2-1(IEC 61966-2-1 Equations 7 and 8);pq/st2084/2084; orhlg/std-b67(display-referred, BT.2100 1.2-power OOTF).matrix_s (str) –
Output matrix:
rgb(RGB color family output),bt709/709,bt2020ncl/bt2100/2020ncl/2020/2100, or2020cl(BT.2020 constant luminance, H.273 matrix 10), orchromacl/chromaticity-derived-cl(H.273 matrix 13: constant luminance whose luma weights are derived fromprimaries_sper H.273 Equations E-22 to E-27, so it pairs with any output chromaticity —2020clitself means BT.2020’s weights by definition and so requiresbt2020primaries).Constant luminance is not a transfer characteristic: BT.2020 Table 4 gives CL and NCL the same OETF and differs only in where it is applied. NCL encodes each channel and then matrixes; CL matrixes the linear tristimulus and encodes the result, so luminance survives chroma subsampling intact. The color-difference normalizers (PB/NB/PR/NR) follow the transfer curve rather than fixing it — H.273 Equations E-62 to E-65 define them as the transfer characteristic function applied to expressions in KB and KR — so
transfer_sstays free and is applied to the CL constants and the picture alike. BT.2020 Table 4’s published numbers are that derivation under BT.2020’s own OETF, which is what a CL matrix falls back to whentransfer_sis unset.Pairing CL with the display-referred
bt1886-annex-1is supported on the strength of H.273’s note that the BT.709/BT.2020 OETF code points, though defined as an OETF, take BT.1886 as their corresponding reference EOTF. Be aware that decoders which read those code points strictly as the OETF (zimg does, treating CL as always scene-referred) will derive different normalizers than a display-referred flow.output_preset (str) –
Bundles the three output parameters:
hdtv,bt709— BT.709 primaries, BT.1886 Annex 1 transfer, BT.709 matrixuhdtv,bt2100-pq— BT.2020 primaries, PQ transfer, BT.2020 NCL matrixbt2100-hlg— BT.2020 primaries, HLG transfer, BT.2020 NCL matrixbt2020-sdr— BT.2020 primaries, BT.1886 Annex 1 transfer, BT.2020 NCL matrixsrgb,iec-61966-2-1— BT.709 primaries, sRGB transfer, RGB output (the standard defines no matrix; addmatrix_sfor Y’CbCr)
Explicit
primaries_s/transfer_s/matrix_swin over the preset, somatrix_s="rgb"combined with a preset keeps its colorimetry but emits RGB.resample_filter_uv (str) – Kernel for the internal chroma round trip on subsampled input:
point,bilinear,bicubic(default, as inresample_secam),spline16,spline36,spline64, orlanczos. The upsample sites against the frame’s_ChromaLocation; Y’CbCr output is brought back to the input subsampling with the same kernel, and_ChromaLocationis preserved. Unused for 4:4:4 and RGB input. 4:4:0 input is rejected: SECAM fromdecode_4fsc_videocarries a line-sequential Db/Dr lattice that plain resampling would blend — realign it withresample_secam, orfill_secam_by_delayfor the classic delay-line treatment.filter_param_a_uv (float)
filter_param_b_uv (float) – Kernel tuning for
resample_filter_uv, as in theresizefunctions: the bicubic b/c coefficients, or the lanczos tap count (filter_param_a_uvonly).chromatic_adaptation (int) –
Set to 1 to apply a Bradford chromatic adaptation from the input white point to the output one. Default 0 (unlike some converters): whites keep their original tint, so e.g. a D93-mastered picture stays cool on a D65 display, as it looked in its era.
Beware that with adaptation off, extremes can clip unintentionally in SDR output: a full-strength white under a non-D65 input white point lands outside the output’s unit RGB range — NTSC-1953’s Illuminant C white overshoots BT.709’s red and blue channels by roughly 5-10% linear. Integer output clamps those channels (tinting the brightest highlights); float output carries the overshoot to whatever clips next. PQ and HLG output have headroom above SDR reference white and are unaffected. Enable
chromatic_adaptation— or attenuate before conversion — when unclipped SDR highlights matter.nominal_luminance (float) – Physical luminance in cd/m² that linear 1.0 (SDR reference white) maps to for PQ and HLG output. Default
100.0.contrast_in (float) – BT.1886 user gain (legacy “contrast”) for the input EOTF: the screen white luminance LW as a 0.0-1.0 fraction of reference white. Default
1.0.brightness_in (float) – BT.1886 black lift (legacy “brightness”) for the input EOTF: Annex 1’s LB, or Appendix 1’s
b, as a 0.0-1.0 fraction. Default0.0.contrast (float)
brightness (float) – Output-side counterparts, valid only with the
bt1886-annex-1output transfer.
Output frames are tagged with the matching
_Matrix,_Transfer,_Primaries,_ColorRangeand_Rangeproperties._ChromaLocationis preserved when the output keeps the input’s subsampling and removed otherwise (siting is moot at 4:4:4). The BT.1886 output transfer is signalled as BT.709 (_Transfer=1), or as the BT.2020 10/12-bit OETF tag when paired with BT.2020 primaries, since H.273 has no display-side code point for it.
Examples:
import vapoursynth as vs
from vapoursynth import core
clip = core.analog.decode_4fsc_video("/path/to/capture.tbc")
# Straight to Rec. 709 SDTV-successor colorimetry:
hd = core.analog.modernize_chromaticity(clip, output_preset="hdtv")
# A LaserDisc mastered on a 1969-registered RCA tube, to BT.2100 PQ:
pq = core.analog.modernize_chromaticity(
clip, primaries_in_s="ecia-xxd", transfer_in_s="crt",
output_preset="bt2100-pq")
# Quantize to the 10-bit 4:2:0 an HDR10 deliverable calls for. This filter
# only converts colorimetry, never depth, so the dither is yours to place.
hdr10 = core.resize.Spline36(pq, format=vs.YUV420P10,
dither_type="error_diffusion")
The remaining HDR10 ingredients — ST 2086 mastering-display metadata and
MaxCLL/MaxFALL — are static metadata carried alongside the picture rather than
in it, so they are set at encode time (x265’s --master-display and
--max-cll), not by anything in the filter graph.
- core.analog.amplify_chroma(clip, gain [, resample_filter_uv] [, filter_param_a_uv] [, filter_param_b_uv])¶
Amplifies or attenuates the color-difference signals: the post-decode counterpart of
decode_4fsc_video’schroma_gain, which scales the demodulated color differences on their way out of the decoder. Because it works on a clip rather than a decode, a conventional capture loaded through a source plugin (BestSource and the like) is as valid an input as a fresh decode.Think of it as a saturation control, but saturation as the analog video domain defines it — a gain on E’Cb/E’Cr — rather than the saturation axis of an HSV or HLS model.
Frames that already carry E’Y E’Cb E’Cr — 32-bit float Y’CbCr tagged
_Matrix=4(NTSC-1953),_Matrix=5(BT.470 BG) or_Matrix=6(SMPTE ST 170), asdecode_4fsc_videoemits — are scaled in place, leaving luma, chroma siting and every frame property alone. All three are the same luma/chroma split: the coefficients NTSC-1953 derived from its primaries at Illuminant C, code 4 at the precision they were first published to and codes 5 and 6 at the higher one later systems restated them to. Those later systems kept the coefficients even though their primaries and white had moved, which fits their own chromaticity no better — but it is how the signals were built, so it is what a gain on them means.Frames carrying those same color differences in another format — integer Y’CbCr of any depth — go through a 32-bit float intermediate of the same subsampling and back, both conversions running through the resize plugin. That trip names no matrix, so
resizeconverts the samples and nothing else: no chroma is resampled, whichever analog matrix the frame carries, and even the 4:4:0 lattice comes back untouched.Frames on other axes take the same trip to a
_Matrix=6intermediate instead, which is a real color-difference change and so does resample the chroma of a subsampled clip (seeresample_filter_uv). RGB always takes that path, having no color differences of its own. The choice is made per frame from the frame’s own_Matrix, which frames fail on if absent orunspecified.On a frame whose matrix isn’t an analog one, the round trip holds the analog luma constant, which is what the decoder’s own gain does. Its own Y’ therefore shifts a little as the color is scaled — a BT.709 frame taken to
gain=0.0lands on the analog luma of its colors, not on its BT.709 one — while the chroma comes out scaled by exactlygaineither way.Only analog-era colorimetry is accepted. A frame’s
_Primariesmust be 4 (NTSC-1953), 5 (EBU), 6 (SMPTE ST 170) or 7 (SMPTE ST 240), or absent orunspecified(2) — untagged captures are taken at their word. Anything newer is rejected: no signal was ever built by splitting luma from chroma with the analog coefficients on those primaries, and there is no telling what such a picture was originally broadcast in. Amplify beforemodernize_chromaticity(or another conversion) rather than after.- Parameters:
clip (vnode) – Input clip: YUV or RGB, constant format. GRAY carries no chroma and is rejected.
gain (float) – Multiplier applied to both color differences. Above
1.0amplifies and below1.0attenuates;0.0leaves a monochrome picture, and1.0returns the clip untouched, without the conversion round trip a unity gain could only lose precision to. Must be0.0or greater.resample_filter_uv (str) –
Kernel for the chroma resampling a matrix change entails:
point,bilinear,bicubic(default, as inresample_secam),spline16,spline36,spline64, orlanczos. Only subsampled frames on non-analog axes use it — the matrix change happens at 4:4:4 and is resampled back to the source subsampling, sited against the frame’s_ChromaLocation. Frames already carrying analog color differences never reach it, in any format or subsampling.4:4:0 frames needing that matrix change are refused rather than resampled: SECAM from
decode_4fsc_videocarries a line-sequential Db/Dr lattice that plain resampling would blend, so realign it withresample_secam(orfill_secam_by_delay) first. Analog-matrix 4:4:0 is amplified normally, integer included, and needs no realignment — the gain is per sample.filter_param_a_uv (float)
filter_param_b_uv (float) – Kernel tuning for
resample_filter_uv, as in theresizefunctions: the bicubic b/c coefficients, or the lanczos tap count (filter_param_a_uvonly).
Output keeps the input’s format, dimensions and frame properties. Integer output is rounded without dithering and clamps at the format’s bounds, so amplifying an already saturated picture can flatten its most colorful areas; float clips nothing.
Examples:
from vapoursynth import core
clip = core.analog.decode_4fsc_video("/path/to/capture.tbc")
# A washed-out capture, given back some color:
livelier = core.analog.amplify_chroma(clip, 1.2)
# Equally at home on a conventional capture, whatever its colorimetry:
vhs = core.bs.VideoSource("/path/to/vhs_capture.mkv")
calmer = core.analog.amplify_chroma(vhs, 0.85)
Logging¶
- core.analog.set_log_level(level)¶
Sets the threshold for the decoder’s diagnostic messages.
Diagnostics that describe how a decode went but don’t stop it — an accelerated neural-network backend falling back to CPU, a SECAM field ident that disagrees with the sidecar, a capture that isn’t at a 4𝑓𝑠𝑐 sample rate — are emitted as VapourSynth log messages, so
core.add_log_handlerreceives them alongside every other filter’s. Failures are reported the other way, as an error on the call that failed.levelis one ofdebug,info(the default),warning,criticaloroff. The setting is process-wide rather than per clip.Note
Under
vspipe, or any other host that installs its own log handler, these messages go straight to that handler. Under a plain Python interpreter with no handler registered, VapourSynth’s Python module forwards them to the standard library’slogginginstead, under the logger named"vapoursynth". Without alogging.basicConfig()call (or some other handler attached), onlywarningand above will actually reach stderr —debugandinfoare silently discarded. See the logging HOWTO for how to configure it.