///////////////////////////////////////////////////////////////////////////////////////// // File : tg.c // Date : octobre 2015 // author : Alain Greiner ///////////////////////////////////////////////////////////////////////////////////////// // This file define the code of the TG (trafic generator) thread for MJPEG application. // It transfer the byte stream from the file identified by the fd argument to a 1024 // bytes local buffer. It analyses the byte stream to detect the End_of_Image markers. // All the bytes corresponding to a single image (from the first byte, to the EOI marker // included) is written in the TG_2_DEMUX[index] channel of a single cluster, // in increasing order in of the cluster index. ///////////////////////////////////////////////////////////////////////////////////////// #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 tg() /////////////////////////////////////// { // 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 ); // private TTY allocation // giet_tty_alloc( 0 ); PRINTF("\n[MJPEG] thread TG starts on P[%d,%d,%d]\n", x , y , p ) // allocate input buffer : 1024 bytes uint8_t bufin[1024]; // allocate output bufio to access MWMR channel : 64 bytes == 16 words mwmr_bufio_t bufio; uint8_t bufout[64]; mwmr_bufio_init( &bufio , bufout , 64 , 0 , tg_2_demux[0] ); uint32_t image; // image index uint32_t cluster; // cluster index / modulo x_size*y_size uint32_t ptr; // byte pointer in input buffer uint32_t eoi_found; // boolean : End-of-Image found uint32_t ff_found; // boolean : 0xFF value found uint32_t bytes_count; // mumber of bytes in compressed image // initialise image and cluster index, and bufin pointer image = 0; cluster = 0; ptr = 0; while( image < MAX_IMAGES ) // one compressed image per iteration { // initialise image specific variables eoi_found = 0; ff_found = 0; bytes_count = 0; // re-initialise the destination buffer for each image bufio.mwmr = tg_2_demux[cluster]; // scan bit stream until EOI found // transfer one byte per iteration from input buffer to output bufio while ( eoi_found == 0 ) { // - tranfer 1024 bytes from file to input buffer when input buffer empty. // - return to first byte in input file when EOF found, // to emulate an infinite stream of images. if ( ptr == 0 ) { uint32_t r = giet_fat_read( fd , bufin , 1024 ); if ( r < 1024 ) { giet_fat_lseek( fd , 0 , SEEK_SET ); giet_fat_read( fd , bufin + r , 1024 - r ); } } // transfer one byte from input buffer to output bufio mwmr_bufio_write_byte( &bufio , bufin[ptr] ); // analyse this byte to find EOI marker OxFFD8 // flush the output buffer when EOI found if ( ff_found ) // possible End of Image { ff_found = 0; if ( bufin[ptr] == 0xD9 ) // End of Image found { // exit current image eoi_found = 1; // flush output bufio mwmr_bufio_flush( &bufio ); } } else // test if first byte of a marker { if ( bufin[ptr] == 0xFF ) ff_found = 1; } // increment input buffer pointer modulo 1024 ptr++; if ( ptr == 1024 ) ptr = 0; // increment bytes_count for current image bytes_count++; } // end while (eoi) #if DEBUG_TG PRINTF("\nTG send image %d to cluster %d at cycle %d : %d bytes\n", image , cluster , giet_proctime() , bytes_count ) #endif // increment image index image++; // increment cluster index modulo (x_size*y_size) cluster++; if (cluster == x_size * y_size) cluster = 0; } // end while on images giet_pthread_exit("TG completed"); } // end tg()