x265-1.8版本-common/wavefront.cpp注释
2016-02-15 19:55
519 查看
注:问号以及未注释部分 会在x265-1.9版本内更新
/***************************************************************************** * Copyright (C) 2013 x265 project * * Authors: Steve Borho <steve@borho.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. * * This program is also available under a commercial proprietary license. * For more information, contact us at license @ x265.com *****************************************************************************/ #include "threadpool.h" #include "threading.h" #include "wavefront.h" #include "common.h" namespace X265_NS { // x265 private namespace /** 函数功能 : 初始化WaveFront /* 调用范围 : 只在FrameEncoder::init函数中被调用 * \参数 numRows : 一帧的CTU行数*2 * 返回值 : 成功返回ture 失败返回 false **/ bool WaveFront::init(int numRows) { m_numRows = numRows;//一帧CTU行数*2 m_numWords = (numRows + 31) >> 5;//map占用的字节数目 m_internalDependencyBitmap = X265_MALLOC(uint32_t, m_numWords); if (m_internalDependencyBitmap) memset((void*)m_internalDependencyBitmap, 0, sizeof(uint32_t) * m_numWords); m_externalDependencyBitmap = X265_MALLOC(uint32_t, m_numWords); if (m_externalDependencyBitmap) memset((void*)m_externalDependencyBitmap, 0, sizeof(uint32_t) * m_numWords); return m_internalDependencyBitmap && m_externalDependencyBitmap; } /** 函数功能 : 释放内存 析构函数 /* 调用范围 : 只在~FrameEncoder()函数中被调用 **/ WaveFront::~WaveFront() { x265_free((void*)m_internalDependencyBitmap); x265_free((void*)m_externalDependencyBitmap); } /** 函数功能 : 将当前WPPmap全部初始化为不可执行 /* 调用范围 : 只在FrameEncoder::compressFrame()函数中被调用 * \返回 : null * */ void WaveFront::clearEnabledRowMask() { memset((void*)m_externalDependencyBitmap, 0, sizeof(uint32_t) * m_numWords); memset((void*)m_internalDependencyBitmap, 0, sizeof(uint32_t) * m_numWords); } /** 函数功能 : 将当前row对应位置的map置为1 标记可以执行 /* 调用范围 : 只在enqueueRowEncoder和enqueueRowFilter函数中被调用 * \参数 row : CTU行号*2 + x x= 0 为 enqueueRowEncoder x= 1 为enqueueRowFilter * \返回 : null* */ void WaveFront::enqueueRow(int row) { uint32_t bit = 1 << (row & 31);//(row & 31) 表示当前row在当前组(32个row行为一组)的标号 1 << (row & 31) 表示 其具体位置: 如 组内偏移地址为(0~31)对应(1~2^31) ATOMIC_OR(&m_internalDependencyBitmap[row >> 5], bit);//m_internalDependencyBitmap[row >> 5] 表示其组位置 与bit后对应位置置为1 } /** 函数功能 : 将当前row对应位置的map置为1 标记可以执行 /* 调用范围 : 只在enableRowEncoder和enableRowFilter函数中被调用 * \参数 row : CTU行号*2 + x x= 0 为 enableRowEncoder x= 1 为enableRowFilter * \返回 : null* */ void WaveFront::enableRow(int row) { uint32_t bit = 1 << (row & 31);//(row & 31) 表示当前row在当前组(32个row行为一组)的标号 1 << (row & 31) 表示 其具体位置: 如 组内偏移地址为(0~31)对应(1~2^31) ATOMIC_OR(&m_externalDependencyBitmap[row >> 5], bit);//m_externalDependencyBitmap[row >> 5] 表示其组位置 与bit后对应位置置为1 } /** 函数功能 : 将外部map全部标记为可执行 /* 调用范围 : 无调用位置 * \返回 : null* */ void WaveFront::enableAllRows() { memset((void*)m_externalDependencyBitmap, ~0, sizeof(uint32_t) * m_numWords); } /** 函数功能 : 将当前row对应位置的map置为0 标记可以执行 /* 调用范围 : 只在processRowEncoder函数中被调用 * \参数 row : CTU行号*2 + x x= 0 为 enableRowEncoder x= 1 为enableRowFilter * \返回 : 一般返回false* */ bool WaveFront::dequeueRow(int row) { uint32_t bit = 1 << (row & 31);//(row & 31) 表示当前row在当前组(32个row行为一组)的标号 1 << (row & 31) 表示 其具体位置: 如 组内偏移地址为(0~31)对应(1~2^31) return !!(ATOMIC_AND(&m_internalDependencyBitmap[row >> 5], ~bit) & bit);//m_externalDependencyBitmap[row >> 5] 表示其组位置 将对应位置的map标记为0 } /** 函数功能 : 触发WPP(在threadMain()主动发起) 只进行处理一个CTU行即退出(不一定执行完毕)(其它CTU需要重新触发) /* 调用范围 : 只在WorkerThread::threadMain()(在compressFrame()、processRowEncoder通过tryWakeOne()中触发执行) * \参数 threadId : 当前的内核号 * \返回 : null * */ void WaveFront::findJob(int threadId) { unsigned long id;//用于获取组内地址 /* Loop over each word until all available rows are finished */ for (int w = 0; w < m_numWords; w++)//遍历所有的CTU组 (32rows(16CTU行)一组) { uint32_t oldval = m_internalDependencyBitmap[w] & m_externalDependencyBitmap[w];//判读当前组是否有CTU行可执行 (其当前帧和refs的参考块都准备好) while (oldval)//遍历CTU行 { CTZ(id, oldval);// 返回数值x从低位起 有多个连续0的个数 如 0:0 1:0 2(10):1 3(11):0 4(100):2 5(101):0 6(110):1 7(111):0 8(1000):3 优先低行先运行 uint32_t bit = 1 << id;//其具体位置: 如 组内偏移地址为(0~31)对应(1~2^31) if (ATOMIC_AND(&m_internalDependencyBitmap[w], ~bit) & bit)//判断是否可执行 并清除当前位置的标记为0(防止重复触发相同行,如果编码CTU行时,不符合规则提前跳出,后序会再次触发) 注意:ATOMIC_AND(&m_internalDependencyBitmap[w], ~bit) 返回m_internalDependencyBitmap[w]原来的值再更新 { /* we cleared the bit, we get to process the row */ processRow(w * 32 + id, threadId);//执行具体CTU行(编码或者滤波) m_helpWanted = true;//有可执行CTU行 置为true return; //退出 只执行一个CTU行/* check for a higher priority task */ } oldval = m_internalDependencyBitmap[w] & m_externalDependencyBitmap[w];//判读当前组是否有CTU行可执行 (其当前帧和refs的参考块都准备好) } } m_helpWanted = false;//无可执行CTU行 置为false } }
相关文章推荐
- USACO US OPEN 2015 BRONZE 三四题 C++翻译代码
- c语言:用8个2*1的小矩形横着或竖着无重叠地覆盖一个2*8的大矩形,总共有多少种方法?
- glibc detected
- c语言:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法?
- C++学习之primer
- c语言入门之项目1.1——三数最大值
- 纯C语言简单模拟C++的虚函数表
- C++学习
- 关于vs开发windows程序过程中内存检查二三事
- c++ static应用在普通变量
- C++中复制构造函数与重载赋值操作符总结
- leetcode - Best Time to Buy and Sell Stock with Cooldown
- 孟岩的c++ 的学习方法,这何尝有不是做人做事的方法呢?
- 浅谈Windows系统下C语言编程中Glib库的使用
- Python报错:Visual C++ is required和ImportError: DLL load failed
- LeetCode本博客题解索引(C++实现)
- C++复数四则运算的实现
- C++不同数据类型的转换
- c语言:写一个函数,输入n,求斐波拉契数列的第n项(5种方法,层层优化)
- C++重载流插入运算符与流提取运算符