From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <ffmpeg-devel-bounces@ffmpeg.org>
Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100])
	by master.gitmailbox.com (Postfix) with ESMTPS id 001424BF54
	for <ffmpegdev@gitmailbox.com>; Tue,  4 Feb 2025 17:00:33 +0000 (UTC)
Received: from [127.0.1.1] (localhost [127.0.0.1])
	by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1E3C468B59A;
	Tue,  4 Feb 2025 19:00:30 +0200 (EET)
Received: from mail-oa1-f98.google.com (mail-oa1-f98.google.com
 [209.85.160.98])
 by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id AFA67680CC5
 for <ffmpeg-devel@ffmpeg.org>; Tue,  4 Feb 2025 19:00:23 +0200 (EET)
Received: by mail-oa1-f98.google.com with SMTP id
 586e51a60fabf-2b6b902e77aso90148fac.2
 for <ffmpeg-devel@ffmpeg.org>; Tue, 04 Feb 2025 09:00:23 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=proxyid.net; s=google; t=1738688422; x=1739293222; darn=ffmpeg.org;
 h=content-transfer-encoding:mime-version:message-id:date:subject:cc
 :to:from:from:to:cc:subject:date:message-id:reply-to;
 bh=Gu89pdV9exP4MEZPguiZ2W/2XREzJ1vIntHexpdifZs=;
 b=Ugr5zEIm2aXpAuOpWBPLaKMvqKIjrBApN+twVExUZVd/X+r27kTyrTkPYiUT0Hd+vK
 JVKCQp+gSlNCWQ0K5BDMFyjVzJ8hUTgF99eoz0aSbtxv6gqUTKV6hhE5sNX9VYLKDrIs
 eUN7GZglMJUEVLloosw+2PFIzj4UsyXTKaxvkdI2Ewc5whA0m5schN077hlV184ulbES
 7K7S4vtLBte44dCgSAQHq/tAB2Qi/mByf/XJnY+l/ZJ3+3VniZP8o8F9okfJQlcHgUM3
 PF/Jua8f7Je3/r5eRCnjg7qIIghHh2c+YT0LFAcRJqA7SCErLT1slWXJ+ldSTJeqbqXu
 jp9A==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1738688422; x=1739293222;
 h=content-transfer-encoding:mime-version:message-id:date:subject:cc
 :to:from:x-gm-message-state:from:to:cc:subject:date:message-id
 :reply-to;
 bh=Gu89pdV9exP4MEZPguiZ2W/2XREzJ1vIntHexpdifZs=;
 b=a70XLzLs6HqEIdyoYdWu/rZjQmAG6Hq8L9ACNRExNdUruH3fU78KfLHqwuQKGnG7YC
 FWUMljgvayYnGW7tNg19aTDanR/SyHjvdKl5tZa3VVRqVJK+bHp3JBJPmrbizRe4o0QI
 OAqVH8HnUsG+n4YvzlkXZLsQO/RAdYsZ8qJwml3dcsFT//VdWzlk325GiZgBXTLUYwjr
 899GHaJuZsoxZjMHF/nckkM6CBvpGGPK6gnQjrvHUhY6ylS+rjPl3oPxvEDf/p+t86Ol
 GFhJDp0zzPB08zLO0xnqHgVFVUXQAJK7XFjgMFIYdXXhIJtDF820OityD6Q3aa9Wg9Zz
 Cu8w==
X-Gm-Message-State: AOJu0YwV7vn1eT1nbRmu+d1FpuQDvTW/yIwf1RdhvQQXC5wRtFahZCVE
 pAedz4JjVU93XINfOhoR6cDR7THtRKe9d0WcwVq11bOa/qcvAL1v5wKEsLsNkH2xaSLwZqJPNmE
 /22HYwWKBD6wfhw1mcnCEz11zSRnPu+UMaOMfDxlxrWazZJMu/wcw2d1JxTQ5muxpvrVcHM/up2
 BXEBhQLWAb5sbE6l+9X240a07zD5mAAtygNqbXVvdmaQmTu6QxzPzBx/M1YKJO9licUxpZiH+A4
 /P7gJE=
X-Gm-Gg: ASbGncsJYXt7qiIQR/3RoT0HGV1BoT/dYiaWlaN0BrTu8iFaPPCxbCsmDRhs2pU6Rv+
 VN5XmwPJyv+MHm2GmRZ9La9ovgCKPtdlF2JEMPkIwHM75Aen974CHEViOuWL9ikNRpB2IXjI+Ix
 5dB0hwsFiVjDXm4CTmIWkQe7sGTuJRx+lDBTR4eW8RozRbeUHqtWtpY0ZkV9bAwcnkfhhjcdrsb
 EKj972PKhEfrbdVVsRXptFXXW6XynGEx6lzRywTDhweMTI5RvGt94tz13xCcAVJ/VKpuxAGndnF
 p7Er+tia2N8EuGyzzNsKuo50iVirk3AKUE2/xkik9WFZPnQ=
X-Google-Smtp-Source: AGHT+IFpYy1WxrYho49otmWq8o7hh3uqD8P9cqZU/EZaoaPY6fJR3xuHGDWjtcO+e32r6y28m/idjV6Vb8rk
X-Received: by 2002:a05:6871:72a:b0:295:f266:8aee with SMTP id
 586e51a60fabf-2b3e5ecc555mr859693fac.5.1738688421839; 
 Tue, 04 Feb 2025 09:00:21 -0800 (PST)
Received: from ff-public-001.. (c-76-136-218-80.hsd1.il.comcast.net.
 [76.136.218.80]) by smtp-relay.gmail.com with ESMTPS id
 586e51a60fabf-2b7f9ecb284sm38786fac.9.2025.02.04.09.00.19
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Tue, 04 Feb 2025 09:00:21 -0800 (PST)
X-Relaying-Domain: proxyid.net
From: Marth64 <marth64@proxyid.net>
To: ffmpeg-devel@ffmpeg.org
Date: Tue,  4 Feb 2025 10:55:19 -0600
Message-ID: <20250204165524.2716-2-marth64@proxyid.net>
X-Mailer: git-send-email 2.43.0
MIME-Version: 1.0
Subject: [FFmpeg-devel] [PATCH] avformat/dvdvideodec: fix seeking on
 multi-angle discs
X-BeenThere: ffmpeg-devel@ffmpeg.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: FFmpeg development discussions and patches <ffmpeg-devel.ffmpeg.org>
List-Unsubscribe: <https://ffmpeg.org/mailman/options/ffmpeg-devel>,
 <mailto:ffmpeg-devel-request@ffmpeg.org?subject=unsubscribe>
List-Archive: <https://ffmpeg.org/pipermail/ffmpeg-devel>
List-Post: <mailto:ffmpeg-devel@ffmpeg.org>
List-Help: <mailto:ffmpeg-devel-request@ffmpeg.org?subject=help>
List-Subscribe: <https://ffmpeg.org/mailman/listinfo/ffmpeg-devel>,
 <mailto:ffmpeg-devel-request@ffmpeg.org?subject=subscribe>
Reply-To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>
Cc: Marth64 <marth64@proxyid.net>, Kacper Michajlow <kasper93@gmail.com>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: ffmpeg-devel-bounces@ffmpeg.org
Sender: "ffmpeg-devel" <ffmpeg-devel-bounces@ffmpeg.org>
Archived-At: <https://master.gitmailbox.com/ffmpegdev/20250204165524.2716-2-marth64@proxyid.net/>
List-Archive: <https://master.gitmailbox.com/ffmpegdev/>
List-Post: <mailto:ffmpegdev@gitmailbox.com>

When seeking on multi-angle titles, libdvdnav does not lock on
to the correct sectors initially as it seeks to find the right NAV packet.

This manifests itself as two bugs:
(1) When seeking on the first angle in a multi-angle segment,
frames from another angle will appear (for example in intro
or credits scenes). This issue is present in VLC also.

(2) When seeking during a segment on angle n+1, the demuxer
cannot deduce the right position from dvdnav and does not allow
seeking within the segment (due to it maintaining a strict state).

Correct the issue by switching to angle 1 before doing the seek
operation, and skipping 3 VOBUs (NAV packet led segments) ahead
where dvdnav will have positioned itself correctly.

Reported-by: Kacper Michajlow <kasper93@gmail.com>
Signed-off-by: Marth64 <marth64@proxyid.net>

---
 libavformat/dvdvideodec.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/libavformat/dvdvideodec.c b/libavformat/dvdvideodec.c
