rtmp: make C_AMF_EncodeInt{24,32,String} take []byte

This commit is contained in:
Dan Kortschak 2018-09-14 22:06:13 +09:30
parent 73dd7f3a7c
commit cf87480070
2 changed files with 78 additions and 77 deletions

View File

@ -55,6 +55,15 @@ const (
AMF3_INTEGER_MIN = -268435456 AMF3_INTEGER_MIN = -268435456
) )
func pp2b(b, e *byte) []byte {
if b == nil {
return nil
}
base := unsafe.Pointer(b)
len := uintptr(unsafe.Pointer(e)) - uintptr(base)
return (*[_Gi]byte)(base)[:len]
}
// unsigned short AMF_DecodeInt16(const char* data); // unsigned short AMF_DecodeInt16(const char* data);
// amf.c +41 // amf.c +41
func C_AMF_DecodeInt16(data []byte) uint16 { func C_AMF_DecodeInt16(data []byte) uint16 {
@ -101,71 +110,64 @@ func C_AMF_DecodeBoolean(data []byte) bool {
// char* AMF_EncodeInt24(char* output, char* outend, int nVal); // char* AMF_EncodeInt24(char* output, char* outend, int nVal);
// amf.c +149 // amf.c +149
func C_AMF_EncodeInt24(output *byte, outend *byte, nVal int32) *byte { func C_AMF_EncodeInt24(dst []byte, val int32) *byte {
outputPtr := unsafe.Pointer(output) if len(dst) < 3 {
outendPtr := unsafe.Pointer(outend)
if uintptr(outputPtr)+3 > uintptr(outendPtr) {
// length < 3
return nil return nil
} }
// Assign output[2] _ = dst[2]
third := (*byte)(incBytePtr(outputPtr, 2)) dst[0] = byte(val >> 16)
*third = (byte)(nVal & 0xff) dst[1] = byte(val >> 8)
// Assign output[1] dst[2] = byte(val)
second := (*byte)(incBytePtr(outputPtr, 1)) if len(dst) == 3 {
*second = (byte)(nVal >> 8) return nil
// Assign output[0] }
*output = (byte)(nVal >> 16) return &dst[3:][0]
return (*byte)(incBytePtr(outputPtr, 3))
} }
// char* AMF_EncodeInt32(char* output, char* outend, int nVal); // char* AMF_EncodeInt32(char* output, char* outend, int nVal);
// amf.c +161 // amf.c +160
func C_AMF_EncodeInt32(output *byte, outend *byte, nVal int32) *byte { func C_AMF_EncodeInt32(dst []byte, val int32) *byte {
outputPtr := unsafe.Pointer(output) if len(dst) < 4 {
outendPtr := unsafe.Pointer(outend)
if uintptr(outputPtr)+4 > uintptr(outendPtr) {
// length < 4
return nil return nil
} }
// Assign output[3] binary.BigEndian.PutUint32(dst, uint32(val))
forth := (*byte)(incBytePtr(outputPtr, 3)) if len(dst) == 4 {
*forth = (byte)(nVal & 0xff) return nil
// Assign output[2] }
third := (*byte)(incBytePtr(outputPtr, 2)) return &dst[4:][0]
*third = (byte)(nVal >> 8)
// Assign output[1]
second := (*byte)(incBytePtr(outputPtr, 1))
*second = (byte)(nVal >> 16)
// Assign output[0]
*output = (byte)(nVal >> 24)
return (*byte)(incBytePtr(outputPtr, 4))
} }
// char* AMF_EncodeString(char* output, char* outend, const C_AVal* bv); // char* AMF_EncodeString(char* output, char* outend, const C_AVal* bv);
// amf.c +174 // amf.c +173
func C_AMF_EncodeString(output *byte, outend *byte, s string) *byte { func C_AMF_EncodeString(dst []byte, val string) *byte {
buflen := int(uintptr(unsafe.Pointer(outend)) - uintptr(unsafe.Pointer(output))) const typeSize = 1
if len(s) < 65536 && 1+2+len(s) > buflen { if len(val) < 65536 && len(val)+typeSize+binary.Size(int16(0)) > len(dst) {
return nil return nil
} }
if 1+4+len(s) > buflen { if len(val)+typeSize+binary.Size(int32(0)) > len(dst) {
return nil return nil
} }
outputPtr := unsafe.Pointer(output)
dst := (*[_Gi]byte)(unsafe.Pointer(output))[:buflen] if len(val) < 65536 {
if len(s) < 65536 {
dst[0] = AMF_STRING dst[0] = AMF_STRING
binary.BigEndian.PutUint16(dst[1:3], uint16(len(s))) dst = dst[1:]
copy(dst[3:], s) binary.BigEndian.PutUint16(dst[:2], uint16(len(val)))
outputPtr = incBytePtr(outputPtr, 3+len(s)) dst = dst[2:]
} else { copy(dst, val)
dst[0] = AMF_LONG_STRING if len(dst) == len(val) {
binary.BigEndian.PutUint32(dst[1:5], uint32(len(s))) return nil
copy(dst[5:], s)
outputPtr = incBytePtr(outputPtr, 5+len(s))
} }
return (*byte)(outputPtr) return &dst[len(val):][0]
}
dst[0] = AMF_LONG_STRING
dst = dst[1:]
binary.BigEndian.PutUint32(dst[:4], uint32(len(val)))
dst = dst[4:]
copy(dst, val)
if len(dst) == len(val) {
return nil
}
return &dst[len(val):][0]
} }
// char* AMF_EncodeNumber(char* output, char* outend, double dVal); // char* AMF_EncodeNumber(char* output, char* outend, double dVal);
@ -216,7 +218,7 @@ func C_AMF_EncodeNamedString(output *byte, outend *byte, key, val string) *byte
binary.BigEndian.PutUint16(dst[:2], uint16(len(key))) binary.BigEndian.PutUint16(dst[:2], uint16(len(key)))
copy(dst[2:], key) copy(dst[2:], key)
output = (*byte)(incBytePtr(unsafe.Pointer(output), 2+len(key))) output = (*byte)(incBytePtr(unsafe.Pointer(output), 2+len(key)))
return C_AMF_EncodeString(output, outend, val) return C_AMF_EncodeString(pp2b(output, outend), val)
} }
// char* AMF_EncodeNamedNumber(char* output, char* outend, const C_AVal* strName, double dVal); // char* AMF_EncodeNamedNumber(char* output, char* outend, const C_AVal* strName, double dVal);
@ -305,7 +307,7 @@ func C_AMF_PropEncode(p *C_AMFObjectProperty, pBuffer *byte, pBufEnd *byte) *byt
case AMF_BOOLEAN: case AMF_BOOLEAN:
pBuffer = C_AMF_EncodeBoolean(pBuffer, pBufEnd, p.p_vu.p_number != 0) pBuffer = C_AMF_EncodeBoolean(pBuffer, pBufEnd, p.p_vu.p_number != 0)
case AMF_STRING: case AMF_STRING:
pBuffer = C_AMF_EncodeString(pBuffer, pBufEnd, p.p_vu.p_aval) pBuffer = C_AMF_EncodeString(pp2b(pBuffer, pBufEnd), p.p_vu.p_aval)
case AMF_NULL: case AMF_NULL:
buflen = int(uintptr(unsafe.Pointer(pBufEnd)) - uintptr(unsafe.Pointer(pBuffer))) buflen = int(uintptr(unsafe.Pointer(pBufEnd)) - uintptr(unsafe.Pointer(pBuffer)))
if 1 >= buflen { if 1 >= buflen {
@ -571,7 +573,7 @@ func C_AMF_Encode(obj *C_AMFObject, pBuffer *byte, pBufEnd *byte) *byte {
return nil return nil
} }
pBuffer = C_AMF_EncodeInt24(pBuffer, pBufEnd, int32(AMF_OBJECT_END)) pBuffer = C_AMF_EncodeInt24(pp2b(pBuffer, pBufEnd), int32(AMF_OBJECT_END))
return pBuffer return pBuffer
} }
@ -586,7 +588,7 @@ func C_AMF_EncodeEcmaArray(obj *C_AMFObject, pBuffer *byte, pBufEnd *byte) *byte
*pBuffer = AMF_ECMA_ARRAY *pBuffer = AMF_ECMA_ARRAY
pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 1)) pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 1))
pBuffer = C_AMF_EncodeInt32(pBuffer, pBufEnd, obj.o_num) pBuffer = C_AMF_EncodeInt32(pp2b(pBuffer, pBufEnd), obj.o_num)
for i := 0; i < int(obj.o_num); i++ { for i := 0; i < int(obj.o_num); i++ {
res := C_AMF_PropEncode((*C_AMFObjectProperty)(incPtr(unsafe.Pointer( res := C_AMF_PropEncode((*C_AMFObjectProperty)(incPtr(unsafe.Pointer(
@ -603,7 +605,7 @@ func C_AMF_EncodeEcmaArray(obj *C_AMFObject, pBuffer *byte, pBufEnd *byte) *byte
return nil return nil
} }
pBuffer = C_AMF_EncodeInt24(pBuffer, pBufEnd, AMF_OBJECT_END) pBuffer = C_AMF_EncodeInt24(pp2b(pBuffer, pBufEnd), AMF_OBJECT_END)
return pBuffer return pBuffer
} }
@ -618,7 +620,7 @@ func C_AMF_EncodeArray(obj *C_AMFObject, pBuffer *byte, pBufEnd *byte) *byte {
*pBuffer = AMF_STRICT_ARRAY *pBuffer = AMF_STRICT_ARRAY
pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 1)) pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 1))
pBuffer = C_AMF_EncodeInt32(pBuffer, pBufEnd, obj.o_num) pBuffer = C_AMF_EncodeInt32(pp2b(pBuffer, pBufEnd), obj.o_num)
for i := 0; i < int(obj.o_num); i++ { for i := 0; i < int(obj.o_num); i++ {
res := C_AMF_PropEncode((*C_AMFObjectProperty)(incPtr(unsafe.Pointer( res := C_AMF_PropEncode((*C_AMFObjectProperty)(incPtr(unsafe.Pointer(

View File

@ -670,7 +670,7 @@ func C_SendConnectPacket(r *C_RTMP, cp *C_RTMPPacket) (ok bool) {
enc = (*byte)(unsafe.Pointer(packet.m_body)) enc = (*byte)(unsafe.Pointer(packet.m_body))
enc = C_AMF_EncodeString(enc, pend, av_connect) enc = C_AMF_EncodeString(pp2b(enc, pend), av_connect)
r.m_numInvokes += 1 r.m_numInvokes += 1
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes)) enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
@ -764,7 +764,7 @@ func C_SendConnectPacket(r *C_RTMP, cp *C_RTMPPacket) (ok bool) {
if enc == nil { if enc == nil {
return false return false
} }
enc = C_AMF_EncodeString(enc, pend, r.Link.auth) enc = C_AMF_EncodeString(pp2b(enc, pend), r.Link.auth)
if enc == nil { if enc == nil {
return false return false
} }
@ -806,7 +806,7 @@ func C_RTMP_SendCreateStream(r *C_RTMP) (ok bool) {
packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE] packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE]
enc = (*byte)(unsafe.Pointer(packet.m_body)) enc = (*byte)(unsafe.Pointer(packet.m_body))
enc = C_AMF_EncodeString(enc, pend, av_createStream) enc = C_AMF_EncodeString(pp2b(enc, pend), av_createStream)
r.m_numInvokes++ r.m_numInvokes++
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes)) enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL *enc = AMF_NULL
@ -836,12 +836,12 @@ func C_SendReleaseStream(r *C_RTMP) (ok bool) {
packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE] packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE]
enc = (*byte)(unsafe.Pointer(packet.m_body)) enc = (*byte)(unsafe.Pointer(packet.m_body))
enc = C_AMF_EncodeString(enc, pend, av_releaseStream) enc = C_AMF_EncodeString(pp2b(enc, pend), av_releaseStream)
r.m_numInvokes++ r.m_numInvokes++
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes)) enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL *enc = AMF_NULL
enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1)) enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1))
enc = C_AMF_EncodeString(enc, pend, r.Link.playpath) enc = C_AMF_EncodeString(pp2b(enc, pend), r.Link.playpath)
if enc == nil { if enc == nil {
return false return false
} }
@ -869,12 +869,12 @@ func C_SendFCPublish(r *C_RTMP) (ok bool) {
packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE] packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE]
enc = (*byte)(unsafe.Pointer(packet.m_body)) enc = (*byte)(unsafe.Pointer(packet.m_body))
enc = C_AMF_EncodeString(enc, pend, av_FCPublish) enc = C_AMF_EncodeString(pp2b(enc, pend), av_FCPublish)
r.m_numInvokes++ r.m_numInvokes++
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes)) enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL *enc = AMF_NULL
enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1)) enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1))
enc = C_AMF_EncodeString(enc, pend, r.Link.playpath) enc = C_AMF_EncodeString(pp2b(enc, pend), r.Link.playpath)
if enc == nil { if enc == nil {
return false return false
} }
@ -902,12 +902,12 @@ func C_SendFCUnpublish(r *C_RTMP) (ok bool) {
packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE] packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE]
enc = (*byte)(unsafe.Pointer(packet.m_body)) enc = (*byte)(unsafe.Pointer(packet.m_body))
enc = C_AMF_EncodeString(enc, pend, av_FCUnpublish) enc = C_AMF_EncodeString(pp2b(enc, pend), av_FCUnpublish)
r.m_numInvokes++ r.m_numInvokes++
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes)) enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL *enc = AMF_NULL
enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1)) enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1))
enc = C_AMF_EncodeString(enc, pend, r.Link.playpath) enc = C_AMF_EncodeString(pp2b(enc, pend), r.Link.playpath)
if enc == nil { if enc == nil {
return false return false
@ -937,18 +937,18 @@ func C_SendPublish(r *C_RTMP) (ok bool) {
packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE] packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE]
enc = (*byte)(unsafe.Pointer(packet.m_body)) enc = (*byte)(unsafe.Pointer(packet.m_body))
enc = C_AMF_EncodeString(enc, pend, av_publish) enc = C_AMF_EncodeString(pp2b(enc, pend), av_publish)
r.m_numInvokes++ r.m_numInvokes++
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes)) enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL *enc = AMF_NULL
enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1)) enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1))
enc = C_AMF_EncodeString(enc, pend, r.Link.playpath) enc = C_AMF_EncodeString(pp2b(enc, pend), r.Link.playpath)
if enc == nil { if enc == nil {
return false return false
} }
enc = C_AMF_EncodeString(enc, pend, av_live) enc = C_AMF_EncodeString(pp2b(enc, pend), av_live)
if enc == nil { if enc == nil {
return false return false
} }
@ -977,7 +977,7 @@ func C_SendDeleteStream(r *C_RTMP, dStreamId float64) (ok bool) {
packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE] packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE]
enc = (*byte)(unsafe.Pointer(packet.m_body)) enc = (*byte)(unsafe.Pointer(packet.m_body))
enc = C_AMF_EncodeString(enc, pend, av_deleteStream) enc = C_AMF_EncodeString(pp2b(enc, pend), av_deleteStream)
r.m_numInvokes++ r.m_numInvokes++
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes)) enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL *enc = AMF_NULL
@ -1008,7 +1008,7 @@ func C_SendBytesReceived(r *C_RTMP) (ok bool) {
packet.m_nBodySize = 4 packet.m_nBodySize = 4
C_AMF_EncodeInt32(packet.m_body, pend, r.m_nBytesIn) C_AMF_EncodeInt32(pp2b(packet.m_body, pend), r.m_nBytesIn)
r.m_nBytesInSent = r.m_nBytesIn r.m_nBytesInSent = r.m_nBytesIn
@ -1033,7 +1033,7 @@ func C_SendCheckBW(r *C_RTMP) (ok bool) {
packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE] packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE]
enc = (*byte)(unsafe.Pointer(packet.m_body)) enc = (*byte)(unsafe.Pointer(packet.m_body))
enc = C_AMF_EncodeString(enc, pend, av__checkbw) enc = C_AMF_EncodeString(pp2b(enc, pend), av__checkbw)
r.m_numInvokes++ r.m_numInvokes++
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes)) enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL *enc = AMF_NULL
@ -1598,11 +1598,11 @@ func C_RTMP_SendPacket(r *C_RTMP, packet *C_RTMPPacket, queue int) (ok bool) {
if t > 0xffffff { if t > 0xffffff {
res = 0xffffff res = 0xffffff
} }
hptr = unsafe.Pointer(C_AMF_EncodeInt24((*byte)(hptr), (*byte)(hend), int32(res))) hptr = unsafe.Pointer(C_AMF_EncodeInt24(pp2b((*byte)(hptr), (*byte)(hend)), int32(res)))
} }
if nSize > 4 { if nSize > 4 {
hptr = unsafe.Pointer(C_AMF_EncodeInt24((*byte)(hptr), (*byte)(hend), (int32(packet.m_nBodySize)))) hptr = unsafe.Pointer(C_AMF_EncodeInt24(pp2b((*byte)(hptr), (*byte)(hend)), (int32(packet.m_nBodySize))))
*(*byte)(hptr) = packet.m_packetType *(*byte)(hptr) = packet.m_packetType
hptr = incBytePtr(hptr, 1) hptr = incBytePtr(hptr, 1)
} }
@ -1612,7 +1612,7 @@ func C_RTMP_SendPacket(r *C_RTMP, packet *C_RTMPPacket, queue int) (ok bool) {
} }
if t >= 0xffffff { if t >= 0xffffff {
hptr = unsafe.Pointer(C_AMF_EncodeInt32((*byte)(hptr), (*byte)(hend), (int32)(t))) hptr = unsafe.Pointer(C_AMF_EncodeInt32(pp2b((*byte)(hptr), (*byte)(hend)), (int32)(t)))
} }
nSize = int(packet.m_nBodySize) nSize = int(packet.m_nBodySize)
@ -1668,8 +1668,7 @@ func C_RTMP_SendPacket(r *C_RTMP, packet *C_RTMPPacket, queue int) (ok bool) {
} }
if t >= 0xffffff { if t >= 0xffffff {
extendedTimestamp := incBytePtr(header, 1+cSize) extendedTimestamp := incBytePtr(header, 1+cSize)
C_AMF_EncodeInt32((*byte)(extendedTimestamp), C_AMF_EncodeInt32((*[_Gi]byte)(extendedTimestamp)[:4], (int32)(t))
(*byte)(incBytePtr(extendedTimestamp, 4)), (int32)(t))
} }
} }
} }
@ -1873,8 +1872,8 @@ func C_RTMP_Write(r *C_RTMP, buf []byte) int {
pend = enc[pkt.m_nBodySize:] pend = enc[pkt.m_nBodySize:]
if pkt.m_packetType == RTMP_PACKET_TYPE_INFO { if pkt.m_packetType == RTMP_PACKET_TYPE_INFO {
enc = (*[_Gi]byte)(unsafe.Pointer(C_AMF_EncodeString((*byte)(unsafe.Pointer(&enc[0])), enc = (*[_Gi]byte)(unsafe.Pointer(C_AMF_EncodeString(pp2b((*byte)(unsafe.Pointer(&enc[0])),
(*byte)(unsafe.Pointer(&pend[0])), setDataFrame)))[:pkt.m_nBodySize] (*byte)(unsafe.Pointer(&pend[0]))), setDataFrame)))[:pkt.m_nBodySize]
// TODO: work out what to do with this // TODO: work out what to do with this
pkt.m_nBytesRead = uint32(float64(uintptr(unsafe.Pointer(&enc[0])) - pkt.m_nBytesRead = uint32(float64(uintptr(unsafe.Pointer(&enc[0])) -