recongob.c

来自「symbian 下的helix player源代码」· C语言 代码 · 共 1,202 行 · 第 1/4 页

C
1,202
字号
            mb->blkMvY[blk] = mb->mv_y;
        }
    }

    // Upper Left 16x16
    mb->x = 2 * saveX;
    mb->y = 2 * saveY;
    mb->mv_x = ReducedResMvComponent( mb->blkMvX[UPPER_LEFT_BLK] );
    mb->mv_y = ReducedResMvComponent( mb->blkMvY[UPPER_LEFT_BLK] );
    MotionComp263( mb, prevPic, pic);
    // Upper Right 16x16
    mb->x = 2 * saveX + 1;
    if (16 * mb->x < pic->y.nhor) {
        mb->mv_x = ReducedResMvComponent( mb->blkMvX[UPPER_RIGHT_BLK] );
        mb->mv_y = ReducedResMvComponent( mb->blkMvY[UPPER_RIGHT_BLK] );
        MotionComp263( mb, prevPic, pic);
    }

    mb->y = 2 * saveY + 1;
    if (16 * mb->y < pic->y.nvert) {
        // Lower Left 16x16
        mb->x = 2 * saveX;
        mb->mv_x = ReducedResMvComponent( mb->blkMvX[LOWER_LEFT_BLK] );
        mb->mv_y = ReducedResMvComponent( mb->blkMvY[LOWER_LEFT_BLK] );
        MotionComp263( mb, prevPic, pic);
        // Lower Right 16x16
        mb->x = 2 * saveX + 1;
        if (16 * mb->x < pic->y.nhor) {
            mb->mv_x = ReducedResMvComponent( mb->blkMvX[LOWER_RIGHT_BLK] );
            mb->mv_y = ReducedResMvComponent( mb->blkMvY[LOWER_RIGHT_BLK] );
            MotionComp263( mb, prevPic, pic);
        }
    }

    // Restore MTYPE, x/y position, and motion vector
    mb->mtype = saveType;
    mb->x = saveX;
    mb->y = saveY;
    mb->mv_x = saveMvX;
    mb->mv_y = saveMvY;
}


// Overlap32x32 - Do overlapped motion comp. for luma (Reduced-res. Update mode)
extern void Overlap32x32( MACROBLOCK_DESCR * mb,   // Describes block to be motion-compensated
                        PICTURE * prevPic,  // Describes previous picture used to form MC
                        PICTURE * pic,      // Output picture where MC block is placed
                        int     mbWidth,    // Macroblocks per row
                        int     mbOffset,   // Row offset; (mb-mbOffset) is neighbor on top
                        int     overlap[4]  // Returns YES or NO to indicate whether overlap
                                            // was done in each 8x8 subblock
                        )
{
    // Placeholder -- not yet implemented
    overlap[UPPER_LEFT_BLK] = NO;
    overlap[UPPER_RIGHT_BLK] = NO;
    overlap[LOWER_LEFT_BLK] = NO;
    overlap[LOWER_RIGHT_BLK] = NO;
}


// Fill32x32 - Fill Reduced-res. MB (32x32 block) with constant color
extern void Fill32x32( MACROBLOCK_DESCR * mb, PICTURE * pic, PIXEL value )
{
    // Get MB coordinates
    int saveX = mb->x;
    int saveY = mb->y;

    // Fill Upper Left 16x16
    mb->x = 2 * saveX;
    mb->y = 2 * saveY;
    fill_mb( mb, pic, value);
    // Fill Upper Right 16x16
    mb->x = 2 * saveX + 1;
    if (16 * mb->x < pic->y.nhor) {
        fill_mb( mb, pic, value);
    }

    mb->y = 2 * saveY + 1;
    if (16 * mb->y < pic->y.nvert) {
        // Fill Lower Left 16x16
        mb->x = 2 * saveX;
        fill_mb( mb, pic, value);
        // Fill Lower Right 16x16
        mb->x = 2 * saveX + 1;
        if (16 * mb->x < pic->y.nhor) {
            fill_mb( mb, pic, value);
        }
    }
    // Restore MB coordinates
    mb->x = saveX;
    mb->y = saveY;
}


// ReconReducedResMb - Reconstruct macroblock in Reduced-resolution Update mode
extern void ReconReducedResMb( MACROBLOCK_DESCR * mb,   // Macroblock to be reconstructed
                               PICTURE * pic,   // Input: motioncomp. prediction;
                                                // output: reconstr. picture
                               int intra,       // INTER block if zero, otherwise INTRA
                               PICTURE * tempPic// Use for temporary storage
                               )
{
    // Perform IDCT of prediction error; use "first half" of tempPic for temporary storage
    idct32x32( mb, tempPic, intra );
    // Interpolate prediction error, add to motioncomp. prediction and clip to [0,255]
    filtAddClip32x32( mb, pic, tempPic );
}


