mirror of https://bitbucket.org/ausocean/av.git
Merged in fix-merge (pull request #213)
codec/h264/decode: did not copy over most up to date version from old repo, so fixing that
This commit is contained in:
commit
8a7a89d5a3
|
@ -1,3 +0,0 @@
|
|||
.*.swp
|
||||
*.mp4
|
||||
*.h264
|
|
@ -93,6 +93,7 @@ func MbTypeName(sliceType string, mbType int) string {
|
|||
var (
|
||||
errNaMode = errors.New("no mode for given slice and mb type")
|
||||
errPartition = errors.New("partition must be 0")
|
||||
errSliceType = errors.New("bad sliceType")
|
||||
)
|
||||
|
||||
// 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 {
|
||||
return intra16x16, nil
|
||||
}
|
||||
return -1, errNaMode
|
||||
return naMbPartPredMode, errNaMode
|
||||
case "SI":
|
||||
if mbType != 0 {
|
||||
return naMbPartPredMode, errNaMode
|
||||
}
|
||||
return intra4x4, nil
|
||||
case "P":
|
||||
fallthrough
|
||||
|
@ -120,7 +124,7 @@ func MbPartPredMode(data *SliceData, sliceType string, mbType, partition int) (m
|
|||
if mbType >= 0 && mbType < 3 {
|
||||
return predL0, nil
|
||||
} else if mbType == 3 || mbType == 4 {
|
||||
return -1, errNaMode
|
||||
return naMbPartPredMode, errNaMode
|
||||
} else {
|
||||
return predL0, nil
|
||||
}
|
||||
|
@ -128,6 +132,8 @@ func MbPartPredMode(data *SliceData, sliceType string, mbType, partition int) (m
|
|||
switch mbType {
|
||||
case 0:
|
||||
return direct, nil
|
||||
case 3:
|
||||
return biPred, nil
|
||||
case 1:
|
||||
fallthrough
|
||||
case 4:
|
||||
|
@ -157,14 +163,16 @@ func MbPartPredMode(data *SliceData, sliceType string, mbType, partition int) (m
|
|||
case 15:
|
||||
return predL1, nil
|
||||
case 22:
|
||||
return -1, errNaMode
|
||||
return naMbPartPredMode, errNaMode
|
||||
default:
|
||||
if mbType > 15 && mbType < 22 {
|
||||
return biPred, 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 (
|
||||
"math"
|
||||
|
||||
"github.com/icza/bitio"
|
||||
"github.com/ausocean/h264decode/h264/bits"
|
||||
"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
|
||||
|
||||
const (
|
||||
|
@ -31,6 +33,7 @@ const (
|
|||
direct
|
||||
biPred
|
||||
inter
|
||||
naMbPartPredMode
|
||||
)
|
||||
|
||||
// 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
|
||||
// to happen.
|
||||
func readUe(r bitio.Reader) (int, error) {
|
||||
func readUe(r *bits.BitReader) (int, error) {
|
||||
nZeros := -1
|
||||
var err error
|
||||
for b := uint64(0); b == 0; nZeros++ {
|
||||
|
@ -47,7 +50,7 @@ func readUe(r bitio.Reader) (int, error) {
|
|||
return 0, err
|
||||
}
|
||||
}
|
||||
rem, err := r.ReadBits(byte(nZeros))
|
||||
rem, err := r.ReadBits(int(nZeros))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -59,7 +62,7 @@ func readUe(r bitio.Reader) (int, error) {
|
|||
// Rec. ITU-T H.264 (04/2017).
|
||||
//
|
||||
// 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 {
|
||||
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
|
||||
// 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).
|
||||
func readSe(r bitio.Reader) (int, error) {
|
||||
func readSe(r *bits.BitReader) (int, error) {
|
||||
codeNum, err := readUe(r)
|
||||
if err != nil {
|
||||
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
|
||||
// Exp-Golomb-coded element, using methods described in sections 9.1 and 9.1.2
|
||||
// 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.
|
||||
var i1, i2, i3 int
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/icza/bitio"
|
||||
"github.com/ausocean/h264decode/h264/bits"
|
||||
)
|
||||
|
||||
// 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 {
|
||||
got, err := readUe(bitio.NewReader(bytes.NewReader(test.in)))
|
||||
got, err := readUe(bits.NewBitReader(bytes.NewReader(test.in)))
|
||||
if err != nil {
|
||||
t.Fatalf("did not expect error: %v from readUe", err)
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ func TestReadTe(t *testing.T) {
|
|||
}
|
||||
|
||||
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 {
|
||||
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 {
|
||||
got, err := readSe(bitio.NewReader(bytes.NewReader(test.in)))
|
||||
got, err := readSe(bits.NewBitReader(bytes.NewReader(test.in)))
|
||||
if err != nil {
|
||||
t.Fatalf("did not expect error: %v from readSe", err)
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ func TestReadMe(t *testing.T) {
|
|||
}
|
||||
|
||||
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 {
|
||||
t.Fatalf("did not expect to get error: %v for test: %v", err, i)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue