mirror of https://bitbucket.org/ausocean/av.git
generator: add CRC32 calculation
This uses a big-endian CRC32 algorithm rather than the hash/crc32 package's little-endian implementation.
This commit is contained in:
parent
9a73d00fff
commit
b036517329
|
@ -29,6 +29,9 @@ LICENSE
|
|||
package generator
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"hash/crc32"
|
||||
"math/bits"
|
||||
"time"
|
||||
|
||||
"bitbucket.org/ausocean/av/mpegts"
|
||||
|
@ -42,6 +45,7 @@ var (
|
|||
patTable = []byte{
|
||||
0x00, // pointer
|
||||
|
||||
// ---- section included in data sent to CRC32 during check
|
||||
// table header
|
||||
0x00, // table id
|
||||
0xb0, // section syntax indicator:1|private bit:1|reserved:2|section length:2|more bytes...:2
|
||||
|
@ -56,13 +60,15 @@ var (
|
|||
0x00, 0x01, // Program number
|
||||
0xf0, 0x00, // reserved:3|program map PID:13
|
||||
|
||||
0x2a, 0xb1, 0x04, 0xb2, // CRC
|
||||
// 0x2a, 0xb1, 0x04, 0xb2, // CRC
|
||||
// ----
|
||||
}
|
||||
pmtTable = []byte{
|
||||
0x00, // pointer
|
||||
|
||||
// ---- section included in data sent to CRC32 during check
|
||||
// table header
|
||||
0x02, // table id.
|
||||
0x02, // table id
|
||||
0xb0, // section syntax indicator:1|private bit:1|reserved:2|section length:2|more bytes...:2
|
||||
0x12, // more bytes...
|
||||
|
||||
|
@ -79,19 +85,56 @@ var (
|
|||
0x1b, // stream type
|
||||
0xe1, 0x00, // reserved:3|elementary PID:13
|
||||
0xf0, 0x00, // reserved:4|unused:2|ES info length:10
|
||||
// No elementary stream descriptos since ES info length is 0.
|
||||
// No elementary stream descriptors since ES info length is 0.
|
||||
|
||||
0x15, 0xbd, 0x4d, 0x56, // CRC
|
||||
// 0x15, 0xbd, 0x4d, 0x56, // CRC
|
||||
// ----
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
for len(patTable) < psiPacketSize {
|
||||
patTable = append(patTable, 0xff)
|
||||
// Generate IEEE polynomial table
|
||||
// for the big-endian algorithm.
|
||||
crcTable := crc32_MakeTable(bits.Reverse32(crc32.IEEE))
|
||||
|
||||
patTable = completePSI(patTable, crcTable)
|
||||
pmtTable = completePSI(pmtTable, crcTable)
|
||||
}
|
||||
|
||||
func completePSI(psi []byte, tab *crc32.Table) []byte {
|
||||
var buf [4]byte
|
||||
crc := crc32_Update(0xffffffff, tab, psi[1:])
|
||||
binary.BigEndian.PutUint32(buf[:], crc)
|
||||
dst := make([]byte, len(psi), psiPacketSize)
|
||||
copy(dst, psi)
|
||||
dst = append(dst, buf[:]...)
|
||||
for len(dst) < cap(dst) {
|
||||
dst = append(dst, 0xff)
|
||||
}
|
||||
for len(pmtTable) < psiPacketSize {
|
||||
pmtTable = append(pmtTable, 0xff)
|
||||
return dst
|
||||
}
|
||||
|
||||
func crc32_MakeTable(poly uint32) *crc32.Table {
|
||||
var t crc32.Table
|
||||
for i := range t {
|
||||
crc := uint32(i) << 24
|
||||
for j := 0; j < 8; j++ {
|
||||
if crc&0x80000000 != 0 {
|
||||
crc = (crc << 1) ^ poly
|
||||
} else {
|
||||
crc <<= 1
|
||||
}
|
||||
}
|
||||
t[i] = crc
|
||||
}
|
||||
return &t
|
||||
}
|
||||
|
||||
func crc32_Update(crc uint32, tab *crc32.Table, p []byte) uint32 {
|
||||
for _, v := range p {
|
||||
crc = tab[byte(crc>>24)^v] ^ (crc << 8)
|
||||
}
|
||||
return crc
|
||||
}
|
||||
|
||||
const (
|
||||
|
|
Loading…
Reference in New Issue