mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
qtdemux: place incomming timestamps on output
Place the incomming timestamp (if any) directly onto the outgoing buffers and interpollate other timestamps. Conflicts: gst/isomp4/qtdemux.c
This commit is contained in:
parent
cca2f555d1
commit
d9cd4fcc17
1 changed files with 32 additions and 26 deletions
|
@ -2404,18 +2404,21 @@ qtdemux_parse_trun (GstQTDemux * qtdemux, GstByteReader * trun,
|
||||||
if (stream->samples == NULL)
|
if (stream->samples == NULL)
|
||||||
goto out_of_memory;
|
goto out_of_memory;
|
||||||
|
|
||||||
if (G_UNLIKELY (stream->n_samples == 0)) {
|
if (GST_CLOCK_TIME_IS_VALID (qtdemux->base_timestamp)) {
|
||||||
if (GST_CLOCK_TIME_IS_VALID (qtdemux->base_timestamp)) {
|
timestamp = gst_util_uint64_scale_int (qtdemux->base_timestamp,
|
||||||
timestamp = qtdemux->base_timestamp;
|
stream->timescale, GST_SECOND);
|
||||||
} else
|
qtdemux->base_timestamp = GST_CLOCK_TIME_NONE;
|
||||||
|
} else {
|
||||||
|
if (G_UNLIKELY (stream->n_samples == 0)) {
|
||||||
/* the timestamp of the first sample is also provided by the tfra entry
|
/* the timestamp of the first sample is also provided by the tfra entry
|
||||||
* but we shouldn't rely on it as it is at the end of files */
|
* but we shouldn't rely on it as it is at the end of files */
|
||||||
timestamp = 0;
|
timestamp = 0;
|
||||||
} else {
|
} else {
|
||||||
/* subsequent fragments extend stream */
|
/* subsequent fragments extend stream */
|
||||||
timestamp =
|
timestamp =
|
||||||
stream->samples[stream->n_samples - 1].timestamp +
|
stream->samples[stream->n_samples - 1].timestamp +
|
||||||
stream->samples[stream->n_samples - 1].duration;
|
stream->samples[stream->n_samples - 1].duration;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sample = stream->samples + stream->n_samples;
|
sample = stream->samples + stream->n_samples;
|
||||||
for (i = 0; i < samples_count; i++) {
|
for (i = 0; i < samples_count; i++) {
|
||||||
|
@ -2647,8 +2650,16 @@ qtdemux_parse_moof (GstQTDemux * qtdemux, const guint8 * buffer, guint length,
|
||||||
&tfdt_data);
|
&tfdt_data);
|
||||||
if (tfdt_node) {
|
if (tfdt_node) {
|
||||||
guint64 decode_time = 0;
|
guint64 decode_time = 0;
|
||||||
|
GstClockTime decode_time_ts;
|
||||||
|
|
||||||
qtdemux_parse_tfdt (qtdemux, &tfdt_data, &decode_time);
|
qtdemux_parse_tfdt (qtdemux, &tfdt_data, &decode_time);
|
||||||
qtdemux->base_timestamp = decode_time;
|
|
||||||
|
decode_time_ts = gst_util_uint64_scale (decode_time, GST_SECOND,
|
||||||
|
stream->timescale);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (qtdemux, "decode time %" G_GUINT64_FORMAT
|
||||||
|
" (%" GST_TIME_FORMAT ")", decode_time,
|
||||||
|
GST_TIME_ARGS (decode_time_ts));
|
||||||
|
|
||||||
/* If there is a new segment pending, update the time/position.
|
/* If there is a new segment pending, update the time/position.
|
||||||
* Don't replace if the pending newsegment is from upstream */
|
* Don't replace if the pending newsegment is from upstream */
|
||||||
|
@ -2656,8 +2667,6 @@ qtdemux_parse_moof (GstQTDemux * qtdemux, const guint8 * buffer, guint length,
|
||||||
GstSegment segment;
|
GstSegment segment;
|
||||||
|
|
||||||
gst_segment_init (&segment, GST_FORMAT_TIME);
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
segment.time = gst_util_uint64_scale (decode_time,
|
|
||||||
GST_SECOND, stream->timescale);
|
|
||||||
gst_event_replace (&qtdemux->pending_newsegment,
|
gst_event_replace (&qtdemux->pending_newsegment,
|
||||||
gst_event_new_segment (&segment));
|
gst_event_new_segment (&segment));
|
||||||
/* ref added when replaced, release the original _new one */
|
/* ref added when replaced, release the original _new one */
|
||||||
|
@ -4391,13 +4400,17 @@ gst_qtdemux_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * inbuf)
|
||||||
{
|
{
|
||||||
GstQTDemux *demux;
|
GstQTDemux *demux;
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
GstClockTime timestamp;
|
||||||
|
|
||||||
demux = GST_QTDEMUX (parent);
|
demux = GST_QTDEMUX (parent);
|
||||||
|
|
||||||
if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (demux->base_timestamp)))
|
timestamp = GST_BUFFER_TIMESTAMP (inbuf);
|
||||||
demux->base_timestamp =
|
|
||||||
gst_util_uint64_scale_round (GST_BUFFER_TIMESTAMP (inbuf),
|
if (G_UNLIKELY (GST_CLOCK_TIME_IS_VALID (timestamp))) {
|
||||||
demux->timescale, GST_SECOND);
|
demux->base_timestamp = timestamp;
|
||||||
|
GST_DEBUG_OBJECT (demux, "got base_timestamp %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (timestamp));
|
||||||
|
}
|
||||||
|
|
||||||
gst_adapter_push (demux->adapter, inbuf);
|
gst_adapter_push (demux->adapter, inbuf);
|
||||||
|
|
||||||
|
@ -4582,16 +4595,9 @@ gst_qtdemux_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * inbuf)
|
||||||
/* in MSS we need to expose the pads after the first moof as we won't get a moov */
|
/* in MSS we need to expose the pads after the first moof as we won't get a moov */
|
||||||
if (!demux->exposed) {
|
if (!demux->exposed) {
|
||||||
if (!demux->pending_newsegment) {
|
if (!demux->pending_newsegment) {
|
||||||
guint64 start_ts = 0;
|
GstSegment segment;
|
||||||
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
if (GST_CLOCK_TIME_IS_VALID (demux->base_timestamp))
|
demux->pending_newsegment = gst_event_new_segment (&segment);
|
||||||
start_ts = gst_util_uint64_scale (demux->base_timestamp,
|
|
||||||
GST_SECOND, demux->timescale);
|
|
||||||
|
|
||||||
demux->segment.start = demux->segment.time =
|
|
||||||
demux->segment.position = start_ts;
|
|
||||||
demux->pending_newsegment =
|
|
||||||
gst_event_new_segment (&demux->segment);
|
|
||||||
}
|
}
|
||||||
qtdemux_expose_streams (demux);
|
qtdemux_expose_streams (demux);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue