Open chivstyle opened 1 year ago
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; }
Please see the comment below for detail.