From patchwork Tue Mar 5 03:21:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andriy Gelman X-Patchwork-Id: 12195 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 845CD448C52 for ; Tue, 5 Mar 2019 05:27:16 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5C925689F1A; Tue, 5 Mar 2019 05:27:16 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qt1-f194.google.com (mail-qt1-f194.google.com [209.85.160.194]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8CF8E68095C for ; Tue, 5 Mar 2019 05:27:09 +0200 (EET) Received: by mail-qt1-f194.google.com with SMTP id d2so7572399qti.11 for ; Mon, 04 Mar 2019 19:27:09 -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=6Un+LGY5X+hNOe4ssjlXTe6gmv3fyOXAIk6yLB1z99U=; b=IR0Npes/9ltOwxGDJurXfEL+zE93cJfi8IE4IKYi7PThbh09h1hsGi+Oe1yNKozCAP 8DnTfprSTIcu8qDeUE1SUiv7p6r5eK9kNSUYXI5KSHYAkQ3VkeOpcGr9KNHqaJVBUlBg gh6R96+OX7wiOmzr4BEeVHWOO1MsnDUMzfzPHGSehXe18nYp/gsI4ypSq6ycwza8CnRX rnbp6sBXiwlJSAtml5I2XIIxGvaMIVtpFJ7WOflQCh9IMrrbtbzW9XNoU/n4abRE7L5h PAm1ZvI1hQEHuPFu1aLHeCorNBjw9GbTL2fNGdyrfIrlwd1M2NQNhcavLfnZ6cO4W3OR b9Pw== 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=6Un+LGY5X+hNOe4ssjlXTe6gmv3fyOXAIk6yLB1z99U=; b=l/L/P/CCMaqP+C+GL5QKgUPimKNOC52Kf8eV3AK9g+qjZGACfLw4ZxwFXqCljf3QRW jQ5r7HtvmxdwTZlvgr2ZLhdMC94sFdmRkpvBvGOKMVRQfKJ3XHHwtmV+YGtiZNBzmYeX VVJ2UslV2EzVbUaxo3mv30RLyCQUV9NrzkvxuU6UPvMicQhEU3U3w6rVwtEy2W1xRoaF HjzaN6auMxdkJzboIfU6NO9tGCIJAjcbUESuKlrDBx3BearOR5BADFXtgfC2ZDCpvSOu Ywo05tvRa/kSPfLjQDxoGGnMuna05mubcrdkInucdDj5YxHiNVIkzg9ZqJpxBIbiXrjR xsBg== X-Gm-Message-State: APjAAAV5Mkns/yCLykjezaOukYzRIH5p+I5L+cfOqWE7fODQ0BMEX99u K9j5HC8sPHwvQgeG6wHQkrpecPN3 X-Google-Smtp-Source: APXvYqy8POuY3bOCD2ZGIZZkLT2d2NLjmhOmz/6uJdX817J15k2oV4aJDoFjZEwMt1mv/+ftaDp+5g== X-Received: by 2002:a0c:ac93:: with SMTP id m19mr485506qvc.27.1551756086665; Mon, 04 Mar 2019 19:21:26 -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 h10sm9471151qta.3.2019.03.04.19.21.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 04 Mar 2019 19:21:26 -0800 (PST) From: andriy.gelman@gmail.com To: ffmpeg-devel@ffmpeg.org Date: Mon, 4 Mar 2019 22:21:01 -0500 Message-Id: <20190305032101.18661-1-andriy.gelman@gmail.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] avformat/mpegts.c: 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 during estimation of mpegts raw_packet_size parameter. Instead of buffering a fixed 8192 bytes, calculate probe scores on a smaller buffer. Increase buffer size until probe score is greater than minimum value. --- libavformat/mpegts.c | 82 +++++++++++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 23 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b04fd7b4f4..a7b33eae69 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -53,6 +53,10 @@ (prev_dividend) = (dividend); \ } while (0) +#define MAX_RAW_PACKET_PROBE 8192 +#define PROBE_PACKET_STEP 512 +#define RAW_PACKET_MIN_SCORE 10 + enum MpegTSFilterType { MPEGTS_PES, MPEGTS_SECTION, @@ -591,28 +595,64 @@ 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 pd_packet_size = TS_PACKET_SIZE; + int best_score = 0; + int ret; - if (size < (TS_FEC_PACKET_SIZE * 5 + 1)) - return AVERROR_INVALIDDATA; + AVProbeData pd = { 0 }; + while (best_score < RAW_PACKET_MIN_SCORE && + pd.buf_size + PROBE_PACKET_STEP <= MAX_RAW_PACKET_PROBE) { + + /*create extra space for next packet*/ + uint8_t *new_buf = av_realloc(pd.buf, pd.buf_size + PROBE_PACKET_STEP); + if (new_buf) { + pd.buf = new_buf; + ret = avio_read(pb, pd.buf + pd.buf_size, PROBE_PACKET_STEP); + if (ret < 0) { + av_log(pb, AV_LOG_ERROR, "Error reading from input: %s.\n", + av_err2str(ret)); + break; + } + pd.buf_size += ret; + } else + goto fail; + + /*check score for each fec packet size*/ + score = analyze(pd.buf, pd.buf_size, TS_PACKET_SIZE, 0); + if (score > best_score) { + best_score = score; + pd_packet_size = TS_PACKET_SIZE; + } - 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; + dvhs_score = analyze(pd.buf, pd.buf_size, TS_DVHS_PACKET_SIZE, 0); + if (dvhs_score > best_score) { + best_score = dvhs_score; + pd_packet_size = TS_DVHS_PACKET_SIZE; + } + + fec_score = analyze(pd.buf, pd.buf_size, TS_FEC_PACKET_SIZE, 0); + if (fec_score > best_score) { + best_score = fec_score; + pd_packet_size = TS_FEC_PACKET_SIZE; + } + + av_log(NULL, AV_LOG_TRACE, "Probe size: %d, score: %d, dvhs_score: %d, fec_score: %d \n", + pd.buf_size, score, dvhs_score, fec_score); + } + + if (pd.buf) + av_freep(&pd.buf); + + return pd_packet_size; + +fail: + if (pd.buf) + av_freep(&pd.buf); + return AVERROR(ENOMEM); } typedef struct SectionHeader { @@ -2841,8 +2881,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 +2888,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;