add synchronous video frame bridge
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
package playback
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type PendingVideoFrame struct {
|
||||
Frame VideoFrame
|
||||
|
||||
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,
|
||||
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
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user