From patchwork Mon Nov 2 11:42:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthieu Bouron X-Patchwork-Id: 23329 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 3B18444B597 for ; Mon, 2 Nov 2020 14:10:30 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1659468AA9C; Mon, 2 Nov 2020 14:10:30 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f68.google.com (mail-wr1-f68.google.com [209.85.221.68]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 81F4568AA9C for ; Mon, 2 Nov 2020 14:10:23 +0200 (EET) Received: by mail-wr1-f68.google.com with SMTP id w14so14284417wrs.9 for ; Mon, 02 Nov 2020 04:10:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=VynK7u5Vi4fDH2t1rcBhAliAFQGiBgDqFIMfnRoFVNc=; b=GwVd8KE/3urL2C41nzwxW0NXSVEIVgkFJ1VCIr8XUg1gHIy1BwjiaV4PoHoFMIoMNx cr/pguOEn2xiy1uWcVG/uVr4A03rlTttxdEP8xJzRzcPNVtw/NG0o3myutzQWhU7vzFK k+mSCRmL4HwIn1FtlK2Dgj3myohoxZfbBkHmtAy1SAod5gmq9+FIjvqrt/mVpzvN4FAU fsOPZj02jIEX+Mt005v9URrRG1q9b4N57NlbOkhvpw60FG5+GGmiQ5CBqmC+U6iJKY/S Yj3Kp0/IVcmmYyojiiPRis3uxtyLfGBljCXUV2vab8dDR3pN8dt4o/wXPlcUHmAqaxi7 vvkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=VynK7u5Vi4fDH2t1rcBhAliAFQGiBgDqFIMfnRoFVNc=; b=FftlzunjD8Ec07T+wjexDia2yfVjvgMdXRMz2A0g9kRI1FsuWkBRwkJeNey53vnKmG 4TB2SqHtwSa1a6Lk0qDamZDgpyG0v6QSGh7nVcML4u1XThLw7gG9/31ljW2g+5fDyQDf rl917WqBSsNhD/tfEbWCtq1UelljLRU7IegLGI4mJrqLm1CU80MTOcyJDtze22ejlbmv XTItDGWQhRQsyfPr+4RprBIbh+Go569mDQ8mS5+N5YfoXNMVKrmh+YWnOWNKfEYFhREG EYtcMjtHaaXa9Xi4F8QsITNjmHaVlXtF391j3bvpwW1DS/rNQg4kPLVBA6yi9hC4fhj0 BFcw== X-Gm-Message-State: AOAM5339Cv5hU1d+S+6jN8TqCApionjm3BVGaKRx3+TwpQHM8MNIqOAJ M91FaTFV+Qfdi4MRLIe7tLzA23Qh6EA= X-Google-Smtp-Source: ABdhPJyCjQqIf2uv5y2cVgcOf1kdxCD1l7kOROKcjUIGRWelJ6K7x25BWtccaYwGXeuR0HQsiJmWtQ== X-Received: by 2002:adf:814f:: with SMTP id 73mr19571291wrm.174.1604317394213; Mon, 02 Nov 2020 03:43:14 -0800 (PST) Received: from localhost.localdomain (lputeaux-656-1-153-220.w217-128.abo.wanadoo.fr. [217.128.47.220]) by smtp.gmail.com with ESMTPSA id o3sm21135029wru.15.2020.11.02.03.43.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Nov 2020 03:43:13 -0800 (PST) From: Matthieu Bouron To: ffmpeg-devel@ffmpeg.org Date: Mon, 2 Nov 2020 12:42:19 +0100 Message-Id: <20201102114219.459524-1-matthieu.bouron@gmail.com> X-Mailer: git-send-email 2.29.2 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] avformat/mov: adjust skip_samples according to seek timestamp 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 Cc: Matthieu Bouron Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Currently skip_samples is set to start_pad if sample_time is lesser or equal to 0. This can cause issues if the stream starts with packets that have negative pts. Calling avformat_seek_file() with ts set to 0 on such streams makes the mov demuxer return the right corresponding packets (near the 0 timestamp) but set skip_samples to start_pad which is incorrect as the audio decoder will discard the returned samples according to skip_samples from the first packet it receives (which has its timestamp near 0). For example, considering the following audio stream with start_pad=1344: [PKT pts=-1344] [PKT pts=-320] [PKT pts=704] [PKT pts=1728] [...] Calling avformat_seek_file() with ts=0 makes the next call to av_read_frame() return the packet with pts=-320 and a skip samples side data set to 1344 (start_pad). This makes the audio decoder incorrectly discard (1344 - 320) samples. This commit makes the move demuxer adjust skip_samples according to the stream start_pad, seek timestamp and first sample timestamp. The above example will now result in av_read_frame() still returning the packet with pts=-320 but with a skip samples side data set to 320 (src_pad - (seek_timestamp - first_timestamp)). This makes the audio decoder only discard 320 samples (from pts=-320 to pts=0). --- libavformat/mov.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index dd0db6bca79..f99cb0df25a 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -8098,20 +8098,34 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti return sample; if (mc->seek_individually) { + MOVStreamContext *sc = s->streams[stream_index]->priv_data; + /* adjust seek timestamp to found sample timestamp */ + int64_t first_timestamp = st->internal->index_entries[0].timestamp; int64_t seek_timestamp = st->internal->index_entries[sample].timestamp; + /* adjust skip samples according to stream start_pad, seek timestamp and first timestamp */ + int64_t skip_samples = FFMAX(sc->start_pad - (seek_timestamp - first_timestamp), 0); + st->internal->skip_samples = skip_samples; + for (i = 0; i < s->nb_streams; i++) { int64_t timestamp; MOVStreamContext *sc = s->streams[i]->priv_data; st = s->streams[i]; - st->internal->skip_samples = (sample_time <= 0) ? sc->start_pad : 0; if (stream_index == i) continue; timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base); - mov_seek_stream(s, st, timestamp, flags); + sample = mov_seek_stream(s, st, timestamp, flags); + if (sample >= 0) { + first_timestamp = st->internal->index_entries[0].timestamp; + seek_timestamp = st->internal->index_entries[sample].timestamp; + + /* adjust skip samples according to stream start_pad, seek timestamp and first timestamp */ + skip_samples = FFMAX(sc->start_pad - (seek_timestamp - first_timestamp), 0); + st->internal->skip_samples = skip_samples; + } } } else { for (i = 0; i < s->nb_streams; i++) {