From 12f02fb261bb23c7474aa740adc1d5cdf86bcbfc Mon Sep 17 00:00:00 2001 From: saxon Date: Sun, 15 Jul 2018 16:21:20 +0930 Subject: [PATCH] Updating my progress - currently porting sendPacket --- rtmp/rtmp.go | 182 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 174 insertions(+), 8 deletions(-) diff --git a/rtmp/rtmp.go b/rtmp/rtmp.go index b2c8ded0..e2bf7f8f 100644 --- a/rtmp/rtmp.go +++ b/rtmp/rtmp.go @@ -54,6 +54,7 @@ import ( const ( minDataSize = 11 + debugMode = false ) const ( @@ -257,18 +258,21 @@ func ptrToSlice(data unsafe.Pointer, size int) []byte { func incPtr(ptr unsafe.Pointer, inc int) unsafe.Pointer { return unsafe.Pointer(uintptr(ptr) + uintptr(inc)) } -/* + +// incPtr attempts to replicate C like pointer arithmatic functionality +func decPtr(ptr unsafe.Pointer, dec int) unsafe.Pointer { + return unsafe.Pointer(uintptr(ptr) - uintptr(inc)) +} + func sendPacket(r *C.RTMP, pkt *C.RTMPPacket, queue int) int { const prevPacket *C.RTMPPacket last := 0 var nSize, hSize, cSize, nChunkSize, tlen int - var header, hptr, hend, buffer *C.char + var header, hptr, hend, buffer, tbuf, toff unsafe.Pointer var goHbuf [RTMP_MAX_HEADER_SIZE]byte - var hbuf = (*C.char)(unsafe.Pointer(&goHbuf[0])) - var c C.char + var hbuf = unsafe.Pointer(&goHbuf[0]) + var c byte var t int32 - var tbuf *C.char = nil - var toff *C.char = nil if packet.m_nChannel >= r.m_channelsAllocatedOut { n := int(packet.m_nChannel+10) @@ -285,10 +289,172 @@ func sendPacket(r *C.RTMP, pkt *C.RTMPPacket, queue int) int { unsafe.Sizeof(*RTMPPacket) * (n-r.m_channelsAllocatedOut)) r.m_channelsAllocatedOut = n } + prevPackt = *(**C.RTMPPacket)(incPtr(unsafe.Pointer(r.m_vecChannelsOut), + packet.m_nChannel)) + + if prevPacket != nil && packet.m_headerType != RTMP_PACKET_SIZE_LARGE { + // compress a bit by using the prev packet's attributes + if prevPacket.m_nBodySize == packet.m_nBodySize && + prevPacket.m_packetType == packet.m_packetType && + packet.m_headerType == RTMP_PACKET_SIZE_MEDIUM { + + packet.m_headerType = RTMP_PACKET_SIZE_SMALL + } + + if prevPacket.m_nTimeStamp == packet.m_nTimeStamp && + packet.m_headerType == RTMP_PACKET_SIZE_SMALL { + + packet.m_headerType = RTMP_PACKET_SIZE_MINIMUM + } + + last = prevPacket.m_nTimeStamp + } + + if packet.m_headerType > 3 { + log.Printf("Sanity failed! trying to send header of type: 0x%02x.", + packet.m_headerType) + return 0 + } + + nSize = int(*(*int)(incPtr(unsafe.Pointer(packetSize),int(packet.m_headerType)))) + hSize = nSize + cSize = 0 + t = packet.m_nTimeStamp - last + + if packet.m_body { + header = packet.m_body - nSize + hend = packet.m_body + } else { + header = incPtr(hbuf,6) + // TODO: be cautious about this size of - make sure it works how you think it + // does. C code used sizeof(hbuf) where hbuf is a *char + hend = incPtr(hbuf,unsafe.Sizeof((*byte)(hbuf))) + } + + switch { + case packet.m_nChannel > 319: + cSize = 2 + case packet.m_nChannel > 63: + cSize = 1 + } + + if cSize != 0 { + header = decPtr(header,4) + hSize = incPtr(hSize,4) + log.Printf("Larger timsetamp than 24-bit: 0x%x", t) + } + + hptr = header + c = byte(packet.m_headerType) << 6 + + switch cSize { + case 0: + c |= byte(packet.m_nChannel) + case 1: + case 2: + c |= byte(1) + } + + hptr* = tmp >> 8 + hptr = incPtr(hptr,1) + + if nSize > 1 { + res := t + if t > 0xffffff { + res = 0xffffff + } + hptr = unsafe.Pointer(AMF_EncodeInt24((*C.char)(hptr),(*C.char)(hend), res)) + } + + if nSize > 4 { + *(*byte)(hptr) = byte(packet.m_packetType) + hptr = unsafe.Pointer(AMF_EncodeInt24((*C.char)(hptr), (*C.char)(hend), + packet.m_nbodySize)) + } + + if nSize > 8 { + hptr = incPtr(hptr, int(EncodeInt32LE((*C.char)(hptr), packet.m_nInfoField2))) + } + + if t >= 0xffffff { + hptr = unsafe.Pointer(AMF_EncodeInt32((*C.char)(hptr), (*C.char)(hend), t)) + } + + nSize = int(packet.m_nBodySize) + buffer = unsafe.Pointer(m_body) + nChunkSize = int(r.m_outChunkSize) + + if debugMode { + log.Printf("sendPacket: fd=%v, size=%v", r.m_sb.sb_socket, nSize) + } + + // send all chunks in one HTTP request + // TODO: port RTMP_FEATURE_HTTP + if r.Link.protocol & C.RTMP_FEATURE_HTTP { + chunks := (nSize+nChunkSize-1)/nChunkSize + if chunks > 1 { + tlen = chunks *(cSize+1) +nSize +hSize + // TODO: figure out how to do this in go + tbuf = C.malloc(tlen) + + if tbuf == 0 { + return 0 + } + toff = tbuf + } + } + for (nSize + hSize) != 0 { + var wrote int + + if nSize < nChunkSize { + nChunkSize = nSize + } + + // TODO: figure out what's happening here: + // RTMP_LogHexString(RTMP_LOGDEBUG2, (uint8_t *)header, hSize); + // RTMP_LogHexString(RTMP_LOGDEBUG2, (uint8_t *)buffer, nChunkSize); + + if tbuf != nil { + memmove(toff, header, nChunksize + hSize) + toff = incPtr(toff, nChunkSize + hSize) + } else { + // TODO: port this + wrote = C.WriteN(r, (*C.char)(header), C.int(nChunkSize+hSize)) + + if wrote == 0 { + return 0 + } + } + + nSize -= nChunkSize + buffer = incPtr(buffer,nChunkSize) + hSize = 0 + + if nSize > 0 { + header = decPtr(buffer, 1) + hSize = 1 + + if cSize != 0 { + header = decPtr(header,1) + hSize += cSize + } + + if t >= 0xffffff { + header = decPtr(header,4) + hSize += 4 + } + + *(*byte)(header) = (0xc0 | c) + + if cSize != 0 { + + } + } + + } - prevPackt = (*RTMPPacket)(unsafe.Pointer() ) } -*/ + // Close terminates the rtmp connection func (s *session) Close() error {