mirror of https://bitbucket.org/ausocean/av.git
codec/h264/h2646dec: fixed up binarization tables and added mbTypeBinarization function along with test TestMbTypeBinarization.
This commit is contained in:
parent
b41ae4bcd3
commit
cd83cf9e8e
|
@ -100,13 +100,7 @@ func CondTermFlag(mbAddr, mbSkipFlag int) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// s9.3.3 p 278: Returns the value of the syntax element
|
// s9.3.3 p 278: Returns the value of the syntax element
|
||||||
func (bin *Binarization) Decode(sliceContext *SliceContext, b *bits.BitReader, rbsp []byte) {
|
func (bin *Binarization) Decode(sliceContext *SliceContext, b *bits.BitReader, rbsp []byte) {}
|
||||||
if bin.SyntaxElement == "MbType" {
|
|
||||||
bin.binString = binIdxMbMap[sliceContext.Slice.Data.SliceTypeName][sliceContext.Slice.Data.MbType]
|
|
||||||
} else {
|
|
||||||
logger.Printf("TODO: no means to find binString for %s\n", bin.SyntaxElement)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 9.3.3.1.1 : returns ctxIdxInc
|
// 9.3.3.1.1 : returns ctxIdxInc
|
||||||
func Decoder9_3_3_1_1_1(condTermFlagA, condTermFlagB int) int {
|
func Decoder9_3_3_1_1_1(condTermFlagA, condTermFlagB int) int {
|
||||||
|
@ -178,13 +172,11 @@ func initCabac(binarization *Binarization, context *SliceContext) *CABAC {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Table 9-36, 9-37
|
// Binarizations for macroblock types in slice types.
|
||||||
// func BinIdx(mbType int, sliceTypeName string) []int {
|
|
||||||
// Map of SliceTypeName[MbType][]int{binString}
|
|
||||||
// {"SliceTypeName": {MbTypeCode: []BinString}}
|
|
||||||
var (
|
var (
|
||||||
binIdxMbMap = map[string]map[int][]int{
|
// binOfIMBTypes provides binarization strings for values of macroblock
|
||||||
"I": {
|
// type in I slices as defined in table 9-36 of the specifications.
|
||||||
|
binOfIMBTypes = [numOfIMBTypes][]int{
|
||||||
0: {0},
|
0: {0},
|
||||||
1: {1, 0, 0, 0, 0, 0},
|
1: {1, 0, 0, 0, 0, 0},
|
||||||
2: {1, 0, 0, 0, 0, 1},
|
2: {1, 0, 0, 0, 0, 1},
|
||||||
|
@ -211,102 +203,129 @@ var (
|
||||||
23: {1, 0, 1, 1, 1, 1, 0},
|
23: {1, 0, 1, 1, 1, 1, 0},
|
||||||
24: {1, 0, 1, 1, 1, 1, 1},
|
24: {1, 0, 1, 1, 1, 1, 1},
|
||||||
25: {1, 1},
|
25: {1, 1},
|
||||||
},
|
}
|
||||||
// Table 9-37
|
|
||||||
"P": {
|
// binOfPOrSPMBTypes provides binarization strings for values of macroblock
|
||||||
|
// type in P or SP slices as defined in table 9-37 of the specifications.
|
||||||
|
// NB: binarization of macroblock types 5 to 30 is 1 and not included here.
|
||||||
|
binOfPOrSPMBTypes = [5][]int{
|
||||||
0: {0, 0, 0},
|
0: {0, 0, 0},
|
||||||
1: {0, 1, 1},
|
1: {0, 1, 1},
|
||||||
2: {0, 1, 0},
|
2: {0, 1, 0},
|
||||||
3: {0, 0, 1},
|
3: {0, 0, 1},
|
||||||
4: {},
|
4: {},
|
||||||
5: {1},
|
|
||||||
6: {1},
|
|
||||||
7: {1},
|
|
||||||
8: {1},
|
|
||||||
9: {1},
|
|
||||||
10: {1},
|
|
||||||
11: {1},
|
|
||||||
12: {1},
|
|
||||||
13: {1},
|
|
||||||
14: {1},
|
|
||||||
15: {1},
|
|
||||||
16: {1},
|
|
||||||
17: {1},
|
|
||||||
18: {1},
|
|
||||||
19: {1},
|
|
||||||
20: {1},
|
|
||||||
21: {1},
|
|
||||||
22: {1},
|
|
||||||
23: {1},
|
|
||||||
24: {1},
|
|
||||||
25: {1},
|
|
||||||
26: {1},
|
|
||||||
27: {1},
|
|
||||||
28: {1},
|
|
||||||
29: {1},
|
|
||||||
30: {1},
|
|
||||||
},
|
|
||||||
// Table 9-37
|
|
||||||
"SP": {
|
|
||||||
0: {0, 0, 0},
|
|
||||||
1: {0, 1, 1},
|
|
||||||
2: {0, 1, 0},
|
|
||||||
3: {0, 0, 1},
|
|
||||||
4: {},
|
|
||||||
5: {1},
|
|
||||||
6: {1},
|
|
||||||
7: {1},
|
|
||||||
8: {1},
|
|
||||||
9: {1},
|
|
||||||
10: {1},
|
|
||||||
11: {1},
|
|
||||||
12: {1},
|
|
||||||
13: {1},
|
|
||||||
14: {1},
|
|
||||||
15: {1},
|
|
||||||
16: {1},
|
|
||||||
17: {1},
|
|
||||||
18: {1},
|
|
||||||
19: {1},
|
|
||||||
20: {1},
|
|
||||||
21: {1},
|
|
||||||
22: {1},
|
|
||||||
23: {1},
|
|
||||||
24: {1},
|
|
||||||
25: {1},
|
|
||||||
26: {1},
|
|
||||||
27: {1},
|
|
||||||
28: {1},
|
|
||||||
29: {1},
|
|
||||||
30: {1},
|
|
||||||
},
|
|
||||||
// TODO: B Slice table 9-37
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map of SliceTypeName[SubMbType][]int{binString}
|
// binOfBMBTypes provides binarization strings for values of macroblock
|
||||||
binIdxSubMbMap = map[string]map[int][]int{
|
// type in B slice as defined in table 9-37 of the specifications.
|
||||||
"P": {
|
// NB: binarization of macroblock types 23 to 48 is 111101 and is not
|
||||||
0: {1},
|
// included here.
|
||||||
1: {0, 0},
|
binOfBMBTypes = [23][]int{
|
||||||
2: {0, 1, 1},
|
0: {0},
|
||||||
3: {0, 1, 0},
|
1: {1, 0, 0},
|
||||||
},
|
2: {1, 0, 1},
|
||||||
"SP": {
|
3: {1, 1, 0, 0, 0, 0},
|
||||||
0: {1},
|
4: {1, 1, 0, 0, 0, 1},
|
||||||
1: {0, 0},
|
5: {1, 1, 0, 0, 1, 0},
|
||||||
2: {0, 1, 1},
|
6: {1, 1, 0, 0, 1, 1},
|
||||||
3: {0, 1, 0},
|
7: {1, 1, 0, 1, 0, 0},
|
||||||
},
|
8: {1, 1, 0, 1, 0, 1},
|
||||||
// TODO: B slice table 9-38
|
9: {1, 1, 0, 1, 1, 0},
|
||||||
|
10: {1, 1, 0, 1, 1, 1},
|
||||||
|
11: {1, 1, 1, 1, 1, 0},
|
||||||
|
12: {1, 1, 1, 0, 0, 0, 0},
|
||||||
|
13: {1, 1, 1, 0, 0, 0, 1},
|
||||||
|
14: {1, 1, 1, 0, 0, 1, 0},
|
||||||
|
15: {1, 1, 1, 0, 0, 1, 1},
|
||||||
|
16: {1, 1, 1, 0, 1, 0, 0},
|
||||||
|
17: {1, 1, 1, 0, 1, 0, 1},
|
||||||
|
18: {1, 1, 1, 0, 1, 1, 0},
|
||||||
|
19: {1, 1, 1, 0, 1, 1, 1},
|
||||||
|
20: {1, 1, 1, 1, 0, 0, 0},
|
||||||
|
21: {1, 1, 1, 1, 0, 0, 1},
|
||||||
|
22: {1, 1, 1, 1, 1, 1},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Table 9-36, 9-37
|
|
||||||
MbBinIdx = []int{1, 2, 3, 4, 5, 6}
|
|
||||||
|
|
||||||
// Table 9-38
|
|
||||||
SubMbBinIdx = []int{0, 1, 2, 3, 4, 5}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Binarizations for sub-macroblock types in slice types.
|
||||||
|
var (
|
||||||
|
// binOfPorSPSubMBTypes provides binarization strings for values of sub-macroblock
|
||||||
|
// type in P or SP slices as defined in table 9-38 of the specifications.
|
||||||
|
binOfPOrSPSubMBTypes = [4][]int{
|
||||||
|
0: {1},
|
||||||
|
1: {0, 0},
|
||||||
|
2: {0, 1, 1},
|
||||||
|
3: {0, 1, 0},
|
||||||
|
}
|
||||||
|
|
||||||
|
// binOfBSubMBTypes provides binarization strings for values of sub-macroblock
|
||||||
|
// type in B slices as defined in table 9-38 of the specifications.
|
||||||
|
binOfBSubMBTypes = [numOfBSubMBTypes][]int{
|
||||||
|
0: {1},
|
||||||
|
1: {1, 0, 0},
|
||||||
|
2: {1, 0, 1},
|
||||||
|
3: {1, 1, 0, 0, 0},
|
||||||
|
4: {1, 1, 0, 0, 1},
|
||||||
|
5: {1, 1, 0, 1, 0},
|
||||||
|
6: {1, 1, 0, 1, 1},
|
||||||
|
7: {1, 1, 1, 0, 0, 0},
|
||||||
|
8: {1, 1, 1, 0, 0, 1},
|
||||||
|
9: {1, 1, 1, 0, 1, 0},
|
||||||
|
10: {1, 1, 1, 0, 1, 1},
|
||||||
|
11: {1, 1, 1, 1, 0},
|
||||||
|
12: {1, 1, 1, 1, 1},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Errors used by mbTypeBinarization.
|
||||||
|
var (
|
||||||
|
errBadMbType = errors.New("macroblock type outside of valid range")
|
||||||
|
errInvalidSliceType = errors.New("slice type does not exist")
|
||||||
|
)
|
||||||
|
|
||||||
|
// mbTypeBinarization returns the macroblock type binarization for the given
|
||||||
|
// macroblock type value and slice type using the process defined in section
|
||||||
|
// 9.3.2.5 of the specifications.
|
||||||
|
func mbTypeBinarization(v, slice int) ([]int, error) {
|
||||||
|
switch slice {
|
||||||
|
case sliceTypeI:
|
||||||
|
if v < minIMbType || v > maxIMbType {
|
||||||
|
return nil, errBadMbType
|
||||||
|
}
|
||||||
|
return binOfIMBTypes[v], nil
|
||||||
|
|
||||||
|
case sliceTypeSI:
|
||||||
|
if v < minSIMbType || v > maxSIMbType {
|
||||||
|
return nil, errBadMbType
|
||||||
|
}
|
||||||
|
if v == sliceTypeSI {
|
||||||
|
return []int{0}, nil
|
||||||
|
}
|
||||||
|
return append([]int{1}, binOfIMBTypes[v-1]...), nil
|
||||||
|
|
||||||
|
case sliceTypeP, sliceTypeSP:
|
||||||
|
if v < minPOrSPMbType || v > maxPOrSPMbType || v == P8x8ref0 {
|
||||||
|
return nil, errBadMbType
|
||||||
|
}
|
||||||
|
if v < 5 {
|
||||||
|
return binOfPOrSPMBTypes[v], nil
|
||||||
|
}
|
||||||
|
return append([]int{1}, binOfIMBTypes[v-5]...), nil
|
||||||
|
|
||||||
|
case sliceTypeB:
|
||||||
|
if v < minBMbType || v > maxBMbType {
|
||||||
|
return nil, errBadMbType
|
||||||
|
}
|
||||||
|
if v < 23 {
|
||||||
|
return binOfBMBTypes[v], nil
|
||||||
|
}
|
||||||
|
return append([]int{1, 1, 1, 1, 0, 1}, binOfIMBTypes[v-23]...), nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, errInvalidSliceType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Table 9-34
|
// Table 9-34
|
||||||
type MaxBinIdxCtx struct {
|
type MaxBinIdxCtx struct {
|
||||||
// When false, Prefix is the MaxBinIdxCtx
|
// When false, Prefix is the MaxBinIdxCtx
|
||||||
|
|
|
@ -1,6 +1,46 @@
|
||||||
package h264dec
|
package h264dec
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMbTypeBinarization(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
v, slice int
|
||||||
|
want []int
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
{v: 6, slice: sliceTypeI, want: []int{1, 0, 0, 1, 0, 0, 1}},
|
||||||
|
{v: 26, slice: sliceTypeI, err: errBadMbType},
|
||||||
|
{v: -1, slice: sliceTypeI, err: errBadMbType},
|
||||||
|
{v: 4, slice: sliceTypeSI, want: []int{0}},
|
||||||
|
{v: 6, slice: sliceTypeSI, want: []int{1, 1, 0, 0, 1, 0, 0, 0}},
|
||||||
|
{v: 0, slice: sliceTypeSI, err: errBadMbType},
|
||||||
|
{v: 27, slice: sliceTypeSI, err: errBadMbType},
|
||||||
|
{v: 2, slice: sliceTypeP, want: []int{0, 1, 0}},
|
||||||
|
{v: 3, slice: sliceTypeSP, want: []int{0, 0, 1}},
|
||||||
|
{v: 7, slice: sliceTypeP, want: []int{1, 1, 0, 0, 0, 0, 1}},
|
||||||
|
{v: 7, slice: sliceTypeSP, want: []int{1, 1, 0, 0, 0, 0, 1}},
|
||||||
|
{v: -1, slice: sliceTypeP, err: errBadMbType},
|
||||||
|
{v: 31, slice: sliceTypeP, err: errBadMbType},
|
||||||
|
{v: 8, slice: sliceTypeB, want: []int{1, 1, 0, 1, 0, 1}},
|
||||||
|
{v: 30, slice: sliceTypeB, want: []int{1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0}},
|
||||||
|
{v: -1, slice: sliceTypeB, err: errBadMbType},
|
||||||
|
{v: 49, slice: sliceTypeB, err: errBadMbType},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, test := range tests {
|
||||||
|
got, err := mbTypeBinarization(test.v, test.slice)
|
||||||
|
if err != test.err {
|
||||||
|
t.Errorf("did not get expected error for test %d\nGot: %v\nWant: %v", i, err, test.err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(got, test.want) {
|
||||||
|
t.Errorf("did not get expected result for test %d\nGot: %v\nWant: %v", i, got, test.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var ctxIdxTests = []struct {
|
var ctxIdxTests = []struct {
|
||||||
binIdx int
|
binIdx int
|
||||||
|
|
|
@ -4,6 +4,38 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// P slice macroblock types.
|
||||||
|
const (
|
||||||
|
P8x8ref0 = 4
|
||||||
|
)
|
||||||
|
|
||||||
|
// Number of macroblock types for each slice type.
|
||||||
|
const (
|
||||||
|
numOfIMBTypes = 26
|
||||||
|
numOfPMBTypes = 31
|
||||||
|
numOfSPMBTypes = 31
|
||||||
|
numOfBMBTypes = 49
|
||||||
|
)
|
||||||
|
|
||||||
|
// Number of sub macroblock types for each slice type.
|
||||||
|
const (
|
||||||
|
numOfPSubMBTypes = 4
|
||||||
|
numOfSPSubMBTypes = 4
|
||||||
|
numOfBSubMBTypes = 13
|
||||||
|
)
|
||||||
|
|
||||||
|
// Min and max macroblock types for slice types.
|
||||||
|
const (
|
||||||
|
minIMbType = 0
|
||||||
|
maxIMbType = 25
|
||||||
|
minPOrSPMbType = 0
|
||||||
|
maxPOrSPMbType = 30
|
||||||
|
minBMbType = 0
|
||||||
|
maxBMbType = 48
|
||||||
|
minSIMbType = 1
|
||||||
|
maxSIMbType = 26
|
||||||
|
)
|
||||||
|
|
||||||
const MB_TYPE_INFERRED = 1000
|
const MB_TYPE_INFERRED = 1000
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -9,6 +9,15 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Slice types.
|
||||||
|
const (
|
||||||
|
sliceTypeP = 0
|
||||||
|
sliceTypeB = 1
|
||||||
|
sliceTypeI = 2
|
||||||
|
sliceTypeSP = 3
|
||||||
|
sliceTypeSI = 4
|
||||||
|
)
|
||||||
|
|
||||||
// Chroma formats as defined in section 6.2, tab 6-1.
|
// Chroma formats as defined in section 6.2, tab 6-1.
|
||||||
const (
|
const (
|
||||||
chromaMonochrome = iota
|
chromaMonochrome = iota
|
||||||
|
|
Loading…
Reference in New Issue