From patchwork Mon Sep 23 05:19:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marth64 X-Patchwork-Id: 51725 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:d154:0:b0:48e:c0f8:d0de with SMTP id bt20csp2245937vqb; Sun, 22 Sep 2024 22:29:23 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWc7t2xr1GoK84Z0LXJK9/LHf3LluzkkmkHnd3xBezw3TfACESl43OM/hT5fELmHf7libh+D6ahXXF8TU0Fzgkj@gmail.com X-Google-Smtp-Source: AGHT+IHDwFgy4U4gIejDwY073Sq9stzSxmE/Ptv9haOgL4Pi0qgKusS2h+8448fG9WfgLho1ItVh X-Received: by 2002:a05:6402:274c:b0:5c5:b73c:593 with SMTP id 4fb4d7f45d1cf-5c5b73c05b5mr6728163a12.17.1727069363641; Sun, 22 Sep 2024 22:29:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1727069363; cv=none; d=google.com; s=arc-20240605; b=BA6a+FiGryOTxWzijj/ORKXjQqpDUxFuNm9Et/Miqh438CjiMS2aINxxPZM37m4LIF hkdLUHAd8SZIZYoISKCGfaRVowfkGEbXWk+BNbe6Pua1nOxK2W49OC0vquwBDuROQvdt fSHSD0f/EykzMWbRbf4CWzvR3wTv5cg4NiW4HpwfB0IIyiK1I4tlBhO6jXb98j/dNVne 9U/COQRdAH9CR8wG4OlBpcE2fI9z5j0hqHAGk6K2WnlwIKrxgONa3Wf3wJXYsuC+ibRn 6bILzpsFkBet6ssFvmUn+95HeT8ehToOjfbfM3vd/OSOKJdgl0BzpAX4bN2yGcvZEPbi Yqxw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=AbEsFVnDOsNPGHO+z3YbA+/L7bROcI/DI41GkU02GFE=; fh=PlWMzmI9LD2qGS7ipLrQl8z0iaQTLQLHzoGuXcBzpCg=; b=aTXo9Fg5SQ5FC+EOQZDH4egBU3DP0QWt0EBSwhSaEar+KRc36+7MTJF9DGSAcpcwH6 cDp5XZ+E3/wNy8ScZ0uf3yZf2DwTllIpgXuS2wxOLkdkFBYvymLyTYm+k0Ypo7Cz3SLU X+nkRpa5ScxLf8uVujAtg3DbeC2avhuqX952BmdmPAphDUPBKnk/vQo78eHGnpusJPRW gNwECERBmpsc6qZIrF7pEdPV8trO2yY6lY3JUJJEIRdlu7dBM0XKm0li48eILV4hcHu9 XHxADkzHUjspjff5xWXrszWlSeq2d1YV2hTG2SMSvb7XsR88nM0huCD+2vG+b+572wqF 46mQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@proxyid.net header.s=google header.b=eowooVxz; 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; dara=fail header.i=@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 4fb4d7f45d1cf-5c42bb5b3bfsi13511010a12.154.2024.09.22.22.29.22; Sun, 22 Sep 2024 22:29: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=@proxyid.net header.s=google header.b=eowooVxz; 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; dara=fail header.i=@gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id DF13968DC25; Mon, 23 Sep 2024 08:20:05 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-oo1-f100.google.com (mail-oo1-f100.google.com [209.85.161.100]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0EC9668D942 for ; Mon, 23 Sep 2024 08:19:52 +0300 (EEST) Received: by mail-oo1-f100.google.com with SMTP id 006d021491bc7-5e1b50feb9bso2630366eaf.1 for ; Sun, 22 Sep 2024 22:19:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proxyid.net; s=google; t=1727068790; x=1727673590; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=JKh1wULo5HLHZNy6igFsfhXvWfMZQ6uK0YNxTQyHxe0=; b=eowooVxz2nwjotwpaHaR3tON6d49GAYaudOFagzd1dfdwqG+5G/c2LpRNFsiCE6eVz UQhXow+qaEgWkAAhGlVcPY9HC0eDYwyPldsNiJofBnZxMb6MtvR/lMX29BcdETivGdaJ rtmifdlQmQskuVe5nvEPHtHqT0ScSAQXumJlfl/ue1L5kREyRi1la+ppZB4cS2JNyB5A Pc0vw9wWdUwYZ4lXJhN8I7NFbLfuntkbHSOui03iFIluBesPV0bPjLHd2WkLvt+qsiRk bPtO+iW11jkOGeKwiIxJLdKcqqO6C6VQFn/Jp47nOow1TLtF+2xXmQIduOMpdW1SWPzF eUfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727068790; x=1727673590; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JKh1wULo5HLHZNy6igFsfhXvWfMZQ6uK0YNxTQyHxe0=; b=PVI+9tinky/NHbNqKhn4N5vsik0HhFlGSBl3YvzZIS2OSyLdGsemqal4bnEe+F7Kih WUj6UVah/vSJzH78Yz0Eq8UceBJLItfvUF9xrulbsGARjhtfOSscoD+2gtsgky8b3XDv Bxh47kVXOoQHSaOZQe3tDmya3R+fRqpAX5aVktMh66H6E3bR+X5KAXBrFOiUeQN46eIc l+iuf3LVpoYmIkr2N2ZH9jKFyVvq/03dkHyDtkDYWYGAjR0PRb4b61AsbjNP3mXQdBfq 1kvRrmvfWcGG5gzgyA1O2WpAN/pOzKzzowK1dP2uXr6szOPVMbjIl1h8oglE6EIF3tmU LaDg== X-Gm-Message-State: AOJu0YxtY2A/4vCHKDBaVTJIHPwl+agLLg6FuDHzQ90FkPybZdbWpymp 0Ot50ug3nOpUNTGeVYkst+eh2SJBvMnw+JrssFsCxzcSMJttyOflzFA1ciFBplVBfZfCezkKZ+z O2gV65/Zz+cysyKx1HYmALHWEc6FQPt5f6JjD4y2T X-Received: by 2002:a05:6820:617:b0:5e1:e1a4:add1 with SMTP id 006d021491bc7-5e58d1965demr4258299eaf.7.1727068790708; Sun, 22 Sep 2024 22:19:50 -0700 (PDT) Received: from localhost.localdomain (c-69-245-177-215.hsd1.il.comcast.net. [69.245.177.215]) by smtp-relay.gmail.com with ESMTPS id 006d021491bc7-5e3bc69661csm202010eaf.20.2024.09.22.22.19.50 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 22 Sep 2024 22:19:50 -0700 (PDT) X-Relaying-Domain: proxyid.net From: Marth64 To: ffmpeg-devel@ffmpeg.org Date: Mon, 23 Sep 2024 00:19:39 -0500 Message-Id: <20240923051941.54124-10-marth64@proxyid.net> X-Mailer: git-send-email 2.39.5 (Apple Git-154) In-Reply-To: <20240923051941.54124-1-marth64@proxyid.net> References: <20240923051941.54124-1-marth64@proxyid.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 09/11] avformat/dvdvideodec: reset the subdemuxer on discontinuity instead of flushing 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 Cc: Marth64 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: uHKGkORkx+8e DVDs naturally consist of segmented MPEG-PS blobs within a VOB (i.e. VOBs are not linear). NAV packs set the segment boundaries. When switching between segments, discontinuities occur and thus the subdemuxer needs to be reset. The current approach to manage this is by invoking ff_read_frame_flush() on the subdemuxer context, via a callback function which is invoked during the menu or dvdnav block functions. The same subdemuxer context is used throughout the demux, with a stretched PTS wrap bits value (64) + disabled overflow correction, and then flushed on each segment. Eventually, a play_end context variable is set to declare EOF. However, this approach causes frame drops. The block read flushes the demuxer before the frame read is complete, causing frames to drop on discontinuity. The play_end signal likewise ends playback before the frame read is complete, causing frames to drop at end of the title. To compound the issue, the PTS wrap bits value of 64 is wrong; the VOBU limit is actually 32 and the overflow correction should work. Instead, EOF the MPEG-PS subdemuxer organically when each VOB segment ends, and re-open it if needed with the offset after the full frame read is complete. In doing so, correct the PTS wrap behavior to 32 bits and remove the play_end/segment_started signals and callback pattern. Note that the timestamps as reported by the NAV packets are known as "PTMs", so the fields storing the time prior to adjustment are renamed accordingly. This makes it more clear when we are offsetting the NAV packet reported timestamps versus what we present as a demuxer. Signed-off-by: Marth64 --- libavformat/dvdvideodec.c | 139 ++++++++++++++++++++------------------ 1 file changed, 75 insertions(+), 64 deletions(-) diff --git a/libavformat/dvdvideodec.c b/libavformat/dvdvideodec.c index ebcfdca9a5..6f947c3927 100644 --- a/libavformat/dvdvideodec.c +++ b/libavformat/dvdvideodec.c @@ -56,7 +56,7 @@ #define DVDVIDEO_MAX_PS_SEARCH_BLOCKS 128 #define DVDVIDEO_BLOCK_SIZE 2048 #define DVDVIDEO_TIME_BASE_Q (AVRational) { 1, 90000 } -#define DVDVIDEO_PTS_WRAP_BITS 64 /* VOBUs use 32 (PES allows 33) */ +#define DVDVIDEO_PTS_WRAP_BITS 32 /* VOBUs use 32 (PES allows 33) */ #define DVDVIDEO_LIBDVDX_LOG_BUFFER_SIZE 1024 #define PCI_START_BYTE 45 /* complement dvdread's DSI_START_BYTE */ @@ -115,8 +115,9 @@ typedef struct DVDVideoPlaybackState { int pgc_nb_pg_est; /* number of PGs as reported by IFOs */ int pgcn; /* ID of the PGC we are playing */ int pgn; /* ID of the PG we are in now */ + int ptm_discont; /* signal that a PTM discontinuity occurred */ + int64_t ptm_offset; /* PTM discontinuity offset (as NAV value) */ int ptt; /* ID of the chapter we are in now */ - int64_t ts_offset; /* PTS discontinuity offset (ex. VOB change) */ uint32_t vobu_duration; /* duration of the current VOBU */ uint32_t vobu_e_ptm; /* end PTM of the current VOBU */ int vtsn; /* ID of the active VTS (video title set) */ @@ -163,11 +164,11 @@ typedef struct DVDVideoDemuxContext { /* playback control */ int64_t first_pts; /* the PTS of the first video keyframe */ - int play_end; /* signal EOF to the parent demuxer */ - DVDVideoPlaybackState play_state; /* the active playback state */ int play_started; /* signal that playback has started */ int seek_warned; /* signal that we warned about seeking limits */ - int segment_started; /* signal that subdemuxer is on a segment */ + DVDVideoPlaybackState play_state; /* the active playback state */ + int64_t pts_offset; /* PTS discontinuity offset (ex. VOB change) */ + int subdemux_reset; /* signal that subdemuxer should be reset */ } DVDVideoDemuxContext; static void dvdvideo_libdvdread_log(void *opaque, dvd_logger_level_t level, @@ -390,8 +391,7 @@ static int dvdvideo_menu_open(AVFormatContext *s, DVDVideoPlaybackState *state) } static int dvdvideo_menu_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState *state, - uint8_t *buf, int buf_size, int *p_is_nav_packet, - void (*flush_cb)(AVFormatContext *s)) + uint8_t *buf, int buf_size, int *p_is_nav_packet) { int64_t blocks_read = 0; uint8_t read_buf[DVDVIDEO_BLOCK_SIZE] = {0}; @@ -399,6 +399,7 @@ static int dvdvideo_menu_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState dsi_t dsi = (dsi_t) {0}; (*p_is_nav_packet) = 0; + state->ptm_discont = 0; if (buf_size != DVDVIDEO_BLOCK_SIZE) { av_log(s, AV_LOG_ERROR, "Invalid buffer size (expected=%d actual=%d)\n", @@ -465,10 +466,8 @@ static int dvdvideo_menu_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState if (state->in_pgc) { if (state->vobu_e_ptm != pci.pci_gi.vobu_s_ptm) { - if (flush_cb) - flush_cb(s); - - state->ts_offset += state->vobu_e_ptm - pci.pci_gi.vobu_s_ptm; + state->ptm_discont = 1; + state->ptm_offset += state->vobu_e_ptm - pci.pci_gi.vobu_s_ptm; } } else { state->in_pgc = 1; @@ -479,9 +478,10 @@ static int dvdvideo_menu_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState state->vobu_duration = pci.pci_gi.vobu_e_ptm - pci.pci_gi.vobu_s_ptm; av_log(s, AV_LOG_DEBUG, "NAV packet: sector=%d " - "vobu_s_ptm=%d vobu_e_ptm=%d ts_offset=%" PRId64 "\n", + "vobu_s_ptm=%d vobu_e_ptm=%d ptm_offset=%" PRId64 "\n", dsi.dsi_gi.nv_pck_lbn, - pci.pci_gi.vobu_s_ptm, pci.pci_gi.vobu_e_ptm, state->ts_offset); + pci.pci_gi.vobu_s_ptm, pci.pci_gi.vobu_e_ptm, state->ptm_offset); + (*p_is_nav_packet) = 1; @@ -615,8 +615,7 @@ end_dvdnav_error: } static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState *state, - uint8_t *buf, int buf_size, int *p_is_nav_packet, - void (*flush_cb)(AVFormatContext *s)) + uint8_t *buf, int buf_size, int *p_is_nav_packet) { DVDVideoDemuxContext *c = s->priv_data; @@ -631,6 +630,7 @@ static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState dsi_t *e_dsi; (*p_is_nav_packet) = 0; + state->ptm_discont = 0; if (buf_size != DVDVIDEO_BLOCK_SIZE) { av_log(s, AV_LOG_ERROR, "Invalid buffer size (expected=%d actual=%d)\n", @@ -776,10 +776,8 @@ static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState state->in_ps = 1; } else { if (state->vobu_e_ptm != e_pci->pci_gi.vobu_s_ptm) { - if (flush_cb) - flush_cb(s); - - state->ts_offset += state->vobu_e_ptm - e_pci->pci_gi.vobu_s_ptm; + state->ptm_discont = 1; + state->ptm_offset += state->vobu_e_ptm - e_pci->pci_gi.vobu_s_ptm; } } @@ -938,11 +936,9 @@ static int dvdvideo_chapters_setup_preindex(AVFormatContext *s) while (!(interrupt = ff_check_interrupt(&s->interrupt_callback))) { if (c->opt_menu) - ret = dvdvideo_menu_next_ps_block(s, &state, nav_buf, DVDVIDEO_BLOCK_SIZE, &is_nav_packet, - NULL); + ret = dvdvideo_menu_next_ps_block(s, &state, nav_buf, DVDVIDEO_BLOCK_SIZE, &is_nav_packet); else - ret = dvdvideo_play_next_ps_block(s, &state, nav_buf, DVDVIDEO_BLOCK_SIZE, &is_nav_packet, - NULL); + ret = dvdvideo_play_next_ps_block(s, &state, nav_buf, DVDVIDEO_BLOCK_SIZE, &is_nav_packet); if (ret < 0 && ret != AVERROR_EOF) goto end_close; @@ -1444,19 +1440,6 @@ static int dvdvideo_subp_stream_add_all(AVFormatContext *s) return 0; } -static void dvdvideo_subdemux_flush(AVFormatContext *s) -{ - DVDVideoDemuxContext *c = s->priv_data; - - if (!c->segment_started) - return; - - av_log(s, AV_LOG_DEBUG, "flushing sub-demuxer\n"); - avio_flush(&c->mpeg_pb.pub); - ff_read_frame_flush(c->mpeg_ctx); - c->segment_started = 0; -} - static int dvdvideo_subdemux_read_data(void *opaque, uint8_t *buf, int buf_size) { AVFormatContext *s = opaque; @@ -1465,25 +1448,32 @@ static int dvdvideo_subdemux_read_data(void *opaque, uint8_t *buf, int buf_size) int ret; int is_nav_packet; - if (c->play_end) - return AVERROR_EOF; - if (c->opt_menu) - ret = dvdvideo_menu_next_ps_block(s, &c->play_state, buf, buf_size, &is_nav_packet, - dvdvideo_subdemux_flush); + ret = dvdvideo_menu_next_ps_block(s, &c->play_state, buf, buf_size, &is_nav_packet); else - ret = dvdvideo_play_next_ps_block(s, &c->play_state, buf, buf_size, &is_nav_packet, - dvdvideo_subdemux_flush); + ret = dvdvideo_play_next_ps_block(s, &c->play_state, buf, buf_size, &is_nav_packet); - if (ret == AVERROR_EOF) { - c->mpeg_pb.pub.eof_reached = 1; - c->play_end = 1; + if (ret < 0) + goto subdemux_eof; - return AVERROR_EOF; - } + if (is_nav_packet) { + if (c->play_state.ptm_discont) { + c->subdemux_reset = 1; + + ret = AVERROR_EOF; + goto subdemux_eof; + } - if (ret == 0 && is_nav_packet) return FFERROR_REDO; + } + + return ret; + +subdemux_eof: + c->mpeg_pb.pub.eof_reached = 1; + c->mpeg_pb.pub.error = ret; + c->mpeg_pb.pub.read_packet = NULL; + c->mpeg_pb.pub.buf_end = c->mpeg_pb.pub.buf_ptr = c->mpeg_pb.pub.buffer; return ret; } @@ -1525,12 +1515,24 @@ static int dvdvideo_subdemux_open(AVFormatContext *s) c->mpeg_ctx->max_analyze_duration = 0; c->mpeg_ctx->interrupt_callback = s->interrupt_callback; c->mpeg_ctx->pb = &c->mpeg_pb.pub; - c->mpeg_ctx->correct_ts_overflow = 0; c->mpeg_ctx->io_open = NULL; return avformat_open_input(&c->mpeg_ctx, "", &ff_mpegps_demuxer.p, NULL); } +static int dvdvideo_subdemux_reset(AVFormatContext *s) +{ + int ret; + + av_log(s, AV_LOG_VERBOSE, "Resetting sub-demuxer\n"); + + dvdvideo_subdemux_close(s); + if ((ret = dvdvideo_subdemux_open(s)) < 0) + return ret; + + return 0; +} + static int dvdvideo_read_header(AVFormatContext *s) { DVDVideoDemuxContext *c = s->priv_data; @@ -1619,16 +1621,20 @@ static int dvdvideo_read_packet(AVFormatContext *s, AVPacket *pkt) int st_mapped = 0; AVStream *st_subdemux; - if (c->play_end) - return AVERROR_EOF; - ret = av_read_frame(c->mpeg_ctx, pkt); + if (ret < 0) { + if (c->subdemux_reset && ret == AVERROR_EOF) { + c->subdemux_reset = 0; + c->pts_offset = c->play_state.ptm_offset; - if (ret < 0) - return ret; + if ((ret = dvdvideo_subdemux_reset(s)) < 0) + return ret; + + return FFERROR_REDO; + } - if (!c->segment_started) - c->segment_started = 1; + return ret; + } st_subdemux = c->mpeg_ctx->streams[pkt->stream_index]; is_key = pkt->flags & AV_PKT_FLAG_KEY; @@ -1656,8 +1662,8 @@ static int dvdvideo_read_packet(AVFormatContext *s, AVPacket *pkt) c->play_started = 1; } - pkt->pts += c->play_state.ts_offset - c->first_pts; - pkt->dts += c->play_state.ts_offset - c->first_pts; + pkt->pts += c->pts_offset - c->first_pts; + pkt->dts += c->pts_offset - c->first_pts; if (pkt->pts < 0) goto discard; @@ -1667,11 +1673,11 @@ static int dvdvideo_read_packet(AVFormatContext *s, AVPacket *pkt) } av_log(s, AV_LOG_TRACE, "st=%d pts=%" PRId64 " dts=%" PRId64 " " - "ts_offset=%" PRId64 " first_pts=%" PRId64 "\n", + "pts_offset=%" PRId64 " first_pts=%" PRId64 "\n", pkt->stream_index, pkt->pts, pkt->dts, - c->play_state.ts_offset, c->first_pts); + c->pts_offset, c->first_pts); - return c->play_end ? AVERROR_EOF : 0; + return 0; discard: av_log(s, st_mapped ? AV_LOG_VERBOSE : AV_LOG_DEBUG, @@ -1700,6 +1706,7 @@ static int dvdvideo_close(AVFormatContext *s) static int dvdvideo_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { DVDVideoDemuxContext *c = s->priv_data; + int ret; int64_t new_nav_pts; pci_t* new_nav_pci; dsi_t* new_nav_dsi; @@ -1744,13 +1751,17 @@ static int dvdvideo_read_seek(AVFormatContext *s, int stream_index, int64_t time c->play_state.in_ps = 0; c->play_state.is_seeking = 1; c->play_state.nav_pts = timestamp; - c->play_state.ts_offset = timestamp; + c->play_state.ptm_offset = timestamp; + c->play_state.ptm_discont = 0; c->play_state.vobu_e_ptm = new_nav_pci->pci_gi.vobu_s_ptm; c->first_pts = 0; c->play_started = 0; + c->pts_offset = timestamp; + c->subdemux_reset = 0; - dvdvideo_subdemux_flush(s); + if ((ret = dvdvideo_subdemux_reset(s)) < 0) + return ret; av_log(s, AV_LOG_DEBUG, "seeking: requested_nav_pts=%" PRId64 " new_nav_pts=%" PRId64 "\n", timestamp, new_nav_pts);