[RTMP] client / server full support h265 video codec
This commit is contained in:
		| @@ -531,7 +531,7 @@ type AVCDecoderConfRecord struct { | |||||||
| var ErrDecconfInvalid = fmt.Errorf("h265parser: AVCDecoderConfRecord invalid") | var ErrDecconfInvalid = fmt.Errorf("h265parser: AVCDecoderConfRecord invalid") | ||||||
|  |  | ||||||
| func (self *AVCDecoderConfRecord) Unmarshal(b []byte) (n int, err error) { | func (self *AVCDecoderConfRecord) Unmarshal(b []byte) (n int, err error) { | ||||||
| 	if len(b) < 7 { | 	if len(b) < 30 { | ||||||
| 		err = ErrDecconfInvalid | 		err = ErrDecconfInvalid | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| @@ -539,8 +539,36 @@ func (self *AVCDecoderConfRecord) Unmarshal(b []byte) (n int, err error) { | |||||||
| 	self.ProfileCompatibility = b[2] | 	self.ProfileCompatibility = b[2] | ||||||
| 	self.AVCLevelIndication = b[3] | 	self.AVCLevelIndication = b[3] | ||||||
| 	self.LengthSizeMinusOne = b[4] & 0x03 | 	self.LengthSizeMinusOne = b[4] & 0x03 | ||||||
| 	spscount := int(b[5] & 0x1f) |  | ||||||
| 	n += 6 | 	vpscount := int(b[25] & 0x1f) | ||||||
|  | 	n += 26 | ||||||
|  | 	for i := 0; i < vpscount; i++ { | ||||||
|  | 		if len(b) < n+2 { | ||||||
|  | 			err = ErrDecconfInvalid | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		vpslen := int(pio.U16BE(b[n:])) | ||||||
|  | 		n += 2 | ||||||
|  |  | ||||||
|  | 		if len(b) < n+vpslen { | ||||||
|  | 			err = ErrDecconfInvalid | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		self.VPS = append(self.VPS, b[n:n+vpslen]) | ||||||
|  | 		n += vpslen | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if len(b) < n+1 { | ||||||
|  | 		err = ErrDecconfInvalid | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	n++ | ||||||
|  | 	n++ | ||||||
|  |  | ||||||
|  | 	spscount := int(b[n]) | ||||||
|  | 	n++ | ||||||
|  |  | ||||||
| 	for i := 0; i < spscount; i++ { | 	for i := 0; i < spscount; i++ { | ||||||
| 		if len(b) < n+2 { | 		if len(b) < n+2 { | ||||||
| 			err = ErrDecconfInvalid | 			err = ErrDecconfInvalid | ||||||
| @@ -557,10 +585,8 @@ func (self *AVCDecoderConfRecord) Unmarshal(b []byte) (n int, err error) { | |||||||
| 		n += spslen | 		n += spslen | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(b) < n+1 { | 	n++ | ||||||
| 		err = ErrDecconfInvalid | 	n++ | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ppscount := int(b[n]) | 	ppscount := int(b[n]) | ||||||
| 	n++ | 	n++ | ||||||
| @@ -580,25 +606,6 @@ func (self *AVCDecoderConfRecord) Unmarshal(b []byte) (n int, err error) { | |||||||
| 		self.PPS = append(self.PPS, b[n:n+ppslen]) | 		self.PPS = append(self.PPS, b[n:n+ppslen]) | ||||||
| 		n += ppslen | 		n += ppslen | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	vpscount := int(b[n]) |  | ||||||
| 	n++ |  | ||||||
|  |  | ||||||
| 	for i := 0; i < vpscount; i++ { |  | ||||||
| 		if len(b) < n+2 { |  | ||||||
| 			err = ErrDecconfInvalid |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		vpslen := int(pio.U16BE(b[n:])) |  | ||||||
| 		n += 2 |  | ||||||
|  |  | ||||||
| 		if len(b) < n+vpslen { |  | ||||||
| 			err = ErrDecconfInvalid |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		self.VPS = append(self.VPS, b[n:n+vpslen]) |  | ||||||
| 		n += vpslen |  | ||||||
| 	} |  | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ import ( | |||||||
| 	"github.com/deepch/vdk/codec/aacparser" | 	"github.com/deepch/vdk/codec/aacparser" | ||||||
| 	"github.com/deepch/vdk/codec/fake" | 	"github.com/deepch/vdk/codec/fake" | ||||||
| 	"github.com/deepch/vdk/codec/h264parser" | 	"github.com/deepch/vdk/codec/h264parser" | ||||||
|  | 	"github.com/deepch/vdk/codec/h265parser" | ||||||
| 	"github.com/deepch/vdk/format/flv/flvio" | 	"github.com/deepch/vdk/format/flv/flvio" | ||||||
| 	"github.com/deepch/vdk/utils/bits/pio" | 	"github.com/deepch/vdk/utils/bits/pio" | ||||||
| ) | ) | ||||||
| @@ -28,6 +29,8 @@ func NewMetadataByStreams(streams []av.CodecData) (metadata flvio.AMFMap, err er | |||||||
| 			switch typ { | 			switch typ { | ||||||
| 			case av.H264: | 			case av.H264: | ||||||
| 				metadata["videocodecid"] = flvio.VIDEO_H264 | 				metadata["videocodecid"] = flvio.VIDEO_H264 | ||||||
|  | 			case av.H265: | ||||||
|  | 				metadata["videocodecid"] = flvio.VIDEO_H265 | ||||||
|  |  | ||||||
| 			default: | 			default: | ||||||
| 				err = fmt.Errorf("flv: metadata: unsupported video codecType=%v", stream.Type()) | 				err = fmt.Errorf("flv: metadata: unsupported video codecType=%v", stream.Type()) | ||||||
| @@ -87,10 +90,12 @@ func (self *Prober) PushTag(tag flvio.Tag, timestamp int32) (err error) { | |||||||
| 		switch tag.AVCPacketType { | 		switch tag.AVCPacketType { | ||||||
| 		case flvio.AVC_SEQHDR: | 		case flvio.AVC_SEQHDR: | ||||||
| 			if !self.GotVideo { | 			if !self.GotVideo { | ||||||
| 				var stream h264parser.CodecData | 				var stream av.CodecData | ||||||
| 				if stream, err = h264parser.NewCodecDataFromAVCDecoderConfRecord(tag.Data); err != nil { | 				if stream, err = h264parser.NewCodecDataFromAVCDecoderConfRecord(tag.Data); err != nil { | ||||||
| 					err = fmt.Errorf("flv: h264 seqhdr invalid") | 					if stream, err = h265parser.NewCodecDataFromAVCDecoderConfRecord(tag.Data); err != nil { | ||||||
| 					return | 						err = fmt.Errorf("flv: h264 seqhdr invalid") | ||||||
|  | 						return | ||||||
|  | 					} | ||||||
| 				} | 				} | ||||||
| 				self.VideoStreamIdx = len(self.Streams) | 				self.VideoStreamIdx = len(self.Streams) | ||||||
| 				self.Streams = append(self.Streams, stream) | 				self.Streams = append(self.Streams, stream) | ||||||
| @@ -222,7 +227,17 @@ func CodecDataToTag(stream av.CodecData) (_tag flvio.Tag, ok bool, err error) { | |||||||
| 		} | 		} | ||||||
| 		ok = true | 		ok = true | ||||||
| 		_tag = tag | 		_tag = tag | ||||||
|  | 	case av.H265: | ||||||
|  | 		h264 := stream.(h264parser.CodecData) | ||||||
|  | 		tag := flvio.Tag{ | ||||||
|  | 			Type:          flvio.TAG_VIDEO, | ||||||
|  | 			AVCPacketType: flvio.AVC_SEQHDR, | ||||||
|  | 			CodecID:       flvio.VIDEO_H265, | ||||||
|  | 			Data:          h264.AVCDecoderConfRecordBytes(), | ||||||
|  | 			FrameType:     flvio.FRAME_KEY, | ||||||
|  | 		} | ||||||
|  | 		ok = true | ||||||
|  | 		_tag = tag | ||||||
| 	case av.NELLYMOSER: | 	case av.NELLYMOSER: | ||||||
| 	case av.SPEEX: | 	case av.SPEEX: | ||||||
|  |  | ||||||
| @@ -272,7 +287,19 @@ func PacketToTag(pkt av.Packet, stream av.CodecData) (tag flvio.Tag, timestamp i | |||||||
| 		} else { | 		} else { | ||||||
| 			tag.FrameType = flvio.FRAME_INTER | 			tag.FrameType = flvio.FRAME_INTER | ||||||
| 		} | 		} | ||||||
|  | 	case av.H265: | ||||||
|  | 		tag = flvio.Tag{ | ||||||
|  | 			Type:            flvio.TAG_VIDEO, | ||||||
|  | 			AVCPacketType:   flvio.AVC_NALU, | ||||||
|  | 			CodecID:         flvio.VIDEO_H265, | ||||||
|  | 			Data:            pkt.Data, | ||||||
|  | 			CompositionTime: flvio.TimeToTs(pkt.CompositionTime), | ||||||
|  | 		} | ||||||
|  | 		if pkt.IsKeyFrame { | ||||||
|  | 			tag.FrameType = flvio.FRAME_KEY | ||||||
|  | 		} else { | ||||||
|  | 			tag.FrameType = flvio.FRAME_INTER | ||||||
|  | 		} | ||||||
| 	case av.AAC: | 	case av.AAC: | ||||||
| 		tag = flvio.Tag{ | 		tag = flvio.Tag{ | ||||||
| 			Type:          flvio.TAG_AUDIO, | 			Type:          flvio.TAG_AUDIO, | ||||||
| @@ -336,7 +363,7 @@ func NewMuxer(w io.Writer) *Muxer { | |||||||
| 	return NewMuxerWriteFlusher(bufio.NewWriterSize(w, pio.RecommendBufioSize)) | 	return NewMuxerWriteFlusher(bufio.NewWriterSize(w, pio.RecommendBufioSize)) | ||||||
| } | } | ||||||
|  |  | ||||||
| var CodecTypes = []av.CodecType{av.H264, av.AAC, av.SPEEX} | var CodecTypes = []av.CodecType{av.H264, av.AAC, av.SPEEX, av.H265} | ||||||
|  |  | ||||||
| func (self *Muxer) WriteHeader(streams []av.CodecData) (err error) { | func (self *Muxer) WriteHeader(streams []av.CodecData) (err error) { | ||||||
| 	var flags uint8 | 	var flags uint8 | ||||||
|   | |||||||
| @@ -59,6 +59,7 @@ const ( | |||||||
| 	FRAME_INTER = 2 | 	FRAME_INTER = 2 | ||||||
|  |  | ||||||
| 	VIDEO_H264 = 7 | 	VIDEO_H264 = 7 | ||||||
|  | 	VIDEO_H265 = 12 | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type Tag struct { | type Tag struct { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 deepch
					deepch