mirror of
https://github.com/bluenviron/mediamtx
synced 2024-12-12 18:00:12 +00:00
rtmp: add Chunk2
This commit is contained in:
parent
420b6b21c4
commit
d1c6c56077
@ -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)
|
||||
|
31
internal/rtmp/base/chunk2.go
Normal file
31
internal/rtmp/base/chunk2.go
Normal 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
|
||||
}
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user