diff --git a/pkg/codecs/h265/dtsextractor.go b/pkg/codecs/h265/dtsextractor.go index 93450c7d..1f1e486e 100644 --- a/pkg/codecs/h265/dtsextractor.go +++ b/pkg/codecs/h265/dtsextractor.go @@ -182,6 +182,10 @@ func (d *DTSExtractor) extractInner(au [][]byte, pts time.Duration) (time.Durati return pts, nil } + if d.spsp.VUI == nil || d.spsp.VUI.TimingInfo == nil { + return pts, nil + } + var poc uint32 var dtsPOC uint32 diff --git a/pkg/codecs/h265/dtsextractor_test.go b/pkg/codecs/h265/dtsextractor_test.go new file mode 100644 index 00000000..71c3adf8 --- /dev/null +++ b/pkg/codecs/h265/dtsextractor_test.go @@ -0,0 +1,59 @@ +package h265 + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestDTSExtractor(t *testing.T) { + type sequenceSample struct { + nalus [][]byte + pts time.Duration + dts time.Duration + } + + for _, ca := range []struct { + name string + sequence []sequenceSample + }{ + { + "no timing info", + []sequenceSample{ + { + [][]byte{ + { // SPS + 0x42, 0x01, 0x01, 0x02, 0x20, 0x00, 0x00, 0x03, + 0x00, 0xb0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, + 0x00, 0x7b, 0xa0, 0x07, 0x82, 0x00, 0x88, 0x7d, + 0xb6, 0x71, 0x8b, 0x92, 0x44, 0x80, 0x53, 0x88, + 0x88, 0x92, 0xcf, 0x24, 0xa6, 0x92, 0x72, 0xc9, + 0x12, 0x49, 0x22, 0xdc, 0x91, 0xaa, 0x48, 0xfc, + 0xa2, 0x23, 0xff, 0x00, 0x01, 0x00, 0x01, 0x6a, + 0x02, 0x02, 0x02, 0x01, + }, + { + // PPS + 0x44, 0x01, 0xc0, 0x25, 0x2f, 0x05, 0x32, 0x40, + }, + { + byte(NALUType_CRA_NUT) << 1, + }, + }, + 1 * time.Second, + 1 * time.Second, + }, + }, + }, + } { + t.Run(ca.name, func(t *testing.T) { + ex := NewDTSExtractor() + for _, sample := range ca.sequence { + dts, err := ex.Extract(sample.nalus, sample.pts) + require.NoError(t, err) + require.Equal(t, sample.dts, dts) + } + }) + } +}