Files
go-mxl-player/internal/playback/video_bridge.go
T
2026-09-01 23:45:10 +03:00

65 lines
1.1 KiB
Go

package playback
import (
"context"
"sync"
)
type PendingVideoFrame struct {
Frame VideoFrame
Generation uint64
Source FeedConfig
completeOnce sync.Once
result chan error
}
type VideoBridge struct {
requests chan *PendingVideoFrame
}
func NewVideoBridge() *VideoBridge {
return &VideoBridge{
requests: make(chan *PendingVideoFrame),
}
}
func (b *VideoBridge) ConsumeVideo(
ctx context.Context,
frame VideoFrame,
) error {
pending := &PendingVideoFrame{
Frame: frame,
Generation: generationFromContext(ctx),
Source: videoSourceFromContext(ctx),
result: make(chan error, 1),
}
select {
case b.requests <- pending:
case <-ctx.Done():
return ctx.Err()
}
// The render thread now owns temporary access to the borrowed payload.
// We must wait for Complete even if ctx is canceled.
return <-pending.result
}
func (b *VideoBridge) Next(
ctx context.Context,
) (*PendingVideoFrame, error) {
select {
case pending := <-b.requests:
return pending, nil
case <-ctx.Done():
return nil, ctx.Err()
}
}
func (f *PendingVideoFrame) Complete(err error) {
f.completeOnce.Do(func() {
f.result <- err
})
}