/Decoder/src/h264bsd_transform.c

https://github.com/mbebenita/Broadway · C · 402 lines · 223 code · 45 blank · 134 comment · 17 complexity · df050937a9519f10fc94be51639d4c16 MD5 · raw file

  1. /*
  2. * Copyright (C) 2009 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /*------------------------------------------------------------------------------
  17. Table of contents
  18. 1. Include headers
  19. 2. External compiler flags
  20. 3. Module defines
  21. 4. Local function prototypes
  22. 5. Functions
  23. h264bsdProcessBlock
  24. h264bsdProcessLumaDc
  25. h264bsdProcessChromaDc
  26. ------------------------------------------------------------------------------*/
  27. /*------------------------------------------------------------------------------
  28. 1. Include headers
  29. ------------------------------------------------------------------------------*/
  30. #include "basetype.h"
  31. #include "h264bsd_transform.h"
  32. #include "h264bsd_util.h"
  33. /*------------------------------------------------------------------------------
  34. 2. External compiler flags
  35. --------------------------------------------------------------------------------
  36. --------------------------------------------------------------------------------
  37. 3. Module defines
  38. ------------------------------------------------------------------------------*/
  39. /* Switch off the following Lint messages for this file:
  40. * Info 701: Shift left of signed quantity (int)
  41. * Info 702: Shift right of signed quantity (int)
  42. */
  43. /*lint -e701 -e702 */
  44. /* LevelScale function */
  45. static const i32 levelScale[6][3] = {
  46. {10,13,16}, {11,14,18}, {13,16,20}, {14,18,23}, {16,20,25}, {18,23,29}};
  47. /* qp % 6 as a function of qp */
  48. static const u8 qpMod6[52] = {0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,
  49. 0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3};
  50. /* qp / 6 as a function of qp */
  51. static const u8 qpDiv6[52] = {0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,
  52. 4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8};
  53. /*------------------------------------------------------------------------------
  54. 4. Local function prototypes
  55. ------------------------------------------------------------------------------*/
  56. /*------------------------------------------------------------------------------
  57. Function: h264bsdProcessBlock
  58. Functional description:
  59. Function performs inverse zig-zag scan, inverse scaling and
  60. inverse transform for a luma or a chroma residual block
  61. Inputs:
  62. data pointer to data to be processed
  63. qp quantization parameter
  64. skip skip processing of data[0], set to non-zero value
  65. if dc coeff hanled separately
  66. coeffMap 16 lsb's indicate which coeffs are non-zero,
  67. bit 0 (lsb) for coeff 0, bit 1 for coeff 1 etc.
  68. Outputs:
  69. data processed data
  70. Returns:
  71. HANTRO_OK success
  72. HANTRO_NOK processed data not in valid range [-512, 511]
  73. ------------------------------------------------------------------------------*/
  74. u32 h264bsdProcessBlock(i32 *data, u32 qp, u32 skip, u32 coeffMap)
  75. {
  76. /* Variables */
  77. i32 tmp0, tmp1, tmp2, tmp3;
  78. i32 d1, d2, d3;
  79. u32 row,col;
  80. u32 qpDiv;
  81. i32 *ptr;
  82. /* Code */
  83. qpDiv = qpDiv6[qp];
  84. tmp1 = levelScale[qpMod6[qp]][0] << qpDiv;
  85. tmp2 = levelScale[qpMod6[qp]][1] << qpDiv;
  86. tmp3 = levelScale[qpMod6[qp]][2] << qpDiv;
  87. if (!skip)
  88. data[0] = (data[0] * tmp1);
  89. /* at least one of the rows 1, 2 or 3 contain non-zero coeffs, mask takes
  90. * the scanning order into account */
  91. if (coeffMap & 0xFF9C)
  92. {
  93. /* do the zig-zag scan and inverse quantization */
  94. d1 = data[1];
  95. d2 = data[14];
  96. d3 = data[15];
  97. data[1] = (d1 * tmp2);
  98. data[14] = (d2 * tmp2);
  99. data[15] = (d3 * tmp3);
  100. d1 = data[2];
  101. d2 = data[5];
  102. d3 = data[4];
  103. data[4] = (d1 * tmp2);
  104. data[2] = (d2 * tmp1);
  105. data[5] = (d3 * tmp3);
  106. d1 = data[8];
  107. d2 = data[3];
  108. d3 = data[6];
  109. tmp0 = (d1 * tmp2);
  110. data[8] = (d2 * tmp1);
  111. data[3] = (d3 * tmp2);
  112. d1 = data[7];
  113. d2 = data[12];
  114. d3 = data[9];
  115. data[6] = (d1 * tmp2);
  116. data[7] = (d2 * tmp3);
  117. data[12] = (d3 * tmp2);
  118. data[9] = tmp0;
  119. d1 = data[10];
  120. d2 = data[11];
  121. d3 = data[13];
  122. data[13] = (d1 * tmp3);
  123. data[10] = (d2 * tmp1);
  124. data[11] = (d3 * tmp2);
  125. /* horizontal transform */
  126. for (row = 4, ptr = data; row--; ptr += 4)
  127. {
  128. tmp0 = ptr[0] + ptr[2];
  129. tmp1 = ptr[0] - ptr[2];
  130. tmp2 = (ptr[1] >> 1) - ptr[3];
  131. tmp3 = ptr[1] + (ptr[3] >> 1);
  132. ptr[0] = tmp0 + tmp3;
  133. ptr[1] = tmp1 + tmp2;
  134. ptr[2] = tmp1 - tmp2;
  135. ptr[3] = tmp0 - tmp3;
  136. }
  137. /*lint +e661 +e662*/
  138. /* then vertical transform */
  139. for (col = 4; col--; data++)
  140. {
  141. tmp0 = data[0] + data[8];
  142. tmp1 = data[0] - data[8];
  143. tmp2 = (data[4] >> 1) - data[12];
  144. tmp3 = data[4] + (data[12] >> 1);
  145. data[0 ] = (tmp0 + tmp3 + 32)>>6;
  146. data[4 ] = (tmp1 + tmp2 + 32)>>6;
  147. data[8 ] = (tmp1 - tmp2 + 32)>>6;
  148. data[12] = (tmp0 - tmp3 + 32)>>6;
  149. /* check that each value is in the range [-512,511] */
  150. if (((u32)(data[0] + 512) > 1023) ||
  151. ((u32)(data[4] + 512) > 1023) ||
  152. ((u32)(data[8] + 512) > 1023) ||
  153. ((u32)(data[12] + 512) > 1023) )
  154. return(HANTRO_NOK);
  155. }
  156. }
  157. else /* rows 1, 2 and 3 are zero */
  158. {
  159. /* only dc-coeff is non-zero, i.e. coeffs at original positions
  160. * 1, 5 and 6 are zero */
  161. if ((coeffMap & 0x62) == 0)
  162. {
  163. tmp0 = (data[0] + 32) >> 6;
  164. /* check that value is in the range [-512,511] */
  165. if ((u32)(tmp0 + 512) > 1023)
  166. return(HANTRO_NOK);
  167. data[0] = data[1] = data[2] = data[3] = data[4] = data[5] =
  168. data[6] = data[7] = data[8] = data[9] = data[10] =
  169. data[11] = data[12] = data[13] = data[14] = data[15] =
  170. tmp0;
  171. }
  172. else /* at least one of the coeffs 1, 5 or 6 is non-zero */
  173. {
  174. data[1] = (data[1] * tmp2);
  175. data[2] = (data[5] * tmp1);
  176. data[3] = (data[6] * tmp2);
  177. tmp0 = data[0] + data[2];
  178. tmp1 = data[0] - data[2];
  179. tmp2 = (data[1] >> 1) - data[3];
  180. tmp3 = data[1] + (data[3] >> 1);
  181. data[0] = (tmp0 + tmp3 + 32)>>6;
  182. data[1] = (tmp1 + tmp2 + 32)>>6;
  183. data[2] = (tmp1 - tmp2 + 32)>>6;
  184. data[3] = (tmp0 - tmp3 + 32)>>6;
  185. data[4] = data[8] = data[12] = data[0];
  186. data[5] = data[9] = data[13] = data[1];
  187. data[6] = data[10] = data[14] = data[2];
  188. data[7] = data[11] = data[15] = data[3];
  189. /* check that each value is in the range [-512,511] */
  190. if (((u32)(data[0] + 512) > 1023) ||
  191. ((u32)(data[1] + 512) > 1023) ||
  192. ((u32)(data[2] + 512) > 1023) ||
  193. ((u32)(data[3] + 512) > 1023) )
  194. return(HANTRO_NOK);
  195. }
  196. }
  197. return(HANTRO_OK);
  198. }
  199. /*------------------------------------------------------------------------------
  200. Function: h264bsdProcessLumaDc
  201. Functional description:
  202. Function performs inverse zig-zag scan, inverse transform and
  203. inverse scaling for a luma DC coefficients block
  204. Inputs:
  205. data pointer to data to be processed
  206. qp quantization parameter
  207. Outputs:
  208. data processed data
  209. Returns:
  210. none
  211. ------------------------------------------------------------------------------*/
  212. void h264bsdProcessLumaDc(i32 *data, u32 qp)
  213. {
  214. /* Variables */
  215. i32 tmp0, tmp1, tmp2, tmp3;
  216. u32 row,col;
  217. u32 qpMod, qpDiv;
  218. i32 levScale;
  219. i32 *ptr;
  220. /* Code */
  221. qpMod = qpMod6[qp];
  222. qpDiv = qpDiv6[qp];
  223. /* zig-zag scan */
  224. tmp0 = data[2];
  225. data[2] = data[5];
  226. data[5] = data[4];
  227. data[4] = tmp0;
  228. tmp0 = data[8];
  229. data[8] = data[3];
  230. data[3] = data[6];
  231. data[6] = data[7];
  232. data[7] = data[12];
  233. data[12] = data[9];
  234. data[9] = tmp0;
  235. tmp0 = data[10];
  236. data[10] = data[11];
  237. data[11] = data[13];
  238. data[13] = tmp0;
  239. /* horizontal transform */
  240. for (row = 4, ptr = data; row--; ptr += 4)
  241. {
  242. tmp0 = ptr[0] + ptr[2];
  243. tmp1 = ptr[0] - ptr[2];
  244. tmp2 = ptr[1] - ptr[3];
  245. tmp3 = ptr[1] + ptr[3];
  246. ptr[0] = tmp0 + tmp3;
  247. ptr[1] = tmp1 + tmp2;
  248. ptr[2] = tmp1 - tmp2;
  249. ptr[3] = tmp0 - tmp3;
  250. }
  251. /*lint +e661 +e662*/
  252. /* then vertical transform and inverse scaling */
  253. levScale = levelScale[ qpMod ][0];
  254. if (qp >= 12)
  255. {
  256. levScale <<= (qpDiv-2);
  257. for (col = 4; col--; data++)
  258. {
  259. tmp0 = data[0] + data[8 ];
  260. tmp1 = data[0] - data[8 ];
  261. tmp2 = data[4] - data[12];
  262. tmp3 = data[4] + data[12];
  263. data[0 ] = ((tmp0 + tmp3)*levScale);
  264. data[4 ] = ((tmp1 + tmp2)*levScale);
  265. data[8 ] = ((tmp1 - tmp2)*levScale);
  266. data[12] = ((tmp0 - tmp3)*levScale);
  267. }
  268. }
  269. else
  270. {
  271. i32 tmp;
  272. tmp = ((1 - qpDiv) == 0) ? 1 : 2;
  273. for (col = 4; col--; data++)
  274. {
  275. tmp0 = data[0] + data[8 ];
  276. tmp1 = data[0] - data[8 ];
  277. tmp2 = data[4] - data[12];
  278. tmp3 = data[4] + data[12];
  279. data[0 ] = ((tmp0 + tmp3)*levScale+tmp) >> (2-qpDiv);
  280. data[4 ] = ((tmp1 + tmp2)*levScale+tmp) >> (2-qpDiv);
  281. data[8 ] = ((tmp1 - tmp2)*levScale+tmp) >> (2-qpDiv);
  282. data[12] = ((tmp0 - tmp3)*levScale+tmp) >> (2-qpDiv);
  283. }
  284. }
  285. }
  286. /*------------------------------------------------------------------------------
  287. Function: h264bsdProcessChromaDc
  288. Functional description:
  289. Function performs inverse transform and inverse scaling for a
  290. chroma DC coefficients block
  291. Inputs:
  292. data pointer to data to be processed
  293. qp quantization parameter
  294. Outputs:
  295. data processed data
  296. Returns:
  297. none
  298. ------------------------------------------------------------------------------*/
  299. void h264bsdProcessChromaDc(i32 *data, u32 qp)
  300. {
  301. /* Variables */
  302. i32 tmp0, tmp1, tmp2, tmp3;
  303. u32 qpDiv;
  304. i32 levScale;
  305. u32 levShift;
  306. /* Code */
  307. qpDiv = qpDiv6[qp];
  308. levScale = levelScale[ qpMod6[qp] ][0];
  309. if (qp >= 6)
  310. {
  311. levScale <<= (qpDiv-1);
  312. levShift = 0;
  313. }
  314. else
  315. {
  316. levShift = 1;
  317. }
  318. tmp0 = data[0] + data[2];
  319. tmp1 = data[0] - data[2];
  320. tmp2 = data[1] - data[3];
  321. tmp3 = data[1] + data[3];
  322. data[0] = ((tmp0 + tmp3) * levScale) >> levShift;
  323. data[1] = ((tmp0 - tmp3) * levScale) >> levShift;
  324. data[2] = ((tmp1 + tmp2) * levScale) >> levShift;
  325. data[3] = ((tmp1 - tmp2) * levScale) >> levShift;
  326. tmp0 = data[4] + data[6];
  327. tmp1 = data[4] - data[6];
  328. tmp2 = data[5] - data[7];
  329. tmp3 = data[5] + data[7];
  330. data[4] = ((tmp0 + tmp3) * levScale) >> levShift;
  331. data[5] = ((tmp0 - tmp3) * levScale) >> levShift;
  332. data[6] = ((tmp1 + tmp2) * levScale) >> levShift;
  333. data[7] = ((tmp1 - tmp2) * levScale) >> levShift;
  334. }
  335. /*lint +e701 +e702 */