mirror of
https://github.com/pion/webrtc.git
synced 2025-10-05 15:16:52 +08:00
Add support for RTP header extensions, and IVF videos now fully work!
This commit is contained in:
@@ -9,8 +9,6 @@ import (
|
|||||||
"github.com/pions/webrtc/rtp"
|
"github.com/pions/webrtc/rtp"
|
||||||
)
|
)
|
||||||
|
|
||||||
var le = binary.LittleEndian
|
|
||||||
|
|
||||||
type IVFWriter struct {
|
type IVFWriter struct {
|
||||||
fd *os.File
|
fd *os.File
|
||||||
time time.Time
|
time time.Time
|
||||||
@@ -49,16 +47,16 @@ func NewIVFWriter(fileName string) (*IVFWriter, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
header := make([]byte, 32)
|
header := make([]byte, 32)
|
||||||
copy(header[0:], []byte("DKIF")) // DKIF
|
copy(header[0:], []byte("DKIF")) // DKIF
|
||||||
le.PutUint16(header[4:], 0) // Version
|
binary.LittleEndian.PutUint16(header[4:], 0) // Version
|
||||||
le.PutUint16(header[6:], 32) // Header Size
|
binary.LittleEndian.PutUint16(header[6:], 32) // Header Size
|
||||||
copy(header[8:], []byte("VP80")) // FOURCC
|
copy(header[8:], []byte("VP80")) // FOURCC
|
||||||
le.PutUint16(header[12:], 640) // Version
|
binary.LittleEndian.PutUint16(header[12:], 640) // Version
|
||||||
le.PutUint16(header[14:], 480) // Header Size
|
binary.LittleEndian.PutUint16(header[14:], 480) // Header Size
|
||||||
le.PutUint32(header[16:], 30) // Framerate numerator
|
binary.LittleEndian.PutUint32(header[16:], 30) // Framerate numerator
|
||||||
le.PutUint32(header[20:], 1) // Framerate Denominator
|
binary.LittleEndian.PutUint32(header[20:], 1) // Framerate Denominator
|
||||||
le.PutUint32(header[24:], 900) // Frame count
|
binary.LittleEndian.PutUint32(header[24:], 900) // Frame count
|
||||||
le.PutUint32(header[28:], 0) // Unused
|
binary.LittleEndian.PutUint32(header[28:], 0) // Unused
|
||||||
|
|
||||||
panicWrite(f, header)
|
panicWrite(f, header)
|
||||||
|
|
||||||
@@ -103,7 +101,6 @@ func (i *IVFWriter) DecodeVP8RTPPacket(packet *rtp.Packet) (*VP8RTPPacket, error
|
|||||||
payloadIndex++
|
payloadIndex++
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Print(vp8Packet)
|
|
||||||
vp8Packet.Payload = p[payloadIndex:]
|
vp8Packet.Payload = p[payloadIndex:]
|
||||||
|
|
||||||
return vp8Packet, nil
|
return vp8Packet, nil
|
||||||
@@ -123,9 +120,8 @@ func (i *IVFWriter) AddPacket(packet *rtp.Packet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
frameHeader := make([]byte, 12)
|
frameHeader := make([]byte, 12)
|
||||||
|
binary.LittleEndian.PutUint32(frameHeader[0:], uint32(len(i.currentFrame))) // Frame length
|
||||||
le.PutUint32(frameHeader[0:], uint32(len(i.currentFrame))) // Frame length
|
binary.LittleEndian.PutUint64(frameHeader[4:], i.count) // PTS
|
||||||
le.PutUint64(frameHeader[4:], i.count) // PTS
|
|
||||||
|
|
||||||
i.count += 1
|
i.count += 1
|
||||||
|
|
||||||
|
@@ -14,23 +14,26 @@ type Packet struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
headerLength = 4
|
headerLength = 4
|
||||||
versionShift = 6
|
versionShift = 6
|
||||||
versionMask = 0x3
|
versionMask = 0x3
|
||||||
paddingShift = 5
|
paddingShift = 5
|
||||||
paddingMask = 0x1
|
paddingMask = 0x1
|
||||||
extensionShift = 4
|
extensionShift = 4
|
||||||
extensionMask = 0x1
|
extensionMask = 0x1
|
||||||
ccMask = 0xF
|
ccMask = 0xF
|
||||||
markerShift = 7
|
markerShift = 7
|
||||||
markerMask = 0x1
|
markerMask = 0x1
|
||||||
ptMask = 0x7F
|
ptMask = 0x7F
|
||||||
seqNumOffset = 2
|
seqNumOffset = 2
|
||||||
seqNumLength = 2
|
seqNumLength = 2
|
||||||
timestampOffset = 4
|
timestampOffset = 4
|
||||||
timestampLength = 4
|
timestampLength = 4
|
||||||
ssrcOffset = 8
|
ssrcOffset = 8
|
||||||
ssrcLength = 4
|
ssrcLength = 4
|
||||||
csrcOffset = 12
|
csrcOffset = 12
|
||||||
csrcLength = 4
|
csrcLength = 4
|
||||||
|
extensionHeaderIdLength = 2
|
||||||
|
extensionLengthFieldLength = 2
|
||||||
|
extensionHeaderAssumedLength = 4
|
||||||
)
|
)
|
||||||
|
@@ -2,6 +2,7 @@ package rtp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -37,9 +38,9 @@ func (p *Packet) Unmarshal(rawPacket []byte) error {
|
|||||||
p.Timestamp = binary.BigEndian.Uint32(rawPacket[timestampOffset : timestampOffset+timestampLength])
|
p.Timestamp = binary.BigEndian.Uint32(rawPacket[timestampOffset : timestampOffset+timestampLength])
|
||||||
p.SSRC = binary.BigEndian.Uint32(rawPacket[ssrcOffset : ssrcOffset+ssrcLength])
|
p.SSRC = binary.BigEndian.Uint32(rawPacket[ssrcOffset : ssrcOffset+ssrcLength])
|
||||||
|
|
||||||
headerPlusCsrcs := headerLength + timestampLength + ssrcLength + (len(p.CSRC) * csrcLength)
|
currOffset := headerLength + timestampLength + ssrcLength + (len(p.CSRC) * csrcLength)
|
||||||
if len(rawPacket) < headerPlusCsrcs {
|
if len(rawPacket) < currOffset {
|
||||||
return errors.Errorf("RTP header size insufficient; %d < %d", len(rawPacket), headerPlusCsrcs)
|
return errors.Errorf("RTP header size insufficient; %d < %d", len(rawPacket), currOffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range p.CSRC {
|
for i := range p.CSRC {
|
||||||
@@ -47,7 +48,15 @@ func (p *Packet) Unmarshal(rawPacket []byte) error {
|
|||||||
p.CSRC[i] = binary.BigEndian.Uint32(rawPacket[offset:offset])
|
p.CSRC[i] = binary.BigEndian.Uint32(rawPacket[offset:offset])
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Payload = rawPacket[headerPlusCsrcs:]
|
if p.Extension {
|
||||||
|
currOffset += extensionHeaderIdLength
|
||||||
|
extensionLength := binary.BigEndian.Uint16(rawPacket[currOffset:])
|
||||||
|
currOffset += extensionLengthFieldLength
|
||||||
|
|
||||||
|
currOffset += (int(extensionLength) * extensionHeaderAssumedLength)
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Payload = rawPacket[currOffset:]
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user