efpmux: absolute-from-running-time writes buffer PTS + base_time, which is wrong behind an encoder
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 58/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- rust
- Domain
- audio-video-rtc, backend
Research direction
Read gst-plugin-efp/src/efpmux/imp.rs, especially the timestamp calculation at lines 527-528 and segment handling at lines 640 and 473-474. Track the incoming segment per sink pad and convert PTS and DTS to running time in AbsoluteFromRunningTime mode before adding base_time. Add a regression test with x264enc before efpmux that compares wire PTS with running time at the mux sink pad.
Written by the indexing model from the issue text.
Description
Opened by Claude (AI assistant) on Peter Wagenet's behalf.
In timestamp-mode=absolute-from-running-time (the default), efpmux writes
buffer.pts() + base_time on the wire. That is the absolute pipeline-clock time only when the
incoming segment starts at zero, because efpmux drops the upstream segment and never converts
buffer PTS to running time. Behind a video encoder the segment does not start at zero, and the wire
timestamp is off by segment.start.
Where (at a8687618, unchanged since v0.3.0):
efpmux/imp.rs:527-528:pts/dtsarebuffer_pts + base_time_ns.efpmux/imp.rs:640: the upstream segment event is consumed ("mux has its own segment").efpmux/imp.rs:473-474: a fresh zero-based segment is pushed downstream.to_running_timeis not called anywhere in the file.
Why an encoder triggers it. GStreamer video encoders call gst_video_encoder_set_min_pts() so
that DTS never goes below zero with B-frames, and shift the segment by the same amount (x264enc uses
1000 hours). Running time stays correct, so ordinary pipelines are unaffected. An element that reads
buffer PTS and ignores the segment sees the shifted values.
Measured with v0.3.0 (videotestsrc ! x264enc ! … ! efpmux), in nanoseconds:
videotestsrc output PTS |
16,626,000 |
segment start reaching efpmux |
3,599,999,983,374,000 |
buffer PTS reaching efpmux |
3,600,000,000,000,000 |
| running time (what should be used) | 16,626,000 |
| written on the wire | base_time + 3.6 × 10¹⁵ |
Why the tests pass. The timestamp tests feed efpmux from appsrc with a zero-based segment,
where buffer PTS equals running time. The x264enc tests in tests/pipeline.rs check that the
round trip runs and what caps are negotiated, not the timestamp values.
Scope. It affects a sender that encodes inside the same pipeline as efpmux, and any upstream
segment that does not start at zero, for example after a seek. A sender that passes already-encoded
video through (parser straight into efpmux) is unaffected.
Suggested fix: in AbsoluteFromRunningTime mode, keep the incoming segment per sink pad and
write segment.to_running_time(pts) + base_time (likewise for DTS). A regression test could put
x264enc in front of efpmux and compare the wire PTS with the running time at the mux's sink pad.
- Dominant language
- Rust
- Stars
- 0
- Forks
- 0
- Avg merge
- 15m
- Merged PRs (30d)
- 1
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 80/100
storytold/craft-libs#1674 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
bug file-compat priority: high
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
storytold/gridcraft#4296 · 1 comment ·
Maintainers usually reply within 1 day
-
@solana/pay: `exports["."].require.types` points to `./dist/index.d.cts`, which is never emittedOpen
Difficulty 2/5 1-3 hours Newbie friendliness 80/100
solana-foundation/pay#547 ·
Maintainers usually reply within 1 day