Skip to content

Commit

Permalink
h264: support AVCC with empty NALUs
Browse files Browse the repository at this point in the history
  • Loading branch information
aler9 committed Sep 24, 2023
1 parent 7fae03f commit d914cd1
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 17 deletions.
41 changes: 24 additions & 17 deletions pkg/codecs/h264/avcc.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ package h264

import (
"fmt"
"errors"
)

var (
ErrAVCCNoNALUs = errors.New("AVCC doesn't contain any NALU")
)

// AVCCUnmarshal decodes an access unit from the AVCC stream format.
Expand All @@ -21,33 +26,35 @@ func AVCCUnmarshal(buf []byte) ([][]byte, error) {
l := int(uint32(buf[pos])<<24 | uint32(buf[pos+1])<<16 | uint32(buf[pos+2])<<8 | uint32(buf[pos+3]))
pos += 4

if l == 0 {
return nil, fmt.Errorf("invalid NALU")
}
if l != 0 {
if (auSize + l) > MaxAccessUnitSize {
return nil, fmt.Errorf("access unit size (%d) is too big, maximum is %d", auSize+l, MaxAccessUnitSize)
}

if (auSize + l) > MaxAccessUnitSize {
return nil, fmt.Errorf("access unit size (%d) is too big, maximum is %d", auSize+l, MaxAccessUnitSize)
}
if (naluCount + 1) > MaxNALUsPerAccessUnit {
return nil, fmt.Errorf("NALU count (%d) exceeds maximum allowed (%d)",
len(ret)+1, MaxNALUsPerAccessUnit)
}

if (naluCount + 1) > MaxNALUsPerAccessUnit {
return nil, fmt.Errorf("NALU count (%d) exceeds maximum allowed (%d)",
len(ret)+1, MaxNALUsPerAccessUnit)
}
if (bl - pos) < l {
return nil, fmt.Errorf("invalid length")
}

if (bl - pos) < l {
return nil, fmt.Errorf("invalid length")
ret = append(ret, buf[pos:pos+l])
auSize += l
naluCount++
pos += l
}

ret = append(ret, buf[pos:pos+l])
auSize += l
naluCount++
pos += l

if (bl - pos) == 0 {
break
}
}

if ret == nil {
return nil, ErrAVCCNoNALUs
}

return ret, nil
}

Expand Down
22 changes: 22 additions & 0 deletions pkg/codecs/h264/avcc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,28 @@ func TestAVCCUnmarshal(t *testing.T) {
}
}

// issue mediamtx/2375
func TestAVCCUnmarshalEmpty(t *testing.T) {
caenc := []byte{
0x0, 0x0, 0x0, 0x0,
}

dec, err = AVCCUnmarshal(caenc)
require.Equal(t, ErrAVCCNoNALUs, err)
require.Equal(t, [][]byte(nil), dec)

caenc = []byte{
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x1, 0x2, 0x3,
}
cadec := [][]byte{
{1, 2, 3},
}

dec, err = AVCCUnmarshal(caenc)
require.NoError(t, err)
require.Equal(t, cadec, dec)
}

func TestAVCCMarshal(t *testing.T) {
for _, ca := range casesAVCC {
t.Run(ca.name, func(t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions pkg/formats/fmp4/part_track.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package fmp4

import (
"fmt"

"github.com/abema/go-mp4"

"github.com/bluenviron/mediacommon/pkg/codecs/av1"
Expand Down

0 comments on commit d914cd1

Please sign in to comment.