最新版(2013.01.17)x264的多线程代码研究(一)
先罗列出代码中与多线程有关的宏定义、结构体、变量、函数等,锁定为需要重点关注的对象,在接下来的研究中逐步深入探讨这些对象的含义和作用。[cpp]
#define X264_THREAD_MAX 128
#define X264_LOOKAHEAD_THREAD_MAX 16
#define X264_LOOKAHEAD_MAX 250
// arbitrary, but low because SATD scores are 1/4 normal
#define X264_LOOKAHEAD_QP (12+QP_BD_OFFSET)
// number of pixels (per thread) in progress at any given time.
// 16 for the macroblock in progress + 3 for deblocking + 3 for motion compensation filter + 2 for extra safety
#define X264_THREAD_HEIGHT 24
[cpp]
#define x264_pthread_t pthread_t
#define x264_pthread_create pthread_create
#define x264_pthread_join pthread_join
#define x264_pthread_mutex_t pthread_mutex_t
#define x264_pthread_mutex_init pthread_mutex_init
#define x264_pthread_mutex_destroy pthread_mutex_destroy
#define x264_pthread_mutex_lock pthread_mutex_lock
#define x264_pthread_mutex_unlock pthread_mutex_unlock
#define x264_pthread_cond_t pthread_cond_t
#define x264_pthread_cond_init pthread_cond_init
#define x264_pthread_cond_destroy pthread_cond_destroy
#define x264_pthread_cond_broadcast pthread_cond_broadcast
#define x264_pthread_cond_wait pthread_cond_wait
#define x264_pthread_attr_t pthread_attr_t
#define x264_pthread_attr_init pthread_attr_init
#define x264_pthread_attr_destroy pthread_attr_destroy
#define x264_pthread_num_processors_np pthread_num_processors_np
#define X264_PTHREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
[cpp]
typedef struct x264_lookahead_t
{
volatile uint8_t b_exit_thread;
uint8_t b_thread_active;
uint8_t b_易做图yse_keyframe;
int i_last_keyframe;
int i_slicetype_length;
x264_frame_t *last_nonb;
x264_pthread_t thread_handle;
x264_sync_frame_list_t ifbuf;
x264_sync_frame_list_t next;
x264_sync_frame_list_t ofbuf;
} x264_lookahead_t;
[cpp]
/* synchronized frame list */
typedef struct
{
x264_frame_t **list;
int i_max_size;
int i_size;
x264_pthread_mutex_t mutex;
x264_pthread_cond_t cv_fill; /* event signaling that the list became fuller */
x264_pthread_cond_t cv_empty; /* event signaling that the list became emptier */
} x264
typedef struct x264_frame //!< 为节省篇幅,仅附上与线程有关的成员变量
{
/* threading */
int i_lines_completed; /* in pixels */
int i_lines_weighted; /* FIXME: this only supports weighting of one reference frame */
int i_reference_count; /* number of threads using this frame (not necessarily the number of pointers) */
x264_pthread_mutex_t mutex;
x264_pthread_cond_t cv;
} x264_frame_t;
[cpp]
/* threading */
void x264_frame_cond_broadcast( x264_frame_t *frame, int i_lines_completed )
{
x264_pthread_mutex_lock( &frame->mutex );
frame->i_lines_completed = i_lines_completed;
x264_pthread_cond_broadcast( &frame->cv );
x264_pthread_mutex_unlock( &frame->mutex );
}
void x264_frame_cond_wait( x264_frame_t *frame, int i_lines_completed )
{
x264_pthread_mutex_lock( &frame->mutex );
while( frame->i_lines_completed < i_lines_completed )
x264_pthread_cond_wait( &frame->cv, &frame->mutex );
x264_pthread_mutex_unlock( &frame->mutex );
}
void x264_threadslice_cond_broadcast( x264_t *h, int pass )
{
x264_pthread_mutex_lock( &h->mutex );
h->i_threadslice_pass = pass;
if( pass > 0 )
x264_pthread_cond_broadcast( &h->cv );
x264_pthread_mutex_unlock( &h->mutex );
}
void x264_threadslice_cond_wait( x264_t *h, int pass )
{
x264_pthread_mutex_lock( &h->mutex );
while( h->i_threadslice_pass < pass )
x264_pthread_cond_wait( &h->cv, &h->mutex );
x264_pthread_mutex_unlock( &h->mutex );
}
[cpp]
int x264_sync_frame_list_init( x264_sync_frame_list_t *slist, int max_size )
{
if( max_size < 0 )
return -1;
slist->i_max_size = max_size;
slist->i_size = 0;
CHECKED_MALLOCZERO( slist->list, (max_size+1) * sizeof(x264_frame_t*) );
if( x264_pthread_mutex_init( &slist->mutex, NULL ) ||
x264_pthread_cond_init( &slist->cv_fill, NULL ) ||
x264_pthread_cond_init( &slist->cv_empty, NULL ) )
return -1;
return 0;
fail: