AV1标准文档定义了函数initialize_buffer_pool 初始化缓冲池和VBI数组,该过程描述如下:
initialize_buffer_pool()
{
//BUFFER POOL MAX SIZE等于10
for (i = 0; i < BUFFER_POOL_MAC_SIZE; i++) free_buffer(i)
for(i = 0; i < 8; i++) VBI[i] = -1;
free_buffer(idx) {
DecoderrefCount[idx] = 0;
PlayerRefCount[idx] = 0;
//PresentationTimes[i]是一个与缓冲池Framebuffers[i] 关联的数组
//它记录了在该插槽中存储的解码帧最后一次展示时间
PresentationTimes[idx] = -1;
}
}
随着解码过程的进行,解码器需要对缓冲池进行管理。为此,AV1标准文档定义了两个数组变量DecoderRefCount[10]和PlayerRefCount[10];分别用于跟踪解码过程和现实过程中每个帧缓冲区插槽的使用状态,图2-4为AV1中DPB的管理示意图,其中FrameBuffers[10]表示10个物理帧缓冲区,该物理帧缓冲区由f0 ~f9表示帧缓冲区插槽组成。
PlayerRefCount[10]
DecoderRefCount[10]
FrameBuffers[10]
VBI[x]
图2-4 AV1中DPB管理示意图
变量DecoerRefCount[idx] 表示在解码过程中位于缓冲池中索引为idx的槽位被引用的次数,初始化为0,并且每次解码器将缓冲池的卡槽idx添加到VBI索引槽时,该变量的值会增加1.相应的,每次解码器从VBI索引槽中移除卡槽idx时,该变量的值会减少1.这个参数由语法元素refresh_frame_type 来更新VBI索引时,计数器DecoderRefCount[idx] 才会按照上述方式修改。当计数器DecoderRefCount[idx] = 0时,表示缓冲池索引为idx的卡槽所存储的图像像素数据将永久失败,并且解码过程不应再使用这些数据。
在AV1标准文档中,函数update_ref_buffers 用于在更新DBP时,更新数组VBI和DecoderRefCount 该函数定义的更新过程如下。
当前帧 解码完毕后,解码器需要调用update_ref_buffers 来用VBI记录当前解码帧的插槽位置。所以这里的idx一般是cfbi。
update_ref_buffers(idx, refresh_frame_flags)
遍历VBI中国呢的每个位置,寻找语法元素refresh_frame_flags指示的位置。
for (i = 0; i < 8; i++)
if (refresh_frame_flags & (1 << i))
if (VBI[i] != -1)
DecoderRefCount[VBI[i]] --;
把语法元素refresh_frame_flags 指示的位置设置为当前帧的插槽索引。
VBI[i] = idx
DecoderRefCount[VBI[i]] ++;
变量PlayerRefCount[idx]是一个计数器,用于指示解码过程中缓冲池索引为idx的插槽所存储的解码帧是否仍然需要用于显示过程。在初始化的时候被设置为0,并且每档解码器确定某个帧是一个展示帧时,这个计数器的值就会增加1.当帧最后一次被展示的时候,PlayerRefCount[idx]会被重置为0,因此,当show_frame等于1或者show_existing_frame 等于1时,解码器需要设置对应的PlayerRefCount[idx]。该过程位于解码器模型函数decode_process之中,描述如下
if (initialPresentationDelay != 0 && show_existing_frame == 1 || show_frame == 1)
{
displayIdx即此处的idx,表示待显示帧在缓冲池BufferPool中的卡槽索引。
//displayIdx = VBI[fame_to_show_map_idx]或者displayidx = cfbl
//ShowFrameNum是显示帧的数量,即每一帧显示ShownFrameNum增加1.
PresetationTimes[displayIdx] = presentationTime[ShownFrameNum]
PlayRefCount[displayIdx]++
}
当解码帧在其最后呈现时间已经显示了,则将PlayerRefCount[idx]设置为0,在AV1标准文档中,函数start_decode_at_removal_time 描述了PlayerRefCount[idx]设置为0的过程。