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:
Dan Kortschak 2018-08-19 09:59:33 +09:30
parent 9a73d00fff
commit b036517329
1 changed files with 51 additions and 8 deletions

View File

@ -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 (