I’ve been working on a program recently that will hopefully be posted soon that deals with timecode and Quicktime movies. Specifically, adding timecode tracks and doing timecode addition and subtraction. In order to do this, you need to convert the timecode, which is in an hours:minutes:seconds:frames format into a number representing the total number of frames, do your math with frame numbers, and convert back to the timecode format. For non-drop frame timecode, this is trivial. It gets complicated when you’re dealing with drop frame timecode. If you don’t know what that is, it’s a way of accurately measuring the running time of video that doesn’t run at an even frame rate. In America, video runs at 29.97 frames per second, but we usually count it at 30 fps. This means after a while, the number we use to count is wrong. The solution to this problem is drop frame timecode, which is sort of like leap year for timecode. At 29.97 fps, every minute (except ones divisible by ten), you skip counting the first two frames. You know you’re looking at drop frame timecode because the colon between minutes and frames is usually replaced by a semicolon. For example, you go:
12:38:59;27
12:38:59;27
12:38:59;28
12:38:59;29
and then you skip to…
12:39:00;02
12:39:00;03
[This code has been updated on 8/8/2010 to correct a bug on line 27 caught by Jean-Baptiste Mardelle of Kdenlive. It was updated again on 1/4/2012 to fix a minor syntax error and correct a display issue with < and > symbols. Thanks to Martin Baker for catching those.]
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
//CONVERT A FRAME NUMBER TO DROP FRAME TIMECODE //Code by David Heidelberger, adapted from Andrew Duncan //Given an int called framenumber and a double called framerate //Framerate should be 29.97, 59.94, or 23.976, otherwise the calculations will be off. int d; int m; int dropFrames = round(framerate * .066666); //Number of frames to drop on the minute marks is the nearest integer to 6% of the framerate int framesPerHour = round(framerate*60*60); //Number of frames in an hour int framesPer24Hours = framesPerHour*24; //Number of frames in a day - timecode rolls over after 24 hours int framesPer10Minutes = round(framerate * 60 * 10); //Number of frames per ten minutes int framesPerMinute = (round(framerate)*60)- dropFrames; //Number of frames per minute is the round of the framerate * 60 minus the number of dropped frames if (framenumber<0) //Negative time. Add 24 hours. { framenumber=framesPer24Hours+framenumber; } //If framenumber is greater than 24 hrs, next operation will rollover clock framenumber = framenumber % framesPer24Hours; //% is the modulus operator, which returns a remainder. a % b = the remainder of a/b d = framenumber\framesPer10Minutes; // \ means integer division, which is a/b without a remainder. Some languages you could use floor(a/b) m = framenumber % framesPer10Minutes //In the original post, the next line read m>1, which only worked for 29.97. Jean-Baptiste Mardelle correctly pointed out that m should be compared to dropFrames. if (m>dropFrames) { framenumber=framenumber + (dropFrames*9*d) + dropFrames*((m-dropFrames)\framesPerMinute); } else { framenumber = framenumber + dropFrames*9*d; } int frRound = round(framerate); int frames = framenumber % frRound; int seconds = (framenumber \ frRound) % 60; int minutes = ((framenumber \ frRound) \ 60) % 60; int hours = (((framenumber \ frRound) \ 60) \ 60); |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
//CONVERT DROP FRAME TIMECODE TO A FRAME NUMBER //Code by David Heidelberger, adapted from Andrew Duncan //Given ints called hours, minutes, seconds, frames, and a double called framerate int dropFrames = round(framerate*.066666); //Number of drop frames is 6% of framerate rounded to nearest integer int timeBase = round(framerate); //We don't need the exact framerate anymore, we just need it rounded to nearest integer int hourFrames = timeBase*60*60; //Number of frames per hour (non-drop) int minuteFrames = timebase*60; //Number of frames per minute (non-drop) int totalMinutes = (60*hours) + minutes; //Total number of minuts int frameNumber = ((hourFrames * hours) + (minuteFrames * minutes) + (timeBase * seconds) + frames) - (dropFrames * (totalMinutes - (totalMinutes \ 10))); return frameNumber; |
Pingback: The Editblog » Linkage: June 2010