Log in

View Full Version : Freezing chroma


valja
23rd August 2005, 22:06
The FreezeFrame filter FreezeFrame(first-frame, last-frame, source-frame) replaces all the frames between first-frame and last-frame with a copy of source-frame. But is there a filter or simple way to do the same thing with only chroma channel and left luma untouched? In other words, for some frames replace only chroma by a copy from other frame?

scharfis_brain
23rd August 2005, 22:09
mergechroma(FreezeFrame(first-frame, last-frame, source-frame))

valja
23rd August 2005, 22:25
mergechroma(FreezeFrame(first-frame, last-frame, source-frame))

Thanx! Really simple. I should be able to discover it myself :(

valja
24th August 2005, 06:23
mergechroma(FreezeFrame(first-frame, last-frame, source-frame))

Well, that's working just as I wanted, but can anybody explayn, why replacing lines

FreezeFrame(first-frame, last-frame, source-frame)

by

mergechroma(FreezeFrame(first-frame, last-frame, source-frame))

makes the script dead slow? I'm recoding VHS rip (PAL MPEG2 720x576 and neuron2 decoder) where some 80 frames need correction. With just FreezeFrame the script with Convolution3D, resize etc is working 6-8 fps, but with MergeChroma it works about 1 fps (even without Convolution3D, resize etc).

Any way to fight against it?

IanB
25th August 2005, 13:31
:script: Complete script please.

valja
25th August 2005, 17:19
:script: Complete script please.Well, here's script:
LoadPlugin("d:\DGDecode.dll")
MPEG2Source("planeta.d2v",cpu=0,iPP=true)
ConverttoYUY2()
crop(0,4,-16,-12)
AssumeTFF()
FieldDeinterlace(blend=false)
MergeChroma(FreezeFrame(1298,1298,1297))
MergeChroma(FreezeFrame(1317,1317,1316))
MergeChroma(FreezeFrame(1318,1318,1319))
MergeChroma(FreezeFrame(1329,1329,1328))
MergeChroma(FreezeFrame(1357,1357,1356))
MergeChroma(FreezeFrame(1364,1364,1363))
MergeChroma(FreezeFrame(1368,1368,1367))
MergeChroma(FreezeFrame(1405,1405,1404))
MergeChroma(FreezeFrame(1419,1419,1418))
MergeChroma(FreezeFrame(1421,1421,1420))
MergeChroma(FreezeFrame(1422,1424,1421))
MergeChroma(FreezeFrame(1425,1427,1428))
MergeChroma(FreezeFrame(1430,1430,1429))
MergeChroma(FreezeFrame(1437,1441,1436))
MergeChroma(FreezeFrame(1442,1445,1446))
MergeChroma(FreezeFrame(1447,1447,1446))
MergeChroma(FreezeFrame(1449,1450,1451))
MergeChroma(FreezeFrame(1453,1453,1452))
MergeChroma(FreezeFrame(1456,1456,1457))
MergeChroma(FreezeFrame(1464,1464,1463))
MergeChroma(FreezeFrame(1481,1481,1482))
MergeChroma(FreezeFrame(1489,1489,1490))
MergeChroma(FreezeFrame(1497,1497,1498))
MergeChroma(FreezeFrame(1519,1519,1520))
MergeChroma(FreezeFrame(1547,1547,1548))
MergeChroma(FreezeFrame(1592,1592,1591))
MergeChroma(FreezeFrame(1598,1598,1597))
MergeChroma(FreezeFrame(1605,1605,1606))
MergeChroma(FreezeFrame(1625,1625,1626))
MergeChroma(FreezeFrame(1633,1638,1632))
MergeChroma(FreezeFrame(1642,1642,1643))
MergeChroma(FreezeFrame(1651,1651,1650))
MergeChroma(FreezeFrame(1654,1658,1653))
MergeChroma(FreezeFrame(1659,1662,1663))
MergeChroma(FreezeFrame(1664,1664,1665))
MergeChroma(FreezeFrame(1667,1667,1666))
MergeChroma(FreezeFrame(1668,1668,1669))
MergeChroma(FreezeFrame(1671,1672,1670))
MergeChroma(FreezeFrame(1674,1682,1673))
MergeChroma(FreezeFrame(1684,1686,1683))
MergeChroma(FreezeFrame(1713,1713,1712))
MergeChroma(FreezeFrame(1777,1777,1776))
MergeChroma(FreezeFrame(1826,1827,1825))
MergeChroma(FreezeFrame(1848,1849,1847))
MergeChroma(FreezeFrame(1862,1864,1861))
MergeChroma(FreezeFrame(1872,1872,1871))
MergeChroma(FreezeFrame(1872,1872,1871))
MergeChroma(FreezeFrame(1875,1875,1874))
MergeChroma(FreezeFrame(1877,1877,1876))
MergeChroma(FreezeFrame(1884,1884,1883))
MergeChroma(FreezeFrame(1900,1900,1901))
MergeChroma(FreezeFrame(1903,1903,1904))
MergeChroma(FreezeFrame(1914,1916,1913))
MergeChroma(FreezeFrame(1917,1917,1916))
MergeChroma(FreezeFrame(3464,3464,3463))
MergeChroma(FreezeFrame(3688,3688,3687))
MergeChroma(FreezeFrame(3723,3723,3722))
FreezeFrame(3929,3929,3928)
MergeChroma(FreezeFrame(3986,3986,3987))
MergeChroma(FreezeFrame(4383,4383,4382))
MergeChroma(FreezeFrame(4427,4427,4426))
MergeChroma(FreezeFrame(4454,4454,4453))
MergeChroma(FreezeFrame(4473,4473,4472))
MergeChroma(FreezeFrame(4810,4810,4809))
MergeChroma(FreezeFrame(4851,4851,4852))
MergeChroma(FreezeFrame(4854,4854,4853))
MergeChroma(FreezeFrame(4865,4865,4864))
MergeChroma(FreezeFrame(5062,5062,5061))
MergeChroma(FreezeFrame(5073,5073,5072))
MergeChroma(FreezeFrame(5079,5079,5078))
MergeChroma(FreezeFrame(5090,5090,5089))
MergeChroma(FreezeFrame(5094,5094,5093))
MergeChroma(FreezeFrame(5096,5099,5095))
MergeChroma(FreezeFrame(5101,5101,5102))
MergeChroma(FreezeFrame(5124,5124,5123))
MergeChroma(FreezeFrame(5168,5168,5167))
MergeChroma(FreezeFrame(5224,5224,5223))
MergeChroma(FreezeFrame(5258,5259,5260))
MergeChroma(FreezeFrame(7729,7729,7728))
MergeChroma(FreezeFrame(23245,23245,23244))
MergeChroma(FreezeFrame(23407,23407,23406))
MergeChroma(FreezeFrame(24901,24901,24900))
MergeChroma(FreezeFrame(25538,25538,25539))
MergeChroma(FreezeFrame(25580,25580,25579))
MergeChroma(FreezeFrame(25615,25615,25614))
MergeChroma(FreezeFrame(71882,71882,71881))
MergeChroma(FreezeFrame(71887,71887,71886))
MergeChroma(FreezeFrame(72068,72068,72067))
MergeChroma(FreezeFrame(72070,72070,72069))
MergeChroma(FreezeFrame(82933,82933,82932))
MergeChroma(FreezeFrame(89616,89616,89615))
MergeChroma(FreezeFrame(94060,94060,94059))
MergeChroma(FreezeFrame(102342,102342,102341))
MergeChroma(FreezeFrame(112478,112478,112477))
#convolution3d(0,6,10,8,12,4,0)
VirtualDub gives estimated coding time 44h. When all lines

mergechroma(FreezeFrame(first-frame, last-frame, source-frame))
are replaced by

FreezeFrame(first-frame, last-frame, source-frame)
estimated coding time is 6h. Slow down with MergeChroma() is over 7 times.

mg262
25th August 2005, 17:43
To be more exact: slowdown with merge chroma on the order of 100 times is about a factor of seven. Try this...

Immediately b efore the freezeframes, write

Original = last

Then immediately afterwards you can write

Original.mergechroma(last)

By the way,how fast is it without the freezeframesat all?

valja
25th August 2005, 18:32
To be more exact: slowdown with merge chroma on the order of 100 times is about a factor of seven. Try this...

Immediately b efore the freezeframes, write

Original = last

Then immediately afterwards you can write

Original.mergechroma(last)

By the way,how fast is it without the freezeframesat all?Did you mean here replacing
MergeChroma(FreezeFrame(1298,1298,1297))
etc. by
Original = last
FreezeFrame(1298,1298,1297)
Original.mergechroma(last)
?

It does not work. When all MergeChroma() lines were replaced in this way, I got the same estimated 44 hours :(

And when I remove all FreezeFrame() I have the same estimated 6h as with these lines. The difference is too small , may be a few minutes at end of coding. So, FreezeFrame() is very fast, but when I want to do a half of his job, freeze only chroma, I have huge slow down so far :(

mg262
25th August 2005, 19:02
Sorry, that was unclear, I meant that the two new lines only appear once each, immediately before and after the block of freezeframes. That way you are only invoking mergechroma once. Is that what you tried?

valja
25th August 2005, 19:18
Sorry, that was unclear, I meant that the two new lines only appear once each, immediately before and after the block of freezeframes. That way you are only invoking mergechroma once. Is that what you tried?Thanks, I got it! Estimated time increased only by few minutes (from initial 6h). It works now, thanks again!

IanB
26th August 2005, 14:29
@valja,

mg262 got you an answer, the details why may be a little trickey to a novice, but I think worth sharing.

FreezeFrame() is a zero cost filter, it does no per frame processing just shuffles the frame numnber on the way thru, adding them to the processing chain cost only the overhead of 1 subroutine call plus an if test, equivalent to say the cost of processing 1 channel of 1 pixel. Putting 100's of these in a script doesn't cost very much.

MergeChroma() costs a frame copy, more like read 2 write 1 for YUY2, in all a fairly low cost filter as filters go. However the way you originally structured your script meant when you asked for frame 1 every MergeChroma() instance, all 94 of them, dutifully merged and remerged the chroma for frame 1. In total 188 full frame reads and 94 full frame writes, an awful lot of extra work.

In mg262's version the one MergeChroma asks once for the donor luma frame and asks all the 94 FreezeFrames in a chain for the donor chroma frame at negligable processing cost. A lot better, but....

An even faster script would be to add a stack of ApplyRange()'s so only the frames needing repair had a MergeChroma() performed. Probably not worth the complexity for low cost filters, but for heavy duty filters it would be very helpful. E.g 20000 frame stream normal tweaking runs 15fps, need to fix 100 frames with a slow motion vector based jugernaut that runs 2fps.

The really slow way 50 seconds per frame, 11+ days, the improved way 2fps, 3 hours, the ApplyRange way 15fps plus an extra 50 seconds for the 100 repaired frames, 24 minutes.

IanB

valja
26th August 2005, 16:03
@IanB

Thanks for explanation. Right now I'm satisfied with mg262's solution, but I will take in account ApplyRange() in future.

trolltuning
26th August 2005, 18:48
Any chance of some one writing a sticky or adding to the FAQ about general ways to avoid unecessary overhead in scripts? IanB's answer was great but a more general list of do's and don'ts might help many of us.

stickboy
26th August 2005, 19:09
@valja,
An even faster script would be to add a stack of ApplyRange()'s so only the frames needing repair had a MergeChroma() performed. Probably not worth the complexity for low cost filters, but for heavy duty filters it would be very helpful.Or consider trying my RemapFrames plugin (http://www.avisynth.org/stickboy/) to select which frames you want merged chroma from. Then you wouldn't need stacks of FreezeFrame or ApplyRange calls.

sh0dan
27th August 2005, 22:24
I put up a tutorial on how to do this much easier, using built in functions. It seems like the power of ConditionalReader hasn't hit doom9 yet. :)

Anyway - read more at

http://www.avisynth.org/HowToApplyFilterToManySingleFrames

mg262
27th August 2005, 22:26
Nice solution! (But I wish we had streams of integers available rather than the global variable stuff...)

sh0dan
27th August 2005, 22:34
Nice solution! (But I wish we had streams of integers available rather than the global variable stuff...)
:confused: ConditionalReader is a stream of integers. You define it in your external file.

mg262
27th August 2005, 23:29
I meant a stream of integers that was treated as a built-in type (in the sense that a clip is a stream of videoframes)... sorry, I'm still not being very clear; this might be better:

class IntStream
{
int GetPt (int n, IScriptEnvironment *env);
};

I have implemented some streams like this in a plug-in (by coding the values into frames); I find the resulting syntax a bit more natural than that of ConditionalReader -- although of course this might just be me.

Here is a concrete example of some streams (using global motion vectors rather than integers); the functions in bold return motion vectors.

function melddirect(clip A, clip scene)
{
white = blankclip(a, color = $ffffff)
metric = CapAbsoluteMetric(a, 15)
FindIntegerPan(white, a, metric)
motion = RefinePan(white, a, metric, last)

trans = PanToPositiveTranslate(scene,ScaleMotion(motion, -1.0))

Meld(white, a, scene, trans, blankclip(a, width = 2100, height = 600))
}

So this
finds a set of motion vectors (one per frame, as it happens, relative to the previous frame) using one method
refines them using a different (slower but more accurate) method
multiplies them by -1 (because it is essentially a stabiliser)
takes cumulative sums (because I want all motion vectors to be relative to the first frame in the scene)

It then passes the results into another function (Meld) which makes use of the motion vectors.

I like this kind of method because it lets you tweak each of the individual steps in script.

I have gone well off topic... sorry. I'll stop here!