From 9891f19a7187ba77dac72f6bbbe99c8cfb327f31 Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Wed, 1 Oct 2025 11:05:59 +0200 Subject: [PATCH] vcap/file: fix raw HEVC rewinding Rewinding the file (:loop option) doesn't work using raw HEVC like with the [file]. avformat_seek_file retrurns EPERM, which was handled as an error, so stopped the worker. avio_seek seems to do the job but must be performed _after_ (unsuccessful) avformat_seek_file. [file]: https://ultravideo.fi/video/ReadySetGo_3840x2160_120fps_420_8bit_HEVC_RAW.hevc --- src/video_capture/file.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/video_capture/file.c b/src/video_capture/file.c index dfb0d9016..9c6e26310 100644 --- a/src/video_capture/file.c +++ b/src/video_capture/file.c @@ -465,6 +465,19 @@ static void print_packet_info(const AVPacket *pkt, const AVStream *st) { pts_val, dts_val, pkt->duration, tb.num, tb.den, pkt->size); } +static void +rewind_file(struct vidcap_state_lavf_decoder *s) +{ + CHECK_FF(avformat_seek_file(s->fmt_ctx, -1, INT64_MIN, + s->fmt_ctx->start_time, INT64_MAX, 0), + {}); + // handle single JPEG loop, inspired by libavformat's seek_frame_generic + // because img_read_seek (AVInputFormat::read_seek) doesn't do the job - + // seeking is inmplemeted just in img2dec if VideoDemuxData::loop == 1 + CHECK_FF(avio_seek(s->fmt_ctx->pb, s->video_stream_idx, SEEK_SET), {}); + flush_captured_data(s); +} + #define FAIL_WORKER { pthread_mutex_lock(&s->lock); s->failed = true; pthread_mutex_unlock(&s->lock); pthread_cond_signal(&s->new_frame_ready); return NULL; } static void *vidcap_file_worker(void *state) { set_thread_name(__func__); @@ -497,9 +510,7 @@ static void *vidcap_file_worker(void *state) { int ret = av_read_frame(s->fmt_ctx, pkt); if (ret == AVERROR_EOF) { if (s->loop) { - CHECK_FF(avio_seek(s->fmt_ctx->pb, s->video_stream_idx, SEEK_SET), {}); // handle single JPEG loop, inspired by libavformat's seek_frame_generic because img_read_seek (AVInputFormat::read_seek) doesn't do the job - seeking is inmplemeted just in img2dec if VideoDemuxData::loop == 1 - CHECK_FF(avformat_seek_file(s->fmt_ctx, -1, INT64_MIN, s->fmt_ctx->start_time, INT64_MAX, 0), FAIL_WORKER); - flush_captured_data(s); + rewind_file(s); log_msg(LOG_LEVEL_NOTICE, MOD_NAME "Rewinding the file.\n"); continue; } else {