Log in

View Full Version : How to invoke another filter (sometimes) on my filter's output?


wonkey_monkey
7th December 2016, 16:22
Hi,

I'm writing a filter which may, at times, need to display a message. I'm something of a trial-and-error programmer so I've never quite grasped the proper use of classes and invoking in AviSynth :o

My filter has a number of input clips and produces an output clip. My GetFrame does the following standard thing:

PVideoFrame dst=env->NewVideoFrame(vi);


to create a new output frame, then writes to the buffer given by dst->GetWritePtr(); and returns dst.

What I'd like to know is: before I return, can I then invoke some other filter (subtitle, specifically) on what I've just painted? If so, what's the recommended way? I need to do inside GetFrame, as only some frames will be getting subtitled.

Previously I've only ever invoked filters on input clips, prior to them being read by my GetFrame.

---

Followup question: if my filter is internally multithreaded, is there some way/need to inform newer versions of AviSynth (+, MT, etc, I don't follow them much) of this so it doesn't try to do it itself?

StainlessS
7th December 2016, 17:24
I'm fairly sure that you have used Info.h metrics in the past, and so shall not suggest that (but DDigit also prints in color, but not always too appealingly in YV12).
DDigit:- http://forum.doom9.org/showthread.php?t=156888&highlight=ddigit

Presumably the text is not static, so will require call from within GetFrame.

Here a couple of links that might be worth your time.

http://forum.doom9.org/showthread.php?p=1776368&highlight=invoke#post1776368

Eval: http://forum.doom9.org/showthread.php?p=1785164#post1785164

I'll pass on the MT q.

EDIT: This thread has Info.h metrics capability with both frame and string formatting:- http://forum.doom9.org/showthread.php?t=163082

wonkey_monkey
7th December 2016, 18:32
I'm fairly sure that you have used Info.h metrics in the past, and so shall not suggest that

I haven't, so please do suggest it. Which I guess you sort of already did.

StainlessS
7th December 2016, 19:12
DDigit has frame and string formatting (eg "\n" frame and "%.6.2f" string), and color, vertical print, character and pixel coords.

Info.h and sister header InfoF.h (also both available in DDigit zip [dont use old bugged versions of Info.h, IanB did a refactor a few years back])
also provide frame/string formatting using eg this code snippet from to 'CPP for C Proggers' thread.


void __stdcall INTERNALNAME::DrawFStr(PVideoFrame &dst,int x,int y,const char *format, ...)
{
// This member function added in v0.2, adds BOTH string and screen formatting, eg '%f' for string and '\n' for screen.

// Firstly, string formatting, into the buffer implemented in the class instance, formatted_buf[FMT_BUFSZ].
va_list args;
va_start(args, format);
_vsnprintf(formatted_buf,FMT_BUFSZ-1, format, args);
va_end(args);

// The DrawFStrXXX fn's are implemented in the InfoF.h file and provide screen formatting, eg '\n' and '\t'.
// As string formatting has already been done above (eg floats etc turned to character strings), and the below
// DrawFStrXXX functions provide screen formatting, so full formatting is achieved on the video frame.
//
// Formatting control codes (as provided by InfoF.h):-
// '\n', Newline, positioning cursor 1 line down and at left edge of screen.
// '\r', Newline Special, moves 1 line down and positions cursor at on-entry X position.
// '\b', Backspace, obvious, not sure how useful this will be.
// '\f', Forward Space, again obvious, re-uses formfeed code for this. Again, maybe not so useful.
// '\t', Tab, @ character positions, every 4 characters.(relative screen LHS).
//
if(vi.IsPlanar()) DrawFStrPlanar(dst,x,y,formatted_buf);
else if(vi.IsYUY2()) DrawFStrYUY2(dst,x,y,formatted_buf);
else if(vi.IsRGB32()) DrawFStrRGB32(dst,x,y,formatted_buf);
else if(vi.IsRGB24()) DrawFStrRGB24(dst,x,y,formatted_buf);
}


See the graphic in this post, http://forum.doom9.org/showthread.php?p=1539764#post1539764
that chunk of text at bottom is result of a single DrawFStr() call using Info.h (white only text).
DDigit can do all of that + color + vertical print. I use DDigit all of the time (occasionally Info/InfoF.h),
only other plug that has used it (to my knowledge) is Frustrum's AutoLevels.

EDIT:
DDigitTest (in Developer folder in MediaFire below this post in sig), is a source code library, but has a demo function
called DDigitTest, so you can see what it can do. Info/InfoF.h is separately available in Developer folder and also in
DDigit zip.
If you have seen GamMac plugin images, then you have already seen DDigit in action (also used in many other
of my plugins).

EDIT: Not much of a demo but below shows colored text in GamMac() metrics using DDigit:-
https://s20.postimg.cc/brdtn4nel/Pup_A_zpsznn6pzoc.png (https://postimg.cc/image/srwpvt0ft/)

Info/InfoF.h combo can do same, but not in color.
RT_Subtitle() also uses DDigit library, and can also print in color for Script metrics (way faster than Subtitle in ScriptClip).
EDIT: Also either Info.h or DDigit in GetFrame() would be well faster than Subtitle.

EDIT:
From InfoF.H header giving frame formatted output (RGB24 only shown)

void __stdcall DrawFStringRGB24(PVideoFrame &dst,int x,int y,const char *s,bool pix = true)
{ // Draw formatted string at pixel or character coords, pix == false = character coords
if(pix == false) {x *= 10; y *= 20;} // To Chars
int in_x = x; // REM x for '\r'
const unsigned char *se=(unsigned char*)s; // unsigned
while(*se) { // while, some to do
int n;
for(s=(char*)se; n = *se, n>=' ' && n <= 223; ++se); // Find end+1 of printable
int len = (char*)se - s; // Len of printable
if (len) { // Some to print
DrawStringRGB24(dst,x,y,s,len); // do the biz # EDIT: Call Info.h
x += len * 10; // update x coord
} else { // Ctrl code OR nonsense;
if(n == '\n') {
x = 0; y+=20; // Newline, down 1, LHS
} else if (n == '\r') {
x = in_x; y +=20; // Newline Special, Down 1, orig x coord
} else if(n == '\b') {
x -= 10; // Backward Space
} else if (n == '\f') {
x += 10; // Forward Space
} else if (n == '\t') {
x+= ((4*10)-(x%(4*10))); // H-Tab (step 4)
}
++se; // skip ctrl code (and unknowns, outer loop detects nul sentinel)
}
}
}

void __stdcall DrawFStrRGB24(PVideoFrame &dst,int x,int y,const char *s)
{ // Formatted Print @ character coords
DrawFStringRGB24(dst,x,y,s,false);
}

Wilbert
7th December 2016, 20:07
Use ApplyMessage: http://avisynth.nl/index.php/Filter_SDK/Cplusplus_API#ApplyMessage.2C_v5

StainlessS
7th December 2016, 20:34
Note, ApplyMessage as above req AVISYNTH_HEADER version 5+, so even if RGB only, needs v2.6 plugin, otherwise
you need to (if I remember correctly) #include "Internal.h", from core, so as to get at ApplyMessage.

EDIT: Also, think I'm correct in saying that nobody should ever use Avisynth header v5, causes crashes in current version
Final 2.6, cant remember why (just come in from pub). :) (where v2.6 plug, use v 6 header).

wonkey_monkey
7th December 2016, 23:58
:thanks:

StainlessS
8th December 2016, 02:27
It has just come to my attention that DDigit timing test only works if used in VDub, time does not show if played in some kind of media player, (does not seem to always show last frame with result time, frame) not sure if I care tooo much though. :(

EDIT: All media players tried failed to render the last frame with timing results, this in itself is a little concerning, vdub
always shows last frame (all versions tested). Why dont media players play last frame ???