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. Domains: forum.doom9.org / forum.doom9.net / forum.doom9.se |
|
|
#21 | Link |
|
Registered User
Join Date: Jan 2005
Location: Praha (not that one in Texas)
Posts: 863
|
OK, i see:
Few options how to deal with this issue depending how much rounding errors bother you... Let's clear Code:
#drawsrtm5=lutexpression resulting in mask (0,255) #drawsrtm6=lutexpression resulting in mask (0,256) #drawsrtm16=lutexpression resulting in 16bit mask (0,65535) #if no better idea #drawsrtm16=drawsrtm5 256 * drawsrtm5 128 - 2 * #drawsrtm6=drawsrtm16 256 / Code:
picture=mt_lutspa(c,drawstry+ " 256 "+drawstrm6+" - * 128 + 256 /") mask=mt_lutspa(c,drawstrm5) mask2=mt_lutspa(c,drawstrm5+" 128 - 2 *") result1=mt_lutxy(c,mask,"x y * 128 + 256 /") #i don't know any faster multiplication algorithm axcept my modification of AverageM result2=mt_lutxy(c,mask2,"x y * 128 + 256 /") Average(picture, 1.0, result1, 1.0, result2, 1/256) |
|
|
|
|
|
#22 | Link |
|
Registered User
Join Date: Jan 2005
Location: Praha (not that one in Texas)
Posts: 863
|
Unless you want to go to higher bitdepth like dither...
...this should be fast and precise Code:
picture=mt_lutspa(c,drawstry) #4 masks (I still believe, lutspa runs only once per clip, so this should be no efficiency issue, otherwise and in case of real masks we might need binarize...) m_up=mt_lutspa(c,drawstrm6+" 128 -") m_dn=mt_lutspa(c,drawstrm6+" 128 max") m_n_up=mt_lutspa(c,"256 "+drawstrm6+" - 128 -") m_n_dn=mt_lutspa(c,"256 "+drawstrm6+" - 128 max") AverageM(c, m_up, c, m_dn, picture, m_n_up, picture, m_n_dn) (c*m_up+c*m_dn+picture*m_n_up+picture*m_n_dn+128)/256 which should be quite fast. Definitely faster than your script. Moreover, you can use (0;256) masks this way... But, it does all color planes always... Average thread Last edited by redfordxx; 4th November 2011 at 09:40. |
|
|
|
|
|
#23 | Link |
|
Excessively jovial fellow
Join Date: Jun 2004
Location: rude
Posts: 1,100
|
Excuse me for being the devil's advocate, but why exactly have you written 100 lines of masktools voodoo to do something that is trivially accomplished with blankclip, crop, stack(vertical|horizontal) and overlay? There are also several other existing ways to do this using various plugins (textsub and assrender allow you to render arbitrary vector drawings with subpixel precision, for example), most of which render roughly an order of magnitude faster.
I understanding coding for the sake of coding and being fascinated with one's own cleverness, but this does seem a bit excessive. Last edited by TheFluff; 8th November 2011 at 15:33. |
|
|
|
|
|
#24 | Link |
|
Registered User
Join Date: Jan 2006
Posts: 1,869
|
I looked at textsub and assrender, and see no way that they can draw arbitrary shapes. They both take a special text file. About the only way to draw anything might be with spaces, and even then it would be very difficult to specify they're exact coordinates. Finally, they don't accept any kind of yuv colors.
We both tried blank/crop/stack, it's slow and quite awkward (not trivial), but the killer is overlay is not precise enough. It converts everything to it's internal format, mixes, then converts back again, making it slow and imprecise. Both crop and overlay have bugs: http://avisynth.org/mediawiki/Known_Issues By all means, if you can think of a way to draw a few types of shapes in YUV directly, quickly and accurately, please let me know! Most people seem to want only masks of 255 in certain shapes, but I want to make specifically test patterns (not just colorbars). Last edited by jmac698; 8th November 2011 at 17:18. |
|
|
|
|
|
#25 | Link |
|
Registered User
Join Date: Oct 2007
Posts: 135
|
So what you're saying here is, you looked at textsub and assrender as plugins, but did not spend any time whatsoever looking at the ass format that they, er... render before coming to this conclusion? Because you're completely wrong, and TheFluff is absolutely correct.
|
|
|
|
|
|
#26 | Link |
|
Registered User
Join Date: Jan 2006
Posts: 1,869
|
No, I did look at the formats. Here's a link: http://matroska.org/technical/specs/subtitles/ssa.html
I also read both manuals. No mention of drawing shapes. You don't have to use such wording; if there's no obvious mention of how to do this, it's understandable that I can't find it. I looked again and still can't find it. I didn't explain a further point of using text files; this doesn't help me draw shapes programaticaly (sp?). As I mentioned I'm making test images; some of them I'd like to animate as well. |
|
|
|
|
|
#28 | Link | |
|
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,442
|
Quote:
Also, conversion in Overlay doesn't change luma of YUV inputs, though yes, YUY2 and YV12 chroma will be internally upsampled to 4:4:4. But in any case, your function is far more complex than it need be. There is no need to use (the extremely slow loading) mt_lutxyz, or to have a special case opacity=256. You can use opacity=255 to mean full opacity, and implement the function as follows: 1. Create the (luma and chroma) mask using mt_lutspa, setting pixels to 'opacity' in the drawing region and zero elsewhere. 2. Use mt_lutxy to process the input clip and mask to set output = (mask*color + (255-mask)*input)/255 where color is the specified drawing color (for each of y, u, v). That's it! |
|
|
|
|
|
|
#29 | Link | |
|
Excessively jovial fellow
Join Date: Jun 2004
Location: rude
Posts: 1,100
|
Quote:
The least incomplete documentation of the ASS format that I am aware of is available in the manual for the Aegisub subtitle editor. There are several modified versions of VSFilter (textsub) floating around that add their own custom extensions, but the stuff that the Aegisub manual covers is supported in all known modern versions. For the vector drawing stuff, take a look at the bottom of the page linked above, under the heading "Drawing commands". That said, even the ancient document I was referring to above, which the Matroska page you mention links to, mentions the drawing tags. The syntax is still the same despite the format being old enough to drive a car in some jurisdictions. A feature of the ASS format's vector drawing mode that is worth mentioning is that since it's actually a real vector drawing system, it uses its own internal coordinate system that is completely unrelated to the video pixel grid, which means that any shapes you draw with it can be rendered at any video resolution without modification of the drawing commands. It also means you can actually render with subpixel precision if you so desire. If you want to generate animated shapes programatically, Avisynth script seems like an exceptionally bad choice of programming language. Even if you use grunt and/or gscript it still seems like an incredibly annoying task. ASS subtitle files are plain text; it's rather trivial to generate them programatically in almost any language. There is also a multitude of existing tools for generating such files in various ways already. Aegisub, for example, comes both with a vector drawing tool that outputs ASS drawing commands, as well as with a complete scripting system intended for generating and manipulating ASS subtitle files (and much like with Avisynth scripting, there is a rather big library of user-contributed scripts written for this scripting system). Last edited by TheFluff; 8th November 2011 at 23:17. |
|
|
|
|
|
|
#30 | Link | |
|
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,442
|
Quote:
Code:
drawstry=buildrectexp(xl, yl, xh, yh, y, 16, filled)
drawstru=buildrectexp(xl2, yl2, xh2, yh2, u, 128, filled)
drawstrv=buildrectexp(xl2, yl2, xh2, yh2, v, 128, filled)
drawstrm=buildrectexp(xl, yl, xh, yh, opacity, 0, filled)
drawstrmuv=buildrectexp(xl2, yl2, xh2, yh2, opacity, 0, filled)
mergeit(c, drawstry, drawstru, drawstrv, drawstrm, drawstrmuv, opacity)
}
function mergeit(clip c, string drawstry, string drawstru, string drawstrv, string drawstrm, string drawstrmuv, int opacity){
mt_lutspa(c, mode="absolute", yexpr=drawstry, uexpr=drawstru, vexpr=drawstrv, chroma="process")
mask=mt_lutspa(c, mode="absolute", yexpr=drawstrm, uexpr=drawstrmuv, vexpr=drawstrmuv, chroma="process")
opacity==256?mt_lutxyz(c, mask, last, expr="y 255 = z x ?", chroma="process"):mt_merge(c, last, mask, luma=true, chroma="process")
}
Code:
drawstrm=buildrectexp(xl, yl, xh, yh, opacity, 0, filled)
drawstrmuv=buildrectexp(xl2, yl2, xh2, yh2, opacity, 0, filled)
mask=mt_lutspa(c, mode="absolute", yexpr=drawstrm, uexpr=drawstrmuv, vexpr=drawstrmuv, chroma="process")
mt_lutxy(c, mask, yexpr=drawstr(y), uexpr=drawstr(u), vexpr=drawstr(v), chroma="process")
}
function drawstr(int clr) {
return string(clr)+ " y * 255 y - x * + 255 /"
}
|
|
|
|
|
|
|
#31 | Link | |
|
Registered User
Join Date: Jan 2006
Posts: 1,869
|
@Dogway,
Quote:
@Gavino Thanks, I used some of your suggestions, and still have a full range for opacity. @Fluff I found the documentation for drawing, but it only does lines and splines, so I can't draw a circle. Also it only specifies colors in RGB, so it's impossible to create certain YUV colors. And now my script is almost 170 lines, and that's because Avisynth is missing so many features. That reminds me of the day I tried Gimp. I wanted to draw a circle, but couldn't figure out how. Then I read a doc which said "Gimp can't draw circles, but that's not what it's for...". I gave up on Gimp on that day. @any I'd like to make this deepcolor compatible, but I discovered yet another bug in 2.6a3 which prevents me. Last edited by jmac698; 9th November 2011 at 17:56. |
|
|
|
|
|
|
#32 | Link | ||
|
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,442
|
Quote:
The latter seems more natural to me and the former introduces an unnecessary special case into the code for no appreciable gain. But then it's your function, so please yourself. ![]() BTW Your 'higher' and 'lower' functions can be replaced by 'min' and 'max' (since v2.58). Quote:
Perhaps you want a (faster) option that just sets the luma. |
||
|
|
|
|
|
#33 | Link |
|
Registered User
Join Date: Jan 2006
Posts: 1,869
|
Updated. Thanks for the suggestion.
I have to use opacity(0,256) solely for the important case of 128, which gives an exact average. I could even add another special case for that and use averagem which is apparently faster. Oh, how horrid would that be
|
|
|
|
|
|
#34 | Link |
|
Registered User
Join Date: Jan 2006
Posts: 1,869
|
Here's my function which will break if floats ever change in avisynth:
Code:
x1=getword1(65536*256+256*1+3,0)
x2=getword2(65536*256+256*1+3,0)
messageclip("Result of getword1="+string(x1)+" result of getword2="+string(x2))
function getword1(int n, int p, int "size"){
#Get word p of size size from n, limited to p=(0,2)
#Warning: due to the implementation in avisynth, p=2 and size=2 gives wrong answers
size=default(size, 1)
f=pow(2,8*size*2)
p2=floor(n/f)
n=n-p2*f#This subtraction won't work in some cases when n is int and f is float
f=pow(2,8*size*1)
p1=floor(n/f)
n=n-p1*f
p0=n
int(p==0?p0:p==1?p1:p2)
}
function getword2(int n, int p, int "size"){
#Get word p of size size from n, limited to p=(0,2)
#Warning: only works with an assumed implementation in avisynth
size=default(size, 1)
f=int(pow(2,8*size*2))
p2=n/f
n=n-p2*f
f=int(pow(2,8*size*1))
p1=n/f
n=n-p1*f
p0=n
int(p==0?p0:p==1?p1:p2)
}
|
|
|
|
|
|
#36 | Link | |
|
Excessively jovial fellow
Join Date: Jun 2004
Location: rude
Posts: 1,100
|
Quote:
I don't see how "certain YUV colors" can be impossible to create either (the YUV<->RGB conversion formula is not exactly rocket science), and I most certainly don't see what the GIMP team's design decision to not make it a vector art tool has to do with all of this. |
|
|
|
|
|
|
#37 | Link |
|
Registered User
Join Date: Jan 2006
Posts: 1,869
|
I need to do my computations in the format (float or int) which has enough precision for them; in my case I want to extract words from a packed deepcolor value, which takes 3*16=48 bits. So it turns out I can't do this anyway. It's bad enough that Avisynth doesn't handle deepcolor, but it's a real pain when I can't even store a single color properly. I need much higher precision.
Another problem is trying to pass around multiple values in the language itself; it just can't be done. I guess my problem is the single return value isn't big enough to even pack my answer into. |
|
|
|
|
|
#39 | Link | |
|
Excessively jovial fellow
Join Date: Jun 2004
Location: rude
Posts: 1,100
|
Quote:
You could probably write a standalone C program that does what your script does on uncompressed video files in less lines of code than your entire script, even if you included file I/O operations. |
|
|
|
|
|
|
#40 | Link | ||
|
Registered User
Join Date: Jan 2006
Posts: 1,869
|
@Fluff
Quote:
Two problems: I'm afraid you don't understand the finer points of colorspaces. It would take negative rgb components to cover all the normal yuv colors. Here's an example calculation for -Q in Rec601: y = 16, cb = 158, cr = 95 for rgb [16,235]: r = 219*(-0.2067)+16 = -29, g = 219*0.0588+16 = 29, b = 219*0.2394+16 = 68 From http://avisynth.org/mediawiki/ColorBars_theory which is actually from a discussion I started years ago, resulting in proper colorbars colors in avisynth 2.56: http://forum.doom9.org/showthread.php?t=107682&page=2 Quote:
|
||
|
|
|
![]() |
| Thread Tools | Search this Thread |
| Display Modes | |
|
|