Within, like, 15 minutes, someone pointed out that it did indeed work for detecting PAL vs. NTSC, and this person, with both PAL and NTSC discs, enjoyed the feature very much. So it got thrown back in.
Of course, the problems are enduring. HandBrake's FPS problems have even been highlighted for scorn by jwz himself. Despite being in the FAQ, every week someone comes along suffering from "Same as source"'s stupidity.
Let me explain in detail what's going on with Same as source. All it does is not specify a frame rate, so HandBrake sticks with what it decided to use when it scanned the disc. However, there's a little bit of code in decmpeg2.c (the interface with libmpeg2's mpeg2dec) that switches things up a bit:
Code: Select all
if( m->rate == 900900 )
{
/* 29.97 fps. 3:2 pulldown might, or might not be
used. I can't find a way to know, so we always
output 23.976 */
m->rate = 1126125;
}
My first idea was to apply some crude heuristics. Most 16x9 NTSC content is film speed, most 4x3 NTSC content is video speed. So instead of decimating all NTSC stuff to 23.976, only do it for widescreen.
That didn't work out too well, because of all the 4:3 NTSC TV-on-DVD boxed sets that are at 23.976.
So instead, I'm thinking of looking at the flag info we get about the frames from libmpeg2. The first step was patching libmpeg2 to see the flag REPEAT_FIRST_FIELD, which I ripped off of mencoder:
Code: Select all
diff -ur orig/header.c mpeg2dec/libmpeg2/header.c
--- orig/header.c 2003-12-22 12:24:02.000000000 +0100
+++ mpeg2dec/libmpeg2/header.c 2004-08-02 18:07:50.000000000 +0200
@@ -100,6 +100,9 @@
mpeg2dec->decoder.convert = NULL;
mpeg2dec->decoder.convert_id = NULL;
mpeg2dec->picture = mpeg2dec->pictures;
+ memset(&mpeg2dec->fbuf_alloc[0].fbuf, 0, sizeof(mpeg2_fbuf_t));
+ memset(&mpeg2dec->fbuf_alloc[1].fbuf, 0, sizeof(mpeg2_fbuf_t));
+ memset(&mpeg2dec->fbuf_alloc[2].fbuf, 0, sizeof(mpeg2_fbuf_t));
mpeg2dec->fbuf[0] = &mpeg2dec->fbuf_alloc[0].fbuf;
mpeg2dec->fbuf[1] = &mpeg2dec->fbuf_alloc[1].fbuf;
mpeg2dec->fbuf[2] = &mpeg2dec->fbuf_alloc[2].fbuf;
@@ -551,6 +554,7 @@
if (!(mpeg2dec->sequence.flags & SEQ_FLAG_PROGRESSIVE_SEQUENCE)) {
picture->nb_fields = (buffer[3] & 2) ? 3 : 2;
flags |= (buffer[3] & 128) ? PIC_FLAG_TOP_FIELD_FIRST : 0;
+ flags |= (buffer[3] & 2) ? PIC_FLAG_REPEAT_FIRST_FIELD : 0;
} else
picture->nb_fields = (buffer[3]&2) ? ((buffer[3]&128) ? 6 : 4) : 2;
break;
diff -ur orig/mpeg2.h mpeg2dec/include/mpeg2.h
--- orig/mpeg2.h 2003-12-22 13:13:35.000000000 +0100
+++ mpeg2dec/include/mpeg2.h 2004-02-18 13:50:13.000000000 +0100
@@ -82,6 +82,7 @@
#define PIC_FLAG_COMPOSITE_DISPLAY 32
#define PIC_FLAG_SKIP 64
#define PIC_FLAG_TAGS 128
+#define PIC_FLAG_REPEAT_FIRST_FIELD 256
#define PIC_MASK_COMPOSITE_DISPLAY 0xfffff000
typedef struct mpeg2_picture_s {
Code: Select all
hb_log("MPEG 2 Info for PTS %lld", m->last_pts);
if( m->info->display_picture->flags & PIC_FLAG_TOP_FIELD_FIRST )
hb_log("MPEG2 Flag: Top field first");
if( m->info->display_picture->flags & PIC_FLAG_PROGRESSIVE_FRAME )
hb_log("MPEG2 Flag: Progressive");
if( m->info->display_picture->flags & PIC_FLAG_COMPOSITE_DISPLAY )
hb_log("MPEG2 Flag: Composite");
if( m->info->display_picture->flags & PIC_FLAG_SKIP )
hb_log("MPEG2 Flag: Skip!");
if( m->info->display_picture->flags & PIC_FLAG_TAGS )
hb_log("MPEG2 Flag: TAGS");
if( m->info->display_picture->flags & PIC_FLAG_REPEAT_FIRST_FIELD )
hb_log("MPEG2 Flag: REPEAT FIRST FIELD");
And this on a 29.97 video with hard telecining:Scanning title 1 of 5...
[13:28:40] scan: preview 1
[13:28:40] MPEG 2 Info for PTS -1
[13:28:40] MPEG2 Flag: Top field first
[13:28:40] MPEG2 Flag: Progressive
[13:28:40] MPEG2 Flag: TAGS
[13:28:40] scan: preview 2
[13:28:40] MPEG 2 Info for PTS -1
[13:28:40] MPEG2 Flag: Progressive
[13:28:40] MPEG2 Flag: TAGS
[13:28:40] MPEG2 Flag: REPEAT FIRST FIELD
[13:28:40] scan: preview 3
[13:28:40] MPEG 2 Info for PTS -1
[13:28:40] MPEG2 Flag: Progressive
[13:28:40] MPEG2 Flag: TAGS
So. It seems to me that this could be an easy way of autodetecting NTSC frame rate. See the progressive and repeat flags in most of the preview scans? Assume the title's 23.976. Otherwise? 29.97.[13:36:43] scan: preview 1
[13:36:43] MPEG 2 Info for PTS -1
[13:36:43] MPEG2 Flag: Top field first
[13:36:43] MPEG2 Flag: TAGS
[13:36:43] scan: preview 2
[13:36:43] MPEG 2 Info for PTS -1
[13:36:43] MPEG2 Flag: Top field first
[13:36:43] MPEG2 Flag: TAGS
[13:36:43] scan: preview 3
[13:36:44] MPEG 2 Info for PTS -1
[13:36:44] MPEG2 Flag: Top field first
[13:36:44] MPEG2 Flag: TAGS
Obviously, this won't solve anything for mixed content, and sure -- those preview scans will be wrong some of the time -- but it's a start.
I imagine we can extend this further, too. In my testing, running detelecine on truly interlaced content hasn't caused any problems. Might make sense to make that the default when scanning detects NTSC with no progressive or repeat first field flags, unless I'm missing something.