📄 macroblock.c
字号:
currStream->bits_to_go = currStream->stored_bits_to_go;
currStream->byte_pos = currStream->stored_byte_pos;
currStream->byte_buf = currStream->stored_byte_buf;
if (input->symbol_mode == CABAC)
{
eep = &(dataPart->ee_cabac);
eep->Elow = eep->ElowS;
eep->Erange = eep->ErangeS;
eep->Ebuffer = eep->EbufferS;
eep->Ebits_to_go = eep->Ebits_to_goS;
eep->Ebits_to_follow = eep->Ebits_to_followS;
eep->Ecodestrm = eep->EcodestrmS;
eep->Ecodestrm_len = eep->Ecodestrm_lenS;
eep->C = eep->CS;
eep->B = eep->BS;
eep->E = eep->ES;
}
}
}
if(*end_of_slice == TRUE && skip == TRUE) //! TO 4.11.2001 Skip MBs at the end of this slice
{
//! only for Slice Mode 2 or 3
// If we still have to write the skip, let's do it!
if(img->cod_counter && *recode_macroblock == TRUE) //! MB that did not fit in this slice
{
// If recoding is true and we have had skip,
// we have to reduce the counter in case of recoding
img->cod_counter--;
if(img->cod_counter)
{
currSE->value1 = img->cod_counter;
currSE->mapping = ue_linfo;
currSE->type = SE_MBTYPE;
if (img->type != B_IMG && img->type != BS_IMG) dataPart = &(currSlice->partArr[partMap[currSE->type]]);
else dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
dataPart->writeSyntaxElement( currSE, dataPart);
rlc_bits=currSE->len;
currMB->bitcounter[BITS_MB_MODE]+=rlc_bits;
img->cod_counter = 0;
}
}
else //! MB that did not fit in this slice anymore is not a Skip MB
{
if (img->type != B_IMG && img->type != BS_IMG) dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
else dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
currStream = dataPart->bitstream;
// update the bitstream
currStream->bits_to_go = currStream->bits_to_go_skip;
currStream->byte_pos = currStream->byte_pos_skip;
currStream->byte_buf = currStream->byte_buf_skip;
// update the statistics
img->cod_counter = 0;
skip = FALSE;
}
}
//! TO 4.11.2001 Skip MBs at the end of this slice for Slice Mode 0 or 1
if(*end_of_slice == TRUE && img->cod_counter && !use_bitstream_backing)
{
currSE->value1 = img->cod_counter;
currSE->mapping = ue_linfo;
currSE->type = SE_MBTYPE;
if (img->type != B_IMG && img->type != BS_IMG) dataPart = &(currSlice->partArr[partMap[currSE->type]]);
else dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
dataPart->writeSyntaxElement( currSE, dataPart);
rlc_bits=currSE->len;
currMB->bitcounter[BITS_MB_MODE]+=rlc_bits;
img->cod_counter = 0;
}
}
/*!
*****************************************************************************
*
* \brief
* For Slice Mode 2: Checks if one partition of one slice exceeds the
* allowed size
*
* \return
* FALSE if all Partitions of this slice are smaller than the allowed size
* TRUE is at least one Partition exceeds the limit
*
* \para Parameters
*
*
*
* \para Side effects
* none
*
* \para Other Notes
*
*
*
* \date
* 4 November 2001
*
* \author
* Tobias Oelbaum drehvial@gmx.net
*****************************************************************************/
int slice_too_big(int rlc_bits)
{
Slice *currSlice = img->currentSlice;
DataPartition *dataPart;
Bitstream *currStream;
EncodingEnvironmentPtr eep;
int i;
int size_in_bytes;
//! UVLC
if (input->symbol_mode == UVLC)
{
for (i=0; i<currSlice->max_part_nr; i++)
{
dataPart = &(currSlice->partArr[i]);
currStream = dataPart->bitstream;
size_in_bytes = currStream->byte_pos /*- currStream->tmp_byte_pos*/;
if (currStream->bits_to_go < 8)
size_in_bytes++;
if (currStream->bits_to_go < rlc_bits)
size_in_bytes++;
if(size_in_bytes > input->slice_argument)
return TRUE;
}
}
//! CABAC
if (input->symbol_mode ==CABAC)
{
for (i=0; i<currSlice->max_part_nr; i++)
{
dataPart= &(currSlice->partArr[i]);
eep = &(dataPart->ee_cabac);
if( arienco_bits_written(eep) > (input->slice_argument*8))
return TRUE;
}
}
return FALSE;
}
/*!
************************************************************************
* \brief
* Checks the availability of neighboring macroblocks of
* the current macroblock for prediction and context determination;
* marks the unavailable MBs for intra prediction in the
* ipredmode-array by -1. Only neighboring MBs in the causal
* past of the current MB are checked.
************************************************************************
*/
void CheckAvailabilityOfNeighbors()
{
int i,j;
const int mb_width = img->width/MB_BLOCK_SIZE;
const int mb_nr = img->current_mb_nr;
Macroblock *currMB = &img->mb_data[mb_nr];
int pix_y = img->pix_y; // For MB level Frame/field coding
int block_y = img->block_y; // For MB level Frame/field coding
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode)
{
pix_y = img->field_pix_y;
block_y = img->field_block_y;
}
// mark all neighbors as unavailable
for (i=0; i<3; i++)
for (j=0; j<3; j++)
{
img->mb_data[mb_nr].mb_available[i][j]=NULL;
}
img->mb_data[mb_nr].mb_available[1][1]=currMB; // current MB
// Check MB to the left
if(img->pix_x >= MB_BLOCK_SIZE)
{
int remove_prediction = currMB->slice_nr != img->mb_data[mb_nr-1].slice_nr;
// upper blocks
if (remove_prediction || (input->UseConstrainedIntraPred && img->intra_block[mb_nr-1][1]==0))
{
img->ipredmode[img->block_x][img->block_y+1] = -1;
img->ipredmode[img->block_x][img->block_y+2] = -1;
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode) // GB
{
if(img->top_field)
{
img->ipredmode_top[img->block_x][block_y+1] = -1;
img->ipredmode_top[img->block_x][block_y+2] = -1;
}
else
{
img->ipredmode_bot[img->block_x][block_y+1] = -1;
img->ipredmode_bot[img->block_x][block_y+2] = -1;
}
}
}
// lower blocks
if (remove_prediction || (input->UseConstrainedIntraPred && img->intra_block[mb_nr-1][3]==0))
{
img->ipredmode[img->block_x][img->block_y+3] = -1;
img->ipredmode[img->block_x][img->block_y+4] = -1;
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode) //GB
{
if(img->top_field)
{
img->ipredmode_top[img->block_x][block_y+3] = -1;
img->ipredmode_top[img->block_x][block_y+4] = -1;
}
else
{
img->ipredmode_bot[img->block_x][block_y+3] = -1;
img->ipredmode_bot[img->block_x][block_y+4] = -1;
}
}
}
if (!remove_prediction)
{
currMB->mb_available[1][0]=&(img->mb_data[mb_nr-1]);
}
}
// Check MB above
if(pix_y >= MB_BLOCK_SIZE) // wrong for MBAFF
//if(img->pix_y >= MB_BLOCK_SIZE)
{
int remove_prediction = currMB->slice_nr != img->mb_data[mb_nr-mb_width].slice_nr;
// upper blocks
if (remove_prediction || (input->UseConstrainedIntraPred && img->intra_block[mb_nr-mb_width][2]==0))
{
img->ipredmode[img->block_x+1][img->block_y] = -1;
img->ipredmode[img->block_x+2][img->block_y] = -1;
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode) //GB
{
if(img->top_field)
{
img->ipredmode_top[img->block_x+1][block_y] = -1;
img->ipredmode_top[img->block_x+2][block_y] = -1;
}
else
{
img->ipredmode_bot[img->block_x+1][block_y] = -1;
img->ipredmode_bot[img->block_x+2][block_y] = -1;
}
}
}
// lower blocks
if (remove_prediction || (input->UseConstrainedIntraPred && img->intra_block[mb_nr-mb_width][3]==0))
{
img->ipredmode[img->block_x+3][img->block_y] = -1;
img->ipredmode[img->block_x+4][img->block_y] = -1;
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode) //GB
{
if(img->top_field)
{
img->ipredmode_top[img->block_x+3][block_y] = -1;
img->ipredmode_top[img->block_x+4][block_y] = -1;
}
else
{
img->ipredmode_bot[img->block_x+3][block_y] = -1;
img->ipredmode_bot[img->block_x+4][block_y] = -1;
}
}
}
if (!remove_prediction)
{
currMB->mb_available[0][1]=&(img->mb_data[mb_nr-mb_width]);
}
}
// Check MB left above
if(img->pix_x >= MB_BLOCK_SIZE && img->pix_y >= MB_BLOCK_SIZE )
{
int remove_prediction = currMB->slice_nr != img->mb_data[mb_nr-mb_width-1].slice_nr;
if (remove_prediction || (input->UseConstrainedIntraPred && img->intra_block[mb_nr-mb_width-1][3]==0))
{
img->ipredmode[img->block_x][img->block_y] = -1;
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive && img->field_mode) //GB
{
if(img->top_field)
{
img->ipredmode_top[img->block_x][block_y] = -1;
}
else
{
img->ipredmode_bot[img->block_x][block_y] = -1;
}
}
}
if (!remove_prediction)
{
currMB->mb_available[0][0]=&(img->mb_data[mb_nr-mb_width-1]);
}
}
// Check MB right above
if(pix_y >= MB_BLOCK_SIZE && img->pix_x < (img->width-MB_BLOCK_SIZE ))
{
if(currMB->slice_nr == img->mb_data[mb_nr-mb_width+1].slice_nr)
currMB->mb_available[0][2]=&(img->mb_data[mb_nr-mb_width+1]);
}
if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive)
currMB->mb_available[0][2] = NULL; // set the prediction from top right MB to zero
}
void CheckAvailabilityOfNeighborsForAff()
{
const int mb_width = img->width/MB_BLOCK_SIZE;
const int mb_nr = img->current_mb_nr;
Macroblock *currMB = &img->mb_data[mb_nr];
// Check Field to the left
if ((img->pix_x >= MB_BLOCK_SIZE) && (currMB->slice_nr == img->mb_data[mb_nr-1].slice_nr))
currMB->field_available[1]=&(img->mb_data[mb_nr-1]);
else
currMB->field_available[1]=NULL;
// Check Field above
if ((img->pix_y >= 2*MB_BLOCK_SIZE) && (currMB->slice_nr == img->mb_data[mb_nr-mb_width*2].slice_nr))
currMB->field_available[0]=&(img->mb_data[mb_nr-mb_width*2]);
else
currMB->field_available[0]=NULL;
}
/*!
************************************************************************
* \brief
* Predict one component of a 4x4 Luma block
************************************************************************
*/
void
OneComponentLumaPrediction4x4 (byte* mpred, // --> array of prediction values (row by row)
int pic_pix_x, // <-- absolute horizontal coordinate of 4x4 block
int pic_pix_y, // <-- absolute vertical coordinate of 4x4 block
int* mv, // <-- motion vector
int ref) // <-- reference frame (0.. / -1:backward)
{
int incr;
pel_t** ref_pic;
int pix_add = 4;
int j0 = (pic_pix_y << 2) + mv[1], j1=j0+pix_add, j2=j1+pix_add, j3=j2+pix_add;
int i0 = (pic_pix_x << 2) + mv[0], i1=i0+pix_add, i2=i1+pix_add, i3=i2+pix_add;
int left=-(IMG_PAD_SIZE<<2),right=(img->width)<<2,top=-(IMG_PAD_SIZE<<2),bottom=(img->height)<<2;
pel_t (*get_pel) (pel_t**, int, int) = UMVPelY_14;
// Tian Dong: PLUS1, June 06, 2002
incr = 0 ;
ref_pic = img->type==B_IMG? mref [ref+1+incr] : mref [ref];
if(j0<bottom&&j0>top&&i0>left&&i0<right)
{
pel_t *pt=&(ref_pic[j0+(IMG_PAD_SIZE<<2)][i0+(IMG_PAD_SIZE<<2)]);
int w=(img->width+2*IMG_PAD_SIZE)<<2;
_asm
{
mov edi,mpred
mov esi,pt
mov eax,w
shl eax,2
movdqu xmm0,[esi]
add esi,eax
movdqu xmm1,[esi]
add esi,eax
movdqu xmm2,[esi]
add esi,eax
movdqu xmm3,[esi]
pslld xmm0,24
pslld xmm1,24
pslld xmm2,24
pslld xmm3,24
psrld xmm0,24
psrld xmm1,24
psrld xmm2,24
psrld xmm3,24
pxor xmm7,xmm7
PACKSSDW xmm0,xmm7
PACKSSDW xmm1,xmm7
PACKSSDW xmm2,xmm7
PACKSSDW xmm3,xmm7
PACKUSWB xmm0,xmm7
PACKUSWB xmm1,xmm7
PACKUSWB xmm2,xmm7
PACKUSWB xmm3,xmm7
movdq2q mm0,xmm0
movdq2q mm1,xmm1
movdq2q mm2,xmm2
movdq2q mm3,xmm3
movd [edi],mm0
movd [edi+4],mm1
movd [edi+8],mm2
movd [edi+12],mm3
emms
}
}
else
{
*mpred++ = get_pel (ref_pic, j0, i0);
*mpred++ = get_pel (ref_pic, j0, i1);
*mpred++ = get_pel (ref_pic, j0, i2);
*mpred++ = get_pel (ref_pic, j0, i3);
*mpred++ = get_pel (ref_pic, j1, i0);
*mpred++ = get_pel (ref_pic, j1, i1);
*mpred++ = get_pel (ref_pic, j1, i2);
*mpred++ = get_pel (ref_pic, j1, i3);
*mpred++ = get_pel (ref_pic, j2, i0);
*mpred++ = get_pel (ref_pic, j2, i1);
*mpred++ = get_pel (ref_pic, j2, i2);
*mpred++ = get_pel (ref_pic, j2, i3);
*mpred++ = get_pel (ref_pic, j3, i0);
*mpred++ = get_pel (ref_pic, j3, i1);
*mpred++ = get_pel (ref_pic, j3, i2);
*mpred++ = get_pel (ref_pic, j3, i3);
}
}
/*!
************************************************************************
* \brief
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -