From patchwork Thu Sep 12 05:02:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anthony Delannoy X-Patchwork-Id: 15037 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 C325C4473E3 for ; Thu, 12 Sep 2019 08:03:19 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 99F606809EB; Thu, 12 Sep 2019 08:03:19 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-yw1-f48.google.com (mail-yw1-f48.google.com [209.85.161.48]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E4F7568048A for ; Thu, 12 Sep 2019 08:03:12 +0300 (EEST) Received: by mail-yw1-f48.google.com with SMTP id n126so8701148ywf.1 for ; Wed, 11 Sep 2019 22:03:12 -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=3ROnTAEle24fP0zOw/JxvNWjy9ZxW19TlPKwhoZgAwo=; b=ZyNW7byB9MuaXbE5H62HE9iJM9sU780s8wNZ6EWC4qLBQ5liKab7LPnVZP+wsB4AHF xkmt8302PnBq/yoT6VtJPfpPVA/sHXrD56t1A/3zZLRLGSofSt5QaitV2WTUAAkhE+Pf x0CLGfCFANT6GnTuw0OMrx30hrGqGJjpezJ1X7y9LdBkD76rxJXj2wToAgDYr40HmNBB 2iX1sxlWRIhlruM9Nu2Q1M5gGdX7Lhg+D9xya2NkIV2wARDXjPvivnJyrxSRXF8Nif0u pgjcx+W/YytLosSappP7ihMjwHxCYaFMZ/hK9gNJWEH8WFdCTF5XGGsL1HDPAEeXLhJg YzDg== 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=3ROnTAEle24fP0zOw/JxvNWjy9ZxW19TlPKwhoZgAwo=; b=rroQ3qs3Ia/vDpUCD2eBabku52NHhZgDlyKcLdVWw8coLRVRn/GnIYgLshi9UAM2mX w6aeqOL9vXwNlNl2dT3MozKHFF1YBgyke7UDQqDppg8aaMmoUBpVoeFx7iXFeB4NxBtT uwWV15pqR1Y1PAO8ZIwFaIJSiBmDgE/ukBy2mcs4lH01x0WKjTHlna7BgNrtT4OBnRuh wX1rMfQyXlkwak+c1hfQZfPSKrUrhvyqnDImg5ys6WNwCyr6tE0xPEpksjmT1jVOMT9E GQR5pjxdJOQWzl54MSVL1l3d0qfpShKq3o3UzD/VwbacEKL7Vid2sQ/WBJ7bHpa5rQyO 7WTQ== X-Gm-Message-State: APjAAAWPrxMPmw6OLqROyRhZewc5KotHVSn5XkCj0yvMEHBALje4Q7bT 9/d2LsSHedzkcYzDuKlYK/iGLumLmy10l/PQG3xZ4YMo X-Google-Smtp-Source: APXvYqx/zd4BGGccj5YtAP6GCFbQAK/u8rrWcD3z056DKb5Fee9oLBOrLY0L7EqCh6wXGk69/M/39pB0WBod9pd6+XM= X-Received: by 2002:a81:528d:: with SMTP id g135mr27972597ywb.445.1568264591212; Wed, 11 Sep 2019 22:03:11 -0700 (PDT) MIME-Version: 1.0 References: <20190822104225.GI3219@michaelspb> In-Reply-To: From: Anthony Delannoy Date: Thu, 12 Sep 2019 07:02:59 +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" > > 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? > > I don't see how, as it does not fit into the concept of the libav* > libraries. I feel this belongs to a separate library. A new libavdata library for data handling ? > In case of a scrambled EIT (which I have never seen myself in the wild) you'd > print this at every packet. You should either remove the warning, or check if > this is the first time (e.g. by checking if the EPG stream was just created). > You should remove this, there are tons of captures where EIT PID is > intentionally filtered, we should not spam the user. I made both of this log print on AV_LOG_TRACE level, I rather keep them here if i need them. > Not needed, as context is zero initialized. I deleted the unnecessary init. Anthony Delannoy From 506706294edd6359c2ef6402a77065447396d9ce 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 | 70 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 0415ceea02..312e10fc37 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_TRACE, "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_TRACE, "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,10 @@ MpegTSContext *avpriv_mpegts_parse_open(AVFormatContext *s) ts->raw_packet_size = TS_PACKET_SIZE; ts->stream = 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