diff --git a/CHANGELOG.md b/CHANGELOG.md index d87b35df..5e318a64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,16 +12,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `stpp` box handles optional empty lists properly (a single zero byte) - AVC slice size value +### Added + +- Exported function: bits.CeilLog2 + ## [0.34.1] - 2023-03-09 ### Fixed - Only start new segment at start or styp box -### Changed - -- - ## [0.34.0] - 2023-02-28 ### Added diff --git a/avc/pps.go b/avc/pps.go index 0b8bfcc9..7ba54577 100644 --- a/avc/pps.go +++ b/avc/pps.go @@ -87,7 +87,7 @@ func ParsePPSNALUnit(data []byte, spsMap map[uint32]*SPS) (*PPS, error) { pps.SliceGroupChangeRateMinus1 = reader.ReadExpGolomb() case 6: // slice_group_id[i] has Ceil(Log2(num_slice_groups_minus1 +1) bits) - nrBits := ceilLog2(pps.NumSliceGroupsMinus1 + 1) + nrBits := bits.CeilLog2(pps.NumSliceGroupsMinus1 + 1) for iGroup := uint(0); iGroup <= pps.NumSliceGroupsMinus1; iGroup++ { sgi := reader.Read(nrBits) @@ -170,14 +170,3 @@ func ParsePPSNALUnit(data []byte, spsMap map[uint32]*SPS) (*PPS, error) { } return pps, nil } - -// ceilLog2 - nr bits needed to represent numbers 0 - n-1 values -func ceilLog2(n uint) int { - for i := 0; i < 32; i++ { - maxNr := uint(1 << i) - if maxNr >= n { - return i - } - } - return 32 -} diff --git a/bits/log2.go b/bits/log2.go new file mode 100644 index 00000000..1714d75a --- /dev/null +++ b/bits/log2.go @@ -0,0 +1,12 @@ +package bits + +// CeilLog2 returns nr bits needed to represent numbers 0 - n-1. +func CeilLog2(n uint) int { + for i := 0; i < 32; i++ { + maxNr := uint(1 << i) + if maxNr >= n { + return i + } + } + return 32 +} diff --git a/bits/log2_test.go b/bits/log2_test.go new file mode 100644 index 00000000..bb8600a7 --- /dev/null +++ b/bits/log2_test.go @@ -0,0 +1,27 @@ +package bits_test + +import ( + "testing" + + "github.com/Eyevinn/mp4ff/bits" +) + +func TestCeilLog2(t *testing.T) { + testCases := []struct { + n uint + want int + }{ + {0, 0}, + {1, 0}, + {2, 1}, + {3, 2}, + {4, 2}, + {5, 3}, + {128, 7}, + } + for _, tc := range testCases { + if got := bits.CeilLog2(tc.n); got != tc.want { + t.Errorf("CeilLog2(%d) = %d, want %d", tc.n, got, tc.want) + } + } +}