qtdemux: unselect instead of ignoring disabled track, detect chapter track

https://bugzilla.gnome.org/show_bug.cgi?id=704007
This commit is contained in:
Matej Knopp 2013-07-11 16:13:05 +02:00 committed by Sebastian Dröge
parent 9a7321872f
commit 3111161e8a
4 changed files with 44 additions and 6 deletions

View file

@ -351,6 +351,8 @@ struct _QtDemuxStream
guint32 def_sample_duration;
guint32 def_sample_size;
guint32 def_sample_flags;
gboolean disabled;
};
enum QtDemuxState
@ -1813,6 +1815,7 @@ gst_qtdemux_reset (GstQTDemux * qtdemux, gboolean hard)
qtdemux->duration = 0;
qtdemux->mfra_offset = 0;
qtdemux->moof_offset = 0;
qtdemux->chapters_track_id = 0;
}
qtdemux->offset = 0;
gst_adapter_clear (qtdemux->adapter);
@ -4094,8 +4097,9 @@ gst_qtdemux_loop_state_movie (GstQTDemux * qtdemux)
/* gap events for subtitle streams */
for (i = 0; i < qtdemux->n_streams; i++) {
stream = qtdemux->streams[i];
if (stream->subtype == FOURCC_subp || stream->subtype == FOURCC_text
|| stream->subtype == FOURCC_sbtl) {
if (stream->pad && (stream->subtype == FOURCC_subp
|| stream->subtype == FOURCC_text
|| stream->subtype == FOURCC_sbtl)) {
/* send one second gap events until the stream catches up */
/* gaps can only be sent after segment is activated (segment.stop is no longer -1) */
while (GST_CLOCK_TIME_IS_VALID (stream->segment.stop) &&
@ -5672,11 +5676,16 @@ gst_qtdemux_configure_stream (GstQTDemux * qtdemux, QtDemuxStream * stream)
GST_DEBUG_OBJECT (qtdemux, "setting caps %" GST_PTR_FORMAT, stream->caps);
if (stream->new_stream) {
gchar *stream_id;
GstEvent *event;
stream->new_stream = FALSE;
stream_id =
gst_pad_create_stream_id_printf (stream->pad,
GST_ELEMENT_CAST (qtdemux), "%03u", stream->track_id);
event = gst_event_new_stream_start (stream_id);
if (stream->disabled) {
gst_event_set_stream_flags (event, GST_STREAM_FLAG_UNSELECT);
}
gst_pad_push_event (stream->pad, gst_event_new_stream_start (stream_id));
g_free (stream_id);
}
@ -6909,6 +6918,8 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
GNode *wave;
GNode *esds;
GNode *pasp;
GNode *tref;
QtDemuxStream *stream = NULL;
GstTagList *list = NULL;
gchar *codec = NULL;
@ -6928,9 +6939,6 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
|| !gst_byte_reader_get_uint24_be (&tkhd, &tkhd_flags))
goto corrupt_file;
if ((tkhd_flags & 1) == 0)
goto track_disabled;
/* pick between 64 or 32 bits */
value_size = tkhd_version == 1 ? 8 : 4;
if (!gst_byte_reader_skip (&tkhd, value_size * 2) ||
@ -6950,6 +6958,9 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
}
}
if ((tkhd_flags & 1) == 0)
stream->disabled = TRUE;
GST_LOG_OBJECT (qtdemux, "track[tkhd] version/flags/id: 0x%02x/%06x/%u",
tkhd_version, tkhd_flags, stream->track_id);
@ -6999,6 +7010,21 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
if (G_UNLIKELY (stream->timescale == 0 || qtdemux->timescale == 0))
goto corrupt_file;
if ((tref = qtdemux_tree_get_child_by_type (trak, FOURCC_tref))) {
/* chapters track reference */
GNode *chap = qtdemux_tree_get_child_by_type (tref, FOURCC_chap);
if (chap) {
gsize length = GST_READ_UINT32_BE (chap->data);
if (qtdemux->chapters_track_id)
GST_FIXME_OBJECT (qtdemux, "Multiple CHAP tracks");
if (length >= 12) {
qtdemux->chapters_track_id =
GST_READ_UINT32_BE ((gint8 *) chap->data + 8);
}
}
}
/* fragmented files may have bogus duration in moov */
if (!qtdemux->fragmented &&
qtdemux->duration != G_MAXINT64 && stream->duration != G_MAXINT32) {
@ -8126,7 +8152,6 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
/* ERRORS */
skip_track:
track_disabled:
{
GST_INFO_OBJECT (qtdemux, "skip disabled track");
g_free (stream);
@ -8363,6 +8388,13 @@ qtdemux_expose_streams (GstQTDemux * qtdemux)
GST_DEBUG_OBJECT (qtdemux, "stream %d, id %d, fourcc %" GST_FOURCC_FORMAT,
i, stream->track_id, GST_FOURCC_ARGS (stream->fourcc));
if ((stream->subtype == FOURCC_text || stream->subtype == FOURCC_sbtl) &&
stream->track_id == qtdemux->chapters_track_id) {
/* TODO - parse chapters track and expose it as GstToc; For now just ignore it
so that it doesn't look like a subtitle track */
continue;
}
/* now we have all info and can expose */
list = stream->pending_tags;
stream->pending_tags = NULL;

View file

@ -121,6 +121,8 @@ struct _GstQTDemux {
gboolean exposed;
gboolean mss_mode; /* flag to indicate that we're working with a smoothstreaming fragment */
guint64 fragment_start;
gint64 chapters_track_id;
};
struct _GstQTDemuxClass {

View file

@ -240,6 +240,9 @@ G_BEGIN_DECLS
/* MPEG DASH */
#define FOURCC_tfdt GST_MAKE_FOURCC('t','f','d','t')
/* Chapters reference */
#define FOURCC_chap GST_MAKE_FOURCC('c','h','a','p')
G_END_DECLS
#endif /* __GST_QTDEMUX_FOURCC_H__ */

View file

@ -172,6 +172,7 @@ static const QtNodeType qt_node_types[] = {
{FOURCC_ovc1, "ovc1", 0},
{FOURCC_owma, "owma", 0},
{FOURCC_tfdt, "Track fragment decode time", 0, qtdemux_dump_tfdt},
{FOURCC_chap, "Chapter Reference"},
{0, "unknown", 0,},
};