void x264_lookahead_put_frame( x264_t *h, x264_frame_t *frame ) { if( h->param.i_sync_lookahead ) x264_sync_frame_list_push( &h->lookahead->ifbuf, frame ); else x264_sync_frame_list_push( &h->lookahead->next, frame ); }
int x264_threadpool_init( x264_threadpool_t **p_pool, int threads, void (*init_func)(void *), void *init_arg ) { if( threads <= 0 ) return -1; x264_threadpool_t *pool; CHECKED_MALLOCZERO( pool, sizeof(x264_threadpool_t) ); *p_pool = pool; pool->init_func = init_func; pool->init_arg = init_arg; pool->threads = threads; CHECKED_MALLOC( pool->thread_handle, pool->threads * sizeof(x264_pthread_t) ); if( x264_sync_frame_list_init( &pool->uninit, pool->threads ) || x264_sync_frame_list_init( &pool->run, pool->threads ) || x264_sync_frame_list_init( &pool->done, pool->threads ) ) goto fail; for( int i = 0; i < pool->threads; i++ ) { x264_threadpool_job_t *job; CHECKED_MALLOC( job, sizeof(x264_threadpool_job_t) ); x264_sync_frame_list_push( &pool->uninit, (void*)job ); } for( int i = 0; i < pool->threads; i++ ) if( x264_pthread_create( pool->thread_handle+i, NULL, (void*)x264_threadpool_thread, pool ) ) goto fail; return 0; fail: return -1; }
void *x264_threadpool_wait( x264_threadpool_t *pool, void *arg ) { x264_threadpool_job_t *job = NULL; x264_pthread_mutex_lock( &pool->done.mutex ); while( !job ) { for( int i = 0; i < pool->done.i_size; i++ ) { x264_threadpool_job_t *t = (void*)pool->done.list[i]; if( t->arg == arg ) { job = (void*)x264_frame_shift( pool->done.list+i ); pool->done.i_size--; } } if( !job ) x264_pthread_cond_wait( &pool->done.cv_fill, &pool->done.mutex ); } x264_pthread_mutex_unlock( &pool->done.mutex ); void *ret = job->ret; x264_sync_frame_list_push( &pool->uninit, (void*)job ); return ret; }
void x264_threadpool_run( x264_threadpool_t *pool, void *(*func)(void *), void *arg ) { x264_threadpool_job_t *job = (void*)x264_sync_frame_list_pop( &pool->uninit ); job->func = func; job->arg = arg; x264_sync_frame_list_push( &pool->run, (void*)job ); }
static void x264_threadpool_thread( x264_threadpool_t *pool ) { if( pool->init_func ) pool->init_func( pool->init_arg ); while( !pool->exit ) { x264_threadpool_job_t *job = NULL; x264_pthread_mutex_lock( &pool->run.mutex ); while( !pool->exit && !pool->run.i_size ) x264_pthread_cond_wait( &pool->run.cv_fill, &pool->run.mutex ); if( pool->run.i_size ) { job = (void*)x264_frame_shift( pool->run.list ); pool->run.i_size--; } x264_pthread_mutex_unlock( &pool->run.mutex ); if( !job ) continue; job->ret = job->func( job->arg ); /* execute the function */ x264_sync_frame_list_push( &pool->done, (void*)job ); } }