rtmp: remove C_AVal from encoder/decoder functions

This commit is contained in:
Dan Kortschak 2018-09-06 13:43:40 +09:30
parent 019a1f1c90
commit 470e61a465
3 changed files with 99 additions and 101 deletions

View File

@ -39,6 +39,7 @@ package rtmp
import "C"
import (
"encoding/binary"
"log"
"unsafe"
)
@ -91,24 +92,22 @@ func C_AMF_DecodeInt32(data *byte) uint32 {
// void AMF_DecodeString(const char* data, C_AVal* bv);
// amf.c +68
func C_AMF_DecodeString(data *byte) C_AVal {
var bv C_AVal
bv.av_len = int32(C_AMF_DecodeInt16(data))
if bv.av_len != 0 {
bv.av_val = (*byte)(incBytePtr(unsafe.Pointer(data), 2))
func C_AMF_DecodeString(data *byte) string {
n := C_AMF_DecodeInt16(data)
if n == 0 {
return ""
}
return bv
return string((*[_Gi]byte)(incBytePtr(unsafe.Pointer(data), 2))[:n])
}
// void AMF_DecodeLongString(const char *data, AVal *bv);
// amf.c +75
func C_AMF_DecodeLongString(data *byte) C_AVal {
var bv C_AVal
bv.av_len = int32(C_AMF_DecodeInt32(data))
if bv.av_len != 0 {
bv.av_val = (*byte)(incBytePtr(unsafe.Pointer(data), 4))
func C_AMF_DecodeLongString(data *byte) string {
n := C_AMF_DecodeInt32(data)
if n == 0 {
return ""
}
return bv
return string((*[_Gi]byte)(incBytePtr(unsafe.Pointer(data), 4))[:n])
}
// double AMF_DecodeNumber(const char* data);
@ -195,33 +194,27 @@ func C_AMF_EncodeInt32(output *byte, outend *byte, nVal int32) *byte {
// char* AMF_EncodeString(char* output, char* outend, const C_AVal* bv);
// amf.c +174
func C_AMF_EncodeString(output *byte, outend *byte, bv *C_AVal) *byte {
outputPtr := unsafe.Pointer(output)
outendPtr := unsafe.Pointer(outend)
if (bv.av_len < 65536 && uintptr(incBytePtr(outputPtr, 1+2+int(bv.av_len))) >
uintptr(outendPtr)) || uintptr(incBytePtr(outputPtr, 1+4+int(bv.av_len))) >
uintptr(outendPtr) {
func C_AMF_EncodeString(output *byte, outend *byte, s string) *byte {
buflen := int(uintptr(unsafe.Pointer(outend)) - uintptr(unsafe.Pointer(output)))
if len(s) < 65536 && 1+2+len(s) > buflen {
return nil
}
if bv.av_len < 65536 {
*(*byte)(outputPtr) = AMF_STRING
outputPtr = incBytePtr(outputPtr, 1)
// TODO: port AMF_EncodeInt16
outputPtr = unsafe.Pointer(C_AMF_EncodeInt16((*byte)(outputPtr), (*byte)(
outendPtr), int16(bv.av_len)))
//outputPtr = unsafe.Pointer(C_AMF_EncodeInt16((*byte)(outputPtr),
//(*byte)(outendPtr), (int16)(bv.av_len)))
} else {
*(*byte)(outputPtr) = AMF_LONG_STRING
outputPtr = incBytePtr(outputPtr, 1)
outputPtr = unsafe.Pointer(C_AMF_EncodeInt32((*byte)(outputPtr), (*byte)(
outendPtr), int32(bv.av_len)))
//outputPtr = unsafe.Pointer(C_AMF_EncodeInt32((*byte)(outputPtr),
//(*byte)(outendPtr), (int32)(bv.av_len)))
if 1+4+len(s) > buflen {
return nil
}
outputPtr := unsafe.Pointer(output)
dst := (*[_Gi]byte)(unsafe.Pointer(output))[:buflen]
if len(s) < 65536 {
dst[0] = AMF_STRING
binary.BigEndian.PutUint16(dst[1:3], uint16(len(s)))
copy(dst[3:], s)
outputPtr = incBytePtr(outputPtr, 3+len(s))
} else {
dst[0] = AMF_LONG_STRING
binary.BigEndian.PutUint32(dst[1:5], uint32(len(s)))
copy(dst[5:], s)
outputPtr = incBytePtr(outputPtr, 5+len(s))
}
memmove(unsafe.Pointer(outputPtr), unsafe.Pointer(bv.av_val), uintptr(bv.av_len))
//C.memcpy(unsafe.Pointer(outputPtr), unsafe.Pointer(bv.av_val), (C.size_t)(bv.av_len))
outputPtr = incBytePtr(outputPtr, int(bv.av_len))
return (*byte)(outputPtr)
}
@ -264,38 +257,44 @@ func C_AMF_EncodeBoolean(output *byte, outend *byte, bVal int) *byte {
// char* AMF_EncodeNamedString(char* output, char* outend, const C_AVal* strName, const C_AVal* strValue);
// amf.c +273
func C_AMF_EncodeNamedString(output *byte, outend *byte, strName *C_AVal, strValue *C_AVal) *byte {
if int(uintptr(unsafe.Pointer(output)))+2+int(strName.av_len) > int(uintptr(unsafe.Pointer(outend))) {
func C_AMF_EncodeNamedString(output *byte, outend *byte, key, val string) *byte {
buflen := int(uintptr(unsafe.Pointer(outend)) - uintptr(unsafe.Pointer(output)))
if 2+len(key) > buflen {
return nil
}
output = C_AMF_EncodeInt16(output, outend, int16(strName.av_len))
memmove(unsafe.Pointer(output), unsafe.Pointer(strName.av_val), uintptr(strName.av_len))
output = (*byte)(incBytePtr(unsafe.Pointer(output), int(strName.av_len)))
return C_AMF_EncodeString(output, outend, strValue)
dst := (*[_Gi]byte)(unsafe.Pointer(output))[:buflen]
binary.BigEndian.PutUint16(dst[:2], uint16(len(key)))
copy(dst[2:], key)
output = (*byte)(incBytePtr(unsafe.Pointer(output), 2+len(key)))
return C_AMF_EncodeString(output, outend, val)
}
// char* AMF_EncodeNamedNumber(char* output, char* outend, const C_AVal* strName, double dVal);
// amf.c +286
func C_AMF_EncodeNamedNumber(output *byte, outend *byte, strName *C_AVal, dVal float64) *byte {
if int(uintptr(unsafe.Pointer(output)))+2+int(strName.av_len) > int(uintptr(unsafe.Pointer(outend))) {
func C_AMF_EncodeNamedNumber(output *byte, outend *byte, key string, val float64) *byte {
buflen := int(uintptr(unsafe.Pointer(outend)) - uintptr(unsafe.Pointer(output)))
if 2+len(key) > buflen {
return nil
}
output = C_AMF_EncodeInt16(output, outend, int16(strName.av_len))
memmove(unsafe.Pointer(output), unsafe.Pointer(strName.av_val), uintptr(strName.av_len))
output = (*byte)(incBytePtr(unsafe.Pointer(output), int(strName.av_len)))
return C_AMF_EncodeNumber(output, outend, dVal)
dst := (*[_Gi]byte)(unsafe.Pointer(output))[:buflen]
binary.BigEndian.PutUint16(dst[:2], uint16(len(key)))
copy(dst[2:], key)
output = (*byte)(incBytePtr(unsafe.Pointer(output), 2+len(key)))
return C_AMF_EncodeNumber(output, outend, val)
}
// char* AMF_EncodeNamedBoolean(char* output, char* outend, const C_AVal* strname, int bVal);
// amf.c +299
func C_AMF_EncodeNamedBoolean(output *byte, outend *byte, strName *C_AVal, bVal int) *byte {
if int(uintptr(unsafe.Pointer(output)))+2+int(strName.av_len) > int(uintptr(unsafe.Pointer(outend))) {
func C_AMF_EncodeNamedBoolean(output *byte, outend *byte, key string, val int) *byte {
buflen := int(uintptr(unsafe.Pointer(outend)) - uintptr(unsafe.Pointer(output)))
if 2+len(key) > buflen {
return nil
}
output = C_AMF_EncodeInt16(output, outend, int16(strName.av_len))
memmove(unsafe.Pointer(output), unsafe.Pointer(strName.av_val), uintptr(strName.av_len))
output = (*byte)(incBytePtr(unsafe.Pointer(output), int(strName.av_len)))
return C_AMF_EncodeBoolean(output, outend, bVal)
dst := (*[_Gi]byte)(unsafe.Pointer(output))[:buflen]
binary.BigEndian.PutUint16(dst[:2], uint16(len(key)))
copy(dst[2:], key)
output = (*byte)(incBytePtr(unsafe.Pointer(output), 2+len(key)))
return C_AMF_EncodeBoolean(output, outend, val)
}
// void AMFProp_SetName(AMFObjectProperty *prop, AVal *name);
@ -363,7 +362,7 @@ func C_AMF_PropEncode(p *C_AMFObjectProperty, pBuffer *byte, pBufEnd *byte) *byt
}
pBuffer = C_AMF_EncodeBoolean(pBuffer, pBufEnd, val)
case AMF_STRING:
pBuffer = C_AMF_EncodeString(pBuffer, pBufEnd, &p.p_vu.p_aval)
pBuffer = C_AMF_EncodeString(pBuffer, pBufEnd, CAV(&p.p_vu.p_aval))
case AMF_NULL:
if uintptr(incBytePtr(unsafe.Pointer(pBuffer), 1)) >= uintptr(unsafe.Pointer(
pBufEnd)) {
@ -489,7 +488,7 @@ func C_AMFProp_Decode(prop *C_AMFObjectProperty, pBuffer *byte, nSize, bDecodeNa
return -1
}
prop.p_name = C_AMF_DecodeString(pBuffer)
prop.p_name = AVC(C_AMF_DecodeString(pBuffer))
nSize -= int32(2 + nNameSize)
pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), int(2+nNameSize)))
}
@ -520,7 +519,7 @@ func C_AMFProp_Decode(prop *C_AMFObjectProperty, pBuffer *byte, nSize, bDecodeNa
if int64(nSize) < int64(nStringSize)+2 {
return -1
}
prop.p_vu.p_aval = C_AMF_DecodeString(pBuffer)
prop.p_vu.p_aval = AVC(C_AMF_DecodeString(pBuffer))
nSize -= int32(2 + nStringSize)
case AMF_OBJECT:

View File

@ -81,6 +81,10 @@ func AVC(str string) C_AVal {
return aval
}
func CAV(av *C_AVal) string {
return string((*[_Gi]byte)(unsafe.Pointer(av.av_val))[:av.av_len])
}
// #define AVMATCH(a1,a2)
// amf.h +63
func C_AVMATCH(a1, a2 *C_AVal) int32 {

View File

@ -737,7 +737,7 @@ func C_SendConnectPacket(r *C_RTMP, cp *C_RTMPPacket) (ok bool) {
enc = (*byte)(unsafe.Pointer(packet.m_body))
enc = C_AMF_EncodeString(enc, pend, &av_connect)
enc = C_AMF_EncodeString(enc, pend, CAV(&av_connect))
r.m_numInvokes += 1
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
@ -746,60 +746,60 @@ func C_SendConnectPacket(r *C_RTMP, cp *C_RTMPPacket) (ok bool) {
enc = (*byte)(unsafe.Pointer(incBytePtr(unsafe.Pointer(enc), 1)))
enc = C_AMF_EncodeNamedString(enc, pend, &av_app, &r.Link.app)
enc = C_AMF_EncodeNamedString(enc, pend, CAV(&av_app), CAV(&r.Link.app))
if enc == nil {
return false
}
if r.Link.protocol&RTMP_FEATURE_WRITE != 0 {
enc = C_AMF_EncodeNamedString(enc, pend, &av_type, &av_nonprivate)
enc = C_AMF_EncodeNamedString(enc, pend, CAV(&av_type), CAV(&av_nonprivate))
if enc == nil {
return false
}
}
if r.Link.flashVer.av_len != 0 {
enc = C_AMF_EncodeNamedString(enc, pend, &av_flashVer, &r.Link.flashVer)
enc = C_AMF_EncodeNamedString(enc, pend, CAV(&av_flashVer), CAV(&r.Link.flashVer))
if enc == nil {
return false
}
}
if r.Link.swfUrl.av_len != 0 {
enc = C_AMF_EncodeNamedString(enc, pend, &av_swfUrl, &r.Link.swfUrl)
enc = C_AMF_EncodeNamedString(enc, pend, CAV(&av_swfUrl), CAV(&r.Link.swfUrl))
if enc == nil {
return false
}
}
if r.Link.tcUrl.av_len != 0 {
enc = C_AMF_EncodeNamedString(enc, pend, &av_tcUrl, &r.Link.tcUrl)
enc = C_AMF_EncodeNamedString(enc, pend, CAV(&av_tcUrl), CAV(&r.Link.tcUrl))
if enc == nil {
return false
}
}
if r.Link.protocol&RTMP_FEATURE_WRITE == 0 {
enc = C_AMF_EncodeNamedBoolean(enc, pend, &av_fpad, 0)
enc = C_AMF_EncodeNamedBoolean(enc, pend, CAV(&av_fpad), 0)
if enc == nil {
return false
}
enc = C_AMF_EncodeNamedNumber(enc, pend, &av_capabilities, 15.0)
enc = C_AMF_EncodeNamedNumber(enc, pend, CAV(&av_capabilities), 15)
if enc == nil {
return false
}
enc = C_AMF_EncodeNamedNumber(enc, pend, &av_audioCodecs, float64(r.m_fAudioCodecs))
enc = C_AMF_EncodeNamedNumber(enc, pend, CAV(&av_audioCodecs), float64(r.m_fAudioCodecs))
if enc == nil {
return false
}
enc = C_AMF_EncodeNamedNumber(enc, pend, &av_videoCodecs, float64(r.m_fVideoCodecs))
enc = C_AMF_EncodeNamedNumber(enc, pend, CAV(&av_videoCodecs), float64(r.m_fVideoCodecs))
if enc == nil {
return false
}
enc = C_AMF_EncodeNamedNumber(enc, pend, &av_videoFunction, 1.0)
enc = C_AMF_EncodeNamedNumber(enc, pend, CAV(&av_videoFunction), 1)
if enc == nil {
return false
}
if r.Link.pageUrl.av_len != 0 {
enc = C_AMF_EncodeNamedString(enc, pend, &av_pageUrl, &r.Link.pageUrl)
enc = C_AMF_EncodeNamedString(enc, pend, CAV(&av_pageUrl), CAV(&r.Link.pageUrl))
if enc == nil {
return false
}
@ -807,7 +807,7 @@ func C_SendConnectPacket(r *C_RTMP, cp *C_RTMPPacket) (ok bool) {
}
if r.m_fEncoding != 0.0 || r.m_bSendEncoding != 0 {
enc = C_AMF_EncodeNamedNumber(enc, pend, &av_objectEncoding, float64(r.m_fEncoding))
enc = C_AMF_EncodeNamedNumber(enc, pend, CAV(&av_objectEncoding), float64(r.m_fEncoding))
if enc == nil {
return false
}
@ -831,7 +831,7 @@ func C_SendConnectPacket(r *C_RTMP, cp *C_RTMPPacket) (ok bool) {
if enc == nil {
return false
}
enc = C_AMF_EncodeString(enc, (*byte)(pend), &r.Link.auth)
enc = C_AMF_EncodeString(enc, (*byte)(pend), CAV(&r.Link.auth))
if enc == nil {
return false
}
@ -873,7 +873,7 @@ func C_RTMP_SendCreateStream(r *C_RTMP) (ok bool) {
packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE]
enc = (*byte)(unsafe.Pointer(packet.m_body))
enc = C_AMF_EncodeString(enc, pend, &av_createStream)
enc = C_AMF_EncodeString(enc, pend, CAV(&av_createStream))
r.m_numInvokes++
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL
@ -903,12 +903,12 @@ func C_SendReleaseStream(r *C_RTMP) (ok bool) {
packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE]
enc = (*byte)(unsafe.Pointer(packet.m_body))
enc = C_AMF_EncodeString(enc, pend, &av_releaseStream)
enc = C_AMF_EncodeString(enc, pend, CAV(&av_releaseStream))
r.m_numInvokes++
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL
enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1))
enc = C_AMF_EncodeString(enc, pend, &r.Link.playpath)
enc = C_AMF_EncodeString(enc, pend, CAV(&r.Link.playpath))
if enc == nil {
return false
}
@ -936,12 +936,12 @@ func C_SendFCPublish(r *C_RTMP) (ok bool) {
packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE]
enc = (*byte)(unsafe.Pointer(packet.m_body))
enc = C_AMF_EncodeString(enc, pend, &av_FCPublish)
enc = C_AMF_EncodeString(enc, pend, CAV(&av_FCPublish))
r.m_numInvokes++
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL
enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1))
enc = C_AMF_EncodeString(enc, pend, &r.Link.playpath)
enc = C_AMF_EncodeString(enc, pend, CAV(&r.Link.playpath))
if enc == nil {
return false
}
@ -969,12 +969,12 @@ func C_SendFCUnpublish(r *C_RTMP) (ok bool) {
packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE]
enc = (*byte)(unsafe.Pointer(packet.m_body))
enc = C_AMF_EncodeString(enc, pend, &av_FCUnpublish)
enc = C_AMF_EncodeString(enc, pend, CAV(&av_FCUnpublish))
r.m_numInvokes++
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL
enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1))
enc = C_AMF_EncodeString(enc, pend, &r.Link.playpath)
enc = C_AMF_EncodeString(enc, pend, CAV(&r.Link.playpath))
if enc == nil {
return false
@ -1004,18 +1004,18 @@ func C_SendPublish(r *C_RTMP) (ok bool) {
packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE]
enc = (*byte)(unsafe.Pointer(packet.m_body))
enc = C_AMF_EncodeString(enc, pend, &av_publish)
enc = C_AMF_EncodeString(enc, pend, CAV(&av_publish))
r.m_numInvokes++
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL
enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1))
enc = C_AMF_EncodeString(enc, pend, &r.Link.playpath)
enc = C_AMF_EncodeString(enc, pend, CAV(&r.Link.playpath))
if enc == nil {
return false
}
enc = C_AMF_EncodeString(enc, pend, &av_live)
enc = C_AMF_EncodeString(enc, pend, CAV(&av_live))
if enc == nil {
return false
}
@ -1044,7 +1044,7 @@ func C_SendDeleteStream(r *C_RTMP, dStreamId float64) (ok bool) {
packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE]
enc = (*byte)(unsafe.Pointer(packet.m_body))
enc = C_AMF_EncodeString(enc, pend, &av_deleteStream)
enc = C_AMF_EncodeString(enc, pend, CAV(&av_deleteStream))
r.m_numInvokes++
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL
@ -1100,7 +1100,7 @@ func C_SendCheckBW(r *C_RTMP) (ok bool) {
packet.m_body = &pbuf[RTMP_MAX_HEADER_SIZE]
enc = (*byte)(unsafe.Pointer(packet.m_body))
enc = C_AMF_EncodeString(enc, pend, &av__checkbw)
enc = C_AMF_EncodeString(enc, pend, CAV(&av__checkbw))
r.m_numInvokes++
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL
@ -1135,23 +1135,20 @@ func C_AV_erase(vals *C_RTMP_METHOD, num *int32, i, freeit int32) {
// void AV_queue(RTMP_METHOD** vals, int* num, C_AVal* av, int txn);
// rtmp.c +2414
func C_AV_queue(vals **C_RTMP_METHOD, num *int32, av *C_AVal, txn int32) {
func C_AV_queue(vals **C_RTMP_METHOD, num *int32, av string, txn int32) {
if (*num & 0x0f) == 0 {
*vals = (*C_RTMP_METHOD)(C.realloc(unsafe.Pointer(*vals), C.size_t((*num+16)*
int32(unsafe.Sizeof(*(*vals))))))
*vals = (*C_RTMP_METHOD)(C.realloc(unsafe.Pointer(*vals), C.size_t((*num+16)*int32(unsafe.Sizeof(**vals)))))
}
tmp := malloc(uintptr(av.av_len + 1))
//tmp := allocate(uintptr(av.av_len + 1))
memmove(tmp, unsafe.Pointer(av.av_val), uintptr(av.av_len))
(*[_Gi]byte)(tmp)[av.av_len] = '\000'
tmp := make([]byte, len(av)+1)
copy(tmp, av)
(*(*C_RTMP_METHOD)(incPtr(unsafe.Pointer(*vals), int(*num),
int(unsafe.Sizeof(*(*vals)))))).num = int32(txn)
int(unsafe.Sizeof(**vals))))).num = int32(txn)
(*(*C_RTMP_METHOD)(incPtr(unsafe.Pointer(*vals), int(*num),
int(unsafe.Sizeof(*(*vals)))))).name.av_len = av.av_len
int(unsafe.Sizeof(**vals))))).name.av_len = int32(len(av))
(*(*C_RTMP_METHOD)(incPtr(unsafe.Pointer(*vals), int(*num),
int(unsafe.Sizeof(*(*vals)))))).name.av_val = (*byte)(tmp)
(*num)++
int(unsafe.Sizeof(**vals))))).name.av_val = &tmp[0]
*num++
}
// int HandleInvoke(RTMP* r, const char* body, unsigned int nBodySize);
@ -1863,15 +1860,13 @@ func C_RTMP_SendPacket(r *C_RTMP, packet *C_RTMPPacket, queue int) (ok bool) {
method := C_AMF_DecodeString((*byte)(ptr))
if debugMode {
log.Printf("Invoking %v", method.av_val)
log.Printf("invoking %v", method)
}
// keep it in call queue till result arrives
if queue != 0 {
var txn int
ptr = incBytePtr(ptr, 3+int(method.av_len))
txn = int(C_AMF_DecodeNumber((*byte)(ptr)))
C_AV_queue(&r.m_methodCalls, (*int32)(unsafe.Pointer(&r.m_numCalls)),
&method, int32(txn))
ptr = incBytePtr(ptr, 3+len(method))
txn := int32(C_AMF_DecodeNumber((*byte)(ptr)))
C_AV_queue(&r.m_methodCalls, (*int32)(unsafe.Pointer(&r.m_numCalls)), method, txn)
}
}
@ -2076,7 +2071,7 @@ func C_RTMP_Write(r *C_RTMP, buf []byte) int {
if pkt.m_packetType == RTMP_PACKET_TYPE_INFO {
enc = (*[_Gi]byte)(unsafe.Pointer(C_AMF_EncodeString((*byte)(unsafe.Pointer(&enc[0])),
(*byte)(unsafe.Pointer(&pend[0])), &setDataFrame)))[:pkt.m_nBodySize]
(*byte)(unsafe.Pointer(&pend[0])), CAV(&setDataFrame))))[:pkt.m_nBodySize]
// TODO: work out what to do with this
pkt.m_nBytesRead = uint32(float64(uintptr(unsafe.Pointer(&enc[0])) -