Skip to content

Commit

Permalink
add bits
Browse files Browse the repository at this point in the history
  • Loading branch information
nareix committed Nov 3, 2017
1 parent 261fd7f commit dfc1226
Show file tree
Hide file tree
Showing 22 changed files with 547 additions and 14 deletions.
2 changes: 1 addition & 1 deletion codec/aacparser/parser.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package aacparser

import (
"github.com/nareix/bits"
"github.com/nareix/joy4/utils/bits"
"github.com/nareix/joy4/av"
"time"
"fmt"
Expand Down
4 changes: 2 additions & 2 deletions codec/h264parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package h264parser

import (
"github.com/nareix/joy4/av"
"github.com/nareix/bits"
"github.com/nareix/bits/pio"
"github.com/nareix/joy4/utils/bits"
"github.com/nareix/joy4/utils/bits/pio"
"fmt"
"bytes"
)
Expand Down
2 changes: 1 addition & 1 deletion format/flv/flv.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package flv
import (
"bufio"
"fmt"
"github.com/nareix/bits/pio"
"github.com/nareix/joy4/utils/bits/pio"
"github.com/nareix/joy4/av"
"github.com/nareix/joy4/av/avutil"
"github.com/nareix/joy4/codec"
Expand Down
2 changes: 1 addition & 1 deletion format/flv/flvio/amf0.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"math"
"fmt"
"time"
"github.com/nareix/bits/pio"
"github.com/nareix/joy4/utils/bits/pio"
)

type AMF0ParseError struct {
Expand Down
2 changes: 1 addition & 1 deletion format/flv/flvio/flvio.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package flvio

import (
"fmt"
"github.com/nareix/bits/pio"
"github.com/nareix/joy4/utils/bits/pio"
"github.com/nareix/joy4/av"
"io"
"time"
Expand Down
2 changes: 1 addition & 1 deletion format/mp4/mp4io/atoms.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package mp4io

import "github.com/nareix/bits/pio"
import "github.com/nareix/joy4/utils/bits/pio"
import "time"

const MOOF = Tag(0x6d6f6f66)
Expand Down
2 changes: 1 addition & 1 deletion format/mp4/mp4io/gen/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -967,7 +967,7 @@ func genatoms(filename, outfilename string) {
&ast.GenDecl{
Tok: token.IMPORT,
Specs: []ast.Spec{
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"github.com/nareix/bits/pio"`}},
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"github.com/nareix/joy4/utils/bits/pio"`}},
},
},
&ast.GenDecl{
Expand Down
2 changes: 1 addition & 1 deletion format/mp4/mp4io/mp4io.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
package mp4io

import (
"github.com/nareix/bits/pio"
"github.com/nareix/joy4/utils/bits/pio"
"os"
"io"
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion format/mp4/muxer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/nareix/joy4/codec/aacparser"
"github.com/nareix/joy4/codec/h264parser"
"github.com/nareix/joy4/format/mp4/mp4io"
"github.com/nareix/bits/pio"
"github.com/nareix/joy4/utils/bits/pio"
"io"
"bufio"
)
Expand Down
2 changes: 1 addition & 1 deletion format/rtmp/rtmp.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"crypto/sha256"
"encoding/hex"
"fmt"
"github.com/nareix/bits/pio"
"github.com/nareix/joy4/utils/bits/pio"
"github.com/nareix/joy4/av"
"github.com/nareix/joy4/av/avutil"
"github.com/nareix/joy4/format/flv"
Expand Down
2 changes: 1 addition & 1 deletion format/rtsp/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"encoding/binary"
"encoding/hex"
"fmt"
"github.com/nareix/bits/pio"
"github.com/nareix/joy4/utils/bits/pio"
"github.com/nareix/joy4/av"
"github.com/nareix/joy4/av/avutil"
"github.com/nareix/joy4/codec"
Expand Down
2 changes: 1 addition & 1 deletion format/ts/demuxer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"bufio"
"fmt"
"time"
"github.com/nareix/bits/pio"
"github.com/nareix/joy4/utils/bits/pio"
"github.com/nareix/joy4/av"
"github.com/nareix/joy4/format/ts/tsio"
"github.com/nareix/joy4/codec/aacparser"
Expand Down
2 changes: 1 addition & 1 deletion format/ts/tsio/tsio.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"io"
"time"
"fmt"
"github.com/nareix/bits/pio"
"github.com/nareix/joy4/utils/bits/pio"
)

const (
Expand Down
118 changes: 118 additions & 0 deletions utils/bits/bits.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package bits

import (
"io"
)

type Reader struct {
R io.Reader
n int
bits uint64
}

func (self *Reader) ReadBits64(n int) (bits uint64, err error) {
if self.n < n {
var b [8]byte
var got int
want := (n - self.n + 7) / 8
if got, err = self.R.Read(b[:want]); err != nil {
return
}
if got < want {
err = io.EOF
return
}
for i := 0; i < got; i++ {
self.bits <<= 8
self.bits |= uint64(b[i])
}
self.n += got * 8
}
bits = self.bits >> uint(self.n-n)
self.bits ^= bits << uint(self.n-n)
self.n -= n
return
}

func (self *Reader) ReadBits(n int) (bits uint, err error) {
var bits64 uint64
if bits64, err = self.ReadBits64(n); err != nil {
return
}
bits = uint(bits64)
return
}

func (self *Reader) Read(p []byte) (n int, err error) {
for n < len(p) {
want := 8
if len(p)-n < want {
want = len(p) - n
}
var bits uint64
if bits, err = self.ReadBits64(want * 8); err != nil {
break
}
for i := 0; i < want; i++ {
p[n+i] = byte(bits >> uint((want-i-1)*8))
}
n += want
}
return
}

type Writer struct {
W io.Writer
n int
bits uint64
}

func (self *Writer) WriteBits64(bits uint64, n int) (err error) {
if self.n+n > 64 {
move := uint(64 - self.n)
mask := bits >> move
self.bits = (self.bits << move) | mask
self.n = 64
if err = self.FlushBits(); err != nil {
return
}
n -= int(move)
bits ^= (mask << move)
}
self.bits = (self.bits << uint(n)) | bits
self.n += n
return
}

func (self *Writer) WriteBits(bits uint, n int) (err error) {
return self.WriteBits64(uint64(bits), n)
}

func (self *Writer) Write(p []byte) (n int, err error) {
for n < len(p) {
if err = self.WriteBits64(uint64(p[n]), 8); err != nil {
return
}
n++
}
return
}

func (self *Writer) FlushBits() (err error) {
if self.n > 0 {
var b [8]byte
bits := self.bits
if self.n%8 != 0 {
bits <<= uint(8 - (self.n % 8))
}
want := (self.n + 7) / 8
for i := 0; i < want; i++ {
b[i] = byte(bits >> uint((want-i-1)*8))
}
if _, err = self.W.Write(b[:want]); err != nil {
return
}
self.n = 0
}
return
}
51 changes: 51 additions & 0 deletions utils/bits/bits_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package bits

import (
"bytes"
"testing"
)

func TestBits(t *testing.T) {
rdata := []byte{0xf3, 0xb3, 0x45, 0x60}
rbuf := bytes.NewReader(rdata[:])
r := &Reader{R: rbuf}
var u32 uint
if u32, _ = r.ReadBits(4); u32 != 0xf {
t.FailNow()
}
if u32, _ = r.ReadBits(4); u32 != 0x3 {
t.FailNow()
}
if u32, _ = r.ReadBits(2); u32 != 0x2 {
t.FailNow()
}
if u32, _ = r.ReadBits(2); u32 != 0x3 {
t.FailNow()
}
b := make([]byte, 2)
if r.Read(b); b[0] != 0x34 || b[1] != 0x56 {
t.FailNow()
}

wbuf := &bytes.Buffer{}
w := &Writer{W: wbuf}
w.WriteBits(0xf, 4)
w.WriteBits(0x3, 4)
w.WriteBits(0x2, 2)
w.WriteBits(0x3, 2)
n, _ := w.Write([]byte{0x34, 0x56})
if n != 2 {
t.FailNow()
}
w.FlushBits()
wdata := wbuf.Bytes()
if wdata[0] != 0xf3 || wdata[1] != 0xb3 || wdata[2] != 0x45 || wdata[3] != 0x60 {
t.FailNow()
}

b = make([]byte, 8)
PutUInt64BE(b, 0x11223344, 32)
if b[0] != 0x11 || b[1] != 0x22 || b[2] != 0x33 || b[3] != 0x44 {
t.FailNow()
}
}
23 changes: 23 additions & 0 deletions utils/bits/bufio/bufio.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package bufio

import (
"io"
)

type Reader struct {
buf [][]byte
R io.ReadSeeker
}

func NewReaderSize(r io.ReadSeeker, size int) *Reader {
buf := make([]byte, size*2)
return &Reader{
R: r,
buf: [][]byte{buf[0:size], buf[size:]},
}
}

func (self *Reader) ReadAt(b []byte, off int64) (n int, err error) {
return
}

65 changes: 65 additions & 0 deletions utils/bits/golomb_reader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package bits

import (
"io"
)

type GolombBitReader struct {
R io.Reader
buf [1]byte
left byte
}

func (self *GolombBitReader) ReadBit() (res uint, err error) {
if self.left == 0 {
if _, err = self.R.Read(self.buf[:]); err != nil {
return
}
self.left = 8
}
self.left--
res = uint(self.buf[0]>>self.left) & 1
return
}

func (self *GolombBitReader) ReadBits(n int) (res uint, err error) {
for i := 0; i < n; i++ {
var bit uint
if bit, err = self.ReadBit(); err != nil {
return
}
res |= bit << uint(n-i-1)
}
return
}

func (self *GolombBitReader) ReadExponentialGolombCode() (res uint, err error) {
i := 0
for {
var bit uint
if bit, err = self.ReadBit(); err != nil {
return
}
if !(bit == 0 && i < 32) {
break
}
i++
}
if res, err = self.ReadBits(i); err != nil {
return
}
res += (1 << uint(i)) - 1
return
}

func (self *GolombBitReader) ReadSE() (res uint, err error) {
if res, err = self.ReadExponentialGolombCode(); err != nil {
return
}
if res&0x01 != 0 {
res = (res + 1) / 2
} else {
res = -res / 2
}
return
}
5 changes: 5 additions & 0 deletions utils/bits/pio/pio.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

package pio

var RecommendBufioSize = 1024*64

Loading

0 comments on commit dfc1226

Please sign in to comment.