From patchwork Tue Dec 4 18:19:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adrian_Trzci=C5=84ski?= X-Patchwork-Id: 11277 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 6F4AD44C4CF for ; Tue, 4 Dec 2018 20:19:44 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1387A68A58F; Tue, 4 Dec 2018 20:19:36 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-vs1-f43.google.com (mail-vs1-f43.google.com [209.85.217.43]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 94A0968A05D for ; Tue, 4 Dec 2018 20:19:29 +0200 (EET) Received: by mail-vs1-f43.google.com with SMTP id v10so10399501vsv.12 for ; Tue, 04 Dec 2018 10:19:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vewd-com.20150623.gappssmtp.com; s=20150623; h=mime-version:from:date:message-id:subject:to; bh=opUEBAiD2/OgfPpGCDOP6+AiInGplO/vhLgpikyaPv8=; b=SvI914KIYyXHLSUTABu/U7hN1FiaKvO4eOH7ZjCT6Cvuqy6RUcbv0te/tfp11+E0RX AVF8FpqmUotq5Agb1nn2Wm2tcukhEnlBwKUPzWkUsCXe/xH+lyULXT30hGzjwjy5+2mC L80gK8s4WYbE26/G/Cou1Ngy5Dvw/PxUneliLNpR9y4/nxv0hQ8LEjT9RNfqI2NbIsQp knjYp4c5zJE8YxrFwNDskxp1WiY2TpW7PMCD7C3HuQRPmYN26kucekcMEwhMMn9JlJhp 7es30ej0O1+zxEKcFjSkk5CAFr2ncpdCs4KeEXD4z41RSgg6hy3QwC3yv8KCT0EEkt6s ExVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=opUEBAiD2/OgfPpGCDOP6+AiInGplO/vhLgpikyaPv8=; b=FfuKWpMR/nPYML7FOUElQfDd9LBYPkChR4cKGcG1T471uyzsum4cW/196Ctu2iLDPa B1yRcIAhvAOH8dh+r7IiFP9TDWTRuWqWVn1lKfAIYKizPP3r9FGpz6yByHzMUqPEOnP8 ubLvNWUpN9nBXAFZnQ1IfhstoXPtr9lWYnfpMwtUsLYl34pi1BbSMdV7ewnPA7KGEzUa A0iEV9kXLazKi3K6ayFV6eNwLVBZfn8CE9x81I7D/uEC+eGWdh6hQoPhR1Gt7mOqTvQw i64gkuNr8CTcpsbkzY9+yVCdhZg8zplVUuEPkTG5EG6nFVMg2wWhdjYK+uy1LxHNWwcU kTzQ== X-Gm-Message-State: AA+aEWbOLxIOKtdJY4N8zAwQTGENb003zo25oEg9P9NgpvrfxD+OHdVm SodXH051mFKoenxuLFa0v9ejqs4RC0nhUSLpyGnGc0ru5uk= X-Google-Smtp-Source: AFSGD/X0QrNdQTEWC8v8d7D2y/LuKJLfTSsxM5hI2Uvj6o/yMOWm1umWz/SwMQolmmsnFzXCCnpXpBeUTXhi4QhuDTY= X-Received: by 2002:a67:ad0b:: with SMTP id t11mr8992999vsl.170.1543947576138; Tue, 04 Dec 2018 10:19:36 -0800 (PST) MIME-Version: 1.0 From: =?UTF-8?Q?Adrian_Trzci=C5=84ski?= Date: Tue, 4 Dec 2018 19:19:24 +0100 Message-ID: To: ffmpeg-devel@ffmpeg.org X-Content-Filtered-By: Mailman/MimeDel 2.1.20 Subject: [FFmpeg-devel] [FFmpeg-trac] #7592(avformat:new): FFmpeg download data twice 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" In case of data muxed in a way, that video and audio packets for the same ptses are more than 1 sec distant (so when ff_configure_buffers_for_index changes size of AVIOContext buffers to 2 * biggest_distance_between_data_for_1_sec_pts) FFmpeg fetches the same data twice from the server. This is because in fill_buffer in aviobuf.c when we need data audio from pts x that we don't currently have in buffer, we drop the whole buffer and download new range. But afterward, we need video from pts x, which was in buffer already (before seek caused by audio), so we drop buffer again and seek to this position. The patch changes the mechanism of data reading in aviobuf.c/fill_buffer. If data aren't in buffer new mechanism still leaves one time_unit of data in a buffer for further seeks to the same pts but in a different stream (it needs to be within one time_unit, it is calculated in ff_configure_buffers_for_index). From 71cadd60a2f71d2d39bd7999e080c206291b55da Mon Sep 17 00:00:00 2001 From: Adrian Trzcinski Date: Tue, 4 Dec 2018 19:00:22 +0100 Subject: [PATCH] avformat/avio: fill_buffer drops less data Signed-off-by: Adrian Trzcinski --- libavformat/avio.h | 1 + libavformat/aviobuf.c | 21 ++++++++++++++++----- libavformat/utils.c | 1 + 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/libavformat/avio.h b/libavformat/avio.h index 75912ce6be..c44e1c7e9c 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -225,6 +225,7 @@ typedef struct AVIOContext { */ unsigned char *buffer; /**< Start of the buffer. */ int buffer_size; /**< Maximum buffer size */ + int time_units_in_buffer; /**< Number of time units in buffer */ unsigned char *buf_ptr; /**< Current position in the buffer */ unsigned char *buf_end; /**< End of the data, may be less than buffer+buffer_size if the read function returned diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 5a33f82950..afccc61491 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -92,6 +92,7 @@ int ffio_init_context(AVIOContext *s, s->buffer = buffer; s->orig_buffer_size = s->buffer_size = buffer_size; + s->time_units_in_buffer = 0; s->buf_ptr = buffer; s->buf_ptr_max = buffer; s->opaque = opaque; @@ -550,9 +551,19 @@ static void fill_buffer(AVIOContext *s) { int max_buffer_size = s->max_packet_size ? s->max_packet_size : IO_BUFFER_SIZE; - uint8_t *dst = s->buf_end - s->buffer + max_buffer_size < s->buffer_size ? - s->buf_end : s->buffer; - int len = s->buffer_size - (dst - s->buffer); + int need_erase = !(s->buf_end - s->buffer + max_buffer_size < s->buffer_size); + uint8_t *dst = need_erase ? s->buffer : s->buf_end; + int len; + + if (need_erase && s->time_units_in_buffer > 1) { + const int bytes_in_time_unit = (s->buf_end - s->buffer) / s->time_units_in_buffer; + const int offset = bytes_in_time_unit * (s->time_units_in_buffer - 1); + memcpy(s->buffer, s->buffer + offset, bytes_in_time_unit); + dst = s->buf_end = s->buffer + bytes_in_time_unit; + s->buf_ptr = s->buf_ptr - s->buffer < offset ? s->buffer : s->buf_ptr - offset; + } + + len = s->buffer_size - (dst - s->buffer); /* can't fill the buffer without read_packet, just set EOF if appropriate */ if (!s->read_packet && s->buf_ptr >= s->buf_end) @@ -562,7 +573,7 @@ static void fill_buffer(AVIOContext *s) if (s->eof_reached) return; - if (s->update_checksum && dst == s->buffer) { + if (s->update_checksum && need_erase) { if (s->buf_end > s->checksum_ptr) s->checksum = s->update_checksum(s->checksum, s->checksum_ptr, s->buf_end - s->checksum_ptr); @@ -571,7 +582,7 @@ static void fill_buffer(AVIOContext *s) /* make buffer smaller in case it ended up large after probing */ if (s->read_packet && s->orig_buffer_size && s->buffer_size > s->orig_buffer_size) { - if (dst == s->buffer && s->buf_ptr != dst) { + if (need_erase && s->buf_ptr != dst) { int ret = ffio_set_buf_size(s, s->orig_buffer_size); if (ret < 0) av_log(s, AV_LOG_WARNING, "Failed to decrease buffer size\n"); diff --git a/libavformat/utils.c b/libavformat/utils.c index 93e588ee1e..62deaa710b 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2138,6 +2138,7 @@ void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance) av_log(s, AV_LOG_VERBOSE, "Reconfiguring buffers to size %"PRId64"\n", pos_delta); ffio_set_buf_size(s->pb, pos_delta); s->pb->short_seek_threshold = FFMAX(s->pb->short_seek_threshold, pos_delta/2); + s->pb->time_units_in_buffer = 2; } if (skip < (1<<23)) { -- 2.19.2