From patchwork Sat Apr 9 15:15:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: TADANO Tokumei X-Patchwork-Id: 35240 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:671c:b0:7c:62c8:b2d1 with SMTP id q28csp171143pzh; Sat, 9 Apr 2022 08:16:51 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwo7hqBeSso2OUZiwAKibmuyEySLdQQZ5Ia0AimaYTLsxHlDpM+z1Ch920thxhkE0/HkQ7N X-Received: by 2002:a17:906:4fcb:b0:6e8:74db:6b04 with SMTP id i11-20020a1709064fcb00b006e874db6b04mr1968812ejw.676.1649517410810; Sat, 09 Apr 2022 08:16:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1649517410; cv=none; d=google.com; s=arc-20160816; b=zhQDuXcrRrXCqRaUZMjLwCqKcfVhuO8V4q1U2Cg14IYcIEdIrDy5+FBou+1p37Ac32 op9o4hfmtJQsEFORTS2eYpniFPk2HMHqVqeq6GVUFwHrmuMTcDj/Zi5xpW5OOOw3TKzt f4Z1Un2O1V9/jOK5bgsMjFjUVSa0YqVd9VEMKbbeqfIsrJ15x6UgX9HjLKokX86ne0rF e9oUA2t1G1XPMM96/zZsI8BfPCVSTS9O/QOUKrUHKcU3p2RPk7bIjC1Ve2ryc4hut34u f6BXf9MOucg+H507JlTWNojkcANMzmhdKqHkqaY1ds09PZqJofolT3aIENUHxJCEbMZj +y2Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:message-id:date:to:from :dkim-signature:dkim-filter:delivered-to; bh=4nj1ElzyzIvWkME7u7L4IaWJDymgme0SPSdJDqhy28E=; b=Ey0dP08oKUdA2naOsJXMXc6FomoGE9R2VMHboj1jROGTjwSl0pTsGoen0m9SvXfoQI exo3r1jl0++/2EyksbXplJ3d+byZNmVN5p4AwJwO8KHVXW3MA0tce3WhmI6agJn3aId6 7BLHH+mMbWirUTkrWIG+rKyw/YAaNYhqqzZNHrk8JW/p1L9KZk0uC+2xUnzRUkvaOEW5 zPCz13GPop27rAl9pKBj0fDMtcv3oB1zZzq1hW4H4OtFha3Y0gyHPvuoj/oz5yFIinI5 2+AhM8TNsGI7z0OqIYYHDvFnldeamr//pN3xMt3B+DR6ceuPHJf7i80ps3ue/c/pEKD0 4fAw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@nifty.com header.s=dec2015msa header.b=Od9duvaS; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id qn25-20020a170907211900b006dfe7bc2fb7si2870512ejb.375.2022.04.09.08.16.49; Sat, 09 Apr 2022 08:16:50 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@nifty.com header.s=dec2015msa header.b=Od9duvaS; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 18CEB68B2E3; Sat, 9 Apr 2022 18:16:45 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from conssluserg-01.nifty.com (conssluserg-01.nifty.com [210.131.2.80]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 35E5B68A785 for ; Sat, 9 Apr 2022 18:16:35 +0300 (EEST) Received: from osamu-pc.kimura.local (M106073025034.v4.enabler.ne.jp [106.73.25.34]) (authenticated) by conssluserg-01.nifty.com with ESMTP id 239FGBE1019530; Sun, 10 Apr 2022 00:16:16 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conssluserg-01.nifty.com 239FGBE1019530 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1649517376; bh=jdD3sfGVyWJ8KiL2qZOoyLLO/jK2l0hUDEizHp7JUFo=; h=From:To:Cc:Subject:Date:From; b=Od9duvaSMlyNgLbnqfTlsR6tB0G/1s/ZUDikesC/gZY1fVJdAz+GiMhWChcl8RTK7 me3LiqeXoYDM/dV2ot9jcEFNDxJDd9OZ4bxeCAj91HPBzimTaY6Avck0PjkL8Tr5wQ VJhQ9OVDjerC3R2mBGbvzUbHPs15DewQ810y/VvpvpnBdYln0m5UXiDwYrjc3pSjHO f1PMcZg7yAz+0wLfPDY2Zy+XNyNcCYl5FXf7SNWaA8EtYbfmE2r2evuM/E12xl4p+S 9ivPBASVvdPBryzAbveDQoDeLmprVdQ4rr9vv91oOoDBgzlTj57oBaXFML/WlQBWdm J5ZTK39gD2rkw== X-Nifty-SrcIP: [106.73.25.34] From: TADANO Tokumei To: ffmpeg-devel@ffmpeg.org Date: Sun, 10 Apr 2022 00:15:18 +0900 Message-Id: <20220409151518.38945-1-aimingoff@pc.nifty.jp> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] libavformat/mpegts.c: add: parse EIT descriptors X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 Cc: TADANO Tokumei Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: AcsmD3Gt5PRP This patch add to parse descriptors on EIT packets. The patch is intended to set information to current program and/or A/V stream. On Japanese ISDB, some important / useful information is provided via EIT only. ref: ARIB STD B10 Table 6-1, Section 6.1, Part 2. This patch only parse short event descriptor (0x4d) and set title information to the program. It may not be useful, but a good example of EIT descriptor common for DVB and ISDB. Note that it only parse EIT for actual and present TS stream as bllow: * Parse EIT table_id 0x4E (actual TS stream) only. ref: DVB Blue Book A038 (EN 300 468) Table 2, Section 5.1.3. * Parse section number 0x00 only. Section number 0x00 is present event. Section number 0x01 is following (i.e., not for present stream). Section number 0x02 or later may contain event for present stream, but it is hard to distinguish and rarely sent. ref: DVB-SI Guidelines (TS 101 211) Section 4.1.4.1. * Find a program associated to the EIT in already initialized AVProgram and Program structures. If no program found, abort to parse the EIT. Since EIT packets may be sent several times for the same program, add 'eit_version' in Program structure and ignore EITs with the same version as previously parsed one. There is a warning: "variable 'language' set but not used" at compilation. It should be resolved by later patches. An sample DVB TS file is found at: https://streams.videolan.org/streams/ts/Teletext/TELETEXTO.ts After aplying this patch, ffprobe TELETEXTO.ts shows tile as: Program 340 Metadata: title : NAVY : INVESTIGACIÓN CRIMINAL Many sample ISDB TS files are found at: https://streams.videolan.org/streams/ts/ARIB/japan/ Most of TS files show their title by ffprobe, but unrecognizable. It is due to encoding problem of text string. It should be also resolved by future patches. Signed-off-by: TADANO Tokumei --- libavformat/mpegts.c | 129 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 127 insertions(+), 2 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 49f7735123..8417d71fb3 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -123,6 +123,8 @@ struct Program { /** have we found pmt for this program */ int pmt_found; + + int eit_version; }; struct MpegTSContext { @@ -304,6 +306,7 @@ static void clear_program(struct Program *p) p->nb_pids = 0; p->nb_streams = 0; p->pmt_found = 0; + p->eit_version = -1; } static void clear_programs(MpegTSContext *ts) @@ -2616,8 +2619,12 @@ 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; + const uint8_t *p, *p_end, *desc_list_end, *desc_end; SectionHeader h1, *h = &h1; + AVProgram *program; + struct Program *prg; + int desc_len; + char language[252]; /* * Sometimes we receive EPG packets but SDT table do not have @@ -2645,6 +2652,7 @@ static void eit_cb(MpegTSFilter *filter, const uint8_t *section, int section_len return; av_log(ts->stream, AV_LOG_TRACE, "EIT: tid received = %.02x\n", h->tid); + hex_dump_debug(ts->stream, section, section_len); /** * Service_id 0xFFFF is reserved, it indicates that the current EIT table @@ -2664,7 +2672,124 @@ static void eit_cb(MpegTSFilter *filter, const uint8_t *section, int section_len new_data_packet(section, section_len, ts->pkt); ts->pkt->stream_index = ts->epg_stream->index; - ts->stop_parse = 1; + + /* parse present event of actual TS stream only */ + if (h->tid != EIT_TID) + return; + if (!h->current_next) + return; + if (ts->skip_changes) + return; + + av_log(ts->stream, AV_LOG_TRACE, "sid=0x%x sec_num=%d/%d version=%d\n", + h->id, h->sec_num, h->last_sec_num, h->version); + + /* DVB-SI Guidelines (TS 101 211) 4.1.4.1 */ + /* 0x00 indicates present event, 0x01 indicates following event */ + /* 0x02 and after is optional */ + if (h->sec_num > 0) + return; + + program = NULL; + for (int i = 0; i < ts->stream->nb_programs; i++) + if (ts->stream->programs[i]->id == h->id) + program = ts->stream->programs[i]; + if (!program || program->nb_stream_indexes <= 0) + return; + + prg = get_program(ts, h->id); + if (!prg) + return; + if (h->version == prg->eit_version) + return; + prg->eit_version = h->version; + + /* skip ts_id, original_network_id, last_section_no, last_table_id */ + if (p + 6 > p_end) + return; + p += 6; + + for (;;) { + int eid, val; + + eid = get16(&p, p_end); + if (eid < 0) + break; + { + int hh, mm, ss, d_hh, d_mm, d_ss, running_status; + val = get16(&p, p_end); /* Date */ + if (val < 0) + break; + hh = get8(&p, p_end); + if (hh < 0) + break; + mm = get8(&p, p_end); + if (mm < 0) + break; + ss = get8(&p, p_end); + if (ss < 0) + break; + d_hh = get8(&p, p_end); + if (d_hh < 0) + break; + d_mm = get8(&p, p_end); + if (d_mm < 0) + break; + d_ss = get8(&p, p_end); + if (d_ss < 0) + break; + desc_len = get16(&p, p_end); + if (desc_len < 0) + break; + running_status = (desc_len & 0xe000) >> 5; + av_log(ts->stream, AV_LOG_TRACE, + "eid=0x%04x start %02x:%02x:%02x duration %02x:%02x:%02x running_status=%d\n", + eid, hh, mm, ss, d_hh, d_mm, d_ss, running_status); + } + desc_len &= 0x0fff; + desc_list_end = p + desc_len; + if (desc_list_end > p_end) + break; + + for (;;) { + int desc_tag; + + desc_tag = get8(&p, desc_list_end); + if (desc_tag < 0) + break; + desc_len = get8(&p, desc_list_end); + desc_end = p + desc_len; + if (desc_len < 0 || desc_end > desc_list_end) + break; + + av_log(ts->stream, AV_LOG_DEBUG, "tag: 0x%02x len=%d\n", + desc_tag, desc_len); + + switch (desc_tag) { + case 0x4d: /* short event descriptor */ + { + char *txt; + + if (desc_len < 3) + break; + language[0] = get8(&p, desc_end); + language[1] = get8(&p, desc_end); + language[2] = get8(&p, desc_end); + language[3] = '\0'; + txt = getstr8(&p, desc_end); + if (!txt) + break; + av_dict_set(&program->metadata, "title", txt, 0); + av_free(txt); + } + break; + default: + break; + } + p = desc_end; + } + p = desc_list_end; + } } static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)