diff options
author | jstebbins <[email protected]> | 2012-05-17 19:51:35 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2012-05-17 19:51:35 +0000 |
commit | 5a0673d1572fdfcd00063cfa9dffba907c808056 (patch) | |
tree | b55af15b31edc30a69bf2c17818f6ea3565f9a9a /libhb/deinterlace.c | |
parent | d005ce0b526630bd428c1e5a466b0a96f0b8ecba (diff) |
libhb: tasksets API provided by scsiguy
This is an easier to use API for launching multithreaded tasks. And it is more
portable since it does not rely on undefined/implementation specific behavior
of POSIX mutexes. That is, the ability for one thread to unlock a mutex owned
by another thread.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4685 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb/deinterlace.c')
-rw-r--r-- | libhb/deinterlace.c | 111 |
1 files changed, 33 insertions, 78 deletions
diff --git a/libhb/deinterlace.c b/libhb/deinterlace.c index 49681512c..e654817c3 100644 --- a/libhb/deinterlace.c +++ b/libhb/deinterlace.c @@ -20,6 +20,7 @@ #include "hbffmpeg.h" #include "mpeg2dec/mpeg2.h" #include "mcdeint.h" +#include "taskset.h" // yadif_mode is a bit vector with the following flags // Note that 2PASS should be enabled when using MCDEINT @@ -42,7 +43,6 @@ typedef struct yadif_arguments_s { uint8_t **dst; int parity; int tff; - int stop; } yadif_arguments_t; struct hb_filter_private_s @@ -59,9 +59,8 @@ struct hb_filter_private_s int cpu_count; - hb_thread_t ** yadif_threads; // Threads for Yadif - one per CPU - hb_lock_t ** yadif_begin_lock; // Thread has work - hb_lock_t ** yadif_complete_lock; // Thread has completed work + taskset_t yadif_taskset; // Threads for Yadif - one per CPU + yadif_arguments_t *yadif_arguments; // Arguments to thread for work int mcdeint_mode; @@ -220,27 +219,27 @@ void yadif_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->yadif_begin_lock[segment] ); + taskset_thread_wait4start( &pv->yadif_taskset, segment ); - yadif_work = &pv->yadif_arguments[segment]; - if( yadif_work->stop ) + if( taskset_thread_stop( &pv->yadif_taskset, segment ) ) { /* * No more work to do, exit this thread. */ run = 0; - continue; + goto report_completion; } + yadif_work = &pv->yadif_arguments[segment]; + if( yadif_work->dst == NULL ) { hb_error( "Thread started when no work available" ); hb_snooze(500); - continue; + goto report_completion; } /* @@ -332,12 +331,13 @@ void yadif_filter_thread( void *thread_args_v ) } } } + +report_completion: /* * Finished this segment, let everyone know. */ - hb_unlock( pv->yadif_complete_lock[segment] ); + taskset_thread_complete( &pv->yadif_taskset, segment ); } - free( thread_args_v ); } @@ -364,28 +364,10 @@ static void yadif_filter( uint8_t ** dst, pv->yadif_arguments[segment].parity = parity; pv->yadif_arguments[segment].tff = tff; pv->yadif_arguments[segment].dst = dst; - - /* - * 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->yadif_complete_lock[segment] ); - hb_unlock( pv->yadif_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. - */ - for( segment = 0; segment < pv->cpu_count; segment++ ) - { - hb_lock( pv->yadif_complete_lock[segment] ); - hb_unlock( pv->yadif_complete_lock[segment] ); - } + /* Allow the taskset threads to make one pass over the data. */ + taskset_cycle( &pv->yadif_taskset ); /* * Entire frame is now deinterlaced. @@ -444,41 +426,32 @@ static int hb_deinterlace_init( hb_filter_object_t * filter, } /* - * Create yadif threads and locks. + * Setup yadif taskset. */ - pv->yadif_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count ); - pv->yadif_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count ); - pv->yadif_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count ); pv->yadif_arguments = malloc( sizeof( yadif_arguments_t ) * pv->cpu_count ); + if( pv->yadif_arguments == NULL || + taskset_init( &pv->yadif_taskset, /*thread_count*/pv->cpu_count, + sizeof( yadif_arguments_t ) ) == 0 ) + { + hb_error( "yadif could not initialize taskset" ); + } for( i = 0; i < pv->cpu_count; i++ ) { yadif_thread_arg_t *thread_args; - thread_args = malloc( sizeof( yadif_thread_arg_t ) ); - - if( thread_args ) { - thread_args->pv = pv; - thread_args->segment = i; + thread_args = taskset_thread_args( &pv->yadif_taskset, i ); - pv->yadif_begin_lock[i] = hb_lock_init(); - pv->yadif_complete_lock[i] = hb_lock_init(); + thread_args->pv = pv; + thread_args->segment = i; + pv->yadif_arguments[i].dst = NULL; - /* - * Important to start off with the threads locked waiting - * on input. - */ - hb_lock( pv->yadif_begin_lock[i] ); - - pv->yadif_arguments[i].stop = 0; - pv->yadif_arguments[i].dst = NULL; - - pv->yadif_threads[i] = hb_thread_init( "yadif_filter_segment", - yadif_filter_thread, - thread_args, - HB_NORMAL_PRIORITY ); - } else { - hb_error( "Yadif could not create threads" ); + if( taskset_thread_spawn( &pv->yadif_taskset, i, + "yadif_filter_segment", + yadif_filter_thread, + HB_NORMAL_PRIORITY ) == 0 ) + { + hb_error( "yadif could not spawn thread" ); } } } @@ -526,25 +499,7 @@ static void hb_deinterlace_close( hb_filter_object_t * filter ) } } - for( i = 0; i < pv->cpu_count; i++) - { - /* - * Tell each yadif thread to stop, and then cleanup. - */ - pv->yadif_arguments[i].stop = 1; - hb_unlock( pv->yadif_begin_lock[i] ); - - hb_thread_close( &pv->yadif_threads[i] ); - hb_lock_close( &pv->yadif_begin_lock[i] ); - hb_lock_close( &pv->yadif_complete_lock[i] ); - } - - /* - * free memory for yadif structs - */ - free( pv->yadif_threads ); - free( pv->yadif_begin_lock ); - free( pv->yadif_complete_lock ); + taskset_fini( &pv->yadif_taskset ); free( pv->yadif_arguments ); } |