/* NAME parse_test.go DESCRIPTION parse_test.go provides testing for parsing utilities provided in parse.go AUTHOR Saxon Nelson-Milton , The Australian Ocean Laboratory (AusOcean) */ package h264dec import ( "bytes" "testing" "bitbucket.org/ausocean/av/codec/h264/h264dec/bits" ) // TestReadUe checks that readUe correctly parses an Exp-Golomb-coded element // to a code number. func TestReadUe(t *testing.T) { // tests has been derived from Table 9-2 in ITU-T H.H264, showing bit strings // and corresponding codeNums. tests := []struct { in []byte // The bitstring we wish to read. want uint // The expected codeNum. }{ {[]byte{0x80}, 0}, // Bit string: 1, codeNum: 0 {[]byte{0x40}, 1}, // Bit string: 010, codeNum: 1 {[]byte{0x60}, 2}, // Bit string: 011, codeNum: 2 {[]byte{0x20}, 3}, // Bit string: 00100, codeNum: 3 {[]byte{0x28}, 4}, // Bit string: 00101, codeNum: 4 {[]byte{0x30}, 5}, // Bit string: 00110, codeNum: 5 {[]byte{0x38}, 6}, // Bit string: 00111, codeNum: 6 {[]byte{0x10}, 7}, // Bit string: 0001000, codeNum: 7 {[]byte{0x12}, 8}, // Bit string: 0001001, codeNum: 8 {[]byte{0x14}, 9}, // Bit string: 0001010, codeNum: 9 {[]byte{0x16}, 10}, // Bit string: 0001011, codeNum: 10 } for i, test := range tests { got, err := readUe(bits.NewBitReader(bytes.NewReader(test.in))) if err != nil { t.Fatalf("did not expect error: %v from readUe", err) } if test.want != uint(got) { t.Errorf("did not get expected result for test: %v\nGot: %v\nWant: %v\n", i, got, test.want) } } } // TestReadTe checks that readTe correctly parses a truncated Exp-Golomb-coded // syntax element. Expected results are outlined in section 9.1 pg209 Rec ITU-T // H.264 (04/2017) func TestReadTe(t *testing.T) { tests := []struct { in []byte // The bitstring we will read. x uint // The upper bound of the range. want uint // Expected result from readTe. err error // Expected error from readTe. }{ {[]byte{0x30}, 1, 1, nil}, {[]byte{0x80}, 1, 0, nil}, {[]byte{0x30}, 5, 5, nil}, {[]byte{0x30}, 0, 0, errReadTeBadX}, } for i, test := range tests { 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) } if test.want != uint(got) { t.Errorf("did not get expected result for test: %v\nGot: %v\nWant: %v\n", i, got, test.want) } } } // TestReadSe checks that readSe correctly parses an se(v) signed integer // Exp-Golomb-coded syntax element. Expected behaviour is found in section 9.1 // and 9.1.1 of the Rec. ITU-T H.264(04/2017). func TestReadSe(t *testing.T) { // tests has been derived from table 9-3 of the specifications. tests := []struct { in []byte // Bitstring to read. want int // Expected value from se(v) parsing process. }{ {[]byte{0x80}, 0}, // Bit string: 1, codeNum: 0, syntax element val: 0 {[]byte{0x40}, 1}, // Bit string: 010, codeNum: 1, syntax element val: 1 {[]byte{0x60}, -1}, // Bit string: 011, codeNum: 2, syntax element val: -1 {[]byte{0x20}, 2}, // Bit string: 00100, codeNum: 3, syntax element val: 2 {[]byte{0x28}, -2}, // Bit string: 00101, codeNum: 4, syntax element val: -2 {[]byte{0x30}, 3}, // Bit string: 00110, codeNum: 5, syntax element val: 3 {[]byte{0x38}, -3}, // Bit string: 00111, codeNum: 6, syntax element val: -3 } for i, test := range tests { got, err := readSe(bits.NewBitReader(bytes.NewReader(test.in))) if err != nil { t.Fatalf("did not expect error: %v from readSe", err) } if test.want != got { t.Errorf("did not get expected result for test: %v\nGot: %v\nWant: %v\n", i, got, test.want) } } } // TestReadMe checks that readMe correctly parses a me(v) mapped // Exp-Golomb-coded element. Expected behaviour is described in in sections 9.1 // and 9.1.2 in Rec. ITU-T H.264 (04/2017). func TestReadMe(t *testing.T) { in := []byte{0x38} // Bit string: 00111, codeNum: 6. inErr := []byte{0x07, 0xe0} // Bit string: 0000 0111 111, codeNum: 62 (will give invalid codeNum err) tests := []struct { in []byte // Input data. cat uint // Chroma array.. mpm mbPartPredMode want uint // Expected result from readMe. err error // Expected value of err from readMe. }{ {in, 1, intra4x4, 29, nil}, {in, 1, intra8x8, 29, nil}, {in, 1, inter, 32, nil}, {in, 2, intra4x4, 29, nil}, {in, 2, intra8x8, 29, nil}, {in, 2, inter, 32, nil}, {in, 0, intra4x4, 3, nil}, {in, 0, intra8x8, 3, nil}, {in, 0, inter, 5, nil}, {in, 3, intra4x4, 3, nil}, {in, 3, intra8x8, 3, nil}, {in, 3, inter, 5, nil}, {inErr, 1, intra4x4, 0, errInvalidCodeNum}, {in, 4, intra4x4, 0, errInvalidCAT}, {in, 0, 4, 0, errInvalidMPM}, } for i, test := range tests { 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) } if test.want != got { t.Errorf("did not get expected result for test: %v\nGot: %v\nWant: %v\n", i, got, test.want) } } }