Log in

View Full Version : ShowSMPTE every "n" frames?


trapp
24th September 2008, 03:45
Is there a way to use ShowSMPTE to place the time code on every other frame or every three frames (or more), instead of every frame? For my purposes less than every frame would be fine, and I’m hoping it would drastically reduce the time required to write the file. I’m working in 30fps, and possibly 24fps in the future.

I’m brand-new to Avisynth and not yet a script writer, so clear instructions would be greatly appreciated.

Thanks.

Alex_ander
24th September 2008, 05:33
For every other frame (count for every frame):

a=avisource("video.avi")
b=a.showsmpte().selectodd()
c=a.selecteven()
interleave(c,b)
In case of every third frame etc. maybe it would be easier to also use a plugin like RemapFrames or ApplyEvery from here:

http://avisynth.org/stickboy/

P.S. looks like fo each 3rd frame it's also easy enough:

a=avisource("video.avi")
b=a.selectevery(3,0)
c=a.selectevery(3,1)
d=a.showsmpte().selectevery(3,2)
interleave(b,c,d)

I don't think this reduces processing time however.

hanfrunz
24th September 2008, 09:03
if you can live with framenumbers only try my very fast framenumbers (http://forum.doom9.org/showthread.php?s=&threadid=91968) filter.

hanfrunz

IanB
24th September 2008, 09:28
Yes it save a stack of time the inbuilt text rendering routines are very slow in the setup phase.

Subtitle() slowly sets up the text once and draws it onto each frame very fast, no problem.

ShowFrameNumber()/ShowSMPTE/ShowTime all slowly setup new text every frame then draw it once, problem!

Sh0dan via Neuron2 has a new simple fast text writing primitive. We will be using it in the future to improve the performance of such applications in the Avisynth core.

To do 1 in 4 :-a=avisource("video.avi")
b=a.showsmpte().selecteven().selecteven()
c=a.selecteven().selectodd()
d=interleave(c, b)
e=a.selectodd()
interleave(d, e)

stickboy
24th September 2008, 19:03
Use my ApplyEvery plug-in in combination with JDL_SimpleApplyEvery (from jdl-range.avsi), which internally would do:
orig = AVISource("video.avi")
smpte = orig.ShowSMPTE()
orig.DeleteEvery(n, 0)
InteleaveEvery(last, smpte, n, 0)

trapp
25th September 2008, 04:51
Alex_ander, Hanfrunz, IanB and stickboy, thanks to all of you for the seasoned guidance. It’s been enlightening experimenting with all of these suggestions, and I’ve got plenty of learning ahead just figuring out how your code works.

After trying your code, I can see now that the resulting “flashing”effect or “n frames” will ultimately prove too annoying to work with for long periods of time – my bad.

Hanfrunz, I tried your framenumber filter and am only sorry that the frame count alone won’t do in this situation – otherwise it would seem the perfect solution.

I’m glad to hear future releases of Avisynth may reduce the time needed to write things like ShowSYMPTE. In the meantime, it was a great experience discovering the kind of help available here.

Thanks again,

John

Didée
25th September 2008, 07:50
Rendering will be faster when done on a small clip.

a = avisource("video.avi")
b = blankclip(a,width=a.width(),height=32).ShowSMPTE()
stackvertical(a,b)
or
a = avisource("video.avi")
top = a.crop(0,0,-0,-32)
bot = a.crop(0,a.height()-32,-0,-0)
stackvertical(top,bot.showSMPTE())



Edit -- Some quick results:

a) Mpeg2Source("PAL_720x576.d2v")

ShowSMPTE rendering on full frames: ~ 43.5 fps (100%)
StackVertical(Crop,Crop.ShowSMPTE): ~ 94.0 fps (216%)
(Without ShowSMPTE) ............ : ~111.0 fps (255%)

b) RawSource("720p_1280x720.yuv")

ShowSMPTE rendering on full frames: ~08.6 fps (100%)
StackVertical(Crop,Crop.ShowSMPTE): ~27.0 fps (314%) ??
(Without ShowSMPTE) ............ : ~26.3 fps (305%) ??


c) DirectShowSource("H264_1280x528.mkv") # decoding by ffdshow (older version, Dec.2007)

ShowSMPTE rendering on full frames: ~16.4 fps (100%)
StackVertical(Crop,Crop.ShowSMPTE): ~28.1 fps (171%)
(Without ShowSMPTE) ............. : ~29.2 fps (178%)

Seems that the speed penalty got reduced by a good bit. :)

Comatose
25th September 2008, 15:59
Nice work, very good thinking =)

IanB
25th September 2008, 23:47
Yes, Most of the time is spent is Antialiaser::GetAlphaRect(). It does a multipass bitwise scan of a buffer, 8*Width*Height bytes, to build the anti-aliased pixel and mask buffers. So reducing the frame size being painted will make a big difference.

A while back I added an optimisation to remember the active text window rectangle in the constructor, which improved the speed of Subtitle by allowing for only processing pixels in that small window rectangle in the GetFrame call. It did not help the Show*() routines as they rebuild the text every frame. An obvious improvement would be to render a worst case text, I guess "888:88:88:88", in the constructor and use that as the active text rectangle in the GetFrame calls. Added to the To Do list ;)

Leak
26th September 2008, 09:20
Wouldn't it make more sense to give users an option to disable anti-aliasing? ShowSMPTE probably should work just as well without anti-aliasing... :)

IanB
26th September 2008, 14:00
@Leak,Sh0dan via Neuron2 has a new simple fast text writing primitive. We will be using it in the future to improve the performance of such applications in the Avisynth core.

Leak
26th September 2008, 14:03
@Leak,
Ummm... if that's what I think it is (the text renderer Donald uses for his debug output) it's got a hard-coded font that definitely doesn't support most special characters...

trapp
1st October 2008, 05:12
Didée, this worked excellently and very fast!

One problem: I mangled the code trying to get the time code to show up in the top right corner. I don’t understand the code well enough to modify it. Here’s what I ended up with, which unfortunately still crops a region from the bottom and puts that at the top.

a = avisource("video.avi")
top = a.crop(0,a.height()-32,-0,-0)
bot = a.crop(0,32,-0,-0)
stackvertical(top.showSMPTE(offset="01:00:00:00", x=280, font="arial", size=16, text_color=$ffffff),bot)

Could you please tell me how to fix the crop command here?

Fortunately one of the tasks I needed it for was a letterbox video, so since both top and bottom were black matte, it didn’t matter – and on that one it worked like a charm.

Thanks so much for the great suggestion.

John

Didée
1st October 2008, 07:44
Using the top stripe is even more simple:

top = a.crop(0,0,0,32)
bot = a.crop(0,32,0,0)