Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
3.8 kB · 109 lines
Go
at next
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110package api
import ( "context" "errors" "testing" "time"
"github.com/bluenviron/gortmplib/pkg/h264conf" "github.com/bluenviron/gortmplib/pkg/message" "github.com/bluenviron/gortsplib/v5/pkg/format" "github.com/stretchr/testify/require" "stream.place/streamplace/pkg/media")
func TestH264ConfigMessage(t *testing.T) { sps := []byte{0x67, 0x42, 0xc0, 0x15, 0xda, 0x06, 0xc7, 0xf9} pps := []byte{0x68, 0xce, 0x3c, 0x80} idr := []byte{0x65, 0x88, 0x84} slice := []byte{0x41, 0x9a}
msg, ok := h264ConfigMessage([][]byte{sps, pps}, 40*time.Millisecond) require.True(t, ok) require.EqualValues(t, message.VideoTypeConfig, msg.Type) require.EqualValues(t, message.CodecH264, msg.Codec) require.Equal(t, 40*time.Millisecond, msg.DTS) // it round-trips through the reader's own parsing var conf h264conf.Conf require.NoError(t, conf.Unmarshal(msg.Payload)) require.Equal(t, sps, conf.SPS) require.Equal(t, pps, conf.PPS)
for name, au := range map[string][][]byte{ "keyframe with parameter sets": {sps, pps, idr}, "slice": {slice}, "SPS alone": {sps}, "two SPS": {sps, sps, pps}, "empty NALU": {sps, {}, pps}, "empty AU": nil, } { _, ok := h264ConfigMessage(au, 0) require.False(t, ok, name) }}
// recordingConn is a gortmplib.Conn that keeps what's written to it.type recordingConn struct { msgs []message.Message}
func (c *recordingConn) BytesReceived() uint64 { return 0 }func (c *recordingConn) BytesSent() uint64 { return 0 }func (c *recordingConn) Read() (message.Message, error) { return nil, errors.New("write-only") }func (c *recordingConn) Write(msg message.Message) error { c.msgs = append(c.msgs, msg) return nil}
// What the relay writes for a stream's start as gortmplib's reader hands it// on: the replayed sequence header as an SPS/PPS access unit, then the first// keyframe at the same timestamp. The header has to go out as a sequence// header, not a frame of its own, so the keyframe is the only frame at that// timestamp.func TestRelayRTMPSessionSequenceHeader(t *testing.T) { sps := []byte{0x67, 0x42, 0xc0, 0x15, 0xda, 0x06, 0xc7, 0xf9} pps := []byte{0x68, 0xce, 0x3c, 0x80} idr := []byte{0x65, 0x88, 0x84, 0x00} slice := []byte{0x41, 0x9a, 0x02}
session := &media.RTMPSession{ EventChan: make(chan any, 8), VideoTrack: &format.H264{PayloadTyp: 96, SPS: sps, PPS: pps, PacketizationMode: 1}, } session.EventChan <- &media.RTMPH264Data{AU: [][]byte{sps, pps}} session.EventChan <- &media.RTMPH264Data{AU: [][]byte{idr}} session.EventChan <- &media.RTMPH264Data{AU: [][]byte{slice}, PTS: 33 * time.Millisecond, DTS: 33 * time.Millisecond} close(session.EventChan)
conn := &recordingConn{} err := relayRTMPSession(context.Background(), conn, session) require.ErrorContains(t, err, "session closed")
var video []*message.Video for _, msg := range conn.msgs { if v, ok := msg.(*message.Video); ok { video = append(video, v) } } // the writer's own header for the track, the relayed one, then frames require.Len(t, video, 4) for i, want := range []struct { typ message.VideoType dts time.Duration key bool }{ {message.VideoTypeConfig, 0, true}, {message.VideoTypeConfig, 0, true}, {message.VideoTypeAU, 0, true}, {message.VideoTypeAU, 33 * time.Millisecond, false}, } { require.Equal(t, want.typ, video[i].Type, "message %d", i) require.Equal(t, want.dts, video[i].DTS, "message %d", i) require.Equal(t, want.key, video[i].IsKeyFrame, "message %d", i) } var conf h264conf.Conf require.NoError(t, conf.Unmarshal(video[1].Payload)) require.Equal(t, sps, conf.SPS) require.Equal(t, pps, conf.PPS)}