///////////////////////////////////////////////////////////////////////////////////////// // File : iqzz.c // Date : octobre 2015 // author : Alain Greiner ///////////////////////////////////////////////////////////////////////////////////////// // This file define the code of the IQZZ (Invert Quantisation) thread for MJPEG. ///////////////////////////////////////////////////////////////////////////////////////// #include #include #include #include "mjpeg.h" // macro to use a shared TTY #define PRINTF(...) lock_acquire( &tty_lock ); \ giet_tty_printf(__VA_ARGS__); \ lock_release( &tty_lock ); ////////////////////////////////////////////////////////////// __attribute__ ((constructor)) void iqzz( unsigned int index ) ////////////////////////////////////////////////////////////// { const uint8_t G_ZZ[64] = { 0 , 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 }; mwmr_channel_t* mwmr_in_data = vld_2_iqzz[index]; mwmr_channel_t* mwmr_in_quanti = demux_2_iqzz[index]; mwmr_channel_t* mwmr_out_data = iqzz_2_idct[index]; uint32_t block; uint32_t i; uint8_t QTable[64]; // Quantisation Table / 1 byte per pixel int16_t bufin[64]; // Input data buffer / 2 bytes per pixel int32_t bufout[64]; // Output data buffer / 4 bytes per pixel uint32_t nblocks = nblocks_w * nblocks_h; // get platform parameters uint32_t x_size; uint32_t y_size; uint32_t nprocs; giet_procs_number( &x_size , &y_size , &nprocs ); // get processor coordinates uint32_t x, y, p; giet_proc_xyp( &x , &y , &p ); PRINTF("\n[MJPEG] thread IQZZ[%d] starts on P[%d,%d,%d]\n", index, x, y, p ) uint32_t image = index; while ( image < MAX_IMAGES ) // one image per iteration { // read the quantization coefs from mwmr_in_quanti (one byte per coef) mwmr_read( mwmr_in_quanti , (uint32_t*)QTable , 16 ); #if (DEBUG_IQZZ > 1) PRINTF("\nIQZZ[%d] get quantisation coefs for image %d\n", index , image ) #endif for ( block = 0 ; block < nblocks ; ++block ) { // read one block from mwmr_in_data (2 bytes per pixel) mwmr_read( mwmr_in_data , (uint32_t*)bufin , 32 ); // unquantify & UnZZ each pixel for ( i = 0 ; i < 64 ; ++i ) { bufout[G_ZZ[i]] = bufin[i] * QTable[i]; } // write one block to IDCT / 4 bytes per pixel mwmr_write( mwmr_out_data , (uint32_t*)bufout , 64 ); #if (DEBUG_IQZZ > 1) PRINTF("\nIQZZ[%d] completes block %d/%d in image %d\n", index , block , nblocks , image ) PRINTF(" %d %d %d %d %d %d %d %d\n" " %d %d %d %d %d %d %d %d\n" " %d %d %d %d %d %d %d %d\n" " %d %d %d %d %d %d %d %d\n" " %d %d %d %d %d %d %d %d\n" " %d %d %d %d %d %d %d %d\n" " %d %d %d %d %d %d %d %d\n" " %d %d %d %d %d %d %d %d\n", bufout[0] , bufout[1] , bufout[2] , bufout[3] , bufout[4] , bufout[5] , bufout[6] , bufout[7] , bufout[8] , bufout[9] , bufout[10], bufout[11], bufout[12], bufout[13], bufout[14], bufout[15], bufout[16], bufout[17], bufout[18], bufout[19], bufout[20], bufout[21], bufout[22], bufout[23], bufout[24], bufout[25], bufout[26], bufout[27], bufout[28], bufout[29], bufout[30], bufout[31], bufout[32], bufout[33], bufout[34], bufout[35], bufout[36], bufout[37], bufout[38], bufout[39], bufout[40], bufout[41], bufout[42], bufout[43], bufout[44], bufout[45], bufout[46], bufout[47], bufout[48], bufout[49], bufout[50], bufout[51], bufout[52], bufout[53], bufout[54], bufout[55], bufout[56], bufout[57], bufout[58], bufout[59], bufout[60], bufout[61], bufout[62], bufout[63]) #endif } // end for blocks #if DEBUG_IQZZ PRINTF("\nIQZZ[%d] completes image %d at cycle %d\n", index , image , giet_proctime() ) #endif image = image + x_size* y_size; } // end while(1) on images giet_pthread_exit( "iqzz completed" ); } // end iqzz()