Ignite/cli/encode-server/encode.go

148 lines
3.6 KiB
Go
Raw Normal View History

2023-10-21 21:00:19 +00:00
package main
import (
"compress/bzip2"
"compress/flate"
"compress/gzip"
"errors"
"fmt"
"git.gammaspectra.live/S.O.N.G/Ignite/frame"
"github.com/ulikunitz/xz"
"io"
"log"
"maps"
2023-10-21 21:00:19 +00:00
"net/http"
"os"
"time"
)
func handleDecompress(contentEncoding string, reader io.ReadCloser) (io.ReadCloser, error) {
var err error
switch contentEncoding {
case "gzip":
reader, err = gzip.NewReader(reader)
if err != nil {
return nil, err
}
case "bzip2":
reader = io.NopCloser(bzip2.NewReader(reader))
case "deflate":
reader = flate.NewReader(reader)
case "xz":
r, err := xz.NewReader(reader)
if err != nil {
return nil, err
}
reader = io.NopCloser(r)
case "":
return reader, nil
default:
return nil, errors.New("unsupported encoding")
}
return reader, nil
}
2023-11-03 04:56:47 +00:00
func encodeFromReader(reader io.ReadCloser, job *Job, inputMimeType string, w http.ResponseWriter) {
2023-10-21 21:00:19 +00:00
defer reader.Close()
2023-11-03 04:56:47 +00:00
d := GetDecoderByMimeType(inputMimeType)
if d == nil {
//try for generic reader
d = GetDecoderByMimeType("*")
if d == nil {
w.WriteHeader(http.StatusBadRequest)
return
}
2023-11-03 04:56:47 +00:00
}
2023-10-21 21:00:19 +00:00
defer func() {
log.Printf("[job %s] finished, took %s", job.Id, time.Now().Sub(time.Unix(int64(job.Status.Start.Load()), 0)))
}()
job.Status.Start.Store(uint64(time.Now().Unix()))
job.Status.Read.Store(0)
job.Status.Processed.Store(0)
2023-10-26 04:44:41 +00:00
settings := make(map[string]any)
maps.Copy(settings, job.Config.Decoder.Settings)
2023-10-26 04:44:41 +00:00
if len(job.Config.Timecodes) > 0 {
settings["timecodes"] = job.Config.Timecodes
}
2023-11-03 04:56:47 +00:00
decoder, err := d.New(reader, settings)
2023-10-21 21:00:19 +00:00
if err != nil {
2023-11-03 06:09:01 +00:00
job.Logger.Printf("[error]: %s", err.Error())
2023-10-21 21:00:19 +00:00
w.Header().Set("x-encoder-error", "")
w.Header().Set("x-decoder-error", err.Error())
w.WriteHeader(http.StatusBadRequest)
return
}
//check decoder frame properties match
2023-10-26 04:44:41 +00:00
decProps := decoder.Properties()
if decProps.Width != job.Config.Properties.Width ||
decProps.Height != job.Config.Properties.Height ||
decProps.ColorSpace != job.Config.Properties.ColorSpace ||
decProps.FullColorRange != job.Config.Properties.FullColorRange ||
decProps.TimeBase() != job.Config.Properties.TimeBase() {
2023-10-21 21:00:19 +00:00
w.Header().Set("x-encoder-error", "")
w.Header().Set("x-decoder-error", "mismatched config properties")
w.WriteHeader(http.StatusBadRequest)
return
}
2023-11-03 04:43:04 +00:00
mimeType := "application/octet-stream"
if e := GetEncoder(job.Config.Encoder.Name); e != nil {
mimeType = e.MimeType
}
w.Header().Set("Content-Type", mimeType)
2023-10-21 21:00:19 +00:00
w.Header().Add("Trailer", "x-encoder-error, x-decoder-error")
w.WriteHeader(http.StatusOK)
job.Logger = log.New(os.Stderr, fmt.Sprintf("[job %s] ", job.Id), log.LstdFlags)
err = job.Init(w)
if err != nil {
2023-11-03 06:09:01 +00:00
job.Logger.Printf("[error]: %s", err.Error())
2023-10-21 21:00:19 +00:00
w.Header().Set("x-encoder-error", err.Error())
w.Header().Set("x-decoder-error", "")
return
}
defer job.Close()
var f frame.Frame
for {
f, err = decoder.Decode()
if err != nil {
if errors.Is(err, io.EOF) {
//we are done
break
}
2023-11-03 06:09:01 +00:00
job.Logger.Printf("[error]: %s", err.Error())
2023-10-21 21:00:19 +00:00
w.Header().Set("x-encoder-error", "")
w.Header().Set("x-decoder-error", err.Error())
return
}
job.Status.Read.Add(1)
err = job.Encoder.Encode(f)
if err != nil {
2023-11-03 06:09:01 +00:00
job.Logger.Printf("[error]: %s", err.Error())
2023-10-21 21:00:19 +00:00
w.Header().Set("x-encoder-error", err.Error())
w.Header().Set("x-decoder-error", "")
return
}
2023-10-27 22:50:59 +00:00
f.Return()
2023-10-21 21:00:19 +00:00
job.Status.Processed.Add(1)
//log.Printf("[job %s] %d", job.Id, job.Status.Read.Load())
}
err = job.Encoder.Flush()
if err != nil {
2023-11-03 06:09:01 +00:00
job.Logger.Printf("[error]: %s", err.Error())
2023-10-21 21:00:19 +00:00
w.Header().Set("x-encoder-error", err.Error())
w.Header().Set("x-decoder-error", "")
return
}
}