📄 macroblock.c
字号:
if (input->symbol_mode == UVLC)
{
currSE->mapping = n_linfo2;
}
else
{
currSE->context = BType2CtxRef (mode);
img->subblock_x = i; // position used for context determination
img->subblock_y = j; // position used for context determination
currSE->writing = writeRefFrame2Buffer_CABAC;
}
dataPart = &(currSlice->partArr[partMap[currSE->type]]);
dataPart->writeSyntaxElement (currSE, dataPart);
bitCount[BITS_INTER_MB] += currSE->len;
rate += currSE->len;
#if TRACE
snprintf(currSE->tracestring, TRACESTRING_SIZE, "Reference frame no %d", currSE->value1);
#endif
currSE++;
currMB->currSEnr++;
return rate;
}
/*!
************************************************************************
* \brief
* Writes motion vectors of an 8x8 block
************************************************************************
*/
int
writeMotionVector8x8 (int i0,
int j0,
int i1,
int j1,
int refframe,
int mv_mode)
{
int i, j, k, l, m;
int curr_mvd;
DataPartition* dataPart;
int bwflag = (refframe<0?1:0);
int rate = 0;
int step_h = input->blc_size[mv_mode][0] >> 2;
int step_v = input->blc_size[mv_mode][1] >> 2;
Macroblock* currMB = &img->mb_data[img->current_mb_nr];
SyntaxElement* currSE = &img->MB_SyntaxElements[currMB->currSEnr];
Slice* currSlice = img->currentSlice;
int* bitCount = currMB->bitcounter;
const int* partMap = assignSE2partition[input->partition_mode];
int refindex = (refframe<0 ? 0 : refframe);
int***** all_mv = (refframe<0 ? img->all_bmv : img->all_mv);
int***** pred_mv = (img->type!=B_IMG ? img->mv : refframe<0 ? img->p_bwMV : img->p_fwMV);
for (j=j0; j<j1; j+=step_v)
for (i=i0; i<i1; i+=step_h)
{
for (k=0; k<2; k++)
{
curr_mvd = all_mv[i][j][refindex][mv_mode][k] - pred_mv[i][j][refindex][mv_mode][k];
//--- store (oversampled) mvd ---
for (l=0; l < step_v; l++)
for (m=0; m < step_h; m++) currMB->mvd[bwflag][j+l][i+m][k] = curr_mvd;
currSE->value1 = curr_mvd;
currSE->type = (img->type==B_IMG ? SE_BFRAME : SE_MVD);
if (input->symbol_mode == UVLC)
{
currSE->mapping = mvd_linfo2;
}
else
{
img->subblock_x = i; // position used for context determination
img->subblock_y = j; // position used for context determination
if (img->type!=B_IMG)
{
currSE->value2 = k; // identifies the component and the direction; only used for context determination
currSE->writing = writeMVD2Buffer_CABAC;
}
else
{
currSE->value2 = 2*k+bwflag; // identifies the component and the direction; only used for context determination
currSE->writing = writeBiMVD2Buffer_CABAC;
}
}
dataPart = &(currSlice->partArr[partMap[img->type==B_IMG ? SE_BFRAME : SE_MVD]]);
dataPart->writeSyntaxElement (currSE, dataPart);
#if TRACE
snprintf(currSE->tracestring, TRACESTRING_SIZE, " MVD(%d) = %3d",k, curr_mvd);
#endif
bitCount[BITS_INTER_MB] += currSE->len;
rate += currSE->len;
currSE++;
currMB->currSEnr++;
}
}
return rate;
}
/*!
************************************************************************
* \brief
* Writes motion info
************************************************************************
*/
int writeMotionInfo2NAL ()
{
int k, j0, i0, refframe;
Macroblock* currMB = &img->mb_data[img->current_mb_nr];
int no_bits = 0;
int bframe = (img->type==B_IMG);
int** refframe_array = (img->type==B_IMG ? fw_refFrArr : refFrArr);
#ifdef _ADDITIONAL_REFERENCE_FRAME_
int multframe = (input->no_multpred>1 || input->add_ref_frame>0);
#else
int multframe = (input->no_multpred>1);
#endif
int step_h0 = (input->blc_size[IS_P8x8(currMB) ? 4 : currMB->mb_type][0] >> 2);
int step_v0 = (input->blc_size[IS_P8x8(currMB) ? 4 : currMB->mb_type][1] >> 2);
//=== If multiple ref. frames, write reference frame for the MB ===
if (IS_INTERMV (currMB) && multframe)
{
// if UVLC is turned on, a 8x8 macroblock with all ref=0 in a P-frame is signalled in macroblock mode
if (!IS_P8x8 (currMB) || !ZeroRef (currMB) || input->symbol_mode==CABAC || bframe)
{
for (j0=0; j0<4; j0+=step_v0)
for (i0=0; i0<4; i0+=step_h0)
{
k=j0+(i0/2);
if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)//has forward vector
{
no_bits += writeReferenceFrame (currMB->b8mode[k], i0, j0, refframe_array[img->block_y+j0][img->block_x+i0]);
}
}
}
}
//===== write forward motion vectors =====
if (IS_INTERMV (currMB))
{
for (j0=0; j0<4; j0+=step_v0)
for (i0=0; i0<4; i0+=step_h0)
{
k=j0+(i0/2);
if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)//has forward vector
{
refframe = refframe_array[img->block_y+j0][img->block_x+i0];
no_bits += writeMotionVector8x8 (i0, j0, i0+step_h0, j0+step_v0, refframe, currMB->b8mode[k]);
}
}
}
//===== write backward motion vectors =====
if (IS_INTERMV (currMB) && bframe)
{
for (j0=0; j0<4; j0+=step_v0)
for (i0=0; i0<4; i0+=step_h0)
{
k=j0+(i0/2);
if ((currMB->b8pdir[k]==1 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)//has backward vector
{
refframe = refframe_array[img->block_y+j0][img->block_x+i0];
no_bits += writeMotionVector8x8 (i0, j0, i0+step_h0, j0+step_v0, -1, currMB->b8mode[k]);
}
}
}
return no_bits;
}
/*!
************************************************************************
* \brief
* Writes chrominance coefficients
************************************************************************
*/
int
writeChromaCoeff ()
{
int rate = 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;
const int* partMap = assignSE2partition[input->partition_mode];
int cbp = currMB->cbp;
DataPartition* dataPart;
int level, run;
int i, j, k, uv, mb_x, mb_y, i1, ii, j1, jj;
int b8, b4;
int* ACLevel;
int* ACRun;
int* DCLevel;
int* DCRun;
//=====
//===== D C - C O E F F I C I E N T S
//=====
if (cbp > 15) // check if any chroma bits in coded block pattern is set
{
for (uv=0; uv < 2; uv++)
{
DCLevel = img->cofDC[uv+1][0];
DCRun = img->cofDC[uv+1][1];
level=1;
for (k=0; k < 5 && level != 0; ++k)
{
level = currSE->value1 = DCLevel[k]; // level
run = currSE->value2 = DCRun [k]; // run
if (input->symbol_mode == UVLC) currSE->mapping = levrun_linfo_c2x2;
else currSE->writing = writeRunLevel2Buffer_CABAC;
currSE->k = uv; //ctx for coeff_count
if (IS_INTRA (currMB))
{
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;
rate += currSE->len;
#if TRACE
snprintf(currSE->tracestring, TRACESTRING_SIZE, "2x2 DC Chroma %2d: level =%3d run =%2d",k, level, run);
#endif
// proceed to next SE
currSE++;
currMB->currSEnr++;
}
}
}
//=====
//===== A C - C O E F F I C I E N T S
//=====
uv=-1;
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++)
{
b8 = 4 + i/2;
b4 = 2*(j/5)+ (i%2);
ACLevel = img->cofAC[b8][b4][0];
ACRun = img->cofAC[b8][b4][1];
ii=i/2;
i1=i%2;
level=1;
uv++;
for (k=0; k < 16 && level != 0; k++)
{
level = currSE->value1 = ACLevel[k]; // level
run = currSE->value2 = ACRun [k]; // run
if (input->symbol_mode == UVLC) currSE->mapping = levrun_linfo_inter;
else currSE->writing = writeRunLevel2Buffer_CABAC;
currSE->k=uv; //ctx for coeff_count
if (IS_INTRA (currMB))
{
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;
rate += currSE->len;
#if TRACE
snprintf(currSE->tracestring, TRACESTRING_SIZE, "AC Chroma %2d: level =%3d run =%2d",k, level, run);
#endif
// proceed to next SE
currSE++;
currMB->currSEnr++;
}
}
}
}
}
return rate;
}
/*!
************************************************************************
* \brief
* Writes Luma coeff of an 4x4 block
************************************************************************
*/
int
writeLumaCoeff4x4 (int b8, int b4, int intra4x4mode)
{
int rate = 0;
Macroblock* currMB = &img->mb_data[img->current_mb_nr];
SyntaxElement* currSE = &img->MB_SyntaxElements[currMB->currSEnr];
Slice* currSlice = img->currentSlice;
const int* partMap = assignSE2partition[input->partition_mode];
int* bitCount = currMB->bitcounter;
DataPartition* dataPart;
int kk,kbeg,kend;
int level, run;
int k;
int* ACLevel = img->cofAC[b8][b4][0];
int* ACRun = img->cofAC[b8][b4][1];
img->subblock_x = ((b8&0x1)==0)?(((b4&0x1)==0)?0:1):(((b4&0x1)==0)?2:3); // horiz. position for coeff_count context
img->subblock_y = (b8<2)?((b4<2)?0:1):((b4<2)?2:3); // vert. position for coeff_count context
if (intra4x4mode && (img->qp<24 || input->symbol_mode == CABAC)) // double scan, for CABAC always
{
for(kk=0;kk<2;kk++)
{
kbeg = kk*9;
kend = kbeg+8;
level = 1; // get inside loop
for (k=kbeg; k<=kend && level!=0; k++)
{
level = currSE->value1 = ACLevel[k];
run = currSE->value2 = ACRun [k];
if (input->symbol_mode == UVLC)
{
currSE->mapping = levrun_linfo_intra;
}
else
{
currSE->context = 0; // for choosing context model
currSE->writing = writeRunLevel2Buffer_CABAC;
}
if (k == kb
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -