forked from Eyevinn/mp4ff
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathslice.go
77 lines (64 loc) · 1.41 KB
/
slice.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
65
66
67
68
69
70
71
72
73
74
75
76
77
package avc
import (
"bytes"
"errors"
"github.com/edgeware/mp4ff/bits"
)
var ErrNoSliceHeader = errors.New("No slice header")
var ErrInvalidSliceType = errors.New("Invalid slice type")
var ErrTooFewBytesToParse = errors.New("Too few bytes to parse symbol")
type SliceType uint
func (s SliceType) String() string {
switch s {
case SLICE_I:
return "I"
case SLICE_P:
return "P"
case SLICE_B:
return "B"
default:
return ""
}
}
const (
SLICE_P = SliceType(0)
SLICE_B = SliceType(1)
SLICE_I = SliceType(2)
SLICE_SP = SliceType(3)
SLICE_SI = SliceType(4)
)
// GetSliceTypeFromNALU - parse slice header to get slice type in interval 0 to 4
func GetSliceTypeFromNALU(data []byte) (sliceType SliceType, err error) {
if len(data) <= 1 {
err = ErrTooFewBytesToParse
return
}
naluType := GetNaluType(data[0])
switch naluType {
case 1, 2, 5, 19:
// slice_layer_without_partitioning_rbsp
// slice_data_partition_a_layer_rbsp
default:
err = ErrNoSliceHeader
return
}
r := bits.NewEBSPReader(bytes.NewReader((data[1:])))
// first_mb_in_slice
if _, err = r.ReadExpGolomb(); err != nil {
return
}
// slice_type
var st uint
if st, err = r.ReadExpGolomb(); err != nil {
return
}
sliceType = SliceType(st)
if sliceType > 9 {
err = ErrInvalidSliceType
return
}
if sliceType >= 5 {
sliceType -= 5 // The same type is repeated twice to tell if all slices in picture are the same
}
return
}