codec/h264/h264dec: using const string instead of CSV file to hold table 9-5. Also made some other minor improvements

This commit is contained in:
Saxon 2019-09-07 22:13:38 +09:30
parent 92eb3e85a5
commit 42a1918c0d
3 changed files with 156 additions and 160 deletions

View File

@ -29,32 +29,13 @@ import (
"encoding/csv" "encoding/csv"
"errors" "errors"
"fmt" "fmt"
"os"
"strconv" "strconv"
"strings"
"bitbucket.org/ausocean/av/codec/h264/h264dec/bits" "bitbucket.org/ausocean/av/codec/h264/h264dec/bits"
) )
// Initialize the CAVLC coeff_token mapping table. // TODO: find where these are defined in the specifications.
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))
}
}
const ( const (
chromaDCLevel = iota chromaDCLevel = iota
intra16x16DCLevel intra16x16DCLevel
@ -68,6 +49,93 @@ const (
crLevel4x4 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. // TODO: put this somewhere more appropriate once context is understood.
type block struct { type block struct {
usingInterMbPredMode bool usingInterMbPredMode bool
@ -243,80 +311,6 @@ func available(b block) bool {
return true 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 // parseLevelPrefix parses the level_prefix variable as specified by the process
// outlined in section 9.2.2.1 in the specifications. // outlined in section 9.2.2.1 in the specifications.
func parseLevelPrefix(br *bits.BitReader) (int, error) { func parseLevelPrefix(br *bits.BitReader) (int, error) {

View File

@ -35,14 +35,14 @@ import (
func TestFormCoeffTokenMap(t *testing.T) { func TestFormCoeffTokenMap(t *testing.T) {
tests := []struct { tests := []struct {
in [][]string in [][]string
want [nColumns]map[int]map[int][2]int want [nColumns]tokenMap
}{ }{
{ {
in: [][]string{ in: [][]string{
{"0", "0", "1", "11", "1111", "0000 11", "01", "1"}, {"0", "0", "1", "11", "1111", "0000 11", "01", "1"},
{"0", "1", "0001 01", "0010 11", "0011 11", "0000 00", "0001 11", "0001 111"}, {"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: {
0: {1: {0, 0}}, 0: {1: {0, 0}},
3: {5: {0, 1}}, 3: {5: {0, 1}},
@ -74,7 +74,7 @@ func TestFormCoeffTokenMap(t *testing.T) {
{"0", "0", "1", "11", "1111", "0000 11", "01", "1"}, {"0", "0", "1", "11", "1111", "0000 11", "01", "1"},
{"0", "1", "0001 01", "0010 11", "0011 11", "-", "0001 11", "0001 111"}, {"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: {
0: {1: {0, 0}}, 0: {1: {0, 0}},
3: {5: {0, 1}}, 3: {5: {0, 1}},

View File

@ -1,4 +1,6 @@
0,0,1,11,1111,0000 11,01,1 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 0,1,0001 01,0010 11,0011 11,0000 00,0001 11,0001 111
1,1,01,10,1110,0000 01,1,01 1,1,01,10,1110,0000 01,1,01
0,2,0000 0111,0001 11,0010 11,0001 00,0001 00,0001 110 0,2,0000 0111,0001 11,0010 11,0001 00,0001 00,0001 110
@ -59,4 +61,4 @@
0,16,0000 0000 0000 0100,0000 0000 0001 11,0000 0000 01,1111 00,-,- 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,-,- 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,-,- 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,-,- 3,16,0000 0000 0000 1000,0000 0000 0001 00,0000 0000 10,1111 11,-,-`