qtdemux: offset samples according to edit list

https://bugzilla.gnome.org/show_bug.cgi?id=700264
This commit is contained in:
Matej Knopp 2013-07-06 17:20:49 +02:00 committed by Sebastian Dröge
parent cff0b179d3
commit ca32442f86
2 changed files with 46 additions and 12 deletions

View file

@ -353,6 +353,8 @@ struct _QtDemuxStream
guint32 def_sample_flags; guint32 def_sample_flags;
gboolean disabled; gboolean disabled;
GstClockTime elst_offset; /* sample offset from edit list */
}; };
enum QtDemuxState enum QtDemuxState
@ -721,7 +723,7 @@ gst_qtdemux_get_duration (GstQTDemux * qtdemux, gint64 * duration)
if (qtdemux->duration != 0) { if (qtdemux->duration != 0) {
if (qtdemux->duration != G_MAXINT64 && qtdemux->timescale != 0) { if (qtdemux->duration != G_MAXINT64 && qtdemux->timescale != 0) {
*duration = gst_util_uint64_scale (qtdemux->duration, *duration = gst_util_uint64_scale (qtdemux->duration,
GST_SECOND, qtdemux->timescale); GST_SECOND, qtdemux->timescale) - qtdemux->min_elst_offset;
} }
} }
return res; return res;
@ -3923,6 +3925,13 @@ gst_qtdemux_decorate_and_push_buffer (GstQTDemux * qtdemux,
{ {
GstFlowReturn ret = GST_FLOW_OK; GstFlowReturn ret = GST_FLOW_OK;
/* offset the timestamps according to the edit list */
if (GST_CLOCK_TIME_IS_VALID (pts))
pts += stream->elst_offset;
if (GST_CLOCK_TIME_IS_VALID (dts))
dts += stream->elst_offset;
position += stream->elst_offset;
if (G_UNLIKELY (stream->fourcc == FOURCC_rtsp)) { if (G_UNLIKELY (stream->fourcc == FOURCC_rtsp)) {
gchar *url; gchar *url;
GstMapInfo map; GstMapInfo map;
@ -6565,12 +6574,17 @@ qtdemux_parse_segments (GstQTDemux * qtdemux, QtDemuxStream * stream,
guint32 rate_int; guint32 rate_int;
media_time = QT_UINT32 (buffer + 20 + i * 12); media_time = QT_UINT32 (buffer + 20 + i * 12);
duration = QT_UINT32 (buffer + 16 + i * 12);
/* -1 media time is an empty segment, just ignore it */ /* -1 media time is an empty segment, just ignore it */
if (media_time == G_MAXUINT32) if (media_time == G_MAXUINT32) {
if (i == 0) {
/* first empty segment specifies sample offset (if movie timescale) */
stream->elst_offset =
gst_util_uint64_scale (duration, GST_SECOND, qtdemux->timescale);
}
continue; continue;
}
duration = QT_UINT32 (buffer + 16 + i * 12);
segment = &stream->segments[count++]; segment = &stream->segments[count++];
@ -9566,6 +9580,7 @@ qtdemux_parse_tree (GstQTDemux * qtdemux)
guint64 creation_time; guint64 creation_time;
GstDateTime *datetime = NULL; GstDateTime *datetime = NULL;
gint version; gint version;
int i;
/* make sure we have a usable taglist */ /* make sure we have a usable taglist */
if (!qtdemux->tag_list) { if (!qtdemux->tag_list) {
@ -9638,6 +9653,31 @@ qtdemux_parse_tree (GstQTDemux * qtdemux)
qtdemux_parse_mehd (qtdemux, &mehd_data); qtdemux_parse_mehd (qtdemux, &mehd_data);
} }
/* parse all traks */
trak = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_trak);
while (trak) {
qtdemux_parse_trak (qtdemux, trak);
/* iterate all siblings */
trak = qtdemux_tree_get_sibling_by_type (trak, FOURCC_trak);
}
/* make sure we don't offset samples more than we have to */
qtdemux->min_elst_offset = GST_CLOCK_TIME_NONE;
for (i = 0; i < qtdemux->n_streams; ++i) {
QtDemuxStream *stream = qtdemux->streams[i];
if (!GST_CLOCK_TIME_IS_VALID (qtdemux->min_elst_offset)
|| stream->elst_offset < qtdemux->min_elst_offset) {
qtdemux->min_elst_offset = stream->elst_offset;
}
}
if (!GST_CLOCK_TIME_IS_VALID (qtdemux->min_elst_offset)) {
qtdemux->min_elst_offset = 0;
}
for (i = 0; i < qtdemux->n_streams; ++i) {
QtDemuxStream *stream = qtdemux->streams[i];
stream->elst_offset -= qtdemux->min_elst_offset;
}
/* set duration in the segment info */ /* set duration in the segment info */
gst_qtdemux_get_duration (qtdemux, &duration); gst_qtdemux_get_duration (qtdemux, &duration);
if (duration) { if (duration) {
@ -9648,14 +9688,6 @@ qtdemux_parse_tree (GstQTDemux * qtdemux)
qtdemux->segment.stop = duration; qtdemux->segment.stop = duration;
} }
/* parse all traks */
trak = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_trak);
while (trak) {
qtdemux_parse_trak (qtdemux, trak);
/* iterate all siblings */
trak = qtdemux_tree_get_sibling_by_type (trak, FOURCC_trak);
}
/* find tags */ /* find tags */
udta = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_udta); udta = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_udta);
if (udta) { if (udta) {

View file

@ -123,6 +123,8 @@ struct _GstQTDemux {
guint64 fragment_start; guint64 fragment_start;
gint64 chapters_track_id; gint64 chapters_track_id;
GstClockTime min_elst_offset;
}; };
struct _GstQTDemuxClass { struct _GstQTDemuxClass {