Skip to content

Commit

Permalink
[RTMP] client / server full support h265 video codec
Browse files Browse the repository at this point in the history
  • Loading branch information
deepch committed Oct 25, 2022
1 parent b31edcc commit 472775f
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 26 deletions.
47 changes: 27 additions & 20 deletions codec/h265parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -531,73 +531,80 @@ type AVCDecoderConfRecord struct {
var ErrDecconfInvalid = fmt.Errorf("h265parser: AVCDecoderConfRecord invalid")

func (self *AVCDecoderConfRecord) Unmarshal(b []byte) (n int, err error) {
if len(b) < 7 {
if len(b) < 30 {
err = ErrDecconfInvalid
return
}
self.AVCProfileIndication = b[1]
self.ProfileCompatibility = b[2]
self.AVCLevelIndication = b[3]
self.LengthSizeMinusOne = b[4] & 0x03
spscount := int(b[5] & 0x1f)
n += 6
for i := 0; i < spscount; i++ {

vpscount := int(b[25] & 0x1f)
n += 26
for i := 0; i < vpscount; i++ {
if len(b) < n+2 {
err = ErrDecconfInvalid
return
}
spslen := int(pio.U16BE(b[n:]))
vpslen := int(pio.U16BE(b[n:]))
n += 2

if len(b) < n+spslen {
if len(b) < n+vpslen {
err = ErrDecconfInvalid
return
}
self.SPS = append(self.SPS, b[n:n+spslen])
n += spslen
self.VPS = append(self.VPS, b[n:n+vpslen])
n += vpslen
}

if len(b) < n+1 {
err = ErrDecconfInvalid
return
}

ppscount := int(b[n])
n++
n++

for i := 0; i < ppscount; i++ {
spscount := int(b[n])
n++

for i := 0; i < spscount; i++ {
if len(b) < n+2 {
err = ErrDecconfInvalid
return
}
ppslen := int(pio.U16BE(b[n:]))
spslen := int(pio.U16BE(b[n:]))
n += 2

if len(b) < n+ppslen {
if len(b) < n+spslen {
err = ErrDecconfInvalid
return
}
self.PPS = append(self.PPS, b[n:n+ppslen])
n += ppslen
self.SPS = append(self.SPS, b[n:n+spslen])
n += spslen
}

vpscount := int(b[n])
n++
n++

for i := 0; i < vpscount; i++ {
ppscount := int(b[n])
n++

for i := 0; i < ppscount; i++ {
if len(b) < n+2 {
err = ErrDecconfInvalid
return
}
vpslen := int(pio.U16BE(b[n:]))
ppslen := int(pio.U16BE(b[n:]))
n += 2

if len(b) < n+vpslen {
if len(b) < n+ppslen {
err = ErrDecconfInvalid
return
}
self.VPS = append(self.VPS, b[n:n+vpslen])
n += vpslen
self.PPS = append(self.PPS, b[n:n+ppslen])
n += ppslen
}
return
}
Expand Down
39 changes: 33 additions & 6 deletions format/flv/flv.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/deepch/vdk/codec/aacparser"
"github.com/deepch/vdk/codec/fake"
"github.com/deepch/vdk/codec/h264parser"
"github.com/deepch/vdk/codec/h265parser"
"github.com/deepch/vdk/format/flv/flvio"
"github.com/deepch/vdk/utils/bits/pio"
)
Expand All @@ -28,6 +29,8 @@ func NewMetadataByStreams(streams []av.CodecData) (metadata flvio.AMFMap, err er
switch typ {
case av.H264:
metadata["videocodecid"] = flvio.VIDEO_H264
case av.H265:
metadata["videocodecid"] = flvio.VIDEO_H265

default:
err = fmt.Errorf("flv: metadata: unsupported video codecType=%v", stream.Type())
Expand Down Expand Up @@ -87,10 +90,12 @@ func (self *Prober) PushTag(tag flvio.Tag, timestamp int32) (err error) {
switch tag.AVCPacketType {
case flvio.AVC_SEQHDR:
if !self.GotVideo {
var stream h264parser.CodecData
var stream av.CodecData
if stream, err = h264parser.NewCodecDataFromAVCDecoderConfRecord(tag.Data); err != nil {
err = fmt.Errorf("flv: h264 seqhdr invalid")
return
if stream, err = h265parser.NewCodecDataFromAVCDecoderConfRecord(tag.Data); err != nil {
err = fmt.Errorf("flv: h264 seqhdr invalid")
return
}
}
self.VideoStreamIdx = len(self.Streams)
self.Streams = append(self.Streams, stream)
Expand Down Expand Up @@ -222,7 +227,17 @@ func CodecDataToTag(stream av.CodecData) (_tag flvio.Tag, ok bool, err error) {
}
ok = true
_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.SPEEX:

Expand Down Expand Up @@ -272,7 +287,19 @@ func PacketToTag(pkt av.Packet, stream av.CodecData) (tag flvio.Tag, timestamp i
} else {
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:
tag = flvio.Tag{
Type: flvio.TAG_AUDIO,
Expand Down Expand Up @@ -336,7 +363,7 @@ func NewMuxer(w io.Writer) *Muxer {
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) {
var flags uint8
Expand Down
1 change: 1 addition & 0 deletions format/flv/flvio/flvio.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const (
FRAME_INTER = 2

VIDEO_H264 = 7
VIDEO_H265 = 12
)

type Tag struct {
Expand Down

0 comments on commit 472775f

Please sign in to comment.