📄 macroblock.c
字号:
else
{
currSE->context = 1; // for choosing context model
currSE->type = SE_LUM_DC_INTER;
}
}
else
{
if (img->imod == INTRA_MB_OLD || img->imod == INTRA_MB_NEW)
{
currSE->context = 2; // for choosing context model
currSE->type = SE_LUM_AC_INTRA;
}
else
{
currSE->context = 1; // for choosing context model
currSE->type = SE_LUM_AC_INTER;
}
}
/* choose the appropriate data partition */
if (img->type != B_IMG)
dataPart = &(currSlice->partArr[partMap[currSE->type]]);
else
dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
dataPart->writeSyntaxElement (currSE, dataPart);
bitCount[BITS_COEFF_Y_MB]+=currSE->len;
no_bits +=currSE->len;
#if TRACE
sprintf(currSE->tracestring, "Luma sng(%2d) level =%3d run =%2d", k, level,run);
#endif
/* proceed to next SE */
currSE++;
currMB->currSEnr++;
if (level!=0 && filtering)
{
loopb[img->block_x+i+1][img->block_y+j+1]=max(loopb[img->block_x+i+1][img->block_y+j+1],2);
loopb[img->block_x+i ][img->block_y+j+1]=max(loopb[img->block_x+i ][img->block_y+j+1],1);
loopb[img->block_x+i+1][img->block_y+j ]=max(loopb[img->block_x+i+1][img->block_y+j ],1);
loopb[img->block_x+i+2][img->block_y+j+1]=max(loopb[img->block_x+i+2][img->block_y+j+1],1);
loopb[img->block_x+i+1][img->block_y+j+2]=max(loopb[img->block_x+i+1][img->block_y+j+2],1);
}
}
}
return no_bits;
}
int
writeMB_bits_for_16x16_luma ()
{
int no_bits = 0;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
SyntaxElement *currSE = &img->MB_SyntaxElements[currMB->currSEnr];
int *bitCount = currMB->bitcounter;
Slice *currSlice = img->currentSlice;
DataPartition *dataPart;
int *partMap = assignSE2partition[input->partition_mode];
int level, run;
int i, j, k, mb_x, mb_y;
/* DC coeffs */
level=1; /* get inside loop */
for (k=0;k<=16 && level !=0;k++)
{
level = currSE->value1 = img->cof[0][0][k][0][1]; // level
run = currSE->value2 = img->cof[0][0][k][1][1]; // run
if (input->symbol_mode == UVLC)
currSE->mapping = levrun_linfo_inter;
else
{
currSE->context = 3; // for choosing context model
currSE->writing = writeRunLevel2Buffer_CABAC;
}
currSE->type = SE_LUM_DC_INTRA; /* element is of type DC */
/* choose the appropriate data partition */
if (img->type != B_IMG)
dataPart = &(currSlice->partArr[partMap[currSE->type]]);
else
dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
dataPart->writeSyntaxElement (currSE, dataPart);
bitCount[BITS_COEFF_Y_MB]+=currSE->len;
no_bits +=currSE->len;
#if TRACE
sprintf(currSE->tracestring, "DC luma 16x16 sng(%2d) level =%3d run =%2d", k, level, run);
#endif
/* proceed to next SE */
currSE++;
currMB->currSEnr++;
}
/* AC coeffs */
if (img->kac==1)
{
for (mb_y=0; mb_y < 4; mb_y += 2)
{
for (mb_x=0; mb_x < 4; mb_x += 2)
{
for (j=mb_y; j < mb_y+2; j++)
{
for (i=mb_x; i < mb_x+2; i++)
{
level=1; /* get inside loop */
for (k=0;k<16 && level !=0;k++)
{
level = currSE->value1 = img->cof[i][j][k][0][SINGLE_SCAN]; // level
run = currSE->value2 = img->cof[i][j][k][1][SINGLE_SCAN]; // run
if (input->symbol_mode == UVLC)
currSE->mapping = levrun_linfo_inter;
else
{
currSE->context = 4; // for choosing context model
currSE->writing = writeRunLevel2Buffer_CABAC;
}
currSE->type = SE_LUM_AC_INTRA; /* element is of type AC */
/* choose the appropriate data partition */
if (img->type != B_IMG)
dataPart = &(currSlice->partArr[partMap[currSE->type]]);
else
dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
dataPart->writeSyntaxElement (currSE, dataPart);
bitCount[BITS_COEFF_Y_MB]+=currSE->len;
no_bits +=currSE->len;
#if TRACE
sprintf(currSE->tracestring, "AC luma 16x16 sng(%2d) level =%3d run =%2d", k, level, run);
#endif
/* proceed to next SE */
currSE++;
currMB->currSEnr++;
}
}
}
}
}
}
return no_bits;
}
int
writeMB_bits_for_DC_chroma (int filtering)
{
int no_bits = 0;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
SyntaxElement *currSE = &img->MB_SyntaxElements[currMB->currSEnr];
int *bitCount = currMB->bitcounter;
Slice *currSlice = img->currentSlice;
DataPartition *dataPart;
int *partMap = assignSE2partition[input->partition_mode];
int m2 = img->mb_x << 1;
int jg2 = img->mb_y << 1;
int cbp = img->mb_data [img->current_mb_nr].cbp;
int level, run;
int i, j, k, uv;
if (cbp > 15) /* check if any chroma bits in coded block pattern is set */
{
for (uv=0; uv < 2; uv++)
{
level=1;
for (k=0; k < 5 && level != 0; ++k)
{
level = currSE->value1 = img->cofu[k][0][uv]; // level
run = currSE->value2 = img->cofu[k][1][uv]; // run
if (input->symbol_mode == UVLC)
currSE->mapping = levrun_linfo_c2x2;
else
currSE->writing = writeRunLevel2Buffer_CABAC;
if (img->imod == INTRA_MB_OLD || img->imod == INTRA_MB_NEW)
{
currSE->context = 6; // for choosing context model
currSE->type = SE_CHR_DC_INTRA;
}
else
{
currSE->context = 5; // for choosing context model
currSE->type = SE_CHR_DC_INTER;
}
/* choose the appropriate data partition */
if (img->type != B_IMG)
dataPart = &(currSlice->partArr[partMap[currSE->type]]);
else
dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
dataPart->writeSyntaxElement (currSE, dataPart);
bitCount[BITS_COEFF_UV_MB]+=currSE->len;
no_bits +=currSE->len;
#if TRACE
sprintf(currSE->tracestring, "2x2 DC Chroma %2d: level =%3d run =%2d",k, level, run);
#endif
/* proceed to next SE */
currSE++;
currMB->currSEnr++;
if (level != 0 && filtering)/* fix from ver 4.1 */
{
for (j=0;j<2;j++)
{
for (i=0;i<2;i++)
{
loopc[m2+i+1][jg2+j+1]=max(loopc[m2+i+1][jg2+j+1],2);
}
}
for (i=0;i<2;i++)
{
loopc[m2+i+1][jg2 ]=max(loopc[m2+i+1][jg2 ],1);
loopc[m2+i+1][jg2+3 ]=max(loopc[m2+i+1][jg2+3 ],1);
loopc[m2 ][jg2+i+1]=max(loopc[m2 ][jg2+i+1],1);
loopc[m2+3 ][jg2+i+1]=max(loopc[m2+3 ][jg2+i+1],1);
}
}
}
}
}
return no_bits;
}
int
writeMB_bits_for_AC_chroma (int filtering)
{
int no_bits = 0;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
SyntaxElement *currSE = &img->MB_SyntaxElements[currMB->currSEnr];
int *bitCount = currMB->bitcounter;
Slice *currSlice = img->currentSlice;
DataPartition *dataPart;
int *partMap = assignSE2partition[input->partition_mode];
int m2 = img->mb_x << 1;
int jg2 = img->mb_y << 1;
int cbp = img->mb_data [img->current_mb_nr].cbp;
int level, run;
int i, j, k, mb_x, mb_y, i1, ii, j1, jj;
if (cbp >> 4 == 2) /* check if chroma bits in coded block pattern = 10b */
{
for (mb_y=4; mb_y < 6; mb_y += 2)
{
for (mb_x=0; mb_x < 4; mb_x += 2)
{
for (j=mb_y; j < mb_y+2; j++)
{
jj=j/2;
j1=j-4;
for (i=mb_x; i < mb_x+2; i++)
{
ii=i/2;
i1=i%2;
level=1;
for (k=0; k < 16 && level != 0; k++)
{
level = currSE->value1 = img->cof[i][j][k][0][0]; // level
run = currSE->value2 = img->cof[i][j][k][1][0]; // run
if (input->symbol_mode == UVLC)
currSE->mapping = levrun_linfo_inter;
else
currSE->writing = writeRunLevel2Buffer_CABAC;
if (img->imod == INTRA_MB_OLD || img->imod == INTRA_MB_NEW)
{
currSE->context = 8; // for choosing context model
currSE->type = SE_CHR_AC_INTRA;
}
else
{
currSE->context = 7; // for choosing context model
currSE->type = SE_CHR_AC_INTER;
}
/* choose the appropriate data partition */
if (img->type != B_IMG)
dataPart = &(currSlice->partArr[partMap[currSE->type]]);
else
dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
dataPart->writeSyntaxElement (currSE, dataPart);
bitCount[BITS_COEFF_UV_MB]+=currSE->len;
no_bits +=currSE->len;
#if TRACE
sprintf(currSE->tracestring, "AC Chroma %2d: level =%3d run =%2d",k, level, run);
#endif
/* proceed to next SE */
currSE++;
currMB->currSEnr++;
if (level != 0 && filtering)
{
loopc[m2+i1+1][jg2+j1+1]=max(loopc[m2+i1+1][jg2+j1+1],2);
loopc[m2+i1 ][jg2+j1+1]=max(loopc[m2+i1 ][jg2+j1+1],1);
loopc[m2+i1+1][jg2+j1 ]=max(loopc[m2+i1+1][jg2+j1 ],1);
loopc[m2+i1+2][jg2+j1+1]=max(loopc[m2+i1+2][jg2+j1+1],1);
loopc[m2+i1+1][jg2+j1+2]=max(loopc[m2+i1+1][jg2+j1+2],1);
}
}
}
}
}
}
}
return no_bits;
}
/************************************************************************
*
* Routine : find_sad2()
*
* Description: Find best 16x16 based intra mode
*
*
* Input : Image parameters, pointer to best 16x16 intra mode
*
* Output : best 16x16 based SAD
*
************************************************************************/
int find_sad2(int *intra_mode)
{
int current_intra_sad_2,best_intra_sad2;
int M1[16][16],M0[4][4][4][4],M3[4],M4[4][4];
int i,j,k;
int ii,jj;
best_intra_sad2=MAX_VALUE;
for (k=0;k<4;k++)
{
int mb_nr = img->current_mb_nr;
int mb_width = img->width/16;
int mb_available_up = (img->mb_y == 0) ? 0 : (img->slice_numbers[mb_nr] == img->slice_numbers[mb_nr-mb_width]);
int mb_available_left = (img->mb_x == 0) ? 0 : (img->slice_numbers[mb_nr] == img->slice_numbers[mb_nr-1]);
/*check if there are neighbours to predict from */
if ((k==0 && !mb_available_up) || (k==1 && !mb_available_left) || (k==3 && (!mb_available_left || !mb_available_up)))
{
; /* edge, do nothing */
}
else
{
for (j=0;j<16;j++)
{
for (i=0;i<16;i++)
{
M1[i][j]=imgY_org[img->pix_y+j][img->pix_x+i]-img->mprr_2[k][j][i];
M0[i%4][i/4][j%4][j/4]=M1[i][j];
}
}
current_intra_sad_2=0; /* no SAD start handicap here */
for (jj=0;jj<4;jj++)
{
for (ii=0;ii<4;ii++)
{
for (j=0;j<4;j++)
{
M3[0]=M0[0][ii][j][jj]+M0[3][ii][j][jj];
M3[1]=M0[1][ii][j][jj]+M0[2][ii][j][jj];
M3[2]=M0[1][ii][j][jj]-M0[2][ii][j][jj];
M3[3]=M0[0][ii][j][jj]-M0[3][ii][j][jj];
M0[0][ii][j][jj]=M3[0]+M3[1];
M0[2][ii][j][jj]=M3[0]-M3[1];
M0[1][ii][j][jj]=M3[2]+M3[3];
M0[3][ii][j][jj]=M3[3]-M3[2];
}
for (i=0;i<4;i++)
{
M3[0]=M0[i][ii][0][jj]+M0[i][ii][3][jj];
M3[1]=M0[i][ii][1][jj]+M0[i][ii][2][jj];
M3[2]=M0[i][ii][1][jj]-M0[i][ii][2][jj];
M3[3]=M0[i][ii][0][jj]-M0[i][ii][3][jj];
M0[i][ii][0][jj]=M3[0]+M3[1];
M0[i][ii][2][jj]=M3[0]-M3[1];
M0[i][ii][1][jj]=M3[2]+M3[3];
M0[i][ii][3][jj]=M3[3]-M3[2];
for (j=0;j<4;j++)
if ((i+j)!=0)
current_intra_sad_2 += abs(M0[i][ii][j][jj]);
}
}
}
for (j=0;j<4;j++)
for (i=0;i<4;i++)
M4[i][j]=M0[0][i][0][j]/4;
/* Hadamard of DC koeff */
for (j=0;j<4;j++)
{
M3[0]=M4[0][j]+M4[3][j];
M3[1]=M4[1][j]+M4[2][j];
M3[2]=M4[1][j]-M4[2][j];
M3[3]=M4[0][j]-M4[3][j];
M4[0][j]=M3[0]+M3[1];
M4[2][j]=M3[0]-M3[1];
M4[1][j]=M3[2]+M3[3];
M4[3][j]=M3[3]-M3[2];
}
for (i=0;i<4;i++)
{
M3[0]=M4[i][0]+M4[i][3];
M3[1]=M4[i][1]+M4[i][2];
M3[2]=M4[i][1]-M4[i][2];
M3[3]=M4[i][0]-M4[i][3];
M4[i][0]=M3[0]+M3[1];
M4[i][2]=M3[0]-M3[1];
M4[i][1]=M3[2]+M3[3];
M4[i][3]=M3[3]-M3[2];
for (j=0;j<4;j++)
current_intra_sad_2 += abs(M4[i][j]);
}
if(current_intra_sad_2 < best_intra_sad2)
{
best_intra_sad2=current_intra_sad_2;
*intra_mode = k; /* update best intra mode */
}
}
}
best_intra_sad2 = best_intra_sad2/2;
return best_intra_sad2;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -