1bebc99d6fa433c04139294a5057f8439d772dbd9James Dong/*
2bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * Copyright (C) 2009 The Android Open Source Project
3bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *
4bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * Licensed under the Apache License, Version 2.0 (the "License");
5bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * you may not use this file except in compliance with the License.
6bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * You may obtain a copy of the License at
7bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *
8bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *      http://www.apache.org/licenses/LICENSE-2.0
9bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *
10bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * Unless required by applicable law or agreed to in writing, software
11bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * distributed under the License is distributed on an "AS IS" BASIS,
12bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * See the License for the specific language governing permissions and
14bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * limitations under the License.
15bebc99d6fa433c04139294a5057f8439d772dbd9James Dong */
16bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
17bebc99d6fa433c04139294a5057f8439d772dbd9James Dong/*------------------------------------------------------------------------------
18bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
19bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    Table of contents
20bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
21bebc99d6fa433c04139294a5057f8439d772dbd9James Dong     1. Include headers
22bebc99d6fa433c04139294a5057f8439d772dbd9James Dong     2. External compiler flags
23bebc99d6fa433c04139294a5057f8439d772dbd9James Dong     3. Module defines
24bebc99d6fa433c04139294a5057f8439d772dbd9James Dong     4. Local function prototypes
25bebc99d6fa433c04139294a5057f8439d772dbd9James Dong     5. Functions
26bebc99d6fa433c04139294a5057f8439d772dbd9James Dong          h264bsdConceal
27bebc99d6fa433c04139294a5057f8439d772dbd9James Dong          ConcealMb
28bebc99d6fa433c04139294a5057f8439d772dbd9James Dong          Transform
29bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
30bebc99d6fa433c04139294a5057f8439d772dbd9James Dong------------------------------------------------------------------------------*/
31bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
32bebc99d6fa433c04139294a5057f8439d772dbd9James Dong/*------------------------------------------------------------------------------
33bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    1. Include headers
34bebc99d6fa433c04139294a5057f8439d772dbd9James Dong------------------------------------------------------------------------------*/
35bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
36bebc99d6fa433c04139294a5057f8439d772dbd9James Dong#include "h264bsd_conceal.h"
37bebc99d6fa433c04139294a5057f8439d772dbd9James Dong#include "h264bsd_util.h"
38bebc99d6fa433c04139294a5057f8439d772dbd9James Dong#include "h264bsd_reconstruct.h"
39bebc99d6fa433c04139294a5057f8439d772dbd9James Dong#include "h264bsd_dpb.h"
40bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
41bebc99d6fa433c04139294a5057f8439d772dbd9James Dong/*------------------------------------------------------------------------------
42bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    2. External compiler flags
43bebc99d6fa433c04139294a5057f8439d772dbd9James Dong--------------------------------------------------------------------------------
44bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
45bebc99d6fa433c04139294a5057f8439d772dbd9James Dong--------------------------------------------------------------------------------
46bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    3. Module defines
47bebc99d6fa433c04139294a5057f8439d772dbd9James Dong------------------------------------------------------------------------------*/
48bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
49bebc99d6fa433c04139294a5057f8439d772dbd9James Dong/*lint -e702 disable lint warning on right shift of signed quantity */
50bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
51bebc99d6fa433c04139294a5057f8439d772dbd9James Dong/*------------------------------------------------------------------------------
52bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    4. Local function prototypes
53bebc99d6fa433c04139294a5057f8439d772dbd9James Dong------------------------------------------------------------------------------*/
54bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
55bebc99d6fa433c04139294a5057f8439d772dbd9James Dongstatic u32 ConcealMb(mbStorage_t *pMb, image_t *currImage, u32 row, u32 col,
56bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    u32 sliceType, u8 *data);
57bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
58bebc99d6fa433c04139294a5057f8439d772dbd9James Dongstatic void Transform(i32 *data);
59bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
60bebc99d6fa433c04139294a5057f8439d772dbd9James Dong/*------------------------------------------------------------------------------
61bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
62bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    Function name: h264bsdConceal
63bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
64bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        Functional description:
65bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            Perform error concealment for a picture. Two types of concealment
66bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            is performed based on sliceType:
67bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                1) copy from previous picture for P-slices.
68bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                2) concealment from neighbour pixels for I-slices
69bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
70bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            I-type concealment is based on ideas presented by Jarno Tulkki.
71bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            The concealment algorithm determines frequency domain coefficients
72bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            from the neighbour pixels, applies integer transform (the same
73bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            transform used in the residual processing) and uses the results as
74bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            pixel values for concealed macroblocks. Transform produces 4x4
75bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            array and one pixel value has to be used for 4x4 luma blocks and
76bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            2x2 chroma blocks.
77bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
78bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            Similar concealment is performed for whole picture (the choise
79bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            of the type is based on last successfully decoded slice header of
80bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            the picture but it is handled by the calling function). It is
81bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            acknowledged that this may result in wrong type of concealment
82bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            when a picture contains both types of slices. However,
83bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            determination of slice type macroblock-by-macroblock cannot
84bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            be done due to the fact that it is impossible to know to which
85bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            slice each corrupted (not successfully decoded) macroblock
86bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            belongs.
87bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
88bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            The error concealment is started by searching the first propoerly
89bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            decoded macroblock and concealing the row containing the macroblock
90bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            in question. After that all macroblocks above the row in question
91bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            are concealed. Finally concealment of rows below is performed.
92bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            The order of concealment for 4x4 picture where macroblock 9 is the
93bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            first properly decoded one is as follows (properly decoded
94bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            macroblocks marked with 'x', numbers indicating the order of
95bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            concealment):
96bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
97bebc99d6fa433c04139294a5057f8439d772dbd9James Dong               4  6  8 10
98bebc99d6fa433c04139294a5057f8439d772dbd9James Dong               3  5  7  9
99bebc99d6fa433c04139294a5057f8439d772dbd9James Dong               1  x  x  2
100bebc99d6fa433c04139294a5057f8439d772dbd9James Dong              11 12 13 14
101bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
102bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            If all macroblocks of the picture are lost, the concealment is
103bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            copy of previous picture for P-type and setting the image to
104bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            constant gray (pixel value 128) for I-type.
105bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
106bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            Concealment sets quantization parameter of the concealed
107bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            macroblocks to value 40 and macroblock type to intra to enable
108bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            deblocking filter to smooth the edges of the concealed areas.
109bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
110bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        Inputs:
111bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            pStorage        pointer to storage structure
112bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            currImage       pointer to current image structure
113bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            sliceType       type of the slice
114bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
115bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        Outputs:
116bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            currImage       concealed macroblocks will be written here
117bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
118bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        Returns:
119bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            HANTRO_OK
120bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
121bebc99d6fa433c04139294a5057f8439d772dbd9James Dong------------------------------------------------------------------------------*/
122bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
123bebc99d6fa433c04139294a5057f8439d772dbd9James Dongu32 h264bsdConceal(storage_t *pStorage, image_t *currImage, u32 sliceType)
124bebc99d6fa433c04139294a5057f8439d772dbd9James Dong{
125bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
126bebc99d6fa433c04139294a5057f8439d772dbd9James Dong/* Variables */
127bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
128bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    u32 i, j;
129bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    u32 row, col;
130bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    u32 width, height;
131bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    u8 *refData;
132bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    mbStorage_t *mb;
133bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
134bebc99d6fa433c04139294a5057f8439d772dbd9James Dong/* Code */
135bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
136bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    ASSERT(pStorage);
137bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    ASSERT(currImage);
138bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
139bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    DEBUG(("Concealing %s slice\n", IS_I_SLICE(sliceType) ?
140bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            "intra" : "inter"));
141bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
142bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    width = currImage->width;
143bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    height = currImage->height;
144bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    refData = NULL;
145bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* use reference picture with smallest available index */
146bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    if (IS_P_SLICE(sliceType) || (pStorage->intraConcealmentFlag != 0))
147bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
148bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        i = 0;
149bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        do
150bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        {
151bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            refData = h264bsdGetRefPicData(pStorage->dpb, i);
152bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            i++;
153bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            if (i >= 16)
154bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                break;
155bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        } while (refData == NULL);
156bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
157bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
158bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    i = row = col = 0;
159bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* find first properly decoded macroblock -> start point for concealment */
160bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    while (i < pStorage->picSizeInMbs && !pStorage->mb[i].decoded)
161bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
162bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        i++;
163bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        col++;
164bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        if (col == width)
165bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        {
166bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            row++;
167bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            col = 0;
168bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        }
169bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
170bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
171bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* whole picture lost -> copy previous or set grey */
172bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    if (i == pStorage->picSizeInMbs)
173bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
174bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        if ( (IS_I_SLICE(sliceType) && (pStorage->intraConcealmentFlag == 0)) ||
175bebc99d6fa433c04139294a5057f8439d772dbd9James Dong             refData == NULL)
176bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            H264SwDecMemset(currImage->data, 128, width*height*384);
177bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        else
178bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            H264SwDecMemcpy(currImage->data, refData, width*height*384);
179bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
180bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        pStorage->numConcealedMbs = pStorage->picSizeInMbs;
181bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
182bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        /* no filtering if whole picture concealed */
183bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        for (i = 0; i < pStorage->picSizeInMbs; i++)
184bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            pStorage->mb[i].disableDeblockingFilterIdc = 1;
185bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
186bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        return(HANTRO_OK);
187bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
188bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
189bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* start from the row containing the first correct macroblock, conceal the
190bebc99d6fa433c04139294a5057f8439d772dbd9James Dong     * row in question, all rows above that row and then continue downwards */
191bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    mb = pStorage->mb + row * width;
192bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    for (j = col; j--;)
193bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
194bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        ConcealMb(mb+j, currImage, row, j, sliceType, refData);
195bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        mb[j].decoded = 1;
196bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        pStorage->numConcealedMbs++;
197bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
198bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    for (j = col + 1; j < width; j++)
199bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
200bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        if (!mb[j].decoded)
201bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        {
202bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            ConcealMb(mb+j, currImage, row, j, sliceType, refData);
203bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            mb[j].decoded = 1;
204bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            pStorage->numConcealedMbs++;
205bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        }
206bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
207bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* if previous row(s) could not be concealed -> conceal them now */
208bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    if (row)
209bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
210bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        for (j = 0; j < width; j++)
211bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        {
212bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            i = row - 1;
213bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            mb = pStorage->mb + i*width + j;
214bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            do
215bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            {
216bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                ConcealMb(mb, currImage, i, j, sliceType, refData);
217bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                mb->decoded = 1;
218bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                pStorage->numConcealedMbs++;
219bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                mb -= width;
220bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            } while(i--);
221bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        }
222bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
223bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
224bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* process rows below the one containing the first correct macroblock */
225bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    for (i = row + 1; i < height; i++)
226bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
227bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        mb = pStorage->mb + i * width;
228bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
229bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        for (j = 0; j < width; j++)
230bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        {
231bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            if (!mb[j].decoded)
232bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            {
233bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                ConcealMb(mb+j, currImage, i, j, sliceType, refData);
234bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                mb[j].decoded = 1;
235bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                pStorage->numConcealedMbs++;
236bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            }
237bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        }
238bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
239bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
240bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    return(HANTRO_OK);
241bebc99d6fa433c04139294a5057f8439d772dbd9James Dong}
242bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
243bebc99d6fa433c04139294a5057f8439d772dbd9James Dong/*------------------------------------------------------------------------------
244bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
245bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    Function name: ConcealMb
246bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
247bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        Functional description:
248bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            Perform error concealment for one macroblock, location of the
249bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            macroblock in the picture indicated by row and col
250bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
251bebc99d6fa433c04139294a5057f8439d772dbd9James Dong------------------------------------------------------------------------------*/
252bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
253bebc99d6fa433c04139294a5057f8439d772dbd9James Dongu32 ConcealMb(mbStorage_t *pMb, image_t *currImage, u32 row, u32 col,
254bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    u32 sliceType, u8 *refData)
255bebc99d6fa433c04139294a5057f8439d772dbd9James Dong{
256bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
257bebc99d6fa433c04139294a5057f8439d772dbd9James Dong/* Variables */
258bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
259bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    u32 i, j, comp;
260bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    u32 hor, ver;
261bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    u32 mbNum;
262bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    u32 width, height;
263bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    u8 *mbPos;
264bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    u8 data[384];
265bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    u8 *pData;
266bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    i32 tmp;
267bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    i32 firstPhase[16];
268bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    i32 *pTmp;
269bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* neighbours above, below, left and right */
270bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    i32 a[4], b[4], l[4], r[4];
271bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    u32 A, B, L, R;
272bebc99d6fa433c04139294a5057f8439d772dbd9James Dong#ifdef H264DEC_OMXDL
273bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    u8 fillBuff[32*21 + 15 + 32];
274bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    u8 *pFill;
275bebc99d6fa433c04139294a5057f8439d772dbd9James Dong#endif
276bebc99d6fa433c04139294a5057f8439d772dbd9James Dong/* Code */
277bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
278bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    ASSERT(pMb);
279bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    ASSERT(!pMb->decoded);
280bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    ASSERT(currImage);
281bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    ASSERT(col < currImage->width);
282bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    ASSERT(row < currImage->height);
283bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
284bebc99d6fa433c04139294a5057f8439d772dbd9James Dong#ifdef H264DEC_OMXDL
285bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    pFill = ALIGN(fillBuff, 16);
286bebc99d6fa433c04139294a5057f8439d772dbd9James Dong#endif
287bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    width = currImage->width;
288bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    height = currImage->height;
289bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    mbNum = row * width + col;
290bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
291bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    h264bsdSetCurrImageMbPointers(currImage, mbNum);
292bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
293bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    mbPos = currImage->data + row * 16 * width * 16 + col * 16;
294bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    A = B = L = R = HANTRO_FALSE;
295bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
296bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* set qpY to 40 to enable some filtering in deblocking (stetson value) */
297bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    pMb->qpY = 40;
298bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    pMb->disableDeblockingFilterIdc = 0;
299bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* mbType set to intra to perform filtering despite the values of other
300bebc99d6fa433c04139294a5057f8439d772dbd9James Dong     * boundary strength determination fields */
301bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    pMb->mbType = I_4x4;
302bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    pMb->filterOffsetA = 0;
303bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    pMb->filterOffsetB = 0;
304bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    pMb->chromaQpIndexOffset = 0;
305bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
306bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    if (IS_I_SLICE(sliceType))
307bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        H264SwDecMemset(data, 0, sizeof(data));
308bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    else
309bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
310bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        mv_t mv = {0,0};
311bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        image_t refImage;
312bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        refImage.width = width;
313bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        refImage.height = height;
314bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        refImage.data = refData;
315bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        if (refImage.data)
316bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        {
317bebc99d6fa433c04139294a5057f8439d772dbd9James Dong#ifndef H264DEC_OMXDL
318bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            h264bsdPredictSamples(data, &mv, &refImage, col*16, row*16,
319bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                0, 0, 16, 16);
320bebc99d6fa433c04139294a5057f8439d772dbd9James Dong#else
321bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            h264bsdPredictSamples(data, &mv, &refImage,
322bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                    ((row*16) + ((col*16)<<16)),
323bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                    0x00001010, pFill);
324bebc99d6fa433c04139294a5057f8439d772dbd9James Dong#endif
325bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            h264bsdWriteMacroblock(currImage, data);
326bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
327bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            return(HANTRO_OK);
328bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        }
329bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        else
330bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            H264SwDecMemset(data, 0, sizeof(data));
331bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
332bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
333bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    H264SwDecMemset(firstPhase, 0, sizeof(firstPhase));
334bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
335bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* counter for number of neighbours used */
336bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    j = 0;
337bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    hor = ver = 0;
338bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    if (row && (pMb-width)->decoded)
339bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
340bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        A = HANTRO_TRUE;
341bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        pData = mbPos - width*16;
342bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        a[0] = *pData++; a[0] += *pData++; a[0] += *pData++; a[0] += *pData++;
343bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        a[1] = *pData++; a[1] += *pData++; a[1] += *pData++; a[1] += *pData++;
344bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        a[2] = *pData++; a[2] += *pData++; a[2] += *pData++; a[2] += *pData++;
345bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        a[3] = *pData++; a[3] += *pData++; a[3] += *pData++; a[3] += *pData++;
346bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        j++;
347bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        hor++;
348bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        firstPhase[0] += a[0] + a[1] + a[2] + a[3];
349bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        firstPhase[1] += a[0] + a[1] - a[2] - a[3];
350bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
351bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    if ((row != height - 1) && (pMb+width)->decoded)
352bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
353bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        B = HANTRO_TRUE;
354bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        pData = mbPos + 16*width*16;
355bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        b[0] = *pData++; b[0] += *pData++; b[0] += *pData++; b[0] += *pData++;
356bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        b[1] = *pData++; b[1] += *pData++; b[1] += *pData++; b[1] += *pData++;
357bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        b[2] = *pData++; b[2] += *pData++; b[2] += *pData++; b[2] += *pData++;
358bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        b[3] = *pData++; b[3] += *pData++; b[3] += *pData++; b[3] += *pData++;
359bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        j++;
360bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        hor++;
361bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        firstPhase[0] += b[0] + b[1] + b[2] + b[3];
362bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        firstPhase[1] += b[0] + b[1] - b[2] - b[3];
363bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
364bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    if (col && (pMb-1)->decoded)
365bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
366bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        L = HANTRO_TRUE;
367bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        pData = mbPos - 1;
368bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        l[0] = pData[0]; l[0] += pData[16*width];
369bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        l[0] += pData[32*width]; l[0] += pData[48*width];
370bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        pData += 64*width;
371bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        l[1] = pData[0]; l[1] += pData[16*width];
372bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        l[1] += pData[32*width]; l[1] += pData[48*width];
373bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        pData += 64*width;
374bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        l[2] = pData[0]; l[2] += pData[16*width];
375bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        l[2] += pData[32*width]; l[2] += pData[48*width];
376bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        pData += 64*width;
377bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        l[3] = pData[0]; l[3] += pData[16*width];
378bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        l[3] += pData[32*width]; l[3] += pData[48*width];
379bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        j++;
380bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        ver++;
381bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        firstPhase[0] += l[0] + l[1] + l[2] + l[3];
382bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        firstPhase[4] += l[0] + l[1] - l[2] - l[3];
383bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
384bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    if ((col != width - 1) && (pMb+1)->decoded)
385bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
386bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        R = HANTRO_TRUE;
387bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        pData = mbPos + 16;
388bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        r[0] = pData[0]; r[0] += pData[16*width];
389bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        r[0] += pData[32*width]; r[0] += pData[48*width];
390bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        pData += 64*width;
391bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        r[1] = pData[0]; r[1] += pData[16*width];
392bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        r[1] += pData[32*width]; r[1] += pData[48*width];
393bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        pData += 64*width;
394bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        r[2] = pData[0]; r[2] += pData[16*width];
395bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        r[2] += pData[32*width]; r[2] += pData[48*width];
396bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        pData += 64*width;
397bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        r[3] = pData[0]; r[3] += pData[16*width];
398bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        r[3] += pData[32*width]; r[3] += pData[48*width];
399bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        j++;
400bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        ver++;
401bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        firstPhase[0] += r[0] + r[1] + r[2] + r[3];
402bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        firstPhase[4] += r[0] + r[1] - r[2] - r[3];
403bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
404bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
405bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* at least one properly decoded neighbour available */
406bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    ASSERT(j);
407bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
408bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /*lint -esym(644,l,r,a,b) variable initialized above */
409bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    if (!hor && L && R)
410bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        firstPhase[1] = (l[0]+l[1]+l[2]+l[3]-r[0]-r[1]-r[2]-r[3]) >> 5;
411bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    else if (hor)
412bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        firstPhase[1] >>= (3+hor);
413bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
414bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    if (!ver && A && B)
415bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        firstPhase[4] = (a[0]+a[1]+a[2]+a[3]-b[0]-b[1]-b[2]-b[3]) >> 5;
416bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    else if (ver)
417bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        firstPhase[4] >>= (3+ver);
418bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
419bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    switch (j)
420bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
421bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        case 1:
422bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            firstPhase[0] >>= 4;
423bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            break;
424bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
425bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        case 2:
426bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            firstPhase[0] >>= 5;
427bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            break;
428bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
429bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        case 3:
430bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            /* approximate (firstPhase[0]*4/3)>>6 */
431bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            firstPhase[0] = (21 * firstPhase[0]) >> 10;
432bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            break;
433bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
434bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        default: /* 4 */
435bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            firstPhase[0] >>= 6;
436bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            break;
437bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
438bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
439bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
440bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
441bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    Transform(firstPhase);
442bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
443bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    for (i = 0, pData = data, pTmp = firstPhase; i < 256;)
444bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
445bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        tmp = pTmp[(i & 0xF)>>2];
446bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        /*lint -e734 CLIP1 macro results in value that fits into 8 bits */
447bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        *pData++ = CLIP1(tmp);
448bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        /*lint +e734 */
449bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
450bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        i++;
451bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        if (!(i & 0x3F))
452bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            pTmp += 4;
453bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
454bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
455bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* chroma components */
456bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    mbPos = currImage->data + width * height * 256 +
457bebc99d6fa433c04139294a5057f8439d772dbd9James Dong       row * 8 * width * 8 + col * 8;
458bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    for (comp = 0; comp < 2; comp++)
459bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
460bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
461bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        H264SwDecMemset(firstPhase, 0, sizeof(firstPhase));
462bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
463bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        /* counter for number of neighbours used */
464bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        j = 0;
465bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        hor = ver = 0;
466bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        if (A)
467bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        {
468bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            pData = mbPos - width*8;
469bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            a[0] = *pData++; a[0] += *pData++;
470bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            a[1] = *pData++; a[1] += *pData++;
471bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            a[2] = *pData++; a[2] += *pData++;
472bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            a[3] = *pData++; a[3] += *pData++;
473bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            j++;
474bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            hor++;
475bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            firstPhase[0] += a[0] + a[1] + a[2] + a[3];
476bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            firstPhase[1] += a[0] + a[1] - a[2] - a[3];
477bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        }
478bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        if (B)
479bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        {
480bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            pData = mbPos + 8*width*8;
481bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            b[0] = *pData++; b[0] += *pData++;
482bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            b[1] = *pData++; b[1] += *pData++;
483bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            b[2] = *pData++; b[2] += *pData++;
484bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            b[3] = *pData++; b[3] += *pData++;
485bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            j++;
486bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            hor++;
487bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            firstPhase[0] += b[0] + b[1] + b[2] + b[3];
488bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            firstPhase[1] += b[0] + b[1] - b[2] - b[3];
489bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        }
490bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        if (L)
491bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        {
492bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            pData = mbPos - 1;
493bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            l[0] = pData[0]; l[0] += pData[8*width];
494bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            pData += 16*width;
495bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            l[1] = pData[0]; l[1] += pData[8*width];
496bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            pData += 16*width;
497bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            l[2] = pData[0]; l[2] += pData[8*width];
498bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            pData += 16*width;
499bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            l[3] = pData[0]; l[3] += pData[8*width];
500bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            j++;
501bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            ver++;
502bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            firstPhase[0] += l[0] + l[1] + l[2] + l[3];
503bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            firstPhase[4] += l[0] + l[1] - l[2] - l[3];
504bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        }
505bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        if (R)
506bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        {
507bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            pData = mbPos + 8;
508bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            r[0] = pData[0]; r[0] += pData[8*width];
509bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            pData += 16*width;
510bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            r[1] = pData[0]; r[1] += pData[8*width];
511bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            pData += 16*width;
512bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            r[2] = pData[0]; r[2] += pData[8*width];
513bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            pData += 16*width;
514bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            r[3] = pData[0]; r[3] += pData[8*width];
515bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            j++;
516bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            ver++;
517bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            firstPhase[0] += r[0] + r[1] + r[2] + r[3];
518bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            firstPhase[4] += r[0] + r[1] - r[2] - r[3];
519bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        }
520bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        if (!hor && L && R)
521bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            firstPhase[1] = (l[0]+l[1]+l[2]+l[3]-r[0]-r[1]-r[2]-r[3]) >> 4;
522bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        else if (hor)
523bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            firstPhase[1] >>= (2+hor);
524bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
525bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        if (!ver && A && B)
526bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            firstPhase[4] = (a[0]+a[1]+a[2]+a[3]-b[0]-b[1]-b[2]-b[3]) >> 4;
527bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        else if (ver)
528bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            firstPhase[4] >>= (2+ver);
529bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
530bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        switch (j)
531bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        {
532bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            case 1:
533bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                firstPhase[0] >>= 3;
534bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                break;
535bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
536bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            case 2:
537bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                firstPhase[0] >>= 4;
538bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                break;
539bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
540bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            case 3:
541bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                /* approximate (firstPhase[0]*4/3)>>5 */
542bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                firstPhase[0] = (21 * firstPhase[0]) >> 9;
543bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                break;
544bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
545bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            default: /* 4 */
546bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                firstPhase[0] >>= 5;
547bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                break;
548bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
549bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        }
550bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
551bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        Transform(firstPhase);
552bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
553bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        pData = data + 256 + comp*64;
554bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        for (i = 0, pTmp = firstPhase; i < 64;)
555bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        {
556bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            tmp = pTmp[(i & 0x7)>>1];
557bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            /*lint -e734 CLIP1 macro results in value that fits into 8 bits */
558bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            *pData++ = CLIP1(tmp);
559bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            /*lint +e734 */
560bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
561bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            i++;
562bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            if (!(i & 0xF))
563bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                pTmp += 4;
564bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        }
565bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
566bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        /* increment pointers for cr */
567bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        mbPos += width * height * 64;
568bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
569bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
570bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    h264bsdWriteMacroblock(currImage, data);
571bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
572bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    return(HANTRO_OK);
573bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
574bebc99d6fa433c04139294a5057f8439d772dbd9James Dong}
575bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
576bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
577bebc99d6fa433c04139294a5057f8439d772dbd9James Dong/*------------------------------------------------------------------------------
578bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
579bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    Function name: Transform
580bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
581bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        Functional description:
582bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            Simplified transform, assuming that only dc component and lowest
583bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            horizontal and lowest vertical component may be non-zero
584bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
585bebc99d6fa433c04139294a5057f8439d772dbd9James Dong------------------------------------------------------------------------------*/
586bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
587bebc99d6fa433c04139294a5057f8439d772dbd9James Dongvoid Transform(i32 *data)
588bebc99d6fa433c04139294a5057f8439d772dbd9James Dong{
589bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
590bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    u32 col;
591bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    i32 tmp0, tmp1;
592bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
593bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    if (!data[1] && !data[4])
594bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
595bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        data[1]  = data[2]  = data[3]  = data[4]  = data[5]  =
596bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        data[6]  = data[7]  = data[8]  = data[9]  = data[10] =
597bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        data[11] = data[12] = data[13] = data[14] = data[15] = data[0];
598bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        return;
599bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
600bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* first horizontal transform for rows 0 and 1 */
601bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    tmp0 = data[0];
602bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    tmp1 = data[1];
603bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    data[0] = tmp0 + tmp1;
604bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    data[1] = tmp0 + (tmp1>>1);
605bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    data[2] = tmp0 - (tmp1>>1);
606bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    data[3] = tmp0 - tmp1;
607bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
608bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    tmp0 = data[4];
609bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    data[5] = tmp0;
610bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    data[6] = tmp0;
611bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    data[7] = tmp0;
612bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
613bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* then vertical transform */
614bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    for (col = 4; col--; data++)
615bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
616bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        tmp0 = data[0];
617bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        tmp1 = data[4];
618bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        data[0] = tmp0 + tmp1;
619bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        data[4] = tmp0 + (tmp1>>1);
620bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        data[8] = tmp0 - (tmp1>>1);
621bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        data[12] = tmp0 - tmp1;
622bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
623bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
624bebc99d6fa433c04139294a5057f8439d772dbd9James Dong}
625bebc99d6fa433c04139294a5057f8439d772dbd9James Dong/*lint +e702 */
626bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
627