先上代码及注释

  1. #define X264_SCAN8_SIZE (6*8) //!< 扫描表的尺寸
  2. #define X264_SCAN8_0 (4+1*8) //!< 扫描表第一个扫描序(即亮度的首扫描序)
  3. static const int x264_scan8[16+2*4+3] =
  4. {
  5. /* Luma */
  6. 4+1*8, 5+1*8, 4+2*8, 5+2*8,
  7. 6+1*8, 7+1*8, 6+2*8, 7+2*8,
  8. 4+3*8, 5+3*8, 4+4*8, 5+4*8,
  9. 6+3*8, 7+3*8, 6+4*8, 7+4*8,
  10. /* Cb */
  11. 1+1*8, 2+1*8,
  12. 1+2*8, 2+2*8,
  13. /* Cr */
  14. 1+4*8, 2+4*8,
  15. 1+5*8, 2+5*8,
  16. /* Luma DC */
  17. 4+5*8,
  18. /* Chroma DC */
  19. 5+5*8, 6+5*8
  20. };
  21. /*
  22. 0 1 2 3 4 5 6 7
  23. 0
  24. 1 B B L L L L
  25. 2 B B L L L L
  26. 3 L L L L
  27. 4 R R L L L L
  28. 5 R R DyDuDv
  29. */ // B – Cb; R – Cr; L – Luma; Dy – Luma DC; Du – Cb DC; Dv – Cr DC

x264_scan8是一个存放着4x4亮度块及色度块扫描序的数组,其内存存储方式如下所示:

其中,每一个小方格代表着一个4x4块,方格中的数字则是对应块的序号。

根据代码中对x264_scan8这个数组的赋值不难得到上图,其中,红色方块代表的是亮度块,绿色块和蓝色块分别代表两个色度块,而三个橙色块则依次代表亮度、两个色度的DC块。

为什么要这么做呢?我们知道,在进行帧内预测,帧间运动矢量预测的时候,需要使用到当前块的left块和top块,在CAVLC编码过程中,也需要知道当前块的left块和top块的non_zero_count,故由上图可以看到,空出来的部分可以用于存储前述所需的left块和top块的相关参数,起到便于访问和节省内存的作用。

看下面这个例子:

  1. void x264_mb_predict_mv_16x16( x264_t *h, int i_list, int i_ref, int16_t mvp[2] )
  2. {
  3. int i_refa = h->mb.cache.ref[i_list][X264_SCAN8_0 - 1]; //!< a块参考帧序号
  4. int16_t *mv_a = h->mb.cache.mv[i_list][X264_SCAN8_0 - 1]; //!< a块的运动矢量
  5. int i_refb = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8]; //!< b块参考帧序号
  6. int16_t *mv_b = h->mb.cache.mv[i_list][X264_SCAN8_0 - 8]; //!< b块的运动矢量
  7. int i_refc = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8 + 4]; //!< c块参考帧序号
  8. int16_t *mv_c = h->mb.cache.mv[i_list][X264_SCAN8_0 - 8 + 4]; //!< c块的运动矢量
  9. int i_count;
  10. if( i_refc == -2 )
  11. {
  12. i_refc = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8 - 1];
  13. mv_c = h->mb.cache.mv[i_list][X264_SCAN8_0 - 8 - 1];
  14. }
  15. i_count = 0;
  16. if( i_refa == i_ref ) i_count++;
  17. if( i_refb == i_ref ) i_count++;
  18. if( i_refc == i_ref ) i_count++;
  19. if( i_count > 1 )
  20. x264_median_mv( mvp, mv_a, mv_b, mv_c );
  21. else if( i_count == 1 )
  22. {
  23. if( i_refa == i_ref )
  24. *(uint32_t*)mvp = *(uint32_t*)mv_a;
  25. else if( i_refb == i_ref )
  26. *(uint32_t*)mvp = *(uint32_t*)mv_b;
  27. else
  28. *(uint32_t*)mvp = *(uint32_t*)mv_c;
  29. }
  30. else if( i_refb == -2 && i_refc == -2 && i_refa != -2 )
  31. *(uint32_t*)mvp = *(uint32_t*)mv_a;
  32. else
  33. x264_median_mv( mvp, mv_a, mv_b, mv_c );
  34. }

其中,a块,b块,c块分别是当前宏块左、上、右上邻块,结合x264_scan8的赋值及上图不难分析出上述结论。

(转载请注明出处。)

转载自:https://blog.csdn.net/hevc_cjl/article/details/8273533

x264_scan8分析相关推荐

  1. x264里的2pass指的是什么意思? x264源代码分析2.encode()

    A:x264里的2pass指的是什么意思?另外stat是什么意思, 比如有个参数--stats <string>        Filename for 2 pass stats [/&q ...

  2. x264源代码简单分析:熵编码(Entropy Encoding)部分

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  3. x264源代码简单分析:宏块编码(Encode)部分

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  4. x264源代码简单分析:宏块分析(Analysis)部分-帧间宏块(Inter)

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  5. x264源代码简单分析:x264_slice_write()

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  6. x264源代码分析.

    l 相关说明: 1. 使用版本: x264-cvs- 2004-05-11 2. 这次的分析基本上已经将代码中最难理解的部分做了阐释,对代码的主线也做了剖析,如果这个主线理解了,就容易设置几个区间,进 ...

  7. x264源代码简单分析:宏块分析(Analysis)部分-帧内宏块(Intra)

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  8. 【Golang源码分析】Go Web常用程序包gorilla/mux的使用与源码简析

    目录[阅读时间:约10分钟] 一.概述 二.对比: gorilla/mux与net/http DefaultServeMux 三.简单使用 四.源码简析 1.NewRouter函数 2.HandleF ...

  9. 2022-2028年中国自动驾驶系统行业现状调研分析报告

    [报告类型]产业研究 [报告价格]4500起 [出版时间]即时更新(交付时间约3个工作日) [发布机构]智研瞻产业研究院 [报告格式]PDF版 本报告介绍了中国自动驾驶系统行业市场行业相关概述.中国自 ...

最新文章

  1. linux进程间通信:POSIX 消息队列
  2. 什么是Closed-form solution?
  3. 面向行人重识别的局部特征研究进展、挑战与展望
  4. mysql实验的好处_用好UniProt 数据库,蛋白实验不用愁
  5. 【opencv】7. cv::VideoWriter的使用,把图片写进video
  6. Linux DNS服务配置与管理详解
  7. ABAP 代码中,哪些特殊字符不能用于变量命名?
  8. TSynDBDataSet内存表
  9. 合肥一六八2021高考成绩查询,合肥高考成绩查询入口
  10. DSP28335看门狗复位
  11. Minio入门系列【19】断点续传和断点下载实现方案
  12. Java微服务和分布式区别
  13. 运兴ETF:期权多空双向,策略多样优势大
  14. 捷太格特PC10G与三菱MR-J4的SSCNETⅢ通讯
  15. java 通用事件回调类(观察者队列)
  16. SPA(单页面应用)的理解
  17. 全新UI宝宝起名神器小程序源码+样式非常美观
  18. 网络可视对讲系统服务器解决方案,医护可视对讲系统(IP网络)解决方案
  19. preLaunchTask“C/C++:g++.exe生成活动文件“已终止,退出代码为-1
  20. [js常用积累] js正则表达式验证手机号和数字验证码

热门文章

  1. 容器编排技术 -- Kubernetes 给容器和Pod分配CPU资源
  2. Mac OS下Tomcat native-APR的安装
  3. Spring ActiveMQ教程
  4. 界面发布2019中国最富1000人榜:凛冬望春,马云问鼎中国首富
  5. Java8新特性教程 - 终极指南
  6. Debian/Ubuntu系统下,apt-get update 、apt-get upgrade 、apt-get dist-upgrade 命令之间的区别
  7. jQuery封装tab选项卡组件(自定义自动功能和延迟显示功能)
  8. 【JAVA 第五章 】课后习题 奇数排前
  9. C while 循环
  10. 【mysql】显式加锁