Commit 8747c982 authored by Seungha Yang's avatar Seungha Yang

qtdemux: Allow a sample for multple output streams

A sample of meta item (such as an image) can be also other stream's sample.
parent 3932dcb3
Pipeline #39909 passed with stages
in 53 minutes and 40 seconds
...@@ -8016,10 +8016,13 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force) ...@@ -8016,10 +8016,13 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
} }
case QTDEMUX_STATE_MOVIE:{ case QTDEMUX_STATE_MOVIE:{
QtDemuxStream *stream = NULL; QtDemuxStream *stream = NULL;
GList *stream_list = NULL;
GList *iter;
QtDemuxSample *sample; QtDemuxSample *sample;
GstClockTime dts, pts, duration; GstClockTime dts, pts, duration;
gboolean keyframe; gboolean keyframe;
gint i; gint i;
GstBuffer *outbuf;
GST_DEBUG_OBJECT (demux, GST_DEBUG_OBJECT (demux,
"BEGIN // in MOVIE for offset %" G_GUINT64_FORMAT, demux->offset); "BEGIN // in MOVIE for offset %" G_GUINT64_FORMAT, demux->offset);
...@@ -8095,11 +8098,9 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force) ...@@ -8095,11 +8098,9 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
/* Figure out which stream this packet belongs to */ /* Figure out which stream this packet belongs to */
for (i = 0; i < QTDEMUX_N_STREAMS (demux); i++) { for (i = 0; i < QTDEMUX_N_STREAMS (demux); i++) {
stream = QTDEMUX_NTH_STREAM (demux, i); stream = QTDEMUX_NTH_STREAM (demux, i);
if (stream->sample_index >= stream->n_samples) { if (stream->sample_index >= stream->n_samples)
/* reset to be checked below G_UNLIKELY (stream == NULL) */
stream = NULL;
continue; continue;
}
GST_LOG_OBJECT (demux, GST_LOG_OBJECT (demux,
"Checking track-id %u (sample_index:%d / offset:%" "Checking track-id %u (sample_index:%d / offset:%"
G_GUINT64_FORMAT " / size:%d)", stream->track_id, G_GUINT64_FORMAT " / size:%d)", stream->track_id,
...@@ -8107,73 +8108,77 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force) ...@@ -8107,73 +8108,77 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
stream->samples[stream->sample_index].offset, stream->samples[stream->sample_index].offset,
stream->samples[stream->sample_index].size); stream->samples[stream->sample_index].size);
if (stream->samples[stream->sample_index].offset == demux->offset) if (stream->samples[stream->sample_index].offset == demux->offset) {
break; stream_list = g_list_append (stream_list, stream);
}
} }
if (G_UNLIKELY (stream == NULL)) if (G_UNLIKELY (stream_list == NULL))
goto unknown_stream; goto unknown_stream;
gst_qtdemux_stream_check_and_change_stsd_index (demux, stream); /* multiple stream can have identical sample offset */
outbuf = gst_adapter_take_buffer (demux->adapter, demux->neededbytes);
if (stream->new_caps) { for (iter = stream_list; iter; iter = g_list_next (iter)) {
gst_qtdemux_configure_stream (demux, stream); QtDemuxStream *stream = (QtDemuxStream *) iter->data;
}
/* Put data in a buffer, set timestamps, caps, ... */ gst_qtdemux_stream_check_and_change_stsd_index (demux, stream);
sample = &stream->samples[stream->sample_index];
if (G_LIKELY (!(STREAM_IS_EOS (stream)))) { if (stream->new_caps) {
GST_DEBUG_OBJECT (demux, "stream : %" GST_FOURCC_FORMAT, gst_qtdemux_configure_stream (demux, stream);
GST_FOURCC_ARGS (CUR_STREAM (stream)->fourcc)); }
dts = QTSAMPLE_DTS (stream, sample); /* Put data in a buffer, set timestamps, caps, ... */
pts = QTSAMPLE_PTS (stream, sample); sample = &stream->samples[stream->sample_index];
duration = QTSAMPLE_DUR_DTS (stream, sample, dts);
keyframe = QTSAMPLE_KEYFRAME (stream, sample); if (G_LIKELY (!(STREAM_IS_EOS (stream)))) {
GST_DEBUG_OBJECT (demux, "stream : %" GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (CUR_STREAM (stream)->fourcc));
dts = QTSAMPLE_DTS (stream, sample);
pts = QTSAMPLE_PTS (stream, sample);
duration = QTSAMPLE_DUR_DTS (stream, sample, dts);
keyframe = QTSAMPLE_KEYFRAME (stream, sample);
/* check for segment end */
if (G_UNLIKELY (demux->segment.stop != -1
&& demux->segment.stop <= pts && stream->on_keyframe)
&& !(demux->upstream_format_is_time && demux->segment.rate < 0)) {
GST_DEBUG_OBJECT (demux, "we reached the end of our segment.");
stream->time_position = GST_CLOCK_TIME_NONE; /* this means EOS */
/* check if all streams are eos */
ret = GST_FLOW_EOS;
for (i = 0; i < QTDEMUX_N_STREAMS (demux); i++) {
if (!STREAM_IS_EOS (QTDEMUX_NTH_STREAM (demux, i))) {
ret = GST_FLOW_OK;
break;
}
}
} else {
GstBuffer *new_buf;
/* check for segment end */ /* FIXME: should either be an assert or a plain check */
if (G_UNLIKELY (demux->segment.stop != -1 g_return_val_if_fail (outbuf != NULL, GST_FLOW_ERROR);
&& demux->segment.stop <= pts && stream->on_keyframe)
&& !(demux->upstream_format_is_time && demux->segment.rate < 0)) {
GST_DEBUG_OBJECT (demux, "we reached the end of our segment.");
stream->time_position = GST_CLOCK_TIME_NONE; /* this means EOS */
/* skip this data, stream is EOS */ new_buf = gst_buffer_new ();
gst_adapter_flush (demux->adapter, demux->neededbytes); gst_buffer_copy_into (new_buf, outbuf, GST_BUFFER_COPY_ALL, 0,
demux->offset += demux->neededbytes; -1);
/* check if all streams are eos */ ret = gst_qtdemux_decorate_and_push_buffer (demux, stream,
ret = GST_FLOW_EOS; new_buf, dts, pts, duration, keyframe, dts, demux->offset);
for (i = 0; i < QTDEMUX_N_STREAMS (demux); i++) {
if (!STREAM_IS_EOS (QTDEMUX_NTH_STREAM (demux, i))) {
ret = GST_FLOW_OK;
break;
}
} }
} else {
GstBuffer *outbuf;
outbuf =
gst_adapter_take_buffer (demux->adapter, demux->neededbytes);
/* FIXME: should either be an assert or a plain check */
g_return_val_if_fail (outbuf != NULL, GST_FLOW_ERROR);
ret = gst_qtdemux_decorate_and_push_buffer (demux, stream, outbuf, /* combine flows */
dts, pts, duration, keyframe, dts, demux->offset); ret = gst_qtdemux_combine_flows (demux, stream, ret);
} else {
/* skip this data, stream is EOS */
} }
/* combine flows */ stream->sample_index++;
ret = gst_qtdemux_combine_flows (demux, stream, ret); stream->offset_in_sample = 0;
} else {
/* skip this data, stream is EOS */
gst_adapter_flush (demux->adapter, demux->neededbytes);
} }
stream->sample_index++;
stream->offset_in_sample = 0;
/* update current offset and figure out size of next buffer */ /* update current offset and figure out size of next buffer */
GST_LOG_OBJECT (demux, "increasing offset %" G_GUINT64_FORMAT " by %u", GST_LOG_OBJECT (demux, "increasing offset %" G_GUINT64_FORMAT " by %u",
demux->offset, demux->neededbytes); demux->offset, demux->neededbytes);
...@@ -8181,6 +8186,9 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force) ...@@ -8181,6 +8186,9 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
GST_LOG_OBJECT (demux, "offset is now %" G_GUINT64_FORMAT, GST_LOG_OBJECT (demux, "offset is now %" G_GUINT64_FORMAT,
demux->offset); demux->offset);
gst_buffer_unref (outbuf);
if (stream_list)
g_list_free (stream_list);
if (ret == GST_FLOW_EOS) { if (ret == GST_FLOW_EOS) {
GST_DEBUG_OBJECT (demux, "All streams are EOS, signal upstream"); GST_DEBUG_OBJECT (demux, "All streams are EOS, signal upstream");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment