gst/typefind/gsttypefindfunctions.c: Fix MPEG-1 stream typefinding.

Original commit message from CVS:
2004-01-23  Ronald Bultje  <rbultje@ronald.bitfreak.net>

* gst/typefind/gsttypefindfunctions.c: (mpeg1_parse_header),
(mpeg1_sys_type_find):
Fix MPEG-1 stream typefinding.
This commit is contained in:
Ronald S. Bultje 2004-01-23 16:55:21 +00:00
parent f14069a741
commit 6b2e142ccb
2 changed files with 79 additions and 53 deletions

View file

@ -1,3 +1,9 @@
2004-01-23 Ronald Bultje <rbultje@ronald.bitfreak.net>
* gst/typefind/gsttypefindfunctions.c: (mpeg1_parse_header),
(mpeg1_sys_type_find):
Fix MPEG-1 stream typefinding.
2004-01-23 Ronald Bultje <rbultje@ronald.bitfreak.net> 2004-01-23 Ronald Bultje <rbultje@ronald.bitfreak.net>
* gst/typefind/gsttypefindfunctions.c: (mpeg2_sys_type_find): * gst/typefind/gsttypefindfunctions.c: (mpeg2_sys_type_find):

View file

@ -449,74 +449,94 @@ mpeg2_sys_type_find (GstTypeFind *tf, gpointer unused)
static guint static guint
mpeg1_parse_header (GstTypeFind *tf, guint64 offset) mpeg1_parse_header (GstTypeFind *tf, guint64 offset)
{ {
guint8 *data = gst_type_find_peek (tf, offset, 18); guint8 *data = gst_type_find_peek (tf, offset, 4);
guint size; guint size;
if (!data) { if (!data) {
GST_LOG ("couldn't get 18 bytes to parse MPEG header"); GST_LOG ("couldn't get MPEG header bytes");
return 1; return 1;
} }
/* check header */ if (data[0] != 0 || data[1] != 0 || data[2] != 1) {
if (!IS_MPEG_HEADER (data)) {
GST_LOG ("This isn't an MPEG header");
return 0; return 0;
} }
data += 4; offset += 4;
switch (data[3]) {
case 0xBA: /* pack header */
data = gst_type_find_peek (tf, offset, 8);
if (!data) {
GST_LOG ("couldn't get MPEG pack header bytes");
return 1;
}
size = 12;
/* check marker bits */ /* check marker bits */
if ((*data & 0xF1) != 0x21) { if ((data[0] & 0xF1) != 0x21 ||
GST_LOG ("marker bits in byte 4 don't match"); (data[2] & 0x01) != 0x01 ||
(data[4] & 0x01) != 0x01 ||
(data[5] & 0x80) != 0x80 ||
(data[7] & 0x01) != 0x01)
return 0; return 0;
} break;
data += 2;
if ((*data & 0x01) != 0x01) {
GST_LOG ("marker bits in byte 6 don't match");
return 0;
}
data += 2;
if ((*data & 0x01) != 0x01) {
GST_LOG ("marker bits in byte 8 don't match");
return 0;
}
data ++;
if ((*data & 0x80) != 0x80) {
GST_LOG ("marker bits in byte 9 don't match");
return 0;
}
data += 2;
if ((*data & 0x01) != 0x01) {
GST_LOG ("marker bits in byte 11 don't match");
return 0;
}
data++;
if (!IS_MPEG_PACKET_HEADER (data) && case 0xB9: /* ISO end code */
!IS_MPEG_SYSTEM_HEADER (data)) { size = 4;
GST_LOG ("MPEG packet header doesn't match: %8.8X", GUINT32_FROM_BE (*((guint32 *) data))); break;
case 0xBB: /* system header */
data = gst_type_find_peek (tf, offset, 2);
if (!data) {
GST_LOG ("couldn't get MPEG pack header bytes");
return 1;
}
size = GUINT16_FROM_BE (* (guint16 *) data) + 6;
offset += 2;
data = gst_type_find_peek (tf, offset, size - 6);
if (!data) {
GST_LOG ("couldn't get MPEG pack header bytes");
return 1;
}
/* check marker bits */
if ((data[0] & 0x80) != 0x80 ||
(data[2] & 0x01) != 0x01 ||
(data[4] & 0x20) != 0x20)
return 0; return 0;
/* check stream marker bits */
for (offset = 6; offset < (size - 6); offset += 3) {
if (data[offset] <= 0xBB ||
(data[offset + 1] & 0xC0) != 0xC0)
return 0;
}
break;
default:
if (data[3] < 0xB9)
return 0;
data = gst_type_find_peek (tf, offset, 2);
if (!data) {
GST_LOG ("couldn't get MPEG pack header bytes");
return 1;
}
size = GUINT16_FROM_BE (* (guint16 *) data) + 6;
/* FIXME: we could check PTS/DTS marker bits here... (bit overkill) */
break;
} }
data += 4;
size = GUINT16_FROM_BE (*((guint16 *) data)) + 18;
GST_DEBUG ("found mpeg1 packet at offset %"G_GUINT64_FORMAT" with size %u", offset, size);
return size; return size;
} }
/* calculation of possibility to identify random data as mpeg systemstream: /* calculation of possibility to identify random data as mpeg systemstream:
* bits that must match in header detection: 65 * bits that must match in header detection: 32 (or more)
* chance that random data is identifed: 1/2^65 * chance that random data is identifed: 1/2^32
* chance that GST_MPEG_TYPEFIND_TRY_HEADERS headers are identified: * chance that GST_MPEG_TYPEFIND_TRY_HEADERS headers are identified:
* 1/2^(65*GST_MPEG_TYPEFIND_TRY_HEADERS) * 1/2^(32*GST_MPEG_TYPEFIND_TRY_HEADERS)
* chance that this happens in GST_MPEG_TYPEFIND_TRY_SYNC bytes: * chance that this happens in GST_MPEG_TYPEFIND_TRY_SYNC bytes:
* 1-(1-1/2^(65*GST_MPEG_TYPEFIND_TRY_HEADERS))^GST_MPEG_TYPEFIND_TRY_SYNC * 1-(1+1/2^(32*GST_MPEG_TYPEFIND_TRY_HEADERS)^GST_MPEG_TYPEFIND_TRY_SYNC)
* for current values: * for current values:
* 1-(1-1/2^(65*2)^50000 * 1-(1+1/2^(32*4)^101024)
* = 3.6734..*10^-35 * = <some_number>
*/ */
#define GST_MPEG_TYPEFIND_TRY_HEADERS 2 #define GST_MPEG_TYPEFIND_TRY_HEADERS 4
#define GST_MPEG_TYPEFIND_TRY_SYNC (GST_TYPE_FIND_MAXIMUM * 500) /* 50kB */ #define GST_MPEG_TYPEFIND_TRY_SYNC (100 * 1024) /* 100kB */
#define GST_MPEG_TYPEFIND_SYNC_SIZE 2048 #define GST_MPEG_TYPEFIND_SYNC_SIZE 2048
static void static void
mpeg1_sys_type_find (GstTypeFind *tf, gpointer unused) mpeg1_sys_type_find (GstTypeFind *tf, gpointer unused)