diff --git a/checksum.go b/checksum.go index 61fe192..c5ac537 100644 --- a/checksum.go +++ b/checksum.go @@ -1,13 +1,12 @@ - package ts import ( - "io" - "fmt" "encoding/hex" + "fmt" + "io" ) -var ieeeCrc32Tbl = []uint32 { +var ieeeCrc32Tbl = []uint32{ 0x00000000, 0xB71DC104, 0x6E3B8209, 0xD926430D, 0xDC760413, 0x6B6BC517, 0xB24D861A, 0x0550471E, 0xB8ED0826, 0x0FF0C922, 0xD6D68A2F, 0x61CB4B2B, 0x649B0C35, 0xD386CD31, 0x0AA08E3C, 0xBDBD4F38, 0x70DB114C, 0xC7C6D048, @@ -55,13 +54,13 @@ var ieeeCrc32Tbl = []uint32 { func updateIeeeCrc32(crc uint32, data []byte) uint32 { for _, b := range data { - crc = ieeeCrc32Tbl[b^byte(crc)]^(crc>>8) + crc = ieeeCrc32Tbl[b^byte(crc)] ^ (crc >> 8) } return crc } type Crc32Reader struct { - R io.Reader + R io.Reader Crc32 uint32 } @@ -90,7 +89,7 @@ func (self *Crc32Reader) ReadCrc32UIntAndCheck() (err error) { } type Crc32Writer struct { - W io.Writer + W io.Writer Crc32 uint32 } @@ -101,4 +100,3 @@ func (self *Crc32Writer) Write(b []byte) (n int, err error) { self.Crc32 = updateIeeeCrc32(self.Crc32, b) return } - diff --git a/checksum_test.go b/checksum_test.go index ecadf32..fc4316e 100644 --- a/checksum_test.go +++ b/checksum_test.go @@ -1,4 +1,3 @@ - package ts import ( @@ -7,8 +6,7 @@ import ( func TestChecksum(t *testing.T) { b := []byte("hello world") - b = append(b, []byte{0xbb,0x08,0xec,0x87}...) + b = append(b, []byte{0xbb, 0x08, 0xec, 0x87}...) crc := updateIeeeCrc32(0xffffffff, b) t.Logf("%x", crc) } - diff --git a/demuxer.go b/demuxer.go index 03b05ff..1af05a3 100644 --- a/demuxer.go +++ b/demuxer.go @@ -1,21 +1,20 @@ - package ts import ( - "io" "bytes" "fmt" - "github.com/nareix/mp4/isom" + "github.com/nareix/codec/aacparser" + "io" ) type Demuxer struct { R io.Reader - pat PAT - pmt *PMT - Tracks []*Track + pat PAT + pmt *PMT + Tracks []*Track TrackH264 *Track - TrackAAC *Track + TrackAAC *Track } // ParsePacket() (pid uint, counter int, isStart bool, pts, dst int64, isKeyFrame bool) @@ -33,7 +32,7 @@ func (self *Demuxer) ReadHeader() (err error) { for { if self.pmt != nil { n := 0 - for _, track := range(self.Tracks) { + for _, track := range self.Tracks { if track.payloadReady { n++ } @@ -58,7 +57,7 @@ func (self *Demuxer) ReadSample() (track *Track, err error) { } for { - for _, _track := range(self.Tracks) { + for _, _track := range self.Tracks { if _track.payloadReady { track = _track return @@ -87,13 +86,13 @@ func (self *Demuxer) readPacket() (err error) { } } else { if self.pmt == nil { - for _, entry := range(self.pat.Entries) { + for _, entry := range self.pat.Entries { if entry.ProgramMapPID == header.PID { self.pmt = new(PMT) if *self.pmt, err = ReadPMT(bytes.NewReader(payload)); err != nil { return } - for _, info := range(self.pmt.ElementaryStreamInfos) { + for _, info := range self.pmt.ElementaryStreamInfos { track := &Track{} track.demuxer = self @@ -113,7 +112,7 @@ func (self *Demuxer) readPacket() (err error) { } } else { - for _, track := range(self.Tracks) { + for _, track := range self.Tracks { if header.PID == track.pid { if err = track.appendPacket(header, payload); err != nil { return @@ -126,7 +125,7 @@ func (self *Demuxer) readPacket() (err error) { return } -func (self *Track) GetMPEG4AudioConfig() isom.MPEG4AudioConfig { +func (self *Track) GetMPEG4AudioConfig() aacparser.MPEG4AudioConfig { return self.mpeg4AudioConfig } @@ -154,7 +153,7 @@ func (self *Track) appendPayload() (err error) { if self.Type == AAC { if !self.mpeg4AudioConfig.IsValid() { - if self.mpeg4AudioConfig, _, _, _, err = isom.ReadADTSFrame(self.payload); err != nil { + if self.mpeg4AudioConfig, _, _, _, err = aacparser.ReadADTSFrame(self.payload); err != nil { return } self.mpeg4AudioConfig = self.mpeg4AudioConfig.Complete() @@ -200,4 +199,3 @@ func (self *Track) appendPacket(header TSHeader, payload []byte) (err error) { return } - diff --git a/example/test.go b/example/test.go index d86cdaa..5156ac5 100644 --- a/example/test.go +++ b/example/test.go @@ -1,52 +1,51 @@ - package main import ( - "bytes" - "os" - "io" ts "../" - "fmt" - "encoding/hex" + "bytes" "encoding/gob" - "runtime/pprof" + "encoding/hex" "flag" + "fmt" + "io" + "os" + "runtime/pprof" ) type GobAllSamples struct { TimeScale int - SPS []byte - PPS []byte - Samples []GobSample + SPS []byte + PPS []byte + Samples []GobSample } type GobSample struct { Duration int - Data []byte - Sync bool + Data []byte + Sync bool } type Stream struct { - PID uint - PESHeader *ts.PESHeader + PID uint + PESHeader *ts.PESHeader FirstTSHeader ts.TSHeader - Title string - Data bytes.Buffer - Type uint - PCR uint64 + Title string + Data bytes.Buffer + Type uint + PCR uint64 } type Sample struct { - Type uint - PCR uint64 - PTS uint64 - DTS uint64 - Data []byte + Type uint + PCR uint64 + PTS uint64 + DTS uint64 + Data []byte RandomAccessIndicator bool } var ( - debugData = true + debugData = true debugStream = true ) @@ -75,7 +74,7 @@ func readSamples(filename string, ch chan Sample) { stream, _ = streams[pid] if stream == nil { stream = &Stream{ - PID: pid, + PID: pid, Type: info.StreamType, } if stream.Type == ts.ElementaryStreamTypeH264 { @@ -99,9 +98,9 @@ func readSamples(filename string, ch chan Sample) { ch <- Sample{ Type: stream.Type, Data: stream.Data.Bytes(), - PTS: stream.PESHeader.PTS, - DTS: stream.PESHeader.DTS, - PCR: stream.FirstTSHeader.PCR, + PTS: stream.PESHeader.PTS, + DTS: stream.PESHeader.DTS, + PCR: stream.FirstTSHeader.PCR, RandomAccessIndicator: stream.FirstTSHeader.RandomAccessIndicator, } } @@ -157,7 +156,7 @@ func readSamples(filename string, ch chan Sample) { } } - for _, entry := range(pat.Entries) { + for _, entry := range pat.Entries { if entry.ProgramMapPID == header.PID { //fmt.Println("matchs", entry) if pmt, err = ts.ReadPMT(pr); err != nil { @@ -167,7 +166,7 @@ func readSamples(filename string, ch chan Sample) { } } - for _, info = range(pmt.ElementaryStreamInfos) { + for _, info = range pmt.ElementaryStreamInfos { if info.ElementaryPID == header.PID { onStreamPayload() } @@ -231,7 +230,7 @@ func testInputGob(pathGob string, pathOut string, testSeg bool, writeM3u8 bool) if sample.Sync { syncCount++ if testSeg { - if syncCount % 3 == 0 { + if syncCount%3 == 0 { filename := fmt.Sprintf("%s.seg%d.ts", pathOut, segCount) if debugStream { @@ -241,7 +240,7 @@ func testInputGob(pathGob string, pathOut string, testSeg bool, writeM3u8 bool) if m3u8file != nil { info, _ := outfile.Stat() size := info.Size() - dur := float64(trackH264.PTS - lastPTS) / float64(allSamples.TimeScale) + dur := float64(trackH264.PTS-lastPTS) / float64(allSamples.TimeScale) writeM3U8Item(m3u8file, lastFilename, size, dur) } @@ -353,8 +352,8 @@ func main() { pes := ts.PESHeader{ StreamId: streamId, - PTS: sample.PTS, - DTS: sample.DTS, + PTS: sample.PTS, + DTS: sample.DTS, } w.PID = pid w.PCR = sample.PCR @@ -369,7 +368,7 @@ func main() { writePAT() writePMT() w = &ts.TSWriter{ - W: file, + W: file, PID: 0x100, } w.EnableVecWriter() @@ -395,4 +394,3 @@ func main() { } } - diff --git a/muxer.go b/muxer.go index 94b4641..2503933 100644 --- a/muxer.go +++ b/muxer.go @@ -1,21 +1,20 @@ - package ts import ( "bytes" "fmt" - "io" - "github.com/nareix/mp4/isom" "github.com/nareix/codec/h264parser" + "github.com/nareix/codec/aacparser" + "io" ) type Muxer struct { - W io.Writer - tswPAT *TSWriter - tswPMT *TSWriter + W io.Writer + tswPAT *TSWriter + tswPMT *TSWriter elemStreams []ElementaryStreamInfo - TrackH264 *Track - Tracks []*Track + TrackH264 *Track + Tracks []*Track } func (self *Muxer) newTrack(pid uint, streamId uint) (track *Track) { @@ -66,7 +65,7 @@ func (self *Muxer) WriteHeader() (err error) { } WritePAT(bufPAT, pat) pmt := PMT{ - PCRPID: 0x100, + PCRPID: 0x100, ElementaryStreamInfos: self.elemStreams, } WritePMT(bufPMT, pmt) @@ -87,7 +86,7 @@ func (self *Muxer) WriteHeader() (err error) { } // about to remove - for _, track := range(self.Tracks) { + for _, track := range self.Tracks { track.spsHasWritten = false } @@ -106,20 +105,20 @@ func (self *Track) TimeScale() int64 { return self.timeScale } -func (self *Track) SetMPEG4AudioConfig(config isom.MPEG4AudioConfig) { +func (self *Track) SetMPEG4AudioConfig(config aacparser.MPEG4AudioConfig) { self.mpeg4AudioConfig = config } func (self *Track) tsToPesTs(ts int64) uint64 { - return uint64(ts)*PTS_HZ/uint64(self.timeScale)+PTS_HZ + return uint64(ts)*PTS_HZ/uint64(self.timeScale) + PTS_HZ } func (self *Track) tsToPCR(ts int64) uint64 { - return uint64(ts)*PCR_HZ/uint64(self.timeScale)+PCR_HZ + return uint64(ts)*PCR_HZ/uint64(self.timeScale) + PCR_HZ } func (self *Track) tsToTime(ts int64) float64 { - return float64(ts)/float64(self.timeScale) + return float64(ts) / float64(self.timeScale) } func (self *Track) WriteSample(pts int64, dts int64, isKeyFrame bool, data []byte) (err error) { @@ -129,8 +128,8 @@ func (self *Track) WriteSample(pts int64, dts int64, isKeyFrame bool, data []byt if self.Type == AAC { - if !isom.IsADTSFrame(data) { - data = append(isom.MakeADTSHeader(self.mpeg4AudioConfig, 1024, len(data)), data...) + if !aacparser.IsADTSFrame(data) { + data = append(aacparser.MakeADTSHeader(self.mpeg4AudioConfig, 1024, len(data)), data...) } if false { fmt.Printf("WriteSample=%x\n", data[:5]) @@ -139,7 +138,7 @@ func (self *Track) WriteSample(pts int64, dts int64, isKeyFrame bool, data []byt buf := &bytes.Buffer{} pes := PESHeader{ StreamId: self.streamId, - PTS: self.tsToPesTs(pts), + PTS: self.tsToPesTs(pts), } WritePESHeader(buf, pes, len(data)) buf.Write(data) @@ -154,7 +153,7 @@ func (self *Track) WriteSample(pts int64, dts int64, isKeyFrame bool, data []byt buf := &bytes.Buffer{} pes := PESHeader{ StreamId: self.streamId, - PTS: self.tsToPesTs(pts), + PTS: self.tsToPesTs(pts), } if dts != pts { pes.DTS = self.tsToPesTs(dts) @@ -182,17 +181,17 @@ func (self *Track) WriteSample(pts int64, dts int64, isKeyFrame bool, data []byt /* about to remove */ func (self *Track) setPCR() { - self.tsw.PCR = uint64(self.PTS)*PCR_HZ/uint64(self.timeScale) + self.tsw.PCR = uint64(self.PTS) * PCR_HZ / uint64(self.timeScale) } -func (self *Track) getPesHeader(dataLength int) (data []byte){ +func (self *Track) getPesHeader(dataLength int) (data []byte) { if self.PTS == 0 { self.PTS = self.timeScale } buf := &bytes.Buffer{} pes := PESHeader{ StreamId: self.streamId, - PTS: uint64(self.PTS)*PTS_HZ/uint64(self.timeScale), + PTS: uint64(self.PTS) * PTS_HZ / uint64(self.timeScale), } WritePESHeader(buf, pes, dataLength) return buf.Bytes() @@ -216,9 +215,9 @@ func (self *Track) WriteH264NALU(sync bool, duration int, nalu []byte) (err erro for i, nalu := range nalus { var startCode []byte if i == 0 { - startCode = []byte{0,0,0,1,0x9,0xf0,0,0,0,1} // AUD + startCode = []byte{0, 0, 0, 1, 0x9, 0xf0, 0, 0, 0, 1} // AUD } else { - startCode = []byte{0,0,1} + startCode = []byte{0, 0, 1} } data.Append(startCode) data.Append(nalu) @@ -252,4 +251,3 @@ func (self *Track) WriteADTSAACFrame(duration int, frame []byte) (err error) { self.incPTS(duration) return } - diff --git a/reader.go b/reader.go index dfd01a6..a4d36c9 100644 --- a/reader.go +++ b/reader.go @@ -1,4 +1,3 @@ - package ts import ( @@ -32,7 +31,7 @@ func ReadUInt64(r io.Reader, n int) (res uint64, err error) { if res32, err = ReadUInt(r, n-4); err != nil { return } - res |= uint64(res32)<<32 + res |= uint64(res32) << 32 n = 4 } if res32, err = ReadUInt(r, n); err != nil { @@ -59,9 +58,9 @@ func ReadTSHeader(r io.Reader) (self TSHeader, err error) { if DebugReader { fmt.Printf("ts: flags %s\n", FieldsDumper{ - Fields: []struct{ + Fields: []struct { Length int - Desc string + Desc string }{ {8, "sync"}, {1, "transport_error_indicator"}, @@ -73,17 +72,17 @@ func ReadTSHeader(r io.Reader) (self TSHeader, err error) { {1, "payload_flag"}, {4, "continuity_counter"}, }, - Val: flags, + Val: flags, Length: 32, }) } - if flags & 0x400000 != 0 { + if flags&0x400000 != 0 { // When set to '1' it indicates that this TS packet contains the first PES packet. self.PayloadUnitStart = true } - if (flags & 0xff000000) >> 24 != 0x47 { + if (flags&0xff000000)>>24 != 0x47 { err = fmt.Errorf("invalid sync") return } @@ -91,7 +90,7 @@ func ReadTSHeader(r io.Reader) (self TSHeader, err error) { self.PID = (flags & 0x1fff00) >> 8 self.ContinuityCounter = flags & 0xf - if flags & 0x20 != 0 { + if flags&0x20 != 0 { var flags, length uint if length, err = ReadUInt(r, 1); err != nil { return @@ -104,9 +103,9 @@ func ReadTSHeader(r io.Reader) (self TSHeader, err error) { if DebugReader { fmt.Printf("ts: ext_flags %s\n", FieldsDumper{ - Fields: []struct{ + Fields: []struct { Length int - Desc string + Desc string }{ {1, "discontinuity_indicator"}, {1, "random_access_indicator"}, @@ -117,18 +116,18 @@ func ReadTSHeader(r io.Reader) (self TSHeader, err error) { {1, "transport_private_data_flag"}, {1, "adaptation_field_extension_flag"}, }, - Val: flags, + Val: flags, Length: 8, }) } // random_access_indicator - if flags & 0x40 != 0 { + if flags&0x40 != 0 { self.RandomAccessIndicator = true } // PCR - if flags & 0x10 != 0 { + if flags&0x10 != 0 { var v uint64 if v, err = ReadUInt64(lr, 6); err != nil { return @@ -141,7 +140,7 @@ func ReadTSHeader(r io.Reader) (self TSHeader, err error) { } // OPCR - if flags & 0x08 != 0 { + if flags&0x08 != 0 { var v uint64 if v, err = ReadUInt64(lr, 6); err != nil { return @@ -150,14 +149,14 @@ func ReadTSHeader(r io.Reader) (self TSHeader, err error) { } // Splice countdown - if flags & 0x04 != 0 { + if flags&0x04 != 0 { if _, err = ReadUInt(lr, 1); err != nil { return } } // Transport private data - if flags & 0x02 != 0 { + if flags&0x02 != 0 { var length uint if length, err = ReadUInt(lr, 1); err != nil { return @@ -212,7 +211,6 @@ func ReadPSI(r io.Reader) (self PSI, lr *io.LimitedReader, cr *Crc32Reader, err fmt.Printf("psi: pointer=%d\n", pointer) } - if pointer != 0 { if err = ReadDummy(r, int(pointer)); err != nil { return @@ -253,15 +251,15 @@ func ReadPSI(r io.Reader) (self PSI, lr *io.LimitedReader, cr *Crc32Reader, err if DebugReader { fmt.Printf("psi: %s\n", FieldsDumper{ - Fields: []struct{ + Fields: []struct { Length int - Desc string + Desc string }{ {2, "resverd"}, {5, "version"}, {1, "current_next_indicator"}, }, - Val: flags, + Val: flags, Length: 8, }) } @@ -328,14 +326,14 @@ func ReadPMT(r io.Reader) (self PMT, err error) { if DebugReader { fmt.Printf("pmt: %s\n", FieldsDumper{ - Fields: []struct{ + Fields: []struct { Length int - Desc string + Desc string }{ {3, "reserved"}, {13, "pcrpid"}, }, - Val: flags, + Val: flags, Length: 16, }) } @@ -374,14 +372,14 @@ func ReadPMT(r io.Reader) (self PMT, err error) { if DebugReader { fmt.Printf("pmt: info1 %s\n", FieldsDumper{ - Fields: []struct{ + Fields: []struct { Length int - Desc string + Desc string }{ {3, "reserved"}, {13, "elementary_pid"}, }, - Val: flags, + Val: flags, Length: 16, }) } @@ -395,14 +393,14 @@ func ReadPMT(r io.Reader) (self PMT, err error) { if DebugReader { fmt.Printf("pmt: info2 %s\n", FieldsDumper{ - Fields: []struct{ + Fields: []struct { Length int - Desc string + Desc string }{ {6, "reserved"}, {10, "es_info_length"}, }, - Val: flags, + Val: flags, Length: 16, }) } @@ -500,7 +498,7 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) { } if length == 0 { - length = 1<<31 + length = 1 << 31 } lrAll := &io.LimitedReader{R: r, N: int64(length)} lr := lrAll @@ -517,9 +515,9 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) { if DebugReader { fmt.Printf("pes: %s\n", FieldsDumper{ - Fields: []struct{ + Fields: []struct { Length int - Desc string + Desc string }{ {2, "scrambling_control"}, {1, "priority"}, @@ -527,7 +525,7 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) { {1, "copyright"}, {1, "original_or_copy"}, }, - Val: flags, + Val: flags, Length: 6, }) } @@ -545,9 +543,9 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) { if DebugReader { fmt.Printf("pes: %s\n", FieldsDumper{ - Fields: []struct{ + Fields: []struct { Length int - Desc string + Desc string }{ {2, "pts_dts_flags"}, {1, "escr_flag"}, @@ -557,7 +555,7 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) { {1, "pes_crc_flag"}, {1, "pes_extension_flag"}, }, - Val: flags, + Val: flags, Length: 8, }) } @@ -568,7 +566,7 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) { } lr = &io.LimitedReader{R: lr, N: int64(length)} - if flags & 0x80 != 0 { + if flags&0x80 != 0 { var v uint64 if v, err = ReadUInt64(lr, 5); err != nil { return @@ -580,7 +578,7 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) { } } - if flags & 0x40 != 0 && flags & 0x80 != 0 { + if flags&0x40 != 0 && flags&0x80 != 0 { var v uint64 if v, err = ReadUInt64(lr, 5); err != nil { return @@ -592,35 +590,35 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) { } // ESCR flag - if flags & 0x20 != 0 { + if flags&0x20 != 0 { if _, err = ReadUInt64(lr, 6); err != nil { return } } // ES rate flag - if flags & 0x10 != 0 { + if flags&0x10 != 0 { if _, err = ReadUInt64(lr, 3); err != nil { return } } // additional copy info flag - if flags & 0x04 != 0 { + if flags&0x04 != 0 { if _, err = ReadUInt(lr, 1); err != nil { return } } // PES CRC flag - if flags & 0x02 != 0 { + if flags&0x02 != 0 { if _, err = ReadUInt(lr, 2); err != nil { return } } // PES extension flag - if flags & 0x01 != 0 { + if flags&0x01 != 0 { var flags uint // PES private data flag(1) @@ -634,7 +632,7 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) { } // PES private data flag(1) - if flags & 0x80 != 0 { + if flags&0x80 != 0 { // if set to 1 16 bytes of user defined data is appended to the header data field if err = ReadDummy(lr, 16); err != nil { return @@ -642,7 +640,7 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) { } // pack header field flag(1) - if flags & 0x40 != 0 { + if flags&0x40 != 0 { // if set to 1 the 8-bit pack field length value is appended to the header data field if err = ReadDummy(lr, 1); err != nil { return @@ -650,21 +648,21 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) { } // program packet sequence counter flag(1) - if flags & 0x20 != 0 { + if flags&0x20 != 0 { if err = ReadDummy(lr, 2); err != nil { return } } // P-STD buffer flag(1) - if flags & 0x10 != 0 { + if flags&0x10 != 0 { if err = ReadDummy(lr, 2); err != nil { return } } // PES extension flag 2(1) - if flags & 0x01 != 0 { + if flags&0x01 != 0 { if err = ReadDummy(lr, 2); err != nil { return } @@ -684,4 +682,3 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) { res = self return } - diff --git a/track.go b/track.go index cb407cf..23e34d8 100644 --- a/track.go +++ b/track.go @@ -1,9 +1,8 @@ - package ts import ( "bytes" - "github.com/nareix/mp4/isom" + "github.com/nareix/codec/aacparser" ) type Track struct { @@ -12,28 +11,27 @@ type Track struct { Type int - pid uint - PTS int64 + pid uint + PTS int64 timeScale int64 - mpeg4AudioConfig isom.MPEG4AudioConfig - buf bytes.Buffer - payload []byte - peshdr *PESHeader - tshdr TSHeader - spsHasWritten bool - payloadReady bool + mpeg4AudioConfig aacparser.MPEG4AudioConfig + buf bytes.Buffer + payload []byte + peshdr *PESHeader + tshdr TSHeader + spsHasWritten bool + payloadReady bool - demuxer *Demuxer - mux *Muxer - streamId uint - tsw *TSWriter - dataBuf *iovec + demuxer *Demuxer + mux *Muxer + streamId uint + tsw *TSWriter + dataBuf *iovec cacheSize int } const ( H264 = 1 - AAC = 2 + AAC = 2 ) - diff --git a/ts.go b/ts.go index 3c9ec2d..1019f14 100644 --- a/ts.go +++ b/ts.go @@ -1,4 +1,3 @@ - package ts import ( @@ -6,24 +5,24 @@ import ( ) const ( - ElementaryStreamTypeH264 = 0x1B + ElementaryStreamTypeH264 = 0x1B ElementaryStreamTypeAdtsAAC = 0x0F ) type TSHeader struct { - PID uint - PCR uint64 - OPCR uint64 - ContinuityCounter uint - PayloadUnitStart bool + PID uint + PCR uint64 + OPCR uint64 + ContinuityCounter uint + PayloadUnitStart bool DiscontinuityIndicator bool - RandomAccessIndicator bool - HeaderLength uint + RandomAccessIndicator bool + HeaderLength uint } type PATEntry struct { ProgramNumber uint - NetworkPID uint + NetworkPID uint ProgramMapPID uint } @@ -32,45 +31,45 @@ type PAT struct { } type PMT struct { - PCRPID uint - ProgramDescriptors []Descriptor + PCRPID uint + ProgramDescriptors []Descriptor ElementaryStreamInfos []ElementaryStreamInfo } type Descriptor struct { - Tag uint + Tag uint Data []byte } type ElementaryStreamInfo struct { - StreamType uint + StreamType uint ElementaryPID uint - Descriptors []Descriptor + Descriptors []Descriptor } type PSI struct { TableIdExtension uint - TableId uint - SecNum uint - LastSecNum uint + TableId uint + SecNum uint + LastSecNum uint } const ( StreamIdH264 = 0xe0 - StreamIdAAC = 0xc0 + StreamIdAAC = 0xc0 ) type PESHeader struct { - StreamId uint // H264=0xe0 AAC=0xc0 + StreamId uint // H264=0xe0 AAC=0xc0 DataLength uint - PTS uint64 - DTS uint64 - ESCR uint64 + PTS uint64 + DTS uint64 + ESCR uint64 } func PESUIntToTs(v uint64) (ts uint64) { // 0010 PTS 32..30 1 PTS 29..15 1 PTS 14..00 1 - return (((v>>33)&0x7)<<30) | (((v>>17)&0x7fff)<<15) | ((v>>1)&0x7fff) + return (((v >> 33) & 0x7) << 30) | (((v >> 17) & 0x7fff) << 15) | ((v >> 1) & 0x7fff) } func PESTsToUInt(ts uint64) (v uint64) { @@ -85,23 +84,23 @@ const ( func UIntToPCR(v uint64) uint64 { // base(33)+resverd(6)+ext(9) - base := v>>15 - ext := v&0x1ff - return base*300+ext + base := v >> 15 + ext := v & 0x1ff + return base*300 + ext } func PCRToUInt(pcr uint64) uint64 { - base := pcr/300 - ext := pcr%300 - return base<<15|0x3f<<9|ext + base := pcr / 300 + ext := pcr % 300 + return base<<15 | 0x3f<<9 | ext } type FieldsDumper struct { Fields []struct { Length int - Desc string + Desc string } - Val uint + Val uint Length uint } @@ -109,11 +108,10 @@ func (self FieldsDumper) String() (res string) { pos := uint(self.Length) for _, field := range self.Fields { pos -= uint(field.Length) - val := (self.Val>>pos)&(1<> pos) & (1<= 0; i-- { + for i := n - 1; i >= 0; i-- { b[i] = byte(val) val >>= 8 } @@ -51,13 +50,13 @@ func WriteTSHeader(w io.Writer, self TSHeader, dataLength int) (written int, err // Payload flag(1) 0x10 // Continuity counter(4) - flags = 0x47<<24 + flags = 0x47 << 24 flags |= 0x10 if self.PayloadUnitStart { flags |= 0x400000 } - flags |= (self.PID&0x1fff)<<8 - flags |= self.ContinuityCounter&0xf + flags |= (self.PID & 0x1fff) << 8 + flags |= self.ContinuityCounter & 0xf if DebugWriter { fmt.Printf("tsw: pid=%x\n", self.PID) @@ -94,26 +93,26 @@ func WriteTSHeader(w io.Writer, self TSHeader, dataLength int) (written int, err } written += 4 - if flags & EXT != 0 { + if flags&EXT != 0 { var length uint - // Discontinuity indicator 1 0x80 - // Random Access indicator 1 0x40 - // Elementary stream priority indicator 1 0x20 + // Discontinuity indicator 1 0x80 + // Random Access indicator 1 0x40 + // Elementary stream priority indicator 1 0x20 // PCR flag 1 0x10 - // OPCR flag 1 0x08 + // OPCR flag 1 0x08 length = 1 // extFlags - if extFlags & PCR != 0 { + if extFlags&PCR != 0 { length += 6 } - if extFlags & OPCR != 0 { + if extFlags&OPCR != 0 { length += 6 } paddingLength := 0 // need padding - if int(length) + 5 + dataLength < 188 { + if int(length)+5+dataLength < 188 { paddingLength = 188 - dataLength - 5 - int(length) length = 188 - uint(dataLength) - 5 } @@ -129,13 +128,13 @@ func WriteTSHeader(w io.Writer, self TSHeader, dataLength int) (written int, err return } - if extFlags & PCR != 0 { + if extFlags&PCR != 0 { if err = WriteUInt64(w, PCRToUInt(self.PCR), 6); err != nil { return } } - if extFlags & OPCR != 0 { + if extFlags&OPCR != 0 { if err = WriteUInt64(w, PCRToUInt(self.OPCR), 6); err != nil { return } @@ -147,17 +146,17 @@ func WriteTSHeader(w io.Writer, self TSHeader, dataLength int) (written int, err } } - written += int(length)+1 + written += int(length) + 1 } return } type TSWriter struct { - W io.Writer + W io.Writer PID uint TSHeader - DisableHeaderPadding bool + DisableHeaderPadding bool DiscontinuityIndicator bool vecw *vecWriter @@ -192,8 +191,8 @@ func (self *TSWriter) WriteIovec(data *iovec) (err error) { func (self *TSWriter) WriteIovecTo(w io.Writer, data *iovec) (err error) { for i := 0; data.Len > 0; i++ { header := TSHeader{ - PID: self.PID, - ContinuityCounter: self.ContinuityCounter, + PID: self.PID, + ContinuityCounter: self.ContinuityCounter, DiscontinuityIndicator: self.DiscontinuityIndicator, } @@ -214,7 +213,7 @@ func (self *TSWriter) WriteIovecTo(w io.Writer, data *iovec) (err error) { } payloadLength := 188 - headerLength if self.DisableHeaderPadding && data.Len < payloadLength { - data.Append(makeRepeatValBytes(0xff, payloadLength - data.Len)) + data.Append(makeRepeatValBytes(0xff, payloadLength-data.Len)) } if DebugWriter { @@ -267,8 +266,8 @@ func WritePSI(w io.Writer, self PSI, data []byte) (err error) { // section_syntax_indicator(1)=1,private_bit(1)=0,reserved(2)=3,unused(2)=0,section_length(10) var flags, length uint - length = 2+3+4+uint(len(data)) - flags = 0xa<<12|length + length = 2 + 3 + 4 + uint(len(data)) + flags = 0xa<<12 | length if err = WriteUInt(cw, flags, 2); err != nil { return } @@ -283,7 +282,7 @@ func WritePSI(w io.Writer, self PSI, data []byte) (err error) { } // resverd(2)=3,version(5)=0,Current_next_indicator(1)=1 - flags = 0x3<<6|1 + flags = 0x3<<6 | 1 if err = WriteUInt(cw, flags, 1); err != nil { return } @@ -312,7 +311,7 @@ func WritePSI(w io.Writer, self PSI, data []byte) (err error) { } func bswap32(v uint) uint { - return (v>>24)|((v>>16)&0xff)<<8|((v>>8)&0xff)<<16|(v&0xff)<<24 + return (v >> 24) | ((v>>16)&0xff)<<8 | ((v>>8)&0xff)<<16 | (v&0xff)<<24 } func WritePESHeader(w io.Writer, self PESHeader, dataLength int) (err error) { @@ -340,8 +339,8 @@ func WritePESHeader(w io.Writer, self PESHeader, dataLength int) (err error) { return } - const PTS = 1<<7 - const DTS = 1<<6 + const PTS = 1 << 7 + const DTS = 1 << 6 if self.PTS != 0 { pts_dts_flags |= PTS @@ -350,10 +349,10 @@ func WritePESHeader(w io.Writer, self PESHeader, dataLength int) (err error) { } } - if pts_dts_flags & PTS != 0 { + if pts_dts_flags&PTS != 0 { header_length += 5 } - if pts_dts_flags & DTS != 0 { + if pts_dts_flags&DTS != 0 { header_length += 5 } @@ -361,8 +360,8 @@ func WritePESHeader(w io.Writer, self PESHeader, dataLength int) (err error) { packet_length = uint(dataLength) + header_length + 3 } // packet_length(16) if zero then variable length - // Specifies the number of bytes remaining in the packet after this field. Can be zero. - // If the PES packet length is set to zero, the PES packet can be of any length. + // Specifies the number of bytes remaining in the packet after this field. Can be zero. + // If the PES packet length is set to zero, the PES packet can be of any length. // A value of zero for the PES packet length can be used only when the PES packet payload is a video elementary stream. if err = WriteUInt(w, packet_length, 2); err != nil { return @@ -385,8 +384,8 @@ func WritePESHeader(w io.Writer, self PESHeader, dataLength int) (err error) { // pts(40)? // dts(40)? - if pts_dts_flags & PTS != 0 { - if pts_dts_flags & DTS != 0 { + if pts_dts_flags&PTS != 0 { + if pts_dts_flags&DTS != 0 { if err = WriteUInt64(w, PESTsToUInt(self.PTS)|3<<36, 5); err != nil { return } @@ -447,8 +446,8 @@ func WritePAT(w io.Writer, self PAT) (err error) { func WritePATPacket(w io.Writer, pat PAT) (err error) { tsw := &TSWriter{ - W: w, - PID: 0, + W: w, + PID: 0, DisableHeaderPadding: true, } bw := &bytes.Buffer{} @@ -529,8 +528,8 @@ func WritePMT(w io.Writer, self PMT) (err error) { return } - psi := PSI { - TableId: 2, + psi := PSI{ + TableId: 2, TableIdExtension: 1, } if err = WritePSI(w, psi, bw.Bytes()); err != nil { @@ -542,8 +541,8 @@ func WritePMT(w io.Writer, self PMT) (err error) { func WritePMTPacket(w io.Writer, pmt PMT, pid uint) (err error) { tsw := &TSWriter{ - W: w, - PID: pid, + W: w, + PID: pid, DisableHeaderPadding: true, } bw := &bytes.Buffer{} @@ -557,14 +556,14 @@ func WritePMTPacket(w io.Writer, pmt PMT, pid uint) (err error) { } type SimpleH264Writer struct { - W io.Writer + W io.Writer TimeScale int SPS []byte PPS []byte - tswPAT *TSWriter - tswPMT *TSWriter + tswPAT *TSWriter + tswPMT *TSWriter tswH264 *TSWriter PTS int64 @@ -668,7 +667,7 @@ func (self *SimpleH264Writer) WriteNALU(sync bool, duration int, nalu []byte) (e pes := PESHeader{ StreamId: StreamIdH264, - PTS: uint64(self.PTS)*PTS_HZ/uint64(self.TimeScale), + PTS: uint64(self.PTS) * PTS_HZ / uint64(self.TimeScale), } if err = WritePESHeader(self.pesBuf, pes, 0); err != nil { return @@ -679,16 +678,16 @@ func (self *SimpleH264Writer) WriteNALU(sync bool, duration int, nalu []byte) (e for i, nalu := range nalus { var startCode []byte if i == 0 { - startCode = []byte{0,0,0,1,0x9,0xf0,0,0,0,1} // AUD + startCode = []byte{0, 0, 0, 1, 0x9, 0xf0, 0, 0, 0, 1} // AUD } else { - startCode = []byte{0,0,1} + startCode = []byte{0, 0, 1} } data.Append(startCode) data.Append(nalu) } self.tswH264.RandomAccessIndicator = sync - self.tswH264.PCR = uint64(self.PCR)*PCR_HZ/uint64(self.TimeScale) + self.tswH264.PCR = uint64(self.PCR) * PCR_HZ / uint64(self.TimeScale) self.tswH264.W = self.W if err = self.tswH264.WriteIovec(data); err != nil { @@ -701,4 +700,3 @@ func (self *SimpleH264Writer) WriteNALU(sync bool, duration int, nalu []byte) (e return } - diff --git a/writer_test.go b/writer_test.go index 3439b87..5450006 100644 --- a/writer_test.go +++ b/writer_test.go @@ -1,19 +1,17 @@ - package ts import ( - "testing" - "encoding/hex" "bytes" + "encoding/hex" + "testing" ) func TestWriteTSHeader(t *testing.T) { bw := &bytes.Buffer{} w := &TSWriter{ - W: bw, + W: bw, PCR: 0x12345678, } - w.Write([]byte{'h','e','l','o'}[:], false) + w.Write([]byte{'h', 'e', 'l', 'o'}[:], false) t.Logf("\n%s", hex.Dump(bw.Bytes())) } -