diff --git a/codec/h265/lex.go b/codec/h265/lex.go index 7baaf734..61a4dab7 100644 --- a/codec/h265/lex.go +++ b/codec/h265/lex.go @@ -83,6 +83,7 @@ func (l *Lexer) Lex(dst io.Writer, src io.Reader, delay time.Duration) error { // If not currently fragmented then we ignore current write if l.fragmented && nalType != typeFragmentation { l.off = 0 + l.fragmented = false continue } @@ -137,7 +138,25 @@ func (l *Lexer) handleAggregation(d []byte) { // handleFragmentation parses NAL units from fragmentation packets and writes // them to the Lexer's buf. func (l *Lexer) handleFragmentation(d []byte) { + _d := d[3:] + if l.UsingDON { + _d = d[5:] + } + s := d[2]&0x80 == 1 + e := d[2]&0x40 == 1 + switch { + case s && !e: + l.fragmented = true + l.write(_d) + case !s && e: + l.fragmented = false + fallthrough + case !s && !e: + l.writeNoPrefix(_d) + default: + panic("bad fragmentation unit") + } } // handlePACI will handl PACI packets @@ -147,11 +166,18 @@ func (l *Lexer) handlePACI(d []byte) { panic("unsupported nal type") } -// write writes a NAL unit to the Lexers buf in byte stream format using the +// write writes a NAL unit to the Lexer's buf in byte stream format using the // start code. func (l *Lexer) write(d []byte) { - const startCode = "\x00\x00\x00\x01" - copy(l.buf[l.off:], []byte(startCode)) + const prefix = "\x00\x00\x00\x01" + copy(l.buf[l.off:], []byte(prefix)) copy(l.buf[l.off+4:], d) l.off += len(d) + 4 } + +// writeNoPrefix writes data to the Lexer's buf. This is used for non start +// fragmentations of a NALU. +func (l *Lexer) writeNoPrefix(d []byte) { + copy(l.buf[l.off:], d) + l.off += len(d) +}