/H264Dec/source/h264bsd_image.c

http://github.com/mbebenita/Broadway · C · 345 lines · 192 code · 53 blank · 100 comment · 10 complexity · 2e851e43ca23ddba84f5b3d7b13b7dd8 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. h264bsdWriteMacroblock
  24. h264bsdWriteOutputBlocks
  25. ------------------------------------------------------------------------------*/
  26. /*------------------------------------------------------------------------------
  27. 1. Include headers
  28. ------------------------------------------------------------------------------*/
  29. #include "h264bsd_image.h"
  30. #include "h264bsd_util.h"
  31. #include "h264bsd_neighbour.h"
  32. /*------------------------------------------------------------------------------
  33. 2. External compiler flags
  34. --------------------------------------------------------------------------------
  35. --------------------------------------------------------------------------------
  36. 3. Module defines
  37. ------------------------------------------------------------------------------*/
  38. /* x- and y-coordinates for each block, defined in h264bsd_intra_prediction.c */
  39. extern const u32 h264bsdBlockX[];
  40. extern const u32 h264bsdBlockY[];
  41. /* clipping table, defined in h264bsd_intra_prediction.c */
  42. extern const u8 h264bsdClip[];
  43. /*------------------------------------------------------------------------------
  44. 4. Local function prototypes
  45. ------------------------------------------------------------------------------*/
  46. /*------------------------------------------------------------------------------
  47. Function: h264bsdWriteMacroblock
  48. Functional description:
  49. Write one macroblock into the image. Both luma and chroma
  50. components will be written at the same time.
  51. Inputs:
  52. data pointer to macroblock data to be written, 256 values for
  53. luma followed by 64 values for both chroma components
  54. Outputs:
  55. image pointer to the image where the macroblock will be written
  56. Returns:
  57. none
  58. ------------------------------------------------------------------------------*/
  59. #ifndef H264DEC_NEON
  60. void h264bsdWriteMacroblock(image_t *image, u8 *data)
  61. {
  62. /* Variables */
  63. u32 i;
  64. u32 width;
  65. u32 *lum, *cb, *cr;
  66. u32 *ptr;
  67. u32 tmp1, tmp2;
  68. /* Code */
  69. ASSERT(image);
  70. ASSERT(data);
  71. ASSERT(!((u32)data&0x3));
  72. width = image->width;
  73. /*lint -save -e826 lum, cb and cr used to copy 4 bytes at the time, disable
  74. * "area too small" info message */
  75. lum = (u32*)image->luma;
  76. cb = (u32*)image->cb;
  77. cr = (u32*)image->cr;
  78. ASSERT(!((u32)lum&0x3));
  79. ASSERT(!((u32)cb&0x3));
  80. ASSERT(!((u32)cr&0x3));
  81. ptr = (u32*)data;
  82. width *= 4;
  83. for (i = 16; i ; i--)
  84. {
  85. tmp1 = *ptr++;
  86. tmp2 = *ptr++;
  87. *lum++ = tmp1;
  88. *lum++ = tmp2;
  89. tmp1 = *ptr++;
  90. tmp2 = *ptr++;
  91. *lum++ = tmp1;
  92. *lum++ = tmp2;
  93. lum += width-4;
  94. }
  95. width >>= 1;
  96. for (i = 8; i ; i--)
  97. {
  98. tmp1 = *ptr++;
  99. tmp2 = *ptr++;
  100. *cb++ = tmp1;
  101. *cb++ = tmp2;
  102. cb += width-2;
  103. }
  104. for (i = 8; i ; i--)
  105. {
  106. tmp1 = *ptr++;
  107. tmp2 = *ptr++;
  108. *cr++ = tmp1;
  109. *cr++ = tmp2;
  110. cr += width-2;
  111. }
  112. }
  113. #endif
  114. #ifndef H264DEC_OMXDL
  115. /*------------------------------------------------------------------------------
  116. Function: h264bsdWriteOutputBlocks
  117. Functional description:
  118. Write one macroblock into the image. Prediction for the macroblock
  119. and the residual are given separately and will be combined while
  120. writing the data to the image
  121. Inputs:
  122. data pointer to macroblock prediction data, 256 values for
  123. luma followed by 64 values for both chroma components
  124. mbNum number of the macroblock
  125. residual pointer to residual data, 16 16-element arrays for luma
  126. followed by 4 16-element arrays for both chroma
  127. components
  128. Outputs:
  129. image pointer to the image where the data will be written
  130. Returns:
  131. none
  132. ------------------------------------------------------------------------------*/
  133. void h264bsdWriteOutputBlocks(image_t *image, u32 mbNum, u8 *data,
  134. i32 residual[][16])
  135. {
  136. /* Variables */
  137. u32 i;
  138. u32 picWidth, picSize;
  139. u8 *lum, *cb, *cr;
  140. u8 *imageBlock;
  141. u8 *tmp;
  142. u32 row, col;
  143. u32 block;
  144. u32 x, y;
  145. i32 *pRes;
  146. i32 tmp1, tmp2, tmp3, tmp4;
  147. const u8 *clp = h264bsdClip + 512;
  148. /* Code */
  149. ASSERT(image);
  150. ASSERT(data);
  151. ASSERT(mbNum < image->width * image->height);
  152. ASSERT(!((u32)data&0x3));
  153. /* Image size in macroblocks */
  154. picWidth = image->width;
  155. picSize = picWidth * image->height;
  156. row = mbNum / picWidth;
  157. col = mbNum % picWidth;
  158. /* Output macroblock position in output picture */
  159. lum = (image->data + row * picWidth * 256 + col * 16);
  160. cb = (image->data + picSize * 256 + row * picWidth * 64 + col * 8);
  161. cr = (cb + picSize * 64);
  162. picWidth *= 16;
  163. for (block = 0; block < 16; block++)
  164. {
  165. x = h264bsdBlockX[block];
  166. y = h264bsdBlockY[block];
  167. pRes = residual[block];
  168. ASSERT(pRes);
  169. tmp = data + y*16 + x;
  170. imageBlock = lum + y*picWidth + x;
  171. ASSERT(!((u32)tmp&0x3));
  172. ASSERT(!((u32)imageBlock&0x3));
  173. if (IS_RESIDUAL_EMPTY(pRes))
  174. {
  175. /*lint -e826 */
  176. i32 *in32 = (i32*)tmp;
  177. i32 *out32 = (i32*)imageBlock;
  178. /* Residual is zero => copy prediction block to output */
  179. tmp1 = *in32; in32 += 4;
  180. tmp2 = *in32; in32 += 4;
  181. *out32 = tmp1; out32 += picWidth/4;
  182. *out32 = tmp2; out32 += picWidth/4;
  183. tmp1 = *in32; in32 += 4;
  184. tmp2 = *in32;
  185. *out32 = tmp1; out32 += picWidth/4;
  186. *out32 = tmp2;
  187. }
  188. else
  189. {
  190. RANGE_CHECK_ARRAY(pRes, -512, 511, 16);
  191. /* Calculate image = prediction + residual
  192. * Process four pixels in a loop */
  193. for (i = 4; i; i--)
  194. {
  195. tmp1 = tmp[0];
  196. tmp2 = *pRes++;
  197. tmp3 = tmp[1];
  198. tmp1 = clp[tmp1 + tmp2];
  199. tmp4 = *pRes++;
  200. imageBlock[0] = (u8)tmp1;
  201. tmp3 = clp[tmp3 + tmp4];
  202. tmp1 = tmp[2];
  203. tmp2 = *pRes++;
  204. imageBlock[1] = (u8)tmp3;
  205. tmp1 = clp[tmp1 + tmp2];
  206. tmp3 = tmp[3];
  207. tmp4 = *pRes++;
  208. imageBlock[2] = (u8)tmp1;
  209. tmp3 = clp[tmp3 + tmp4];
  210. tmp += 16;
  211. imageBlock[3] = (u8)tmp3;
  212. imageBlock += picWidth;
  213. }
  214. }
  215. }
  216. picWidth /= 2;
  217. for (block = 16; block <= 23; block++)
  218. {
  219. x = h264bsdBlockX[block & 0x3];
  220. y = h264bsdBlockY[block & 0x3];
  221. pRes = residual[block];
  222. ASSERT(pRes);
  223. tmp = data + 256;
  224. imageBlock = cb;
  225. if (block >= 20)
  226. {
  227. imageBlock = cr;
  228. tmp += 64;
  229. }
  230. tmp += y*8 + x;
  231. imageBlock += y*picWidth + x;
  232. ASSERT(!((u32)tmp&0x3));
  233. ASSERT(!((u32)imageBlock&0x3));
  234. if (IS_RESIDUAL_EMPTY(pRes))
  235. {
  236. /*lint -e826 */
  237. i32 *in32 = (i32*)tmp;
  238. i32 *out32 = (i32*)imageBlock;
  239. /* Residual is zero => copy prediction block to output */
  240. tmp1 = *in32; in32 += 2;
  241. tmp2 = *in32; in32 += 2;
  242. *out32 = tmp1; out32 += picWidth/4;
  243. *out32 = tmp2; out32 += picWidth/4;
  244. tmp1 = *in32; in32 += 2;
  245. tmp2 = *in32;
  246. *out32 = tmp1; out32 += picWidth/4;
  247. *out32 = tmp2;
  248. }
  249. else
  250. {
  251. RANGE_CHECK_ARRAY(pRes, -512, 511, 16);
  252. for (i = 4; i; i--)
  253. {
  254. tmp1 = tmp[0];
  255. tmp2 = *pRes++;
  256. tmp3 = tmp[1];
  257. tmp1 = clp[tmp1 + tmp2];
  258. tmp4 = *pRes++;
  259. imageBlock[0] = (u8)tmp1;
  260. tmp3 = clp[tmp3 + tmp4];
  261. tmp1 = tmp[2];
  262. tmp2 = *pRes++;
  263. imageBlock[1] = (u8)tmp3;
  264. tmp1 = clp[tmp1 + tmp2];
  265. tmp3 = tmp[3];
  266. tmp4 = *pRes++;
  267. imageBlock[2] = (u8)tmp1;
  268. tmp3 = clp[tmp3 + tmp4];
  269. tmp += 8;
  270. imageBlock[3] = (u8)tmp3;
  271. imageBlock += picWidth;
  272. }
  273. }
  274. }
  275. }
  276. #endif /* H264DEC_OMXDL */