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. |
12th August 2003, 08:24 | #1 | Link |
Fascinated Lurker
Join Date: Feb 2002
Location: Durham, UK
Posts: 243
|
New Function Request - Telecine()
Hi All,
Currently it is very simple to do a 23,976fps to 29.97fps conversion using seperatefields, selectevery and weave. 24 FPS with the field shuffle will make a 30 FPS video... However, what if we want 29.97 but don't want to touch our audio stream and don't want a desynch? every 100 seconds there is 2997 frames (29.97fps) or every 100 seconds there is 3000 frames (30fps) so... every 3000 frames, we have to remove 3... or in 1000 remove 1 so we have a 999 frame block of stuff... or a 995 + 4 block (this will be important in a second) when we go from 24-30 we are going from 4-5 (995 is devisable by 5 ^_^) so if we Telecine 796 frames, and leave 4 frames alone... 800 frames, which normally would translate to 1000 frames, instead translates to 999 frames... perfect.... now how to do this smoothly (the easy method would just to Telecine the first 796, then copy the last 4) the longer than you can smooth over the frame transitions... the better the Telecine process is going to be (which is why AA AB BC CD DD is better than AA BB BC CD DD ) So... what if the "solid" frames were 197, 398, 599, 800 out of every 800 frame block...? So, in short the idea is to telecine every 196 frames, then copy one, then telecine 196, then copy one, then telecine 196, then copy one... etc... the "solid" frames as i refered to them are the copied frames... so technically this could be accomplished with AssumeFrameBased() SeparateFields() a very long SelectEvery command ^_^ with 246 field settings Weave() AssumeFPS(29.97) [not sure if it would be required with selectevery] However, a selectevery that big will get thrown out by avisynth. A better option would be to have a plugin such as Telecine(clip,fieldorder,outputframerate) where possible output framerates are 25, 29.97 and 30 [and have a conditional telecine pattern for each common mapping] Thoughts? |
12th August 2003, 09:19 | #3 | Link |
Fascinated Lurker
Join Date: Feb 2002
Location: Durham, UK
Posts: 243
|
ChangeFPS isn't what we want here.
The aim is to telecine the footage so that it ends up being 29.97fps - ChangeFPS would reduce 30fps to 29.97fps by removing frames which is what we want to avoid.... especially with telecinied footage. You could change to 23.976 at the beginning but again that's losing a frame where you honestly don't need to. We're not doing any frame duplication either, we're just choosing to NOT telecine 4 frames in every 800. It's a pretty simple idea but can't be done as far as I can tell with avisynth scripting at the moment (or at least, can't be done with one script that will work for every video file... you can do it with trim but it's nasty). |
12th August 2003, 10:24 | #4 | Link |
AviSynth Enthusiast
Join Date: Jul 2002
Location: California, U.S.
Posts: 1,267
|
Ah, sorry, I misread. I think I see what you mean now.
How did you come up with the 197, 398, 500, and 800 values? (Is that right? If you're counting from 0, frame 800 is the 801st frame and isn't part of the 800-frame block...) Hmm... if only there were an ApplyRangeEvery function... Last edited by stickboy; 12th August 2003 at 10:28. |
12th August 2003, 10:52 | #6 | Link |
Fascinated Lurker
Join Date: Feb 2002
Location: Durham, UK
Posts: 243
|
AH! Yes, I know where I got 196.
It's because you generally take 4 frames and make them into 5 when you telecine, so you have to work in 4 frame sections. 199 isn't divisable by 4. so you do 1-4 Telecine to 1-5 4-8 Telecine to 6-10 9-12..... 192-196 Telecine to 240-245 197 copy to 246 you repeat this 4 times. When you've done it 4 times you get to frame 985. You then add on the next 3 sequences of 5 telecined frames to get to 999. Then you reset and start again. So, yeah, complicated ^_^ |
12th August 2003, 12:12 | #7 | Link |
AviSynth Enthusiast
Join Date: Jul 2002
Location: California, U.S.
Posts: 1,267
|
I believe your math is a little off... if you remove every 196th frame, you'll remove 5 frames of every 800. (If you neglect to remove the fifth frame, one of the segments will not be a multiple of 4.)
I think it should be: Code:
keep telecine 0 [ 1, 200] 201 [202, 401] 402 [403, 602] 603 [604, 799] Code:
function min(int m, int n) { return (m < n) ? m : n } function Telecine(clip c) { assert(c.IsFrameBased(), "Telecine: clip must be frame-based") # we need to handle the case of a null-clip manually; # otherwise, SelectEvery(...) will generate unwanted blank frames return (c.FrameCount() == 0) \ ? c.AssumeFPS(c.FrameRate() * 5.0 / 4.0) \ : c.ComplementParity().DoubleWeave().SelectEvery(8, 0, 2, 3, 5, 6) } function NewTelecineHelper(clip c, int iterLeft) { assert(iterLeft > 0, "NewTelecineHelper: invalid <iterLeft> value") iterLeft = iterLeft - 1 start = iterLeft * 800 end = min(c.FrameCount(), (iterLeft + 1) * 800) seg = c.Trim2(start, length=800) seg1 = seg.Trim2( 0, length=1) + seg.Trim2( 1, 201).Telecine() seg2 = seg.Trim2(201, length=1) + seg.Trim2(202, 402).Telecine() seg3 = seg.Trim2(402, length=1) + seg.Trim2(403, 603).Telecine() seg4 = seg.Trim2(603, length=1) + seg.Trim2(604 ).Telecine() c = c.Trim2(0, start) + seg1 + seg2 + seg3 + seg4 + c.Trim2(end) return (iterLeft == 0) \ ? c \ : NewTelecineHelper(c, iterLeft) } function NewTelecine(clip c) { assert(c.FrameCount() > 0, "NewTelecine: input clip must have at least one frame") c.NewTelecineHelper(Ceil(c.FrameCount() / 800.0)).AssumeFPS(29.97) return AudioDub(last, c) } Edit: The code should no longer add blank frames to the end when the framecount of the input clip is not a multiple of 800. Last edited by stickboy; 13th August 2003 at 09:54. |
12th August 2003, 13:45 | #8 | Link | |
Fascinated Lurker
Join Date: Feb 2002
Location: Durham, UK
Posts: 243
|
Quote:
You telecine 196 frames and then copy fram 197 and then telecine the next 196 frames until you've reached frame 800 then you start the cycle again. 196*4 = 784 1*4 = 4 total 788, continue cycles of 4 until frame 800. If you do things your way (from what I can understand of your code) then you will have frame 200 being the 199th frame being telecinied which would happen in the middle of a normal telecine pattern and that wouldn't be a good thing, I don't think, as you really want to keep the cycle of 4 frames being telecinied at once. However, I think I can adapt your script to what I need it to do. Please check my reasoning behind 196 again and how it would work. It's the same principle but it's making sure that you are always doing telecine on sections of 4 frames with the last frames being the exception. EDIT: OK, yes, I see the flaw in the 196 model now. I would prefer to not have to have telecine stop mid sequence (as it could end on one frame being represented by only one field. Perhaps then I could telecine 196 frames then just copy the other 4 directly and then repeat. Hmm, not sure... I want this telecine process to be as smooth as possible, you see. Last edited by zettai; 12th August 2003 at 14:00. |
|
12th August 2003, 17:24 | #9 | Link | |||
AviSynth Enthusiast
Join Date: Jul 2002
Location: California, U.S.
Posts: 1,267
|
Quote:
Quote:
Quote:
Last edited by stickboy; 12th August 2003 at 19:23. |
|||
12th August 2003, 18:54 | #10 | Link |
Fascinated Lurker
Join Date: Feb 2002
Location: Durham, UK
Posts: 243
|
Yes, sorry - I've had a good chance to really play around with it and it's perfect! Sorry for doubting you
Thank you ever so much for working out how to use trim like that and helping me with the script. It's exactly what I need! |
12th August 2003, 19:20 | #11 | Link | |
AviSynth Enthusiast
Join Date: Jul 2002
Location: California, U.S.
Posts: 1,267
|
BTW, the code above is sort of meant as proof-of-concept, not for production use or anything...
If the framecount of the original clip is not a multiple of 800, you might end up with some extra frames at the very end, because if you call Trim with a start frame past the end of the clip, it returns the last frame of the clip instead of a 0-frame clip. I really should use my Trim2 function instead, but currently its bounds-checking is too strict to be used in this case easily. I will relax the checks and post an updated version later today. Quote:
OTOH, using intervals of 200 should be a little bit smoother, since the discrepancy at the end is smaller. Last edited by stickboy; 12th August 2003 at 19:58. |
|
13th August 2003, 16:50 | #15 | Link |
Registered User
Join Date: Aug 2002
Posts: 467
|
A question: Where did you get actual 24 fps content? PAL is 25 fps, so if you convert to 24 fps, then why not just convert to 23.976 fps? IVTC'd NTSC is 23.976.
Anyway, you can always just: Code:
ChangeFPS(59.94) SeparateFields() SelectEvery(4,0,3) Weave() # or not Xesdeeni |
13th August 2003, 17:38 | #16 | Link |
Fascinated Lurker
Join Date: Feb 2002
Location: Durham, UK
Posts: 243
|
Well, it's a long story
One of the annoying bugs of Adobe Premiere is that it can't deal with 23.976fps footage. Upon export it will make it 23.98fps which is no use to man nor beast. What I used to do to get around this was to: a) take my audio stream and do a rate change on it b) assuemfps(24) on all 23.976 source footage c) edit at 24fps, export at 24fps d) Assumefps(23.976) on exported video e) Re-attach original unchanged audio stream. But once upon a time, I didn't think about doing things this way - I just edited at 24fps so I wouldnt have frame drift because of premiere being dumb. Then I realised that to make things 29.97fps I'd have to either change the audio stream or remove frames... neither of which I wanted to do. This is where the idea came from. I'll look into changefps, but I figured doing it in the telecine would smooth out the transition as much as possible. |
15th October 2006, 21:42 | #17 | Link |
Registered User
Join Date: Jan 2006
Posts: 1,867
|
Stickboy, thanks a lot! I've wanted this exact function for a while. Changefps(), has a phase problem. Example, 24p->30i starting at 0 you get clean, laced, laced, clean, clean but changefps() gives me laced,laced,laced,clean,clean... I wanted precise control to be able to label each field and frame for a test video, one counter runs at 24fps, another at 60i, another at 30p, so I could see the exact effects of doubleweave, deint, pulldown, and other functions.
Thanks stickboy again, for explaining doubleweave on your page! My other problem has been deint's picking the wrong duplicate because of B frame causing a ghosting with the next frame, but that's another topic... |
18th October 2006, 02:40 | #18 | Link |
Registered User
Join Date: Oct 2003
Posts: 209
|
Hate to break this to you, but Premiere Pro (I tested 1.5, 2.0 is now the current version) works with it just fine. It only rounds to 23.98 when *displaying* the framerate -- internally, it is properly represented at 23.976 and I've never had a frame drop/desynch when working with 23.976p footage.
|
18th October 2006, 19:33 | #19 | Link | |
Registered User
Join Date: Dec 2001
Posts: 1,219
|
Quote:
On that note though, I think I have seen premiere pro (1.5 at least, maybe 2.0 as well) drop a frame or 2 with 23.976 footage. I believe it relates to the rational framerate value that is stored in the avi. |
|
Thread Tools | Search this Thread |
Display Modes | |
|
|