// idct32x32 - Perform IDCT for 32x32 macroblock (Reduced-res. update mode)
static void idct32x32( MACROBLOCK_DESCR * mb,   // Macroblock to be reconstructed
                       PICTURE * tempPic,       // Store 16-bit IDCT values here
                       int intra                // INTER block if zero, otherwise INTRA
                       )
{
    int     row, col, yHoffset, cHoffset, chromaPixels;
    S16     * pIdct;
    S16     * recon_tab;

    recon_tab = Recon[mb->quant - QUANT_MIN];

    // Reconstruct luminance
    // The PIXEL y[V][H] array is used as S16[V/2][H/2], i.e., only upper half is used
    col = 16 * mb->x;
    row = 16 * mb->y;
    yHoffset = tempPic->y.hoffset >> 1;
    pIdct = (S16 *)tempPic->y.ptr;
    pIdct += col + row * yHoffset;
    Idct2_s16( intra, mb->block[0].sym, mb->block[0].nsym, 
               pIdct + 0 + 0 * yHoffset,
               yHoffset, recon_tab );
    if (2 * col + 16 < tempPic->y.nhor) {
        Idct2_s16( intra, mb->block[1].sym, mb->block[1].nsym, 
                   pIdct + 8 + 0 * yHoffset,
                   yHoffset, recon_tab );
    }
    if (2 * row + 16  <  tempPic->y.nvert) {
        Idct2_s16( intra, mb->block[2].sym, mb->block[2].nsym, 
                   pIdct + 0 + 8 * yHoffset,
                   yHoffset, recon_tab );
        if (2 * col + 16 < tempPic->y.nhor) {
            Idct2_s16( intra, mb->block[3].sym, mb->block[3].nsym, 
                       pIdct + 8 + 8 * yHoffset,
                       yHoffset, recon_tab );
        }
    }

    // Reconstruct chrominance
    //  Ensure that we have memory for picture sizes that are
    //  not multiples of 32, i.e., odd number of macroblocks.  In that case, we will
    //  throw away 4 chroma pixels on the right and/or bottom after the IDCT.
    //  This routine assumes that the two VxH chroma arrays can be treated as one block of
    //  memory starting at tempPic->cb.ptr and of size (V+8)/16 * (H+8)/16 * 256 bytes.
    //  The current memory allocation done in initializePicture fulfills this as long
    //  as each chroma array is at least 16x16 (2x2 macroblocks).
    if (tempPic->color) {
        col = 8 * mb->x;
        row = 8 * mb->y;
        chromaPixels = 8 * ((tempPic->cb.nhor + 8) >> 4);
        cHoffset =  2 * chromaPixels;
        pIdct = (S16 *)tempPic->cb.ptr;
        pIdct += col + row * cHoffset;
        //printf("CB block \n");
        Idct2_s16( intra, mb->block[4].sym, mb->block[4].nsym, pIdct,
                        cHoffset, recon_tab );
        // CR array is placed "to the right" of CB array
        //printf("CR block \n");
        Idct2_s16( intra, mb->block[5].sym, mb->block[5].nsym, pIdct + chromaPixels,
                        cHoffset, recon_tab );
    }
}


// filtAddClip32x32 - Interpolate, add & clip 32x32 macroblock (Reduced-res. update mode)
static void filtAddClip32x32( MACROBLOCK_DESCR * mb,// Macroblock to be reconstructed
                              PICTURE * pic,    // Input: motion-comp prediction w/ filtered
                                                // intra borders; output: reconstr. picture
                              PICTURE * tempPic // 16-bit IDCT values
                              )
{
    int     row, col, offset, yHoffset, cHoffset, chromaPixels;
    int     hSize, vSize;
    PIXEL   * pixel0;
    S16     * pIdct;

    yHoffset = pic->y.hoffset >> 1;
    col = 16 * mb->x;
    row = 16 * mb->y;
    hSize = vSize = 16;
    if (2 * col + 16 >= pic->y.nhor)
        hSize = 8;
    if (2 * row + 16 >= pic->y.nvert)
        vSize = 8;

    // Interpolate, add, and clip
    pixel0 = pic->y.ptr + 2 * col + 2 * row * pic->y.hoffset;
    pIdct = (S16 *)tempPic->y.ptr;
    pIdct += col + row * yHoffset;
    filtAddClip( pixel0, pic->y.hoffset, pIdct, yHoffset, 8, 8 );
    if (hSize == 16)
        filtAddClip( pixel0 + 16, pic->y.hoffset, pIdct + 8, yHoffset, 8, 8 );
    if (vSize == 16) {
        pixel0 += 16 * pic->y.hoffset;
        pIdct += 8 * yHoffset;
        filtAddClip( pixel0, pic->y.hoffset, pIdct, yHoffset, 8, 8 );
        if (hSize == 16)
            filtAddClip( pixel0 + 16, pic->y.hoffset, pIdct + 8, yHoffset, 8, 8 );
    }
    if (pic->color) {
        chromaPixels = 8 * ((pic->cb.nhor + 8) >> 4);
        cHoffset =  2 * chromaPixels;
        offset = col + row * pic->cb.hoffset;
        pixel0 = pic->cb.ptr + offset;
        pIdct = (S16 *)tempPic->cb.ptr;
        pIdct += (col >> 1) + (row >> 1) * cHoffset;
        filtAddClip( pixel0, pic->cb.hoffset, pIdct,
                    cHoffset, hSize>>1, vSize>>1 );
        pixel0 = pic->cr.ptr + offset;
        filtAddClip( pixel0, pic->cr.hoffset, pIdct + chromaPixels,
                    cHoffset, hSize>>1, vSize>>1 );
    }
}


