Skip to content

Commit

Permalink
Allow changing video resolution during the stream
Browse files Browse the repository at this point in the history
  • Loading branch information
sergystepanov committed Oct 17, 2023
1 parent f8fb128 commit d698660
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 7 deletions.
10 changes: 10 additions & 0 deletions pkg/worker/caged/libretro/caged.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ type Caged struct {
conf CagedConf
log *logger.Logger
w, h int

OnSysInfoChange func()
}

type CagedConf struct {
Expand Down Expand Up @@ -44,6 +46,14 @@ func (c *Caged) ReloadFrontend() {
c.base = frontend
}

func (c *Caged) HandleOnSystemAvInfo(fn func()) {
c.base.SetOnAV(func() {
w, h := c.ViewportCalc()
c.SetViewport(w, h)
fn()
})
}

func (c *Caged) Load(game games.GameMetadata, path string) error {
c.Emulator.LoadCore(game.System)
if err := c.Emulator.LoadGame(game.FullPath(path)); err != nil {
Expand Down
2 changes: 2 additions & 0 deletions pkg/worker/caged/libretro/frontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ func (f *Frontend) linkNano(nano *nanoarch.Nanoarch) {
f.nano.OnAudio = f.handleAudio
}

func (f *Frontend) SetOnAV(fn func()) { f.nano.OnSystemAvInfo = fn }

func (f *Frontend) Start() {
f.log.Debug().Msgf("Frontend start")

Expand Down
15 changes: 11 additions & 4 deletions pkg/worker/caged/libretro/nanoarch/nanoarch.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,11 @@ type Nanoarch struct {
}

type Handlers struct {
OnDpad func(port uint, axis uint) (shift int16)
OnKeyPress func(port uint, key int) int
OnAudio func(ptr unsafe.Pointer, frames int)
OnVideo func(data []byte, delta int32, fi FrameInfo)
OnDpad func(port uint, axis uint) (shift int16)
OnKeyPress func(port uint, key int) int
OnAudio func(ptr unsafe.Pointer, frames int)
OnVideo func(data []byte, delta int32, fi FrameInfo)
OnSystemAvInfo func()
}

type FrameInfo struct {
Expand Down Expand Up @@ -689,6 +690,12 @@ func coreEnvironment(cmd C.unsigned, data unsafe.Pointer) C.bool {
case C.RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO:
av := *(*C.struct_retro_system_av_info)(data)
Nan0.log.Info().Msgf(">>> SET SYS AV INFO: %v", av)
Nan0.sysAvInfo = av
go func() {
if Nan0.OnSystemAvInfo != nil {
Nan0.OnSystemAvInfo()
}
}()
return true
case C.RETRO_ENVIRONMENT_SET_GEOMETRY:
geom := *(*C.struct_retro_game_geometry)(data)
Expand Down
9 changes: 9 additions & 0 deletions pkg/worker/coordinatorhandlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ func (c *coordinator) HandleGameStart(rq api.StartGameRequest[com.Uid], w *Worke
m.SetPixFmt(app.PixFormat())
m.SetRot(app.Rotation())

app.HandleOnSystemAvInfo(func() {
m.VideoW, m.VideoH = app.ViewportSize()
m.VideoScale = app.Scale()
err := m.Reinit()
if err != nil {
c.log.Error().Err(err).Msgf("av reinit fail")
}
})

r.BindAppMedia()
r.StartApp()
}
Expand Down
24 changes: 21 additions & 3 deletions pkg/worker/media/media.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ type WebrtcMediaPipe struct {
AudioFrame int
VideoW, VideoH int
VideoScale float64

// keep the old settings for reinit
oldPf uint32
oldRot uint
oldFlip bool
}

func NewWebRtcMediaPipe(ac config.Audio, vc config.Video, log *logger.Logger) *WebrtcMediaPipe {
Expand Down Expand Up @@ -200,6 +205,19 @@ func round(x int, scale float64) int { return (int(float64(x)*scale) + 1) & ^1 }
func (wmp *WebrtcMediaPipe) ProcessVideo(v app.Video) []byte {
return wmp.v.Encode(encoder.InFrame(v.Frame))
}
func (wmp *WebrtcMediaPipe) SetPixFmt(f uint32) { wmp.v.SetPixFormat(f) }
func (wmp *WebrtcMediaPipe) SetVideoFlip(b bool) { wmp.v.SetFlip(b) }
func (wmp *WebrtcMediaPipe) SetRot(r uint) { wmp.v.SetRot(r) }

func (wmp *WebrtcMediaPipe) Reinit() error {
wmp.v.Stop()
if err := wmp.initVideo(wmp.VideoW, wmp.VideoH, wmp.VideoScale, wmp.vConf); err != nil {
return err
}
// restore old
wmp.SetPixFmt(wmp.oldPf)
wmp.SetRot(wmp.oldRot)
wmp.SetVideoFlip(wmp.oldFlip)
return nil
}

func (wmp *WebrtcMediaPipe) SetPixFmt(f uint32) { wmp.oldPf = f; wmp.v.SetPixFormat(f) }
func (wmp *WebrtcMediaPipe) SetVideoFlip(b bool) { wmp.oldFlip = b; wmp.v.SetFlip(b) }
func (wmp *WebrtcMediaPipe) SetRot(r uint) { wmp.oldRot = r; wmp.v.SetRot(r) }
2 changes: 2 additions & 0 deletions pkg/worker/room/room.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ type MediaPipe interface {
Destroy()
// Init initializes the pipe: allocates needed resources.
Init() error
// Reinit initializes video and audio pipes with the new settings.
Reinit() error
// PushAudio pushes the 16bit PCM audio frames into an encoder.
// Because we need to fill the buffer, the SetAudioCb should be
// used in order to get the result.
Expand Down

0 comments on commit d698660

Please sign in to comment.