From patchwork Tue Aug 16 14:48:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derek Buitenhuis X-Patchwork-Id: 37318 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:3d0d:b0:8d:a68e:8a0e with SMTP id y13csp1915096pzi; Tue, 16 Aug 2022 07:49:16 -0700 (PDT) X-Google-Smtp-Source: AA6agR7Ptn0y44bpPDH8CEHKu/Y7oPV7yTabyu4jgK8Oejo++XS1UAs1Lx340dHPbrwBWjBMC9wa X-Received: by 2002:a17:906:9bc4:b0:730:957f:34b3 with SMTP id de4-20020a1709069bc400b00730957f34b3mr13520958ejc.231.1660661356226; Tue, 16 Aug 2022 07:49:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660661356; cv=none; d=google.com; s=arc-20160816; b=gTncggg7KmFJsfvBDu84976DCYS/6ldZLSzONLyf8SimgHz7OQTZGsfnyZZ376pdya bfVfBVLv5yNu9fYm8UcCUM+Ts0RZAwpInWo864gXW4u/aAykZCdzsPqRz56QVZUEnxHq WlE3EsBEeD8MuuSdcAaryDfK5xdB3pyjZ85/0iO9xfikoRl+cmgGiZXmhLSYbZ85TXni /yqdQsavzGwaYNafLyWjaUgZ9OvAi+wR0FhFvJ9XWo+oTE0ckKQ19ZWp5fpdevYe4vKx Sn6FHeDWVSbNq1KgqQkx7JVKTEDrCKHViVVtJOaU9OcL54dOf0yLoFKYBCGq0gcJTu2G Xp5g== 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=d2oZgkRNIJ7rPqneQ5Xo2VlbKMfif9fOPFqboceO3rU=; b=cWEkRWpNurP/h+FuO+onwYcAATGQ9UqEgqnMf/z3ExDM+QwwP51+7L7iS+HMmzPXBM GtdmBAymO37MKky/eG2JXawC57sByiHTnAKEJKAYiPJKzZFXo0BbqHCD7/+4Uom8Nb6G AbtE8hJuxVmxEIjcOIwAISlVDk4/R7ug2Bl/dxregdvPEdhZNUc6sIxmb1apL6b5Z7OI LRAF5UvZmTJNObZJsR4zx5EpzVQxUuR7lSSl4I/xwNjL85oCjyoGLpsSgJsEKM9QCoNt hJuaJ7nXfl/lcAuZ0WXgqE+NyXq2UZRvJ1XFU3v/cU2MQx9N4UPf+5Ahhvh69FiicLQx g9JQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=hzgOW2YY; 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 cs10-20020a170906dc8a00b00730b62beb20si10478348ejc.798.2022.08.16.07.49.15; Tue, 16 Aug 2022 07:49:16 -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=hzgOW2YY; 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 2108968B59C; Tue, 16 Aug 2022 17:49:14 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6CA2B68B59C for ; Tue, 16 Aug 2022 17:49:06 +0300 (EEST) Received: by mail-wm1-f43.google.com with SMTP id ay39-20020a05600c1e2700b003a5503a80cfso5500775wmb.2 for ; Tue, 16 Aug 2022 07:49:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc; bh=79FcozKL5FyvF+Vr3Z7Q+/qazStErQEGR5pjxMgE56Y=; b=hzgOW2YYIOxuRYJI5344Ph9117Mu/6ERLUYWTbLZWf7ZEQ8MlgPr2i9Ytr+GX6bb8I P3PrtBmItRr8NW2NnIcR4yAmu+UE6p8MchVFWqNI5UkRoZzBmbbFVnWJjmmxdeQtSGMh XdOLlDH17BvU+MTZJ4qgJnivrNP8u6a/jsBDY5pe2nt3CuUwlCL6MIJCGi3Om2y6EmqJ MEWxI5GknKiQtGeBgwnoh1xCPxumhqFlqyjZAV85diHPg+1lA1rRfKi1krrIKcleMPIJ 9xRETSkZ8nuAAchwHW/GebHo4WgeTvS75SZr6V+rWJwZh1vtbZc/qjgEDruBcpQHJQ+Z N/XA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc; bh=79FcozKL5FyvF+Vr3Z7Q+/qazStErQEGR5pjxMgE56Y=; b=rBtQffdrITaIAuptM3RrvOFZpk78BKH0fcPsZg/2xLeuErJVZPnXznqWvtbzT69JzN ap06OuB7B2q7b5uQDcBlwUpgWORjmYcX3ZT8RW3W4SkONbeU5tm/zgh9c8+VztEIBiuL oD1aayAG+pxyXIn731W2Jh5kYYb+1IbepgHjwDhkJA1Txg95YW5YRu+owq4Qe4quL5On q+AIKFPwewhdTSq8bGtFiAa5ZoUanWwzM4eq9qluByTD4xziNWxvhq21xfSD3GFp0lpY PpPY+RrOwUZZPHtjPzu6sMKAuj32gPAO5TZ+aAYXeFOCbzwrsxRGv0uEa4kFWKgkw5HO aV7A== X-Gm-Message-State: ACgBeo3ALdvx2PD92ZZfCpaQnpUTRr/gU/jLj/Z7f1r76iZT0BFPyEGj ZQvmmGikvTrZHSl+DcnMJoA5/aZUzmE= X-Received: by 2002:a05:600c:3ac4:b0:3a5:f6e5:1cbc with SMTP id d4-20020a05600c3ac400b003a5f6e51cbcmr5665063wms.92.1660661345629; Tue, 16 Aug 2022 07:49:05 -0700 (PDT) Received: from localhost.localdomain ([149.12.10.163]) by smtp.gmail.com with ESMTPSA id i22-20020a05600c355600b003a60f0f34b7sm320208wmq.40.2022.08.16.07.49.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Aug 2022 07:49:05 -0700 (PDT) From: Derek Buitenhuis To: ffmpeg-devel@ffmpeg.org Date: Tue, 16 Aug 2022 15:48:50 +0100 Message-Id: <20220816144850.196109-1-derek.buitenhuis@gmail.com> X-Mailer: git-send-email 2.36.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v3] 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: NB10ToTMkbZy 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 | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 31f3249ca6..1d8c5b2904 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]; + if (!frag_stream) { + av_log(s, AV_LOG_WARNING, "No stream matching sidx ID found.\n"); + continue; + } timestamp = get_stream_info_time(frag_stream_info); if (timestamp != AV_NOPTS_VALUE) - return timestamp; + return av_rescale_q(timestamp, frag_stream->time_base, dst_st->time_base); } 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) @@ -8862,7 +8864,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)