diff --git a/srtgo.go b/srtgo.go index a56bcfd..5cee00e 100644 --- a/srtgo.go +++ b/srtgo.go @@ -277,8 +277,8 @@ func (s SrtSocket) Connect() error { return nil } -// Read data from the SRT socket -func (s SrtSocket) Read(b []byte) (n int, err error) { +// ReadMsg from the socket including SRT control data. +func (s SrtSocket) ReadMsg(b []byte) (n int, ctrl SrtMsgCtrl, err error) { if !s.blocking { len := C.int(2) timeoutMs := C.int64_t(s.pollTimeout) @@ -286,18 +286,32 @@ func (s SrtSocket) Read(b []byte) (n int, err error) { if C.srt_epoll_wait(s.epollIo, &ready[0], &len, nil, nil, timeoutMs, nil, nil, nil, nil) == SRT_ERROR { if C.srt_getlasterror(nil) == C.SRT_ETIMEOUT { - return 0, nil + return } - return 0, fmt.Errorf("error in read:epoll %s", C.GoString(C.srt_getlasterror_str())) + err = fmt.Errorf("error in read:epoll %s", C.GoString(C.srt_getlasterror_str())) + return } } - res := C.srt_recvmsg2(s.socket, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)), nil) + var c C.SRT_MSGCTRL + + res := C.srt_recvmsg2(s.socket, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)), &c) + if res == SRT_ERROR { - return 0, fmt.Errorf("error in read::recv %s", C.GoString(C.srt_getlasterror_str())) + err = fmt.Errorf("error in read::recv %s", C.GoString(C.srt_getlasterror_str())) + return } - return int(res), nil + n = int(res) + ctrl = newSrtMsgCtrl(&c) + + return +} + +// Read data from the SRT socket +func (s SrtSocket) Read(b []byte) (n int, err error) { + n, _, err = s.ReadMsg(b) + return } // Write data to the SRT socket @@ -621,3 +635,8 @@ func (s SrtSocket) postconfiguration(sck *SrtSocket) error { err := setSocketOptions(sck.socket, bindingPost, s.options) return err } + +// Now - Time in microseconds elapsed since epoch using SRT internal clock +func Now() int64 { + return int64(C.srt_time_now()) +} diff --git a/srtmsgctrl.go b/srtmsgctrl.go new file mode 100644 index 0000000..1e668be --- /dev/null +++ b/srtmsgctrl.go @@ -0,0 +1,24 @@ +package srtgo + +// #cgo LDFLAGS: -lsrt +// #include +import "C" + +type SrtMsgCtrl struct { + MsgTTL int // TTL for a message (millisec), default -1 (no TTL limitation) + InOrder int // Whether a message is allowed to supersede partially lost one. Unused in stream and live mode. + Boundary int // 0:mid pkt, 1(01b):end of frame, 2(11b):complete frame, 3(10b): start of frame + SrcTime int64 // source time since epoch (usec), 0: use internal time (sender) + PktSeq int32 // sequence number of the first packet in received message (unused for sending) + MsgNo int32 // message number (output value for both sending and receiving) +} + +func newSrtMsgCtrl(ctrl *C.SRT_MSGCTRL) (res SrtMsgCtrl) { + res.MsgTTL = int(ctrl.msgttl) + res.InOrder = int(ctrl.inorder) + res.Boundary = int(ctrl.boundary) + res.SrcTime = int64(ctrl.srctime) + res.PktSeq = int32(ctrl.pktseq) + res.MsgNo = int32(ctrl.msgno) + return +}