mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-12 10:25:33 +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 (guint8 tag, guint8 length);
|
||||||
G_GNUC_INTERNAL GstMpegTsDescriptor *_new_descriptor_with_extension (guint8 tag,
|
G_GNUC_INTERNAL GstMpegTsDescriptor *_new_descriptor_with_extension (guint8 tag,
|
||||||
guint8 tag_extension, guint8 length);
|
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 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);
|
typedef gpointer (*GstMpegTsParseFunc) (GstMpegTsSection *section);
|
||||||
G_GNUC_INTERNAL gpointer __common_desc_checks (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 *
|
GstMpegTsDescriptor *
|
||||||
_new_descriptor (guint8 tag, guint8 length)
|
_new_descriptor (guint8 tag, guint8 length)
|
||||||
{
|
{
|
||||||
|
|
|
@ -733,6 +733,44 @@ _gst_mpegts_section_init (guint16 pid, guint8 table_id)
|
||||||
return section;
|
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:
|
* gst_mpegts_section_new:
|
||||||
* @pid: the PID to which this section belongs
|
* @pid: the PID to which this section belongs
|
||||||
|
@ -808,3 +846,39 @@ short_packet:
|
||||||
return NULL;
|
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;
|
} GstMpegTsSectionTableID;
|
||||||
|
|
||||||
|
typedef gboolean (*GstMpegTsPacketizeFunc) (GstMpegTsSection *section);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstMpegTsSection:
|
* GstMpegTsSection:
|
||||||
* @section_type: The type of section
|
* @section_type: The type of section
|
||||||
|
@ -156,6 +158,7 @@ struct _GstMpegTsSection
|
||||||
* FIXME : Maybe make public later on when allowing creation of
|
* FIXME : Maybe make public later on when allowing creation of
|
||||||
* sections to that people can create private short sections ? */
|
* sections to that people can create private short sections ? */
|
||||||
gboolean short_section;
|
gboolean short_section;
|
||||||
|
GstMpegTsPacketizeFunc packetizer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -364,6 +367,8 @@ GstMpegTsSection *gst_mpegts_section_new (guint16 pid,
|
||||||
guint8 * data,
|
guint8 * data,
|
||||||
gsize data_size);
|
gsize data_size);
|
||||||
|
|
||||||
|
guint8 *gst_mpegts_section_packetize (GstMpegTsSection * section, gsize * output_size);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* GST_MPEGTS_SECTION_H */
|
#endif /* GST_MPEGTS_SECTION_H */
|
||||||
|
|
Loading…
Reference in a new issue