mirror of https://bitbucket.org/ausocean/av.git
Merged in gardening/simplify (pull request #53)
rtmp: simplify rtmp code and make more type-safe Approved-by: Saxon Milton <saxon.milton@gmail.com>
This commit is contained in:
commit
3f8082d52e
192
rtmp/amf.go
192
rtmp/amf.go
|
@ -39,6 +39,7 @@ package rtmp
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"log"
|
"log"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
@ -91,26 +92,22 @@ func C_AMF_DecodeInt32(data *byte) uint32 {
|
||||||
|
|
||||||
// void AMF_DecodeString(const char* data, C_AVal* bv);
|
// void AMF_DecodeString(const char* data, C_AVal* bv);
|
||||||
// amf.c +68
|
// amf.c +68
|
||||||
func C_AMF_DecodeString(data *byte, bv *C_AVal) {
|
func C_AMF_DecodeString(data *byte) string {
|
||||||
dataPtr := unsafe.Pointer(data)
|
n := C_AMF_DecodeInt16(data)
|
||||||
//bv.av_len = int32(C.AMF_DecodeInt16((*byte)(dataPtr)))
|
if n == 0 {
|
||||||
bv.av_len = int32(C_AMF_DecodeInt16((*byte)(dataPtr)))
|
return ""
|
||||||
if bv.av_len > 0 {
|
|
||||||
bv.av_val = (*byte)(incBytePtr(dataPtr, 2))
|
|
||||||
} else {
|
|
||||||
bv.av_val = nil
|
|
||||||
}
|
}
|
||||||
|
return string((*[_Gi]byte)(incBytePtr(unsafe.Pointer(data), 2))[:n])
|
||||||
}
|
}
|
||||||
|
|
||||||
// void AMF_DecodeLongString(const char *data, AVal *bv);
|
// void AMF_DecodeLongString(const char *data, AVal *bv);
|
||||||
// amf.c +75
|
// amf.c +75
|
||||||
func C_AMF_DecodeLongString(data *byte, bv *C_AVal) {
|
func C_AMF_DecodeLongString(data *byte) string {
|
||||||
bv.av_len = int32(C_AMF_DecodeInt32(data))
|
n := C_AMF_DecodeInt32(data)
|
||||||
if bv.av_len > 0 {
|
if n == 0 {
|
||||||
bv.av_val = (*byte)(incBytePtr(unsafe.Pointer(data), 4))
|
return ""
|
||||||
} else {
|
|
||||||
bv.av_val = nil
|
|
||||||
}
|
}
|
||||||
|
return string((*[_Gi]byte)(incBytePtr(unsafe.Pointer(data), 4))[:n])
|
||||||
}
|
}
|
||||||
|
|
||||||
// double AMF_DecodeNumber(const char* data);
|
// double AMF_DecodeNumber(const char* data);
|
||||||
|
@ -128,11 +125,8 @@ func C_AMF_DecodeNumber(data *byte) float64 {
|
||||||
|
|
||||||
// int AMF_DecodeBoolean(const char *data);
|
// int AMF_DecodeBoolean(const char *data);
|
||||||
// amf.c +132
|
// amf.c +132
|
||||||
func C_AMF_DecodeBoolean(data *byte) int32 {
|
func C_AMF_DecodeBoolean(data *byte) bool {
|
||||||
if *data != 0 {
|
return *data != 0
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// char* AMF_EncodeInt16(char* output, char* outend, short nVal);
|
// char* AMF_EncodeInt16(char* output, char* outend, short nVal);
|
||||||
|
@ -197,33 +191,27 @@ func C_AMF_EncodeInt32(output *byte, outend *byte, nVal int32) *byte {
|
||||||
|
|
||||||
// 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 +174
|
||||||
func C_AMF_EncodeString(output *byte, outend *byte, bv *C_AVal) *byte {
|
func C_AMF_EncodeString(output *byte, outend *byte, s string) *byte {
|
||||||
outputPtr := unsafe.Pointer(output)
|
buflen := int(uintptr(unsafe.Pointer(outend)) - uintptr(unsafe.Pointer(output)))
|
||||||
outendPtr := unsafe.Pointer(outend)
|
if len(s) < 65536 && 1+2+len(s) > buflen {
|
||||||
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) {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if bv.av_len < 65536 {
|
if 1+4+len(s) > buflen {
|
||||||
*(*byte)(outputPtr) = AMF_STRING
|
return nil
|
||||||
outputPtr = incBytePtr(outputPtr, 1)
|
}
|
||||||
// TODO: port AMF_EncodeInt16
|
outputPtr := unsafe.Pointer(output)
|
||||||
outputPtr = unsafe.Pointer(C_AMF_EncodeInt16((*byte)(outputPtr), (*byte)(
|
dst := (*[_Gi]byte)(unsafe.Pointer(output))[:buflen]
|
||||||
outendPtr), int16(bv.av_len)))
|
if len(s) < 65536 {
|
||||||
//outputPtr = unsafe.Pointer(C_AMF_EncodeInt16((*byte)(outputPtr),
|
dst[0] = AMF_STRING
|
||||||
//(*byte)(outendPtr), (int16)(bv.av_len)))
|
binary.BigEndian.PutUint16(dst[1:3], uint16(len(s)))
|
||||||
} else {
|
copy(dst[3:], s)
|
||||||
*(*byte)(outputPtr) = AMF_LONG_STRING
|
outputPtr = incBytePtr(outputPtr, 3+len(s))
|
||||||
outputPtr = incBytePtr(outputPtr, 1)
|
} else {
|
||||||
outputPtr = unsafe.Pointer(C_AMF_EncodeInt32((*byte)(outputPtr), (*byte)(
|
dst[0] = AMF_LONG_STRING
|
||||||
outendPtr), int32(bv.av_len)))
|
binary.BigEndian.PutUint32(dst[1:5], uint32(len(s)))
|
||||||
//outputPtr = unsafe.Pointer(C_AMF_EncodeInt32((*byte)(outputPtr),
|
copy(dst[5:], s)
|
||||||
//(*byte)(outendPtr), (int32)(bv.av_len)))
|
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)
|
return (*byte)(outputPtr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,15 +237,15 @@ func C_AMF_EncodeNumber(output *byte, outend *byte, dVal float64) *byte {
|
||||||
|
|
||||||
// char* AMF_EncodeBoolean(char* output, char* outend, int bVal);
|
// char* AMF_EncodeBoolean(char* output, char* outend, int bVal);
|
||||||
// amf.c +260
|
// amf.c +260
|
||||||
func C_AMF_EncodeBoolean(output *byte, outend *byte, bVal int) *byte {
|
func C_AMF_EncodeBoolean(output *byte, outend *byte, bVal bool) *byte {
|
||||||
if int(uintptr(unsafe.Pointer(output)))+2 > int(uintptr(unsafe.Pointer(outend))) {
|
if int(uintptr(unsafe.Pointer(output)))+2 > int(uintptr(unsafe.Pointer(outend))) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
*(*byte)(unsafe.Pointer(output)) = AMF_BOOLEAN
|
*(*byte)(unsafe.Pointer(output)) = AMF_BOOLEAN
|
||||||
output = (*byte)(incBytePtr(unsafe.Pointer(output), 1))
|
output = (*byte)(incBytePtr(unsafe.Pointer(output), 1))
|
||||||
val := byte(0x01)
|
var val byte
|
||||||
if bVal == 0 {
|
if bVal {
|
||||||
val = byte(0x00)
|
val = 1
|
||||||
}
|
}
|
||||||
*(*byte)(unsafe.Pointer(output)) = val
|
*(*byte)(unsafe.Pointer(output)) = val
|
||||||
output = (*byte)(incBytePtr(unsafe.Pointer(output), 1))
|
output = (*byte)(incBytePtr(unsafe.Pointer(output), 1))
|
||||||
|
@ -266,44 +254,50 @@ 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);
|
// 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, key, val string) *byte {
|
||||||
if int(uintptr(unsafe.Pointer(output)))+2+int(strName.av_len) > int(uintptr(unsafe.Pointer(outend))) {
|
buflen := int(uintptr(unsafe.Pointer(outend)) - uintptr(unsafe.Pointer(output)))
|
||||||
|
if 2+len(key) > buflen {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
output = C_AMF_EncodeInt16(output, outend, int16(strName.av_len))
|
dst := (*[_Gi]byte)(unsafe.Pointer(output))[:buflen]
|
||||||
memmove(unsafe.Pointer(output), unsafe.Pointer(strName.av_val), uintptr(strName.av_len))
|
binary.BigEndian.PutUint16(dst[:2], uint16(len(key)))
|
||||||
output = (*byte)(incBytePtr(unsafe.Pointer(output), int(strName.av_len)))
|
copy(dst[2:], key)
|
||||||
return C_AMF_EncodeString(output, outend, strValue)
|
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);
|
// char* AMF_EncodeNamedNumber(char* output, char* outend, const C_AVal* strName, double dVal);
|
||||||
// amf.c +286
|
// amf.c +286
|
||||||
func C_AMF_EncodeNamedNumber(output *byte, outend *byte, strName *C_AVal, dVal float64) *byte {
|
func C_AMF_EncodeNamedNumber(output *byte, outend *byte, key string, val float64) *byte {
|
||||||
if int(uintptr(unsafe.Pointer(output)))+2+int(strName.av_len) > int(uintptr(unsafe.Pointer(outend))) {
|
buflen := int(uintptr(unsafe.Pointer(outend)) - uintptr(unsafe.Pointer(output)))
|
||||||
|
if 2+len(key) > buflen {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
output = C_AMF_EncodeInt16(output, outend, int16(strName.av_len))
|
dst := (*[_Gi]byte)(unsafe.Pointer(output))[:buflen]
|
||||||
memmove(unsafe.Pointer(output), unsafe.Pointer(strName.av_val), uintptr(strName.av_len))
|
binary.BigEndian.PutUint16(dst[:2], uint16(len(key)))
|
||||||
output = (*byte)(incBytePtr(unsafe.Pointer(output), int(strName.av_len)))
|
copy(dst[2:], key)
|
||||||
return C_AMF_EncodeNumber(output, outend, dVal)
|
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);
|
// char* AMF_EncodeNamedBoolean(char* output, char* outend, const C_AVal* strname, int bVal);
|
||||||
// amf.c +299
|
// amf.c +299
|
||||||
func C_AMF_EncodeNamedBoolean(output *byte, outend *byte, strName *C_AVal, bVal int) *byte {
|
func C_AMF_EncodeNamedBoolean(output *byte, outend *byte, key string, val bool) *byte {
|
||||||
if int(uintptr(unsafe.Pointer(output)))+2+int(strName.av_len) > int(uintptr(unsafe.Pointer(outend))) {
|
buflen := int(uintptr(unsafe.Pointer(outend)) - uintptr(unsafe.Pointer(output)))
|
||||||
|
if 2+len(key) > buflen {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
output = C_AMF_EncodeInt16(output, outend, int16(strName.av_len))
|
dst := (*[_Gi]byte)(unsafe.Pointer(output))[:buflen]
|
||||||
memmove(unsafe.Pointer(output), unsafe.Pointer(strName.av_val), uintptr(strName.av_len))
|
binary.BigEndian.PutUint16(dst[:2], uint16(len(key)))
|
||||||
output = (*byte)(incBytePtr(unsafe.Pointer(output), int(strName.av_len)))
|
copy(dst[2:], key)
|
||||||
return C_AMF_EncodeBoolean(output, outend, bVal)
|
output = (*byte)(incBytePtr(unsafe.Pointer(output), 2+len(key)))
|
||||||
|
return C_AMF_EncodeBoolean(output, outend, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
// void AMFProp_SetName(AMFObjectProperty *prop, AVal *name);
|
// void AMFProp_SetName(AMFObjectProperty *prop, AVal *name);
|
||||||
// amf.c +318
|
// amf.c +318
|
||||||
func C_AMFProp_SetName(prop *C_AMFObjectProperty, name *C_AVal) {
|
func C_AMFProp_SetName(prop *C_AMFObjectProperty, name string) {
|
||||||
prop.p_name = *name
|
prop.p_name = name
|
||||||
}
|
}
|
||||||
|
|
||||||
// double AMFProp_GetNumber(AMFObjectProperty* prop);
|
// double AMFProp_GetNumber(AMFObjectProperty* prop);
|
||||||
|
@ -314,12 +308,11 @@ func C_AMFProp_GetNumber(prop *C_AMFObjectProperty) float64 {
|
||||||
|
|
||||||
// void AMFProp_GetString(AMFObjectProperty* prop, AVal* str);
|
// void AMFProp_GetString(AMFObjectProperty* prop, AVal* str);
|
||||||
// amf.c +341
|
// amf.c +341
|
||||||
func C_AMFProp_GetString(prop *C_AMFObjectProperty, str *C_AVal) {
|
func C_AMFProp_GetString(prop *C_AMFObjectProperty) string {
|
||||||
if prop.p_type == AMF_STRING {
|
if prop.p_type == AMF_STRING {
|
||||||
*str = prop.p_vu.p_aval
|
return prop.p_vu.p_aval
|
||||||
} else {
|
|
||||||
*str = AV_empty
|
|
||||||
}
|
}
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// void AMFProp_GetObject(AMFObjectProperty *prop, AMFObject *obj);
|
// void AMFProp_GetObject(AMFObjectProperty *prop, AMFObject *obj);
|
||||||
|
@ -339,36 +332,30 @@ func C_AMF_PropEncode(p *C_AMFObjectProperty, pBuffer *byte, pBufEnd *byte) *byt
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.p_type != AMF_NULL && int(uintptr(unsafe.Pointer(pBuffer)))+
|
buflen := int(uintptr(unsafe.Pointer(pBufEnd)) - uintptr(unsafe.Pointer(pBuffer)))
|
||||||
int(p.p_name.av_len)+2+1 >= int(
|
if p.p_type != AMF_NULL && len(p.p_name)+2+1 >= buflen {
|
||||||
uintptr(unsafe.Pointer(pBufEnd))) {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.p_type != AMF_NULL && p.p_name.av_len != 0 {
|
if p.p_type != AMF_NULL && len(p.p_name) != 0 {
|
||||||
(*[_Gi]byte)(unsafe.Pointer(pBuffer))[0] = byte(p.p_name.av_len >> 8)
|
(*[_Gi]byte)(unsafe.Pointer(pBuffer))[0] = byte(len(p.p_name) >> 8)
|
||||||
pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 1))
|
pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 1))
|
||||||
(*[_Gi]byte)(unsafe.Pointer(pBuffer))[0] = byte(p.p_name.av_len & 0xff)
|
(*[_Gi]byte)(unsafe.Pointer(pBuffer))[0] = byte(len(p.p_name) & 0xff)
|
||||||
pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 1))
|
pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), 1))
|
||||||
memmove(unsafe.Pointer(pBuffer), unsafe.Pointer(p.p_name.av_val),
|
copy((*[_Gi]byte)(unsafe.Pointer(pBuffer))[:], p.p_name)
|
||||||
uintptr(p.p_name.av_len))
|
pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), len(p.p_name)))
|
||||||
pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), int(p.p_name.av_len)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch p.p_type {
|
switch p.p_type {
|
||||||
case AMF_NUMBER:
|
case AMF_NUMBER:
|
||||||
pBuffer = C_AMF_EncodeNumber(pBuffer, pBufEnd, float64(p.p_vu.p_number))
|
pBuffer = C_AMF_EncodeNumber(pBuffer, pBufEnd, float64(p.p_vu.p_number))
|
||||||
case AMF_BOOLEAN:
|
case AMF_BOOLEAN:
|
||||||
val := 0
|
pBuffer = C_AMF_EncodeBoolean(pBuffer, pBufEnd, p.p_vu.p_number != 0)
|
||||||
if p.p_vu.p_number != 0 {
|
|
||||||
val = 1
|
|
||||||
}
|
|
||||||
pBuffer = C_AMF_EncodeBoolean(pBuffer, pBufEnd, val)
|
|
||||||
case AMF_STRING:
|
case AMF_STRING:
|
||||||
pBuffer = C_AMF_EncodeString(pBuffer, pBufEnd, &p.p_vu.p_aval)
|
pBuffer = C_AMF_EncodeString(pBuffer, pBufEnd, p.p_vu.p_aval)
|
||||||
case AMF_NULL:
|
case AMF_NULL:
|
||||||
if uintptr(incBytePtr(unsafe.Pointer(pBuffer), 1)) >= uintptr(unsafe.Pointer(
|
buflen = int(uintptr(unsafe.Pointer(pBufEnd)) - uintptr(unsafe.Pointer(pBuffer)))
|
||||||
pBufEnd)) {
|
if 1 >= buflen {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
*(*byte)(unsafe.Pointer(pBuffer)) = AMF_NULL
|
*(*byte)(unsafe.Pointer(pBuffer)) = AMF_NULL
|
||||||
|
@ -434,7 +421,7 @@ func C_AMF3ReadInteger(data *byte, valp *int32) int32 {
|
||||||
|
|
||||||
// int AMF3ReadString(const char *data, AVal *str);
|
// int AMF3ReadString(const char *data, AVal *str);
|
||||||
// amf.c +466
|
// amf.c +466
|
||||||
func C_AMF3ReadString(data *byte, str *C_AVal) int32 {
|
func C_AMF3ReadString(data *byte, str *string) int32 {
|
||||||
var ref int32
|
var ref int32
|
||||||
// assert elided - we will get a panic if it's nil.
|
// assert elided - we will get a panic if it's nil.
|
||||||
|
|
||||||
|
@ -448,13 +435,11 @@ func C_AMF3ReadString(data *byte, str *C_AVal) int32 {
|
||||||
// RTMP_Log(RTMP_LOGDEBUG,
|
// RTMP_Log(RTMP_LOGDEBUG,
|
||||||
// "%s, string reference, index: %d, not supported, ignoring!",
|
// "%s, string reference, index: %d, not supported, ignoring!",
|
||||||
// __FUNCTION__, refIndex);
|
// __FUNCTION__, refIndex);
|
||||||
str.av_val = nil
|
*str = ""
|
||||||
str.av_len = 0
|
|
||||||
return len
|
return len
|
||||||
} else {
|
} else {
|
||||||
nSize := (ref >> 1)
|
nSize := (ref >> 1)
|
||||||
str.av_val = data
|
*str = string((*[_Gi]byte)(unsafe.Pointer(data))[:nSize])
|
||||||
str.av_len = int32(nSize)
|
|
||||||
return len + nSize
|
return len + nSize
|
||||||
}
|
}
|
||||||
return len
|
return len
|
||||||
|
@ -467,8 +452,7 @@ func C_AMFProp_Decode(prop *C_AMFObjectProperty, pBuffer *byte, nSize, bDecodeNa
|
||||||
var nOriginalSize int32 = nSize
|
var nOriginalSize int32 = nSize
|
||||||
var nRes int32
|
var nRes int32
|
||||||
|
|
||||||
prop.p_name.av_len = 0
|
prop.p_name = ""
|
||||||
prop.p_name.av_val = nil
|
|
||||||
|
|
||||||
if nSize == 0 || pBuffer == nil {
|
if nSize == 0 || pBuffer == nil {
|
||||||
// TODO use new logger here
|
// TODO use new logger here
|
||||||
|
@ -491,7 +475,7 @@ func C_AMFProp_Decode(prop *C_AMFObjectProperty, pBuffer *byte, nSize, bDecodeNa
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
C_AMF_DecodeString(pBuffer, &prop.p_name)
|
prop.p_name = C_AMF_DecodeString(pBuffer)
|
||||||
nSize -= int32(2 + nNameSize)
|
nSize -= int32(2 + nNameSize)
|
||||||
pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), int(2+nNameSize)))
|
pBuffer = (*byte)(incBytePtr(unsafe.Pointer(pBuffer), int(2+nNameSize)))
|
||||||
}
|
}
|
||||||
|
@ -522,7 +506,7 @@ func C_AMFProp_Decode(prop *C_AMFObjectProperty, pBuffer *byte, nSize, bDecodeNa
|
||||||
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)
|
prop.p_vu.p_aval = C_AMF_DecodeString(pBuffer)
|
||||||
nSize -= int32(2 + nStringSize)
|
nSize -= int32(2 + nStringSize)
|
||||||
|
|
||||||
case AMF_OBJECT:
|
case AMF_OBJECT:
|
||||||
|
@ -605,8 +589,7 @@ func C_AMFProp_Reset(prop *C_AMFObjectProperty) {
|
||||||
prop.p_type == AMF_STRICT_ARRAY {
|
prop.p_type == AMF_STRICT_ARRAY {
|
||||||
C_AMF_Reset(&prop.p_vu.p_object)
|
C_AMF_Reset(&prop.p_vu.p_object)
|
||||||
} else {
|
} else {
|
||||||
prop.p_vu.p_aval.av_len = 0
|
prop.p_vu.p_aval = ""
|
||||||
prop.p_vu.p_aval.av_val = nil
|
|
||||||
}
|
}
|
||||||
prop.p_type = AMF_INVALID
|
prop.p_type = AMF_INVALID
|
||||||
}
|
}
|
||||||
|
@ -802,18 +785,17 @@ func C_AMF_AddProp(obj *C_AMFObject, prop *C_AMFObjectProperty) {
|
||||||
|
|
||||||
// AMFObjectProperty* AMF_GetProp(AMFObject *obj, const AVal* name, int nIndex);
|
// AMFObjectProperty* AMF_GetProp(AMFObject *obj, const AVal* name, int nIndex);
|
||||||
// amf.c + 1249
|
// amf.c + 1249
|
||||||
func C_AMF_GetProp(obj *C_AMFObject, name *C_AVal, nIndex int32) *C_AMFObjectProperty {
|
func C_AMF_GetProp(obj *C_AMFObject, name string, nIndex int32) *C_AMFObjectProperty {
|
||||||
if nIndex >= 0 {
|
if nIndex >= 0 {
|
||||||
if nIndex < int32(obj.o_num) {
|
if nIndex < int32(obj.o_num) {
|
||||||
return &(*(*C_AMFObjectProperty)(incPtr(unsafe.Pointer(obj.o_props),
|
return &(*(*C_AMFObjectProperty)(incPtr(unsafe.Pointer(obj.o_props),
|
||||||
int(nIndex), int(unsafe.Sizeof(*obj.o_props)))))
|
int(nIndex), int(unsafe.Sizeof(*obj.o_props)))))
|
||||||
//return &obj.o_props[nIndex]
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var n int32
|
for n := int32(0); n < obj.o_num; n++ {
|
||||||
for n = 0; n < int32(obj.o_num); n++ {
|
p_name := (*(*C_AMFObjectProperty)(incPtr(unsafe.Pointer(obj.o_props),
|
||||||
if C_AVMATCH(&(*(*C_AMFObjectProperty)(incPtr(unsafe.Pointer(obj.o_props),
|
int(n), int(unsafe.Sizeof(*obj.o_props))))).p_name
|
||||||
int(n), int(unsafe.Sizeof(*obj.o_props))))).p_name, name) != 0 {
|
if p_name == name {
|
||||||
return &(*(*C_AMFObjectProperty)(incPtr(unsafe.Pointer(obj.o_props),
|
return &(*(*C_AMFObjectProperty)(incPtr(unsafe.Pointer(obj.o_props),
|
||||||
int(n), int(unsafe.Sizeof(*obj.o_props)))))
|
int(n), int(unsafe.Sizeof(*obj.o_props)))))
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,10 +31,6 @@ LICENSE
|
||||||
*/
|
*/
|
||||||
package rtmp
|
package rtmp
|
||||||
|
|
||||||
import (
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
AMF_NUMBER = iota
|
AMF_NUMBER = iota
|
||||||
AMF_BOOLEAN
|
AMF_BOOLEAN
|
||||||
|
@ -61,37 +57,6 @@ const (
|
||||||
// amf.h +40
|
// amf.h +40
|
||||||
type C_AMFDataType int32
|
type C_AMFDataType int32
|
||||||
|
|
||||||
// typedef struct C_AVal
|
|
||||||
// amf.h +57
|
|
||||||
type C_AVal struct {
|
|
||||||
av_val *byte
|
|
||||||
av_len int32
|
|
||||||
}
|
|
||||||
|
|
||||||
// C_AVal is in amf.h
|
|
||||||
// amf.h +62
|
|
||||||
func AVC(str string) C_AVal {
|
|
||||||
var aval C_AVal
|
|
||||||
if len(str) != 0 {
|
|
||||||
aval.av_val = &([]byte(str)[0])
|
|
||||||
} else {
|
|
||||||
aval.av_val = nil
|
|
||||||
}
|
|
||||||
aval.av_len = int32(len(str))
|
|
||||||
return aval
|
|
||||||
}
|
|
||||||
|
|
||||||
// #define AVMATCH(a1,a2)
|
|
||||||
// amf.h +63
|
|
||||||
func C_AVMATCH(a1, a2 *C_AVal) int32 {
|
|
||||||
if a1.av_len == a2.av_len && memcmp(unsafe.Pointer(a1.av_val),
|
|
||||||
unsafe.Pointer(a2.av_val), int(a1.av_len)) == 0 {
|
|
||||||
return 1
|
|
||||||
} else {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// typedef struct AMF_Object
|
// typedef struct AMF_Object
|
||||||
// amf.h +67
|
// amf.h +67
|
||||||
type C_AMFObject struct {
|
type C_AMFObject struct {
|
||||||
|
@ -103,14 +68,14 @@ type C_AMFObject struct {
|
||||||
// amf.h +73
|
// amf.h +73
|
||||||
type P_vu struct {
|
type P_vu struct {
|
||||||
p_number float64
|
p_number float64
|
||||||
p_aval C_AVal
|
p_aval string
|
||||||
p_object C_AMFObject
|
p_object C_AMFObject
|
||||||
}
|
}
|
||||||
|
|
||||||
// typedef struct AMFObjectProperty
|
// typedef struct AMFObjectProperty
|
||||||
// amf.h +79
|
// amf.h +79
|
||||||
type C_AMFObjectProperty struct {
|
type C_AMFObjectProperty struct {
|
||||||
p_name C_AVal
|
p_name string
|
||||||
p_type C_AMFDataType
|
p_type C_AMFDataType
|
||||||
p_vu P_vu
|
p_vu P_vu
|
||||||
p_UTCoffset int16
|
p_UTCoffset int16
|
||||||
|
|
341
rtmp/parseurl.go
341
rtmp/parseurl.go
|
@ -6,6 +6,7 @@ DESCRIPTION
|
||||||
See Readme.md
|
See Readme.md
|
||||||
|
|
||||||
AUTHOR
|
AUTHOR
|
||||||
|
Dan Kortschak <dan@ausocean.org>
|
||||||
Saxon Nelson-Milton <saxon@ausocean.org>
|
Saxon Nelson-Milton <saxon@ausocean.org>
|
||||||
|
|
||||||
LICENSE
|
LICENSE
|
||||||
|
@ -32,303 +33,71 @@ LICENSE
|
||||||
package rtmp
|
package rtmp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
|
"net/url"
|
||||||
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// int RTMP_ParseURL(const char *url, int *protocol, AVal *host, unsigned int *port,
|
// int RTMP_ParseURL(const char *url, int *protocol, AVal *host, unsigned int *port, AVal *playpath, AVal *app);
|
||||||
// AVal *playpath, AVal *app);
|
|
||||||
// parseurl.c +33
|
// parseurl.c +33
|
||||||
func C_RTMP_ParseURL(url *byte, protocol *int32, host *C_AVal, port *uint32,
|
func C_RTMP_ParseURL(addr string) (protocol int32, host string, port uint16, app, playpath string, ok bool) {
|
||||||
playpath *C_AVal, app *C_AVal) int {
|
u, err := url.Parse(addr)
|
||||||
|
if err != nil {
|
||||||
var p, end, col, ques, slash *byte
|
log.Printf("failed to parse addr: %v", err)
|
||||||
// TODO: use our logger here
|
return protocol, host, port, app, playpath, false
|
||||||
// RTMP_Log(RTMP_LOGDEBUG, "Parsing...");
|
|
||||||
|
|
||||||
*protocol = RTMP_PROTOCOL_RTMP
|
|
||||||
*port = 0
|
|
||||||
playpath.av_len = 0
|
|
||||||
playpath.av_val = nil
|
|
||||||
app.av_len = 0
|
|
||||||
app.av_val = nil
|
|
||||||
|
|
||||||
p = strstr(url, goStrToCStr("://"))
|
|
||||||
|
|
||||||
if p == nil {
|
|
||||||
// TODO: use our logger here
|
|
||||||
log.Println("RTMP URL: No :// in url!")
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
NOTE: the following code nees to be ported if we're using anything other than
|
|
||||||
rtmp!
|
|
||||||
{
|
|
||||||
int len = (int)(p-url);
|
|
||||||
|
|
||||||
if(len == 4 && strncasecmp(url, "rtmp", 4)==0)
|
|
||||||
*protocol = RTMP_PROTOCOL_RTMP;
|
|
||||||
else if(len == 5 && strncasecmp(url, "rtmpt", 5)==0)
|
|
||||||
*protocol = RTMP_PROTOCOL_RTMPT;
|
|
||||||
else if(len == 5 && strncasecmp(url, "rtmps", 5)==0)
|
|
||||||
*protocol = RTMP_PROTOCOL_RTMPS;
|
|
||||||
else if(len == 5 && strncasecmp(url, "rtmpe", 5)==0)
|
|
||||||
*protocol = RTMP_PROTOCOL_RTMPE;
|
|
||||||
else if(len == 5 && strncasecmp(url, "rtmfp", 5)==0)
|
|
||||||
*protocol = RTMP_PROTOCOL_RTMFP;
|
|
||||||
else if(len == 6 && strncasecmp(url, "rtmpte", 6)==0)
|
|
||||||
*protocol = RTMP_PROTOCOL_RTMPTE;
|
|
||||||
else if(len == 6 && strncasecmp(url, "rtmpts", 6)==0)
|
|
||||||
*protocol = RTMP_PROTOCOL_RTMPTS;
|
|
||||||
else {
|
|
||||||
RTMP_Log(RTMP_LOGWARNING, "Unknown protocol!\n");
|
|
||||||
goto parsehost;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// TODO: implement new logger here
|
|
||||||
// RTMP_Log(RTMP_LOGDEBUG, "Parsed protocol: %d", *protocol);
|
|
||||||
|
|
||||||
// Get the hostname
|
|
||||||
p = (*byte)(incBytePtr(unsafe.Pointer(p), 3))
|
|
||||||
|
|
||||||
// check for sudden death
|
|
||||||
if *p == 0 {
|
|
||||||
// TODO: use new logger here
|
|
||||||
// RTMP_Log(RTMP_LOGWARNING, "No hostname in URL!");
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
end = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + uintptr(strlen(p))))
|
switch u.Scheme {
|
||||||
col = strchr(p, ':')
|
case "rtmp":
|
||||||
ques = strchr(p, '?')
|
protocol = RTMP_PROTOCOL_RTMP
|
||||||
slash = strchr(p, '/')
|
case "rtmpt":
|
||||||
|
protocol = RTMP_PROTOCOL_RTMPT
|
||||||
{
|
case "rtmps":
|
||||||
var hostlen int32
|
protocol = RTMP_PROTOCOL_RTMPS
|
||||||
if slash != nil {
|
case "rtmpe":
|
||||||
hostlen = int32(uintptr(unsafe.Pointer(slash)) - uintptr(unsafe.Pointer(p)))
|
protocol = RTMP_PROTOCOL_RTMPE
|
||||||
} else {
|
case "rtmfp":
|
||||||
hostlen = int32(uintptr(unsafe.Pointer(end)) - uintptr(unsafe.Pointer(p)))
|
protocol = RTMP_PROTOCOL_RTMFP
|
||||||
}
|
case "rtmpte":
|
||||||
if col != nil && int32(uintptr(unsafe.Pointer(col))-uintptr(unsafe.Pointer(p))) < hostlen {
|
protocol = RTMP_PROTOCOL_RTMPTE
|
||||||
hostlen = int32(uintptr(unsafe.Pointer(col)) - uintptr(unsafe.Pointer(p)))
|
case "rtmpts":
|
||||||
}
|
protocol = RTMP_PROTOCOL_RTMPTS
|
||||||
|
default:
|
||||||
if hostlen < 256 {
|
log.Printf("unknown scheme: %q", u.Scheme)
|
||||||
host.av_val = (*byte)(unsafe.Pointer(p))
|
return protocol, host, port, app, playpath, false
|
||||||
host.av_len = hostlen
|
|
||||||
// TODO: use new logger with this
|
|
||||||
//RTMP_Log(RTMP_LOGDEBUG, "Parsed host : %.*s", hostlen, host.av_val);
|
|
||||||
} else {
|
|
||||||
// TODO: use new logger with this
|
|
||||||
// RTMP_Log(RTMP_LOGWARNING, "Hostname exceeds 255 characters!");
|
|
||||||
}
|
|
||||||
|
|
||||||
p = (*byte)(incBytePtr(unsafe.Pointer(p), int(hostlen)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get port number if available
|
host = u.Host
|
||||||
if *p == ':' {
|
if p := u.Port(); p != "" {
|
||||||
var p2 uint32
|
pi, err := strconv.Atoi(p)
|
||||||
p = (*byte)(incBytePtr(unsafe.Pointer(p), 1))
|
if err != nil {
|
||||||
tmp, _ := strconv.Atoi(cStrToGoStr(p))
|
return protocol, host, port, app, playpath, false
|
||||||
p2 = uint32(tmp)
|
}
|
||||||
if p2 > 65535 {
|
port = uint16(pi)
|
||||||
// TODO: use new logger with this
|
}
|
||||||
// RTMP_Log(RTMP_LOGWARNING, "Invalid port number!");
|
|
||||||
} else {
|
if !path.IsAbs(u.Path) {
|
||||||
*port = p2
|
return protocol, host, port, app, playpath, true
|
||||||
|
}
|
||||||
|
elems := strings.SplitN(u.Path[1:], "/", 3)
|
||||||
|
app = elems[0]
|
||||||
|
playpath = elems[1]
|
||||||
|
if len(elems) == 3 && len(elems[2]) != 0 {
|
||||||
|
playpath = path.Join(elems[1:]...)
|
||||||
|
switch ext := path.Ext(playpath); ext {
|
||||||
|
case ".f4v", ".mp4":
|
||||||
|
playpath = "mp4:" + playpath[:len(playpath)-len(ext)]
|
||||||
|
case ".mp3":
|
||||||
|
playpath = "mp3:" + playpath[:len(playpath)-len(ext)]
|
||||||
|
case ".flv":
|
||||||
|
playpath = playpath[:len(playpath)-len(ext)]
|
||||||
|
}
|
||||||
|
if u.RawQuery != "" {
|
||||||
|
playpath += "?" + u.RawQuery
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if slash == nil {
|
return protocol, host, port, app, playpath, true
|
||||||
// TODO: use new logger
|
|
||||||
// RTMP_Log(RTMP_LOGWARNING, "No application or playpath in URL!");
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
p = (*byte)(incBytePtr(unsafe.Pointer(slash), 1))
|
|
||||||
|
|
||||||
{
|
|
||||||
/* parse application
|
|
||||||
*
|
|
||||||
* rtmp://host[:port]/app[/appinstance][/...]
|
|
||||||
* application = app[/appinstance]
|
|
||||||
*/
|
|
||||||
|
|
||||||
var slash2 *byte
|
|
||||||
var slash3 *byte = nil
|
|
||||||
var slash4 *byte = nil
|
|
||||||
var applen, appnamelen int32
|
|
||||||
|
|
||||||
slash2 = strchr(p, '/')
|
|
||||||
|
|
||||||
if slash2 != nil {
|
|
||||||
slash3 = strchr((*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(slash2))+
|
|
||||||
uintptr(1))), '/')
|
|
||||||
}
|
|
||||||
if slash3 != nil {
|
|
||||||
slash4 = strchr((*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(slash3))+
|
|
||||||
uintptr(1))), '/')
|
|
||||||
}
|
|
||||||
|
|
||||||
// ondemand, pass all parameters as app
|
|
||||||
applen = int32(uintptr(unsafe.Pointer(end)) - uintptr(unsafe.Pointer(p)))
|
|
||||||
appnamelen = applen
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case ques != nil && strstr(p, goStrToCStr("slist=")) != nil:
|
|
||||||
appnamelen = int32(uintptr(unsafe.Pointer(ques)) - uintptr(unsafe.Pointer(p)))
|
|
||||||
case strings.Compare(cStrToGoStr(p)[:9], "ondemand/") == 0:
|
|
||||||
/* app = ondemand/foobar, only pass app=ondemand */
|
|
||||||
applen = 8
|
|
||||||
appnamelen = 8
|
|
||||||
default:
|
|
||||||
switch {
|
|
||||||
case slash4 != nil:
|
|
||||||
appnamelen = int32(uintptr(unsafe.Pointer(slash4)) - uintptr(
|
|
||||||
unsafe.Pointer(p)))
|
|
||||||
case slash3 != nil:
|
|
||||||
appnamelen = int32(uintptr(unsafe.Pointer(slash3)) - uintptr(
|
|
||||||
unsafe.Pointer(p)))
|
|
||||||
case slash2 != nil:
|
|
||||||
appnamelen = int32(uintptr(unsafe.Pointer(slash2)) - uintptr(
|
|
||||||
unsafe.Pointer(p)))
|
|
||||||
}
|
|
||||||
|
|
||||||
applen = appnamelen
|
|
||||||
}
|
|
||||||
|
|
||||||
app.av_val = (*byte)(unsafe.Pointer(p))
|
|
||||||
app.av_len = applen
|
|
||||||
// TODO: use new logging here
|
|
||||||
// RTMP_Log(RTMP_LOGDEBUG, "Parsed app : %.*s", applen, p);
|
|
||||||
|
|
||||||
p = (*byte)(incBytePtr(unsafe.Pointer(p), int(appnamelen)))
|
|
||||||
}
|
|
||||||
|
|
||||||
if *p == '/' {
|
|
||||||
p = (*byte)(incBytePtr(unsafe.Pointer(p), 1))
|
|
||||||
}
|
|
||||||
// NOTE: don't think we currently need this section - see 787 for this func
|
|
||||||
|
|
||||||
if int(uintptr(unsafe.Pointer(end))-uintptr(unsafe.Pointer(p))) != 0 {
|
|
||||||
var av C_AVal
|
|
||||||
av.av_val = (*byte)(unsafe.Pointer(p))
|
|
||||||
av.av_len = int32(uintptr(unsafe.Pointer(end)) - uintptr(unsafe.Pointer(p)))
|
|
||||||
// TODO: port THis
|
|
||||||
//C.RTMP_ParsePlaypath(&av, playpath)
|
|
||||||
C_RTMP_ParsePlaypath(&av, playpath)
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// void RTMP_ParsePlaypath(AVal *in, AVal *out);
|
|
||||||
// parseurl.c +201
|
|
||||||
func C_RTMP_ParsePlaypath(in, out *C_AVal) {
|
|
||||||
var addMP4 int32 = 0
|
|
||||||
var addMP3 int32 = 0
|
|
||||||
var subExt int32 = 0
|
|
||||||
playpath := in.av_val
|
|
||||||
var temp, q *byte
|
|
||||||
var ext *byte = nil
|
|
||||||
ppstart := (*byte)(unsafe.Pointer(playpath))
|
|
||||||
var streamname, destptr, p *byte
|
|
||||||
|
|
||||||
pplen := in.av_len
|
|
||||||
|
|
||||||
out.av_val = nil
|
|
||||||
out.av_len = 0
|
|
||||||
|
|
||||||
temp = strstr((*byte)(unsafe.Pointer(ppstart)), goStrToCStr("slist="))
|
|
||||||
if *ppstart == '?' && temp != nil {
|
|
||||||
ppstart = (*byte)(incBytePtr(unsafe.Pointer(temp), 6))
|
|
||||||
pplen = strlen(ppstart)
|
|
||||||
|
|
||||||
temp = strchr(ppstart, '&')
|
|
||||||
|
|
||||||
if temp != nil {
|
|
||||||
pplen = int32(uintptr(unsafe.Pointer(temp)) - uintptr(unsafe.Pointer(ppstart)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
q = strchr(ppstart, '?')
|
|
||||||
|
|
||||||
if pplen >= 4 {
|
|
||||||
if q != nil {
|
|
||||||
ext = (*byte)(decBytePtr(unsafe.Pointer(q), 4))
|
|
||||||
} else {
|
|
||||||
ext = (*byte)(sliceToPtr((*[_Gi]byte)(unsafe.Pointer(ppstart))[uintptr(pplen)-4:]))
|
|
||||||
}
|
|
||||||
switch {
|
|
||||||
case strings.Compare(cStrToGoStr(ext)[:4], ".f4v") == 0 ||
|
|
||||||
strings.Compare(cStrToGoStr(ext)[:4], ".mp4") == 0:
|
|
||||||
addMP4 = 1
|
|
||||||
subExt = 1
|
|
||||||
case ppstart == (*byte)(unsafe.Pointer(playpath)) && strings.Compare(
|
|
||||||
cStrToGoStr(ext)[:4], ".flv") == 0:
|
|
||||||
subExt = 1
|
|
||||||
case strings.Compare(cStrToGoStr(ext)[:4], ".mp3") == 0:
|
|
||||||
addMP3 = 1
|
|
||||||
subExt = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
streamname = (*byte)(malloc(uintptr(pplen + 4 + 1)))
|
|
||||||
|
|
||||||
if streamname == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
destptr = streamname
|
|
||||||
switch {
|
|
||||||
case addMP4 != 0:
|
|
||||||
if strings.Compare(cStrToGoStr(ppstart)[:4], "mp4") != 0 {
|
|
||||||
memmove(unsafe.Pointer(destptr), unsafe.Pointer(goStrToCStr("mp4:")),
|
|
||||||
uintptr(len("mp4:")))
|
|
||||||
destptr = (*byte)(incBytePtr(unsafe.Pointer(destptr), 4))
|
|
||||||
} else {
|
|
||||||
subExt = 0
|
|
||||||
}
|
|
||||||
case addMP3 != 0:
|
|
||||||
if strings.Compare(cStrToGoStr(ppstart)[:4], "mp3") != 0 {
|
|
||||||
memmove(unsafe.Pointer(destptr), unsafe.Pointer(goStrToCStr("mp3:")),
|
|
||||||
uintptr(len("mp4:")))
|
|
||||||
destptr = (*byte)(incBytePtr(unsafe.Pointer(destptr), 4))
|
|
||||||
} else {
|
|
||||||
subExt = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p = ppstart
|
|
||||||
for pplen > 0 {
|
|
||||||
if subExt != 0 && p == ext {
|
|
||||||
p = (*byte)(incBytePtr(unsafe.Pointer(p), 4))
|
|
||||||
pplen -= 4
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if *p == '%' {
|
|
||||||
var c uint32
|
|
||||||
fmt.Sscanf(cStrToGoStr((*byte)(incBytePtr(unsafe.Pointer(p), 1))), "%02x", &c)
|
|
||||||
(*[_Gi]byte)(unsafe.Pointer(destptr))[0] = byte(c)
|
|
||||||
destptr = (*byte)(incBytePtr(unsafe.Pointer(destptr), 1))
|
|
||||||
pplen -= 3
|
|
||||||
p = (*byte)(incBytePtr(unsafe.Pointer(p), 3))
|
|
||||||
} else {
|
|
||||||
(*[_Gi]byte)(unsafe.Pointer(destptr))[0] = *p
|
|
||||||
destptr = (*byte)(incBytePtr(unsafe.Pointer(destptr), 1))
|
|
||||||
p = (*byte)(incBytePtr(unsafe.Pointer(p), 1))
|
|
||||||
pplen--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*destptr = '\x00'
|
|
||||||
|
|
||||||
out.av_val = (*byte)(unsafe.Pointer(streamname))
|
|
||||||
out.av_len = int32(uintptr(unsafe.Pointer(destptr)) - uintptr(unsafe.Pointer(
|
|
||||||
streamname)))
|
|
||||||
}
|
}
|
||||||
|
|
1098
rtmp/rtmp.go
1098
rtmp/rtmp.go
File diff suppressed because it is too large
Load Diff
|
@ -142,65 +142,46 @@ type C_RTMPSockBuf struct {
|
||||||
sb_start *byte
|
sb_start *byte
|
||||||
sb_buf [RTMP_BUFFER_CACHE_SIZE]byte // port const
|
sb_buf [RTMP_BUFFER_CACHE_SIZE]byte // port const
|
||||||
sb_timedout int32
|
sb_timedout int32
|
||||||
sb_ssl uintptr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTMPPacket_IsReady(a)
|
// RTMPPacket_IsReady(a)
|
||||||
// rtmp.h +142
|
// rtmp.h +142
|
||||||
func C_RTMPPacket_IsReady(p *C_RTMPPacket) int {
|
func C_RTMPPacket_IsReady(p *C_RTMPPacket) bool {
|
||||||
if p.m_nBytesRead == p.m_nBodySize {
|
return p.m_nBytesRead == p.m_nBodySize
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// typedef struct RTMP_LNK
|
// typedef struct RTMP_LNK
|
||||||
// rtmp.h +144
|
// rtmp.h +144
|
||||||
type C_RTMP_LNK struct {
|
type C_RTMP_LNK struct {
|
||||||
hostname C_AVal
|
hostname string
|
||||||
sockshost C_AVal
|
sockshost string
|
||||||
playpath0 C_AVal
|
playpath0 string
|
||||||
playpath C_AVal
|
playpath string
|
||||||
tcUrl C_AVal
|
tcUrl string
|
||||||
swfUrl C_AVal
|
swfUrl string
|
||||||
pageUrl C_AVal
|
pageUrl string
|
||||||
app C_AVal
|
app string
|
||||||
auth C_AVal
|
auth string
|
||||||
flashVer C_AVal
|
flashVer string
|
||||||
subscribepath C_AVal
|
token string
|
||||||
usherToken C_AVal
|
extras C_AMFObject
|
||||||
token C_AVal
|
seekTime int32
|
||||||
pubUser C_AVal
|
lFlags int32
|
||||||
pubPasswd C_AVal
|
swfAge int32
|
||||||
extras C_AMFObject
|
protocol int32
|
||||||
edepth int32
|
timeout int32
|
||||||
seekTime int32
|
socksport uint16
|
||||||
stopTime int32
|
port uint16
|
||||||
lFlags int32
|
|
||||||
swfAge int32
|
|
||||||
protocol int32
|
|
||||||
timeout int32
|
|
||||||
pFlags int32
|
|
||||||
socksport uint16
|
|
||||||
port uint16
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// typedef struct RTMP_READ
|
// typedef struct RTMP_READ
|
||||||
// rtmp.h +200
|
// rtmp.h +200
|
||||||
type C_RTMP_READ struct {
|
type C_RTMP_READ struct {
|
||||||
buf *byte
|
buf *byte
|
||||||
bufpos *byte
|
|
||||||
buflen uint
|
|
||||||
timestamp uint32
|
|
||||||
dataType uint8
|
dataType uint8
|
||||||
flags uint8
|
flags uint8
|
||||||
status int8
|
status int8
|
||||||
initialFrameType uint8
|
|
||||||
nResumeTS uint32
|
nResumeTS uint32
|
||||||
metaHeader *byte
|
|
||||||
initialFrame *byte
|
|
||||||
nMetaHeaderSize uint32
|
|
||||||
nInitialFrameSize uint32
|
|
||||||
nIgnoredFrameCounter uint32
|
nIgnoredFrameCounter uint32
|
||||||
nIgnoredFlvFrameCounter uint32
|
nIgnoredFlvFrameCounter uint32
|
||||||
}
|
}
|
||||||
|
@ -208,7 +189,7 @@ type C_RTMP_READ struct {
|
||||||
// typedef struct RTMPMethod
|
// typedef struct RTMPMethod
|
||||||
// rtmp.h +231
|
// rtmp.h +231
|
||||||
type C_RTMP_METHOD struct {
|
type C_RTMP_METHOD struct {
|
||||||
name C_AVal
|
name string
|
||||||
num int32
|
num int32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,13 +204,11 @@ type C_RTMP struct {
|
||||||
m_nBufferMS int32
|
m_nBufferMS int32
|
||||||
m_stream_id int32
|
m_stream_id int32
|
||||||
m_mediaChannel int32
|
m_mediaChannel int32
|
||||||
m_mediaStamp uint32
|
|
||||||
m_pauseStamp uint32
|
|
||||||
m_pausing int32
|
m_pausing int32
|
||||||
m_nServerBW int32
|
m_nServerBW int32
|
||||||
m_nClientBW int32
|
m_nClientBW int32
|
||||||
m_nClientBW2 uint8
|
m_nClientBW2 uint8
|
||||||
m_bPlaying uint8
|
m_bPlaying bool
|
||||||
m_bSendEncoding uint8
|
m_bSendEncoding uint8
|
||||||
m_bSendCounter uint8
|
m_bSendCounter uint8
|
||||||
m_numInvokes int32
|
m_numInvokes int32
|
||||||
|
@ -245,10 +224,8 @@ type C_RTMP struct {
|
||||||
m_fEncoding float64
|
m_fEncoding float64
|
||||||
m_fDuration float64
|
m_fDuration float64
|
||||||
m_msgCounter int32
|
m_msgCounter int32
|
||||||
m_polling int32
|
|
||||||
m_resplen int32
|
m_resplen int32
|
||||||
m_unackd int32
|
m_unackd int32
|
||||||
m_clientID C_AVal
|
|
||||||
m_read C_RTMP_READ
|
m_read C_RTMP_READ
|
||||||
m_write C_RTMPPacket
|
m_write C_RTMPPacket
|
||||||
m_sb C_RTMPSockBuf
|
m_sb C_RTMPSockBuf
|
||||||
|
|
|
@ -76,7 +76,7 @@ func TestMemset(t *testing.T) {
|
||||||
setNum := 5
|
setNum := 5
|
||||||
testVal := byte('A')
|
testVal := byte('A')
|
||||||
mem := malloc(uintptr(size))
|
mem := malloc(uintptr(size))
|
||||||
memset((*byte)(mem), int(testVal), setNum)
|
memset((*byte)(mem), testVal, setNum)
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
if i > setNum-1 {
|
if i > setNum-1 {
|
||||||
testVal = byte(0)
|
testVal = byte(0)
|
||||||
|
|
Loading…
Reference in New Issue