AV1中帧类型
在H.26X系列标准中,根据帧允许的预测模式可以将帧分为I帧、P帧和B帧,根据帧在码流中前后的参考关系又可以分为IRAP、RADL等。AV1也类似地将帧分为4种类型,在码流中用frame_type来标识帧类型。
KEY_FRAME:相当于IDR帧;
INTER_FRAME:相当于265中的P/B帧;
INTRA_ONLY_FRAME:相当于265中的I帧;
SWITCH_FRAME(S-FRAME):当码流在不同分辨率间切换时可以插入S-FRAME来代替部分IDR帧,S-FRAME可以参考不同分辨率的帧;
AV1中帧的显示顺序
由于后向参考的存在使得帧的编码顺序和显示顺序可能不同,在H265中为了按正确的顺序播放视频,使用POC来控制解码后帧的显示。而AV1中没有POC,为了按正确顺序播放帧AV1采用show_frame / showable_frame / show_existing_frame机制来完成这一功能。这三个语法元素都写在frame_header中。
show_frame:当前帧解码完后是否立刻输出。对于解码顺序在播放顺序前的帧该值为0。
showable_frame:这个标志只在show_frame=0时有意义,它是指当前帧是否可以显示。AV1有一个ARNR技术,它会对GPB帧进行一些时域滤波产生ARF帧,ARF帧只用作参考而不显示。
show_existing_frame:输出图像是否已经在DPB中。这个语法元素是为了显示那些延迟输出的图像。
frame_to_show_map_idx:当show_existing_frame=1时输出对应帧。
参考帧管理
AV1中解码后的帧放入DFB(Decoded Frame Buffer)中,其作用类似于265中的DPB。DFB最多只能放8帧,其中7帧可以作为参考帧。AV1为这7个参考帧分别命名,
参考帧名称 | 含义 |
LAST_FRAME | POC小于当前帧的图像中最近的帧 |
LAST2_FRAME | POC小于当前帧的图像中第二接近的帧 |
LAST3_FRAME | POC小于当前帧的图像中第三接近的帧 |
GOLDEN_FRAME | POC小于当前帧的I帧或者GPB帧,类似于长期参考帧 |
BWDREF_FRAME | POC大于当前帧的图像中最接近当前帧的 |
ALTREF2_FRAME | POC大于当前帧的图像中第二接近当前帧的 |
ALTREF_FRAME | POC大于当前帧的图像中离当前帧最远的图像 |
注意,上面参考帧和当前帧的位置关系只是建议不是必须的,例如ALFREF_FRAME的POC可以小于当前帧。
AV1中参考帧管理涉及两个方面,一个是DFB管理,一个是当前帧如何在DFB中找到自己的参考帧。
DFB管理
更新类型Update Type
update type不是编码标准的一部分,它是编码器为了进行码率控制和参考帧管理而引入的,包括KF_UPDATE, LF_UPDATE, GF_UPDATE, ARF_UPDATE, OVERLAY_UPDATE, INTNL_OVERLAY_UPDATE, INTNL_ARF_UPDATE等7种。frame_update_type在编码前由帧类型和其在GOP中的位置决定。
更新类型 | 备注 |
KF_UPDATE | IDR |
LF_UPDATE | 不被其他帧参考的B帧 |
ARF_UPDATE | GPB |
INTNL_ARF_UPDATE | 层级高于GPB帧,低于普通B帧的帧 |
INTNL_OVERLAY_UPDATE | 参考GPB,同时被其他B帧参考的图像的延迟输出帧 |
OVERYLAY_UPDATE | GPB的延迟输出帧 |
GF_UPDATE |
DFB更新过程
AV1通过语法元素refresh_frame_flags 来管理DFB状态。refresh_frame_flags 是一个8比特数据,每一位对应DFB中的一个位置,某位置1表示当前帧解码后替换DFB中的该帧。
DFB具体更新过程为:
1、每帧图像编码前根据帧类型和其在GOP中的位置决定更新类型frame_update_type。
2、DPB中的帧根据和当前帧的位置关系等被分为三类:arf_stack、lst_stack、gld_stack。每类包含对应类型的参考帧。
1、当前帧编码完后检查DFB是否填满,若未填满则将当前帧加入DFB。若DFB已填满则根据每类帧的数量和类型选择最老的一帧替换掉。并根据该帧在DFB中的位置计算refresh_frame_flags 。
参考列表构建:
DFB构建完毕后当前帧需要使用DFB中的帧构建自己的参考列表,av1规定参考列表只能包含7帧。
-
DPB中的帧被分为三类:arf_stack、lst_stack、gld_stack。
-
确定后向的参考帧,将arf_stack中的POC最大的帧作为ALTREF_FRAME(这一帧一般是当前GOP的GPB);如果alt_stack中还有其他帧,则第0帧作为BWDREF_FRAME,第1帧作为ALTREF2_FRAME。若alf_stack中只有1帧则将其作为BWDREF_FRAME。
-
确定前向的参考帧,将lst_stack中的第0帧作为LAST_FRAME,第1帧作为LAST2_FRAME,如果lst_stack中还有帧则将第2帧作为LAST3_FRAME。
-
确定GOLDEN_FRAME,将golden_stack中的第0帧作为GOLDEN_FRAME,若golden_stack中还有帧且BWDREF_FRAME或者ALTREF_FRAME或者LAST3_FRAME未被指定,则用第1帧填充。
-
从后向前检查所有帧类型是否都已经被指定,如果还有一些帧还没有被指定,那么它分别在arf_ref、last_ref和golden_ref队列中寻找仍然没有被分配的帧,并将它指定为所需要的帧类型。
-
如果有些参考帧类型仍然没有被指定,那就将golden_ref中的第0帧指定为该类型的参考帧。
-
填充之后所有类型的参考帧都是可用的。编码器会记录下所有类型的参考帧在DPB中的位置,并把结果写入码流。这样解码器拿到DFB之后立刻就可以组合出参考帧队列。
-
这些参考帧类型有可能会有重复。在实际编码时需要进行去重,避免重复搜索。
参考列表如何在码流中传输?构建完参考列表后需要在码流中写入每个参考帧对应在DFB中的位置,相关语法元素为ref_frame_idx
i:0-6,0表示LAST_FRAME,1表示LAST2_FRAME,2表示LAST3_FRAME,3表示GOLDEN_FRAME,4表示BWDREF_FRAME,5表示ALTREF2_FRAME,6表示ALTREF_FRAME。那ref_frame_idx[LAST_FRAME]=5 就表示DPB 下标为5的位置上存在的帧(ref_frame_map[5])就是当前帧的LAST_FRAME。
ref_frame_idx的值有2种传输方式,当frame_refs_short_signaling=0的时候,所有的参考值都是显示传递的,也就是直接通过码流读取到的,当frame_refs_short_signaling=1的时候,只有last_frame_idx和gold_fame_idx是显示传递的,其他参考值则是通过计算得到的。
ARF参考帧和overlay帧
ARF(Alternate Reference Frame)帧是一类特殊参考帧,它会被编码并在DFB中存储用于其他帧的帧间预测参考,但是不会在解码端显示。它对应的showable_frame语法元素值为0。
ARF帧往往是对原始帧们进行时域滤波处理,以降低原始帧里的噪声而得到的帧,用它作为参考帧可以提高视频编码的性能。
上图是含有ARF的AV1编码结构,这里的GOP大小4,灰色框表示的是需要显示的帧,ARF不需要显示用白色表示。
从上图可以看出,每一帧在显示之前需要完成解码,且ARF帧的解码顺序很靠前。这是因为通常ARF帧是时域滤波处理得到的,而时域滤波处理一般只对低layer的帧进行,这也意味着,在一个GOP里面并不是谁都可以成为ARF帧。
因为ARF帧解码后不显示,这会导致编码器送入的帧会比播放端的帧多,这时就需要overlay帧和ARF帧配合使用,这个Overlay它会以(相同帧号的)ARF作为参考帧进行预测编码得到压缩码流,当在解码端解码以后,可以显示它的画面,而且它自身不会被用来作参考帧。
感兴趣的请关注微信公众号Video Coding