This commit is contained in:
Sense T
2022-10-02 11:29:57 +00:00
parent b945218c85
commit 708732a37b
8 changed files with 76 additions and 281 deletions

View File

@@ -1,36 +1,58 @@
package qemuserver
import (
"fmt"
"net/url"
"os"
"path"
"syscall"
"time"
)
type Options struct {
QmpAddress string `yaml:"address"`
Timeout time.Duration `yaml:"timeout"`
Name string `yaml:"name"`
VNCAddress string `yaml:"vnc"`
AudioPipe string `yaml:"audio_pipe"`
AudioDevice string `yaml:"audio_device"`
QmpAddress string `yaml:"address"`
Timeout time.Duration `yaml:"timeout"`
Name string `yaml:"name"`
Audio AudioOptions `yaml:"audio_options"`
Video VideoOptions `yaml:"video_options"`
}
type AudioOptions struct {
Device string `yaml:"device"`
BufferSize uint16 `yaml:"buffer_size"` // in bytes
}
type VideoOptions struct {
Height int `yaml:"height"`
Width int `yaml:"width"`
FPS float32 `yaml:"fps"`
}
func ExampleOptions() *Options {
return &Options{
QmpAddress: (&url.URL{
Scheme: "unix",
Path: "/tmp/qemu.sock",
Scheme: "tcp",
Host: "localhost:4444",
}).String(),
Timeout: time.Duration(60 * time.Second),
Name: "ace-qemu",
VNCAddress: "localhost:5900",
AudioPipe: "/tmp/audio",
AudioDevice: "snd0",
Timeout: time.Duration(30 * time.Second),
Name: "ace-qemu",
Audio: AudioOptions{
Device: "snd0",
BufferSize: 2048,
},
Video: VideoOptions{
Height: 1024,
Width: 768,
FPS: 60,
},
}
}
func (o *Options) MakeFIFO() error {
os.Remove(o.AudioPipe)
return syscall.Mkfifo(o.AudioPipe, 0600)
func (o *Options) MakeFIFO() (string, error) {
path := path.Join(
os.TempDir(),
fmt.Sprintf("%s-%s-audio", o.Name, o.Audio.Device),
)
os.Remove(path)
return path, syscall.Mkfifo(path, 0600)
}

View File

@@ -9,7 +9,6 @@ import (
"git.sense-t.eu.org/ACE/ace/drivers/audio"
"git.sense-t.eu.org/ACE/ace/drivers/video"
"git.sense-t.eu.org/ACE/ace/lib/audiodriver"
"git.sense-t.eu.org/ACE/ace/lib/qemuconnection"
"github.com/digitalocean/go-qemu/qemu"
"github.com/digitalocean/go-qemu/qmp"
@@ -36,15 +35,11 @@ type Server struct {
var DefaultServer *Server
func NewServer(o *Options) (*Server, error) {
if err := o.MakeFIFO(); err != nil {
return nil, err
}
server := &Server{
options: o,
audioHeader: make(chan *audio.WavHeader, 1),
pcm: make(chan []byte),
ppm: make(chan io.ReadCloser),
ppm: make(chan io.ReadCloser, 60), // to be configured
}
u, err := url.Parse(o.QmpAddress)
@@ -77,7 +72,7 @@ func NewServer(o *Options) (*Server, error) {
audio := &audio.PCMStreamDriver{
PCM: server.pcm,
WaveHeader: waveHeader,
BufferSizeByBytes: 2048, // to be configured
BufferSizeByBytes: o.Audio.BufferSize, // to be configured
}
if err := driver.GetManager().Register(
audio,
@@ -91,9 +86,9 @@ func NewServer(o *Options) (*Server, error) {
}
video := &video.PPMStreamDriver{
Height: 768,
Width: 1024,
FPS: 60,
Height: o.Video.Height,
Width: o.Video.Width,
FPS: o.Video.FPS,
PPMImage: server.ppm,
}
if err := driver.GetManager().Register(
@@ -112,9 +107,26 @@ func NewServer(o *Options) (*Server, error) {
func (s *Server) Run() error {
logrus.Debug("qemu server running")
path, err := s.options.MakeFIFO()
if err != nil {
return err
}
go func() {
f, err := os.Open(s.options.AudioPipe)
logrus.Debug("screen capture start")
defer close(s.ppm)
for range time.Tick(time.Second / time.Duration(s.options.Video.FPS)) { // to be configured
ppm, err := s.qemu.ScreenDump()
if err != nil {
logrus.Error(err)
continue
}
s.ppm <- ppm
}
}()
go func() {
f, err := os.Open(path)
if err != nil {
logrus.Fatal(err)
}
@@ -123,9 +135,9 @@ func (s *Server) Run() error {
logrus.Debug("skip wave headers, to the PCM!")
// skip to pcm data, for 44 bytes.
var _dataChunkHeader [audiodriver.FmtHeaderOffset +
audiodriver.FmtHeaderIDSize + audiodriver.FmtHeaderChunkSizeSize + waveHeaderSize +
audiodriver.DataChunkIDSize + audiodriver.DataChunkSizeSize]byte
var _dataChunkHeader [audio.FmtHeaderOffset +
audio.FmtHeaderIDSize + audio.FmtHeaderChunkSizeSize + waveHeaderSize +
audio.DataChunkIDSize + audio.DataChunkSizeSize]byte
if _, err := f.Read(_dataChunkHeader[:]); err != nil {
logrus.Fatal(err)
}
@@ -139,7 +151,7 @@ func (s *Server) Run() error {
}
select {
case s.pcm <- b:
case <-time.After(waveHeader.GetLatnecy(2048)):
case <-time.After(waveHeader.GetLatnecy(s.options.Audio.BufferSize)):
}
}
}()
@@ -151,8 +163,8 @@ func (s *Server) Run() error {
Args: map[string]string{
"command-line": fmt.Sprintf(
"wavcapture %s %s %d %d %d",
s.options.AudioPipe,
s.options.AudioDevice,
path,
s.options.Audio.Device,
waveHeader.SampleRate,
waveHeader.BitsPerSample,
waveHeader.NumChannels,
@@ -164,19 +176,6 @@ func (s *Server) Run() error {
logrus.Debug("audio capture set")
}()
go func() {
logrus.Debug("screen capture start")
defer close(s.ppm)
for range time.Tick(time.Second / 60) { // to be configured
ppm, err := s.qemu.ScreenDump()
if err != nil {
logrus.Error(err)
continue
}
s.ppm <- ppm
}
}()
select {}
}