PageRenderTime 51ms CodeModel.GetById 16ms app.highlight 29ms RepoModel.GetById 1ms app.codeStats 0ms

/Show/avc/residual.cpp

http://github.com/mbebenita/Broadway
C++ | 523 lines | 402 code | 71 blank | 50 comment | 60 complexity | 891055b3fe548b11b0f2e7c351f0dbad MD5 | raw file
  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#include <string.h>
 20
 21#include "avcdec_lib.h"
 22#include "avcdec_bitstream.h"
 23
 24AVCDec_Status DecodeIntraPCM(AVCCommonObj *video, AVCDecBitstream *stream)
 25{
 26    AVCDec_Status status;
 27    int j;
 28    int mb_x, mb_y, offset1;
 29    uint8 *pDst;
 30    uint32 byte0, byte1;
 31    int pitch;
 32
 33    mb_x = video->mb_x;
 34    mb_y = video->mb_y;
 35
 36#ifdef USE_PRED_BLOCK
 37    pDst = video->pred_block + 84;
 38    pitch = 20;
 39#else
 40    offset1 = (mb_x << 4) + (mb_y << 4) * video->PicWidthInSamplesL;
 41    pDst = video->currPic->Sl + offset1;
 42    pitch = video->currPic->pitch;
 43#endif
 44
 45    /* at this point bitstream is byte-aligned */
 46    j = 16;
 47    while (j > 0)
 48    {
 49        status = BitstreamReadBits(stream, 8, (uint*) & byte0);
 50        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
 51        byte0 |= (byte1 << 8);
 52        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
 53        byte0 |= (byte1 << 16);
 54        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
 55        byte0 |= (byte1 << 24);
 56        *((uint32*)pDst) = byte0;
 57
 58        status = BitstreamReadBits(stream, 8, (uint*) & byte0);
 59        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
 60        byte0 |= (byte1 << 8);
 61        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
 62        byte0 |= (byte1 << 16);
 63        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
 64        byte0 |= (byte1 << 24);
 65        *((uint32*)(pDst + 4)) = byte0;
 66
 67        status = BitstreamReadBits(stream, 8, (uint*) & byte0);
 68        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
 69        byte0 |= (byte1 << 8);
 70        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
 71        byte0 |= (byte1 << 16);
 72        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
 73        byte0 |= (byte1 << 24);
 74        *((uint32*)(pDst + 8)) = byte0;
 75
 76        status = BitstreamReadBits(stream, 8, (uint*) & byte0);
 77        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
 78        byte0 |= (byte1 << 8);
 79        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
 80        byte0 |= (byte1 << 16);
 81        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
 82        byte0 |= (byte1 << 24);
 83        *((uint32*)(pDst + 12)) = byte0;
 84        j--;
 85        pDst += pitch;
 86
 87        if (status != AVCDEC_SUCCESS)  /* check only once per line */
 88            return status;
 89    }
 90
 91#ifdef USE_PRED_BLOCK
 92    pDst = video->pred_block + 452;
 93    pitch = 12;
 94#else
 95    offset1 = (offset1 >> 2) + (mb_x << 2);
 96    pDst = video->currPic->Scb + offset1;
 97    pitch >>= 1;
 98#endif
 99
100    j = 8;
101    while (j > 0)
102    {
103        status = BitstreamReadBits(stream, 8, (uint*) & byte0);
104        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
105        byte0 |= (byte1 << 8);
106        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
107        byte0 |= (byte1 << 16);
108        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
109        byte0 |= (byte1 << 24);
110        *((uint32*)pDst) = byte0;
111
112        status = BitstreamReadBits(stream, 8, (uint*) & byte0);
113        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
114        byte0 |= (byte1 << 8);
115        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
116        byte0 |= (byte1 << 16);
117        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
118        byte0 |= (byte1 << 24);
119        *((uint32*)(pDst + 4)) = byte0;
120
121        j--;
122        pDst += pitch;
123
124        if (status != AVCDEC_SUCCESS)  /* check only once per line */
125            return status;
126    }
127
128#ifdef USE_PRED_BLOCK
129    pDst = video->pred_block + 596;
130    pitch = 12;
131#else
132    pDst = video->currPic->Scr + offset1;
133#endif
134    j = 8;
135    while (j > 0)
136    {
137        status = BitstreamReadBits(stream, 8, (uint*) & byte0);
138        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
139        byte0 |= (byte1 << 8);
140        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
141        byte0 |= (byte1 << 16);
142        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
143        byte0 |= (byte1 << 24);
144        *((uint32*)pDst) = byte0;
145
146        status = BitstreamReadBits(stream, 8, (uint*) & byte0);
147        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
148        byte0 |= (byte1 << 8);
149        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
150        byte0 |= (byte1 << 16);
151        status = BitstreamReadBits(stream, 8, (uint*) & byte1);
152        byte0 |= (byte1 << 24);
153        *((uint32*)(pDst + 4)) = byte0;
154
155        j--;
156        pDst += pitch;
157
158        if (status != AVCDEC_SUCCESS)  /* check only once per line */
159            return status;
160    }
161
162#ifdef MB_BASED_DEBLOCK
163    SaveNeighborForIntraPred(video, offset1);
164#endif
165
166    return AVCDEC_SUCCESS;
167}
168
169
170
171/* see subclause 7.3.5.3 and readCBPandCoeffsFromNAL() in JM*/
172AVCDec_Status residual(AVCDecObject *decvid, AVCMacroblock *currMB)
173{
174    AVCCommonObj *video = decvid->common;
175    int16 *block;
176    int level[16], run[16], numcoeff; /* output from residual_block_cavlc */
177    int block_x, i, j, k, idx, iCbCr;
178    int mbPartIdx, subMbPartIdx, mbPartIdx_X, mbPartIdx_Y;
179    int nC, maxNumCoeff = 16;
180    int coeffNum, start_scan = 0;
181    uint8 *zz_scan;
182    int Rq, Qq;
183    uint32 cbp4x4 = 0;
184
185    /* in 8.5.4, it only says if it's field macroblock. */
186
187    zz_scan = (uint8*) ZZ_SCAN_BLOCK;
188
189
190    /* see 8.5.8 for the initialization of these values */
191    Qq = video->QPy_div_6;
192    Rq = video->QPy_mod_6;
193
194    memset(video->block, 0, sizeof(int16)*NUM_PIXELS_IN_MB);
195
196    if (currMB->mbMode == AVC_I16)
197    {
198        nC = predict_nnz(video, 0, 0);
199        decvid->residual_block(decvid, nC, 16, level, run, &numcoeff);
200        /* then performs zigzag and transform */
201        block = video->block;
202        coeffNum = -1;
203        for (i = numcoeff - 1; i >= 0; i--)
204        {
205            coeffNum += run[i] + 1;
206            if (coeffNum > 15)
207            {
208                return AVCDEC_FAIL;
209            }
210            idx = zz_scan[coeffNum] << 2;
211            /*          idx = ((idx>>2)<<6) + ((idx&3)<<2); */
212            block[idx] = level[i];
213        }
214
215        /* inverse transform on Intra16x16DCLevel */
216        if (numcoeff)
217        {
218            Intra16DCTrans(block, Qq, Rq);
219            cbp4x4 = 0xFFFF;
220        }
221        maxNumCoeff = 15;
222        start_scan = 1;
223    }
224
225    memset(currMB->nz_coeff, 0, sizeof(uint8)*24);
226
227    for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
228    {
229        mbPartIdx_X = (mbPartIdx & 1) << 1;
230        mbPartIdx_Y = mbPartIdx & -2;
231
232        if (currMB->CBP&(1 << mbPartIdx))
233        {
234            for (subMbPartIdx = 0; subMbPartIdx < 4; subMbPartIdx++)
235            {
236                i = mbPartIdx_X + (subMbPartIdx & 1);  // check this
237                j = mbPartIdx_Y + (subMbPartIdx >> 1);
238                block = video->block + (j << 6) + (i << 2);  //
239                nC = predict_nnz(video, i, j);
240                decvid->residual_block(decvid, nC, maxNumCoeff, level, run, &numcoeff);
241
242                /* convert to raster scan and quantize*/
243                /* Note: for P mb in SP slice and SI mb in SI slice,
244                 the quantization cannot be done here.
245                 block[idx] should be assigned with level[k].
246                itrans will be done after the prediction.
247                There will be transformation on the predicted value,
248                then addition with block[idx], then this quantization
249                and transform.*/
250
251                coeffNum = -1 + start_scan;
252                for (k = numcoeff - 1; k >= 0; k--)
253                {
254                    coeffNum += run[k] + 1;
255                    if (coeffNum > 15)
256                    {
257                        return AVCDEC_FAIL;
258                    }
259                    idx = zz_scan[coeffNum];
260                    block[idx] = (level[k] * dequant_coefres[Rq][coeffNum]) << Qq ;
261                }
262
263                currMB->nz_coeff[(j<<2)+i] = numcoeff;
264                if (numcoeff)
265                {
266                    cbp4x4 |= (1 << ((j << 2) + i));
267                }
268            }
269        }
270    }
271
272    Qq = video->QPc_div_6;
273    Rq = video->QPc_mod_6;
274
275    if (currMB->CBP & (3 << 4)) /* chroma DC residual present */
276    {
277        for (iCbCr = 0; iCbCr < 2; iCbCr++)
278        {
279            decvid->residual_block(decvid, -1, 4, level, run, &numcoeff);
280            block = video->block + 256 + (iCbCr << 3);
281            coeffNum = -1;
282            for (i = numcoeff - 1; i >= 0; i--)
283            {
284                coeffNum += run[i] + 1;
285                if (coeffNum > 3)
286                {
287                    return AVCDEC_FAIL;
288                }
289                block[(coeffNum>>1)*64 + (coeffNum&1)*4] = level[i];
290            }
291            /* inverse transform on chroma DC */
292            /* for P in SP and SI in SI, this function can't be done here,
293            must do prediction transform/quant first. */
294            if (numcoeff)
295            {
296                ChromaDCTrans(block, Qq, Rq);
297                cbp4x4 |= (iCbCr ? 0xcc0000 : 0x330000);
298            }
299        }
300    }
301
302    if (currMB->CBP & (2 << 4))
303    {
304        for (block_x = 0; block_x < 4; block_x += 2) /* for iCbCr */
305        {
306            for (j = 4; j < 6; j++)  /* for each block inside Cb or Cr */
307            {
308                for (i = block_x; i < block_x + 2; i++)
309                {
310
311                    block = video->block + (j << 6) + (i << 2);
312
313                    nC = predict_nnz_chroma(video, i, j);
314                    decvid->residual_block(decvid, nC, 15, level, run, &numcoeff);
315
316                    /* convert to raster scan and quantize */
317                    /* for P MB in SP slice and SI MB in SI slice,
318                       the dequant and transform cannot be done here.
319                       It needs the prediction values. */
320                    coeffNum = 0;
321                    for (k = numcoeff - 1; k >= 0; k--)
322                    {
323                        coeffNum += run[k] + 1;
324                        if (coeffNum > 15)
325                        {
326                            return AVCDEC_FAIL;
327                        }
328                        idx = zz_scan[coeffNum];
329                        block[idx] = (level[k] * dequant_coefres[Rq][coeffNum]) << Qq;
330                    }
331
332
333                    /* then transform */
334                    //              itrans(block); /* transform */
335                    currMB->nz_coeff[(j<<2)+i] = numcoeff;    //
336                    if (numcoeff)
337                    {
338                        cbp4x4 |= (1 << ((j << 2) + i));
339                    }
340                }
341
342            }
343        }
344    }
345
346    video->cbp4x4 = cbp4x4;
347
348    return AVCDEC_SUCCESS;
349}
350
351/* see subclause 7.3.5.3.1 and 9.2 and readCoeff4x4_CAVLC() in JM */
352AVCDec_Status residual_block_cavlc(AVCDecObject *decvid, int nC, int maxNumCoeff,
353                                   int *level, int *run, int *numcoeff)
354{
355    int i, j;
356    int TrailingOnes, TotalCoeff;
357    AVCDecBitstream *stream = decvid->bitstream;
358    int suffixLength;
359    uint trailing_ones_sign_flag, level_prefix, level_suffix;
360    int levelCode, levelSuffixSize, zerosLeft;
361    int run_before;
362
363
364    if (nC >= 0)
365    {
366        ce_TotalCoeffTrailingOnes(stream, &TrailingOnes, &TotalCoeff, nC);
367    }
368    else
369    {
370        ce_TotalCoeffTrailingOnesChromaDC(stream, &TrailingOnes, &TotalCoeff);
371    }
372
373    *numcoeff = TotalCoeff;
374
375    /* This part is done quite differently in ReadCoef4x4_CAVLC() */
376    if (TotalCoeff == 0)
377    {
378        return AVCDEC_SUCCESS;
379    }
380
381    if (TrailingOnes) /* keep reading the sign of those trailing ones */
382    {
383        /* instead of reading one bit at a time, read the whole thing at once */
384        BitstreamReadBits(stream, TrailingOnes, &trailing_ones_sign_flag);
385        trailing_ones_sign_flag <<= 1;
386        for (i = 0; i < TrailingOnes; i++)
387        {
388            level[i] = 1 - ((trailing_ones_sign_flag >> (TrailingOnes - i - 1)) & 2);
389        }
390    }
391
392    i = TrailingOnes;
393    suffixLength = 1;
394    if (TotalCoeff > TrailingOnes)
395    {
396        ce_LevelPrefix(stream, &level_prefix);
397        if (TotalCoeff < 11 || TrailingOnes == 3)
398        {
399            if (level_prefix < 14)
400            {
401//              levelSuffixSize = 0;
402                levelCode = level_prefix;
403            }
404            else if (level_prefix == 14)
405            {
406//              levelSuffixSize = 4;
407                BitstreamReadBits(stream, 4, &level_suffix);
408                levelCode = 14 + level_suffix;
409            }
410            else /* if (level_prefix == 15) */
411            {
412//              levelSuffixSize = 12;
413                BitstreamReadBits(stream, 12, &level_suffix);
414                levelCode = 30 + level_suffix;
415            }
416        }
417        else
418        {
419            /*              suffixLength = 1; */
420            if (level_prefix < 15)
421            {
422                levelSuffixSize = suffixLength;
423            }
424            else
425            {
426                levelSuffixSize = 12;
427            }
428            BitstreamReadBits(stream, levelSuffixSize, &level_suffix);
429
430            levelCode = (level_prefix << 1) + level_suffix;
431        }
432
433        if (TrailingOnes < 3)
434        {
435            levelCode += 2;
436        }
437
438        level[i] = (levelCode + 2) >> 1;
439        if (level[i] > 3)
440        {
441            suffixLength = 2;
442        }
443
444        if (levelCode & 1)
445        {
446            level[i] = -level[i];
447        }
448        i++;
449
450    }
451
452    for (j = TotalCoeff - i; j > 0 ; j--)
453    {
454        ce_LevelPrefix(stream, &level_prefix);
455        if (level_prefix < 15)
456        {
457            levelSuffixSize = suffixLength;
458        }
459        else
460        {
461            levelSuffixSize = 12;
462        }
463        BitstreamReadBits(stream, levelSuffixSize, &level_suffix);
464
465        levelCode = (level_prefix << suffixLength) + level_suffix;
466        level[i] = (levelCode >> 1) + 1;
467        if (level[i] > (3 << (suffixLength - 1)) && suffixLength < 6)
468        {
469            suffixLength++;
470        }
471        if (levelCode & 1)
472        {
473            level[i] = -level[i];
474        }
475        i++;
476    }
477
478
479    if (TotalCoeff < maxNumCoeff)
480    {
481        if (nC >= 0)
482        {
483            ce_TotalZeros(stream, &zerosLeft, TotalCoeff);
484        }
485        else
486        {
487            ce_TotalZerosChromaDC(stream, &zerosLeft, TotalCoeff);
488        }
489    }
490    else
491    {
492        zerosLeft = 0;
493    }
494
495    for (i = 0; i < TotalCoeff - 1; i++)
496    {
497        if (zerosLeft > 0)
498        {
499            ce_RunBefore(stream, &run_before, zerosLeft);
500            run[i] = run_before;
501        }
502        else
503        {
504            run[i] = 0;
505            zerosLeft = 0; // could be negative under error conditions
506        }
507
508        zerosLeft = zerosLeft - run[i];
509    }
510
511    if (zerosLeft < 0)
512    {
513        zerosLeft = 0;
514//      return AVCDEC_FAIL;
515    }
516
517    run[TotalCoeff-1] = zerosLeft;
518
519    /* leave the inverse zigzag scan part for the caller */
520
521
522    return AVCDEC_SUCCESS;
523}