⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 get_videoinfo.c

📁 6410BSP1
💻 C
📖 第 1 页 / 共 2 页
字号:
/////
///   get_videoinfo.c
///
///   Written by Simon Chun (simon.chun@samsung.com)
///   2008/06/16
///

#include <stdio.h>
#include <string.h>


#define NAL_UNIT_TYPE_TYPE(n)    ((0x001F) & (unsigned int) (n))


static int find_one(unsigned int bits8)
{
    if (bits8 >= 8)
        return 4;
    else if (bits8 >= 4)
        return 3;
    else if (bits8 >= 2)
        return 2;
    else if (bits8 == 1)
        return 1;

    return 0;
}

static int num_bits(unsigned int bits)
{
    if (bits & 0xFFFF0000) {
        if (bits & 0xF0000000) {
            return (find_one(bits >> 28) + 28);
        }
        else if (bits & 0x0F000000) {
            return (find_one(bits >> 24) + 24);
        }
        else if (bits & 0x00F00000) {
            return (find_one(bits >> 20) + 20);
        }
        else {
            return (find_one(bits) + 16);
        }
    }
    else if (bits & 0x0000FFFF) {
        if (bits & 0x0000F000) {
            return (find_one(bits >> 12) + 12);
        }
        else if (bits & 0x00000F00) {
            return (find_one(bits >> 8) + 8);
        }
        else if (bits & 0x000000F0) {
            return (find_one(bits >> 4) + 4);
        }
        else {
            return find_one(bits);
        }
    }

    return 0;
}

static unsigned int read_bits(unsigned char bytes[], int num_read, int *bit_offset)
{
    unsigned int   bits;
    unsigned int   utmp;

    int            i;
    int            bit_shift;

    int   byte_offset, bit_offset_in_byte;
    int   num_bytes_copy;


    if (num_read > 24)    // Max 24 bits鳖瘤父 瘤盔等促.
        return 0xFFFFFFFF;
    if (num_read == 0)
        return 0;


    // byte_offset苞
    // 弊 byte 郴俊辑 bit_offset阑 备茄促.
    byte_offset = (*bit_offset) >> 3;    // byte_offset = (*bit_offset) / 8
    bit_offset_in_byte = (*bit_offset) - (byte_offset << 3);


    num_bytes_copy = ((*bit_offset + num_read) >> 3) - (*bit_offset >> 3) + 1;
    bits = 0;
    for (i=0; i<num_bytes_copy; i++) {
        utmp = bytes[byte_offset + i];
        bits = (bits << 8) | (utmp);
    }

    bit_shift = (num_bytes_copy << 3) - (bit_offset_in_byte + num_read);
    bits >>= bit_shift;
    bits &= (0xFFFFFFFF >> (32 - num_read));

    *bit_offset += num_read;

    return bits;
}

// unsigned integer Exp-Golomb-codec element with the left bit first.
// The parsing process for this descriptor is specified in subclause 9.1 (ITU-T Rec. H.264).
static unsigned int ue_v(unsigned char bytes[], int *bit_offset)
{
    unsigned int   b;
    int            leadingZeroBits = -1;
    unsigned int   codeNum;


    for (b=0; !b; leadingZeroBits++) {
        b = read_bits(bytes, 1, bit_offset);
    }

    // codeNum = 2^(leadingZeroBits) - 1 + read_bits(leadingZeroBits)
    codeNum = (1 << leadingZeroBits) - 1 + read_bits(bytes, leadingZeroBits, bit_offset);


    return codeNum;
}

// signed integer Exp-Golomb-codec element with the left bit first.
// The parsing process for this descriptor is specified in subclause 9.1 (ITU-T Rec. H.264).
static signed int se_v(unsigned char bytes[], int *bit_offset)
{
    signed int   b;
    int          leadingZeroBits = -1;
    signed int   codeNum;


    for (b=0; !b; leadingZeroBits++) {
        b = read_bits(bytes, 1, bit_offset);
    }

    // codeNum = 2^(leadingZeroBits) - 1 + read_bits(leadingZeroBits)
    codeNum = (1 << leadingZeroBits) - 1 + read_bits(bytes, leadingZeroBits, bit_offset);


    return codeNum;
}

static unsigned int u_n(unsigned char bytes[], int n_bits, int *bit_offset)
{
    return read_bits(bytes, n_bits, bit_offset);
}


int get_h264_info(unsigned char *sps, int sps_leng, int *profile_idc, int *width, int *height)
{
    int                loop_exit = 0;
    unsigned int       delimiter;
    unsigned char     *pdat, *p_vos_end;


    int                j;
    int                bit_offset;
    unsigned char      utmp, utmp2;
    int                itmp;

    unsigned char      PicHeightInMapUnits;
    unsigned char      FrameHeightInMbs;
    unsigned char      PicHeightInMbs;

    unsigned int       log2_max_frame_num_minus4 = 0;
    unsigned int       frame_mbs_only_flag = 0;


    pdat       = sps;
    p_vos_end  = sps + sps_leng;
    do {

        delimiter = pdat[0];
        delimiter = (delimiter << 8) | pdat[1];
        delimiter = (delimiter << 8) | pdat[2];
        delimiter = (delimiter << 8) | pdat[3];
        pdat += 4;


        while (pdat != p_vos_end) {
            if (delimiter == 0x00000001)
                break;

            delimiter = (delimiter << 8) | *pdat;
            pdat++;
        }

        switch (NAL_UNIT_TYPE_TYPE(*pdat)) {
        case 7:        // SPS (Sequence Parameter Set)
            pdat++;
            bit_offset = 0;


            *profile_idc = u_n(pdat, 8, &bit_offset);        // profile_idc

            utmp = u_n(pdat, 1, &bit_offset);        // constraint_set0_flag
            utmp = u_n(pdat, 1, &bit_offset);        // constraint_set1_flag
            utmp = u_n(pdat, 1, &bit_offset);        // constraint_set2_flag
            utmp = u_n(pdat, 1, &bit_offset);        // constraint_set3_flag
            utmp = u_n(pdat, 4, &bit_offset);        // reserved_zero_4bits
            utmp = u_n(pdat, 8, &bit_offset);        // level_idc


            utmp = ue_v(pdat, &bit_offset);            // seq_parameter_set_id
            if ((*profile_idc == 100) || (*profile_idc == 110) ||
                (*profile_idc == 122) || (*profile_idc == 144)) {

                utmp = ue_v(pdat, &bit_offset);        // chroma_format_idc
                if( utmp == 3 )
                    utmp = u_n(pdat, 1, &bit_offset);        // residual_colour_transform_flag
                utmp = ue_v(pdat, &bit_offset);        // bit_depth_luma_minus8
                utmp = ue_v(pdat, &bit_offset);        // bit_depth_chroma_minus8
                utmp = u_n(pdat, 1, &bit_offset);        // qpprime_y_zero_transform_bypass_flag
                utmp = u_n(pdat, 1, &bit_offset);        // seq_scaling_matrix_present_flag

                if (utmp) {
                    return -1;        // In this case, the parsing routine does not support.
                }
                    
            }


            log2_max_frame_num_minus4
                = ue_v(pdat, &bit_offset);            // log2_max_frame_num_minus4


            utmp = ue_v(pdat, &bit_offset);            // pic_order_cnt_type
            if (utmp == 0)
                utmp = ue_v(pdat, &bit_offset);        // log2_max_pic_order_cnt_lsb_minus4
            else if (utmp == 1) {
                utmp = u_n(pdat, 1, &bit_offset);    // delta_pic_order_always_zero_flag
                itmp = se_v(pdat, &bit_offset);        // offset_for_non_ref_pic
                itmp = se_v(pdat, &bit_offset);        // offset_for_non_ref_pic
                utmp = ue_v(pdat, &bit_offset);        // num_ref_frames_in_pic_order_cnt_cycle
                for (j = 0; j < (int) utmp; j++)
                    se_v(pdat, &bit_offset);
            }
            utmp = ue_v(pdat, &bit_offset);            // num_ref_frames
            utmp = u_n(pdat, 1, &bit_offset);        // gaps_in_frame_num_value_allowed_flag

            // Picture Width
            utmp = ue_v(pdat, &bit_offset);            // pic_width_in_mbs_minus1
            *width = ((unsigned int) (utmp + 1)) << 4;    // width = (pic_width_in_mbs_minus1 + 1) * 16

            // Picture Height
            utmp  = ue_v(pdat, &bit_offset);        // pic_height_in_map_units_minus1
            utmp2 = u_n(pdat, 1, &bit_offset);        // frame_mbs_only_flag
            frame_mbs_only_flag = utmp2;            // frame_mbs_only_flag

            PicHeightInMapUnits = utmp + 1;
            FrameHeightInMbs    = (2 - utmp2) * PicHeightInMapUnits;
            PicHeightInMbs      = FrameHeightInMbs;// / (1 + field_pic_flag);
            *height             = ((unsigned int) PicHeightInMbs) << 4;


            // 
            if (!frame_mbs_only_flag)
                utmp = u_n(pdat, 1, &bit_offset);    // mb_adaptive_frame_field_flag
            utmp = u_n(pdat, 1, &bit_offset);        // direct_8x8_inference_flag
            utmp = u_n(pdat, 1, &bit_offset);        // frame_cropping_flag
            if (utmp) {
                utmp = ue_v(pdat, &bit_offset);        // frame_crop_left_offset
                utmp = ue_v(pdat, &bit_offset);        // frame_crop_right_offset
                utmp = ue_v(pdat, &bit_offset);        // frame_crop_top_offset
                utmp = ue_v(pdat, &bit_offset);        // frame_crop_bottom_offset

                *height = (*height - utmp);
            }



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -