mpegtsbase: Add a GList of streams to the program

Allows faster iteration of all program streams.

We still keep the Array to allow fast retrieval of stream by PID.
This commit is contained in:
Edward Hervey 2011-07-19 09:34:37 +02:00
parent dc18e2b16d
commit b170b2020c
3 changed files with 51 additions and 56 deletions

View file

@ -432,14 +432,16 @@ mpegts_base_deactivate_program (MpegTSBase * base, MpegTSBaseProgram * program)
static void static void
mpegts_base_free_program (MpegTSBaseProgram * program) mpegts_base_free_program (MpegTSBaseProgram * program)
{ {
guint i; GList *tmp;
if (program->pmt_info) if (program->pmt_info)
gst_structure_free (program->pmt_info); gst_structure_free (program->pmt_info);
for (i = 0; i < 0x2000; i++) for (tmp = program->stream_list; tmp; tmp = tmp->next)
if (program->streams[i]) mpegts_base_free_stream ((MpegTSBaseStream *) tmp->data);
mpegts_base_free_stream (program->streams[i]); if (program->stream_list)
g_list_free (program->stream_list);
g_free (program->streams); g_free (program->streams);
if (program->tags) if (program->tags)
@ -482,6 +484,7 @@ mpegts_base_program_add_stream (MpegTSBase * base,
stream->stream_info = stream_info; stream->stream_info = stream_info;
program->streams[pid] = stream; program->streams[pid] = stream;
program->stream_list = g_list_append (program->stream_list, stream);
if (klass->stream_added) if (klass->stream_added)
klass->stream_added (base, stream, program); klass->stream_added (base, stream, program);
@ -500,12 +503,17 @@ mpegts_base_program_remove_stream (MpegTSBase * base,
MpegTSBaseProgram * program, guint16 pid) MpegTSBaseProgram * program, guint16 pid)
{ {
MpegTSBaseClass *klass = GST_MPEGTS_BASE_GET_CLASS (base); MpegTSBaseClass *klass = GST_MPEGTS_BASE_GET_CLASS (base);
MpegTSBaseStream *stream = program->streams[pid];
GST_DEBUG ("pid:0x%04x", pid);
/* If subclass needs it, inform it of the stream we are about to remove */ /* If subclass needs it, inform it of the stream we are about to remove */
if (klass->stream_removed) if (klass->stream_removed)
klass->stream_removed (base, program->streams[pid]); klass->stream_removed (base, stream);
mpegts_base_free_stream (program->streams[pid]); program->stream_list = g_list_remove_all (program->stream_list, stream);
mpegts_base_free_stream (stream);
program->streams[pid] = NULL; program->streams[pid] = NULL;
} }

View file

@ -64,6 +64,7 @@ struct _MpegTSBaseProgram
guint16 pcr_pid; guint16 pcr_pid;
GstStructure *pmt_info; GstStructure *pmt_info;
MpegTSBaseStream **streams; MpegTSBaseStream **streams;
GList *stream_list;
gint patcount; gint patcount;
/* Pending Tags for the program */ /* Pending Tags for the program */

View file

@ -891,18 +891,16 @@ static gboolean
push_event (MpegTSBase * base, GstEvent * event) push_event (MpegTSBase * base, GstEvent * event)
{ {
GstTSDemux *demux = (GstTSDemux *) base; GstTSDemux *demux = (GstTSDemux *) base;
guint i; GList *tmp;
if (G_UNLIKELY (demux->program == NULL)) if (G_UNLIKELY (demux->program == NULL))
return FALSE; return FALSE;
for (i = 0; i < 0x2000; i++) { for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
if (demux->program->streams[i]) { TSDemuxStream *stream = (TSDemuxStream *) tmp->data;
if (((TSDemuxStream *) demux->program->streams[i])->pad) { if (stream->pad) {
gst_event_ref (event); gst_event_ref (event);
gst_pad_push_event (((TSDemuxStream *) demux->program->streams[i])->pad, gst_pad_push_event (stream->pad, event);
event);
}
} }
} }
@ -913,7 +911,7 @@ static GstFlowReturn
tsdemux_combine_flows (GstTSDemux * demux, TSDemuxStream * stream, tsdemux_combine_flows (GstTSDemux * demux, TSDemuxStream * stream,
GstFlowReturn ret) GstFlowReturn ret)
{ {
guint i; GList *tmp;
/* Store the value */ /* Store the value */
stream->flow_return = ret; stream->flow_return = ret;
@ -923,16 +921,14 @@ tsdemux_combine_flows (GstTSDemux * demux, TSDemuxStream * stream,
goto done; goto done;
/* Only return NOT_LINKED if all other pads returned NOT_LINKED */ /* Only return NOT_LINKED if all other pads returned NOT_LINKED */
for (i = 0; i < 0x2000; i++) { for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
if (demux->program->streams[i]) { stream = (TSDemuxStream *) tmp->data;
stream = (TSDemuxStream *) demux->program->streams[i]; if (stream->pad) {
if (stream->pad) { ret = stream->flow_return;
ret = stream->flow_return; /* some other return value (must be SUCCESS but we can return
/* some other return value (must be SUCCESS but we can return * other values as well) */
* other values as well) */ if (ret != GST_FLOW_NOT_LINKED)
if (ret != GST_FLOW_NOT_LINKED) goto done;
goto done;
}
} }
/* if we get here, all other pads were unlinked and we return /* if we get here, all other pads were unlinked and we return
* NOT_LINKED then */ * NOT_LINKED then */
@ -1262,13 +1258,8 @@ gst_ts_demux_stream_flush (TSDemuxStream * stream)
static void static void
gst_ts_demux_flush_streams (GstTSDemux * demux) gst_ts_demux_flush_streams (GstTSDemux * demux)
{ {
gint i; g_list_foreach (demux->program->stream_list,
(GFunc) gst_ts_demux_stream_flush, NULL);
for (i = 0; i < 0x2000; i++) {
if (demux->program->streams[i]) {
gst_ts_demux_stream_flush ((TSDemuxStream *) demux->program->streams[i]);
}
}
} }
static void static void
@ -1278,7 +1269,7 @@ gst_ts_demux_program_started (MpegTSBase * base, MpegTSBaseProgram * program)
if (demux->program_number == -1 || if (demux->program_number == -1 ||
demux->program_number == program->program_number) { demux->program_number == program->program_number) {
guint i; GList *tmp;
GST_LOG ("program %d started", program->program_number); GST_LOG ("program %d started", program->program_number);
demux->program_number = program->program_number; demux->program_number = program->program_number;
@ -1290,10 +1281,8 @@ gst_ts_demux_program_started (MpegTSBase * base, MpegTSBaseProgram * program)
* For example, we don't want to expose HDV AUX private streams, we will just * For example, we don't want to expose HDV AUX private streams, we will just
* be using them directly for seeking and metadata. */ * be using them directly for seeking and metadata. */
if (base->mode != BASE_MODE_SCANNING) if (base->mode != BASE_MODE_SCANNING)
for (i = 0; i < 0x2000; i++) for (tmp = program->stream_list; tmp; tmp = tmp->next)
if (program->streams[i]) activate_pad_for_stream (demux, (TSDemuxStream *) tmp->data);
activate_pad_for_stream (demux,
(TSDemuxStream *) program->streams[i]);
/* Inform scanner we have got our program */ /* Inform scanner we have got our program */
demux->current_program_number = program->program_number; demux->current_program_number = program->program_number;
@ -1303,7 +1292,7 @@ gst_ts_demux_program_started (MpegTSBase * base, MpegTSBaseProgram * program)
static void static void
gst_ts_demux_program_stopped (MpegTSBase * base, MpegTSBaseProgram * program) gst_ts_demux_program_stopped (MpegTSBase * base, MpegTSBaseProgram * program)
{ {
guint i; GList *tmp;
GstTSDemux *demux = GST_TS_DEMUX (base); GstTSDemux *demux = GST_TS_DEMUX (base);
TSDemuxStream *localstream = NULL; TSDemuxStream *localstream = NULL;
@ -1312,19 +1301,18 @@ gst_ts_demux_program_stopped (MpegTSBase * base, MpegTSBaseProgram * program)
if (demux->program == NULL || program != demux->program) if (demux->program == NULL || program != demux->program)
return; return;
for (i = 0; i < 0x2000; i++) { for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
if (demux->program->streams[i]) { localstream = (TSDemuxStream *) tmp->data;
localstream = (TSDemuxStream *) program->streams[i]; if (localstream->pad) {
if (localstream->pad) { GST_DEBUG ("HAVE PAD %s:%s", GST_DEBUG_PAD_NAME (localstream->pad));
GST_DEBUG ("HAVE PAD %s:%s", GST_DEBUG_PAD_NAME (localstream->pad)); if (gst_pad_is_active (localstream->pad))
if (gst_pad_is_active (localstream->pad)) gst_element_remove_pad (GST_ELEMENT_CAST (demux), localstream->pad);
gst_element_remove_pad (GST_ELEMENT_CAST (demux), localstream->pad); else
else gst_object_unref (localstream->pad);
gst_object_unref (localstream->pad); localstream->pad = NULL;
localstream->pad = NULL;
}
} }
} }
demux->program = NULL; demux->program = NULL;
demux->program_number = -1; demux->program_number = -1;
} }
@ -2067,7 +2055,7 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream)
MpegTSBase *base = (MpegTSBase *) demux; MpegTSBase *base = (MpegTSBase *) demux;
GstClockTime firstpts = GST_CLOCK_TIME_NONE; GstClockTime firstpts = GST_CLOCK_TIME_NONE;
GstEvent *newsegmentevent; GstEvent *newsegmentevent;
guint i; GList *tmp;
gint64 start, stop, position; gint64 start, stop, position;
GST_DEBUG ("Creating new newsegment"); GST_DEBUG ("Creating new newsegment");
@ -2083,12 +2071,10 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream)
*/ */
/* Find the earliest current PTS we're going to push */ /* Find the earliest current PTS we're going to push */
for (i = 0; i < 0x2000; i++) { for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
if (demux->program->streams[i]) { TSDemuxStream *pstream = (TSDemuxStream *) tmp->data;
if ((!GST_CLOCK_TIME_IS_VALID (firstpts)) if (!GST_CLOCK_TIME_IS_VALID (firstpts) || pstream->pts < firstpts)
|| (((TSDemuxStream *) demux->program->streams[i])->pts < firstpts)) firstpts = pstream->pts;
firstpts = ((TSDemuxStream *) demux->program->streams[i])->pts;
}
} }
if (base->mode == BASE_MODE_PUSHING) { if (base->mode == BASE_MODE_PUSHING) {