X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fmpegts.c;h=613584e4b6b06f4602238f89b1ef337de165f253;hb=e0153145f6f8f3aa813652980862bafc8fd9b5c9;hp=39da4712f5f6b378ef6d161cc7aefd8f292b2e90;hpb=400810abee8fdf1a58ea852065b08e8ce1ca70c4;p=ffmpeg diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 39da4712f5f..613584e4b6b 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -75,6 +75,9 @@ typedef void SetServiceCallback (void *opaque, int ret); typedef struct MpegTSSectionFilter { int section_index; int section_h_size; + int last_ver; + unsigned crc; + unsigned last_crc; uint8_t *section_buf; unsigned int check_crc : 1; unsigned int end_of_section_reached : 1; @@ -418,6 +421,9 @@ static void write_section_data(MpegTSContext *ts, MpegTSFilter *tss1, if (tss->check_crc) { crc_valid = !av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, tss->section_buf, tss->section_h_size); + if (tss->section_h_size >= 4) + tss->crc = AV_RB32(tss->section_buf + tss->section_h_size - 4); + if (crc_valid) { ts->crc_validity[ tss1->pid ] = 100; }else if (ts->crc_validity[ tss1->pid ] > -10) { @@ -425,8 +431,11 @@ static void write_section_data(MpegTSContext *ts, MpegTSFilter *tss1, }else crc_valid = 2; } - if (crc_valid) + if (crc_valid) { tss->section_cb(tss1, tss->section_buf, tss->section_h_size); + if (crc_valid != 1) + tss->last_ver = -1; + } } } @@ -469,6 +478,8 @@ static MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts, sec->opaque = opaque; sec->section_buf = av_malloc(MAX_SECTION_SIZE); sec->check_crc = check_crc; + sec->last_ver = -1; + if (!sec->section_buf) { av_free(filter); return NULL; @@ -577,6 +588,17 @@ typedef struct SectionHeader { uint8_t last_sec_num; } SectionHeader; +static int skip_identical(const SectionHeader *h, MpegTSSectionFilter *tssf) +{ + if (h->version == tssf->last_ver && tssf->last_crc == tssf->crc) + return 1; + + tssf->last_ver = h->version; + tssf->last_crc = tssf->crc; + + return 0; +} + static inline int get8(const uint8_t **pp, const uint8_t *p_end) { const uint8_t *p; @@ -1451,6 +1473,7 @@ static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) { MpegTSContext *ts = filter->u.section_filter.opaque; + MpegTSSectionFilter *tssf = &filter->u.section_filter; SectionHeader h; const uint8_t *p, *p_end; AVIOContext pb; @@ -1465,6 +1488,8 @@ static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, return; if (h.tid != M4OD_TID) return; + if (skip_identical(&h, tssf)) + return; mp4_read_od(s, p, (unsigned) (p_end - p), mp4_descr, &mp4_descr_count, MAX_MP4_DESCR_COUNT); @@ -1584,7 +1609,9 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type if (get16(pp, desc_end) < 0) break; if (mp4_descr_count > 0 && - (st->codec->codec_id == AV_CODEC_ID_AAC_LATM || st->request_probe > 0) && + (st->codec->codec_id == AV_CODEC_ID_AAC_LATM || + (st->request_probe == 0 && st->codec->codec_id == AV_CODEC_ID_NONE) || + st->request_probe > 0) && mp4_descr->dec_config_descr_len && mp4_descr->es_id == pid) { AVIOContext pb; ffio_init_context(&pb, mp4_descr->dec_config_descr, @@ -1787,6 +1814,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) { MpegTSContext *ts = filter->u.section_filter.opaque; + MpegTSSectionFilter *tssf = &filter->u.section_filter; SectionHeader h1, *h = &h1; PESContext *pes; AVStream *st; @@ -1806,6 +1834,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len p = section; if (parse_section_header(h, &p, p_end) < 0) return; + if (skip_identical(h, tssf)) + return; av_log(ts->stream, AV_LOG_TRACE, "sid=0x%x sec_num=%d/%d version=%d\n", h->id, h->sec_num, h->last_sec_num, h->version); @@ -1955,6 +1985,7 @@ out: static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) { MpegTSContext *ts = filter->u.section_filter.opaque; + MpegTSSectionFilter *tssf = &filter->u.section_filter; SectionHeader h1, *h = &h1; const uint8_t *p, *p_end; int sid, pmt_pid; @@ -1972,6 +2003,8 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len if (ts->skip_changes) return; + if (skip_identical(h, tssf)) + return; ts->stream->ts_id = h->id; clear_programs(ts); @@ -2027,6 +2060,7 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) { MpegTSContext *ts = filter->u.section_filter.opaque; + MpegTSSectionFilter *tssf = &filter->u.section_filter; SectionHeader h1, *h = &h1; const uint8_t *p, *p_end, *desc_list_end, *desc_end; int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type; @@ -2043,6 +2077,9 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len return; if (ts->skip_changes) return; + if (skip_identical(h, tssf)) + return; + onid = get16(&p, p_end); if (onid < 0) return; @@ -2349,6 +2386,8 @@ static int handle_packets(MpegTSContext *ts, int64_t nb_packets) av_buffer_unref(&pes->buffer); pes->data_index = 0; pes->state = MPEGTS_SKIP; /* skip until pes header */ + } else if (ts->pids[i]->type == MPEGTS_SECTION) { + ts->pids[i]->u.section_filter.last_ver = -1; } ts->pids[i]->last_cc = -1; ts->pids[i]->last_pcr = -1;