gst-libs/gst/riff/riff-read.c: Additional pad usability check.

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

* gst-libs/gst/riff/riff-read.c: (gst_riff_read_info):
Additional pad usability check.
* gst/mpeg1videoparse/gstmp1videoparse.c: (gst_mp1videoparse_init),
(mp1videoparse_find_next_gop), (gst_mp1videoparse_time_code),
(gst_mp1videoparse_real_chain):
Fix MPEG video stream parsing. The original plugin had several
issues, including not timestamping streams where the source was
not timestamped (this happens with PTS values in mpeg system
streams, but MPEG video is also a valid stream on its own so
that needs timestamps too). We use the display time code for that
for now. Also, if one incoming buffer contains multiple valid
frames, we push them all on correctly now, including proper EOS
handling. Lastly, several potential segfaults were fixed, and we
properly sync on new sequence/gop headers to include them in next,
not previous frames (since they're header for the next frame, not
the previous). Also see #119206.
* gst/mpegaudioparse/gstmpegaudioparse.c: (gst_mp3parse_chain),
(bpf_from_header):
Move caps setting so we only do it after finding several valid
MPEG-1 fraes sequentially, not right after the first one (which
might be coincidental).
* gst/typefind/gsttypefindfunctions.c: (mpeg1_sys_type_find),
(mpeg_video_type_find), (mpeg_video_stream_type_find),
(plugin_init):
Add unsynced MPEG video stream typefinding, and change some
probability values so we detect streams rightly. The idea is as
follows: I can have an unsynced system stream which contains
video. In the current code, I would randomly get a type for either
system or video stream type found, because the probabilities are
being calculated rather randomly. I now use fixed values, so we
always prefer system stream if that was found (and that is how it
should be). If no system stream was found, we can still identity
the stream as video-only.
This commit is contained in:
Ronald S. Bultje 2004-01-25 00:25:16 +00:00
parent 978d3d6ab7
commit 20af0be15e
3 changed files with 129 additions and 10 deletions

View file

@ -1,3 +1,38 @@
2004-01-25 Ronald Bultje <rbultje@ronald.bitfreak.net>
* gst-libs/gst/riff/riff-read.c: (gst_riff_read_info):
Additional pad usability check.
* gst/mpeg1videoparse/gstmp1videoparse.c: (gst_mp1videoparse_init),
(mp1videoparse_find_next_gop), (gst_mp1videoparse_time_code),
(gst_mp1videoparse_real_chain):
Fix MPEG video stream parsing. The original plugin had several
issues, including not timestamping streams where the source was
not timestamped (this happens with PTS values in mpeg system
streams, but MPEG video is also a valid stream on its own so
that needs timestamps too). We use the display time code for that
for now. Also, if one incoming buffer contains multiple valid
frames, we push them all on correctly now, including proper EOS
handling. Lastly, several potential segfaults were fixed, and we
properly sync on new sequence/gop headers to include them in next,
not previous frames (since they're header for the next frame, not
the previous). Also see #119206.
* gst/mpegaudioparse/gstmpegaudioparse.c: (gst_mp3parse_chain),
(bpf_from_header):
Move caps setting so we only do it after finding several valid
MPEG-1 fraes sequentially, not right after the first one (which
might be coincidental).
* gst/typefind/gsttypefindfunctions.c: (mpeg1_sys_type_find),
(mpeg_video_type_find), (mpeg_video_stream_type_find),
(plugin_init):
Add unsynced MPEG video stream typefinding, and change some
probability values so we detect streams rightly. The idea is as
follows: I can have an unsynced system stream which contains
video. In the current code, I would randomly get a type for either
system or video stream type found, because the probabilities are
being calculated rather randomly. I now use fixed values, so we
always prefer system stream if that was found (and that is how it
should be). If no system stream was found, we can still identity the stream as video-only.
2004-01-23 Benjamin Otte <in7y118@public.uni-hamburg.de>
* gst/avi/gstavidemux.c: (gst_avi_demux_stream_avih),

View file

@ -815,7 +815,7 @@ gst_riff_read_info (GstRiffRead *riff)
/* let the world know about this wonderful thing */
for (padlist = gst_element_get_pad_list (element);
padlist != NULL; padlist = padlist->next) {
if (GST_PAD_IS_SRC (padlist->data)) {
if (GST_PAD_IS_SRC (padlist->data) && GST_PAD_IS_USABLE(padlist->data)) {
gst_event_ref (event);
gst_pad_push (GST_PAD (padlist->data), GST_DATA (event));
}

View file

@ -569,17 +569,10 @@ mpeg1_sys_type_find (GstTypeFind *tf, gpointer unused)
g_assert (found <= GST_MPEG_TYPEFIND_TRY_HEADERS);
if (found == GST_MPEG_TYPEFIND_TRY_HEADERS ||
packet_size == 1) {
guint probability = found * GST_TYPE_FIND_MAXIMUM *
(GST_MPEG_TYPEFIND_TRY_SYNC - skipped) /
GST_MPEG_TYPEFIND_TRY_HEADERS / GST_MPEG_TYPEFIND_TRY_SYNC;
if (probability < GST_TYPE_FIND_MINIMUM)
probability = GST_TYPE_FIND_MINIMUM;
g_assert (probability <= GST_TYPE_FIND_MAXIMUM);
caps = MPEG_SYS_CAPS;
gst_structure_set (gst_caps_get_structure (caps, 0), "mpegversion",
G_TYPE_INT, 1, 0);
gst_type_find_suggest (tf, probability, caps);
gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM - 1, caps);
return;
}
}
@ -603,7 +596,96 @@ mpeg_video_type_find (GstTypeFind *tf, gpointer unused)
data = gst_type_find_peek (tf, 0, 8);
if (data && memcmp(data, sequence_header, 4)==0){
gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, MPEG_VIDEO_CAPS);
GstCaps *caps = MPEG_VIDEO_CAPS;
gst_structure_set (gst_caps_get_structure (caps, 0), "mpegversion",
G_TYPE_INT, 1, 0);
gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM - 1, caps);
}
}
/*
* Idea is the same as MPEG system stream typefinding: We check each
* byte of the stream to see if - from that point on - the stream
* matches a predefined set of marker bits as defined in the MPEG
* video specs.
*
* I'm sure someone will do a chance calculation here too.
*/
#define GST_MPEGVID_TYPEFIND_TRY_PICTURES 6
#define GST_MPEGVID_TYPEFIND_TRY_SYNC (100 * 1024) /* 100 kB */
#define GST_MPEGVID_TYPEFIND_SYNC_SIZE 2048
static void
mpeg_video_stream_type_find (GstTypeFind *tf, gpointer unused)
{
gint size = 0, found = 0;
guint64 skipped = 0;
guint8 *data = NULL;
while (1) {
if (found >= GST_MPEGVID_TYPEFIND_TRY_PICTURES) {
GstCaps *caps = MPEG_VIDEO_CAPS;
gst_structure_set (gst_caps_get_structure (caps, 0), "mpegversion",
G_TYPE_INT, 1, 0);
gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM - 2, caps);
return;
}
if (skipped > GST_MPEGVID_TYPEFIND_TRY_SYNC)
break;
if (size < 4) {
data = gst_type_find_peek (tf, skipped, GST_MPEGVID_TYPEFIND_SYNC_SIZE);
if (!data)
break;
size = GST_MPEGVID_TYPEFIND_SYNC_SIZE;
}
/* are we a sequence (0xB3) or GOP (0xB8) header? */
if (data[0] == 0x0 && data[1] == 0x0 && data[2] == 0x1 &&
(data[3] == 0xB3 || data[3] == 0xB8)) {
size -= 8;
data += 8;
skipped += 8;
if (data[3] == 0xB3)
continue;
else if (size < 4) {
data = gst_type_find_peek (tf, skipped, GST_MPEGVID_TYPEFIND_SYNC_SIZE);
size = GST_MPEGVID_TYPEFIND_SYNC_SIZE;
if (!data)
break;
}
/* else, we should now see an image */
}
/* image header (and, when found, slice header) */
if (data[0] == 0x0 && data[1] == 0x0 &&
data[2] == 0x1 && data[4] == 0x0) {
size -= 8;
data += 8;
skipped += 8;
if (size < 5) {
data = gst_type_find_peek (tf, skipped, GST_MPEGVID_TYPEFIND_SYNC_SIZE);
size = GST_MPEGVID_TYPEFIND_SYNC_SIZE;
if (!data)
break;
}
if ((data[0] == 0x0 && data[1] == 0x0 &&
data[2] == 0x1 && data[3] == 0x1) ||
(data[1] == 0x0 && data[2] == 0x0 &&
data[3] == 0x1 && data[4] == 0x1)) {
size -= 4;
data += 4;
skipped += 4;
found += 1;
continue;
}
}
size--;
data++;
skipped++;
}
}
@ -1141,6 +1223,8 @@ plugin_init (GstPlugin *plugin)
ogg_exts, "OggS", 4, GST_TYPE_FIND_MAXIMUM);
TYPE_FIND_REGISTER (plugin, "video/mpeg", GST_RANK_SECONDARY,
mpeg_video_type_find, mpeg_video_exts, MPEG_VIDEO_CAPS, NULL);
TYPE_FIND_REGISTER (plugin, "video/mpeg", GST_RANK_MARGINAL,
mpeg_video_stream_type_find, mpeg_video_exts, MPEG_VIDEO_CAPS, NULL);
TYPE_FIND_REGISTER (plugin, "video/quicktime", GST_RANK_SECONDARY,
qt_type_find, qt_exts, QT_CAPS, NULL);
TYPE_FIND_REGISTER_START_WITH (plugin, "application/vnd.rn-realmedia", GST_RANK_SECONDARY,