Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

S and E combination error #14

Open
chivstyle opened this issue Oct 25, 2023 · 0 comments
Open

S and E combination error #14

chivstyle opened this issue Oct 25, 2023 · 0 comments

Comments

@chivstyle
Copy link

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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant