diff options
author | Jesper Larsen <jesper.larsen@ixonos.com> | 2013-10-28 14:44:13 +0100 |
---|---|---|
committer | Jesper Larsen <jesper.larsen@ixonos.com> | 2014-02-06 14:00:28 +0100 |
commit | 930cde73a7313d29335d93637e8609b612cf9df4 (patch) | |
tree | c9a555e54240001b99b58523b24a35a36c996d7e | |
parent | b1c5143b79be4285584a3905eeb8b7e0d42ddce9 (diff) |
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
-rw-r--r-- | gst-libs/gst/mpegts/gstmpegts-private.h | 3 | ||||
-rw-r--r-- | gst-libs/gst/mpegts/gstmpegtsdescriptor.c | 26 | ||||
-rw-r--r-- | gst-libs/gst/mpegts/gstmpegtssection.c | 74 | ||||
-rw-r--r-- | gst-libs/gst/mpegts/gstmpegtssection.h | 5 |
4 files changed, 108 insertions, 0 deletions
diff --git a/gst-libs/gst/mpegts/gstmpegts-private.h b/gst-libs/gst/mpegts/gstmpegts-private.h index 7607b813e..7387014b0 100644 --- a/gst-libs/gst/mpegts/gstmpegts-private.h +++ b/gst-libs/gst/mpegts/gstmpegts-private.h @@ -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, diff --git a/gst-libs/gst/mpegts/gstmpegtsdescriptor.c b/gst-libs/gst/mpegts/gstmpegtsdescriptor.c index a49adfdc8..35a8f89fd 100644 --- a/gst-libs/gst/mpegts/gstmpegtsdescriptor.c +++ b/gst-libs/gst/mpegts/gstmpegtsdescriptor.c @@ -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) { diff --git a/gst-libs/gst/mpegts/gstmpegtssection.c b/gst-libs/gst/mpegts/gstmpegtssection.c index 6a2bed506..054a07737 100644 --- a/gst-libs/gst/mpegts/gstmpegtssection.c +++ b/gst-libs/gst/mpegts/gstmpegtssection.c @@ -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; +} diff --git a/gst-libs/gst/mpegts/gstmpegtssection.h b/gst-libs/gst/mpegts/gstmpegtssection.h index fd4db98d1..077a074ab 100644 --- a/gst-libs/gst/mpegts/gstmpegtssection.h +++ b/gst-libs/gst/mpegts/gstmpegtssection.h @@ -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 */ |