From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id D9E934A2A0 for ; Tue, 20 May 2025 15:27:38 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id 9AFBC68D84D; Tue, 20 May 2025 18:27:34 +0300 (EEST) Received: from mail-ed1-f45.google.com (mail-ed1-f45.google.com [209.85.208.45]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id 01C1768CA14 for ; Tue, 20 May 2025 18:27:27 +0300 (EEST) Received: by mail-ed1-f45.google.com with SMTP id 4fb4d7f45d1cf-60179d8e65fso669223a12.0 for ; Tue, 20 May 2025 08:27:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1747754847; x=1748359647; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=Nbp26YWLzwR+yVObLH0Ohbae5Sva6BjdxChiAY4REok=; b=lJ4uRKneO/U3NknIS8RjelUQZWEAKIs3+s606gIs/KuQUMJYC9I845bSj7m1D/ZUFw zsBrwO+cLxjQkJBHhBO5oGa4mZRTnE98jYeOhYzf9GI1Qh5GjS2AQJJhkjwKteLlY14V V/PROwQ9+96ywAIvU61QnPP17F1SlTDdrLcX0Orja7plAZuwD0xVPdF8pKv303bfFgAk AC3JzBUeyHE1EboRTcENZYv94cSBOH0g4+CzGLn7tZlSF4dzflX7x1hRY0TkdH1MwHw/ +mAyz+rui52HPtSWst3QmBx3NTuwmLk7wthHiu3sFR1YEolY3vHc0TLHDhvC3rjpAURl 8X+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747754847; x=1748359647; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Nbp26YWLzwR+yVObLH0Ohbae5Sva6BjdxChiAY4REok=; b=ClJW+KYoRIirUNf65uE43W3P10wld61HHcZ900QzRnx/T7Xuy7EpT/nkEZ4tU8W0lt itIIToRot2Q87wok71pc0TrpcTamLhpbwceteWIapllsbbJ7ewlvGEJwNEkWFeHObbd1 5FW42u5BtrJ6Nm1RAmWNa2AQv7hM8V3icvtLXDoy6AXptIV1GcFrXm0fCpBxBu9TO2Wk GxbduV1dszLlIuNc8Sc8ufW9mKi+SjmCbAVjS7igKL0fhAhaMzF8FrQnocfyKwtDA+Ur jEfo8ZSydXDuvmRy5/yj3GP8TyS+Cm3ijGqUeSD7EZZU+x19eNlqlAMDmZG5hdJ++GDW 7THA== X-Gm-Message-State: AOJu0YzwxxOZX2hmG5HZgI6B+o8HSnsoJrdNTnK5rreUY4oxSRzBIdcJ ZX72sf5jumodqDgrpOaqPhybolDv8N9NevarD24PB9AxNbk31qKJxdONqhAXJw== X-Gm-Gg: ASbGncs5mlqGcl6x7AFy9DsUUv+9sTlknUIqEZqyPN6l11JuWRXBPiIWPXQUJW2zFiU FnPPN0AYZLyBEFhZAl5eTVFa79NFZ1wUYXGLaEFtPWrMvQi4UsJfksb306lTRqgYPhFsjp6MvDv 5y5smlWwk9f8/93toz6b0Ltp22eUQW8jJBuYuh4tDobYO2ON5nSGnEeJdtdyEy8F89LuQvAWVNa qbLmiCslWv/V60NOjj5RLsWhrvhDWhVboLzlqqBJGp4MLCzDK/oaABr0cIkdqzn7laoTIg/6i7W kM+Dxrj335wE96Ve4D4lnhNJGnaFigzolUKiU0fibMzeXP1sb9W2P0cBdoPjjVsPOHo+3ab1eUZ scJN34z++HTZYiJvDYkPX X-Google-Smtp-Source: AGHT+IG7ARFcU7H4LPrK5Rl3cIQoaw2PQ5MpFhjjX+1canDJgoV37l2/KkenU68zo/4aVoUWls8IoA== X-Received: by 2002:a05:6402:5248:b0:5fb:f4a5:7871 with SMTP id 4fb4d7f45d1cf-60090076e17mr15846174a12.16.1747754846526; Tue, 20 May 2025 08:27:26 -0700 (PDT) Received: from localhost.localdomain (33bf1e4c.skybroadband.com. [51.191.30.76]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-6004d4f1ca8sm7352692a12.6.2025.05.20.08.27.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 20 May 2025 08:27:25 -0700 (PDT) From: Derek Buitenhuis To: ffmpeg-devel@ffmpeg.org Date: Tue, 20 May 2025 16:27:16 +0100 Message-ID: <20250520152717.15343-1-derek.buitenhuis@gmail.com> X-Mailer: git-send-email 2.49.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2] avformat/dhav: fix backward scanning for get_duration and optimize seeking X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: From: Justin Ruggles The backwards scanning done for incomplete final packets should not assume a specific alignment at the end of the file. Truncated files result in hundreds of thousands of seeks if the final packet does not fall on a specific byte boundary, which can be extremely slow. For example, with HTTP, each backwards seek results in a separate HTTP request. This changes the scanning to check for the end tag 1 byte at a time and buffers the last 1 MiB using ffio_ensure_seekback to avoid additional seek operations. Signed-off-by: Justin Ruggles Signed-off-by: Derek Buitenhuis --- Addresses Andreas' comments from the previous round. --- libavformat/dhav.c | 48 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/libavformat/dhav.c b/libavformat/dhav.c index b2ead99609..27e2f4db23 100644 --- a/libavformat/dhav.c +++ b/libavformat/dhav.c @@ -22,6 +22,7 @@ #include +#include "libavutil/intreadwrite.h" #include "libavutil/mem.h" #include "libavutil/parseutils.h" #include "avio_internal.h" @@ -232,34 +233,59 @@ static void get_timeinfo(unsigned date, struct tm *timeinfo) timeinfo->tm_sec = sec; } +#define MAX_DURATION_BUFFER_SIZE (1024*1024) + static int64_t get_duration(AVFormatContext *s) { DHAVContext *dhav = s->priv_data; int64_t start_pos = avio_tell(s->pb); + int64_t end_pos = -1; int64_t start = 0, end = 0; struct tm timeinfo; - int max_interations = 100000; + uint8_t *end_buffer; + int64_t end_buffer_size; + int64_t end_buffer_pos; + int64_t offset; + int ret; if (!s->pb->seekable) return 0; - avio_seek(s->pb, avio_size(s->pb) - 8, SEEK_SET); - while (avio_tell(s->pb) > 12 && max_interations--) { - if (avio_rl32(s->pb) == MKTAG('d','h','a','v')) { - int64_t seek_back = avio_rl32(s->pb); + end_buffer_size = FFMIN(MAX_DURATION_BUFFER_SIZE, avio_size(s->pb)); + end_buffer = av_malloc(end_buffer_size); + if (!end_buffer) + return 0; + end_buffer_pos = avio_size(s->pb) - end_buffer_size; + avio_seek(s->pb, end_buffer_pos, SEEK_SET); + ret = ffio_ensure_seekback(s->pb, end_buffer_size); + if (ret < 0) + return 0; + avio_read(s->pb, end_buffer, end_buffer_size); - avio_seek(s->pb, -seek_back, SEEK_CUR); - read_chunk(s); - get_timeinfo(dhav->date, &timeinfo); - end = av_timegm(&timeinfo) * 1000LL; + offset = end_buffer_size - 8; + while (offset > 0) { + if (AV_RL32(end_buffer + offset) == MKTAG('d','h','a','v')) { + int64_t seek_back = AV_RL32(end_buffer + offset + 4); + end_pos = end_buffer_pos + offset - seek_back + 8; break; } else { - avio_seek(s->pb, -12, SEEK_CUR); + offset -= 9; } } - avio_seek(s->pb, start_pos, SEEK_SET); + av_freep(&end_buffer); + + if (end_pos < 0) { + avio_seek(s->pb, start_pos, SEEK_SET); + return 0; + } + + avio_seek(s->pb, end_pos, SEEK_SET); + read_chunk(s); + get_timeinfo(dhav->date, &timeinfo); + end = av_timegm(&timeinfo) * 1000LL; + avio_seek(s->pb, start_pos, SEEK_SET); read_chunk(s); get_timeinfo(dhav->date, &timeinfo); start = av_timegm(&timeinfo) * 1000LL; -- 2.49.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".