📄 recongob.c
字号:
Fill32x32( &mb[mbnum], pic, GRAY); intra = NO; ReconReducedResMb( &mb[mbnum], pic, intra, tempPic ); state->actComp += 4; // Increment computation measure } else { gray_mb( &mb[mbnum], pic); ReconInter( &mb[mbnum], pic, CLEAN); ++state->actComp; // Increment computation measure if (reconBflag) { // Reconstruct B frame gray_mb( &mb[mbnum], Bpic ); reconBframe( &mb[mbnum], Bpic ); } } break; case MTYPE263_INTRA: case MTYPE263_INTRA_Q: case MTYPE_INTRA: case MTYPE_INTRA_MQUANT: if (reducedResUpdate) { Fill32x32( &mb[mbnum], pic, 0 ); intra = YES; ReconReducedResMb( &mb[mbnum], pic, intra, tempPic ); state->actComp += 4; // Increment computation measure } else { if(advancedIntraMode) ReconAdvancedIntra( &mb[mbnum], pic, CLEAN ); else ReconIntra( &mb[mbnum], pic, CLEAN ); ++state->actComp; // Increment computation measure if (reconBflag) { // Reconstruct B frame gray_mb( &mb[mbnum], Bpic ); reconBframe( &mb[mbnum], Bpic ); } } break; default: CHECKSYM( sprintf( msg, "PROGRAM ERROR: MTYPE = %d in recon_gob", mb[mbnum].mtype); /* Flawfinder: ignore */ H261ErrMsg( msg ); state->i = 0; // Indicate that we finished without timing out return( H261_ERROR ); ) break; } i++, mbnum++; col++; if (col == gob->mb_width) { // Start on next row of macroblocks mbnum += gob->mb_offset - gob->mb_width; col = 0; } if (maxComp > 0 && state->actComp >= maxComp) { // We have timed out: save state and return state->i = i; state->mbnum= mbnum; state->col = col; return H261_ERROR; } } state->i = 0; // Indicate that we finished without timing out return (H261_ERROR); }}// Reconstruct GOB by repeating previous pictureextern int ConcealGob( GOB_DESCR * gob, MACROBLOCK_DESCR mb[], int reducedResUpdate, PICTURE * prev_pic, PICTURE * pic ){ int mbnum, i, col; i = 0; mbnum = gob->first_col + gob->first_row * gob->mb_offset; col = gob->first_col; // Used to check when we reach end of line if (pic->y.nhor == prev_pic->y.nhor && pic->y.nvert == prev_pic->y.nvert) { // Size of prev_pic is OK; use it for new picture while (i < gob->num_mb) { mb[mbnum].mv_x = 0; mb[mbnum].mv_y = 0; if (reducedResUpdate) { MotionComp32x32( &mb[mbnum], prev_pic, pic); } else { MotionComp( &mb[mbnum], prev_pic, pic); } i++, mbnum++; col++; if (col == gob->mb_width) { // Start on next row of macroblocks mbnum += gob->mb_offset - gob->mb_width; col = 0; } } return (OK); } else { // Paint gray while (i < gob->num_mb) { if (reducedResUpdate) { Fill32x32( &mb[mbnum], pic, GRAY); } else { gray_mb( &mb[mbnum], pic); } i++, mbnum++; col++; if (col == gob->mb_width) { // Start on next row of macroblocks mbnum += gob->mb_offset - gob->mb_width; col = 0; } } return (H261_ERROR); }}// ReconIntraextern void ReconIntra( MACROBLOCK_DESCR * mb, PICTURE * pic, int clean){ int row, col, offset; PIXEL * pixel0; S16 * recon_tab; recon_tab = Recon[mb->quant - QUANT_MIN]; col = 16 * mb->x; row = 16 * mb->y; /*{ int isym; printf("ReconIntra: x = %d y = %d\n", col, row); printf("nsym = %d %d %d %d %d %d \n", mb->block[0].nsym, mb->block[1].nsym, mb->block[2].nsym, mb->block[3].nsym, mb->block[4].nsym, mb->block[5].nsym); printf("Symbol number to print: "); scanf("%d", &isym); while (isym > 0) { printf("Luma 1: "); printsym( *(mb->block[0].sym + isym - 1) ); printf("\n"); printf("Luma 2: "); printsym( *(mb->block[1].sym + isym - 1) ); printf("\n"); printf("Luma 3: "); printsym( *(mb->block[2].sym + isym - 1) ); printf("\n"); printf("Luma 4: "); printsym( *(mb->block[3].sym + isym - 1) ); printf("\n"); printf("Symbol number to print: "); scanf("%d", &isym); } }*/ pixel0 = pic->y.ptr + col + row * pic->y.hoffset; //printf("Luma block 1 \n"); Idct2( mb->block[0].sym, mb->block[0].nsym, pixel0, pic->y.hoffset, recon_tab, clean); //printf("Luma block 2 \n"); Idct2( mb->block[1].sym, mb->block[1].nsym, pixel0 + 8, pic->y.hoffset, recon_tab, clean); //printf("Luma block 3 \n"); Idct2( mb->block[2].sym, mb->block[2].nsym, pixel0 + 8 * pic->y.hoffset, pic->y.hoffset, recon_tab, clean); //printf("Luma block 4 \n"); Idct2( mb->block[3].sym, mb->block[3].nsym, pixel0 + 8 + 8 * pic->y.hoffset, pic->y.hoffset, recon_tab, clean); if (pic->color) { // Assuming same offset for Cr and Cb col = 8 * mb->x; row = 8 * mb->y; offset = col + row * pic->cb.hoffset; pixel0 = pic->cb.ptr + offset; //printf("CB block \n"); Idct2( mb->block[4].sym, mb->block[4].nsym, pixel0, pic->cb.hoffset, recon_tab, clean); pixel0 = pic->cr.ptr + offset; //printf("CR block \n"); Idct2( mb->block[5].sym, mb->block[5].nsym, pixel0, pic->cr.hoffset, recon_tab, clean); } return;}#ifdef DO_H263_PLUS#define MAX_MACROBLKS_PER_ROW (88) /* Up to 16CIF (1408 pixels/line) */#define UPPER_LUMA_BLOCK_CACHE_LENGTH (2 * MAX_MACROBLKS_PER_ROW)#define UPPER_CHROMA_BLOCK_CACHE_LENGTH (MAX_MACROBLKS_PER_ROW)// Storage for the first rows of the lower 8x8 blocks of the intra macroblocks in the previous GOB.// Refer to these for appropriate predictions. For right now we make this static// data, but should really allocate it on the heap only if advanced intra is being// used?static S8 upperLumaBlockCache[UPPER_LUMA_BLOCK_CACHE_LENGTH][8]; // allocated for CIF video!static S8 upperCrBlockCache[UPPER_CHROMA_BLOCK_CACHE_LENGTH][8]; // allocated for CIF video!static S8 upperCbBlockCache[UPPER_CHROMA_BLOCK_CACHE_LENGTH][8]; // allocated for CIF video!// Storage for the first columns of the 8x8 blocks of the most recent intra macroblock.// Refer to these for appropriate predictions.static S8 leftLumaBlockCache[4][8];static S8 leftCrBlockCache[1][8];static S8 leftCbBlockCache[1][8];static U8 upperDCLumaBlockCache[UPPER_LUMA_BLOCK_CACHE_LENGTH][1];static U8 upperDCCrBlockCache[UPPER_CHROMA_BLOCK_CACHE_LENGTH][1];static U8 upperDCCbBlockCache[UPPER_CHROMA_BLOCK_CACHE_LENGTH][1];static U8 leftDCLumaBlockCache[4][1];static U8 leftDCCrBlockCache[1];static U8 leftDCCbBlockCache[1];static void InitializeLeftCache(int qp){ int i; for(i=0; i<4; i++) { //leftDCLumaBlockCache[i][0] = ( U8 )128; // MPEG4 style boundary conditions leftDCLumaBlockCache[i][0] = ( U8 )(512/qp); // H.263+ style boundary conditions memset(&leftLumaBlockCache[i][1], 0, 7); } leftDCCrBlockCache[0] = ( U8 )(512/qp); // H.263+ style boundary conditions memset(&leftCrBlockCache[0][1], 0, 7); leftDCCbBlockCache[0] = ( U8 )(512/qp); // H.263+ style boundary conditions memset(&leftCbBlockCache[0][1], 0, 7);}static void InitializeUpperCache(int qp, int i){ //upperDCLumaBlockCache[2*i][0] = ( U8 )128; // MPEG4 style boundary conditions upperDCLumaBlockCache[2*i][0] = ( U8 )(512/qp); // H.263+ style boundary conditions memset(&upperLumaBlockCache[2*i][1], 0, 7); //upperDCLumaBlockCache[2*i+1][0] = ( U8 )128; // MPEG4 style boundary conditions upperDCLumaBlockCache[2*i+1][0] = ( U8 )(512/qp); // H.263+ style boundary conditions memset(&upperLumaBlockCache[2*i+1][1], 0, 7); //upperDCCrBlockCache[i][0] = ( U8 )128; // MPEG4 style boundary conditions upperDCCrBlockCache[i][0] = ( U8 )(512/qp); // H.263+ style boundary conditions memset(&upperCrBlockCache[i][1], 0, 7); //upperDCCbBlockCache[i][0] = ( U8 )128; // MPEG4 style boundary conditions upperDCCbBlockCache[i][0] = ( U8 )(512/qp); // H.263+ style boundary conditions memset(&upperCbBlockCache[i][1], 0, 7);}#define INTRA(mb) (((mb).mtype >= MTYPE263_INTRA_MIN && (mb).mtype <= MTYPE263_INTRA_MAX) ? 1:0)extern void ReconAdvancedIntra( MACROBLOCK_DESCR * mb, PICTURE * pic, int clean){ int row, col, offset; PIXEL * pixel0; S16 * recon_tab; int predtype = mb->intra_mode; int fixedDC = mb->quant<8; int numhor=pic->y.nhor>>4; // number of mb per row // Ensure that we are not scribbling outside the allocated cache if (mb->x >= MAX_MACROBLKS_PER_ROW) return; // Reinitialize predictors if we're on a new row or if one of our abutting macroblocks // isn't intra if(mb->x == 0 || !INTRA(mb[-1])) { InitializeLeftCache(fixedDC ? 4 : mb->quant); } if(mb->y == 0 || !INTRA(mb[-numhor])) { InitializeUpperCache(fixedDC ? 4 : mb->quant, mb->x); } recon_tab = Recon[mb->quant - QUANT_MIN]; col = 16 * mb->x; row = 16 * mb->y; /*{ int isym; printf("ReconAdvancedIntra: x = %d y = %d\n", col, row); printf("nsym = %d %d %d %d %d %d \n", mb->block[0].nsym, mb->block[1].nsym, mb->block[2].nsym, mb->block[3].nsym, mb->block[4].nsym, mb->block[5].nsym); printf("Symbol number to print: "); scanf("%d", &isym); while (isym > 0) { printf("Luma 1: "); printsym( *(mb->block[0].sym + isym - 1) ); printf("\n"); printf("Luma 2: "); printsym( *(mb->block[1].sym + isym - 1) ); printf("\n"); printf("Luma 3: "); printsym( *(mb->block[2].sym + isym - 1) ); printf("\n"); printf("Luma 4: "); printsym( *(mb->block[3].sym + isym - 1) ); printf("\n"); printf("Symbol number to print: "); scanf("%d", &isym); } }*/ pixel0 = pic->y.ptr + col + row * pic->y.hoffset; //printf("Luma block 1 \n"); Idct2AdvancedIntra( mb->block[0].sym, mb->block[0].nsym, pixel0, pic->y.hoffset, recon_tab, upperDCLumaBlockCache[2*mb->x][0], upperLumaBlockCache[2*mb->x], // DC and AC pred for row upperDCLumaBlockCache[2*mb->x],upperLumaBlockCache[2*mb->x], // DC and AC store for row leftDCLumaBlockCache[1][0], leftLumaBlockCache[1], // DC and AC pred for column leftDCLumaBlockCache[0], leftLumaBlockCache[0], // DC and AC store for column predtype, fixedDC, mb->x==0, mb->y==0); // can be on left or upper boundary //printf("Luma block 2 \n"); Idct2AdvancedIntra( mb->block[1].sym, mb->block[1].nsym, pixel0 + 8, pic->y.hoffset, recon_tab, upperDCLumaBlockCache[2*mb->x+1][0], upperLumaBlockCache[2*mb->x+1], // DC and AC pred for row upperDCLumaBlockCache[2*mb->x+1],upperLumaBlockCache[2*mb->x+1], // DC and AC store for row leftDCLumaBlockCache[0][0], leftLumaBlockCache[0], // DC and AC pred for column leftDCLumaBlockCache[1], leftLumaBlockCache[1], // DC and AC store for column predtype, fixedDC, FALSE, mb->y==0); // can only be on upper boudary //printf("Luma block 3 \n"); Idct2AdvancedIntra( mb->block[2].sym, mb->block[2].nsym, pixel0 + 8 * pic->y.hoffset, pic->y.hoffset, recon_tab,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -