PDA

View Full Version : few letters on a clip


Wilbert
1st December 2005, 00:22
I want to make a filter which outputs just a few letters on a black clip. What is an easy way to do this?

neuron2
1st December 2005, 02:28
Why not BlankClip() + Subtitle()?

Wilbert
1st December 2005, 10:33
Because i'm making a vectorscope and wanted to know how to put letters on it (to denote the colors). ShowSMPTE and ShowFrameNumber use this

HDC hdc = antialiaser.GetDC();
SetTextAlign(hdc, TA_BASELINE|TA_CENTER);
TextOut(hdc, x*8, y*8-48, text, strlen(text));
GdiFlush();

antialiaser.Apply(vi, &frame, frame->GetPitch());

stuff. I was wondering whether this was all necessary just to put some letters on a clip.

neuron2
1st December 2005, 15:03
You can use code like what Telecide() uses for show=true.

Bidoche
1st December 2005, 17:24
Unless for bitmap fonts, text rendering is a big work.

sh0dan
1st December 2005, 19:46
The easiest way is probably to use render the background, when the filter is created, keep the PVideoFrame as a class member and use bitblit to blit it into a new frame on every frame. That way you keep the cost of the textrendering to one blit per frame, which is very acceptable.

If you're doing a plugin:

Constructor:
PClip c = env->Invoke("Blankclip",blah..blah);
c = env->Invoke("Subtitle", blah...blah);
PVideoFrame staticframe = c->GetFrame(0, env);
vi = c->GetVideoInfo();

GetFrame:
PVideoFrame dst = env->NewVideoFrame(vi);
env->BitBlt(dst, staticframe);

... or something close to that.

Bidoche
6th December 2005, 17:22
@sh0dan

That method doesn't get the correct antialiased output DEPENDING on the frame on which you renders.

To get the correct one, it's the antialiaser that should be kept as member.

sh0dan
7th December 2005, 19:04
That method doesn't get the correct antialiased output DEPENDING on the frame on which you renders.

I can't see that Wilbert writes anywhere, that he wants to change the text every frame. If it's the background for a vectorscope he might just want to add text to a background on which the scope is written, the method above should be ok.

Wilbert
7th December 2005, 20:45
I can't see that Wilbert writes anywhere, that he wants to change the text every frame.
No, i don't want to change the text. I decided not to use text on the vectorscope though :)

I'm still interested in how to do it though, because this
The easiest way is probably to use render the background, when the filter is created, keep the PVideoFrame as a class member (...)
is a bit too cryptic for me :)

mg262
7th December 2005, 21:56
It would be great to have some sort of straightforward text-writing helper-function callable via AVISynth.h... there's a lot of filters out there that could do with it for debug mode.

IanB
8th December 2005, 23:15
@Wilbert,class Foo {
PVideoFrame staticframe; // Always available
...
}

@mg262,

You can always use the internal.h interface and access the guts of the text rendering, just remember if you do so you must release the source code in a compliant manner. We can't make everything available to the secret source shops. ;)

mg262
8th December 2005, 23:42
Ian, are you advocating hackerishly bypassing the provided interface and accessing implementation-internal code?!? Doesn't sound like you ;)

IanB
9th December 2005, 01:04
Now where did that tongue-in-cheek icon go :D:D:D

mg262
9th December 2005, 14:18
This library...

http://freetype.sourceforge.net/freetype2/index.html

... looks interesting.

Bidoche
9th December 2005, 16:04
avs 3 uses Freetype for its text rendering.
As it needed something for the linux version... finally it uses it for Windows as well.

Personally I won't qualify it as interesting but rather as a **** ** *** ***.

Chainmax
9th December 2005, 20:37
An annoyance in the buttocks? :p

d'Oursse
28th December 2005, 14:18
the design of freetype is ugly and the documentation is, well, hmm, unreadable.
beside that, it's a very good library.
here is waht is done in avs3 : http://avisynth3.unite-video.com/avs_text.png (with freetype)

Bidoche
28th December 2005, 18:21
Using freetype in avs3 allowed one improvement in rendering :
The calculation of halos is now perfectly exact.

Not that it matters much with the classical 1 pixel wide halo... but it can do fractional widths as well


Anyway, you can merge the freetype code in the 2.5 branch if you dare.
good Luck, you will need it ;p

IanB
30th December 2005, 14:23
@Bidoche,

Question, how fast is freetype at painting new text per frame.

I did some work on the text painting engine a while ago, I wanted to improve ShowFrameNumber(), turns out I wasted my time (well Subtitle got a minor speed increase). The Windoze GDI stuff take years to scribble text into a buffer. Masking the text onto the frame take no time in comparison.

Bidoche
30th December 2005, 15:40
@IanB

I do not know exactly, never benchmarked it.

But my bet would be the freetype scheme is faster.

Not so much coz it's freetype and not gdi, but because of how the antialiasing is done :
- current scheme uses gdi to renders in black and white at x8 size and count lit dots in a 8x8 square ... takes forever as it counts lots of 0 for naught

- freetype scheme renders text into transitions (from black to white and reverse) at x8 size ... that means when you count the dots in 8x8 squares you go from transition to transition and skip counting the black dots.

WarpEnterprises
27th January 2006, 22:50
The easiest way is probably to use render the background, when the filter is created, keep the PVideoFrame as a class member and use bitblit to blit it into a new frame on every frame.

(1) For a fixed text this seems a nice way.
I used it for a variable text and it works. I don't care about speed because quite often text-output is used only as debugging/adjusting help and not in the final run, and using Subtitle has the advantage that I don't have to care about colorspace settings:
(code in a plugin-GetFrame)
const char* arg_names[8] = { 0, 0, "x", "y", "font", "size", "text_color", "halo_color"};
AVSValue args[9] = {child, AVSValue(message),posx,posy, font, size, text_color, halo_color};
PClip resultClip = (env->Invoke("Subtitle",AVSValue(args, 9), arg_names )).AsClip();
PVideoFrame dst = resultClip->GetFrame(n, env);
//now here you have the Subtitle'd frame

(2) I tried a version in a source filter which works, but maybe is a bit hacky?
class myfilter : public IClip {
int level=0;
...
GetFrame(int n, IScriptEnvironment* env) {
if (level==0) { //avoid recursive calls
strcpy(message, "some message");
const char* arg_names[9] = { 0, 0, "x", "y", "first_frame", "font", "size", "text_color", "halo_color"};
AVSValue args[9] = {this, AVSValue(message),posx,posy, -1, font, size, text_color, halo_color};
level = 1;
resultClip = (env->Invoke("Subtitle", AVSValue(args, 9), arg_names )).AsClip();
dst = resultClip->GetFrame(n, env);
level = 0;
return dst;
}
//here comes the true code for GetFrame

Is way (2) OK / very bad / or has anybody a nicer recipe?