#include #include #include #ifdef MSWIN #include typedef HANDLE THREAD_HANDLE; #else #include typedef pthread_t THREAD_HANDLE; #endif class Bayer_MT_datastruct{ public: uint slice_start_row, slice_height, slice_width, frame_width; uchar * slice_uniterpolated_buffer, * slice_pixmap; int vid_uses_two_bytes_per_pixel; int work_done; Bayer_MT_datastruct(){ init(); } void init(){ slice_start_row = slice_height = slice_width = 0; slice_uniterpolated_buffer = slice_pixmap = NULL; vid_uses_two_bytes_per_pixel = 0; work_done = 0; } void init_thread_data( uint threadid, uint in_frame_width, uint * row_partitions, uchar * frame_uniterpolated_buffer, uchar * frame_pixmap, int in_vid_uses_two_bytes_per_pixel ){ init(); frame_width = in_frame_width; vid_uses_two_bytes_per_pixel = in_vid_uses_two_bytes_per_pixel; slice_start_row = row_partitions[threadid]; slice_width = frame_width * ( 1 + vid_uses_two_bytes_per_pixel ); slice_height = row_partitions[threadid + 1] - row_partitions[threadid]; slice_uniterpolated_buffer = frame_uniterpolated_buffer + slice_start_row * slice_width; slice_pixmap = frame_pixmap + slice_start_row * frame_width * 3; } void bayer_interpolate(){ if( vid_uses_two_bytes_per_pixel ) bayer_interpolate_frame( slice_uniterpolated_buffer, slice_pixmap, frame_width, slice_height ); else gp_bayer_decode( slice_uniterpolated_buffer, frame_width, slice_height, slice_pixmap, BAYER_TILE_GBRG ); work_done = 1; } }; #ifdef MSWIN DWORD WINAPI bayer_interpolate_thread( LPVOID thread_arg ){ #else void * bayer_interpolate_thread( void * thread_arg ){ #endif Bayer_MT_datastruct * bayer_args = (Bayer_MT_datastruct*) thread_arg; bayer_args -> bayer_interpolate(); return NULL; } void bayer_interpolate_MT( uchar * frame_uniterpolated_buffer, uchar * frame_pixmap, uint frame_width, uint frame_height, int vid_uses_two_bytes_per_pixel ){ int num_threads = get_num_processing_cores(); if( frame_height < 250 ) num_threads = 1; else if( frame_height < 500 ) num_threads = my_min( num_threads, 2 ); else if( frame_height < 1500 ) num_threads = my_min( num_threads, 4 ); else num_threads = my_min( num_threads, 8 ); uint * row_partitions = new uint[num_threads + 1]; uint num_rows_per_partition = my_ceil( frame_height, num_threads ); num_rows_per_partition += num_rows_per_partition % 2; for( int i = 0; i <= num_threads; i++ ) row_partitions[i] = my_min( i * num_rows_per_partition, frame_height ); Bayer_MT_datastruct * thread_datastruct = new Bayer_MT_datastruct[num_threads]; for( int i = 0; i < num_threads; i++ ) thread_datastruct[i].init_thread_data( i, frame_width, row_partitions, frame_uniterpolated_buffer, frame_pixmap, vid_uses_two_bytes_per_pixel ); THREAD_HANDLE * threads = new THREAD_HANDLE[num_threads]; for( int i = 0; i < num_threads; i++ ){ #ifdef MSWIN threads[i] = CreateThread( NULL, 0, bayer_interpolate_thread, (LPVOID)(thread_datastruct + i), 0, NULL ); #else int pthread_err = pthread_create( &threads[i], NULL, bayer_interpolate_thread, (void *)(thread_datastruct + i) ); if( pthread_err != 0 ){ DISPLAY_PTHREAD_ERROR( i, __FILE__, __LINE__ ) threads[i] = NULL; } #endif } wait_until_processing_threads_are_done_then_cleanup( num_threads, threads, thread_datastruct ); delete [] row_partitions; }