1 /******************************************************************************
2  *
3  * Copyright (C) 2015 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 #ifndef _IH264D_MB_UTILS_H_
21 #define _IH264D_MB_UTILS_H_
22 /*!
23  **************************************************************************
24  * \file ih264d_mb_utils.h
25  *
26  * \brief
27  *    Contains declarations of the utility functions needed to decode MB
28  *
29  * \date
30  *    18/12/2002
31  *
32  * \author  AI
33  **************************************************************************
34  */
35 #include "ih264_typedefs.h"
36 #include "ih264_macros.h"
37 #include "ih264_platform_macros.h"
38 #include "ih264d_structs.h"
39 
40 /*--------------------------------------------------------------------*/
41 /* Macros to get raster scan position of a block[8x8] / sub block[4x4]*/
42 /*--------------------------------------------------------------------*/
43 
44 #define GET_BLK_RASTER_POS_X(x)     ((x & 0x01) << 1)
45 #define GET_BLK_RASTER_POS_Y(y)     ((y >> 1)   << 1)
46 #define GET_SUB_BLK_RASTER_POS_X(x) ((x & 0x01))
47 #define GET_SUB_BLK_RASTER_POS_Y(y) ((y >> 1))
48 
49 /*--------------------------------------------------------------------*/
50 /* Masks used in decoding of Macroblock                               */
51 /*--------------------------------------------------------------------*/
52 
53 #define LEFT_MB_AVAILABLE_MASK      0x01
54 #define TOP_LEFT_MB_AVAILABLE_MASK  0x02
55 #define TOP_MB_AVAILABLE_MASK       0x04
56 #define TOP_RIGHT_MB_AVAILABLE_MASK 0x08
57 
58 #define TOP_RT_SUBBLOCK_MASK_MOD               0xFFF7
59 
60 #define TOP_RIGHT_DEFAULT_AVAILABLE            0x5750
61 #define TOP_RIGHT_TOPR_AVAILABLE               0x0008
62 #define TOP_RIGHT_TOP_AVAILABLE                0x0007
63 
64 #define TOP_LEFT_DEFAULT_AVAILABLE            0xEEE0
65 #define TOP_LEFT_TOPL_AVAILABLE               0x0001
66 #define TOP_LEFT_TOP_AVAILABLE                0x000E
67 #define TOP_LEFT_LEFT_AVAILABLE               0x1110
68 
69 #define CHECK_MB_MAP(u4_mb_num, mb_map, u4_cond)                                                    \
70 {                                                                                                   \
71         UWORD32 u4_bit_number;                                                                      \
72         volatile UWORD8 *pu1_mb_flag;                                                                       \
73                                                                                                     \
74         u4_bit_number = u4_mb_num & 0x07;                                                           \
75         pu1_mb_flag    = (UWORD8 *)mb_map + (u4_mb_num >> 3);                                                       \
76                                                                                                     \
77         u4_cond = CHECKBIT((*pu1_mb_flag), u4_bit_number);                                              \
78 }
79 
80 #define CHECK_MB_MAP_BYTE(u4_mb_num, mb_map, u4_cond)                                               \
81 {                                                                                                   \
82         volatile UWORD8 *pu1_mb_flag;                                                               \
83                                                                                                     \
84         pu1_mb_flag    = (UWORD8 *)mb_map + (u4_mb_num );                                           \
85                                                                                                     \
86         u4_cond = (*pu1_mb_flag);                                                                   \
87 }
88 
89 #define UPDATE_MB_MAP(u2_frm_wd_in_mbs, u2_mbx, u2_mby, mb_map, mb_count)                     \
90 {                                                                                                   \
91         UWORD32 u4_bit_number;                                                                      \
92         UWORD32 u4_mb_number;                                                                       \
93                                                                                                     \
94         u4_mb_number    = u2_frm_wd_in_mbs * (u2_mby >> u1_mbaff) + u2_mbx;                   \
95                                                                                                     \
96         u4_bit_number = u4_mb_number & 0x07;                                                        \
97         /*                                                                                          \
98          * In case of MbAff, update the mb_map only if the entire MB is done. We can check that     \
99          * by checking if Y is odd, implying that this is the second row in the MbAff MB            \
100          */                                                                                         \
101         SET_BIT(mb_map[u4_mb_number >> 3], u4_bit_number);                                           \
102                                                                                                     \
103         if (1 == u1_mbaff)                                                                          \
104         {                                                                                           \
105             /*                                                                                      \
106              * If MBAFF u4_flag is set, set this MB and the MB just below this.                        \
107              * So, add frame width to the MB number and set that bit.                               \
108              */                                                                                     \
109             /*                                                                                      \
110             u4_mb_number    += u2_frm_wd_in_mbs;                                                  \
111                                                                                                     \
112             u4_bit_number = u4_mb_number & 0x07;                                                    \
113                                                                                                     \
114             SET_BIT(mb_map[u4_mb_number >> 3], u4_bit_number);                                       \
115             */                                                                                      \
116         }                                                                                           \
117                                                                                                     \
118         /*H264_DEC_DEBUG_PRINT("SETBIT: %d\n", u4_mb_number);*/                                     \
119         mb_count++;                                                                                 \
120 }
121 
122 #define UPDATE_MB_MAP_MBNUM(mb_map, u4_mb_number)                                                   \
123 {                                                                                                   \
124         UWORD32 u4_bit_number;                                                                      \
125         volatile UWORD8 *pu1_mb_flag;                                                                       \
126                                                                                                     \
127         u4_bit_number = u4_mb_number & 0x07;                                                        \
128         pu1_mb_flag    = (UWORD8 *)mb_map + (u4_mb_number >> 3);                                                        \
129         /*                                                                                          \
130          * In case of MbAff, update the mb_map only if the entire MB is done. We can check that     \
131          * by checking if Y is odd, implying that this is the second row in the MbAff MB            \
132          */                                                                                         \
133         SET_BIT((*pu1_mb_flag), u4_bit_number);                                                          \
134 }
135 
136 #define UPDATE_MB_MAP_MBNUM_BYTE(mb_map, u4_mb_number)                                                  \
137 {                                                                                                   \
138         volatile UWORD8 *pu1_mb_flag;                                                                       \
139                                                                                                     \
140         pu1_mb_flag    = (UWORD8 *)mb_map + (u4_mb_number);                                                     \
141         /*                                                                                          \
142          * In case of MbAff, update the mb_map only if the entire MB is done. We can check that     \
143          * by checking if Y is odd, implying that this is the second row in the MbAff MB            \
144          */                                                                                         \
145         (*pu1_mb_flag) = 1;                                                             \
146 }
147 
148 #define UPDATE_SLICE_NUM_MAP(slice_map, u4_mb_number,u2_slice_num)                                                  \
149 {                                                                                                   \
150         volatile UWORD16 *pu2_slice_map;                                                               \
151                                                                                                     \
152         pu2_slice_map    = (UWORD16 *)slice_map + (u4_mb_number);                                         \
153         (*pu2_slice_map) = u2_slice_num;                                                              \
154 }
155 
156 #define GET_SLICE_NUM_MAP(slice_map, mb_number,u2_slice_num)                                                  \
157 {                                                                                                   \
158         volatile UWORD16 *pu2_slice_map;                                                               \
159                                                                                                     \
160         pu2_slice_map    = (UWORD16 *)slice_map + (mb_number);                                         \
161         u2_slice_num = (*pu2_slice_map) ;                                                               \
162 }
163 
164 
165 #define GET_XPOS_PRED(u1_out,pkd_info)                        \
166 {                                                               \
167     WORD32 bit_field;                                           \
168     bit_field = pkd_info & 0x3;                                 \
169     u1_out = bit_field;                                       \
170 }
171 
172 
173 #define GET_YPOS_PRED(u1_out,pkd_info)                        \
174 {                                                               \
175     WORD32 bit_field;                                           \
176     bit_field = pkd_info >> 2;                                  \
177     u1_out = bit_field & 0x3;                                  \
178 }
179 
180 
181 
182 #define GET_WIDTH_PRED(u1_out,pkd_info)                        \
183 {                                                               \
184     WORD32 bit_field;                                           \
185     bit_field = pkd_info >> 4;                                  \
186     bit_field = (bit_field & 0x3) << 1 ;                        \
187     u1_out = (bit_field == 0)?1:bit_field;                       \
188     }
189 
190 #define GET_HEIGHT_PRED(u1_out,pkd_info)                        \
191 {                                                               \
192     WORD32 bit_field;                                           \
193     bit_field = pkd_info >> 6;                                  \
194     bit_field = (bit_field & 0x3) << 1 ;                        \
195     u1_out = (bit_field == 0)?1:bit_field;                      \
196 }
197 
198 /*!
199  **************************************************************************
200  *   \brief   Masks for elements present in the first column but not on the
201  *   first row.
202  **************************************************************************
203  */
204 #define FIRST_COL_NOT_FIRST_ROW             0xFAFB
205 #define FIRST_ROW_MASK                      0xFFCC
206 /*!
207  **************************************************************************
208  *   \brief   Mask for elements presen in the first row but not in the
209  *   last column.
210  **************************************************************************
211  */
212 #define FIRST_ROW_NOT_LAST_COL             0xFFEC
213 /*!
214  **************************************************************************
215  *   \brief   Mask for elements presen in the first row but not in the
216  *   first column.
217  **************************************************************************
218  */
219 #define FIRST_ROW_NOT_FIRST_COL            0xFFCD
220 /*!
221  **************************************************************************
222  *   \brief   Masks for the top right subMB of a 4x4 block
223  **************************************************************************
224  */
225 #define TOP_RT_SUBBLOCK_MASK                0xFFDF
226 /*!
227  **************************************************************************
228  *   \brief   Masks for the top left subMB of a 4x4 block
229  **************************************************************************
230  */
231 #define TOP_LT_SUBBLOCK_MASK                0xFFFE
232 /*!
233  **************************************************************************
234  *   \brief   Indicates if a subMB has a top right subMB available
235  **************************************************************************
236  */
237 #define TOP_RT_SUBBLOCK_MB_MASK  0x5F4C
238 
239 #define FIRST_COL_MASK           0xFAFA
240 
241 /*--------------------------------------------------------------------*/
242 /* Macros to calculate the current position of a MB wrt picture       */
243 /*--------------------------------------------------------------------*/
244 #define MB_LUMA_PIC_OFFSET(mb_x,mb_y,frmWidthY)   (((mb_y)*(frmWidthY) + (mb_x))<<4)
245 #define MB_CHROMA_PIC_OFFSET(mb_x,mb_y,frmWidthUV) (((mb_y)*(frmWidthUV) + (mb_x))<<3)
246 
247 /*--------------------------------------------------------------------*/
248 /* Macros to calculate the current position of a MB wrt N[ Num coeff] Array */
249 /*--------------------------------------------------------------------*/
250 #define MB_PARAM_OFFSET(mb_x,mb_y,frmWidthInMbs,u1_mbaff,u1_topmb)  \
251         ((mb_x << u1_mbaff) + (1 - u1_topmb) + (mb_y * frmWidthInMbs))
252 
253 UWORD32 ih264d_get_mb_info_cavlc_mbaff(dec_struct_t * ps_dec,
254                                        const UWORD16 ui16_curMbAddress,
255                                        dec_mb_info_t * ps_cur_mb_info,
256                                        UWORD32 u4_mbskip_run);
257 UWORD32 ih264d_get_mb_info_cavlc_nonmbaff(dec_struct_t * ps_dec,
258                                           const UWORD16 ui16_curMbAddress,
259                                           dec_mb_info_t * ps_cur_mb_info,
260                                           UWORD32 u4_mbskip_run);
261 
262 UWORD32 ih264d_get_mb_info_cabac_mbaff(dec_struct_t * ps_dec,
263                                        const UWORD16 ui16_curMbAddress,
264                                        dec_mb_info_t * ps_cur_mb_info,
265                                        UWORD32 u4_mbskip_run);
266 
267 UWORD32 ih264d_get_mb_info_cabac_nonmbaff(dec_struct_t * ps_dec,
268                                           const UWORD16 ui16_curMbAddress,
269                                           dec_mb_info_t * ps_cur_mb_info,
270                                           UWORD32 u4_mbskip_run);
271 
272 UWORD8 get_cabac_context_non_mbaff(dec_struct_t * ps_dec, UWORD16 u2_mbskip);
273 
274 UWORD32 ih264d_get_cabac_context_mbaff(dec_struct_t * ps_dec,
275                                        dec_mb_info_t * ps_cur_mb_info,
276                                        UWORD32 u4_mbskip);
277 
278 WORD32 PutMbToFrame(dec_struct_t * ps_dec);
279 void ih264d_get_mbaff_neighbours(dec_struct_t * ps_dec,
280                                  dec_mb_info_t * ps_cur_mb_info,
281                                  UWORD8 uc_curMbFldDecFlag);
282 
283 void ih264d_update_mbaff_left_nnz(dec_struct_t * ps_dec,
284                                   dec_mb_info_t * ps_cur_mb_info);
285 void ih264d_transfer_mb_group_data(dec_struct_t * ps_dec,
286                                    const UWORD8 u1_num_mbs,
287                                    const UWORD8 u1_end_of_row, /* Cur n-Mb End of Row Flag */
288                                    const UWORD8 u1_end_of_row_next /* Next n-Mb End of Row Flag */
289                                    );
290 
291 //void FillRandomData(UWORD8 *pu1_buf, WORD32 u4_bufSize);
292 
293 #endif /* _MB_UTILS_H_ */
294