static void x264_lookahead_encoder_shift( x264_t *h ) { int bframes = 0; int i_frames = 0; while( h->lookahead->ofbuf.list[i_frames] ) { if( IS_X264_TYPE_B( h->lookahead->ofbuf.list[bframes]->i_type ) ) bframes++; else break; i_frames++; } if( h->lookahead->ofbuf.list[i_frames] ) { x264_frame_push( h->frames.current, x264_frame_shift( &h->lookahead->ofbuf.list[bframes] ) ); h->lookahead->ofbuf.i_size--; if( h->param.b_bframe_pyramid && bframes > 1 ) { x264_frame_t *mid = x264_frame_shift( &h->lookahead->ofbuf.list[bframes/2] ); h->lookahead->ofbuf.i_size--; mid->i_type = X264_TYPE_BREF; x264_frame_push( h->frames.current, mid ); bframes--; } while( bframes-- ) { x264_frame_push( h->frames.current, x264_frame_shift( h->lookahead->ofbuf.list ) ); h->lookahead->ofbuf.i_size--; } x264_pthread_cond_broadcast( &h->lookahead->ofbuf.cv_empty ); } }
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; }
static void fill_cache( cache_hnd_t *h, int frame ) { /* shift frames out of the cache as the frame request is beyond the filled cache */ int shift = frame - LAST_FRAME; /* no frames to shift or no frames left to read */ if( shift <= 0 || h->eof ) return; /* the next frames to read are either * A) starting at the end of the current cache, or * B) starting at a new frame that has the end of the cache at the desired frame * and proceeding to fill the entire cache */ int cur_frame = X264_MAX( h->first_frame + h->cur_size, frame - h->max_size + 1 ); /* the new starting point is either * A) the current one shifted the number of frames entering/leaving the cache, or * B) at a new frame that has the end of the cache at the desired frame. */ h->first_frame = X264_MIN( h->first_frame + shift, cur_frame ); h->cur_size = X264_MAX( h->cur_size - shift, 0 ); while( h->cur_size < h->max_size ) { cli_pic_t temp; /* the old front frame is going to shift off, overwrite it with the new frame */ cli_pic_t *cache = h->cache[0]; if( h->prev_filter.get_frame( h->prev_hnd, &temp, cur_frame ) || x264_cli_pic_copy( cache, &temp ) || h->prev_filter.release_frame( h->prev_hnd, &temp, cur_frame ) ) { h->eof = cur_frame; return; } /* the read was successful, shift the frame off the front to the end */ x264_frame_push( (void*)h->cache, x264_frame_shift( (void*)h->cache ) ); cur_frame++; h->cur_size++; } }
static void x264_lookahead_encoder_shift( x264_t *h ) { if( !h->lookahead->ofbuf.i_size ) return; int i_frames = h->lookahead->ofbuf.list[0]->i_bframes + 1; while( i_frames-- ) { x264_frame_push( h->frames.current, x264_frame_shift( h->lookahead->ofbuf.list ) ); h->lookahead->ofbuf.i_size--; } x264_pthread_cond_broadcast( &h->lookahead->ofbuf.cv_empty ); }
static void x264_lookahead_shift( x264_synch_frame_list_t *dst, x264_synch_frame_list_t *src, int count ) { int i = count; while( i-- ) { assert( dst->i_size < dst->i_max_size ); assert( src->i_size ); dst->list[ dst->i_size++ ] = x264_frame_shift( src->list ); src->i_size--; } if( count ) { x264_pthread_cond_broadcast( &dst->cv_fill ); x264_pthread_cond_broadcast( &src->cv_empty ); } }
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 ); } }