Finish up most of AMFProp_Decode

Punt one call, AMF3_Decode, that has AMF3ReadInteger, AMF3ReadString,
AMF3CD_AddProp, AMF3Prop_Decode and AMFProp_SetName as deps.
This commit is contained in:
Dan Kortschak 2018-08-15 17:29:05 +09:30
parent 2e608aba88
commit 346e63ca7c
1 changed files with 94 additions and 38 deletions

View File

@ -188,6 +188,12 @@ const (
debugMode = false debugMode = false
) )
// TODO(kortschak): Remove these.
const (
TRUE = 1
FALSE = 0
)
// av_setDataFrame is a static const global in rtmp.c // av_setDataFrame is a static const global in rtmp.c
var ( var (
AV_empty = AVC("") AV_empty = AVC("")
@ -1567,7 +1573,7 @@ func C_SendConnectPacket(r *C.RTMP, cp *C.RTMPPacket) int {
//incPtr(unsafe.Pointer(&r.Link.extras.o_props), int(unsafe.Sizeof( //incPtr(unsafe.Pointer(&r.Link.extras.o_props), int(unsafe.Sizeof(
//r.Link.extras.o_props)), i)), (*C.char)(unsafe.Pointer(enc)), (*C.char)( //r.Link.extras.o_props)), i)), (*C.char)(unsafe.Pointer(enc)), (*C.char)(
//unsafe.Pointer(pend))))) //unsafe.Pointer(pend)))))
enc = C_AMFPropEncode((*C.AMFObjectProperty)(incPtr(unsafe.Pointer( enc = C_AMF_PropEncode((*C.AMFObjectProperty)(incPtr(unsafe.Pointer(
&r.Link.extras.o_props), int(unsafe.Sizeof(r.Link.extras.o_props)), i)), &r.Link.extras.o_props), int(unsafe.Sizeof(r.Link.extras.o_props)), i)),
enc, pend) enc, pend)
@ -1586,7 +1592,7 @@ func C_SendConnectPacket(r *C.RTMP, cp *C.RTMPPacket) int {
// char* AMFPropEncode(AMFOBjectProperty* prop, char* pBufer, char* pBufEnd); // char* AMFPropEncode(AMFOBjectProperty* prop, char* pBufer, char* pBufEnd);
// amf.c +366 // amf.c +366
func C_AMFPropEncode(p *C.AMFObjectProperty, pBuffer *byte, pBufEnd *byte) *byte { func C_AMF_PropEncode(p *C.AMFObjectProperty, pBuffer *byte, pBufEnd *byte) *byte {
if p.p_type == AMF_INVALID { if p.p_type == AMF_INVALID {
return nil return nil
} }
@ -1626,25 +1632,25 @@ func C_AMFPropEncode(p *C.AMFObjectProperty, pBuffer *byte, pBufEnd *byte) *byte
*(*byte)(unsafe.Pointer(pBuffer)) = AMF_NULL *(*byte)(unsafe.Pointer(pBuffer)) = AMF_NULL
pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 1)) pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 1))
case AMF_OBJECT: case AMF_OBJECT:
pBuffer = C_AMFEncode(&p.p_vu.p_object, pBuffer, pBufEnd) pBuffer = C_AMF_Encode(&p.p_vu.p_object, pBuffer, pBufEnd)
//pBuffer = (*byte)(unsafe.Pointer(C.AMF_Encode(&p.p_vu.p_object, (*C.char)( //pBuffer = (*byte)(unsafe.Pointer(C.AMF_Encode(&p.p_vu.p_object, (*C.char)(
//unsafe.Pointer(pBuffer)), (*C.char)(unsafe.Pointer(pBufEnd))))) //unsafe.Pointer(pBuffer)), (*C.char)(unsafe.Pointer(pBufEnd)))))
case AMF_ECMA_ARRAY: case AMF_ECMA_ARRAY:
pBuffer = C_AMFEncodeEcmaArray(&p.p_vu.p_object, pBuffer, pBufEnd) pBuffer = C_AMF_EncodeEcmaArray(&p.p_vu.p_object, pBuffer, pBufEnd)
//pBuffer = (*byte)(unsafe.Pointer(C.AMF_EncodeEcmaArray(&p.p_vu.p_object, (*C.char)(unsafe.Pointer(pBuffer)), (*C.char)(unsafe.Pointer(pBufEnd))))) //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: 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))))) //pBuffer = (*byte)(unsafe.Pointer(C.AMF_EncodeArray(&p.p_vu.p_object, (*C.char)(unsafe.Pointer(pBuffer)), (*C.char)(unsafe.Pointer(pBufEnd)))))
pBuffer = C_AMFEncodeArray(&p.p_vu.p_object, pBuffer, pBufEnd) pBuffer = C_AMF_EncodeArray(&p.p_vu.p_object, pBuffer, pBufEnd)
default: default:
log.Println("C_AMFPropEncode: invalid type!") log.Println("C_AMF_PropEncode: invalid type!")
pBuffer = nil pBuffer = nil
} }
return pBuffer return pBuffer
} }
// char* AMF_ENCODE(AMFObject* obj, char* pBuffer, char* pBufEnd); // char* AMF_Encode(AMFObject* obj, char* pBuffer, char* pBufEnd);
// amf.c +891 // amf.c +891
func C_AMFEncode(obj *C.AMFObject, pBuffer *byte, pBufEnd *byte) *byte { func C_AMF_Encode(obj *C.AMFObject, pBuffer *byte, pBufEnd *byte) *byte {
if uintptr(unsafe.Pointer(pBuffer))+uintptr(4) >= uintptr(unsafe.Pointer(pBufEnd)) { if uintptr(unsafe.Pointer(pBuffer))+uintptr(4) >= uintptr(unsafe.Pointer(pBufEnd)) {
return nil return nil
} }
@ -1653,10 +1659,10 @@ func C_AMFEncode(obj *C.AMFObject, pBuffer *byte, pBufEnd *byte) *byte {
pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 1)) pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 1))
for i := 0; i < int(obj.o_num); i++ { for i := 0; i < int(obj.o_num); i++ {
res := C_AMFPropEncode((*C.AMFObjectProperty)(incPtr(unsafe.Pointer( res := C_AMF_PropEncode((*C.AMFObjectProperty)(incPtr(unsafe.Pointer(
obj.o_props), i, int(unsafe.Sizeof(*obj.o_props)))), pBuffer, pBufEnd) obj.o_props), i, int(unsafe.Sizeof(*obj.o_props)))), pBuffer, pBufEnd)
if res == nil { if res == nil {
log.Println("C_AMFEncode: failed to encode property in index") log.Println("C_AMF_Encode: failed to encode property in index")
break break
} else { } else {
pBuffer = res pBuffer = res
@ -1667,14 +1673,14 @@ func C_AMFEncode(obj *C.AMFObject, pBuffer *byte, pBufEnd *byte) *byte {
return nil return nil
} }
pBuffer = C_AMFEncodeInt24(pBuffer, pBufEnd, int32(AMF_OBJECT_END)) pBuffer = C_AMF_EncodeInt24(pBuffer, pBufEnd, int32(AMF_OBJECT_END))
return pBuffer return pBuffer
} }
// char* AMF_EncodeEcmaArray(AMFObject* obj, char* pBuffer, char* pBufEnd); // char* AMF_EncodeEcmaArray(AMFObject* obj, char* pBuffer, char* pBufEnd);
// amf.c +924 // amf.c +924
func C_AMFEncodeEcmaArray(obj *C.AMFObject, pBuffer *byte, pBufEnd *byte) *byte { func C_AMF_EncodeEcmaArray(obj *C.AMFObject, pBuffer *byte, pBufEnd *byte) *byte {
if int(uintptr(unsafe.Pointer(pBuffer)))+4 >= int(uintptr(unsafe.Pointer(pBufEnd))) { if int(uintptr(unsafe.Pointer(pBuffer)))+4 >= int(uintptr(unsafe.Pointer(pBufEnd))) {
return nil return nil
} }
@ -1685,10 +1691,10 @@ func C_AMFEncodeEcmaArray(obj *C.AMFObject, pBuffer *byte, pBufEnd *byte) *byte
pBuffer = C_AMF_EncodeInt32(pBuffer, pBufEnd, int32(obj.o_num)) pBuffer = C_AMF_EncodeInt32(pBuffer, pBufEnd, int32(obj.o_num))
for i := 0; i < int(obj.o_num); i++ { for i := 0; i < int(obj.o_num); i++ {
res := C_AMFPropEncode((*C.AMFObjectProperty)(incPtr(unsafe.Pointer( res := C_AMF_PropEncode((*C.AMFObjectProperty)(incPtr(unsafe.Pointer(
obj.o_props), i, int(unsafe.Sizeof(*obj.o_props)))), pBuffer, pBufEnd) obj.o_props), i, int(unsafe.Sizeof(*obj.o_props)))), pBuffer, pBufEnd)
if res == nil { if res == nil {
log.Println("C_AMFEncodeEcmaArray: failed to encode property!") log.Println("C_AMF_EncodeEcmaArray: failed to encode property!")
break break
} else { } else {
pBuffer = res pBuffer = res
@ -1699,14 +1705,14 @@ func C_AMFEncodeEcmaArray(obj *C.AMFObject, pBuffer *byte, pBufEnd *byte) *byte
return nil return nil
} }
pBuffer = C_AMFEncodeInt24(pBuffer, pBufEnd, AMF_OBJECT_END) pBuffer = C_AMF_EncodeInt24(pBuffer, pBufEnd, AMF_OBJECT_END)
return pBuffer return pBuffer
} }
// char* AMF_EncodeArray(AMFObject* obj, char* pBuffer, char* pBufEnd); // char* AMF_EncodeArray(AMFObject* obj, char* pBuffer, char* pBufEnd);
// amf.c +959 // amf.c +959
func C_AMFEncodeArray(obj *C.AMFObject, pBuffer *byte, pBufEnd *byte) *byte { func C_AMF_EncodeArray(obj *C.AMFObject, pBuffer *byte, pBufEnd *byte) *byte {
if int(uintptr(unsafe.Pointer(pBuffer)))+4 >= int(uintptr(unsafe.Pointer(pBufEnd))) { if int(uintptr(unsafe.Pointer(pBuffer)))+4 >= int(uintptr(unsafe.Pointer(pBufEnd))) {
return nil return nil
} }
@ -1717,10 +1723,10 @@ func C_AMFEncodeArray(obj *C.AMFObject, pBuffer *byte, pBufEnd *byte) *byte {
pBuffer = C_AMF_EncodeInt32(pBuffer, pBufEnd, int32(obj.o_num)) pBuffer = C_AMF_EncodeInt32(pBuffer, pBufEnd, int32(obj.o_num))
for i := 0; i < int(obj.o_num); i++ { for i := 0; i < int(obj.o_num); i++ {
res := C_AMFPropEncode((*C.AMFObjectProperty)(incPtr(unsafe.Pointer( res := C_AMF_PropEncode((*C.AMFObjectProperty)(incPtr(unsafe.Pointer(
obj.o_props), i, int(unsafe.Sizeof(*obj.o_props)))), pBuffer, pBufEnd) obj.o_props), i, int(unsafe.Sizeof(*obj.o_props)))), pBuffer, pBufEnd)
if res == nil { if res == nil {
log.Println("C_AMFEncodeEcmaArray: failed to encode property!") log.Println("C_AMF_EncodeEcmaArray: failed to encode property!")
break break
} else { } else {
pBuffer = res pBuffer = res
@ -1730,6 +1736,39 @@ func C_AMFEncodeArray(obj *C.AMFObject, pBuffer *byte, pBufEnd *byte) *byte {
return pBuffer return pBuffer
} }
// int AMF_DecodeArray(AMFObject *obj, const char *pBuffer, int nSize, int nArrayLen, int bDecodeName);
func C_AMF_DecodeArray(obj *C.AMFObject, pBuffer *byte, nSize, nArrayLen, bDecodeName int32) int32 {
nOriginalSize := nSize
var bError int32 = FALSE
obj.o_num = 0
obj.o_props = nil
for nArrayLen > 0 {
var prop C.AMFObjectProperty
var nRes int32
nArrayLen--
if nSize <= 0 {
bError = TRUE
break
}
nRes = C_AMFProp_Decode(&prop, pBuffer, nSize, bDecodeName)
if nRes == -1 {
bError = TRUE
break
} else {
nSize -= nRes
pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), int(nRes)))
C_AMF_AddProp(obj, &prop)
}
}
if bError != 0 {
return -1
}
return nOriginalSize - nSize
}
// int RTMP_ConnectStream(RTMP* r, int seekTime); // int RTMP_ConnectStream(RTMP* r, int seekTime);
// rtmp.c +1099 // rtmp.c +1099
func C_RTMP_ConnectStream(r *C.RTMP, seekTime int32) int { func C_RTMP_ConnectStream(r *C.RTMP, seekTime int32) int {
@ -2786,8 +2825,7 @@ func C_AMF_Decode(obj *C.AMFObject, pBuffer *byte, nSize int32, bDecodeName int3
// int AMFProp_Decode(C.AMFOBjectProperty* prop, const char* pBuffer, int nSize, int bDecodeName); // int AMFProp_Decode(C.AMFOBjectProperty* prop, const char* pBuffer, int nSize, int bDecodeName);
// amf.c +619 // amf.c +619
func C_AMFProp_Decode(prop *C.AMFObjectProperty, pBuffer *byte, func C_AMFProp_Decode(prop *C.AMFObjectProperty, pBuffer *byte, nSize, bDecodeName int32) int32 {
nSize, bDecodeName int32) int32 {
var nOriginalSize int32 = nSize var nOriginalSize int32 = nSize
var nRes int32 var nRes int32
@ -2809,7 +2847,7 @@ func C_AMFProp_Decode(prop *C.AMFObjectProperty, pBuffer *byte,
} }
if bDecodeName != 0 { if bDecodeName != 0 {
var nNameSize uint8 = uint8(C_AMF_DecodeInt16(pBuffer)) nNameSize := C_AMF_DecodeInt16(pBuffer)
if int32(nNameSize) > nSize-2 { if int32(nNameSize) > nSize-2 {
// TODO use new logger here // TODO use new logger here
//RTMP_Log(RTMP_LOGDEBUG, "%s: Name size out of range: namesize (%d) > len (%d) - 2",__FUNCTION__, nNameSize, nSize); //RTMP_Log(RTMP_LOGDEBUG, "%s: Name size out of range: namesize (%d) > len (%d) - 2",__FUNCTION__, nNameSize, nSize);
@ -2842,19 +2880,18 @@ func C_AMFProp_Decode(prop *C.AMFObjectProperty, pBuffer *byte,
if nSize < 1 { if nSize < 1 {
return -1 return -1
} }
// TODO port AMF_DecodeBoolean prop.p_vu.p_number = C.double(C_AMF_DecodeBoolean((*byte)(unsafe.Pointer(pBuffer))))
prop.p_vu.p_number = C.double(C.AMF_DecodeBoolean((*C.char)(unsafe.Pointer(pBuffer))))
nSize-- nSize--
case AMF_STRING: case AMF_STRING:
{ {
var nStringSize uint8 = uint8(C_AMF_DecodeInt16(pBuffer)) var nStringSize = C_AMF_DecodeInt16(pBuffer)
if int64(nSize) < int64(nStringSize)+2 { if int64(nSize) < int64(nStringSize)+2 {
return -1 return -1
} }
C_AMF_DecodeString(pBuffer, &prop.p_vu.p_aval) C_AMF_DecodeString(pBuffer, &prop.p_vu.p_aval)
nSize -= uint8(2 + nStringSize) nSize -= int32(2 + nStringSize)
} }
case AMF_OBJECT: case AMF_OBJECT:
@ -2907,11 +2944,10 @@ func C_AMFProp_Decode(prop *C.AMFObjectProperty, pBuffer *byte,
} }
case AMF_STRICT_ARRAY: case AMF_STRICT_ARRAY:
{ {
var nArrayLen uint32 = C_AMF_DecodeInt32(pBuffer) nArrayLen := int32(C_AMF_DecodeInt32(pBuffer))
nSize -= 4 nSize -= 4
nRes = C_AMF_DecodeArray(&prop.p_vu.p_object, pBuffer+4, nSize, nRes = C_AMF_DecodeArray(&prop.p_vu.p_object, (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 4)), nSize, int32(nArrayLen), FALSE)
nArrayLen, FALSE)
if nRes == -1 { if nRes == -1 {
return -1 return -1
} }
@ -2927,8 +2963,8 @@ func C_AMFProp_Decode(prop *C.AMFObjectProperty, pBuffer *byte,
return -1 return -1
} }
prop.p_vu.p_number = C_AMF_DecodeNumber(pBuffer) prop.p_vu.p_number = C.double(C_AMF_DecodeNumber(pBuffer))
prop.p_UTCoffset = C_AMF_DecodeInt16(pBuffer + 8) prop.p_UTCoffset = C.short(C_AMF_DecodeInt16((*byte)(incBytePtr(unsafe.Pointer(pBuffer), 8))))
nSize -= 10 nSize -= 10
@ -2937,11 +2973,11 @@ func C_AMFProp_Decode(prop *C.AMFObjectProperty, pBuffer *byte,
case AMF_XML_DOC: case AMF_XML_DOC:
{ {
var nStringSize uint32 = C_AMF_DecodeInt32(pBuffer) var nStringSize uint32 = C_AMF_DecodeInt32(pBuffer)
if nSize < int64(nStringSize)+4 { if int64(nSize) < int64(nStringSize)+4 {
return -1 return -1
} }
AMF_DecodeLongString(pBuffer, &prop.p_vu.p_aval) C_AMF_DecodeLongString(pBuffer, &prop.p_vu.p_aval)
nSize -= (4 + nStringSize) nSize -= int32(4 + nStringSize)
if prop.p_type == AMF_LONG_STRING { if prop.p_type == AMF_LONG_STRING {
prop.p_type = AMF_STRING prop.p_type = AMF_STRING
} }
@ -2958,13 +2994,13 @@ func C_AMFProp_Decode(prop *C.AMFObjectProperty, pBuffer *byte,
case AMF_TYPED_OBJECT: case AMF_TYPED_OBJECT:
{ {
// TODO use new logger here // TODO use new logger here
RTMP_Log(RTMP_LOGERROR, "AMF_TYPED_OBJECT not supported!") // RTMP_Log(RTMP_LOGERROR, "AMF_TYPED_OBJECT not supported!")
return -1 return -1
} }
case AMF_AVMPLUS: case AMF_AVMPLUS:
{ {
var nRes int32 = int32(C.AMF3_Decode(&prop.p_vu.p_object, pBuffer, nSize, 1)) nRes := int32(C.AMF3_Decode(&prop.p_vu.p_object, (*C.char)(unsafe.Pointer(pBuffer)), C.int(nSize), 1))
if nRes == -1 { if nRes == -1 {
return -1 return -1
} }
@ -3288,11 +3324,11 @@ func C_RTMP_SendPacket(r *C.RTMP, packet *C.RTMPPacket, queue int) int {
if t > 0xffffff { if t > 0xffffff {
res = 0xffffff res = 0xffffff
} }
hptr = unsafe.Pointer(C_AMFEncodeInt24((*byte)(hptr), (*byte)(hend), res)) hptr = unsafe.Pointer(C_AMF_EncodeInt24((*byte)(hptr), (*byte)(hend), res))
} }
if nSize > 4 { if nSize > 4 {
hptr = unsafe.Pointer(C_AMFEncodeInt24((*byte)(hptr), (*byte)(hend), (int32(packet.m_nBodySize)))) hptr = unsafe.Pointer(C_AMF_EncodeInt24((*byte)(hptr), (*byte)(hend), (int32(packet.m_nBodySize))))
*(*byte)(hptr) = byte(packet.m_packetType) *(*byte)(hptr) = byte(packet.m_packetType)
hptr = incBytePtr(hptr, 1) hptr = incBytePtr(hptr, 1)
} }
@ -3559,6 +3595,17 @@ func C_AMF_EncodeNumber(output *byte, outend *byte, dVal float64) *byte {
return (*byte)(incBytePtr(unsafe.Pointer(output), 8)) return (*byte)(incBytePtr(unsafe.Pointer(output), 8))
} }
// void AMF_DecodeLongString(const char *data, AVal *bv);
// amf.c +75
func C_AMF_DecodeLongString(data *byte, bv *C.AVal) {
bv.av_len = C.int(C_AMF_DecodeInt32(data))
if bv.av_len > 0 {
bv.av_val = (*C.char)(incBytePtr(unsafe.Pointer(data), 4))
} else {
bv.av_val = nil
}
}
// double AMF_DecodeNumber(const char* data); // double AMF_DecodeNumber(const char* data);
// amf.c +82 // amf.c +82
func C_AMF_DecodeNumber(data *byte) float64 { func C_AMF_DecodeNumber(data *byte) float64 {
@ -3572,6 +3619,15 @@ func C_AMF_DecodeNumber(data *byte) float64 {
return dVal return dVal
} }
// int AMF_DecodeBoolean(const char *data);
// amf.c +132
func C_AMF_DecodeBoolean(data *byte) int32 {
if *data != 0 {
return 1
}
return 0
}
// char* AMF_EncodeNamedString(char* output, char* outend, const C.AVal* strName, const C.AVal* strValue); // char* AMF_EncodeNamedString(char* output, char* outend, const C.AVal* strName, const C.AVal* strValue);
// amf.c +273 // amf.c +273
func C_AMF_EncodeNamedString(output *byte, outend *byte, strName *C.AVal, strValue *C.AVal) *byte { func C_AMF_EncodeNamedString(output *byte, outend *byte, strName *C.AVal, strValue *C.AVal) *byte {
@ -3606,7 +3662,7 @@ func C_AMF_DecodeInt16(data *byte) uint16 {
// 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_AMFEncodeInt24(output *byte, outend *byte, nVal int32) *byte { func C_AMF_EncodeInt24(output *byte, outend *byte, nVal int32) *byte {
outputPtr := unsafe.Pointer(output) outputPtr := unsafe.Pointer(output)
outendPtr := unsafe.Pointer(outend) outendPtr := unsafe.Pointer(outend)
if uintptr(outputPtr)+3 > uintptr(outendPtr) { if uintptr(outputPtr)+3 > uintptr(outendPtr) {