mpegts: add dvb-t2 delivery system descriptor

Signed-off-by: Stefan Ringel <linuxtv@stefanringel.de>

https://bugzilla.gnome.org/show_bug.cgi?id=727356
This commit is contained in:
Stefan Ringel 2014-03-30 21:02:10 +02:00 committed by Edward Hervey
parent e8c86e355f
commit b7efacfe15
3 changed files with 307 additions and 0 deletions

View file

@ -1032,3 +1032,186 @@ gst_mpegts_descriptor_parse_dvb_data_broadcast (const GstMpegTsDescriptor
return TRUE;
}
/* GST_MTS_DESC_EXT_DVB_T2_DELIVERY_SYSTEM (0x7F && 0x04) */
static void
_gst_mpegts_t2_delivery_system_cell_extension_free
(GstMpegTsT2DeliverySystemCellExtension * ext)
{
g_slice_free (GstMpegTsT2DeliverySystemCellExtension, ext);
}
static void
_gst_mpegts_t2_delivery_system_cell_free (GstMpegTsT2DeliverySystemCell * cell)
{
g_ptr_array_unref (cell->sub_cells);
g_slice_free (GstMpegTsT2DeliverySystemCell, cell);
}
/**
* gst_mpegts_descriptor_parse_dvb_t2_delivery_system:
* @descriptor: a %GST_MTS_DESC_EXT_DVB_T2_DELIVERY_SYSTEM #GstMpegTsDescriptor
* @res: (out) (transfer none): #GstMpegTsT2DeliverySystemDescriptor
*
* Parses out the DVB-T2 delivery system from the @descriptor.
*
* Returns: %TRUE if the parsing happened correctly, else %FALSE.
*/
gboolean
gst_mpegts_descriptor_parse_dvb_t2_delivery_system (const GstMpegTsDescriptor
* descriptor, GstMpegTsT2DeliverySystemDescriptor * res)
{
guint8 *data;
guint8 len, freq_len, sub_cell_len;
guint32 tmp_freq;
g_return_val_if_fail (descriptor != NULL && res != NULL, FALSE);
__common_desc_ext_checks (descriptor, GST_MTS_DESC_EXT_DVB_T2_DELIVERY_SYSTEM,
4, FALSE);
data = (guint8 *) descriptor->data + 3;
res->plp_id = *data;
data += 1;
res->t2_system_id = GST_READ_UINT16_BE (data);
data += 2;
if (descriptor->length > 4) {
// FIXME: siso / miso
res->siso_miso = (*data >> 6) & 0x03;
switch ((*data >> 2) & 0x0f) {
case 0:
res->bandwidth = 8000000;
break;
case 1:
res->bandwidth = 7000000;
break;
case 2:
res->bandwidth = 6000000;
break;
case 3:
res->bandwidth = 5000000;
break;
case 4:
res->bandwidth = 10000000;
break;
case 5:
res->bandwidth = 1712000;
break;
default:
res->bandwidth = 0;
break;
}
data += 1;
switch ((*data >> 5) & 0x07) {
case 0:
res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_32;
break;
case 1:
res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_16;
break;
case 2:
res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_8;
break;
case 3:
res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_4;
break;
case 4:
res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_1_128;
break;
case 5:
res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_19_128;
break;
case 6:
res->guard_interval = GST_MPEGTS_GUARD_INTERVAL_19_256;
break;
default:
break;
}
switch ((*data >> 2) & 0x07) {
case 0:
res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_2K;
break;
case 1:
res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_8K;
break;
case 2:
res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_4K;
break;
case 3:
res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_1K;
break;
case 4:
res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_16K;
break;
case 5:
res->transmission_mode = GST_MPEGTS_TRANSMISSION_MODE_32K;
break;
default:
break;
}
res->other_frequency = (*data >> 1) & 0x01;
res->tfs = (*data) & 0x01;
data += 1;
len = descriptor->length - 6;
res->cells = g_ptr_array_new_with_free_func ((GDestroyNotify)
_gst_mpegts_t2_delivery_system_cell_free);
for (guint8 i = 0; i < len;) {
GstMpegTsT2DeliverySystemCell *cell;
cell = g_slice_new0 (GstMpegTsT2DeliverySystemCell);
g_ptr_array_add (res->cells, cell);
cell->cell_id = GST_READ_UINT16_BE (data);
data += 2;
i += 2;
cell->centre_frequencies = g_array_new (FALSE, FALSE, sizeof (guint32));
if (res->tfs == TRUE) {
freq_len = *data;
data += 1;
i += 1;
for (guint8 j = 0; j < freq_len;) {
tmp_freq = GST_READ_UINT32_BE (data) * 10;
g_array_append_val (cell->centre_frequencies, tmp_freq);
data += 4;
j += 4;
i += 4;
}
} else {
tmp_freq = GST_READ_UINT32_BE (data) * 10;
g_array_append_val (cell->centre_frequencies, tmp_freq);
data += 4;
i += 4;
}
sub_cell_len = (*data);
data += 1;
i += 1;
cell->sub_cells = g_ptr_array_new_with_free_func ((GDestroyNotify)
_gst_mpegts_t2_delivery_system_cell_extension_free);
for (guint8 k = 0; k < sub_cell_len;) {
GstMpegTsT2DeliverySystemCellExtension *cell_ext;
cell_ext = g_slice_new0 (GstMpegTsT2DeliverySystemCellExtension);
cell_ext->cell_id_extension = *data;
data += 1;
cell_ext->transposer_frequency = GST_READ_UINT32_BE (data) * 10;
data += 4;
i += 5;
k += 5;
}
}
}
return TRUE;
}

View file

@ -116,6 +116,42 @@ typedef enum {
GST_MTS_DESC_DVB_EXTENSION = 0x7F,
} GstMpegTsDVBDescriptorType;
/**
* GstMpegTsDVBExtendedDescriptorType:
*
* The type of #GstMpegTsDescriptor
*
* These values correspond to the registered extended descriptor
* type from the various DVB specifications.
*
* Consult the relevant specifications for more details.
*/
typedef enum {
/* 00 - 0x7F DVB extended tags ETSI EN 300 468
* (Specification for Service Information (SI) in DVB systems)
*/
GST_MTS_DESC_EXT_DVB_IMAGE_ICON = 0x00,
/* TS/TR 102 825 */
GST_MTS_DESC_EXT_DVB_CPCM_DELIVERY_SIGNALLING = 0x01,
GST_MTS_DESC_EXT_DVB_CP = 0x02,
GST_MTS_DESC_EXT_DVB_CP_IDENTIFIER = 0x03,
GST_MTS_DESC_EXT_DVB_T2_DELIVERY_SYSTEM = 0x04,
GST_MTS_DESC_EXT_DVB_SH_DELIVERY_SYSTEM = 0x05,
GST_MTS_DESC_EXT_DVB_SUPPLEMENTARY_AUDIO = 0x06,
GST_MTS_DESC_EXT_DVB_NETWORK_CHANGE_NOTIFY = 0x07,
GST_MTS_DESC_EXT_DVB_MESSAGE = 0x08,
GST_MTS_DESC_EXT_DVB_TARGET_REGION = 0x09,
GST_MTS_DESC_EXT_DVB_TARGET_REGION_NAME = 0x0A,
GST_MTS_DESC_EXT_DVB_SERVICE_RELOCATED = 0x0B,
GST_MTS_DESC_EXT_DVB_XAIT_PID = 0x0C,
GST_MTS_DESC_EXT_DVB_C2_DELIVERY_SYSTEM = 0x0D,
GST_MTS_DESC_EXT_DVB_DTS_HD_AUDIO_STREAM = 0x0E,
GST_MTS_DESC_EXT_DVB_DTS_NEUTRAL = 0x0F,
GST_MTS_DESC_EXT_DVB_VIDEO_DEPTH_RANGE = 0x10,
GST_MTS_DESC_EXT_DVB_T2MI = 0x11,
GST_MTS_DESC_EXT_DVB_URI_LINKAGE = 0x13,
} GstMpegTsDVBExtendedDescriptorType;
/* GST_MTS_DESC_DVB_CAROUSEL_IDENTIFIER (0x13) */
/* FIXME : Implement */
@ -508,6 +544,68 @@ gboolean gst_mpegts_descriptor_parse_dvb_data_broadcast (const GstMpegTsDescript
/* GST_MTS_DESC_DVB_AC3 (0x6a) */
/* FIXME : Implement */
/* GST_MTS_DESC_EXT_DVB_T2_DELIVERY_SYSTEM (0x7F && 0x04) */
typedef struct _GstMpegTsT2DeliverySystemCellExtension GstMpegTsT2DeliverySystemCellExtension;
/**
* GstMpegTsT2DeliverySystemCellExtension:
* @cell_id_extension: id of the sub cell
* @transposer_frequency: centre frequency of the sub cell in Hz
*/
struct _GstMpegTsT2DeliverySystemCellExtension
{
guint8 cell_id_extension;
guint32 transposer_frequency;
};
typedef struct _GstMpegTsT2DeliverySystemCell GstMpegTsT2DeliverySystemCell;
/**
* GstMpegTsT2DeliverySystemCell:
* @cell_id: id of the cell
* @centre_frequencies: centre frequencies in Hz
* @sub_cells: (element-type GstMpegTsT2DeliverySystemCellExtension):
*/
struct _GstMpegTsT2DeliverySystemCell
{
guint16 cell_id;
GArray *centre_frequencies;
GPtrArray *sub_cells;
};
typedef struct _GstMpegTsT2DeliverySystemDescriptor GstMpegTsT2DeliverySystemDescriptor;
/**
* GstMpegTsT2DeliverySystemDescriptor:
* @plp_id:
* @t2_system_id:
* @siso_miso:
* @bandwidth:
* @guard_interval:
* @transmission_mode:
* @other_frequency:
* @tfs:
* @cells: (element-type GstMpegTsT2DeliverySystemCell):
*
* describe DVB-T2 transmissions according to EN 302 755
*/
struct _GstMpegTsT2DeliverySystemDescriptor
{
guint8 plp_id;
guint16 t2_system_id;
/* FIXME: */
guint8 siso_miso;
guint32 bandwidth;
GstMpegTsTerrestrialGuardInterval guard_interval;
GstMpegTsTerrestrialTransmissionMode transmission_mode;
gboolean other_frequency;
gboolean tfs;
GPtrArray *cells;
};
gboolean gst_mpegts_descriptor_parse_dvb_t2_delivery_system (const GstMpegTsDescriptor
*descriptor, GstMpegTsT2DeliverySystemDescriptor * res);
G_END_DECLS
#endif /* GST_MPEGTS_DESCRIPTOR_H */

View file

@ -74,6 +74,32 @@ G_GNUC_INTERNAL gpointer __common_section_checks (GstMpegTsSection *section,
return retval; \
}
#define __common_desc_ext_check_base(desc, tagexttype, retval) \
if (G_UNLIKELY ((desc)->data == NULL)) { \
GST_WARNING ("Descriptor is empty (data field == NULL)"); \
return retval; \
} \
if (G_UNLIKELY ((desc)->tag != 0x7f) || \
((desc)->tag_extension != (tagexttype))) { \
GST_WARNING ("Wrong descriptor type (Got 0x%02x, expected 0x%02x)", \
(desc)->tag_extension, tagexttype); \
return retval; \
}
#define __common_desc_ext_checks(desc, tagexttype, minlen, retval) \
__common_desc_ext_check_base(desc, tagexttype, retval); \
if (G_UNLIKELY ((desc)->length < (minlen))) { \
GST_WARNING ("Descriptor too small (Got %d, expected at least %d)", \
(desc)->length, minlen); \
return retval; \
}
#define __common_desc_ext_checks_exact(desc, tagexttype, len, retval) \
__common_desc_ext_check_base(desc, tagexttype, retval); \
if (G_UNLIKELY ((desc)->length != (len))) { \
GST_WARNING ("Wrong descriptor size (Got %d, expected %d)", \
(desc)->length, len); \
return retval; \
}
G_END_DECLS
#endif /* _GST_MPEGTS_PRIVATE_H_ */