Skip to content

Add in-memory timeshift feature#3745

Draft
jbleyel wants to merge 5 commits intomasterfrom
eram
Draft

Add in-memory timeshift feature#3745
jbleyel wants to merge 5 commits intomasterfrom
eram

Conversation

@jbleyel
Copy link
Copy Markdown
Contributor

@jbleyel jbleyel commented Mar 26, 2026

RAM-based timeshift as an alternative to disk-based timeshift. When enabled via config.timeshift.ram_mode, live DVB TS data is buffered in a fixed-size circular RAM ring buffer instead of written to disk. After a configurable delay (config.timeshift.ram_delay_seconds, default 10 s) timeshift activates automatically so the viewer sees the time-delayed picture. Pause, unpause, and seek all work identically to disk timeshift.

The ring buffer capacity is derived from the delay setting with delay_seconds * 4 MB (e.g. 10 s -> 40 MB). Once the buffer wraps, the oldest data is silently overwritten, so only the most recent seconds of content are available for rewind -- by design this is an "instant replay" feature, not a replacement for disk timeshift.

Core components:

eRamRingBuffer -- seekable circular RAM buffer addressed by
monotonically increasing absolute byte offsets.
Handles wrap-around transparently.

eRamTsSource -- iTsSource implementation backed by the ring
buffer. Returns EAGAIN when the read position
has been lapped (ring overwrite) and signals the
service layer to recover. Returns 0 at the
write edge so the push thread retries.

eRamRecorder -- eDVBRecordScrambledThread subclass that writes
into RAM instead of disk and extracts PCR
timestamps for seek support.

eRamServicePlay -- extends eDVBServicePlay with RAM recording,
timer-based auto-activation, PCR-based seeking,
lap-detection watchdog, and CSA descrambling
support for StreamRelay channels.

Seeking and lap-recovery use forcePosition() on eFilePushThread which directly sets the push thread's m_current_position. This bypasses both setStartOffset() (which has no effect because the push thread never calls m_source->offset()) and the cue-sheet path (which relies on tstools .ap data that does not exist for RAM buffers).

The push thread EOF path is reordered so that timeshift mode (m_flags == 1) returns to the read loop without sending evtEOF, avoiding ~70 spurious "End of file!" events per session.

jbleyel added 5 commits March 26, 2026 12:53
RAM-based timeshift as an alternative to disk-based timeshift.  When
enabled via config.timeshift.ram_mode, live DVB TS data is buffered
in a fixed-size circular RAM ring buffer instead of written to disk.
After a configurable delay (config.timeshift.ram_delay_seconds,
default 10 s) timeshift activates automatically so the viewer sees
the time-delayed picture.  Pause, unpause, and seek all work
identically to disk timeshift.

The ring buffer capacity is derived from the delay setting with
delay_seconds * 4 MB (e.g. 10 s -> 40 MB).  Once the buffer wraps,
the oldest data is silently overwritten, so only the most recent
seconds of content are available for rewind -- by design this is an
"instant replay" feature, not a replacement for disk timeshift.

Core components:

  eRamRingBuffer  -- seekable circular RAM buffer addressed by
                     monotonically increasing absolute byte offsets.
                     Handles wrap-around transparently.

  eRamTsSource    -- iTsSource implementation backed by the ring
                     buffer.  Returns EAGAIN when the read position
                     has been lapped (ring overwrite) and signals the
                     service layer to recover.  Returns 0 at the
                     write edge so the push thread retries.

  eRamRecorder    -- eDVBRecordScrambledThread subclass that writes
                     into RAM instead of disk and extracts PCR
                     timestamps for seek support.

  eRamServicePlay -- extends eDVBServicePlay with RAM recording,
                     timer-based auto-activation, PCR-based seeking,
                     lap-detection watchdog, and CSA descrambling
                     support for StreamRelay channels.

Seeking and lap-recovery use forcePosition() on eFilePushThread which
directly sets the push thread's m_current_position.  This bypasses
both setStartOffset() (which has no effect because the push thread
never calls m_source->offset()) and the cue-sheet path (which relies
on tstools .ap data that does not exist for RAM buffers).

The push thread EOF path is reordered so that timeshift mode
(m_flags == 1) returns to the read loop without sending evtEOF,
avoiding ~70 spurious "End of file!" events per session.
* improve stream recovery for ram timeshift
* master:
  [RestoreScreen] * improve backup flag file detection * find alternative backup tar files
  [StartEnigma] * improve backup flag file detection
  [StartEnigma] * use /etc/autorestoreloop instead of /media/hdd/images/config/autorestore for autorestore loop check
  add h8se
  [Scan] Fix services with same SID on different transponders overwriting each other
  [Navigation] * add recording support for wrapper links
  Update groupedservices
  Refactor BaseParser and SubRipParser for consistency and readability; update method names to snake_case
  [Migration] * finally fix Filecommander settings migration
  Migration.py fix typo
  text updates
  pot update
  translation update
  [Menu.py] Fix menu navigation via digit entry
  Revert "Update groupedservices"
  [FileCommander] * move convertSettings to Migration
  [FileCommander] Add missing method spacing
* update
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
B Maintainability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant