PR #22951 opened by Link Mauve (linkmauve) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22951 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22951.patch
This lets us seek in the video properly, based on the table at the end of the files, and has been tested with [Suikoden Tierkreis](https://en.wikipedia.org/wiki/Suikoden_Tierkreis) videos. While at it I’ve also set the duration of the stream, this makes the progress bar work correctly in mpv. From cc0264a1b5c057dd32031f9fbea469991aa3f47e Mon Sep 17 00:00:00 2001 From: Link Mauve <[email protected]> Date: Tue, 28 Apr 2026 17:49:25 +0200 Subject: [PATCH] avformat/mods: Parse the index entries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This lets us seek in the video properly, based on the table at the end of the files, and has been tested with Suikoden Tierkreis videos. While at it I’ve also set the duration of the stream, this makes the progress bar work correctly in mpv. --- libavformat/mods.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/libavformat/mods.c b/libavformat/mods.c index 7f76124821..2bfea62559 100644 --- a/libavformat/mods.c +++ b/libavformat/mods.c @@ -3,6 +3,7 @@ * Copyright (c) 2015-2016 Florian Nouwt * Copyright (c) 2017 Adib Surani * Copyright (c) 2020 Paul B Mahol + * Copyright (c) 2026 Link Mauve * * This file is part of FFmpeg. * @@ -45,6 +46,9 @@ static int mods_read_header(AVFormatContext *s) AVIOContext *pb = s->pb; AVRational fps; int64_t pos; + int64_t timestamp; + int num_keyframes; + const AVIndexEntry *e; AVStream *st = avformat_new_stream(s, NULL); if (!st) @@ -53,6 +57,7 @@ static int mods_read_header(AVFormatContext *s) avio_skip(pb, 8); st->nb_frames = avio_rl32(pb); + st->duration = st->nb_frames; st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; st->codecpar->codec_id = AV_CODEC_ID_MOBICLIP; st->codecpar->width = avio_rl32(pb); @@ -64,11 +69,22 @@ static int mods_read_header(AVFormatContext *s) avio_skip(pb, 16); - pos = avio_rl32(pb) + 4; - avio_seek(pb, pos, SEEK_SET); pos = avio_rl32(pb); + num_keyframes = avio_rl32(pb); avio_seek(pb, pos, SEEK_SET); + for (int i = 0; i < num_keyframes; ++i) { + timestamp = avio_rl32(pb); + pos = avio_rl32(pb); + av_add_index_entry(st, pos, timestamp, 0, 0, AVINDEX_KEYFRAME); + } + + e = avformat_index_get_entry(st, 0); + if (!e) + return AVERROR(EINVAL); + + avio_seek(pb, e->pos, SEEK_SET); + return 0; } @@ -87,7 +103,6 @@ static int mods_read_packet(AVFormatContext *s, AVPacket *pkt) ret = av_get_packet(pb, pkt, size); pkt->pos = pos; pkt->stream_index = 0; - pkt->flags |= AV_PKT_FLAG_KEY; return ret; } -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
