h265 1080 2k 4k 分辨率解析

void get_profile(int profile_idc, char* profile_str)
{
    switch (profile_idc) {
    case 66:
        strcpy(profile_str, "Baseline");
        break;
    case 77:
        strcpy(profile_str, "Main");
        break;
    case 88:
        strcpy(profile_str, "Extended");
        break;
    case 100:
        strcpy(profile_str, "High(FRExt)");
        break;
    case 110:
        strcpy(profile_str, "High10(FRExt)");
        break;
    case 122:
        strcpy(profile_str, "High4:2:2(FRExt)");
        break;
    case 144:
        strcpy(profile_str, "High4:4:4(FRExt)");
        break;
    default:
        strcpy(profile_str, "Unknown");
    }
}

unsigned int Ue(unsigned char* pBuff, unsigned int nLen, unsigned int* nStartBit)
{
    unsigned int nZeroNum = 0;
    while (*nStartBit < nLen * 8)
    {
        if (pBuff[*nStartBit / 8] & (0x80 >> (*nStartBit % 8)))
        {
            break;
        }
        nZeroNum++;
        *nStartBit += 1;
    }
    *nStartBit += 1;

    unsigned long dwRet = 0;
    for (unsigned int i = 0; i < nZeroNum; i++)
    {
        dwRet <<= 1;
        if (pBuff[*nStartBit / 8] & (0x80 >> (*nStartBit % 8)))
        {
            dwRet += 1;
        }
        *nStartBit += 1;
    }
    return (1 << nZeroNum) - 1 + dwRet;
}

int Se(unsigned char* pBuff, unsigned int nLen, unsigned int* nStartBit)
{
    int UeVal = Ue(pBuff, nLen, nStartBit);
    double k = UeVal;
    int nValue = ceil(k / 2);
    if (UeVal % 2 == 0)
        nValue = -nValue;
    return nValue;
}

unsigned long u(unsigned int BitCount, unsigned char* buf, unsigned int* nStartBit)
{
    unsigned long dwRet = 0;
    for (unsigned int i = 0; i < BitCount; i++)
    {
        dwRet <<= 1;
        if (buf[*nStartBit / 8] & (0x80 >> (*nStartBit % 8)))
        {
            dwRet += 1;
        }
        *nStartBit += 1;
    }
    return dwRet;
}

void de_emulation_prevention(unsigned char* buf, unsigned int* buf_size)
{
    unsigned char* ptr = NULL;
    unsigned int tmp_buf_size = 0;
    unsigned int i = 0, j = 0, val = 0;

    ptr = buf;
    tmp_buf_size = *buf_size;
    for (i = 0; i < (tmp_buf_size - 2); i++)
    {
        //check for 0x000003
        val = (ptr[i] ^ 0x00) + (ptr[i + 1] ^ 0x00) + (ptr[i + 2] ^ 0x03);
        if (val == 0)
        {
            //kick out 0x03
            for (j = i + 2; j < tmp_buf_size - 1; j++)
                ptr[j] = ptr[j + 1];
            //and so we should devrease bufsize
            (*buf_size)--;
        }
    }
}


struct h265_sub_layer_t {
    uint8_t sub_layer_profile_present_flag; // u(1)
    uint8_t sub_layer_level_present_flag; // u(1)
    uint8_t sub_layer_profile_space; // u(2)
    uint8_t sub_layer_tier_flag; // u(1)
    uint8_t sub_layer_profile_idc; // u(5)
    uint32_t sub_layer_profile_compatibility_flag; // u(32)
    uint64_t sub_layer_constraint_flags; // u(48)
    uint8_t sub_layer_level_idc;// u(8)
};

struct h265_profile_tier_level_t {
    uint8_t general_profile_space; // u(2)
    uint8_t general_tier_flag;  // u(1)
    uint8_t general_profile_idc; // u(5)
    uint32_t general_profile_compatibility_flag; // u(32)
    uint64_t general_constraint_flags; // u(48)
    uint8_t general_level_idc; // u(8)
    struct h265_sub_layer_t sub_layer[64]; // maxNumSubLayersMinus1
};


int h265_profile_tier_level(struct h265_profile_tier_level_t* profile, int profilePresentFlag, int maxNumSubLayersMinus1, unsigned char* buf, unsigned int& StartBit)
{
    int i;
    if (profilePresentFlag){
        profile->general_profile_idc = (uint8_t)u(2, buf, &StartBit);
        profile->general_tier_flag = (uint8_t)u(1, buf, &StartBit);
        profile->general_profile_idc = (uint8_t)u(5, buf, &StartBit);
        profile->general_profile_compatibility_flag = u(32, buf, &StartBit);
        profile->general_constraint_flags = (((uint64_t)u(32, buf, &StartBit)) << 16) | u(16, buf, &StartBit);
    }

    profile->general_level_idc = (uint8_t)u(8, buf, &StartBit);
    for (i = 0; i < maxNumSubLayersMinus1; i++){
        profile->sub_layer[i].sub_layer_profile_present_flag = (uint8_t)u(1, buf, &StartBit);
        profile->sub_layer[i].sub_layer_level_present_flag = (uint8_t)u(1, buf, &StartBit);
    }

    // align to byte
    if (maxNumSubLayersMinus1 > 0){
        for (i = maxNumSubLayersMinus1; i < 8; i++)
            u(2, buf, &StartBit); // reserved_zero_2bits
    }

    for (i = 0; i < maxNumSubLayersMinus1; i++){
        if (profile->sub_layer[i].sub_layer_profile_present_flag){
            profile->sub_layer[i].sub_layer_profile_space = (uint8_t)u(2, buf, &StartBit);
            profile->sub_layer[i].sub_layer_tier_flag = (uint8_t)u(1, buf, &StartBit);
            profile->sub_layer[i].sub_layer_profile_idc = (uint8_t)u(5, buf, &StartBit);
            profile->sub_layer[i].sub_layer_profile_compatibility_flag = u(32, buf, &StartBit);
            profile->sub_layer[i].sub_layer_constraint_flags = (((uint64_t)u(32, buf, &StartBit)) << 16) | u(16, buf, &StartBit);
        }
        if (profile->sub_layer[i].sub_layer_level_present_flag)
            profile->sub_layer[i].sub_layer_level_idc = (uint8_t)u(8, buf, &StartBit);
    }

    return 0;
}

//return: 0/false 1/success
int h265_decode_sps(unsigned char* buf, unsigned int nLen, int* width, int* height, int* fps,int* general_level_idc)
{
    unsigned int StartBit = 0;
    de_emulation_prevention(buf, &nLen);
    struct h265_profile_tier_level_t profile = { 0 };

    //--- nal_uint_header ---
    int forbidden_zero_bit = u(1, buf, &StartBit);
    int nal_unit_type = u(6, buf, &StartBit);
    if (nal_unit_type != 33)
        return 0;
    int nuh_layer_id = u(6, buf, &StartBit);
    int nuh_temporal_id_plus = u(3, buf, &StartBit);

    int sps_video_parameter_set_id = (uint8_t)u(4, buf, &StartBit);
    int sps_max_sub_layers_minus1 = (uint8_t)u(3, buf, &StartBit);
    int sps_temporal_id_nesting_flag = (uint8_t)u(1, buf, &StartBit);
    h265_profile_tier_level(&profile, 1, sps_max_sub_layers_minus1, buf, StartBit);


    int sps_seq_parameter_set_id = Ue(buf, nLen, &StartBit);
    int chroma_format_id = (uint8_t)Ue(buf, nLen, &StartBit);
    int separate_colour_plane_flag = 0;
    if (3 == chroma_format_id)
        separate_colour_plane_flag = (uint8_t)u(1, buf, &StartBit);

    int pic_width_in_luma_samples = Ue(buf, nLen, &StartBit);
    int pic_height_in_luma_samples = Ue(buf, nLen, &StartBit);
    int conformance_window_flag = u(1, buf, &StartBit);

    int conf_win_left_offset = 0;
    int conf_win_right_offset = 0;
    int conf_win_top_offset = 0;
    int conf_win_bottom_offset = 0;
    if (conformance_window_flag)
    {
        int conf_win_left_offset = Ue(buf, nLen, &StartBit);
        int conf_win_right_offset = Ue(buf, nLen, &StartBit);
        int conf_win_top_offset = Ue(buf, nLen, &StartBit);
        int conf_win_bottom_offset = Ue(buf, nLen, &StartBit);
        int sub_width_c = ((1 == chroma_format_id) || (2 == chroma_format_id)) && (0 == separate_colour_plane_flag) ? 2 : 1;
        int sub_height_c = (1 == chroma_format_id) && (0 == separate_colour_plane_flag) ? 2 : 1;
        *width = pic_width_in_luma_samples - (sub_width_c * conf_win_right_offset + sub_width_c * conf_win_left_offset);
        *height = pic_height_in_luma_samples - (sub_height_c * conf_win_bottom_offset + sub_height_c * conf_win_top_offset);
    }
    else {
        *width = pic_width_in_luma_samples;
        *height = pic_height_in_luma_samples;
    }

    *fps = 0;

    return 1;
}

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ww506772362

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值