diff --git a/rtmp/rtmp.go b/rtmp/rtmp.go index c8e64699..4711acc5 100644 --- a/rtmp/rtmp.go +++ b/rtmp/rtmp.go @@ -1093,10 +1093,13 @@ func sendConnectPacket(r *C.RTMP, cp *C.RTMPPacket) int { if r.Link.extras.o_num != 0 { for i := 0; i < int(r.Link.extras.o_num); i++ { - enc = (*byte)(unsafe.Pointer(C.AMFProp_Encode((*C.AMFObjectProperty)( - incPtr(unsafe.Pointer(&r.Link.extras.o_props), int(unsafe.Sizeof( - r.Link.extras.o_props)), i)), (*C.char)(unsafe.Pointer(enc)), (*C.char)( - unsafe.Pointer(pend))))) + //enc = (*byte)(unsafe.Pointer(C.AMFProp_Encode((*C.AMFObjectProperty)( + //incPtr(unsafe.Pointer(&r.Link.extras.o_props), int(unsafe.Sizeof( + //r.Link.extras.o_props)), i)), (*C.char)(unsafe.Pointer(enc)), (*C.char)( + //unsafe.Pointer(pend))))) + enc = amfPropEncode((*C.AMFObjectProperty)(incPtr(unsafe.Pointer( + &r.Link.extras.o_props), int(unsafe.Sizeof(r.Link.extras.o_props)), i)), + enc, pend) if enc == nil { return 0 @@ -1111,6 +1114,59 @@ func sendConnectPacket(r *C.RTMP, cp *C.RTMPPacket) int { return rtmpSendPacket(r, &packet, 1) } +func amfPropEncode(p *C.AMFObjectProperty, pBuffer *byte, pBufEnd *byte) *byte { + if p.p_type == AMF_INVALID { + return nil + } + + if p.p_type != AMF_NULL && int(uintptr(unsafe.Pointer(pBuffer)))+ + int(p.p_name.av_len)+2+1 >= int( + uintptr(unsafe.Pointer(pBufEnd))) { + return nil + } + + if p.p_type != AMF_NULL && p.p_name.av_len != 0 { + *indxBytePtr(unsafe.Pointer(pBuffer), 0) = byte(p.p_name.av_len >> 8) + pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 1)) + *indxBytePtr(unsafe.Pointer(pBuffer), 0) = byte(p.p_name.av_len & 0xff) + pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 1)) + memmove(unsafe.Pointer(pBuffer), unsafe.Pointer(p.p_name.av_val), + uintptr(p.p_name.av_len)) + pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), int(p.p_name.av_len))) + } + + switch p.p_type { + case AMF_NUMBER: + pBuffer = amfEncodeNumber(pBuffer, pBufEnd, float64(p.p_vu.p_number)) + case AMF_BOOLEAN: + val := 0 + if p.p_vu.p_number != 0 { + val = 1 + } + pBuffer = amfEncodeBoolean(pBuffer, pBufEnd, val) + case AMF_STRING: + pBuffer = amfEncodeString(pBuffer, pBufEnd, &p.p_vu.p_aval) + case AMF_NULL: + if uintptr(incBytePtr(unsafe.Pointer(pBuffer), 1)) >= uintptr(unsafe.Pointer( + pBufEnd)) { + return nil + } + *(*byte)(unsafe.Pointer(pBuffer)) = AMF_NULL + pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 1)) + case AMF_OBJECT: + pBuffer = (*byte)(unsafe.Pointer(C.AMF_Encode(&p.p_vu.p_object, (*C.char)( + unsafe.Pointer(pBuffer)), (*C.char)(unsafe.Pointer(pBufEnd))))) + case AMF_ECMA_ARRAY: + pBuffer = (*byte)(unsafe.Pointer(C.AMF_EncodeEcmaArray(&p.p_vu.p_object, (*C.char)(unsafe.Pointer(pBuffer)), (*C.char)(unsafe.Pointer(pBufEnd))))) + case AMF_STRICT_ARRAY: + pBuffer = (*byte)(unsafe.Pointer(C.AMF_EncodeArray(&p.p_vu.p_object, (*C.char)(unsafe.Pointer(pBuffer)), (*C.char)(unsafe.Pointer(pBufEnd))))) + default: + log.Println("amfPropEncode: invalid type!") + pBuffer = nil + } + return pBuffer +} + func rtmpConnectStream(r *C.RTMP, seekTime int32) int { var packet C.RTMPPacket memset((*byte)(unsafe.Pointer(&packet)), 0, int(unsafe.Sizeof(packet))) @@ -1121,7 +1177,7 @@ func rtmpConnectStream(r *C.RTMP, seekTime int32) int { r.m_mediaChannel = 0 - // TODO: port is connected and read packet + // TODO: read packet for r.m_bPlaying == 0 && rtmpIsConnected(r) != 0 && C.RTMP_ReadPacket(r, &packet) != 0 { @@ -1495,7 +1551,6 @@ func rtmpSendPacket(r *C.RTMP, packet *C.RTMPPacket, queue int) int { ptr = incBytePtr(ptr, 3+int(method.av_len)) //txn = int(C.AMF_DecodeNumber((*C.char)(ptr))) txn = int(amfDecodeNumber((*byte)(ptr))) - // TODO: port this avQueue(&r.m_methodCalls, (*int32)(unsafe.Pointer(&r.m_numCalls)), &method, int32(txn)) //C.AV_queue(&r.m_methodCalls, (*C.int)(unsafe.Pointer(&r.m_numCalls)), &method,