diff options
Diffstat (limited to 'libhb/rotate.c')
-rw-r--r-- | libhb/rotate.c | 106 |
1 files changed, 31 insertions, 75 deletions
diff --git a/libhb/rotate.c b/libhb/rotate.c index 5f9558764..a60f92ce5 100644 --- a/libhb/rotate.c +++ b/libhb/rotate.c @@ -2,6 +2,7 @@ #include "hb.h" #include "hbffmpeg.h" //#include "mpeg2dec/mpeg2.h" +#include "taskset.h" #define MODE_DEFAULT 3 // Mode 1: Flip vertically (y0 becomes yN and yN becomes y0) @@ -11,7 +12,6 @@ typedef struct rotate_arguments_s { hb_buffer_t *dst; hb_buffer_t *src; - int stop; } rotate_arguments_t; struct hb_filter_private_s @@ -24,9 +24,7 @@ struct hb_filter_private_s int cpu_count; - hb_thread_t ** rotate_threads; // Threads for Rotate - one per CPU - hb_lock_t ** rotate_begin_lock; // Thread has work - hb_lock_t ** rotate_complete_lock; // Thread has completed work + taskset_t rotate_taskset; // Threads for Rotate - one per CPU rotate_arguments_t *rotate_arguments; // Arguments to thread for work }; @@ -85,27 +83,25 @@ void rotate_filter_thread( void *thread_args_v ) while( run ) { /* - * Wait here until there is work to do. hb_lock() blocks until - * render releases it to say that there is more work to do. + * Wait here until there is work to do. */ - hb_lock( pv->rotate_begin_lock[segment] ); + taskset_thread_wait4start( &pv->rotate_taskset, segment ); - rotate_work = &pv->rotate_arguments[segment]; - - if( rotate_work->stop ) + if( taskset_thread_stop( &pv->rotate_taskset, segment ) ) { /* * No more work to do, exit this thread. */ run = 0; - continue; + goto report_completion; } + rotate_work = &pv->rotate_arguments[segment]; if( rotate_work->dst == NULL ) { hb_error( "Thread started when no work available" ); hb_snooze(500); - continue; + goto report_completion; } /* @@ -168,12 +164,13 @@ void rotate_filter_thread( void *thread_args_v ) } } } + +report_completion: /* * Finished this segment, let everyone know. */ - hb_unlock( pv->rotate_complete_lock[segment] ); + taskset_thread_complete( &pv->rotate_taskset, segment ); } - free( thread_args_v ); } @@ -199,28 +196,12 @@ static void rotate_filter( */ pv->rotate_arguments[segment].dst = out; pv->rotate_arguments[segment].src = in; - - /* - * Let the thread for this plane know that we've setup work - * for it by releasing the begin lock (ensuring that the - * complete lock is already locked so that we block when - * we try to lock it again below). - */ - hb_lock( pv->rotate_complete_lock[segment] ); - hb_unlock( pv->rotate_begin_lock[segment] ); } /* - * Wait until all three threads have completed by trying to get - * the complete lock that we locked earlier for each thread, which - * will block until that thread has completed the work on that - * plane. + * Allow the taskset threads to make one pass over the data. */ - for( segment = 0; segment < pv->cpu_count; segment++ ) - { - hb_lock( pv->rotate_complete_lock[segment] ); - hb_unlock( pv->rotate_complete_lock[segment] ); - } + taskset_cycle( &pv->rotate_taskset ); /* * Entire frame is now rotated. @@ -244,44 +225,34 @@ static int hb_rotate_init( hb_filter_object_t * filter, pv->cpu_count = hb_get_cpu_count(); - /* - * Create threads and locks. + * Create rotate taskset. */ - pv->rotate_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count ); - pv->rotate_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count ); - pv->rotate_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count ); pv->rotate_arguments = malloc( sizeof( rotate_arguments_t ) * pv->cpu_count ); + if( pv->rotate_arguments == NULL || + taskset_init( &pv->rotate_taskset, /*thread_count*/pv->cpu_count, + sizeof( rotate_thread_arg_t ) ) == 0 ) + { + hb_error( "rotate could not initialize taskset" ); + } int i; for( i = 0; i < pv->cpu_count; i++ ) { rotate_thread_arg_t *thread_args; - thread_args = malloc( sizeof( rotate_thread_arg_t ) ); - - if( thread_args ) { - thread_args->pv = pv; - thread_args->segment = i; - - pv->rotate_begin_lock[i] = hb_lock_init(); - pv->rotate_complete_lock[i] = hb_lock_init(); + thread_args = taskset_thread_args( &pv->rotate_taskset, i ); - /* - * Important to start off with the threads locked waiting - * on input. - */ - hb_lock( pv->rotate_begin_lock[i] ); + thread_args->pv = pv; + thread_args->segment = i; + pv->rotate_arguments[i].dst = NULL; - pv->rotate_arguments[i].stop = 0; - pv->rotate_arguments[i].dst = NULL; - - pv->rotate_threads[i] = hb_thread_init( "rotate_filter_segment", - rotate_filter_thread, - thread_args, - HB_NORMAL_PRIORITY ); - } else { - hb_error( "rotate could not create threads" ); + if( taskset_thread_spawn( &pv->rotate_taskset, i, + "rotate_filter_segment", + rotate_filter_thread, + HB_NORMAL_PRIORITY ) == 0 ) + { + hb_error( "rotate could not spawn thread" ); } } // Set init width/height so the next stage in the pipline @@ -344,26 +315,11 @@ static void hb_rotate_close( hb_filter_object_t * filter ) return; } - int i; - for( i = 0; i < pv->cpu_count; i++) - { - /* - * Tell each rotate thread to stop, and then cleanup. - */ - pv->rotate_arguments[i].stop = 1; - hb_unlock( pv->rotate_begin_lock[i] ); - - hb_thread_close( &pv->rotate_threads[i] ); - hb_lock_close( &pv->rotate_begin_lock[i] ); - hb_lock_close( &pv->rotate_complete_lock[i] ); - } + taskset_fini( &pv->rotate_taskset ); /* * free memory for rotate structs */ - free( pv->rotate_threads ); - free( pv->rotate_begin_lock ); - free( pv->rotate_complete_lock ); free( pv->rotate_arguments ); free( pv ); |