From patchwork Fri Mar 8 02:31:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andriy Gelman X-Patchwork-Id: 12239 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 A6037448877 for ; Fri, 8 Mar 2019 04:40:01 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 858C368A62F; Fri, 8 Mar 2019 04:40:01 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qt1-f195.google.com (mail-qt1-f195.google.com [209.85.160.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 30AE468A4BD for ; Fri, 8 Mar 2019 04:39:55 +0200 (EET) Received: by mail-qt1-f195.google.com with SMTP id d18so19678026qtg.12 for ; Thu, 07 Mar 2019 18:39:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=iAyfFUHAKaKHovIuBxEPjpWFyU0B56y2zQoo78DPiwU=; b=TM947L1seTel/pe+21vIqXsJT5i53RlMVvp1S4g3LWP3pwOxYssHFU0UtyWTN4UoWE vkJQZE4P3Awbk9AIlJjEEWgulOv87whvwBUfp6p+OH+jSlQckqcwE/pX5YPuQE4/mHao DBxONN26itP9A1kZkhoiE3EVdVxFUIc2NeCHHCsoevDTuePahclUGE29Sn76Sp1E4ii6 tfPTDlIrzQl5zU987dgtrH+/BsChX3Nu3ngP2FEmeG64Oxx3aGqEBf0+82C0xN6X6J2A eLhsIqCuXP1h7/XSYMgowWoWY9zOZv7LOsyDq5GUsxH86w8kgq2zEy8fkEhKdUOYyGBC Cv8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=iAyfFUHAKaKHovIuBxEPjpWFyU0B56y2zQoo78DPiwU=; b=DF91NTJPjN5curMPfAf7exBMmUZCp5s1jWBpg56g4/vyIP3DvpZYsOt65TBAEZDjnZ I7sur2WA3/1fCigrL5X3yXW6Amik3IzYBM6ks3FHYeo+7lq5xfnzmun277j+Ze+Bz8PN 1KFZ8OVMVl9ZsmMrdYq9hMWe92zY4EDoKE/V0KCEO0cw1zCjqZOIO4przqkzREBvHY93 VO3kSWHpawVLEwEYHClz/G0kFfzIespTubdxvAXWfxafJCdXa+ncTjCaGVU/Y6s8Jyom QV/Cq7Rdxq4dS0CODRSH0OW5zSoNcm8jtaaJaLg4+HMmTfyMJz7XP2U6hTXbJVWymgNk nYPg== X-Gm-Message-State: APjAAAUv47b9NFjgXiNT2Ut69cJoAFmN5QtPSspEFB4xZZKl1uWDAoIB RWprTH8znMOifXWdJEfFXahmD6fs X-Google-Smtp-Source: APXvYqx5C7soR1Kn3MA8Ydo/BTyxz95k4yIh1bPLZXmlqqIpgtKJ7qN3PzhB4ATsyCQO+HXB36ce2g== X-Received: by 2002:ac8:330d:: with SMTP id t13mr13139455qta.57.1552012288081; Thu, 07 Mar 2019 18:31:28 -0800 (PST) Received: from localhost.localdomain (c-24-60-253-205.hsd1.ma.comcast.net. [24.60.253.205]) by smtp.gmail.com with ESMTPSA id g82sm284713qkb.34.2019.03.07.18.31.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Mar 2019 18:31:27 -0800 (PST) From: Andriy Gelman X-Google-Original-From: Andriy Gelman To: ffmpeg-devel@ffmpeg.org Date: Thu, 7 Mar 2019 21:31:19 -0500 Message-Id: <20190308023119.8164-1-andriy.gelman@gmail.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v4] avformat/mpegts: reduce buffering during initialization 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 Cc: Andriy Gelman Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Andriy Gelman Reduces buffering latency with low bitrate streams, where 8192 bytes can mean several seconds. --- libavformat/mpegts.c | 59 +++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b04fd7b4f4..88e2150d55 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -53,6 +53,9 @@ (prev_dividend) = (dividend); \ } while (0) +#define PROBE_PACKET_MAX_BUF 8192 +#define PROBE_PACKET_MARGIN 5 + enum MpegTSFilterType { MPEGTS_PES, MPEGTS_SECTION, @@ -591,28 +594,42 @@ static int analyze(const uint8_t *buf, int size, int packet_size, return best_score - FFMAX(stat_all - 10*best_score, 0)/10; } -/* autodetect fec presence. Must have at least 1024 bytes */ -static int get_packet_size(const uint8_t *buf, int size) +/* autodetect fec presence */ +static int get_packet_size(AVIOContext* pb) { int score, fec_score, dvhs_score; + int margin; + int ret; - if (size < (TS_FEC_PACKET_SIZE * 5 + 1)) - return AVERROR_INVALIDDATA; + /*init buffer to store stream for probing */ + uint8_t buf[PROBE_PACKET_MAX_BUF] = {0}; + int buf_size = 0; - score = analyze(buf, size, TS_PACKET_SIZE, 0); - dvhs_score = analyze(buf, size, TS_DVHS_PACKET_SIZE, 0); - fec_score = analyze(buf, size, TS_FEC_PACKET_SIZE, 0); - av_log(NULL, AV_LOG_TRACE, "score: %d, dvhs_score: %d, fec_score: %d \n", - score, dvhs_score, fec_score); - - if (score > fec_score && score > dvhs_score) - return TS_PACKET_SIZE; - else if (dvhs_score > score && dvhs_score > fec_score) - return TS_DVHS_PACKET_SIZE; - else if (score < fec_score && dvhs_score < fec_score) - return TS_FEC_PACKET_SIZE; - else - return AVERROR_INVALIDDATA; + while (buf_size < PROBE_PACKET_MAX_BUF) { + ret = avio_read_partial(pb, buf + buf_size, PROBE_PACKET_MAX_BUF - buf_size); + if (ret < 0) + return AVERROR_INVALIDDATA; + buf_size += ret; + + score = analyze(buf, buf_size, TS_PACKET_SIZE, 0); + dvhs_score = analyze(buf, buf_size, TS_DVHS_PACKET_SIZE, 0); + fec_score = analyze(buf, buf_size, TS_FEC_PACKET_SIZE, 0); + av_log(NULL, AV_LOG_TRACE, "Probe: %d, score: %d, dvhs_score: %d, fec_score: %d \n", + buf_size, score, dvhs_score, fec_score); + + if (buf_size < PROBE_PACKET_MAX_BUF) + margin = PROBE_PACKET_MARGIN; /*if buffer not filled */ + else + margin = 0; + + if (score > FFMAX(fec_score, dvhs_score) + margin) + return TS_PACKET_SIZE; + else if (dvhs_score > FFMAX(score, fec_score) + margin) + return TS_DVHS_PACKET_SIZE; + else if (fec_score > FFMAX(score, dvhs_score) + margin) + return TS_FEC_PACKET_SIZE; + } + return AVERROR_INVALIDDATA; } typedef struct SectionHeader { @@ -2841,8 +2858,6 @@ static int mpegts_read_header(AVFormatContext *s) { MpegTSContext *ts = s->priv_data; AVIOContext *pb = s->pb; - uint8_t buf[8 * 1024] = {0}; - int len; int64_t pos, probesize = s->probesize; s->internal->prefer_codec_framerate = 1; @@ -2850,10 +2865,8 @@ static int mpegts_read_header(AVFormatContext *s) if (ffio_ensure_seekback(pb, probesize) < 0) av_log(s, AV_LOG_WARNING, "Failed to allocate buffers for seekback\n"); - /* read the first 8192 bytes to get packet size */ pos = avio_tell(pb); - len = avio_read(pb, buf, sizeof(buf)); - ts->raw_packet_size = get_packet_size(buf, len); + ts->raw_packet_size = get_packet_size(pb); if (ts->raw_packet_size <= 0) { av_log(s, AV_LOG_WARNING, "Could not detect TS packet size, defaulting to non-FEC/DVHS\n"); ts->raw_packet_size = TS_PACKET_SIZE;