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.

 

Go Back   Doom9's Forum > Capturing and Editing Video > VapourSynth

Reply
 
Thread Tools Search this Thread Display Modes
Old 7th February 2021, 08:32   #4201  |  Link
feisty2
I'm Siri
 
feisty2's Avatar
 
Join Date: Oct 2012
Location: void
Posts: 2,633
Quote:
Originally Posted by lansing View Post

But I need to wrap the whole script inside this warnings.catch_warnings in order to catch them.
no need.

Code:
import logging

class MessageAbsorber(logging.Handler):
    def __init__(self, MessageContainer):
        logging.Handler.__init__(self)
        self.MessageContainer = MessageContainer
    def emit(self, MessageRecord):
        self.MessageContainer += [MessageRecord.getMessage()]

WarningMessages = []
logging.captureWarnings(True)
logging.getLogger('py.warnings').addHandler(MessageAbsorber(WarningMessages))

def PassWarningMessagesToCxxPrograms():
    return WarningMessages

# user script goes here

core.vsedit.PythonEval(PassWarningMessagesToCxxPrograms)
feisty2 is offline   Reply With Quote
Old 8th February 2021, 06:34   #4202  |  Link
lansing
Registered User
 
Join Date: Sep 2006
Posts: 1,657
Quote:
Originally Posted by feisty2 View Post
no need.

Code:
import logging

class MessageAbsorber(logging.Handler):
    def __init__(self, MessageContainer):
        logging.Handler.__init__(self)
        self.MessageContainer = MessageContainer
    def emit(self, MessageRecord):
        self.MessageContainer += [MessageRecord.getMessage()]

WarningMessages = []
logging.captureWarnings(True)
logging.getLogger('py.warnings').addHandler(MessageAbsorber(WarningMessages))

def PassWarningMessagesToCxxPrograms():
    return WarningMessages

# user script goes here

core.vsedit.PythonEval(PassWarningMessagesToCxxPrograms)
I came to understand the logging part after some reading, but I still don't get the last line, what is this PythonEval() and how does it talk to C++?

The script will be pass to vsscript_evaluateScript(), which doesn't return warning messages. Where do this PythonEval() play in the process?
lansing is offline   Reply With Quote
Old 8th February 2021, 07:29   #4203  |  Link
feisty2
I'm Siri
 
feisty2's Avatar
 
Join Date: Oct 2012
Location: void
Posts: 2,633
PythonEval() is a special C++ filter that takes a python function as its argument and returns nothing. it's somewhat similar to std.LoadPlugin() or std.SetMaxCPU() in terms of functionality (an infrastructure function rather than an actual filter that applies some processing to a video clip). its implementation should be something similar to #4274, basically it retrieves the warning messages by calling the foreign python function and sends all retrieved messages to stderr thru vsapi->logMessage()
feisty2 is offline   Reply With Quote
Old 8th February 2021, 09:49   #4204  |  Link
lansing
Registered User
 
Join Date: Sep 2006
Posts: 1,657
Quote:
Originally Posted by feisty2 View Post
PythonEval() is a special C++ filter that takes a python function as its argument and returns nothing. it's somewhat similar to std.LoadPlugin() or std.SetMaxCPU() in terms of functionality (an infrastructure function rather than an actual filter that applies some processing to a video clip). its implementation should be something similar to #4274, basically it retrieves the warning messages by calling the foreign python function and sends all retrieved messages to stderr thru vsapi->logMessage()
If I get this right, you're saying to create a dummy vs filter to sends the collected messages through stdder, and then in the C++ side, retrieve the messages through stdder and then output them with vsapi->logMessage()?
lansing is offline   Reply With Quote
Old 8th February 2021, 10:02   #4205  |  Link
feisty2
I'm Siri
 
feisty2's Avatar
 
Join Date: Oct 2012
Location: void
Posts: 2,633
no, it sends the collected messages TO stderr BY USING vsapi->logMessage(), read the documentation of vaporsynth's C API. any string passed to logMessage() already automatically appears in vsedit, you don't need any extra stuff.
feisty2 is offline   Reply With Quote
Old 8th February 2021, 10:18   #4206  |  Link
lansing
Registered User
 
Join Date: Sep 2006
Posts: 1,657
Quote:
Originally Posted by feisty2 View Post
no, it sends the collected messages TO stderr BY USING vsapi->logMessage(), read the documentation of vaporsynth's C API. any string passed to logMessage() already automatically appears in vsedit, you don't need any extra stuff.
So the chain would be like this?

Code:
collected messages -> dummy vs filter -> inside dummy vs filter -> logMessage()
lansing is offline   Reply With Quote
Old 8th February 2021, 10:20   #4207  |  Link
feisty2
I'm Siri
 
feisty2's Avatar
 
