From patchwork Sat Dec 15 01:31:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Jan_Ekstr=C3=B6m?= X-Patchwork-Id: 11419 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 B2D7D44D24A for ; Sat, 15 Dec 2018 03:37:15 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D10C368A9FB; Sat, 15 Dec 2018 03:37:15 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lj1-f194.google.com (mail-lj1-f194.google.com [209.85.208.194]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8F04268AB1F for ; Sat, 15 Dec 2018 03:37:09 +0200 (EET) Received: by mail-lj1-f194.google.com with SMTP id 83-v6so6416530ljf.10 for ; Fri, 14 Dec 2018 17:37:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=I3EHSU7LkoBG8JYrFg/NElQc4+mCoHWFHlQBOir8sqE=; b=Y+GgIE3byPp2mBigv64cinfdNE9lF5Y4nWOBugXQGlTrUBEeLYMFQNi4SZHm+JDTtM YFSsSKe9WnrScnWecwKNnU5xUFLqa0+XkiXsEmLK9uOv7Q8wML4wzr906kLrMPDMykkO eg3ydPNknRY9wTNfSe/uaDvxHXu+fj4k6WPaKFhV8Uu83F4bQeaKTvWgpucSTZiYOdYw DcNOSR730t5RK3WH6PC+70uvVltKmP1MJxn4K83csZEiAe0OVZw3JYMHavMHUURhgskU L4qLIZmU7x4Ddt9aNcMn5vCFEZlLZUpw6ZzXWMkxbXWndYwQFZDEZxa6fZgt1zPzVA3r JrbA== 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:mime-version :content-transfer-encoding; bh=I3EHSU7LkoBG8JYrFg/NElQc4+mCoHWFHlQBOir8sqE=; b=nDknCLDRiopWwdYEXkH0uBjgLiPeP7iYVAZeEyNss8CuDKwrH5ah2rsof/UILFJ9WY fasDo9szQIFkvLgsjfy9qOihGk6ZDr3OGH4HZY1WA5sWLtpnLNW2aM8xKgtbxD4jMbC2 cEoZZ6WAr8AZ+MGabPAFsUhjpxS1FcMswOrNBEGCpQg9PNFWB6OfPXiAxM4v6hC5BYYT jbAXXxnruo2FJEoCjhEE2EwVfosDU453UCZP4jWByUuLkNdPVsA60Eyp8kFlEp+PT0CE s3vaTRnsOzBqr5daz8iKAiWGk3MNTHvk6vGP+7DfBeVPlf5EsRGFu6P3ivkmyohbBvma ePTQ== X-Gm-Message-State: AA+aEWYZMi9ZEjsqX+ApYp+fT7jz+hDtVCvnBCPNKA9fTpq4QRb6UH/F e9mMSJwrFmlHOjcDhuR7GgHqKmH/ X-Google-Smtp-Source: AFSGD/X1/q/pchfvxX9NSoDgQ2Rzo0KBpUt7MxRu9S/ejUeiwebLciZ5YKayxda+o7vnSZrx95F6Ig== X-Received: by 2002:a2e:9107:: with SMTP id m7-v6mr3041415ljg.23.1544837506057; Fri, 14 Dec 2018 17:31:46 -0800 (PST) Received: from localhost.localdomain (91-159-194-103.elisa-laajakaista.fi. [91.159.194.103]) by smtp.gmail.com with ESMTPSA id h85-v6sm1142715ljf.68.2018.12.14.17.31.45 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 14 Dec 2018 17:31:45 -0800 (PST) From: =?UTF-8?q?Jan=20Ekstr=C3=B6m?= To: ffmpeg-devel@ffmpeg.org Date: Sat, 15 Dec 2018 03:31:44 +0200 Message-Id: <20181215013144.21623-1-jeebjp@gmail.com> X-Mailer: git-send-email 2.20.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] avformat/mpegts: skip subtitle PES packets if PCR not available 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" Fixes issues when a subtitle packet is received before PCR for the program has been received, leading to wildly jumping timestamps on the lavf client side as well as in the re-ordering logic. This usually happens in case of multiplexes where the PCR of a program is not taken into account with subtitle tracks' DTS/PTS. In case someone actually wants to pass through all received packets, the behavior can be controlled with an AVOption. --- libavformat/mpegts.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index edf6b5701d..50404e8272 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -59,6 +59,12 @@ enum MpegTSFilterType { MPEGTS_PCR, }; +enum MpegTSPESSkipMode { + MPEGTS_PES_SKIP_MODE_SUBTITLES = 0, + MPEGTS_PES_SKIP_MODE_NONE, + MPEGTS_PES_SKIP_MODE_MAX, +}; + typedef struct MpegTSFilter MpegTSFilter; typedef int PESCallback (MpegTSFilter *f, const uint8_t *buf, int len, @@ -150,6 +156,8 @@ struct MpegTSContext { int resync_size; int merge_pmt_versions; + enum MpegTSPESSkipMode pes_packet_skip_mode; + /******************************************/ /* private mpegts data */ /* scan context */ @@ -182,6 +190,10 @@ static const AVOption options[] = { {.i64 = 0}, 0, 1, 0 }, {"skip_clear", "skip clearing programs", offsetof(MpegTSContext, skip_clear), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, 0 }, + {"skip_pes_packets_without_pcr", "Skip PES packets without PCR matching to rule", offsetof(MpegTSContext, pes_packet_skip_mode), AV_OPT_TYPE_INT, + {.i64 = MPEGTS_PES_SKIP_MODE_SUBTITLES}, MPEGTS_PES_SKIP_MODE_SUBTITLES, MPEGTS_PES_SKIP_MODE_MAX - 1, AV_OPT_FLAG_DECODING_PARAM , "skip_pes_packets_without_pcr"}, + { "subtitles", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_PES_SKIP_MODE_SUBTITLES }, INT_MIN, INT_MAX, AV_OPT_FLAG_DECODING_PARAM, "skip_pes_packets_without_pcr" }, + { "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_PES_SKIP_MODE_NONE }, INT_MIN, INT_MAX, AV_OPT_FLAG_DECODING_PARAM, "skip_pes_packets_without_pcr" }, { NULL }, }; @@ -1219,6 +1231,7 @@ skip: || pes->st->codecpar->codec_id == AV_CODEC_ID_DVB_SUBTITLE) ) { AVProgram *p = NULL; + int pcr_found = 0; while ((p = av_find_program_from_stream(pes->stream, p, pes->st->index))) { if (p->pcr_pid != -1 && p->discard != AVDISCARD_ALL) { MpegTSFilter *f = pes->ts->pids[p->pcr_pid]; @@ -1242,6 +1255,7 @@ skip: // and the pcr error to this packet should be no more than 100 ms. // TODO: we should interpolate the PCR, not just use the last one int64_t pcr = f->last_pcr / 300; + pcr_found = 1; pes->st->pts_wrap_reference = st->pts_wrap_reference; pes->st->pts_wrap_behavior = st->pts_wrap_behavior; if (pes->dts == AV_NOPTS_VALUE || pes->dts < pcr) { @@ -1258,6 +1272,14 @@ skip: } } } + + if (!pcr_found && + ts->pes_packet_skip_mode != MPEGTS_PES_SKIP_MODE_NONE) { + av_log(pes->stream, AV_LOG_VERBOSE, + "Skipping non-trustworthy PES packet for PID %d as PCR hasn't been received yet.\n", + pes->pid); + pes->state = MPEGTS_SKIP; + } } } break;