您的位置:首页 > Web前端

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

2012-11-13 16:15 651 查看
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];中的参数类型来

得出结论。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: