diff --git a/pkg/magic/keyframe.go b/pkg/magic/keyframe.go index 8f70eec6..9b6ef562 100644 --- a/pkg/magic/keyframe.go +++ b/pkg/magic/keyframe.go @@ -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) diff --git a/pkg/mjpeg/consumer.go b/pkg/mjpeg/consumer.go index 16edc895..819c558a 100644 --- a/pkg/mjpeg/consumer.go +++ b/pkg/mjpeg/consumer.go @@ -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) diff --git a/pkg/mjpeg/helpers.go b/pkg/mjpeg/helpers.go index d1acbd45..87f59e07 100644 --- a/pkg/mjpeg/helpers.go +++ b/pkg/mjpeg/helpers.go @@ -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 diff --git a/pkg/y4m/y4m.go b/pkg/y4m/y4m.go index 4ac54da6..24c43164 100644 --- a/pkg/y4m/y4m.go +++ b/pkg/y4m/y4m.go @@ -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 +}