From ce803ba4883c7f7b668c363ec9aacc072f010579 Mon Sep 17 00:00:00 2001 From: Saxon Date: Fri, 6 Sep 2019 17:45:23 +0930 Subject: [PATCH 1/3] codec/h264/h264dec: add function for parsing level information using process in section 9.2.2 of specifications --- codec/h264/h264dec/cavlc.go | 91 +++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/codec/h264/h264dec/cavlc.go b/codec/h264/h264dec/cavlc.go index c477a490..0dcbc64b 100644 --- a/codec/h264/h264dec/cavlc.go +++ b/codec/h264/h264dec/cavlc.go @@ -26,6 +26,7 @@ LICENSE package h264dec import ( + "errors" "fmt" "bitbucket.org/ausocean/av/codec/h264/h264dec/bits" @@ -44,3 +45,93 @@ func parseLevelPrefix(br *bits.BitReader) (int, error) { } return zeros, nil } + +// parseLevelInformation parses level information and returns the resultant +// levelVal list using the process defined by section 9.2.2 in the specifications. +func parseLevelInformation(br *bits.BitReader, totalCoeff, trailingOnes int) ([]int, error) { + var levelVal []int + var i int + if trailingOnes != 0 { + for ; i < trailingOnes; i++ { + b, err := br.ReadBits(1) + if err != nil { + return nil, fmt.Errorf("could not read trailing_ones_sign_flag, failed with error: %v", err) + } + if b == 0 { + levelVal = append(levelVal, 1) + continue + } + levelVal = append(levelVal, -1) + } + } + + var suffixLen int + switch { + case totalCoeff > 10 && trailingOnes < 3: + suffixLen = 1 + case totalCoeff <= 10 || trailingOnes == 3: + suffixLen = 0 + default: + return nil, errors.New("invalid TotalCoeff and TrailingOnes combination") + } + + if totalCoeff-trailingOnes != 0 { + for j := 0; j < totalCoeff-trailingOnes; j++ { + levelPrefix, err := parseLevelPrefix(br) + if err != nil { + return nil, fmt.Errorf("could not parse level prefix, failed with error: %v", err) + } + + var levelSuffixSize int + switch { + case levelPrefix == 14 && suffixLen == 0: + levelSuffixSize = 4 + case levelPrefix >= 15: + levelSuffixSize = levelPrefix - 3 + default: + levelSuffixSize = suffixLen + } + + var levelSuffix int + if levelSuffixSize > 0 { + b, err := br.ReadBits(levelSuffixSize) + if err != nil { + return nil, fmt.Errorf("could not parse levelSuffix, failed with error: %v", err) + } + levelSuffix = int(b) + } else { + levelSuffix = 0 + } + + levelCode := (mini(15, levelPrefix) << uint(suffixLen)) + levelSuffix + + if levelPrefix >= 15 && suffixLen == 0 { + levelCode += 15 + } + + if levelPrefix >= 16 { + levelCode += (1 << uint(levelPrefix-3)) - 4096 + } + + if i == trailingOnes && trailingOnes < 3 { + levelCode += 2 + } + + if levelCode%2 == 0 { + levelVal = append(levelVal, (levelCode+2)>>1) + } else { + levelVal = append(levelVal, (-levelCode-1)>>1) + } + + if suffixLen == 0 { + suffixLen = 1 + } + + if absi(levelVal[i]) > (3< Date: Sun, 8 Sep 2019 13:31:10 +0930 Subject: [PATCH 2/3] codec/h264/h264dec/cavlc.go: removed redundant if checks in parseLevelInformation --- codec/h264/h264dec/cavlc.go | 130 +++++++++++++++++------------------- 1 file changed, 63 insertions(+), 67 deletions(-) diff --git a/codec/h264/h264dec/cavlc.go b/codec/h264/h264dec/cavlc.go index 0dcbc64b..820ec67c 100644 --- a/codec/h264/h264dec/cavlc.go +++ b/codec/h264/h264dec/cavlc.go @@ -51,18 +51,16 @@ func parseLevelPrefix(br *bits.BitReader) (int, error) { func parseLevelInformation(br *bits.BitReader, totalCoeff, trailingOnes int) ([]int, error) { var levelVal []int var i int - if trailingOnes != 0 { - for ; i < trailingOnes; i++ { - b, err := br.ReadBits(1) - if err != nil { - return nil, fmt.Errorf("could not read trailing_ones_sign_flag, failed with error: %v", err) - } - if b == 0 { - levelVal = append(levelVal, 1) - continue - } - levelVal = append(levelVal, -1) + for ; i < trailingOnes; i++ { + b, err := br.ReadBits(1) + if err != nil { + return nil, fmt.Errorf("could not read trailing_ones_sign_flag, failed with error: %v", err) } + if b == 0 { + levelVal = append(levelVal, 1) + continue + } + levelVal = append(levelVal, -1) } var suffixLen int @@ -75,63 +73,61 @@ func parseLevelInformation(br *bits.BitReader, totalCoeff, trailingOnes int) ([] return nil, errors.New("invalid TotalCoeff and TrailingOnes combination") } - if totalCoeff-trailingOnes != 0 { - for j := 0; j < totalCoeff-trailingOnes; j++ { - levelPrefix, err := parseLevelPrefix(br) - if err != nil { - return nil, fmt.Errorf("could not parse level prefix, failed with error: %v", err) - } - - var levelSuffixSize int - switch { - case levelPrefix == 14 && suffixLen == 0: - levelSuffixSize = 4 - case levelPrefix >= 15: - levelSuffixSize = levelPrefix - 3 - default: - levelSuffixSize = suffixLen - } - - var levelSuffix int - if levelSuffixSize > 0 { - b, err := br.ReadBits(levelSuffixSize) - if err != nil { - return nil, fmt.Errorf("could not parse levelSuffix, failed with error: %v", err) - } - levelSuffix = int(b) - } else { - levelSuffix = 0 - } - - levelCode := (mini(15, levelPrefix) << uint(suffixLen)) + levelSuffix - - if levelPrefix >= 15 && suffixLen == 0 { - levelCode += 15 - } - - if levelPrefix >= 16 { - levelCode += (1 << uint(levelPrefix-3)) - 4096 - } - - if i == trailingOnes && trailingOnes < 3 { - levelCode += 2 - } - - if levelCode%2 == 0 { - levelVal = append(levelVal, (levelCode+2)>>1) - } else { - levelVal = append(levelVal, (-levelCode-1)>>1) - } - - if suffixLen == 0 { - suffixLen = 1 - } - - if absi(levelVal[i]) > (3<= 15: + levelSuffixSize = levelPrefix - 3 + default: + levelSuffixSize = suffixLen + } + + var levelSuffix int + if levelSuffixSize > 0 { + b, err := br.ReadBits(levelSuffixSize) + if err != nil { + return nil, fmt.Errorf("could not parse levelSuffix, failed with error: %v", err) + } + levelSuffix = int(b) + } else { + levelSuffix = 0 + } + + levelCode := (mini(15, levelPrefix) << uint(suffixLen)) + levelSuffix + + if levelPrefix >= 15 && suffixLen == 0 { + levelCode += 15 + } + + if levelPrefix >= 16 { + levelCode += (1 << uint(levelPrefix-3)) - 4096 + } + + if i == trailingOnes && trailingOnes < 3 { + levelCode += 2 + } + + if levelCode%2 == 0 { + levelVal = append(levelVal, (levelCode+2)>>1) + } else { + levelVal = append(levelVal, (-levelCode-1)>>1) + } + + if suffixLen == 0 { + suffixLen = 1 + } + + if absi(levelVal[i]) > (3< Date: Mon, 9 Sep 2019 09:11:50 +0930 Subject: [PATCH 3/3] codec/h264/h264dec/cavlc.go: simplified some logic regarding appending of values onto levelVal based on trailing_ones_sign_flag --- codec/h264/h264dec/cavlc.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/codec/h264/h264dec/cavlc.go b/codec/h264/h264dec/cavlc.go index 820ec67c..e1932548 100644 --- a/codec/h264/h264dec/cavlc.go +++ b/codec/h264/h264dec/cavlc.go @@ -56,11 +56,7 @@ func parseLevelInformation(br *bits.BitReader, totalCoeff, trailingOnes int) ([] if err != nil { return nil, fmt.Errorf("could not read trailing_ones_sign_flag, failed with error: %v", err) } - if b == 0 { - levelVal = append(levelVal, 1) - continue - } - levelVal = append(levelVal, -1) + levelVal = append(levelVal, 1-int(b)*2) } var suffixLen int