关于参考帧中的x264_reference_update函数的补充及h->frames.unused[]的理解

2009-11-11 19:25
encoder.c


 1.   x264_encoder_encode(  )函数里面:
if( x264_reference_update( h ) )
return -1;



其中:
static inline int x264_reference_update( x264_t *h )
{   //在b_kept_as_ref=0的时候,也就是B帧不作为参考帧的时候,
//h->fenc->b_kept_as_ref =
//   h->fdec->b_kept_as_ref = i_nal_ref_idc != NAL_PRIORITY_DISPOSABLE && h->param.i_keyint_max > 1;


if( !h->fdec->b_kept_as_ref )
{
if( h->param.i_threads > 1 ) //多线程的情况
{                   
/
/这里面的语句就是取出h->fdec并不断的更新h->fdec
,关于POP和PUSH函数的详解在下面
x264_frame_push_unused( h, h->fdec ); //这个函数的就是当h->fdec中的参考帧数目为1的时候将h->fdec压进h的 unused[frame->b_fdec]数组里面         见函数解析1

h->fdec = x264_frame_pop_unused( h, 1 ); //这个函数是在这里相当于在fdec顶上中取一个farme出来给h->fdec              “见函数解析2”
if( !h->fdec )
return -1;
}
return 0;
}

/* move frame in the buffer */
//将 h->fdec压进h->frames.reference中作为参考
x264_frame_push( h->frames.reference, h->fdec );
//当还有参考帧存在时,x264_frame_shift( h->frames.reference )就是取出第一个参考帧h的 unused[frame->b_fdec]数组里面
if( h->frames.reference[h->frames.i_max_dpb] )
x264_frame_push_unused( h, x264_frame_shift( h->frames.reference ) );
//......
h->fdec = x264_frame_pop_unused( h, 1 );
if( !h->fdec )
return -1;
//当参考没有参考完就一直得到return 0
return 0;
}



函数解析1
//这个函数的就是参考帧数目为1的时候将frame压进unused数组里面
void x264_frame_push_unused( x264_t *h, x264_frame_t *frame )
{
assert( frame->i_reference_count > 0 );//参考帧的数目要大于0
frame->i_reference_count--;
if( frame->i_reference_count == 0 )//成立的条件是参看帧的数目只有一个
x264_frame_push( h->frames.unused[frame->b_fdec], frame );//从下面的分析x264_frame_push就是将
frame压进h->frames.unused[frame->b_fdec]数组里面
}

void x264_frame_push( x264_frame_t **list, x264_frame_t *frame )
{
int i = 0;
while( list[i] ) i++;
list[i] = frame;
}


函数解析2
x264_frame_t *x264_frame_pop_unused( x264_t *h, int b_fdec )//b_fdec=1
{
x264_frame_t *frame;
if( h->frames.unused[b_fdec][0] )
frame = x264_frame_pop( h->frames.unused[b_fdec] );//这里相当于再fdec顶上中取一个farme出来
else
frame = x264_frame_new( h, b_fdec );
if( !frame )
return NULL;
frame->b_last_minigop_bframe = 0;
frame->i_reference_count = 1;//初始化
frame->b_intra_calculated = 0;
return frame;
}

x264_frame_t *x264_frame_pop( x264_frame_t **list )
{
x264_frame_t *frame;
int i = 0;
assert( list[0] );
while( list[i+1] ) i++;
frame = list[i];
list[i] = NULL;
return frame;
}


2.关于unuesed的问题
struct
{
/* Frames to be encoded (whose types have been decided) */
x264_frame_t **current;
/* Unused frames: 0 = fenc, 1 = fdec */
x264_frame_t **unused[2];

/* frames used for reference + sentinels */
x264_frame_t *reference[16+2];

int i_last_idr; /* Frame number of the last IDR */

int i_input;    /* Number of input frames already accepted */

int i_max_dpb;  /* Number of frames allocated in the decoded picture buffer */
int i_max_ref0;
int i_max_ref1;
int i_delay;    /* Number of frames buffered for B reordering */
int b_have_lowres;  /* Whether 1/2 resolution luma planes are being used */
int b_have_sub8x8_esa;
} frames;


//截取的关于**unused[]的空间分配定义
CHECKED_MALLOCZERO( h->frames.unused[0], (h->frames.i_delay + 3) * sizeof(x264_frame_t *) );
/* Allocate room for max refs plus a few extra just in case. */
CHECKED_MALLOCZERO( h->frames.unused[1], (h->param.i_threads + 20) * sizeof(x264_frame_t *) );


从上面的/* Unused frames: 0 = fenc, 1 = fdec */
x264_frame_t **unused[2];
中可以看出二维指针**unused[0]代表的fenc的缓存,**unused[1]代表的fdec的缓存,至于这两个缓存的作用进我的博客
《参考帧管理》,至于为什么取名为unused,我觉得应该可以这么理解:从上面得update函数中可以看出来,pop,push中都是将
参考帧不停在**unused[0/1]中更新,也就是这里面的都是没有用到得帧。可以由定义x264_frame_t **unused[2];中的参数类型来
得出结论。

你可能感兴趣的:(多线程,list,buffer,input,reference,delay)