gst/typefind/gsttypefindfunctions.c: Further fine-tuning: don't absolutely require sequence or GOP headers but adjust...

Original commit message from CVS:
* 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).
This commit is contained in:
Tim-Philipp Müller 2008-05-03 12:09:16 +00:00
parent c6389eec57
commit 6de5983831
2 changed files with 41 additions and 18 deletions

View file

@ -1,3 +1,13 @@
2008-05-03 Tim-Philipp Müller <tim.muller at collabora co uk>
* 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 <wim.taymans@collabora.co.uk> 2008-05-02 Wim Taymans <wim.taymans@collabora.co.uk>
* gst-libs/gst/rtp/gstbasertppayload.c: (gst_basertppayload_init), * gst-libs/gst/rtp/gstbasertppayload.c: (gst_basertppayload_init),

View file

@ -1699,8 +1699,10 @@ static void
mpeg_video_stream_type_find (GstTypeFind * tf, gpointer unused) mpeg_video_stream_type_find (GstTypeFind * tf, gpointer unused)
{ {
MpegVideoStreamCtx c = { 0, NULL, 0 }; MpegVideoStreamCtx c = { 0, NULL, 0 };
gboolean seen_seq_at_0 = FALSE;
gboolean seen_seq = FALSE; gboolean seen_seq = FALSE;
gboolean seen_gop = FALSE; gboolean seen_gop = FALSE;
guint64 last_pic_offset = 0;
guint num_pic_headers = 0; guint num_pic_headers = 0;
gint found = 0; gint found = 0;
@ -1720,35 +1722,32 @@ mpeg_video_stream_type_find (GstTypeFind * tf, gpointer unused)
/* do we have a sequence header? */ /* do we have a sequence header? */
if (c.data[3] == 0xB3) { if (c.data[3] == 0xB3) {
seen_seq_at_0 = seen_seq_at_0 || (c.offset == 0);
seen_seq = TRUE; seen_seq = TRUE;
mpeg_video_stream_ctx_advance (tf, &c, 4 + 8); mpeg_video_stream_ctx_advance (tf, &c, 4 + 8);
continue; continue;
} }
/* we really want to see a sequence header first */ /* or a GOP header */
if (!seen_seq)
goto next;
/* next, a GOP header would be nice */
if (c.data[3] == 0xB8) { if (c.data[3] == 0xB8) {
seen_gop = TRUE; seen_gop = TRUE;
mpeg_video_stream_ctx_advance (tf, &c, 8); mpeg_video_stream_ctx_advance (tf, &c, 8);
continue; continue;
} }
/* we really want to see a sequence+GOP header before continuing */ /* but what we'd really like to see is a picture header */
if (!seen_gop)
goto next;
/* now that we've had a sequence+GOP, we'd like to see a picture header */
if (c.data[3] == 0x00) { if (c.data[3] == 0x00) {
++num_pic_headers; ++num_pic_headers;
last_pic_offset = c.offset;
mpeg_video_stream_ctx_advance (tf, &c, 8); mpeg_video_stream_ctx_advance (tf, &c, 8);
continue; continue;
} }
/* ... each followed by a slice header with slice_vertical_pos=1 */ /* ... each followed by a slice header with slice_vertical_pos=1 that's
if (c.data[3] == 0x01 && num_pic_headers > found) { * 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); mpeg_video_stream_ctx_advance (tf, &c, 4);
found += 1; found += 1;
continue; continue;
@ -1759,16 +1758,30 @@ mpeg_video_stream_type_find (GstTypeFind * tf, gpointer unused)
mpeg_video_stream_ctx_advance (tf, &c, 1); mpeg_video_stream_ctx_advance (tf, &c, 1);
} }
if (found > 0 || num_pic_headers > 0) { if (found > 0 || seen_seq) {
GstTypeFindProbability probability; GstTypeFindProbability probability = 0;
GstCaps *caps; GstCaps *caps;
if (found >= GST_MPEGVID_TYPEFIND_TRY_PICTURES) GST_LOG ("Found %d pictures, seq:%d, gop:%d", found, seen_seq, seen_gop);
probability = GST_TYPE_FIND_MAXIMUM - 2;
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) else if (found > 0)
probability = GST_TYPE_FIND_POSSIBLE + 1;
else
probability = GST_TYPE_FIND_POSSIBLE - 10; probability = GST_TYPE_FIND_POSSIBLE - 10;
else if (seen_seq)
probability = GST_TYPE_FIND_POSSIBLE - 20;
caps = gst_caps_copy (MPEG_VIDEO_CAPS); caps = gst_caps_copy (MPEG_VIDEO_CAPS);
gst_caps_set_simple (caps, "mpegversion", G_TYPE_INT, 1, NULL); gst_caps_set_simple (caps, "mpegversion", G_TYPE_INT, 1, NULL);