VapourSynth 65__zip → 70__zip

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. {VapourSynth-65/VapourSynth.egg-info → vapoursynth-70}/PKG-INFO +1 -1
  2. vapoursynth-70/VAPOURSYNTH_VERSION +1 -0
  3. {VapourSynth-65 → vapoursynth-70/VapourSynth.egg-info}/PKG-INFO +1 -1
  4. {VapourSynth-65 → vapoursynth-70}/VapourSynth.egg-info/SOURCES.txt +0 -10
  5. {VapourSynth-65 → vapoursynth-70}/include/VSConstants4.h +1 -0
  6. {VapourSynth-65 → vapoursynth-70}/include/VSScript4.h +12 -0
  7. {VapourSynth-65 → vapoursynth-70}/include/VapourSynth4.h +38 -13
  8. {VapourSynth-65 → vapoursynth-70}/setup.py +1 -1
  9. {VapourSynth-65 → vapoursynth-70}/src/cython/vapoursynth.c +23716 -33877
  10. {VapourSynth-65 → vapoursynth-70}/src/cython/vapoursynth.pxd +120 -105
  11. {VapourSynth-65 → vapoursynth-70}/src/cython/vapoursynth.pyx +364 -82
  12. vapoursynth-70/src/cython/vsconstants.pxd +150 -0
  13. {VapourSynth-65 → vapoursynth-70}/test/environment_test.py +3 -0
  14. {VapourSynth-65 → vapoursynth-70}/test/zimgtest.py +3 -0
  15. VapourSynth-65/VAPOURSYNTH_VERSION +0 -1
  16. VapourSynth-65/src/cython/vsconstants.pxd +0 -83
  17. VapourSynth-65/test/__pycache__/async_test.cpython-311.pyc +0 -0
  18. VapourSynth-65/test/__pycache__/environment_test.cpython-311.pyc +0 -0
  19. VapourSynth-65/test/__pycache__/expr_test.cpython-311.pyc +0 -0
  20. VapourSynth-65/test/__pycache__/filter_test.cpython-311.pyc +0 -0
  21. VapourSynth-65/test/__pycache__/log_test.cpython-311.pyc +0 -0
  22. VapourSynth-65/test/__pycache__/lut_test.cpython-311.pyc +0 -0
  23. VapourSynth-65/test/__pycache__/prop_dict_test.cpython-311.pyc +0 -0
  24. VapourSynth-65/test/__pycache__/test.cpython-311.pyc +0 -0
  25. VapourSynth-65/test/__pycache__/weakref_test.cpython-311.pyc +0 -0
  26. VapourSynth-65/test/__pycache__/zimgtest.cpython-311.pyc +0 -0
  27. {VapourSynth-65 → vapoursynth-70}/COPYING.LESSER +0 -0
  28. {VapourSynth-65 → vapoursynth-70}/MANIFEST.in +0 -0
  29. {VapourSynth-65 → vapoursynth-70}/README.md +0 -0
  30. {VapourSynth-65 → vapoursynth-70}/VapourSynth.egg-info/dependency_links.txt +0 -0
  31. {VapourSynth-65 → vapoursynth-70}/VapourSynth.egg-info/top_level.txt +0 -0
  32. {VapourSynth-65 → vapoursynth-70}/include/VSHelper.h +0 -0
  33. {VapourSynth-65 → vapoursynth-70}/include/VSHelper4.h +0 -0
  34. {VapourSynth-65 → vapoursynth-70}/include/VSScript.h +0 -0
  35. {VapourSynth-65 → vapoursynth-70}/include/VapourSynth.h +0 -0
  36. {VapourSynth-65 → vapoursynth-70}/setup.cfg +0 -0
  37. {VapourSynth-65 → vapoursynth-70}/src/cython/vsscript.pxd +0 -0
  38. {VapourSynth-65 → vapoursynth-70}/src/cython/vsscript_internal.pxd +0 -0
  39. {VapourSynth-65 → vapoursynth-70}/src/vsscript/vsscript_internal.h +0 -0
  40. {VapourSynth-65 → vapoursynth-70}/test/async_test.py +0 -0
  41. {VapourSynth-65 → vapoursynth-70}/test/expr_compiler/compiler_test.py +0 -0
  42. {VapourSynth-65 → vapoursynth-70}/test/expr_compiler/havs_exprs.txt +0 -0
  43. {VapourSynth-65 → vapoursynth-70}/test/expr_compiler/muvs_exprs.txt +0 -0
  44. {VapourSynth-65 → vapoursynth-70}/test/expr_compiler/reference_output.txt +0 -0
  45. {VapourSynth-65 → vapoursynth-70}/test/expr_test.py +0 -0
  46. {VapourSynth-65 → vapoursynth-70}/test/filter_test.py +0 -0
  47. {VapourSynth-65 → vapoursynth-70}/test/log_test.py +0 -0
  48. {VapourSynth-65 → vapoursynth-70}/test/lut_test.py +0 -0
  49. {VapourSynth-65 → vapoursynth-70}/test/prop_dict_test.py +0 -0
  50. {VapourSynth-65 → vapoursynth-70}/test/test.py +0 -0
  51. {VapourSynth-65 → vapoursynth-70}/test/weakref_test.py +0 -0
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2012-2021 Fredrik Mellbin
1
+ # Copyright (c) 2012-2024 Fredrik Mellbin
2
2
  #
3
3
  # This file is part of VapourSynth.
4
4
  #
@@ -66,7 +66,7 @@ __all__ = [
66
66
  'YUV420P8', 'YUV420P9', 'YUV420P10', 'YUV420P12', 'YUV420P14', 'YUV420P16',
67
67
  'YUV422P8', 'YUV422P9', 'YUV422P10', 'YUV422P12', 'YUV422P14', 'YUV422P16',
68
68
  'YUV440P8',
69
- 'YUV444P8', 'YUV444P9', 'YUV444P10', 'YUV444P12', 'YUV444P14', 'YUV444P16', 'YUV444PH', 'YUV444PS',
69
+ 'YUV444P8', 'YUV444P9', 'YUV444P10', 'YUV444P12', 'YUV444P14', 'YUV444P16', 'YUV420PH', 'YUV420PS', 'YUV422PH', 'YUV422PS', 'YUV444PH', 'YUV444PS',
70
70
  'NONE',
71
71
 
72
72
  'FLOAT', 'INTEGER',
@@ -83,9 +83,163 @@ __all__ = [
83
83
  'core',
84
84
  ]
85
85
 
86
- __version__ = namedtuple("VapourSynthVersion", "release_major release_minor")(VS_CURRENT_RELEASE, 0)
87
- __api_version__ = namedtuple("VapourSynthAPIVersion", "api_major api_minor")(VAPOURSYNTH_API_MAJOR, VAPOURSYNTH_API_MINOR)
86
+ class MediaType(IntEnum):
87
+ VIDEO = mtVideo
88
+ AUDIO = mtAudio
89
+
90
+ class ColorFamily(IntEnum):
91
+ UNDEFINED = cfUndefined
92
+ GRAY = cfGray
93
+ RGB = cfRGB
94
+ YUV = cfYUV
95
+
96
+ class SampleType(IntEnum):
97
+ INTEGER = stInteger
98
+ FLOAT = stFloat
99
+
100
+ class PresetVideoFormat(IntEnum):
101
+ NONE = pfNone
102
+
103
+ GRAY8 = pfGray8
104
+ GRAY9 = pfGray9
105
+ GRAY10 = pfGray10
106
+ GRAY12 = pfGray12
107
+ GRAY14 = pfGray14
108
+ GRAY16 = pfGray16
109
+ GRAY32 = pfGray32
110
+
111
+ GRAYH = pfGrayH
112
+ GRAYS = pfGrayS
113
+
114
+ YUV410P8 = pfYUV410P8
115
+ YUV411P8 = pfYUV411P8
116
+ YUV440P8 = pfYUV440P8
117
+
118
+ YUV420P8 = pfYUV420P8
119
+ YUV422P8 = pfYUV422P8
120
+ YUV444P8 = pfYUV444P8
121
+
122
+ YUV420P9 = pfYUV420P9
123
+ YUV422P9 = pfYUV422P9
124
+ YUV444P9 = pfYUV444P9
125
+
126
+ YUV420P10 = pfYUV420P10
127
+ YUV422P10 = pfYUV422P10
128
+ YUV444P10 = pfYUV444P10
129
+
130
+ YUV420P12 = pfYUV420P12
131
+ YUV422P12 = pfYUV422P12
132
+ YUV444P12 = pfYUV444P12
133
+
134
+ YUV420P14 = pfYUV420P14
135
+ YUV422P14 = pfYUV422P14
136
+ YUV444P14 = pfYUV444P14
137
+
138
+ YUV420P16 = pfYUV420P16
139
+ YUV422P16 = pfYUV422P16
140
+ YUV444P16 = pfYUV444P16
141
+
142
+ YUV420PH = pfYUV420PH
143
+ YUV420PS = pfYUV420PS
144
+
145
+ YUV422PH = pfYUV422PH
146
+ YUV422PS = pfYUV422PS
147
+
148
+ YUV444PH = pfYUV444PH
149
+ YUV444PS = pfYUV444PS
150
+
151
+ RGB24 = pfRGB24
152
+ RGB27 = pfRGB27
153
+ RGB30 = pfRGB30
154
+ RGB36 = pfRGB36
155
+ RGB42 = pfRGB42
156
+ RGB48 = pfRGB48
157
+
158
+ RGBH = pfRGBH
159
+ RGBS = pfRGBS
160
+
161
+ class FilterMode(IntEnum):
162
+ PARALLEL = fmParallel
163
+ PARALLEL_REQUESTS = fmParallelRequests
164
+ UNORDERED = fmUnordered
165
+ FRAME_STATE = fmFrameState
166
+
167
+ class AudioChannels(IntEnum):
168
+ FRONT_LEFT = acFrontLeft
169
+ FRONT_RIGHT = acFrontRight
170
+ FRONT_CENTER = acFrontCenter
171
+ LOW_FREQUENCY = acLowFrequency
172
+ BACK_LEFT = acBackLeft
173
+ BACK_RIGHT = acBackRight
174
+ FRONT_LEFT_OF_CENTER = acFrontLeftOFCenter
175
+ FRONT_RIGHT_OF_CENTER = acFrontRightOFCenter
176
+ BACK_CENTER = acBackCenter
177
+ SIDE_LEFT = acSideLeft
178
+ SIDE_RIGHT = acSideRight
179
+ TOP_CENTER = acTopCenter
180
+ TOP_FRONT_LEFT = acTopFrontLeft
181
+ TOP_FRONT_CENTER = acTopFrontCenter
182
+ TOP_FRONT_RIGHT = acTopFrontRight
183
+ TOP_BACK_LEFT = acTopBackLeft
184
+ TOP_BACK_CENTER = acTopBackCenter
185
+ TOP_BACK_RIGHT = acTopBackRight
186
+ STEREO_LEFT = acStereoLeft
187
+ STEREO_RIGHT = acStereoRight
188
+ WIDE_LEFT = acWideLeft
189
+ WIDE_RIGHT = acWideRight
190
+ SURROUND_DIRECT_LEFT = acSurroundDirectLeft
191
+ SURROUND_DIRECT_RIGHT = acSurroundDirectRight
192
+ LOW_FREQUENCY2 = acLowFrequency2
193
+
194
+ class MessageType(IntFlag):
195
+ MESSAGE_TYPE_DEBUG = mtDebug
196
+ MESSAGE_TYPE_INFORMATION = mtInformation
197
+ MESSAGE_TYPE_WARNING = mtWarning
198
+ MESSAGE_TYPE_CRITICAL = mtCritical
199
+ MESSAGE_TYPE_FATAL = mtFatal
200
+
201
+ class CoreCreationFlags(IntFlag):
202
+ ENABLE_GRAPH_INSPECTION = ccfEnableGraphInspection
203
+ DISABLE_AUTO_LOADING = ccfDisableAutoLoading
204
+ DISABLE_LIBRARY_UNLOADING = ccfDisableLibraryUnloading
205
+
206
+ # In this file
207
+ globals().update(MediaType.__members__)
208
+ globals().update(ColorFamily.__members__)
209
+ globals().update(SampleType.__members__)
210
+ globals().update(PresetVideoFormat.__members__)
211
+ globals().update(FilterMode.__members__)
212
+ globals().update(AudioChannels.__members__)
213
+ globals().update(MessageType.__members__)
214
+ globals().update(CoreCreationFlags.__members__)
215
+
216
+ # From vsconstants.pxd
217
+ globals().update(ColorRange.__members__)
218
+ globals().update(ChromaLocation.__members__)
219
+ globals().update(FieldBased.__members__)
220
+ globals().update(MatrixCoefficients.__members__)
221
+ globals().update(TransferCharacteristics.__members__)
222
+ globals().update(ColorPrimaries.__members__)
223
+
224
+ class VapourSynthVersion(typing.NamedTuple):
225
+ release_major: int
226
+ release_minor: int
88
227
 
228
+ def __str__(self):
229
+ if self.release_minor:
230
+ return f'R{self.release_major}.{self.release_minor}'
231
+ return f'R{self.release_major}'
232
+
233
+ class VapourSynthAPIVersion(typing.NamedTuple):
234
+ api_major: int
235
+ api_minor: int
236
+
237
+ def __str__(self):
238
+ return f'R{self.api_major}.{self.api_minor}'
239
+
240
+
241
+ __version__ = VapourSynthVersion(VS_CURRENT_RELEASE, 0)
242
+ __api_version__ = VapourSynthAPIVersion(VAPOURSYNTH_API_MAJOR, VAPOURSYNTH_API_MINOR)
89
243
 
90
244
  @final
91
245
  cdef class EnvironmentData(object):
@@ -201,7 +355,7 @@ cdef void _unset_logger(EnvironmentData env):
201
355
  cdef void __stdcall _logCb(int msgType, const char *msg, void *userData) noexcept nogil:
202
356
  with gil:
203
357
  message = msg.decode("utf-8")
204
- (<object>userData)(MessageType(msgType), message)
358
+ (<object>userData)(msgType, message)
205
359
 
206
360
  cdef void __stdcall _logFree(void* userData) noexcept nogil:
207
361
  with gil:
@@ -326,7 +480,7 @@ def _try_enable_introspection(version=None):
326
480
  return False
327
481
 
328
482
  cdef StandaloneEnvironmentPolicy standalone_policy = StandaloneEnvironmentPolicy.__new__(StandaloneEnvironmentPolicy)
329
- standalone_policy._flags = int(CoreCreationFlags.ccfEnableGraphInspection)
483
+ standalone_policy._flags = ccfEnableGraphInspection;
330
484
  register_policy(standalone_policy)
331
485
 
332
486
  return True
@@ -848,7 +1002,7 @@ cdef void dictToMap(dict ndict, VSMap *inm, VSCore *core, const VSAPI *funcs) ex
848
1002
  ckey = key.encode('utf-8')
849
1003
  val = ndict[key]
850
1004
 
851
- if isinstance(val, (str, bytes, bytearray, RawNode, RawFrame)):
1005
+ if isinstance(val, (str, bytes, bytearray, RawNode, RawFrame, enum.Flag)):
852
1006
  val = [val]
853
1007
  else:
854
1008
  try:
@@ -896,7 +1050,7 @@ cdef void typedDictToMap(dict ndict, dict atypes, VSMap *inm, VSCore *core, cons
896
1050
  if val is None:
897
1051
  continue
898
1052
 
899
- if isinstance(val, (str, bytes, bytearray, enum.Flag, RawNode, RawFrame)) or not isinstance(val, Iterable):
1053
+ if isinstance(val, (str, bytes, bytearray, enum.Flag, RawNode, RawFrame, enum.Flag)) or not isinstance(val, Iterable):
900
1054
  val = [val]
901
1055
 
902
1056
  for v in val:
@@ -1098,7 +1252,7 @@ cdef class FrameProps(object):
1098
1252
  cdef bytes b = name.encode('utf-8')
1099
1253
  cdef const VSAPI *funcs = self.funcs
1100
1254
  val = value
1101
- if isinstance(val, (str, bytes, bytearray, RawNode, RawFrame)):
1255
+ if isinstance(val, (str, bytes, bytearray, RawNode, RawFrame, enum.Flag)):
1102
1256
  val = [val]
1103
1257
  else:
1104
1258
  try:
@@ -1518,7 +1672,7 @@ cdef class _frame:
1518
1672
  cdef:
1519
1673
  unsigned mask
1520
1674
 
1521
- if lib.getFrameType(frame) is VIDEO:
1675
+ if lib.getFrameType(frame) == mtVideo:
1522
1676
  mask = 1 << index+1
1523
1677
  else:
1524
1678
  mask = ~1 # there's only one plane in audio frames
@@ -1578,14 +1732,14 @@ cdef class _video:
1578
1732
  self.base.itemsize = format.bytesPerSample
1579
1733
  self.base.strides[1] = format.bytesPerSample
1580
1734
 
1581
- if format.sampleType == INTEGER:
1735
+ if format.sampleType == stInteger:
1582
1736
  if format.bytesPerSample == 1:
1583
1737
  self.base.format = 'B'
1584
1738
  elif format.bytesPerSample == 2:
1585
1739
  self.base.format = 'H'
1586
1740
  elif format.bytesPerSample == 4:
1587
1741
  self.base.format = 'I'
1588
- elif format.sampleType == FLOAT:
1742
+ elif format.sampleType == stFloat:
1589
1743
  if format.bytesPerSample == 2:
1590
1744
  self.base.format = 'e'
1591
1745
  elif format.bytesPerSample == 4:
@@ -1750,12 +1904,12 @@ cdef class _audio:
1750
1904
  self = _1dview_contig.__new__(_1dview_contig)
1751
1905
  self.base.itemsize = format.bytesPerSample
1752
1906
 
1753
- if format.sampleType == INTEGER:
1907
+ if format.sampleType == stInteger:
1754
1908
  if format.bytesPerSample == 2:
1755
1909
  self.base.format = 'H'
1756
1910
  elif format.bytesPerSample == 4:
1757
1911
  self.base.format = 'I'
1758
- elif format.sampleType == FLOAT:
1912
+ elif format.sampleType == stFloat:
1759
1913
  if format.bytesPerSample == 4:
1760
1914
  self.base.format = 'f'
1761
1915
 
@@ -1921,11 +2075,14 @@ cdef class RawNode(object):
1921
2075
 
1922
2076
  gc.collect()
1923
2077
 
2078
+ def clear_cache(self):
2079
+ self.funcs.clearNodeCache(self.node)
2080
+
1924
2081
  # Inspect API
1925
2082
  cdef bint _inspectable(self):
1926
2083
  if self.funcs.getAPIVersion() != VAPOURSYNTH_API_VERSION:
1927
2084
  return False
1928
- return bool(self.core.flags & CoreCreationFlags.ccfEnableGraphInspection)
2085
+ return bool(self.core.flags & ccfEnableGraphInspection)
1929
2086
 
1930
2087
  def is_inspectable(self, version=None):
1931
2088
  if version != 0:
@@ -1933,11 +2090,30 @@ cdef class RawNode(object):
1933
2090
  return self._inspectable()
1934
2091
 
1935
2092
  @property
1936
- def _node_name(self):
1937
- if not self._inspectable():
1938
- raise Error("This node is not inspectable")
2093
+ def node_name(self):
1939
2094
  return self.funcs.getNodeName(self.node).decode("utf-8")
1940
2095
 
2096
+ property timings:
2097
+ def __get__(self):
2098
+ return self.funcs.getNodeProcessingTime(self.node, False)
2099
+
2100
+ def __set__(self, bint value):
2101
+ if value != 0:
2102
+ raise ValueError('You can only set timings to 0, to reset its counter!')
2103
+
2104
+ self.funcs.getNodeProcessingTime(self.node, True)
2105
+
2106
+ @property
2107
+ def mode(self):
2108
+ return FilterMode(self.funcs.getNodeFilterMode(self.node))
2109
+
2110
+ @property
2111
+ def dependencies(self):
2112
+ return tuple(
2113
+ createNode(self.funcs.addNodeRef(self.funcs.getNodeDependency(self.node, idx).source), self.funcs, self.core)
2114
+ for idx in range(self.funcs.getNumNodeDependencies(self.node))
2115
+ )
2116
+
1941
2117
  @property
1942
2118
  def _name(self):
1943
2119
  if not self._inspectable():
@@ -1952,28 +2128,6 @@ cdef class RawNode(object):
1952
2128
 
1953
2129
  return mapToDict(self.funcs.getNodeCreationFunctionArguments(self.node, 0), False)
1954
2130
 
1955
- @property
1956
- def _timings(self):
1957
- if not self._inspectable():
1958
- raise Error("This node is not inspectable")
1959
- return self.funcs.getNodeFilterTime(self.node)
1960
-
1961
- @property
1962
- def _mode(self):
1963
- if not self._inspectable():
1964
- raise Error("This node is not inspectable")
1965
- return FilterMode(self.funcs.getNodeFilterMode(self.node))
1966
-
1967
- @property
1968
- def _dependencies(self):
1969
- if not self._inspectable():
1970
- raise Error("This node is not inspectable")
1971
-
1972
- return tuple(
1973
- createNode(self.funcs.addNodeRef(self.funcs.getNodeDependencies(self.node)[idx].source), self.funcs, self.core)
1974
- for idx in range(self.funcs.getNumNodeDependencies(self.node))
1975
- )
1976
-
1977
2131
  def __eq__(self, other):
1978
2132
  if other is self:
1979
2133
  return True
@@ -2019,7 +2173,7 @@ cdef class VideoNode(RawNode):
2019
2173
  (<Plugin>obj).injected_arg = self
2020
2174
  return obj
2021
2175
  except AttributeError:
2022
- raise AttributeError(f'There is no attribute or namespace named {name}') from None
2176
+ raise AttributeError(f'There is no attribute or namespace named {name}. Did you mistype a plugin namespace or forget to install a plugin?') from None
2023
2177
 
2024
2178
  cdef ensure_valid_frame_number(self, int n):
2025
2179
  if n < 0:
@@ -2028,13 +2182,13 @@ cdef class VideoNode(RawNode):
2028
2182
  raise ValueError('Requesting frame number is beyond the last frame')
2029
2183
 
2030
2184
  def get_frame(self, int n):
2031
- cdef char errorMsg[512]
2185
+ cdef char errorMsg[4096]
2032
2186
  cdef char *ep = errorMsg
2033
2187
  cdef const VSFrame *f
2034
2188
  self.ensure_valid_frame_number(n)
2035
2189
 
2036
2190
  with nogil:
2037
- f = self.funcs.getFrame(n, self.node, errorMsg, 500)
2191
+ f = self.funcs.getFrame(n, self.node, errorMsg, 4096)
2038
2192
  if f == NULL:
2039
2193
  if (errorMsg[0]):
2040
2194
  raise Error(ep.decode('utf-8'))
@@ -2049,10 +2203,10 @@ cdef class VideoNode(RawNode):
2049
2203
  raise Error('Alpha clip dimensions must match the main video')
2050
2204
  if (self.num_frames != alpha.num_frames):
2051
2205
  raise Error('Alpha clip length must match the main video')
2052
- if (self.vi.format.colorFamily != UNDEFINED) and (alpha.vi.format.colorFamily != UNDEFINED):
2053
- if (alpha.vi.format.colorFamily != GRAY) or (alpha.vi.format.sampleType != self.vi.format.sampleType) or (alpha.vi.format.bitsPerSample != self.vi.format.bitsPerSample):
2206
+ if (self.vi.format.colorFamily != cfUndefined) and (alpha.vi.format.colorFamily != cfUndefined):
2207
+ if (alpha.vi.format.colorFamily != cfGray) or (alpha.vi.format.sampleType != self.vi.format.sampleType) or (alpha.vi.format.bitsPerSample != self.vi.format.bitsPerSample):
2054
2208
  raise Error('Alpha clip format must match the main video')
2055
- elif (self.vi.format.colorFamily != UNDEFINED) or (alpha.vi.format.colorFamily != UNDEFINED):
2209
+ elif (self.vi.format.colorFamily != cfUndefined) or (alpha.vi.format.colorFamily != cfUndefined):
2056
2210
  raise Error('Format must be either known or unknown for both alpha and main clip')
2057
2211
 
2058
2212
  _get_output_dict("set_output")[index] = VideoOutputTuple(self, alpha, alt_output)
@@ -2071,11 +2225,11 @@ cdef class VideoNode(RawNode):
2071
2225
  progress_update(0, len(self))
2072
2226
 
2073
2227
  if y4m:
2074
- if self.format.color_family == GRAY:
2228
+ if self.format.color_family == cfGray:
2075
2229
  y4mformat = 'mono'
2076
2230
  if self.format.bits_per_sample > 8:
2077
2231
  y4mformat = y4mformat + str(self.format.bits_per_sample)
2078
- elif self.format.color_family == YUV:
2232
+ elif self.format.color_family == cfYUV:
2079
2233
  if self.format.subsampling_w == 1 and self.format.subsampling_h == 1:
2080
2234
  y4mformat = '420'
2081
2235
  elif self.format.subsampling_w == 1 and self.format.subsampling_h == 0:
@@ -2228,7 +2382,7 @@ cdef VideoNode createVideoNode(VSNode *node, const VSAPI *funcs, Core core):
2228
2382
  instance.funcs = funcs
2229
2383
  instance.vi = funcs.getVideoInfo(node)
2230
2384
 
2231
- if (instance.vi.format.colorFamily != UNDEFINED):
2385
+ if (instance.vi.format.colorFamily != cfUndefined):
2232
2386
  instance.format = createVideoFormat(&instance.vi.format, funcs, core.core)
2233
2387
  else:
2234
2388
  instance.format = None
@@ -2270,7 +2424,7 @@ cdef class AudioNode(RawNode):
2270
2424
  except AttributeError:
2271
2425
  err = True
2272
2426
  if err:
2273
- raise AttributeError('There is no attribute or namespace named ' + name)
2427
+ raise AttributeError(f'There is no attribute or namespace named {name}. Did you mistype a plugin namespace or forget to install a plugin?')
2274
2428
 
2275
2429
  cdef ensure_valid_frame_number(self, int n):
2276
2430
  if n < 0:
@@ -2279,13 +2433,13 @@ cdef class AudioNode(RawNode):
2279
2433
  raise ValueError('Requesting frame number is beyond the last frame')
2280
2434
 
2281
2435
  def get_frame(self, int n):
2282
- cdef char errorMsg[512]
2436
+ cdef char errorMsg[4096]
2283
2437
  cdef char *ep = errorMsg
2284
2438
  cdef const VSFrame *f
2285
2439
  self.ensure_valid_frame_number(n)
2286
2440
 
2287
2441
  with nogil:
2288
- f = self.funcs.getFrame(n, self.node, errorMsg, 500)
2442
+ f = self.funcs.getFrame(n, self.node, errorMsg, 4096)
2289
2443
  if f == NULL:
2290
2444
  if (errorMsg[0]):
2291
2445
  raise Error(ep.decode('utf-8'))
@@ -2433,17 +2587,64 @@ cdef LogHandle createLogHandle(object handler_func):
2433
2587
 
2434
2588
  cdef void __stdcall log_handler_wrapper(int msgType, const char *msg, void *userData) noexcept nogil:
2435
2589
  with gil:
2436
- (<LogHandle>userData).handler_func(MessageType(msgType), msg.decode('utf-8'))
2590
+ (<LogHandle>userData).handler_func(msgType, msg.decode('utf-8'))
2437
2591
 
2438
2592
  cdef void __stdcall log_handler_free(void *userData) noexcept nogil:
2439
2593
  with gil:
2440
2594
  Py_DECREF(<LogHandle>userData)
2441
2595
 
2596
+
2597
+ cdef class CoreTimings(object):
2598
+ cdef Core core
2599
+
2600
+ cdef object __weakref__
2601
+
2602
+ def __init__(self):
2603
+ raise Error('Class cannot be instantiated directly')
2604
+
2605
+ property enabled:
2606
+ def __get__(self):
2607
+ return bool(self.core.funcs.getCoreNodeTiming(self.core.core))
2608
+
2609
+ def __set__(self, bint enabled):
2610
+ self.core.funcs.setCoreNodeTiming(self.core.core, enabled)
2611
+
2612
+ property freed_nodes:
2613
+ def __get__(self):
2614
+ return self.core.funcs.getFreedNodeProcessingTime(self.core.core, False)
2615
+
2616
+ def __set__(self, bint value):
2617
+ if value != 0:
2618
+ raise ValueError('You can only set freed_nodes to 0, to reset its counter!')
2619
+
2620
+ self.core.funcs.getFreedNodeProcessingTime(self.core.core, True)
2621
+
2622
+ def __repr__(self):
2623
+ return _construct_repr(
2624
+ self, enabled=self.enabled, freed_nodes=self.freed_nodes
2625
+ )
2626
+
2627
+ def __str__(self):
2628
+ return (
2629
+ 'CoreTimings\n'
2630
+ f'\tEnabled: {self.enabled}\n'
2631
+ f'\tFreed Nodes Time: {self.freed_nodes}\n'
2632
+ )
2633
+
2634
+ cdef CoreTimings createCoreTimings(Core core):
2635
+ cdef CoreTimings instance = CoreTimings.__new__(CoreTimings)
2636
+ instance.core = core
2637
+
2638
+ return instance
2639
+
2640
+
2442
2641
  cdef class Core(object):
2443
2642
  cdef int creationFlags
2444
2643
  cdef VSCore *core
2445
2644
  cdef const VSAPI *funcs
2446
2645
 
2646
+ cdef readonly object timings
2647
+
2447
2648
  cdef object __weakref__
2448
2649
 
2449
2650
  def __init__(self):
@@ -2478,6 +2679,12 @@ cdef class Core(object):
2478
2679
  new_size = new_size * 1024 * 1024
2479
2680
  self.funcs.setMaxCacheSize(new_size, self.core)
2480
2681
 
2682
+ @property
2683
+ def used_cache_size(self):
2684
+ cdef VSCoreInfo v
2685
+ self.funcs.getCoreInfo(self.core, &v)
2686
+ return v.usedFramebufferSize
2687
+
2481
2688
  @property
2482
2689
  def flags(self):
2483
2690
  return self.creationFlags
@@ -2491,7 +2698,7 @@ cdef class Core(object):
2491
2698
  if plugin:
2492
2699
  return createPlugin(plugin, self.funcs, self)
2493
2700
  else:
2494
- raise AttributeError('No attribute with the name ' + name + ' exists. Did you mistype a plugin namespace?')
2701
+ raise AttributeError('No attribute with the name ' + name + ' exists. Did you mistype a plugin namespace or forget to install a plugin?')
2495
2702
 
2496
2703
  def plugins(self):
2497
2704
  cdef VSPlugin *plugin = self.funcs.getNextPlugin(NULL, self.core)
@@ -2500,7 +2707,7 @@ cdef class Core(object):
2500
2707
  plugin = self.funcs.getNextPlugin(plugin, self.core)
2501
2708
  yield tmp
2502
2709
 
2503
- def query_video_format(self, ColorFamily color_family, SampleType sample_type, int bits_per_sample, int subsampling_w = 0, int subsampling_h = 0):
2710
+ def query_video_format(self, int color_family, int sample_type, int bits_per_sample, int subsampling_w = 0, int subsampling_h = 0):
2504
2711
  cdef VSVideoFormat fmt
2505
2712
  if not self.funcs.queryVideoFormat(&fmt, color_family, sample_type, bits_per_sample, subsampling_w, subsampling_h, self.core):
2506
2713
  raise Error('Invalid format specified')
@@ -2521,11 +2728,11 @@ cdef class Core(object):
2521
2728
  cdef VSFrame* ref = self.funcs.newVideoFrame(&fmt, width, height, NULL, self.core)
2522
2729
  return createVideoFrame(ref, self.funcs, self.core)
2523
2730
 
2524
- def log_message(self, MessageType message_type, str message):
2731
+ def log_message(self, int message_type, str message):
2525
2732
  self.funcs.logMessage(message_type, message.encode('utf-8'), self.core)
2526
2733
 
2527
2734
  def add_log_handler(self, handler_func):
2528
- handler_func(MESSAGE_TYPE_DEBUG, 'New message handler installed from python')
2735
+ handler_func(mtDebug, 'New message handler installed from python')
2529
2736
  cdef LogHandle lh = createLogHandle(handler_func)
2530
2737
  Py_INCREF(lh)
2531
2738
  lh.handle = self.funcs.addLogHandler(log_handler_wrapper, log_handler_free, <void *>lh, self.core)
@@ -2534,15 +2741,33 @@ cdef class Core(object):
2534
2741
  def remove_log_handler(self, LogHandle handle):
2535
2742
  return self.funcs.removeLogHandler(handle.handle, self.core)
2536
2743
 
2537
- def version(self):
2744
+ def clear_cache(self):
2745
+ self.funcs.clearCoreCaches(self.core)
2746
+
2747
+ @property
2748
+ def core_version(self):
2538
2749
  cdef VSCoreInfo v
2539
2750
  self.funcs.getCoreInfo(self.core, &v)
2540
- return (<const char *>v.versionString).decode('utf-8')
2541
2751
 
2542
- def version_number(self):
2752
+ return VapourSynthVersion(v.core, 0)
2753
+
2754
+ @property
2755
+ def api_version(self):
2543
2756
  cdef VSCoreInfo v
2544
2757
  self.funcs.getCoreInfo(self.core, &v)
2545
- return v.core
2758
+
2759
+ api_major = (v.api >> 16)
2760
+ api_minor = v.api - (api_major << 16)
2761
+
2762
+ return VapourSynthAPIVersion(api_major, api_minor)
2763
+
2764
+ def version(self):
2765
+ warnings.warn('core.version() is deprecated, use str(core)!', DeprecationWarning)
2766
+ return str(self)
2767
+
2768
+ def version_number(self):
2769
+ warnings.warn('core.version_number() is deprecated, use core.core_version.release_major!', DeprecationWarning)
2770
+ return self.core_version.release_major
2546
2771
 
2547
2772
  def __dir__(self):
2548
2773
  plugins = []
@@ -2551,38 +2776,37 @@ cdef class Core(object):
2551
2776
  return super(Core, self).__dir__() + plugins
2552
2777
 
2553
2778
  def __repr__(self):
2554
- cdef VSCoreInfo v
2555
- self.funcs.getCoreInfo(self.core, &v)
2556
-
2557
- api_major = (v.api >> 16)
2558
- api_minor = v.api - (api_major << 16)
2559
-
2560
- api_v = api_major + api_minor / 10
2561
-
2562
2779
  return _construct_repr(
2563
- self, core_version=v.core, api_version=api_v, num_threads=v.numThreads,
2564
- max_cache_size=(<int64_t>v.maxFramebufferSize + 1024 * 1024 - 1) // <int64_t>(1024 * 1024)
2780
+ self, core_version=self.core_version, api_version=self.api_version,
2781
+ num_threads=self.num_threads, max_cache_size=self.max_cache_size,
2782
+ used_cache_size=self.used_cache_size
2565
2783
  )
2566
2784
 
2567
2785
  def __str__(self):
2568
- version_lines = [x.strip() for x in self.version().splitlines()]
2786
+ cdef VSCoreInfo v
2787
+ self.funcs.getCoreInfo(self.core, &v)
2788
+
2789
+ versionString = (<const char *>v.versionString).decode('utf-8')
2790
+
2791
+ version_lines = [x.strip() for x in versionString.splitlines()]
2569
2792
  copyright = '\n'.join(version_lines[:2])
2570
2793
  version = '\n\t'.join(version_lines[2:])
2571
2794
 
2572
2795
  return (
2573
- f'{copyright}\n\t{version}\n'
2796
+ f'{copyright}\n'
2797
+ f'\t{version}\n'
2574
2798
  f'\tNumber of Threads: {self.num_threads:d}\n'
2575
2799
  f'\tMax Cache Size: {self.max_cache_size:d}\n'
2576
2800
  )
2577
2801
 
2578
2802
  cdef object createNode(VSNode *node, const VSAPI *funcs, Core core):
2579
- if funcs.getNodeType(node) == VIDEO:
2803
+ if funcs.getNodeType(node) == mtVideo:
2580
2804
  return createVideoNode(node, funcs, core)
2581
2805
  else:
2582
2806
  return createAudioNode(node, funcs, core)
2583
2807
 
2584
2808
  cdef object createConstFrame(const VSFrame *f, const VSAPI *funcs, VSCore *core):
2585
- if funcs.getFrameType(f) == VIDEO:
2809
+ if funcs.getFrameType(f) == mtVideo:
2586
2810
  return createConstVideoFrame(f, funcs, core)
2587
2811
  else:
2588
2812
  return createConstAudioFrame(f, funcs, core)
@@ -2591,17 +2815,36 @@ cdef Core createCore(EnvironmentData env):
2591
2815
  cdef Core instance = Core.__new__(Core)
2592
2816
  instance.funcs = getVapourSynthAPI(VAPOURSYNTH_API_VERSION)
2593
2817
  if instance.funcs == NULL:
2594
- raise Error('Failed to obtain VapourSynth API pointer. System does not support SSE2 or is the Python module and loaded core library mismatched?')
2818
+ raise Error('Failed to obtain VapourSynth API pointer. Is the Python module and loaded core library mismatched?')
2595
2819
  instance.core = instance.funcs.createCore(env.coreCreationFlags)
2820
+ instance.timings = createCoreTimings(instance)
2596
2821
  instance.creationFlags = env.coreCreationFlags
2822
+ if instance.core_version.release_major <> VS_CURRENT_RELEASE:
2823
+ instance.log_message(mtWarning, f'Version mismatch: The VapourSynth Python module version is R{__version__.release_major:d} but the VapourSynth core library is R{instance.core_version.release_major:d}. This usually indicates a broken install.')
2597
2824
  return instance
2598
2825
 
2599
2826
  cdef Core createCore2(VSCore *core):
2600
2827
  cdef Core instance = Core.__new__(Core)
2828
+ cdef VSMap *min
2829
+ cdef VSMap *mout
2830
+ cdef VSPlugin *plugin
2831
+ cdef VSNode *node
2601
2832
  instance.funcs = getVapourSynthAPI(VAPOURSYNTH_API_VERSION)
2602
2833
  if instance.funcs == NULL:
2603
- raise Error('Failed to obtain VapourSynth API pointer. System does not support SSE2 or is the Python module and loaded core library mismatched?')
2834
+ raise Error('Failed to obtain VapourSynth API pointer. Is the Python module and loaded core library mismatched?')
2604
2835
  instance.core = core
2836
+ instance.timings = createCoreTimings(instance)
2837
+ if instance.core_version.release_major <> VS_CURRENT_RELEASE:
2838
+ instance.log_message(mtWarning, f'Version mismatch: The VapourSynth Python module version is R{__version__.release_major:d} but the VapourSynth core library is R{instance.core_version.release_major:d}. This usually indicates a broken install.')
2839
+ plugin = instance.funcs.getPluginByID('com.vapoursynth.std', core)
2840
+ min = instance.funcs.createMap()
2841
+ mout = instance.funcs.invoke(plugin, "BlankClip", min)
2842
+ instance.funcs.freeMap(min)
2843
+ node = instance.funcs.mapGetNode(mout, "clip", 0, NULL)
2844
+ instance.funcs.freeMap(mout)
2845
+ if instance.funcs.getNodeCreationFunctionName(node, 0) <> NULL:
2846
+ instance.creationFlags = ccfEnableGraphInspection
2847
+ instance.funcs.freeNode(node)
2605
2848
  return instance
2606
2849
 
2607
2850
  cdef Core _get_core(threads = None):
@@ -2625,8 +2868,21 @@ cdef class _CoreProxy(object):
2625
2868
  def core(self):
2626
2869
  return _get_core()
2627
2870
 
2871
+ @property
2872
+ def core_version(self):
2873
+ return __version__
2874
+
2875
+ @property
2876
+ def api_version(self):
2877
+ return __api_version__
2878
+
2879
+ def version(self):
2880
+ warnings.warn('core.version() is deprecated, use str(core)!', DeprecationWarning)
2881
+ return str(self)
2882
+
2628
2883
  def version_number(self):
2629
- return __version__[0]
2884
+ warnings.warn('core.version_number() is deprecated, use core.core_version.release_major!', DeprecationWarning)
2885
+ return self.core_version.release_major
2630
2886
 
2631
2887
  def __dir__(self):
2632
2888
  d = dir(self.core)
@@ -2649,13 +2905,12 @@ cdef class _CoreProxy(object):
2649
2905
 
2650
2906
  return _construct_repr(self, core=core_repr)
2651
2907
 
2652
-
2653
2908
  def __str__(self):
2654
2909
  if _env_current() is None:
2655
2910
  return (
2656
2911
  'Uninitialized Environment:\n'
2657
- f'\tCore R{__version__[0]}\n'
2658
- f'\tAPI R{__api_version__[0]}.{__api_version__[1]}\n'
2912
+ f'\tCore {__version__:s}\n'
2913
+ f'\tAPI {__api_version__:s}\n'
2659
2914
  '\tOptions: Unknown\n'
2660
2915
  '\tNumber of Threads: Unknown\n'
2661
2916
  '\tMax Cache Size: Unknown\n'
@@ -2705,6 +2960,14 @@ cdef class Plugin(object):
2705
2960
  ver_minor = (ver_major > -1) and (ver - (ver_major << 16)) or 0
2706
2961
 
2707
2962
  return PluginVersion(ver_major, ver_minor)
2963
+
2964
+ @property
2965
+ def plugin_path(self):
2966
+ cdef const char *ppath = self.funcs.getPluginPath(self.plugin)
2967
+ if ppath:
2968
+ return ppath.decode('utf-8')
2969
+ else:
2970
+ return None
2708
2971
 
2709
2972
  def __dir__(self):
2710
2973
  attrs = []
@@ -2908,7 +3171,7 @@ def _showwarning(message, category, filename, lineno, file=None, line=None):
2908
3171
 
2909
3172
  s = warnings.formatwarning(message, category, filename, lineno, line)
2910
3173
  core = vsscript_get_core_internal(env)
2911
- core.log_message(MESSAGE_TYPE_WARNING, s)
3174
+ core.log_message(mtWarning, s)
2912
3175
 
2913
3176
  class PythonVSScriptLoggingBridge(logging.Handler):
2914
3177
 
@@ -3312,6 +3575,25 @@ cdef public api int vpy4_getAltOutputMode(VSScript *se, int index) nogil:
3312
3575
  if isinstance(output, VideoOutputTuple):
3313
3576
  return output[2]
3314
3577
  return 0
3578
+
3579
+ cdef public api int vpy4_getAvailableOutputNodes(VSScript *se, int size, int *dst) nogil:
3580
+ cdef int dstidx = 0
3581
+ with gil:
3582
+ pyenvdict = <dict>se.pyenvdict
3583
+ nodes = None
3584
+ try:
3585
+ nodes = _get_vsscript_policy().get_environment(se.id).outputs
3586
+ except:
3587
+ return 0
3588
+
3589
+ if size > 0:
3590
+ for key in nodes:
3591
+ dst[dstidx] = key
3592
+ dstidx = dstidx + 1
3593
+ if size - dstidx <= 0:
3594
+ break
3595
+
3596
+ return len(nodes)
3315
3597
 
3316
3598
  cdef public api int vpy_clearOutput(VSScript *se, int index) nogil:
3317
3599
  with gil: