fix WriteUInt

This commit is contained in:
nareix 2015-12-06 16:55:18 +08:00
parent 5d520f0d72
commit 57a7d68cf3
5 changed files with 142 additions and 43 deletions

View File

@ -65,13 +65,13 @@ type Crc32Reader struct {
Crc32 uint32 Crc32 uint32
} }
var debugCrc32 = false var DebugCrc32 = false
func (self *Crc32Reader) Read(b []byte) (n int, err error) { func (self *Crc32Reader) Read(b []byte) (n int, err error) {
if n, err = self.R.Read(b); err != nil { if n, err = self.R.Read(b); err != nil {
return return
} }
if debugCrc32 { if DebugCrc32 {
fmt.Println("crc32: update", hex.EncodeToString(b)) fmt.Println("crc32: update", hex.EncodeToString(b))
} }
self.Crc32 = updateIeeeCrc32(self.Crc32, b) self.Crc32 = updateIeeeCrc32(self.Crc32, b)
@ -83,7 +83,7 @@ func (self *Crc32Reader) ReadCrc32UIntAndCheck() (err error) {
return return
} }
if self.Crc32 != 0 { if self.Crc32 != 0 {
err = fmt.Errorf("crc32 != 0") err = fmt.Errorf("crc32(%x) != 0", self.Crc32)
return return
} }
return return

View File

@ -8,6 +8,7 @@ import (
ts "../" ts "../"
"fmt" "fmt"
"encoding/hex" "encoding/hex"
"flag"
) )
type Stream struct { type Stream struct {
@ -27,7 +28,7 @@ type Sample struct {
Data []byte Data []byte
} }
func readSamples(ch chan Sample) { func readSamples(filename string, ch chan Sample) {
defer func() { defer func() {
close(ch) close(ch)
}() }()
@ -36,7 +37,7 @@ func readSamples(ch chan Sample) {
var file *os.File var file *os.File
var err error var err error
if file, err = os.Open("/tmp/out.ts"); err != nil { if file, err = os.Open(filename); err != nil {
return return
} }
@ -137,8 +138,46 @@ func readSamples(ch chan Sample) {
} }
func main() { func main() {
input := flag.String("i", "", "input file")
output := flag.String("o", "", "output file")
flag.Parse()
var file *os.File
var err error
ch := make(chan Sample, 0) ch := make(chan Sample, 0)
go readSamples(ch) go readSamples(*input, ch)
if *output != "" {
if file, err = os.Create(*output); err != nil {
return
}
}
writePAT := func() (err error) {
w := &ts.TSWriter{
W: file,
PID: 0,
}
pat := ts.PAT {
Entries: []ts.PATEntry{
{ProgramNumber: 1, ProgramMapPID: 4096},
},
}
bw := &bytes.Buffer{}
if err = ts.WritePAT(bw, pat); err != nil {
return
}
if err = w.Write(bw.Bytes(), false); err != nil {
return
}
return
}
if file != nil {
writePAT()
file.Close()
}
for { for {
var sample Sample var sample Sample
@ -147,8 +186,10 @@ func main() {
break break
} }
if sample.Type == ts.ElementaryStreamTypeH264 { if sample.Type == ts.ElementaryStreamTypeH264 {
fmt.Println("sample", len(sample.Data), "PCR", sample.PCR) if false {
fmt.Print(hex.Dump(sample.Data)) fmt.Println("sample: ", len(sample.Data), "PCR", sample.PCR)
//fmt.Print(hex.Dump(sample.Data))
}
} }
} }
} }

View File

@ -7,6 +7,8 @@ import (
"io/ioutil" "io/ioutil"
) )
var DebugReader = true
func ReadUInt(r io.Reader, n int) (res uint, err error) { func ReadUInt(r io.Reader, n int) (res uint, err error) {
var b [4]byte var b [4]byte
if _, err = r.Read(b[0:n]); err != nil { if _, err = r.Read(b[0:n]); err != nil {
@ -55,7 +57,7 @@ func ReadTSHeader(r io.Reader) (self TSHeader, err error) {
return return
} }
if debug { if DebugReader {
fmt.Printf("ts: flags %s\n", FieldsDumper{ fmt.Printf("ts: flags %s\n", FieldsDumper{
Fields: []struct{ Fields: []struct{
Length int Length int
@ -99,7 +101,7 @@ func ReadTSHeader(r io.Reader) (self TSHeader, err error) {
return return
} }
if debug { if DebugReader {
fmt.Printf("ts: ext_flags %s\n", FieldsDumper{ fmt.Printf("ts: ext_flags %s\n", FieldsDumper{
Fields: []struct{ Fields: []struct{
Length int Length int
@ -127,7 +129,7 @@ func ReadTSHeader(r io.Reader) (self TSHeader, err error) {
} }
// clock is 27MHz // clock is 27MHz
self.PCR = UIntToPCR(v) self.PCR = UIntToPCR(v)
if debug { if DebugReader {
fmt.Printf("ts: PCR %d %f\n", self.PCR, float64(self.PCR)/27000000) fmt.Printf("ts: PCR %d %f\n", self.PCR, float64(self.PCR)/27000000)
} }
} }
@ -168,7 +170,7 @@ func ReadTSHeader(r io.Reader) (self TSHeader, err error) {
return return
} }
if debug { if DebugReader {
// rubish // rubish
//fmt.Println("ts: ", data) //fmt.Println("ts: ", data)
} }
@ -216,17 +218,8 @@ func ReadPSI(r io.Reader) (self PSI, lr *io.LimitedReader, cr *Crc32Reader, err
} }
length = flags & 0x3FF length = flags & 0x3FF
if debug { if DebugReader {
fmt.Printf("psi: %s\n", FieldsDumper{ fmt.Printf("psi: tableid=%d len=%d\n", self.TableId, length)
Fields: []struct{
Length int
Desc string
}{
{4, "reserved"},
},
Val: flags,
Length: 16,
})
} }
lr = &io.LimitedReader{R: cr, N: int64(length)} lr = &io.LimitedReader{R: cr, N: int64(length)}
@ -243,7 +236,7 @@ func ReadPSI(r io.Reader) (self PSI, lr *io.LimitedReader, cr *Crc32Reader, err
return return
} }
if debug { if DebugReader {
fmt.Printf("psi: %s\n", FieldsDumper{ fmt.Printf("psi: %s\n", FieldsDumper{
Fields: []struct{ Fields: []struct{
Length int Length int
@ -268,7 +261,7 @@ func ReadPSI(r io.Reader) (self PSI, lr *io.LimitedReader, cr *Crc32Reader, err
return return
} }
if debug { if DebugReader {
fmt.Printf("psi: table_id=%x table_extension=%x secnum=%x lastsecnum=%x\n", fmt.Printf("psi: table_id=%x table_extension=%x secnum=%x lastsecnum=%x\n",
self.TableId, self.TableId,
self.TableIdExtension, self.TableIdExtension,
@ -299,7 +292,7 @@ func ReadPMT(r io.Reader) (self PMT, err error) {
} }
self.PCRPID = flags & 0x1fff self.PCRPID = flags & 0x1fff
if debug { if DebugReader {
fmt.Printf("pmt: %s\n", FieldsDumper{ fmt.Printf("pmt: %s\n", FieldsDumper{
Fields: []struct{ Fields: []struct{
Length int Length int
@ -375,12 +368,15 @@ func ReadPMT(r io.Reader) (self PMT, err error) {
self.ElementaryStreamInfos = append(self.ElementaryStreamInfos, info) self.ElementaryStreamInfos = append(self.ElementaryStreamInfos, info)
} }
if debug { if DebugReader {
fmt.Printf("pmt: ProgramDescriptors %v\n", self.ProgramDescriptors) fmt.Printf("pmt: ProgramDescriptors %v\n", self.ProgramDescriptors)
fmt.Printf("pmt: ElementaryStreamInfos %v\n", self.ElementaryStreamInfos) fmt.Printf("pmt: ElementaryStreamInfos %v\n", self.ElementaryStreamInfos)
} }
if err = cr.ReadCrc32UIntAndCheck(); err != nil { if err = cr.ReadCrc32UIntAndCheck(); err != nil {
if DebugReader {
fmt.Printf("pmt: %s\n", err)
}
return return
} }
@ -416,10 +412,13 @@ func ReadPAT(r io.Reader) (self PAT, err error) {
} }
if err = cr.ReadCrc32UIntAndCheck(); err != nil { if err = cr.ReadCrc32UIntAndCheck(); err != nil {
if DebugReader {
fmt.Printf("pat: %s\n", err)
}
return return
} }
if debug { if DebugReader {
fmt.Printf("pat: %v\n", self) fmt.Printf("pat: %v\n", self)
} }
@ -461,7 +460,7 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) {
return return
} }
if debug { if DebugReader {
fmt.Printf("pes: %s\n", FieldsDumper{ fmt.Printf("pes: %s\n", FieldsDumper{
Fields: []struct{ Fields: []struct{
Length int Length int
@ -489,7 +488,7 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) {
return return
} }
if debug { if DebugReader {
fmt.Printf("pes: %s\n", FieldsDumper{ fmt.Printf("pes: %s\n", FieldsDumper{
Fields: []struct{ Fields: []struct{
Length int Length int
@ -521,7 +520,7 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) {
} }
self.PTS = PESUIntToTs(v) self.PTS = PESUIntToTs(v)
if debug { if DebugReader {
fmt.Printf("pes: pts %x=>%x %f\n", fmt.Printf("pes: pts %x=>%x %f\n",
v, self.PTS, float64(self.PTS)/90000) v, self.PTS, float64(self.PTS)/90000)
} }
@ -533,7 +532,7 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) {
return return
} }
self.DTS = PESUIntToTs(v) self.DTS = PESUIntToTs(v)
if debug { if DebugReader {
fmt.Printf("pes: dts %d\n", self.PTS) fmt.Printf("pes: dts %d\n", self.PTS)
} }
} }

2
ts.go
View File

@ -5,8 +5,6 @@ import (
"fmt" "fmt"
) )
const debug = true
const ( const (
ElementaryStreamTypeH264 = 0x1B ElementaryStreamTypeH264 = 0x1B
ElementaryStreamTypeAdtsAAC = 0x0F ElementaryStreamTypeAdtsAAC = 0x0F

View File

@ -2,16 +2,12 @@
package ts package ts
import ( import (
_ "fmt" "fmt"
"io" "io"
"bytes" "bytes"
) )
type TSWriter struct { const DebugWriter = true
W io.Writer
ContinuityCounter uint
PayloadUnitStart bool
}
func WriteUInt64(w io.Writer, val uint64, n int) (err error) { func WriteUInt64(w io.Writer, val uint64, n int) (err error) {
var b [8]byte var b [8]byte
@ -19,7 +15,7 @@ func WriteUInt64(w io.Writer, val uint64, n int) (err error) {
b[i] = byte(val) b[i] = byte(val)
val >>= 8 val >>= 8
} }
if _, err = w.Write(b[:]); err != nil { if _, err = w.Write(b[:n]); err != nil {
return return
} }
return return
@ -108,6 +104,63 @@ func WriteTSHeader(w io.Writer, self TSHeader) (err error) {
return return
} }
type TSWriter struct {
W io.Writer
PID uint
PCR uint64
OPCR uint64
ContinuityCounter uint
}
func (self *TSWriter) Write(b []byte, RandomAccessIndicator bool) (err error) {
for i := 0; len(b) > 0; i++ {
header := TSHeader{
PID: self.PID,
PCR: self.PCR,
OPCR: self.OPCR,
ContinuityCounter: self.ContinuityCounter,
RandomAccessIndicator: RandomAccessIndicator,
}
if i == 0 {
header.PayloadUnitStart = true
}
bw := &bytes.Buffer{}
if err = WriteTSHeader(bw, header); err != nil {
return
}
var data []byte
dataLen := 188-bw.Len()
if DebugWriter {
fmt.Printf("tsw: datalen=%d blen=%d\n", dataLen, len(b))
}
if len(b) > dataLen {
data = b[:dataLen]
b = b[dataLen:]
} else {
data = make([]byte, dataLen)
copy(data, b)
for i := len(b); i < dataLen; i++ {
data[i] = 0xff
}
b = b[len(b):]
}
if _, err = self.W.Write(bw.Bytes()); err != nil {
return
}
if _, err = self.W.Write(data); err != nil {
return
}
self.ContinuityCounter++
}
return
}
func WritePSI(w io.Writer, self PSI, data []byte) (err error) { func WritePSI(w io.Writer, self PSI, data []byte) (err error) {
// pointer(8) // pointer(8)
// table_id(8) // table_id(8)
@ -135,10 +188,14 @@ func WritePSI(w io.Writer, self PSI, data []byte) (err error) {
var flags, length uint var flags, length uint
length = 2+3+4+uint(len(data)) length = 2+3+4+uint(len(data))
flags = 0xb<<10|length flags = 0xb<<10|length
if err = WriteUInt(cw, flags, 1); err != nil { if err = WriteUInt(cw, flags, 2); err != nil {
return return
} }
if DebugWriter {
fmt.Printf("wpsi: flags=%x\n", flags)
}
// Table ID extension(16) // Table ID extension(16)
if err = WriteUInt(cw, self.TableIdExtension, 2); err != nil { if err = WriteUInt(cw, self.TableIdExtension, 2); err != nil {
return return
@ -166,13 +223,17 @@ func WritePSI(w io.Writer, self PSI, data []byte) (err error) {
} }
// crc(32) // crc(32)
if err = WriteUInt(w, uint(cw.Crc32), 4); err != nil { if err = WriteUInt(w, bswap32(uint(cw.Crc32)), 4); err != nil {
return return
} }
return return
} }
func bswap32(v uint) uint {
return (v>>24)|((v>>16)&0xff)<<8|((v>>8)&0xff)<<16|(v&0xff)<<24
}
func WritePES(w io.Writer, self PESHeader, data []byte) (err error) { func WritePES(w io.Writer, self PESHeader, data []byte) (err error) {
// http://dvd.sourceforge.net/dvdinfo/pes-hdr.html // http://dvd.sourceforge.net/dvdinfo/pes-hdr.html