SVAC 2.0 解码库——ref_count参数(1)

来源:互联网 发布:金融建模需要会编程吗 编辑:程序博客网 时间:2024/06/05 16:30
  ref_count参数是结构体frame_bufs[15]的一个参数,frame_bufs[i]中的i是通过cm->new_fb_idx确定的。  初始化时 ref_count等于0,通过函数cm->new_fb_idx = get_free_fb(cm)赋值,代码如下:
static int get_free_fb(SVAC2_COMMON *cm) {    RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;    int i;    // 一共15个Buffer, 根据frame_bufs对应的ref_count来决定new_fb_idx    // 如果ref_count等于0, 表示此frame_bufs还没有存储重构数据    for (i = 0; i < FRAME_BUFFERS; ++i)    {        if (frame_bufs[i].ref_count == 0)        {            break;        }    }    assert(i < FRAME_BUFFERS);    frame_bufs[i].ref_count = 1;    return i;}

找到空闲的frame_bufs后, 会将其ref_count赋值为1,并得到cm->new_fb_idx=0。
在read_sps_rbsp函数中,根据pbi->refresh_frame_flags,对ref_count进行操作,代码如下:

for (mask = pbi->refresh_frame_flags; mask; mask >>= 1)    {        if (mask & 1)         {            cm->next_ref_frame_map[ref_index] = cm->new_fb_idx;            ++frame_bufs[cm->new_fb_idx].ref_count;        }         else        {            cm->next_ref_frame_map[ref_index] = cm->ref_frame_map[ref_index];        }        if (cm->ref_frame_map[ref_index] >= 0)        {            ++frame_bufs[cm->ref_frame_map[ref_index]].ref_count;        }        ++ref_index;    }    for (; ref_index < REF_FRAMES; ++ref_index)    {        cm->next_ref_frame_map[ref_index] = cm->ref_frame_map[ref_index];        if (cm->ref_frame_map[ref_index] >= 0)        {            ++frame_bufs[cm->ref_frame_map[ref_index]].ref_count;        }    }
  对于key_frame来说,因为pbi->refresh_frame_flags等于255,所以会循环8次,循环结束之后ref_count=9。并且在上述函数中对next_ref_frame_map进行了赋值。对于P帧,根据可用参考帧个数对ref_count进行操作。  ****备注:在初始化svac2_decoder_create函数时,对next_ref_frame_map和ref_frame_map进行了初始化。另:所有的操作都只针对next_ref_frame_map而不是ref_frame_map。****  在编码结束时在swap_frame_buffers函数中对ref_count进行操作。如下:
static void swap_frame_buffers(SVAC2Decoder *pbi){    int ref_index = 0, mask;    SVAC2_COMMON *const cm = &pbi->common;    BufferPool *const pool = cm->buffer_pool;    RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;    for (mask = pbi->refresh_frame_flags; mask; mask >>= 1)     {        const int old_idx = cm->ref_frame_map[ref_index];        decrease_ref_count(old_idx, frame_bufs, pool);        // Release the reference frame in reference map.        if ((mask & 1) && old_idx >= 0)         {            decrease_ref_count(old_idx, frame_bufs, pool);        }        cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index];        ++ref_index;    }    for (; ref_index < REF_FRAMES && !cm->show_existing_frame; ++ref_index)    {        const int old_idx = cm->ref_frame_map[ref_index];        decrease_ref_count(old_idx, frame_bufs, pool);        cm->ref_frame_map[ref_index] = cm->next_ref_frame_map[ref_index];    }    pbi->hold_ref_buf = 0;    cm->frame_to_show = get_frame_new_buffer(cm);    --frame_bufs[cm->new_fb_idx].ref_count;    // Invalidate these references until the next frame starts.    for (ref_index = 0; ref_index < 3; ref_index++)    {        cm->frame_refs[ref_index].idx = -1;    }}
  上述函数中对ref_count的操作可以理解为:如果当前帧使用了参考帧,就将ref_count做减1的操作,将已使用的参考帧buffer空出来以便增加新的参考帧。
0 0
原创粉丝点击