int graphics_processor_decode_ts(GRAPHICS_PROCESSOR *p, PG_DISPLAY_SET **s, uint16_t pid, uint8_t *unit, unsigned num_units, int64_t stc) { unsigned ii; if (pid != p->pid) { m2ts_demux_free(&p->demux); pes_buffer_free(&p->queue); } if (!p->demux) { p->demux = m2ts_demux_init(pid); p->pid = pid; } for (ii = 0; ii < num_units; ii++) { pes_buffer_append(&p->queue, m2ts_demux(p->demux, unit)); unit += 6144; } if (p->queue) { return graphics_processor_decode_pes(s, &p->queue, stc); } return 0; }
void m2ts_demux_free(M2TS_DEMUX **p) { if (p && *p) { pes_buffer_free(&(*p)->buf); X_FREE(*p); } }
void m2ts_demux_reset(M2TS_DEMUX *p) { if (p) { PES_BUFFER *buf = _flush(p); pes_buffer_free(&buf); } }
void graphics_processor_free(GRAPHICS_PROCESSOR **p) { if (p && *p) { m2ts_demux_free(&(*p)->demux); pes_buffer_free(&(*p)->queue); X_FREE(*p); } }
PES_BUFFER *m2ts_demux(M2TS_DEMUX *p, uint8_t *buf) { uint8_t *end = buf + 6144; PES_BUFFER *result = NULL; if (!buf) { // flush result = p->buf; p->buf = NULL; return result; } for (; buf < end; buf += 192) { unsigned tp_error = buf[4+1] & 0x80; unsigned pusi = buf[4+1] & 0x40; uint16_t pid = ((buf[4+1] & 0x1f) << 8) | buf[4+2]; unsigned payload_exists = buf[4+3] & 0x10; int payload_offset = (buf[4+3] & 0x20) ? buf[4+4] + 5 : 4; if (buf[4] != 0x47) { BD_DEBUG(DBG_DECODE, "missing sync byte. scrambled data ?\n"); return NULL; } if (pid != p->pid) { M2TS_TRACE("skipping packet (pid %d)\n", pid); continue; } if (tp_error) { BD_DEBUG(DBG_DECODE, "skipping packet (transport error)\n"); continue; } if (!payload_exists) { M2TS_TRACE("skipping packet (no payload)\n"); continue; } if (payload_offset >= 188) { BD_DEBUG(DBG_DECODE, "skipping packet (invalid payload start address)\n"); continue; } if (pusi) { if (p->buf) { BD_DEBUG(DBG_DECODE, "PES length mismatch: have %d, expected %d\n", p->buf->len, p->pes_length); pes_buffer_free(&p->buf); } p->buf = pes_buffer_alloc(0xffff); } if (!p->buf) { BD_DEBUG(DBG_DECODE, "skipping packet (no pusi seen)\n"); continue; } int r = _add_ts(p->buf, pusi, buf + 4 + payload_offset, 188 - payload_offset); if (r) { if (r < 0) { BD_DEBUG(DBG_DECODE, "skipping block (PES header error)\n"); pes_buffer_free(&p->buf); continue; } p->pes_length = r; } if (p->buf->len == p->pes_length) { M2TS_TRACE("PES complete (%d bytes)\n", p->pes_length); pes_buffer_append(&result, p->buf); p->buf = NULL; } } return result; }