H265的sps解析

可以通过很多方法,这里参考一个简答方法:

简答修改了一下:

from: http://read.pudn.com/downloads760/sourcecode/multimedia/streaming/3021379/test_h265_sps/h265_sps_prase.c__.htm

#ifndef h265_decode_info_h__
#define h265_decode_info_h__


#include <iostream>   
#include <sstream>   
//#include <unistd.h>  
#include <stdint.h>
#include <stdio.h>   
#include <string.h>   
#include <stdlib.h>

struct vc_params_t
{
    LONG width, height;
    DWORD profile, level;
    DWORD nal_length_size;
    void clear()
    {
        memset(this, 0, sizeof(*this));
    }
};

class NALBitstream
{
public:
    NALBitstream() : m_data(NULL), m_len(0), m_idx(0), m_bits(0), m_byte(0), m_zeros(0) {};
    NALBitstream(void * data, int len) { Init(data, len); };
    void Init(void * data, int len) { m_data = (LPBYTE)data; m_len = len; m_idx = 0; m_bits = 0; m_byte = 0; m_zeros = 0; };


    BYTE GetBYTE()
    {
        printf("m_idx=%d,m_len=%d\n", m_idx, m_len);
        if (m_idx >= m_len)
            return 0;
        BYTE b = m_data[m_idx++];

        // to avoid start-code emulation, a byte 0x03 is inserted   
        // after any 00 00 pair. Discard that here.   
        if (b == 0)
        {
            m_zeros++;
            if ((m_idx < m_len) && (m_zeros == 2) && (m_data[m_idx] == 0x03))
            {

                m_idx++;
                m_zeros = 0;
            }
        }

        else
        {
            m_zeros = 0;

        }
        return b;
    };


    UINT32 GetBit()
    {
        printf("m_bits=%d\n", m_bits);
        if (m_bits == 0)
        {
            m_byte = GetBYTE();
            m_bits = 8;

        }
        m_bits--;
        return (m_byte >> m_bits) & 0x1;
    };

    UINT32 GetWord(int bits)
    {

        UINT32 u = 0;
        while (bits > 0)

        {
            u <<= 1;
            u |= GetBit();
            bits--;
        }
        return u;
    };
    UINT32 GetUE()
    {

        // Exp-Golomb entropy coding: leading zeros, then a one, then   
        // the data bits. The number of leading zeros is the number of   
        // data bits, counting up from that number of 1s as the base.   
        // That is, if you see   
        //      0001010   
        // You have three leading zeros, so there are three data bits (010)   
        // counting up from a base of 111: thus 111 + 010 = 1001 = 9   
        int zeros = 0;
        while (m_idx < m_len && GetBit() == 0) zeros++;
        return GetWord(zeros) + ((1 << zeros) - 1);
    };


    INT32 GetSE()
    {

        // same as UE but signed.   
        // basically the unsigned numbers are used as codes to indicate signed numbers in pairs   
        // in increasing value. Thus the encoded values   
        //      0, 1, 2, 3, 4   
        // mean   
        //      0, 1, -1, 2, -2 etc   
        UINT32 UE = GetUE();
        bool positive = UE & 1;
        INT32 SE = (UE + 1) >> 1;
        if (!positive)
        {
            SE = -SE;
        }
        return SE;
    };


private:
    LPBYTE m_data;
    int m_len;
    int m_idx;
    int m_bits;
    BYTE m_byte;
    int m_zeros;
};


