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

📄 mpeg4frames.c

📁 6410BSP3
💻 C
字号:
/////
///   MPEG4Frames.c
///
///   Written by Simon Chun (simon.chun@samsung.com)
///   2007/03/23
///

#include <stdio.h>
#include "FrameExtractor.h"
#include "MPEG4Frames.h"


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


int ExtractConfigStreamMpeg4(FRAMEX_CTX  *pFrameExCtx,
                             void *fp,
                             unsigned char buf[],
                             int buf_size,
                             MPEG4_CONFIG_DATA *conf_data)
{
    int                i;
    int                ret;
    unsigned char      frame_type[4];
    int                nStreamSize, nFrameSize;
    int                includeIframe=1;
    unsigned int       coding_type;

    int                bit_offset;
    int                nbits;
    unsigned char      utmp, *ptmp;
    unsigned int       video_object_layer_shape, vop_time_increment_resolution;


    for (i=0, nStreamSize=0; i<30; i++) {

        ret = FrameExtractorPeek(pFrameExCtx, fp, frame_type, sizeof(frame_type), (int *)&nFrameSize);
        if (frame_type[3] == 0xB6) {
            break;
        }

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

        if ((buf[nStreamSize + 3] & 0xF0) == 0x20) {    // Video Object Layer
            ptmp = buf + nStreamSize + 4;
            bit_offset = 0;

            if (conf_data != NULL) {

                utmp = read_bits(ptmp, 1, &bit_offset);        // random_accessible_vol
                utmp = read_bits(ptmp, 8, &bit_offset);        // video_object_type_indication
                utmp = read_bits(ptmp, 1, &bit_offset);        // is_object_layer_identifier
                if (utmp) {
                    utmp = read_bits(ptmp, 4, &bit_offset);        // video_object_layer_verid
                    utmp = read_bits(ptmp, 3, &bit_offset);        // video_object_layer_priority
                }
                utmp = read_bits(ptmp, 4, &bit_offset);        // aspect_ratio_info
                if (utmp == 15) {
                    // aspect_ratio_info == extended_PAR (0x0F)
                    utmp = read_bits(ptmp, 8, &bit_offset);        // par_width
                    utmp = read_bits(ptmp, 8, &bit_offset);        // par_height
                }
                utmp = read_bits(ptmp, 1, &bit_offset);        // vol_control_parameters
                if (utmp) {
                    bit_offset += 3;
                    utmp = read_bits(ptmp, 1, &bit_offset);        // vbv_parameters
                    if (utmp) {
                        bit_offset += 63;
                    }
                }

                video_object_layer_shape = read_bits(ptmp, 2, &bit_offset);        // video_object_layer_shape


                utmp = read_bits(ptmp, 1, &bit_offset);        // marker_bit
                vop_time_increment_resolution = read_bits(ptmp, 16, &bit_offset);    // vop_time_increment_resolution
                utmp = read_bits(ptmp, 1, &bit_offset);        // marker_bit
                utmp = read_bits(ptmp, 1, &bit_offset);        // fixed_vop_rate
                if (utmp) {
                    nbits = num_bits(vop_time_increment_resolution);
                    utmp  = read_bits(ptmp, nbits, &bit_offset);    // fixed_vop_time_increment
                }

                if (video_object_layer_shape == 0) {
                    utmp = read_bits(ptmp, 1, &bit_offset);        // marker_bit
                    conf_data->width   = read_bits(ptmp, 13, &bit_offset);    // video_object_layer_width
                    utmp = read_bits(ptmp, 1, &bit_offset);        // marker_bit
                    conf_data->height  = read_bits(ptmp, 13, &bit_offset);    // video_object_layer_height
                    utmp = read_bits(ptmp, 1, &bit_offset);        // marker_bit
                }
                utmp = read_bits(ptmp, 1, &bit_offset);        // interlaced
            }
        }
        else if (buf[nStreamSize + 3] == 0xB3) {    // GOV牢 版快,,, skip
            continue;
        }


        nStreamSize += nFrameSize;
    }


    // includeIframe 啊 1牢 版快绰
    // 府畔登绰 config stream俊 I-frame阑 器窃矫懦瘤 搬沥茄促.
    if (includeIframe == 1) {
        nFrameSize = NextFrameMpeg4(pFrameExCtx, fp, buf + nStreamSize, buf_size - nStreamSize, &coding_type);

        nStreamSize += nFrameSize;
    }


    return nStreamSize;
}


int NextFrameMpeg4(FRAMEX_CTX  *pFrameExCtx, void *fp, unsigned char buf[], int buf_size, unsigned int *coding_type)
{
    int                i;
    int                ret;
    int                nStreamSize, nFrameSize;

    int                bit_offset;



    nStreamSize=0;

    for (i=0; i<20; i++) {
        ret = FrameExtractorNext(pFrameExCtx, fp, buf + nStreamSize, buf_size - nStreamSize, (int *)&nFrameSize);
        if (ret != FRAMEX_OK)
            return 0;

        if (buf[nStreamSize + 3] == 0xB6) {    // VIDEO OBJECT牢 版快俊 府畔
            if (coding_type) {
                bit_offset = 0;
                *coding_type = read_bits(buf + nStreamSize + 4, 2, &bit_offset);        // vop_coding_type
            }

            nStreamSize += nFrameSize;
            break;
        }
        else if (buf[nStreamSize + 3] == 0xB3) {    // GOV牢 版快,,, skip
            continue;
        }

        nStreamSize += nFrameSize;
    }

    return nStreamSize;
}

⌨️ 快捷键说明

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