Add support snapshot for raw image format

This commit is contained in:
Alex X
2025-01-07 20:08:29 +03:00
parent 33e0ccdd10
commit e4b8d1807d
4 changed files with 43 additions and 2 deletions

View File

@@ -24,6 +24,7 @@ func NewKeyframe() *Keyframe {
Direction: core.DirectionSendonly,
Codecs: []*core.Codec{
{Name: core.CodecJPEG},
{Name: core.CodecRAW},
{Name: core.CodecH264},
{Name: core.CodecH265},
},
@@ -87,6 +88,15 @@ func (k *Keyframe) AddTrack(media *core.Media, _ *core.Codec, track *core.Receiv
if track.Codec.IsRTP() {
sender.Handler = mjpeg.RTPDepay(sender.Handler)
}
case core.CodecRAW:
sender.Handler = func(packet *rtp.Packet) {
if n, err := k.wr.Write(packet.Payload); err == nil {
k.Send += n
}
}
sender.Handler = mjpeg.Encoder(track.Codec, 5, sender.Handler)
}
sender.HandleRTP(track)

View File

@@ -46,7 +46,7 @@ func (c *Consumer) AddTrack(media *core.Media, _ *core.Codec, track *core.Receiv
if track.Codec.IsRTP() {
sender.Handler = RTPDepay(sender.Handler)
} else if track.Codec.Name == core.CodecRAW {
sender.Handler = Encoder(track.Codec, sender.Handler)
sender.Handler = Encoder(track.Codec, 0, sender.Handler)
}
sender.HandleRTP(track)

View File

@@ -52,12 +52,19 @@ func FixJPEG(b []byte) []byte {
return buf.Bytes()
}
func Encoder(codec *core.Codec, handler core.HandlerFunc) core.HandlerFunc {
// 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

View File

@@ -123,3 +123,27 @@ func NewImage(fmtp string) func(frame []byte) image.Image {
return nil
}
// HasSameColor checks if all pixels has same color
func HasSameColor(img image.Image) bool {
var pix []byte
switch img := img.(type) {
case *image.Gray:
pix = img.Pix
case *image.YCbCr:
pix = img.Y
}
if len(pix) == 0 {
return false
}
i0 := pix[0]
for _, i := range pix {
if i != i0 {
return false
}
}
return true
}