bool  ParseSequenceParameterSet(BYTE* data, int size, vc_params_t& params)
{
    if (size < 20)
    {
        return false;
    }

    NALBitstream bs(data, size);

    // seq_parameter_set_rbsp()   
    bs.GetWord(4);// sps_video_parameter_set_id   
    int sps_max_sub_layers_minus1 = bs.GetWord(3); // "The value of sps_max_sub_layers_minus1 shall be in the range of 0 to 6, inclusive."   
    if (sps_max_sub_layers_minus1 > 6)
    {
        return false;
    }
    bs.GetWord(1);// sps_temporal_id_nesting_flag   
                  // profile_tier_level( sps_max_sub_layers_minus1 )   
    {
        bs.GetWord(2);// general_profile_space   
        bs.GetWord(1);// general_tier_flag   
        params.profile = bs.GetWord(5);// general_profile_idc   
        bs.GetWord(32);// general_profile_compatibility_flag[32]   
        bs.GetWord(1);// general_progressive_source_flag   
        bs.GetWord(1);// general_interlaced_source_flag   
        bs.GetWord(1);// general_non_packed_constraint_flag   
        bs.GetWord(1);// general_frame_only_constraint_flag   
        bs.GetWord(44);// general_reserved_zero_44bits   
        params.level = bs.GetWord(8);// general_level_idc   
        unsigned char sub_layer_profile_present_flag[6] = { 0 };
        unsigned char sub_layer_level_present_flag[6] = { 0 };
        for (int i = 0; i < sps_max_sub_layers_minus1; i++)
        {
            sub_layer_profile_present_flag[i] = bs.GetWord(1);
            sub_layer_level_present_flag[i] = bs.GetWord(1);
        }
        if (sps_max_sub_layers_minus1 > 0)
        {
            for (int i = sps_max_sub_layers_minus1; i < 8; i++)
            {
                unsigned char reserved_zero_2bits = bs.GetWord(2);
            }
        }
        for (int i = 0; i < sps_max_sub_layers_minus1; i++)
        {
            if (sub_layer_profile_present_flag[i])
            {
                bs.GetWord(2);// sub_layer_profile_space[i]   
                bs.GetWord(1);// sub_layer_tier_flag[i]   
                bs.GetWord(5);// sub_layer_profile_idc[i]   
                bs.GetWord(32);// sub_layer_profile_compatibility_flag[i][32]   
                bs.GetWord(1);// sub_layer_progressive_source_flag[i]   
                bs.GetWord(1);// sub_layer_interlaced_source_flag[i]   
                bs.GetWord(1);// sub_layer_non_packed_constraint_flag[i]   
                bs.GetWord(1);// sub_layer_frame_only_constraint_flag[i]   
                bs.GetWord(44);// sub_layer_reserved_zero_44bits[i]   
            }
            if (sub_layer_level_present_flag[i])
            {
                bs.GetWord(8);// sub_layer_level_idc[i]   
            }
        }
    }
    unsigned long sps_seq_parameter_set_id = bs.GetUE(); // "The  value  of sps_seq_parameter_set_id shall be in the range of 0 to 15, inclusive."   
    if (sps_seq_parameter_set_id > 15)
    {
        return false;
    }
    unsigned long chroma_format_idc = bs.GetUE(); // "The value of chroma_format_idc shall be in the range of 0 to 3, inclusive."   
    if (sps_seq_parameter_set_id > 3)
    {
        return false;
    }
    if (chroma_format_idc == 3)
    {
        bs.GetWord(1);// separate_colour_plane_flag   
    }
    params.width = bs.GetUE(); // pic_width_in_luma_samples   
    params.height = bs.GetUE(); // pic_height_in_luma_samples   
    if (bs.GetWord(1))
    {// conformance_window_flag   
        bs.GetUE();  // conf_win_left_offset   
        bs.GetUE();  // conf_win_right_offset   
        bs.GetUE();  // conf_win_top_offset   
        bs.GetUE();  // conf_win_bottom_offset   
    }
    unsigned long bit_depth_luma_minus8 = bs.GetUE();
    unsigned long bit_depth_chroma_minus8 = bs.GetUE();
    if (bit_depth_luma_minus8 != bit_depth_chroma_minus8)
    {
        return false;
    }
    //...   


    return true;
}

// int main(int argc, _TCHAR* argv[])
// {
//     vc_params_t params = { 0 };
//     //BYTE Sps[41] = {0X42,0X01,0X01,0X01,0X60,0X00,0X00,0X03,0X00,0X80,0X00,0X00,0X03,0X00,0X00,0X03,0X00,0X5D,0XA0,0X02,0X80,0X80,0X2D,0X16,0X59,0X5E,0X49,0X32,0XB8,0X04,0X00,0X00,0X03,0X00,0X04,0X00,0X00,0X03,0X00,0X64,0X20};   
//     BYTE Sps[] = { 0X42,0X01,0X01,0X01,0X60,0X00,0X00,0X03,0X00,0Xb0,0X00,0X00,0X03,0X00,0X00,0X03,0X00,0X7b,0XA0,0X03,0Xc0,0X80,0X10,0Xe5,0X8d,0Xaa,0X92,0X4c,0Xbe,0X40 };
//     ParseSequenceParameterSet(Sps, 30, params);
//     printf("%d-%d-%d\n", params.width, params.height, params.level);
//     //system("pause");   
//     return 0;
// }


#endif // h265_decode_info_h__
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值