From patchwork Wed Aug 3 13:18:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derek Buitenhuis X-Patchwork-Id: 37097 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:1649:b0:8b:613a:194d with SMTP id no9csp435840pzb; Wed, 3 Aug 2022 06:19:24 -0700 (PDT) X-Google-Smtp-Source: AA6agR7/KunvCpdcVFi6tZUDQz3fA3P5iENMYGB5q6iLW8maNwXnQTyvbnwYBb1ioeUA+iWztydJ X-Received: by 2002:a17:907:2c4a:b0:730:87ff:b69 with SMTP id hf10-20020a1709072c4a00b0073087ff0b69mr11063825ejc.116.1659532763721; Wed, 03 Aug 2022 06:19:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1659532763; cv=none; d=google.com; s=arc-20160816; b=kP65Cy9ZQuPtF0BrTYSrnAYxiTo8lp5HXx+297oqu0AcVyg+efukHcYnJQDhaCTegl yp6lkDekx61G1wU9nsomCDyztbWRAyRRP9Vb3SXyNt0zI+hmhQTHTEFqtim2PJlhNr0T fHoqvLZbsMltk/QqyfqkdlnYzw48nz6EAkemVQcpmUCPdV33l9+u/G6Pyrx3XG0f0cTl J5JHGU2TXKFrNEi+eyo1r565T6InwtwZk242R0ekPHTzErt0bhPJHdA6qj9PMsu/w2el LHiG+wft+qsSeBkPFUN1NLUACwDag4NxhoRqIQpno7VWI/K9E4UhdOIm8bh37to7AqSQ SKLQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to; bh=i15dyrz6/OlMGg/4IiE4yWNnakToIhZ/B1Infbou/kI=; b=osjC43ljUetU7YiuCilZg3G18sdBo32oG16gwR7JTsip9TvMHF34lNkUFs5NRKSRB0 0whD5cHDBh/ltGf1H5BRInRFIYkjcxvMsxHe82BMEy/uYD8VByBtK9Yd8Kv67ehJxxVW pmK1MzwbIQEmE0Taa3F1W8G7VJtLubjmTKnRNYGp5lRDR9wC8fdRD2/C8j4As6L0Tv1d KQquGqNluZF/lI7X1VtZlnTm/m6EOmEZ9MePuy2iGpXGlsuIKzFKA2s36xokQpjlR9Re 2cqyskTfNSyoee7sExW2ZeC6hgZf+8tYFnS8yf6QdjAV6Y+k1TDiTBzhPNeN3KshZY2v cKeQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b="hkkCnYi/"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id e8-20020a056402330800b0043d8509aa06si9696721eda.366.2022.08.03.06.19.23; Wed, 03 Aug 2022 06:19:23 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b="hkkCnYi/"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B7A7F68B616; Wed, 3 Aug 2022 16:19:20 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f44.google.com (mail-wr1-f44.google.com [209.85.221.44]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E3674689751 for ; Wed, 3 Aug 2022 16:19:13 +0300 (EEST) Received: by mail-wr1-f44.google.com with SMTP id l4so21558881wrm.13 for ; Wed, 03 Aug 2022 06:19:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=CIRzfGdHqKp70NpHbMXVLQLGqY2kC1o2TTq9aEnz/f0=; b=hkkCnYi/khw/if9YlsmPr43Yg/CpPTLFQIUIepbT0pN4oqieCLwak3honpAfLiOxZw KjwrPECPGHEvF9G+RtEj6ATRpq+SXB9wlVTC1jQLVqXmUQKT7cxqJfpAqj+87vMuoCPQ tI0NLa1IbbS5K9aGnDGIJMHM0oE+FZ/09HT1aQyeuEh5ft+hhHgGiCwWGfFXt8ZdZmws WbYZVC8CSzzBdaLHs0+VXUS8rMrd3m5eYHGxaFYGKgYkHmFbZhloROGx/YT9e8qtFjOd d+W09RfMzr+/V0kJKSE5HWB/qb3cp7pcIDf9FrlJoI9nCnt/1nGQ65yXeVGpLKHaPkQV W8Hw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=CIRzfGdHqKp70NpHbMXVLQLGqY2kC1o2TTq9aEnz/f0=; b=4ZqUFzJ7JN5c0mSvLuREBzPYBginqzROE3OPuaIbJLg/m7EL9MVM3h5l/0szCtpC2v qFSRv7i8dnDYAR85aFoZIQE+5N9Gr+sjjKh87G9D7FM1LTCJFEkmivC9WLRzL2/MjAGe G/SEa4lEc+gDH0IY3bkiwbriAslVsRAC36lZQV6qmMJiHj8tXFjlfZaKNLF4W1PAFypy M0bf+4JoLXw99csXhwotEtQTRCz47ILI5eVpbVOS+JyvyO8onH69X2jKdXMduE7YYBdL umQ3PIx2KqhI11KK4WDoy5YbvNZDEdmDeb/iJBKTjpjqoQNJuoX6Perxkm+c+5fAPOvL mBWQ== X-Gm-Message-State: ACgBeo0pKbjmaxl+ekO5PouYcaD6toKcnaWN69eHtEpmi/hWRFLLOhp1 25zaeflGZvEqueUzGxBjkceCEE9XlDI= X-Received: by 2002:a5d:4fcc:0:b0:21f:dd9:df09 with SMTP id h12-20020a5d4fcc000000b0021f0dd9df09mr16779020wrw.294.1659532752542; Wed, 03 Aug 2022 06:19:12 -0700 (PDT) Received: from localhost.localdomain ([149.12.10.163]) by smtp.gmail.com with ESMTPSA id d14-20020a05600c34ce00b003a325bd8517sm3072344wmq.5.2022.08.03.06.19.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Aug 2022 06:19:11 -0700 (PDT) From: Derek Buitenhuis To: ffmpeg-devel@ffmpeg.org Date: Wed, 3 Aug 2022 14:18:59 +0100 Message-Id: <20220803131859.167392-1-derek.buitenhuis@gmail.com> X-Mailer: git-send-email 2.36.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2] mov: Compare frag times in correct time base when seeking a stream without a corresponding sidx 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: yJywJuT86PcB Some muxers, such as GPAC, create files with only one sidx, but two streams muxed into the same fragments pointed to by this sidx. Prevously, in such a case, when we seeked in such files, we fell back to, for example, using the sidx associated with the video stream, to seek the audio stream, leaving the seekhead in the wrong place. We can still do this, but we need to take care to compare timestamps in the same time base. Signed-off-by: Derek Buitenhuis --- libavformat/mov.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index a09a762d91..c101a1acdd 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1271,15 +1271,18 @@ static int64_t get_stream_info_time(MOVFragmentStreamInfo * frag_stream_info) return frag_stream_info->tfdt_dts; } -static int64_t get_frag_time(MOVFragmentIndex *frag_index, - int index, int track_id) +static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st, + MOVFragmentIndex *frag_index, int index) { MOVFragmentStreamInfo * frag_stream_info; + MOVStreamContext *sc = dst_st->priv_data; int64_t timestamp; - int i; + int i, j; - if (track_id >= 0) { - frag_stream_info = get_frag_stream_info(frag_index, index, track_id); + // If the stream is referenced by any sidx, limit the search + // to fragments that referenced this stream in the sidx + if (sc->has_sidx) { + frag_stream_info = get_frag_stream_info(frag_index, index, dst_st->id); if (frag_stream_info->sidx_pts != AV_NOPTS_VALUE) return frag_stream_info->sidx_pts; if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE) @@ -1288,28 +1291,27 @@ static int64_t get_frag_time(MOVFragmentIndex *frag_index, } for (i = 0; i < frag_index->item[index].nb_stream_info; i++) { + AVStream *frag_stream = NULL; frag_stream_info = &frag_index->item[index].stream_info[i]; + for (j = 0; j < s->nb_streams; j++) + if (s->streams[j]->id == frag_stream_info->id) + frag_stream = s->streams[j]; timestamp = get_stream_info_time(frag_stream_info); - if (timestamp != AV_NOPTS_VALUE) - return timestamp; + if (timestamp != AV_NOPTS_VALUE) { + if (frag_stream) + return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base); + else + return timestamp; + } } return AV_NOPTS_VALUE; } -static int search_frag_timestamp(MOVFragmentIndex *frag_index, +static int search_frag_timestamp(AVFormatContext *s, MOVFragmentIndex *frag_index, AVStream *st, int64_t timestamp) { int a, b, m, m0; int64_t frag_time; - int id = -1; - - if (st) { - // If the stream is referenced by any sidx, limit the search - // to fragments that referenced this stream in the sidx - MOVStreamContext *sc = st->priv_data; - if (sc->has_sidx) - id = st->id; - } a = -1; b = frag_index->nb_items; @@ -1318,7 +1320,7 @@ static int search_frag_timestamp(MOVFragmentIndex *frag_index, m0 = m = (a + b) >> 1; while (m < b && - (frag_time = get_frag_time(frag_index, m, id)) == AV_NOPTS_VALUE) + (frag_time = get_frag_time(s, st, frag_index, m)) == AV_NOPTS_VALUE) m++; if (m < b && frag_time <= timestamp) @@ -8806,7 +8808,7 @@ static int mov_seek_fragment(AVFormatContext *s, AVStream *st, int64_t timestamp if (!mov->frag_index.complete) return 0; - index = search_frag_timestamp(&mov->frag_index, st, timestamp); + index = search_frag_timestamp(s, &mov->frag_index, st, timestamp); if (index < 0) index = 0; if (!mov->frag_index.item[index].headers_read)