| /* /////////////////////////////////////////////////////////////////////// |
| // |
| // 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) 2001-2006 Intel Corporation. All Rights Reserved. |
| // |
| // Description: h264 bistream decoding |
| // |
| ///////////////////////////////////////////////////////////////////////*/ |
| |
| |
| #include "h264.h" |
| #include "h264parse.h" |
| #include "viddec_parser_ops.h" |
| #include "viddec_pm_utils_bstream.h" |
| #include "viddec_pm.h" |
| #include "vbp_trace.h" |
| |
| |
| /** |
| get_codeNum :Get codenum based on sec 9.1 of H264 spec. |
| @param cxt : Buffer adress & size are part inputs, the cxt is updated |
| with codeNum & sign on sucess. |
| Assumption: codeNum is a max of 32 bits |
| |
| @retval 1 : Sucessfuly found a code num, cxt is updated with codeNum, sign, and size of code. |
| @retval 0 : Couldn't find a code in the current buffer. |
| be freed. |
| */ |
| |
| uint32_t h264_get_codeNum(void *parent, h264_Info* pInfo) |
| { |
| int32_t leadingZeroBits= 0; |
| uint32_t temp = 0, match = 0, noOfBits = 0, count = 0; |
| uint32_t codeNum =0; |
| uint32_t bits_offset =0, byte_offset =0; |
| uint8_t is_emul =0; |
| uint8_t is_first_byte = 1; |
| uint32_t length =0; |
| uint32_t bits_need_add_in_first_byte =0; |
| int32_t bits_operation_result=0; |
| |
| viddec_pm_utils_bstream_cxt_t *cxt = &((viddec_pm_cxt_t *)parent)->getbits; |
| viddec_pm_utils_bstream_buf_cxt_t* bstream = &cxt->bstrm_buf; |
| uint8_t curr_byte; |
| |
| bits_offset = bstream->buf_bitoff; |
| |
| uint32_t total_bits, act_bytes; |
| uint32_t isemul = 0; |
| uint8_t *curr_addr = bstream->buf + bstream->buf_index; |
| |
| uint32_t i = 0; |
| VTRACE("bstream->buf_bitoff = %d", bstream->buf_bitoff); |
| VTRACE("bstream->buf_index = %d", bstream->buf_index); |
| |
| while (!match) |
| { |
| curr_byte = *curr_addr++; |
| VTRACE("curr_byte = 0x%x", curr_byte); |
| if (cxt->phase >= 2 && curr_byte == 0x03) { |
| curr_byte = *curr_addr++; |
| isemul = 1; |
| cxt->phase = 0; |
| } |
| noOfBits = 8; |
| if (is_first_byte) |
| { |
| is_first_byte = 0; |
| if (bits_offset != 0) |
| { |
| noOfBits = 8 - bits_offset; |
| curr_byte = curr_byte << bits_offset; |
| } |
| } |
| else |
| { |
| cxt->phase = curr_byte? 0: cxt->phase + 1; |
| } |
| |
| if (curr_byte != 0) |
| { |
| count=1; |
| VTRACE("curr_byte & 0x80 = 0x%x", curr_byte & 0x80); |
| while (((curr_byte & 0x80) != 0x80) && (count <= noOfBits)) |
| { |
| VTRACE("curr_byte & 0x80 = 0x%x", curr_byte & 0x80); |
| count++; |
| curr_byte = curr_byte <<1; |
| } |
| match = 1; |
| leadingZeroBits += count; |
| } |
| else |
| { |
| leadingZeroBits += noOfBits; |
| } |
| |
| VTRACE("count = %d", count); |
| |
| total_bits = match ? count : noOfBits; |
| total_bits = noOfBits == 8? total_bits: total_bits + bits_offset; |
| |
| VTRACE("total_bits = %d", total_bits); |
| |
| act_bytes = 1 + isemul; |
| cxt->emulation_byte_counter += isemul; |
| isemul = 0; |
| if ((total_bits & 0x7) == 0) |
| { |
| bstream->buf_bitoff = 0; |
| bstream->buf_index +=act_bytes; |
| } |
| else |
| { |
| bstream->buf_bitoff = total_bits & 0x7; |
| bstream->buf_index += (act_bytes - 1); |
| } |
| } |
| |
| VTRACE("leadingZeroBits = %d", leadingZeroBits); |
| VTRACE("bstream->buf_bitoff = %x", bstream->buf_bitoff); |
| VTRACE("bstream->buf_index = %x", bstream->buf_index); |
| |
| if (match) |
| { |
| length = --leadingZeroBits; |
| codeNum = 0; |
| if (length > 0) |
| { |
| bits_operation_result = viddec_pm_get_bits(parent, &temp, leadingZeroBits); |
| if (-1 == bits_operation_result) |
| { |
| VTRACE("h264_get_codeNum: viddec_pm_get_bits error!"); |
| length = 0; |
| } |
| codeNum = temp; |
| } |
| codeNum = codeNum + (1 << length) -1; |
| } |
| |
| return codeNum; |
| } |
| |
| |
| /*---------------------------------------*/ |
| /*---------------------------------------*/ |
| int32_t h264_GetVLCElement(void *parent, h264_Info* pInfo, uint8_t bIsSigned) |
| { |
| int32_t sval = 0; |
| signed char sign; |
| |
| sval = h264_get_codeNum(parent , pInfo); |
| |
| if (bIsSigned) //get signed integer golomb code else the value is unsigned |
| { |
| sign = (sval & 0x1)?1:-1; |
| sval = (sval +1) >> 1; |
| sval = sval * sign; |
| } |
| |
| return sval; |
| } // Ipp32s H264Bitstream::GetVLCElement(bool bIsSigned) |
| |
| /// |
| /// Check whether more RBSP data left in current NAL |
| /// |
| uint8_t h264_More_RBSP_Data(void *parent, h264_Info * pInfo) |
| { |
| uint8_t cnt = 0; |
| |
| uint8_t is_emul =0; |
| uint8_t cur_byte = 0; |
| int32_t shift_bits =0; |
| uint32_t ctr_bit = 0; |
| uint32_t bits_offset =0, byte_offset =0; |
| |
| //remove warning |
| pInfo = pInfo; |
| |
| if (!viddec_pm_is_nomoredata(parent)) |
| return 1; |
| |
| viddec_pm_get_au_pos(parent, &bits_offset, &byte_offset, &is_emul); |
| |
| shift_bits = 7-bits_offset; |
| |
| // read one byte |
| viddec_pm_get_cur_byte(parent, &cur_byte); |
| |
| ctr_bit = ((cur_byte)>> (shift_bits--)) & 0x01; |
| |
| // a stop bit has to be one |
| if (ctr_bit == 0) |
| return 1; |
| |
| while (shift_bits >= 0 && !cnt) |
| { |
| cnt |= (((cur_byte)>> (shift_bits--)) & 0x01); // set up control bit |
| } |
| |
| return (cnt); |
| } |