From patchwork Sun Jul 28 07:34:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marth64 X-Patchwork-Id: 50779 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:612c:16f:b0:489:2eb3:e4c4 with SMTP id h47csp537801vqi; Sun, 28 Jul 2024 00:41:55 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUzT9zFp/owv6Y34yFJTCMadcvp/pf+DzrqnSsayA0tkxswmtChzPuruT0JnWmTsKsmmxiGPOLSbjD2ZloBVQXa9ccBDW6gCBfFNw== X-Google-Smtp-Source: AGHT+IEtrvX2Y1jUEhTe+BecPHKYyVVowbK/SOInz3NWzIHMtCChigm2ldUjlc7SbATvnTVkoXNt X-Received: by 2002:a17:906:d551:b0:a6f:6b6a:e8d0 with SMTP id a640c23a62f3a-a7d3ffa5ae0mr334908966b.7.1722152515695; Sun, 28 Jul 2024 00:41:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1722152515; cv=none; d=google.com; s=arc-20160816; b=uVIKFvgpKnl46uamJ2fgUrFTCnkqVr7oX5fncKMVCJ5ThClm2C5KnC5jXEC5WxOgNR y4Z4M+N5fpTJOvd+ECSwxRaQbielM+vTcSegdmT+Sfk818AgDs8f2+jROkCdntKIooSM Rgfb6eLRvE1OLiCvJZZ1b/TEfd2w2AMGHHAp1NKNqiHZaDJ7OtjdpqIBcSQ2Ax91D7iO 10hUyx0K4FZi6uOXTgA16c9qoatZOBEFRUR8bSPv2hxEz8zlNb0vuT0mxdHgvblMm4N5 MRnYy9EuOipoLHXNu5u6EBKWS0BZQayRWHHtsJTNPdHZFvmMvoDQTlSnIvb7i34F2ddT hADA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; 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=pKFJ2wXr1BzcJ9WPnE9pYWbpDcJpMqtl6imew13+nCY=; fh=PlWMzmI9LD2qGS7ipLrQl8z0iaQTLQLHzoGuXcBzpCg=; b=vPzlXCLeRMbUX4umXj/GptlN9OmVOmddexlUtyn0wfduEnttatG6SJywfEwVIjT2N0 dI//PDuWPzdtPPiWNjCxUx1OIBtd3FPx1q83HjwIkvbOV9Ps90u6gz7BZaWyo32zB8lY YZOcEXffmrUyMYbAULPtO8bsBDCILDh83gG12/qhrUJd6fsvyKwZGwvG/qt3b3lktvnk aP1qSaFQJJwaJRq8Mz1A1R2gJzt1OPCkjXJJaKZNynbzfifYDZsge895wz89SikQq/RO Afl955Vcle1B+G0I8Q8vDl2yjlGalvA5qGoEOKKGfbEa6d0sT2hSsh1yHb4n2LI7lIKB 0fSw==; 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=JByzXi9x; 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 a640c23a62f3a-a7acacc4c65si471581866b.1024.2024.07.28.00.41.55; Sun, 28 Jul 2024 00:41:55 -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=JByzXi9x; 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 9F3EC68D744; Sun, 28 Jul 2024 10:35:18 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-yw1-f226.google.com (mail-yw1-f226.google.com [209.85.128.226]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 754CC68D76C for ; Sun, 28 Jul 2024 10:35:08 +0300 (EEST) Received: by mail-yw1-f226.google.com with SMTP id 00721157ae682-65f9e25fffaso11660867b3.3 for ; Sun, 28 Jul 2024 00:35:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proxyid.net; s=google; t=1722152107; x=1722756907; 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=3sJGFNPKSJja60wnkhuKxZ7kdB4iZ88cu2C6+C6h0bo=; b=JByzXi9xBEH3saUhsOlKNkBJCDi8G6l4APZ8GE0Zndc+OKWMlg7mreiXvKHkyW6TPS hUrvBsI6c49KN1FlHQMylxnw0puL3zFqmz6Iik/zaqdMYl+X5r5pP+QSUGilBdI1GhWX 3ha68w7Th3FvDxx5AqqxsE3FgAjQ0ynJ/aUm+4I07zgp8CiJbp20FCEAHVyLqpciNOiZ 4SjVoNu+IdnntGu7MKdO4IDaDBUu5rXlyqFRZbIJMeXg4DziE3WpsVBVCVrrmvDg0Ibk pqD77f1enLcGgEjSymeoiffQDm3TmQynU15HbXZhsF36LlU9WiHdITVDgwj+C/LWKaZz GkQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722152107; x=1722756907; 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=3sJGFNPKSJja60wnkhuKxZ7kdB4iZ88cu2C6+C6h0bo=; b=eRWu1IEduWDcaPZZdSXSf/3J3zjWglynxssVKUDmruyfgVqJul9o284isAj4MYFpRr TSo7N2XceJULm556exh4uMHNcZLzPra0IMo4pdFVWfBklPwBJudOl+z9ZzmTlbUVJ12y o5tQptjlaBug2hwgZRA4k00T77dMRjz5J4ycsWC4+HkUtGtgIwyKxuDZL0rasAwpyhjQ 8wdmfU/V+jRcKVBSaDd63p774Flpptb9bAaESuZvnrZFLkBPU4a2jArWdeOmNau4lB1L M7BgKaobMQRQHUNMmWuO+GDb+enNDANV5BQqhenD0PWapIMfyFGpTF4S9ttiQWcvPHky OhVg== X-Gm-Message-State: AOJu0Yyki04scL1IrJ51FGWrawiQ5CiRaAkPiBS9ymBMU0TfZwiNM2cJ ACYdvpGerVxxJz788PTGaloAhT3o4s5Vti174SeB8lCrhw1DlaI+WvSK7SAdf6Oj0AqxnVIqYop QYlIYKKLaxZvU2+zyeLda5Eb0e9ELfl47zZCHX6WH X-Received: by 2002:a0d:c885:0:b0:64b:7859:a92f with SMTP id 00721157ae682-67a053e0c51mr50581847b3.5.1722152107111; Sun, 28 Jul 2024 00:35:07 -0700 (PDT) Received: from wsx-cc1-001.. (c-76-136-218-80.hsd1.il.comcast.net. [76.136.218.80]) by smtp-relay.gmail.com with ESMTPS id 00721157ae682-6756ad425desm5735937b3.61.2024.07.28.00.35.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Jul 2024 00:35:07 -0700 (PDT) X-Relaying-Domain: proxyid.net From: Marth64 To: ffmpeg-devel@ffmpeg.org Date: Sun, 28 Jul 2024 02:34:40 -0500 Message-Id: <20240728073445.725161-3-marth64@proxyid.net> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240728073445.725161-1-marth64@proxyid.net> References: <20240728073445.725161-1-marth64@proxyid.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/7] 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: yeurvUX0i7IY Player applications can now enjoy seeking while playing back a title. Accuracy is at the mercy of what libdvdnav offers, which is currently dvdnav_jump_to_sector_by_time(). Signed-off-by: Marth64 --- libavformat/dvdvideodec.c | 93 ++++++++++++++++++++++++++++++++++----- 1 file changed, 82 insertions(+), 11 deletions(-) diff --git a/libavformat/dvdvideodec.c b/libavformat/dvdvideodec.c index e745165e00..e8301b1173 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 */ @@ -722,7 +723,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; } @@ -735,7 +737,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; } @@ -807,13 +809,15 @@ static int dvdvideo_play_next_ps_block(AVFormatContext *s, DVDVideoPlaybackState return AVERROR_INPUT_CHANGED; } - memcpy(buf, &nav_buf, nav_len); - if (state->pgn != cur_pgn) av_log(s, AV_LOG_WARNING, "Unexpected PG change (expected=%d actual=%d); " "this could be due to a missed NAV packet\n", state->pgn, cur_pgn); + memcpy(buf, &nav_buf, nav_len); + + state->is_seeking = 0; + return nav_len; case DVDNAV_WAIT: if (dvdnav_wait_skip(state->dvdnav) != DVDNAV_STATUS_OK) { @@ -1659,17 +1663,17 @@ static int dvdvideo_read_packet(AVFormatContext *s, AVPacket *pkt) } av_log(s, AV_LOG_TRACE, "st=%d pts=%" PRId64 " dts=%" PRId64 " " - "pts_offset=%" PRId64 " first_pts=%" PRId64 "\n", + "pts_offset=%" PRId64 " first_pts=%" PRId64 " is_seeking=%d\n", pkt->stream_index, pkt->pts, pkt->dts, - c->pts_offset); + c->pts_offset, c->first_pts, c->play_state.is_seeking); return 0; discard: av_log(s, AV_LOG_VERBOSE, "Discarding packet @ st=%d pts=%" PRId64 " dts=%" PRId64 " " - "st_matched=%d\n", + "st_matched=%d is_seeking=%d\n", st_matched ? pkt->stream_index : -1, pkt->pts, pkt->dts, - st_matched); + st_matched, c->play_state.is_seeking); return FFERROR_REDO; } @@ -1690,6 +1694,72 @@ 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; + int ret; + 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.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; + + 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); + + 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 }, @@ -1718,11 +1788,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 };