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

📄 h264frames.c

📁 6410BSP3
💻 C
📖 第 1 页 / 共 2 页
字号:
/////
///   H264Frames.c
///
///   Written by Simon Chun (simon.chun@samsung.com)
///   2007/03/13
///   2007/07/18
///   2007/08/31
///   2007/10/05
///

#include <stdio.h>
#include <string.h>
#include "FrameExtractor.h"
#include "H264Frames.h"


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


typedef struct tagH264_SLICE_INFO
{
    unsigned int   first_mb;
    unsigned short slice_type;
    unsigned short pic_parameter_set_id;
    unsigned int   frame_num;
} H264_SLICE_INFO;


// SPS 单捞磐俊 甸绢啊 乐绰 颇扼固磐
static unsigned int   log2_max_frame_num_minus4 = 0;
static unsigned int   frame_mbs_only_flag = 0;
// PPS ID 硅凯
static unsigned short pic_parameter_set_id_arr[32] = {0xFFFF, };
static void add_pps_id(unsigned short pic_parameter_set_id)
{
    int  i;

    for (i=0; i<32; i++) {
        if (pic_parameter_set_id_arr[i] == pic_parameter_set_id)
            break;
        if (pic_parameter_set_id_arr[i] == 0xFFFF) {
            pic_parameter_set_id_arr[i] = pic_parameter_set_id;
            break;
        }
    }
}
static int find_pps_id(unsigned short pic_parameter_set_id)
{
    int  i;

    for (i=0; i<32; i++) {
        if (pic_parameter_set_id_arr[i] == pic_parameter_set_id)
            return 1;
    }
    return 0;
}


static int NextIFrameH264(FRAMEX_CTX  *pFrameExCtx, void *fp, unsigned char buf[], int buf_size);


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);
}


static void get_h264_slice_info(unsigned char slice_header[], H264_SLICE_INFO *h264_slice_info)
{
    unsigned int   utmp = 0;
    int            bit_offset;

    bit_offset = 0;

    h264_slice_info->first_mb              = ue_v(slice_header, &bit_offset);
    h264_slice_info->slice_type            = ue_v(slice_header, &bit_offset);
    h264_slice_info->pic_parameter_set_id  = ue_v(slice_header, &bit_offset);
    h264_slice_info->frame_num             = u_n(slice_header, log2_max_frame_num_minus4 + 4, &bit_offset);

#if 1
    if (!frame_mbs_only_flag) {
        utmp = u_n(slice_header, 1, &bit_offset);        // field_pic_flag
        if (utmp)
            utmp = u_n(slice_header, 1, &bit_offset);    // bottom_field_flag
    }

#endif
}




int ExtractConfigStreamH264(FRAMEX_CTX  *pFrameExCtx,
                            void *fp,
                            unsigned char buf[],
                            int buf_size,
                            H264_CONFIG_DATA *conf_data)
{
    int                i, j;
    int                ret;
    unsigned char      frame_type[10];
    unsigned char      nal_type;
    int                nStreamSize, nFrameSize;
    int                includeIframe=1;

    int                bit_offset;
    unsigned char      profile_idc, utmp, utmp2, *ptmp;
    int                itmp;


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


    // PPS ID狼 硅凯阑 檬扁拳 茄促.
    memset(pic_parameter_set_id_arr, 0xFF, sizeof(pic_parameter_set_id_arr));

    // SPS/PPS/SEI 何盒 眠免
    for (i=0, nStreamSize=0; i<100; i++) {

        ret = FrameExtractorPeek(pFrameExCtx, fp, frame_type, sizeof(frame_type), (int *)&nFrameSize);
        nal_type = NAL_UNIT_TYPE_TYPE(frame_type[4]);

        if ((nal_type != 6) && (nal_type != 7) && (nal_type != 8) && (nal_type != 9)) {
            break;
        }

        ret = FrameExtractorNext(pFrameExCtx, fp, buf + nStreamSize, buf_size - nStreamSize, (int *)&nFrameSize);
        if (ret != FRAMEX_OK)
            break;

        // SPS case
        // (Extracting 'log2_max_frame_num_minus4' value for SPS NAL.)
        if (nal_type == 7) {
            ptmp = buf + nStreamSize + 5;

            bit_offset = 0;
            profile_idc = u_n(ptmp, 8, &bit_offset);        // profile_idc
            if ((profile_idc == 100) || (profile_idc == 110) ||
                (profile_idc == 122) || (profile_idc == 144)) {
                return -1;
            }

            utmp = u_n(ptmp, 1, &bit_offset);        // constraint_set0_flag
            utmp = u_n(ptmp, 1, &bit_offset);        // constraint_set1_flag
            utmp = u_n(ptmp, 1, &bit_offset);        // constraint_set2_flag
            utmp = u_n(ptmp, 1, &bit_offset);        // constraint_set3_flag
            utmp = u_n(ptmp, 4, &bit_offset);        // reserved_zero_4bits
            utmp = u_n(ptmp, 8, &bit_offset);        // level_idc
            utmp = ue_v(ptmp, &bit_offset);            // seq_parameter_set_id
            log2_max_frame_num_minus4
                = ue_v(ptmp, &bit_offset);            // log2_max_frame_num_minus4

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

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

⌨️ 快捷键说明

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