From patchwork Wed Jul 4 18:35:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baptiste Coudurier X-Patchwork-Id: 9615 Delivered-To: ffmpegpatchwork@gmail.com Received: by 2002:a02:104:0:0:0:0:0 with SMTP id c4-v6csp1079377jad; Wed, 4 Jul 2018 11:36:43 -0700 (PDT) X-Google-Smtp-Source: AAOMgpco5i17ofDZPrLi0tNJwgfU2aEwpNLha4YoSxTC+txW2nKSm9F7H8AdaB85ubpLqXoy3AUA X-Received: by 2002:adf:b786:: with SMTP id s6-v6mr2287703wre.247.1530729403722; Wed, 04 Jul 2018 11:36:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530729403; cv=none; d=google.com; s=arc-20160816; b=mtUJltqvJpKFBCMqtSfOfECiObkgknfCyDWYs+MM7yLd8FbuvJJr1HE8Le36Py9EgN ZQYjkbobA/qTCGMloWHo2EFC8hpjkLMjp/s85WOWpbsdN2IoZBvS3WlXNlkVFnGs+kkJ boo+pcgs4Uc+48xkldiWv42bzNNcIXYgfctGB88yOde+iB+G6whAgRBL0yQeBJdInxYa N6mKMZpc2WOVuBexeUvNwlksG3hL3qp+YCxPo+HU+2RwkikyY8+ePDqdgD2wyjSkJ04M j4CB3bF3tqucV/8mVBTOH5NJvQRhc3Pd6CbKPJnGQg//T9OzkJbgQdVSzo4bo8vSBvs9 bCSA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:message-id:date:to:from:dkim-signature :delivered-to:arc-authentication-results; bh=qufMDZb5czehqgV3bFjhi1JhCAifo2jgmiDKtogGlLo=; b=Ck1VxLzY2XTc0Dmd76juiWmp7fv457Gk4jqcZvcTX//8Bn7zbMYXHOtaJlypV3Sn1L 03v99fzxqBIfV4fehSsinA8c0sCYNUgjYR9v1iLzSLrUjtMtIz1/WPXKLTXaXhKqa3Ug HFkJtVYJBNS9qDf8k/BuUNiGztlbMYZofNUVjrO6lM28yN5o6u7X3Z+1l2rxktCFzRnY PSDYedjy9jX5z1J3PvMLeaM6ZX5hCBJJgBHJIR+Z4OTUk4F0P9CP1OARcjJ77vmAyAJF MjA6akiXB5v5c9t/mVXEoE7FCJ4qZF3gmKNbKswaEcMudb1+P13TPwzlOeZiRFnzm5Fi NiMw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=IgUdPUqV; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id h74-v6si3231516wme.116.2018.07.04.11.36.43; Wed, 04 Jul 2018 11:36:43 -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=@gmail.com header.s=20161025 header.b=IgUdPUqV; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 97D1068AB55; Wed, 4 Jul 2018 21:35:31 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf0-f172.google.com (mail-pf0-f172.google.com [209.85.192.172]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0163868AB28 for ; Wed, 4 Jul 2018 21:35:23 +0300 (EEST) Received: by mail-pf0-f172.google.com with SMTP id j3-v6so3247795pfh.11 for ; Wed, 04 Jul 2018 11:35:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=W2TzyAuq+ArMPgnTUos40wD0OVY5UW2+G84I3+BHkuM=; b=IgUdPUqV5nDkhV1mBGYOJ/vtVHbgxsrqODxux2xKkx4ZvQiBL4I+2Cwc3xYpblvsrt dPU62uWN8+xyd41hrxr4XoutuAtQo6ieIxK7pFsXqnbMvw90xA7cCQl1XiBRPqeBf0/U N6iZOkPJRW0MOsb0U03hzoa5JducDF0FLpxG2VewEYsbjzDPW3pNQjtXi20GTrQ9TBtH ab+mK/pNcSr3e3P59vwxKHhPm9oMF6iWi2/6IIUuYFPKVMStImzZKlh764xZWIO/uVyk AxINovmAfinhe07wFerSsR4ijN64J/MkwFz8YdeesiDe6AmP14mzXn4djkpLdqpYZ33y U1MQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=W2TzyAuq+ArMPgnTUos40wD0OVY5UW2+G84I3+BHkuM=; b=oSP4OhDLAqKmNudZjhrMjDWbNsyosz6FYK2WLTfWN6r7t9hI8Da2pd4P4CQzdxis25 9I2ix7s5YlFMjwpg1/YVkgNFrdJd6VG2/GcjkRqCFZrbBST/i7F2jg13KIFlaAl+h1kQ HB9O9BYBA8/5sHXrsUaLP62l4FBz0tk06GWYVXhqNq5+yrqWNa5ES3uvHIzhXe5ZBph8 jsgUgyV0TdnQwsKORS7bfWSRjMnyjAC31aM5jrCLAstCLPNO7RNqVDgPPIGjhwNJjWZl 2rmRbsgTW/+0MPzKDuQ+7C1g2rjnySFpgPiBE2+1iGtevrXhkQcyfq8eh2+vuCJyHEcE xtmA== X-Gm-Message-State: APt69E1UIgwkzEBnVnsOiOdGym4UK1sI6bHe0si0+b6glgm7dY+WwXZc c1amRiXCgtgPB0y+ttsHoc7Swg== X-Received: by 2002:a63:6cc8:: with SMTP id h191-v6mr2841192pgc.359.1530729325879; Wed, 04 Jul 2018 11:35:25 -0700 (PDT) Received: from localhost.localdomain (cpe-104-173-251-254.socal.res.rr.com. [104.173.251.254]) by smtp.gmail.com with ESMTPSA id v126-v6sm8591239pgv.39.2018.07.04.11.35.24 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 04 Jul 2018 11:35:24 -0700 (PDT) From: Baptiste Coudurier To: ffmpeg-devel@ffmpeg.org Date: Wed, 4 Jul 2018 11:35:13 -0700 Message-Id: <20180704183514.71654-11-baptiste.coudurier@gmail.com> X-Mailer: git-send-email 2.17.0 (Apple Git-106) Subject: [FFmpeg-devel] [PATCH 11/12] lavf/sccdec: fix timestamps and demux one eai608 frame at a time 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- libavformat/sccdec.c | 100 ++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 44 deletions(-) diff --git a/libavformat/sccdec.c b/libavformat/sccdec.c index 89d21b9c1f..0472b4e031 100644 --- a/libavformat/sccdec.c +++ b/libavformat/sccdec.c @@ -24,9 +24,14 @@ #include "subtitles.h" #include "libavutil/bprint.h" #include "libavutil/intreadwrite.h" +#include "libavutil/timecode.h" +#include "libavutil/opt.h" typedef struct SCCContext { + AVClass *av_class; FFDemuxSubtitlesQueue q; + AVTimecode initial_tc; + char *timecode_start; } SCCContext; static int scc_probe(AVProbeData *p) @@ -62,57 +67,53 @@ static int scc_read_header(AVFormatContext *s) { SCCContext *scc = s->priv_data; AVStream *st = avformat_new_stream(s, NULL); - char line[4096], line2[4096]; - int count = 0, ret = 0; - ptrdiff_t len2, len; - uint8_t out[4096]; + char line[4096]; + int ret = 0; + ptrdiff_t len; FFTextReader tr; + const AVRational frame_rate = {30000,1001}; ff_text_init_avio(s, &tr, s->pb); if (!st) return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 64, 1, 1000); + avpriv_set_pts_info(st, 64, 1001, 30000); st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; st->codecpar->codec_id = AV_CODEC_ID_EIA_608; + if (av_timecode_init_from_string(&scc->initial_tc, + (AVRational){30000, 1001}, + scc->timecode_start, s) < 0) + return -1; + + while (!ff_text_eof(&tr)) { + len = ff_subtitles_read_line(&tr, line, sizeof(line)); + if (!strncmp(line, "Scenarist_SCC V1.0", 18)) + break; + } + while (!ff_text_eof(&tr)) { const int64_t pos = ff_text_pos(&tr); char *saveptr = NULL, *lline; - int hh1, mm1, ss1, fs1, i; - int hh2, mm2, ss2, fs2; - int64_t ts_start, ts_end; + AVTimecode tc_start; + int i; AVPacket *sub; - - if (count == 0) { - while (!ff_text_eof(&tr)) { - len = ff_subtitles_read_line(&tr, line, sizeof(line)); - if (len > 13) - break; - } - } - - if (!strncmp(line, "Scenarist_SCC V1.0", 18)) - continue; - if (sscanf(line, "%d:%d:%d%*[:;]%d", &hh1, &mm1, &ss1, &fs1) != 4) - continue; - - ts_start = (hh1 * 3600LL + mm1 * 60LL + ss1) * 1000LL + fs1 * 33; + char out[4]; while (!ff_text_eof(&tr)) { - len2 = ff_subtitles_read_line(&tr, line2, sizeof(line2)); - if (len2 > 13) + len = ff_subtitles_read_line(&tr, line, sizeof(line)); + if (len > 13) break; } - if (sscanf(line2, "%d:%d:%d%*[:;]%d", &hh2, &mm2, &ss2, &fs2) != 4) - continue; - ts_end = (hh2 * 3600LL + mm2 * 60LL + ss2) * 1000LL + fs2 * 33; - count++; + if (av_timecode_init_from_string(&tc_start, frame_rate, line, s) < 0) + continue; lline = (char *)&line; lline += 12; + out[3] = 0; + for (i = 0; i < 4095; i += 3) { char *ptr = av_strtok(lline, " ", &saveptr); char c1, c2, c3, c4; @@ -124,21 +125,17 @@ static int scc_read_header(AVFormatContext *s) break; lline = NULL; - out[i+0] = 0xfc; - out[i+1] = convert(c2) | (convert(c1) << 4); - out[i+2] = convert(c4) | (convert(c3) << 4); + out[0] = 0xfc; + out[1] = convert(c2) | (convert(c1) << 4); + out[2] = convert(c4) | (convert(c3) << 4); + + sub = ff_subtitles_queue_insert(&scc->q, out, 3, 0); + if (!sub) + return AVERROR(ENOMEM); + sub->pos = pos + i * 3; + sub->pts = tc_start.start + i / 3; + sub->duration = 1; } - out[i] = 0; - - sub = ff_subtitles_queue_insert(&scc->q, out, i, 0); - if (!sub) - return AVERROR(ENOMEM); - - sub->pos = pos; - sub->pts = ts_start; - sub->duration = FFMAX(1200, ts_end - ts_start); - memmove(line, line2, sizeof(line)); - FFSWAP(ptrdiff_t, len, len2); } ff_subtitles_queue_finalize(s, &scc->q); @@ -149,7 +146,8 @@ static int scc_read_header(AVFormatContext *s) static int scc_read_packet(AVFormatContext *s, AVPacket *pkt) { SCCContext *scc = s->priv_data; - return ff_subtitles_queue_read_packet(&scc->q, pkt); + int ret = ff_subtitles_queue_read_packet(&scc->q, pkt); + return ret; } static int scc_read_seek(AVFormatContext *s, int stream_index, @@ -167,6 +165,19 @@ static int scc_read_close(AVFormatContext *s) return 0; } +static const AVOption scc_options[] = { + { "timecode_start", "Set the SCC file initial timecode, to adjust timestamps", + offsetof(SCCContext, timecode_start), AV_OPT_TYPE_STRING, {.str = "00:00:00;00"}, CHAR_MIN, CHAR_MAX, AV_OPT_FLAG_ENCODING_PARAM}, + { NULL }, +}; + +static const AVClass scc_demuxer_class = { + .class_name = "scc demuxer", + .item_name = av_default_item_name, + .option = scc_options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVInputFormat ff_scc_demuxer = { .name = "scc", .long_name = NULL_IF_CONFIG_SMALL("Scenarist Closed Captions"), @@ -177,4 +188,5 @@ AVInputFormat ff_scc_demuxer = { .read_seek2 = scc_read_seek, .read_close = scc_read_close, .extensions = "scc", + .priv_class = &scc_demuxer_class, };