diff --git a/trunk/3rdparty/srs-bench/blackbox/rtsp_test.go b/trunk/3rdparty/srs-bench/blackbox/rtsp_test.go
index 62dcdbe1e..e1480c055 100644
--- a/trunk/3rdparty/srs-bench/blackbox/rtsp_test.go
+++ b/trunk/3rdparty/srs-bench/blackbox/rtsp_test.go
@@ -109,7 +109,8 @@ func TestFast_RtmpPublish_RtspPlay_Basic(t *testing.T) {
r3 = errors.Errorf("invalid streams=%v, %v, %v", len(m.Streams), m.String(), str)
}
- if ts := 90; m.Format.ProbeScore < ts {
+ // Note that RTSP score might be lower than RTMP, so we use a lower threshold
+ if ts := 80; m.Format.ProbeScore < ts {
r4 = errors.Errorf("low score=%v < %v, %v, %v", m.Format.ProbeScore, ts, m.String(), str)
}
if dv := m.Duration(); dv < duration {
@@ -117,3 +118,296 @@ func TestFast_RtmpPublish_RtspPlay_Basic(t *testing.T) {
}
}
}
+
+func TestFast_RtmpPublish_RtspPlay_MultipleClients(t *testing.T) {
+ // This case is run in parallel.
+ t.Parallel()
+
+ // Setup the max timeout for this case.
+ ctx, cancel := context.WithTimeout(logger.WithContext(context.Background()), time.Duration(*srsTimeout)*time.Millisecond)
+ defer cancel()
+
+ // Check a set of errors.
+ var r0, r1, r2, r3, r4, r5, r6, r7, r8, r9 error
+ defer func(ctx context.Context) {
+ if err := filterTestError(ctx.Err(), r0, r1, r2, r3, r4, r5, r6, r7, r8, r9); err != nil {
+ t.Errorf("Fail for err %+v", err)
+ } else {
+ logger.Tf(ctx, "test done with err %+v", err)
+ }
+ }(ctx)
+
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ // Start SRS server and wait for it to be ready.
+ svr := NewSRSServer(func(v *srsServer) {
+ v.envs = []string{
+ "SRS_RTSP_SERVER_ENABLED=on",
+ "SRS_VHOST_RTSP_ENABLED=on",
+ "SRS_VHOST_RTSP_RTMP_TO_RTSP=on",
+ }
+ })
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ r0 = svr.Run(ctx, cancel)
+ }()
+
+ // Start FFmpeg to publish stream.
+ streamID := fmt.Sprintf("stream-%v-%v", os.Getpid(), rand.Int())
+ streamURL := fmt.Sprintf("rtmp://localhost:%v/live/%v", svr.RTMPPort(), streamID)
+ ffmpeg := NewFFmpeg(func(v *ffmpegClient) {
+ v.args = []string{
+ "-stream_loop", "-1", "-re", "-i", *srsPublishAvatar, "-c", "copy", "-f", "flv", streamURL,
+ }
+ })
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ <-svr.ReadyCtx().Done()
+ r1 = ffmpeg.Run(ctx, cancel)
+ }()
+
+ // Start multiple FFprobe clients to test concurrent RTSP playback.
+ duration := time.Duration(*srsFFprobeDuration) * time.Millisecond
+ rtspURL := fmt.Sprintf("rtsp://localhost:%v/live/%v", svr.RTSPPort(), streamID)
+
+ // First RTSP client
+ ffprobe1 := NewFFprobe(func(v *ffprobeClient) {
+ v.dvrFile = path.Join(svr.WorkDir(), "objs", fmt.Sprintf("srs-ffprobe1-%v.mp4", streamID))
+ v.streamURL = rtspURL
+ v.duration, v.timeout = duration, time.Duration(*srsFFprobeTimeout)*time.Millisecond
+ })
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ <-svr.ReadyCtx().Done()
+ r2 = ffprobe1.Run(ctx, cancel)
+ }()
+
+ // Second RTSP client
+ ffprobe2 := NewFFprobe(func(v *ffprobeClient) {
+ v.dvrFile = path.Join(svr.WorkDir(), "objs", fmt.Sprintf("srs-ffprobe2-%v.mp4", streamID))
+ v.streamURL = rtspURL
+ v.duration, v.timeout = duration, time.Duration(*srsFFprobeTimeout)*time.Millisecond
+ })
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ <-svr.ReadyCtx().Done()
+ r3 = ffprobe2.Run(ctx, cancel)
+ }()
+
+ // Wait for both probes to complete and verify results.
+ var probe1Done, probe2Done bool
+ for !probe1Done || !probe2Done {
+ select {
+ case <-ctx.Done():
+ return
+ case <-ffprobe1.ProbeDoneCtx().Done():
+ if !probe1Done {
+ probe1Done = true
+ str, m := ffprobe1.Result()
+ if len(m.Streams) != 2 {
+ r4 = errors.Errorf("client1: invalid streams=%v, %v, %v", len(m.Streams), m.String(), str)
+ }
+ if ts := 80; m.Format.ProbeScore < ts {
+ r5 = errors.Errorf("client1: low score=%v < %v, %v, %v", m.Format.ProbeScore, ts, m.String(), str)
+ }
+ if dv := m.Duration(); dv < duration {
+ r6 = errors.Errorf("client1: short duration=%v < %v, %v, %v", dv, duration, m.String(), str)
+ }
+ }
+ case <-ffprobe2.ProbeDoneCtx().Done():
+ if !probe2Done {
+ probe2Done = true
+ str, m := ffprobe2.Result()
+ if len(m.Streams) != 2 {
+ r7 = errors.Errorf("client2: invalid streams=%v, %v, %v", len(m.Streams), m.String(), str)
+ }
+ if ts := 80; m.Format.ProbeScore < ts {
+ r8 = errors.Errorf("client2: low score=%v < %v, %v, %v", m.Format.ProbeScore, ts, m.String(), str)
+ }
+ if dv := m.Duration(); dv < duration {
+ r9 = errors.Errorf("client2: short duration=%v < %v, %v, %v", dv, duration, m.String(), str)
+ }
+ }
+ }
+ }
+ defer cancel()
+}
+
+func TestFast_RtmpPublish_RtspPlay_CustomPort(t *testing.T) {
+ // This case is run in parallel.
+ t.Parallel()
+
+ // Setup the max timeout for this case.
+ ctx, cancel := context.WithTimeout(logger.WithContext(context.Background()), time.Duration(*srsTimeout)*time.Millisecond)
+ defer cancel()
+
+ // Check a set of errors.
+ var r0, r1, r2, r3, r4, r5 error
+ defer func(ctx context.Context) {
+ if err := filterTestError(ctx.Err(), r0, r1, r2, r3, r4, r5); err != nil {
+ t.Errorf("Fail for err %+v", err)
+ } else {
+ logger.Tf(ctx, "test done with err %+v", err)
+ }
+ }(ctx)
+
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ // Start SRS server with custom RTSP port.
+ customRTSPPort := 15540 + rand.Intn(1000)
+ svr := NewSRSServer(func(v *srsServer) {
+ v.envs = []string{
+ "SRS_RTSP_SERVER_ENABLED=on",
+ "SRS_VHOST_RTSP_ENABLED=on",
+ "SRS_VHOST_RTSP_RTMP_TO_RTSP=on",
+ fmt.Sprintf("SRS_RTSP_SERVER_LISTEN=%d", customRTSPPort),
+ }
+ })
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ r0 = svr.Run(ctx, cancel)
+ }()
+
+ // Start FFmpeg to publish stream.
+ streamID := fmt.Sprintf("stream-%v-%v", os.Getpid(), rand.Int())
+ streamURL := fmt.Sprintf("rtmp://localhost:%v/live/%v", svr.RTMPPort(), streamID)
+ ffmpeg := NewFFmpeg(func(v *ffmpegClient) {
+ v.args = []string{
+ "-stream_loop", "-1", "-re", "-i", *srsPublishAvatar, "-c", "copy", "-f", "flv", streamURL,
+ }
+ })
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ <-svr.ReadyCtx().Done()
+ r1 = ffmpeg.Run(ctx, cancel)
+ }()
+
+ // Start FFprobe to detect and verify stream on custom port.
+ duration := time.Duration(*srsFFprobeDuration) * time.Millisecond
+ ffprobe := NewFFprobe(func(v *ffprobeClient) {
+ v.dvrFile = path.Join(svr.WorkDir(), "objs", fmt.Sprintf("srs-ffprobe-%v.mp4", streamID))
+ v.streamURL = fmt.Sprintf("rtsp://localhost:%v/live/%v", customRTSPPort, streamID)
+ v.duration, v.timeout = duration, time.Duration(*srsFFprobeTimeout)*time.Millisecond
+ })
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ <-svr.ReadyCtx().Done()
+ r2 = ffprobe.Run(ctx, cancel)
+ }()
+
+ // Fast quit for probe done.
+ select {
+ case <-ctx.Done():
+ case <-ffprobe.ProbeDoneCtx().Done():
+ defer cancel()
+
+ str, m := ffprobe.Result()
+ if len(m.Streams) != 2 {
+ r3 = errors.Errorf("invalid streams=%v, %v, %v", len(m.Streams), m.String(), str)
+ }
+
+ // Note that RTSP score might be lower than RTMP, so we use a lower threshold
+ if ts := 80; m.Format.ProbeScore < ts {
+ r4 = errors.Errorf("low score=%v < %v, %v, %v", m.Format.ProbeScore, ts, m.String(), str)
+ }
+ if dv := m.Duration(); dv < duration {
+ r5 = errors.Errorf("short duration=%v < %v, %v, %v", dv, duration, m.String(), str)
+ }
+ }
+}
+
+func TestFast_RtmpPublish_RtspPlay_AudioOnly(t *testing.T) {
+ // This case is run in parallel.
+ t.Parallel()
+
+ // Setup the max timeout for this case.
+ ctx, cancel := context.WithTimeout(logger.WithContext(context.Background()), time.Duration(*srsTimeout)*time.Millisecond)
+ defer cancel()
+
+ // Check a set of errors.
+ var r0, r1, r2, r3, r4, r5 error
+ defer func(ctx context.Context) {
+ if err := filterTestError(ctx.Err(), r0, r1, r2, r3, r4, r5); err != nil {
+ t.Errorf("Fail for err %+v", err)
+ } else {
+ logger.Tf(ctx, "test done with err %+v", err)
+ }
+ }(ctx)
+
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ // Start SRS server and wait for it to be ready.
+ svr := NewSRSServer(func(v *srsServer) {
+ v.envs = []string{
+ "SRS_RTSP_SERVER_ENABLED=on",
+ "SRS_VHOST_RTSP_ENABLED=on",
+ "SRS_VHOST_RTSP_RTMP_TO_RTSP=on",
+ }
+ })
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ r0 = svr.Run(ctx, cancel)
+ }()
+
+ // Start FFmpeg to publish audio-only stream.
+ streamID := fmt.Sprintf("stream-%v-%v", os.Getpid(), rand.Int())
+ streamURL := fmt.Sprintf("rtmp://localhost:%v/live/%v", svr.RTMPPort(), streamID)
+ ffmpeg := NewFFmpeg(func(v *ffmpegClient) {
+ v.args = []string{
+ "-stream_loop", "-1", "-re", "-i", *srsPublishAvatar, "-vn", "-c:a", "copy", "-f", "flv", streamURL,
+ }
+ })
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ <-svr.ReadyCtx().Done()
+ r1 = ffmpeg.Run(ctx, cancel)
+ }()
+
+ // Start FFprobe to detect and verify audio-only stream.
+ duration := time.Duration(*srsFFprobeDuration) * time.Millisecond
+ ffprobe := NewFFprobe(func(v *ffprobeClient) {
+ v.dvrFile = path.Join(svr.WorkDir(), "objs", fmt.Sprintf("srs-ffprobe-%v.mp4", streamID))
+ v.streamURL = fmt.Sprintf("rtsp://localhost:%v/live/%v", svr.RTSPPort(), streamID)
+ v.duration, v.timeout = duration, time.Duration(*srsFFprobeTimeout)*time.Millisecond
+ })
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ <-svr.ReadyCtx().Done()
+ r2 = ffprobe.Run(ctx, cancel)
+ }()
+
+ // Fast quit for probe done.
+ select {
+ case <-ctx.Done():
+ case <-ffprobe.ProbeDoneCtx().Done():
+ defer cancel()
+
+ str, m := ffprobe.Result()
+ // Audio-only stream should have 1 stream
+ if len(m.Streams) != 1 {
+ r3 = errors.Errorf("invalid streams=%v, expected 1 for audio-only, %v, %v", len(m.Streams), m.String(), str)
+ }
+
+ // Check if it's audio stream
+ if len(m.Streams) > 0 && m.Streams[0].CodecType != "audio" {
+ r4 = errors.Errorf("expected audio stream, got %v, %v, %v", m.Streams[0].CodecType, m.String(), str)
+ }
+
+ if dv := m.Duration(); dv < duration {
+ r5 = errors.Errorf("short duration=%v < %v, %v, %v", dv, duration, m.String(), str)
+ }
+ }
+}
\ No newline at end of file
diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md
index a1d216280..1add26045 100644
--- a/trunk/doc/CHANGELOG.md
+++ b/trunk/doc/CHANGELOG.md
@@ -7,6 +7,7 @@ The changelog for SRS.
## SRS 7.0 Changelog
+* v7.0, 2025-09-21, Merge [#4505](https://github.com/ossrs/srs/pull/4505): improve blackbox test for rtsp. v7.0.93 (#4505)
* v7.0, 2025-09-21, Fix WHIP with transcoding bug. v7.0.92 (#4495)
* v7.0, 2025-09-20, Merge [#4504](https://github.com/ossrs/srs/pull/4504): fix rtsp compiling warning. v7.0.91 (#4504)
* v7.0, 2025-09-19, Merge [#4503](https://github.com/ossrs/srs/pull/4503): AI: Refine RTMP/SRT/RTC bridge. v7.0.90 (#4503)
diff --git a/trunk/src/core/srs_core_version7.hpp b/trunk/src/core/srs_core_version7.hpp
index 1ad45ef8e..5e0b34ce7 100644
--- a/trunk/src/core/srs_core_version7.hpp
+++ b/trunk/src/core/srs_core_version7.hpp
@@ -9,6 +9,6 @@
#define VERSION_MAJOR 7
#define VERSION_MINOR 0
-#define VERSION_REVISION 92
+#define VERSION_REVISION 93
#endif
\ No newline at end of file
diff --git a/trunk/src/utest/srs_utest_app3.cpp b/trunk/src/utest/srs_utest_app3.cpp
index 982bb5484..8d5509c5c 100644
--- a/trunk/src/utest/srs_utest_app3.cpp
+++ b/trunk/src/utest/srs_utest_app3.cpp
@@ -1287,13 +1287,13 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_FilterSEIFiltering)
// Create SEI NALU sample
uint8_t sei_data[] = {0x06, 0x01, 0x02, 0x03}; // SEI NALU type (6)
- SrsNaluSample sei_sample((char*)sei_data, sizeof(sei_data));
+ SrsNaluSample sei_sample((char *)sei_data, sizeof(sei_data));
format.video_->samples_[0] = sei_sample;
format.video_->nb_samples_ = 1;
SrsMediaPacket msg;
bool has_idr = false;
- std::vector samples;
+ std::vector samples;
// When keep_avc_nalu_sei_ = true, SEI should be kept
HELPER_EXPECT_SUCCESS(builder.filter(&msg, &format, has_idr, samples));
@@ -1309,7 +1309,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_FilterSEIFiltering)
// Test 3: Non-SEI NALU with SEI filtering enabled
uint8_t idr_data[] = {0x05, 0x01, 0x02, 0x03}; // IDR NALU type (5)
- SrsNaluSample idr_sample((char*)idr_data, sizeof(idr_data));
+ SrsNaluSample idr_sample((char *)idr_data, sizeof(idr_data));
format.video_->samples_[0] = idr_sample;
samples.clear();
@@ -1319,9 +1319,9 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_FilterSEIFiltering)
// Test 4: Mixed SEI and non-SEI NALUs
SrsNaluSample mixed_samples[3];
- mixed_samples[0] = sei_sample; // SEI (should be filtered)
- mixed_samples[1] = idr_sample; // IDR (should be kept)
- mixed_samples[2] = sei_sample; // SEI (should be filtered)
+ mixed_samples[0] = sei_sample; // SEI (should be filtered)
+ mixed_samples[1] = idr_sample; // IDR (should be kept)
+ mixed_samples[2] = sei_sample; // SEI (should be filtered)
format.video_->samples_[0] = mixed_samples[0];
format.video_->samples_[1] = mixed_samples[1];
@@ -1365,14 +1365,14 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_FilterBFrameFilteringAVC)
SrsMediaPacket msg;
bool has_idr = false;
- std::vector samples;
+ std::vector samples;
// Test 1: B-frame filtering disabled (keep_bframe_ = true)
builder.keep_bframe_ = true;
// Create B-frame NALU sample (NonIDR with B-frame slice type)
uint8_t bframe_data[] = {0x01, 0xA8, 0x00, 0x00}; // NonIDR NALU type (1), slice_type=1 (B)
- SrsNaluSample bframe_sample((char*)bframe_data, sizeof(bframe_data));
+ SrsNaluSample bframe_sample((char *)bframe_data, sizeof(bframe_data));
format.video_->samples_[0] = bframe_sample;
format.video_->nb_samples_ = 1;
@@ -1390,7 +1390,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_FilterBFrameFilteringAVC)
// Test 3: Non-B-frame NALU with B-frame filtering enabled
uint8_t pframe_data[] = {0x01, 0x88, 0x00, 0x00}; // NonIDR NALU type (1), slice_type=0 (P)
- SrsNaluSample pframe_sample((char*)pframe_data, sizeof(pframe_data));
+ SrsNaluSample pframe_sample((char *)pframe_data, sizeof(pframe_data));
format.video_->samples_[0] = pframe_sample;
samples.clear();
@@ -1446,14 +1446,14 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_FilterBFrameFilteringHEVC)
SrsMediaPacket msg;
bool has_idr = false;
- std::vector samples;
+ std::vector samples;
// Test 1: B-frame filtering disabled (keep_bframe_ = true)
builder.keep_bframe_ = true;
// Create HEVC B-frame NALU sample
uint8_t hevc_bframe_data[] = {0x02, 0x01, 0xE0, 0x44}; // HEVC NALU with B-frame slice type
- SrsNaluSample hevc_bframe_sample((char*)hevc_bframe_data, sizeof(hevc_bframe_data));
+ SrsNaluSample hevc_bframe_sample((char *)hevc_bframe_data, sizeof(hevc_bframe_data));
format.video_->samples_[0] = hevc_bframe_sample;
format.video_->nb_samples_ = 1;
@@ -1471,7 +1471,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_FilterBFrameFilteringHEVC)
// Test 3: Non-B-frame HEVC NALU with B-frame filtering enabled
uint8_t hevc_pframe_data[] = {0x02, 0x01, 0xD0, 0x30}; // HEVC NALU with P-frame slice type
- SrsNaluSample hevc_pframe_sample((char*)hevc_pframe_data, sizeof(hevc_pframe_data));
+ SrsNaluSample hevc_pframe_sample((char *)hevc_pframe_data, sizeof(hevc_pframe_data));
format.video_->samples_[0] = hevc_pframe_sample;
samples.clear();
@@ -1481,7 +1481,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_FilterBFrameFilteringHEVC)
// Test 4: HEVC VPS/SPS/PPS NALUs (should not be filtered as B-frames)
uint8_t hevc_vps_data[] = {0x40, 0x01, 0xE0, 0x44}; // VPS NALU
- SrsNaluSample hevc_vps_sample((char*)hevc_vps_data, sizeof(hevc_vps_data));
+ SrsNaluSample hevc_vps_sample((char *)hevc_vps_data, sizeof(hevc_vps_data));
format.video_->samples_[0] = hevc_vps_sample;
samples.clear();
@@ -1522,33 +1522,33 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_FilterCombinedSEIAndBFrameFiltering
SrsMediaPacket msg;
bool has_idr = false;
- std::vector samples;
+ std::vector samples;
// Test complex scenario with multiple NALU types
SrsNaluSample test_samples[6];
// SEI NALU (should be filtered by SEI filter)
uint8_t sei_data[] = {0x06, 0x01, 0x02, 0x03};
- test_samples[0] = SrsNaluSample((char*)sei_data, sizeof(sei_data));
+ test_samples[0] = SrsNaluSample((char *)sei_data, sizeof(sei_data));
// B-frame NALU (should be filtered by B-frame filter)
uint8_t bframe_data[] = {0x01, 0xA8, 0x00, 0x00};
- test_samples[1] = SrsNaluSample((char*)bframe_data, sizeof(bframe_data));
+ test_samples[1] = SrsNaluSample((char *)bframe_data, sizeof(bframe_data));
// P-frame NALU (should be kept)
uint8_t pframe_data[] = {0x01, 0x88, 0x00, 0x00};
- test_samples[2] = SrsNaluSample((char*)pframe_data, sizeof(pframe_data));
+ test_samples[2] = SrsNaluSample((char *)pframe_data, sizeof(pframe_data));
// IDR NALU (should be kept)
uint8_t idr_data[] = {0x05, 0x01, 0x02, 0x03};
- test_samples[3] = SrsNaluSample((char*)idr_data, sizeof(idr_data));
+ test_samples[3] = SrsNaluSample((char *)idr_data, sizeof(idr_data));
// Another SEI NALU (should be filtered by SEI filter)
- test_samples[4] = SrsNaluSample((char*)sei_data, sizeof(sei_data));
+ test_samples[4] = SrsNaluSample((char *)sei_data, sizeof(sei_data));
// SPS NALU (should be kept)
uint8_t sps_data[] = {0x07, 0x01, 0x02, 0x03};
- test_samples[5] = SrsNaluSample((char*)sps_data, sizeof(sps_data));
+ test_samples[5] = SrsNaluSample((char *)sps_data, sizeof(sps_data));
// Set up format with all samples
for (int i = 0; i < 6; i++) {
@@ -1564,9 +1564,12 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_FilterCombinedSEIAndBFrameFiltering
bool found_pframe = false, found_idr = false, found_sps = false;
for (size_t i = 0; i < samples.size(); i++) {
uint8_t nalu_type = samples[i]->bytes_[0] & 0x1F;
- if (nalu_type == 0x01) found_pframe = true; // P-frame
- if (nalu_type == 0x05) found_idr = true; // IDR
- if (nalu_type == 0x07) found_sps = true; // SPS
+ if (nalu_type == 0x01)
+ found_pframe = true; // P-frame
+ if (nalu_type == 0x05)
+ found_idr = true; // IDR
+ if (nalu_type == 0x07)
+ found_sps = true; // SPS
}
EXPECT_TRUE(found_pframe);
EXPECT_TRUE(found_idr);
@@ -1606,12 +1609,12 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_FilterIDRDetection)
SrsMediaPacket msg;
bool has_idr = false;
- std::vector samples;
+ std::vector samples;
// Test 1: No IDR frame
format.video_->has_idr_ = false;
uint8_t pframe_data[] = {0x01, 0x88, 0x00, 0x00};
- SrsNaluSample pframe_sample((char*)pframe_data, sizeof(pframe_data));
+ SrsNaluSample pframe_sample((char *)pframe_data, sizeof(pframe_data));
format.video_->samples_[0] = pframe_sample;
format.video_->nb_samples_ = 1;
@@ -1660,7 +1663,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_FilterErrorHandling)
SrsMediaPacket msg;
bool has_idr = false;
- std::vector samples;
+ std::vector samples;
// Test with empty NALU sample (should cause parse error)
SrsNaluSample empty_sample(NULL, 0);
@@ -1706,13 +1709,13 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_FilterNonAVCCodecSkipsSEIFiltering)
// Create a sample that would be SEI in AVC (0x06), but should be kept for HEVC
uint8_t hevc_data[] = {0x06, 0x01, 0x02, 0x03};
- SrsNaluSample hevc_sample((char*)hevc_data, sizeof(hevc_data));
+ SrsNaluSample hevc_sample((char *)hevc_data, sizeof(hevc_data));
hevc_format.video_->samples_[0] = hevc_sample;
hevc_format.video_->nb_samples_ = 1;
SrsMediaPacket msg;
bool has_idr = false;
- std::vector samples;
+ std::vector samples;
// For HEVC, SEI filtering should be skipped, so sample should be kept
HELPER_EXPECT_SUCCESS(builder.filter(&msg, &hevc_format, has_idr, samples));
@@ -1729,7 +1732,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_FilterNonAVCCodecSkipsSEIFiltering)
unknown_format.video_ = new SrsParsedVideoPacket();
uint8_t unknown_data[] = {0x06, 0x01, 0x02, 0x03};
- SrsNaluSample unknown_sample((char*)unknown_data, sizeof(unknown_data));
+ SrsNaluSample unknown_sample((char *)unknown_data, sizeof(unknown_data));
unknown_format.video_->samples_[0] = unknown_sample;
unknown_format.video_->nb_samples_ = 1;
@@ -1775,7 +1778,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_FilterZeroSamples)
SrsMediaPacket msg;
bool has_idr = false;
- std::vector samples;
+ std::vector samples;
// Should handle zero samples gracefully
HELPER_EXPECT_SUCCESS(builder.filter(&msg, &format, has_idr, samples));
@@ -1811,8 +1814,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoMergeNalusMultipleSamples)
0x17, // keyframe + AVC codec
0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20,
0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
- 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c
- };
+ 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c};
char *h264_data = new char[sizeof(h264_seq_raw)];
memcpy(h264_data, h264_seq_raw, sizeof(h264_seq_raw));
@@ -1831,10 +1833,10 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoMergeNalusMultipleSamples)
// Create H.264 frame with single NALU (known working pattern)
uint8_t h264_frame_raw[] = {
- 0x17, // keyframe + AVC codec
- 0x01, // AVC NALU (not sequence header)
- 0x00, 0x00, 0x00, // composition time
- 0x00, 0x00, 0x00, 0x05, // NALU length (5 bytes)
+ 0x17, // keyframe + AVC codec
+ 0x01, // AVC NALU (not sequence header)
+ 0x00, 0x00, 0x00, // composition time
+ 0x00, 0x00, 0x00, 0x05, // NALU length (5 bytes)
0x65, 0x88, 0x84, 0x00, (uint8_t)(0x10 + i) // IDR slice data (vary last byte)
};
@@ -1885,8 +1887,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoLargeNaluPackageFuA)
0x17, // keyframe + AVC codec
0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20,
0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
- 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c
- };
+ 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c};
char *h264_data = new char[sizeof(h264_seq_raw)];
memcpy(h264_data, h264_seq_raw, sizeof(h264_seq_raw));
@@ -1971,8 +1972,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoExtremelyLargeNaluPackageFuA
0x17, // keyframe + AVC codec
0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20,
0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
- 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c
- };
+ 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c};
char *h264_data = new char[sizeof(h264_seq_raw)];
memcpy(h264_data, h264_seq_raw, sizeof(h264_seq_raw));
@@ -2052,8 +2052,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoMergeNalusWithMultipleNalus)
0x17, // keyframe + AVC codec
0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20,
0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
- 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c
- };
+ 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c};
char *h264_data = new char[sizeof(h264_seq_raw)];
memcpy(h264_data, h264_seq_raw, sizeof(h264_seq_raw));
@@ -2070,17 +2069,17 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoMergeNalusWithMultipleNalus)
// Create frame with multiple small NALUs - use minimal valid NALU structure
// Total frame: 5 (header) + 4+3 (first NALU) + 4+3 (second NALU) = 19 bytes
uint8_t h264_idr_raw[] = {
- 0x17, // keyframe + AVC codec
- 0x01, // AVC NALU (not sequence header)
+ 0x17, // keyframe + AVC codec
+ 0x01, // AVC NALU (not sequence header)
0x00, 0x00, 0x00, // composition time
// First NALU: 3 bytes of data
0x00, 0x00, 0x00, 0x03, // NALU length (3 bytes)
- 0x65, 0x88, 0x84, // Minimal IDR slice
+ 0x65, 0x88, 0x84, // Minimal IDR slice
// Second NALU: 3 bytes of data
0x00, 0x00, 0x00, 0x03, // NALU length (3 bytes)
- 0x65, 0x88, 0x85 // Minimal IDR slice (slightly different)
+ 0x65, 0x88, 0x85 // Minimal IDR slice (slightly different)
};
char *idr_data = new char[sizeof(h264_idr_raw)];
@@ -2136,8 +2135,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoMultipleLargeNalusPackageFuA
0x17, // keyframe + AVC codec
0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20,
0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
- 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c
- };
+ 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c};
char *h264_data = new char[sizeof(h264_seq_raw)];
memcpy(h264_data, h264_seq_raw, sizeof(h264_seq_raw));
@@ -2217,8 +2215,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoMergeNalusLargePayload)
0x17, // keyframe + AVC codec
0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20,
0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
- 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c
- };
+ 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c};
char *h264_data = new char[sizeof(h264_seq_raw)];
memcpy(h264_data, h264_seq_raw, sizeof(h264_seq_raw));
@@ -2244,7 +2241,9 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoMergeNalusLargePayload)
// AVC header
large_data[pos++] = 0x17; // keyframe + AVC codec
large_data[pos++] = 0x01; // AVC NALU
- large_data[pos++] = 0x00; large_data[pos++] = 0x00; large_data[pos++] = 0x00; // composition time
+ large_data[pos++] = 0x00;
+ large_data[pos++] = 0x00;
+ large_data[pos++] = 0x00; // composition time
// First large NALU
large_data[pos++] = (first_nalu_size >> 24) & 0xFF;
@@ -2318,7 +2317,9 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnAudioRealAacFrames)
frame_data[0] = 0xAF; // AAC, 44kHz, 16-bit, stereo
frame_data[1] = 0x01; // AAC raw data (not sequence header)
// Add minimal AAC raw data - transcoding may fail but we'll reach the target lines
- frame_data[2] = 0x21; frame_data[3] = 0x10; frame_data[4] = 0x05;
+ frame_data[2] = 0x21;
+ frame_data[3] = 0x10;
+ frame_data[4] = 0x05;
aac_frame->wrap(frame_data, 5);
aac_frame->timestamp_ = 2000;
@@ -2379,7 +2380,9 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnAudioAddSampleFailure)
char *frame_data = new char[5];
frame_data[0] = 0xAF; // AAC, 44kHz, 16-bit, stereo
frame_data[1] = 0x01; // AAC raw data
- frame_data[2] = 0x21; frame_data[3] = 0x10; frame_data[4] = 0x05;
+ frame_data[2] = 0x21;
+ frame_data[3] = 0x10;
+ frame_data[4] = 0x05;
aac_frame->wrap(frame_data, 5);
aac_frame->timestamp_ = 2000;
@@ -2433,7 +2436,8 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnAudioTranscodeFailure)
frame_data[0] = 0xAF; // AAC, 44kHz, 16-bit, stereo
frame_data[1] = 0x01; // AAC raw data
// Add minimal AAC data - will likely cause transcoding to fail
- frame_data[2] = 0x00; frame_data[3] = 0x00;
+ frame_data[2] = 0x00;
+ frame_data[3] = 0x00;
aac_frame->wrap(frame_data, 4);
aac_frame->timestamp_ = 2000;
@@ -2486,7 +2490,9 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnAudioMemoryCleanup)
char *frame_data = new char[5];
frame_data[0] = 0xAF; // AAC, 44kHz, 16-bit, stereo
frame_data[1] = 0x01; // AAC raw data
- frame_data[2] = 0x21 + i; frame_data[3] = 0x10; frame_data[4] = 0x05;
+ frame_data[2] = 0x21 + i;
+ frame_data[3] = 0x10;
+ frame_data[4] = 0x05;
aac_frame->wrap(frame_data, 5);
aac_frame->timestamp_ = 2000 + i * 1000;
@@ -2531,8 +2537,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoComprehensiveCoverage)
0x17, // keyframe + AVC codec
0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20,
0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
- 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c
- };
+ 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c};
char *h264_data = new char[sizeof(h264_seq_raw)];
memcpy(h264_data, h264_seq_raw, sizeof(h264_seq_raw));
@@ -2548,10 +2553,10 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoComprehensiveCoverage)
h264_frame->message_type_ = SrsFrameTypeVideo;
uint8_t h264_frame_raw[] = {
- 0x17, // keyframe + AVC codec
- 0x01, // AVC NALU (not sequence header)
- 0x00, 0x00, 0x00, // composition time
- 0x00, 0x00, 0x00, 0x05, // NALU length
+ 0x17, // keyframe + AVC codec
+ 0x01, // AVC NALU (not sequence header)
+ 0x00, 0x00, 0x00, // composition time
+ 0x00, 0x00, 0x00, 0x05, // NALU length
0x65, 0x88, 0x84, 0x00, 0x10 // IDR slice data
};
@@ -2592,9 +2597,9 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoUnsupportedCodec)
h263_frame->message_type_ = SrsFrameTypeVideo;
uint8_t h263_raw[] = {
- 0x22, // keyframe + H.263 codec (codec ID 2)
- 0x00, // packet type
- 0x00, 0x00, 0x00, // composition time
+ 0x22, // keyframe + H.263 codec (codec ID 2)
+ 0x00, // packet type
+ 0x00, 0x00, 0x00, // composition time
0x01, 0x02, 0x03, 0x04, 0x05 // dummy H.263 data
};
@@ -2633,7 +2638,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoNoVcodecParsed)
// Create invalid video data that format_->on_video() can process but won't set vcodec_
uint8_t invalid_raw[] = {
- 0x00, // invalid frame type and codec combination
+ 0x00, // invalid frame type and codec combination
0x00, 0x00, 0x00, 0x00 // minimal data
};
@@ -2675,8 +2680,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoInitializeTrackError)
0x17, // keyframe + AVC codec
0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20,
0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
- 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c
- };
+ 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c};
char *h264_data = new char[sizeof(h264_seq_raw)];
memcpy(h264_data, h264_seq_raw, sizeof(h264_seq_raw));
@@ -2696,10 +2700,10 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoInitializeTrackError)
h264_frame2->message_type_ = SrsFrameTypeVideo;
uint8_t h264_frame_raw[] = {
- 0x17, // keyframe + AVC codec
- 0x01, // AVC NALU (not sequence header)
- 0x00, 0x00, 0x00, // composition time
- 0x00, 0x00, 0x00, 0x05, // NALU length
+ 0x17, // keyframe + AVC codec
+ 0x01, // AVC NALU (not sequence header)
+ 0x00, 0x00, 0x00, // composition time
+ 0x00, 0x00, 0x00, 0x05, // NALU length
0x65, 0x88, 0x84, 0x00, 0x10 // IDR slice data
};
@@ -2739,8 +2743,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoFilterMethod)
0x17, // keyframe + AVC codec
0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20,
0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
- 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c
- };
+ 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c};
char *h264_data = new char[sizeof(h264_seq_raw)];
memcpy(h264_data, h264_seq_raw, sizeof(h264_seq_raw));
@@ -2755,17 +2758,17 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoFilterMethod)
// Create IDR frame with multiple NALUs to test filter method thoroughly
uint8_t idr_raw[] = {
- 0x17, // keyframe + AVC codec
- 0x01, // AVC NALU (not sequence header)
+ 0x17, // keyframe + AVC codec
+ 0x01, // AVC NALU (not sequence header)
0x00, 0x00, 0x00, // composition time
// First NALU (SPS)
- 0x00, 0x00, 0x00, 0x08, // NALU length
+ 0x00, 0x00, 0x00, 0x08, // NALU length
0x67, 0x64, 0x00, 0x20, 0xac, 0xd9, 0x40, 0xc0, // SPS data
// Second NALU (PPS)
0x00, 0x00, 0x00, 0x04, // NALU length
0x68, 0xeb, 0xec, 0xb2, // PPS data
// Third NALU (IDR slice)
- 0x00, 0x00, 0x00, 0x06, // NALU length
+ 0x00, 0x00, 0x00, 0x06, // NALU length
0x65, 0x88, 0x84, 0x00, 0x10, 0x20 // IDR slice data
};
@@ -2782,10 +2785,10 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoFilterMethod)
p_frame->message_type_ = SrsFrameTypeVideo;
uint8_t p_raw[] = {
- 0x27, // inter frame + AVC codec
- 0x01, // AVC NALU
- 0x00, 0x00, 0x00, // composition time
- 0x00, 0x00, 0x00, 0x05, // NALU length
+ 0x27, // inter frame + AVC codec
+ 0x01, // AVC NALU
+ 0x00, 0x00, 0x00, // composition time
+ 0x00, 0x00, 0x00, 0x05, // NALU length
0x41, 0x88, 0x84, 0x00, 0x10 // P slice data
};
@@ -2843,8 +2846,8 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoFormatError)
// Create malformed data with valid codec ID but invalid structure
uint8_t malformed_raw[] = {
- 0x17, // keyframe + AVC codec
- 0x00, // sequence header indicator
+ 0x17, // keyframe + AVC codec
+ 0x00, // sequence header indicator
0xFF, 0xFF, 0xFF // invalid composition time and truncated data
};
@@ -2888,8 +2891,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoCodecSwitching)
0x17, // keyframe + AVC codec
0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20,
0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
- 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c
- };
+ 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c};
char *h264_data = new char[sizeof(h264_seq_raw)];
memcpy(h264_data, h264_seq_raw, sizeof(h264_seq_raw));
@@ -2903,10 +2905,10 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoCodecSwitching)
h264_frame->message_type_ = SrsFrameTypeVideo;
uint8_t h264_frame_raw[] = {
- 0x17, // keyframe + AVC codec
- 0x01, // AVC NALU
- 0x00, 0x00, 0x00, // composition time
- 0x00, 0x00, 0x00, 0x05, // NALU length
+ 0x17, // keyframe + AVC codec
+ 0x01, // AVC NALU
+ 0x00, 0x00, 0x00, // composition time
+ 0x00, 0x00, 0x00, 0x05, // NALU length
0x65, 0x88, 0x84, 0x00, 0x10 // IDR slice data
};
@@ -2927,8 +2929,7 @@ VOID TEST(StreamBridgeTest, SrsRtcRtpBuilder_OnVideoCodecSwitching)
0x17, // keyframe + AVC codec
0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0x00, 0x20, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x64, 0x00, 0x20,
0xac, 0xd9, 0x40, 0xc0, 0x29, 0xb0, 0x11, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00,
- 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c
- };
+ 0x32, 0x0f, 0x18, 0x31, 0x96, 0x01, 0x00, 0x05, 0x68, 0xeb, 0xec, 0xb2, 0x2c};
char *h264_data2 = new char[sizeof(h264_seq_raw2)];
memcpy(h264_data2, h264_seq_raw2, sizeof(h264_seq_raw2));
@@ -4256,8 +4257,6 @@ VOID TEST(RtcFrameBuilderTest, TranscodeAudio_ErrorInTranscoderLoop)
EXPECT_EQ(1, target.on_frame_count_); // Failed on first transcoded frame
}
-
-
// Test SrsRtcFrameBuilder::packet_video with complete frame detection and packet_video_rtmp error
VOID TEST(RtcFrameBuilderTest, PacketVideo_CompleteFrameDetectionWithPacketVideoRtmpError)
{
diff --git a/trunk/src/utest/srs_utest_app4.cpp b/trunk/src/utest/srs_utest_app4.cpp
index ac7cb289a..3e6bf895e 100644
--- a/trunk/src/utest/srs_utest_app4.cpp
+++ b/trunk/src/utest/srs_utest_app4.cpp
@@ -8,15 +8,15 @@
using namespace std;
+#include
#include
+#include
#include
#include
+#include
#include
#include
#include
-#include
-#include
-#include
MockRtcFrameTarget::MockRtcFrameTarget()
{
@@ -33,13 +33,13 @@ MockRtcFrameTarget::~MockRtcFrameTarget()
srs_error_t MockRtcFrameTarget::on_frame(SrsMediaPacket *frame)
{
on_frame_count_++;
-
+
// Store a copy of the frame for verification
srs_freep(last_frame_);
if (frame) {
last_frame_ = frame->copy();
}
-
+
return srs_error_copy(frame_error_);
}
@@ -360,21 +360,21 @@ SrsRtpPacket *create_hevc_stap_packet_with_vps_sps_pps()
VOID TEST(RtcFrameBuilderTest, OnRtp_NoPayload)
{
srs_error_t err;
-
+
MockRtcFrameTarget target;
SrsRtcFrameBuilder builder(&target);
-
+
// Initialize the builder
SrsUniquePtr req(new MockRtcRequest());
HELPER_EXPECT_SUCCESS(builder.initialize(req.get(), SrsAudioCodecIdAAC, SrsVideoCodecIdAVC));
-
+
// Create RTP packet with no payload
SrsUniquePtr pkt(new SrsRtpPacket());
pkt->set_avsync_time(1000);
-
+
// Should return success but do nothing
HELPER_EXPECT_SUCCESS(builder.on_rtp(pkt.get()));
-
+
// No frames should be generated
EXPECT_EQ(0, target.on_frame_count_);
}
@@ -383,20 +383,20 @@ VOID TEST(RtcFrameBuilderTest, OnRtp_NoPayload)
VOID TEST(RtcFrameBuilderTest, OnRtp_NoAvsyncTime_InitialState)
{
srs_error_t err;
-
+
MockRtcFrameTarget target;
SrsRtcFrameBuilder builder(&target);
-
+
// Initialize the builder
SrsUniquePtr req(new MockRtcRequest());
HELPER_EXPECT_SUCCESS(builder.initialize(req.get(), SrsAudioCodecIdAAC, SrsVideoCodecIdAVC));
-
+
// Create RTP packet with no avsync_time (initial sync_state_ is -1)
SrsUniquePtr pkt(create_mock_rtp_packet(true, 0)); // avsync_time = 0
-
+
// Should return success but discard packet and change sync_state_ from -1 to 0
HELPER_EXPECT_SUCCESS(builder.on_rtp(pkt.get()));
-
+
// No frames should be generated
EXPECT_EQ(0, target.on_frame_count_);
}
@@ -405,22 +405,22 @@ VOID TEST(RtcFrameBuilderTest, OnRtp_NoAvsyncTime_InitialState)
VOID TEST(RtcFrameBuilderTest, OnRtp_NoAvsyncTime_StateZero)
{
srs_error_t err;
-
+
MockRtcFrameTarget target;
SrsRtcFrameBuilder builder(&target);
-
+
// Initialize the builder
SrsUniquePtr req(new MockRtcRequest());
HELPER_EXPECT_SUCCESS(builder.initialize(req.get(), SrsAudioCodecIdAAC, SrsVideoCodecIdAVC));
-
+
// First packet with no avsync_time to set sync_state_ to 0
SrsUniquePtr pkt1(create_mock_rtp_packet(true, 0));
HELPER_EXPECT_SUCCESS(builder.on_rtp(pkt1.get()));
-
+
// Second packet with no avsync_time (sync_state_ is now 0, should not trace)
SrsUniquePtr pkt2(create_mock_rtp_packet(false, -1)); // avsync_time = -1
HELPER_EXPECT_SUCCESS(builder.on_rtp(pkt2.get()));
-
+
// No frames should be generated
EXPECT_EQ(0, target.on_frame_count_);
}
@@ -1789,8 +1789,6 @@ VOID TEST(RtcFrameBuilderTest, OnRtp_ComprehensiveCodePathCoverage)
HELPER_EXPECT_SUCCESS(builder.on_rtp(video_process.get()));
}
-
-
// Helper function to create a mock RTP packet with STAP-A payload containing SPS and PPS
SrsRtpPacket *create_stap_a_packet_with_sps_pps()
{
@@ -1844,10 +1842,6 @@ SrsRtpPacket *create_raw_payload_packet(SrsAvcNaluType nalu_type, const uint8_t
return pkt;
}
-
-
-
-
// Test SrsRtcFrameBuilder::packet_sequence_header_avc with STAP-A payload containing SPS and PPS
VOID TEST(RtcFrameBuilderTest, PacketSequenceHeaderAvc_STAPAPayload_WithSPSAndPPS)
{
@@ -3332,7 +3326,7 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_OutOfOrderPackets)
HELPER_EXPECT_SUCCESS(builder.initialize(req.get(), SrsAudioCodecIdAAC, SrsVideoCodecIdAVC));
// Helper function to create audio packet
- auto create_audio_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket* {
+ auto create_audio_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket * {
SrsRtpPacket *pkt = new SrsRtpPacket();
pkt->header_.set_ssrc(12345);
pkt->header_.set_sequence(seq);
@@ -3354,23 +3348,28 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_OutOfOrderPackets)
// Send packets out of order: 100, 102, 101, 104, 103
SrsUniquePtr pkt1(create_audio_packet(100, 48000, 1000));
srs_error_t result1 = builder.packet_audio(pkt1.get());
- if (result1 != srs_success) srs_freep(result1);
+ if (result1 != srs_success)
+ srs_freep(result1);
SrsUniquePtr pkt3(create_audio_packet(102, 48000 + 2 * 960, 1040));
srs_error_t result3 = builder.packet_audio(pkt3.get());
- if (result3 != srs_success) srs_freep(result3);
+ if (result3 != srs_success)
+ srs_freep(result3);
SrsUniquePtr pkt2(create_audio_packet(101, 48000 + 960, 1020));
srs_error_t result2 = builder.packet_audio(pkt2.get());
- if (result2 != srs_success) srs_freep(result2);
+ if (result2 != srs_success)
+ srs_freep(result2);
SrsUniquePtr pkt5(create_audio_packet(104, 48000 + 4 * 960, 1080));
srs_error_t result5 = builder.packet_audio(pkt5.get());
- if (result5 != srs_success) srs_freep(result5);
+ if (result5 != srs_success)
+ srs_freep(result5);
SrsUniquePtr pkt4(create_audio_packet(103, 48000 + 3 * 960, 1060));
srs_error_t result4 = builder.packet_audio(pkt4.get());
- if (result4 != srs_success) srs_freep(result4);
+ if (result4 != srs_success)
+ srs_freep(result4);
// Audio cache should handle out-of-order packets and deliver them in sequence
}
@@ -3388,7 +3387,7 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_DuplicatePackets)
HELPER_EXPECT_SUCCESS(builder.initialize(req.get(), SrsAudioCodecIdAAC, SrsVideoCodecIdAVC));
// Helper function to create audio packet
- auto create_audio_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket* {
+ auto create_audio_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket * {
SrsRtpPacket *pkt = new SrsRtpPacket();
pkt->header_.set_ssrc(12345);
pkt->header_.set_sequence(seq);
@@ -3410,17 +3409,20 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_DuplicatePackets)
// Send original packet
SrsUniquePtr pkt1(create_audio_packet(100, 48000, 1000));
srs_error_t result1 = builder.packet_audio(pkt1.get());
- if (result1 != srs_success) srs_freep(result1);
+ if (result1 != srs_success)
+ srs_freep(result1);
// Send duplicate packet with same sequence number
SrsUniquePtr pkt1_dup(create_audio_packet(100, 48000, 1000));
srs_error_t result1_dup = builder.packet_audio(pkt1_dup.get());
- if (result1_dup != srs_success) srs_freep(result1_dup);
+ if (result1_dup != srs_success)
+ srs_freep(result1_dup);
// Send next packet
SrsUniquePtr pkt2(create_audio_packet(101, 48000 + 960, 1020));
srs_error_t result2 = builder.packet_audio(pkt2.get());
- if (result2 != srs_success) srs_freep(result2);
+ if (result2 != srs_success)
+ srs_freep(result2);
// Audio cache should handle duplicate packets gracefully
}
@@ -3438,7 +3440,7 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_LatePackets)
HELPER_EXPECT_SUCCESS(builder.initialize(req.get(), SrsAudioCodecIdAAC, SrsVideoCodecIdAVC));
// Helper function to create audio packet
- auto create_audio_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket* {
+ auto create_audio_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket * {
SrsRtpPacket *pkt = new SrsRtpPacket();
pkt->header_.set_ssrc(12345);
pkt->header_.set_sequence(seq);
@@ -3460,20 +3462,24 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_LatePackets)
// Send packets in order: 100, 101, 102
SrsUniquePtr pkt1(create_audio_packet(100, 48000, 1000));
srs_error_t result1 = builder.packet_audio(pkt1.get());
- if (result1 != srs_success) srs_freep(result1);
+ if (result1 != srs_success)
+ srs_freep(result1);
SrsUniquePtr pkt2(create_audio_packet(101, 48000 + 960, 1020));
srs_error_t result2 = builder.packet_audio(pkt2.get());
- if (result2 != srs_success) srs_freep(result2);
+ if (result2 != srs_success)
+ srs_freep(result2);
SrsUniquePtr pkt3(create_audio_packet(102, 48000 + 2 * 960, 1040));
srs_error_t result3 = builder.packet_audio(pkt3.get());
- if (result3 != srs_success) srs_freep(result3);
+ if (result3 != srs_success)
+ srs_freep(result3);
// Now send a late packet with sequence number 99 (before already processed 100)
SrsUniquePtr late_pkt(create_audio_packet(99, 48000 - 960, 980));
srs_error_t late_result = builder.packet_audio(late_pkt.get());
- if (late_result != srs_success) srs_freep(late_result);
+ if (late_result != srs_success)
+ srs_freep(late_result);
// Audio cache should discard late packets gracefully
}
@@ -3662,7 +3668,7 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_SequenceWrapAround)
HELPER_EXPECT_SUCCESS(builder.initialize(req.get(), SrsAudioCodecIdAAC, SrsVideoCodecIdAVC));
// Helper function to create audio packet
- auto create_audio_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket* {
+ auto create_audio_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket * {
SrsRtpPacket *pkt = new SrsRtpPacket();
pkt->header_.set_ssrc(12345);
pkt->header_.set_sequence(seq);
@@ -3684,19 +3690,23 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_SequenceWrapAround)
// Test sequence number wrap-around: 65534, 65535, 0, 1
SrsUniquePtr pkt1(create_audio_packet(65534, 48000, 1000));
srs_error_t result1 = builder.packet_audio(pkt1.get());
- if (result1 != srs_success) srs_freep(result1);
+ if (result1 != srs_success)
+ srs_freep(result1);
SrsUniquePtr pkt2(create_audio_packet(65535, 48000 + 960, 1020));
srs_error_t result2 = builder.packet_audio(pkt2.get());
- if (result2 != srs_success) srs_freep(result2);
+ if (result2 != srs_success)
+ srs_freep(result2);
SrsUniquePtr pkt3(create_audio_packet(0, 48000 + 2 * 960, 1040));
srs_error_t result3 = builder.packet_audio(pkt3.get());
- if (result3 != srs_success) srs_freep(result3);
+ if (result3 != srs_success)
+ srs_freep(result3);
SrsUniquePtr pkt4(create_audio_packet(1, 48000 + 3 * 960, 1060));
srs_error_t result4 = builder.packet_audio(pkt4.get());
- if (result4 != srs_success) srs_freep(result4);
+ if (result4 != srs_success)
+ srs_freep(result4);
// Audio cache should handle sequence number wrap-around correctly
}
@@ -3714,7 +3724,7 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_TimestampWrapAround)
HELPER_EXPECT_SUCCESS(builder.initialize(req.get(), SrsAudioCodecIdAAC, SrsVideoCodecIdAVC));
// Helper function to create audio packet
- auto create_audio_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket* {
+ auto create_audio_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket * {
SrsRtpPacket *pkt = new SrsRtpPacket();
pkt->header_.set_ssrc(12345);
pkt->header_.set_sequence(seq);
@@ -3736,19 +3746,23 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_TimestampWrapAround)
// Test timestamp wrap-around: near UINT32_MAX, then wrap to 0
SrsUniquePtr pkt1(create_audio_packet(100, UINT32_MAX - 960, 1000));
srs_error_t result1 = builder.packet_audio(pkt1.get());
- if (result1 != srs_success) srs_freep(result1);
+ if (result1 != srs_success)
+ srs_freep(result1);
SrsUniquePtr pkt2(create_audio_packet(101, UINT32_MAX, 1020));
srs_error_t result2 = builder.packet_audio(pkt2.get());
- if (result2 != srs_success) srs_freep(result2);
+ if (result2 != srs_success)
+ srs_freep(result2);
SrsUniquePtr pkt3(create_audio_packet(102, 0, 1040));
srs_error_t result3 = builder.packet_audio(pkt3.get());
- if (result3 != srs_success) srs_freep(result3);
+ if (result3 != srs_success)
+ srs_freep(result3);
SrsUniquePtr pkt4(create_audio_packet(103, 960, 1060));
srs_error_t result4 = builder.packet_audio(pkt4.get());
- if (result4 != srs_success) srs_freep(result4);
+ if (result4 != srs_success)
+ srs_freep(result4);
// Should handle timestamp wrap-around correctly
}
@@ -3766,7 +3780,7 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_DifferentSSRC)
HELPER_EXPECT_SUCCESS(builder.initialize(req.get(), SrsAudioCodecIdAAC, SrsVideoCodecIdAVC));
// Helper function to create audio packet
- auto create_audio_packet = [](uint16_t seq, uint32_t ssrc, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket* {
+ auto create_audio_packet = [](uint16_t seq, uint32_t ssrc, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket * {
SrsRtpPacket *pkt = new SrsRtpPacket();
pkt->header_.set_ssrc(ssrc);
pkt->header_.set_sequence(seq);
@@ -3788,15 +3802,18 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_DifferentSSRC)
// Send packets with different SSRC values
SrsUniquePtr pkt1(create_audio_packet(100, 11111, 48000, 1000));
srs_error_t result1 = builder.packet_audio(pkt1.get());
- if (result1 != srs_success) srs_freep(result1);
+ if (result1 != srs_success)
+ srs_freep(result1);
SrsUniquePtr pkt2(create_audio_packet(101, 22222, 48000 + 960, 1020));
srs_error_t result2 = builder.packet_audio(pkt2.get());
- if (result2 != srs_success) srs_freep(result2);
+ if (result2 != srs_success)
+ srs_freep(result2);
SrsUniquePtr pkt3(create_audio_packet(102, 33333, 48000 + 2 * 960, 1040));
srs_error_t result3 = builder.packet_audio(pkt3.get());
- if (result3 != srs_success) srs_freep(result3);
+ if (result3 != srs_success)
+ srs_freep(result3);
// Should handle packets with different SSRC values
}
@@ -3814,7 +3831,7 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_RapidSequence)
HELPER_EXPECT_SUCCESS(builder.initialize(req.get(), SrsAudioCodecIdAAC, SrsVideoCodecIdAVC));
// Helper function to create audio packet
- auto create_audio_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket* {
+ auto create_audio_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket * {
SrsRtpPacket *pkt = new SrsRtpPacket();
pkt->header_.set_ssrc(12345);
pkt->header_.set_sequence(seq);
@@ -3837,7 +3854,8 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_RapidSequence)
for (int i = 0; i < 50; ++i) {
SrsUniquePtr pkt(create_audio_packet(100 + i, 48000 + i * 960, 1000 + i * 20));
srs_error_t result = builder.packet_audio(pkt.get());
- if (result != srs_success) srs_freep(result);
+ if (result != srs_success)
+ srs_freep(result);
}
// All packets should be processed through audio cache (transcoding may fail)
@@ -4185,7 +4203,7 @@ VOID TEST(RtcFrameBuilderTest, PacketVideo_SequenceWrapAround)
HELPER_EXPECT_SUCCESS(builder.initialize(req.get(), SrsAudioCodecIdAAC, SrsVideoCodecIdAVC));
// Helper function to create video packet
- auto create_video_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket* {
+ auto create_video_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket * {
SrsRtpPacket *pkt = new SrsRtpPacket();
pkt->header_.set_ssrc(12345);
pkt->header_.set_sequence(seq);
@@ -4234,7 +4252,7 @@ VOID TEST(RtcFrameBuilderTest, PacketVideo_TimestampWrapAround)
HELPER_EXPECT_SUCCESS(builder.initialize(req.get(), SrsAudioCodecIdAAC, SrsVideoCodecIdAVC));
// Helper function to create video packet
- auto create_video_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket* {
+ auto create_video_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket * {
SrsRtpPacket *pkt = new SrsRtpPacket();
pkt->header_.set_ssrc(12345);
pkt->header_.set_sequence(seq);
@@ -4283,7 +4301,7 @@ VOID TEST(RtcFrameBuilderTest, PacketVideo_DifferentSSRC)
HELPER_EXPECT_SUCCESS(builder.initialize(req.get(), SrsAudioCodecIdAAC, SrsVideoCodecIdAVC));
// Helper function to create video packet
- auto create_video_packet = [](uint16_t seq, uint32_t ssrc, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket* {
+ auto create_video_packet = [](uint16_t seq, uint32_t ssrc, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket * {
SrsRtpPacket *pkt = new SrsRtpPacket();
pkt->header_.set_ssrc(ssrc);
pkt->header_.set_sequence(seq);
@@ -4371,7 +4389,7 @@ VOID TEST(RtcFrameBuilderTest, PacketVideo_RapidSequence)
HELPER_EXPECT_SUCCESS(builder.initialize(req.get(), SrsAudioCodecIdAAC, SrsVideoCodecIdAVC));
// Helper function to create video packet
- auto create_video_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time, bool is_keyframe = false) -> SrsRtpPacket* {
+ auto create_video_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time, bool is_keyframe = false) -> SrsRtpPacket * {
SrsRtpPacket *pkt = new SrsRtpPacket();
pkt->header_.set_ssrc(12345);
pkt->header_.set_sequence(seq);
@@ -4414,7 +4432,7 @@ VOID TEST(RtcFrameBuilderTest, PacketVideo_MixedKeyframeSequence)
HELPER_EXPECT_SUCCESS(builder.initialize(req.get(), SrsAudioCodecIdAAC, SrsVideoCodecIdAVC));
// Helper function to create video packet
- auto create_video_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time, SrsAvcNaluType nalu_type) -> SrsRtpPacket* {
+ auto create_video_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time, SrsAvcNaluType nalu_type) -> SrsRtpPacket * {
SrsRtpPacket *pkt = new SrsRtpPacket();
pkt->header_.set_ssrc(12345);
pkt->header_.set_sequence(seq);
@@ -4653,7 +4671,7 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_MixedPayloadSizes)
HELPER_EXPECT_SUCCESS(builder.initialize(req.get(), SrsAudioCodecIdAAC, SrsVideoCodecIdAVC));
// Helper function to create audio packet with specific payload size
- auto create_audio_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time, int payload_size) -> SrsRtpPacket* {
+ auto create_audio_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time, int payload_size) -> SrsRtpPacket * {
SrsRtpPacket *pkt = new SrsRtpPacket();
pkt->header_.set_ssrc(12345);
pkt->header_.set_sequence(seq);
@@ -4675,7 +4693,8 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_MixedPayloadSizes)
for (int i = 0; i < 8; ++i) {
SrsUniquePtr pkt(create_audio_packet(100 + i, 48000 + i * 960, 1000 + i * 20, payload_sizes[i]));
srs_error_t result = builder.packet_audio(pkt.get());
- if (result != srs_success) srs_freep(result);
+ if (result != srs_success)
+ srs_freep(result);
}
// Should handle packets with different payload sizes
@@ -4694,7 +4713,7 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_ComprehensiveScenario)
HELPER_EXPECT_SUCCESS(builder.initialize(req.get(), SrsAudioCodecIdAAC, SrsVideoCodecIdAVC));
// Helper function to create audio packet
- auto create_audio_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket* {
+ auto create_audio_packet = [](uint16_t seq, uint32_t ts, uint32_t avsync_time) -> SrsRtpPacket * {
SrsRtpPacket *pkt = new SrsRtpPacket();
pkt->header_.set_ssrc(12345);
pkt->header_.set_sequence(seq);
@@ -4717,36 +4736,43 @@ VOID TEST(RtcFrameBuilderTest, PacketAudio_ComprehensiveScenario)
// 1. Normal sequential packets
SrsUniquePtr pkt1(create_audio_packet(100, 48000, 1000));
srs_error_t result1 = builder.packet_audio(pkt1.get());
- if (result1 != srs_success) srs_freep(result1);
+ if (result1 != srs_success)
+ srs_freep(result1);
SrsUniquePtr pkt2(create_audio_packet(101, 48000 + 960, 1020));
srs_error_t result2 = builder.packet_audio(pkt2.get());
- if (result2 != srs_success) srs_freep(result2);
+ if (result2 != srs_success)
+ srs_freep(result2);
// 2. Out-of-order packet
SrsUniquePtr pkt4(create_audio_packet(103, 48000 + 3 * 960, 1060));
srs_error_t result4 = builder.packet_audio(pkt4.get());
- if (result4 != srs_success) srs_freep(result4);
+ if (result4 != srs_success)
+ srs_freep(result4);
// 3. Fill the gap
SrsUniquePtr pkt3(create_audio_packet(102, 48000 + 2 * 960, 1040));
srs_error_t result3 = builder.packet_audio(pkt3.get());
- if (result3 != srs_success) srs_freep(result3);
+ if (result3 != srs_success)
+ srs_freep(result3);
// 4. Duplicate packet
SrsUniquePtr pkt3_dup(create_audio_packet(102, 48000 + 2 * 960, 1040));
srs_error_t result3_dup = builder.packet_audio(pkt3_dup.get());
- if (result3_dup != srs_success) srs_freep(result3_dup);
+ if (result3_dup != srs_success)
+ srs_freep(result3_dup);
// 5. Late packet (should be discarded)
SrsUniquePtr late_pkt(create_audio_packet(99, 48000 - 960, 980));
srs_error_t late_result = builder.packet_audio(late_pkt.get());
- if (late_result != srs_success) srs_freep(late_result);
+ if (late_result != srs_success)
+ srs_freep(late_result);
// 6. Continue with normal sequence
SrsUniquePtr pkt5(create_audio_packet(104, 48000 + 4 * 960, 1080));
srs_error_t result5 = builder.packet_audio(pkt5.get());
- if (result5 != srs_success) srs_freep(result5);
+ if (result5 != srs_success)
+ srs_freep(result5);
// All scenarios should be handled correctly by the audio cache (transcoding may fail)
}
diff --git a/trunk/src/utest/srs_utest_app4.hpp b/trunk/src/utest/srs_utest_app4.hpp
index cf1166b3d..76d5f0291 100644
--- a/trunk/src/utest/srs_utest_app4.hpp
+++ b/trunk/src/utest/srs_utest_app4.hpp
@@ -12,12 +12,12 @@
*/
#include
+#include
#include
#include
+#include
#include
#include
-#include
-#include
// Forward declarations
class SrsMediaPacket;