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

📄 h263util.c

📁 基于intel ipp的h263_decoder
💻 C
字号:
/******************************************************************************
//               INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//        Copyright (c) 2003 Intel Corporation. All Rights Reserved.
//
//  Description:
//    Intel(R) Integrated Performance Primitives Sample Code H263 Decoder
//
//  Table List:
//    read_stream_bits()
//    preview_stream_bits()
//    skip_stream_bits()
//    seek_next_sync_code_h263()
//    insert_stream_bits_bytealign()
//
******************************************************************************/
#include "samph263.h"
#include <stdlib.h>
#include <string.h>

/******************************************************************************
// Function Name:   read_stream_bits
//
// Description:     Read a certain number of bits from stream, stream position
//                  pointer is updated to pointer to next byte for reading.
//
// Parameter:
// Input:
//        stream:   Pointer to sample_bitstream structure holding input stream
//      bits_len:   Number of bits to be read, max number is 32 bits.
// Output:
//        stream:   Pointer to sample_bitstream structure holding input stream
//                  Stream position pointer is updated to next available byte
//          data:   Pointer to output data
//
// Return:
//          TRUE:   Succeeds
//         FALSE:   Read fails
//
// Notes:   None
******************************************************************************/
SAMPLE_BOOL read_stream_bits(sample_bitstream *stream,
                             int              bits_len, 
                             unsigned int     *data)
{
    int i;
    int max_buf_bytes  =   stream->bs_bytelen;
    int pad_bits_len   =   stream->bs_cur_bitoffset;
    int read_byte_len  =   (bits_len+pad_bits_len+7)/8;
    int write_byte_len =   (bits_len+7)/8;  
    unsigned char *cur =   (unsigned char*)data+write_byte_len-1;
    
    if (read_byte_len>(max_buf_bytes-(stream->bs_cur_byte-stream->bs_buffer))) {
        return FALSE;
    }

    for (i=0; i<write_byte_len-1; i++) {
        *cur = (unsigned char)((stream->bs_cur_byte[i] << pad_bits_len) |
               (stream->bs_cur_byte[i+1] >> (8-pad_bits_len)));
        cur --;
    }
    *cur = (unsigned char)((stream->bs_cur_byte[i] << pad_bits_len) |
           (stream->bs_cur_byte[i+1] >> (8-pad_bits_len)));
    
    stream->bs_cur_bitoffset = (pad_bits_len+bits_len)%8;
    stream->bs_cur_byte += (stream->bs_cur_bitoffset==0)?
                            read_byte_len:(read_byte_len-1);

    if(0 != (bits_len % 8) && 32 >= bits_len) {
        Ipp32u *temp = (Ipp32u*)cur;
        *temp >>= (8-(bits_len % 8));
    }

    return TRUE;
}

/******************************************************************************
// Function Name:   preview_stream_bits
//
// Description:     Read a certain number of bits from stream, stream position
//                  pointer isn't updated after reading.
//
// Parameter:
// Input:
//        stream:   Pointer to sample_bitstream structure holding input stream
//      bits_len:   Number of bits to be read, max number is 32 bits.
// Output:
//          data:   Pointer to output data
//
// Return:
//          TRUE:   Succeeds
//         FALSE:   Read fails
//
// Notes:   None
******************************************************************************/
SAMPLE_BOOL preview_stream_bits(sample_bitstream *stream,
                                int              bits_len, 
                                unsigned int     *data)
{
    /* stream pointer is before the unfinished byte */
    int i;
    int max_buf_bytes  =   stream->bs_bytelen;
    int pad_bits_len   =   stream->bs_cur_bitoffset;
    int read_byte_len  =   (bits_len+pad_bits_len+7)/8;
    int write_byte_len =   (bits_len+7)/8;  
    unsigned char *cur =   (unsigned char*)data+write_byte_len-1;
    
    if (read_byte_len>(max_buf_bytes-(stream->bs_cur_byte-stream->bs_buffer))) {
        return FALSE;
    }

    for (i=0; i<write_byte_len-1; i++) {
        *cur = (unsigned char)((stream->bs_cur_byte[i] << pad_bits_len) |
               (stream->bs_cur_byte[i+1] >> (8-pad_bits_len)));
        cur --;
    }
    *cur = (unsigned char)((stream->bs_cur_byte[i] << pad_bits_len) |
           (stream->bs_cur_byte[i+1] >> (8-pad_bits_len)));
    
    if(0 != (bits_len % 8) && 32 >= bits_len) {
        unsigned int *temp = (Ipp32u*)cur;
        *temp >>= (8-(bits_len % 8));
    }

    return TRUE;
}

/******************************************************************************
// Function Name:   skip_stream_bits
//
// Description:     Skip a certain number of bits from stream, stream position
//                  pointer is updated accordingly.
//
// Parameter:
// Input:
//        stream:   Pointer to sample_bitstream structure holding input stream
//      bits_len:   Number of bits to be read, max number is 32 bits.
// Output:
//        stream:   Pointer to sample_bitstream structure holding input stream
//                  Stream position pointer is updated to next available byte
//
// Return:
//          TRUE:   Succeeds
//         FALSE:   Read fails
//
// Notes:   None
******************************************************************************/
SAMPLE_BOOL skip_stream_bits(sample_bitstream *stream,
                             int              bits_len)
{
    int pad_bits_len   =   stream->bs_cur_bitoffset;
    int max_buf_bytes  =   stream->bs_bytelen;
    int read_byte_len  =   (bits_len+pad_bits_len+7)/8;
    
    if (read_byte_len>(max_buf_bytes-(stream->bs_cur_byte-stream->bs_buffer))) {
        return FALSE;
    }

    stream->bs_cur_bitoffset += (bits_len % 8);
    stream->bs_cur_byte += bits_len / 8;
    if(8 <= stream->bs_cur_bitoffset) {
        stream->bs_cur_bitoffset -= 8;
        stream->bs_cur_byte      += 1;
    } 

    return TRUE;
}

