-
-
Notifications
You must be signed in to change notification settings - Fork 88
Open
Description
Please see the comment below for detail.
int SmolRTSP_NalTransport_send_packet(
SmolRTSP_NalTransport *self, SmolRTSP_RtpTimestamp ts,
SmolRTSP_NalUnit nalu) {
assert(self);
const size_t max_packet_size = MATCHES(nalu.header, SmolRTSP_NalHeader_H264)
? self->config.max_h264_nalu_size
: self->config.max_h265_nalu_size,
nalu_size =
SmolRTSP_NalHeader_size(nalu.header) + nalu.payload.len;
if (nalu_size < max_packet_size) {
const bool marker =
SmolRTSP_NalHeader_is_coded_slice_idr(nalu.header) ||
SmolRTSP_NalHeader_is_coded_slice_non_idr(nalu.header);
const size_t header_buf_size = SmolRTSP_NalHeader_size(nalu.header);
uint8_t *header_buf = alloca(header_buf_size);
SmolRTSP_NalHeader_serialize(nalu.header, header_buf);
return SmolRTSP_RtpTransport_send_packet(
self->transport, ts, marker,
U8Slice99_new(header_buf, header_buf_size), nalu.payload);
}
// send fragmentized nal data ? Not absolutely.
return send_fragmentized_nal_data(
self->transport, ts, max_packet_size, nalu);
}
// See <https://tools.ietf.org/html/rfc6184#section-5.8> (H.264),
// <https://tools.ietf.org/html/rfc7798#section-4.4.3> (H.265).
static int send_fragmentized_nal_data(
SmolRTSP_RtpTransport *t, SmolRTSP_RtpTimestamp ts, size_t max_packet_size,
SmolRTSP_NalUnit nalu) {
// define ENABLE_BUGFIX_S_AND_E to apply bugfix.
#ifdef ENABLE_BUGFIX_S_AND_E
if (nalu.payload.len <= max_packet_size) {
max_packet_size >>= 1;
}
#endif
const size_t rem = nalu.payload.len % max_packet_size,
packets_count = (nalu.payload.len - rem) / max_packet_size;
// max_packet_size == sizeof(header) + sizeof(nalu), but the loop below ingores the header size, it only split the nalu.
// it means that nalu.play.len may be less than max_packet_size, it tell us that it's the first fragment and it's also the last fragment,
// the FU header contains S and E bit simultaneously. It's a bug, right ?
for (size_t packet_idx = 0; packet_idx < packets_count; packet_idx++) {
const bool is_first_fragment = 0 == packet_idx,
is_last_fragment =
0 == rem && (packets_count - 1 == packet_idx);
const U8Slice99 fu_data = U8Slice99_sub(
nalu.payload, packet_idx * max_packet_size,
is_last_fragment ? nalu.payload.len
: (packet_idx + 1) * max_packet_size);
const SmolRTSP_NalUnit fu = {nalu.header, fu_data};
if (send_fu(t, ts, fu, is_first_fragment, is_last_fragment) == -1) {
return -1;
}
}
if (rem != 0) {
const U8Slice99 fu_data =
U8Slice99_advance(nalu.payload, packets_count * max_packet_size);
const SmolRTSP_NalUnit fu = {nalu.header, fu_data};
const bool is_first_fragment = 0 == packets_count,
is_last_fragment = true;
if (send_fu(t, ts, fu, is_first_fragment, is_last_fragment) == -1) {
return -1;
}
}
return 0;
}Metadata
Metadata
Assignees
Labels
No labels