Repository: ossrs/srs
File: trunk/src/app/srs_app_rtc_source.cpp (C++)

Code before:

    bool raw_is_sps_pps = false;

    // For OBS WHIP, it uses RTP Raw packet with SPS/PPS/IDR frame.
    SrsRtpRawPayload* raw_payload = dynamic_cast<SrsRtpRawPayload*>(pkt->payload());
    if (raw_payload) {
        if (pkt->nalu_type == SrsAvcNaluTypeSPS) {
            raw_is_sps_pps = true;
            srs_freep(obs_whip_sps_);
            obs_whip_sps_ = pkt->copy();
        } else if (pkt->nalu_type == SrsAvcNaluTypePPS) {
            raw_is_sps_pps = true;
            srs_freep(obs_whip_pps_);
            obs_whip_pps_ = pkt->copy();
        }
        // Ignore if one of OBS WHIP SPS/PPS is not ready.
        if (raw_is_sps_pps && (!obs_whip_sps_ || !obs_whip_pps_)) {
            return err;
        }
    }

    // Generally, there will be SPS+PPS+IDR in a STAP-A packet.
    SrsRtpSTAPPayload* stap_payload = dynamic_cast<SrsRtpSTAPPayload*>(pkt->payload());

    // Handle SPS/PPS in cache or STAP-A packet.
    if (stap_payload || (raw_payload && raw_is_sps_pps)) {
        // Get the SPS/PPS from cache or STAP-A packet.
        SrsSample* sps = stap_payload ? stap_payload->get_sps() : NULL;
        if (!sps && obs_whip_sps_) sps = dynamic_cast<SrsRtpRawPayload*>(obs_whip_sps_->payload())->sample_;
        SrsSample* pps = stap_payload ? stap_payload->get_pps() : NULL;
        if (!pps && obs_whip_pps_) pps = dynamic_cast<SrsRtpRawPayload*>(obs_whip_pps_->payload())->sample_;
        if (!sps || !pps) {
            return srs_error_new(ERROR_RTC_RTP_MUXER, "no sps or pps in stap-a rtp. sps: %p, pps:%p", sps, pps);
        }

        // Reset SPS/PPS cache, ensuring that the next SPS/PPS will be handled when both are received.
        SrsAutoFree(SrsRtpPacket, obs_whip_sps_);
        SrsAutoFree(SrsRtpPacket, obs_whip_pps_);

        // h264 raw to h264 packet.
        std::string sh;
        SrsRawH264Stream* avc = new SrsRawH264Stream();
        SrsAutoFree(SrsRawH264Stream, avc);

        if ((err = avc->mux_sequence_header(string(sps->bytes, sps->size), string(pps->bytes, pps->size), sh)) != srs_success) {
            return srs_error_wrap(err, "mux sequence header");
        }

        // h264 packet to flv packet.
        char* flv = NULL;
        int nb_flv = 0;

Review comment (suggestion):
When raw_is_sps_pps is set to true, the raw_payload must not be null.

The logic you added dictates that the generation of the Sequence header should not be triggered when raw_payload is present but does not contain sps or pps.

`TRANS_BY_GPT4`

Code after:

    // For OBS WHIP, it uses RTP Raw packet with SPS/PPS/IDR frame. Note that not all
    // raw payload is SPS/PPS.
    bool has_sps_pps_in_raw_payload = false;
    SrsRtpRawPayload* raw_payload = dynamic_cast<SrsRtpRawPayload*>(pkt->payload());
    if (raw_payload) {
        if (pkt->nalu_type == SrsAvcNaluTypeSPS) {
            has_sps_pps_in_raw_payload = true;
            srs_freep(obs_whip_sps_);
            obs_whip_sps_ = pkt->copy();
        } else if (pkt->nalu_type == SrsAvcNaluTypePPS) {
            has_sps_pps_in_raw_payload = true;
            srs_freep(obs_whip_pps_);
            obs_whip_pps_ = pkt->copy();
        }
        // Ignore if one of OBS WHIP SPS/PPS is not ready.
        if (has_sps_pps_in_raw_payload && (!obs_whip_sps_ || !obs_whip_pps_)) {
            return err;
        }
    }

    // Generally, there will be SPS+PPS+IDR in a STAP-A packet.
    SrsRtpSTAPPayload* stap_payload = dynamic_cast<SrsRtpSTAPPayload*>(pkt->payload());

    // Handle SPS/PPS in cache or STAP-A packet.
    if (stap_payload || has_sps_pps_in_raw_payload) {
        // Get the SPS/PPS from cache or STAP-A packet.
        SrsSample* sps = stap_payload ? stap_payload->get_sps() : NULL;
        if (!sps && obs_whip_sps_) sps = dynamic_cast<SrsRtpRawPayload*>(obs_whip_sps_->payload())->sample_;
        SrsSample* pps = stap_payload ? stap_payload->get_pps() : NULL;
        if (!pps && obs_whip_pps_) pps = dynamic_cast<SrsRtpRawPayload*>(obs_whip_pps_->payload())->sample_;
        if (!sps || !pps) {
            return srs_error_new(ERROR_RTC_RTP_MUXER, "no sps or pps in stap-a rtp. sps: %p, pps:%p", sps, pps);
        }

        // Reset SPS/PPS cache, ensuring that the next SPS/PPS will be handled when both are received.
        SrsAutoFree(SrsRtpPacket, obs_whip_sps_);
        SrsAutoFree(SrsRtpPacket, obs_whip_pps_);

        // h264 raw to h264 packet.
        std::string sh;
        SrsRawH264Stream* avc = new SrsRawH264Stream();
        SrsAutoFree(SrsRawH264Stream, avc);

        if ((err = avc->mux_sequence_header(string(sps->bytes, sps->size), string(pps->bytes, pps->size), sh)) != srs_success) {
            return srs_error_wrap(err, "mux sequence header");
        }

        // h264 packet to flv packet.
        char* flv = NULL;
        int nb_flv = 0;