From patchwork Thu Dec 6 12:28:54 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: 11304 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 7A0EF44C985 for ; Thu, 6 Dec 2018 14:36:39 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 28E2C68A73A; Thu, 6 Dec 2018 14:36:31 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ua1-f44.google.com (mail-ua1-f44.google.com [209.85.222.44]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D781268A6F3 for ; Thu, 6 Dec 2018 14:36:24 +0200 (EET) Received: by mail-ua1-f44.google.com with SMTP id j3so99847uap.3 for ; Thu, 06 Dec 2018 04:36:34 -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=gf5QVwgSi5urquMrXdE7Cka0fhd0qZ+efvnGW6Fc1Dw=; b=DleiGj1eis5lXz8QSWkRX9N/GluNHhOCB2G+ZygGVjoBPGJDmDsBYadIsr/UgqPnfD DXZQSFiv/IDOZjkgXKM7nn2MvWASl6oQ0JY+0UiYwnheEsrPVUBjm1wY/o9eImy2tLAt PcogAs22bngnsJz+0aT0DOG3jRpeoQUuc9orsPHXRWW2wkEvTRvYVVbiPBOmt9yPz02W xhpPn1QaiqNRyI2R8QPG2ImyCCGD35I7ZNu6Y4qRtPj+ecP3T/ndpKjkxO0QAsU2KCiq puZwPa2RKVxlxQ7g88yLP6EpGq0+8yaZz8I3rlYdwgNVIP6jsB0bYR0z2HHHB5VuJlJH zNag== 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=gf5QVwgSi5urquMrXdE7Cka0fhd0qZ+efvnGW6Fc1Dw=; b=BihXERGG6ActTJ6L7fODto5bv+Bxo8C+tUOFB6qMJ/m4IWUF+2fB51bUk5CvdfL68W MJLIBd4nflFa0/hpe0yenfh727Ll9wTNF1OfcDJLnoHKWWeOWxUJAG2nIQLffH3kcPQ/ eyqcLiYir7luIAw6FFVedNjtIPsLVinHuYLNKv7OcukML1JvnU0O3n32tuP3X8xSntBK AeYf2RIemLij230OddbxZCeU8Nqrw/P1c1hOscrqafxmOMVh3VJrcheD3c653ITfbML+ nYjLeJsRvStp37doWHm00435eDVGm6bHTweH9vuRa5Wb8EEopxokToYLlcdzC/Bu7eeE JB0w== X-Gm-Message-State: AA+aEWZyBeMWvx7U6Xqr5BdhMZLIQwviVksQdu1szVu8WA7y4wH+oKsm VFKBYM1f5Lausv+U4+D1h8zk7ETfkqecy/nBhawb754n5d8= X-Google-Smtp-Source: AFSGD/XcZcB3x/BMlZ1bgy4xgnDp+s+5dNILPfVuUG6mhtsGwhxJ61hrbL/HTccPrQqRdYhv6tB9Yw5R1UN6sVuzcDc= X-Received: by 2002:ab0:2314:: with SMTP id a20mr12633926uao.130.1544099345715; Thu, 06 Dec 2018 04:29:05 -0800 (PST) MIME-Version: 1.0 From: =?UTF-8?Q?Adrian_Trzci=C5=84ski?= Date: Thu, 6 Dec 2018 13:28:54 +0100 Message-ID: To: ffmpeg-devel@ffmpeg.org X-Content-Filtered-By: Mailman/MimeDel 2.1.20 Subject: [FFmpeg-devel] [PATCH] avformat/avio: don't 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" Like I wrote in #7592 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