@@ -57,6 +57,7 @@ enum MpegTSFilterType {
MPEGTS_PES,
MPEGTS_SECTION,
MPEGTS_PCR,
+ MPEGTS_DATA,
};
typedef struct MpegTSFilter MpegTSFilter;
@@ -510,6 +511,11 @@ static MpegTSFilter *mpegts_open_pcr_filter(MpegTSContext *ts, unsigned int pid)
return mpegts_open_filter(ts, pid, MPEGTS_PCR);
}
+static MpegTSFilter *mpegts_open_data_filter(MpegTSContext *ts, unsigned int pid)
+{
+ return mpegts_open_filter(ts, pid, MPEGTS_DATA);
+}
+
static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter)
{
int pid;
@@ -725,6 +731,12 @@ static const StreamType HDMV_types[] = {
{ 0 },
};
+/* SCTE types */
+static const StreamType SCTE_types[] = {
+ { 0x86, AVMEDIA_TYPE_DATA, AV_CODEC_ID_SCTE_35 },
+ { 0 },
+};
+
/* ATSC ? */
static const StreamType MISC_types[] = {
{ 0x81, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 },
@@ -872,6 +884,13 @@ static void reset_pes_packet_state(PESContext *pes)
av_buffer_unref(&pes->buffer);
}
+static void new_data_packet(const uint8_t *buffer, int len, AVPacket *pkt)
+{
+ av_init_packet(pkt);
+ pkt->data = buffer;
+ pkt->size = len;
+}
+
static int new_pes_packet(PESContext *pes, AVPacket *pkt)
{
char *sd;
@@ -1975,6 +1994,19 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
pes->st->id = pes->pid;
}
st = pes->st;
+ } else if (stream_type == 0x86 && prog_reg_desc == AV_RL32("CUEI")) {
+ int idx = ff_find_stream_index(ts->stream, pid);
+ if (idx >= 0) {
+ st = ts->stream->streams[idx];
+ } else {
+ st = avformat_new_stream(ts->stream, NULL);
+ if (!st)
+ goto out;
+ st->id = pid;
+ st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
+ mpegts_find_stream_type(st, stream_type, SCTE_types);
+ mpegts_open_data_filter(ts, pid);
+ }
} else if (stream_type != 0x13) {
if (ts->pids[pid])
mpegts_close_filter(ts, ts->pids[pid]); // wrongly added sdt filter probably
@@ -2317,7 +2349,21 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
}
}
}
-
+ } else if (tss->type == MPEGTS_DATA) {
+ AVProgram *prg = NULL;
+ int idx = ff_find_stream_index(ts->stream, pid);
+ p++;
+ new_data_packet(p,p_end - p, ts->pkt);
+ if (idx >= 0) {
+ ts->pkt->stream_index = idx;
+ }
+ prg = av_find_program_from_stream(ts->stream, prg, idx);
+ if (prg->pcr_pid != -1 && prg->discard != AVDISCARD_ALL) {
+ MpegTSFilter *f = ts->pids[prg->pcr_pid];
+ if(f)
+ ts->pkt->pts = ts->pkt->dts = f->last_pcr/300;
+ }
+ ts->stop_parse = 1;
} else {
int ret;
// Note: The position here points actually behind the current packet.
@@ -2730,6 +2776,8 @@ static int mpegts_read_packet(AVFormatContext *s, AVPacket *pkt)
ret = 0;
break;
}
+ } else if (ts->pids[i] && ts->pids[i]->type == MPEGTS_DATA) {
+ return ret;
}
}