Join Date: Oct 2012
Location: void
Posts: 2,633
yes,,,
feisty2 is offline   Reply With Quote
Old 8th February 2021, 10:31   #4208  |  Link
lansing
Registered User
 
Join Date: Sep 2006
Posts: 1,657
Quote:
Originally Posted by feisty2 View Post
yes,,,
Thanks, I'll work on it.
lansing is offline   Reply With Quote
Old 10th February 2021, 10:34   #4209  |  Link
feisty2
I'm Siri
 
feisty2's Avatar
 
Join Date: Oct 2012
Location: void
Posts: 2,633
@Myrsloik
should I release *frameData instantly if an exception is thrown from the arAllFramesReady branch? or should I just leave it unhandled and expect it gets deleted when getFrame() is invoked again with arError?

basically, this
Code:
try {
    if (auto& ResourceHandle = reinterpret_cast<ResourceType*&>(*frameData); activationReason == arInitial)
        ResourceHandle = new auto{ FilterInstance->AcquireResources(...) };
    else if (activationReason == arAllFramesReady) {
        auto ManagedResourceHandle = std::unique_ptr<ResourceType>{ ResourceHandle };
        auto GeneratedFrame = FilterInstance->DrawFrame(*ManagedResourceHandle, ...);
        // if DrawFrame() throws an exception, *ResourceHandle is instantly released
        // by the destructor of std::unique_ptr

        return GeneratedFrame.ReleaseOwnership();
    }
    else if (activationReason == arError)
        delete ResourceHandle;
        // possible double-free here?

    return nullptr;
}
catch (RuntimeError& ErrorMessage) {
    FrameContext.RaiseError(ErrorMessage);
    return nullptr;
}
or this
Code:
try {
    if (auto& ResourceHandle = reinterpret_cast<ResourceType*&>(*frameData); activationReason == arInitial)
        ResourceHandle = new auto{ FilterInstance->AcquireResources(...) };
    else if (activationReason == arAllFramesReady) {
        auto GeneratedFrame = FilterInstance->DrawFrame(*ResourceHandle, ...);
        // no leak if DrawFrame() throws an exception
        // *ResourceHandle will be released later from the arError branch

        delete ResourceHandle;
        return GeneratedFrame.ReleaseOwnership();
    }
    else if (activationReason == arError)
        delete ResourceHandle;
    return nullptr;
}
catch (RuntimeError& ErrorMessage) {
    FrameContext.RaiseError(ErrorMessage);
    return nullptr;
}
?
feisty2 is offline   Reply With Quote
Old 10th February 2021, 10:39   #4210  |  Link
Myrsloik
Professional Code Monkey
 
Myrsloik's Avatar
 
Join Date: Jun 2003
Location: Kinnarps Chair
Posts: 2,548
Quote:
Originally Posted by feisty2 View Post
@Myrsloik
should I release *frameData instantly if an exception is thrown from the arAllFramesReady branch? or should I just leave it unhandled and expect it gets deleted when getFrame() is invoked again with arError?

basically, this
...
?
You can't get an "exception" or error in arAllFramesReady. All frames are already successfully produced so I'm not sure what you're asking. And if there is an error arAllFramesReady won't be called, only arError, so obviously you should free the frameData there.
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet
Myrsloik is offline   Reply With Quote
Old 10th February 2021, 10:49   #4211  |  Link
feisty2
I'm Siri
 
feisty2's Avatar
 
Join Date: Oct 2012
Location: void
Posts: 2,633
the exception is thrown from the user defined function DrawFrame() when for instance, a required frame property is missing from the input (basically any situation that involves setFilterError() in a C plugin).
feisty2 is offline   Reply With Quote
Old 10th February 2021, 11:02   #4212  |  Link
feisty2
I'm Siri
 
feisty2's Avatar
 
Join Date: Oct 2012
Location: void
Posts: 2,633
oh I see, I think I kinda get it now, so arError indicates error getting an input frame, not error in an attempt to generate an output frame, is that right?
feisty2 is offline   Reply With Quote
Old 10th February 2021, 11:22   #4213  |  Link
Myrsloik
Professional Code Monkey
 
Myrsloik's Avatar
 
Join Date: Jun 2003
Location: Kinnarps Chair
Posts: 2,548
Quote:
Originally Posted by feisty2 View Post
oh I see, I think I kinda get it now, so arError indicates error getting an input frame, not error in an attempt to generate an output frame, is that right?
Exactly!
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet
Myrsloik is offline   Reply With Quote
Old 11th February 2021, 07:32   #4214  |  Link
lansing
Registered User
 
Join Date: Sep 2006
Posts: 1,657
Quote:
Originally Posted by lansing View Post
Thanks, I'll work on it.
I have created a dummy filter and passed in a list from the script to the filter, but I couldn't figure out the right syntax to retrieve it in C.

