From 42a1918c0db4890e162e111b88833dd4246c0a77 Mon Sep 17 00:00:00 2001 From: Saxon Date: Sat, 7 Sep 2019 22:13:38 +0930 Subject: [PATCH] codec/h264/h264dec: using const string instead of CSV file to hold table 9-5. Also made some other minor improvements --- codec/h264/h264dec/cavlc.go | 184 +++++++++--------- codec/h264/h264dec/cavlc_test.go | 6 +- .../{coefftokenmap.csv => cavlctab.go} | 126 ++++++------ 3 files changed, 156 insertions(+), 160 deletions(-) rename codec/h264/h264dec/{coefftokenmap.csv => cavlctab.go} (97%) diff --git a/codec/h264/h264dec/cavlc.go b/codec/h264/h264dec/cavlc.go index b3d276d6..58464502 100644 --- a/codec/h264/h264dec/cavlc.go +++ b/codec/h264/h264dec/cavlc.go @@ -29,32 +29,13 @@ import ( "encoding/csv" "errors" "fmt" - "os" "strconv" + "strings" "bitbucket.org/ausocean/av/codec/h264/h264dec/bits" ) -// Initialize the CAVLC coeff_token mapping table. -func init() { - const file = "coefftokenmap.csv" - f, err := os.Open(file) - if err != nil { - panic(fmt.Sprintf("could not open coefftokenmap.csv file, failed with error: %v", err)) - } - defer f.Close() - - lines, err := csv.NewReader(f).ReadAll() - if err != nil { - panic(fmt.Sprintf("could not read lines from coeftokenmap.csv file, failed with error: %v", err)) - } - - coeffTokenMaps, err = formCoeffTokenMap(lines) - if err != nil { - panic(fmt.Sprintf("could not form coeff_token map, failed with err: %v", err)) - } -} - +// TODO: find where these are defined in the specifications. const ( chromaDCLevel = iota intra16x16DCLevel @@ -68,6 +49,93 @@ const ( crLevel4x4 ) +// Initialize the CAVLC coeff_token mapping table. +func init() { + lines, err := csv.NewReader(strings.NewReader(coeffTokenTable)).ReadAll() + if err != nil { + panic(fmt.Sprintf("could not read lines from coeftokenmap.csv file, failed with error: %v", err)) + } + + coeffTokenMaps, err = formCoeffTokenMap(lines) + if err != nil { + panic(fmt.Sprintf("could not form coeff_token map, failed with err: %v", err)) + } +} + +// tokenMap maps coeff_token to values of TrailingOnes(coeff_token) and +// TotalCoeff(coeff_token) given as tokenMap[ number of leading zeros in +// coeff_token][ coeff_token val ][ 0 for trailing ones and 1 for totalCoef ] +type tokenMap map[int]map[int][2]int + +// The number of columns in the coeffTokenMap defined below. This is +// representative of the number of defined nC ranges in table 9-5. +const nColumns = 6 + +// coeffTokenMaps holds a representation of table 9-5 from the specifications, and +// is indexed as follows, coeffToken[ nC group ][ number of coeff_token leading +// zeros ][ value of coeff_token ][ 0 for TrailingOnes(coeff_token) and 1 for +// TotalCoef(coeff_token) ]. +var coeffTokenMaps [nColumns]tokenMap + +// formCoeffTokenMap populates the global [nColumns]tokenMap coeffTokenMaps +// representation of table 9-5 in the specifications using the coeffTokenTable +// const string defined in cavlctab.go. +func formCoeffTokenMap(lines [][]string) ([nColumns]tokenMap, error) { + var maps [nColumns]tokenMap + + for i := range maps { + maps[i] = make(tokenMap) + } + + for _, line := range lines { + trailingOnes, err := strconv.Atoi(line[0]) + if err != nil { + return maps, fmt.Errorf("could not convert trailingOnes string to int, failed with error: %v", err) + } + + totalCoeff, err := strconv.Atoi(line[1]) + if err != nil { + return maps, fmt.Errorf("could not convert totalCoeff string to int, failed with error: %v", err) + } + + // For each column in this row, therefore each nC category, load the + // coeff_token leading zeros and value into the map. + for j, v := range line[2:] { + if v[0] == '-' { + continue + } + + // Count the leading zeros. + var nZeros int + for _, c := range v { + if c == ' ' { + continue + } + + if c == '0' { + nZeros++ + continue + } + break + } + + // This will be the value of the coeff_token (without leading zeros). + val, err := binToInt(v[nZeros:]) + if err != nil { + return maps, fmt.Errorf("could not get value of remaining binary, failed with error: %v", err) + } + + // Add the TrailingOnes(coeff_token) and TotalCoeff(coeff_token) values + // into the map for the coeff_token leading zeros and value. + if maps[j][nZeros] == nil { + maps[j][nZeros] = make(map[int][2]int) + } + maps[j][nZeros][val] = [2]int{trailingOnes, totalCoeff} + } + } + return maps, nil +} + // TODO: put this somewhere more appropriate once context is understood. type block struct { usingInterMbPredMode bool @@ -243,80 +311,6 @@ func available(b block) bool { return true } -// The number of columns in the coeffTokenMap defined below. This is -// representative of the number of defined nC ranges defined in table 9-5. -const nColumns = 6 - -// coeffMapping maps values of coeff_token to values of TrailingOnes(coeff_token) -// and TotalCoeff(coeff_token) given as map[ coeff_token val ][ 0 for trailing ones -// and 1 for totalCoef ] -type tokenMap map[int]map[int][2]int - -// coeffTokenMap will a representation of table 9-5 from the specifications, and -// is indexed as follows, coeffToken[ nC group ][ number of coeff_token leading -// zeros ][ value of coeff_token ][ 0 for TrailingOnes(coeff_token) and 1 for -// TotalCoef(coeff_token) ]. -var coeffTokenMaps [nColumns]tokenMap - -// formCoeffTokenMap populates the global [nColumns]map[int]map[int][2]int, -// coeffTokenMap representation of table 9-5 from the specifications using lines -// read from a corresponding CSV file coefftokenmap.csv. -func formCoeffTokenMap(lines [][]string) ([nColumns]tokenMap, error) { - var maps [nColumns]tokenMap - - for i := range maps { - maps[i] = make(tokenMap) - } - - for _, line := range lines { - trailingOnes, err := strconv.Atoi(line[0]) - if err != nil { - return maps, fmt.Errorf("could not convert trailingOnes string to int, failed with error: %v", err) - } - - totalCoeff, err := strconv.Atoi(line[1]) - if err != nil { - return maps, fmt.Errorf("could not convert totalCoeff string to int, failed with error: %v", err) - } - - // For each column in this row, therefore each nC category, load the - // coeff_token leading zeros and value into the map. - for j, v := range line[2:] { - if v[0] == '-' { - continue - } - - // Count the leading zeros. - var nZeros int - for _, c := range v { - if c == ' ' { - continue - } - - if c == '0' { - nZeros++ - continue - } - break - } - - // This will be the value of the coeff_token (without leading zeros). - val, err := binToInt(v[nZeros:]) - if err != nil { - return maps, fmt.Errorf("could not get value of remaining binary, failed with error: %v", err) - } - - // Add the TrailingOnes(coeff_token) and TotalCoeff(coeff_token) values - // into the map for the coeff_token leading zeros and value. - if maps[j][nZeros] == nil { - maps[j][nZeros] = make(map[int][2]int) - } - maps[j][nZeros][val] = [2]int{trailingOnes, totalCoeff} - } - } - return maps, nil -} - // parseLevelPrefix parses the level_prefix variable as specified by the process // outlined in section 9.2.2.1 in the specifications. func parseLevelPrefix(br *bits.BitReader) (int, error) { diff --git a/codec/h264/h264dec/cavlc_test.go b/codec/h264/h264dec/cavlc_test.go index 28ab3e95..0abccbac 100644 --- a/codec/h264/h264dec/cavlc_test.go +++ b/codec/h264/h264dec/cavlc_test.go @@ -35,14 +35,14 @@ import ( func TestFormCoeffTokenMap(t *testing.T) { tests := []struct { in [][]string - want [nColumns]map[int]map[int][2]int + want [nColumns]tokenMap }{ { in: [][]string{ {"0", "0", "1", "11", "1111", "0000 11", "01", "1"}, {"0", "1", "0001 01", "0010 11", "0011 11", "0000 00", "0001 11", "0001 111"}, }, - want: [nColumns]map[int]map[int][2]int{ + want: [nColumns]tokenMap{ 0: { 0: {1: {0, 0}}, 3: {5: {0, 1}}, @@ -74,7 +74,7 @@ func TestFormCoeffTokenMap(t *testing.T) { {"0", "0", "1", "11", "1111", "0000 11", "01", "1"}, {"0", "1", "0001 01", "0010 11", "0011 11", "-", "0001 11", "0001 111"}, }, - want: [nColumns]map[int]map[int][2]int{ + want: [nColumns]tokenMap{ 0: { 0: {1: {0, 0}}, 3: {5: {0, 1}}, diff --git a/codec/h264/h264dec/coefftokenmap.csv b/codec/h264/h264dec/cavlctab.go similarity index 97% rename from codec/h264/h264dec/coefftokenmap.csv rename to codec/h264/h264dec/cavlctab.go index e558c1a5..7bbf01d5 100644 --- a/codec/h264/h264dec/coefftokenmap.csv +++ b/codec/h264/h264dec/cavlctab.go @@ -1,62 +1,64 @@ -0,0,1,11,1111,0000 11,01,1 -0,1,0001 01,0010 11,0011 11,0000 00,0001 11,0001 111 -1,1,01,10,1110,0000 01,1,01 -0,2,0000 0111,0001 11,0010 11,0001 00,0001 00,0001 110 -1,2,0001 00,0011 1,0111 1,0001 01,0001 10,0001 101 -2,2,001,011,1101,0001 10,001,001 -0,3,0000 0011 1,0000 111,0010 00,0010 00,0000 11,0000 0011 1 -1,3,0000 0110,0010 10,0110 0,0010 01,0000 011,0001 100 -2,3,0000 101,0010 01,0111 0,0010 10,0000 010,0001 011 -3,3,0001 1,0101,1100,0010 11,0001 01,0000 1 -0,4,0000 0001 11,0000 0111,0001 111,0011 00,0000 10,0000 0011 0 -1,4,0000 0011 0,0001 10,0101 0,0011 01,0000 0011,0000 0010 1 -2,4,0000 0101,0001 01,0101 1,0011 10,0000 0010,0001 010 -3,4,0000 11,0100,1011,0011 11,0000 000,0000 01 -0,5,0000 0000 111,0000 0100,0001 011,0100 00,-,0000 0001 11 -1,5,0000 0001 10,0000 110,0100 0,0100 01,-,0000 0001 10 -2,5,0000 0010 1,0000 101,0100 1,0100 10,-,0000 0010 0 -3,5,0000 100,0011 0,1010,0100 11,-,0001 001 -0,6,0000 0000 0111 1,0000 0011 1,0001 001,0101 00,-,0000 0000 111 -1,6,0000 0000 110,0000 0110,0011 10,0101 01,-,0000 0000 110 -2,6,0000 0001 01,0000 0101,0011 01,0101 10,-,0000 0001 01 -3,6,0000 0100,0010 00,1001,0101 11,-,0001 000 -0,7,0000 0000 0101 1,0000 0001 111,0001 000,0110 00,-,0000 0000 0111 -1,7,0000 0000 0111 0,0000 0011 0,0010 10,0110 01,-,0000 0000 0110 -2,7,0000 0000 101,0000 0010 1,0010 01,0110 10,-,0000 0000 101 -3,7,0000 0010 0,0001 00,1000,0110 11,-,0000 0001 00 -0,8,0000 0000 0100 0,0000 0001 011,0000 1111,0111 00,-,0000 0000 0011 1 -1,8,0000 0000 0101 0,0000 0001 110,0001 110,0111 01,-,0000 0000 0101 -2,8,0000 0000 0110 1,0000 0001 101,0001 101,0111 10,-,0000 0000 0100 -3,8,0000 0001 00,0000 100,0110 1,0111 11,-,0000 0000 100 -0,9,0000 0000 0011 11,0000 0000 1111,0000 1011,1000 00,-,- -1,9,0000 0000 0011 10,0000 0001 010,0000 1110,1000 01,-,- -2,9,0000 0000 0100 1,0000 0001 001,0001 010,1000 10,-,- -3,9,0000 0000 100,0000 0010 0,0011 00,1000 11,-,- -0,10,0000 0000 0010 11,0000 0000 1011,0000 0111 1,1001 00,-,- -1,10,0000 0000 0010 10,0000 0000 1110,0000 1010,1001 01,-,- -2,10,0000 0000 0011 01,0000 0000 1101,0000 1101,1001 10,-,- -3,10,0000 0000 0110 0,0000 0001 100,0001 100,1001 11,-,- -0,11,0000 0000 0001 111,0000 0000 1000,0000 0101 1,1010 00,-,- -1,11,0000 0000 0001 110,0000 0000 1010,0000 0111 0,1010 01,-,- -2,11,0000 0000 0010 01,0000 0000 1001,0000 1001,1010 10,-,- -3,11,0000 0000 0011 00,0000 0001 000,0000 1100,1010 11,-,- -0,12,0000 0000 0001 011,0000 0000 0111 1,0000 0100 0,1011 00,-,- -1,12,0000 0000 0001 010,0000 0000 0111 0,0000 0101 0,1011 01,-,- -2,12,0000 0000 0001 101,0000 0000 0110 1,0000 0110 1,1011 10,-,- -3,12,0000 0000 0010 00,0000 0000 1100,0000 1000,1011 11,-,- -0,13,0000 0000 0000 1111,0000 0000 0101 1,0000 0011 01,1100 00,-,- -1,13,0000 0000 0000 001,0000 0000 0101 0,0000 0011 1,1100 01,-,- -2,13,0000 0000 0001 001,0000 0000 0100 1,0000 0100 1,1100 10,-,- -3,13,0000 0000 0001 100,0000 0000 0110 0,0000 0110 0,1100 11,-,- -0,14,0000 0000 0000 1011,0000 0000 0011 1,0000 0010 01,1101 00,-,- -1,14,0000 0000 0000 1110,0000 0000 0010 11,0000 0011 00,1101 01,-,- -2,14,0000 0000 0000 1101,0000 0000 0011 0,0000 0010 11,1101 10,-,- -3,14,0000 0000 0001 000,0000 0000 0100 0,0000 0010 10,1101 11,-,- -0,15,0000 0000 0000 0111,0000 0000 0010 01,0000 0001 01,1110 00,-,- -1,15,0000 0000 0000 1010,0000 0000 0010 00,0000 0010 00,1110 01,-,- -2,15,0000 0000 0000 1001,0000 0000 0010 10,0000 0001 11,1110 10,-,- -3,15,0000 0000 0000 1100,0000 0000 0000 1,0000 0001 10,1110 11,-,- -0,16,0000 0000 0000 0100,0000 0000 0001 11,0000 0000 01,1111 00,-,- -1,16,0000 0000 0000 0110,0000 0000 0001 10,0000 0001 00,1111 01,-,- -2,16,0000 0000 0000 0101,0000 0000 0001 01,0000 0000 11,1111 10,-,- -3,16,0000 0000 0000 1000,0000 0000 0001 00,0000 0000 10,1111 11,-,- +package h264dec + +const coeffTokenTable = `0,0,1,11,1111,0000 11,01,1 +0,1,0001 01,0010 11,0011 11,0000 00,0001 11,0001 111 +1,1,01,10,1110,0000 01,1,01 +0,2,0000 0111,0001 11,0010 11,0001 00,0001 00,0001 110 +1,2,0001 00,0011 1,0111 1,0001 01,0001 10,0001 101 +2,2,001,011,1101,0001 10,001,001 +0,3,0000 0011 1,0000 111,0010 00,0010 00,0000 11,0000 0011 1 +1,3,0000 0110,0010 10,0110 0,0010 01,0000 011,0001 100 +2,3,0000 101,0010 01,0111 0,0010 10,0000 010,0001 011 +3,3,0001 1,0101,1100,0010 11,0001 01,0000 1 +0,4,0000 0001 11,0000 0111,0001 111,0011 00,0000 10,0000 0011 0 +1,4,0000 0011 0,0001 10,0101 0,0011 01,0000 0011,0000 0010 1 +2,4,0000 0101,0001 01,0101 1,0011 10,0000 0010,0001 010 +3,4,0000 11,0100,1011,0011 11,0000 000,0000 01 +0,5,0000 0000 111,0000 0100,0001 011,0100 00,-,0000 0001 11 +1,5,0000 0001 10,0000 110,0100 0,0100 01,-,0000 0001 10 +2,5,0000 0010 1,0000 101,0100 1,0100 10,-,0000 0010 0 +3,5,0000 100,0011 0,1010,0100 11,-,0001 001 +0,6,0000 0000 0111 1,0000 0011 1,0001 001,0101 00,-,0000 0000 111 +1,6,0000 0000 110,0000 0110,0011 10,0101 01,-,0000 0000 110 +2,6,0000 0001 01,0000 0101,0011 01,0101 10,-,0000 0001 01 +3,6,0000 0100,0010 00,1001,0101 11,-,0001 000 +0,7,0000 0000 0101 1,0000 0001 111,0001 000,0110 00,-,0000 0000 0111 +1,7,0000 0000 0111 0,0000 0011 0,0010 10,0110 01,-,0000 0000 0110 +2,7,0000 0000 101,0000 0010 1,0010 01,0110 10,-,0000 0000 101 +3,7,0000 0010 0,0001 00,1000,0110 11,-,0000 0001 00 +0,8,0000 0000 0100 0,0000 0001 011,0000 1111,0111 00,-,0000 0000 0011 1 +1,8,0000 0000 0101 0,0000 0001 110,0001 110,0111 01,-,0000 0000 0101 +2,8,0000 0000 0110 1,0000 0001 101,0001 101,0111 10,-,0000 0000 0100 +3,8,0000 0001 00,0000 100,0110 1,0111 11,-,0000 0000 100 +0,9,0000 0000 0011 11,0000 0000 1111,0000 1011,1000 00,-,- +1,9,0000 0000 0011 10,0000 0001 010,0000 1110,1000 01,-,- +2,9,0000 0000 0100 1,0000 0001 001,0001 010,1000 10,-,- +3,9,0000 0000 100,0000 0010 0,0011 00,1000 11,-,- +0,10,0000 0000 0010 11,0000 0000 1011,0000 0111 1,1001 00,-,- +1,10,0000 0000 0010 10,0000 0000 1110,0000 1010,1001 01,-,- +2,10,0000 0000 0011 01,0000 0000 1101,0000 1101,1001 10,-,- +3,10,0000 0000 0110 0,0000 0001 100,0001 100,1001 11,-,- +0,11,0000 0000 0001 111,0000 0000 1000,0000 0101 1,1010 00,-,- +1,11,0000 0000 0001 110,0000 0000 1010,0000 0111 0,1010 01,-,- +2,11,0000 0000 0010 01,0000 0000 1001,0000 1001,1010 10,-,- +3,11,0000 0000 0011 00,0000 0001 000,0000 1100,1010 11,-,- +0,12,0000 0000 0001 011,0000 0000 0111 1,0000 0100 0,1011 00,-,- +1,12,0000 0000 0001 010,0000 0000 0111 0,0000 0101 0,1011 01,-,- +2,12,0000 0000 0001 101,0000 0000 0110 1,0000 0110 1,1011 10,-,- +3,12,0000 0000 0010 00,0000 0000 1100,0000 1000,1011 11,-,- +0,13,0000 0000 0000 1111,0000 0000 0101 1,0000 0011 01,1100 00,-,- +1,13,0000 0000 0000 001,0000 0000 0101 0,0000 0011 1,1100 01,-,- +2,13,0000 0000 0001 001,0000 0000 0100 1,0000 0100 1,1100 10,-,- +3,13,0000 0000 0001 100,0000 0000 0110 0,0000 0110 0,1100 11,-,- +0,14,0000 0000 0000 1011,0000 0000 0011 1,0000 0010 01,1101 00,-,- +1,14,0000 0000 0000 1110,0000 0000 0010 11,0000 0011 00,1101 01,-,- +2,14,0000 0000 0000 1101,0000 0000 0011 0,0000 0010 11,1101 10,-,- +3,14,0000 0000 0001 000,0000 0000 0100 0,0000 0010 10,1101 11,-,- +0,15,0000 0000 0000 0111,0000 0000 0010 01,0000 0001 01,1110 00,-,- +1,15,0000 0000 0000 1010,0000 0000 0010 00,0000 0010 00,1110 01,-,- +2,15,0000 0000 0000 1001,0000 0000 0010 10,0000 0001 11,1110 10,-,- +3,15,0000 0000 0000 1100,0000 0000 0000 1,0000 0001 10,1110 11,-,- +0,16,0000 0000 0000 0100,0000 0000 0001 11,0000 0000 01,1111 00,-,- +1,16,0000 0000 0000 0110,0000 0000 0001 10,0000 0001 00,1111 01,-,- +2,16,0000 0000 0000 0101,0000 0000 0001 01,0000 0000 11,1111 10,-,- +3,16,0000 0000 0000 1000,0000 0000 0001 00,0000 0000 10,1111 11,-,-`