forked from 32bitkid/mpeg
/
slice.go
136 lines (112 loc) · 2.94 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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package video
import "errors"
import "image"
var ErrInvalidReservedBits = errors.New("invalid reserved bits")
type Slice struct {
slice_start_code StartCode // 32 bslbf
slice_vertical_position_extension uint32 // 3 uimsbf
priority_breakpoint uint32 // 7 uimsbf
intra_slice_flag bool // 1 bslbf
intra_slice bool // 1 uimsbf
extra_information []uint8
}
func (br *VideoSequence) slice(frame *image.YCbCr) error {
code, err := br.Read32(32)
if err != nil {
return err
}
if StartCode(code).IsSlice() == false {
return ErrUnexpectedStartCode
}
var dcp dcDctPredictors
resetDcPredictors := dcp.createResetter(br.PictureCodingExtension.intra_dc_precision)
// Reset dcDctPredictors: at start of slice (7.2.1)
resetDcPredictors()
// Reset motion vector predictors: Start if each slice (7.6.4.3)
var mvd motionVectorData
mvd.reset()
s := Slice{}
s.slice_start_code = StartCode(code)
mb_row := int((code & 0xFF) - 1)
frameSlice := &image.YCbCr{
Y: frame.Y[16*mb_row*frame.YStride:],
Cb: frame.Cb[8*mb_row*frame.CStride:],
Cr: frame.Cr[8*mb_row*frame.CStride:],
YStride: frame.YStride,
CStride: frame.CStride,
Rect: image.Rect(frame.Rect.Min.X, mb_row*16, frame.Rect.Max.X, mb_row*16+16),
}
if br.SequenceHeader.vertical_size_value > 2800 {
s.slice_vertical_position_extension, err = br.Read32(3)
if err != nil {
return err
}
}
// TODO(jh): sequence_scalable support
if false /* (<sequence_scalable_extension() is present in the bitstream>) */ {
if false /* (scalable_mode == “data partitioning” ) */ {
s.priority_breakpoint, err = br.Read32(7)
if err != nil {
return err
}
}
}
var quantiser_scale_code uint32
if qsc, err := br.Read32(5); err != nil {
return err
} else {
quantiser_scale_code = qsc
}
if nextbits, err := br.Peek32(1); err != nil {
return err
} else if nextbits == 1 {
s.intra_slice_flag, err = br.Read1()
if err != nil {
return err
}
s.intra_slice, err = br.Read1()
if err != nil {
return err
}
if reserved_bits, err := br.Read32(7); err != nil {
return err
} else if reserved_bits != 0 {
return ErrInvalidReservedBits
}
for {
if nextbits, err := br.Peek32(1); err != nil {
return err
} else if nextbits != 1 {
break
} else if err := br.Skip(1); err != nil {
return err
}
if data, err := br.Read32(8); err != nil {
return err
} else {
s.extra_information = append(s.extra_information, uint8(data))
}
}
}
if err := br.Skip(1); err != nil {
return err
}
var mb_address int = -1
for {
mb_address, err = br.macroblock(
mb_address, mb_row,
&dcp, resetDcPredictors,
&mvd,
&quantiser_scale_code,
frameSlice)
if err != nil {
return err
}
if nextbits, err := br.Peek32(23); err != nil {
return err
} else if nextbits == 0 {
break
}
}
return next_start_code(br)
}