static int _parse_pes(PES_BUFFER *p, uint8_t *buf, unsigned len) { int result = 0; if (len < 6) { BD_DEBUG(DBG_DECODE, "invalid BDAV TS (PES header not in single TS packet)\n"); return -1; } if (buf[0] || buf[1] || buf[2] != 1) { BD_DEBUG(DBG_DECODE, "invalid PES header (00 00 01)"); return -1; } // Parse PES header unsigned pes_pid = buf[3]; unsigned pes_length = buf[4] << 8 | buf[5]; unsigned hdr_len = 6; if (pes_pid != 0xbf) { if (len < 9) { BD_DEBUG(DBG_DECODE, "invalid BDAV TS (PES header not in single TS packet)\n"); return -1; } unsigned pts_exists = buf[7] & 0x80; unsigned dts_exists = buf[7] & 0x40; hdr_len += buf[8] + 3; if (len < hdr_len) { BD_DEBUG(DBG_DECODE, "invalid BDAV TS (PES header not in single TS packet)\n"); return -1; } if (pts_exists) { p->pts = _parse_timestamp(buf + 9); } if (dts_exists) { p->dts = _parse_timestamp(buf + 14); } } result = pes_length + 6 - hdr_len; if (_realloc(p, BD_MAX(result, 0x100)) < 0) { return -1; } p->len = len - hdr_len; memcpy(p->buf, buf + hdr_len, p->len); return result; }
/* * _add_ts() * - add ts payload to buffer. * - parse PES header if pusi is set. * - return: * < 0 error (incorrect PES header) * = 0 PES packet continue * > 0 PES packet payload length from PES header */ static int _add_ts(PES_BUFFER *p, unsigned pusi, uint8_t *buf, unsigned len) { int result = 0; if (pusi) { // Parse PES header unsigned pes_length = buf[4] << 8 | buf[5]; unsigned pts_exists = buf[7] & 0x80; unsigned dts_exists = buf[7] & 0x40; unsigned hdr_len = buf[8] + 9; if (buf[0] || buf[1] || buf[2] != 1) { BD_DEBUG(DBG_DECODE, "invalid PES header (00 00 01)"); return -1; } if (len < hdr_len) { BD_DEBUG(DBG_DECODE, "invalid BDAV TS (PES header not in single TS packet)\n"); return -1; } if (pts_exists) { p->pts = _parse_timestamp(buf + 9); } if (dts_exists) { p->dts = _parse_timestamp(buf + 14); } buf += hdr_len; len -= hdr_len; result = pes_length + 6 - hdr_len; } // realloc if (p->size < p->len + len) { p->size *= 2; p->buf = realloc(p->buf, p->size); } // append memcpy(p->buf + p->len, buf, len); p->len += len; return result; }
/* * _add_ts() * - add ts payload to buffer. * - parse PES header if pusi is set. * - return: * < 0 error (incorrect PES header) * = 0 PES packet continue * > 0 PES packet payload length from PES header */ static int _add_ts(PES_BUFFER *p, unsigned pusi, uint8_t *buf, unsigned len) { int result = 0; if (pusi) { if (len < 6) { BD_DEBUG(DBG_DECODE, "invalid BDAV TS (PES header not in single TS packet)\n"); return -1; } if (buf[0] || buf[1] || buf[2] != 1) { BD_DEBUG(DBG_DECODE, "invalid PES header (00 00 01)"); return -1; } // Parse PES header unsigned pes_pid = buf[3]; unsigned pes_length = buf[4] << 8 | buf[5]; unsigned hdr_len = 6; if (pes_pid != 0xbf) { if (len < 9) { BD_DEBUG(DBG_DECODE, "invalid BDAV TS (PES header not in single TS packet)\n"); return -1; } unsigned pts_exists = buf[7] & 0x80; unsigned dts_exists = buf[7] & 0x40; hdr_len += buf[8] + 3; if (len < hdr_len) { BD_DEBUG(DBG_DECODE, "invalid BDAV TS (PES header not in single TS packet)\n"); return -1; } if (pts_exists) { p->pts = _parse_timestamp(buf + 9); } if (dts_exists) { p->dts = _parse_timestamp(buf + 14); } } buf += hdr_len; len -= hdr_len; result = pes_length + 6 - hdr_len; } // realloc if (p->size < p->len + len) { uint8_t *tmp; p->size *= 2; p->size = BD_MAX(p->size, BD_MAX(result, 0x100)); tmp = realloc(p->buf, p->size); if (!tmp) { BD_DEBUG(DBG_DECODE | DBG_CRIT, "out of memory\n"); p->size = 0; return -1; } p->buf = tmp; } // append memcpy(p->buf + p->len, buf, len); p->len += len; return result; }