mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 09:10:36 +00:00
qtdemux: offset samples according to edit list
https://bugzilla.gnome.org/show_bug.cgi?id=700264
This commit is contained in:
parent
cff0b179d3
commit
ca32442f86
2 changed files with 46 additions and 12 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue