diff --git a/pkg/h265/mpeg4.go b/pkg/h265/mpeg4.go index e06d08365..db3c357cb 100644 --- a/pkg/h265/mpeg4.go +++ b/pkg/h265/mpeg4.go @@ -10,33 +10,49 @@ import ( ) func DecodeConfig(conf []byte) (profile, vps, sps, pps []byte) { + // minimum: 23-byte header + 5-byte VPS prefix (no data) + if len(conf) < 28 { + return + } profile = conf[1:4] b := conf[23:] - if binary.BigEndian.Uint16(b[1:]) != 1 { + if len(b) < 5 || binary.BigEndian.Uint16(b[1:]) != 1 { + return + } + vpsSize := int(binary.BigEndian.Uint16(b[3:])) + if len(b) < 5+vpsSize { return } - vpsSize := binary.BigEndian.Uint16(b[3:]) vps = b[5 : 5+vpsSize] b = conf[23+5+vpsSize:] - if binary.BigEndian.Uint16(b[1:]) != 1 { + if len(b) < 5 || binary.BigEndian.Uint16(b[1:]) != 1 { + return + } + spsSize := int(binary.BigEndian.Uint16(b[3:])) + if len(b) < 5+spsSize { return } - spsSize := binary.BigEndian.Uint16(b[3:]) sps = b[5 : 5+spsSize] b = conf[23+5+vpsSize+5+spsSize:] - if binary.BigEndian.Uint16(b[1:]) != 1 { + if len(b) < 5 || binary.BigEndian.Uint16(b[1:]) != 1 { + return + } + ppsSize := int(binary.BigEndian.Uint16(b[3:])) + if len(b) < 5+ppsSize { return } - ppsSize := binary.BigEndian.Uint16(b[3:]) pps = b[5 : 5+ppsSize] return } func EncodeConfig(vps, sps, pps []byte) []byte { + if len(vps) == 0 || len(sps) < 6 || len(pps) == 0 { + return nil + } vpsSize := uint16(len(vps)) spsSize := uint16(len(sps)) ppsSize := uint16(len(pps)) diff --git a/pkg/h265/rtp.go b/pkg/h265/rtp.go index 9c571ec5f..e86fa143b 100644 --- a/pkg/h265/rtp.go +++ b/pkg/h265/rtp.go @@ -76,12 +76,6 @@ func RTPDepay(codec *core.Codec, handler core.HandlerFunc) core.HandlerFunc { buf = append(buf, data[3:]...) - if nuStart > len(buf)+4 { - //log.Printf("broken H265 fragment") - buf = buf[:0] // drop data - return - } - binary.BigEndian.PutUint32(buf[nuStart:], uint32(len(buf)-nuStart-4)) case 0b11: // wrong RFC 7798 realisation from OpenIPC project // A non-fragmented NAL unit MUST NOT be transmitted in one FU; i.e.,