diff --git a/TODO b/TODO index 2c4d599..5d078b1 100644 --- a/TODO +++ b/TODO @@ -9,4 +9,7 @@ 2. qemu只在声卡初始化后才开始抓取声音 # 2022-10-3 -1. 虚拟设备应当一直运行,无阻塞 \ No newline at end of file +1. 虚拟设备应当一直运行,无阻塞 + +# 2022-10-10 +1. 视频设备延迟过高 \ No newline at end of file diff --git a/drivers/audio/wavfifo.go b/drivers/audio/wavfifo.go index 5be1806..432b6e5 100644 --- a/drivers/audio/wavfifo.go +++ b/drivers/audio/wavfifo.go @@ -68,12 +68,14 @@ func (w *PCMStreamDriver) AudioRecord(p prop.Media) (audio.Reader, error) { reader := func() (wave.Audio, func(), error) { a := wave.NewInt16Interleaved(chunkInfo) + ticker := time.NewTicker(p.Latency) + defer ticker.Stop() select { case <-w.closed: return nil, func() {}, io.EOF case pcmData := <-w.PCM: copy(a.Data, bytesTo16BitSamples(pcmData[:])) - case <-time.After(p.Latency): + case <-ticker.C: // no stuck } return a, func() {}, nil diff --git a/drivers/video/ppm.go b/drivers/video/ppm.go index 76b76c2..7269ce4 100644 --- a/drivers/video/ppm.go +++ b/drivers/video/ppm.go @@ -59,6 +59,9 @@ func (v *PPMStreamDriver) VideoRecord(p prop.Media) (video.Reader, error) { image.YCbCrSubsampleRatio420, ) r := video.ReaderFunc(func() (img image.Image, release func(), err error) { + ticker := time.NewTicker(time.Second / time.Duration(p.FrameRate)) + defer ticker.Stop() + select { case <-v.closed: return nil, func() {}, io.EOF @@ -82,7 +85,7 @@ func (v *PPMStreamDriver) VideoRecord(p prop.Media) (video.Reader, error) { canvas.Cr[canvas.COffset(x, y)] = Cr } } - case <-time.After(time.Second / time.Duration(p.FrameRate)): + case <-ticker.C: } return canvas, func() {}, nil }) diff --git a/lib/webrtcconnection/connection.go b/lib/webrtcconnection/connection.go index 48db210..605beb7 100644 --- a/lib/webrtcconnection/connection.go +++ b/lib/webrtcconnection/connection.go @@ -119,6 +119,7 @@ func setupCodec(videoBPS int) (*mediadevices.CodecSelector, error) { return nil, err } x264Prarm.BitRate = videoBPS + x264Prarm.Preset = x264.PresetMedium opusParam, err := opus.NewParams() if err != nil { diff --git a/lib/webrtcconnection/options.go b/lib/webrtcconnection/options.go index d584926..d0d218e 100644 --- a/lib/webrtcconnection/options.go +++ b/lib/webrtcconnection/options.go @@ -11,7 +11,7 @@ func ExampleOptions() *Options { "stun:stun.l.google.com:19302", "stun:wetofu.me:3478", }, - VideoBPS: 500_000, + VideoBPS: 2_048_000, } return options } diff --git a/servers/qemuserver/server.go b/servers/qemuserver/server.go index d977179..ef0b4d4 100644 --- a/servers/qemuserver/server.go +++ b/servers/qemuserver/server.go @@ -39,7 +39,7 @@ func NewServer(o *Options) (*Server, error) { options: o, audioHeader: make(chan *audio.WavHeader, 1), pcm: make(chan []byte), - ppm: make(chan io.ReadCloser, 60), // to be configured + ppm: make(chan io.ReadCloser, int(o.Video.FPS)), // to be configured } u, err := url.Parse(o.QmpAddress) @@ -115,13 +115,22 @@ func (s *Server) Run() error { go func() { logrus.Debug("screen capture start") defer close(s.ppm) - for range time.Tick(time.Second / time.Duration(s.options.Video.FPS)) { // to be configured + + ticker := time.NewTicker(time.Second / time.Duration(s.options.Video.FPS)) + defer ticker.Stop() + + for { // to be configured ppm, err := s.qemu.ScreenDump() if err != nil { logrus.Error(err) continue } - s.ppm <- ppm + select { + case s.ppm <- ppm: + case <-ticker.C: + continue + } + //<-ticker.C } }() @@ -144,6 +153,8 @@ func (s *Server) Run() error { logrus.Debug("start reading PCM") defer close(s.pcm) + ticker := time.NewTicker(waveHeader.GetLatnecy(s.options.Audio.BufferSize)) + defer ticker.Stop() for { b := make([]byte, s.options.Audio.BufferSize) // to be configured if _, err := f.Read(b[:]); err != nil { @@ -151,7 +162,7 @@ func (s *Server) Run() error { } select { case s.pcm <- b: - case <-time.After(waveHeader.GetLatnecy(s.options.Audio.BufferSize)): + case <-ticker.C: } } }()