mirror of https://bitbucket.org/ausocean/av.git
codec/h264/decode: did not copy over most up to date version from old repo, so fixing that
This commit is contained in:
parent
6880cc3298
commit
4a9da74ff0
|
@ -1,3 +0,0 @@
|
||||||
.*.swp
|
|
||||||
*.mp4
|
|
||||||
*.h264
|
|
|
@ -93,6 +93,7 @@ func MbTypeName(sliceType string, mbType int) string {
|
||||||
var (
|
var (
|
||||||
errNaMode = errors.New("no mode for given slice and mb type")
|
errNaMode = errors.New("no mode for given slice and mb type")
|
||||||
errPartition = errors.New("partition must be 0")
|
errPartition = errors.New("partition must be 0")
|
||||||
|
errSliceType = errors.New("bad sliceType")
|
||||||
)
|
)
|
||||||
|
|
||||||
// MbPartPredMode returns a macroblock partition prediction mode for the given
|
// MbPartPredMode returns a macroblock partition prediction mode for the given
|
||||||
|
@ -111,8 +112,11 @@ func MbPartPredMode(data *SliceData, sliceType string, mbType, partition int) (m
|
||||||
if mbType > 0 && mbType < 25 {
|
if mbType > 0 && mbType < 25 {
|
||||||
return intra16x16, nil
|
return intra16x16, nil
|
||||||
}
|
}
|
||||||
return -1, errNaMode
|
return naMbPartPredMode, errNaMode
|
||||||
case "SI":
|
case "SI":
|
||||||
|
if mbType != 0 {
|
||||||
|
return naMbPartPredMode, errNaMode
|
||||||
|
}
|
||||||
return intra4x4, nil
|
return intra4x4, nil
|
||||||
case "P":
|
case "P":
|
||||||
fallthrough
|
fallthrough
|
||||||
|
@ -120,7 +124,7 @@ func MbPartPredMode(data *SliceData, sliceType string, mbType, partition int) (m
|
||||||
if mbType >= 0 && mbType < 3 {
|
if mbType >= 0 && mbType < 3 {
|
||||||
return predL0, nil
|
return predL0, nil
|
||||||
} else if mbType == 3 || mbType == 4 {
|
} else if mbType == 3 || mbType == 4 {
|
||||||
return -1, errNaMode
|
return naMbPartPredMode, errNaMode
|
||||||
} else {
|
} else {
|
||||||
return predL0, nil
|
return predL0, nil
|
||||||
}
|
}
|
||||||
|
@ -128,6 +132,8 @@ func MbPartPredMode(data *SliceData, sliceType string, mbType, partition int) (m
|
||||||
switch mbType {
|
switch mbType {
|
||||||
case 0:
|
case 0:
|
||||||
return direct, nil
|
return direct, nil
|
||||||
|
case 3:
|
||||||
|
return biPred, nil
|
||||||
case 1:
|
case 1:
|
||||||
fallthrough
|
fallthrough
|
||||||
case 4:
|
case 4:
|
||||||
|
@ -157,14 +163,16 @@ func MbPartPredMode(data *SliceData, sliceType string, mbType, partition int) (m
|
||||||
case 15:
|
case 15:
|
||||||
return predL1, nil
|
return predL1, nil
|
||||||
case 22:
|
case 22:
|
||||||
return -1, errNaMode
|
return naMbPartPredMode, errNaMode
|
||||||
default:
|
default:
|
||||||
if mbType > 15 && mbType < 22 {
|
if mbType > 15 && mbType < 22 {
|
||||||
return biPred, nil
|
return biPred, nil
|
||||||
}
|
}
|
||||||
return direct, nil
|
return direct, nil
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
return naMbPartPredMode, errSliceType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1, errPartition
|
return naMbPartPredMode, errPartition
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
NAME
|
||||||
|
parse.go
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
mbtype_test.go provides testing for functions provided in mbtype.go.
|
||||||
|
|
||||||
|
AUTHORS
|
||||||
|
Saxon Nelson-Milton <saxon@ausocean.org>, The Australian Ocean Laboratory (AusOcean)
|
||||||
|
*/
|
||||||
|
package h264
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMbPartPredMode(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
sliceType string
|
||||||
|
mbType int
|
||||||
|
data *SliceData
|
||||||
|
want mbPartPredMode
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
// Table 7-11 (I-slices).
|
||||||
|
0: {"I", 0, &SliceData{TransformSize8x8Flag: false}, intra4x4, nil},
|
||||||
|
1: {"I", 0, &SliceData{TransformSize8x8Flag: true}, intra8x8, nil},
|
||||||
|
2: {"I", 1, nil, intra16x16, nil},
|
||||||
|
3: {"I", 2, nil, intra16x16, nil},
|
||||||
|
4: {"I", 3, nil, intra16x16, nil},
|
||||||
|
5: {"I", 4, nil, intra16x16, nil},
|
||||||
|
6: {"I", 5, nil, intra16x16, nil},
|
||||||
|
7: {"I", 6, nil, intra16x16, nil},
|
||||||
|
8: {"I", 7, nil, intra16x16, nil},
|
||||||
|
9: {"I", 8, nil, intra16x16, nil},
|
||||||
|
10: {"I", 9, nil, intra16x16, nil},
|
||||||
|
11: {"I", 10, nil, intra16x16, nil},
|
||||||
|
12: {"I", 11, nil, intra16x16, nil},
|
||||||
|
13: {"I", 12, nil, intra16x16, nil},
|
||||||
|
14: {"I", 13, nil, intra16x16, nil},
|
||||||
|
15: {"I", 14, nil, intra16x16, nil},
|
||||||
|
16: {"I", 15, nil, intra16x16, nil},
|
||||||
|
17: {"I", 16, nil, intra16x16, nil},
|
||||||
|
18: {"I", 17, nil, intra16x16, nil},
|
||||||
|
19: {"I", 18, nil, intra16x16, nil},
|
||||||
|
20: {"I", 19, nil, intra16x16, nil},
|
||||||
|
21: {"I", 20, nil, intra16x16, nil},
|
||||||
|
22: {"I", 21, nil, intra16x16, nil},
|
||||||
|
23: {"I", 22, nil, intra16x16, nil},
|
||||||
|
24: {"I", 23, nil, intra16x16, nil},
|
||||||
|
25: {"I", 24, nil, intra16x16, nil},
|
||||||
|
26: {"I", 25, nil, naMbPartPredMode, errNaMode},
|
||||||
|
|
||||||
|
// Table 7-12 (SI-slices).
|
||||||
|
27: {"SI", 0, nil, intra4x4, nil},
|
||||||
|
|
||||||
|
// Table 7-13 (SP-slices).
|
||||||
|
28: {"SP", 0, nil, predL0, nil},
|
||||||
|
29: {"SP", 1, nil, predL0, nil},
|
||||||
|
30: {"SP", 2, nil, predL0, nil},
|
||||||
|
31: {"SP", 3, nil, naMbPartPredMode, errNaMode},
|
||||||
|
32: {"SP", 4, nil, naMbPartPredMode, errNaMode},
|
||||||
|
|
||||||
|
// Table 7-14 (B-slices).
|
||||||
|
33: {"B", 0, nil, direct, nil},
|
||||||
|
34: {"B", 1, nil, predL0, nil},
|
||||||
|
35: {"B", 2, nil, predL1, nil},
|
||||||
|
36: {"B", 3, nil, biPred, nil},
|
||||||
|
37: {"B", 4, nil, predL0, nil},
|
||||||
|
38: {"B", 5, nil, predL0, nil},
|
||||||
|
39: {"B", 6, nil, predL1, nil},
|
||||||
|
40: {"B", 7, nil, predL1, nil},
|
||||||
|
41: {"B", 8, nil, predL0, nil},
|
||||||
|
42: {"B", 9, nil, predL0, nil},
|
||||||
|
43: {"B", 10, nil, predL1, nil},
|
||||||
|
44: {"B", 11, nil, predL1, nil},
|
||||||
|
45: {"B", 12, nil, predL0, nil},
|
||||||
|
46: {"B", 13, nil, predL0, nil},
|
||||||
|
47: {"B", 14, nil, predL1, nil},
|
||||||
|
48: {"B", 15, nil, predL1, nil},
|
||||||
|
49: {"B", 16, nil, biPred, nil},
|
||||||
|
50: {"B", 17, nil, biPred, nil},
|
||||||
|
51: {"B", 18, nil, biPred, nil},
|
||||||
|
52: {"B", 19, nil, biPred, nil},
|
||||||
|
53: {"B", 20, nil, biPred, nil},
|
||||||
|
54: {"B", 21, nil, biPred, nil},
|
||||||
|
55: {"B", 22, nil, naMbPartPredMode, errNaMode},
|
||||||
|
|
||||||
|
// Test some weird cases where we expect error.
|
||||||
|
56: {"O", 0, nil, naMbPartPredMode, errSliceType},
|
||||||
|
57: {"I", 26, nil, naMbPartPredMode, errNaMode},
|
||||||
|
58: {"I", -1, nil, naMbPartPredMode, errNaMode},
|
||||||
|
59: {"SI", 1, nil, naMbPartPredMode, errNaMode},
|
||||||
|
|
||||||
|
// Cases for inferred mbtype.
|
||||||
|
60: {"SP", 5, nil, predL0, nil},
|
||||||
|
61: {"SP", -1, nil, predL0, nil},
|
||||||
|
62: {"B", -1, nil, direct, nil},
|
||||||
|
63: {"B", 23, nil, direct, nil},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, test := range tests {
|
||||||
|
m, err := MbPartPredMode(test.data, test.sliceType, test.mbType, 0)
|
||||||
|
if err != test.err {
|
||||||
|
t.Errorf("unexpected error from test %d.\nGot: %v\nWant: %v\n", i, err, test.err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if m != test.want {
|
||||||
|
t.Errorf("did not get expected result for test %d.\nGot: %v\nWant: %v\n", i, m, test.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,10 +16,12 @@ package h264
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/icza/bitio"
|
"github.com/ausocean/h264decode/h264/bits"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// mbPartPredMode represents a macroblock partition prediction mode.
|
||||||
|
// Modes are defined as consts below. These modes are in section 7.4.5.
|
||||||
type mbPartPredMode int8
|
type mbPartPredMode int8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -31,6 +33,7 @@ const (
|
||||||
direct
|
direct
|
||||||
biPred
|
biPred
|
||||||
inter
|
inter
|
||||||
|
naMbPartPredMode
|
||||||
)
|
)
|
||||||
|
|
||||||
// readUe parses a syntax element of ue(v) descriptor, i.e. an unsigned integer
|
// readUe parses a syntax element of ue(v) descriptor, i.e. an unsigned integer
|
||||||
|
@ -38,7 +41,7 @@ const (
|
||||||
//
|
//
|
||||||
// TODO: this should return uint, but rest of code needs to be changed for this
|
// TODO: this should return uint, but rest of code needs to be changed for this
|
||||||
// to happen.
|
// to happen.
|
||||||
func readUe(r bitio.Reader) (int, error) {
|
func readUe(r *bits.BitReader) (int, error) {
|
||||||
nZeros := -1
|
nZeros := -1
|
||||||
var err error
|
var err error
|
||||||
for b := uint64(0); b == 0; nZeros++ {
|
for b := uint64(0); b == 0; nZeros++ {
|
||||||
|
@ -47,7 +50,7 @@ func readUe(r bitio.Reader) (int, error) {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rem, err := r.ReadBits(byte(nZeros))
|
rem, err := r.ReadBits(int(nZeros))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -59,7 +62,7 @@ func readUe(r bitio.Reader) (int, error) {
|
||||||
// Rec. ITU-T H.264 (04/2017).
|
// Rec. ITU-T H.264 (04/2017).
|
||||||
//
|
//
|
||||||
// TODO: this should also return uint.
|
// TODO: this should also return uint.
|
||||||
func readTe(r bitio.Reader, x uint) (int, error) {
|
func readTe(r *bits.BitReader, x uint) (int, error) {
|
||||||
if x > 1 {
|
if x > 1 {
|
||||||
return readUe(r)
|
return readUe(r)
|
||||||
}
|
}
|
||||||
|
@ -83,7 +86,7 @@ var errReadTeBadX = errors.New("x must be more than or equal to 1")
|
||||||
// readSe parses a syntax element with descriptor se(v), i.e. a signed integer
|
// readSe parses a syntax element with descriptor se(v), i.e. a signed integer
|
||||||
// Exp-Golomb-coded syntax element, using the method described in sections
|
// Exp-Golomb-coded syntax element, using the method described in sections
|
||||||
// 9.1 and 9.1.1 in Rec. ITU-T H.264 (04/2017).
|
// 9.1 and 9.1.1 in Rec. ITU-T H.264 (04/2017).
|
||||||
func readSe(r bitio.Reader) (int, error) {
|
func readSe(r *bits.BitReader) (int, error) {
|
||||||
codeNum, err := readUe(r)
|
codeNum, err := readUe(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, errors.Wrap(err, "error reading ue(v)")
|
return 0, errors.Wrap(err, "error reading ue(v)")
|
||||||
|
@ -95,7 +98,7 @@ func readSe(r bitio.Reader) (int, error) {
|
||||||
// readMe parses a syntax element of me(v) descriptor, i.e. mapped
|
// readMe parses a syntax element of me(v) descriptor, i.e. mapped
|
||||||
// Exp-Golomb-coded element, using methods described in sections 9.1 and 9.1.2
|
// Exp-Golomb-coded element, using methods described in sections 9.1 and 9.1.2
|
||||||
// in Rec. ITU-T H.264 (04/2017).
|
// in Rec. ITU-T H.264 (04/2017).
|
||||||
func readMe(r bitio.Reader, chromaArrayType uint, mpm mbPartPredMode) (uint, error) {
|
func readMe(r *bits.BitReader, chromaArrayType uint, mpm mbPartPredMode) (uint, error) {
|
||||||
// Indexes to codedBlockPattern map.
|
// Indexes to codedBlockPattern map.
|
||||||
var i1, i2, i3 int
|
var i1, i2, i3 int
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/icza/bitio"
|
"github.com/ausocean/h264decode/h264/bits"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestReadUe checks that readUe correctly parses an Exp-Golomb-coded element
|
// TestReadUe checks that readUe correctly parses an Exp-Golomb-coded element
|
||||||
|
@ -41,7 +41,7 @@ func TestReadUe(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
got, err := readUe(bitio.NewReader(bytes.NewReader(test.in)))
|
got, err := readUe(bits.NewBitReader(bytes.NewReader(test.in)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("did not expect error: %v from readUe", err)
|
t.Fatalf("did not expect error: %v from readUe", err)
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ func TestReadTe(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
got, err := readTe(bitio.NewReader(bytes.NewReader(test.in)), test.x)
|
got, err := readTe(bits.NewBitReader(bytes.NewReader(test.in)), test.x)
|
||||||
if err != test.err {
|
if err != test.err {
|
||||||
t.Fatalf("did not get expected error for test: %v\nGot: %v\nWant: %v\n", i, err, test.err)
|
t.Fatalf("did not get expected error for test: %v\nGot: %v\nWant: %v\n", i, err, test.err)
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ func TestReadSe(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
got, err := readSe(bitio.NewReader(bytes.NewReader(test.in)))
|
got, err := readSe(bits.NewBitReader(bytes.NewReader(test.in)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("did not expect error: %v from readSe", err)
|
t.Fatalf("did not expect error: %v from readSe", err)
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ func TestReadMe(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
got, err := readMe(bitio.NewReader(bytes.NewReader(test.in)), test.cat, test.mpm)
|
got, err := readMe(bits.NewBitReader(bytes.NewReader(test.in)), test.cat, test.mpm)
|
||||||
if err != test.err {
|
if err != test.err {
|
||||||
t.Fatalf("did not expect to get error: %v for test: %v", err, i)
|
t.Fatalf("did not expect to get error: %v for test: %v", err, i)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue