diff --git a/ChangeLog b/ChangeLog index 4fa2ccd2f9..82fdb21f78 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2008-05-03 Tim-Philipp Müller + + * gst/typefind/gsttypefindfunctions.c: (mpeg_video_stream_type_find): + Further fine-tuning: don't absolutely require sequence or GOP headers + (as introduced in the previous commit), but adjust the typefind + probabilities returned accordingly if we don't see them. Also make sure + picture header and first slice are somewhat close to each other (which + is not perfect but still better than requiring a fixed offset or having + no limit at all). + 2008-05-02 Wim Taymans * gst-libs/gst/rtp/gstbasertppayload.c: (gst_basertppayload_init), diff --git a/gst/typefind/gsttypefindfunctions.c b/gst/typefind/gsttypefindfunctions.c index 5f8c284339..c8b706a4ca 100644 --- a/gst/typefind/gsttypefindfunctions.c +++ b/gst/typefind/gsttypefindfunctions.c @@ -1699,8 +1699,10 @@ static void mpeg_video_stream_type_find (GstTypeFind * tf, gpointer unused) { MpegVideoStreamCtx c = { 0, NULL, 0 }; + gboolean seen_seq_at_0 = FALSE; gboolean seen_seq = FALSE; gboolean seen_gop = FALSE; + guint64 last_pic_offset = 0; guint num_pic_headers = 0; gint found = 0; @@ -1720,35 +1722,32 @@ mpeg_video_stream_type_find (GstTypeFind * tf, gpointer unused) /* do we have a sequence header? */ if (c.data[3] == 0xB3) { + seen_seq_at_0 = seen_seq_at_0 || (c.offset == 0); seen_seq = TRUE; mpeg_video_stream_ctx_advance (tf, &c, 4 + 8); continue; } - /* we really want to see a sequence header first */ - if (!seen_seq) - goto next; - - /* next, a GOP header would be nice */ + /* or a GOP header */ if (c.data[3] == 0xB8) { seen_gop = TRUE; mpeg_video_stream_ctx_advance (tf, &c, 8); continue; } - /* we really want to see a sequence+GOP header before continuing */ - if (!seen_gop) - goto next; - - /* now that we've had a sequence+GOP, we'd like to see a picture header */ + /* but what we'd really like to see is a picture header */ if (c.data[3] == 0x00) { ++num_pic_headers; + last_pic_offset = c.offset; mpeg_video_stream_ctx_advance (tf, &c, 8); continue; } - /* ... each followed by a slice header with slice_vertical_pos=1 */ - if (c.data[3] == 0x01 && num_pic_headers > found) { + /* ... each followed by a slice header with slice_vertical_pos=1 that's + * not too far away from the previously seen picture header. */ + if (c.data[3] == 0x01 && num_pic_headers > found && + (c.offset - last_pic_offset) >= 4 && + (c.offset - last_pic_offset) <= 64) { mpeg_video_stream_ctx_advance (tf, &c, 4); found += 1; continue; @@ -1759,16 +1758,30 @@ mpeg_video_stream_type_find (GstTypeFind * tf, gpointer unused) mpeg_video_stream_ctx_advance (tf, &c, 1); } - if (found > 0 || num_pic_headers > 0) { - GstTypeFindProbability probability; + if (found > 0 || seen_seq) { + GstTypeFindProbability probability = 0; GstCaps *caps; - if (found >= GST_MPEGVID_TYPEFIND_TRY_PICTURES) - probability = GST_TYPE_FIND_MAXIMUM - 2; + GST_LOG ("Found %d pictures, seq:%d, gop:%d", found, seen_seq, seen_gop); + + if (found >= GST_MPEGVID_TYPEFIND_TRY_PICTURES && seen_seq && seen_gop) + probability = GST_TYPE_FIND_NEARLY_CERTAIN - 1; + else if (found >= GST_MPEGVID_TYPEFIND_TRY_PICTURES && seen_seq) + probability = GST_TYPE_FIND_NEARLY_CERTAIN - 9; + else if (found >= GST_MPEGVID_TYPEFIND_TRY_PICTURES) + probability = GST_TYPE_FIND_LIKELY; + else if (seen_seq_at_0 && seen_gop && found > 2) + probability = GST_TYPE_FIND_LIKELY - 10; + else if (seen_seq && seen_gop && found > 2) + probability = GST_TYPE_FIND_LIKELY - 20; + else if (seen_seq_at_0 && found > 0) + probability = GST_TYPE_FIND_POSSIBLE; + else if (seen_seq && found > 0) + probability = GST_TYPE_FIND_POSSIBLE - 5; else if (found > 0) - probability = GST_TYPE_FIND_POSSIBLE + 1; - else probability = GST_TYPE_FIND_POSSIBLE - 10; + else if (seen_seq) + probability = GST_TYPE_FIND_POSSIBLE - 20; caps = gst_caps_copy (MPEG_VIDEO_CAPS); gst_caps_set_simple (caps, "mpegversion", G_TYPE_INT, 1, NULL);