discard buffered frames for < 1fps (#470)

This commit is contained in:
Clyde Bazile
2023-03-06 16:52:59 -05:00
committed by GitHub
parent dbd37689e4
commit 62009a882b
2 changed files with 29 additions and 9 deletions

View File

@@ -12,6 +12,7 @@ import (
"path/filepath" "path/filepath"
"strconv" "strconv"
"sync" "sync"
"time"
"github.com/blackjack/webcam" "github.com/blackjack/webcam"
"github.com/pion/mediadevices/pkg/driver" "github.com/pion/mediadevices/pkg/driver"
@@ -70,6 +71,7 @@ type camera struct {
started bool started bool
mutex sync.Mutex mutex sync.Mutex
cancel func() cancel func()
prevFrameTime time.Time
} }
func init() { func init() {
@@ -158,8 +160,13 @@ func (c *camera) Open() error {
return err return err
} }
// Late frames should be discarded. Buffering should be handled in higher level. // Buffering should be handled in higher level.
cam.SetBufferCount(1) err = cam.SetBufferCount(1)
if err != nil {
return err
}
c.prevFrameTime = time.Now()
c.cam = cam c.cam = cam
return nil return nil
} }
@@ -228,6 +235,13 @@ func (c *camera) VideoRecord(p prop.Media) (video.Reader, error) {
return nil, func() {}, io.EOF return nil, func() {}, io.EOF
} }
if p.DiscardFramesOlderThan != 0 {
if time.Now().Sub(c.prevFrameTime) >= p.DiscardFramesOlderThan {
_ = cam.WaitForFrame(readTimeoutSec)
_, _ = cam.ReadFrame()
}
}
err := cam.WaitForFrame(readTimeoutSec) err := cam.WaitForFrame(readTimeoutSec)
switch err.(type) { switch err.(type) {
case nil: case nil:
@@ -244,6 +258,10 @@ func (c *camera) VideoRecord(p prop.Media) (video.Reader, error) {
return nil, func() {}, err return nil, func() {}, err
} }
if p.DiscardFramesOlderThan != 0 {
c.prevFrameTime = time.Now()
}
// Frame is empty. // Frame is empty.
// Retry reading and return errEmptyFrame if it exceeds maxEmptyFrameCount. // Retry reading and return errEmptyFrame if it exceeds maxEmptyFrameCount.
if len(b) == 0 { if len(b) == 0 {

View File

@@ -9,7 +9,7 @@ import (
"github.com/pion/mediadevices/pkg/frame" "github.com/pion/mediadevices/pkg/frame"
) )
// MediaConstraints represents set of media propaty constraints. // MediaConstraints represents set of media property constraints.
// Each field constrains property by min/ideal/max range, exact match, or oneof match. // Each field constrains property by min/ideal/max range, exact match, or oneof match.
type MediaConstraints struct { type MediaConstraints struct {
DeviceID StringConstraint DeviceID StringConstraint
@@ -229,16 +229,18 @@ func (c *comparisons) fitnessDistance() (float64, bool) {
// VideoConstraints represents a video's constraints // VideoConstraints represents a video's constraints
type VideoConstraints struct { type VideoConstraints struct {
Width, Height IntConstraint Width, Height IntConstraint
FrameRate FloatConstraint FrameRate FloatConstraint
FrameFormat FrameFormatConstraint FrameFormat FrameFormatConstraint
DiscardFramesOlderThan time.Duration
} }
// Video represents a video's constraints // Video represents a video's constraints
type Video struct { type Video struct {
Width, Height int Width, Height int
FrameRate float32 FrameRate float32
FrameFormat frame.Format FrameFormat frame.Format
DiscardFramesOlderThan time.Duration
} }
// AudioConstraints represents an audio's constraints // AudioConstraints represents an audio's constraints