From a6bcf5cd9481d3f9335a8f2e3147e2e1ccc1a4fe Mon Sep 17 00:00:00 2001 From: Sergey Stepanov Date: Sat, 27 May 2023 17:36:57 +0300 Subject: [PATCH] Fix scale option (it is slow) --- pkg/worker/emulator/emulator.go | 2 +- pkg/worker/emulator/image/canvas.go | 5 ++++ pkg/worker/emulator/libretro/frontend.go | 4 +-- pkg/worker/emulator/libretro/nanoarch_test.go | 6 ++++- pkg/worker/media.go | 25 ++++++++----------- pkg/worker/room.go | 2 +- 6 files changed, 25 insertions(+), 19 deletions(-) diff --git a/pkg/worker/emulator/emulator.go b/pkg/worker/emulator/emulator.go index 32602549..08232202 100644 --- a/pkg/worker/emulator/emulator.go +++ b/pkg/worker/emulator/emulator.go @@ -22,7 +22,7 @@ type Emulator interface { // Start is called after LoadGame Start() // SetViewport sets viewport size - SetViewport(width int, height int) + SetViewport(width int, height int, scale int) // SetMainSaveName sets distinct name for saves naming SetMainSaveName(name string) // SaveGameState save game state diff --git a/pkg/worker/emulator/image/canvas.go b/pkg/worker/emulator/image/canvas.go index 84194ee1..3c1636c6 100644 --- a/pkg/worker/emulator/image/canvas.go +++ b/pkg/worker/emulator/image/canvas.go @@ -86,6 +86,11 @@ func (c *Canvas) Draw(encoding uint32, rot *Rotate, w, h, packedW, bpp int, data // rescale if dst.Rect.Dx() != c.w || dst.Rect.Dy() != c.h { + ww, hh := c.w, c.h + // w, h supposedly have been swapped before + if c.vertical { + ww, hh = hh, ww + } out := c.Get(c.w, c.h) Resize(ScaleNearestNeighbour, dst.RGBA, out.RGBA) c.Put(dst) diff --git a/pkg/worker/emulator/libretro/frontend.go b/pkg/worker/emulator/libretro/frontend.go index 92c15843..2b016b5f 100644 --- a/pkg/worker/emulator/libretro/frontend.go +++ b/pkg/worker/emulator/libretro/frontend.go @@ -189,10 +189,10 @@ func (f *Frontend) LoadGameState() error { return f.Load() } func (f *Frontend) HasVerticalFrame() bool { return nano.rot != nil && nano.rot.IsEven } func (f *Frontend) SaveGameState() error { return f.Save() } func (f *Frontend) SetMainSaveName(name string) { f.storage.SetMainSaveName(name) } -func (f *Frontend) SetViewport(width int, height int) { +func (f *Frontend) SetViewport(width int, height int, scale int) { f.mu.Lock() f.vw, f.vh = width, height - size := int(nano.sysAvInfo.geometry.max_width * nano.sysAvInfo.geometry.max_height) + size := int(nano.sysAvInfo.geometry.max_width) * scale * int(nano.sysAvInfo.geometry.max_height) * scale f.canvas = image.NewCanvas(width, height, size) f.mu.Unlock() } diff --git a/pkg/worker/emulator/libretro/nanoarch_test.go b/pkg/worker/emulator/libretro/nanoarch_test.go index 39267f4d..7b08f534 100644 --- a/pkg/worker/emulator/libretro/nanoarch_test.go +++ b/pkg/worker/emulator/libretro/nanoarch_test.go @@ -111,7 +111,11 @@ func (emu *EmulatorMock) loadRom(game string) { if err != nil { log.Fatal(err) } - emu.SetViewport(emu.GetFrameSize()) + w, h := emu.GetFrameSize() + if emu.conf.Scale == 0 { + emu.conf.Scale = 1 + } + emu.SetViewport(w, h, emu.conf.Scale) } // shutdownEmulator closes the emulator and cleans its resources. diff --git a/pkg/worker/media.go b/pkg/worker/media.go index 14191a7a..be5ac2ac 100644 --- a/pkg/worker/media.go +++ b/pkg/worker/media.go @@ -118,11 +118,7 @@ func (r *Room) initAudio(srcHz int, conf config.Audio) { r.log.Error().Err(err).Msgf("opus encode fail") return } - r.handleSample(data, frameDur, func(u *Session, s *webrtc.Sample) { - if err := u.SendAudio(s); err != nil { - r.log.Error().Err(err).Send() - } - }) + r.handleSample(data, frameDur, func(u *Session, s *webrtc.Sample) error { return u.SendAudio(s) }) }) }) } @@ -156,18 +152,17 @@ func (r *Room) initVideo(width, height int, conf config.Video) { r.vEncoder = encoder.NewVideoEncoder(enc, width, height, conf.Concurrency, r.log) - r.emulator.SetVideo(func(frame *emulator.GameFrame) { - if fr := r.vEncoder.Encode(frame.Data.RGBA); fr != nil { - r.handleSample(fr, frame.Duration, func(u *Session, s *webrtc.Sample) { - if err := u.SendVideo(s); err != nil { - r.log.Error().Err(err).Send() - } - }) + r.emulator.SetVideo(func(raw *emulator.GameFrame) { + data := r.vEncoder.Encode(raw.Data.RGBA) + if data == nil { + r.log.Warn().Msgf("no data after video encoding") + return } + r.handleSample(data, raw.Duration, func(u *Session, s *webrtc.Sample) error { return u.SendVideo(s) }) }) } -func (r *Room) handleSample(b []byte, d time.Duration, fn func(*Session, *webrtc.Sample)) { +func (r *Room) handleSample(b []byte, d time.Duration, fn func(*Session, *webrtc.Sample) error) { sample, _ := samplePool.Get().(*webrtc.Sample) if sample == nil { sample = new(webrtc.Sample) @@ -176,7 +171,9 @@ func (r *Room) handleSample(b []byte, d time.Duration, fn func(*Session, *webrtc sample.Duration = d r.users.ForEach(func(u *Session) { if u.IsConnected() { - fn(u, sample) + if err := fn(u, sample); err != nil { + r.log.Error().Err(err).Send() + } } }) samplePool.Put(sample) diff --git a/pkg/worker/room.go b/pkg/worker/room.go index ab63843d..596a4cd6 100644 --- a/pkg/worker/room.go +++ b/pkg/worker/room.go @@ -65,7 +65,7 @@ func NewRoom(id string, game games.GameMetadata, onClose func(*Room), conf confi if room.emulator.HasVerticalFrame() { w, h = h, w } - room.emulator.SetViewport(w, h) + room.emulator.SetViewport(w, h, conf.Emulator.Scale) room.initVideo(w, h, conf.Encoder.Video) room.initAudio(int(room.emulator.GetSampleRate()), conf.Encoder.Audio)