Allow AV1 input on encode server

This commit is contained in:
DataHoarder 2023-11-03 05:56:47 +01:00
parent 53fd0c93f2
commit b8f21ea1f3
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
6 changed files with 104 additions and 13 deletions

View file

@ -0,0 +1,20 @@
//go:build cgo && !disable_library_libdav1d
package main
import (
"git.gammaspectra.live/S.O.N.G/Ignite/decoder"
"git.gammaspectra.live/S.O.N.G/Ignite/decoder/libdav1d"
"io"
)
func init() {
Decoders = append(Decoders, DecoderEntry{
Name: DecoderDav1d,
Version: libdav1d.Version,
MimeType: "video/x-ivf",
New: func(w io.Reader, settings map[string]any) (decoder.Decoder, error) {
return libdav1d.NewDecoder(w, settings)
},
})
}

View file

@ -0,0 +1,20 @@
package main
import (
"git.gammaspectra.live/S.O.N.G/Ignite/decoder"
"git.gammaspectra.live/S.O.N.G/Ignite/decoder/y4m"
"io"
)
func init() {
Decoders = append(Decoders, DecoderEntry{
Name: DecoderY4M,
Version: func() string {
return "1.0"
},
MimeType: "video/x-yuv4mpeg2",
New: func(w io.Reader, settings map[string]any) (decoder.Decoder, error) {
return y4m.NewDecoder(w, settings)
},
})
}

View file

@ -0,0 +1,38 @@
package main
import (
"git.gammaspectra.live/S.O.N.G/Ignite/decoder"
"io"
"slices"
)
const (
DecoderY4M = "y4m"
DecoderDav1d = "libdav1d"
)
type DecoderEntry struct {
Name string
Version func() string
MimeType string
New func(w io.Reader, settings map[string]any) (decoder.Decoder, error)
}
var Decoders []DecoderEntry
func GetDecoderByName(name string) *DecoderEntry {
if i := slices.IndexFunc(Decoders, func(entry DecoderEntry) bool {
return entry.Name == name
}); i != -1 {
return &Decoders[i]
}
return nil
}
func GetDecoderByMimeType(mimeType string) *DecoderEntry {
if i := slices.IndexFunc(Decoders, func(entry DecoderEntry) bool {
return entry.MimeType == mimeType
}); i != -1 {
return &Decoders[i]
}
return nil
}

View file

@ -6,7 +6,6 @@ import (
"compress/gzip"
"errors"
"fmt"
"git.gammaspectra.live/S.O.N.G/Ignite/decoder/y4m"
"git.gammaspectra.live/S.O.N.G/Ignite/frame"
"github.com/ulikunitz/xz"
"io"
@ -42,8 +41,15 @@ func handleDecompress(contentEncoding string, reader io.ReadCloser) (io.ReadClos
return reader, nil
}
func encodeFromReader(reader io.ReadCloser, job *Job, w http.ResponseWriter) {
func encodeFromReader(reader io.ReadCloser, job *Job, inputMimeType string, w http.ResponseWriter) {
defer reader.Close()
d := GetDecoderByMimeType(inputMimeType)
if d == nil {
w.WriteHeader(http.StatusBadRequest)
return
}
defer func() {
log.Printf("[job %s] finished, took %s", job.Id, time.Now().Sub(time.Unix(int64(job.Status.Start.Load()), 0)))
}()
@ -58,7 +64,7 @@ func encodeFromReader(reader io.ReadCloser, job *Job, w http.ResponseWriter) {
settings["timecodes"] = job.Config.Timecodes
}
decoder, err := y4m.NewDecoder(reader, settings)
decoder, err := d.New(reader, settings)
if err != nil {
w.Header().Set("x-encoder-error", "")
w.Header().Set("x-decoder-error", err.Error())

View file

@ -194,11 +194,6 @@ func main() {
}
defer job.Unlock()
if r.Header.Get("Content-Type") != "video/x-yuv4mpeg2" {
w.WriteHeader(http.StatusBadRequest)
return
}
reader, err := handleDecompress(r.Header.Get("Content-Encoding"), r.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
@ -208,7 +203,7 @@ func main() {
defer r.Body.Close()
log.Printf("[job %s] started POST", job.Id)
encodeFromReader(reader, job, w)
encodeFromReader(reader, job, r.Header.Get("Content-Type"), w)
})
serveMux.HandleFunc("/startURL", func(w http.ResponseWriter, r *http.Request) {
@ -270,21 +265,21 @@ func main() {
// Handle filenames
switch strings.ToLower(path.Ext(urlVal.Path)) {
case "gz":
case ".gz":
reader, err = handleDecompress("gz", reader)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
_, _ = w.Write([]byte(err.Error()))
return
}
case "bz2", "bzip2":
case ".bz2", ".bzip2":
reader, err = handleDecompress("bz2", reader)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
_, _ = w.Write([]byte(err.Error()))
return
}
case "xz":
case ".xz":
reader, err = handleDecompress("xz", reader)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
@ -293,8 +288,19 @@ func main() {
}
}
fname := strings.TrimSuffix(urlVal.Path, path.Ext(urlVal.Path))
inputMimeType := response.Header.Get("Content-Type")
switch strings.ToLower(path.Ext(fname)) {
case ".y4m":
inputMimeType = "video/x-yuv4mpeg2"
case ".av1":
inputMimeType = "video/x-ivf"
case ".h264", ".x264":
inputMimeType = "video/h264"
}
log.Printf("[job %s] started URL", job.Id)
encodeFromReader(reader, job, w)
encodeFromReader(reader, job, inputMimeType, w)
})
serveMux.HandleFunc("/job", func(w http.ResponseWriter, r *http.Request) {

View file

@ -5,6 +5,7 @@ import "git.gammaspectra.live/S.O.N.G/Ignite/frame"
type Decoder interface {
Decode() (frame.Frame, error)
DecodeStream() *frame.Stream
Properties() frame.StreamProperties
Close()
Version() string
}