Skip to content

add support for bypassing fragmented mp4 generation for live TS streams#150

Closed
lukseven wants to merge 15 commits intoluk/srtfrom
luk/bypass-processor
Closed

add support for bypassing fragmented mp4 generation for live TS streams#150
lukseven wants to merge 15 commits intoluk/srtfrom
luk/bypass-processor

Conversation

@lukseven
Copy link
Copy Markdown
Contributor

@lukseven lukseven commented Feb 4, 2026

No description provided.

lukseven and others added 3 commits January 13, 2026 18:12
* Add timecode parameter. Add elv_channel stats
* Fix parsing for exc timecode, add timecode to mux text, and correct sample cmd

---------

Co-authored-by: Peter Tseng <42591958+elv-peter@users.noreply.github.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new “raw-only” pathway for live MPEG-TS inputs that bypasses ffmpeg/libavpipe entirely, enabling verbatim TS part generation without producing fragmented MP4.

Changes:

  • Introduces CopyModeRawOnly and a new MPEGTS “start” stat (AV_IN_STAT_MPEGTS_START).
  • Adds a BypassProcessor abstraction + global registry to run non-ffmpeg pipelines.
  • Implements an MPEGTS bypass processor with first-packet start reporting and wires it into XcInit/XcRun/XcCancel.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
goavpipe/structs.go Adds new copy mode + MPEGTS start stat; adds JSON tags to input processor config fields.
goavpipe/handlers.go Adds BypassProcessor interface and global handle registry for bypass processors.
broadcastproto/mpegts/mpegts.go Extends SequentialOpener to support reporting stream start; adds ReportStart() on processor.
broadcastproto/mpegts/custom.go Adds a first-packet hook to trigger “start” reporting.
broadcastproto/mpegts/bypass.go New bypass processor implementation that reads TS and segments/writes parts without ffmpeg.
avpipe_seq_writer.go Implements ReportStart() and emits the new MPEGTS start stat.
avpipe.go Adds bypass-mode execution/cancel support and refactors AVPipeOpenInput into a Go helper.
Comments suppressed due to low confidence (1)

avpipe.go:1186

  • Bypass-handle execution falls through into the normal ffmpeg path. For handles < -1 this will hit if handle < 0 { return EAV_BAD_HANDLE } after the bypass processor completes, so bypass runs will always be reported as EAV_BAD_HANDLE. Add an explicit return nil (and any needed cleanup) after processor.Wait() in the bypass branch.
	defer goavpipe.XCEnded()
	if handle < 0 {
		return EAV_BAD_HANDLE
	}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread avpipe.go Outdated
Comment on lines +1133 to +1142
if params.InputCfg.CopyMode == goavpipe.CopyModeRawOnly {
goavpipe.Log.Info("initializing bypass processor", "copy_mode", params.InputCfg.CopyMode)
// Bypass ffmpeg completely and copy the stream verbatim to parts
bypassProcessor, err := mpegts.NewBypassProcessor(params, seqOpenerF)
if err != nil {
return -1, errors.E("XcInit", errors.K.Invalid.Default(), err)
}
handle := goavpipe.Globals.InitBypassProcessor(bypassProcessor)
return handle, nil
}
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New bypass mode (CopyModeRawOnly / negative handles) is not covered by existing tests in avpipe_test.go (no references to raw_only). Add tests that exercise XcInit/XcRun/XcCancel for bypass handles, including the early-cancel-before-start case and ensuring resources (CIO handler/output opener tables) are cleaned up.

Copilot uses AI. Check for mistakes.
Comment thread broadcastproto/mpegts/bypass.go
Comment thread broadcastproto/mpegts/bypass.go
Comment thread goavpipe/structs.go Outdated
Comment thread avpipe.go
Comment on lines +1175 to +1180
fd, _ := AVPipeOpenInputGo(processor.XcParams().Url)
err := processor.Start(fd)
if err != nil {
return err
}
processor.Wait()
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bypass path opens an input fd via AVPipeOpenInputGo(...) but never closes it, which will leak the input handler and associated global maps (gHandlers, gURLOutputOpenersByHandler). Ensure the fd is closed (e.g., call AVPipeCloseInput/equivalent) once the bypass processor finishes (including on error paths). Also check fd < 0 before calling processor.Start(fd) and return a meaningful error if opening fails.

Copilot uses AI. Check for mistakes.
Comment thread avpipe.go
Comment on lines 1196 to +1201
func XcCancel(handle int32) error {
if handle < -1 {
processor, ok := goavpipe.Globals.GetBypassProcessor(handle)
if !ok {
return EAV_BAD_HANDLE
}
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

XcCancel for bypass handles calls processor.Cancel() unconditionally. If cancel can be invoked before XcRun has called Start(), Cancel() may dereference a nil netReader (panic). Make bypass cancellation safe before start (either guard here or make BypassProcessor.Cancel() a no-op until started).

Suggested change
func XcCancel(handle int32) error {
if handle < -1 {
processor, ok := goavpipe.Globals.GetBypassProcessor(handle)
if !ok {
return EAV_BAD_HANDLE
}
func XcCancel(handle int32) (err error) {
if handle < -1 {
processor, ok := goavpipe.Globals.GetBypassProcessor(handle)
if !ok {
return EAV_BAD_HANDLE
}
// Make bypass cancellation safe even if invoked before the processor has started.
// If Cancel() panics (for example, due to a nil internal reader), convert that
// into a regular error instead of crashing the process.
defer func() {
if r := recover(); r != nil {
err = EAV_CANCEL_FAILED
}
}()

Copilot uses AI. Check for mistakes.
Comment thread broadcastproto/mpegts/bypass.go
Comment thread goavpipe/structs.go
Comment on lines +439 to +440
// CopyModeRawOnly is like CopyModeRaw, but also disables transcoding and production of fragmented mp4 parts
CopyModeRawOnly CopyMode = "raw_only"
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CopyModeRawOnly is introduced here, but InputConfig.Validate() does not currently accept/handle the raw_only value, so XcParams.Validate() will reject configs that try to use this new mode. Update the validation switch statements to include CopyModeRawOnly (and apply the intended constraints, likely similar to CopyModeRaw).

Copilot uses AI. Check for mistakes.
lukseven and others added 12 commits February 5, 2026 00:57
* use bypass processor if `raw_only` is specified on the stream independent of the `bypass_libav_reader` setting
* ensure BypassProcessor.Status/Cancel/Wait don't panic if called before Start()
* ensure net reader is canceled even if blocked on reading from network (by closing the socket)
* comment typo
* Fix RTP streamids - use udp://
* Fix atof NULL seg_duration

---------

Co-authored-by: Serban Simu <serban@Serbans-MacBook-Pro.local>
@lukseven lukseven closed this Feb 16, 2026
@lukseven lukseven deleted the luk/bypass-processor branch February 16, 2026 17:44
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.

3 participants