mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2025-09-27 04:36:12 +08:00
96 lines
2.0 KiB
Go
96 lines
2.0 KiB
Go
package mjpeg
|
|
|
|
import (
|
|
"github.com/AlexxIT/go2rtc/pkg/streamer"
|
|
"github.com/pion/rtp"
|
|
)
|
|
|
|
type Consumer struct {
|
|
streamer.Element
|
|
|
|
UserAgent string
|
|
RemoteAddr string
|
|
|
|
codecs []*streamer.Codec
|
|
start bool
|
|
|
|
send int
|
|
}
|
|
|
|
func (c *Consumer) GetMedias() []*streamer.Media {
|
|
return []*streamer.Media{{
|
|
Kind: streamer.KindVideo,
|
|
Direction: streamer.DirectionRecvonly,
|
|
Codecs: []*streamer.Codec{{Name: streamer.CodecJPEG}},
|
|
}}
|
|
}
|
|
|
|
func (c *Consumer) AddTrack(media *streamer.Media, track *streamer.Track) *streamer.Track {
|
|
var header, payload []byte
|
|
|
|
push := func(packet *rtp.Packet) error {
|
|
//fmt.Printf(
|
|
// "[RTP] codec: %s, size: %6d, ts: %10d, pt: %2d, ssrc: %d, seq: %d, mark: %v\n",
|
|
// track.Codec.Name, len(packet.Payload), packet.Timestamp,
|
|
// packet.PayloadType, packet.SSRC, packet.SequenceNumber, packet.Marker,
|
|
//)
|
|
|
|
// https://www.rfc-editor.org/rfc/rfc2435#section-3.1
|
|
b := packet.Payload
|
|
|
|
// 3.1. JPEG header
|
|
t := b[4]
|
|
|
|
// 3.1.7. Restart Marker header
|
|
if 64 <= t && t <= 127 {
|
|
b = b[12:] // skip it
|
|
} else {
|
|
b = b[8:]
|
|
}
|
|
|
|
if header == nil {
|
|
var lqt, cqt []byte
|
|
|
|
// 3.1.8. Quantization Table header
|
|
q := packet.Payload[5]
|
|
if q >= 128 {
|
|
lqt = b[4:68]
|
|
cqt = b[68:132]
|
|
b = b[132:]
|
|
} else {
|
|
lqt, cqt = MakeTables(q)
|
|
}
|
|
|
|
// https://www.rfc-editor.org/rfc/rfc2435#section-3.1.5
|
|
// The maximum width is 2040 pixels.
|
|
w := uint16(packet.Payload[6]) << 3
|
|
h := uint16(packet.Payload[7]) << 3
|
|
|
|
// fix 2560x1920 and 2560x1440
|
|
if w == 512 && (h == 1920 || h == 1440) {
|
|
w = 2560
|
|
}
|
|
|
|
//fmt.Printf("t: %d, q: %d, w: %d, h: %d\n", t, q, w, h)
|
|
header = MakeHeaders(t, w, h, lqt, cqt)
|
|
}
|
|
|
|
// 3.1.9. JPEG Payload
|
|
payload = append(payload, b...)
|
|
|
|
if packet.Marker {
|
|
b = append(header, payload...)
|
|
if end := b[len(b)-2:]; end[0] != 0xFF && end[1] != 0xD9 {
|
|
b = append(b, 0xFF, 0xD9)
|
|
}
|
|
c.Fire(b)
|
|
|
|
header = nil
|
|
payload = nil
|
|
}
|
|
|
|
return nil
|
|
}
|
|
return track.Bind(push)
|
|
}
|