run video-only playback through video slot
This commit is contained in:
+76
-7
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
mxladapter "mxl-player/internal/adapter/mxl"
|
||||
"mxl-player/internal/imgui"
|
||||
"mxl-player/internal/playback"
|
||||
"mxl-player/internal/renderer"
|
||||
@@ -144,7 +145,8 @@ func main() {
|
||||
if !args.ListAudio && !args.ListGPU {
|
||||
checkMXLargs(args)
|
||||
}
|
||||
// end of cli args parse
|
||||
// path selection
|
||||
useVideoSlot := args.VideoFlowId != "" && args.AudioFlowId == ""
|
||||
|
||||
runtime.LockOSThread()
|
||||
if err := sdl.Load(); err != nil {
|
||||
@@ -297,12 +299,7 @@ func main() {
|
||||
fmt.Printf("sync: video %dx%d audio %dch batch=%d\n",
|
||||
syncSrc.Width(), syncSrc.Height(), aChans, audioBatch)
|
||||
case args.VideoFlowId != "":
|
||||
videoSrc, err = source.Open(args.Domain, args.VideoFlowId)
|
||||
if err != nil {
|
||||
log.Fatalf("source: %v", err)
|
||||
}
|
||||
fmt.Printf("video: %dx%d stride=%d\n", videoSrc.Width(), videoSrc.Height(), videoSrc.Stride())
|
||||
|
||||
// VideoSlot owns opening and closing the video reader.
|
||||
default:
|
||||
audioSrc, err = source.OpenAudio(args.Domain, args.AudioFlowId)
|
||||
if err != nil {
|
||||
@@ -400,6 +397,39 @@ func main() {
|
||||
control := make(chan reconnectParams, 1)
|
||||
videoBridge := playback.NewVideoBridge()
|
||||
|
||||
videoWorker, err := playback.NewVideoWorker(
|
||||
mxladapter.VideoFactory{},
|
||||
videoBridge,
|
||||
retryPolicy,
|
||||
mxladapter.ShouldRetry,
|
||||
func(status playback.Status) {
|
||||
if status.Err != nil {
|
||||
log.Printf(
|
||||
"video: state=%v attempt=%d failed=%d: %v",
|
||||
status.State,
|
||||
status.Attempt,
|
||||
status.FailedAttempts,
|
||||
status.Err,
|
||||
)
|
||||
return
|
||||
}
|
||||
log.Printf(
|
||||
"video: state=%v attempt=%d failed=%d",
|
||||
status.State,
|
||||
status.Attempt,
|
||||
status.FailedAttempts,
|
||||
)
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
videoSlot, err := playback.NewVideoSlot(videoWorker)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
videoCommands := make(chan playback.FeedConfig, 1)
|
||||
|
||||
reopen := func(params reconnectParams) error {
|
||||
// Close current sources
|
||||
if syncSrc != nil {
|
||||
@@ -452,6 +482,23 @@ func main() {
|
||||
}
|
||||
|
||||
doReconnect := func() {
|
||||
if useVideoSlot {
|
||||
config := playback.FeedConfig{
|
||||
Domain: domainStr,
|
||||
UUID: videoStr,
|
||||
Active: videoStr != "",
|
||||
}
|
||||
// GUI is the only sender. Replace an older pending command
|
||||
select {
|
||||
case <-videoCommands:
|
||||
default:
|
||||
}
|
||||
select {
|
||||
case videoCommands <- config:
|
||||
default:
|
||||
}
|
||||
return
|
||||
}
|
||||
select {
|
||||
case <-control:
|
||||
default:
|
||||
@@ -459,7 +506,26 @@ func main() {
|
||||
control <- reconnectParams{domain: domainStr, video: videoStr, audio: audioStr}
|
||||
}
|
||||
|
||||
playbackDone := make(chan struct{})
|
||||
go func() {
|
||||
defer close(playbackDone)
|
||||
|
||||
if useVideoSlot {
|
||||
err := videoSlot.Run(
|
||||
ctx,
|
||||
playback.FeedConfig{
|
||||
Domain: args.Domain,
|
||||
UUID: args.VideoFlowId,
|
||||
Active: true,
|
||||
},
|
||||
videoCommands,
|
||||
)
|
||||
if err != nil && !errors.Is(err, context.Canceled) {
|
||||
log.Printf("video slot: %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Audio-only mode: independent loop.
|
||||
if audioSrc != nil && syncSrc == nil && videoSrc == nil {
|
||||
for {
|
||||
@@ -809,4 +875,7 @@ func main() {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
cancel()
|
||||
<-playbackDone
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user