From 94bd146e77d065a5d28bc3426a89dbc08cd6e03d Mon Sep 17 00:00:00 2001 From: Muaz Ahmad Date: Sun, 13 Aug 2023 14:31:04 +0500 Subject: [PATCH] Basic msg chunking and writing --- rtmp/chunk2.go | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 rtmp/chunk2.go diff --git a/rtmp/chunk2.go b/rtmp/chunk2.go new file mode 100644 index 0000000..99b2b14 --- /dev/null +++ b/rtmp/chunk2.go @@ -0,0 +1,74 @@ +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 +}