rtmp: add Chunk2

This commit is contained in:
aler9 2022-05-14 00:11:01 +02:00
parent 420b6b21c4
commit d1c6c56077
3 changed files with 88 additions and 10 deletions

View File

@ -11,16 +11,20 @@ import (
// formats) SHOULD use this format for the first chunk of each new
// message after the first.
type Chunk1 struct {
ChunkStreamID byte
Type MessageType
BodyLen uint32
Body []byte
ChunkStreamID byte
TimestampDelta uint32
Type MessageType
BodyLen uint32
Body []byte
}
// Write writes the chunk.
func (c Chunk1) Write(w io.Writer) error {
header := make([]byte, 8)
header[0] = 1<<6 | c.ChunkStreamID
header[1] = byte(c.TimestampDelta >> 16)
header[2] = byte(c.TimestampDelta >> 8)
header[3] = byte(c.TimestampDelta)
header[4] = byte(c.BodyLen >> 16)
header[5] = byte(c.BodyLen >> 8)
header[6] = byte(c.BodyLen)

View File

@ -0,0 +1,31 @@
package base
import (
"io"
)
// Chunk2 is a type 2 chunk.
// Neither the stream ID nor the
// message length is included; this chunk has the same stream ID and
// message length as the preceding chunk.
type Chunk2 struct {
ChunkStreamID byte
TimestampDelta uint32
Body []byte
}
// Write writes the chunk.
func (c Chunk2) Write(w io.Writer) error {
header := make([]byte, 4)
header[0] = 1<<6 | c.ChunkStreamID
header[1] = byte(c.TimestampDelta >> 16)
header[2] = byte(c.TimestampDelta >> 8)
header[3] = byte(c.TimestampDelta)
_, err := w.Write(header)
if err != nil {
return err
}
_, err = w.Write(c.Body)
return err
}

View File

@ -7,6 +7,10 @@ import (
type messageWriterChunkStream struct {
mw *MessageWriter
lastMessageStreamID *uint32
lastType *MessageType
lastBodyLen *int
lastTimestamp *uint32
lastTimestampDelta *uint32
}
func (wc *messageWriterChunkStream) write(msg *Message) error {
@ -14,6 +18,12 @@ func (wc *messageWriterChunkStream) write(msg *Message) error {
pos := 0
firstChunk := true
var timestampDelta *uint32
if wc.lastTimestamp != nil {
v := msg.Timestamp - *wc.lastTimestamp
timestampDelta = &v
}
for {
chunkBodyLen := bodyLen - pos
if chunkBodyLen > wc.mw.chunkSize {
@ -23,7 +33,8 @@ func (wc *messageWriterChunkStream) write(msg *Message) error {
if firstChunk {
firstChunk = false
if wc.lastMessageStreamID == nil || *wc.lastMessageStreamID != msg.MessageStreamID {
switch {
case wc.lastMessageStreamID == nil || *wc.lastMessageStreamID != msg.MessageStreamID:
err := Chunk0{
ChunkStreamID: msg.ChunkStreamID,
Type: msg.Type,
@ -35,19 +46,51 @@ func (wc *messageWriterChunkStream) write(msg *Message) error {
return err
}
v := msg.MessageStreamID
wc.lastMessageStreamID = &v
} else {
case wc.lastTimestampDelta == nil || *wc.lastType != msg.Type || *wc.lastBodyLen != bodyLen:
err := Chunk1{
ChunkStreamID: msg.ChunkStreamID,
TimestampDelta: *timestampDelta,
Type: msg.Type,
BodyLen: uint32(bodyLen),
Body: msg.Body[pos : pos+chunkBodyLen],
}.Write(wc.mw.w)
if err != nil {
return err
}
case *wc.lastTimestampDelta != *timestampDelta:
err := Chunk2{
ChunkStreamID: msg.ChunkStreamID,
TimestampDelta: *timestampDelta,
Body: msg.Body[pos : pos+chunkBodyLen],
}.Write(wc.mw.w)
if err != nil {
return err
}
default:
err := Chunk3{
ChunkStreamID: msg.ChunkStreamID,
Type: msg.Type,
BodyLen: uint32(bodyLen),
Body: msg.Body[pos : pos+chunkBodyLen],
}.Write(wc.mw.w)
if err != nil {
return err
}
}
v1 := msg.MessageStreamID
wc.lastMessageStreamID = &v1
v2 := msg.Type
wc.lastType = &v2
v3 := bodyLen
wc.lastBodyLen = &v3
v4 := msg.Timestamp
wc.lastTimestamp = &v4
if timestampDelta != nil {
v5 := *timestampDelta
wc.lastTimestampDelta = &v5
}
} else {
err := Chunk3{
ChunkStreamID: msg.ChunkStreamID,