From patchwork Sat Feb 11 16:29:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Sabatini X-Patchwork-Id: 40371 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:5494:b0:bf:7b3a:fd32 with SMTP id i20csp2240952pzk; Sat, 11 Feb 2023 08:29:12 -0800 (PST) X-Google-Smtp-Source: AK7set+NqSq2RaL/ZqK5cdyUpgoPcJYqzAn4jK2rJiVIrKAwd5AFl0RfBOEHJ6dWAXYe/nQmIBHx X-Received: by 2002:a17:906:dc9:b0:888:33a:e359 with SMTP id p9-20020a1709060dc900b00888033ae359mr19066432eji.38.1676132952077; Sat, 11 Feb 2023 08:29:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1676132952; cv=none; d=google.com; s=arc-20160816; b=axPhu1n8xyki92UK41MGPKC9YVrJkhWJ0WRLW2YQqh8MPUYYl3gFFLyxv6DZkeSsR+ p9z0A+t8zpBlvrB2b2VGTQSEwXPMM+Q51ZrgSUcrohSzcHSUL1g2EaGHmTtcmVg/a12g nRgDLYc6wjPCITcPYfAxklneT7A+3LiHV5OBgHT7csRCN7YPi9Xo9mtoPTEI2IWRQ4PO 72qnNS9T/SR8zH2+LOox9JtXN9uZu7N1Bw44nn0xzHeW1wsTqQXjYqnPZ5//mBfHjSxK 9Nc+MyreMvDlohIP9XhuGsDQHpEWmT0mNsSjaD/c4Vvg+COeCC5jb1g/2MWqII0Ye9ub LslA== 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:delivered-to; bh=JgRjPbIescVlB8voyJlABYJVGE6h+lD3mAIfUbpWUZs=; b=bZJkCqop9CVp4IMGrQ8/3TWbtjSZt60LmTIUOkYwdJYfC3HMbhRZp8F33//fmrHMFU TjMCeRQUNG2yczMGThpVqKm1XDhUce4rMCLeAGJj+XorwoRqLo1+NEx5lKFBRpRh4eUb GMcGSu0QIReBEPlYKdiWCh0iR+wvXfcZyVYMWCn1R8sqsDLvuugPJFTeZTq2eUN8VjM2 DkDKq3F3vNbj3e3W4zrq1bVBeg11HR14v+z0r/xxpBaUtEV3kROzOr3DLK7xcoo846/6 0nz+7EPM7DGiosF68i98ZoYwfTNWM/yaWvYWlEuv14XjHp1rM4TRSGsN5WrkCfscHUHN KjRg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=dqxZ7Qq4; 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 ev2-20020a17090729c200b008796a9cd15dsi6880565ejc.978.2023.02.11.08.29.11; Sat, 11 Feb 2023 08:29:12 -0800 (PST) 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=20210112 header.b=dqxZ7Qq4; 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 AE39A68BD1D; Sat, 11 Feb 2023 18:29:09 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ej1-f51.google.com (mail-ej1-f51.google.com [209.85.218.51]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6C558680741 for ; Sat, 11 Feb 2023 18:29:03 +0200 (EET) Received: by mail-ej1-f51.google.com with SMTP id ud5so22701606ejc.4 for ; Sat, 11 Feb 2023 08:29:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=xu9mcInCwwIYMeQ1IznATpvpYGKhZOIfC5SjazOQMmk=; b=dqxZ7Qq4GzQf40UKZF3bfkS6MM1agHlMxpfKPmihjnqEwBGz/EvfG2GDbRkzROATZ6 pTfGGsTWKoWWF01mEdIIONzHh+X//0d98ds9qpjXYcxFupwat9g4sQRs7vIwjLF1+db3 HXmiSXvvIdjEs+gheWMck5e6PiAPk1QlcC/Fct47YV6s8Dx38nyPZlwlvji6eEcD/9mz f2EDkeq1BUEl2s3EaqHIzTUGVDiRlLCJWT8gN66RxZlqTAMhNGiHB1eiGG5dhwNYGcje 9hsGkqD3cQsYvet5S+QChxcQ3JmpwNKEycd1Dt3Jy8qiYjUl7B5KCvBuS0wygGezFX1v 1sHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=xu9mcInCwwIYMeQ1IznATpvpYGKhZOIfC5SjazOQMmk=; b=W8x1UCQInnND0Lo++QwrW2NrZetoRHMgvo+rU7Z8kdqZi4Ma0jbeztCkGe9C99amgj Pr0d+SMXenq0pRsk6Rj1PYeeJbs2jEbONoWE0T+xV2vA4Z78WOZgLk1YjGiGCH58AYRh i+Cu3Sd01xCakb3CO/SzASqWh5Ml5uP7LWY3rqL/39dWwuq5s2OD+b9bYE2XY4YiCawV xdiMOSngL6B9LHiPdVeZucQ+mcRyg9IfdvbEXhSh7ZdHi7HSOEo76Nf/63xvlx7bqN3Q 0clVhTl1DuonZKA2Rt82rSdml73fO4J3kWoOjRI5D8GtbDYBoTWrsNBwrM7xRDUtxyh5 GZWA== X-Gm-Message-State: AO0yUKVIrdHUAFN0xh2ynUsWZwATvLhvt5N36G2eQFcAFmQiItU+KeZV TnJdiV2h1yt+ijZK3mBMIuMzludfz0EIQg== X-Received: by 2002:a17:906:f209:b0:878:6477:d7 with SMTP id gt9-20020a170906f20900b00878647700d7mr18322598ejb.72.1676132942280; Sat, 11 Feb 2023 08:29:02 -0800 (PST) Received: from mariano (94-37-133-75.adsl-ull.clienti.tiscali.it. [94.37.133.75]) by smtp.gmail.com with ESMTPSA id ci4-20020a170906c34400b0087873afb1b4sm4018682ejb.41.2023.02.11.08.29.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Feb 2023 08:29:01 -0800 (PST) Received: by mariano (Postfix, from userid 1000) id E29A0BFB73; Sat, 11 Feb 2023 17:29:00 +0100 (CET) From: Stefano Sabatini To: FFmpeg development discussions and patches Date: Sat, 11 Feb 2023 17:29:00 +0100 Message-Id: <20230211162900.125018-1-stefasab@gmail.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/3] ffmpeg: review -dts_delta_threshold and -dts_delta_error options 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: Stefano Sabatini Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: kUQqSjjEixoW Review handling of -dts_delta_threshold and -dts_delta_error options in order to simplify a bit the logic and improve logging. --- fftools/ffmpeg.c | 101 +++++++++++++++++++++++++---------------- fftools/ffmpeg.h | 2 + fftools/ffmpeg_demux.c | 3 ++ 3 files changed, 68 insertions(+), 38 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 064ec6d4b3..22287f6a5e 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -3671,62 +3671,87 @@ static void decode_flush(InputFile *ifile) static void ts_discontinuity_detect(InputFile *ifile, InputStream *ist, AVPacket *pkt) { - const int fmt_is_discont = ifile->ctx->iformat->flags & AVFMT_TS_DISCONT; + const int fmt_is_discont = !!(ifile->ctx->iformat->flags & AVFMT_TS_DISCONT); int disable_discontinuity_correction = copy_ts; int64_t pkt_dts = av_rescale_q_rnd(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); + char ist_desc[32]; + snprintf(ist_desc, sizeof(ist_desc), "input stream #%d:%d", ist->file_index, ist->st->index); + +#define BASE_TS(ts_) av_ts2timestr(ts_, &AV_TIME_BASE_Q) +#define PKT_TS(ts_) av_ts2timestr(ts_, &ist->st->time_base) + + av_log(NULL, AV_LOG_TRACE, + "ts discontinuity detection on %s pkt_dts:%s pkt_pts:%s next_dts:%s last_ts:%s fmt_discont:%d copy_ts:%d\n", + ist_desc, PKT_TS(pkt->dts), PKT_TS(pkt->pts), + BASE_TS(ist->next_dts), BASE_TS(ifile->last_ts), + fmt_is_discont, copy_ts); if (copy_ts && ist->next_dts != AV_NOPTS_VALUE && fmt_is_discont && ist->st->pts_wrap_bits < 60) { int64_t wrap_dts = av_rescale_q_rnd(pkt->dts + (1LL<st->pts_wrap_bits), ist->st->time_base, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); - if (FFABS(wrap_dts - ist->next_dts) < FFABS(pkt_dts - ist->next_dts)/10) + if (FFABS(wrap_dts - ist->next_dts) < FFABS(pkt_dts - ist->next_dts)/10) { disable_discontinuity_correction = 0; + av_log(NULL, AV_LOG_DEBUG, + "wrapped ts detected in copy_ts, enabled discontinuity correction\n"); + } } - if (ist->next_dts != AV_NOPTS_VALUE && !disable_discontinuity_correction) { - int64_t delta = pkt_dts - ist->next_dts; +#define CHECK_INVALID_TS(delta_, ts_type_, ts_) \ + if (FFABS(delta_) > ist->dts_error_threshold) { \ + av_log(NULL, AV_LOG_WARNING, \ + "drop invalid " #ts_type_ ":%s on %s delta:%s > dts_error_threshold:%s on %s\n", \ + PKT_TS(ts_), BASE_TS(delta), ist_desc, BASE_TS(ist->dts_error_threshold), ist_desc); \ + ts_ = AV_NOPTS_VALUE; \ + } + + if (!disable_discontinuity_correction) { + int64_t delta; + if (fmt_is_discont) { - if (FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE || - pkt_dts + AV_TIME_BASE/10 < FFMAX(ist->pts, ist->dts)) { - ifile->ts_offset_discont -= delta; - av_log(NULL, AV_LOG_DEBUG, - "timestamp discontinuity for stream #%d:%d " - "(id=%d, type=%s): %"PRId64", new offset= %"PRId64"\n", - ist->file_index, ist->st->index, ist->st->id, - av_get_media_type_string(ist->par->codec_type), - delta, ifile->ts_offset_discont); - pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); - if (pkt->pts != AV_NOPTS_VALUE) - pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); - } - } else { - if (FFABS(delta) > 1LL * dts_error_threshold * AV_TIME_BASE) { - av_log(NULL, AV_LOG_WARNING, "DTS %"PRId64", next:%"PRId64" st:%d invalid dropping\n", pkt->dts, ist->next_dts, pkt->stream_index); - pkt->dts = AV_NOPTS_VALUE; + delta = + ist->next_dts != AV_NOPTS_VALUE ? pkt_dts - ist->next_dts : + ifile->last_ts != AV_NOPTS_VALUE ? pkt_dts - ifile->last_ts : + AV_NOPTS_VALUE; + + if (delta != AV_NOPTS_VALUE) { + char fix_delta = 0; + int64_t dts_limit = FFMAX(ist->pts, ist->dts) - AV_TIME_BASE/10; + + if (FFABS(delta) > ist->dts_delta_threshold) { + av_log(NULL, AV_LOG_DEBUG, + "detected dts:%s delta:%s > dts_delta_threshold:%s on %s\n", + BASE_TS(pkt_dts), BASE_TS(delta), BASE_TS(ist->dts_delta_threshold), + ist_desc); + fix_delta = 1; + } else if (ist->next_dts != AV_NOPTS_VALUE && pkt_dts < dts_limit) { + av_log(NULL, AV_LOG_DEBUG, "detected dts:%s < dts_limit:%s on %s\n", + BASE_TS(pkt_dts), BASE_TS(dts_limit), ist_desc); + fix_delta = 1; + } + + if (fix_delta) { + ifile->ts_offset_discont -= delta; + pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); + if (pkt->pts != AV_NOPTS_VALUE) + pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); + av_log(NULL, AV_LOG_DEBUG, + "ts delta:%s applied -> ts_offset_discont:%s dts:%s pts:%s on %s\n", + BASE_TS(-delta), BASE_TS(ifile->ts_offset_discont), + PKT_TS(pkt->dts), PKT_TS(pkt->pts), ist_desc); + } } - if (pkt->pts != AV_NOPTS_VALUE){ + } else if (ist->next_dts != AV_NOPTS_VALUE) { + delta = pkt_dts - ist->next_dts; + CHECK_INVALID_TS(delta, dts, pkt->dts); + if (pkt->pts != AV_NOPTS_VALUE) { int64_t pkt_pts = av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q); delta = pkt_pts - ist->next_dts; - if (FFABS(delta) > 1LL * dts_error_threshold * AV_TIME_BASE) { - av_log(NULL, AV_LOG_WARNING, "PTS %"PRId64", next:%"PRId64" invalid dropping st:%d\n", pkt->pts, ist->next_dts, pkt->stream_index); - pkt->pts = AV_NOPTS_VALUE; - } + CHECK_INVALID_TS(delta, pts, pkt->pts); } } - } else if (ist->next_dts == AV_NOPTS_VALUE && !copy_ts && - fmt_is_discont && ifile->last_ts != AV_NOPTS_VALUE) { - int64_t delta = pkt_dts - ifile->last_ts; - if (FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE) { - ifile->ts_offset_discont -= delta; - av_log(NULL, AV_LOG_DEBUG, - "Inter stream timestamp discontinuity %"PRId64", new offset= %"PRId64"\n", - delta, ifile->ts_offset_discont); - pkt->dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); - if (pkt->pts != AV_NOPTS_VALUE) - pkt->pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); - } } ifile->last_ts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index f1412f6446..686d38c934 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -368,6 +368,8 @@ typedef struct InputStream { int64_t next_pts; ///< synthetic pts for the next decode frame (in AV_TIME_BASE units) int64_t pts; ///< current pts of the decoded frame (in AV_TIME_BASE units) int wrap_correction_done; + int64_t dts_delta_threshold; ///< dts_delta_threshold value rescaled to AV_TIME_BASE units + int64_t dts_error_threshold; ///< dts_error_threshold value rescaled to AV_TIME_BASE units // the value of AVCodecParserContext.repeat_pict from the AVStream parser // for the last packet returned from ifile_get_packet() diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c index 98da0678f5..18f8ed8946 100644 --- a/fftools/ffmpeg_demux.c +++ b/fftools/ffmpeg_demux.c @@ -736,6 +736,9 @@ static void add_input_streams(const OptionsContext *o, Demuxer *d) ist->filter_in_rescale_delta_last = AV_NOPTS_VALUE; ist->prev_pkt_pts = AV_NOPTS_VALUE; + ist->dts_delta_threshold = 1LL * dts_delta_threshold * AV_TIME_BASE; + ist->dts_error_threshold = 1LL * dts_error_threshold * AV_TIME_BASE; + ist->dec_ctx = avcodec_alloc_context3(ist->dec); if (!ist->dec_ctx) report_and_exit(AVERROR(ENOMEM));