13306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong/* ------------------------------------------------------------------
23306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong * Copyright (C) 1998-2009 PacketVideo
33306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong *
43306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong * Licensed under the Apache License, Version 2.0 (the "License");
53306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong * you may not use this file except in compliance with the License.
63306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong * You may obtain a copy of the License at
73306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong *
83306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong *      http://www.apache.org/licenses/LICENSE-2.0
93306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong *
103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong * Unless required by applicable law or agreed to in writing, software
113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong * distributed under the License is distributed on an "AS IS" BASIS,
123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong * express or implied.
143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong * See the License for the specific language governing permissions
153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong * and limitations under the License.
163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong * -------------------------------------------------------------------
173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong */
183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include    "mp4dec_lib.h"
193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#include    "post_proc.h"
203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#ifdef PV_POSTPROC_ON
223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dongvoid Deringing_Chroma(
243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    uint8 *Rec_C,
253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int width,
263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int height,
273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int16 *QP_store,
283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int,
293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    uint8 *pp_mod
303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong)
313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong{
323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    /*----------------------------------------------------------------------------
333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ; Define all local variables
343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ----------------------------------------------------------------------------*/
353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int thres;
363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int v_blk, h_blk;
373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int max_diff;
383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int v_pel, h_pel;
393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int max_blk, min_blk;
403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int v0, h0;
413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    uint8 *ptr;
423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int sum, sum1, incr;
433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int32 addr_v;
443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int sign_v[10], sum_v[10];
453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    int *ptr2, *ptr3;
463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    uint8 pelu, pelc, pell;
473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    incr = width - BLKSIZE;
483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    /*----------------------------------------------------------------------------
503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ; Function body here
513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ----------------------------------------------------------------------------*/
523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    /* chrominance */
533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    /* Do the first line (7 pixels at a time => Don't use MMX)*/
543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    for (h_blk = 0; h_blk < width; h_blk += BLKSIZE)
553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    {
563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        max_diff = (QP_store[h_blk>>3] >> 2) + 4;
573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ptr = &Rec_C[h_blk];
583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        max_blk = min_blk = *ptr;
593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        FindMaxMin(ptr, &min_blk, &max_blk, width);
603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        h0 = ((h_blk - 1) >= 1) ? (h_blk - 1) : 1;
613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (max_blk - min_blk >= 4)
633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        {
643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            thres = (max_blk + min_blk + 1) >> 1;
653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            for (v_pel = 1; v_pel < BLKSIZE - 1; v_pel++)
683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            {
693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                addr_v = (int32)v_pel * width;
703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                ptr = &Rec_C[addr_v + h0 - 1];
713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                ptr2 = &sum_v[0];
723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                ptr3 = &sign_v[0];
733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                pelu = *(ptr - width);
753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                pelc = *ptr;
763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                pell = *(ptr + width);
773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                ptr++;
783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                *ptr2++ = pelu + (pelc << 1) + pell;
793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                pelu = *(ptr - width);
823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                pelc = *ptr;
833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                pell = *(ptr + width);
843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                ptr++;
853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                *ptr2++ = pelu + (pelc << 1) + pell;
863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                for (h_pel = h0; h_pel < h_blk + BLKSIZE - 1; h_pel++)
893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                {
903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    pelu = *(ptr - width);
913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    pelc = *ptr;
923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    pell = *(ptr + width);
933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    *ptr2 = pelu + (pelc << 1) + pell;
953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    *ptr3 = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    sum1 = *(ptr3 - 2) + *(ptr3 - 1) + *ptr3;
983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    if (sum1 == 0 || sum1 == 9)
993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    {
1003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        sum = (*(ptr2 - 2) + (*(ptr2 - 1) << 1) + *ptr2 + 8) >> 4;
1013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        ptr--;
1033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        if (PV_ABS(*ptr - sum) > max_diff)
1043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        {
1053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                            if (sum > *ptr)
1063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                sum = *ptr + max_diff;
1073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                            else
1083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                sum = *ptr - max_diff;
1093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        }
1103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        *ptr++ = (uint8) sum;
1113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    }
1123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    ptr++;
1133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    ptr2++;
1143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    ptr3++;
1153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                }
1163306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            }
1173306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
1183306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    }
1193306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1203306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    for (v_blk = BLKSIZE; v_blk < height; v_blk += BLKSIZE)
1213306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    {
1223306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        v0 = v_blk - 1;
1233306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        /* Do the first block (pixels=7 => No MMX) */
1243306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        max_diff = (QP_store[((((int32)v_blk*width)>>3))>>3] >> 2) + 4;
1253306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        ptr = &Rec_C[(int32)v_blk * width];
1263306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        max_blk = min_blk = *ptr;
1273306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        FindMaxMin(ptr, &min_blk, &max_blk, incr);
1283306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1293306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        if (max_blk - min_blk >= 4)
1303306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        {
1313306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            thres = (max_blk + min_blk + 1) >> 1;
1323306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1333306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            for (v_pel = v0; v_pel < v_blk + BLKSIZE - 1; v_pel++)
1343306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            {
1353306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                addr_v = v_pel * width;
1363306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                ptr = &Rec_C[addr_v];
1373306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                ptr2 = &sum_v[0];
1383306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                ptr3 = &sign_v[0];
1393306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1403306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                pelu = *(ptr - width);
1413306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                pelc = *ptr;
1423306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                pell = *(ptr + width);
1433306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                ptr++;
1443306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                *ptr2++ = pelu + (pelc << 1) + pell;
1453306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
1463306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1473306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                pelu = *(ptr - width);
1483306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                pelc = *ptr;
1493306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                pell = *(ptr + width);
1503306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                ptr++;
1513306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                *ptr2++ = pelu + (pelc << 1) + pell;
1523306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                *ptr3++ = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
1533306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1543306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                for (h_pel = 1; h_pel < BLKSIZE - 1; h_pel++)
1553306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                {
1563306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    pelu = *(ptr - width);
1573306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    pelc = *ptr;
1583306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    pell = *(ptr + width);
1593306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1603306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    *ptr2 = pelu + (pelc << 1) + pell;
1613306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    *ptr3 = INDEX(pelu, thres) + INDEX(pelc, thres) + INDEX(pell, thres);
1623306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1633306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    sum1 = *(ptr3 - 2) + *(ptr3 - 1) + *ptr3;
1643306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    if (sum1 == 0 || sum1 == 9)
1653306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    {
1663306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        sum = (*(ptr2 - 2) + (*(ptr2 - 1) << 1) + *ptr2 + 8) >> 4;
1673306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1683306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        ptr--;
1693306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        if (PV_ABS(*ptr - sum) > max_diff)
1703306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        {
1713306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                            if (sum > *ptr)
1723306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                sum = *ptr + max_diff;
1733306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                            else
1743306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                                sum = *ptr - max_diff;
1753306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        }
1763306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                        *ptr++ = (uint8) sum;
1773306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    }
1783306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    ptr++;
1793306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    ptr2++;
1803306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    ptr3++;
1813306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                }
1823306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            }
1833306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
1843306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1853306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1863306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        /* Do the rest in MMX */
1873306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        for (h_blk = BLKSIZE; h_blk < width; h_blk += BLKSIZE)
1883306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        {
1893306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            if ((pp_mod[(v_blk/8)*(width/8)+h_blk/8]&0x4) != 0)
1903306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            {
1913306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                max_diff = (QP_store[((((int32)v_blk*width)>>3)+h_blk)>>3] >> 2) + 4;
1923306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                ptr = &Rec_C[(int32)v_blk * width + h_blk];
1933306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                max_blk = min_blk = *ptr;
1943306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                FindMaxMin(ptr, &min_blk, &max_blk, incr);
1953306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                h0 = h_blk - 1;
1963306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
1973306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                if (max_blk - min_blk >= 4)
1983306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                {
1993306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    thres = (max_blk + min_blk + 1) >> 1;
2003306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#ifdef NoMMX
2013306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    AdaptiveSmooth_NoMMX(Rec_C, v0, h0, v_blk, h_blk, thres, width, max_diff);
2023306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#else
2033306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                    DeringAdaptiveSmoothMMX(&Rec_C[(int32)v0*width+h0], width, thres, max_diff);
2043306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#endif
2053306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong                }
2063306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong            }
2073306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong        }
2083306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    } /* macroblock level */
2093306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong
2103306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    /*----------------------------------------------------------------------------
2113306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ; Return nothing or data or data pointer
2123306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    ----------------------------------------------------------------------------*/
2133306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong    return;
2143306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong}
2153306cfee3bf38ab207a0504e49c2d492bb73ffbfJames Dong#endif
216