rewrite handler codec types logic, rm ts unused files

This commit is contained in:
nareix 2016-07-14 00:33:57 +08:00
parent 66bd404f1a
commit 2dea41f479
18 changed files with 51 additions and 602 deletions

View File

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

View File

@ -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,
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,2 +0,0 @@

View File

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

View File

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

View File

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

View File

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

View File

@ -11,7 +11,6 @@ type Stream struct {
buf bytes.Buffer
peshdr *PESHeader
tshdr TSHeader
demuxer *Demuxer
muxer *Muxer

View File

@ -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<<uint(field.Length) - 1)
if val != 0 {
res += fmt.Sprintf("%s=%x ", field.Desc, val)
}
}
return
}

View File

@ -1,9 +0,0 @@
package ts
import (
"testing"
)
func TestPESTsConv(t *testing.T) {
t.Logf("%x", PESTsToUInt(0x123))
}

View File

@ -1,135 +0,0 @@
package ts
import (
"fmt"
"io"
"net"
"os"
"syscall"
"unsafe"
)
type iovec struct {
data [][]byte
Len int
pos int
idx int
}
func (self *iovec) Prepend(b []byte) {
self.data = append([][]byte{b}, self.data...)
self.Len += len(b)
}
func (self *iovec) Append(b []byte) {
self.data = append(self.data, b)
self.Len += len(b)
}
func (self *iovec) WriteTo(w io.Writer, n int) (written int, err error) {
for n > 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
}

View File

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

View File

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