Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

mxcpcFramewiseMxPEGScanDecoderIPP.cpp

00001 //           ///          //
00002 //          /////        ////
00003 //         /// XXX     XXX ///
00004 //        ///    XXX XXX    ///     $RCSfile: mxcpcFramewiseMxPEGScanDecoderIPP.cpp,v $  
00005 //       ///       XXX       ///     $Revision: 1.2 $
00006 //      ///      XXX XXX      ///     $Date: 2005/12/20 18:04:19 $
00007 //     ////    XXX     XXX    ////     $Author: cvs-kai $
00008 //    ////                     ////
00009 //   ////  M  O  B  O  T  I  X  ////////////////////////////////////////////////
00010 //  //// Security Vision Systems ///////////////////////////////////////////////
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   // init some local data facilitating invocation of the IPP routines...
00131   //   done only once for an entire scan sweep, so we can do this here on the
00132   //   stack...
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   // remaining local data...
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   // guard against missing backend
00198   if(!BackEnd) return;
00199   
00200     
00201   // initialize and decide for bitmask mode...
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;   // default for bitmask-less mode
00209   if(tilebit_ptr) 
00210     use_bitmask = true;
00211   else
00212     use_bitmask = false;
00213    
00214     
00215   // iterate over all tiles (MCUs)...
00216   while(tilebits_left) {
00217   
00218     // advance target tile coordinates...
00219     x++;
00220     if(x == frame_descriptor->TileNumX) {
00221       x = 0;
00222       y++;
00223     }
00224   
00225     // if in bitmask mode, consume and honor current tile bit...
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) {   // decode tile...
00236       
00237       // iterate over the 6 sub-MCUs (Y,Y,Y,Y,U,V)...
00238       for(i = 0; i < 6; i++) {
00239        
00240         if(ipp_status != ippStsNoErr) {   // decoding of previous sub-MCU caused
00241                                           // an error - better stop...
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       // got all 6 sub-MCUs!
00261             
00262       // now perform colorspace conversion... 
00263       ippiYUV420ToRGB_8u_P3C3R(yuv_src_ptrs, yuv_src_steps, 
00264                                (Ipp8u *)mini_buffer,
00265                                16*3, yuv_rgb_roi_size);
00266     
00267       // --- finally negotiate with backend and write decoded pixel data... ---
00268       BackEnd->provideVideoTilePixelTarget(x, y, &final_copy_target, &target_row_stepping);
00269       final_copy_source = mini_buffer;
00270       for(i = 0; i < 16; i++) {   // 16 rows
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 }

Generated on Fri Jan 20 13:33:32 2006 for mxcpc by  doxygen 1.4.4