script
Code:
core.vsedit.Logger(["message 1", "message 2"])
dummy.c
Code:
static void VS_CC logger(VSMap* in, VSMap* out, void *userData, VSCore* core, const VSAPI* vsapi) {
    char messages[] = vsapi->propGetData(in, "name", 0, NULL);

    int i = 0;
    while (messages[i]) {
        vsapi->logMessage("WARNING", messages[i]);        
        i++;
    }
}

VS_EXTERNAL_API(void) VapourSynthPluginInit(VSConfigPlugin configFunc, VSRegisterFunction registerFunc, VSPlugin* plugin) {
    configFunc("com.vsedit.logger", "vsedit", "VapourSynth Logger", VAPOURSYNTH_API_VERSION, 1, plugin);
    registerFunc("Logger", "name:data[]", &logger, 0, plugin);
}
I couldn't get this to compile.
lansing is offline   Reply With Quote
Old 11th February 2021, 09:06   #4215  |  Link
feisty2
I'm Siri
 
feisty2's Avatar
 
Join Date: Oct 2012
Location: void
Posts: 2,633
Code:
auto logger(auto in, auto, auto, auto, auto vsapi) {
    for (auto x : Range{ vsapi->propNumElements(in, "name") })
        vsapi->logMessage(VSMessageType::mtWarning, vsapi->propGetData(in, "name", x, nullptr));
}
feisty2 is offline   Reply With Quote
Old 11th February 2021, 09:28   #4216  |  Link
feisty2
I'm Siri
 
feisty2's Avatar
 
Join Date: Oct 2012
Location: void
Posts: 2,633
Quote:
Code:
char messages[] = vsapi->propGetData(in, "name", 0, NULL);
apparently you're not very familiar with C constructs, you cannot initialize a char array from a pointer (note that string literals are of type const char[N], not const char*, an array type can decay to a pointer type, but arrays and pointers are distinct entities). it's better if you just avoid C stuff all together.
feisty2 is offline   Reply With Quote
Old 11th February 2021, 09:44   #4217  |  Link
lansing
Registered User
 
Join Date: Sep 2006
Posts: 1,657
Quote:
Originally Posted by feisty2 View Post
apparently you're not very familiar with C constructs, you cannot initialize a char array from a pointer (note that string literals are of type const char[N], not const char*, an array type can decay to a pointer type, but arrays and pointers are distinct entities). it's better if you just avoid C stuff all together.
Yes C is confusing to me, it gave me a headache even trying to do simple thing like converting int to string.
lansing is offline   Reply With Quote
Old 11th February 2021, 17:07   #4218  |  Link
lansing
Registered User
 
Join Date: Sep 2006
Posts: 1,657
I got the dummy filter printing messages now, but for some reason the logging module is not catching warnings on evaluation

Code:
import logging

class MessageAbsorber(logging.Handler):
    def __init__(self, message_container):
        logging.Handler.__init__(self)
        self.messageContainer = message_container
    def emit(self, message_record):
        self.messageContainer += [message_record.getMessage()]

WarningMessages = []
logging.captureWarnings(True)
logging.getLogger('py.warnings').addHandler(MessageAbsorber(WarningMessages))

def get_warnings():
    return WarningMessages

import vapoursynth as vs

core = vs.get_core()
core2 = vs.get_core()
core3 = vs.get_core()
clip = core.dgdecodenv.DGSource(r'video.dgi')
clip.set_output()

core.vsedit.Logger(get_warnings())
The same codes worked on PyCharm, but in vseditor, I'm getting error about the WarningMessages list still being empty. It will print if I passed in a list core.vsedit.Logger(["message1", "message2"])

Update: I think the reason for this is because vs disabled the warnings so they aren't even logged.

Last edited by lansing; 12th February 2021 at 01:41. Reason: update
lansing is offline   Reply With Quote
Old 12th February 2021, 13:20   #4219  |  Link
feisty2
I'm Siri
 
feisty2's Avatar
 
Join Date: Oct 2012
Location: void
Posts: 2,633
@Myrsloik
Does the flags field of the VSVideoInfo object passed to setVideoInfo() partially determine the cache mode of the output node (along with the flags argument passed to createFilter()), or is it simply ignored?
feisty2 is offline   Reply With Quote
Old 12th February 2021, 13:27   #4220  |  Link
Myrsloik
Professional Code Monkey
 
Myrsloik's Avatar
 
Join Date: Jun 2003
Location: Kinnarps Chair
Posts: 2,548
Quote:
Originally Posted by feisty2 View Post
@Myrsloik
Does the flags field of the VSVideoInfo object passed to setVideoInfo() partially determine the cache mode of the output node (along with the flags argument passed to createFilter()), or is it simply ignored?
It's simply ignored and is filled out with the flags passed to createFilter()
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet
Myrsloik is offline   Reply With Quote
Reply

Tags
speed, vaporware, vapoursynth

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 11:48.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.