📄 jpege_vlc_kc.sc
字号:
//////////////////////////////////////////////////////////////////////////////////////////////////////// Title: jpege_vlc_kc.sc (KernelC code for Huffman encoding)//// Notice: COPYRIGHT (C) STREAM PROCESSORS, INC. 2005-2007// THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE SPI// END-USER LICENSE AGREEMENT (EULA). THE PROGRAM MAY ONLY// BE USED IN A MANNER EXPLICITLY SPECIFIED IN THE EULA,// WHICH INCLUDES LIMITATIONS ON COPYING, MODIFYING,// REDISTRIBUTION AND WARANTIES. UNAUTHORIZED USE OF THIS// PROGRAM IS STRICTLY PROHIBITED. YOU MAY OBTAIN A COPY OF// THE EULA FROM WWW.STREAMPROCESSORS.COM. // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #includes ////////////////////////////////////////////////////////////////////////////////////////////////////#include "spi_common.h"#include "jpege_vlc_kc.h"inline void kernel stuff_zero_bytes( stream uint32x1 bitstream(array_io), vec uint32x1 input_data(in), vec uint32x1 word_position(in), vec uint32x1 output_data(out), vec uint32x1 stuffed_word(out), vec uint32x1 bits_cur_word_in(in), vec uint32x1 bits_cur_word_out(out) ) // Description: // input_data is searched for "FF" bit pattern // if found, it's stuffed with "00"s // byte stuffed word is wriiten to the bitstream at index specified by lower 16 bits of word_position // High 16 bit is the number of bit already written to at that word position, range 0-31 // bits_cur_word_in specifies the number of bits in input_data // where as bits_cur_word_out specfies the number of bits in output_data which has the bytes // shifted out of input_data because of byte_stuffing // // Returns: Nothing. // ////////////////////////////////////////////////////////////////{ vec uint32x1 data_cur_word, write_word, shifted_data, prev_write_word; vec uint32x1 bits_cur_word; vec uint32x1 flag, control_word, tmp; data_cur_word = input_data; bits_cur_word = bits_cur_word_in; shifted_data = 0; //1st byte from MSB flag = spi_veq32((data_cur_word & 0xFF000000), 0xFF000000); control_word = spi_vselect32(flag, 0x03040201, 0x03020100); write_word = spi_vshuffleu(control_word, data_cur_word, 0); //shifted_data = spi_vselect32(flag, ((data_cur_word & 0x000000FF)<< 24), shifted_data); shifted_data = spi_vselect32(flag, spi_vshuffleu(0x00070605, data_cur_word, 0), shifted_data); bits_cur_word = spi_vselect32(flag, (bits_cur_word + (vec uint32x1)BITS_PER_BYTE), bits_cur_word); //2nd byte from MSB prev_write_word = write_word; flag = spi_veq32((write_word & 0x00FF0000), 0x00FF0000); control_word = spi_vselect32(flag, 0x03020401, 0x03020100); write_word = spi_vshuffleu(control_word, write_word, 0); //shifted_data = spi_vselect32(flag, (((prev_write_word & 0x000000FF) << 24 ) | (shifted_data >> 8)), shifted_data); shifted_data = spi_vselect32(flag, spi_vshuffleu(0x00070605, prev_write_word, shifted_data), shifted_data); bits_cur_word = spi_vselect32(flag, (bits_cur_word + (vec uint32x1)BITS_PER_BYTE), bits_cur_word); //3rd byte from MSB prev_write_word = write_word; flag = spi_veq32((write_word & 0x0000FF00), 0x0000FF00); control_word = spi_vselect32(flag, 0x03020104, 0x03020100); write_word = spi_vshuffleu(control_word, write_word, 0); //shifted_data = spi_vselect32(flag, (((prev_write_word & 0x000000FF) << 24 ) | (shifted_data >> 8)), shifted_data); shifted_data = spi_vselect32(flag, spi_vshuffleu(0x00070605, prev_write_word, shifted_data), shifted_data); bits_cur_word = spi_vselect32(flag, (bits_cur_word + (vec uint32x1)BITS_PER_BYTE), bits_cur_word); //4th byte from MSB flag = spi_veq32((write_word & 0x000000FF), 0x000000FF); //shifted_data = spi_vselect32(flag, (shifted_data >> 8), shifted_data); shifted_data = spi_vselect32(flag, spi_vshuffleu(0x00070605, 0, shifted_data), shifted_data); bits_cur_word = spi_vselect32(flag, (bits_cur_word + (vec uint32x1)BITS_PER_BYTE), bits_cur_word); // write the first byte stuffed word // swap endian tmp = spi_vshuffleu (0x00010203, write_word, 0); spi_array_write (bitstream, tmp, word_position); stuffed_word = write_word; output_data = shifted_data; bits_cur_word_out = bits_cur_word;}inline void kernel write_bits ( stream uint32x1 bitstream(array_io), vec uint32x1 in_size(in), vec uint32x1 out_size(out), vec uint32x1 cur_word_in(in), vec uint32x1 cur_word_out(out), vec uint32x1 data(in), vec uint32x1 num_bits(in), uint32x1 write_last_word(in) ) // Description: // Writes num_bits into bitstream. Bitstream is an indexed array in LRF // out_size points to the current position to write. The low 16 bit is // the word position to write to. High 16 bit is the number of bit already written to at // that word position, range 0-31 // write_last_word flag will be true if the function is called to write the last word in the // row & hence we want to write it to the bitstream even if it is incomplete // // Returns: Nothing. // ////////////////////////////////////////////////////////////////{ vec uint32x1 bits_in_incomplete_word; vec uint32x1 word_position; vec uint32x1 next_word_position; vec uint32x1 bits_cur_word; vec uint32x1 data_cur_word; vec uint32x1 bits_next_word; vec uint32x1 data_next_word; vec uint32x1 stuffed_word; vec uint32x1 data_last_word; vec uint32x1 num_bits_per_word; vec uint32x1 bits_stuffed; vec uint32x1 shifted_data; vec uint32x1 bits_last_word_out; vec uint32x1 last_word_position; vec uint32x1 tmp0; vec uint32x1 half_word_hi_lo; vec uint32x1 ge_32_flag; vec uint32x1 eq_0_flag; num_bits_per_word = 32; half_word_hi_lo = 0xb9b93120; tmp0 = 0; bits_in_incomplete_word = spi_vshuffledi_hi (half_word_hi_lo, in_size, tmp0); // top 16 bits word_position = spi_vshuffledi_lo (half_word_hi_lo, in_size, tmp0); // bottom 16 bits next_word_position = word_position + (vec uint32x1)1; // Now calculate the bits in cur word & next word bits_cur_word = bits_in_incomplete_word + num_bits; ge_32_flag = spi_vle32u(num_bits_per_word, bits_cur_word); bits_next_word = spi_vselect32(ge_32_flag, (bits_cur_word - num_bits_per_word), 0); bits_cur_word = spi_vselect32(ge_32_flag, num_bits_per_word, bits_cur_word); // compute the data in current word & next word // Shift data to top of the 32-bit word. This will mask out any 1s that are not part of the data (when magnitute is a negative number) data = data << (num_bits_per_word - num_bits); data_cur_word = cur_word_in | (data >> bits_in_incomplete_word); data_next_word = data << (num_bits - bits_next_word); bits_in_incomplete_word = spi_vselect32(ge_32_flag, bits_next_word, bits_cur_word); // Use this for debugging // tmp = spi_vrorl (tmp0 != bits_in_incomplete_word); // Search for "FF" pattern in data_cur_word, stuff "00" after "FF" // shifted_data is the data spilled out of data_cur_word becs of "00" byte stuffing stuff_zero_bytes(bitstream, data_cur_word, word_position, shifted_data, stuffed_word, bits_cur_word, bits_cur_word); // bits_cur_word >= 32 implies a full word has been written to the bitstream & we need to increment the index that points to the bitstream ge_32_flag = spi_vle32u(num_bits_per_word, bits_cur_word); // special case : if this is the last word in row, save the incomplete byte stuffed word bits_last_word_out = bits_cur_word; // if bits_cur_word >= 32 we know that the word has been written to bitstream & will not be considered next time // hence assigning 0 to cur_word_out since anyways it is going to be overwritten later cur_word_out = spi_vselect32(ge_32_flag, 0, data_cur_word); last_word_position = spi_vselect32(ge_32_flag, next_word_position, word_position); // the codition (write_last_word == 1) is included below because we don't want to overwrite the incomplete word // in case it's the last word in the row word_position = spi_vselect32((ge_32_flag | write_last_word), next_word_position, word_position); next_word_position = word_position + (vec uint32x1)1; bits_stuffed = spi_vselect32(ge_32_flag, (bits_cur_word - num_bits_per_word), 0); bits_in_incomplete_word = spi_vselect32(ge_32_flag, (bits_next_word + bits_stuffed), bits_in_incomplete_word); // Because of byte stuffing another word might have got created // Search out for FF in the additional word // Hence the above code is repeated with minor changes // calculate the bits in cur word & next word bits_cur_word = bits_next_word + bits_stuffed; ge_32_flag = spi_vle32u(num_bits_per_word, bits_cur_word); eq_0_flag = spi_veq32(0, bits_cur_word); bits_next_word = spi_vselect32(ge_32_flag, (bits_cur_word - num_bits_per_word), 0); bits_cur_word = spi_vselect32(ge_32_flag, num_bits_per_word, bits_cur_word); // compute the data in current word & next word // Shift data to top of the 32-bit word. This will mast out any 1s that are not part of the data (when magnitute is a negative number) data_cur_word = shifted_data | (data_next_word >> bits_stuffed); data_next_word = data_next_word << (num_bits_per_word - bits_stuffed); // If it's the last word in the row, u need to output the stuffed word data_last_word = stuffed_word; stuff_zero_bytes(bitstream, data_cur_word, word_position, shifted_data, stuffed_word, bits_cur_word, bits_cur_word); ge_32_flag = spi_vle32u(num_bits_per_word, bits_cur_word); // get the final incomplete word that'll be the output of this function cur_word_out = spi_vselect32(eq_0_flag, cur_word_out, spi_vselect32(ge_32_flag, (shifted_data | (data_next_word >> bits_stuffed)), data_cur_word)); // get the final incomplete word in case it is the last word data_last_word = spi_vselect32(eq_0_flag, data_last_word, stuffed_word); cur_word_out = spi_vselect32(write_last_word, data_last_word, cur_word_out); // increment the pointer of bitstream in case the word had complete 32 bits word_position = spi_vselect32(ge_32_flag, (word_position + (vec uint32x1)1), word_position); word_position = spi_vselect32(write_last_word, last_word_position, word_position); // calculate the bits in incomplete word bits_stuffed = spi_vselect32(ge_32_flag, (bits_cur_word - num_bits_per_word), 0); bits_in_incomplete_word = spi_vselect32(ge_32_flag, (bits_next_word + bits_stuffed), bits_in_incomplete_word); bits_last_word_out = spi_vselect32(eq_0_flag, bits_last_word_out, bits_cur_word); bits_in_incomplete_word = spi_vselect32(write_last_word, bits_last_word_out, bits_in_incomplete_word); out_size = (bits_in_incomplete_word << 16) | word_position; }inline void kernel dc_coeff_encode( stream uint32x1 dc_huffman_table(array_in), stream uint32x1 bitstream(array_io), vec uint32x1 start_index(in), stream int32x1 prev_block_data_strm(array_io), vec int32x1 zz_0(in), vec uint32x1 half_word_hi_lo(in), vec uint32x1 cur_word(out), vec uint32x1 cur_word_position(out) ) // Description: // DC co-efficient from prev block read from prev_block_data_strm // is subtracted from current DC co-efficient in zz_0. // Huffman entry for the number of bits created & the magnitude of // diffrential coefficient are stored to the bitstream by calling the // inline function write_bits. // ////////////////////////////////////////////////////////////////{ vec int32x1 dc_coef; vec int32x1 diff_dc_coef, prev_dc_coef, prev_blk_bits, no_prev_blk_bits; vec uint32x1 abs_coef; vec uint32x1 code_mag; // code of the magnitute vec uint32x1 num_bits; vec uint32x1 huffman_entry; vec uint32x1 code_length; vec uint32x1 code_word; vec int32x1 tmp; tmp = 0; // The data from previous block spi_array_read (prev_block_data_strm, prev_dc_coef, 0); spi_array_read (prev_block_data_strm, prev_blk_bits, 1); spi_array_read (prev_block_data_strm, no_prev_blk_bits, 2); dc_coef = zz_0; diff_dc_coef = dc_coef - prev_dc_coef;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -