diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 6120f273d2..d4f5355d97 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -254,7 +254,7 @@ typedef struct PESContext { /* used to get the format */ int data_index; int flags; /**< copied to the AVPacket flags */ - int total_size; + int PES_packet_length; int pes_header_size; int extended_stream_id; uint8_t stream_id; @@ -998,8 +998,8 @@ static int new_pes_packet(PESContext *pes, AVPacket *pkt) pkt->data = pes->buffer->data; pkt->size = pes->data_index; - if (pes->total_size != MAX_PES_PAYLOAD && - pes->pes_header_size + pes->data_index != pes->total_size + + if (pes->PES_packet_length && + pes->pes_header_size + pes->data_index != pes->PES_packet_length + PES_START_SIZE) { av_log(pes->stream, AV_LOG_WARNING, "PES packet size mismatch\n"); pes->flags |= AV_PKT_FLAG_CORRUPT; @@ -1183,11 +1183,8 @@ static int mpegts_push_data(MpegTSFilter *filter, mpegts_set_stream_info(pes->st, pes, 0, 0); } - pes->total_size = AV_RB16(pes->header + 4); - /* NOTE: a zero total size means the PES size is - * unbounded */ - if (!pes->total_size) - pes->total_size = MAX_PES_PAYLOAD; + pes->PES_packet_length = AV_RB16(pes->header + 4); + /* NOTE: zero length means the PES size is unbounded */ if (pes->stream_id != STREAM_ID_PROGRAM_STREAM_MAP && pes->stream_id != STREAM_ID_PRIVATE_STREAM_2 && @@ -1360,22 +1357,27 @@ skip: break; case MPEGTS_PAYLOAD: do { + int max_packet_size = MAX_PES_PAYLOAD; + if (pes->PES_packet_length) + max_packet_size = pes->PES_packet_length; + if (pes->data_index > 0 && - pes->data_index + buf_size > pes->total_size) { + pes->data_index + buf_size > max_packet_size) { ret = new_pes_packet(pes, ts->pkt); if (ret < 0) return ret; - pes->total_size = MAX_PES_PAYLOAD; + pes->PES_packet_length = 0; + max_packet_size = MAX_PES_PAYLOAD; ts->stop_parse = 1; } else if (pes->data_index == 0 && - buf_size > pes->total_size) { + buf_size > max_packet_size) { // pes packet size is < ts size packet and pes data is padded with 0xff // not sure if this is legal in ts but see issue #2392 - buf_size = pes->total_size; + buf_size = max_packet_size; } if (!pes->buffer) { - pes->buffer = buffer_pool_get(ts, pes->total_size); + pes->buffer = buffer_pool_get(ts, max_packet_size); if (!pes->buffer) return AVERROR(ENOMEM); } @@ -1384,11 +1386,9 @@ skip: pes->data_index += buf_size; /* emit complete packets with known packet size * decreases demuxer delay for infrequent packets like subtitles from - * a couple of seconds to milliseconds for properly muxed files. - * total_size is the number of bytes following pes_packet_length - * in the pes header, i.e. not counting the first PES_START_SIZE bytes */ - if (!ts->stop_parse && pes->total_size < MAX_PES_PAYLOAD && - pes->pes_header_size + pes->data_index == pes->total_size + PES_START_SIZE) { + * a couple of seconds to milliseconds for properly muxed files. */ + if (!ts->stop_parse && pes->PES_packet_length && + pes->pes_header_size + pes->data_index == pes->PES_packet_length + PES_START_SIZE) { ts->stop_parse = 1; ret = new_pes_packet(pes, ts->pkt); pes->state = MPEGTS_SKIP;