install go2rtc on bob
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
package mjpeg
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"image/jpeg"
|
||||
|
||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||
"github.com/AlexxIT/go2rtc/pkg/y4m"
|
||||
"github.com/pion/rtp"
|
||||
)
|
||||
|
||||
func FixJPEG(b []byte) []byte {
|
||||
// skip non-JPEG
|
||||
if len(b) < 10 || b[0] != 0xFF || b[1] != markerSOI {
|
||||
return b
|
||||
}
|
||||
|
||||
// skip JPEG without app marker
|
||||
if b[2] == 0xFF && b[3] == markerDQT {
|
||||
return b
|
||||
}
|
||||
|
||||
switch string(b[6:10]) {
|
||||
case "JFIF", "Exif":
|
||||
// skip if header OK for imghdr library
|
||||
// - https://docs.python.org/3/library/imghdr.html
|
||||
return b
|
||||
case "AVI1":
|
||||
// adds DHT tables to JPEG file before SOS marker
|
||||
// useful when you want to save a JPEG frame from an MJPEG stream
|
||||
// - https://github.com/image-rs/jpeg-decoder/issues/76
|
||||
// - https://github.com/pion/mediadevices/pull/493
|
||||
// - https://bugzilla.mozilla.org/show_bug.cgi?id=963907#c18
|
||||
return InjectDHT(b)
|
||||
}
|
||||
|
||||
// reencode JPEG if it has wrong header
|
||||
//
|
||||
// for example, this app produce "bad" images:
|
||||
// https://github.com/jacksonliam/mjpg-streamer
|
||||
//
|
||||
// and they can't be uploaded to the Telegram servers:
|
||||
// {"ok":false,"error_code":400,"description":"Bad Request: IMAGE_PROCESS_FAILED"}
|
||||
img, err := jpeg.Decode(bytes.NewReader(b))
|
||||
if err != nil {
|
||||
return b
|
||||
}
|
||||
buf := bytes.NewBuffer(nil)
|
||||
if err = jpeg.Encode(buf, img, nil); err != nil {
|
||||
return b
|
||||
}
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// Encoder convert YUV frame to Img.
|
||||
// Support skipping empty frames, for example if USB cam needs time to start.
|
||||
func Encoder(codec *core.Codec, skipEmpty int, handler core.HandlerFunc) core.HandlerFunc {
|
||||
newImage := y4m.NewImage(codec.FmtpLine)
|
||||
|
||||
return func(packet *rtp.Packet) {
|
||||
img := newImage(packet.Payload)
|
||||
|
||||
if skipEmpty != 0 && y4m.HasSameColor(img) {
|
||||
skipEmpty--
|
||||
return
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
if err := jpeg.Encode(buf, img, nil); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
clone := *packet
|
||||
clone.Payload = buf.Bytes()
|
||||
handler(&clone)
|
||||
}
|
||||
}
|
||||
|
||||
const dhtSize = 432 // known size for 4 default tables
|
||||
|
||||
func InjectDHT(b []byte) []byte {
|
||||
if bytes.Index(b, []byte{0xFF, markerDHT}) > 0 {
|
||||
return b // already exist
|
||||
}
|
||||
|
||||
i := bytes.Index(b, []byte{0xFF, markerSOS})
|
||||
if i < 0 {
|
||||
return b
|
||||
}
|
||||
|
||||
dht := make([]byte, 0, dhtSize)
|
||||
dht = MakeHuffmanHeaders(dht)
|
||||
|
||||
tmp := make([]byte, len(b)+dhtSize)
|
||||
copy(tmp, b[:i])
|
||||
copy(tmp[i:], dht)
|
||||
copy(tmp[i+dhtSize:], b[i:])
|
||||
|
||||
return tmp
|
||||
}
|
||||
Reference in New Issue
Block a user