Skip to content

Commit

Permalink
Use faster Y flip of the video encoders (OpenGL/N64)
Browse files Browse the repository at this point in the history
  • Loading branch information
sergystepanov committed Sep 29, 2023
1 parent a901c84 commit c1c4731
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 3 deletions.
2 changes: 2 additions & 0 deletions pkg/worker/caged/libretro/frontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type Emulator interface {
LoadCore(name string)
LoadGame(path string) error
FPS() int
Flipped() bool
AudioSampleRate() int
IsPortrait() bool
// Start is called after LoadGame
Expand Down Expand Up @@ -239,6 +240,7 @@ func (f *Frontend) Start() {
}
}

func (f *Frontend) Flipped() bool { return f.nano.IsGL() }
func (f *Frontend) FrameSize() (int, int) { return f.nano.GeometryBase() }
func (f *Frontend) FPS() int { return f.nano.VideoFramerate() }
func (f *Frontend) HashPath() string { return f.storage.GetSavePath() }
Expand Down
3 changes: 2 additions & 1 deletion pkg/worker/caged/libretro/nanoarch/nanoarch.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ func (n *Nanoarch) LoadGame(path string) error {
n.stopped.Store(false)

if n.Video.gl.enabled {
setRotation(image.F180) // flip Y coordinates of OpenGL
//setRotation(image.F180) // flip Y coordinates of OpenGL
bufS := uint(n.sysAvInfo.geometry.max_width*n.sysAvInfo.geometry.max_height) * n.Video.BPP
graphics.SetBuffer(int(bufS))
n.log.Info().Msgf("Set buffer: %v", byteCountBinary(int64(bufS)))
Expand Down Expand Up @@ -351,6 +351,7 @@ func (n *Nanoarch) Run() {
}
}

func (n *Nanoarch) IsGL() bool { return n.Video.gl.enabled }
func (n *Nanoarch) IsStopped() bool { return n.stopped.Load() }

func videoSetPixelFormat(format uint32) (C.bool, error) {
Expand Down
3 changes: 3 additions & 0 deletions pkg/worker/coordinatorhandlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ func (c *coordinator) HandleGameStart(rq api.StartGameRequest[com.Uid], w *Worke
app.Close()
return api.EmptyPacket
}
if app.Flipped() {
m.SetVideoFlip(true)
}

// make the room
r = room.NewRoom[*room.GameSession](uid, app, w.router.Users(), m)
Expand Down
3 changes: 3 additions & 0 deletions pkg/worker/encoder/encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type (
LoadBuf(input []byte)
Encode() []byte
IntraRefresh()
SetFlip(bool)
Shutdown() error
}
)
Expand Down Expand Up @@ -65,6 +66,8 @@ func (vp *VideoEncoder) Encode(img InFrame) OutFrame {
return nil
}

func (vp *VideoEncoder) SetFlip(b bool) { vp.encoder.SetFlip(b) }

func (vp *VideoEncoder) Stop() {
vp.stopped.Store(true)
vp.mu.Lock()
Expand Down
4 changes: 2 additions & 2 deletions pkg/worker/encoder/h264/libx264.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ type Nal struct {
const RcCrf = 1

const (
CspI420 = 0x0002 // yuv 4:2:0 planar
CspI420 = 0x0002 // yuv 4:2:0 planar
CspVflip = 0x1000 /* the csp is vertically flipped */

// CspMask = 0x00ff /* */
// CspNone = 0x0000 /* Invalid mode */
Expand All @@ -65,7 +66,6 @@ const (
//CspBgra = 0x000f /* packed bgr 32bits */
//CspRgb = 0x0010 /* packed rgb 24bits */
//CspMax = 0x0011 /* end of list */
//CspVflip = 0x1000 /* the csp is vertically flipped */
//CspHighDepth = 0x2000 /* the csp has a depth of 16 bits per pixel component */
)

Expand Down
8 changes: 8 additions & 0 deletions pkg/worker/encoder/h264/x264.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,14 @@ func (e *H264) IntraRefresh() {
// !to implement
}

func (e *H264) SetFlip(b bool) {
if b {
e.in.Img.ICsp |= CspVflip
} else {
e.in.Img.ICsp &= ^CspVflip
}
}

func (e *H264) Shutdown() error {
e.y = nil
e.u = nil
Expand Down
7 changes: 7 additions & 0 deletions pkg/worker/encoder/vpx/libvpx.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,11 @@ type Vpx struct {
image C.vpx_image_t
codecCtx C.vpx_codec_ctx_t
kfi C.int
flipped bool
}

func (vpx *Vpx) SetFlip(b bool) { vpx.flipped = b }

type Options struct {
// Target bandwidth to use for this stream, in kilobits per second.
Bitrate uint
Expand Down Expand Up @@ -134,6 +137,9 @@ func NewEncoder(w, h int, opts *Options) (*Vpx, error) {

func (vpx *Vpx) LoadBuf(yuv []byte) {
C.vpx_img_read(&vpx.image, unsafe.Pointer(&yuv[0]))
if vpx.flipped {
C.vpx_img_flip(&vpx.image)
}
}

// Encode encodes yuv image with the VPX8 encoder.
Expand Down Expand Up @@ -166,5 +172,6 @@ func (vpx *Vpx) Shutdown() error {
C.vpx_img_free(&vpx.image)
//}
C.vpx_codec_destroy(&vpx.codecCtx)
vpx.flipped = false
return nil
}
2 changes: 2 additions & 0 deletions pkg/worker/media/media.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,5 @@ func (wmp *WebrtcMediaPipe) initVideo(w, h int, conf config.Video) error {
}

func (wmp *WebrtcMediaPipe) ProcessVideo(v app.Video) []byte { return wmp.enc.Encode(&v.Frame) }

func (wmp *WebrtcMediaPipe) SetVideoFlip(b bool) { wmp.enc.SetFlip(b) }

0 comments on commit c1c4731

Please sign in to comment.