75 lines
2.3 KiB
Go
75 lines
2.3 KiB
Go
|
package rtmp
|
||
|
|
||
|
import (
|
||
|
"net"
|
||
|
"encoding/binary"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
func write_basic_header(chunk_buffer *[]byte, format uint8, csid uint32) {
|
||
|
if csid < 64 {
|
||
|
(*chunk_buffer)[0] = (format << 6) + uint8(csid)
|
||
|
} else if csid < 320 {
|
||
|
(*chunk_buffer)[0] = format << 6
|
||
|
(*chunk_buffer)[1] = uint8(csid - 64)
|
||
|
} else {
|
||
|
(*chunk_buffer)[0] = (format << 6) + 1
|
||
|
binary.LittleEndian.PutUint16((*chunk_buffer)[1:3], uint16(csid - 64))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func write_message_header_0(chunk_buffer *[]byte, msg_strmid uint32, msg_ptr *Message, basic_header_size uint32) {
|
||
|
msg_len_inter := make([]byte, 4)
|
||
|
binary.BigEndian.PutUint32(msg_len_inter, msg_ptr.msg_len)
|
||
|
copy((*chunk_buffer)[basic_header_size + 3:basic_header_size + 6], msg_len_inter[1:])
|
||
|
(*chunk_buffer)[basic_header_size + 6] = msg_ptr.msg_type
|
||
|
binary.BigEndian.PutUint32((*chunk_buffer)[basic_header_size + 7:basic_header_size + 11], msg_strmid)
|
||
|
}
|
||
|
|
||
|
func write_chunk_data(chunk_buffer *[]byte, data []byte, bytes_buffered *uint32, chunk_data_size uint32, header_size uint32) {
|
||
|
copy((*chunk_buffer)[header_size:header_size+chunk_data_size], data[*bytes_buffered:*bytes_buffered + chunk_data_size])
|
||
|
*bytes_buffered += chunk_data_size
|
||
|
}
|
||
|
|
||
|
func WriteChunk(conn net.Conn, csid uint32, msg_strmid uint32, msg_ptr *Message, chunk_size uint32) (error) {
|
||
|
conn.SetDeadline(time.Now().Add(10 * time.Second))
|
||
|
|
||
|
var i uint32 = 0
|
||
|
for i < msg_ptr.msg_len {
|
||
|
var chunk_data_size uint32
|
||
|
if msg_ptr.msg_len - i > chunk_size {
|
||
|
chunk_data_size = chunk_size
|
||
|
} else {
|
||
|
chunk_data_size = msg_ptr.msg_len - i
|
||
|
}
|
||
|
|
||
|
basic_header_size := uint32(1)
|
||
|
if csid >= 64 {
|
||
|
basic_header_size += 1
|
||
|
}
|
||
|
if csid >= 320 {
|
||
|
basic_header_size += 1
|
||
|
}
|
||
|
|
||
|
var chunk_buffer []byte
|
||
|
var header_size uint32
|
||
|
if i == 0 {
|
||
|
chunk_buffer = make([]byte, basic_header_size + 11 + chunk_data_size)
|
||
|
write_basic_header(&chunk_buffer, 0, csid)
|
||
|
write_message_header_0(&chunk_buffer, msg_strmid, msg_ptr, basic_header_size)
|
||
|
header_size = basic_header_size + 11
|
||
|
} else {
|
||
|
chunk_buffer = make([]byte, basic_header_size + chunk_data_size)
|
||
|
write_basic_header(&chunk_buffer, 3, csid)
|
||
|
header_size = basic_header_size
|
||
|
}
|
||
|
write_chunk_data(&chunk_buffer, msg_ptr.data, &i, chunk_data_size, header_size)
|
||
|
if _, err := conn.Write(chunk_buffer); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
conn.SetDeadline(time.Time{})
|
||
|
|
||
|
return nil
|
||
|
}
|