5.2.3 Y模式解码

作者:chai51
出处:https://www.cnblogs.com/chai51
版权:本文版权归作者和博客园共有
转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任

引言

Y模式解码是帧间预测模式信息解码的核心步骤,它确定当前块使用的预测模式类型(NEWMV、NEARESTMV、NEARMV、GLOBALMV等)。Y模式的选择决定了如何获取和使用运动向量。

源码说明: 本文档基于作者自己编写的AV1解码器Python实现,所有代码示例和实现细节均来自实际可运行的源码。源码仓库:GitHub - av1_learning


Y模式解码概述

位置: src/tile/tile_group.py - __inter_block_mode_info()

功能说明

Y模式解码确定当前块使用的预测模式类型,包括NEWMV、NEARESTMV、NEARMV、GLOBALMV等模式。

模式类型

  • NEWMV / NEW_NEWMV: 新运动向量,需要解码MV差值
  • NEARESTMV / NEAREST_NEARESTMV: 使用最近的候选MV
  • NEARMV / NEAR_NEARMV: 使用近邻候选MV
  • GLOBALMV / GLOBAL_GLOBALMV: 使用全局运动参数
  • NEAR_NEWMV / NEW_NEARMV: 混合模式

解码流程

# 1. 检查skip_mode
if skip_mode == 1:
    YMode = NEAREST_NEARESTMV

# 2. 检查分段特征
elif segment_feature_enabled(SEG_LVL_SKIP) or segment_feature_enabled(SEG_LVL_GLOBALMV):
    YMode = GLOBALMV

# 3. 如果是复合预测
elif isCompound:
    compound_mode = read_S(av1, 'compound_mode')
    YMode = NEAREST_NEARESTMV + compound_mode

# 4. 单参考模式
else:
    new_mv = read_S(av1, 'new_mv')
    if new_mv == 0:
        YMode = NEWMV
    else:
        zero_mv = read_S(av1, 'zero_mv')
        if zero_mv == 0:
            YMode = GLOBALMV
        else:
            ref_mv = read_S(av1, 'ref_mv')
            YMode = NEARESTMV if ref_mv == 0 else NEARMV

Y模式解码流程图

Y模式解码主流程

graph TD A[Y模式解码开始<br/>__inter_block_mode_info] --> B[初始化调色板大小<br/>PaletteSizeY = 0<br/>PaletteSizeUV = 0] B --> C[解码参考帧<br/>__read_ref_frames] C --> D[构建MV栈<br/>find_mv_stack] D --> E[计算复合预测] E --> F{skip_mode == 1?} F -->|是| G[NEAREST_NEARESTMV] F -->|否| H{分段特征<br/>SEG_LVL_SKIP<br/>或SEG_LVL_GLOBALMV?} G --> REF[解码RefMvIdx] H -->|是| I[GLOBALMV] H -->|否| J{复合预测?} I --> REF J -->|是| K[解码compound_mode] J -->|否| L[单参考模式解码] K --> M[NEAREST_NEARESTMV + compound_mode] M --> REF L --> N[解码new_mv] N --> O{new_mv == 0?} O -->|是| P[NEWMV] O -->|否| Q[解码zero_mv] P --> REF Q --> R{zero_mv == 0?} R -->|是| S[GLOBALMV] R -->|否| T[解码ref_mv] S --> REF T --> U{ref_mv == 0?} U -->|是| V[NEARESTMV] U -->|否| W[NEARMV] V --> REF W --> REF REF --> ASSIGN[分配运动向量<br/>__assign_mv] ASSIGN --> INTERINTRA[解码Inter-Intra模式<br/>__read_interintra_mode] INTERINTRA --> MOTION[解码运动模式<br/>__read_motion_mode] MOTION --> COMPOUND[解码复合类型<br/>__read_compound_type] COMPOUND --> FILTER[解码插值滤波器] FILTER --> END[Y模式解码完成] style A fill:#e1f5ff style F fill:#fff9c4 style H fill:#fff9c4 style J fill:#fff9c4 style O fill:#fff9c4 style R fill:#fff9c4 style U fill:#fff9c4 style END fill:#c8e6c9

详细技术文档参考

说明: 以下内容来自详细技术文档,包含完整的实现细节和代码说明。这些内容主要用于技术参考。

点击展开查看详细技术文档

RefMvIdx解码流程(DRL模式)

graph TD A[RefMvIdx解码开始] --> B[RefMvIdx = 0] B --> C{YMode类型} C -->|NEWMV<br/>NEW_NEWMV| D[DRL模式解码NEWMV] C -->|NEARMV<br/>NEAR_NEARMV<br/>NEAR_NEWMV<br/>NEW_NEARMV| E[DRL模式解码NEARMV] C -->|其他| F[RefMvIdx保持为0] D --> D1{MV候选数量少于2个?} D1 -->|是| D2[解码drl_mode idx=0] D1 -->|否| D3[RefMvIdx = 0] D2 --> D4{drl_mode == 0?} D4 -->|是| D5[RefMvIdx = 0] D4 -->|否| D6[RefMvIdx = 1] D6 --> D7{MV候选数量大于2个?} D7 -->|是| D8[解码drl_mode idx=1] D7 -->|否| D9[RefMvIdx = 1] D8 --> D10{drl_mode == 0?} D10 -->|是| D11[RefMvIdx = 1] D10 -->|否| D12[RefMvIdx = 2] D3 --> END D5 --> END D9 --> END D11 --> END D12 --> END E --> E1[RefMvIdx = 1] E1 --> E2{MV候选数量大于2个?} E2 -->|是| E3[解码drl_mode idx=1] E2 -->|否| E4[RefMvIdx = 1] E3 --> E5{drl_mode == 0?} E5 -->|是| E6[RefMvIdx = 1] E5 -->|否| E7[RefMvIdx = 2] E7 --> E8{MV候选数量大于3个?} E8 -->|是| E9[解码drl_mode idx=2] E8 -->|否| E10[RefMvIdx = 2] E9 --> E11{drl_mode == 0?} E11 -->|是| E12[RefMvIdx = 2] E11 -->|否| E13[RefMvIdx = 3] E4 --> END E6 --> END E10 --> END E12 --> END E13 --> END F --> END[RefMvIdx解码完成] style A fill:#e1f5ff style C fill:#fff9c4 style D4 fill:#fff9c4 style D10 fill:#fff9c4 style E5 fill:#fff9c4 style E11 fill:#fff9c4 style END fill:#c8e6c9

总结

Y模式解码确定当前块使用的预测模式类型,是帧间预测模式信息解码的核心步骤。不同的Y模式对应不同的MV获取方式,直接影响后续的运动向量分配。


参考资源:

上一篇: 运动向量栈构建
下一篇: 运动向量分配

posted @ 2026-01-10 07:52  chai51  阅读(0)  评论(0)    收藏  举报