Repository navigation
Publish each program of a multi-program source as its own track - #17
Merged
Merged
Conversation
* Add MsftsMuxer::catalogJson(QList<MsftsCatalog>): each entry gives its media track, its timeline track, and its initDataList entry, in list order; the root fields come from the first entry * Add workedOutMuxRate(): the mpeg2tsMuxRate of a program measured at a rate, 10 % above it to cover the jitter of a fixed-rate service over the one-second measure, rounded up to 10,000 bit/s * The single-entry catalogJson() is the list of one, so its output is unchanged Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* setTimedStartWindows(): a per-program track of a live multiplex reads the whole multiplex, so open() bounds its windows by PCR time, not by a packet count: 1 s for the PAT and the PMT, 10 s for the first random access point, and 1 s for the rates, within 600,000 packets each. A PCR step back or over 1 s counts as no time, and the rate measure starts again from it, null-packet count included. A PCR that does not advance for about 2 s ends open() with an error, and a program without a PCR PID times its windows on the first PCR of the multiplex * The timed scans keep no packet, so the track starts at the next random access point after them; prebufferedBytes() says what open() keeps * PacketQueueDevice::flushToLiveEdge() drops what is queued but the rest of a begun packet and records a gap there with the new cause LiveEdge. The packetizer starts the first Group there without a warning and without a PCR discontinuity mark, as nothing before it is published, also when a queue overflow falls at the same offset * M2tsObject::sourceOffset gives the source offset of an Object's first packet, which tells the Objects read before a flush from those after * The single-program and file paths keep their packet windows Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Add PublishedObject::endsTrack, a marker that is never sent: it releases its track's held Object as final at once, with the timeline Object that waits for it, so a track that ends while others go on closes its last Group without waiting for the end of the session * Name the catalog track with one shared constant, kCatalogTrackName (MSF -01 Section 5), instead of a literal in each place that builds catalog Objects * Test the marker: the last Object is final without a further read, the marker is not sent, and a stalled media track's timeline Object goes out right after its media Object when the marker comes Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* Add MptsPipeline: MptsFanOut reads the source once, one M2tsPacketizer per program reads its own queue on a worker thread, and the workers push their Objects into one bounded merged queue that the publisher takes through IMoqOutput. One catalog lists every program's track and timeline track * Every program starts at the live edge on the first pull: the queues are flushed, and nothing read before the first subscriber is published but the catalog. atLiveEdge() signals when every program started * Each program declares its own mux rate, or the one worked out from its measured rate, as mpeg2tsMuxRate and as its bitrate; a configured rate below the measured one gets a warning * A PSI change publishes a new independent catalog with the program's updated initData (MSFTS 6.12). A program that ends, or whose read fails, queues its track end and reports programEnded(); error() is fatal only. stop() joins the fan-out thread outside the lock * LivePipeline and MptsPipeline share timelineObject() on a TimelineHistory, nowUnixUs(), and packetizerCatalog(), which builds a track's catalog entry from its packetizer once * The MPTS build guard and posix-only-sources-guards.sh now cover MptsPipeline.cpp, which includes fcntl.h, sys/stat.h, and unistd.h * Tests: two programs, a mux rate below the measured rate, a program missing from the PAT, a PMT change, a program that leaves the PAT, the live edge after a late first subscriber, a gap in every program, start-up windows on a 40 Mbit/s multiplex, ten programs, a seekable file refused, and a prompt stop() Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
MptsPipelinepublishes every program of one live source as a per-program track, with one catalog for all tracks. Every program starts at the live edge on the first pull. The start-up windows of a program are PCR time, because each packetizer reads the whole multiplex. A program declares its configured mux rate, or 10 % above its measured rate. A program that ends closes its last Group at once. The other programs go on. The CLI reaches the pipeline in PR 7. Three known limits stay open: one copy of the multiplex per program, a start-window policy spread over four functions, and FIFO handling inside the pipeline.Depends on #16; only the last four commits belong to this PR.
This change is