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

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage
Register FAQ Today's Posts Search

Reply
 
Thread Tools Search this Thread
Old 23rd October 2007, 17:15   #1  |  Link
mroz
Registered User
 
mroz's Avatar
 
Join Date: Sep 2006
Posts: 201
Can a script save particular frames out to jpg?

I've written a short script below to help investigate problems using MVTools with SetMTMode.

It compares two files frame by frame, spitting out some stats to a log file for any frame pairs which don't match:

Code:
leaf1="noSetMT"
leaf2="SetMT-t1-b10"
global c1=AVISource("E:\Work\test\hfyu_MVMT-longtest-"+leaf1+".avi")
global c2=AVISource("E:\Work\test\hfyu_MVMT-longtest-"+leaf2+".avi")
global total=0
file="E:\Work\test\compare-"+leaf1+"-"+leaf2+".log"
Subtract(c1,c2)
WriteFileStart(file, """ "vim:tabstop=6"+chr(10) """, """ Time("%#c")+chr(10) """, """ "Frame"+chr(9)+"Total"+chr(9)+"Variation" """, append=true)
#nb compare against 0.0001 instead of 0 to allow for rounding errors - 2 identical files will report a variation of 0.000022 
WriteFileIf(file, "variation>0.0001", "current_frame", "chr(9)", "total", "chr(9)", "variation")
WriteFileEnd(file, """ "Test complete."+chr(10) """)
ScriptClip( "global variation = LumaDifference(c1,c2)+ChromaUDifference(c1,c2)+ChromaVDifference(c1,c2)"+chr(13) \
           +"global total = total + ((variation>0.0001) ? 1 : 0)"+chr(13) \
           +"Subtitle(String(variation))" \
)
I'd also like to get it to save to file (as a jpg or png preferably) the problem frames from the returned clip. Can this be done?

Failing that, is there any application, preferably command line driven, which will take a text file listing frame numbers & spit out a capture for each of the listed frames?
mroz is offline   Reply With Quote
Old 23rd October 2007, 17:39   #2  |  Link
Wilbert
Super Moderator
 
Join Date: Nov 2001
Location: Netherlands
Posts: 6,380
Sure, use ImageWriter.
Wilbert is offline   Reply With Quote
Old 23rd October 2007, 22:53   #3  |  Link
foxyshadis
Angel of Night
 
foxyshadis's Avatar
 
Join Date: Nov 2004
Location: Tangled in the silks
Posts: 9,569
Just to make it a bit cleaner, you can also have newlines in quotes:
Code:
ScriptClip( "global variation = LumaDifference(c1,c2)+ChromaUDifference(c1,c2)+ChromaVDifference(c1,c2)
          global total = total + ((variation>0.0001) ? 1 : 0)
          Subtitle(String(variation))
")
avsp doesn't like it unless you use triple-quotes, but either is legal.
foxyshadis is offline   Reply With Quote
Old 24th October 2007, 02:16   #4  |  Link
mroz
Registered User
 
mroz's Avatar
 
Join Date: Sep 2006
Posts: 201
@Wilbert: Don't know how I missed it - spent a while looking for an external filter to do the job. Cheers

@Foxyshadis: Thanks, I didn't know that. Think I switched to the triple quote version since posting.

I'm trying to speed it up atm & get it to work with MT. I figured I don't need the subtract output for every frame; it's only the log that's important (& maybe grabs of the problem frames). Getting rid of the subtract & subtitling has nearly doubled throughput. SetMTMode(2,0) trebles it further on a quad core, but introduces a few problems.

Here's the current version:
Code:
SetMTMode(2,0)
leaf1="noSetMT"
leaf2="SetMT-t1-b10"
global c1=AVISource("E:\Work\test\hfyu_MVMT-longtest-"+leaf1+".avi")
global c2=AVISource("E:\Work\test\hfyu_MVMT-longtest-"+leaf2+".avi")
global total=0
global file="E:\Work\test\compare-"+leaf1+"-"+leaf2+".log"
BlankClip(c1, width=16, height=16) # maybe 15% faster than using c1 as our 'dummy' clip (& 100% faster than using subtract(c1,c2) with variation subtitled)
WriteFileStart(file, """ "vim:tabstop=6"+chr(10) """, """ Time("%#c")+chr(10) """, """ "Frame"+chr(9)+"Total"+chr(9)+"Variation" """, append=true)
WriteFileEnd(file, """ "Test complete."+chr(10) """)
ScriptClip( """
  variation = LumaDifference(c1,c2)+ChromaUDifference(c1,c2)+ChromaVDifference(c1,c2)
  # nb1 keeping writefile inside here allows us to store variation as local, reducing problems with running in MTMode 2
  # nb2 aside: writefile doesn't want to write anything when called inside FrameEvaluate; anyone know why?
  # nb3 sometimes the running total is reported incorrectly in MTMode 2 as another thread updates the total before code writes out data to log;
  #     this isn't terribly important & can be corrected as is implicit in data set
  # nb4 compare against 0.0001 instead of 0 to allow for rounding errors - 2 identical files will report a variation of 0.000022 
  WriteFileIf(file, "variation>0.0001", "current_frame", "chr(9)", "total", "chr(9)", "variation")
  global total = total + ((variation>0.0001) ? 1 : 0)
  return last
""" )
It's less elegant but six times faster. Here's some example output which demonstrates all the problems:

Code:
vim:tabstop=6
Wednesday, October 24, 2007 01:39:43
Frame	Total	Variation
vim:tabstop=6
Wednesday, October 24, 2007 01:39:43
Frame	Total	Variation
vim:tabstop=6
Wednesday, October 24, 2007 01:39:43
Frame	Total	Variation
vim:tabstop=6
Wednesday, October 24, 2007 01:39:43
Frame	Total	Variation
15858	1	1.816673
15861	3	0.210538
15859	3	3.181405
Test complete.

Test complete.

Test complete.

Test complete.
Problems:

1) Cosmetic but annoying: headers & footers are getting written four times, once for each thread. Any solution/workaround?

