fix WriteUInt
This commit is contained in:
parent
5d520f0d72
commit
57a7d68cf3
@ -65,13 +65,13 @@ type Crc32Reader struct {
|
||||
Crc32 uint32
|
||||
}
|
||||
|
||||
var debugCrc32 = false
|
||||
var DebugCrc32 = false
|
||||
|
||||
func (self *Crc32Reader) Read(b []byte) (n int, err error) {
|
||||
if n, err = self.R.Read(b); err != nil {
|
||||
return
|
||||
}
|
||||
if debugCrc32 {
|
||||
if DebugCrc32 {
|
||||
fmt.Println("crc32: update", hex.EncodeToString(b))
|
||||
}
|
||||
self.Crc32 = updateIeeeCrc32(self.Crc32, b)
|
||||
@ -83,7 +83,7 @@ func (self *Crc32Reader) ReadCrc32UIntAndCheck() (err error) {
|
||||
return
|
||||
}
|
||||
if self.Crc32 != 0 {
|
||||
err = fmt.Errorf("crc32 != 0")
|
||||
err = fmt.Errorf("crc32(%x) != 0", self.Crc32)
|
||||
return
|
||||
}
|
||||
return
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
ts "../"
|
||||
"fmt"
|
||||
"encoding/hex"
|
||||
"flag"
|
||||
)
|
||||
|
||||
type Stream struct {
|
||||
@ -27,7 +28,7 @@ type Sample struct {
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func readSamples(ch chan Sample) {
|
||||
func readSamples(filename string, ch chan Sample) {
|
||||
defer func() {
|
||||
close(ch)
|
||||
}()
|
||||
@ -36,7 +37,7 @@ func readSamples(ch chan Sample) {
|
||||
|
||||
var file *os.File
|
||||
var err error
|
||||
if file, err = os.Open("/tmp/out.ts"); err != nil {
|
||||
if file, err = os.Open(filename); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@ -137,8 +138,46 @@ func readSamples(ch chan Sample) {
|
||||
}
|
||||
|
||||
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)
|
||||
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 {
|
||||
var sample Sample
|
||||
@ -147,8 +186,10 @@ func main() {
|
||||
break
|
||||
}
|
||||
if sample.Type == ts.ElementaryStreamTypeH264 {
|
||||
fmt.Println("sample", len(sample.Data), "PCR", sample.PCR)
|
||||
fmt.Print(hex.Dump(sample.Data))
|
||||
if false {
|
||||
fmt.Println("sample: ", len(sample.Data), "PCR", sample.PCR)
|
||||
//fmt.Print(hex.Dump(sample.Data))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
47
reader.go
47
reader.go
@ -7,6 +7,8 @@ import (
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
var DebugReader = true
|
||||
|
||||
func ReadUInt(r io.Reader, n int) (res uint, err error) {
|
||||
var b [4]byte
|
||||
if _, err = r.Read(b[0:n]); err != nil {
|
||||
@ -55,7 +57,7 @@ func ReadTSHeader(r io.Reader) (self TSHeader, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
if debug {
|
||||
if DebugReader {
|
||||
fmt.Printf("ts: flags %s\n", FieldsDumper{
|
||||
Fields: []struct{
|
||||
Length int
|
||||
@ -99,7 +101,7 @@ func ReadTSHeader(r io.Reader) (self TSHeader, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
if debug {
|
||||
if DebugReader {
|
||||
fmt.Printf("ts: ext_flags %s\n", FieldsDumper{
|
||||
Fields: []struct{
|
||||
Length int
|
||||
@ -127,7 +129,7 @@ func ReadTSHeader(r io.Reader) (self TSHeader, err error) {
|
||||
}
|
||||
// clock is 27MHz
|
||||
self.PCR = UIntToPCR(v)
|
||||
if debug {
|
||||
if DebugReader {
|
||||
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
|
||||
}
|
||||
|
||||
if debug {
|
||||
if DebugReader {
|
||||
// rubish
|
||||
//fmt.Println("ts: ", data)
|
||||
}
|
||||
@ -216,17 +218,8 @@ func ReadPSI(r io.Reader) (self PSI, lr *io.LimitedReader, cr *Crc32Reader, err
|
||||
}
|
||||
length = flags & 0x3FF
|
||||
|
||||
if debug {
|
||||
fmt.Printf("psi: %s\n", FieldsDumper{
|
||||
Fields: []struct{
|
||||
Length int
|
||||
Desc string
|
||||
}{
|
||||
{4, "reserved"},
|
||||
},
|
||||
Val: flags,
|
||||
Length: 16,
|
||||
})
|
||||
if DebugReader {
|
||||
fmt.Printf("psi: tableid=%d len=%d\n", self.TableId, 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
|
||||
}
|
||||
|
||||
if debug {
|
||||
if DebugReader {
|
||||
fmt.Printf("psi: %s\n", FieldsDumper{
|
||||
Fields: []struct{
|
||||
Length int
|
||||
@ -268,7 +261,7 @@ func ReadPSI(r io.Reader) (self PSI, lr *io.LimitedReader, cr *Crc32Reader, err
|
||||
return
|
||||
}
|
||||
|
||||
if debug {
|
||||
if DebugReader {
|
||||
fmt.Printf("psi: table_id=%x table_extension=%x secnum=%x lastsecnum=%x\n",
|
||||
self.TableId,
|
||||
self.TableIdExtension,
|
||||
@ -299,7 +292,7 @@ func ReadPMT(r io.Reader) (self PMT, err error) {
|
||||
}
|
||||
self.PCRPID = flags & 0x1fff
|
||||
|
||||
if debug {
|
||||
if DebugReader {
|
||||
fmt.Printf("pmt: %s\n", FieldsDumper{
|
||||
Fields: []struct{
|
||||
Length int
|
||||
@ -375,12 +368,15 @@ func ReadPMT(r io.Reader) (self PMT, err error) {
|
||||
self.ElementaryStreamInfos = append(self.ElementaryStreamInfos, info)
|
||||
}
|
||||
|
||||
if debug {
|
||||
if DebugReader {
|
||||
fmt.Printf("pmt: ProgramDescriptors %v\n", self.ProgramDescriptors)
|
||||
fmt.Printf("pmt: ElementaryStreamInfos %v\n", self.ElementaryStreamInfos)
|
||||
}
|
||||
|
||||
if err = cr.ReadCrc32UIntAndCheck(); err != nil {
|
||||
if DebugReader {
|
||||
fmt.Printf("pmt: %s\n", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -416,10 +412,13 @@ func ReadPAT(r io.Reader) (self PAT, err error) {
|
||||
}
|
||||
|
||||
if err = cr.ReadCrc32UIntAndCheck(); err != nil {
|
||||
if DebugReader {
|
||||
fmt.Printf("pat: %s\n", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if debug {
|
||||
if DebugReader {
|
||||
fmt.Printf("pat: %v\n", self)
|
||||
}
|
||||
|
||||
@ -461,7 +460,7 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
if debug {
|
||||
if DebugReader {
|
||||
fmt.Printf("pes: %s\n", FieldsDumper{
|
||||
Fields: []struct{
|
||||
Length int
|
||||
@ -489,7 +488,7 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
if debug {
|
||||
if DebugReader {
|
||||
fmt.Printf("pes: %s\n", FieldsDumper{
|
||||
Fields: []struct{
|
||||
Length int
|
||||
@ -521,7 +520,7 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) {
|
||||
}
|
||||
self.PTS = PESUIntToTs(v)
|
||||
|
||||
if debug {
|
||||
if DebugReader {
|
||||
fmt.Printf("pes: pts %x=>%x %f\n",
|
||||
v, self.PTS, float64(self.PTS)/90000)
|
||||
}
|
||||
@ -533,7 +532,7 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) {
|
||||
return
|
||||
}
|
||||
self.DTS = PESUIntToTs(v)
|
||||
if debug {
|
||||
if DebugReader {
|
||||
fmt.Printf("pes: dts %d\n", self.PTS)
|
||||
}
|
||||
}
|
||||
|
2
ts.go
2
ts.go
@ -5,8 +5,6 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const debug = true
|
||||
|
||||
const (
|
||||
ElementaryStreamTypeH264 = 0x1B
|
||||
ElementaryStreamTypeAdtsAAC = 0x0F
|
||||
|
79
writer.go
79
writer.go
@ -2,16 +2,12 @@
|
||||
package ts
|
||||
|
||||
import (
|
||||
_ "fmt"
|
||||
"fmt"
|
||||
"io"
|
||||
"bytes"
|
||||
)
|
||||
|
||||
type TSWriter struct {
|
||||
W io.Writer
|
||||
ContinuityCounter uint
|
||||
PayloadUnitStart bool
|
||||
}
|
||||
const DebugWriter = true
|
||||
|
||||
func WriteUInt64(w io.Writer, val uint64, n int) (err error) {
|
||||
var b [8]byte
|
||||
@ -19,7 +15,7 @@ func WriteUInt64(w io.Writer, val uint64, n int) (err error) {
|
||||
b[i] = byte(val)
|
||||
val >>= 8
|
||||
}
|
||||
if _, err = w.Write(b[:]); err != nil {
|
||||
if _, err = w.Write(b[:n]); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
@ -108,6 +104,63 @@ func WriteTSHeader(w io.Writer, self TSHeader) (err error) {
|
||||
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) {
|
||||
// pointer(8)
|
||||
// table_id(8)
|
||||
@ -135,10 +188,14 @@ func WritePSI(w io.Writer, self PSI, data []byte) (err error) {
|
||||
var flags, length uint
|
||||
length = 2+3+4+uint(len(data))
|
||||
flags = 0xb<<10|length
|
||||
if err = WriteUInt(cw, flags, 1); err != nil {
|
||||
if err = WriteUInt(cw, flags, 2); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if DebugWriter {
|
||||
fmt.Printf("wpsi: flags=%x\n", flags)
|
||||
}
|
||||
|
||||
// Table ID extension(16)
|
||||
if err = WriteUInt(cw, self.TableIdExtension, 2); err != nil {
|
||||
return
|
||||
@ -166,13 +223,17 @@ func WritePSI(w io.Writer, self PSI, data []byte) (err error) {
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
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) {
|
||||
// http://dvd.sourceforge.net/dvdinfo/pes-hdr.html
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user