mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-08 23:42:28 +00:00
mpegtsbase: Use an array to track programs
We need to be able to look for programs by their PID also. Using a hash table was a bit sub-par (and overkill) for storing a range of programs. This is needed because there could potentially be two programs with the same program id but different PMT PID (while one is being deactivated the new one would "exist"). Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1919>
This commit is contained in:
parent
2fd6e40a7f
commit
ad74ba6100
2 changed files with 36 additions and 43 deletions
|
@ -96,7 +96,7 @@ static gboolean mpegts_base_get_tags_from_eit (MpegTSBase * base,
|
||||||
GstMpegtsSection * section);
|
GstMpegtsSection * section);
|
||||||
static gboolean mpegts_base_parse_atsc_mgt (MpegTSBase * base,
|
static gboolean mpegts_base_parse_atsc_mgt (MpegTSBase * base,
|
||||||
GstMpegtsSection * section);
|
GstMpegtsSection * section);
|
||||||
static gboolean remove_each_program (gpointer key, MpegTSBaseProgram * program,
|
static void remove_each_program (MpegTSBaseProgram * program,
|
||||||
MpegTSBase * base);
|
MpegTSBase * base);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -241,8 +241,8 @@ mpegts_base_reset (MpegTSBase * base)
|
||||||
base->seen_pat = FALSE;
|
base->seen_pat = FALSE;
|
||||||
base->seek_offset = -1;
|
base->seek_offset = -1;
|
||||||
|
|
||||||
g_hash_table_foreach_remove (base->programs, (GHRFunc) remove_each_program,
|
g_ptr_array_foreach (base->programs, (GFunc) remove_each_program, base);
|
||||||
base);
|
g_ptr_array_remove_range (base->programs, 0, base->programs->len);
|
||||||
|
|
||||||
base->streams_aware = GST_OBJECT_PARENT (base)
|
base->streams_aware = GST_OBJECT_PARENT (base)
|
||||||
&& GST_OBJECT_FLAG_IS_SET (GST_OBJECT_PARENT (base),
|
&& GST_OBJECT_FLAG_IS_SET (GST_OBJECT_PARENT (base),
|
||||||
|
@ -269,8 +269,8 @@ mpegts_base_init (MpegTSBase * base)
|
||||||
|
|
||||||
base->disposed = FALSE;
|
base->disposed = FALSE;
|
||||||
base->packetizer = mpegts_packetizer_new ();
|
base->packetizer = mpegts_packetizer_new ();
|
||||||
base->programs = g_hash_table_new_full (g_direct_hash, g_direct_equal,
|
base->programs =
|
||||||
NULL, (GDestroyNotify) mpegts_base_free_program);
|
g_ptr_array_new_full (16, (GDestroyNotify) mpegts_base_free_program);
|
||||||
|
|
||||||
base->parse_private_sections = FALSE;
|
base->parse_private_sections = FALSE;
|
||||||
base->is_pes = g_new0 (guint8, 1024);
|
base->is_pes = g_new0 (guint8, 1024);
|
||||||
|
@ -310,7 +310,7 @@ mpegts_base_finalize (GObject * object)
|
||||||
g_ptr_array_unref (base->pat);
|
g_ptr_array_unref (base->pat);
|
||||||
base->pat = NULL;
|
base->pat = NULL;
|
||||||
}
|
}
|
||||||
g_hash_table_destroy (base->programs);
|
g_ptr_array_free (base->programs, TRUE);
|
||||||
|
|
||||||
gst_event_replace (&base->seek_event, NULL);
|
gst_event_replace (&base->seek_event, NULL);
|
||||||
|
|
||||||
|
@ -354,8 +354,7 @@ typedef struct
|
||||||
} PIDLookup;
|
} PIDLookup;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
foreach_pid_in_program (gpointer key, MpegTSBaseProgram * program,
|
foreach_pid_in_program (MpegTSBaseProgram * program, PIDLookup * lookup)
|
||||||
PIDLookup * lookup)
|
|
||||||
{
|
{
|
||||||
if (!program->active)
|
if (!program->active)
|
||||||
return;
|
return;
|
||||||
|
@ -370,8 +369,7 @@ mpegts_pid_in_active_programs (MpegTSBase * base, guint16 pid)
|
||||||
|
|
||||||
lookup.res = FALSE;
|
lookup.res = FALSE;
|
||||||
lookup.pid = pid;
|
lookup.pid = pid;
|
||||||
g_hash_table_foreach (base->programs, (GHFunc) foreach_pid_in_program,
|
g_ptr_array_foreach (base->programs, (GFunc) foreach_pid_in_program, &lookup);
|
||||||
&lookup);
|
|
||||||
|
|
||||||
return lookup.res;
|
return lookup.res;
|
||||||
}
|
}
|
||||||
|
@ -434,7 +432,7 @@ mpegts_base_new_program (MpegTSBase * base,
|
||||||
MpegTSBaseProgram *program;
|
MpegTSBaseProgram *program;
|
||||||
gchar *upstream_id, *stream_id;
|
gchar *upstream_id, *stream_id;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (base, "program_number : %d, pmt_pid : %d",
|
GST_DEBUG_OBJECT (base, "program_number : %d, pmt_pid : 0x%04x",
|
||||||
program_number, pmt_pid);
|
program_number, pmt_pid);
|
||||||
|
|
||||||
program = g_malloc0 (base->program_size);
|
program = g_malloc0 (base->program_size);
|
||||||
|
@ -459,7 +457,7 @@ mpegts_base_add_program (MpegTSBase * base,
|
||||||
{
|
{
|
||||||
MpegTSBaseProgram *program;
|
MpegTSBaseProgram *program;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (base, "program_number : %d, pmt_pid : %d",
|
GST_DEBUG_OBJECT (base, "program_number : %d, pmt_pid : 0x%04x",
|
||||||
program_number, pmt_pid);
|
program_number, pmt_pid);
|
||||||
|
|
||||||
program = mpegts_base_new_program (base, program_number, pmt_pid);
|
program = mpegts_base_new_program (base, program_number, pmt_pid);
|
||||||
|
@ -471,8 +469,8 @@ mpegts_base_add_program (MpegTSBase * base,
|
||||||
}
|
}
|
||||||
MPEGTS_BIT_SET (base->known_psi, pmt_pid);
|
MPEGTS_BIT_SET (base->known_psi, pmt_pid);
|
||||||
|
|
||||||
g_hash_table_insert (base->programs,
|
|
||||||
GINT_TO_POINTER (program_number), program);
|
g_ptr_array_add (base->programs, program);
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
@ -480,27 +478,28 @@ mpegts_base_add_program (MpegTSBase * base,
|
||||||
MpegTSBaseProgram *
|
MpegTSBaseProgram *
|
||||||
mpegts_base_get_program (MpegTSBase * base, gint program_number)
|
mpegts_base_get_program (MpegTSBase * base, gint program_number)
|
||||||
{
|
{
|
||||||
MpegTSBaseProgram *program;
|
guint i;
|
||||||
|
|
||||||
program = (MpegTSBaseProgram *) g_hash_table_lookup (base->programs,
|
for (i = 0; i < base->programs->len; i++) {
|
||||||
GINT_TO_POINTER ((gint) program_number));
|
MpegTSBaseProgram *program = g_ptr_array_index (base->programs, i);
|
||||||
|
if (program->program_number == program_number)
|
||||||
return program;
|
return program;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MpegTSBaseProgram *
|
static MpegTSBaseProgram *
|
||||||
mpegts_base_steal_program (MpegTSBase * base, gint program_number)
|
mpegts_base_steal_program (MpegTSBase * base, gint program_number)
|
||||||
{
|
{
|
||||||
MpegTSBaseProgram *program;
|
guint i;
|
||||||
|
|
||||||
program = (MpegTSBaseProgram *) g_hash_table_lookup (base->programs,
|
for (i = 0; i < base->programs->len; i++) {
|
||||||
GINT_TO_POINTER ((gint) program_number));
|
MpegTSBaseProgram *program = g_ptr_array_index (base->programs, i);
|
||||||
|
if (program->program_number == program_number)
|
||||||
|
return g_ptr_array_steal_index (base->programs, i);
|
||||||
|
}
|
||||||
|
|
||||||
if (program)
|
return NULL;
|
||||||
g_hash_table_steal (base->programs,
|
|
||||||
GINT_TO_POINTER ((gint) program_number));
|
|
||||||
|
|
||||||
return program;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -551,11 +550,11 @@ mpegts_base_deactivate_and_free_program (MpegTSBase * base,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mpegts_base_remove_program (MpegTSBase * base, gint program_number)
|
mpegts_base_remove_program (MpegTSBase * base, MpegTSBaseProgram * program)
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (base, "program_number : %d", program_number);
|
GST_DEBUG_OBJECT (base, "program_number : %d", program->program_number);
|
||||||
|
|
||||||
g_hash_table_remove (base->programs, GINT_TO_POINTER (program_number));
|
g_ptr_array_remove (base->programs, program);
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint32
|
static guint32
|
||||||
|
@ -1107,12 +1106,11 @@ mpegts_base_apply_pat (MpegTSBase * base, GstMpegtsSection * section)
|
||||||
|
|
||||||
if (klass->can_remove_program (base, program)) {
|
if (klass->can_remove_program (base, program)) {
|
||||||
mpegts_base_deactivate_program (base, program);
|
mpegts_base_deactivate_program (base, program);
|
||||||
mpegts_base_remove_program (base, patp->program_number);
|
mpegts_base_remove_program (base, program);
|
||||||
} else {
|
} else {
|
||||||
/* sub-class now owns the program and must call
|
/* sub-class now owns the program and must call
|
||||||
* mpegts_base_deactivate_and_free_program later */
|
* mpegts_base_deactivate_and_free_program later */
|
||||||
g_hash_table_steal (base->programs,
|
mpegts_base_steal_program (base, patp->program_number);
|
||||||
GINT_TO_POINTER ((gint) patp->program_number));
|
|
||||||
}
|
}
|
||||||
/* FIXME: when this happens it may still be pmt pid of another
|
/* FIXME: when this happens it may still be pmt pid of another
|
||||||
* program, so setting to False may make it go through expensive
|
* program, so setting to False may make it go through expensive
|
||||||
|
@ -1197,12 +1195,10 @@ mpegts_base_apply_pmt (MpegTSBase * base, GstMpegtsSection * section)
|
||||||
} else {
|
} else {
|
||||||
/* sub-class now owns the program and must call
|
/* sub-class now owns the program and must call
|
||||||
* mpegts_base_deactivate_and_free_program later */
|
* mpegts_base_deactivate_and_free_program later */
|
||||||
g_hash_table_steal (base->programs,
|
mpegts_base_steal_program (base, old_program->program_number);
|
||||||
GINT_TO_POINTER ((gint) old_program->program_number));
|
|
||||||
}
|
}
|
||||||
/* Add new program to the programs we track */
|
/* Add new program to the programs we track */
|
||||||
g_hash_table_insert (base->programs,
|
g_ptr_array_add (base->programs, program);
|
||||||
GINT_TO_POINTER (program_number), program);
|
|
||||||
initial_program = FALSE;
|
initial_program = FALSE;
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG ("Program update, re-using same program");
|
GST_DEBUG ("Program update, re-using same program");
|
||||||
|
@ -1362,14 +1358,11 @@ mpegts_base_get_tags_from_eit (MpegTSBase * base, GstMpegtsSection * section)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static void
|
||||||
remove_each_program (gpointer key, MpegTSBaseProgram * program,
|
remove_each_program (MpegTSBaseProgram * program, MpegTSBase * base)
|
||||||
MpegTSBase * base)
|
|
||||||
{
|
{
|
||||||
/* First deactivate it */
|
/* First deactivate it */
|
||||||
mpegts_base_deactivate_program (base, program);
|
mpegts_base_deactivate_program (base, program);
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline GstFlowReturn
|
static inline GstFlowReturn
|
||||||
|
|
|
@ -123,7 +123,7 @@ struct _MpegTSBase {
|
||||||
|
|
||||||
/* the following vars must be protected with the OBJECT_LOCK as they can be
|
/* the following vars must be protected with the OBJECT_LOCK as they can be
|
||||||
* accessed from the application thread and the streaming thread */
|
* accessed from the application thread and the streaming thread */
|
||||||
GHashTable *programs;
|
GPtrArray *programs;
|
||||||
|
|
||||||
GPtrArray *pat;
|
GPtrArray *pat;
|
||||||
MpegTSPacketizer2 *packetizer;
|
MpegTSPacketizer2 *packetizer;
|
||||||
|
|
Loading…
Reference in a new issue