Extract Video Frames
GUIDE 03 / Frame rate & timecode

Drop-Frame vs Non-Drop-Frame Timecode: Worked Boundary Examples

Follow consecutive frames across 29.97 and 59.94 minute boundaries, reject skipped labels, and convert timecode through checked frame counts.

ExtractVideoFrames.com editorialReviewed November 3, 2026Methods & evidence ↓
29.97 DF / FRAMES CONTINUE, LABELS CHANGEZero-based model
FRAME 179800:00:59;28One actual picture
FRAME 179900:00:59;29One actual picture
FRAME 180000:01:00;02Skip labels ;00 and ;01
FRAME 180100:01:00;03One actual picture
The index advances by one across every tile. DF omits labels, never the corresponding video pictures.

Drop-frame (DF) and non-drop-frame (NDF) timecode label the same pictures at the same playback rate. The only difference is which labels appear in the sequence. At 29.97, DF never uses the labels ;00 and ;01 in the first second of a minute unless that minute is divisible by ten. At 59.94 it never uses ;00 through ;03 on the same schedule. Skipping those labels keeps the label sequence within a few thousandths of a second of the clock at ten-minute marks. It does not delete frames, change playback speed or convert a frame rate.

Counting conventions used below

  • Frame index: zero-based position in the clip. Index 0 is the first frame.

  • Elapsed frames: how many frames have passed. N elapsed frames reach the frame whose index is N.

  • Duration between two labels: the difference of their frame indices, never the difference of their printed fields.

  • Seconds: exact values from 30000/1001 and 60000/1001, with any rounding stated.

What changes between DF and NDF, and what does not

ThingWhat it isChanged by choosing DF?
Actual video framesThe pictures in the fileNo
Actual playback rate30000/1001 fps (29.97002997…) or 60000/1001 fps (59.94005994…)No
Elapsed secondsFrame index × 1001 ÷ 30000 (or ÷ 60000)No
Nominal counting base30 or 60; sets how high the last field countsNo
Timecode label sequenceWhich labels are assigned to consecutive framesYes, and only this

“29.97” and “59.94” are rounded displays of those fractions. Calculations in this article use the exact rational rates.

The exact rates and label rules are separate concepts. For playback-rate mismatches, see 29.97 versus true 30 FPS.

Read the fields and the counting base

A label reads HH:MM:SS:FF. The last field is a frame number inside the current nominal second, counted from zero. It is not hundredths of a second. At 29.97 it runs 00–29 because the counting base is 30; at 59.94 it runs 00–59. For example, 00:00:01:12 at 29.97 NDF is frame index 42, which starts at 1.4014 s, not 1.12 s.

Punctuation is a common clue, not proof. Many editors write DF with a semicolon before the frame field and NDF with colons. SMPTE’s text notation, as summarized by EDLmax, also lets the separator signal interlace field information (period, colon, comma, semicolon). FFmpeg’s timecode option accepts a semicolon or a period for drop frame. A tool can display either style regardless of the file, so confirm the convention with the boundary tests below. Likewise, a frame-rate estimate such as the one from the video FPS checker tells you how quickly frames arrive. It does not tell you whether the labels skip.

Follow the first-minute boundary at 29.97

Table 1 lists six consecutive frames of a clip at 30000/1001 fps, starting at index 0. Each row is one actual picture. The DF and NDF columns label that same picture.

Table 1. 29.97 first-minute boundary (illustrative numbering, computed)

Zero-based frame indexDF labelNDF labelFrame start time (s)
1,79700:00:59;2700:00:59:2759.959900
1,79800:00:59;2800:00:59:2859.993267
1,79900:00:59;2900:00:59:2960.026633
1,80000:01:00;0200:01:00:0060.060000
1,80100:01:00;0300:01:00:0160.093367
1,80200:01:00;0400:01:00:0260.126733

The step from ;29 to ;02 looks like a gap, but the index advances by one (1,799 to 1,800), so exactly one frame interval of 1001/30000 s (33.367 ms) passes. Subtracting the printed fields by hand gives 3 frames; subtracting indices gives 1. Use indices whenever a duration crosses a minute boundary.

Why skip anything? After 1,800 frames, 60.06 s have really elapsed, but an NDF counter has counted them as a nominal 60 s (00:01:00:00). DF jumps to ;02, a nominal 60.0667 s, which is 6.7 ms from the true 60.06 s instead of 60 ms away. SMPTE’s ST 12-1 defines the rule; EDLmax quotes its drop-frame section as saying the first two frame numbers (00 and 01) shall be omitted from the count at the start of each minute except tenth minutes.

As a result, 00:01:00;00 and 00:01:00;01 do not label any frame under 29.97 DF. 00:01:00;02 is the first label of that minute.

Understand the tenth-minute exception

Ten minutes at 30000/1001 fps contain 600 × 30000 ÷ 1001 = 17,982.018 frames. A 30-per-second label count would run to 18,000 labels in that time, so about 18 labels must be skipped. Skipping two in every minute would remove 20, which overshoots. Skipping two in nine of every ten minutes removes exactly 18, leaving 17,982 labels against 17,982.018 frames. The tenth minute is exempt, and the leftover 0.018 frame is about 0.6 ms per ten minutes.

Table 2. 29.97 tenth-minute boundary

Zero-based frame indexDF labelNDF labelFrame start time (s)
17,97900:09:59;2700:09:59:09599.899300
17,98000:09:59;2800:09:59:10599.932667
17,98100:09:59;2900:09:59:11599.966033
17,98200:10:00;0000:09:59:12599.999400
17,98300:10:00;0100:09:59:13600.032767
17,98400:10:00;0200:09:59:14600.066133

Here nothing is skipped, so 00:10:00;00 and 00:10:00;01 are valid labels. The NDF column shows how far the counter has fallen behind: it is 12 labels short of 00:10:00:00 after 17,982 frames.

Off-by-one guard. 17,982 is both the number of elapsed frames at this point and the index of the frame labeled 00:10:00;00. A clip containing exactly 17,982 frames has indices 0 to 17,981. Its last frame is 00:09:59;29, and its duration is 17,982 × 1001 ÷ 30000 = 599.9994 s. A last-frame label is not a clip’s full duration.

Compare the 59.94 convention

At 60000/1001 fps the nominal base is 60 and DF skips four labels, ;00 to ;03, at the same minute boundaries. Software and vendor interfaces that count to 59 at this rate document this: GStreamer supports drop frame only at 30000/1001 and 60000/1001 (and its source comments skip two at 30000/1001 and four at 60000/1001), FFmpeg’s libavutil permits drop frame only with those two rates, and Apple documents a 59.94 drop type whose frame numbers are adjusted to match elapsed clock time. This article describes the 0–59 label convention that such tools display. It does not claim how any particular file stores its timecode.

Table 3. 59.94 first-minute boundary

Zero-based frame indexDF labelNDF labelFrame start time (s)
3,59700:00:59;5700:00:59:5760.009950
3,59800:00:59;5800:00:59:5860.026633
3,59900:00:59;5900:00:59:5960.043317
3,60000:01:00;0400:01:00:0060.060000
3,60100:01:00;0500:01:00:0160.076683
3,60200:01:00;0600:01:00:0260.093367

The skipped-label range at this boundary is 00:01:00;00 through 00:01:00;03.

Table 4. 59.94 tenth-minute boundary

Zero-based frame indexDF labelNDF labelFrame start time (s)
35,96100:09:59;5700:09:59:21599.949350
35,96200:09:59;5800:09:59:22599.966033
35,96300:09:59;5900:09:59:23599.982717
35,96400:10:00;0000:09:59:24599.999400
35,96500:10:00;0100:09:59:25600.016083
35,96600:10:00;0200:09:59:26600.032767

Compact comparison

29.97 NDF29.97 DF59.94 NDF59.94 DF
Actual rate30000/1001same60000/1001same
Last field runs00–2900–2900–5900–59
Labels skippednone;00, ;01none;00 to ;03
Skipped whenneverfirst second of each minute not divisible by 10neversame schedule
Labels per 10 minutes18,00017,98236,00035,964
Labels per hour108,000107,892216,000215,784
Real time at label 01:00:003,603.6 s3,599.9964 s3,603.6 s3,599.9964 s

Convert frame counts into labels and real seconds

Table 5. Checked controls (counts are elapsed frames from 00:00:00 unless stated)

Quantity29.97 (30000/1001)59.94 (60000/1001)
Elapsed frames17,98235,964
DF label of frame index equal to that count00:10:00;0000:10:00;00
NDF label of the same frame00:09:59:1200:09:59:24
Exact elapsed time2,999,997/5,000 s = 599.9994 s2,999,997/5,000 s = 599.9994 s
Last frame within those elapsed frames (index)17,981: DF 00:09:59;2935,963: DF 00:09:59;59
One hour of NDF labels (01:00:00:00)108,000 frames = 3,603.6 s216,000 frames = 3,603.6 s
One hour of DF labels (01:00:00;00)107,892 frames = 3,599.9964 s215,784 frames = 3,599.9964 s

An NDF label of 01:00:00:00 therefore describes 3.6 s more than an hour. Run the clock for exactly 3,600 s and the frame being shown is index 107,892 at 29.97: 00:59:56:12 in NDF and 01:00:00;00 in DF. DF is not perfect: labels read as nominal seconds are 0.6 ms off at each ten-minute mark, 3.6 ms off at one hour, and between those marks a frame’s true start can sit roughly 64 ms below to 60 ms above its nominal label time during the first hour (about two frames at 29.97). Over an unwrapped elapsed count, NDF’s offset accumulates; a displayed clock may roll over. For the intervals here: 0.06 s after one minute, 0.6 s after ten, 3.6 s after one hour.

A calculation you can reproduce: 00:12:34;15 at 29.97 DF

  • Nominal label count at base 30: (12 × 60 + 34) × 30 + 15 = 22,635.

  • Minutes 1 to 12 each begin with a skip except minute 10, which makes 11 skips of 2 labels: 22.

  • Frame index = 22,635 − 22 = 22,613 (zero-based).

  • Start time = 22,613 × 1001 ÷ 30,000 = 22,635,613 ÷ 30,000 = 754.520433 s.

  • Read the same text as NDF and you get index 22,635, which is 22 frames (0.734 s) later. Mixing the two conventions at minute 12 shifts a cue by 22 frames. At 59.94 the same label gives 754 × 60 + 15 = 45,255, minus 11 × 4 = 44, so index 45,211 at 754.270183 s.

The mismatch grows by two frames per minute at 29.97 (four at 59.94), pausing at each tenth minute. You can use the Extract Video Frames timecode calculator to check the frame count and timecode for your own label.

A duration between two labels follows the same rule. From 00:03:21;10 (index 6,034) to 00:12:34;15 (index 22,613) is 16,579 elapsed frames, or 553.185967 s. Subtracting the printed fields would not give that.

Diagnose invalid labels and mismatched settings

A label is invalid when:

  • The frame field reaches the counting base, such as ;30 at 29.97 or ;60 at 59.94.

  • Minutes or seconds are 60 or higher.

  • Under DF, seconds are 00, the minute is not divisible by ten, and the frame field is below the skip count: under 2 at 29.97, under 4 at 59.94.

LabelConventionValid?Why
00:01:00;00, 00:01:00;0129.97 DFNoSkipped at a non-tenth minute
00:01:00;0229.97 DFYesFirst label of the minute
00:10:00;00, 00:10:00;0129.97 DFYesTenth minute, nothing skipped
00:02:00;0129.97 DFNoSkipped at minute 2
00:01:00;00 to ;0359.94 DFNoFour labels skipped
00:01:00;0459.94 DFYesFirst label of the minute
00:01:00:0029.97 NDFYesNDF skips nothing, so the same text is fine here
00:00:59;3029.97NoFrame field exceeds the base

Symptoms from mismatched settings are recognizable by size:

SymptomLikely causeCheck
Label jumps by 2 (or 4) at a minute boundaryNormal DF skip, nothing lostCompare frame indices across the jump
Cues land 2 frames off after minute 1, 22 frames off after minute 12DF text treated as NDF or the reverseConvert via frame index, not by swapping punctuation
Drift reaching about 3.6 s per labeled hourDF/NDF mix, or 1000/1001 rate confused with its integer rateVerify the exact rate and the convention
Constant offset of exactly one hourStart reference of 01:00:00:00Subtract the actual start label
One frame too long or shortInclusive endpoint countingSee the position-or-duration check below

Switching DF/NDF does not repair a frame-rate or audio-sync problem. It changes the numbers printed beside the same frames, and Adobe states that changing the display format does not alter the frame rate of clips or sequences. Closed Caption Creator draws the useful line between relabeling (the picture times stay put) and conforming to a different rate (every time must be recalculated). If cues drift, look for a rate or start mismatch rather than a display toggle.

Choose the convention your workflow requires

  • A written delivery requirement. If a spec, broadcaster or client names DF or NDF, follow it. That is a requirement.

  • The convention of the material you were given. Match the EDL, caption file or project you are working from.

  • Your project default. With neither of the above, choose one and record it. This is a preference, and sources disagree on which is better. For NTSC work, Adobe’s sequence reference recommends drop-frame timecode because it displays duration accurately, while others favor NDF for frame counting. B&H lists system specification, distribution media and editor preference as the deciding factors.

No single convention is universally required. Caption formats illustrate this: per Closed Caption Creator, SCC signals DF with a semicolon, while SRT and WebVTT store real time and have no DF or NDF at all. Converting between them still needs the exact rate and convention.

Checklist when someone sends you a timecode

  • Actual rate: exact value (for example 30000/1001), not just “30.”

  • Counting convention: DF or NDF, confirmed with a boundary test, not punctuation alone.

  • Start reference: does 00:00:00 mean the first frame, or does the source begin at 01:00:00:00 or a time-of-day value?

  • Position or duration: a label is a position; a duration is a difference of indices. Adobe’s timecode help notes that In and Out points identical in timecode give a one-frame duration, so confirm whether the end frame is included.

Frequently asked questions

Does drop frame delete frames or change speed? No. Pictures and playback rate are untouched; only labels differ.

Is DF identical to wall-clock time? No. It stays within about 0.6 ms per ten minutes at the ten-minute marks and a few tens of milliseconds in between.

Is there drop frame at 23.976? The common 29.97/59.94 rules described here do not supply a 23.976 DF convention. The referenced tools limit their supported DF modes to particular multiples of 30000/1001 (GStreamer’s code states that 24000/1001 is not a drop-frame rate, and Medialooks and Epic’s Unreal docs say the same). The 1000/1001 offset still exists there; it is just not corrected by skipping labels.

Can I turn a DF label into NDF by swapping the semicolon? No. Convert through the frame index: 00:01:00;02 DF and 00:01:00:00 NDF are the same frame.

How were these examples checked? They were computed in exact rational arithmetic in Python (a literal label enumeration compared with a closed-form conversion across full hours), and the boundary labels were compared with FFmpeg’s drop-frame counter rendered as a synthetic text overlay. That overlay illustrates the numbering rule only. It does not show that any media file carries valid embedded timecode metadata.

Keep the clocks separate

A constant fractional rate can have regular frame intervals. DF/NDF chooses how those frames are labeled, not when their pictures appear. At film rates, compare 23.976 and true 24 FPS before interpreting a timecode as a stopwatch duration.

Methods & evidence

Boundary labels, skipped-label rejection and frame-count conversions were checked against the calculator functions and independent exact-rational arithmetic. Diagrams show zero-based label models, not embedded media metadata.

Examples and calculations are scoped to their stated settings. Source links support the instructions; an illustration is not a screenshot of an application test.

← Explore all guides