mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-03 05:59:10 +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;
|
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
|
void
|
||||||
mpegts_packetizer_clear (MpegTSPacketizer * packetizer)
|
mpegts_packetizer_clear (MpegTSPacketizer * packetizer)
|
||||||
{
|
{
|
||||||
|
@ -2199,6 +2268,7 @@ mpegts_packetizer_push_section (MpegTSPacketizer * packetizer,
|
||||||
/* flush stuffing bytes */
|
/* flush stuffing bytes */
|
||||||
mpegts_packetizer_clear_section (packetizer, stream);
|
mpegts_packetizer_clear_section (packetizer, stream);
|
||||||
} else {
|
} else {
|
||||||
|
GST_DEBUG ("section not complete");
|
||||||
/* section not complete yet */
|
/* section not complete yet */
|
||||||
section->complete = FALSE;
|
section->complete = FALSE;
|
||||||
}
|
}
|
||||||
|
@ -2209,6 +2279,7 @@ mpegts_packetizer_push_section (MpegTSPacketizer * packetizer,
|
||||||
|
|
||||||
out:
|
out:
|
||||||
packet->data = data;
|
packet->data = data;
|
||||||
|
GST_DEBUG ("result: %d complete: %d", res, section->complete);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,6 +148,8 @@ GstStructure *mpegts_packetizer_parse_sdt (MpegTSPacketizer *packetizer,
|
||||||
MpegTSPacketizerSection *section);
|
MpegTSPacketizerSection *section);
|
||||||
GstStructure *mpegts_packetizer_parse_eit (MpegTSPacketizer *packetizer,
|
GstStructure *mpegts_packetizer_parse_eit (MpegTSPacketizer *packetizer,
|
||||||
MpegTSPacketizerSection *section);
|
MpegTSPacketizerSection *section);
|
||||||
|
GstStructure *mpegts_packetizer_parse_tdt (MpegTSPacketizer *packetizer,
|
||||||
|
MpegTSPacketizerSection *section);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -1095,17 +1095,29 @@ mpegts_parse_apply_eit (MpegTSParse * parse,
|
||||||
gst_structure_copy (eit_info)));
|
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
|
static gboolean
|
||||||
mpegts_parse_handle_psi (MpegTSParse * parse, MpegTSPacketizerSection * section)
|
mpegts_parse_handle_psi (MpegTSParse * parse, MpegTSPacketizerSection * section)
|
||||||
{
|
{
|
||||||
gboolean res = TRUE;
|
gboolean res = TRUE;
|
||||||
GstStructure *structure = NULL;
|
GstStructure *structure = NULL;
|
||||||
|
|
||||||
|
/* 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),
|
if (G_UNLIKELY (mpegts_parse_calc_crc32 (GST_BUFFER_DATA (section->buffer),
|
||||||
GST_BUFFER_SIZE (section->buffer)) != 0)) {
|
GST_BUFFER_SIZE (section->buffer)) != 0)) {
|
||||||
GST_WARNING_OBJECT (parse, "bad crc in psi pid 0x%x", section->pid);
|
GST_WARNING_OBJECT (parse, "bad crc in psi pid 0x%x", section->pid);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (section->table_id) {
|
switch (section->table_id) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
|
@ -1186,6 +1198,14 @@ mpegts_parse_handle_psi (MpegTSParse * parse, MpegTSPacketizerSection * section)
|
||||||
else
|
else
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue