psi_parse_pmt(mpegts_table_t *mt, mpegts_service_t *t,
const uint8_t *ptr, int len, int *_update);
+static inline uint16_t
+extract_2byte(const uint8_t *ptr)
+{
+ return (ptr[0] << 8) | ptr[1];
+}
+
+
+static inline uint16_t
+extract_4byte(const uint8_t *ptr)
+{
+ return (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3];
+}
+
+
+static inline uint16_t
+extract_tsid(const uint8_t *ptr)
+{
+ uint16_t r = (ptr[0] << 8) | ptr[1];
+ if (r == MPEGTS_TSID_NONE) r = 55555;
+ return r;
+}
+
+
+static inline uint16_t
+extract_onid(const uint8_t *ptr)
+{
+ uint16_t r = (ptr[0] << 8) | ptr[1];
+ if (r == MPEGTS_ONID_NONE) r = 55555;
+ return r;
+}
+
+
+static inline uint16_t
+extract_pid(const uint8_t *ptr)
+{
+ return ((ptr[0] & 0x1f) << 8) | ptr[1];
+}
+
+
+static inline uint16_t
+extract_svcid(const uint8_t *ptr)
+{
+ return (ptr[0] << 8) | ptr[1];
+}
+
+
static inline int
mpegts_mux_alive(mpegts_mux_t *mm)
{
if (len < 11) return NULL;
/* Extract data */
- frequency = ((ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3]);
+ frequency = extract_4byte(ptr);
if (frequency < 1000000 || frequency > 200000000) {
tvhtrace(mt->mt_subsys, "%s: dvb-t frequency error (%d)", mt->mt_name, frequency);
return NULL;
int i;
for (i = 0; i < len; i += 3) {
- sid = (ptr[i] << 8) | ptr[i+1];
+ sid = extract_svcid(ptr + i);
stype = ptr[i+2];
tvhdebug(mt->mt_subsys, "%s: service %04X (%d) type %02X (%d)", mt->mt_name, sid, sid, stype, stype);
if (mm) {
return 0;
while(len >= 4) {
- sid = (ptr[0] << 8) | ptr[1];
- lcn = ((ptr[2] & 3) << 8) | ptr[3];
+ sid = extract_svcid(ptr);
+ lcn = extract_2byte(ptr + 2) & 0x3ff;
tvhdebug(mt->mt_subsys, "%s: sid %d lcn %d", mt->mt_name, sid, lcn);
if (sid && lcn && mm) {
s = mpegts_service_find(mm, sid, 0, 0, &save);
int len2;
while (len > 4) {
- sid = (ptr[0] << 8) | ptr[1];
- unk = (ptr[2] << 8) | ptr[3];
+ sid = extract_svcid(ptr);
+ unk = extract_2byte(ptr + 2);
len2 = ptr[4];
ptr += 5;
len -= 5;
break;
tvhtrace(mt->mt_subsys, "%s: sid %04X (%d) uknown %04X (%d)", mt->mt_name, sid, sid, unk, unk);
while (len2 > 3) {
- lcn = ((ptr[0] & 0x0f) << 8) | ptr[1];
- regionid = (ptr[2] << 8) | ptr[3];
+ lcn = extract_2byte(ptr) & 0xfff;
+ regionid = extract_2byte(ptr + 2);
tvhtrace(mt->mt_subsys, "%s: lcn %d region %d", mt->mt_name, lcn, regionid);
TAILQ_FOREACH(fs, &bi->fservices, link)
return;
while (len > 5) {
- id = (ptr[0] << 8) | ptr[1];
+ id = extract_2byte(ptr);
/* language: ptr[2-4]: 'eng' */
if ((r = dvb_get_string_with_len(name, sizeof(name), ptr + 5, len - 5, NULL, NULL)) < 0)
break;
mt->mt_name, regionid, regionid, ptr[0], ptr[0]);
while (len > 8) {
- sid = (ptr[0] << 8) | ptr[1];
- lcn = (ptr[5] << 8) | ptr[6];
+ sid = extract_svcid(ptr);
+ lcn = extract_2byte(ptr + 5);
stype = ptr[2];
- unk = (ptr[3] << 8) | ptr[4];
+ unk = extract_2byte(ptr + 3);
ptr += 9;
len -= 9;
/* Begin */
if (tableid != 0) return -1;
- tsid = (ptr[0] << 8) | ptr[1];
+ tsid = extract_tsid(ptr);
r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len,
tableid, tsid, 5, &st, §, &last, &ver);
if (r != 1) return r;
ptr += 5;
len -= 5;
while(len >= 4) {
- sid = ptr[0] << 8 | ptr[1];
- pid = (ptr[2] & 0x1f) << 8 | ptr[3];
+ sid = extract_svcid(ptr);
+ pid = extract_pid(ptr + 2);
/* NIT PID */
if (sid == 0) {
switch(dtag) {
case DVB_DESC_CA:
if (len >= 4 && dlen >= 4) {
- caid = ( ptr[0] << 8) | ptr[1];
- pid = ((ptr[2] & 0x1f) << 8) | ptr[3];
+ caid = extract_2byte(ptr);
+ pid = extract_pid(ptr + 2);
tvhdebug(mt->mt_subsys, "%s: caid %04X (%d) pid %04X (%d)",
mt->mt_name, (uint16_t)caid, (uint16_t)caid, pid, pid);
}
mpegts_psi_table_state_t *st = NULL;
/* Start */
- sid = ptr[0] << 8 | ptr[1];
+ sid = extract_svcid(ptr);
r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len,
tableid, sid, 9, &st, §, &last, &ver);
if (r != 1) return r;
break;
case DVB_DESC_PRIVATE_DATA:
if (dlen == 4) {
- priv = (dptr[0] << 24) | (dptr[1] << 16) | (dptr[2] << 8) | dptr[3];
+ priv = extract_4byte(dptr);
tvhtrace(mt->mt_subsys, "%s: private %08X", mt->mt_name, priv);
}
break;
dvb_bat_id_t *bi = NULL;
/* Net/Bat ID */
- nbid = (ptr[0] << 8) | ptr[1];
+ nbid = extract_2byte(ptr);
/* Begin */
if (tableid == DVB_FASTSCAN_NIT_BASE) {
break;
case DVB_DESC_PRIVATE_DATA:
if (tableid == 0x4A && dlen == 4) {
- priv = (dptr[0] << 24) | (dptr[1] << 16) | (dptr[2] << 8) | dptr[3];
+ priv = extract_4byte(dptr);
tvhtrace(mt->mt_subsys, "%s: private %08X", mt->mt_name, priv);
}
break;
/* Transport length */
DVB_LOOP_FOREACH(mt, ptr, len, 0, lptr, llen, 6) {
- tsid = (lptr[0] << 8) | lptr[1];
- onid = (lptr[2] << 8) | lptr[3];
+ tsid = extract_tsid(lptr);
+ onid = extract_onid(lptr + 2);
#if ENABLE_MPEGTS_DVB
/* Create new muxes (auto-discovery) */
while(len >= 5) {
mpegts_service_t *s;
int master = 0, save = 0, save2 = 0;
- uint16_t service_id = ptr[0] << 8 | ptr[1];
+ uint16_t service_id = extract_svcid(ptr);
int free_ca_mode = (ptr[3] >> 4) & 0x1;
int stype = 0;
char sprov[256], sname[256], sauth[256];
break;
case DVB_DESC_PRIVATE_DATA:
if (dlen == 4) {
- priv = (dptr[0] << 24) | (dptr[1] << 16) | (dptr[2] << 8) | dptr[3];
+ priv = extract_4byte(dptr);
tvhtrace(mt->mt_subsys, "%s: private %08X", mt->mt_name, priv);
}
break;
mpegts_psi_table_state_t *st = NULL;
/* Begin */
- tsid = ptr[0] << 8 | ptr[1];
- onid = ptr[5] << 8 | ptr[6];
+ tsid = extract_onid(ptr);
+ onid = extract_tsid(ptr + 5);
extraid = ((int)onid) << 16 | tsid;
if (tableid != 0x42 && tableid != 0x46) return -1;
r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len,
if (tableid != 0xc8 && tableid != 0xc9) return -1;
/* Extra ID */
- tsid = ptr[0] << 8 | ptr[1];
+ tsid = extract_tsid(ptr);
extraid = tsid;
/* Begin */
atsc_utf16_to_utf8(ptr, 7, chname, sizeof(chname));
maj = (ptr[14] & 0xF) << 6 | ptr[15] >> 2;
min = (ptr[15] & 0x3) << 2 | ptr[16];
- tsid = (ptr[22]) << 8 | ptr[23];
- sid = (ptr[24]) << 8 | ptr[25];
+ tsid = extract_tsid(ptr + 22);
+ sid = extract_svcid(ptr + 24);
type = ptr[27] & 0x3f;
srcid = (ptr[28]) << 8 | ptr[29];
tvhdebug(mt->mt_subsys, "%s: tsid %04X (%d)", mt->mt_name, tsid, tsid);
if (tableid != DVB_ATSC_STT_BASE) return -1;
/* Extra ID */
- extraid = ptr[0] << 8 | ptr[1];
+ extraid = extract_2byte(ptr);
/* Begin */
r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len, tableid, extraid, 7,
if (r != 1) return r;
/* Parse fields */
- systemtime = ptr[6] << 24 | ptr[7] << 16 | ptr[8] << 8 | ptr[9];
+ systemtime = extract_4byte(ptr + 6);
gps_utc_offset = ptr[10];
is_dst = ptr[11] >> 7;
mpegts_service_t *s;
int stype = 0, save = 0;
- onid = (ptr[0] << 8) | ptr[1];
- tsid = (ptr[2] << 8) | ptr[3];
- service_id = (ptr[4] << 8) | ptr[5];
+ onid = extract_onid(ptr);
+ tsid = extract_tsid(ptr + 2);
+ service_id = extract_svcid(ptr + 4);
/* (ptr[6] << 8) | ptr[7] - video pid */
/* (ptr[7] << 8) | ptr[8] - audio pid */
/* (ptr[9] << 8) | ptr[10] - video ecm pid */
mpegts_psi_table_state_t *st = NULL;
/* Fastscan ID */
- nbid = (ptr[0] << 8) | ptr[1];
+ nbid = extract_2byte(ptr);
/* Begin */
if (tableid != 0xBD)
int r = 0;
int i;
uint32_t provid = 0;
- uint16_t caid = (buffer[0] << 8) | buffer[1];
- uint16_t pid = ((buffer[2]&0x1F) << 8) | buffer[3];
+ uint16_t caid = extract_2byte(buffer);
+ uint16_t pid = extract_pid(buffer + 2);
switch (caid & 0xFF00) {
case 0x0100: // SECA/Mediaguard
- provid = (buffer[4] << 8) | buffer[5];
+ provid = extract_2byte(buffer + 4);
//Add extra providers, if any
for (i = 17; i < size; i += 15){
- uint16_t xpid = ((buffer[i]&0x1F) << 8) | buffer[i + 1];
- uint16_t xprovid = (buffer[i + 2] << 8) | buffer[i + 3];
+ uint16_t xpid = extract_pid(buffer + i);
+ uint16_t xprovid = extract_2byte(buffer + i + 2);
r |= psi_desc_add_ca(mt, t, caid, xprovid, xpid);
}
break;
case 0x0500:// Viaccess
- for (i = 4; i < size;) {
+ for (i = 4; i + 5 <= size;) {
uint8_t nano = buffer[i++];
uint8_t nanolen = buffer[i++];
lock_assert(&t->s_stream_mutex);
version = ptr[2] >> 1 & 0x1f;
- pcr_pid = (ptr[5] & 0x1f) << 8 | ptr[6];
+ pcr_pid = extract_pid(ptr + 5);
dllen = (ptr[7] & 0xf) << 8 | ptr[8];
if(t->s_pcr_pid != pcr_pid) {
while(len >= 5) {
estype = ptr[0];
- pid = (ptr[1] & 0x1f) << 8 | ptr[2];
+ pid = extract_pid(ptr + 1);
dllen = (ptr[3] & 0xf) << 8 | ptr[4];
tvhdebug(mt->mt_subsys, "%s: pid %04X estype %d", mt->mt_name, pid, estype);
tvhlog_hexdump(mt->mt_subsys, ptr, 5);
break;
lang = lang_code_get2((const char*)ptr, 3);
- composition_id = ptr[4] << 8 | ptr[5];
- ancillary_id = ptr[6] << 8 | ptr[7];
+ composition_id = extract_2byte(ptr + 4);
+ ancillary_id = extract_2byte(ptr + 6);
hts_stream_type = SCT_DVBSUB;
break;