/** to detect seek */
int64_t last_pos;
+ int skip_changes;
+ int skip_clear;
+
/******************************************/
/* private mpegts data */
/* scan context */
{.i64 = 1}, 0, 1, AV_OPT_FLAG_DECODING_PARAM },
{"ts_packetsize", "Output option carrying the raw packet size.", offsetof(MpegTSContext, raw_packet_size), AV_OPT_TYPE_INT,
{.i64 = 0}, 0, 0, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY },
+ {"skip_changes", "Skip changing / adding streams / programs.", offsetof(MpegTSContext, skip_changes), AV_OPT_TYPE_INT,
+ {.i64 = 0}, 0, 1, 0 },
+ {"skip_clear", "Skip clearing programs.", offsetof(MpegTSContext, skip_clear), AV_OPT_TYPE_INT,
+ {.i64 = 0}, 0, 1, 0 },
{ NULL },
};
{
AVProgram *prg = NULL;
int i;
+
for (i = 0; i < ts->stream->nb_programs; i++)
if (ts->stream->programs[i]->id == programid) {
prg = ts->stream->programs[i];
* Assemble PES packets out of TS packets, and then call the "section_cb"
* function when they are complete.
*/
-static void write_section_data(AVFormatContext *s, MpegTSFilter *tss1,
+static void write_section_data(MpegTSContext *ts, MpegTSFilter *tss1,
const uint8_t *buf, int buf_size, int is_start)
{
- MpegTSContext *ts = s->priv_data;
MpegTSSectionFilter *tss = &tss1->u.section_filter;
int len;
/* stream not present in PMT */
if (!pes->st) {
+ if (ts->skip_changes)
+ goto skip;
+
pes->st = avformat_new_stream(ts->stream, NULL);
if (!pes->st)
return AVERROR(ENOMEM);
break;
}
}
- if (i) {
+ if (i && language[0]) {
language[i - 1] = 0;
av_dict_set(&st->metadata, "language", language, 0);
}
if (h->tid != PMT_TID)
return;
+ if (ts->skip_changes)
+ return;
clear_program(ts, h->id);
pcr_pid = get16(&p, p_end);
return;
if (h->tid != PAT_TID)
return;
+ if (ts->skip_changes)
+ return;
ts->stream->ts_id = h->id;
for (i = 0; i < ts->nb_prg; i++)
if (ts->prg[i].id == ts->stream->programs[j]->id)
break;
- if (i==ts->nb_prg)
+ if (i==ts->nb_prg && !ts->skip_clear)
clear_avprogram(ts, ts->stream->programs[j]->id);
}
}
return;
if (h->tid != SDT_TID)
return;
+ if (ts->skip_changes)
+ return;
onid = get16(&p, p_end);
if (onid < 0)
return;
/* handle one TS packet */
static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
{
- AVFormatContext *s = ts->stream;
MpegTSFilter *tss;
int len, pid, cc, expected_cc, cc_ok, afc, is_start, is_discontinuity,
has_adaptation, has_payload;
return 0;
if (len && cc_ok) {
/* write remaining section bytes */
- write_section_data(s, tss,
+ write_section_data(ts, tss,
p, len, 0);
/* check whether filter has been closed */
if (!ts->pids[pid])
}
p += len;
if (p < p_end) {
- write_section_data(s, tss,
+ write_section_data(ts, tss,
p, p_end - p, 1);
}
} else {
if (cc_ok) {
- write_section_data(s, tss,
+ write_section_data(ts, tss,
p, p_end - p, 0);
}
}
avio_skip(pb, skip);
}
-static int handle_packets(MpegTSContext *ts, int nb_packets)
+static int handle_packets(MpegTSContext *ts, int64_t nb_packets)
{
AVFormatContext *s = ts->stream;
uint8_t packet[TS_PACKET_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
const uint8_t *data;
- int packet_num, ret = 0;
+ int64_t packet_num;
+ int ret = 0;
if (avio_tell(s->pb) != ts->last_pos) {
int i;
AVIOContext *pb = s->pb;
uint8_t buf[8 * 1024] = {0};
int len;
- int64_t pos;
+ int64_t pos, probesize = s->probesize ? s->probesize : s->probesize2;
- ffio_ensure_seekback(pb, s->probesize);
+ ffio_ensure_seekback(pb, probesize);
/* read the first 8192 bytes to get packet size */
pos = avio_tell(pb);
mpegts_open_section_filter(ts, PAT_PID, pat_cb, ts, 1);
- handle_packets(ts, s->probesize / ts->raw_packet_size);
+ handle_packets(ts, probesize / ts->raw_packet_size);
/* if could not find service, enable auto_guess */
ts->auto_guess = 1;