index 5b9abebbf2..9596468ce2 100644
--- a/libavformat/dvdvideodec.c
+++ b/libavformat/dvdvideodec.c
@@ -111,6 +111,7 @@ typedef struct DVDVideoPlaybackState {
     int                         in_vts;             /* if our navigator is in the VTS */
     int                         is_seeking;         /* relax navigation path while seeking */
     int64_t                     nav_pts;            /* PTS according to IFO, not frame-accurate */
+    int                         nb_vobu_skip;       /* number of VOBUs we should skip */
     uint64_t                    pgc_duration_est;   /* estimated duration as reported by IFO */
     uint64_t                    pgc_elapsed;        /* the elapsed time of the PGC, cell-relative */
     int                         pgc_nb_pg_est;      /* number of PGs as reported by IFOs */
@@ -165,6 +166,7 @@ typedef struct DVDVideoDemuxContext {
 
     /* playback control */
     int64_t                     first_pts;          /* the PTS of the first video keyframe */
+    int                         nb_angles;          /* number of angles in the current title */
     int                         play_started;       /* signal that playback has started */
     DVDVideoPlaybackState       play_state;         /* the active playback state */
     int64_t                     *prev_pts;          /* track the previous PTS emitted per stream */
@@ -298,6 +300,8 @@ static int dvdvideo_ifo_open(AVFormatContext *s)
         return AVERROR_INVALIDDATA;
     }
 
+    c->nb_angles = title_info.nr_of_angles;
+
     return 0;
 }
 
@@ -759,6 +763,13 @@ static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState
                     return AVERROR_INVALIDDATA;
                 }
 
+                if (state->nb_vobu_skip > 0) {
+                    av_log(s, AV_LOG_VERBOSE, "Skipping VOBU at SCR %d\n",
+                                              e_dsi->dsi_gi.nv_pck_scr);
+                    state->nb_vobu_skip -= 1;
+                    continue;
+                }
+
                 state->vobu_duration = e_pci->pci_gi.vobu_e_ptm - e_pci->pci_gi.vobu_s_ptm;
                 state->pgc_elapsed += state->vobu_duration;
                 state->nav_pts = dvdnav_get_current_time(state->dvdnav);
@@ -1736,6 +1747,7 @@ static int dvdvideo_read_seek(AVFormatContext *s, int stream_index, int64_t time
     int64_t new_nav_pts;
     pci_t*  new_nav_pci;
     dsi_t*  new_nav_dsi;
+    int     seek_failed = 0;
 
     if (c->opt_menu || c->opt_chapter_start > 1) {
         av_log(s, AV_LOG_ERROR, "Seeking is not compatible with menus or chapter extraction\n");
@@ -1755,9 +1767,30 @@ static int dvdvideo_read_seek(AVFormatContext *s, int stream_index, int64_t time
         c->seek_warned = 1;
     }
 
+    /* dvdnav loses NAV packets when seeking on multi-angle discs, so enforce angle 1 then revert */
+    if (c->nb_angles > 1) {
+        if (dvdnav_angle_change(c->play_state.dvdnav, 1) != DVDNAV_STATUS_OK) {
+            av_log(s, AV_LOG_ERROR, "Unable to open angle 1 for seeking\n");
+
+            return AVERROR_EXTERNAL;
+        }
+    }
+
     /* XXX(PATCHWELCOME): use dvdnav_jump_to_sector_by_time(c->play_state.dvdnav, timestamp, 0)
      * when it is available in a released version of libdvdnav; it is more accurate */
     if (dvdnav_time_search(c->play_state.dvdnav, timestamp) != DVDNAV_STATUS_OK) {
+        seek_failed = 1;
+    }
+
+    if (c->nb_angles > 1) {
+        if (dvdnav_angle_change(c->play_state.dvdnav, c->opt_angle) != DVDNAV_STATUS_OK) {
+            av_log(s, AV_LOG_ERROR, "Unable to revert to angle %d after seeking\n", c->opt_angle);
+
+            return AVERROR_EXTERNAL;
+        }
+    }
+
+    if (seek_failed) {
         av_log(s, AV_LOG_ERROR, "libdvdnav: seeking to %" PRId64 " failed\n", timestamp);
 
         return AVERROR_EXTERNAL;
@@ -1781,6 +1814,9 @@ static int dvdvideo_read_seek(AVFormatContext *s, int stream_index, int64_t time
     c->play_state.ptm_discont = 0;
     c->play_state.vobu_e_ptm  = new_nav_pci->pci_gi.vobu_s_ptm;
 
+    /* if there are multiple angles, skip the next 3 VOBUs as dvdnav will be at the wrong angle */
+    c->play_state.nb_vobu_skip = c->nb_angles > 1 ? 3 : 0;
+
     c->first_pts              = 0;
     c->play_started           = 0;
     c->pts_offset             = timestamp;
-- 
2.34.1

_______________________________________________
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".