PDA

View Full Version : 25p to 29.97i using SelectEvery


ad25
23rd July 2008, 23:11
I have an AVI file that is 25 progressive frames per second. I would like to end up with an AVI file that is 29.97 interlaced frames per second using a pulldown method like the one used by DGPulldown. I am not encoding to MPEG, so DGPulldown is not an option.

I believe that SelectEvery is the correct function to use, but I'm not sure what the pattern should be. I have the example from the Avisynth documentation for going from 24 fps to 30 fps, but I'm not sure how to adjust that to do 25 to 29.97 instead.

If you feel that this exercise is a waste of time and I should use ConvertFPS, MVFlowFPS, etc. instead, please feel free to mention that. Thanks in advance.

neuron2
23rd July 2008, 23:14
You can't do it with SelectEvery(). The reason is left as an exercise for the student. :)

You could do 25->30 and then AssumeFPS(), but it would go out of AV sync pretty fast.

ad25
23rd July 2008, 23:41
I assume that the reason that we can't do 25 to 29.97 is that the SelectEvery statement would be too long. To make sure that I am understanding correctly, we could AssumeFPS(24.975) and then use SelectEvery to do 24.975 to 29.97. Obviously the audio would have to be adjusted to maintain audio sync.

Strictly as an academic exercise, would this be the correct way to do it?

AssumeFPS(24.975)
AssumeFrameBased()
SeparateFields()
SelectEvery(10,0,1,2,3,2,5,4,7,6,9,8,9)
Weave()

Back to the actual situation at hand, I assume that I will need to do something like this:

AVISource("25fpsclip.avi")
LanczosResize(720,480)
ConvertFPS(59.94)
SeparateFields()
SelectEvery(4,0,3)
Weave()

Does this look like I am headed in the right direction?

Thanks.

neuron2
24th July 2008, 00:48
This is clearer and more exact, I think.

# Start at 25 fps
SeparateFields()
SelectEvery(10,0,1,0,3,2,5,4,7,6,7,8,9)
Weave() # Now 30fps
AssumeFPS(29.97) # Now 29.97 fps

Your second script looks reasonable to me.

IanB
24th July 2008, 02:35
@ad25,

As you want to replicate the effect of DGPulldown, you should be using ChangeFPS() not ConvertFPS(). ConvertFPS() does blending of or switching between adjacent frames. ChangeFPS() does frame duplication/removal to effect the rate change, which is what you need for this effect.
AVISource("25fpsclip.avi")
LanczosResize(720,480)
ChangeFPS("ntsc_double") # 59.9400599400...
SeparateFields()
SelectEvery(4, 0,3)
Weave()



As an aside, I have intended to mention using DoubleWeave() in these situation to get a performance boost, but kept forgetting.

The traditional Separate, Select, Weave method costs a full output frame Blit for every frame, this is pretty fast as filters go.

DoubleWeave() does nothing when outputting a frame with matching top and bottom fields, it just passes the frame buffer through, i.e. zero cost. And if the input frames are writeable it does a single field (half frame) blit from the right frame over the left frame. If the input frames are shared then it does 2 field (half frame) blits into a new output frame buffer.
AVISource("25fpsclip.avi")
LanczosResize(720,480)
ChangeFPS("ntsc_video" ) # 29.9700299700...
DoubleWeave()
SelectEvery(12, 2,3,5,6,8,10)For this example selections 2, 6, 8 & 10 are relative source frames 0, 2, 3 & 4, these are rendered for zero cost. Selections 3 & 5 are interleaves of relative source frames 0+1 & 1+2 and as the input clip is not shared these are rendered for the cost of a single field (half frame) blit each. Thus for every 6 output frames the processing cost is 1 full frame blit. An improvement of 6 fold in this part of the script.

For the above script the approx per frame processing cost would be [Frame Decode=X]+[V.only Resize=6]+[Frame Blit=1]/6+[Output Blit=1] = X+7.166 compared with the more traditional X+8.

ad25
25th July 2008, 16:59
Thanks to both of you. The reason for using ChangeFPS instead of ConvertFPS is very clear to me, but it is going to take a minute for me to digest the DoubleWeave.SelectEvery logic.

Alex_ander
4th August 2008, 15:25
The traditional Separate, Select, Weave method costs a full output frame Blit for every frame, this is pretty fast as filters go.

DoubleWeave() does nothing when outputting a frame with matching top and bottom fields, it just passes the frame buffer through, i.e. zero cost.

Ian, in case of double framerate, will replacement ofSeparateFields().SelectEvery(4,0,3).Weave() with:

DoubleWeave().SelectEvery(4,1)# for 59.94fps input

...make things faster and (if it will) will it still work slower at pulldown than in your example with 29.97 + SelectEvery?

IanB
4th August 2008, 18:57
Every SeparateFields().SelectEvery(...).Weave() can be replaced by an equivalent DoubleWeave().SelectEvery(...) and depending on the access pattern may get a performance boost. If selecting all the weaved combinations with a shared source then there can be no gain. If the source is unshared then a 50% gain is possible. When selecting the unweaved combinations then there is zero cost.

The downside is the DoubleWeave solution requires a lot more thought. And as the potential gain is only 1 frame blit it may often not be worth the effort.

Alex_ander
5th August 2008, 10:25
Thanks for the explanation. If I understand it right, DoubleWeave().SelectEvery(4,1) is also slower at pulldown (than in your example) because all the outputted progressive frames here are combined from fields of adjacent input frames and not taken directly from input. DoubleWeave() on frame based just inserts frames between each input pair of frames using last field from previous frame and first field from next frame. This also inverts field order, so SelectEvery(4,1) here works similar to SeparateFields().SelectEvery(4,1,2).Weave(). And there's no way to pass frames faster other than directly point at numbers of unmodified frames as SelectEvery arguments (I just wanted to use a more compact expression, but thе result is different).

IanB
5th August 2008, 15:48
If the source is unshared then a 50% gain is possible.So as long as the input is unshared and frame based, DoubleWeave().SelectEvery(4,1), will cost a half frame blit. If it is shared then it costs a full frame blit, the same as the alternate coding.

SeparateFields().SelectEvery(4,1,2).Weave() will always cost a full frame blit.

daniel.payne.
10th February 2012, 12:52
Sorry to open a very old thread.

Can anyone answer why this wouldn't work?

Avisource("test.avi")
AssumeFPS(24000,1001, false) # Or AssumeFPS(23.976)
AssumeFrameBased()
SeparateFields()
SelectEvery(8, 0,1, 2,3,2, 5,4, 7,6,7)
Weave()
Assumefps(2997, 100, false)
SSRC(48000)
AssumeBFF()

Thanks if anyone can shed any light....i'm in abject darkness here.

TheSkiller
10th February 2012, 18:58
What exactly does not work?
You should change the last AssumeFPS to

AssumeFPS(30000,1001)

for proper NTSC frame rate. AssumeFPS(2997, 100, false) does not make much sense, it's the same as 29.97 (which is not precise).

Edit: The last AssumeFPS ist not needed anyway, remove it.