add bounded video source read
This commit is contained in:
@@ -120,15 +120,43 @@ func (s *Source) Close() error {
|
||||
|
||||
func (s *Source) NextCtx(ctx context.Context, timeout time.Duration) (Frame, error) {
|
||||
for {
|
||||
frame, err := s.ReadOnceCtx(ctx, timeout)
|
||||
if err == nil {
|
||||
return frame, nil
|
||||
}
|
||||
if ctx.Err() != nil {
|
||||
return Frame{}, ctx.Err()
|
||||
}
|
||||
if KindOf(err) != ErrorKindTemporary {
|
||||
return Frame{}, err
|
||||
}
|
||||
|
||||
if errors.Is(err, mxl.ErrOutOfRangeEarly) {
|
||||
select {
|
||||
case <-time.After(10 * time.Millisecond):
|
||||
case <-ctx.Done():
|
||||
return Frame{}, ctx.Err()
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Source) ReadOnceCtx(
|
||||
ctx context.Context,
|
||||
timeout time.Duration,
|
||||
) (Frame, error) {
|
||||
if err := ctx.Err(); err != nil {
|
||||
return Frame{}, err
|
||||
}
|
||||
|
||||
g, err := s.reader.GetGrain(s.idx, timeout)
|
||||
if ctx.Err() != nil {
|
||||
return Frame{}, ctx.Err()
|
||||
}
|
||||
|
||||
switch {
|
||||
case err == nil:
|
||||
f := Frame{
|
||||
frame := Frame{
|
||||
Index: g.Index,
|
||||
Width: s.width,
|
||||
Height: s.height,
|
||||
@@ -138,16 +166,44 @@ func (s *Source) NextCtx(ctx context.Context, timeout time.Duration) (Frame, err
|
||||
Payload: g.Payload,
|
||||
}
|
||||
s.idx++
|
||||
return f, nil
|
||||
return frame, nil
|
||||
|
||||
case errors.Is(err, mxl.ErrTimeout):
|
||||
s.idx = mxl.CurrentIndex(s.rate)
|
||||
return Frame{}, wrapError(
|
||||
"read video",
|
||||
ErrorKindTemporary,
|
||||
err,
|
||||
)
|
||||
|
||||
case errors.Is(err, mxl.ErrOutOfRangeEarly):
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
return Frame{}, wrapError(
|
||||
"read video",
|
||||
ErrorKindTemporary,
|
||||
err,
|
||||
)
|
||||
|
||||
case errors.Is(err, mxl.ErrOutOfRangeLate):
|
||||
s.idx = mxl.CurrentIndex(s.rate)
|
||||
return Frame{}, wrapError(
|
||||
"read video",
|
||||
ErrorKindTemporary,
|
||||
err,
|
||||
)
|
||||
|
||||
case errors.Is(err, mxl.ErrFlowInvalid):
|
||||
return Frame{}, wrapError(
|
||||
"read video",
|
||||
ErrorKindUnavailable,
|
||||
err,
|
||||
)
|
||||
|
||||
default:
|
||||
return Frame{}, fmt.Errorf("GetGrain: %w", err)
|
||||
}
|
||||
return Frame{}, wrapError(
|
||||
"read video",
|
||||
ErrorKindUnavailable,
|
||||
err,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user