From 2dea41f479364ec97b3f5f9e122139cc0aeb75c1 Mon Sep 17 00:00:00 2001 From: nareix Date: Thu, 14 Jul 2016 00:33:57 +0800 Subject: [PATCH] rewrite handler codec types logic, rm ts unused files --- av/avconv/avconv.go | 10 +- av/avutil/avutil.go | 28 ++-- format/aac/aac.go | 6 +- format/flv/flv.go | 11 +- format/mp4/handler.go | 6 + format/mp4/muxer.go | 4 - format/rtmp/rtmp.go | 10 +- format/ts/README.md | 2 - format/ts/doc.txt | 52 ------- format/ts/handler.go | 4 + format/ts/muxer.go | 10 +- format/ts/reader.go | 297 --------------------------------------- format/ts/stream.go | 1 - format/ts/ts.go | 40 +----- format/ts/ts_test.go | 9 -- format/ts/vecio.go | 135 ------------------ format/ts/writer.go | 11 -- format/ts/writer_test.go | 17 --- 18 files changed, 51 insertions(+), 602 deletions(-) delete mode 100644 format/ts/README.md delete mode 100644 format/ts/doc.txt delete mode 100644 format/ts/ts_test.go delete mode 100644 format/ts/vecio.go delete mode 100644 format/ts/writer_test.go diff --git a/av/avconv/avconv.go b/av/avconv/avconv.go index d51bcbf..b2f6faa 100644 --- a/av/avconv/avconv.go +++ b/av/avconv/avconv.go @@ -171,17 +171,13 @@ func ConvertCmdline(args []string) (err error) { } defer demuxer.Close() - if muxer, err = avutil.Create(output); err != nil { + var handler avutil.RegisterHandler + if handler, muxer, err = avutil.DefaultHandlers.FindCreate(output); err != nil { return } defer muxer.Close() - type intf interface { - SupportedCodecTypes() []av.CodecType - } - if fn, ok := muxer.(intf); ok { - options.OutputCodecTypes = fn.SupportedCodecTypes() - } + options.OutputCodecTypes = handler.CodecTypes convdemux := &Demuxer{ Options: options, diff --git a/av/avutil/avutil.go b/av/avutil/avutil.go index a9a86f4..e4a2085 100644 --- a/av/avutil/avutil.go +++ b/av/avutil/avutil.go @@ -11,22 +11,22 @@ import ( "path" ) -type handlerDemuxer struct { +type HandlerDemuxer struct { av.Demuxer r io.ReadCloser } -func (self *handlerDemuxer) Close() error { +func (self *HandlerDemuxer) Close() error { return self.r.Close() } -type handlerMuxer struct { +type HandlerMuxer struct { av.Muxer w io.WriteCloser stage int } -func (self *handlerMuxer) WriteHeader(streams []av.CodecData) (err error) { +func (self *HandlerMuxer) WriteHeader(streams []av.CodecData) (err error) { if self.stage == 0 { if err = self.Muxer.WriteHeader(streams); err != nil { return @@ -36,7 +36,7 @@ func (self *handlerMuxer) WriteHeader(streams []av.CodecData) (err error) { return } -func (self *handlerMuxer) WriteTrailer() (err error) { +func (self *HandlerMuxer) WriteTrailer() (err error) { if self.stage == 1 { if err = self.Muxer.WriteTrailer(); err != nil { return @@ -46,7 +46,7 @@ func (self *handlerMuxer) WriteTrailer() (err error) { return } -func (self *handlerMuxer) Close() (err error) { +func (self *HandlerMuxer) Close() (err error) { if err = self.WriteTrailer(); err != nil { return } @@ -64,6 +64,7 @@ type RegisterHandler struct { AudioDecoder func(av.AudioCodecData)(av.AudioDecoder,error) ServerDemuxer func(string)(bool,av.DemuxCloser,error) ServerMuxer func(string)(bool,av.MuxCloser,error) + CodecTypes []av.CodecType } type Handlers struct { @@ -163,7 +164,7 @@ func (self *Handlers) Open(uri string) (demuxer av.DemuxCloser, err error) { if r, err = self.openUrl(u, uri); err != nil { return } - demuxer = &handlerDemuxer{ + demuxer = &HandlerDemuxer{ Demuxer: handler.ReaderDemuxer(r), r: r, } @@ -183,7 +184,7 @@ func (self *Handlers) Open(uri string) (demuxer av.DemuxCloser, err error) { for _, handler := range self.handlers { if handler.Probe != nil && handler.Probe(probebuf[:]) && handler.ReaderDemuxer != nil { - demuxer = &handlerDemuxer{ + demuxer = &HandlerDemuxer{ Demuxer: handler.ReaderDemuxer(io.MultiReader(bytes.NewReader(probebuf[:]), r)), r: r, } @@ -197,13 +198,18 @@ func (self *Handlers) Open(uri string) (demuxer av.DemuxCloser, err error) { } func (self *Handlers) Create(uri string) (muxer av.MuxCloser, err error) { + _, muxer, err = self.FindCreate(uri) + return +} + +func (self *Handlers) FindCreate(uri string) (handler RegisterHandler, muxer av.MuxCloser, err error) { listen := false if strings.HasPrefix(uri, "listen:") { uri = uri[len("listen:"):] listen = true } - for _, handler := range self.handlers { + for _, handler = range self.handlers { if listen { if handler.ServerMuxer != nil { var ok bool @@ -223,13 +229,13 @@ func (self *Handlers) Create(uri string) (muxer av.MuxCloser, err error) { } if ext != "" { - for _, handler := range self.handlers { + for _, handler = range self.handlers { if handler.Ext == ext && handler.WriterMuxer != nil { var w io.WriteCloser if w, err = self.createUrl(u, uri); err != nil { return } - muxer = &handlerMuxer{ + muxer = &HandlerMuxer{ Muxer: handler.WriterMuxer(w), w: w, } diff --git a/format/aac/aac.go b/format/aac/aac.go index 42c19f6..0ddce3b 100644 --- a/format/aac/aac.go +++ b/format/aac/aac.go @@ -24,10 +24,6 @@ func NewMuxer(w io.Writer) *Muxer { } } -func (self *Muxer) SupportedCodecTypes() []av.CodecType { - return []av.CodecType{av.AAC} -} - func (self *Muxer) WriteHeader(streams []av.CodecData) (err error) { if len(streams) > 1 || streams[0].Type() != av.AAC { err = fmt.Errorf("aac: must be only one aac stream") @@ -120,4 +116,6 @@ func Handler(h *avutil.RegisterHandler) { _, _, _, _, err := aacparser.ParseADTSHeader(b) return err == nil } + + h.CodecTypes = []av.CodecType{av.AAC} } diff --git a/format/flv/flv.go b/format/flv/flv.go index ac23a9e..779732b 100644 --- a/format/flv/flv.go +++ b/format/flv/flv.go @@ -281,11 +281,7 @@ func NewMuxer(w io.Writer) *Muxer { return self } -var SupportedCodecTypes = []av.CodecType{av.H264, av.AAC, av.SPEEX} - -func (self *Muxer) SupportedCodecTypes() []av.CodecType { - return SupportedCodecTypes -} +var CodecTypes = []av.CodecType{av.H264, av.AAC, av.SPEEX} func (self *Muxer) WriteHeader(streams []av.CodecData) (err error) { var flags uint8 @@ -420,12 +416,17 @@ func Handler(h *avutil.RegisterHandler) { h.Probe = func(b []byte) bool { return b[0] == 'F' && b[1] == 'L' && b[2] == 'V' } + h.Ext = ".flv" + h.ReaderDemuxer = func(r io.Reader) av.Demuxer { return NewDemuxer(r) } + h.WriterMuxer = func(w io.Writer) av.Muxer { return NewMuxer(w) } + + h.CodecTypes = CodecTypes } diff --git a/format/mp4/handler.go b/format/mp4/handler.go index 9ee004a..ce77dc9 100644 --- a/format/mp4/handler.go +++ b/format/mp4/handler.go @@ -6,13 +6,19 @@ import ( "github.com/nareix/joy4/av/avutil" ) +var CodecTypes = []av.CodecType{av.H264, av.AAC} + func Handler(h *avutil.RegisterHandler) { h.Ext = ".mp4" + h.ReaderDemuxer = func(r io.Reader) av.Demuxer { return NewDemuxer(r.(io.ReadSeeker)) } + h.WriterMuxer = func(w io.Writer) av.Muxer { return NewMuxer(w.(io.WriteSeeker)) } + + h.CodecTypes = CodecTypes } diff --git a/format/mp4/muxer.go b/format/mp4/muxer.go index 17e8ff3..1a421cb 100644 --- a/format/mp4/muxer.go +++ b/format/mp4/muxer.go @@ -22,10 +22,6 @@ func NewMuxer(w io.WriteSeeker) *Muxer { return &Muxer{w: w} } -func (self *Muxer) SupportedCodecTypes() []av.CodecType { - return []av.CodecType{av.H264, av.AAC} -} - func (self *Muxer) newStream(codec av.CodecData) (err error) { switch codec.Type() { case av.H264, av.AAC: diff --git a/format/rtmp/rtmp.go b/format/rtmp/rtmp.go index e5e6c95..d9bdc01 100644 --- a/format/rtmp/rtmp.go +++ b/format/rtmp/rtmp.go @@ -21,6 +21,8 @@ import ( "crypto/rand" ) +var Debug bool + func ParseURL(uri string) (u *url.URL, err error) { if u, err = url.Parse(uri); err != nil { return @@ -52,8 +54,6 @@ func DialTimeout(uri string, timeout time.Duration) (conn *Conn, err error) { return } -var Debug bool - type Server struct { Addr string HandlePublish func(*Conn) @@ -317,9 +317,7 @@ func createURL(tcurl, app, play string) (u *url.URL) { return } -func (self *Conn) SupportedCodecTypes() []av.CodecType { - return flv.SupportedCodecTypes -} +var CodecTypes = flv.CodecTypes func (self *Conn) recvConnect() (err error) { var connectpath string @@ -1707,5 +1705,7 @@ func Handler(h *avutil.RegisterHandler) { return } + + h.CodecTypes = CodecTypes } diff --git a/format/ts/README.md b/format/ts/README.md deleted file mode 100644 index 139597f..0000000 --- a/format/ts/README.md +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/format/ts/doc.txt b/format/ts/doc.txt deleted file mode 100644 index 0d698ce..0000000 --- a/format/ts/doc.txt +++ /dev/null @@ -1,52 +0,0 @@ - -The first h264 packet - -00000000 00 00 00 01 09 f0 00 00 00 01 06 00 07 86 96 7f |................| - ^ ^ -00000010 80 00 00 40 80 00 00 01 06 05 11 03 87 f4 4e cd |...@..........N.| - ^ -00000020 0a 4b dc a1 94 3a c3 d4 9b 17 1f 00 80 00 00 00 |.K...:..........| -00000030 01 27 4d 40 0a a9 19 bf 2c b8 0b 50 10 10 13 0a |.'M@....,..P....| - ^ -00000040 d7 bd f0 10 00 00 00 01 28 fe 09 88 00 00 01 25 |........(......%| - ^ ^ -00000050 b8 20 20 bf ed 7e de 3b 56 7f 03 c5 d1 06 9a c3 |. ..~.;V.......| -00000060 74 e5 9d 18 e6 3f 9d 63 19 cc 46 fd 36 13 c5 b8 |t....?.c..F.6...| -00000070 7f 3e d9 39 1b 21 74 61 6d 9d b7 5b 71 e6 a2 de |.>.9.!tam..[q...| -00000080 68 0b bf 7e b8 d4 9d 2f 49 19 3b 11 6e 40 a3 0a |h..~.../I.;.n@..| -00000090 3f 02 c5 a3 47 1d ed 2a 3a a1 33 0e 15 2f 36 d8 |?...G..*:.3../6.| -000000a0 c7 2a eb c6 bf 0d 95 e4 42 3e 7b 5f 44 3f b9 a5 |.*......B>{_D?..| -000000b0 d7 a2 c6 f4 41 e8 82 b5 cc cd c9 a4 ec 29 6f 58 |....A........)oX| -000000c0 6c 78 38 7c b5 5b 27 97 9d 56 5f e0 00 00 01 25 |lx8|.['..V_....%| - ^ -000000d0 2b 82 02 0b af 43 64 9c f1 eb 03 7e 39 a0 b6 f8 |+....Cd....~9...| -000000e0 eb c4 88 d2 ef 79 1f 7c d6 4e 1a d3 5d 27 39 ca |.....y.|.N..]'9.| -000000f0 c6 0b a9 63 78 e2 19 41 71 d4 47 26 bc 58 e4 45 |...cx..Aq.G&.X.E| -00000100 db 77 7b 60 7f d9 e4 11 03 3d 05 0d 72 5e 0d a0 |.w{`.....=..r^..| -00000110 56 4f 1a a9 9e 4f 80 |VO...O.| - -[h264 @ 0x7fdf01802200] NAL 9(AUD) at 4/279 length 1 -[h264 @ 0x7fdf01802200] NAL 6(SEI) at 10/279 length 10 -[h264 @ 0x7fdf01802200] NAL 6(SEI) at 24/279 length 20 -[h264 @ 0x7fdf01802200] NAL 7(SPS) at 49/279 length 18 -[h264 @ 0x7fdf01802200] NAL 8(PPS) at 72/279 length 3 -[h264 @ 0x7fdf01802200] NAL 5(IDR) at 79/279 length 124 -[h264 @ 0x7fdf01802200] NAL 5(IDR) at 207/279 length 71 - -AUD is a must for QuickTime player. - -NAL_SLICE = 1, -NAL_DPA = 2, -NAL_DPB = 3, -NAL_DPC = 4, -NAL_IDR_SLICE = 5, -NAL_SEI = 6, -NAL_SPS = 7, -NAL_PPS = 8, -NAL_AUD = 9, -NAL_END_SEQUENCE = 10, -NAL_END_STREAM = 11, -NAL_FILLER_DATA = 12, -NAL_SPS_EXT = 13, -NAL_AUXILIARY_SLICE = 19, - diff --git a/format/ts/handler.go b/format/ts/handler.go index ac5db75..f27dff0 100644 --- a/format/ts/handler.go +++ b/format/ts/handler.go @@ -8,11 +8,15 @@ import ( func Handler(h *avutil.RegisterHandler) { h.Ext = ".ts" + h.ReaderDemuxer = func(r io.Reader) av.Demuxer { return NewDemuxer(r) } + h.WriterMuxer = func(w io.Writer) av.Muxer { return NewMuxer(w) } + + h.CodecTypes = CodecTypes } diff --git a/format/ts/muxer.go b/format/ts/muxer.go index 703bf27..14e1928 100644 --- a/format/ts/muxer.go +++ b/format/ts/muxer.go @@ -26,22 +26,18 @@ type Muxer struct { tswPMT *TSWriter } -var supportedCodecTypes = []av.CodecType{av.H264, av.AAC} - -func (self Muxer) SupportedCodecTypes() []av.CodecType { - return supportedCodecTypes -} +var CodecTypes = []av.CodecType{av.H264, av.AAC} func (self *Muxer) newStream(codec av.CodecData) (err error) { ok := false - for _, c := range supportedCodecTypes { + for _, c := range CodecTypes { if codec.Type() == c { ok = true break } } if !ok { - err = fmt.Errorf("codec type=%x is not supported", codec.Type()) + err = fmt.Errorf("ts: codec type=%s is not supported", codec.Type()) return } diff --git a/format/ts/reader.go b/format/ts/reader.go index 5e786ff..0074d02 100644 --- a/format/ts/reader.go +++ b/format/ts/reader.go @@ -39,164 +39,6 @@ func ReadUInt64(r io.Reader, n int) (res uint64, err error) { return } -func ReadTSHeader(r io.Reader) (self TSHeader, err error) { - var flags uint - - // sync(8) - // transport_error_indicator(1) - // payload_unit_start_indicator(1) - // transport_priority(1) - // pid(13) - // Scrambling control(2) - // Adaptation field flag(1) - // Continuity counter(4) - if flags, err = ReadUInt(r, 4); err != nil { - return - } - - if DebugReader { - fmt.Fprintf(DebugOutput, "ts: flags %s\n", FieldsDumper{ - Fields: []struct { - Length int - Desc string - }{ - {8, "sync"}, - {1, "transport_error_indicator"}, - {1, "payload_unit_start_indicator"}, - {1, "transport_priority"}, - {13, "pid"}, - {2, "scrambling_control"}, - {1, "adaptation_field_flag"}, - {1, "payload_flag"}, - {4, "continuity_counter"}, - }, - Val: flags, - Length: 32, - }) - } - - 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 { - err = fmt.Errorf("invalid sync") - return - } - - self.PID = (flags & 0x1fff00) >> 8 - self.ContinuityCounter = flags & 0xf - - if flags&0x20 != 0 { - var flags, length uint - if length, err = ReadUInt(r, 1); err != nil { - return - } - if length > 0 { - lr := &io.LimitedReader{R: r, N: int64(length)} - if flags, err = ReadUInt(lr, 1); err != nil { - return - } - - if DebugReader { - fmt.Fprintf(DebugOutput, "ts: ext_flags %s\n", FieldsDumper{ - Fields: []struct { - Length int - Desc string - }{ - {1, "discontinuity_indicator"}, - {1, "random_access_indicator"}, - {1, "elementary_stream_priority_indicator"}, - {1, "pcr_flag"}, - {1, "opcr_flag"}, - {1, "splicing_point_flag"}, - {1, "transport_private_data_flag"}, - {1, "adaptation_field_extension_flag"}, - }, - Val: flags, - Length: 8, - }) - } - - // random_access_indicator - if flags&0x40 != 0 { - self.RandomAccessIndicator = true - } - - // PCR - if flags&0x10 != 0 { - var v uint64 - if v, err = ReadUInt64(lr, 6); err != nil { - return - } - // clock is 27MHz - self.PCR = UIntToPCR(v) - if DebugReader { - fmt.Fprintf(DebugOutput, "ts: PCR %d %f\n", self.PCR, float32(self.PCR)/PCR_HZ) - } - } - - // OPCR - if flags&0x08 != 0 { - var v uint64 - if v, err = ReadUInt64(lr, 6); err != nil { - return - } - self.OPCR = UIntToPCR(v) - } - - // Splice countdown - if flags&0x04 != 0 { - if _, err = ReadUInt(lr, 1); err != nil { - return - } - } - - // Transport private data - if flags&0x02 != 0 { - var length uint - if length, err = ReadUInt(lr, 1); err != nil { - return - } - - b := make([]byte, length) - if _, err = lr.Read(b); err != nil { - return - } - } - - // Adaptation extension - if lr.N > 0 { - if DebugReader { - // rubish - fmt.Fprintln(DebugOutput, "ts: skip", lr.N) - } - - if err = ReadDummy(lr, int(lr.N)); err != nil { - return - } - } - } - } - - return -} - -func ReadTSPacket(r io.Reader, data []byte) (self TSHeader, n int, err error) { - lr := &io.LimitedReader{R: r, N: 188} - if self, err = ReadTSHeader(lr); err != nil { - return - } - if DebugReader { - fmt.Fprintln(DebugOutput, "ts: data len", lr.N) - } - if n, err = lr.Read(data[:lr.N]); err != nil { - return - } - return -} - func ReadPSI(r io.Reader) (self PSI, lr *io.LimitedReader, cr *Crc32Reader, err error) { var flags, pointer, length uint @@ -205,10 +47,6 @@ func ReadPSI(r io.Reader) (self PSI, lr *io.LimitedReader, cr *Crc32Reader, err return } - if DebugReader { - fmt.Fprintf(DebugOutput, "psi: pointer=%d\n", pointer) - } - if pointer != 0 { if err = ReadDummy(r, int(pointer)); err != nil { return @@ -229,10 +67,6 @@ func ReadPSI(r io.Reader) (self PSI, lr *io.LimitedReader, cr *Crc32Reader, err } length = flags & 0x3FF - if DebugReader { - fmt.Fprintf(DebugOutput, "psi: tableid=%d len=%d\n", self.TableId, length) - } - lr = &io.LimitedReader{R: cr, N: int64(length)} // Table ID extension(16) @@ -247,21 +81,6 @@ func ReadPSI(r io.Reader) (self PSI, lr *io.LimitedReader, cr *Crc32Reader, err return } - if DebugReader { - fmt.Fprintf(DebugOutput, "psi: %s\n", FieldsDumper{ - Fields: []struct { - Length int - Desc string - }{ - {2, "resverd"}, - {5, "version"}, - {1, "current_next_indicator"}, - }, - Val: flags, - Length: 8, - }) - } - // section_number(8) if self.SecNum, err = ReadUInt(lr, 1); err != nil { return @@ -272,15 +91,6 @@ func ReadPSI(r io.Reader) (self PSI, lr *io.LimitedReader, cr *Crc32Reader, err return } - if DebugReader { - fmt.Fprintf(DebugOutput, "psi: table_id=%x table_extension=%x secnum=%x lastsecnum=%x\n", - self.TableId, - self.TableIdExtension, - self.SecNum, - self.LastSecNum, - ) - } - lr.N -= 4 return } @@ -322,20 +132,6 @@ func ReadPMT(r io.Reader) (self PMT, err error) { } self.PCRPID = flags & 0x1fff - if DebugReader { - fmt.Fprintf(DebugOutput, "pmt: %s\n", FieldsDumper{ - Fields: []struct { - Length int - Desc string - }{ - {3, "reserved"}, - {13, "pcrpid"}, - }, - Val: flags, - Length: 16, - }) - } - // Reserved(4)=0xf // Reserved(2)=0x0 // Program info length(10) @@ -344,10 +140,6 @@ func ReadPMT(r io.Reader) (self PMT, err error) { } length = flags & 0x3ff - if DebugReader { - fmt.Fprintf(DebugOutput, "pmt: ProgramDescriptorsLen=%d\n", length) - } - if length > 0 { lr := &io.LimitedReader{R: lr, N: int64(length)} if self.ProgramDescriptors, err = readDescs(lr); err != nil { @@ -368,20 +160,6 @@ func ReadPMT(r io.Reader) (self PMT, err error) { } info.ElementaryPID = flags & 0x1fff - if DebugReader { - fmt.Fprintf(DebugOutput, "pmt: info1 %s\n", FieldsDumper{ - Fields: []struct { - Length int - Desc string - }{ - {3, "reserved"}, - {13, "elementary_pid"}, - }, - Val: flags, - Length: 16, - }) - } - // Reserved(6) // ES Info length(10) if flags, err = ReadUInt(lr, 2); err != nil { @@ -389,20 +167,6 @@ func ReadPMT(r io.Reader) (self PMT, err error) { } length = flags & 0x3ff - if DebugReader { - fmt.Fprintf(DebugOutput, "pmt: info2 %s\n", FieldsDumper{ - Fields: []struct { - Length int - Desc string - }{ - {6, "reserved"}, - {10, "es_info_length"}, - }, - Val: flags, - Length: 16, - }) - } - if length > 0 { lr := &io.LimitedReader{R: lr, N: int64(length)} if info.Descriptors, err = readDescs(lr); err != nil { @@ -412,15 +176,7 @@ func ReadPMT(r io.Reader) (self PMT, err error) { self.ElementaryStreamInfos = append(self.ElementaryStreamInfos, info) } - if DebugReader { - fmt.Fprintf(DebugOutput, "pmt: ProgramDescriptors %v\n", self.ProgramDescriptors) - fmt.Fprintf(DebugOutput, "pmt: ElementaryStreamInfos %v\n", self.ElementaryStreamInfos) - } - if err = cr.ReadCrc32UIntAndCheck(); err != nil { - if DebugReader { - fmt.Fprintf(DebugOutput, "pmt: %s\n", err) - } return } @@ -456,16 +212,9 @@ func ReadPAT(r io.Reader) (self PAT, err error) { } if err = cr.ReadCrc32UIntAndCheck(); err != nil { - if DebugReader { - fmt.Fprintf(DebugOutput, "pat: %s\n", err) - } return } - if DebugReader { - fmt.Fprintf(DebugOutput, "pat: %v\n", self) - } - return } @@ -491,9 +240,6 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) { if length, err = ReadUInt(r, 2); err != nil { return } - if DebugReader { - fmt.Fprintf(DebugOutput, "pes: StreamId=%x length=%d\n", self.StreamId, length) - } if length == 0 { length = 1 << 31 @@ -511,23 +257,6 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) { return } - if DebugReader { - fmt.Fprintf(DebugOutput, "pes: %s\n", FieldsDumper{ - Fields: []struct { - Length int - Desc string - }{ - {2, "scrambling_control"}, - {1, "priority"}, - {1, "data_alignment_indicator"}, - {1, "copyright"}, - {1, "original_or_copy"}, - }, - Val: flags, - Length: 6, - }) - } - // PTS DTS flags(2) // ESCR flag(1) // ES rate flag(1) @@ -539,25 +268,6 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) { return } - if DebugReader { - fmt.Fprintf(DebugOutput, "pes: %s\n", FieldsDumper{ - Fields: []struct { - Length int - Desc string - }{ - {2, "pts_dts_flags"}, - {1, "escr_flag"}, - {1, "es_rate_flag"}, - {1, "dsm_trick_mode_flag"}, - {1, "additional_copy_info_flag"}, - {1, "pes_crc_flag"}, - {1, "pes_extension_flag"}, - }, - Val: flags, - Length: 8, - }) - } - // PES header data length(8) if length, err = ReadUInt(lr, 1); err != nil { return @@ -570,10 +280,6 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) { return } self.PTS = PESUIntToTs(v) - - if DebugReader { - fmt.Fprintf(DebugOutput, "pes: pts %d %f\n", self.PTS, float32(self.PTS)/float32(PTS_HZ)) - } } if flags&0x40 != 0 && flags&0x80 != 0 { @@ -582,9 +288,6 @@ func ReadPESHeader(r io.Reader) (res *PESHeader, err error) { return } self.DTS = PESUIntToTs(v) - if DebugReader { - fmt.Fprintf(DebugOutput, "pes: dts %d %f\n", self.DTS, float32(self.DTS)/float32(PTS_HZ)) - } } // ESCR flag diff --git a/format/ts/stream.go b/format/ts/stream.go index 552bfc8..dd75368 100644 --- a/format/ts/stream.go +++ b/format/ts/stream.go @@ -11,7 +11,6 @@ type Stream struct { buf bytes.Buffer peshdr *PESHeader - tshdr TSHeader demuxer *Demuxer muxer *Muxer diff --git a/format/ts/ts.go b/format/ts/ts.go index dccb6a0..651f14c 100644 --- a/format/ts/ts.go +++ b/format/ts/ts.go @@ -1,8 +1,7 @@ package ts import ( - "fmt" - "os" + "io" ) const ( @@ -10,17 +9,6 @@ const ( ElementaryStreamTypeAdtsAAC = 0x0F ) -type TSHeader struct { - PID uint - PCR uint64 - OPCR uint64 - ContinuityCounter uint - PayloadUnitStart bool - DiscontinuityIndicator bool - RandomAccessIndicator bool - HeaderLength uint -} - type PATEntry struct { ProgramNumber uint NetworkPID uint @@ -96,27 +84,9 @@ func PCRToUInt(pcr uint64) uint64 { return base<<15 | 0x3f<<9 | ext } -var DebugOutput = os.Stdout -var DebugReader = false -var DebugWriter = false - -type FieldsDumper struct { - Fields []struct { - Length int - Desc string - } - Val uint - Length uint +type TSWriter struct { + w io.Writer + ContinuityCounter uint + tshdr []byte } -func (self FieldsDumper) String() (res string) { - pos := uint(self.Length) - for _, field := range self.Fields { - pos -= uint(field.Length) - val := (self.Val >> pos) & (1< 0 && self.Len > 0 { - data := self.data[self.idx] - - var b []byte - if n > len(data) { - b = data - } else { - b = data[:n] - } - - data = data[len(b):] - if len(data) == 0 { - self.idx++ - } else { - self.data[self.idx] = data - } - self.Len -= len(b) - n -= len(b) - written += len(b) - - if _, err = w.Write(b); err != nil { - return - } - } - return -} - -type sysiovec struct { - Base uintptr - Len uint64 -} - -type vecWriter struct { - fd uintptr - smallBytesBuf []byte - iov []sysiovec -} - -func (self *vecWriter) Write(p []byte) (written int, err error) { - iov := sysiovec{ - Len: uint64(len(p)), - } - - if len(p) < 16 { - iov.Base = uintptr(len(self.smallBytesBuf)) - self.smallBytesBuf = append(self.smallBytesBuf, p...) - } else { - iov.Base = uintptr(unsafe.Pointer(&p[0])) - } - - self.iov = append(self.iov, iov) - return -} - -func (self *vecWriter) Flush() (err error) { - for i := range self.iov { - iov := &self.iov[i] - if iov.Base < uintptr(len(self.smallBytesBuf)) { - iov.Base = uintptr(unsafe.Pointer(&self.smallBytesBuf[iov.Base])) - } - } - - N := 1024 - for i := 0; i < len(self.iov); i += N { - n := len(self.iov) - i - if n > N { - n = N - } - _, _, errno := syscall.Syscall(syscall.SYS_WRITEV, self.fd, uintptr(unsafe.Pointer(&self.iov[i])), uintptr(n)) - if errno != 0 { - err = fmt.Errorf("writev failed with error: %d", errno) - return - } - } - - if DebugWriter { - fmt.Printf("vecw: smallBytesBuf=%d iovNr=%d\n", len(self.smallBytesBuf), len(self.iov)) - } - - self.iov = self.iov[:0] - self.smallBytesBuf = self.smallBytesBuf[:0] - - return -} - -func newVecWriter(w io.Writer) (vecw *vecWriter) { - var err error - var f *os.File - - switch obj := w.(type) { - case *net.TCPConn: - f, err = obj.File() - if err != nil { - return - } - case *os.File: - f = obj - default: - return - } - - vecw = &vecWriter{ - fd: f.Fd(), - } - return -} diff --git a/format/ts/writer.go b/format/ts/writer.go index 479fd74..9ac3f83 100644 --- a/format/ts/writer.go +++ b/format/ts/writer.go @@ -2,7 +2,6 @@ package ts import ( "bytes" - "fmt" "io" ) @@ -22,12 +21,6 @@ func WriteUInt(w io.Writer, val uint, n int) (err error) { return WriteUInt64(w, uint64(val), n) } -type TSWriter struct { - w io.Writer - ContinuityCounter uint - tshdr []byte -} - func WritePSI(w io.Writer, self PSI, data []byte) (err error) { // pointer(8) // table_id(8) @@ -59,10 +52,6 @@ func WritePSI(w io.Writer, self PSI, data []byte) (err error) { return } - if DebugWriter { - fmt.Fprintf(DebugOutput, "psiw: length=%d\n", length) - } - // Table ID extension(16) if err = WriteUInt(cw, self.TableIdExtension, 2); err != nil { return diff --git a/format/ts/writer_test.go b/format/ts/writer_test.go deleted file mode 100644 index 5450006..0000000 --- a/format/ts/writer_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package ts - -import ( - "bytes" - "encoding/hex" - "testing" -) - -func TestWriteTSHeader(t *testing.T) { - bw := &bytes.Buffer{} - w := &TSWriter{ - W: bw, - PCR: 0x12345678, - } - w.Write([]byte{'h', 'e', 'l', 'o'}[:], false) - t.Logf("\n%s", hex.Dump(bw.Bytes())) -}