enum MpegTSState {
MPEGTS_HEADER = 0,
+ MPEGTS_PESHEADER,
MPEGTS_PESHEADER_FILL,
MPEGTS_PAYLOAD,
MPEGTS_SKIP,
};
/* enough for PES header + length */
-#define PES_START_SIZE 9
+#define PES_START_SIZE 6
+#define PES_HEADER_SIZE 9
#define MAX_PES_HEADER_SIZE (9 + 255)
struct PESContext {
{ 0x7a, CODEC_TYPE_AUDIO, CODEC_ID_EAC3 }, /* E-AC-3 descriptor */
{ 0x7b, CODEC_TYPE_AUDIO, CODEC_ID_DTS },
{ 0x59, CODEC_TYPE_SUBTITLE, CODEC_ID_DVB_SUBTITLE }, /* subtitling descriptor */
+ { 0 },
};
static void mpegts_find_stream_type(AVStream *st,
break;
case 0x05: /* registration descriptor */
st->codec->codec_tag = bytestream_get_le32(&p);
- dprintf(ts->stream, "reg_desc=%x\n", st->codec->codec_tag);
+ dprintf(ts->stream, "reg_desc=%.4s\n", (char*)&st->codec->codec_tag);
if (st->codec->codec_id == CODEC_ID_PROBE &&
stream_type == STREAM_TYPE_PRIVATE_DATA)
mpegts_find_stream_type(st, st->codec->codec_tag, REGD_types);
pes->header[2] == 0x01) {
/* it must be an mpeg2 PES stream */
code = pes->header[3] | 0x100;
+ dprintf(pes->stream, "pid=%x pes_code=%#x\n", pes->pid, code);
+
+ if ((!pes->st && pes->stream->nb_streams == MAX_STREAMS) ||
+ (pes->st && pes->st->discard == AVDISCARD_ALL) ||
+ code == 0x1be) /* padding_stream */
+ goto skip;
/* stream not present in PMT */
if (!pes->st)
if (!pes->st)
return AVERROR(ENOMEM);
- if (pes->st->discard == AVDISCARD_ALL ||
- !((code >= 0x1c0 && code <= 0x1df) ||
- (code >= 0x1e0 && code <= 0x1ef) ||
- (code == 0x1bd) || (code == 0x1fd)))
- goto skip;
- pes->state = MPEGTS_PESHEADER_FILL;
pes->total_size = AV_RB16(pes->header + 4);
/* NOTE: a zero total size means the PES size is
unbounded */
- pes->pes_header_size = pes->header[8] + 9;
+ if (!pes->total_size)
+ pes->total_size = MAX_PES_PAYLOAD;
+
+ /* allocate pes buffer */
+ pes->buffer = av_malloc(pes->total_size+FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!pes->buffer)
+ return AVERROR(ENOMEM);
+
+ if (code != 0x1bc && code != 0x1bf && /* program_stream_map, private_stream_2 */
+ code != 0x1f0 && code != 0x1f1 && /* ECM, EMM */
+ code != 0x1ff && code != 0x1f2 && /* program_stream_directory, DSMCC_stream */
+ code != 0x1f8) { /* ITU-T Rec. H.222.1 type E stream */
+ pes->state = MPEGTS_PESHEADER;
+ } else {
+ pes->state = MPEGTS_PAYLOAD;
+ pes->data_index = 0;
+ }
} else {
/* otherwise, it should be a table */
/* skip packet */
break;
/**********************************************/
/* PES packing parsing */
+ case MPEGTS_PESHEADER:
+ len = PES_HEADER_SIZE - pes->data_index;
+ if (len < 0)
+ return -1;
+ if (len > buf_size)
+ len = buf_size;
+ memcpy(pes->header + pes->data_index, p, len);
+ pes->data_index += len;
+ p += len;
+ buf_size -= len;
+ if (pes->data_index == PES_HEADER_SIZE) {
+ pes->pes_header_size = pes->header[8] + 9;
+ pes->state = MPEGTS_PESHEADER_FILL;
+ }
+ break;
case MPEGTS_PESHEADER_FILL:
len = pes->pes_header_size - pes->data_index;
if (len < 0)
r += 5;
}
- if (pes->total_size > pes->data_index - 6)
- pes->total_size -= pes->data_index - 6;
- else
- pes->total_size = MAX_PES_PAYLOAD;
- /* allocate pes buffer */
- pes->buffer = av_malloc(pes->total_size+FF_INPUT_BUFFER_PADDING_SIZE);
- if (!pes->buffer)
- return AVERROR(ENOMEM);
-
/* we got the full header. We parse it and get the payload */
pes->state = MPEGTS_PAYLOAD;
pes->data_index = 0;
pes->pid = pid;
pes->pcr_pid = pcr_pid;
pes->stream_type = stream_type;
+ pes->state = MPEGTS_SKIP;
tss = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes);
if (!tss) {
av_free(pes);