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 
19 /*----------------------------------------------------------------------------
20 ; INCLUDES
21 ----------------------------------------------------------------------------*/
22 #include "mp4dec_lib.h"
23 #include "vlc_decode.h"
24 #include "bitstream.h"
25 #include "zigzag.h"
26 #include "scaling.h"
27 
doDCACPrediction(VideoDecData * video,int comp,int16 * q_block,int * direction)28 void    doDCACPrediction(
29     VideoDecData *video,
30     int comp,
31     int16 *q_block,
32     int *direction
33 )
34 {
35     /*----------------------------------------------------------------------------
36     ; Define all local variables
37     ----------------------------------------------------------------------------*/
38     int i;
39     int mbnum = video->mbnum;
40     int nMBPerRow = video->nMBPerRow;
41     int x_pos = video->mbnum_col;
42     int y_pos = video->mbnum_row;
43     int16 *AC_tmp;
44     int QP_tmp;
45     int16 *QP_store = video->QPMB + mbnum;
46     int QP = video->QPMB[mbnum];
47     int QP_half = QP >> 1;
48     int32 val;
49     int flag_0 = FALSE, flag_1 = FALSE;
50     uint8 *slice_nb = video->sliceNo;
51     typeDCStore *DC_store = video->predDC + mbnum;
52     typeDCACStore *DCAC_row = video->predDCAC_row + x_pos;
53     typeDCACStore *DCAC_col = video->predDCAC_col;
54 
55     uint ACpred_flag = (uint) video->acPredFlag[mbnum];
56 
57     int left_bnd, up_bnd;
58 
59     static const int Xpos[6] = { -1, 0, -1, 0, -1, -1};
60     static const int Ypos[6] = { -1, -1, 0, 0, -1, -1};
61 
62     static const int Xtab[6] = {1, 0, 3, 2, 4, 5};
63     static const int Ytab[6] = {2, 3, 0, 1, 4, 5};
64     static const int Ztab[6] = {3, 2, 1, 0, 4, 5};
65 
66     /* I added these to speed up comparisons */
67     static const int Pos0[6] = { 1, 1, 0, 0, 1, 1};
68     static const int Pos1[6] = { 1, 0, 1, 0, 1, 1};
69 
70     static const int B_Xtab[6] = {0, 1, 0, 1, 2, 3};
71     static const int B_Ytab[6] = {0, 0, 1, 1, 2, 3};
72 
73 //  int *direction;     /* 0: HORIZONTAL, 1: VERTICAL */
74     int block_A, block_B, block_C;
75     int DC_pred;
76     int y_offset, x_offset, x_tab, y_tab, z_tab;    /* speedup coefficients */
77     int b_xtab, b_ytab;
78 
79     if (!comp && x_pos && !(video->headerInfo.Mode[mbnum-1]&INTRA_MASK)) /* not intra */
80     {
81         oscl_memset(DCAC_col, 0, sizeof(typeDCACStore));
82     }
83     if (!comp && y_pos && !(video->headerInfo.Mode[mbnum-nMBPerRow]&INTRA_MASK)) /* not intra */
84     {
85         oscl_memset(DCAC_row, 0, sizeof(typeDCACStore));
86     }
87 
88     y_offset = Ypos[comp] * nMBPerRow;
89     x_offset = Xpos[comp];
90     x_tab = Xtab[comp];
91     y_tab = Ytab[comp];
92     z_tab = Ztab[comp];
93 
94     b_xtab = B_Xtab[comp];
95     b_ytab = B_Ytab[comp];
96 
97     /*----------------------------------------------------------------------------
98     ; Function body here
99     ----------------------------------------------------------------------------*/
100     /* Find the direction of prediction and the DC prediction */
101 
102     if (x_pos == 0 && y_pos == 0)
103     {   /* top left corner */
104         block_A = (comp == 1 || comp == 3) ? flag_0 = TRUE, DC_store[0][x_tab] : mid_gray;
105         block_B = (comp == 3) ? DC_store[x_offset][z_tab] : mid_gray;
106         block_C = (comp == 2 || comp == 3) ? flag_1 = TRUE, DC_store[0][y_tab] : mid_gray;
107     }
108     else if (x_pos == 0)
109     {   /* left edge */
110         up_bnd   = Pos0[comp] && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow];
111 
112         block_A = (comp == 1 || comp == 3) ? flag_0 = TRUE, DC_store[0][x_tab] : mid_gray;
113         block_B = ((comp == 1 && up_bnd) || comp == 3) ?  DC_store[y_offset+x_offset][z_tab] : mid_gray;
114         block_C = (comp == 2 || comp == 3 || up_bnd) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
115     }
116     else if (y_pos == 0)
117     { /* top row */
118         left_bnd = Pos1[comp] && slice_nb[mbnum] == slice_nb[mbnum-1];
119 
120         block_A = (comp == 1 || comp == 3 || left_bnd) ? flag_0 = TRUE, DC_store[x_offset][x_tab] : mid_gray;
121         block_B = ((comp == 2 && left_bnd) || comp == 3) ? DC_store[y_offset + x_offset][z_tab] : mid_gray;
122         block_C = (comp == 2 || comp == 3) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
123     }
124     else
125     {
126         up_bnd   = Pos0[comp] && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow];
127         left_bnd = Pos1[comp] && slice_nb[mbnum] == slice_nb[mbnum-1];
128 
129         block_A = (comp == 1 || comp == 3 || left_bnd) ? flag_0 = TRUE, DC_store[x_offset][x_tab] : mid_gray;
130         block_B = (((comp == 0 || comp == 4 || comp == 5) && slice_nb[mbnum] == slice_nb[mbnum-1-nMBPerRow]) ||
131                    (comp == 1 && up_bnd) || (comp == 2 && left_bnd) || (comp == 3)) ? DC_store[y_offset+x_offset][z_tab] : mid_gray;
132         block_C = (comp == 2 || comp == 3 || up_bnd) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
133     }
134 
135 
136     if ((PV_ABS((block_A - block_B))) < (PV_ABS((block_B - block_C))))
137     {
138         DC_pred = block_C;
139         *direction = 1;
140         if (ACpred_flag == 1)
141         {
142             if (flag_1)
143             {
144                 AC_tmp = DCAC_row[0][b_xtab];
145                 QP_tmp = QP_store[y_offset];
146                 if (QP_tmp == QP)
147                 {
148                     for (i = 1; i < 8; i++)
149                     {
150                         q_block[i] = *AC_tmp++;
151                     }
152                 }
153                 else
154                 {
155                     for (i = 1; i < 8; i++)
156                     {
157                         val = (int32)(*AC_tmp++) * QP_tmp;
158                         q_block[i] = (val < 0) ? (int16)((val - QP_half) / QP) : (int16)((val + QP_half) / QP);
159                         /* Vertical, top ROW of block C */
160                     }
161                 }
162             }
163         }
164     }
165     else
166     {
167         DC_pred = block_A;
168         *direction = 0;
169         if (ACpred_flag == 1)
170         {
171             if (flag_0)
172             {
173                 AC_tmp = DCAC_col[0][b_ytab];
174                 QP_tmp = QP_store[x_offset];
175                 if (QP_tmp == QP)
176                 {
177                     for (i = 1; i < 8; i++)
178                     {
179                         q_block[i<<3] = *AC_tmp++;
180                     }
181                 }
182                 else
183                 {
184                     for (i = 1; i < 8; i++)
185                     {
186                         val = (int32)(*AC_tmp++) * QP_tmp;
187                         q_block[i<<3] = (val < 0) ? (int16)((val - QP_half) / QP) : (int16)((val + QP_half) / QP);
188                         /* Vertical, top ROW of block C */
189                     }
190                 }
191             }
192         }
193     }
194 
195     /* Now predict the DC coefficient */
196     QP_tmp = (comp < 4) ? video->mblock->DCScalarLum : video->mblock->DCScalarChr;
197     q_block[0] += (int16)((DC_pred + (QP_tmp >> 1)) * scale[QP_tmp] >> 18);
198 //      q_block[0] += (DC_pred+(QP_tmp>>1))/QP_tmp;
199 
200     /*----------------------------------------------------------------------------
201     ; Return nothing or data or data pointer
202     ----------------------------------------------------------------------------*/
203     return;
204 }
205 #ifdef PV_ANNEX_IJKT_SUPPORT
doDCACPrediction_I(VideoDecData * video,int comp,int16 * q_block)206 void    doDCACPrediction_I(
207     VideoDecData *video,
208     int comp,
209     int16 *q_block
210 )
211 {
212     /*----------------------------------------------------------------------------
213     ; Define all local variables
214     ----------------------------------------------------------------------------*/
215     int mbnum = video->mbnum;
216     int nMBPerRow = video->nMBPerRow;
217     int x_pos = video->mbnum_col;
218     int y_pos = video->mbnum_row;
219     int16 *AC_tmp;
220     int flag_0 = FALSE, flag_1 = FALSE;
221     uint8 *slice_nb = video->sliceNo;
222     typeDCStore *DC_store = video->predDC + mbnum;
223     typeDCACStore *DCAC_row = video->predDCAC_row + x_pos;
224     typeDCACStore *DCAC_col = video->predDCAC_col;
225     int left_bnd, up_bnd;
226     uint8 *mode = video->headerInfo.Mode;
227     uint ACpred_flag = (uint) video->acPredFlag[mbnum];
228 
229 
230 
231     static const int Xpos[6] = { -1, 0, -1, 0, -1, -1};
232     static const int Ypos[6] = { -1, -1, 0, 0, -1, -1};
233 
234     static const int Xtab[6] = {1, 0, 3, 2, 4, 5};
235     static const int Ytab[6] = {2, 3, 0, 1, 4, 5};
236 
237     /* I added these to speed up comparisons */
238     static const int Pos0[6] = { 1, 1, 0, 0, 1, 1};
239     static const int Pos1[6] = { 1, 0, 1, 0, 1, 1};
240 
241     static const int B_Xtab[6] = {0, 1, 0, 1, 2, 3};
242     static const int B_Ytab[6] = {0, 0, 1, 1, 2, 3};
243 
244 //  int *direction;     /* 0: HORIZONTAL, 1: VERTICAL */
245     int block_A, block_C;
246     int y_offset, x_offset, x_tab, y_tab;   /* speedup coefficients */
247     int b_xtab, b_ytab;
248     y_offset = Ypos[comp] * nMBPerRow;
249     x_offset = Xpos[comp];
250     x_tab = Xtab[comp];
251     y_tab = Ytab[comp];
252 
253     b_xtab = B_Xtab[comp];
254     b_ytab = B_Ytab[comp];
255 
256     /*----------------------------------------------------------------------------
257     ; Function body here
258     ----------------------------------------------------------------------------*/
259     /* Find the direction of prediction and the DC prediction */
260 
261     if (x_pos == 0 && y_pos == 0)
262     {   /* top left corner */
263         block_A = (comp == 1 || comp == 3) ? flag_0 = TRUE, DC_store[0][x_tab] : mid_gray;
264         block_C = (comp == 2 || comp == 3) ? flag_1 = TRUE, DC_store[0][y_tab] : mid_gray;
265     }
266     else if (x_pos == 0)
267     {   /* left edge */
268         up_bnd   = (Pos0[comp] && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow])
269                    && (mode[mbnum-nMBPerRow] == MODE_INTRA || mode[mbnum-nMBPerRow] == MODE_INTRA_Q);;
270 
271         block_A = (comp == 1 || comp == 3) ? flag_0 = TRUE, DC_store[0][x_tab] : mid_gray;
272         block_C = (comp == 2 || comp == 3 || up_bnd) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
273     }
274     else if (y_pos == 0)
275     { /* top row */
276         left_bnd = (Pos1[comp] && slice_nb[mbnum] == slice_nb[mbnum-1])
277                    && (mode[mbnum-1] == MODE_INTRA || mode[mbnum-1] == MODE_INTRA_Q);
278 
279         block_A = (comp == 1 || comp == 3 || left_bnd) ? flag_0 = TRUE, DC_store[x_offset][x_tab] : mid_gray;
280         block_C = (comp == 2 || comp == 3) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
281     }
282     else
283     {
284         up_bnd   = (Pos0[comp] && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow])
285                    && (mode[mbnum-nMBPerRow] == MODE_INTRA || mode[mbnum-nMBPerRow] == MODE_INTRA_Q);
286         left_bnd = (Pos1[comp] && slice_nb[mbnum] == slice_nb[mbnum-1])
287                    && (mode[mbnum-1] == MODE_INTRA || mode[mbnum-1] == MODE_INTRA_Q);
288 
289         block_A = (comp == 1 || comp == 3 || left_bnd) ? flag_0 = TRUE, DC_store[x_offset][x_tab] : mid_gray;
290         block_C = (comp == 2 || comp == 3 || up_bnd) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
291     }
292 
293     if (ACpred_flag == 0)
294     {
295         if (flag_0 == TRUE)
296         {
297             if (flag_1 == TRUE)
298             {
299                 q_block[0] = (int16)((block_A + block_C) >> 1);
300             }
301             else
302             {
303                 q_block[0] = (int16)block_A;
304             }
305         }
306         else
307         {
308             if (flag_1 == TRUE)
309             {
310                 q_block[0] = (int16)block_C;
311             }
312             else
313             {
314                 q_block[0] = mid_gray;
315             }
316         }
317 
318     }
319     else
320     {
321         if (video->mblock->direction == 1)
322         {
323             if (flag_1 == TRUE)
324             {
325                 q_block[0] = (int16)block_C;
326 
327                 AC_tmp = DCAC_row[0][b_xtab];
328                 q_block[1] = AC_tmp[0];
329                 q_block[2] = AC_tmp[1];
330                 q_block[3] = AC_tmp[2];
331                 q_block[4] = AC_tmp[3];
332                 q_block[5] = AC_tmp[4];
333                 q_block[6] = AC_tmp[5];
334                 q_block[7] = AC_tmp[6];
335             }
336             else
337             {
338                 q_block[0] = mid_gray;
339             }
340         }
341         else
342         {
343             if (flag_0 == TRUE)
344             {
345                 q_block[0] = (int16)block_A;
346 
347                 AC_tmp = DCAC_col[0][b_ytab];
348                 q_block[8] = AC_tmp[0];
349                 q_block[16] = AC_tmp[1];
350                 q_block[24] = AC_tmp[2];
351                 q_block[32] = AC_tmp[3];
352                 q_block[40] = AC_tmp[4];
353                 q_block[48] = AC_tmp[5];
354                 q_block[56] = AC_tmp[6];
355             }
356             else
357             {
358                 q_block[0] = mid_gray;
359             }
360         }
361     }
362     /*----------------------------------------------------------------------------
363     ; Return nothing or data or data pointer
364     ----------------------------------------------------------------------------*/
365     return;
366 }
367 #endif
368 
369