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)
}
case QTDEMUX_STATE_MOVIE:{
QtDemuxStream *stream = NULL;
GList *stream_list = NULL;
GList *iter;
QtDemuxSample *sample;
GstClockTime dts, pts, duration;
gboolean keyframe;
gint i;
GstBuffer *outbuf;
GST_DEBUG_OBJECT (demux,
"BEGIN // in MOVIE for offset %" G_GUINT64_FORMAT, demux->offset);
......@@ -8095,11 +8098,9 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
/* Figure out which stream this packet belongs to */
for (i = 0; i < QTDEMUX_N_STREAMS (demux); i++) {
stream = QTDEMUX_NTH_STREAM (demux, i);
if (stream->sample_index >= stream->n_samples) {
/* reset to be checked below G_UNLIKELY (stream == NULL) */
stream = NULL;
if (stream->sample_index >= stream->n_samples)
continue;
}
GST_LOG_OBJECT (demux,
"Checking track-id %u (sample_index:%d / offset:%"
G_GUINT64_FORMAT " / size:%d)", stream->track_id,
......@@ -8107,73 +8108,77 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
stream->samples[stream->sample_index].offset,
stream->samples[stream->sample_index].size);
if (stream->samples[stream->sample_index].offset == demux->offset)
break;
if (stream->samples[stream->sample_index].offset == demux->offset) {
stream_list = g_list_append (stream_list, stream);
}
}
if (G_UNLIKELY (stream == NULL))
if (G_UNLIKELY (stream_list == NULL))
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) {
gst_qtdemux_configure_stream (demux, stream);
}
for (iter = stream_list; iter; iter = g_list_next (iter)) {
QtDemuxStream *stream = (QtDemuxStream *) iter->data;
/* Put data in a buffer, set timestamps, caps, ... */
sample = &stream->samples[stream->sample_index];
gst_qtdemux_stream_check_and_change_stsd_index (demux, stream);
if (G_LIKELY (!(STREAM_IS_EOS (stream)))) {
GST_DEBUG_OBJECT (demux, "stream : %" GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (CUR_STREAM (stream)->fourcc));
if (stream->new_caps) {
gst_qtdemux_configure_stream (demux, stream);
}
dts = QTSAMPLE_DTS (stream, sample);
pts = QTSAMPLE_PTS (stream, sample);
duration = QTSAMPLE_DUR_DTS (stream, sample, dts);
keyframe = QTSAMPLE_KEYFRAME (stream, sample);
/* Put data in a buffer, set timestamps, caps, ... */
sample = &stream->samples[stream->sample_index];
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 */
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 */
/* FIXME: should either be an assert or a plain check */
g_return_val_if_fail (outbuf != NULL, GST_FLOW_ERROR);
/* skip this data, stream is EOS */
gst_adapter_flush (demux->adapter, demux->neededbytes);
demux->offset += demux->neededbytes;
new_buf = gst_buffer_new ();
gst_buffer_copy_into (new_buf, outbuf, GST_BUFFER_COPY_ALL, 0,
-1);
/* 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;
}
ret = gst_qtdemux_decorate_and_push_buffer (demux, stream,
new_buf, dts, pts, duration, keyframe, dts, demux->offset);
}
} 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,
dts, pts, duration, keyframe, dts, demux->offset);
/* combine flows */
ret = gst_qtdemux_combine_flows (demux, stream, ret);
} else {
/* skip this data, stream is EOS */
}
/* combine flows */
ret = gst_qtdemux_combine_flows (demux, stream, ret);
} else {
/* skip this data, stream is EOS */
gst_adapter_flush (demux->adapter, demux->neededbytes);
stream->sample_index++;
stream->offset_in_sample = 0;
}
stream->sample_index++;
stream->offset_in_sample = 0;
/* update current offset and figure out size of next buffer */
GST_LOG_OBJECT (demux, "increasing offset %" G_GUINT64_FORMAT " by %u",
demux->offset, demux->neededbytes);
......@@ -8181,6 +8186,9 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
GST_LOG_OBJECT (demux, "offset is now %" G_GUINT64_FORMAT,
demux->offset);
gst_buffer_unref (outbuf);
if (stream_list)
g_list_free (stream_list);
if (ret == GST_FLOW_EOS) {
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