Skip to content

Commit 465f939

Browse files
committed
tx_send_h265: emit AP if possible
It is perhaps not worth sending VPS/SPS/PPS in separate packets.
1 parent 770c44a commit 465f939

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

src/transmit.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,73 @@ void tx_send_h264(struct tx *tx, struct video_frame *frame,
11771177
}
11781178
}
11791179

1180+
/**
1181+
* send aggregate packet if possible to aggregate more NALUs (optional)
1182+
* @todo consider this also for tx_send_h264
1183+
*/
1184+
static bool
1185+
send_h265_aggregate(struct rtp *rtp_session, const char pt, const uint32_t ts,
1186+
unsigned max_packet_size, const unsigned char **nal_p,
1187+
uint16_t nalsize_1st, const unsigned char *const end)
1188+
{
1189+
enum {
1190+
AP_THRESH = 100, // aggregate just small pckts (will be copied)
1191+
};
1192+
if (nalsize_1st > AP_THRESH || end - *nal_p == nalsize_1st) {
1193+
return false;
1194+
}
1195+
unsigned char ap_data[RTP_MAX_PACKET_LEN];
1196+
unsigned char *pkt_end = ap_data;
1197+
const unsigned char *nal = *nal_p;
1198+
const int layer_id0 = (nal[0] & 0x1) << 5 & nal[1] >> 3;
1199+
const int tid0 = nal[1] & 0x7;
1200+
const unsigned char *endptr = nullptr;
1201+
bool emit_ap = false;
1202+
while ((nal = rtpenc_get_next_nal(nal, end - nal, &endptr)) !=
1203+
nullptr) {
1204+
const int layer_id = (nal[0] & 0x1) << 5 & nal[1] >> 3;
1205+
const int tid = nal[1] & 0x7;
1206+
if (layer_id != layer_id0 || tid != tid0) { // not compatible
1207+
break;
1208+
}
1209+
const uint16_t sz = endptr - nal;
1210+
if (sz > AP_THRESH) {
1211+
break;
1212+
}
1213+
if (ap_data - pkt_end + sz > max_packet_size) {
1214+
break; // woultd exceed MTU
1215+
}
1216+
if (!emit_ap) { // aggregate pkt will be generated - write
1217+
// first pkt data
1218+
// AP header
1219+
*pkt_end++ = NAL_RTP_HEVC_AP << 1 | layer_id >> 5;
1220+
*pkt_end++ = layer_id << 3 | tid;
1221+
const uint16_t sz_n = htons(nalsize_1st);
1222+
memcpy(pkt_end, &sz_n, sizeof sz_n);
1223+
pkt_end += sizeof sz_n;
1224+
memcpy(pkt_end, *nal_p, nalsize_1st);
1225+
pkt_end += nalsize_1st;
1226+
}
1227+
emit_ap = true;
1228+
*nal_p = nal;
1229+
const uint16_t sz_n = htons(sz);
1230+
memcpy(pkt_end, &sz_n, sizeof sz_n);
1231+
pkt_end += sizeof sz_n;
1232+
memcpy(pkt_end, nal, sz);
1233+
pkt_end += sz;
1234+
}
1235+
if (emit_ap) {
1236+
if (rtp_send_data_hdr(rtp_session, ts, pt, 1 /* m */, 0,
1237+
nullptr, (char *) nullptr, 0,
1238+
(char *) ap_data, pkt_end - ap_data,
1239+
nullptr, 0, 0) < 0) {
1240+
error_msg("There was a problem sending the RTP "
1241+
"packet\n");
1242+
}
1243+
}
1244+
return emit_ap;
1245+
}
1246+
11801247
void tx_send_h265(struct tx *tx, struct video_frame *frame,
11811248
struct rtp *rtp_session) {
11821249
assert(frame->tile_count == 1);
@@ -1195,6 +1262,11 @@ void tx_send_h265(struct tx *tx, struct video_frame *frame,
11951262
while ((nal = rtpenc_get_next_nal(nal, end - nal, &endptr))) {
11961263
unsigned int nalsize = endptr - nal;
11971264

1265+
if (send_h265_aggregate(rtp_session, pt, ts, maxPacketSize,
1266+
&nal, nalsize, end)) {
1267+
continue;
1268+
}
1269+
11981270
if (nalsize <= maxPacketSize) { // single NALU packet
11991271
char *payload = const_cast<char *>(
12001272
reinterpret_cast<const char *>(nal));

0 commit comments

Comments
 (0)