mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 00:06:36 +00:00
mpegtsparse: parse TDT table in mpegts.
Some tables in MPEG-TS do not have a crc in the spec, so also mpegtsparse is not calculating crc for sections with table_id 0x70 - 0x72 because they do not have a CRC in the spec. See EN300468. Parse Time and Date table and output bus message.
This commit is contained in:
parent
ea0fb9a3ee
commit
d2bd939899
3 changed files with 97 additions and 4 deletions
|
@ -1940,6 +1940,75 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
GstStructure *
|
||||
mpegts_packetizer_parse_tdt (MpegTSPacketizer * packetizer,
|
||||
MpegTSPacketizerSection * section)
|
||||
{
|
||||
GstStructure *tdt = NULL;
|
||||
guint16 mjd;
|
||||
guint year, month, day, hour, minute, second;
|
||||
guint8 *data, *end, *utc_ptr;
|
||||
|
||||
GST_DEBUG ("TDT");
|
||||
/* length always 8 */
|
||||
if (G_UNLIKELY (GST_BUFFER_SIZE (section->buffer) != 8)) {
|
||||
GST_WARNING ("PID %d invalid TDT size %d",
|
||||
section->pid, section->section_length);
|
||||
goto error;
|
||||
}
|
||||
|
||||
data = GST_BUFFER_DATA (section->buffer);
|
||||
end = data + GST_BUFFER_SIZE (section->buffer);
|
||||
|
||||
section->table_id = *data++;
|
||||
section->section_length = GST_READ_UINT16_BE (data) & 0x0FFF;
|
||||
data += 2;
|
||||
|
||||
if (data + section->section_length != end) {
|
||||
GST_WARNING ("PID %d invalid TDT section length %d expected %d",
|
||||
section->pid, section->section_length, (gint) (end - data));
|
||||
goto error;
|
||||
}
|
||||
|
||||
mjd = GST_READ_UINT16_BE (data);
|
||||
data += 2;
|
||||
utc_ptr = data;
|
||||
if (mjd == G_MAXUINT16) {
|
||||
year = 1900;
|
||||
month = day = hour = minute = second = 0;
|
||||
} else {
|
||||
/* See EN 300 468 Annex C */
|
||||
year = (guint32) (((mjd - 15078.2) / 365.25));
|
||||
month = (guint8) ((mjd - 14956.1 - (guint) (year * 365.25)) / 30.6001);
|
||||
day = mjd - 14956 - (guint) (year * 365.25) - (guint) (month * 30.6001);
|
||||
if (month == 14 || month == 15) {
|
||||
year++;
|
||||
month = month - 1 - 12;
|
||||
} else {
|
||||
month--;
|
||||
}
|
||||
year += 1900;
|
||||
hour = ((utc_ptr[0] & 0xF0) >> 4) * 10 + (utc_ptr[0] & 0x0F);
|
||||
minute = ((utc_ptr[1] & 0xF0) >> 4) * 10 + (utc_ptr[1] & 0x0F);
|
||||
second = ((utc_ptr[2] & 0xF0) >> 4) * 10 + (utc_ptr[2] & 0x0F);
|
||||
}
|
||||
tdt = gst_structure_new ("tdt",
|
||||
"year", G_TYPE_UINT, year,
|
||||
"month", G_TYPE_UINT, month,
|
||||
"day", G_TYPE_UINT, day,
|
||||
"hour", G_TYPE_UINT, hour,
|
||||
"minute", G_TYPE_UINT, minute, "second", G_TYPE_UINT, second, NULL);
|
||||
|
||||
return tdt;
|
||||
|
||||
error:
|
||||
if (tdt)
|
||||
gst_structure_free (tdt);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mpegts_packetizer_clear (MpegTSPacketizer * packetizer)
|
||||
{
|
||||
|
@ -2199,6 +2268,7 @@ mpegts_packetizer_push_section (MpegTSPacketizer * packetizer,
|
|||
/* flush stuffing bytes */
|
||||
mpegts_packetizer_clear_section (packetizer, stream);
|
||||
} else {
|
||||
GST_DEBUG ("section not complete");
|
||||
/* section not complete yet */
|
||||
section->complete = FALSE;
|
||||
}
|
||||
|
@ -2209,6 +2279,7 @@ mpegts_packetizer_push_section (MpegTSPacketizer * packetizer,
|
|||
|
||||
out:
|
||||
packet->data = data;
|
||||
GST_DEBUG ("result: %d complete: %d", res, section->complete);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -148,6 +148,8 @@ GstStructure *mpegts_packetizer_parse_sdt (MpegTSPacketizer *packetizer,
|
|||
MpegTSPacketizerSection *section);
|
||||
GstStructure *mpegts_packetizer_parse_eit (MpegTSPacketizer *packetizer,
|
||||
MpegTSPacketizerSection *section);
|
||||
GstStructure *mpegts_packetizer_parse_tdt (MpegTSPacketizer *packetizer,
|
||||
MpegTSPacketizerSection *section);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -1095,16 +1095,28 @@ mpegts_parse_apply_eit (MpegTSParse * parse,
|
|||
gst_structure_copy (eit_info)));
|
||||
}
|
||||
|
||||
static void
|
||||
mpegts_parse_apply_tdt (MpegTSParse * parse,
|
||||
guint16 tdt_pid, GstStructure * tdt_info)
|
||||
{
|
||||
gst_element_post_message (GST_ELEMENT_CAST (parse),
|
||||
gst_message_new_element (GST_OBJECT (parse),
|
||||
gst_structure_copy (tdt_info)));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mpegts_parse_handle_psi (MpegTSParse * parse, MpegTSPacketizerSection * section)
|
||||
{
|
||||
gboolean res = TRUE;
|
||||
GstStructure *structure = NULL;
|
||||
|
||||
if (G_UNLIKELY (mpegts_parse_calc_crc32 (GST_BUFFER_DATA (section->buffer),
|
||||
GST_BUFFER_SIZE (section->buffer)) != 0)) {
|
||||
GST_WARNING_OBJECT (parse, "bad crc in psi pid 0x%x", section->pid);
|
||||
return FALSE;
|
||||
/* table ids 0x70 - 0x72 do not have a crc */
|
||||
if (G_LIKELY (section->table_id < 0x70 || section->table_id > 0x72)) {
|
||||
if (G_UNLIKELY (mpegts_parse_calc_crc32 (GST_BUFFER_DATA (section->buffer),
|
||||
GST_BUFFER_SIZE (section->buffer)) != 0)) {
|
||||
GST_WARNING_OBJECT (parse, "bad crc in psi pid 0x%x", section->pid);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
switch (section->table_id) {
|
||||
|
@ -1186,6 +1198,14 @@ mpegts_parse_handle_psi (MpegTSParse * parse, MpegTSPacketizerSection * section)
|
|||
else
|
||||
res = FALSE;
|
||||
break;
|
||||
case 0x70:
|
||||
/* TDT (Time and Date table) */
|
||||
structure = mpegts_packetizer_parse_tdt (parse->packetizer, section);
|
||||
if (G_LIKELY (structure))
|
||||
mpegts_parse_apply_tdt (parse, section->pid, structure);
|
||||
else
|
||||
res = FALSE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue