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 17D204B875 for ; Wed, 21 May 2025 13:23:24 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id F04FA68D85B; Wed, 21 May 2025 16:23:20 +0300 (EEST) Received: from mail-ed1-f48.google.com (mail-ed1-f48.google.com [209.85.208.48]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id 6E64D68CEFB for ; Wed, 21 May 2025 16:23:14 +0300 (EEST) Received: by mail-ed1-f48.google.com with SMTP id 4fb4d7f45d1cf-601d10de7e1so5655048a12.1 for ; Wed, 21 May 2025 06:23:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1747833793; x=1748438593; 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=LDG0J/5jYMis+DPfcQqbkdOiFn2wz7ggH4A7gLX3Jac=; b=NeLgP3m0qnyR0E8WazJUi0i88QLC+0HLhEUIHQTHvl6mglCMGB1KdIEZvQw4PJN90E VsPwSY39VZTYTRM9kblFTbropZ8tvaeh+j78JFWyt0DyJ/IbcZpBI/ph5ibTCWYUrHgi 05Rp8Ur4x3CCZCD0b8B3bUkp+rlM9Og9xV5JPTL13o8+sYBnJO5Ec8sVNH7i7IpGEykA ANXtIdJHpd2nypB3ciDjyhrrrfh/b+Eahg09k6a7M7BZ10RDlTmiNRGLhi2SsC7g1GwM l1ph7kRk+jpMpSbvMazRr8tuf9eMk6TYm5e5qyxpxu6KHUV6oLK7XZUWTKPTEOhgbkVH ixLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747833793; x=1748438593; 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=LDG0J/5jYMis+DPfcQqbkdOiFn2wz7ggH4A7gLX3Jac=; b=FFnbxljar6xdq+q1E8AiWNUNlft6PgeR87Cj2GHNMO35rLo8IYGLnPvkW8kNPqelJs VU5hKAZDRB2CWi+oZZc77ml3TosXNm73zbhucbkfso9iBqei9r1zp42Q3evm21yMj5Hz AVHqptNEzbMBuCZGBTUBd/hqChua9TFHj6NnoJCgBgZcRGB8mxqRb5eNu+lzgtaFN26f ZGkt+WrQjJzHaS4zIf8kISjuLsmf/dZ2o/SPyrF70O7wfgbVvKxEEJ9SSQQl0gub73DS okkTbZM+TvNzFNXAWt+opaYHjbxPVtJhO+L4MrA3xeld5BOupKU5yOH6cWJnNx3kVQ2D eNkA== X-Gm-Message-State: AOJu0Yy+rt/CSkimdfQ6UQjSGJ8IiGLxvt8J5AajxKNXTJC8V9A8Q2NG 5vfu5x5eW8AYKsyRlHbxxNMtBiePptYZBxosGd5XjC2kdfFV3sQIr3oLdp4Hdg== X-Gm-Gg: ASbGncufJDKd+zl4bAg3RvpH0vVliFs5RLfSyTPruOXub7xM8hn2eWnPQzGn0A8ps9W 5dScIuOMAcGnxTuzwN1oD8JWwyGO4sPIW80j/FwDjB+RlF7g0leK1S8Ok916AslBQe/BLKL0y0P RI4vYq2NuZSOycm6YipbkPCWbr0bwUFdAfK5b2KEdwWHC6D3lirVDh0x7whnWf0FBiK0bnf56YB /9wW//W83aAnLeI8kPG/eMRADik1wGAsDfBNO0pnd0X0MI0H6/4k+J3C0yNP2XsiHQw6E5ylAOo E/giQyCHIFAQizqt9tSLvqpnnp85KUh/7W215NCy7DklWE8ejPcp6XExMsg1VrW0m5+CEmBUVit 8r10dLFW4oli8EvgJWRws X-Google-Smtp-Source: AGHT+IFN1dgOwYsqaEkZkGoExWyAMsQKzcrlp4+pZJy51ASgnQL48vosEj28V4KV9T3eUUAb7o/WOw== X-Received: by 2002:a17:907:7b86:b0:ad5:b09:115f with SMTP id a640c23a62f3a-ad536bca50dmr1943120766b.29.1747833793036; Wed, 21 May 2025 06:23:13 -0700 (PDT) Received: from localhost.localdomain (33bf1e4c.skybroadband.com. [51.191.30.76]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ad52d04e80asm897017966b.2.2025.05.21.06.23.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 May 2025 06:23:12 -0700 (PDT) From: Derek Buitenhuis To: ffmpeg-devel@ffmpeg.org Date: Wed, 21 May 2025 14:23:00 +0100 Message-ID: <20250521132300.32387-1-derek.buitenhuis@gmail.com> X-Mailer: git-send-email 2.49.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v3] 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. Co-authored-by: Derek Buitenhuis Signed-off-by: Justin Ruggles Signed-off-by: Derek Buitenhuis --- libavformat/dhav.c | 54 +++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/libavformat/dhav.c b/libavformat/dhav.c index b2ead99609..d9db775802 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,37 +233,60 @@ 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; + unsigned date; 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); + if (start_pos + 16 > avio_size(s->pb)) + return 0; - avio_seek(s->pb, -seek_back, SEEK_CUR); - read_chunk(s); - get_timeinfo(dhav->date, &timeinfo); - end = av_timegm(&timeinfo) * 1000LL; + avio_skip(s->pb, 16); + date = avio_rl32(s->pb); + get_timeinfo(date, &timeinfo); + start = av_timegm(&timeinfo) * 1000LL; + + end_buffer_size = FFMIN(MAX_DURATION_BUFFER_SIZE, avio_size(s->pb)); + end_buffer = av_malloc(end_buffer_size); + if (!end_buffer) { + avio_seek(s->pb, start_pos, SEEK_SET); + return 0; + } + end_buffer_pos = avio_size(s->pb) - end_buffer_size; + avio_seek(s->pb, end_buffer_pos, SEEK_SET); + avio_read(s->pb, end_buffer, end_buffer_size); + + 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); + if (end_pos < 0 || end_pos + 16 > end_buffer_pos + end_buffer_size) { + avio_seek(s->pb, start_pos, SEEK_SET); + return 0; + } - read_chunk(s); - get_timeinfo(dhav->date, &timeinfo); - start = av_timegm(&timeinfo) * 1000LL; + date = AV_RL32(end_buffer + (end_pos - end_buffer_pos) + 16); + get_timeinfo(date, &timeinfo); + end = av_timegm(&timeinfo) * 1000LL; avio_seek(s->pb, start_pos, SEEK_SET); -- 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".