From 8be354a6d5705344e43f2efc2121500e96165c7b Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Wed, 15 Aug 2018 19:27:14 +0930 Subject: [PATCH] Port AMF3ReadInteger, AMF3ReadString, AMF3DC_AddProp and AMFProp_SetName --- rtmp/rtmp.go | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/rtmp/rtmp.go b/rtmp/rtmp.go index 57192e63..16680f8d 100644 --- a/rtmp/rtmp.go +++ b/rtmp/rtmp.go @@ -3558,6 +3558,86 @@ func C_AMF_EncodeNamedBoolean(output *byte, outend *byte, strName *C.AVal, bVal return C_AMF_EncodeBoolean(output, outend, bVal) } +// void AMFProp_SetName(AMFObjectProperty *prop, AVal *name); +// amf.c +318 +func C_AMFProp_SetName(prop *C.AMFObjectProperty, name *C.AVal) { + prop.p_name = *name +} + +const ( + AMF3_INTEGER_MAX = 268435455 + AMF3_INTEGER_MIN = -268435456 +) + +// int AMF3ReadInteger(const char *data, int32_t *valp); +// amf.c +426 +func C_AMF3ReadInteger(data *byte, valp *int32) int32 { + var i int + var val int32 + + for i <= 2 { + /* handle first 3 bytes */ + if *indxBytePtr(unsafe.Pointer(data), i)&0x80 != 0 { + /* byte used */ + val <<= 7 /* shift up */ + val |= int32(*indxBytePtr(unsafe.Pointer(data), i) & 0x7f) /* add bits */ + i++ + } else { + break + } + } + + if i > 2 { + /* use 4th byte, all 8bits */ + val <<= 8 + val |= int32(*indxBytePtr(unsafe.Pointer(data), 3)) + + /* range check */ + if val > AMF3_INTEGER_MAX { + val -= (1 << 29) + } + } else { + /* use 7bits of last unparsed byte (0xxxxxxx) */ + val <<= 7 + val |= int32(*indxBytePtr(unsafe.Pointer(data), i)) + } + + *valp = val + + if i > 2 { + return 4 + } + return int32(i + 1) +} + +// int AMF3ReadString(const char *data, AVal *str); +// amf.c +466 +func C_AMF3ReadString(data *byte, str *C.AVal) int32 { + var ref int32 + // assert elided - we will get a panic if it's nil. + + len := C_AMF3ReadInteger(data, &ref) + data = indxBytePtr(unsafe.Pointer(data), int(len)) + + if ref&0x1 == 0 { + /* reference: 0xxx */ + // TODO(kortschak) Logging. + // refIndex := (ref >> 1) + // RTMP_Log(RTMP_LOGDEBUG, + // "%s, string reference, index: %d, not supported, ignoring!", + // __FUNCTION__, refIndex); + str.av_val = nil + str.av_len = 0 + return len + } else { + nSize := (ref >> 1) + str.av_val = (*C.char)(unsafe.Pointer(data)) + str.av_len = C.int(nSize) + return len + nSize + } + return len +} + // char* AMF_EncodeBoolean(char* output, char* outend, int bVal); // amf.c +260 func C_AMF_EncodeBoolean(output *byte, outend *byte, bVal int) *byte { @@ -3765,6 +3845,16 @@ func C_AMF_EncodeInt32(output *byte, outend *byte, nVal int32) *byte { return (*byte)(incBytePtr(outputPtr, 4)) } +// void AMF3CD_AddProp(AMF3ClassDef *cd, AVal *prop); +// amf.c +1298 +func AMF3CD_AddProp(cd *C.AMF3ClassDef, prop *C.AVal) { + if cd.cd_num&0x0f == 0 { + cd.cd_props = (*C.AVal)(realloc(unsafe.Pointer(cd.cd_props), int(uintptr(cd.cd_num+16)*unsafe.Sizeof(C.AVal{})))) + } + *(*C.AVal)(incPtr(unsafe.Pointer(cd.cd_props), int(cd.cd_num), int(unsafe.Sizeof(C.AVal{})))) = *prop + cd.cd_num++ +} + func realloc(ptr unsafe.Pointer, size int) unsafe.Pointer { dest := allocate(uintptr(size)) if ptr != nil {