PageRenderTime 41ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/Show/avc/fmo.cpp

http://github.com/mbebenita/Broadway
C++ | 249 lines | 197 code | 26 blank | 26 comment | 42 complexity | daaa410633e1c28c850d93b0d8c93b56 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /* ------------------------------------------------------------------
  2. * Copyright (C) 1998-2009 PacketVideo
  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
  13. * express or implied.
  14. * See the License for the specific language governing permissions
  15. * and limitations under the License.
  16. * -------------------------------------------------------------------
  17. */
  18. #include <string.h>
  19. #include "avclib_common.h"
  20. /* see subclause 8.2.2 Decoding process for macroblock to slice group map */
  21. OSCL_EXPORT_REF AVCStatus FMOInit(AVCCommonObj *video)
  22. {
  23. AVCPicParamSet *currPPS = video->currPicParams;
  24. int *MbToSliceGroupMap = video->MbToSliceGroupMap;
  25. int PicSizeInMapUnits = video->PicSizeInMapUnits;
  26. int PicWidthInMbs = video->PicWidthInMbs;
  27. if (currPPS->num_slice_groups_minus1 == 0)
  28. {
  29. memset(video->MbToSliceGroupMap, 0, video->PicSizeInMapUnits*sizeof(uint));
  30. }
  31. else
  32. {
  33. switch (currPPS->slice_group_map_type)
  34. {
  35. case 0:
  36. FmoGenerateType0MapUnitMap(MbToSliceGroupMap, currPPS->run_length_minus1, currPPS->num_slice_groups_minus1, PicSizeInMapUnits);
  37. break;
  38. case 1:
  39. FmoGenerateType1MapUnitMap(MbToSliceGroupMap, PicWidthInMbs, currPPS->num_slice_groups_minus1, PicSizeInMapUnits);
  40. break;
  41. case 2:
  42. FmoGenerateType2MapUnitMap(currPPS, MbToSliceGroupMap, PicWidthInMbs, currPPS->num_slice_groups_minus1, PicSizeInMapUnits);
  43. break;
  44. case 3:
  45. FmoGenerateType3MapUnitMap(video, currPPS, MbToSliceGroupMap, PicWidthInMbs);
  46. break;
  47. case 4:
  48. FmoGenerateType4MapUnitMap(MbToSliceGroupMap, video->MapUnitsInSliceGroup0, currPPS->slice_group_change_direction_flag, PicSizeInMapUnits);
  49. break;
  50. case 5:
  51. FmoGenerateType5MapUnitMap(MbToSliceGroupMap, video, currPPS->slice_group_change_direction_flag, PicSizeInMapUnits);
  52. break;
  53. case 6:
  54. FmoGenerateType6MapUnitMap(MbToSliceGroupMap, (int*)currPPS->slice_group_id, PicSizeInMapUnits);
  55. break;
  56. default:
  57. return AVC_FAIL; /* out of range, shouldn't come this far */
  58. }
  59. }
  60. return AVC_SUCCESS;
  61. }
  62. /* see subclause 8.2.2.1 interleaved slice group map type*/
  63. void FmoGenerateType0MapUnitMap(int *mapUnitToSliceGroupMap, uint *run_length_minus1, uint num_slice_groups_minus1, uint PicSizeInMapUnits)
  64. {
  65. uint iGroup, j;
  66. uint i = 0;
  67. do
  68. {
  69. for (iGroup = 0;
  70. (iGroup <= num_slice_groups_minus1) && (i < PicSizeInMapUnits);
  71. i += run_length_minus1[iGroup++] + 1)
  72. {
  73. for (j = 0; j <= run_length_minus1[ iGroup ] && i + j < PicSizeInMapUnits; j++)
  74. mapUnitToSliceGroupMap[i+j] = iGroup;
  75. }
  76. }
  77. while (i < PicSizeInMapUnits);
  78. }
  79. /* see subclause 8.2.2.2 dispersed slice group map type*/
  80. void FmoGenerateType1MapUnitMap(int *mapUnitToSliceGroupMap, int PicWidthInMbs, uint num_slice_groups_minus1, uint PicSizeInMapUnits)
  81. {
  82. uint i;
  83. for (i = 0; i < PicSizeInMapUnits; i++)
  84. {
  85. mapUnitToSliceGroupMap[i] = ((i % PicWidthInMbs) + (((i / PicWidthInMbs) * (num_slice_groups_minus1 + 1)) / 2))
  86. % (num_slice_groups_minus1 + 1);
  87. }
  88. }
  89. /* see subclause 8.2.2.3 foreground with left-over slice group map type */
  90. void FmoGenerateType2MapUnitMap(AVCPicParamSet *pps, int *mapUnitToSliceGroupMap, int PicWidthInMbs,
  91. uint num_slice_groups_minus1, uint PicSizeInMapUnits)
  92. {
  93. int iGroup;
  94. uint i, x, y;
  95. uint yTopLeft, xTopLeft, yBottomRight, xBottomRight;
  96. for (i = 0; i < PicSizeInMapUnits; i++)
  97. {
  98. mapUnitToSliceGroupMap[ i ] = num_slice_groups_minus1;
  99. }
  100. for (iGroup = num_slice_groups_minus1 - 1 ; iGroup >= 0; iGroup--)
  101. {
  102. yTopLeft = pps->top_left[ iGroup ] / PicWidthInMbs;
  103. xTopLeft = pps->top_left[ iGroup ] % PicWidthInMbs;
  104. yBottomRight = pps->bottom_right[ iGroup ] / PicWidthInMbs;
  105. xBottomRight = pps->bottom_right[ iGroup ] % PicWidthInMbs;
  106. for (y = yTopLeft; y <= yBottomRight; y++)
  107. {
  108. for (x = xTopLeft; x <= xBottomRight; x++)
  109. {
  110. mapUnitToSliceGroupMap[ y * PicWidthInMbs + x ] = iGroup;
  111. }
  112. }
  113. }
  114. }
  115. /* see subclause 8.2.2.4 box-out slice group map type */
  116. /* follow the text rather than the JM, it's quite different. */
  117. void FmoGenerateType3MapUnitMap(AVCCommonObj *video, AVCPicParamSet* pps, int *mapUnitToSliceGroupMap,
  118. int PicWidthInMbs)
  119. {
  120. uint i, k;
  121. int leftBound, topBound, rightBound, bottomBound;
  122. int x, y, xDir, yDir;
  123. int mapUnitVacant;
  124. uint PicSizeInMapUnits = video->PicSizeInMapUnits;
  125. uint MapUnitsInSliceGroup0 = video->MapUnitsInSliceGroup0;
  126. for (i = 0; i < PicSizeInMapUnits; i++)
  127. {
  128. mapUnitToSliceGroupMap[ i ] = 1;
  129. }
  130. x = (PicWidthInMbs - pps->slice_group_change_direction_flag) / 2;
  131. y = (video->PicHeightInMapUnits - pps->slice_group_change_direction_flag) / 2;
  132. leftBound = x;
  133. topBound = y;
  134. rightBound = x;
  135. bottomBound = y;
  136. xDir = pps->slice_group_change_direction_flag - 1;
  137. yDir = pps->slice_group_change_direction_flag;
  138. for (k = 0; k < MapUnitsInSliceGroup0; k += mapUnitVacant)
  139. {
  140. mapUnitVacant = (mapUnitToSliceGroupMap[ y * PicWidthInMbs + x ] == 1);
  141. if (mapUnitVacant)
  142. {
  143. mapUnitToSliceGroupMap[ y * PicWidthInMbs + x ] = 0;
  144. }
  145. if (xDir == -1 && x == leftBound)
  146. {
  147. leftBound = AVC_MAX(leftBound - 1, 0);
  148. x = leftBound;
  149. xDir = 0;
  150. yDir = 2 * pps->slice_group_change_direction_flag - 1;
  151. }
  152. else if (xDir == 1 && x == rightBound)
  153. {
  154. rightBound = AVC_MIN(rightBound + 1, (int)PicWidthInMbs - 1);
  155. x = rightBound;
  156. xDir = 0;
  157. yDir = 1 - 2 * pps->slice_group_change_direction_flag;
  158. }
  159. else if (yDir == -1 && y == topBound)
  160. {
  161. topBound = AVC_MAX(topBound - 1, 0);
  162. y = topBound;
  163. xDir = 1 - 2 * pps->slice_group_change_direction_flag;
  164. yDir = 0;
  165. }
  166. else if (yDir == 1 && y == bottomBound)
  167. {
  168. bottomBound = AVC_MIN(bottomBound + 1, (int)video->PicHeightInMapUnits - 1);
  169. y = bottomBound;
  170. xDir = 2 * pps->slice_group_change_direction_flag - 1;
  171. yDir = 0;
  172. }
  173. else
  174. {
  175. x = x + xDir;
  176. y = y + yDir;
  177. }
  178. }
  179. }
  180. /* see subclause 8.2.2.5 raster scan slice group map types */
  181. void FmoGenerateType4MapUnitMap(int *mapUnitToSliceGroupMap, int MapUnitsInSliceGroup0, int slice_group_change_direction_flag, uint PicSizeInMapUnits)
  182. {
  183. uint sizeOfUpperLeftGroup = slice_group_change_direction_flag ? (PicSizeInMapUnits - MapUnitsInSliceGroup0) : MapUnitsInSliceGroup0;
  184. uint i;
  185. for (i = 0; i < PicSizeInMapUnits; i++)
  186. if (i < sizeOfUpperLeftGroup)
  187. mapUnitToSliceGroupMap[ i ] = 1 - slice_group_change_direction_flag;
  188. else
  189. mapUnitToSliceGroupMap[ i ] = slice_group_change_direction_flag;
  190. }
  191. /* see subclause 8.2.2.6, wipe slice group map type. */
  192. void FmoGenerateType5MapUnitMap(int *mapUnitToSliceGroupMap, AVCCommonObj *video,
  193. int slice_group_change_direction_flag, uint PicSizeInMapUnits)
  194. {
  195. int PicWidthInMbs = video->PicWidthInMbs;
  196. int PicHeightInMapUnits = video->PicHeightInMapUnits;
  197. int MapUnitsInSliceGroup0 = video->MapUnitsInSliceGroup0;
  198. int sizeOfUpperLeftGroup = slice_group_change_direction_flag ? (PicSizeInMapUnits - MapUnitsInSliceGroup0) : MapUnitsInSliceGroup0;
  199. int i, j, k = 0;
  200. for (j = 0; j < PicWidthInMbs; j++)
  201. {
  202. for (i = 0; i < PicHeightInMapUnits; i++)
  203. {
  204. if (k++ < sizeOfUpperLeftGroup)
  205. {
  206. mapUnitToSliceGroupMap[ i * PicWidthInMbs + j ] = 1 - slice_group_change_direction_flag;
  207. }
  208. else
  209. {
  210. mapUnitToSliceGroupMap[ i * PicWidthInMbs + j ] = slice_group_change_direction_flag;
  211. }
  212. }
  213. }
  214. }
  215. /* see subclause 8.2.2.7, explicit slice group map */
  216. void FmoGenerateType6MapUnitMap(int *mapUnitToSliceGroupMap, int *slice_group_id, uint PicSizeInMapUnits)
  217. {
  218. uint i;
  219. for (i = 0; i < PicSizeInMapUnits; i++)
  220. {
  221. mapUnitToSliceGroupMap[i] = slice_group_id[i];
  222. }
  223. }