00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <mxcpcFramewiseMxPEGScanDecoderIPP.h>
00015 #include <mxcpcMxPEGDecoderBackEnd.h>
00016 #include <mxcpc_exceptions.h>
00017
00018 #include <ippcc.h>
00019
00020 #include <exception>
00021 #include <memory>
00022
00023
00024
00025 mxcpcFramewiseMxPEGScanDecoderIPP::mxcpcFramewiseMxPEGScanDecoderIPP() {
00026
00027 int huffman_size;
00028 int i;
00029
00030 ippiDecodeHuffmanSpecGetBufSize_JPEG_8u(&huffman_size);
00031
00032 HuffmanTree_Y_DC = 0;
00033 HuffmanTree_Y_AC = 0;
00034 HuffmanTree_UV_DC = 0;
00035 HuffmanTree_UV_AC = 0;
00036
00037 HuffmanTree_Y_DC = (IppiDecodeHuffmanSpec *)std::malloc(huffman_size);
00038 HuffmanTree_Y_AC = (IppiDecodeHuffmanSpec *)std::malloc(huffman_size);
00039 HuffmanTree_UV_DC = (IppiDecodeHuffmanSpec *)std::malloc(huffman_size);
00040 HuffmanTree_UV_AC = (IppiDecodeHuffmanSpec *)std::malloc(huffman_size);
00041
00042 if( !HuffmanTree_Y_DC
00043 || !HuffmanTree_Y_AC
00044 || !HuffmanTree_UV_DC
00045 || !HuffmanTree_UV_AC) {
00046
00047 std::free(HuffmanTree_Y_DC);
00048 std::free(HuffmanTree_Y_AC);
00049 std::free(HuffmanTree_UV_DC);
00050 std::free(HuffmanTree_UV_AC);
00051 throw std::bad_alloc();
00052 }
00053
00054 try {
00055
00056 if(ippiDecodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_Y_DC[0],
00057 &DefaultHuffmanTable_Y_DC[16],
00058 HuffmanTree_Y_DC)
00059 != ippStsNoErr) throw mxcpcDidntWorkOutException();
00060
00061 if(ippiDecodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_Y_AC[0],
00062 &DefaultHuffmanTable_Y_AC[16],
00063 HuffmanTree_Y_AC)
00064 != ippStsNoErr) throw mxcpcDidntWorkOutException();
00065
00066 if(ippiDecodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_UV_DC[0],
00067 &DefaultHuffmanTable_UV_DC[16],
00068 HuffmanTree_UV_DC)
00069 != ippStsNoErr) throw mxcpcDidntWorkOutException();
00070
00071 if(ippiDecodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_UV_AC[0],
00072 &DefaultHuffmanTable_UV_AC[16],
00073 HuffmanTree_UV_AC)
00074 != ippStsNoErr) throw mxcpcDidntWorkOutException();
00075
00076 } catch(mxcpcDidntWorkOutException) {
00077
00078 std::free(HuffmanTree_Y_DC);
00079 std::free(HuffmanTree_Y_AC);
00080 std::free(HuffmanTree_UV_DC);
00081 std::free(HuffmanTree_UV_AC);
00082
00083 throw;
00084 }
00085
00086 for(i = 0; i < 64; i++) {
00087 QuantizationTable_Y[i] = 0;
00088 QuantizationTable_UV[i] = 0;
00089 }
00090 }
00091
00092
00093 mxcpcFramewiseMxPEGScanDecoderIPP::~mxcpcFramewiseMxPEGScanDecoderIPP() {
00094
00095 std::free(HuffmanTree_Y_DC);
00096 std::free(HuffmanTree_Y_AC);
00097 std::free(HuffmanTree_UV_DC);
00098 std::free(HuffmanTree_UV_AC);
00099 }
00100
00101
00102
00103 const char *mxcpcFramewiseMxPEGScanDecoderIPP
00104 ::getAccelerationTypeString(void) {
00105
00106 return("Intel Performance Primitives");
00107 }
00108
00109
00110 void mxcpcFramewiseMxPEGScanDecoderIPP::setYQuantizationTable(
00111 unsigned char *data_bytes) {
00112
00113 ippiQuantInvTableInit_JPEG_8u16u(data_bytes,
00114 QuantizationTable_Y);
00115 }
00116
00117
00118 void mxcpcFramewiseMxPEGScanDecoderIPP::setUVQuantizationTable(
00119 unsigned char *data_bytes) {
00120
00121 ippiQuantInvTableInit_JPEG_8u16u(data_bytes,
00122 QuantizationTable_UV);
00123 }
00124
00125
00126 void mxcpcFramewiseMxPEGScanDecoderIPP
00127 ::performScanSweep(mxcpcFramewiseMxPEGDecoder::UndecodedFrameDescriptor
00128 *frame_descriptor) {
00129
00130
00131
00132
00133 const IppiDecodeHuffmanSpec *dc_huffman_trees[6] = { HuffmanTree_Y_DC,
00134 HuffmanTree_Y_DC,
00135 HuffmanTree_Y_DC,
00136 HuffmanTree_Y_DC,
00137 HuffmanTree_UV_DC,
00138 HuffmanTree_UV_DC,
00139 };
00140 const IppiDecodeHuffmanSpec *ac_huffman_trees[6] = { HuffmanTree_Y_AC,
00141 HuffmanTree_Y_AC,
00142 HuffmanTree_Y_AC,
00143 HuffmanTree_Y_AC,
00144 HuffmanTree_UV_AC,
00145 HuffmanTree_UV_AC,
00146 };
00147 Ipp16s last_y_dc = 0, last_u_dc = 0, last_v_dc = 0;
00148 Ipp16s *last_dc_ptrs[6] = { &last_y_dc, &last_y_dc, &last_y_dc, &last_y_dc,
00149 &last_u_dc, &last_v_dc
00150 };
00151 int detected_marker = 0;
00152 Ipp32u prefetched_bits = 0;
00153 int prefetched_bit_num = 0;
00154 int pos = 0;
00155 Ipp16u *quantization_table_ptrs[6] = { &QuantizationTable_Y[0],
00156 &QuantizationTable_Y[0],
00157 &QuantizationTable_Y[0],
00158 &QuantizationTable_Y[0],
00159 &QuantizationTable_UV[0],
00160 &QuantizationTable_UV[0]
00161 };
00162 Ipp8u *yuv_target_ptrs[6] = { &Y_ColorValues[0],
00163 &Y_ColorValues[8],
00164 &Y_ColorValues[128 + 0],
00165 &Y_ColorValues[128 + 8],
00166 &U_ColorValues[0],
00167 &V_ColorValues[0]
00168 };
00169 int yuv_target_steps[6] = { 16,
00170 16,
00171 16,
00172 16,
00173 8,
00174 8
00175 };
00176 const Ipp8u *yuv_src_ptrs[3] = { &Y_ColorValues[0],
00177 &U_ColorValues[0],
00178 &V_ColorValues[0]
00179 };
00180 int yuv_src_steps[3] = { 16, 8, 8 };
00181 IppiSize yuv_rgb_roi_size = { 16, 16 };
00182
00183
00184 mxcpc::u32 mini_buffer[16*16*3/4];
00185 mxcpc::u32 *final_copy_source,
00186 *final_copy_target;
00187 int target_row_stepping;
00188 IppStatus ipp_status;
00189 bool use_bitmask;
00190 int tilebits_left;
00191 unsigned char *tilebit_ptr, tilebit_mask;
00192 int x, y;
00193 bool next_tile_right_here;
00194 int i;
00195
00196
00197
00198 if(!BackEnd) return;
00199
00200
00201
00202 tilebits_left = frame_descriptor->TileNumX * frame_descriptor->TileNumY;
00203 tilebit_ptr = frame_descriptor->TileBits;
00204 tilebit_mask = 128;
00205 x = -1;
00206 y = 0;
00207 ipp_status = ippStsNoErr;
00208 next_tile_right_here = true;
00209 if(tilebit_ptr)
00210 use_bitmask = true;
00211 else
00212 use_bitmask = false;
00213
00214
00215
00216 while(tilebits_left) {
00217
00218
00219 x++;
00220 if(x == frame_descriptor->TileNumX) {
00221 x = 0;
00222 y++;
00223 }
00224
00225
00226 if(use_bitmask) {
00227 next_tile_right_here = (*tilebit_ptr & tilebit_mask) != 0;
00228 tilebit_mask /= 2;
00229 if(!tilebit_mask) {
00230 tilebit_mask = 128;
00231 tilebit_ptr++;
00232 }
00233 }
00234
00235 if(next_tile_right_here) {
00236
00237
00238 for(i = 0; i < 6; i++) {
00239
00240 if(ipp_status != ippStsNoErr) {
00241
00242 BackEnd->errorEncountered();
00243 return;
00244 }
00245
00246 ipp_status = ippiDecodeHuffman8x8_Direct_JPEG_1u16s_C1(
00247 frame_descriptor->ScanBytes, &pos,
00248 DecodedHuffmanCoeffs[i],
00249 last_dc_ptrs[i],
00250 &detected_marker,
00251 &prefetched_bits, &prefetched_bit_num,
00252 dc_huffman_trees[i], ac_huffman_trees[i]);
00253
00254 ippiDCTQuantInv8x8LS_JPEG_16s8u_C1R(DecodedHuffmanCoeffs[i],
00255 yuv_target_ptrs[i],
00256 yuv_target_steps[i],
00257 quantization_table_ptrs[i]);
00258 }
00259
00260
00261
00262
00263 ippiYUV420ToRGB_8u_P3C3R(yuv_src_ptrs, yuv_src_steps,
00264 (Ipp8u *)mini_buffer,
00265 16*3, yuv_rgb_roi_size);
00266
00267
00268 BackEnd->provideVideoTilePixelTarget(x, y, &final_copy_target, &target_row_stepping);
00269 final_copy_source = mini_buffer;
00270 for(i = 0; i < 16; i++) {
00271 *final_copy_target++ = *final_copy_source++;
00272 *final_copy_target++ = *final_copy_source++;
00273 *final_copy_target++ = *final_copy_source++;
00274 *final_copy_target++ = *final_copy_source++;
00275 *final_copy_target++ = *final_copy_source++;
00276 *final_copy_target++ = *final_copy_source++;
00277 *final_copy_target++ = *final_copy_source++;
00278 *final_copy_target++ = *final_copy_source++;
00279 *final_copy_target++ = *final_copy_source++;
00280 *final_copy_target++ = *final_copy_source++;
00281 *final_copy_target++ = *final_copy_source++;
00282 *final_copy_target++ = *final_copy_source++;
00283 final_copy_target += target_row_stepping;
00284 }
00285 BackEnd->videoTileReceived();
00286 }
00287
00288 tilebits_left--;
00289 }
00290 }