Seeking back by bytes during a transcode can serve data from much later in the video

Open
#6,371 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
50/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
java
Domain
backend

Research direction

Start with StoreItem.java around line 968 and BufferedOutputFileImpl.java around line 695, then trace how byte-range requests use the shared ring buffer during transcoding. Reproduce a backward byte seek after the buffer reaches its 200 MB limit. Done means an overwritten buffer position cannot serve unrelated later video data, including for the affected byte-seeking renderers.

Written by the indexing model from the issue text.

Description

UMS version: 15.8.1 (macOS 26.7, Apple Silicon)
Renderer: Philips 37PFL8605H (Philips-PFL profile, which seeks by bytes), FFmpeg Video (MPEGPS-MPEG2-AC3)

Problem

While a video is being transcoded, seeking forward on the TV works fine. Seeking back works only right after playback starts. A bit later, even a short step back shows a much later part of the video: from ~38 min, stepping back ~2 min showed the video from ~52 min. Seeking back further can also end up looping. Stopping and starting the video again fixes it.

What I found

The trace log shows the TV seeking with byte ranges (Range: bytes=N-). While the transcode is running, that request is served from the existing buffer:

https://github.com/UniversalMediaServer/UniversalMediaServer/blob/459aa68bbb37ef0e598d8df2bb871f840652b12e/src/main/java/net/pms/store/StoreItem.java#L968

The buffer is a ring of maximum_video_buffer_size (200 MB by default), and the read position is used as readCount % maxMemorySize, without checking whether that part was already overwritten:

https://github.com/UniversalMediaServer/UniversalMediaServer/blob/459aa68bbb37ef0e598d8df2bb871f840652b12e/src/main/java/net/pms/io/BufferedOutputFileImpl.java#L695

FFmpeg transcodes much faster than playback, so the buffer fills up ahead of the TV within seconds (log: buffered: 189,257,728 bytes 9 s after starting, staying around 200 MB after that). At that point there's hardly anything left behind the current read position, and older positions now hold data from roughly 200 MB further into the stream, which matches the jump to ~52 min.

I haven't looked into how this could be fixed. The buffer is shared by all renderers and engines, so I didn't want to guess at a change there.

Notes
  • Renderers with SeekByTime = exclusive aren't affected, since time seeks restart the transcode with -ss. Of the 218 bundled renderer profiles, 93 leave SeekByTime unset/false (bytes only) and 75 set it to true (both).
  • I didn't find an existing report of this. Happy to provide trace logs.

Put together with help from an AI assistant (Claude).

Dominant language
Java
Stars
2.7k
Forks
525
Avg merge
13h 12m
Merged PRs (30d)
44

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from UniversalMediaServer/UniversalMediaServer

All issues in UniversalMediaServer/UniversalMediaServer

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.