#define PIXEL_MIN       0
#define PIXEL_MAX       255
#define CLIPMARGIN      300
#define CLIPMIN         (PIXEL_MIN - CLIPMARGIN)
#define CLIPMAX         (PIXEL_MAX + CLIPMARGIN)
extern PIXEL   clip[(CLIPMAX-CLIPMIN+1)];

// filtAddClip - interpolate IDCT output (typically 8x8), add to prediction (typ. 16x16),
//  and clip.  Interpolation is only done within the block.
static void filtAddClip( PIXEL x[], int xdim,       // Output pixels
                         S16 idct_out[], int idim,  // Input IDCT values
                         int hSize, int vSize       // Input block size for IDCT values
                        )
{
    int     i, j, e;

    // Handle top border
    e = idct_out[0];
    x[0] = clip[ -CLIPMIN + e + x[0] ];
    for (j = 1; j < hSize; ++j) {
        e = (3 * idct_out[j-1] + 1 * idct_out[j] + 2) >> 2;
        x[2*j-1] = clip[ -CLIPMIN + e + x[2*j-1] ];
        e = (1 * idct_out[j-1] + 3 * idct_out[j] + 2) >> 2;
        x[2*j]   = clip[ -CLIPMIN + e + x[2*j] ];
    }
    e = idct_out[hSize-1];
    x[2*hSize-1] = clip[ -CLIPMIN + e + x[2*hSize-1] ];
    x += 2 * xdim;
    idct_out += idim;

    // Process 2*vSize-2 rows
    for (i = 1; i < vSize; ++i) {
        e = (3 * idct_out[-idim] + 1 * idct_out[0] + 2) >> 2;
        x[-xdim] = clip[ -CLIPMIN + e + x[-xdim] ];
        e = (1 * idct_out[-idim] + 3 * idct_out[0] + 2) >> 2;
        x[0]     = clip[ -CLIPMIN + e + x[0] ];
        for (j = 1; j < hSize; ++j) {
            e = (9 * idct_out[j-1-idim] + 3 * idct_out[j-idim]
               + 3 * idct_out[j-1]      + 1 * idct_out[j] + 8) >> 4;
            x[2*j-1 - xdim] = clip[ -CLIPMIN + e + x[2*j-1 - xdim] ];
            e = (3 * idct_out[j-1-idim] + 9 * idct_out[j-idim]
               + 1 * idct_out[j-1]      + 3 * idct_out[j] + 8) >> 4;
            x[2*j - xdim]   = clip[ -CLIPMIN + e + x[2*j - xdim] ];
            e = (3 * idct_out[j-1-idim] + 1 * idct_out[j-idim]
               + 9 * idct_out[j-1]      + 3 * idct_out[j] + 8) >> 4;
            x[2*j-1]        = clip[ -CLIPMIN + e + x[2*j-1] ];
            e = (1 * idct_out[j-1-idim] + 3 * idct_out[j-idim]
               + 3 * idct_out[j-1]      + 9 * idct_out[j] + 8) >> 4;
            x[2*j]          = clip[ -CLIPMIN + e + x[2*j] ];
        }
        e = (3 * idct_out[hSize-1-idim] + 1 * idct_out[hSize-1] + 2) >> 2;
        x[2*hSize-1-xdim] = clip[ -CLIPMIN + e + x[2*hSize-1-xdim] ];
        e = (1 * idct_out[hSize-1-idim] + 3 * idct_out[hSize-1] + 2) >> 2;
        x[2*hSize-1]      = clip[ -CLIPMIN + e + x[2*hSize-1] ];
        x += 2 * xdim;
        idct_out += idim;
    }
    // Handle bottom border
    x -= xdim;
    idct_out -= idim;
    e = idct_out[0];
    x[0] = clip[ -CLIPMIN + e + x[0] ];
    for (j = 1; j < hSize; ++j) {
        e = (3 * idct_out[j-1] + 1 * idct_out[j] + 2) >> 2;
        x[2*j-1] = clip[ -CLIPMIN + e + x[2*j-1] ];
        e = (1 * idct_out[j-1] + 3 * idct_out[j] + 2) >> 2;
        x[2*j]   = clip[ -CLIPMIN + e + x[2*j] ];
    }
    e = idct_out[hSize-1];
    x[2*hSize-1] = clip[ -CLIPMIN + e + x[2*hSize-1] ];
}

#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?