📄 recongob.c
字号:
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 colorextern 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 modeextern 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -