add vecWriter
This commit is contained in:
parent
bc93d48788
commit
8cf764967d
@ -283,6 +283,7 @@ func main() {
|
|||||||
W: file,
|
W: file,
|
||||||
PID: 0x100,
|
PID: 0x100,
|
||||||
}
|
}
|
||||||
|
w.EnableVecWriter()
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
93
vecio.go
93
vecio.go
@ -3,11 +3,18 @@ package ts
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"os"
|
||||||
|
"net"
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
type iovec struct {
|
type iovec struct {
|
||||||
data [][]byte
|
data [][]byte
|
||||||
Len int
|
Len int
|
||||||
|
pos int
|
||||||
|
idx int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *iovec) Append(b []byte) {
|
func (self *iovec) Append(b []byte) {
|
||||||
@ -17,7 +24,7 @@ func (self *iovec) Append(b []byte) {
|
|||||||
|
|
||||||
func (self *iovec) WriteTo(w io.Writer, n int) (written int, err error) {
|
func (self *iovec) WriteTo(w io.Writer, n int) (written int, err error) {
|
||||||
for n > 0 && self.Len > 0 {
|
for n > 0 && self.Len > 0 {
|
||||||
data := self.data[0]
|
data := self.data[self.idx]
|
||||||
|
|
||||||
var b []byte
|
var b []byte
|
||||||
if n > len(data) {
|
if n > len(data) {
|
||||||
@ -28,9 +35,9 @@ func (self *iovec) WriteTo(w io.Writer, n int) (written int, err error) {
|
|||||||
|
|
||||||
data = data[len(b):]
|
data = data[len(b):]
|
||||||
if len(data) == 0 {
|
if len(data) == 0 {
|
||||||
self.data = self.data[1:]
|
self.idx++
|
||||||
} else {
|
} else {
|
||||||
self.data[0] = data
|
self.data[self.idx] = data
|
||||||
}
|
}
|
||||||
self.Len -= len(b)
|
self.Len -= len(b)
|
||||||
n -= len(b)
|
n -= len(b)
|
||||||
@ -43,3 +50,83 @@ func (self *iovec) WriteTo(w io.Writer, n int) (written int, err error) {
|
|||||||
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
|
||||||
|
}
|
||||||
|
|
||||||
|
30
writer.go
30
writer.go
@ -151,9 +151,26 @@ type TSWriter struct {
|
|||||||
PID uint
|
PID uint
|
||||||
TSHeader
|
TSHeader
|
||||||
DisableHeaderPadding bool
|
DisableHeaderPadding bool
|
||||||
|
|
||||||
|
vecw *vecWriter
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *TSWriter) EnableVecWriter() {
|
||||||
|
if self.vecw == nil {
|
||||||
|
self.vecw = newVecWriter(self.W)
|
||||||
|
|
||||||
|
if DebugWriter && self.vecw != nil {
|
||||||
|
fmt.Println("tsw: enabled vec writer")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *TSWriter) WriteIovec(data *iovec) (err error) {
|
func (self *TSWriter) WriteIovec(data *iovec) (err error) {
|
||||||
|
w := self.W
|
||||||
|
if self.vecw != nil {
|
||||||
|
w = self.vecw
|
||||||
|
}
|
||||||
|
|
||||||
for i := 0; data.Len > 0; i++ {
|
for i := 0; data.Len > 0; i++ {
|
||||||
header := TSHeader{
|
header := TSHeader{
|
||||||
PID: self.PID,
|
PID: self.PID,
|
||||||
@ -172,7 +189,7 @@ func (self *TSWriter) WriteIovec(data *iovec) (err error) {
|
|||||||
requestLength = 188
|
requestLength = 188
|
||||||
}
|
}
|
||||||
var headerLength int
|
var headerLength int
|
||||||
if headerLength, err = WriteTSHeader(self.W, header, requestLength); err != nil {
|
if headerLength, err = WriteTSHeader(w, header, requestLength); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
payloadLength := 188 - headerLength
|
payloadLength := 188 - headerLength
|
||||||
@ -184,13 +201,19 @@ func (self *TSWriter) WriteIovec(data *iovec) (err error) {
|
|||||||
fmt.Printf("tsw: payloadLength=%d dataLength=%d\n", payloadLength, data.Len)
|
fmt.Printf("tsw: payloadLength=%d dataLength=%d\n", payloadLength, data.Len)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err = data.WriteTo(self.W, payloadLength); err != nil {
|
if _, err = data.WriteTo(w, payloadLength); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ContinuityCounter++
|
self.ContinuityCounter++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.vecw != nil {
|
||||||
|
if err = self.vecw.Flush(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +255,7 @@ func WritePSI(w io.Writer, self PSI, data []byte) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if DebugWriter {
|
if DebugWriter {
|
||||||
fmt.Printf("wpsi: length=%d\n", length)
|
fmt.Printf("psiw: length=%d\n", length)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Table ID extension(16)
|
// Table ID extension(16)
|
||||||
@ -546,6 +569,7 @@ func (self *SimpleH264Writer) prepare() (err error) {
|
|||||||
W: self.W,
|
W: self.W,
|
||||||
PID: 0x100,
|
PID: 0x100,
|
||||||
}
|
}
|
||||||
|
self.tsw.EnableVecWriter()
|
||||||
self.pts = PTS_HZ
|
self.pts = PTS_HZ
|
||||||
self.pcr = PCR_HZ
|
self.pcr = PCR_HZ
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user