MysteryX
22nd October 2021, 03:42
I'm using a lot of bitdepth conversions in my script. I found that fmtc.bitdepth is actually quite heavy on performance.
I tried resize.Point to do the same bitdepth conversion. It's about 1.5x faster... BUT memory usage is higher and my script puts me short on memory (32-bit 5K clips do take some memory)
Is there a more lightweight way to do bitdepth conversion?
MysteryX
22nd October 2021, 22:19
I did more testing with Point resize with more available memory.
This function works.
Task Manager shows total 9.3GB RAM usage with Point resize, peaking at 9.8GB. FMTC uses a little bit more in the end.
Entire script with FMTC runs at 0.48fps, with Point resize at 0.56fps
# Point resize is 1.5x faster than fmtc
def ConvertBits(c: vs.VideoNode, bits: int = 8, fulls: bool = False, dither: bool = False):
if c.format.bits_per_sample == bits:
return c
#return c.fmtc.bitdepth(bits=bits, fulls=fulls, fulld=fulls, dmode=0 if dither else 1)
fmt = GetFormat(ClipSampling(c), bits)
range = 1 if fulls else 0
return c.resize.Point(format=fmt, dither_type="ordered" if dither else "none", range=range, range_in=range)
def GetFormat(samp: str, bits: int) -> int:
i = 0 if bits==8 else 1 if bits==10 else 2 if bits==12 else 3 if bits==14 else 4 if bits==16 else 5 if bits==32 else -1
if i == -1:
raise ValueError("GetFormat: bits must be 8, 10, 12, 14, 16 or 32")
fmt = 0
if samp == "GRAY":
fmt = [vs.GRAY8, vs.GRAY10, vs.GRAY12, vs.GRAY14, vs.GRAY16, vs.GRAYS] [i]
elif samp == "RGB":
fmt = [vs.RGB24, 0, 0, 0, vs.RGB48, vs.RGBS] [i]
elif samp == "444":
fmt = [vs.YUV444P8, vs.YUV444P10, vs.YUV444P12, vs.YUV444P14, vs.YUV444P16, vs.YUV444PS] [i]
elif samp == "422":
fmt = [vs.YUV422P8, vs.YUV422P10, vs.YUV422P12, vs.YUV422P14, vs.YUV422P16, 0] [i]
elif samp == "420":
fmt = [vs.YUV420P8, vs.YUV420P10, vs.YUV420P12, vs.YUV420P14, vs.YUV420P16, 0] [i]
if fmt == 0:
raise ValueError(f"GetFormat: Invalid bitdepth ({bits}) for format ({samp})")
return fmt
_Al_
22nd October 2021, 23:17
you can successfully use query_video_format() to deal with this:
def GetFormat(clip: vs.VideoNode, bits: int) -> int:
if bits not in [8, 10, 12, 14, 16, 32]:
raise ValueError("GetFormat: bits must be 8, 10, 12, 14, 16 or 32")
return core.query_video_format(
color_family = clip.format.color_family,
sample_type = vs.FLOAT if bits==32 else vs.INTEGER,
bits_per_sample = bits,
subsampling_w = clip.format.subsampling_w,
subsampling_h = clip.format.subsampling_h
)
so instead of passing clip, you can pass subsamplings_w and subsampling_h , not sure what you do
edit: I actually forgot that most important bits line in there ...
_Al_
22nd October 2021, 23:23
but i think this way you can pass any bits from 8 to 16 plus 32 (if it makes any sense, like use 9bit video)
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.