diff --git a/src/formats/h26x.cc b/src/formats/h26x.cc index c677e92..e6a77c2 100644 --- a/src/formats/h26x.cc +++ b/src/formats/h26x.cc @@ -335,6 +335,13 @@ rtp_error_t uvgrtp::formats::h26x::push_media_frame(sockaddr_in& addr, sockaddr_ if (!data || !data_len) return RTP_INVALID_VALUE; + /* This is the first call of init_transaction. It generates a new RTP timestamp. The init_transaction() calls + below will use the same RTP timestamp. */ + if ((ret = fqueue_->init_transaction(data)) != RTP_OK) { + UVG_LOG_ERROR("Invalid frame queue or failed to initialize transaction!"); + return ret; + } + size_t payload_size = rtp_ctx_->get_payload_size(); // find all the locations of NAL units using Start Code Lookup (SCL) @@ -366,10 +373,6 @@ rtp_error_t uvgrtp::formats::h26x::push_media_frame(sockaddr_in& addr, sockaddr_ if (should_aggregate && !do_not_aggr) // an aggregate packet is possible { - if ((ret = fqueue_->init_transaction(data)) != RTP_OK) { - UVG_LOG_ERROR("Invalid frame queue or failed to initialize transaction!"); - return ret; - } // use aggregation function that also may just send the packets as Single NAL units // if aggregates have not been implemented @@ -685,7 +688,7 @@ rtp_error_t uvgrtp::formats::h26x::packet_handler(void* args, int rce_flags, uin // first we check that this packet does not belong to an access unit that has been dropped by garbage collection if (dropped_ts_.find(frame->header.timestamp) != dropped_ts_.end()) { - UVG_LOG_DEBUG("Received an RTP packet belonging to an old, dropped access unit! Timestamp: %lu, seq: %u", + UVG_LOG_DEBUG("Received an RTP packet belonging to an old, dropped access unit! Timestamp: %u, seq: %u", frame->header.timestamp, frame->header.seq); (void)uvgrtp::frame::dealloc_frame(frame); // free fragment memory return RTP_GENERIC_ERROR; diff --git a/test/test_4_formats.cpp b/test/test_4_formats.cpp index 1cef8bf..17ebe5a 100644 --- a/test/test_4_formats.cpp +++ b/test/test_4_formats.cpp @@ -692,7 +692,7 @@ TEST(FormatTests, h264_aggregation) std::this_thread::sleep_for(std::chrono::milliseconds(200)); std::cout << "H264: Received/expected: " << aggr_received << "/" << expected << std::endl; - ASSERT_TRUE(aggr_received >= expected/3); + ASSERT_TRUE(aggr_received == expected); cleanup_ms(sess, sender); cleanup_ms(sess, receiver); cleanup_sess(ctx, sess); @@ -739,7 +739,7 @@ TEST(FormatTests, h265_aggregation) std::this_thread::sleep_for(std::chrono::milliseconds(200)); std::cout << "H265: Received/expected: " << aggr_received << "/" << expected << std::endl; - ASSERT_TRUE(aggr_received >= expected/3); + ASSERT_TRUE(aggr_received == expected); cleanup_ms(sess, sender); cleanup_ms(sess, receiver); cleanup_sess(ctx, sess); @@ -786,7 +786,54 @@ TEST(FormatTests, h266_aggregation) std::this_thread::sleep_for(std::chrono::milliseconds(200)); std::cout << "H266: Received/expected: " << aggr_received << "/" << expected << std::endl; - ASSERT_TRUE(aggr_received >= expected/3); + ASSERT_TRUE(aggr_received == expected); + cleanup_ms(sess, sender); + cleanup_ms(sess, receiver); + cleanup_sess(ctx, sess); +} + +TEST(FormatTests, h265_disable_aggr) +{ + std::cout << "Testing RTP_H26X_DO_NOT_AGGR flag" << std::endl; + uvgrtp::context ctx; + uvgrtp::session* sess = ctx.create_session(LOCAL_ADDRESS); + + uvgrtp::media_stream* sender = nullptr; + uvgrtp::media_stream* receiver = nullptr; + + aggr_received = 0; + int expected = 3; + + if (sess) + { + sender = sess->create_stream(SEND_PORT, RECEIVE_PORT, RTP_FORMAT_H265, RCE_NO_FLAGS); + receiver = sess->create_stream(RECEIVE_PORT, SEND_PORT, RTP_FORMAT_H265, RCE_NO_FLAGS); + receiver->install_receive_hook(nullptr, aggr_receive_hook); + } + + int rtp_flags = RTP_NO_FLAGS; + rtp_format_t format = RTP_FORMAT_H265; + int test_runs = 1; + + std::vector test_sizes = { 100, 200, 300 }; + + size_t total_size = 0; + std::unique_ptr test_frame = std::unique_ptr(new uint8_t[700]); + + for (auto& size : test_sizes) + { + int nal_type = 8; + std::unique_ptr nal_unit = create_test_packet(format, nal_type, true, size, rtp_flags); + memcpy(test_frame.get() + total_size, nal_unit.get(), size); + total_size += size; + } + if (sender->push_frame(std::move(test_frame), total_size, RTP_H26X_DO_NOT_AGGR) != RTP_OK) { + std::cout << "Failed to send test packet!" << std::endl; + } + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + + std::cout << "H265: Received/expected: " << aggr_received << "/" << expected << std::endl; + ASSERT_TRUE(aggr_received == expected); cleanup_ms(sess, sender); cleanup_ms(sess, receiver); cleanup_sess(ctx, sess);