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; }
static int read_frame( x264_picture_t *p_pic, hnd_t handle, int i_frame ) { thread_hnd_t *h = handle; int ret = 0; if( h->next_frame >= 0 ) { x264_pthread_join( h->tid, NULL ); ret |= h->next_args->status; h->in_progress = 0; } if( h->next_frame == i_frame ) XCHG( x264_picture_t, *p_pic, h->pic ); else ret |= h->input.read_frame( p_pic, h->p_handle, i_frame ); if( !h->frame_total || i_frame+1 < h->frame_total ) { h->next_frame = h->next_args->i_frame = i_frame+1; h->next_args->pic = &h->pic; if( x264_pthread_create( &h->tid, NULL, (void*)read_frame_thread_int, h->next_args ) ) return -1; h->in_progress = 1; } else h->next_frame = -1; return ret; }
int x264_lookahead_init( x264_t *h, int i_slicetype_length ) { x264_lookahead_t *look; CHECKED_MALLOCZERO( look, sizeof(x264_lookahead_t) ); for( int i = 0; i < h->param.i_threads; i++ ) h->thread[i]->lookahead = look; look->i_last_keyframe = - h->param.i_keyint_max; look->b_analyse_keyframe = (h->param.rc.b_mb_tree || (h->param.rc.i_vbv_buffer_size && h->param.rc.i_lookahead)) && !h->param.rc.b_stat_read; look->i_slicetype_length = i_slicetype_length; /* init frame lists */ if( x264_sync_frame_list_init( &look->ifbuf, h->param.i_sync_lookahead+3 ) || x264_sync_frame_list_init( &look->next, h->frames.i_delay+3 ) || x264_sync_frame_list_init( &look->ofbuf, h->frames.i_delay+3 ) ) goto fail; if( !h->param.i_sync_lookahead ) return 0; x264_t *look_h = h->thread[h->param.i_threads]; *look_h = *h; if( x264_macroblock_cache_allocate( look_h ) ) goto fail; if( x264_macroblock_thread_allocate( look_h, 1 ) < 0 ) goto fail; if( x264_pthread_create( &look->thread_handle, NULL, (void*)x264_lookahead_thread, look_h ) ) goto fail; look->b_thread_active = 1; return 0; fail: x264_free( look ); return -1; }