* [FFmpeg-devel] [PATCH] libopenmpt: fix seeking
@ 2025-07-28 2:58 kimapr via ffmpeg-devel
2025-07-31 14:19 ` Michael Niedermayer
0 siblings, 1 reply; 3+ messages in thread
From: kimapr via ffmpeg-devel @ 2025-07-28 2:58 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: kimapr
[-- Attachment #1: Type: text/plain, Size: 1391 bytes --]
This patch fixes strange seeking behavior i have observed in mpv when using the libopenmpt demuxer, caused by mismatch in position state between the demuxer and underlying libopenmpt library. Not setting the presentation timestamp field of the AVPacket caused it to be guessed by libavformat, but the guess didn't take seeking into account, so after seeking libopenmpt produced packets at the new seeked position but they were then presented as if they belong to the old position! A quick check for this behavior is to open a tracker tracker module that is, for example 2 minutes and a few seconds long in mpv, and then press "up" 2 times (which would seek 2 minutes forward): buggy demuxer causes mpv to exit immediately after seek because of an EOF, with non-buggy demuxer mpv will play the last few seconds of the song and then exit.
I found the bug when writing my own demuxer for an obscure audio format (which i'm not quite sure if i should submit too) as i was using the libopenmpt one as a reference and copied the bug too. Testing was done on 6.1.1, but libopenmpt demuxer's code didn't really change since then so it should be relevant for the latest one too (unless the default value for pkt->pts changed to take seeking into account), and either way it makes more sense to expose information that is very much available to the demuxer rather than leave it to be guessed.
[-- Attachment #2: 0001-libopenmpt-fix-seeking.patch --]
[-- Type: text/x-patch, Size: 1038 bytes --]
From 451691febac466cee37d9b836228e30c53813d60 Mon Sep 17 00:00:00 2001
From: Kimapr <kimapr.fr@gmail.com>
Date: Mon, 28 Jul 2025 06:32:27 +0500
Subject: [PATCH] libopenmpt: fix seeking
---
libavformat/libopenmpt.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/libavformat/libopenmpt.c b/libavformat/libopenmpt.c
index c270a60cb2..d383d65ad8 100644
--- a/libavformat/libopenmpt.c
+++ b/libavformat/libopenmpt.c
@@ -171,6 +171,8 @@ static int read_packet_openmpt(AVFormatContext *s, AVPacket *pkt)
if ((ret = av_new_packet(pkt, AUDIO_PKT_SIZE)) < 0)
return ret;
+ double pos = openmpt_module_get_position_seconds(openmpt->module);
+
switch (openmpt->ch_layout.nb_channels) {
case 1:
ret = openmpt_module_read_float_mono(openmpt->module, openmpt->sample_rate,
@@ -195,6 +197,7 @@ static int read_packet_openmpt(AVFormatContext *s, AVPacket *pkt)
}
pkt->size = ret * (openmpt->ch_layout.nb_channels * 4);
+ pkt->pts = llrint(pos * AV_TIME_BASE);
return 0;
}
--
2.49.0
[-- Attachment #3: Type: text/plain, Size: 251 bytes --]
_______________________________________________
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".
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [FFmpeg-devel] [PATCH] libopenmpt: fix seeking
2025-07-28 2:58 [FFmpeg-devel] [PATCH] libopenmpt: fix seeking kimapr via ffmpeg-devel
@ 2025-07-31 14:19 ` Michael Niedermayer
2025-08-01 6:04 ` kimapr via ffmpeg-devel
0 siblings, 1 reply; 3+ messages in thread
From: Michael Niedermayer @ 2025-07-31 14:19 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1.1: Type: text/plain, Size: 3319 bytes --]
Hi
On Mon, Jul 28, 2025 at 07:58:18AM +0500, kimapr via ffmpeg-devel wrote:
> This patch fixes strange seeking behavior i have observed in mpv when using the libopenmpt demuxer, caused by mismatch in position state between the demuxer and underlying libopenmpt library. Not setting the presentation timestamp field of the AVPacket caused it to be guessed by libavformat, but the guess didn't take seeking into account, so after seeking libopenmpt produced packets at the new seeked position but they were then presented as if they belong to the old position! A quick check for this behavior is to open a tracker tracker module that is, for example 2 minutes and a few seconds long in mpv, and then press "up" 2 times (which would seek 2 minutes forward): buggy demuxer causes mpv to exit immediately after seek because of an EOF, with non-buggy demuxer mpv will play the last few seconds of the song and then exit.
>
> I found the bug when writing my own demuxer for an obscure audio format (which i'm not quite sure if i should submit too) as i was using the libopenmpt one as a reference and copied the bug too. Testing was done on 6.1.1, but libopenmpt demuxer's code didn't really change since then so it should be relevant for the latest one too (unless the default value for pkt->pts changed to take seeking into account), and either way it makes more sense to expose information that is very much available to the demuxer rather than leave it to be guessed.
> libopenmpt.c | 3 +++
> 1 file changed, 3 insertions(+)
> fd581b2b26ac22fc5bdcac053c98d9b541052fb2 0001-libopenmpt-fix-seeking.patch
> From 451691febac466cee37d9b836228e30c53813d60 Mon Sep 17 00:00:00 2001
> From: Kimapr <kimapr.fr@gmail.com>
> Date: Mon, 28 Jul 2025 06:32:27 +0500
> Subject: [PATCH] libopenmpt: fix seeking
>
> ---
> libavformat/libopenmpt.c | 3 +++
> 1 file changed, 3 insertions(+)
while your email contains quite some details, the commit message of
just "libopenmpt: fix seeking" is too terse
>
> diff --git a/libavformat/libopenmpt.c b/libavformat/libopenmpt.c
> index c270a60cb2..d383d65ad8 100644
> --- a/libavformat/libopenmpt.c
> +++ b/libavformat/libopenmpt.c
> @@ -171,6 +171,8 @@ static int read_packet_openmpt(AVFormatContext *s, AVPacket *pkt)
> if ((ret = av_new_packet(pkt, AUDIO_PKT_SIZE)) < 0)
> return ret;
>
> + double pos = openmpt_module_get_position_seconds(openmpt->module);
is there any possibility of a "unknown" "position" ?
if not its fine otherwise a check may be needed to handle that
> +
> switch (openmpt->ch_layout.nb_channels) {
> case 1:
> ret = openmpt_module_read_float_mono(openmpt->module, openmpt->sample_rate,
> @@ -195,6 +197,7 @@ static int read_packet_openmpt(AVFormatContext *s, AVPacket *pkt)
> }
>
> pkt->size = ret * (openmpt->ch_layout.nb_channels * 4);
> + pkt->pts = llrint(pos * AV_TIME_BASE);
is it possible that this exceeds the int64_t range ?
if so these out of range values should probably be replaced by AV_NOPTS_VALUE
thx
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
I have never wished to cater to the crowd; for what I know they do not
approve, and what they approve I do not know. -- Epicurus
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
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".
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [FFmpeg-devel] [PATCH] libopenmpt: fix seeking
2025-07-31 14:19 ` Michael Niedermayer
@ 2025-08-01 6:04 ` kimapr via ffmpeg-devel
0 siblings, 0 replies; 3+ messages in thread
From: kimapr via ffmpeg-devel @ 2025-08-01 6:04 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: kimapr
[-- Attachment #1: Type: text/plain, Size: 920 bytes --]
revised the patch, hopefully it's better now. i also fixed
another weirdness that i didn't fix in the original patch
On 2025/07/31 19:19, Michael Niedermayer wrote:
> while your email contains quite some details, the commit message of
> just "libopenmpt: fix seeking" is too terse
added some details!
> is there any possibility of a "unknown" "position" ?
> if not its fine otherwise a check may be needed to handle that
no idea. openmpt docs don't mention the possibility, and
besides like returning a NaN there isn't really much the API
can do to indicate such a condition
> is it possible that this exceeds the int64_t range ?
> if so these out of range values should probably be replaced by AV_NOPTS_VALUE
seems unlikely! i added a check anyway though (should also catch the
unknown position if it is indicated by a NaN). rather than replacing
the value with AV_NOPTS_VALUE i just don't set it. Is that good?
[-- Attachment #2: 0001-libopenmpt-fix-seeking-weirdness.patch --]
[-- Type: text/x-patch, Size: 2534 bytes --]
From d6418b665cc80a1680afee8259a242a42c0ed2ad Mon Sep 17 00:00:00 2001
From: Kimapr <kimapr.fr@gmail.com>
Date: Mon, 28 Jul 2025 06:32:27 +0500
Subject: [PATCH] libopenmpt: fix seeking weirdness
- proper pts for packets. leaving it blank leaves it up for guessing,
but the guess doesn't take seeking into account, causing weirdness.
- clamp to 0 when seeking to negative ts. libopenmpt docs are unclear on
this but not doing this causes an immediate EOF when seeking backwards
to the beginning in mpv.
- only set song duration and packet pts when they are non-negative and
in int64 range. NaNs count as out of range. this isn't a fix for any
specific issue but might be helpful still, and shouldn't break
anything.
---
libavformat/libopenmpt.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/libavformat/libopenmpt.c b/libavformat/libopenmpt.c
index 3ca59f506f..ab61000d0a 100644
--- a/libavformat/libopenmpt.c
+++ b/libavformat/libopenmpt.c
@@ -147,7 +147,10 @@ static int read_header_openmpt(AVFormatContext *s)
if (!st)
return AVERROR(ENOMEM);
avpriv_set_pts_info(st, 64, 1, AV_TIME_BASE);
- st->duration = llrint(openmpt->duration*AV_TIME_BASE);
+
+ if (openmpt->duration * AV_TIME_BASE <= INT64_MAX &&
+ openmpt->duration * AV_TIME_BASE >= 0)
+ st->duration = llrint(openmpt->duration*AV_TIME_BASE);
st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
st->codecpar->codec_id = AV_NE(AV_CODEC_ID_PCM_F32BE, AV_CODEC_ID_PCM_F32LE);
@@ -170,6 +173,8 @@ static int read_packet_openmpt(AVFormatContext *s, AVPacket *pkt)
if ((ret = av_new_packet(pkt, AUDIO_PKT_SIZE)) < 0)
return ret;
+ double pos = openmpt_module_get_position_seconds(openmpt->module) * AV_TIME_BASE;
+
switch (openmpt->ch_layout.nb_channels) {
case 1:
ret = openmpt_module_read_float_mono(openmpt->module, openmpt->sample_rate,
@@ -195,6 +200,9 @@ static int read_packet_openmpt(AVFormatContext *s, AVPacket *pkt)
pkt->size = ret * (openmpt->ch_layout.nb_channels * 4);
+ if (pos >= 0 && pos <= INT64_MAX)
+ pkt->pts = llrint(pos);
+
return 0;
}
@@ -211,6 +219,8 @@ static int read_close_openmpt(AVFormatContext *s)
static int read_seek_openmpt(AVFormatContext *s, int stream_idx, int64_t ts, int flags)
{
OpenMPTContext *openmpt = s->priv_data;
+ if (ts < 0)
+ ts = 0;
openmpt_module_set_position_seconds(openmpt->module, (double)ts/AV_TIME_BASE);
return 0;
}
--
2.49.0
[-- Attachment #3: Type: text/plain, Size: 251 bytes --]
_______________________________________________
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".
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-08-01 6:05 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-07-28 2:58 [FFmpeg-devel] [PATCH] libopenmpt: fix seeking kimapr via ffmpeg-devel
2025-07-31 14:19 ` Michael Niedermayer
2025-08-01 6:04 ` kimapr via ffmpeg-devel
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git