Refactoring #3
+76
-7
@@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
mxladapter "mxl-player/internal/adapter/mxl"
|
||||||
"mxl-player/internal/imgui"
|
"mxl-player/internal/imgui"
|
||||||
"mxl-player/internal/playback"
|
"mxl-player/internal/playback"
|
||||||
"mxl-player/internal/renderer"
|
"mxl-player/internal/renderer"
|
||||||
@@ -144,7 +145,8 @@ func main() {
|
|||||||
if !args.ListAudio && !args.ListGPU {
|
if !args.ListAudio && !args.ListGPU {
|
||||||
checkMXLargs(args)
|
checkMXLargs(args)
|
||||||
}
|
}
|
||||||
// end of cli args parse
|
// path selection
|
||||||
|
useVideoSlot := args.VideoFlowId != "" && args.AudioFlowId == ""
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
if err := sdl.Load(); err != nil {
|
if err := sdl.Load(); err != nil {
|
||||||
@@ -297,12 +299,7 @@ func main() {
|
|||||||
fmt.Printf("sync: video %dx%d audio %dch batch=%d\n",
|
fmt.Printf("sync: video %dx%d audio %dch batch=%d\n",
|
||||||
syncSrc.Width(), syncSrc.Height(), aChans, audioBatch)
|
syncSrc.Width(), syncSrc.Height(), aChans, audioBatch)
|
||||||
case args.VideoFlowId != "":
|
case args.VideoFlowId != "":
|
||||||
videoSrc, err = source.Open(args.Domain, args.VideoFlowId)
|
// VideoSlot owns opening and closing the video reader.
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("source: %v", err)
|
|
||||||
}
|
|
||||||
fmt.Printf("video: %dx%d stride=%d\n", videoSrc.Width(), videoSrc.Height(), videoSrc.Stride())
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
audioSrc, err = source.OpenAudio(args.Domain, args.AudioFlowId)
|
audioSrc, err = source.OpenAudio(args.Domain, args.AudioFlowId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -400,6 +397,39 @@ func main() {
|
|||||||
control := make(chan reconnectParams, 1)
|
control := make(chan reconnectParams, 1)
|
||||||
videoBridge := playback.NewVideoBridge()
|
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 {
|
reopen := func(params reconnectParams) error {
|
||||||
// Close current sources
|
// Close current sources
|
||||||
if syncSrc != nil {
|
if syncSrc != nil {
|
||||||
@@ -452,6 +482,23 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
doReconnect := func() {
|
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 {
|
select {
|
||||||
case <-control:
|
case <-control:
|
||||||
default:
|
default:
|
||||||
@@ -459,7 +506,26 @@ func main() {
|
|||||||
control <- reconnectParams{domain: domainStr, video: videoStr, audio: audioStr}
|
control <- reconnectParams{domain: domainStr, video: videoStr, audio: audioStr}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
playbackDone := make(chan struct{})
|
||||||
go func() {
|
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.
|
// Audio-only mode: independent loop.
|
||||||
if audioSrc != nil && syncSrc == nil && videoSrc == nil {
|
if audioSrc != nil && syncSrc == nil && videoSrc == nil {
|
||||||
for {
|
for {
|
||||||
@@ -809,4 +875,7 @@ func main() {
|
|||||||
time.Sleep(10 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cancel()
|
||||||
|
<-playbackDone
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user