mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 13:41:48 +00:00
tsdemux: Fix draining on wrong programs
When draining a program, we might send a newsegment event on the pads that are going to be removed (and then the pending data). In order to do that, calculate_and_push_newsegment() needs to know what list of streams it should take into account (instead of blindly using the current one). All callers to calculate_and_push_newsegment() and push_pending_data() can now specify the program on which to act (or NULL for the default one).
This commit is contained in:
parent
e2b98a7721
commit
51c5ff45de
1 changed files with 21 additions and 13 deletions
|
@ -305,7 +305,8 @@ static void gst_ts_demux_get_property (GObject * object, guint prop_id,
|
||||||
GValue * value, GParamSpec * pspec);
|
GValue * value, GParamSpec * pspec);
|
||||||
static void gst_ts_demux_flush_streams (GstTSDemux * tsdemux, gboolean hard);
|
static void gst_ts_demux_flush_streams (GstTSDemux * tsdemux, gboolean hard);
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream);
|
gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream,
|
||||||
|
MpegTSBaseProgram * program);
|
||||||
static void gst_ts_demux_stream_flush (TSDemuxStream * stream,
|
static void gst_ts_demux_stream_flush (TSDemuxStream * stream,
|
||||||
GstTSDemux * demux, gboolean hard);
|
GstTSDemux * demux, gboolean hard);
|
||||||
|
|
||||||
|
@ -972,7 +973,7 @@ push_event (MpegTSBase * base, GstEvent * event)
|
||||||
/* If we are pushing out EOS, flush out pending data first */
|
/* If we are pushing out EOS, flush out pending data first */
|
||||||
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS &&
|
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS &&
|
||||||
gst_pad_is_active (stream->pad))
|
gst_pad_is_active (stream->pad))
|
||||||
gst_ts_demux_push_pending_data (demux, stream);
|
gst_ts_demux_push_pending_data (demux, stream, NULL);
|
||||||
|
|
||||||
gst_event_ref (event);
|
gst_event_ref (event);
|
||||||
gst_pad_push_event (stream->pad, event);
|
gst_pad_push_event (stream->pad, event);
|
||||||
|
@ -1683,7 +1684,7 @@ gst_ts_demux_stream_removed (MpegTSBase * base, MpegTSBaseStream * bstream)
|
||||||
if (gst_pad_is_active (stream->pad)) {
|
if (gst_pad_is_active (stream->pad)) {
|
||||||
/* Flush out all data */
|
/* Flush out all data */
|
||||||
GST_DEBUG_OBJECT (stream->pad, "Flushing out pending data");
|
GST_DEBUG_OBJECT (stream->pad, "Flushing out pending data");
|
||||||
gst_ts_demux_push_pending_data ((GstTSDemux *) base, stream);
|
gst_ts_demux_push_pending_data ((GstTSDemux *) base, stream, NULL);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (stream->pad, "Pushing out EOS");
|
GST_DEBUG_OBJECT (stream->pad, "Pushing out EOS");
|
||||||
gst_pad_push_event (stream->pad, gst_event_new_eos ());
|
gst_pad_push_event (stream->pad, gst_event_new_eos ());
|
||||||
|
@ -1831,7 +1832,8 @@ gst_ts_demux_program_started (MpegTSBase * base, MpegTSBaseProgram * program)
|
||||||
for (tmp = demux->previous_program->stream_list; tmp; tmp = tmp->next) {
|
for (tmp = demux->previous_program->stream_list; tmp; tmp = tmp->next) {
|
||||||
TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
|
TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
|
||||||
if (stream->pad)
|
if (stream->pad)
|
||||||
gst_ts_demux_push_pending_data (demux, stream);
|
gst_ts_demux_push_pending_data (demux, stream,
|
||||||
|
demux->previous_program);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2231,7 +2233,8 @@ gst_ts_demux_queue_data (GstTSDemux * demux, TSDemuxStream * stream,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream)
|
calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream,
|
||||||
|
MpegTSBaseProgram * target_program)
|
||||||
{
|
{
|
||||||
MpegTSBase *base = (MpegTSBase *) demux;
|
MpegTSBase *base = (MpegTSBase *) demux;
|
||||||
GstClockTime lowest_pts = GST_CLOCK_TIME_NONE;
|
GstClockTime lowest_pts = GST_CLOCK_TIME_NONE;
|
||||||
|
@ -2240,12 +2243,15 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream)
|
||||||
|
|
||||||
GST_DEBUG ("Creating new newsegment for stream %p", stream);
|
GST_DEBUG ("Creating new newsegment for stream %p", stream);
|
||||||
|
|
||||||
|
if (target_program == NULL)
|
||||||
|
target_program = demux->program;
|
||||||
|
|
||||||
/* Speedup : if we don't need to calculate anything, go straight to pushing */
|
/* Speedup : if we don't need to calculate anything, go straight to pushing */
|
||||||
if (demux->segment_event)
|
if (demux->segment_event)
|
||||||
goto push_new_segment;
|
goto push_new_segment;
|
||||||
|
|
||||||
/* Calculate the 'new_start' value, used for newsegment */
|
/* Calculate the 'new_start' value, used for newsegment */
|
||||||
for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
|
for (tmp = target_program->stream_list; tmp; tmp = tmp->next) {
|
||||||
TSDemuxStream *pstream = (TSDemuxStream *) tmp->data;
|
TSDemuxStream *pstream = (TSDemuxStream *) tmp->data;
|
||||||
|
|
||||||
if (GST_CLOCK_TIME_IS_VALID (pstream->first_pts)) {
|
if (GST_CLOCK_TIME_IS_VALID (pstream->first_pts)) {
|
||||||
|
@ -2294,7 +2300,7 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
push_new_segment:
|
push_new_segment:
|
||||||
for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
|
for (tmp = target_program->stream_list; tmp; tmp = tmp->next) {
|
||||||
stream = (TSDemuxStream *) tmp->data;
|
stream = (TSDemuxStream *) tmp->data;
|
||||||
if (stream->pad == NULL)
|
if (stream->pad == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
@ -2369,7 +2375,7 @@ gst_ts_demux_check_and_sync_streams (GstTSDemux * demux, GstClockTime time)
|
||||||
"Stream needs update. Pushing GAP event to TS %" GST_TIME_FORMAT,
|
"Stream needs update. Pushing GAP event to TS %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (time));
|
GST_TIME_ARGS (time));
|
||||||
if (G_UNLIKELY (ps->need_newsegment))
|
if (G_UNLIKELY (ps->need_newsegment))
|
||||||
calculate_and_push_newsegment (demux, ps);
|
calculate_and_push_newsegment (demux, ps, NULL);
|
||||||
|
|
||||||
/* Now send gap event */
|
/* Now send gap event */
|
||||||
gst_pad_push_event (ps->pad, gst_event_new_gap (time, 0));
|
gst_pad_push_event (ps->pad, gst_event_new_gap (time, 0));
|
||||||
|
@ -2477,13 +2483,15 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream)
|
gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream,
|
||||||
|
MpegTSBaseProgram * target_program)
|
||||||
{
|
{
|
||||||
GstFlowReturn res = GST_FLOW_OK;
|
GstFlowReturn res = GST_FLOW_OK;
|
||||||
MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
|
MpegTSBaseStream *bs = (MpegTSBaseStream *) stream;
|
||||||
GstBuffer *buffer = NULL;
|
GstBuffer *buffer = NULL;
|
||||||
GstBufferList *buffer_list = NULL;
|
GstBufferList *buffer_list = NULL;
|
||||||
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (stream->pad,
|
GST_DEBUG_OBJECT (stream->pad,
|
||||||
"stream:%p, pid:0x%04x stream_type:%d state:%d", stream, bs->pid,
|
"stream:%p, pid:0x%04x stream_type:%d state:%d", stream, bs->pid,
|
||||||
bs->stream_type, stream->state);
|
bs->stream_type, stream->state);
|
||||||
|
@ -2597,7 +2605,7 @@ gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G_UNLIKELY (stream->need_newsegment))
|
if (G_UNLIKELY (stream->need_newsegment))
|
||||||
calculate_and_push_newsegment (demux, stream);
|
calculate_and_push_newsegment (demux, stream, target_program);
|
||||||
|
|
||||||
/* FIXME : Push pending buffers if any */
|
/* FIXME : Push pending buffers if any */
|
||||||
if (G_UNLIKELY (stream->pending)) {
|
if (G_UNLIKELY (stream->pending)) {
|
||||||
|
@ -2731,7 +2739,7 @@ gst_ts_demux_handle_packet (GstTSDemux * demux, TSDemuxStream * stream,
|
||||||
if (G_UNLIKELY (packet->payload_unit_start_indicator) &&
|
if (G_UNLIKELY (packet->payload_unit_start_indicator) &&
|
||||||
FLAGS_HAS_PAYLOAD (packet->scram_afc_cc))
|
FLAGS_HAS_PAYLOAD (packet->scram_afc_cc))
|
||||||
/* Flush previous data */
|
/* Flush previous data */
|
||||||
res = gst_ts_demux_push_pending_data (demux, stream);
|
res = gst_ts_demux_push_pending_data (demux, stream, NULL);
|
||||||
|
|
||||||
if (packet->payload && (res == GST_FLOW_OK || res == GST_FLOW_NOT_LINKED)
|
if (packet->payload && (res == GST_FLOW_OK || res == GST_FLOW_NOT_LINKED)
|
||||||
&& stream->pad) {
|
&& stream->pad) {
|
||||||
|
@ -2741,7 +2749,7 @@ gst_ts_demux_handle_packet (GstTSDemux * demux, TSDemuxStream * stream,
|
||||||
/* Finally check if the data we queued completes a packet */
|
/* Finally check if the data we queued completes a packet */
|
||||||
if (stream->expected_size && stream->current_size == stream->expected_size) {
|
if (stream->expected_size && stream->current_size == stream->expected_size) {
|
||||||
GST_LOG ("pushing complete packet");
|
GST_LOG ("pushing complete packet");
|
||||||
res = gst_ts_demux_push_pending_data (demux, stream);
|
res = gst_ts_demux_push_pending_data (demux, stream, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2789,7 +2797,7 @@ gst_ts_demux_drain (MpegTSBase * base)
|
||||||
for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
|
for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
|
||||||
TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
|
TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
|
||||||
if (stream->pad) {
|
if (stream->pad) {
|
||||||
res = gst_ts_demux_push_pending_data (demux, stream);
|
res = gst_ts_demux_push_pending_data (demux, stream, NULL);
|
||||||
if (G_UNLIKELY (res != GST_FLOW_OK))
|
if (G_UNLIKELY (res != GST_FLOW_OK))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue