-
Notifications
You must be signed in to change notification settings - Fork 85
/
sei.go
64 lines (59 loc) · 1.78 KB
/
sei.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package avc
import (
"bytes"
"errors"
"fmt"
"github.com/Eyevinn/mp4ff/sei"
)
var (
ErrNotSEINalu = errors.New("not an SEI NAL unit")
)
// ParseSEINalu - parse SEI NAL unit (incl header) and return messages given SPS.
// Returns sei.ErrRbspTrailingBitsMissing if the NALU is missing the trailing bits.
func ParseSEINalu(nalu []byte, sps *SPS) ([]sei.SEIMessage, error) {
if GetNaluType(nalu[0]) != NALU_SEI {
return nil, ErrNotSEINalu
}
seiBytes := nalu[1:] // Skip NALU header
buf := bytes.NewReader(seiBytes)
seiDatas, err := sei.ExtractSEIData(buf)
missingRbspTrailingBits := false
if err != nil {
if errors.Is(err, sei.ErrRbspTrailingBitsMissing) {
missingRbspTrailingBits = true
} else {
return nil, fmt.Errorf("extracting SEI data: %w", err)
}
}
seiMsgs := make([]sei.SEIMessage, 0, len(seiDatas))
var seiMsg sei.SEIMessage
for _, seiData := range seiDatas {
switch {
case seiData.Type() == sei.SEIPicTimingType && sps != nil && sps.VUI != nil:
var cbpDbpDelay *sei.CbpDbpDelay
var timeOffsetLen byte = 0
hrdParams := sps.VUI.VclHrdParameters
if hrdParams == nil {
hrdParams = sps.VUI.NalHrdParameters
}
if hrdParams != nil {
cbpDbpDelay = &sei.CbpDbpDelay{
CpbRemovalDelayLengthMinus1: byte(hrdParams.CpbRemovalDelayLengthMinus1),
DpbOutputDelayLengthMinus1: byte(hrdParams.DpbOutputDelayLengthMinus1),
}
timeOffsetLen = byte(hrdParams.TimeOffsetLength)
}
seiMsg, err = sei.DecodePicTimingAvcSEIHRD(&seiData, cbpDbpDelay, timeOffsetLen)
default:
seiMsg, err = sei.DecodeSEIMessage(&seiData, sei.AVC)
}
if err != nil {
return nil, fmt.Errorf("sei decode: %w", err)
}
seiMsgs = append(seiMsgs, seiMsg)
}
if missingRbspTrailingBits {
return seiMsgs, sei.ErrRbspTrailingBitsMissing
}
return seiMsgs, nil
}