Repository: ossrs/srs
File: trunk/src/kernel/srs_kernel_codec.cpp (C++)

Code before:
    // profile tier level...
    SrsHevcProfileTierLevel profile_tier_level;
    memset((void*)&profile_tier_level, 0, sizeof(profile_tier_level));
    // profile_tier_level(1, sps_max_sub_layers_minus1)
    if ((err = hevc_demux_rbsp_ptl(&bs, &profile_tier_level, 1, sps_max_sub_layers_minus1)) != srs_success) {
        return srs_error_wrap(err, "sps rbsp ptl sps_max_sub_layers_minus1=%d", sps_max_sub_layers_minus1);
    }

    vcodec->hevc_profile = (SrsHevcProfile)profile_tier_level.general_profile_idc;
    vcodec->hevc_level = (SrsHevcLevel)profile_tier_level.general_level_idc;

    // sps_seq_parameter_set_id  ue(v)
    uint32_t sps_seq_parameter_set_id = 0;
    if ((err = bs.read_bits_ue(sps_seq_parameter_set_id)) != srs_success) {
        return srs_error_wrap(err, "sps_seq_parameter_set_id");
    }

    // for sps_table
    SrsHevcDecoderConfigurationRecord *dec_conf_rec = &(vcodec->hevc_dec_conf_record_);
    SrsHevcRbspSps *sps = &(dec_conf_rec->sps_table[sps_seq_parameter_set_id]);

    sps->sps_video_parameter_set_id = sps_video_parameter_set_id;
    sps->sps_max_sub_layers_minus1 = sps_max_sub_layers_minus1;
    sps->sps_temporal_id_nesting_flag = sps_temporal_id_nesting_flag;
    sps->sps_seq_parameter_set_id = sps_seq_parameter_set_id;
    memcpy((void*)&sps->ptl, &profile_tier_level, sizeof(profile_tier_level));

    // chroma_format_idc  ue(v)
    if ((err = bs.read_bits_ue(sps->chroma_format_idc)) != srs_success) {
        return srs_error_wrap(err, "chroma_format_idc");
    }

    if (sps->chroma_format_idc == 3) {
        if (!bs.require_bits(1)) {
            return srs_error_new(ERROR_HEVC_DECODE_ERROR, "separate_colour_plane_flag requires 1 only %d bits", bs.left_bits());
        }

        // separate_colour_plane_flag  u(1)
        sps->separate_colour_plane_flag = bs.read_bit();
    }

    // pic_width_in_luma_samples  ue(v)
    if ((err = bs.read_bits_ue(sps->pic_width_in_luma_samples)) != srs_success) {
        return srs_error_wrap(err, "pic_width_in_luma_samples");
    }

    // pic_height_in_luma_samples  ue(v)
    if ((err = bs.read_bits_ue(sps->pic_height_in_luma_samples)) != srs_success) {
        return srs_error_wrap(err, "pic_height_in_luma_samples");
    }


Review comment (bug):
profile_tier_level is

```
struct SrsHevcProfileTierLevel {
    uint8_t general_level_idc;
    std::vector<uint8_t> sub_layer_profile_present_flag;
}
```

In the structure, there is also a vector. Is it not good to directly memcpy this? Will there be any issues if some pointers inside are directly copied?

There is another place:

```
memset((void*)&profile_tier_level, 0, sizeof(SrsHevcProfileTierLevel));
```

It should also be incorrect.

This complex structure should be initialized using a constructor, which would be better.

If it is a copy, it would be better to use the assignment operator directly.

`TRANS_BY_GPT3`

Code after:
        nb_rbsp++;
    }

    return hevc_demux_sps_rbsp((char*)&rbsp[0], nb_rbsp);
}

srs_error_t SrsFormat::hevc_demux_sps_rbsp(char* rbsp, int nb_rbsp)
{
    srs_error_t err = srs_success;

    // we donot parse the detail of sps.
    // @see https://github.com/ossrs/srs/issues/474
    if (!avc_parse_sps) {
        return err;
    }

    // reparse the rbsp.
    SrsBuffer stream(rbsp, nb_rbsp);

    // H265 SPS Nal Unit (seq_parameter_set_rbsp()) parser.
    // Section 7.3.2.2 ("Sequence parameter set RBSP syntax") of the H.265
    // ITU-T-H.265-2021.pdf, page 55.
    if (!stream.require(2)) {
        return srs_error_new(ERROR_HEVC_DECODE_ERROR, "sps requires 2 only %d bytes", stream.left());
    }
    uint8_t nutv = stream.read_1bytes();

    // sps_video_parameter_set_id  u(4)
    int sps_video_parameter_set_id = (nutv >> 4) & 0x0f;
    // sps_max_sub_layers_minus1  u(3)
    int sps_max_sub_layers_minus1 = (nutv >> 1) & 0x07;
    // sps_temporal_id_nesting_flag  u(1)
    int sps_temporal_id_nesting_flag = nutv & 0x01;

    SrsBitBuffer bs(&stream);

    // profile tier level...
    SrsHevcProfileTierLevel profile_tier_level;
    // profile_tier_level(1, sps_max_sub_layers_minus1)
    if ((err = hevc_demux_rbsp_ptl(&bs, &profile_tier_level, 1, sps_max_sub_layers_minus1)) != srs_success) {
        return srs_error_wrap(err, "sps rbsp ptl sps_max_sub_layers_minus1=%d", sps_max_sub_layers_minus1);
    }

    vcodec->hevc_profile = (SrsHevcProfile)profile_tier_level.general_profile_idc;
    vcodec->hevc_level = (SrsHevcLevel)profile_tier_level.general_level_idc;

    // sps_seq_parameter_set_id  ue(v)
    uint32_t sps_seq_parameter_set_id = 0;
    if ((err = bs.read_bits_ue(sps_seq_parameter_set_id)) != srs_success) {
        return srs_error_wrap(err, "sps_seq_parameter_set_id");
    }