Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
22nd January 2021, 06:28 | #4161 | Link | |
ангел смерти
Join Date: Nov 2004
Location: Lost
Posts: 9,558
|
Quote:
You're intentionally cutting your userbase off in order to experiment with bleeding edge features, which is fine in the abstract, but marks the project as unsuitable for anyone else. |
|
22nd January 2021, 11:22 | #4162 | Link |
I'm Siri
Join Date: Oct 2012
Location: void
Posts: 2,633
|
the latest version of all 3 mainstream compilers (GCC, Clang, MSVC) have supported many C++20 features, both GCC and Clang have implemented full support for concepts, and MSVC has partial support for it. I can imagine that MSVC should be able to catch up in the following months and my project should work with all mainstream compilers by the time I finish writing the documentation. CentOS is dead so not supporting it is no big deal, regardless of that, GCC is capable of bootstrapping, just download the source code of the latest version and build it with whatever version you already have, you certainly don't need to reinstall your OS to run the latest version of GCC. what's the point really to use Linux if you can't even compile GCC from scratch...
concepts is a must-have in order to design a flexible interface in C++, it is by far the only facility to express type-level equivariance in C++, take the following polymorphic function f() for example: Code:
auto f(auto&& x) { if constexpr (requires { { x.g() }->Iterable; }) if constexpr (requires { { *x.g().begin() }->SubtypeOf<VideoInfo>; }) return std::vector<VideoNode>{}; else if constexpr (requires { { *x.g().begin() }->SubtypeOf<AudioInfo>; }) return std::vector<AudioNode>{}; else static_assert(AlwaysFalse<decltype(x)>, "Type Error!"); else if constexpr (requires { { x.g() }->SubtypeOf<VideoInfo>; }) return VideoNode{}; else if constexpr (requires { { x.g() }->SubtypeOf<AudioInfo>; }) return AudioNode{}; else static_assert(AlwaysFalse<decltype(x)>, "Type Error!"); } you simply cannot write such f() without concepts. you can try mimicking it using SFINAE in older versions of C++ and I guarantee that your code will be an unreadable and unmaintainable mess in no time. therefore concepts is absolutely essential if you agree that the user's freewill matters. edit: simple proof that shows f() is indeed equivariant at the type level for types that it can handle. let F() denote f() at the type level, [] denote a type operator that transforms any type T to std::vector<T>. we have that: F([VideoInfo]) = [VideoNode] [F(VideoInfo)] = [VideoNode] F([AudioInfo]) = [AudioNode] [F(AudioInfo)] = [AudioNode] therefore F() satisfies F(G∙T) = G∙F(T), where G = [], T = VideoInfo, AudioInfo. Last edited by feisty2; 22nd January 2021 at 13:47. |
22nd January 2021, 20:09 | #4163 | Link |
Registered User
Join Date: May 2011
Posts: 321
|
Not that is important, but tried to subclass videonode, if for example could use custom attributes like clip.rgb, clip.isError etc:
Code:
class My_videonode(vs.VideoNode): def __init__(self, clip, *args, **kwargs): super(My_videonode, self).__init__(*args,**kwargs) my_videonode = My_videonode(clip1) from here: https://github.com/vapoursynth/vapou...synth.pyx#L954 is it possible, or is it stupid idea, it could be done differently sure, or forget it? |
22nd January 2021, 20:13 | #4164 | Link |
I'm Siri
Join Date: Oct 2012
Location: void
Posts: 2,633
|
use VaporMagik, it allows you to do dangerous things to native extensions, not just VideoNode, you can even modify the behavior of built-in types like list or int
|
22nd January 2021, 21:41 | #4165 | Link |
Registered User
Join Date: May 2011
Posts: 321
|
thank you,
I think I saw it before, really advanced script for me, thinking what it would be good for :-) . I tried to butcher it a bit and came up with this, which works. So I might use it. Interesting. I realized also I could also use collections.namedtuple lib, not sure how I would implement it yet. But your VaporMagik seams to be fun: Code:
import ctypes import builtins class PyObject(ctypes.Structure): pass PyObject._fields_ = [ ('ob_refcnt', ctypes.c_ssize_t), ('ob_type', ctypes.POINTER(PyObject)), ] class NativeMappingProxy(PyObject): _fields_ = [('UnderlyingDictionary', ctypes.POINTER(PyObject))] def Dereference(Pointer): ObjectHolder = [] ctypes.pythonapi.PyList_Append(ctypes.py_object(ObjectHolder), Pointer) return ObjectHolder[0] def ExposeAttributeDictionary(Type): AttributeMaps = Type.__dict__ TransparentAttributeMaps = NativeMappingProxy.from_address(id(AttributeMaps)) return Dereference(TransparentAttributeMaps.UnderlyingDictionary) def SetTypeAttribute(Type, Name, Attribute): AttributeDictionary = ExposeAttributeDictionary(Type) AttributeDictionary[Name] = Attribute ctypes.pythonapi.PyType_Modified(ctypes.py_object(Type)) @property def rgb(self): return self.resize.Bicubic(format=vs.RGB24) SetTypeAttribute(vs.VideoNode, 'rgb', rgb) clip = core.avisource.AVISource(file.avi) print(clip) print(clip.rgb) Last edited by _Al_; 22nd January 2021 at 21:45. |
22nd January 2021, 22:15 | #4166 | Link |
Registered User
Join Date: May 2011
Posts: 321
|
is it possible using VaporMagik to do get things out of tuple to atribute:
Code:
@property def rgb(self): #action of converting return rgb_clip, isError, log #returned is vs.VideoNode, bool and string #something: SetTypeAttribute(vs.VideoNode, 'rgb', rgb) clip = core.avisource.AVISource(file.avi) print(clip) print(clip.rgb) print(clip.isError) print(clip.log) #or maybe better print(clip.rgb) print(clip.rgb.isError) print(clip.rgb.log) #or print(clip.rgb[0], clip.rgb[1], clip.rgb[2]) |
23rd January 2021, 09:00 | #4168 | Link |
Registered User
Join Date: May 2011
Posts: 321
|
ok, I got that, thanks, but then I could not figure out how to have array/list of clips done by that, that code is too much for me, I settled with something like this at the end:
Code:
import vapoursynth as vs from vapoursynth import core import collections class Clips(list): def __init__(self, inputs): list.__init__(self,[]) self.Clip_data = collections.namedtuple('Clip_data', ['clip','rgb','isError','log','output_index']) if isinstance(inputs, type(vs.get_outputs())): inputs = [ (clip, output_index) for output_index, clip in inputs.items()] elif isinstance(inputs, list): inputs = [ (clip, None) for clip in inputs] else: raise ValueError('wrong input') for clip, output_index in inputs: self.append(self.set(clip, output_index)) def set(self, clip, output_index=None): rgb, isError, log = self.toRGB(clip) #other work return self.Clip_data(clip=clip, rgb=rgb, isError=isError, log=log, output_index=output_index) def replace(self, index, clip, output_index=None): self[index] = self.set(clip, output_index) def appending(self, clip, output_index=None): self.append(self.set(clip, output_index)) def toRGB(self, c): #conversion to rgb, mocking a return for show return core.resize.Bicubic(c, matrix_in_s='170m',format=vs.RGB24), False, 'this is a conversion log' vs.clear_outputs() clip = core.std.BlankClip(format=vs.YUV420P8) clip.set_output(0) bright = clip.std.Expr(['x 40 +','','']) bright.set_output(1) clips = Clips([clip, bright]) ##clips = Clips(vs.get_outputs()) print(clips[0].clip) print(clips[0].rgb) print(clips[0].log) print(clips[1].clip) #... #replacing clip on index 1 brightest = clip.std.Expr(['x 100 +','','']) clips.replace(1, brightest) #apending clip clip = core.std.BlankClip(color=(255,0,0)).resize.Point(matrix_s='170m',format=vs.YUV420P8) clips.appending(clip) |
23rd January 2021, 12:39 | #4169 | Link | |
I'm Siri
Join Date: Oct 2012
Location: void
Posts: 2,633
|
Quote:
Code:
@Inject def f(self: list): for x in self: print(x) [1, 2, 3, 4].f() # prints "1 2 3 4" Last edited by feisty2; 23rd January 2021 at 12:42. |
|
25th January 2021, 23:20 | #4170 | Link |
Registered User
Join Date: May 2011
Posts: 321
|
ok thanks, I used dataclass at the end, same syntax as namedtuple, I understand it, and it can assign and change attributes directly (namedtuple has awkward syntax). Not saying that VaporMagik cannot do that, most likely yes.
|
27th January 2021, 07:12 | #4171 | Link |
I'm Siri
Join Date: Oct 2012
Location: void
Posts: 2,633
|
@Myrsloik
could you explain how getFrame() is invoked with different activation reasons, particularly the case involving arAllFramesReady && !*frameData? it seems getFrame() might be invoked twice with the same activation reason, what happens after getFrame() exits from the arAllFramesReady && !*frameData branch and before it gets invoked again? if several frames (either from the same node or from several nodes) are requested in the arAllFramesReady && !*frameData branch, is it guaranteed that all requested frames are ready before the next call to getFrame()? there seems to be 4 types of filters with different getFrame() skeletons: standard filters arInitial -> RequestReferenceFrames() arAllFramesReady -> DrawFrame() source filters arInitial -> DrawFrame() special filters (e.g. std.FrameEval) arInitial -> RequestReferenceFrames() arAllFramesReady && !*frameData -> RequestSpecialResources() arAllFramesReady -> DrawFrame() special(or weird?) source filters arInitial && !*frameData -> RequestSpecialResources() arInitial -> DrawFrame() any other possibilities? also is it possible to get a concrete error message if the arError branch is activated? |
27th January 2021, 11:09 | #4172 | Link | |
Professional Code Monkey
Join Date: Jun 2003
Location: Kinnarps Chair
Posts: 2,548
|
Quote:
At the end of each invocation either an output frame must be returned OR there must be outstanding frame requests (requestFrameFilter). First call is always arInitial to make things clear. Once all requested frames are available arAllFramesReady is called. You're allowed to request additional frames in arAllFramesReady which will then result in getting called with arAllFramesReady again and you can repeat this as many times as you like. Errors may be propagated from other filters at any time after the arInitial call and then it's not the filter's job to handle it, only to clean up any allocated resources and return nothing. The error message is always propagated to the original requester to display. (As in whoever called getFrame/getFrameAsync) Your last weird example is obviously invalid since it'll have outstanding frame requests when returning an output frame.
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet |
|
27th January 2021, 12:51 | #4173 | Link | |
I'm Siri
Join Date: Oct 2012
Location: void
Posts: 2,633
|
Quote:
Code:
if (activationReason == arInitial) if constexpr (requires { { filter->RequestResources() }->AnyBut<void>; }) *frameData = new auto{ filter->RequestResources() }; else if constexpr (requires { filter->RequestResources(); }) // fails to satisfy AnyBut<void>, therefore returns void, equivalent to RequestReferenceFrames() filter->RequestResources(); else if constexpr (requires { { filter->DrawFrame() }->SubtypeOf<FrameReference>; }) // source filter return filter->DrawFrame().Leak(); else static_assert(AlwaysFalse<decltype(filter)>, "missing attribute!"); |
|
28th January 2021, 07:49 | #4174 | Link |
I'm Siri
Join Date: Oct 2012
Location: void
Posts: 2,633
|
what happens if there's no frame requested or generated in the arInitial branch (empty branch)? it might happen in rare cases like the following
Code:
if (activationReason == arInitial) for (auto& node : inputs) // inputs might be an empty container depending on the user input node.RequestFrame(n, FrameContext); |
28th January 2021, 09:59 | #4175 | Link | |
Professional Code Monkey
Join Date: Jun 2003
Location: Kinnarps Chair
Posts: 2,548
|
Quote:
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet |
|
1st February 2021, 04:39 | #4176 | Link |
Registered User
Join Date: Sep 2006
Posts: 1,657
|
How does the api getCoreInfo2() function works? It asks for the core and VSCoreInfo as parameters. But the only way to get the VSCoreInfo from the document is by using api->getCoreInfo(), but it also said that this function was deprecated.
|
1st February 2021, 06:15 | #4177 | Link | |
I'm Siri
Join Date: Oct 2012
Location: void
Posts: 2,633
|
Quote:
|
|
Tags |
speed, vaporware, vapoursynth |
Thread Tools | Search this Thread |
Display Modes | |
|
|