[FFmpeg-user] 24p-to-25i-to-30i double-telecine

Mark Filipak markfilipak.imdb at gmail.com
Mon Jul 14 02:51:44 EEST 2025


The object of this presentation is to recover 24p from a source that has been 24p-to-25i-to-30i 
double-telecined. Parts 1..3 are the appetizers. Part 4 begins the main course.

Part 1: A review of the combing patterns of the various 24-to-30 telecines to give readers the idea 
of what is to come in Parts 4..6.

input: [A+a][B+b][C+c][D+d]
output: below
'p' - progressive, 'c' - combed

For 2:3:2:3 pull-down:
[A+a][B+b][B+c][C+d][D+d]
p    p    c    c    p

For 3:2:3:2 pull-down:
[A+a][A+b][B+c][C+c][D+d]
p    c    c    p    p

For 2:2:3:3 pull-down:
[A+a][B+b][C+c][C+d][D+d]
p    p    p    c    p

For 2:3:3:2 pull-down:
[A+a][B+b][B+c][C+c][D+d]
p    p    c    p    p

For 3:3:2:2 pull-down:
[A+a][A+b][B+b][C+c][D+d]
p    c    p    p    p

For 3:2:2:3 pull-down:
[A+a][A+b][B+c][C+d][D+d]
p    c    c    c    p

Part 2: A technique for 30i-to-24p detelecining based on the patterns.

void function 30i-to-24p() {
   switch getpattern(separatefields(get5frames(N))) {
     case ppccp: // [A+a][B+b][B+c][C+d][D+d]
       8fieldframes = shuffleframes(0 1 2 3 -1 5 4 7 6 -1);
       break;
     case pccpp: // [A+a][A+b][B+c][C+c][D+d]
       8fieldframes = shuffleframes(0 1 -1 3 2 5 4 -1 6 7);
       break;
     case pppcp: // [A+a][B+b][C+c][C+d][D+d]
       8fieldframes = shuffleframes(0 1 2 3 4 5 -1 7 6 -1);
       break;
     case ppcpp: // [A+a][B+b][B+c][C+c][D+d]
       8fieldframes = shuffleframes(0 1 2 3 -1 5 4 -1 6 7);
       break;
     case pcppp: // [A+a][A+b][B+b][C+c][D+d]
       8fieldframes = shuffleframes(0 1 -1 3 2 -1 4 5 6 7);
       break;
     case pcccp: // [A+a][A+b][B+c][C+d][D+d]
       8fieldframes = shuffleframes(0 1 -1 3 2 5 4 7 6 -1);
     }
     put4frames(weave(8fieldframes));
   N+=5;
}

Kindly don't ridicule me too much. I know I'm literally passing whole frames. I know that 'N' should 
instead be a pointer into an array of frame-buffer pointers. I know that separatefields() and 
weave() probably doesn't exist by those names and that they undoubtedly pass pointers, not frames & 
fields. I know I haven't defined functions getpattern() and put4frames() and variable 8fieldframes. 
Sorry, I don't know 'C' and I don't know how FFmpeg is organized.

Part 3: The point I'm trying to make is that something like this must already exist, eh? And if it 
does, and if it spans all 6 patterns, then it has 100% coverage because 6 patterns is all there can 
be and because each pattern is unique.

This ends the appetizer and begins the main course.

Part 4: It appears to me that BBC, for one, has made 30i videos (so-called "NTSC") from existing 25i 
videos (so-called "PAL") that were initially shot as 24p. Based on comb sequences, it appears that 
the 24p, first, is 24-to-25 (euro) telecined, then, second, telecined a second time via 5-to-6 
telecine. That produces 30i that is a mix of progressive frames, 41.[6..] ns combs, and 83.[3..] ns 
combs. Unfortunately for the NTSC folks, such double-telecined DVDs do exist; I've seen them and 
they're god-awful, especially when the "PAL" was cut and spliced prior to the second telecine and 
also when the "NTSC" was secondarily cut and spliced in the process of assembling an "NTSC" master. 
The BBC, for one, appears to be not very thoughtful or careful doing that -- the "NTSC" version of 
"I, Claudius" comes immediately to mind.

I'm calling the 2-step process "24p-to-25i-to-30i double-telecine". Note that the topic here is only 
30i that has previously been 24p-to-25i telecined, not 30i made from so-called "PAL speed-up" or 30i 
made from native PAL.

Part 5: There are 25 'flavors' of 24-to-25 telecine. Each 'flavor' is further 'spiced' by the 6 
varieties of 5-to-6 telecine above. That means there are 150 combinations of 'spiced flavors' in 
24p-to-25i-to-30i double-telecine. The detelecine (back to 24p) of every 'spiced flavor' based 
solely on 150 comb patterns is quite possible.

Part 6: I could write a Java program to find all 150 comb patterns plus all 150 shuffleframes 
recipes in order to populate a 150 case switch-case, but I need to know first whether there's any 
appetite for this meal. Is there? It would mean also writing a getpattern() that automates the whole 
process, or at least a getpattern() that would report the pattern so that users could then manually 
select and submit the appropriate shuffleframes as a CLI command. Of course, the manual approach 
would break when it encounters a 'bad' cut-n-splice -- meaning: Users would need to know where the 
breaks are so that they can make and process segments that they splice together, later.

Regards,
Mark.

PS: I'm submitting this here because joining ffmpeg-devel has been unsuccessful.



More information about the ffmpeg-user mailing list