snapshot of https://github.com/pion/webrtc.git (main, 2026-09-15; blobs > 131072B omitted)
Some checks failed
REUSE Compliance Check / lint (push) Failing after 0s
Browser E2E / Test (push) Failing after 3s
Test / test (1.24) (push) Failing after 0s
Test / test-i386 (1.25) (push) Failing after 0s
Test / test-i386 (1.24) (push) Failing after 0s
Test / test-windows (1.25) (push) Failing after 0s
Test / test-windows (1.24) (push) Failing after 0s
Test / test (1.25) (push) Failing after 0s
Examples Tests / Test (push) Failing after 3s
Test / test-macos (1.25) (push) Failing after 0s
Test / test-macos (1.24) (push) Failing after 0s
Go mod tidy / tidy (push) Failing after 0s
Test / test-wasm (push) Failing after 0s
CodeQL / analyze (push) Failing after 1s
Fuzz / fuzz (push) Failing after 0s

This commit is contained in:
upstream-mirror
2026-09-15 20:06:07 +05:00
commit 8acb1a3a29
394 changed files with 78746 additions and 0 deletions

View File

@@ -0,0 +1,108 @@
// SPDX-FileCopyrightText: 2026 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT
// Package h264writer implements H264 media container writer
package h264writer
import (
"bytes"
"encoding/binary"
"io"
"os"
"github.com/pion/rtp"
"github.com/pion/rtp/codecs"
)
type (
// H264Writer is used to take RTP packets, parse them and
// write the data to an io.Writer.
// Currently it only supports non-interleaved mode
// Therefore, only 1-23, 24 (STAP-A), 28 (FU-A) NAL types are allowed.
// https://tools.ietf.org/html/rfc6184#section-5.2
H264Writer struct {
writer io.Writer
hasKeyFrame bool
cachedPacket *codecs.H264Packet
}
)
// New builds a new H264 writer.
func New(filename string) (*H264Writer, error) {
f, err := os.Create(filename) //nolint:gosec
if err != nil {
return nil, err
}
return NewWith(f), nil
}
// NewWith initializes a new H264 writer with an io.Writer output.
func NewWith(w io.Writer) *H264Writer {
return &H264Writer{
writer: w,
}
}
// WriteRTP adds a new packet and writes the appropriate headers for it.
func (h *H264Writer) WriteRTP(packet *rtp.Packet) error {
if len(packet.Payload) == 0 {
return nil
}
if !h.hasKeyFrame {
if h.hasKeyFrame = isKeyFrame(packet.Payload); !h.hasKeyFrame {
// key frame not defined yet. discarding packet
return nil
}
}
if h.cachedPacket == nil {
h.cachedPacket = &codecs.H264Packet{}
}
data, err := h.cachedPacket.Unmarshal(packet.Payload)
if err != nil || len(data) == 0 {
return err
}
_, err = h.writer.Write(data)
return err
}
// Close closes the underlying writer.
func (h *H264Writer) Close() error {
h.cachedPacket = nil
if h.writer != nil {
if closer, ok := h.writer.(io.Closer); ok {
return closer.Close()
}
}
return nil
}
func isKeyFrame(data []byte) bool {
const (
typeSTAPA = 24
typeSPS = 7
naluTypeBitmask = 0x1F
)
var word uint32
payload := bytes.NewReader(data)
if err := binary.Read(payload, binary.BigEndian, &word); err != nil {
return false
}
naluType := (word >> 24) & naluTypeBitmask
if naluType == typeSTAPA && word&naluTypeBitmask == typeSPS {
return true
} else if naluType == typeSPS {
return true
}
return false
}

View File

@@ -0,0 +1,190 @@
// SPDX-FileCopyrightText: 2026 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT
package h264writer
import (
"bytes"
"errors"
"testing"
"github.com/pion/rtp"
"github.com/stretchr/testify/assert"
)
type writerCloser struct {
bytes.Buffer
}
var errClose = errors.New("close error")
func (w *writerCloser) Close() error {
return errClose
}
func TestNewWith(t *testing.T) {
writer := &writerCloser{}
h264Writer := NewWith(writer)
assert.NotNil(t, h264Writer.Close())
}
func TestIsKeyFrame(t *testing.T) {
tests := []struct {
name string
payload []byte
want bool
}{
{
"When given a non-keyframe; it should return false",
[]byte{0x27, 0x90, 0x90},
false,
},
{
"When given a SPS packetized with STAP-A; it should return true",
[]byte{0x38, 0x00, 0x03, 0x27, 0x90, 0x90, 0x00, 0x05, 0x28, 0x90, 0x90, 0x90, 0x90},
true,
},
{
"When given a SPS with no packetization; it should return true",
[]byte{0x27, 0x90, 0x90, 0x00},
true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := isKeyFrame(tt.payload)
assert.Equal(t, tt.want, got)
})
}
}
func TestWriteRTP(t *testing.T) {
tests := []struct {
name string
payload []byte
hasKeyFrame bool
wantBytes []byte
wantErr error
reuseWriter bool
}{
{
"When given an empty payload; it should return nil",
[]byte{},
false,
[]byte{},
nil,
false,
},
{
"When no keyframe is defined; it should discard the packet",
[]byte{0x25, 0x90, 0x90},
false,
[]byte{},
nil,
false,
},
{
"When a valid Single NAL Unit packet is given; it should unpack it without error",
[]byte{0x27, 0x90, 0x90},
true,
[]byte{0x00, 0x00, 0x00, 0x01, 0x27, 0x90, 0x90},
nil,
false,
},
{
"When a valid STAP-A packet is given; it should unpack it without error",
[]byte{0x38, 0x00, 0x03, 0x27, 0x90, 0x90, 0x00, 0x05, 0x28, 0x90, 0x90, 0x90, 0x90},
true,
[]byte{0x00, 0x00, 0x00, 0x01, 0x27, 0x90, 0x90, 0x00, 0x00, 0x00, 0x01, 0x28, 0x90, 0x90, 0x90, 0x90},
nil,
false,
},
{
"When a valid FU-A start packet is given; it should unpack it without error",
[]byte{0x3C, 0x85, 0x90, 0x90, 0x90},
true,
[]byte{},
nil,
true,
},
{
"When a valid FU-A end packet is given; it should unpack it without error",
[]byte{0x3C, 0x45, 0x90, 0x90, 0x90},
true,
[]byte{0x00, 0x00, 0x00, 0x01, 0x25, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90},
nil,
false,
},
}
var reuseWriter *bytes.Buffer
var reuseH264Writer *H264Writer
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
writer := &bytes.Buffer{}
h264Writer := &H264Writer{
hasKeyFrame: tt.hasKeyFrame,
writer: writer,
}
if reuseWriter != nil {
writer = reuseWriter
}
if reuseH264Writer != nil {
h264Writer = reuseH264Writer
}
assert.Equal(t, tt.wantErr, h264Writer.WriteRTP(&rtp.Packet{
Payload: tt.payload,
}))
assert.True(t, bytes.Equal(tt.wantBytes, writer.Bytes()))
if !tt.reuseWriter {
assert.Nil(t, h264Writer.Close())
reuseWriter = nil
reuseH264Writer = nil
} else {
reuseWriter = writer
reuseH264Writer = h264Writer
}
})
}
}
type writerCounter struct {
writeCount int
}
func (w *writerCounter) Write([]byte) (int, error) {
w.writeCount++
return 0, nil
}
func (w *writerCounter) Close() error {
return nil
}
func TestNoZeroWrite(t *testing.T) {
payloads := [][]byte{
{0x1c, 0x80, 0x01, 0x02, 0x03},
{0x1c, 0x00, 0x04, 0x05, 0x06},
{0x1c, 0x00, 0x07, 0x08, 0x09},
{0x1c, 0x00, 0x10, 0x11, 0x12},
{0x1c, 0x40, 0x13, 0x14, 0x15},
}
writer := &writerCounter{}
h264Writer := &H264Writer{
hasKeyFrame: true,
writer: writer,
}
for i := range payloads {
assert.NoError(t, h264Writer.WriteRTP(&rtp.Packet{
Payload: payloads[i],
}))
}
assert.Equal(t, 1, writer.writeCount)
}