mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 01:45:33 +00:00
mpegts: ABI/API break: Use GPtrArray instead of GArray
While it was a great idea, various g-i based bindings don't support GArray with entries greater than sizeof(gpointer) :( So let's just make everybody happy by just using GPtrArray. And since we're breaking the API, also rename the various descriptor fields to no longer have the descriptor_ prefix. It does cost a bit more in terms of memory/cpu usage, but makes it usable from bindings.
This commit is contained in:
parent
006e7a3428
commit
5d06aed3e2
8 changed files with 211 additions and 156 deletions
|
@ -67,12 +67,11 @@ gboolean
|
|||
gst_mpegts_descriptor_parse_dvb_network_name (const GstMpegTsDescriptor *
|
||||
descriptor, gchar ** name)
|
||||
{
|
||||
g_return_val_if_fail (descriptor != NULL
|
||||
&& descriptor->descriptor_data != NULL, FALSE);
|
||||
g_return_val_if_fail (descriptor->descriptor_tag == 0x40, FALSE);
|
||||
g_return_val_if_fail (descriptor != NULL && descriptor->data != NULL, FALSE);
|
||||
g_return_val_if_fail (descriptor->tag == 0x40, FALSE);
|
||||
|
||||
*name = get_encoding_and_convert ((gchar *) descriptor->descriptor_data + 2,
|
||||
descriptor->descriptor_data[1]);
|
||||
*name = get_encoding_and_convert ((gchar *) descriptor->data + 2,
|
||||
descriptor->data[1]);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -93,12 +92,11 @@ gst_mpegts_descriptor_parse_satellite_delivery_system (const GstMpegTsDescriptor
|
|||
guint8 *data;
|
||||
guint8 tmp;
|
||||
|
||||
g_return_val_if_fail (descriptor != NULL
|
||||
&& descriptor->descriptor_data != NULL, FALSE);
|
||||
g_return_val_if_fail (descriptor != NULL && descriptor->data != NULL, FALSE);
|
||||
g_return_val_if_fail (res != NULL, FALSE);
|
||||
g_return_val_if_fail (descriptor->descriptor_tag == 0x43, FALSE);
|
||||
g_return_val_if_fail (descriptor->tag == 0x43, FALSE);
|
||||
|
||||
data = (guint8 *) descriptor->descriptor_data + 2;
|
||||
data = (guint8 *) descriptor->data + 2;
|
||||
|
||||
#define BCD_UN(a) ((a) & 0x0f)
|
||||
#define BCD_DEC(a) (((a) >> 4) & 0x0f)
|
||||
|
@ -169,12 +167,11 @@ gst_mpegts_descriptor_parse_cable_delivery_system (const GstMpegTsDescriptor *
|
|||
{
|
||||
guint8 *data;
|
||||
|
||||
g_return_val_if_fail (descriptor != NULL
|
||||
&& descriptor->descriptor_data != NULL, FALSE);
|
||||
g_return_val_if_fail (descriptor != NULL && descriptor->data != NULL, FALSE);
|
||||
g_return_val_if_fail (res != NULL, FALSE);
|
||||
g_return_val_if_fail (descriptor->descriptor_tag == 0x44, FALSE);
|
||||
g_return_val_if_fail (descriptor->tag == 0x44, FALSE);
|
||||
|
||||
data = (guint8 *) descriptor->descriptor_data + 2;
|
||||
data = (guint8 *) descriptor->data + 2;
|
||||
/* BCD in MHz, decimal place after the fourth character */
|
||||
res->frequency = BCD_32 (data) * 100;
|
||||
data += 5;
|
||||
|
@ -235,11 +232,10 @@ gst_mpegts_descriptor_parse_dvb_service (const GstMpegTsDescriptor *
|
|||
{
|
||||
guint8 *data;
|
||||
|
||||
g_return_val_if_fail (descriptor != NULL
|
||||
&& descriptor->descriptor_data != NULL, FALSE);
|
||||
g_return_val_if_fail (descriptor->descriptor_tag == 0x48, FALSE);
|
||||
g_return_val_if_fail (descriptor != NULL && descriptor->data != NULL, FALSE);
|
||||
g_return_val_if_fail (descriptor->tag == 0x48, FALSE);
|
||||
|
||||
data = (guint8 *) descriptor->descriptor_data + 2;
|
||||
data = (guint8 *) descriptor->data + 2;
|
||||
|
||||
if (service_type)
|
||||
*service_type = *data;
|
||||
|
@ -271,11 +267,10 @@ gst_mpegts_descriptor_parse_dvb_short_event (const GstMpegTsDescriptor *
|
|||
{
|
||||
guint8 *data;
|
||||
|
||||
g_return_val_if_fail (descriptor != NULL
|
||||
&& descriptor->descriptor_data != NULL, FALSE);
|
||||
g_return_val_if_fail (descriptor->descriptor_tag == 0x4D, FALSE);
|
||||
g_return_val_if_fail (descriptor != NULL && descriptor->data != NULL, FALSE);
|
||||
g_return_val_if_fail (descriptor->tag == 0x4D, FALSE);
|
||||
|
||||
data = (guint8 *) descriptor->descriptor_data + 2;
|
||||
data = (guint8 *) descriptor->data + 2;
|
||||
|
||||
if (language_code) {
|
||||
*language_code = g_malloc0 (4);
|
||||
|
|
|
@ -98,8 +98,13 @@ _parse_utc_time (guint8 * data)
|
|||
static GstMpegTsEITEvent *
|
||||
_gst_mpegts_eit_event_copy (GstMpegTsEITEvent * eit)
|
||||
{
|
||||
/* FIXME : IMPLEMENT */
|
||||
return NULL;
|
||||
GstMpegTsEITEvent *copy;
|
||||
|
||||
copy = g_slice_dup (GstMpegTsEITEvent, eit);
|
||||
copy->start_time = gst_date_time_ref (eit->start_time);
|
||||
copy->descriptors = g_ptr_array_ref (eit->descriptors);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -107,7 +112,7 @@ _gst_mpegts_eit_event_free (GstMpegTsEITEvent * eit)
|
|||
{
|
||||
if (eit->start_time)
|
||||
gst_date_time_unref (eit->start_time);
|
||||
g_array_unref (eit->descriptors);
|
||||
g_ptr_array_unref (eit->descriptors);
|
||||
g_slice_free (GstMpegTsEITEvent, eit);
|
||||
}
|
||||
|
||||
|
@ -118,8 +123,12 @@ G_DEFINE_BOXED_TYPE (GstMpegTsEITEvent, gst_mpegts_eit_event,
|
|||
static GstMpegTsEIT *
|
||||
_gst_mpegts_eit_copy (GstMpegTsEIT * eit)
|
||||
{
|
||||
/* FIXME : IMPLEMENT */
|
||||
return NULL;
|
||||
GstMpegTsEIT *copy;
|
||||
|
||||
copy = g_slice_dup (GstMpegTsEIT, eit);
|
||||
copy->events = g_ptr_array_ref (eit->events);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -247,14 +256,18 @@ gst_mpegts_section_get_eit (GstMpegTsSection * section)
|
|||
static GstMpegTsBATStream *
|
||||
_gst_mpegts_bat_stream_copy (GstMpegTsBATStream * bat)
|
||||
{
|
||||
/* FIXME : IMPLEMENT */
|
||||
return NULL;
|
||||
GstMpegTsBATStream *copy;
|
||||
|
||||
copy = g_slice_dup (GstMpegTsBATStream, bat);
|
||||
copy->descriptors = g_ptr_array_ref (bat->descriptors);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static void
|
||||
_gst_mpegts_bat_stream_free (GstMpegTsBATStream * bat)
|
||||
{
|
||||
g_array_unref (bat->descriptors);
|
||||
g_ptr_array_unref (bat->descriptors);
|
||||
g_slice_free (GstMpegTsBATStream, bat);
|
||||
}
|
||||
|
||||
|
@ -265,14 +278,19 @@ G_DEFINE_BOXED_TYPE (GstMpegTsBATStream, gst_mpegts_bat_stream,
|
|||
static GstMpegTsBAT *
|
||||
_gst_mpegts_bat_copy (GstMpegTsBAT * bat)
|
||||
{
|
||||
/* FIXME : IMPLEMENT */
|
||||
return NULL;
|
||||
GstMpegTsBAT *copy;
|
||||
|
||||
copy = g_slice_dup (GstMpegTsBAT, bat);
|
||||
copy->descriptors = g_ptr_array_ref (bat->descriptors);
|
||||
copy->streams = g_ptr_array_ref (bat->streams);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static void
|
||||
_gst_mpegts_bat_free (GstMpegTsBAT * bat)
|
||||
{
|
||||
g_array_unref (bat->descriptors);
|
||||
g_ptr_array_unref (bat->descriptors);
|
||||
g_ptr_array_unref (bat->streams);
|
||||
g_slice_free (GstMpegTsBAT, bat);
|
||||
}
|
||||
|
@ -414,14 +432,18 @@ gst_mpegts_section_get_bat (GstMpegTsSection * section)
|
|||
static GstMpegTsNITStream *
|
||||
_gst_mpegts_nit_stream_copy (GstMpegTsNITStream * nit)
|
||||
{
|
||||
/* FIXME : IMPLEMENT */
|
||||
return NULL;
|
||||
GstMpegTsNITStream *copy;
|
||||
|
||||
copy = g_slice_dup (GstMpegTsNITStream, nit);
|
||||
copy->descriptors = g_ptr_array_ref (nit->descriptors);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static void
|
||||
_gst_mpegts_nit_stream_free (GstMpegTsNITStream * nit)
|
||||
{
|
||||
g_array_unref (nit->descriptors);
|
||||
g_ptr_array_unref (nit->descriptors);
|
||||
g_slice_free (GstMpegTsNITStream, nit);
|
||||
}
|
||||
|
||||
|
@ -432,14 +454,18 @@ G_DEFINE_BOXED_TYPE (GstMpegTsNITStream, gst_mpegts_nit_stream,
|
|||
static GstMpegTsNIT *
|
||||
_gst_mpegts_nit_copy (GstMpegTsNIT * nit)
|
||||
{
|
||||
/* FIXME : IMPLEMENT */
|
||||
return NULL;
|
||||
GstMpegTsNIT *copy = g_slice_dup (GstMpegTsNIT, nit);
|
||||
|
||||
copy->descriptors = g_ptr_array_ref (nit->descriptors);
|
||||
copy->streams = g_ptr_array_ref (nit->streams);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static void
|
||||
_gst_mpegts_nit_free (GstMpegTsNIT * nit)
|
||||
{
|
||||
g_array_unref (nit->descriptors);
|
||||
g_ptr_array_unref (nit->descriptors);
|
||||
g_ptr_array_unref (nit->streams);
|
||||
g_slice_free (GstMpegTsNIT, nit);
|
||||
}
|
||||
|
@ -584,14 +610,17 @@ gst_mpegts_section_get_nit (GstMpegTsSection * section)
|
|||
static GstMpegTsSDTService *
|
||||
_gst_mpegts_sdt_service_copy (GstMpegTsSDTService * sdt)
|
||||
{
|
||||
/* FIXME : IMPLEMENT */
|
||||
return NULL;
|
||||
GstMpegTsSDTService *copy = g_slice_dup (GstMpegTsSDTService, sdt);
|
||||
|
||||
copy->descriptors = g_ptr_array_ref (sdt->descriptors);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static void
|
||||
_gst_mpegts_sdt_service_free (GstMpegTsSDTService * sdt)
|
||||
{
|
||||
g_array_unref (sdt->descriptors);
|
||||
g_ptr_array_unref (sdt->descriptors);
|
||||
g_slice_free (GstMpegTsSDTService, sdt);
|
||||
}
|
||||
|
||||
|
@ -602,8 +631,11 @@ G_DEFINE_BOXED_TYPE (GstMpegTsSDTService, gst_mpegts_sdt_service,
|
|||
static GstMpegTsSDT *
|
||||
_gst_mpegts_sdt_copy (GstMpegTsSDT * sdt)
|
||||
{
|
||||
/* FIXME : IMPLEMENT */
|
||||
return NULL;
|
||||
GstMpegTsSDT *copy = g_slice_dup (GstMpegTsSDT, sdt);
|
||||
|
||||
copy->services = g_ptr_array_ref (sdt->services);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -769,8 +801,13 @@ gst_mpegts_section_get_tdt (GstMpegTsSection * section)
|
|||
static GstMpegTsTOT *
|
||||
_gst_mpegts_tot_copy (GstMpegTsTOT * tot)
|
||||
{
|
||||
/* FIXME : IMPLEMENT */
|
||||
return NULL;
|
||||
GstMpegTsTOT *copy = g_slice_dup (GstMpegTsTOT, tot);
|
||||
|
||||
if (tot->utc_time)
|
||||
copy->utc_time = gst_date_time_ref (tot->utc_time);
|
||||
copy->descriptors = g_ptr_array_ref (tot->descriptors);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -778,7 +815,7 @@ _gst_mpegts_tot_free (GstMpegTsTOT * tot)
|
|||
{
|
||||
if (tot->utc_time)
|
||||
gst_date_time_unref (tot->utc_time);
|
||||
g_array_unref (tot->descriptors);
|
||||
g_ptr_array_unref (tot->descriptors);
|
||||
g_slice_free (GstMpegTsTOT, tot);
|
||||
}
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ struct _GstMpegTsNITStream
|
|||
guint16 transport_stream_id;
|
||||
guint16 original_network_id;
|
||||
|
||||
GArray *descriptors;
|
||||
GPtrArray *descriptors;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -155,7 +155,7 @@ struct _GstMpegTsNIT
|
|||
{
|
||||
gboolean actual_network;
|
||||
|
||||
GArray *descriptors;
|
||||
GPtrArray *descriptors;
|
||||
|
||||
GPtrArray *streams;
|
||||
};
|
||||
|
@ -178,7 +178,7 @@ struct _GstMpegTsBATStream
|
|||
guint16 transport_stream_id;
|
||||
guint16 original_network_id;
|
||||
|
||||
GArray *descriptors;
|
||||
GPtrArray *descriptors;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -190,7 +190,7 @@ struct _GstMpegTsBATStream
|
|||
*/
|
||||
struct _GstMpegTsBAT
|
||||
{
|
||||
GArray *descriptors;
|
||||
GPtrArray *descriptors;
|
||||
|
||||
GPtrArray *streams;
|
||||
};
|
||||
|
@ -216,7 +216,7 @@ struct _GstMpegTsSDTService
|
|||
GstMpegTsRunningStatus running_status;
|
||||
gboolean free_CA_mode;
|
||||
|
||||
GArray *descriptors;
|
||||
GPtrArray *descriptors;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -260,7 +260,7 @@ struct _GstMpegTsEITEvent
|
|||
GstMpegTsRunningStatus running_status;
|
||||
gboolean free_CA_mode;
|
||||
|
||||
GArray *descriptors;
|
||||
GPtrArray *descriptors;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -302,7 +302,7 @@ struct _GstMpegTsTOT
|
|||
{
|
||||
GstDateTime *utc_time;
|
||||
|
||||
GArray *descriptors;
|
||||
GPtrArray *descriptors;
|
||||
};
|
||||
|
||||
GType gst_mpegts_tot_get_type (void);
|
||||
|
|
|
@ -465,6 +465,27 @@ failed:
|
|||
}
|
||||
}
|
||||
|
||||
static GstMpegTsDescriptor *
|
||||
_copy_descriptor (GstMpegTsDescriptor * desc)
|
||||
{
|
||||
GstMpegTsDescriptor *copy;
|
||||
|
||||
copy = g_slice_dup (GstMpegTsDescriptor, desc);
|
||||
copy->data = g_memdup (desc->data, desc->length + 2);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static void
|
||||
_free_descriptor (GstMpegTsDescriptor * desc)
|
||||
{
|
||||
g_free ((gpointer) desc->data);
|
||||
g_slice_free (GstMpegTsDescriptor, desc);
|
||||
}
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GstMpegTsDescriptor, gst_mpegts_descriptor,
|
||||
(GBoxedCopyFunc) _copy_descriptor, (GBoxedFreeFunc) _free_descriptor);
|
||||
|
||||
/**
|
||||
* gst_mpegts_parse_descriptors:
|
||||
* @buffer: (transfer none): descriptors to parse
|
||||
|
@ -479,20 +500,22 @@ failed:
|
|||
* array of the parsed descriptors or %NULL if there was an error.
|
||||
* Release with #g_array_unref when done with it.
|
||||
*/
|
||||
GArray *
|
||||
GPtrArray *
|
||||
gst_mpegts_parse_descriptors (guint8 * buffer, gsize buf_len)
|
||||
{
|
||||
GArray *res;
|
||||
GPtrArray *res;
|
||||
guint8 length;
|
||||
guint8 *data;
|
||||
guint i, nb_desc = 0;
|
||||
|
||||
/* fast-path */
|
||||
if (buf_len == 0)
|
||||
return g_array_new (FALSE, FALSE, sizeof (GstMpegTsDescriptor));
|
||||
return g_ptr_array_new ();
|
||||
|
||||
data = buffer;
|
||||
|
||||
GST_MEMDUMP ("Full descriptor array", buffer, buf_len);
|
||||
|
||||
while (data - buffer < buf_len) {
|
||||
data++; /* skip tag */
|
||||
length = *data++;
|
||||
|
@ -516,26 +539,28 @@ gst_mpegts_parse_descriptors (guint8 * buffer, gsize buf_len)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
res = g_array_sized_new (FALSE, FALSE, sizeof (GstMpegTsDescriptor), nb_desc);
|
||||
res = g_ptr_array_new_full (nb_desc + 1, (GDestroyNotify) _free_descriptor);
|
||||
|
||||
data = buffer;
|
||||
|
||||
for (i = 0; i < nb_desc; i++) {
|
||||
GstMpegTsDescriptor *desc = &g_array_index (res, GstMpegTsDescriptor, i);
|
||||
GstMpegTsDescriptor *desc = g_slice_new0 (GstMpegTsDescriptor);
|
||||
|
||||
desc->descriptor_data = data;
|
||||
desc->descriptor_tag = *data++;
|
||||
desc->descriptor_length = *data++;
|
||||
GST_LOG ("descriptor 0x%02x length:%d", desc->descriptor_tag,
|
||||
desc->descriptor_length);
|
||||
GST_MEMDUMP ("descriptor", desc->descriptor_data + 2,
|
||||
desc->descriptor_length);
|
||||
/* Adjust for extended descriptors */
|
||||
if (G_UNLIKELY (desc->descriptor_tag == 0x7f)) {
|
||||
desc->descriptor_tag_extension = *data++;
|
||||
desc->descriptor_length -= 1;
|
||||
}
|
||||
data += desc->descriptor_length;
|
||||
desc->data = data;
|
||||
desc->tag = *data++;
|
||||
desc->length = *data++;
|
||||
/* Copy the data now that we known the size */
|
||||
desc->data = g_memdup (desc->data, desc->length + 2);
|
||||
GST_LOG ("descriptor 0x%02x length:%d", desc->tag, desc->length);
|
||||
GST_MEMDUMP ("descriptor", desc->data + 2, desc->length);
|
||||
/* extended descriptors */
|
||||
if (G_UNLIKELY (desc->tag == 0x7f))
|
||||
desc->tag_extension = *data;
|
||||
|
||||
data += desc->length;
|
||||
|
||||
/* Set the descriptor in the array */
|
||||
g_ptr_array_index (res, i) = desc;
|
||||
}
|
||||
|
||||
res->len = nb_desc;
|
||||
|
@ -557,7 +582,7 @@ gst_mpegts_parse_descriptors (guint8 * buffer, gsize buf_len)
|
|||
* Returns: (transfer none): the first descriptor matchin @tag, else %NULL.
|
||||
*/
|
||||
const GstMpegTsDescriptor *
|
||||
gst_mpegts_find_descriptor (GArray * descriptors, guint8 tag)
|
||||
gst_mpegts_find_descriptor (GPtrArray * descriptors, guint8 tag)
|
||||
{
|
||||
guint i, nb_desc;
|
||||
|
||||
|
@ -565,41 +590,13 @@ gst_mpegts_find_descriptor (GArray * descriptors, guint8 tag)
|
|||
|
||||
nb_desc = descriptors->len;
|
||||
for (i = 0; i < nb_desc; i++) {
|
||||
GstMpegTsDescriptor *desc =
|
||||
&g_array_index (descriptors, GstMpegTsDescriptor, i);
|
||||
if (desc->descriptor_tag == tag)
|
||||
GstMpegTsDescriptor *desc = g_ptr_array_index (descriptors, i);
|
||||
if (desc->tag == tag)
|
||||
return (const GstMpegTsDescriptor *) desc;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GstMpegTsDescriptor *
|
||||
_copy_descriptor (GstMpegTsDescriptor * desc)
|
||||
{
|
||||
GstMpegTsDescriptor *copy;
|
||||
|
||||
copy = g_new0 (GstMpegTsDescriptor, 1);
|
||||
copy->descriptor_tag = desc->descriptor_tag;
|
||||
copy->descriptor_tag_extension = desc->descriptor_tag_extension;
|
||||
copy->descriptor_length = desc->descriptor_length;
|
||||
copy->descriptor_data =
|
||||
g_memdup (desc->descriptor_data, desc->descriptor_length);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
/* This freefunc will only ever be used with descriptors returned by the
|
||||
* above function. That is why we free the descriptor data (unlike the
|
||||
* descriptors created in _parse_descriptors()) */
|
||||
static void
|
||||
_free_descriptor (GstMpegTsDescriptor * desc)
|
||||
{
|
||||
g_free ((gpointer) desc->descriptor_data);
|
||||
g_free (desc);
|
||||
}
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GstMpegTsDescriptor, gst_mpegts_descriptor,
|
||||
(GBoxedCopyFunc) _copy_descriptor, (GBoxedFreeFunc) _free_descriptor);
|
||||
|
||||
/* GST_MTS_DESC_ISO_639_LANGUAGE (0x0A) */
|
||||
/**
|
||||
|
@ -621,14 +618,13 @@ gst_mpegts_descriptor_parse_iso_639_language (const GstMpegTsDescriptor *
|
|||
guint i;
|
||||
guint8 *data;
|
||||
|
||||
g_return_val_if_fail (descriptor != NULL
|
||||
&& descriptor->descriptor_data != NULL, FALSE);
|
||||
g_return_val_if_fail (descriptor != NULL && descriptor->data != NULL, FALSE);
|
||||
g_return_val_if_fail (res != NULL, FALSE);
|
||||
g_return_val_if_fail (descriptor->descriptor_tag == 0x0A, FALSE);
|
||||
g_return_val_if_fail (descriptor->tag == 0x0A, FALSE);
|
||||
|
||||
data = (guint8 *) descriptor->descriptor_data + 2;
|
||||
data = (guint8 *) descriptor->data + 2;
|
||||
/* Each language is 3 + 1 bytes */
|
||||
res->nb_language = descriptor->descriptor_length / 4;
|
||||
res->nb_language = descriptor->length / 4;
|
||||
for (i = 0; i < res->nb_language; i++) {
|
||||
memcpy (res->language[i], data, 3);
|
||||
res->audio_type[i] = data[3];
|
||||
|
@ -654,12 +650,11 @@ gst_mpegts_descriptor_parse_logical_channel (const GstMpegTsDescriptor *
|
|||
guint i;
|
||||
guint8 *data;
|
||||
|
||||
g_return_val_if_fail (descriptor != NULL
|
||||
&& descriptor->descriptor_data != NULL, FALSE);
|
||||
g_return_val_if_fail (descriptor->descriptor_tag == 0x83, FALSE);
|
||||
g_return_val_if_fail (descriptor != NULL && descriptor->data != NULL, FALSE);
|
||||
g_return_val_if_fail (descriptor->tag == 0x83, FALSE);
|
||||
|
||||
data = (guint8 *) descriptor->descriptor_data;
|
||||
res->nb_channels = descriptor->descriptor_length / 4;
|
||||
data = (guint8 *) descriptor->data;
|
||||
res->nb_channels = descriptor->length / 4;
|
||||
|
||||
for (i = 0; i < res->nb_channels; i++) {
|
||||
res->channels[i].service_id = GST_READ_UINT16_BE (data);
|
||||
|
|
|
@ -239,24 +239,25 @@ GType gst_mpegts_descriptor_get_type (void);
|
|||
|
||||
/**
|
||||
* GstMpegTsDescriptor:
|
||||
* @descriptor_tag: the type of descriptor
|
||||
* @descriptor_tag_extension: the extended type (if @descriptor_tag is 0x7f)
|
||||
* @descriptor_length: the length of the descriptor content (excluding tag/length field)
|
||||
* @descriptor_data: the full descriptor data (including tag, extension, length)
|
||||
* @tag: the type of descriptor
|
||||
* @tag_extension: the extended type (if @descriptor_tag is 0x7f)
|
||||
* @length: the length of the descriptor content (excluding tag/length field)
|
||||
* @data: the full descriptor data (including tag, extension, length). The first
|
||||
* two bytes are the @tag and @tag_extension.
|
||||
*
|
||||
* Mpeg-TS descriptor (ISO/IEC 13818-1).
|
||||
*/
|
||||
struct _GstMpegTsDescriptor
|
||||
{
|
||||
guint8 descriptor_tag;
|
||||
guint8 descriptor_tag_extension;
|
||||
guint8 descriptor_length;
|
||||
const guint8 *descriptor_data;
|
||||
guint8 tag;
|
||||
guint8 tag_extension;
|
||||
guint8 length;
|
||||
const guint8 *data;
|
||||
};
|
||||
|
||||
GArray *gst_mpegts_parse_descriptors (guint8 * buffer, gsize buf_len);
|
||||
GPtrArray *gst_mpegts_parse_descriptors (guint8 * buffer, gsize buf_len);
|
||||
|
||||
const GstMpegTsDescriptor * gst_mpegts_find_descriptor (GArray *descriptors,
|
||||
const GstMpegTsDescriptor * gst_mpegts_find_descriptor (GPtrArray *descriptors,
|
||||
guint8 tag);
|
||||
|
||||
/* GST_MTS_DESC_ISO_639_LANGUAGE (0x0A) */
|
||||
|
|
|
@ -316,12 +316,27 @@ gst_message_new_mpegts_section (GstObject * parent, GstMpegTsSection * section)
|
|||
return msg;
|
||||
}
|
||||
|
||||
static GstMpegTsPatProgram *
|
||||
_mpegts_pat_program_copy (GstMpegTsPatProgram * orig)
|
||||
{
|
||||
return g_slice_dup (GstMpegTsPatProgram, orig);
|
||||
}
|
||||
|
||||
static void
|
||||
_mpegts_pat_program_free (GstMpegTsPatProgram * orig)
|
||||
{
|
||||
g_slice_free (GstMpegTsPatProgram, orig);
|
||||
}
|
||||
|
||||
G_DEFINE_BOXED_TYPE (GstMpegTsPatProgram, gst_mpegts_pat_program,
|
||||
(GBoxedCopyFunc) _mpegts_pat_program_copy,
|
||||
(GFreeFunc) _mpegts_pat_program_free);
|
||||
|
||||
/* Program Association Table */
|
||||
static gpointer
|
||||
_parse_pat (GstMpegTsSection * section)
|
||||
{
|
||||
GArray *pat;
|
||||
GPtrArray *pat;
|
||||
guint16 i = 0, nb_programs;
|
||||
GstMpegTsPatProgram *program;
|
||||
guint8 *data, *end;
|
||||
|
@ -335,24 +350,26 @@ _parse_pat (GstMpegTsSection * section)
|
|||
/* Initialize program list */
|
||||
nb_programs = (end - 4 - data) / 4;
|
||||
pat =
|
||||
g_array_sized_new (FALSE, FALSE, sizeof (GstMpegTsPatProgram),
|
||||
nb_programs);
|
||||
g_ptr_array_new_full (nb_programs,
|
||||
(GDestroyNotify) _mpegts_pat_program_free);
|
||||
|
||||
while (data < end - 4) {
|
||||
program = &g_array_index (pat, GstMpegTsPatProgram, i);
|
||||
program = g_slice_new0 (GstMpegTsPatProgram);
|
||||
program->program_number = GST_READ_UINT16_BE (data);
|
||||
data += 2;
|
||||
|
||||
program->network_or_program_map_PID = GST_READ_UINT16_BE (data) & 0x1FFF;
|
||||
data += 2;
|
||||
|
||||
g_ptr_array_index (pat, i) = program;
|
||||
|
||||
i++;
|
||||
}
|
||||
pat->len = nb_programs;
|
||||
|
||||
if (data != end - 4) {
|
||||
GST_ERROR ("at the end of PAT data != end - 4");
|
||||
g_array_unref (pat);
|
||||
g_ptr_array_unref (pat);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -375,7 +392,7 @@ _parse_pat (GstMpegTsSection * section)
|
|||
* #GstMpegTsPatProgram contained in the section, or %NULL if an error
|
||||
* happened. Release with #g_ptr_array_unref when done.
|
||||
*/
|
||||
GArray *
|
||||
GPtrArray *
|
||||
gst_mpegts_section_get_pat (GstMpegTsSection * section)
|
||||
{
|
||||
g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_PAT, NULL);
|
||||
|
@ -384,10 +401,10 @@ gst_mpegts_section_get_pat (GstMpegTsSection * section)
|
|||
if (!section->cached_parsed)
|
||||
section->cached_parsed =
|
||||
__common_desc_checks (section, 12, _parse_pat,
|
||||
(GDestroyNotify) g_array_unref);
|
||||
(GDestroyNotify) g_ptr_array_unref);
|
||||
|
||||
if (section->cached_parsed)
|
||||
return g_array_ref ((GArray *) section->cached_parsed);
|
||||
return g_ptr_array_ref ((GPtrArray *) section->cached_parsed);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -397,14 +414,18 @@ gst_mpegts_section_get_pat (GstMpegTsSection * section)
|
|||
static GstMpegTsPMTStream *
|
||||
_gst_mpegts_pmt_stream_copy (GstMpegTsPMTStream * pmt)
|
||||
{
|
||||
/* FIXME : IMPLEMENT */
|
||||
return NULL;
|
||||
GstMpegTsPMTStream *copy;
|
||||
|
||||
copy = g_slice_dup (GstMpegTsPMTStream, pmt);
|
||||
copy->descriptors = g_ptr_array_ref (pmt->descriptors);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static void
|
||||
_gst_mpegts_pmt_stream_free (GstMpegTsPMTStream * pmt)
|
||||
{
|
||||
g_array_unref (pmt->descriptors);
|
||||
g_ptr_array_unref (pmt->descriptors);
|
||||
g_slice_free (GstMpegTsPMTStream, pmt);
|
||||
}
|
||||
|
||||
|
@ -415,14 +436,19 @@ G_DEFINE_BOXED_TYPE (GstMpegTsPMTStream, gst_mpegts_pmt_stream,
|
|||
static GstMpegTsPMT *
|
||||
_gst_mpegts_pmt_copy (GstMpegTsPMT * pmt)
|
||||
{
|
||||
/* FIXME : IMPLEMENT */
|
||||
return NULL;
|
||||
GstMpegTsPMT *copy;
|
||||
|
||||
copy = g_slice_dup (GstMpegTsPMT, pmt);
|
||||
copy->descriptors = g_ptr_array_ref (pmt->descriptors);
|
||||
copy->streams = g_ptr_array_ref (pmt->streams);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
static void
|
||||
_gst_mpegts_pmt_free (GstMpegTsPMT * pmt)
|
||||
{
|
||||
g_array_unref (pmt->descriptors);
|
||||
g_ptr_array_unref (pmt->descriptors);
|
||||
g_ptr_array_unref (pmt->streams);
|
||||
g_slice_free (GstMpegTsPMT, pmt);
|
||||
}
|
||||
|
@ -564,7 +590,7 @@ _parse_cat (GstMpegTsSection * section)
|
|||
* #GstMpegTsDescriptor contained in the section, or %NULL if an error
|
||||
* happened. Release with #g_array_unref when done.
|
||||
*/
|
||||
GArray *
|
||||
GPtrArray *
|
||||
gst_mpegts_section_get_cat (GstMpegTsSection * section)
|
||||
{
|
||||
g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_CAT, NULL);
|
||||
|
@ -573,10 +599,10 @@ gst_mpegts_section_get_cat (GstMpegTsSection * section)
|
|||
if (!section->cached_parsed)
|
||||
section->cached_parsed =
|
||||
__common_desc_checks (section, 12, _parse_cat,
|
||||
(GDestroyNotify) g_array_unref);
|
||||
(GDestroyNotify) g_ptr_array_unref);
|
||||
|
||||
if (section->cached_parsed)
|
||||
return g_array_ref ((GArray *) section->cached_parsed);
|
||||
return g_ptr_array_ref ((GPtrArray *) section->cached_parsed);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -591,14 +617,14 @@ gst_mpegts_section_get_cat (GstMpegTsSection * section)
|
|||
* #GstMpegTsDescriptor contained in the section, or %NULL if an error
|
||||
* happened. Release with #g_array_unref when done.
|
||||
*/
|
||||
GArray *
|
||||
GPtrArray *
|
||||
gst_mpegts_section_get_tsdt (GstMpegTsSection * section)
|
||||
{
|
||||
g_return_val_if_fail (section->section_type == GST_MPEGTS_SECTION_TSDT, NULL);
|
||||
g_return_val_if_fail (section->cached_parsed || section->data, NULL);
|
||||
|
||||
if (section->cached_parsed)
|
||||
return g_array_ref ((GArray *) section->cached_parsed);
|
||||
return g_ptr_array_ref ((GPtrArray *) section->cached_parsed);
|
||||
|
||||
/* FIXME : parse TSDT */
|
||||
return NULL;
|
||||
|
|
|
@ -157,6 +157,8 @@ struct _GstMpegTsSection
|
|||
|
||||
|
||||
/* PAT */
|
||||
#define GST_TYPE_MPEGTS_PAT_PROGRAM (gst_mpegts_pat_program_get_type())
|
||||
|
||||
typedef struct _GstMpegTsPatProgram GstMpegTsPatProgram;
|
||||
/**
|
||||
* GstMpegTsPatProgram:
|
||||
|
@ -171,11 +173,12 @@ struct _GstMpegTsPatProgram
|
|||
guint16 network_or_program_map_PID;
|
||||
};
|
||||
|
||||
GArray *gst_mpegts_section_get_pat (GstMpegTsSection *section);
|
||||
GPtrArray *gst_mpegts_section_get_pat (GstMpegTsSection *section);
|
||||
GType gst_mpegts_pat_program_get_type (void);
|
||||
|
||||
/* CAT */
|
||||
|
||||
GArray *gst_mpegts_section_get_cat (GstMpegTsSection *section);
|
||||
GPtrArray *gst_mpegts_section_get_cat (GstMpegTsSection *section);
|
||||
|
||||
/* PMT */
|
||||
typedef struct _GstMpegTsPMTStream GstMpegTsPMTStream;
|
||||
|
@ -312,7 +315,7 @@ struct _GstMpegTsPMTStream
|
|||
guint8 stream_type;
|
||||
guint16 pid;
|
||||
|
||||
GArray *descriptors;
|
||||
GPtrArray *descriptors;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -330,7 +333,7 @@ struct _GstMpegTsPMT
|
|||
{
|
||||
guint16 pcr_pid;
|
||||
|
||||
GArray *descriptors;
|
||||
GPtrArray *descriptors;
|
||||
GPtrArray *streams;
|
||||
};
|
||||
|
||||
|
@ -341,7 +344,7 @@ const GstMpegTsPMT *gst_mpegts_section_get_pmt (GstMpegTsSection *section);
|
|||
|
||||
/* TSDT */
|
||||
|
||||
GArray *gst_mpegts_section_get_tsdt (GstMpegTsSection *section);
|
||||
GPtrArray *gst_mpegts_section_get_tsdt (GstMpegTsSection *section);
|
||||
|
||||
|
||||
/* generic */
|
||||
|
|
|
@ -120,20 +120,18 @@ dump_iso_639_language (GstMpegTsDescriptor * desc, guint spacing)
|
|||
|
||||
|
||||
static void
|
||||
dump_descriptors (GArray * descriptors, guint spacing)
|
||||
dump_descriptors (GPtrArray * descriptors, guint spacing)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < descriptors->len; i++) {
|
||||
GstMpegTsDescriptor *desc =
|
||||
&g_array_index (descriptors, GstMpegTsDescriptor, i);
|
||||
GstMpegTsDescriptor *desc = g_ptr_array_index (descriptors, i);
|
||||
g_printf ("%*s [descriptor 0x%02x (%s) length:%d]\n", spacing, "",
|
||||
desc->descriptor_tag, descriptor_name (desc->descriptor_tag),
|
||||
desc->descriptor_length);
|
||||
switch (desc->descriptor_tag) {
|
||||
desc->tag, descriptor_name (desc->tag), desc->length);
|
||||
switch (desc->tag) {
|
||||
case GST_MTS_DESC_REGISTRATION:
|
||||
{
|
||||
const guint8 *data = desc->descriptor_data + 2;
|
||||
const guint8 *data = desc->data + 2;
|
||||
#define SAFE_CHAR(a) (g_ascii_isalnum(a) ? a : '.')
|
||||
g_printf ("%*s Registration : %c%c%c%c\n", spacing, "",
|
||||
SAFE_CHAR (data[0]), SAFE_CHAR (data[1]),
|
||||
|
@ -201,14 +199,14 @@ dump_descriptors (GArray * descriptors, guint spacing)
|
|||
static void
|
||||
dump_pat (GstMpegTsSection * section)
|
||||
{
|
||||
GArray *pat = gst_mpegts_section_get_pat (section);
|
||||
GPtrArray *pat = gst_mpegts_section_get_pat (section);
|
||||
guint i, len;
|
||||
|
||||
len = pat->len;
|
||||
g_printf (" %d program(s):\n", len);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
GstMpegTsPatProgram *patp = &g_array_index (pat, GstMpegTsPatProgram, i);
|
||||
GstMpegTsPatProgram *patp = g_ptr_array_index (pat, i);
|
||||
|
||||
g_print
|
||||
(" program_number:%6d (0x%04x), network_or_program_map_PID:0x%04x\n",
|
||||
|
@ -216,7 +214,7 @@ dump_pat (GstMpegTsSection * section)
|
|||
patp->network_or_program_map_PID);
|
||||
}
|
||||
|
||||
g_array_unref (pat);
|
||||
g_ptr_array_unref (pat);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Reference in a new issue