mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 17:20:36 +00:00
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:
parent
b1c5143b79
commit
930cde73a7
4 changed files with 108 additions and 0 deletions
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue