From patchwork Wed Sep 4 12:27:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Anthony Delannoy X-Patchwork-Id: 14893 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 6B3D644A0EF for ; Wed, 4 Sep 2019 15:28:13 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 457BE687F83; Wed, 4 Sep 2019 15:28:13 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-yw1-f43.google.com (mail-yw1-f43.google.com [209.85.161.43]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 139FD680C0D for ; Wed, 4 Sep 2019 15:28:07 +0300 (EEST) Received: by mail-yw1-f43.google.com with SMTP id 201so7111454ywo.13 for ; Wed, 04 Sep 2019 05:28:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=iKMDVSI2Pg3rpvWJAbeHcNgPYI3MNxHqNn8iiej8uSs=; b=Rdb3QwwL3T/rnCntF1D7iMBEaPkH3RlJu1FED7JfZpDU7fCRkvQBvaOBIcflyPsyBw IGPKYU/02xL6Bmk6GvS9qhPrfWV9KpiS4O+CXTMLjA+MpBJz34TCT8BAQ8TKJ6cSRh+E MntGE29GzmWq13Q2j32NuEXDTdgPYErvdVv07i8+YvsSXNh1zh1jk3CSu5/yBllc0tpn AzWiIxZu18tqATLqqGBZ1uMQNqD6YIEEWSNbSGrRth2uIlHL47OtM99tA68G4W9bd1fq 7R7p4tba4j5KmLPSo7icZruYC+3Dn/gQZk9vC8MFayQiJ1tx872I00fpfqBxnOHjvt75 GlyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=iKMDVSI2Pg3rpvWJAbeHcNgPYI3MNxHqNn8iiej8uSs=; b=Z7na9KdRIqGT0G4RZO5T5mpew9SlieHZ0OCiu0S3Bxw2yR7KcAhJdB8lpS7zrdXl9U Ym0o5+k7hco+lv4jksJRqI0ww6DtbTAOCbqDis6zBHI27yM70xjau7FOobSubNZPFDq1 Lcbo7ewlkcfdw6yRhQkBZtSVhM0KroN9n8FlOkZ9gTlO/0xr/Q0ellZHe14q4EDZbWMo G5N2QGWmnK6UvqibIBJGzSXTSZHOqaSj7gXsJM4plgC3JH/CCcFxAUmT8aa03Ew2FA/6 B0+nFSENXSkTLXEiutsdVjm0oNOpM6Be9SwGFq9ARb602AAZcWkzeZ6oZJxrnAuChf+M 4JOA== X-Gm-Message-State: APjAAAVyOHXgia54W1fSfXyxCkrPDzHEXyYk1QPuCXJjtz7wUSvnTSPW 4sYA5aafPb/1HyQ439DfNZGszYEX6s0orJdW91G6xg== X-Google-Smtp-Source: APXvYqxsFe9IakZAxB41ejJHEuZB0miSqGCDIxUmkfoRn77RrkAg/3gzv1i9JHFR4VavSWwiUzQ1qXZHPlqNNQFxW0g= X-Received: by 2002:a81:650b:: with SMTP id z11mr27953801ywb.29.1567600085176; Wed, 04 Sep 2019 05:28:05 -0700 (PDT) MIME-Version: 1.0 References: <20190822104225.GI3219@michaelspb> In-Reply-To: From: Anthony Delannoy Date: Wed, 4 Sep 2019 14:27:54 +0200 Message-ID: To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [PATCH] DVB EPG decoder X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" 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 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 > > 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-request@ffmpeg.org with subject "unsubscribe". From 335b0bf377c1e5cfc5207561adc9621b113759b0 Mon Sep 17 00:00:00 2001 From: Anthony Delannoy 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