diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 0d1dda1c36..3c9f9421cb 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -391,7 +391,8 @@ static void write_section_data(MpegTSContext *ts, MpegTSFilter *tss1, const uint8_t *buf, int buf_size, int is_start) { MpegTSSectionFilter *tss = &tss1->u.section_filter; - int len; + uint8_t *cur_section_buf = NULL; + int len, offset; if (is_start) { memcpy(tss->section_buf, buf, buf_size); @@ -408,23 +409,26 @@ static void write_section_data(MpegTSContext *ts, MpegTSFilter *tss1, tss->section_index += len; } + offset = 0; + cur_section_buf = tss->section_buf; + while (cur_section_buf - tss->section_buf < MAX_SECTION_SIZE && cur_section_buf[0] != 0xff) { /* compute section length if possible */ - if (tss->section_h_size == -1 && tss->section_index >= 3) { - len = (AV_RB16(tss->section_buf + 1) & 0xfff) + 3; + if (tss->section_h_size == -1 && tss->section_index - offset >= 3) { + len = (AV_RB16(cur_section_buf + 1) & 0xfff) + 3; if (len > MAX_SECTION_SIZE) return; tss->section_h_size = len; } if (tss->section_h_size != -1 && - tss->section_index >= tss->section_h_size) { + tss->section_index >= offset + tss->section_h_size) { int crc_valid = 1; tss->end_of_section_reached = 1; if (tss->check_crc) { - crc_valid = !av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, tss->section_buf, tss->section_h_size); + crc_valid = !av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, cur_section_buf, tss->section_h_size); if (tss->section_h_size >= 4) - tss->crc = AV_RB32(tss->section_buf + tss->section_h_size - 4); + tss->crc = AV_RB32(cur_section_buf + tss->section_h_size - 4); if (crc_valid) { ts->crc_validity[ tss1->pid ] = 100; @@ -434,10 +438,18 @@ static void write_section_data(MpegTSContext *ts, MpegTSFilter *tss1, crc_valid = 2; } if (crc_valid) { - tss->section_cb(tss1, tss->section_buf, tss->section_h_size); + tss->section_cb(tss1, cur_section_buf, tss->section_h_size); if (crc_valid != 1) tss->last_ver = -1; } + + cur_section_buf += tss->section_h_size; + offset += tss->section_h_size; + tss->section_h_size = -1; + } else { + tss->end_of_section_reached = 0; + break; + } } }