strPredQuantEnc.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. //*@@@+++@@@@******************************************************************
  2. //
  3. // Copyright © Microsoft Corp.
  4. // All rights reserved.
  5. //
  6. // Redistribution and use in source and binary forms, with or without
  7. // modification, are permitted provided that the following conditions are met:
  8. //
  9. // • Redistributions of source code must retain the above copyright notice,
  10. // this list of conditions and the following disclaimer.
  11. // • Redistributions in binary form must reproduce the above copyright notice,
  12. // this list of conditions and the following disclaimer in the documentation
  13. // and/or other materials provided with the distribution.
  14. //
  15. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  19. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  20. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  21. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  22. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  25. // POSSIBILITY OF SUCH DAMAGE.
  26. //
  27. //*@@@---@@@@******************************************************************
  28. #include "strcodec.h"
  29. #include "encode.h"
  30. I32 QUANT_Mulless(PixelI v, PixelI o, I32 r)
  31. {
  32. const I32 m = v >> 31;
  33. assert(sizeof(PixelI) == sizeof(U32));
  34. return ((((v ^ m) - m + o) >> r) ^ m) - m;
  35. }
  36. I32 MUL32HR(U32 a, U32 b, U32 r)
  37. {
  38. return (I32)((U32)((U64)a * b >> 32) >> r);
  39. }
  40. I32 QUANT(PixelI v, PixelI o, I32 man, I32 exp)
  41. {
  42. const I32 m = v >> 31;
  43. assert(sizeof(PixelI) == sizeof(U32));
  44. return (MUL32HR((v ^ m) - m + o, man, exp) ^ m) - m;
  45. }
  46. Int quantizeMacroblock(CWMImageStrCodec* pSC)
  47. {
  48. CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
  49. CWMIMBInfo * pMBInfo = &pSC->MBInfo;
  50. const COLORFORMAT cf = pSC->m_param.cfColorFormat;
  51. int iChannel, i, j;
  52. if(/*pSC->m_param.bScaledArith && */pSC->m_param.bTranscode == FALSE)
  53. for(iChannel = 0; iChannel < (int)pSC->m_param.cNumChannels; iChannel ++){
  54. const Bool bUV = (iChannel > 0 && (cf == YUV_444 || cf == YUV_422 || cf == YUV_420));
  55. const int iNumBlock = (bUV ? (cf == YUV_422 ? 8 : (cf == YUV_420 ? 4 : 16)) : 16);
  56. const int * pOffset = (iNumBlock == 4 ? blkOffsetUV : (iNumBlock == 8 ? blkOffsetUV_422 : blkOffset));
  57. CWMIQuantizer * pQPDC = pTile->pQuantizerDC[iChannel];
  58. CWMIQuantizer * pQPLP = pTile->pQuantizerLP[iChannel] + pMBInfo->iQIndexLP;
  59. CWMIQuantizer * pQPHP = pTile->pQuantizerHP[iChannel] + pMBInfo->iQIndexHP;
  60. for(j = 0; j < iNumBlock; j ++){
  61. PixelI * pData = pSC->pPlane[iChannel] + pOffset[j];
  62. if(j == 0) // DC
  63. pData[0] = (pQPDC->iMan == 0 ? QUANT_Mulless(pData[0], pQPDC->iOffset, pQPDC->iExp) : QUANT(pData[0], pQPDC->iOffset, pQPDC->iMan, pQPDC->iExp));
  64. else if(pSC->WMISCP.sbSubband != SB_DC_ONLY) // LP
  65. pData[0] = (pQPLP->iMan == 0 ? QUANT_Mulless(pData[0], pQPLP->iOffset, pQPLP->iExp) : QUANT(pData[0], pQPLP->iOffset, pQPLP->iMan, pQPLP->iExp));
  66. // quantize HP
  67. if(pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS)
  68. for(i = 1; i < 16; i ++)
  69. pData[i] = (pQPHP->iMan == 0 ? QUANT_Mulless(pData[i], pQPHP->iOffset, pQPHP->iExp) : QUANT(pData[i], pQPHP->iOffset, pQPHP->iMan, pQPHP->iExp));
  70. }
  71. }
  72. for(iChannel = 0; iChannel < (int)pSC->m_param.cNumChannels; iChannel ++){
  73. I32 * pDC = pSC->MBInfo.iBlockDC[iChannel];
  74. PixelI * pData = pSC->pPlane[iChannel];
  75. if(iChannel > 0 && cf == YUV_422){
  76. for(i = 0; i < 8; i ++){
  77. pDC[i] = pData[blkOffsetUV_422[i]];
  78. }
  79. }
  80. else if(iChannel > 0 && cf == YUV_420){
  81. for(i = 0; i < 4; i ++){
  82. pDC[i] = pData[blkOffsetUV[i]];
  83. }
  84. }
  85. else{
  86. for(i = 0; i < 16; i ++){
  87. pDC[i] = pData[dctIndex[2][i]];
  88. }
  89. }
  90. }
  91. return 0;
  92. }
  93. /* frequency domain prediction */
  94. Void predMacroblockEnc(CWMImageStrCodec * pSC)
  95. {
  96. const COLORFORMAT cf = pSC->m_param.cfColorFormat;
  97. const Int iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : (Int) pSC->m_param.cNumChannels;
  98. size_t mbX = pSC->cColumn - 1;// mbY = pSC->cRow - 1;
  99. CWMIMBInfo *pMBInfo = &(pSC->MBInfo);
  100. Int iDCACPredMode = getDCACPredMode(pSC, mbX);
  101. Int iDCPredMode = (iDCACPredMode & 0x3);
  102. Int iADPredMode = (iDCACPredMode & 0xC);
  103. Int iACPredMode = getACPredMode(pMBInfo, cf);
  104. PixelI * pOrg, * pRef;
  105. Int i, j, k;
  106. pMBInfo->iOrientation = 2 - iACPredMode;
  107. /* keep necessary info for future prediction */
  108. updatePredInfo(pSC, pMBInfo, mbX, cf);
  109. for(i = 0; i < iChannels; i ++){
  110. pOrg = pMBInfo->iBlockDC[i]; // current DC block
  111. /* DC prediction */
  112. if(iDCPredMode == 1){ // predict DC from top
  113. pOrg[0] -= (pSC->PredInfoPrevRow[i] + mbX)->iDC;
  114. }
  115. else if(iDCPredMode == 0){ // predict DC from left
  116. pOrg[0] -= (pSC->PredInfo[i] + mbX - 1)->iDC;
  117. }
  118. else if(iDCPredMode == 2){// predict DC from top&left
  119. pOrg[0] -= ((pSC->PredInfo[i] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[i] + mbX)->iDC) >> 1;
  120. }
  121. /* AD prediction */
  122. if(iADPredMode == 4){// predict AD from top
  123. pRef = (pSC->PredInfoPrevRow[i] + mbX)->piAD;
  124. pOrg[4] -= pRef[3], pOrg[8] -= pRef[4], pOrg[12] -= pRef[5];
  125. }
  126. else if(iADPredMode == 0){// predict AD from left
  127. pRef = (pSC->PredInfo[i] + mbX - 1)->piAD;
  128. pOrg[1] -= pRef[0], pOrg[2] -= pRef[1], pOrg[3] -= pRef[2];
  129. }
  130. pOrg = pSC->pPlane[i];
  131. /* AC prediction */
  132. if(iACPredMode == 1){ // predict from top
  133. for(k = 0; k <= 192; k += 64){
  134. /* inside macroblock, in reverse order */
  135. for(j = 48; j > 0; j -= 16){
  136. pOrg[k + j + 10] -= pOrg[k + j + 10 - 16];
  137. pOrg[k + j + 2] -= pOrg[k + j + 2 - 16];
  138. pOrg[k + j + 9] -= pOrg[k + j + 9 - 16];
  139. }
  140. }
  141. }
  142. else if(iACPredMode == 0){ // predict from left
  143. for(k = 0; k < 64; k += 16){
  144. /* inside macroblock, in reverse order */
  145. for(j = 192; j > 0; j -= 64){
  146. pOrg[k + j + 5] -= pOrg[k + j + 5 - 64];
  147. pOrg[k + j + 1] -= pOrg[k + j + 1 - 64];
  148. pOrg[k + j + 6] -= pOrg[k + j + 6 - 64];
  149. }
  150. }
  151. }
  152. }
  153. if(cf == YUV_420){
  154. for(i = 1; i < 3; i ++){
  155. pOrg = pMBInfo->iBlockDC[i]; // current DC block
  156. /* DC prediciton */
  157. if(iDCPredMode == 1){ // predict DC from top
  158. pOrg[0] -= (pSC->PredInfoPrevRow[i] + mbX)->iDC;
  159. }
  160. else if(iDCPredMode == 0){ // predict DC from left
  161. pOrg[0] -= (pSC->PredInfo[i] + mbX - 1)->iDC;
  162. }
  163. else if(iDCPredMode == 2){ // predict DC from top&left
  164. pOrg[0] -= (((pSC->PredInfo[i] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[i] + mbX)->iDC + 1) >> 1);
  165. }
  166. /* AD prediction */
  167. if(iADPredMode == 4){// predict AD from top
  168. pOrg[2] -= (pSC->PredInfoPrevRow[i] + mbX)->piAD[1];
  169. }
  170. else if(iADPredMode == 0){// predict AD from left
  171. pOrg[1] -= (pSC->PredInfo[i] + mbX - 1)->piAD[0];
  172. }
  173. pOrg = pSC->pPlane[i];
  174. /* AC prediction */
  175. if(iACPredMode == 1){ // predict from top
  176. for(j = 16; j <= 48; j += 32){
  177. /* inside macroblock */
  178. pOrg[j + 10] -= pOrg[j + 10 - 16];
  179. pOrg[j + 2] -= pOrg[j + 2 - 16];
  180. pOrg[j + 9] -= pOrg[j + 9 - 16];
  181. }
  182. }
  183. else if(iACPredMode == 0){ // predict from left
  184. for(j = 32; j <= 48; j += 16){
  185. /* inside macroblock */
  186. pOrg[j + 5] -= pOrg[j + 5 - 32];
  187. pOrg[j + 1] -= pOrg[j + 1 - 32];
  188. pOrg[j + 6] -= pOrg[j + 6 - 32];
  189. }
  190. }
  191. }
  192. }
  193. else if(cf == YUV_422){
  194. for(i = 1; i < 3; i ++){
  195. pOrg = pMBInfo->iBlockDC[i]; // current DC block
  196. /* DC prediciton */
  197. if(iDCPredMode == 1){ // predict DC from top
  198. pOrg[0] -= (pSC->PredInfoPrevRow[i] + mbX)->iDC;
  199. }
  200. else if(iDCPredMode == 0){ // predict DC from left
  201. pOrg[0] -= (pSC->PredInfo[i] + mbX - 1)->iDC;
  202. }
  203. else if(iDCPredMode == 2){ // predict DC from top&left
  204. pOrg[0] -= (((pSC->PredInfo[i] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[i] + mbX)->iDC + 1) >> 1);
  205. }
  206. /* AD prediction */
  207. if(iADPredMode == 4){// predict AD from top
  208. pOrg[4] -= (pSC->PredInfoPrevRow[i] + mbX)->piAD[4]; // AC of HT !!!
  209. pOrg[6] -= pOrg[2];
  210. pOrg[2] -= (pSC->PredInfoPrevRow[i] + mbX)->piAD[3];
  211. }
  212. else if(iADPredMode == 0){// predict AD from left
  213. pOrg[4] -= (pSC->PredInfo[i] + mbX - 1)->piAD[4]; // AC of HT !!!
  214. pOrg[1] -= (pSC->PredInfo[i] + mbX - 1)->piAD[0];
  215. pOrg[5] -= (pSC->PredInfo[i] + mbX - 1)->piAD[2];
  216. }
  217. else if(iDCPredMode == 1){
  218. pOrg[6] -= pOrg[2];
  219. }
  220. pOrg = pSC->pPlane[i]; // current MB
  221. /* AC prediction */
  222. if(iACPredMode == 1){ // predict from top
  223. for(j = 48; j > 0; j -= 16){
  224. for(k = 0; k <= 64; k += 64){
  225. /* inside macroblock */
  226. pOrg[j + k + 10] -= pOrg[j + k + 10 - 16];
  227. pOrg[j + k + 2] -= pOrg[j + k + 2 - 16];
  228. pOrg[j + k + 9] -= pOrg[j + k + 9 - 16];
  229. }
  230. }
  231. }
  232. else if(iACPredMode == 0){ // predict from left
  233. for(j = 64; j <= 112; j += 16){
  234. /* inside macroblock */
  235. pOrg[j + 5] -= pOrg[j + 5 - 64];
  236. pOrg[j + 1] -= pOrg[j + 1 - 64];
  237. pOrg[j + 6] -= pOrg[j + 6 - 64];
  238. }
  239. }
  240. }
  241. }
  242. }
  243. /* CBP prediction for 16 x 16 MB */
  244. /* block index */
  245. /* 0 1 4 5 */
  246. /* 2 3 6 7 */
  247. /* 8 9 12 13 */
  248. /* 10 11 14 15 */
  249. static int NumOnes(int i)
  250. {
  251. int retval = 0;
  252. static const int g_Count[] = { 0,1,1,2, 1,2,2,3, 1,2,2,3, 2,3,3,4 };
  253. i = i & 0xffff;
  254. while (i) {
  255. retval += g_Count[i & 0xf];
  256. i >>= 4;
  257. }
  258. return retval;
  259. }
  260. #define SATURATE32(x) if((unsigned int)(x + 16) >= 32) { if (x < 0) x = -16; else x = 15; }
  261. static Int predCBPCEnc(CWMImageStrCodec *pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
  262. {
  263. Int iPredCBP = 0, iRetval = 0;
  264. Int iNOrig = NumOnes(iCBP), iNDiff = AVG_NDIFF;//NumOnes(iPredCBP ^ iCBP);
  265. UNREFERENCED_PARAMETER( mbY );
  266. /* only top left block pattern is predicted from neighbour */
  267. if(pSC->m_bCtxLeft) {
  268. if (pSC->m_bCtxTop) {
  269. iPredCBP = 1;
  270. }
  271. else {
  272. Int iTopCBP = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
  273. iPredCBP = (iTopCBP >> 10) & 1; // left: top(10) => 0
  274. }
  275. }
  276. else {
  277. Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
  278. iPredCBP = ((iLeftCBP >> 5) & 1); // left(5) => 0
  279. }
  280. iPredCBP |= (iCBP & 0x3300) << 2; // [8 9 12 13]->[10 11 14 15]
  281. iPredCBP |= (iCBP & 0xcc) << 6; // [2 3 6 7]->[8 9 12 13]
  282. iPredCBP |= (iCBP & 0x33) << 2; // [0 1 4 5]->[2 3 6 7]
  283. iPredCBP |= (iCBP & 0x11) << 1; // [0 4]->[1 5]
  284. iPredCBP |= (iCBP & 0x2) << 3; // [1]->[4]
  285. if (c) c = 1;
  286. if (pModel->m_iState[c] == 0) {
  287. iRetval = iPredCBP ^ iCBP;
  288. }
  289. else if (pModel->m_iState[c] == 1) {
  290. iRetval = iCBP;
  291. }
  292. else {
  293. iRetval = iCBP ^ 0xffff;
  294. }
  295. pModel->m_iCount0[c] += iNOrig - iNDiff;
  296. SATURATE32(pModel->m_iCount0[c]);
  297. pModel->m_iCount1[c] += 16 - iNOrig - iNDiff;
  298. SATURATE32(pModel->m_iCount1[c]);
  299. if (pModel->m_iCount0[c] < 0) {
  300. if (pModel->m_iCount0[c] < pModel->m_iCount1[c]) {
  301. pModel->m_iState[c] = 1;
  302. }
  303. else {
  304. pModel->m_iState[c] = 2;
  305. }
  306. }
  307. else if (pModel->m_iCount1[c] < 0) {
  308. pModel->m_iState[c] = 2;
  309. }
  310. else {
  311. pModel->m_iState[c] = 0;
  312. }
  313. return iRetval;
  314. }
  315. static Int predCBPC420Enc(CWMImageStrCodec *pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
  316. {
  317. Int iPredCBP = 0, iRetval = 0;
  318. Int iNOrig = NumOnes(iCBP) * 4, iNDiff = AVG_NDIFF;//NumOnes(iPredCBP ^ iCBP);
  319. UNREFERENCED_PARAMETER( mbY );
  320. /* only top left block pattern is predicted from neighbour */
  321. if(pSC->m_bCtxLeft) {
  322. if (pSC->m_bCtxTop) {
  323. iPredCBP = 1;
  324. }
  325. else {
  326. Int iTopCBP = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
  327. iPredCBP = (iTopCBP >> 2) & 1; // left: top(2) => 0
  328. }
  329. }
  330. else {
  331. Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
  332. iPredCBP = ((iLeftCBP >> 1) & 1); // left(1) => 0
  333. }
  334. iPredCBP |= (iCBP & 0x1) << 1; // [0]->[1]
  335. iPredCBP |= (iCBP & 0x3) << 2; // [0 1]->[2 3]
  336. if (pModel->m_iState[1] == 0) {
  337. iRetval = iPredCBP ^ iCBP;
  338. }
  339. else if (pModel->m_iState[1] == 1) {
  340. iRetval = iCBP;
  341. }
  342. else {
  343. iRetval = iCBP ^ 0xf;
  344. }
  345. pModel->m_iCount0[1] += iNOrig - iNDiff;
  346. SATURATE32(pModel->m_iCount0[1]);
  347. pModel->m_iCount1[1] += 16 - iNOrig - iNDiff;
  348. SATURATE32(pModel->m_iCount1[1]);
  349. if (pModel->m_iCount0[1] < 0) {
  350. if (pModel->m_iCount0[1] < pModel->m_iCount1[1]) {
  351. pModel->m_iState[1] = 1;
  352. }
  353. else {
  354. pModel->m_iState[1] = 2;
  355. }
  356. }
  357. else if (pModel->m_iCount1[1] < 0) {
  358. pModel->m_iState[1] = 2;
  359. }
  360. else {
  361. pModel->m_iState[1] = 0;
  362. }
  363. return iRetval;
  364. }
  365. static Int predCBPC422Enc(CWMImageStrCodec *pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
  366. {
  367. Int iPredCBP = 0, iRetval = 0;
  368. Int iNOrig = NumOnes(iCBP) * 2, iNDiff = AVG_NDIFF;//NumOnes(iPredCBP ^ iCBP);
  369. UNREFERENCED_PARAMETER( mbY );
  370. /* only top left block pattern is predicted from neighbour */
  371. if(pSC->m_bCtxLeft) {
  372. if (pSC->m_bCtxTop) {
  373. iPredCBP = 1;
  374. }
  375. else {
  376. Int iTopCBP = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
  377. iPredCBP = (iTopCBP >> 6) & 1; // left: top(6) => 0
  378. }
  379. }
  380. else {
  381. Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
  382. iPredCBP = ((iLeftCBP >> 1) & 1); // left(1) => 0
  383. }
  384. iPredCBP |= (iCBP & 0x1) << 1; // [0]->[1]
  385. iPredCBP |= (iCBP & 0x3) << 2; // [0 1]->[2 3]
  386. iPredCBP |= (iCBP & 0xc) << 2; // [2 3]->[4 5]
  387. iPredCBP |= (iCBP & 0x30) << 2; // [4 5]->[6 7]
  388. if (pModel->m_iState[1] == 0) {
  389. iRetval = iPredCBP ^ iCBP;
  390. }
  391. else if (pModel->m_iState[1] == 1) {
  392. iRetval = iCBP;
  393. }
  394. else {
  395. iRetval = iCBP ^ 0xff;
  396. }
  397. pModel->m_iCount0[1] += iNOrig - iNDiff;
  398. SATURATE32(pModel->m_iCount0[1]);
  399. pModel->m_iCount1[1] += 16 - iNOrig - iNDiff;
  400. SATURATE32(pModel->m_iCount1[1]);
  401. if (pModel->m_iCount0[1] < 0) {
  402. if (pModel->m_iCount0[1] < pModel->m_iCount1[1]) {
  403. pModel->m_iState[1] = 1;
  404. }
  405. else {
  406. pModel->m_iState[1] = 2;
  407. }
  408. }
  409. else if (pModel->m_iCount1[1] < 0) {
  410. pModel->m_iState[1] = 2;
  411. }
  412. else {
  413. pModel->m_iState[1] = 0;
  414. }
  415. return iRetval;
  416. }
  417. Void predCBPEnc(CWMImageStrCodec* pSC, CCodingContext *pContext)
  418. {
  419. size_t mbX = pSC->cColumn - 1, mbY = pSC->cRow - 1;
  420. CWMIMBInfo * pMBInfo = &(pSC->MBInfo);
  421. int iChannel, i, j;
  422. for(iChannel = 0; iChannel < (int)pSC->m_param.cNumChannels; iChannel ++){
  423. const COLORFORMAT cf = pSC->m_param.cfColorFormat;
  424. const Bool bUV = (iChannel > 0);
  425. const int iNumBlock = (bUV ? (cf == YUV_422 ? 8 : (cf == YUV_420 ? 4 : 16)) : 16);
  426. const int * pOffset = (iNumBlock == 4 ? blkOffsetUV : (iNumBlock == 8 ? blkOffsetUV_422 : blkOffset));
  427. const Int threshold = (1 << pContext->m_aModelAC.m_iFlcBits[bUV ? 1 : 0]) - 1, threshold2 = threshold * 2 + 1;
  428. Int iCBP = 0;
  429. for(j = 0; j < iNumBlock; j ++){
  430. PixelI * pData = pSC->pPlane[iChannel] + pOffset[j];
  431. for(i = 1; i < 16; i ++){
  432. if((unsigned int)(pData[i] + threshold) >= (unsigned int) threshold2){ // significant coeff
  433. iCBP |= (1 << j); // update CBP
  434. break;
  435. }
  436. }
  437. }
  438. pMBInfo->iCBP[iChannel] = (pSC->PredInfo[iChannel] + mbX)->iCBP = iCBP;
  439. if(iNumBlock == 16){
  440. pMBInfo->iDiffCBP[iChannel] = predCBPCEnc(pSC, pMBInfo->iCBP[iChannel], mbX, mbY, iChannel, &pContext->m_aCBPModel);
  441. }
  442. else if(iNumBlock == 8){
  443. pSC->MBInfo.iDiffCBP[iChannel] = predCBPC422Enc(pSC, pMBInfo->iCBP[iChannel], mbX, mbY, iChannel, &pContext->m_aCBPModel);
  444. }
  445. else{
  446. pSC->MBInfo.iDiffCBP[iChannel] = predCBPC420Enc(pSC, pMBInfo->iCBP[iChannel], mbX, mbY, iChannel, &pContext->m_aCBPModel);
  447. }
  448. }
  449. }