Log in

View Full Version : How to use DuplicateFrame function


TCmullet
12th January 2013, 06:42
In general I (as a seasoned computer programmer) easily cry when trying to do the most basic things every time I experiment with Avisynth. Why doesn't any documentation give CLEAR examples, that is, a working example in which I don't have to make certain inferences that I'm not able to make??

My current "simple" problem that's killing me:

I want my script to include a range of frames from the source video, then have one frame duplicated several times after it. Here's what I try but I CANNOT figure out the correct syntax:

myclip=AviSource("myVideo.avi")
myclip.trim(0,49)+DuplicateFrame(49,49,49,49)

I want to feed to Virtualdub the 1st 50 frames out of my AVI, then give it 4 copies of the 50th frame. New video will be 54 frames long. But it bombs with "Invalid arguments to function DuplicateFrame. I can't find anywhere on the web an example that would show me clearly what to do. Plus for some reason, I cannot visit avisynth.org (gives a standard 404 page not found).

poisondeathray
12th January 2013, 07:29
In general I (as a seasoned computer programmer) easily cry when trying to do the most basic things every time I experiment with Avisynth. Why doesn't any documentation give CLEAR examples, that is, a working example in which I don't have to make certain inferences that I'm not able to make??

My current "simple" problem that's killing me:

I want my script to include a range of frames from the source video, then have one frame duplicated several times after it. Here's what I try but I CANNOT figure out the correct syntax:

myclip=AviSource("myVideo.avi")
myclip.trim(0,49)+DuplicateFrame(49,49,49,49)

I want to feed to Virtualdub the 1st 50 frames out of my AVI, then give it 4 copies of the 50th frame. New video will be 54 frames long. But it bombs with "Invalid arguments to function DuplicateFrame. I can't find anywhere on the web an example that would show me clearly what to do. Plus for some reason, I cannot visit avisynth.org (gives a standard 404 page not found).



AviSource("myVideo.avi")
Trim(0,49)
DuplicateFrame(49,49,49,49)



here "last" is implied with DuplicateFrame and Trim

TCmullet
12th January 2013, 07:51
Thank you SO much, friend! (You are ANYTHING but poison.)

That worked, but am not able to augment it.


AviSource("myVideo.avi")
Trim(0,49)
DuplicateFrame(49,49,49,49)
Trim(50,0)


I want to tack on the rest of the original video starting at the 51st frame. But it screws up royally. I thought plus signs were to be used to concatenate things together.

Also is there a way I can use variables to hold things? I had assigned the avisource to a variable but you took it out. Especially I want to assign 49 to a variable, b/c my real script is like "Trim(0,166016)", and I want to create 22 copies of the 166016th one. Then I want to append the remainder of the source file beginning with frame 166017. I'm inserting 22 frames in the middle of my big video file, and those 22 frames are a copy of the frame that exists right before where they are to get inserted.

I continue to be extremely frustrated every time I try to understand the AviSynth documentation. They assume you know the whole system when you try to learn one item. If they'd only give examples in a real context. (Sorry for the rant. I realize they are volunteers.)

Chikuzen
12th January 2013, 08:15
AviSource("myVideo.avi").Trim(0, 49).Loop(5, 49, 49)
or
AviSource("myVideo.avi").Trim(0, 53).FreezeFrame(49, 53, 49)

TMTOWTDI

Gavino
12th January 2013, 12:04
my real script is like "Trim(0,166016)", and I want to create 22 copies of the 166016th one. Then I want to append the remainder of the source file beginning with frame 166017. I'm inserting 22 frames in the middle of my big video file, and those 22 frames are a copy of the frame that exists right before where they are to get inserted.
That's what DuplicateFrame() does all on its own, without any need for Trim(). The example in the docs
DuplicateFrame(3, 3, 21, 42) # Add 4 frames
adds 4 frames - 2 copies of frame 3 and one each of frames 21 and 42. All original frames are also preserved.

So you could use
DuplicateFrame(166016, ... , 166016) # with 22 arguments

But for many repeats, it's simpler to use Loop (http://avisynth.org/mediawiki/Loop)() as HolyWu has done.
Loop(23, 166016, 166016)

TCmullet
13th January 2013, 01:24
Thanks, Gavino and you others. It's partly working. I'm changing it to look more like the real script, except for the file name. (I usually try to reduce my codes to the simplest form to make it easier for experts to help me. But in this case, it probably just as easy to use real numbers.)

AviSource("2.avi")
Trim(0,166016)
Loop(23, 166016, 166016)This does tack on 22 dups of frame 166016 at the end (of the group of frames from 0 to 166016). But now I need to tack on more. I need to append the rest of the source video, which is source frames 166017 to the end. I thought that adding

Trim(166017,0)would do it, but it shrunk the whole thing down to 21 total frames, whereas I'm expecting around 249,000. How can I append the remainder of the source video, which starts at frame 166017?

Holywu, I think you have misunderstood (when you said Trim was redundant). I'm not appending 22 frames to the end of the file, but to the point after frame 166016.

poisondeathray
13th January 2013, 02:00
Trim is using implicit "last" , so it refers to the last video above, that had already been trimmed from 0-166016, then the frames tacked on , not the original video; that's why you're getting 21 frames only

Here is one way to do it that breaks it all out and should be more clear at what's going on. I named the original video "main" in this example. "a" is the original video cut to frame 166016 plus the additional frames added by loop() , and "b" is the original video from 166017 to the end


main=AviSource("2.avi")

main
Trim(0,166016)
Loop(23, 166016, 166016)
a=last

main
Trim(166017,0)
b=last

a++b

poisondeathray
13th January 2013, 02:42
Apparently you didn't try it. ;)

Loop() will insert the repeated frames after the end_frame, not to the very end. Then the rest frames of the clip are appended after the repeated frames.

Indeed it does... This is the easiest/best* (b-word alert) way to do it

TCmullet
13th January 2013, 03:00
@Poison Your script worked WONDERFULLY! Your's is the best.

@Holywu Your script worked WONDERFULLY! L, I B ! (Well, I'll BE...) Your's is the shortest and most efficient. But what you're saying apparently is that Loop takes the range and repeats it right where it is in place, then lets the rest of the video continue to be in the set. I thought it was appending it to whatever I had previously defined, which was the trim. This is not what I would have thought from the doc, but then the docs are very cryptic (as I've said).

Could we all please consider the broader case?? That is, in my case it was a coincidence that the frame I wanted to duplicate happened to be the last one right before where the duplicated sequence needed to be inserted. What if after 166016 I had needed to insert 22 copies of frame 7?

@Poison, would you be so kind as to work up a script for THAT?

poisondeathray
13th January 2013, 03:29
What if after 166016 I had needed to insert 22 copies of frame 7?

@Poison, would you be so kind as to work up a script for THAT?

do you mean
0-166016 , 22 x frame 7, 166017-end ?

If so, you could use something like


main=AviSource("2.avi")

main
trim(7,-1)
loop(22)
frame7_22=last

main
Trim(0,166016)
a=last

main
Trim(166017,0)
b=last

a ++ frame7_22 ++ b

TCmullet
13th January 2013, 03:57
do you mean
0-166016 , 22 x frame 7, 166017-end ?

YES! And I'm beginning to get the hang of this! Your "spread out" code, even if one could do it in much less code, is better as is more understandable and documentable. (I have to be able to understand my code 6 mos. or 6 years later.)

And let me add that the structure of it reflects what I've sometimes done in Virtualdub when needed. OHHH, it's AWFUL. But it was infrequent enough and with small enough files that I was easily able to quench any thought of dealing with my fears of AviSynth. But I'm now working with numerous video files, easily 2 hours, like 896x504, and have temp-encoded to Lagarith, taking a whopping 90GB! Even with "direct stream copy", an i5 quad-core processor and a SATA-3 controller and drive, the sucker takes forever to cut apart the AVI to then append back together with small frame sequence added inbetween. THAT is what drove me to realize, "I'll bet AviSynth can handle this much easier". Thanks to you, I was right. I've used it much for IVTC of movies and re-TC (with initial help of course), but now I'm getting into the "serious stuff", albeit just beginning.

Thank you, Poison, and to all of you, for helping me.

This example of dupping 22 frames is actually the 2nd patch to my current video. The first one was cutting out a bad range (one with missing frames) and inserting a good counterpart from a different source. I'm redoing that in AviSynth using your examples as my guide. I will probably have a bunch of major surgeries (probably 3-6) for this one video, yet no major file processing before the final pass, thanks to you all.

Oh, and I'll probably use "+" instead of "++" as there's no sound track. In this case (if you're curious), the audio track with the video is damaged beyond repair, but I've been able to get the track from a good lower-res version of the same video. So I'm going through both with Vdub syncing the audio with the action. When I find it's out of sync, I back up and slowly inspect. It appears to always be that my prime video is damaged (missing frames), hence the need to insert them (or dupped frames) at a precise point to bring my silent video frames to exactly match the frame-count of the lower res. video version and therefore of the good audio track.

poisondeathray
13th January 2013, 04:07
Cheers; there is going to be several ways to do this in avisynth - I learn new (often better) ways of doing stuff all the time from these other helpful people

Personally, I like doing it "spread out" (and labelled with better names) because for me it gets confusing very quickly once you have multiple segment appends and various filters

TCmullet
13th January 2013, 04:58
loop(22)
Did you mean "loop(23)"?

poisondeathray
13th January 2013, 05:13
Did you mean "loop(23)"?

No, that script will insert 22 copies of frame 7

Did you mean 23 x frame7 ?

TCmullet
13th January 2013, 05:20
No I meant 22 as originally stated, but Gavino had said to do 22, you must code 23 and he made it bold. I looked in the offline docs and it says it will subtract 1 from whatever you put in there as the "times" value. That's why Gavino put 23 when he knew I wanted 22 copies. I think you copied him, but then you changed to 22 in your last example. So are Gavino and the docs (my understanding of them) correct?

poisondeathray
13th January 2013, 05:41
No I meant 22 as originally stated, but Gavino had said to do 22, you must code 23 and he made it bold. I looked in the offline docs and it says it will subtract 1 from whatever you put in there as the "times" value. That's why Gavino put 23 when he knew I wanted 22 copies. I think you copied him, but then you changed to 22 in your last example. So are Gavino and the docs (my understanding of them) correct?

Gavino is usually correct, but it's 22. I counted them using a test clip and showframenumber()

The documenation agrees - it says the same number of times (n) ; not n+1
ie. loop(10) loops the clip 10 times

http://avisynth.org/mediawiki/Loop

poisondeathray
13th January 2013, 05:50
Oh I see where you might be confused about the documenation

times= -1 is the default setting , this means loop infinitely

It's not telling you to subtract from that value

TCmullet
13th January 2013, 05:59
Yes, I just saw that, but not until I had used my misinterpretation two times, and it worked. Now I'm trying to undo and redo my changes to see what's going on.

Gavino, could you please chime in here? You're the one who "added 1". AT one point, I was wanting to create 4 copies, but you said "5". I ignored that "error" by you at the time, but now we are wondering (or at least I am).

TCmullet
13th January 2013, 06:04
I don't know what's going on, but when I code this:

loop(12,154022,154022) # dupl the last frame of a comm.brk 11 times
it works correctly. I changed it to 11 and it was short one frame. Putting it back to 12 made it do 11 copies. That's 11 copies in addition to the original one.

poisondeathray
13th January 2013, 06:05
I think the reason is he was referring to HolyWu's original example


AVISource("myVideo.avi")
Loop(5, 49, 49)


You wanted to add 4 copies of 49. So 4 copies of 49 + 1 original 49 = 5 total copies

This sequence would go ...47,48,49,49,49,49,49,50,51...

So Loop(5) would give 5, Loop(10) would give 10 .... etc.... just as the documenation says

The correct value for the "spread out script" would be 22 since you want 22



EDIT: LOL I missed your last before posting

TCmullet
13th January 2013, 06:21
I guess we're both right, depending. The docs imply to ME that the "times" is the number of CREATED copies, not the total copies (including the original) afterward. But it is the latter. So therefore my code and the comment I put out to the right is correct.

Hey, I'm re-reading it. It's not really saying "duplicate it" or "copy it". It's say "loop", which I see means "pass thru". You normally pass thru a segment once. If I say "pass thru it 23 times", that's the original pass-over, plus 22 more. Yes, it all makes sense now. So what I wanted was 22 copies, therefore I have to pass-over the 1-frame sequence 23 times.

Case solved! :D

Gavino
13th January 2013, 12:16
That's right.
"times" is the number of occurrences of the specified frame-range in the final result.

In the first example, you wanted to add 22 copies of the frame in its original position, making 23 occurrences in total.
So Loop(23, ...).

But in the second example, you wanted to add 22 copies in a different position. To do that, you need to create a separate clip consisting of just the frame in question, then use Loop(22) to produce the 22 frame sequence to be spliced into the original clip.