From patchwork Fri Sep 13 05:37:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marth64 X-Patchwork-Id: 51563 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:612c:2986:b0:48e:c0f8:d0de with SMTP id ih6csp81670vqb; Thu, 12 Sep 2024 22:39:42 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCWwDO204ijZNAqryRa0/54JYRZMxLURIlc+2AkWeKqid3/Xp1yCxwlMU5TUXfqlXtRmg2tSGD9JE+ntpe10xizp@gmail.com X-Google-Smtp-Source: AGHT+IHJ0CdtlHbxOF227OMIYL2jWiE3XhSOWBCb5QiSJbRlNqm5M4UWI9AhSNzW69wcUR78bPih X-Received: by 2002:a05:6402:510a:b0:5c3:eb29:5400 with SMTP id 4fb4d7f45d1cf-5c413e5f659mr1447445a12.8.1726205982216; Thu, 12 Sep 2024 22:39:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726205982; cv=none; d=google.com; s=arc-20240605; b=RyCPpLm3N76w+wom5E8T3lLX9IIfWYmRuwVCj1jX/bzB2UC0QGHAK8cw7gbCDKhDo3 RCLlaemXWDAFvEroLKUPtgssExDHik0b5D/tDynkLYuT7JxRGiSSieU4WlFm9b09AXVH KVAuUj2xa3P4TtkbXUQaPD7bqCE5gsBmax6O1b+dvBGxMkjasQ4SfgnBK8LHCfCdh2c3 w7aMZDIuQjd4vvcdYCODJbCihR3/uxX10ZKSq8+NBq9uKoWWg9svc7w6KWMQY/tE5nTr mcaIva8xC+XP8usVNYbXJ8zz0SsGL4g9XNphgXH5z3FbPdfmJ8PkRu9jN8kSQ0eqKQno nT5A== 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:message-id:date:to:from :dkim-signature:delivered-to; bh=Anaaf2Nk+XRFej+sTlPgszGGn6aSccaMIP+nLjp32pk=; fh=PlWMzmI9LD2qGS7ipLrQl8z0iaQTLQLHzoGuXcBzpCg=; b=PXYb4rfmXc2JkQn2y/vLEoohGd47s+i16bblk0tGZ/mz7kpekyM6bPyXDs8vHGoDbK kaS2TOhkKPUCgo8WICZGH4H6NVyK7c//eoj3ocOq5wvfP95doEpV7tLWLkEol4BnolE+ 6Ve/n5SO+qxEmzp6t6Hdi7f4Qa244vargUp87tgIP2ElGa44GpPtWuPGPIpChJycROPj IjaXIWlZNvLQjw92fJp4SbXG8XoU9iG6LPug2ytu1eSgc0peQrVGWQAisGkdc9fN0VHe 6//lxyJU+bTIr+f3NSoCzsh0OV6oltlAF0c7yKuasY7hR9sfBsd0uORwBn/wN+d0L4pp KP4g==; 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=bc1nP5pO; 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-5c3ebd42aacsi9728701a12.39.2024.09.12.22.39.41; Thu, 12 Sep 2024 22:39:42 -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=bc1nP5pO; 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 A95B868DDE6; Fri, 13 Sep 2024 08:39:38 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ot1-f97.google.com (mail-ot1-f97.google.com [209.85.210.97]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id BE58468D968 for ; Fri, 13 Sep 2024 08:39:32 +0300 (EEST) Received: by mail-ot1-f97.google.com with SMTP id 46e09a7af769-7093b53f315so141447a34.2 for ; Thu, 12 Sep 2024 22:39:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proxyid.net; s=google; t=1726205971; x=1726810771; 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=5nKutinUhEAkCnsGvRNCA3OgXFBBZ+LOyUJpVGSvRro=; b=bc1nP5pO2rIKEGCK2q0Baf85BBi39HGGjYl4E5ZCljVOyA1ni8avuMcw4It9PhzeYK btpOwbEsHuXAH3yO61Xpsm/PEOWfaao916kkKWmnNPL0+kXm2c7O/BxbgarQZ7afEXxk pqVKaeHDmxKzUeq4BBQWz6LWTze8sbSUpVipAJskFxApOI/TbUrlxO9QYvnAIEkNX+US LzL6F5B5yZPXw20JaCbq07RJ17wsEL6fes3GT/QpFBgVm1ZMy3PfGW9oNmWxYHfxcqZ1 jjIihhswKMR8EtypVaZ8oDTwnQQa1hNrjabMGNvVwkMXBs1BTD22OxUFJMyAAk04Oz/C Ma7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726205971; x=1726810771; 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=5nKutinUhEAkCnsGvRNCA3OgXFBBZ+LOyUJpVGSvRro=; b=tUzoZsiKjOxjxUDm5ZBxIAqd0okVftiQes/VoPZcV0dk2h07mF3pK6HCIc71O1avik VNrvjyX/J+aOgIq2Nvs77s2nSPUG6+436NdBiYE643HFJth/9GSpxEmbaH2NIXg6cD4O mYkqPtnTsF6ErvFGNMBWNIu8cd4/3N9VNXe0Y6rKZmfszI6WSPEFXBhSh7UJ9oxJQjdf 01mCqymSed4QLkuvudJ8D+avCHt9ysgC78ZnGVE0FIKpCCiRAc+BXKpcRLaaSOQjsXdv 2qP92djyX5UMGY1DsFZ1R4ashaDvU5Bw/VDIyvwu9JrOH0/Zr1FJpnQ5vE670uSOTByz +LLw== X-Gm-Message-State: AOJu0YzI4sBLiE31SsRtxtHwXXxUBXQ3JgZtJa+Yk2Tr5UevuHRifbpB ImE1mA5IMfJBIpT5CztgAMCG/DapYso081Z/eETf1lQ4QoqjeHQPMkkxu4+4lubSKTu0tP4Bc/R b9AmaZ+R5hh/A8t9oAXwOiZXoai8A0iPBQwVFUkxC X-Received: by 2002:a05:6870:82a2:b0:261:9fc:16b9 with SMTP id 586e51a60fabf-27c68bd656emr1025996fac.33.1726205970824; Thu, 12 Sep 2024 22:39:30 -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 586e51a60fabf-27ba40a2ec5sm543302fac.30.2024.09.12.22.39.30 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Thu, 12 Sep 2024 22:39:30 -0700 (PDT) X-Relaying-Domain: proxyid.net From: Marth64 To: ffmpeg-devel@ffmpeg.org Date: Fri, 13 Sep 2024 00:37:44 -0500 Message-Id: <20240913053744.64521-1-marth64@proxyid.net> X-Mailer: git-send-email 2.39.3 (Apple Git-146) MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] avformat/dvdvideodec: implement seeking 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: 6nrlpQj6uIE3 Player applications can now enjoy seeking while playing back a title. Accuracy is at the mercy of what libdvdnav exposes, which is currently dvdnav_time_search(). Signed-off-by: Marth64 --- libavformat/dvdvideodec.c | 77 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 5 deletions(-) diff --git a/libavformat/dvdvideodec.c b/libavformat/dvdvideodec.c index 7a859071c3..6bd1dbc17f 100644 --- a/libavformat/dvdvideodec.c +++ b/libavformat/dvdvideodec.c @@ -110,6 +110,7 @@ typedef struct DVDVideoPlaybackState { int in_pgc; /* if our navigator is in the PGC */ int in_ps; /* if our navigator is in the program stream */ 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 */ uint64_t pgc_duration_est; /* estimated duration as reported by IFO */ uint64_t pgc_elapsed; /* the elapsed time of the PGC, cell-relative */ @@ -167,6 +168,7 @@ typedef struct DVDVideoDemuxContext { 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 */ } DVDVideoDemuxContext; @@ -715,7 +717,8 @@ static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState state->in_pgc = 1; } - } else if (state->celln >= e_cell->cellN || state->pgn > cur_pgn) { + } else if (!state->is_seeking && + (state->celln >= e_cell->cellN || state->pgn > cur_pgn)) { return AVERROR_EOF; } @@ -728,7 +731,7 @@ static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState if (!state->in_pgc) continue; - if ((state->ptt > 0 && state->ptt > cur_ptt) || + if ((!state->is_seeking && state->ptt > 0 && state->ptt > cur_ptt) || (c->opt_chapter_end > 0 && cur_ptt > c->opt_chapter_end)) { return AVERROR_EOF; } @@ -811,6 +814,8 @@ static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState (*p_nav_event) = nav_event; + state->is_seeking = 0; + return nav_len; case DVDNAV_WAIT: if (dvdnav_wait_skip(state->dvdnav) != DVDNAV_STATUS_OK) { @@ -1688,6 +1693,67 @@ static int dvdvideo_close(AVFormatContext *s) return 0; } +static int dvdvideo_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) +{ + DVDVideoDemuxContext *c = s->priv_data; + int64_t new_nav_pts; + pci_t* new_nav_pci; + dsi_t* new_nav_dsi; + + 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"); + + return AVERROR_PATCHWELCOME; + } + + if ((flags & AVSEEK_FLAG_BYTE)) + return AVERROR(ENOSYS); + + if (timestamp < 0) + return AVERROR(EINVAL); + + if (!c->seek_warned) { + av_log(s, AV_LOG_WARNING, "Seeking is inherently unreliable and will result " + "in imprecise timecodes from this point\n"); + c->seek_warned = 1; + } + + /* 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) { + av_log(s, AV_LOG_ERROR, "libdvdnav: seeking to %" PRId64 " failed\n", timestamp); + + return AVERROR_EXTERNAL; + } + + new_nav_pts = dvdnav_get_current_time (c->play_state.dvdnav); + new_nav_pci = dvdnav_get_current_nav_pci(c->play_state.dvdnav); + new_nav_dsi = dvdnav_get_current_nav_dsi(c->play_state.dvdnav); + + if (new_nav_pci == NULL || new_nav_dsi == NULL) { + av_log(s, AV_LOG_ERROR, "Invalid NAV packet after seeking\n"); + + return AVERROR_INVALIDDATA; + } + + c->play_state.in_pgc = 1; + 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.vobu_e_ptm = new_nav_pci->pci_gi.vobu_s_ptm; + + c->first_pts = 0; + c->play_started = 0; + + dvdvideo_subdemux_flush(s); + + av_log(s, AV_LOG_DEBUG, "seeking: requested_nav_pts=%" PRId64 " new_nav_pts=%" PRId64 "\n", + timestamp, new_nav_pts); + + return 0; +} + #define OFFSET(x) offsetof(DVDVideoDemuxContext, x) static const AVOption dvdvideo_options[] = { {"angle", "playback angle number", OFFSET(opt_angle), AV_OPT_TYPE_INT, { .i64=1 }, 1, 9, AV_OPT_FLAG_DECODING_PARAM }, @@ -1716,11 +1782,12 @@ const FFInputFormat ff_dvdvideo_demuxer = { .p.name = "dvdvideo", .p.long_name = NULL_IF_CONFIG_SMALL("DVD-Video"), .p.priv_class = &dvdvideo_class, - .p.flags = AVFMT_NOFILE | AVFMT_SHOW_IDS | AVFMT_TS_DISCONT | - AVFMT_NO_BYTE_SEEK | AVFMT_NOGENSEARCH | AVFMT_NOBINSEARCH, + .p.flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT | AVFMT_SEEK_TO_PTS | + AVFMT_NOFILE | AVFMT_NO_BYTE_SEEK | AVFMT_NOGENSEARCH | AVFMT_NOBINSEARCH, .priv_data_size = sizeof(DVDVideoDemuxContext), .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP, .read_close = dvdvideo_close, .read_header = dvdvideo_read_header, - .read_packet = dvdvideo_read_packet + .read_packet = dvdvideo_read_packet, + .read_seek = dvdvideo_read_seek };