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;
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) {
}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;
+ }
}
}
{
MpegTSFilter *filter;
- av_dlog(ts->stream, "Filter: pid=0x%x\n", pid);
+ av_log(ts->stream, AV_LOG_TRACE, "Filter: pid=0x%x\n", pid);
if (pid >= NB_PID_MAX || ts->pids[pid])
return NULL;
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;
score = analyze(buf, size, TS_PACKET_SIZE, NULL, 0);
dvhs_score = analyze(buf, size, TS_DVHS_PACKET_SIZE, NULL, 0);
fec_score = analyze(buf, size, TS_FEC_PACKET_SIZE, NULL, 0);
- av_dlog(NULL, "score: %d, dvhs_score: %d, fec_score: %d \n",
+ av_log(NULL, AV_LOG_TRACE, "score: %d, dvhs_score: %d, fec_score: %d \n",
score, dvhs_score, fec_score);
if (score > fec_score && score > dvhs_score)
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;
pes->header[2] == 0x01) {
/* it must be an mpeg2 PES stream */
code = pes->header[3] | 0x100;
- av_dlog(pes->stream, "pid=%x pes_code=%#x\n", pes->pid,
+ av_log(pes->stream, AV_LOG_TRACE, "pid=%x pes_code=%#x\n", pes->pid,
code);
if ((pes->st && pes->st->discard == AVDISCARD_ALL &&
code != 0x1f8) { /* ITU-T Rec. H.222.1 type E stream */
pes->state = MPEGTS_PESHEADER;
if (pes->st->codec->codec_id == AV_CODEC_ID_NONE && !pes->st->request_probe) {
- av_dlog(pes->stream,
+ av_log(pes->stream, AV_LOG_TRACE,
"pid=%x stream_type=%x probing\n",
pes->pid,
pes->stream_type);
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;
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);
if (desc_end > desc_list_end)
return AVERROR_INVALIDDATA;
- av_dlog(fc, "tag: 0x%02x len=%d\n", desc_tag, desc_len);
+ av_log(fc, AV_LOG_TRACE, "tag: 0x%02x len=%d\n", desc_tag, desc_len);
if ((st->codec->codec_id == AV_CODEC_ID_NONE || st->request_probe > 0) &&
stream_type == STREAM_TYPE_PRIVATE_DATA)
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,
break;
case 0x05: /* registration descriptor */
st->codec->codec_tag = bytestream_get_le32(pp);
- av_dlog(fc, "reg_desc=%.4s\n", (char *)&st->codec->codec_tag);
+ av_log(fc, AV_LOG_TRACE, "reg_desc=%.4s\n", (char *)&st->codec->codec_tag);
if (st->codec->codec_id == AV_CODEC_ID_NONE)
mpegts_find_stream_type(st, st->codec->codec_tag, REGD_types);
break;
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;
Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = { { 0 } };
int i;
- av_dlog(ts->stream, "PMT: len %i\n", section_len);
+ av_log(ts->stream, AV_LOG_TRACE, "PMT: len %i\n", section_len);
hex_dump_debug(ts->stream, section, section_len);
p_end = section + section_len - 4;
p = section;
if (parse_section_header(h, &p, p_end) < 0)
return;
+ if (skip_identical(h, tssf))
+ return;
- av_dlog(ts->stream, "sid=0x%x sec_num=%d/%d version=%d\n",
+ 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);
if (h->tid != PMT_TID)
add_pid_to_pmt(ts, h->id, pcr_pid);
set_pcr_pid(ts->stream, h->id, pcr_pid);
- av_dlog(ts->stream, "pcr_pid=0x%x\n", pcr_pid);
+ av_log(ts->stream, AV_LOG_TRACE, "pcr_pid=0x%x\n", pcr_pid);
program_info_length = get16(&p, p_end);
if (program_info_length < 0)
tag = get8(&p, p_end);
len = get8(&p, p_end);
- av_dlog(ts->stream, "program tag: 0x%02x len=%d\n", tag, len);
+ av_log(ts->stream, AV_LOG_TRACE, "program tag: 0x%02x len=%d\n", tag, len);
if (len > program_info_length - 2)
// something else is broken, exit the program_descriptors_loop
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;
AVProgram *program;
- av_dlog(ts->stream, "PAT:\n");
+ av_log(ts->stream, AV_LOG_TRACE, "PAT:\n");
hex_dump_debug(ts->stream, section, section_len);
p_end = section + section_len - 4;
if (ts->skip_changes)
return;
+ if (skip_identical(h, tssf))
+ return;
ts->stream->ts_id = h->id;
clear_programs(ts);
if (pmt_pid == ts->current_pid)
break;
- av_dlog(ts->stream, "sid=0x%x pid=0x%x\n", sid, pmt_pid);
+ av_log(ts->stream, AV_LOG_TRACE, "sid=0x%x pid=0x%x\n", sid, pmt_pid);
if (sid == 0x0000) {
/* NIT info */
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;
char *name, *provider_name;
- av_dlog(ts->stream, "SDT:\n");
+ av_log(ts->stream, AV_LOG_TRACE, "SDT:\n");
hex_dump_debug(ts->stream, section, section_len);
p_end = section + section_len - 4;
return;
if (ts->skip_changes)
return;
+ if (skip_identical(h, tssf))
+ return;
+
onid = get16(&p, p_end);
if (onid < 0)
return;
if (desc_len < 0 || desc_end > desc_list_end)
break;
- av_dlog(ts->stream, "tag: 0x%02x len=%d\n",
+ av_log(ts->stream, AV_LOG_TRACE, "tag: 0x%02x len=%d\n",
desc_tag, desc_len);
switch (desc_tag) {
if (avio_tell(s->pb) != ts->last_pos) {
int i;
- av_dlog(ts->stream, "Skipping after seek\n");
+ av_log(ts->stream, AV_LOG_TRACE, "Skipping after seek\n");
/* seek detected, flush pes buffer */
for (i = 0; i < NB_PID_MAX; i++) {
if (ts->pids[i]) {
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;
ts->auto_guess = 1;
- av_dlog(ts->stream, "tuning done\n");
+ av_log(ts->stream, AV_LOG_TRACE, "tuning done\n");
s->ctx_flags |= AVFMTCTX_NOHEADER;
} else {
s->bit_rate = TS_PACKET_SIZE * 8 * 27e6 / ts->pcr_incr;
st->codec->bit_rate = s->bit_rate;
st->start_time = ts->cur_pcr;
- av_dlog(ts->stream, "start=%0.3f pcr=%0.3f incr=%d\n",
+ av_log(ts->stream, AV_LOG_TRACE, "start=%0.3f pcr=%0.3f incr=%d\n",
st->start_time / 1000000.0, pcrs[0] / 27e6, ts->pcr_incr);
}