From 04fef9ce1d0b88806901869b2426af3373b148f0 Mon Sep 17 00:00:00 2001 From: Saxon Date: Mon, 12 Aug 2019 02:02:14 +0930 Subject: [PATCH] codec/h264/h264dec: added fixedLenBinarization and testing --- codec/h264/h264dec/cabac.go | 21 +++++++++++++++++++++ codec/h264/h264dec/cabac_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/codec/h264/h264dec/cabac.go b/codec/h264/h264dec/cabac.go index 74cf527c..ea58c124 100644 --- a/codec/h264/h264dec/cabac.go +++ b/codec/h264/h264dec/cabac.go @@ -1,6 +1,8 @@ package h264dec import ( + "math" + "bitbucket.org/ausocean/av/codec/h264/h264dec/bits" "github.com/pkg/errors" ) @@ -830,3 +832,22 @@ func suffix(v, uCoff, k int, signedValFlag bool) []int { return s } + +// Error used by fixedLenBinariztion. +var errNegativeValue = errors.New("cannot get fixed length binarization of negative number") + +// fixedLenBinarization returns the fixed-length (FL) binarization of the syntax +// element v, given cMax to determine bin length, as specified by section 9.3.2.4 +// of the specifications. +func fixedLenBinarization(v, cMax int) ([]int, error) { + if v < 0 { + return nil, errNegativeValue + } + l := int(math.Ceil(math.Log2(float64(cMax + 1)))) + r := make([]int, l) + for i := l - 1; i >= 0; i-- { + r[i] = v % 2 + v = v / 2 + } + return r, nil +} diff --git a/codec/h264/h264dec/cabac_test.go b/codec/h264/h264dec/cabac_test.go index 990ba780..a72be4f8 100644 --- a/codec/h264/h264dec/cabac_test.go +++ b/codec/h264/h264dec/cabac_test.go @@ -215,6 +215,36 @@ func TestUnaryBinarization(t *testing.T) { } } +func TestFixedLengthBinarization(t *testing.T) { + tests := []struct { + v int + cMax int + want []int + err error + }{ + {v: 0, cMax: 7, want: []int{0, 0, 0}}, + {v: 1, cMax: 7, want: []int{0, 0, 1}}, + {v: 2, cMax: 7, want: []int{0, 1, 0}}, + {v: 3, cMax: 7, want: []int{0, 1, 1}}, + {v: 4, cMax: 7, want: []int{1, 0, 0}}, + {v: 5, cMax: 7, want: []int{1, 0, 1}}, + {v: 6, cMax: 7, want: []int{1, 1, 0}}, + {v: 7, cMax: 7, want: []int{1, 1, 1}}, + {v: -1, cMax: 7, want: nil, err: errNegativeValue}, + } + + for i, test := range tests { + got, err := fixedLenBinarization(test.v, test.cMax) + if err != test.err { + t.Errorf("did not get expected error for test %d\nGot: %v\nWant: %v\n", i, err, test.err) + } + + if !reflect.DeepEqual(test.want, got) { + t.Errorf("did not get expected result for test %d\nGot: %v\nWant: %v\n", i, got, test.want) + } + } +} + func TestTruncUnaryBinarization(t *testing.T) { tests := []struct { v int