mpegts: Add functions to packetize section

Sections needs to be packetized for use in i.e. mpegtsmux.
These functions handles the generic common parts of a GstMpegTsSection
This commit is contained in:
Jesper Larsen 2013-10-28 14:44:13 +01:00
parent b1c5143b79
commit 930cde73a7
4 changed files with 108 additions and 0 deletions

View file

@ -37,7 +37,10 @@ G_GNUC_INTERNAL void _free_descriptor (GstMpegTsDescriptor *descriptor);
G_GNUC_INTERNAL GstMpegTsDescriptor *_new_descriptor (guint8 tag, guint8 length);
G_GNUC_INTERNAL GstMpegTsDescriptor *_new_descriptor_with_extension (guint8 tag,
guint8 tag_extension, guint8 length);
G_GNUC_INTERNAL void _packetize_descriptor_array (GPtrArray * array,
guint8 ** out_data);
G_GNUC_INTERNAL GstMpegTsSection *_gst_mpegts_section_init (guint16 pid, guint8 table_id);
G_GNUC_INTERNAL void _packetize_common_section (GstMpegTsSection * section, gsize length);
typedef gpointer (*GstMpegTsParseFunc) (GstMpegTsSection *section);
G_GNUC_INTERNAL gpointer __common_desc_checks (GstMpegTsSection *section,

View file

@ -627,6 +627,32 @@ failed:
}
}
void
_packetize_descriptor_array (GPtrArray * array, guint8 ** out_data)
{
guint i;
guint8 header_size;
GstMpegTsDescriptor *descriptor;
g_return_if_fail (out_data != NULL);
g_return_if_fail (*out_data != NULL);
if (array == NULL)
return;
for (i = 0; i < array->len; i++) {
descriptor = g_ptr_array_index (array, i);
if (descriptor->tag == GST_MTS_DESC_DVB_EXTENSION)
header_size = 3;
else
header_size = 2;
memcpy (*out_data, descriptor->data, descriptor->length + header_size);
*out_data += descriptor->length + header_size;
}
}
GstMpegTsDescriptor *
_new_descriptor (guint8 tag, guint8 length)
{

View file

@ -733,6 +733,44 @@ _gst_mpegts_section_init (guint16 pid, guint8 table_id)
return section;
}
void
_packetize_common_section (GstMpegTsSection * section, gsize length)
{
guint8 *data;
section->section_length = length;
data = section->data = g_malloc (length);
/* table_id - 8 bit uimsbf */
*data++ = section->table_id;
/* section_syntax_indicator - 1 bit
reserved - 3 bit
section_length - 12 bit uimsbf */
GST_WRITE_UINT16_BE (data, (section->section_length - 3) | 0x7000);
if (!section->short_section)
*data |= 0x80;
data += 2;
/* subtable_extension - 16 bit uimsbf */
GST_WRITE_UINT16_BE (data, section->subtable_extension);
data += 2;
/* reserved - 2 bit
version_number - 5 bit uimsbf
current_next_indicator - 1 bit */
*data++ =
0xC0 | ((section->version_number & 0x1F) << 1) | (section->
current_next_indicator & 0x01);
/* section_number - 8 bit uimsbf */
*data++ = section->section_number;
/* last_section_number - 8 bit uimsbf */
*data++ = section->last_section_number;
}
/**
* gst_mpegts_section_new:
* @pid: the PID to which this section belongs
@ -808,3 +846,39 @@ short_packet:
return NULL;
}
}
/**
* gst_mpegts_section_packetize:
* @section: (transfer none): the #GstMpegTsSection that holds the data
* @output_size: (out): #gsize to hold the size of the data
*
* If the data in @section has aldready been packetized, the data pointer is returned
* immediately. Otherwise, the data field is allocated and populated.
*
* Returns: (transfer none): pointer to section data, or %NULL on fail
*/
guint8 *
gst_mpegts_section_packetize (GstMpegTsSection * section, gsize * output_size)
{
guint8 *crc;
g_return_val_if_fail (section != NULL, NULL);
g_return_val_if_fail (output_size != NULL, NULL);
g_return_val_if_fail (section->packetizer != NULL, NULL);
/* Section data has already been packetized */
if (section->data)
return section->data;
if (!section->packetizer (section))
return NULL;
if (!section->short_section) {
/* Update the CRC in the last 4 bytes of the section */
crc = section->data + section->section_length - 4;
GST_WRITE_UINT32_BE (crc, _calc_crc32 (section->data, crc - section->data));
}
*output_size = section->section_length;
return section->data;
}

View file

@ -104,6 +104,8 @@ typedef enum {
} GstMpegTsSectionTableID;
typedef gboolean (*GstMpegTsPacketizeFunc) (GstMpegTsSection *section);
/**
* GstMpegTsSection:
* @section_type: The type of section
@ -156,6 +158,7 @@ struct _GstMpegTsSection
* FIXME : Maybe make public later on when allowing creation of
* sections to that people can create private short sections ? */
gboolean short_section;
GstMpegTsPacketizeFunc packetizer;
};
@ -364,6 +367,8 @@ GstMpegTsSection *gst_mpegts_section_new (guint16 pid,
guint8 * data,
gsize data_size);
guint8 *gst_mpegts_section_packetize (GstMpegTsSection * section, gsize * output_size);
G_END_DECLS
#endif /* GST_MPEGTS_SECTION_H */