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
28void    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
206void    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