2) Results no longer in frame order - I don't really care, but it could be a problem if data used for subsequent processing & order required. Can't be avoided afaics atm when using MT.

3) Running total is sometimes wrong as noted in the comments. Any way around this? I can't see how to track the total without using a global & then multithreading makes it almost inevitable.

Last edited by mroz; 24th October 2007 at 03:17.
mroz is offline   Reply With Quote
Old 24th October 2007, 03:15   #5  |  Link
mroz
Registered User
 
mroz's Avatar
 
Join Date: Sep 2006
Posts: 201
Hm, can mostly work around 3) with:
Code:
SetMTMode(2,0)
leaf1="noSetMT"
leaf2="SetMT-t1-b10"
global c1=AVISource("E:\Work\test\hfyu_MVMT-longtest-"+leaf1+".avi")
global c2=AVISource("E:\Work\test\hfyu_MVMT-longtest-"+leaf2+".avi")
global total=0
global file="E:\Work\test\compare-"+leaf1+"-"+leaf2+".log"
BlankClip(c1, width=16, height=16) # maybe 15% faster than using c1 as our 'dummy' clip (& 100% faster than using subtract(c1,c2) with variation subtitled)
WriteFileStart(file, """ "vim:tabstop=6"+chr(10) """, """ Time("%#c")+chr(10) """, """ "Frame"+chr(9)+"Total"+chr(9)+"Variation" """, append=true)
WriteFileEnd(file, """ "Test complete."+chr(10) """)
ScriptClip( """
  variation = LumaDifference(c1,c2)+ChromaUDifference(c1,c2)+ChromaVDifference(c1,c2)
  # nb1 keeping writefile inside here allows us to store variation as local, reducing problems with running in MTMode 2
  # nb2 aside: writefile doesn't want to when called inside FrameEvaluate; anyone know why?
  # nb3 sometimes the running total is reported incorrectly in MTMode 2 as another thread updates the total before code writes out data to log;
  #     this isn't terribly important & can be corrected as is implicit in data set
  # nb4 compare against 0.0001 instead of 0 to allow for rounding errors - 2 identical files will report a variation of 0.000022 
  WriteFileIf(file, "variation>0.0001", "current_frame", "chr(9)", "thistotal", "chr(9)", "variation")
  global total = total + ((variation>0.0001) ? 1 : 0)
  thistotal = total # massively reduce chance of MTMode 2 screwing up logging of total
  return last
""" )
Edit: Although I understand the filter chain is initially built up backwards, I'm puzzled why the above workaround requires the assignment to total to be after WriteFileIf, but is happy for the variation assignment to be before. Are there any detailed docs on how parsing is handled? For instance, are expressions involving globals handled very differently to locals in respect of parse order?

Last edited by mroz; 24th October 2007 at 03:42.
mroz is offline   Reply With Quote
Old 24th October 2007, 05:08   #6  |  Link
foxyshadis
Angel of Night
 
foxyshadis's Avatar
 
Join Date: Nov 2004
Location: Tangled in the silks
Posts: 9,569
That's pretty much what a race condition is. You have to use something called an interlocked increment to completely eliminate those, or mutually exclusive code sections (critical sections/mutexes/semaphores), but this situation was never foreseen in avisynth (or by tsp), of course, so it isn't available.

To stop the multiple headers, use
SetMTMode(2)
#Sources....
SetMTMode(5)
#WriteFileStart/End
SetMTMode(2)
#ScriptClip

There might be a way to enforce order, but I'll have to experiment once I get home.
foxyshadis is offline   Reply With Quote
Old 24th October 2007, 05:29   #7  |  Link
mroz
Registered User
 
mroz's Avatar
 
Join Date: Sep 2006
Posts: 201
Quote:
Originally Posted by foxyshadis View Post
That's pretty much what a race condition is. You have to use something called an interlocked increment to completely eliminate those, or mutually exclusive code sections (critical sections/mutexes/semaphores), but this situation was never foreseen in avisynth (or by tsp), of course, so it isn't available.
Indeed. In the dim past I used to occasionally code interrupt routines in ARM assembler, which involves such matters.

Quote:
To stop the multiple headers, use
SetMTMode(2)
#Sources....
SetMTMode(5)
#WriteFileStart/End
SetMTMode(2)
#ScriptClip
Already tried it. I expected it to work. It didn't :/

I forget which modes did what, but some gave me four sets of headers while others gave me two.

Quote:
There might be a way to enforce order, but I'll have to experiment once I get home.
Thanks. Have fun. I'm going to sleep now, five hours later than I intended
mroz is offline   Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 14:45.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2026, vBulletin Solutions Inc.