/******************************************************************************
// Function Name:   seek_next_sync_code_h263
//
// Description:     Seek next sync code from stream, stream position
//                  pointer isn't updated after seek.
//
// Parameter:
// Input:
//          stream: Pointer to sample_bitstream structure holding input stream
//       sync_code: Sync code value to seek
//   sync_code_len: Sync code length in number of bits, max lenth is 32 bits.
// is_byte_aligned: Indicator if this sync_code is byte aligned in stream
//seek_byte_offset: Seek starting adress offset from current stream pointer
//   seek_byte_len: The seeking range in number of bytes in stream
//                  0 means infinite, seek till bitstream end.
// Output:
//          None
// Return:
//            TRUE: The sync code is found
//           FALSE: The sync code isn't found
//
// Notes:           The seek range is stream->bs_cur_byte+seek_byte_offset
//                  to stream->bs_cur_byte+seek_byte_len or the end of stream
******************************************************************************/
SAMPLE_BOOL seek_next_sync_code_h263(sample_bitstream  *stream, 
                                     unsigned int      sync_code, 
                                     int               sync_code_len,
                                     int               is_byte_aligned,
                                     int               seek_byte_offset,
                                     int               seek_byte_len)
{
    unsigned int  data_reg   = 0; 
    unsigned char *cur_byte  = stream->bs_cur_byte;
    int           bit_offset = stream->bs_cur_bitoffset;
    int           byte_range = stream->bs_buffer + stream->bs_bytelen 
                                - stream->bs_cur_byte - seek_byte_offset;
    int           limit      = (seek_byte_len==0)?byte_range:seek_byte_len;

    if(!STREAM_CHECK_BYTE_ALIGN(stream) && is_byte_aligned) {
        STREAM_BYTE_ALIGN(stream);
    }

    stream->bs_cur_byte += seek_byte_offset;
    
    if(is_byte_aligned) {
        while(preview_stream_bits(stream, sync_code_len, &data_reg) && 
            stream->bs_cur_byte-cur_byte<limit) {
            if(data_reg == sync_code) {
                /* Restore stream pointer */
                stream->bs_cur_bitoffset = bit_offset;
                stream->bs_cur_byte      = cur_byte;
                return TRUE;
            }
            stream->bs_cur_byte ++;
            data_reg = 0;
        }
    } else {
        while(0<limit && preview_stream_bits(stream, sync_code_len, &data_reg) ) {
            if(data_reg == sync_code) {
                /* Restore stream pointer */
                stream->bs_cur_bitoffset = bit_offset;
                stream->bs_cur_byte      = cur_byte;
                return TRUE;
            }
            stream->bs_cur_bitoffset ++;
            if(stream->bs_cur_bitoffset == 8) {
                stream->bs_cur_bitoffset = 0;
                stream->bs_cur_byte      ++;
            }
            limit --;
            data_reg = 0;
        }
    }

    /* Restore stream pointer */
    stream->bs_cur_bitoffset = bit_offset;
    stream->bs_cur_byte      = cur_byte;
    
    return FALSE;
}

/******************************************************************************
// Function Name:   insert_stream_bits_bytealign
//
// Description:     Insert data into the end of stream, the data is byte 
//                  aligned
//
// Parameter:
// Input:
//        stream:   Pointer to sample_bitstream structure holding input stream
//      bits_len:   Number of bits to be inserted
//          data:   Pointer to the data to be inserted
// Output:
//        stream:   Pointer to sample_bitstream structure holding stream,
//                  stream length is updated after inserting.
//
// Return:
//          TRUE:   Succeeds
//         FALSE:   Insert fails
//
// Notes:   None
******************************************************************************/
SAMPLE_BOOL insert_stream_bits_bytealign(sample_bitstream *stream, 
                                         int              bits_len,
                                         unsigned int     data)
{
    int           remain_data;
    unsigned char *stream_end;
    int           i;

    if((stream->bs_bytelen + bits_len/8) > stream->bs_bytelen) {
        /* No space for inserted bits, reload first */
        remain_data = stream->bs_buffer + stream->bs_bytelen
                      - stream->bs_cur_byte + 1;
        if (remain_data + bits_len/8 > stream->bs_bytelen) {
            return FALSE;
        }

        memcpy(stream->bs_buffer, stream->bs_cur_byte, remain_data);        
        stream->bs_bytelen = remain_data;
        stream->bs_cur_byte = stream->bs_buffer;
    }

    stream_end = stream->bs_buffer + stream->bs_bytelen;
    for(i=bits_len; i>0; i-=8) {
        if((i-8)>0) {
            *stream_end++ = (unsigned char)(((data >> (i-8)) & 0xff));
        } else {
            *stream_end++ = (unsigned char)(((data << (8-i)) & 0xff));
        }
    }

    stream->bs_bytelen += (bits_len+7)/8;

    return TRUE;
}

/* EOF */

⌨️ 快捷键说明

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