rtmp: remove C_AVal

This commit is contained in:
Dan Kortschak 2018-09-07 20:40:46 +09:30
parent dde20e1a7b
commit 834c2bc632
4 changed files with 70 additions and 128 deletions

View File

@ -31,11 +31,6 @@ LICENSE
*/ */
package rtmp package rtmp
import (
"fmt"
"unsafe"
)
const ( const (
AMF_NUMBER = iota AMF_NUMBER = iota
AMF_BOOLEAN AMF_BOOLEAN
@ -62,38 +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
}
func (s *C_AVal) String() string { return CAV(s) }
// 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
}
func CAV(av *C_AVal) string {
if av.av_len <= 0 || av.av_val == nil {
if av.av_len < 0 {
panic(fmt.Sprintf("invalid length: %d", av.av_len))
}
return ""
}
return string((*[_Gi]byte)(unsafe.Pointer(av.av_val))[:av.av_len])
}
// typedef struct AMF_Object // typedef struct AMF_Object
// amf.h +67 // amf.h +67
type C_AMFObject struct { type C_AMFObject struct {

View File

@ -42,7 +42,7 @@ import (
// int RTMP_ParseURL(const char *url, int *protocol, AVal *host, unsigned int *port, AVal *playpath, AVal *app); // int RTMP_ParseURL(const char *url, int *protocol, AVal *host, unsigned int *port, AVal *playpath, AVal *app);
// parseurl.c +33 // parseurl.c +33
func C_RTMP_ParseURL(addr string) (protocol int32, host C_AVal, port uint16, playpath, app C_AVal, ok bool) { func C_RTMP_ParseURL(addr string) (protocol int32, host string, port uint16, app, playpath string, ok bool) {
u, err := url.Parse(addr) u, err := url.Parse(addr)
if err != nil { if err != nil {
log.Printf("failed to parse addr: %v", err) log.Printf("failed to parse addr: %v", err)
@ -69,7 +69,7 @@ func C_RTMP_ParseURL(addr string) (protocol int32, host C_AVal, port uint16, pla
return protocol, host, port, app, playpath, false return protocol, host, port, app, playpath, false
} }
host = AVC(u.Host) host = u.Host
if p := u.Port(); p != "" { if p := u.Port(); p != "" {
pi, err := strconv.Atoi(p) pi, err := strconv.Atoi(p)
if err != nil { if err != nil {
@ -79,25 +79,24 @@ func C_RTMP_ParseURL(addr string) (protocol int32, host C_AVal, port uint16, pla
} }
if !path.IsAbs(u.Path) { if !path.IsAbs(u.Path) {
return protocol, host, port, playpath, app, true return protocol, host, port, app, playpath, true
} }
elems := strings.SplitN(u.Path[1:], "/", 3) elems := strings.SplitN(u.Path[1:], "/", 3)
app = AVC(elems[0]) app = elems[0]
playpath = AVC(elems[1]) playpath = elems[1]
if len(elems) == 3 && len(elems[2]) != 0 { if len(elems) == 3 && len(elems[2]) != 0 {
inst := path.Join(elems[1:]...) playpath = path.Join(elems[1:]...)
switch ext := path.Ext(inst); ext { switch ext := path.Ext(playpath); ext {
case ".f4v", ".mp4": case ".f4v", ".mp4":
inst = "mp4:" + inst[:len(inst)-len(ext)] playpath = "mp4:" + playpath[:len(playpath)-len(ext)]
case ".mp3": case ".mp3":
inst = "mp3:" + inst[:len(inst)-len(ext)] playpath = "mp3:" + playpath[:len(playpath)-len(ext)]
case ".flv": case ".flv":
inst = inst[:len(inst)-len(ext)] playpath = playpath[:len(playpath)-len(ext)]
} }
if u.RawQuery != "" { if u.RawQuery != "" {
inst += "?" + u.RawQuery playpath += "?" + u.RawQuery
} }
playpath = AVC(inst)
} }
return protocol, host, port, app, playpath, true return protocol, host, port, app, playpath, true

View File

@ -52,6 +52,7 @@ import (
"log" "log"
"math/rand" "math/rand"
"strconv" "strconv"
"strings"
"time" "time"
"unsafe" "unsafe"
@ -263,31 +264,21 @@ func C_RTMP_SetBufferMS(r *C_RTMP, size int32) {
// void SocksSetup(RTMP *r, C_AVal* sockshost); // void SocksSetup(RTMP *r, C_AVal* sockshost);
// rtmp.c +410 // rtmp.c +410
func C_SocksSetup(r *C_RTMP, sockshost *C_AVal) { func C_SocksSetup(r *C_RTMP, sockshost string) {
if sockshost.av_len != 0 { if sockshost != "" {
socksport := strchr((*byte)(unsafe.Pointer(sockshost.av_val)), ':') p := strings.SplitN(sockshost, ":", 2)
hostname := strdup((*byte)(unsafe.Pointer(sockshost.av_val))) r.Link.sockshost = p[0]
r.Link.socksport = 1080
if unsafe.Pointer(socksport) != nil { if len(p) != 1 {
(*[_Gi]byte)(unsafe.Pointer(hostname))[uintptr(decBytePtr(unsafe.Pointer(socksport), port, err := strconv.Atoi(p[1])
int(uintptr(unsafe.Pointer(sockshost.av_val)))))] = '\000'
r.Link.sockshost.av_val = (*byte)(unsafe.Pointer(hostname))
r.Link.sockshost.av_len = int32(strlen(hostname))
value, err := strconv.Atoi(string((*[_Gi]byte)(unsafe.Pointer(uintptr(
unsafe.Pointer(socksport)) + uintptr(1)))[:strlen((*byte)(unsafe.Pointer(
uintptr(unsafe.Pointer(socksport))+uintptr(1))))+1]))
if err != nil { if err != nil {
port = 1080
log.Println("C_SocksSetup: bad string conversion!") log.Println("C_SocksSetup: bad string conversion!")
} }
if uintptr(unsafe.Pointer(socksport)) == 0 { r.Link.socksport = uint16(port)
value = 1080
}
r.Link.socksport = uint16(value)
} }
} else { } else {
r.Link.sockshost.av_val = nil r.Link.sockshost = ""
r.Link.sockshost.av_len = 0
r.Link.socksport = 0 r.Link.socksport = 0
} }
} }
@ -302,17 +293,17 @@ func C_RTMP_SetupURL(r *C_RTMP, addr string) (ok bool) {
} }
r.Link.playpath = r.Link.playpath0 r.Link.playpath = r.Link.playpath0
if r.Link.tcUrl.av_len == 0 { if r.Link.tcUrl == "" {
if r.Link.app.av_len != 0 { if r.Link.app != "" {
r.Link.tcUrl = AVC(fmt.Sprintf("%v://%v:%v/%v", r.Link.tcUrl = fmt.Sprintf("%v://%v:%v/%v",
RTMPProtocolStringsLower[r.Link.protocol], &r.Link.hostname, r.Link.port, &r.Link.app)) RTMPProtocolStringsLower[r.Link.protocol], r.Link.hostname, r.Link.port, r.Link.app)
r.Link.lFlags |= RTMP_LF_FTCU r.Link.lFlags |= RTMP_LF_FTCU
} else { } else {
r.Link.tcUrl = AVC(addr) r.Link.tcUrl = addr
} }
} }
C_SocksSetup(r, &r.Link.sockshost) C_SocksSetup(r, r.Link.sockshost)
if r.Link.port == 0 { if r.Link.port == 0 {
switch { switch {
@ -329,20 +320,11 @@ func C_RTMP_SetupURL(r *C_RTMP, addr string) (ok bool) {
// int add_addr_info(struct sockaddr_in *service, AVal *host, int port) // int add_addr_info(struct sockaddr_in *service, AVal *host, int port)
// rtmp.c +869 // rtmp.c +869
func C_add_addr_info(service *C.sockaddr_in, host *C_AVal, port C.int) (ok bool) { func C_add_addr_info(service *C.sockaddr_in, hostname string, port uint16) (ok bool) {
var hostname *byte h := (*C.char)(unsafe.Pointer(goStrToCStr(hostname)))
if (*[1 << 20]byte)(unsafe.Pointer(host.av_val))[host.av_len] != 0 { service.sin_addr.s_addr = C.inet_addr(h)
name := make([]byte, host.av_len+1)
copy(name, (*[1 << 20]byte)(unsafe.Pointer(host.av_val))[:host.av_len])
name[len(name)-1] = 0
hostname = (*byte)(unsafe.Pointer(&name[0]))
} else {
hostname = host.av_val
}
service.sin_addr.s_addr = C.inet_addr((*C.char)(unsafe.Pointer(hostname)))
if service.sin_addr.s_addr == C.INADDR_NONE { if service.sin_addr.s_addr == C.INADDR_NONE {
host := C.gethostbyname((*C.char)(unsafe.Pointer(hostname))) host := C.gethostbyname(h)
if host == nil || *host.h_addr_list == nil { if host == nil || *host.h_addr_list == nil {
//RTMP_Log(RTMP_LOGERROR, "Problem accessing the DNS. (addr: %s)", hostname) //RTMP_Log(RTMP_LOGERROR, "Problem accessing the DNS. (addr: %s)", hostname)
return false return false
@ -350,7 +332,7 @@ func C_add_addr_info(service *C.sockaddr_in, host *C_AVal, port C.int) (ok bool)
service.sin_addr = *(*C.struct_in_addr)(unsafe.Pointer(*host.h_addr_list)) service.sin_addr = *(*C.struct_in_addr)(unsafe.Pointer(*host.h_addr_list))
} }
service.sin_port = C.ushort(inet.Htons(uint16(port))) service.sin_port = C.ushort(inet.Htons(port))
return true return true
} }
@ -426,7 +408,7 @@ func C_RTMP_Connect(r *C_RTMP, cp *C_RTMPPacket) (ok bool) {
// TODO: port this // TODO: port this
var service C.sockaddr_in var service C.sockaddr_in
if r.Link.hostname.av_len == 0 { if r.Link.hostname == "" {
return false return false
} }
memset((*byte)(unsafe.Pointer(&service)), 0, int(unsafe.Sizeof(service))) memset((*byte)(unsafe.Pointer(&service)), 0, int(unsafe.Sizeof(service)))
@ -435,12 +417,12 @@ func C_RTMP_Connect(r *C_RTMP, cp *C_RTMPPacket) (ok bool) {
service.sin_family = C.AF_INET service.sin_family = C.AF_INET
if r.Link.socksport != 0 { if r.Link.socksport != 0 {
if !C_add_addr_info(&service, (*C_AVal)(unsafe.Pointer(&r.Link.sockshost)), C.int(r.Link.socksport)) { if !C_add_addr_info(&service, r.Link.sockshost, r.Link.socksport) {
return false return false
} }
} else { } else {
// connect directly // connect directly
if !C_add_addr_info(&service, (*C_AVal)(unsafe.Pointer(&r.Link.hostname)), C.int(r.Link.port)) { if !C_add_addr_info(&service, r.Link.hostname, r.Link.port) {
return false return false
} }
} }
@ -461,7 +443,7 @@ func C_SocksNegotiate(r *C_RTMP) (ok bool) {
memset((*byte)(unsafe.Pointer(&service)), 0, int(unsafe.Sizeof(service))) memset((*byte)(unsafe.Pointer(&service)), 0, int(unsafe.Sizeof(service)))
C_add_addr_info(&service, (*C_AVal)(unsafe.Pointer(&r.Link.hostname)), C.int(r.Link.port)) C_add_addr_info(&service, r.Link.hostname, r.Link.port)
addr = int32(inet.Htonl(uint32(service.sin_addr.s_addr))) addr = int32(inet.Htonl(uint32(service.sin_addr.s_addr)))
{ {
@ -711,7 +693,7 @@ func C_SendConnectPacket(r *C_RTMP, cp *C_RTMPPacket) (ok bool) {
enc = (*byte)(unsafe.Pointer(incBytePtr(unsafe.Pointer(enc), 1))) enc = (*byte)(unsafe.Pointer(incBytePtr(unsafe.Pointer(enc), 1)))
enc = C_AMF_EncodeNamedString(enc, pend, av_app, CAV(&r.Link.app)) enc = C_AMF_EncodeNamedString(enc, pend, av_app, r.Link.app)
if enc == nil { if enc == nil {
return false return false
} }
@ -722,21 +704,21 @@ func C_SendConnectPacket(r *C_RTMP, cp *C_RTMPPacket) (ok bool) {
} }
} }
if r.Link.flashVer.av_len != 0 { if r.Link.flashVer != "" {
enc = C_AMF_EncodeNamedString(enc, pend, av_flashVer, CAV(&r.Link.flashVer)) enc = C_AMF_EncodeNamedString(enc, pend, av_flashVer, r.Link.flashVer)
if enc == nil { if enc == nil {
return false return false
} }
} }
if r.Link.swfUrl.av_len != 0 { if r.Link.swfUrl != "" {
enc = C_AMF_EncodeNamedString(enc, pend, av_swfUrl, CAV(&r.Link.swfUrl)) enc = C_AMF_EncodeNamedString(enc, pend, av_swfUrl, r.Link.swfUrl)
if enc == nil { if enc == nil {
return false return false
} }
} }
if r.Link.tcUrl.av_len != 0 { if r.Link.tcUrl != "" {
enc = C_AMF_EncodeNamedString(enc, pend, av_tcUrl, CAV(&r.Link.tcUrl)) enc = C_AMF_EncodeNamedString(enc, pend, av_tcUrl, r.Link.tcUrl)
if enc == nil { if enc == nil {
return false return false
} }
@ -763,8 +745,8 @@ func C_SendConnectPacket(r *C_RTMP, cp *C_RTMPPacket) (ok bool) {
if enc == nil { if enc == nil {
return false return false
} }
if r.Link.pageUrl.av_len != 0 { if r.Link.pageUrl != "" {
enc = C_AMF_EncodeNamedString(enc, pend, av_pageUrl, CAV(&r.Link.pageUrl)) enc = C_AMF_EncodeNamedString(enc, pend, av_pageUrl, r.Link.pageUrl)
if enc == nil { if enc == nil {
return false return false
} }
@ -791,12 +773,12 @@ func C_SendConnectPacket(r *C_RTMP, cp *C_RTMPPacket) (ok bool) {
enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1)) enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1))
/* add auth string */ /* add auth string */
if r.Link.auth.av_len != 0 { if r.Link.auth != "" {
enc = C_AMF_EncodeBoolean(enc, pend, r.Link.lFlags&RTMP_LF_AUTH != 0) enc = C_AMF_EncodeBoolean(enc, pend, r.Link.lFlags&RTMP_LF_AUTH != 0)
if enc == nil { if enc == nil {
return false return false
} }
enc = C_AMF_EncodeString(enc, (*byte)(pend), CAV(&r.Link.auth)) enc = C_AMF_EncodeString(enc, (*byte)(pend), r.Link.auth)
if enc == nil { if enc == nil {
return false return false
} }
@ -873,7 +855,7 @@ func C_SendReleaseStream(r *C_RTMP) (ok bool) {
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes)) enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL *enc = AMF_NULL
enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1)) enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1))
enc = C_AMF_EncodeString(enc, pend, CAV(&r.Link.playpath)) enc = C_AMF_EncodeString(enc, pend, r.Link.playpath)
if enc == nil { if enc == nil {
return false return false
} }
@ -906,7 +888,7 @@ func C_SendFCPublish(r *C_RTMP) (ok bool) {
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes)) enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL *enc = AMF_NULL
enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1)) enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1))
enc = C_AMF_EncodeString(enc, pend, CAV(&r.Link.playpath)) enc = C_AMF_EncodeString(enc, pend, r.Link.playpath)
if enc == nil { if enc == nil {
return false return false
} }
@ -939,7 +921,7 @@ func C_SendFCUnpublish(r *C_RTMP) (ok bool) {
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes)) enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL *enc = AMF_NULL
enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1)) enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1))
enc = C_AMF_EncodeString(enc, pend, CAV(&r.Link.playpath)) enc = C_AMF_EncodeString(enc, pend, r.Link.playpath)
if enc == nil { if enc == nil {
return false return false
@ -974,7 +956,7 @@ func C_SendPublish(r *C_RTMP) (ok bool) {
enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes)) enc = C_AMF_EncodeNumber(enc, pend, float64(r.m_numInvokes))
*enc = AMF_NULL *enc = AMF_NULL
enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1)) enc = (*byte)(incBytePtr(unsafe.Pointer(enc), 1))
enc = C_AMF_EncodeString(enc, pend, CAV(&r.Link.playpath)) enc = C_AMF_EncodeString(enc, pend, r.Link.playpath)
if enc == nil { if enc == nil {
return false return false
@ -1157,7 +1139,7 @@ func C_HandleInvoke(r *C_RTMP, body *byte, nBodySize uint32) (ok bool) {
//methodInvoked.av_val); //methodInvoked.av_val);
switch methodInvoked { switch methodInvoked {
case av_connect: case av_connect:
if r.Link.token.av_len != 0 { if r.Link.token != "" {
panic("No support for link token") panic("No support for link token")
} }
@ -1907,14 +1889,12 @@ func C_CloseInternal(r *C_RTMP, reconnect int32) {
r.m_unackd = 0 r.m_unackd = 0
if ((r.Link.lFlags & RTMP_LF_FTCU) != 0) && (reconnect == 0) { if ((r.Link.lFlags & RTMP_LF_FTCU) != 0) && (reconnect == 0) {
//C.free(unsafe.Pointer(r.Link.app.av_val)) r.Link.app = ""
r.Link.app.av_val = nil
r.Link.lFlags ^= RTMP_LF_FAPU r.Link.lFlags ^= RTMP_LF_FAPU
} }
if reconnect == 0 { if reconnect == 0 {
//C.free(unsafe.Pointer(r.Link.playpath0.av_val)) r.Link.playpath0 = ""
r.Link.playpath0.av_val = nil
} }
} }

View File

@ -154,21 +154,21 @@ func C_RTMPPacket_IsReady(p *C_RTMPPacket) bool {
// 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 subscribepath string
usherToken C_AVal usherToken string
token C_AVal token string
pubUser C_AVal pubUser string
pubPasswd C_AVal pubPasswd string
extras C_AMFObject extras C_AMFObject
edepth int32 edepth int32
seekTime int32 seekTime int32