Skip to content

Commit

Permalink
benchmarking and attempt gocv
Browse files Browse the repository at this point in the history
  • Loading branch information
BradLewis committed Aug 16, 2023
1 parent a1cbfb7 commit 9006c2c
Show file tree
Hide file tree
Showing 98 changed files with 20,051 additions and 42 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/justinas/alice v1.2.0
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
github.com/rs/zerolog v1.29.1
gocv.io/x/gocv v0.33.0
)

require (
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGa
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/hybridgroup/mjpeg v0.0.0-20140228234708-4680f319790e/go.mod h1:eagM805MRKrioHYuU7iKLUyFPVKqVV6um5DAvCkUtXs=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
Expand All @@ -45,6 +46,7 @@ github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand All @@ -65,6 +67,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
gocv.io/x/gocv v0.33.0 h1:WDtaBrq92AKrhepYzEktydDzNSm3t5k7ciawZK4rns8=
gocv.io/x/gocv v0.33.0/go.mod h1:oc6FvfYqfBp99p+yOEzs9tbYF9gOrAQSeL/dyIPefJU=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
Expand Down
44 changes: 18 additions & 26 deletions internal/generator/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"image"
"image/gif"
"image/jpeg"
"io"
"net/http"
"net/url"
"path/filepath"
Expand All @@ -15,6 +16,7 @@ import (

"github.com/SongStitch/song-stitch/internal/cache"
"github.com/rs/zerolog"
"gocv.io/x/gocv"
)

const (
Expand All @@ -24,13 +26,11 @@ const (

const maxRetries = 3

var (
backoffSchedule = []time.Duration{
200 * time.Millisecond,
500 * time.Millisecond,
1 * time.Second,
}
)
var backoffSchedule = []time.Duration{
200 * time.Millisecond,
500 * time.Millisecond,
1 * time.Second,
}

func DownloadImageWithRetry(ctx context.Context, entity Downloadable) error {
var err error
Expand Down Expand Up @@ -149,40 +149,32 @@ func getExtension(u string) (string, error) {
return ext, nil
}

func GetImage(ctx context.Context, img *image.Image, url string) error {
func GetImage(ctx context.Context, url string, mat *gocv.Mat) (image.Image, error) {
if len(url) == 0 {
img = nil
// Skip album art if it doesn't exist
return nil
return nil, nil
}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return err
return nil, err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}

extension, err := getExtension(url)
imgBytes, err := io.ReadAll(resp.Body)
if err != nil {
return err
return nil, err
}

if strings.ToLower(extension) == jpgFileType {
*img, err = jpeg.Decode(resp.Body)
} else if strings.ToLower(extension) == gifFileType {
*img, err = gif.Decode(resp.Body)
} else {
*img, _, err = image.Decode(resp.Body)
}
err = gocv.IMDecodeIntoMat(imgBytes, -1, mat)
if err != nil {
return err
return nil, err
}
img, _ := mat.ToImage()

return nil
return img, nil
}
54 changes: 38 additions & 16 deletions internal/generator/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,38 @@ package generator
import (
"bytes"
"context"
"fmt"
"image"
"runtime"
"sync"
"time"

"github.com/SongStitch/go-webp/encoder"
"github.com/SongStitch/go-webp/webp"
"github.com/SongStitch/song-stitch/internal/constants"
"github.com/fogleman/gg"
"gocv.io/x/gocv"

"github.com/nfnt/resize"
"github.com/rs/zerolog"
)

type DisplayOptions struct {
ArtistName bool
AlbumName bool
TrackName bool
PlayCount bool
Compress bool
Resize bool
Width uint
TextLocation constants.TextLocation
Height uint
ImageDimension int
Columns int
Rows int
FontSize float64
Width uint
PlayCount bool
Resize bool
BoldFont bool
Rows int
Columns int
ImageDimension int
Compress bool
ArtistName bool
TrackName bool
Webp bool
TextLocation constants.TextLocation
AlbumName bool
}

const (
Expand Down Expand Up @@ -114,7 +117,6 @@ func resizeImage(ctx context.Context, img *image.Image, width uint, height uint)
} else if int(width) == (*img).Bounds().Dx() && int(height) == (*img).Bounds().Dy() {
return img
} else if height == 0 {

height = uint(float64(width) * float64((*img).Bounds().Dy()) / float64((*img).Bounds().Dx()))
} else if width == 0 {
width = uint(float64(height) * float64((*img).Bounds().Dx()) / float64((*img).Bounds().Dy()))
Expand Down Expand Up @@ -191,7 +193,11 @@ func CreateCollageEfficient[T Drawable](ctx context.Context, albums []T, display
var wg sync.WaitGroup
maxconcurrent := 10
sem := make(chan struct{}, maxconcurrent)
images := make([]image.Image, maxconcurrent)
mats := make([]*gocv.Mat, maxconcurrent)
for i := range mats {
m := gocv.NewMatWithSize(displayOptions.ImageDimension, displayOptions.ImageDimension, gocv.MatTypeCV8UC3)
mats[i] = &m
}

wg.Add(len(albums))

Expand All @@ -205,8 +211,7 @@ func CreateCollageEfficient[T Drawable](ctx context.Context, albums []T, display
wg.Done()
}()

img := images[i%maxconcurrent]
err := GetImage(ctx, &img, album.GetImageUrl())
img, err := GetImage(ctx, album.GetImageUrl(), mats[i%maxconcurrent])
if err != nil {
logger.Error().Err(err).Msg("Failed to fetch image")
return
Expand All @@ -218,8 +223,10 @@ func CreateCollageEfficient[T Drawable](ctx context.Context, albums []T, display
album.ClearImage()

placeText(dc, album, displayOptions, float64(x), float64(y))
if i%10 == 0 {
PrintMemUsage()
}
}

}(album, x, y, i)
}

Expand All @@ -230,7 +237,22 @@ func CreateCollageEfficient[T Drawable](ctx context.Context, albums []T, display
if displayOptions.Resize {
collage = *resizeImage(ctx, &collage, displayOptions.Width, displayOptions.Height)
}
PrintMemUsage()

logger.Info().Dur("duration", time.Since(start)).Int("rows", displayOptions.Rows).Int("columns", displayOptions.Columns).Msg("Collage created")
return &collage, nil
}

func PrintMemUsage() {
var m runtime.MemStats
runtime.ReadMemStats(&m)
// For info on each, see: https://golang.org/pkg/runtime/#MemStats
fmt.Printf("Alloc = %v MiB", bToMb(m.Alloc))
fmt.Printf("\tTotalAlloc = %v MiB", bToMb(m.TotalAlloc))
fmt.Printf("\tSys = %v MiB", bToMb(m.Sys))
fmt.Printf("\tNumGC = %v\n", m.NumGC)
}

func bToMb(b uint64) uint64 {
return b / 1024 / 1024
}
7 changes: 7 additions & 0 deletions internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package server

import (
"net/http"
"net/http/pprof"
"os"
"time"

Expand Down Expand Up @@ -65,6 +66,12 @@ func RunServer() {
router.HandleFunc("/support", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "public/support.html")
})
router.Handle("/debug/pprof/", http.HandlerFunc(pprof.Index))
router.Handle("/debug/pprof/cmdline", http.HandlerFunc(pprof.Cmdline))
router.Handle("/debug/pprof/profile", http.HandlerFunc(pprof.Profile))
router.Handle("/debug/pprof/symbol", http.HandlerFunc(pprof.Symbol))
router.Handle("/debug/pprof/trace", http.HandlerFunc(pprof.Trace))
router.Handle("/debug/pprof/{cmd}", http.HandlerFunc(pprof.Index))

server := &http.Server{
Addr: ":8080",
Expand Down
28 changes: 28 additions & 0 deletions vendor/gocv.io/x/gocv/.astylerc

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions vendor/gocv.io/x/gocv/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 9006c2c

Please sign in to comment.