int pes_read(pes_packet_t *pes, uint8_t *buf, size_t len) { if (buf == NULL || pes == NULL) return 0; bs_t b; bs_init(&b, buf, len); int header_bytes = pes_read_header(&pes->header, &b); if (header_bytes > 0) { pes->payload.len = len - header_bytes; pes->payload.bytes = (uint8_t *) realloc(pes->payload.bytes, pes->payload.len); bs_read_bytes(&b, pes->payload.bytes, pes->payload.len); } return bs_pos(&b); }
static size_t pes_packet_read(struct ps_demuxer_t *ps, const uint8_t* data, size_t bytes) { size_t i = 0; size_t j = 0; size_t pes_packet_length; struct pes_t* pes; // MPEG_program_end_code = 0x000000B9 for (i = 0; i + 5 < bytes && 0x00 == data[i] && 0x00 == data[i + 1] && 0x01 == data[i + 2] && PES_SID_END != data[i + 3] && PES_SID_START != data[i + 3]; i += pes_packet_length + 6) { pes_packet_length = (data[i + 4] << 8) | data[i + 5]; assert(i + 6 + pes_packet_length <= bytes); if (i + 6 + pes_packet_length > bytes) return 0; // stream id switch (data[i+3]) { case PES_SID_PSM: j = psm_read(&ps->psm, data + i, bytes - i); assert(j == pes_packet_length + 6); break; case PES_SID_PSD: j = psd_read(&ps->psd, data + i, bytes - i); assert(j == pes_packet_length + 6); break; case PES_SID_PRIVATE_2: case PES_SID_ECM: case PES_SID_EMM: case PES_SID_DSMCC: case PES_SID_H222_E: // stream data break; case PES_SID_PADDING: // padding break; // ffmpeg mpeg.c mpegps_read_pes_header //case 0x1c0: //case 0x1df: //case 0x1e0: //case 0x1ef: //case 0x1bd: //case 0x01fd: // break; default: pes = psm_fetch(&ps->psm, data[i+3]); if (NULL == pes) continue; assert(PES_SID_END != data[i + 3]); if (ps->pkhd.mpeg2) j = pes_read_header(pes, data + i, bytes - i); else j = pes_read_mpeg1_header(pes, data + i, bytes - i); if (0 == j) continue; pes_packet(&pes->pkt, pes, data + i + j, pes_packet_length + 6 - j, ps_demuxer_onpes, ps); } } return i; }