Hi I'm still interested to have those three commits merged (update in attachments).
But I'd like to see data decoder in the future to use more easily EPG/NIT/BAT etc tables. Will it be possible? With modifications if it needs to be? Anthony Delannoy Le mar. 3 sept. 2019 à 23:39, Marton Balint <c...@passwd.hu> a écrit : > > Hi, > > I am not sure if you are interested getting only patch 1, 2 and 3 > merged, but if you are, then here are my comments for patch 3. > > > From 025ec8e8d607d02f2e5b4021783ab8f3b42d0bc1 Mon Sep 17 00:00:00 2001 > > From: Anthony Delannoy <anthony.2lan...@gmail.com> > > Date: Wed, 21 Aug 2019 11:46:56 +0200 > > Subject: [PATCH 03/10] lavf/mpegts: EPG extraction from mpegts > > > > --- > > libavformat/mpegts.c | 67 ++++++++++++++++++++++++++++++++++++++++++-- > > 1 file changed, 65 insertions(+), 2 deletions(-) > > > > diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c > > index 47d8d5f877..03c1753ac7 100644 > > --- a/libavformat/mpegts.c > > +++ b/libavformat/mpegts.c > > @@ -2489,13 +2489,57 @@ static void pat_cb(MpegTSFilter *filter, const > > uint8_t *section, int section_len > > } > > } > > > > +static void eit_cb(MpegTSFilter *filter, const uint8_t *section, int > > section_len) > > +{ > > + MpegTSContext *ts = filter->u.section_filter.opaque; > > + MpegTSSectionFilter *tssf = &filter->u.section_filter; > > + const uint8_t *p, *p_end; > > + SectionHeader h1, *h = &h1; > > + int idx; > > + AVProgram *prg; > > Maybe you can check if AVStream->discard == DISCARD_ALL for the EIT stream and > skip the packet if the stream is discarded. > > > + > > + p_end = section + section_len - 4; > > + p = section; > > + > > + if (parse_section_header(h, &p, p_end) < 0) > > + return; > > + if (h->tid < EIT_TID || h->tid > OEITS_END_TID) > > + return; > > > + if (ts->skip_changes) > > + return; > > + if (skip_identical(h, tssf)) > > + return; > > I don't think these last two checks (skip changes and skip identical) makes > much sense here, just remove them. > > > + > > + idx = ff_find_stream_index(ts->stream, filter->pid); > > + if (idx < 0) > > + return; > > Instead of finding the stream each time, you should simply add an AVStream > *epg_stream to MpegTsContext, set it where you create the stream, and use that > always. > > > + > > + /** > > + * In case we receive an EPG packet before mpegts context is fully > > + * initialized. > > + */ > > + if (!ts->pkt) > > + return; > > + > > + new_data_packet(section, section_len, ts->pkt); > > + ts->pkt->stream_index = idx; > > > + prg = av_find_program_from_stream(ts->stream, NULL, idx); > > + if (prg && prg->pcr_pid != -1 && prg->discard != AVDISCARD_ALL) { > > + MpegTSFilter *f = ts->pids[prg->pcr_pid]; > > + if (f && f->last_pcr != -1) > > + ts->pkt->pts = ts->pkt->dts = f->last_pcr/300; > > + } > > This program based logic is no longer needed since EIT is not added to > programs. > > > + ts->stop_parse = 1; > > +} > > + > > 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; > > + int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type, > > + eit_sched, eit_pres_following; > > char *name, *provider_name; > > > > av_log(ts->stream, AV_LOG_TRACE, "SDT:\n"); > > @@ -2525,6 +2569,24 @@ static void sdt_cb(MpegTSFilter *filter, const > > uint8_t *section, int section_len > > val = get8(&p, p_end); > > if (val < 0) > > break; > > + eit_sched = (val >> 1) & 0x1; > > + eit_pres_following = val & 0x1; > > + > > + if (eit_sched | eit_pres_following) { > > + int idx = ff_find_stream_index(ts->stream, EIT_PID); > > + AVStream *st = (idx >= 0) ? ts->stream->streams[EIT_PID] : > > NULL; > > I guess ts->stream->streams[EIT_PID] wanted to be ts->stream->streams[idx] but > it does not matter because you should rework this if you add epg_stream to > MpegTsContext. > > > + > > + if (!st) { > > + st = avformat_new_stream(ts->stream, NULL); > > + if (!st) > > + return; > > + st->id = EIT_PID; > > + st->program_num = sid; > > + st->codecpar->codec_type = AVMEDIA_TYPE_DATA; > > + st->codecpar->codec_id = AV_CODEC_ID_EPG; > > + } > > + } > > + > > desc_list_len = get16(&p, p_end); > > if (desc_list_len < 0) > > break; > > @@ -2975,8 +3037,8 @@ static int mpegts_read_header(AVFormatContext *s) > > seek_back(s, pb, pos); > > > > mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1); > > - > > mpegts_open_section_filter(ts, PAT_PID, pat_cb, ts, 1); > > + mpegts_open_section_filter(ts, EIT_PID, eit_cb, ts, 1); > > > > handle_packets(ts, probesize / ts->raw_packet_size); > > /* if could not find service, enable auto_guess */ > > @@ -3233,6 +3295,7 @@ MpegTSContext > > *avpriv_mpegts_parse_open(AVFormatContext *s) > > ts->auto_guess = 1; > > mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1); > > mpegts_open_section_filter(ts, PAT_PID, pat_cb, ts, 1); > > + mpegts_open_section_filter(ts, EIT_PID, eit_cb, ts, 1); > > > > return ts; > > } > > -- > > 2.23.0 > > Regards, > Marton > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
From 7dade98c4e0618c398efd82c15ab99c5c0593903 Mon Sep 17 00:00:00 2001 From: Anthony Delannoy <anthony.2lan...@gmail.com> Date: Wed, 21 Aug 2019 11:36:15 +0200 Subject: [PATCH 2/3] lavc: add EPG codec ID --- libavcodec/avcodec.h | 1 + libavcodec/codec_desc.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index de4feb6a65..1dfff67a35 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -689,6 +689,7 @@ enum AVCodecID { AV_CODEC_ID_TTF = 0x18000, AV_CODEC_ID_SCTE_35, ///< Contain timestamp estimated through PCR of program stream. + AV_CODEC_ID_EPG, AV_CODEC_ID_BINTEXT = 0x18800, AV_CODEC_ID_XBIN, AV_CODEC_ID_IDF, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index e6373be504..5dc8b16b8f 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -3191,6 +3191,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .name = "scte_35", .long_name = NULL_IF_CONFIG_SMALL("SCTE 35 Message Queue"), }, + { + .id = AV_CODEC_ID_EPG, + .type = AVMEDIA_TYPE_DATA, + .name = "epg", + .long_name = NULL_IF_CONFIG_SMALL("Electronic Program Guide"), + }, { .id = AV_CODEC_ID_BINTEXT, .type = AVMEDIA_TYPE_VIDEO, -- 2.23.0
From 096032a788ca1b1523f897e0f57c7b88e2f40f0c Mon Sep 17 00:00:00 2001 From: Anthony Delannoy <anthony.2lan...@gmail.com> Date: Fri, 26 Jul 2019 11:41:00 +0200 Subject: [PATCH 1/3] avformat/mpegts: add all pids & tids --- libavformat/mpegts.h | 74 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 6 deletions(-) diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h index 272e2be4f7..560c319ef1 100644 --- a/libavformat/mpegts.h +++ b/libavformat/mpegts.h @@ -30,17 +30,79 @@ #define TS_MAX_PACKET_SIZE 204 #define NB_PID_MAX 8192 +#define USUAL_SECTION_SIZE 1024 /* except EIT which is limited to 4096 */ #define MAX_SECTION_SIZE 4096 /* pids */ -#define PAT_PID 0x0000 -#define SDT_PID 0x0011 +#define PAT_PID 0x0000 /* Program Association Table */ +#define CAT_PID 0x0001 /* Conditional Access Table */ +#define TSDT_PID 0x0002 /* Transport Stream Description Table */ +#define IPMP_PID 0x0003 +/* PID from 0x0004 to 0x000F are reserved */ +#define NIT_PID 0x0010 /* Network Information Table */ +#define SDT_PID 0x0011 /* Service Description Table */ +#define BAT_PID SDT_PID /* Bouquet Association Table */ +#define EIT_PID 0x0012 /* Event Information Table */ +#define RST_PID 0x0013 /* Running Status Table */ +#define TDT_PID 0x0014 /* Time and Date Table */ +#define TOT_PID TDT_PID +#define NET_SYNC_PID 0x0015 +#define RNT_PID 0x0016 /* RAR Notification Table */ +/* PID from 0x0017 to 0x001B are reserved for future use */ +/* PID value 0x001C allocated to link-local inband signalling shall not be + * used on any broadcast signals. It shall only be used between devices in a + * controlled environment. */ +#define LINK_LOCAL_PID 0x001C +#define MEASUREMENT_PID 0x001D +#define DIT_PID 0x001E /* Discontinuity Information Table */ +#define SIT_PID 0x001F /* Selection Information Table */ +/* PID from 0x0020 to 0x1FFA may be assigned as needed to PMT, elementary + * streams and other data tables */ +/* PID 0x1FFB is used by DigiCipher 2/ATSC MGT metadata */ +/* PID from 0x1FFC to 0x1FFE may be assigned as needed to PMT, elementary + * streams and other data tables */ +#define NULL_PID 0x1FFF /* Null packet (used for fixed bandwidth padding) */ /* table ids */ -#define PAT_TID 0x00 -#define PMT_TID 0x02 -#define M4OD_TID 0x05 -#define SDT_TID 0x42 +#define PAT_TID 0x00 /* Program Association section */ +#define CAT_TID 0x01 /* Conditional Access section */ +#define PMT_TID 0x02 /* Program Map section */ +#define TSDT_TID 0x03 /* Transport Stream Description section */ +/* TID from 0x04 to 0x3F are reserved */ +#define M4OD_TID 0x05 +#define NIT_TID 0x40 /* Network Information section - actual network */ +#define ONIT_TID 0x41 /* Network Information section - other network */ +#define SDT_TID 0x42 /* Service Description section - actual TS */ +/* TID from 0x43 to 0x45 are reserved for future use */ +#define OSDT_TID 0x46 /* Service Descrition section - other TS */ +/* TID from 0x47 to 0x49 are reserved for future use */ +#define BAT_TID 0x4A /* Bouquet Association section */ +#define UNT_TID 0x4B /* Update Notification Table section */ +#define DFI_TID 0x4C /* Downloadable Font Info section */ +/* TID 0x4D is reserved for future use */ +#define EIT_TID 0x4E /* Event Information section - actual TS */ +#define OEIT_TID 0x4F /* Event Information section - other TS */ +#define EITS_START_TID 0x50 /* Event Information section schedule - actual TS */ +#define EITS_END_TID 0x5F /* Event Information section schedule - actual TS */ +#define OEITS_START_TID 0x60 /* Event Information section schedule - other TS */ +#define OEITS_END_TID 0x6F /* Event Information section schedule - other TS */ +#define TDT_TID 0x70 /* Time Date section */ +#define RST_TID 0x71 /* Running Status section */ +#define ST_TID 0x72 /* Stuffing section */ +#define TOT_TID 0x73 /* Time Offset section */ +#define AIT_TID 0x74 /* Application Inforamtion section */ +#define CT_TID 0x75 /* Container section */ +#define RCT_TID 0x76 /* Related Content section */ +#define CIT_TID 0x77 /* Content Identifier section */ +#define MPE_FEC_TID 0x78 /* MPE-FEC section */ +#define RPNT_TID 0x79 /* Resolution Provider Notification section */ +#define MPE_IFEC_TID 0x7A /* MPE-IFEC section */ +#define PROTMT_TID 0x7B /* Protection Message section */ +/* TID from 0x7C to 0x7D are reserved for future use */ +#define DIT_TID 0x7E /* Discontinuity Information section */ +#define SIT_TID 0x7F /* Selection Information section */ +/* TID from 0x80 to 0xFE are user defined */ +/* TID 0xFF is reserved */ #define STREAM_TYPE_VIDEO_MPEG1 0x01 #define STREAM_TYPE_VIDEO_MPEG2 0x02 -- 2.23.0
From 335b0bf377c1e5cfc5207561adc9621b113759b0 Mon Sep 17 00:00:00 2001 From: Anthony Delannoy <anthony.2lan...@gmail.com> Date: Wed, 21 Aug 2019 11:46:56 +0200 Subject: [PATCH 3/3] lavf/mpegts: EPG extraction from mpegts --- libavformat/mpegts.c | 71 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 0415ceea02..9bb6b6add8 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -168,6 +168,8 @@ struct MpegTSContext { /** filters for various streams specified by PMT + for the PAT and PMT */ MpegTSFilter *pids[NB_PID_MAX]; int current_pid; + + AVStream *epg_stream; }; #define MPEGTS_OPTIONS \ @@ -2498,13 +2500,68 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len } } +static void eit_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) +{ + MpegTSContext *ts = filter->u.section_filter.opaque; + const uint8_t *p, *p_end; + SectionHeader h1, *h = &h1; + + /* + * Sometimes we receive EPG packets but SDT table do not have + * eit_pres_following or eit_sched turned on, so we open EPG + * stream directly here. + */ + if (!ts->epg_stream) { + ts->epg_stream = avformat_new_stream(ts->stream, NULL); + if (!ts->epg_stream) + return; + ts->epg_stream->id = EIT_PID; + ts->epg_stream->codecpar->codec_type = AVMEDIA_TYPE_DATA; + ts->epg_stream->codecpar->codec_id = AV_CODEC_ID_EPG; + } + + if (ts->epg_stream->discard == AVDISCARD_ALL) + return; + + p_end = section + section_len - 4; + p = section; + + if (parse_section_header(h, &p, p_end) < 0) + return; + if (h->tid < EIT_TID || h->tid > OEITS_END_TID) + return; + + av_log(ts->stream, AV_LOG_TRACE, "EIT: tid received = %.02x\n", h->tid); + + /** + * Service_id 0xFFFF is reserved, it indicates that the current EIT table + * is scrambled. + */ + if (h->id == 0xFFFF) { + av_log(ts->stream, AV_LOG_WARNING, "Scrambled EIT table received.\n"); + return; + } + + /** + * In case we receive an EPG packet before mpegts context is fully + * initialized. + */ + if (!ts->pkt) + return; + + new_data_packet(section, section_len, ts->pkt); + ts->pkt->stream_index = ts->epg_stream->index; + ts->stop_parse = 1; +} + 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; + int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type, + eit_sched, eit_pres_following; char *name, *provider_name; av_log(ts->stream, AV_LOG_TRACE, "SDT:\n"); @@ -2534,6 +2591,13 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len val = get8(&p, p_end); if (val < 0) break; + eit_sched = (val >> 1) & 0x1; + eit_pres_following = val & 0x1; + + if ((eit_sched | eit_pres_following) && !ts->epg_stream) + av_log(ts->stream, AV_LOG_WARNING, "SDT table advertise EIT but no" + " packets were received yet.\n"); + desc_list_len = get16(&p, p_end); if (desc_list_len < 0) break; @@ -2984,8 +3048,8 @@ static int mpegts_read_header(AVFormatContext *s) seek_back(s, pb, pos); mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1); - mpegts_open_section_filter(ts, PAT_PID, pat_cb, ts, 1); + mpegts_open_section_filter(ts, EIT_PID, eit_cb, ts, 1); handle_packets(ts, probesize / ts->raw_packet_size); /* if could not find service, enable auto_guess */ @@ -3240,8 +3304,11 @@ MpegTSContext *avpriv_mpegts_parse_open(AVFormatContext *s) ts->raw_packet_size = TS_PACKET_SIZE; ts->stream = s; ts->auto_guess = 1; + ts->epg_stream = NULL; + mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1); mpegts_open_section_filter(ts, PAT_PID, pat_cb, ts, 1); + mpegts_open_section_filter(ts, EIT_PID, eit_cb, ts, 1); return ts; } -- 2.23.0
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".