recongob.c
来自「symbian 下的helix player源代码」· C语言 代码 · 共 1,202 行 · 第 1/4 页
C
1,202 行
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 picture
extern 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);
}
}
// ReconIntra
extern 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 + =
减小字号Ctrl + -
显示快捷键?