mirror of https://bitbucket.org/ausocean/av.git
Merged in level-information (pull request #245)
codec/h264/h264dec: add function for parsing level information using process in section 9.2.2 of specifications Approved-by: Alan Noble <anoble@gmail.com>
This commit is contained in:
commit
614f42ec2c
|
@ -26,6 +26,7 @@ LICENSE
|
|||
package h264dec
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"bitbucket.org/ausocean/av/codec/h264/h264dec/bits"
|
||||
|
@ -44,3 +45,85 @@ 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
|
||||
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)
|
||||
}
|
||||
levelVal = append(levelVal, 1-int(b)*2)
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
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<<uint(suffixLen-1)) && suffixLen < 6 {
|
||||
suffixLen++
|
||||
}
|
||||
i++
|
||||
}
|
||||
return levelVal, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue