📄 image.c
字号:
{
static int first_P = TRUE;
int i,j,k,l;
// printf ("init_frame: img->tr %d, img->number %d, img->current_mb_nr %d\n", img->tr, img->number, img->current_mb_nr);
// img->current_mb_nr=-4713; // don't know why this should make sense.
// First MB may be in a lost slcie, slices
// may be out-of-order... STW
img->current_slice_nr=0;
// img->mb_y = img->mb_x = 0;
// img->block_y = img->pix_y = img->pix_c_y = 0; // define vertical positions
// img->block_x = img->pix_x = img->pix_c_x = 0; // define horizontal positions
last_P_no = last_P_no_frm;
nextP_tr = nextP_tr_frm;
//WYK: When entire non-B frames are lost, adjust the reference buffers
//! TO 4.11.2001 Yes, but only for Bitstream mode! We do not loose anything in bitstream mode!
//! Should remove this one time!
/* !KS removed refPicID from Header
#ifndef AFF //to be fixed later
if(inp->FileFormat == PAR_OF_ANNEXB) //! TO 4.11.2001 just to make sure that this piece of code
{ //! does not affect any other input mode where this refPicID is not supported
j = img->refPicID-img->refPicID_old;
if(j<0) j += 16; // img->refPicID is 4 bit, wrapps at 15
if(j > 1) //at least one non-B frame has been lost
{
for(i=1; i<j; i++) // j-1 non-B frames are lost
{
img->number++;
copy2fb(img);
}
}
}
#endif
*/
if (img->number == 0) // first picture
{
nextP_tr=prevP_tr=img->tr;
}
else if(img->type == I_SLICE || img->type == P_SLICE || img->type == SP_SLICE || img->type == SI_SLICE || !img->disposable_flag)
{
#ifdef _ADAPT_LAST_GROUP_
for (i = img->buf_cycle-1; i > 0; i--)
last_P_no[i] = last_P_no[i-1];
last_P_no[0] = nextP_tr;
#endif
nextP_tr=img->tr;
if(first_P) // first P picture
{
first_P = FALSE;
P_interval=nextP_tr-prevP_tr; //! TO 4.11.2001 we get problems here in case the first P-Frame was lost
}
write_prev_Pframe(img, p_out); // imgY_prev, imgUV_prev -> file
}
if (img->type > SI_SLICE)
{
set_ec_flag(SE_PTYPE);
img->type = P_SLICE; // concealed element
}
img->max_mb_nr = (img->width * img->height) / (MB_BLOCK_SIZE * MB_BLOCK_SIZE);
// allocate memory for frame buffers
if (img->number == 0)
{
init_frame_buffers(inp, img);
init_global_buffers(inp, img);
}
for(i=0;i<img->width/BLOCK_SIZE+1;i++) // set edge to -1, indicate nothing to predict from
{
img->ipredmode[i+1][0]=-1;
img->ipredmode[i+1][img->height/BLOCK_SIZE+1]=-1;
}
for(j=0;j<img->height/BLOCK_SIZE+1;j++)
{
img->ipredmode[0][j+1]=-1;
img->ipredmode[img->width/BLOCK_SIZE+1][j+1]=-1;
}
for(i=0;i<img->width/BLOCK_SIZE+1;i++) // set edge to -1, indicate nothing to predict from
img->ipredmode_frm[i+1][0]=-1;
for(j=0;j<img->height/BLOCK_SIZE+1;j++)
img->ipredmode_frm[0][j+1]=-1;
for(i=0;i<img->width/BLOCK_SIZE+1;i++) // set edge to -1, indicate nothing to predict from
img->ipredmode_top[i+1][0]=-1;
for(j=0;j<(img->height /2)/BLOCK_SIZE+1;j++)
img->ipredmode_top[0][j+1]=-1;
for(i=0;i<img->width/BLOCK_SIZE+1;i++) // set edge to -1, indicate nothing to predict from
img->ipredmode_bot[i+1][0]=-1;
for(j=0;j<(img->height /2)/BLOCK_SIZE+1;j++)
img->ipredmode_bot[0][j+1]=-1;
img->ipredmode [0][0]=-1;
img->ipredmode_top[0][0]=-1;
img->ipredmode_bot[0][0]=-1;
// CAVLC init
for (i=0;i < img->width/MB_BLOCK_SIZE; i++)
for (j=0; j < img->height/MB_BLOCK_SIZE; j++)
for (k=0;k<4;k++)
for (l=0;l<6;l++)
img->nz_coeff[i][j][k][l]=-1; // CAVLC
if(img->constrained_intra_pred_flag)
{
for (i=0; i<img->width/MB_BLOCK_SIZE*img->height/MB_BLOCK_SIZE; i++)
{
img->intra_block[i][0] =img->intra_block[i][1] = img->intra_block[i][2] = img->intra_block[i][3] = 1;
}
}
// WYK: Oct. 8, 2001. Set the slice_nr member of each MB to -1, to ensure correct when packet loss occurs
// TO set Macroblock Map (mark all MBs as 'have to be concealed')
for(i=0; i<img->max_mb_nr; i++)
{
img->mb_data[i].slice_nr = -1;
img->mb_data[i].ei_flag = 1;
}
fb = frm;
imgY = imgY_frm;
imgUV = imgUV_frm;
mref = mref_frm;
mcef = mcef_frm;
img->mv = img->mv_frm;
refFrArr = refFrArr_frm;
moving_block = moving_block_frm;
img->fw_refFrArr = img->fw_refFrArr_frm;
img->bw_refFrArr = img->bw_refFrArr_frm;
// printf("short size, used, (%d, %d)\n", frm->short_size, frm->short_used );
}
/*!
************************************************************************
* \brief
* exit a frame
************************************************************************
*/
void exit_frame(struct img_par *img, struct inp_par *inp)
{
if(img->type==I_SLICE || img->type == P_SLICE || img->type == SP_SLICE || img->type == SI_SLICE || !img->disposable_flag)
copy2fb(img);
if (img->structure == FRAME)
{
fld->short_used = frm->short_used * 2;
fld->short_size = frm->short_size * 2;
}
}
/*!
************************************************************************
* \brief
* write the encoding mode and motion vectors of current
* MB to the buffer of the error concealment module.
************************************************************************
*/
void ercWriteMBMODEandMV(struct img_par *img,struct inp_par *inp)
{
extern objectBuffer_t *erc_object_list;
int i, ii, jj, currMBNum = img->current_mb_nr;
int mbx = xPosMB(currMBNum,img->width), mby = yPosMB(currMBNum,img->width);
objectBuffer_t *currRegion, *pRegion;
Macroblock *currMB = &img->mb_data[currMBNum];
int*** mv;
currRegion = erc_object_list + (currMBNum<<2);
if(img->type != B_SLICE) //non-B frame
{
for (i=0; i<4; i++)
{
pRegion = currRegion + i;
pRegion->regionMode = (currMB->mb_type ==I16MB ? REGMODE_INTRA :
currMB->b8mode[i]==IBLOCK ? REGMODE_INTRA_8x8 :
currMB->b8mode[i]==0 ? REGMODE_INTER_COPY :
currMB->b8mode[i]==1 ? REGMODE_INTER_PRED : REGMODE_INTER_PRED_8x8);
if (currMB->b8mode[i]==0 || currMB->b8mode[i]==IBLOCK) // INTRA OR COPY
{
pRegion->mv[0] = 0;
pRegion->mv[1] = 0;
pRegion->mv[2] = 0;
}
else
{
if (currMB->b8mode[i]>=5 && currMB->b8mode[i]<=7) // SMALL BLOCKS
{
ii = 4*mbx + (i%2)*2 + BLOCK_SIZE;
jj = 4*mby + (i/2)*2;
pRegion->mv[0] = (img->mv[ii][jj][0] + img->mv[ii+1][jj][0] + img->mv[ii][jj+1][0] + img->mv[ii+1][jj+1][0] + 2)/4;
pRegion->mv[1] = (img->mv[ii][jj][1] + img->mv[ii+1][jj][1] + img->mv[ii][jj+1][1] + img->mv[ii+1][jj+1][1] + 2)/4;
}
else // 16x16, 16x8, 8x16, 8x8
{
pRegion->mv[0] = img->mv[4*mbx+(i%2)*2+BLOCK_SIZE][4*mby+(i/2)*2][0];
pRegion->mv[1] = img->mv[4*mbx+(i%2)*2+BLOCK_SIZE][4*mby+(i/2)*2][1];
}
erc_mvperMB += mabs(pRegion->mv[0]) + mabs(pRegion->mv[1]);
pRegion->mv[2] = refFrArr[4*mby+(i/2)*2][4*mbx+(i%2)*2];
}
}
}
else //B-frame
{
for (i=0; i<4; i++)
{
ii = 4*mbx + (i%2)*2 + BLOCK_SIZE;
jj = 4*mby + (i/2)*2;
pRegion = currRegion + i;
pRegion->regionMode = (currMB->mb_type ==I16MB ? REGMODE_INTRA :
currMB->b8mode[i]==IBLOCK ? REGMODE_INTRA_8x8 : REGMODE_INTER_PRED_8x8);
if (currMB->mb_type==I16MB || currMB->b8mode[i]==IBLOCK) // INTRA
{
pRegion->mv[0] = 0;
pRegion->mv[1] = 0;
pRegion->mv[2] = 0;
}
else
{
mv = (currMB->b8mode[i]==0 && currMB->b8pdir[i]==2 ? img->dbMV : currMB->b8pdir[i]==1 ? img->bw_mv : img->fw_mv);
pRegion->mv[0] = (mv[ii][jj][0] + mv[ii+1][jj][0] + mv[ii][jj+1][0] + mv[ii+1][jj+1][0] + 2)/4;
pRegion->mv[1] = (mv[ii][jj][1] + mv[ii+1][jj][1] + mv[ii][jj+1][1] + mv[ii+1][jj+1][1] + 2)/4;
erc_mvperMB += mabs(pRegion->mv[0]) + mabs(pRegion->mv[1]);
if (currMB->b8pdir[i]==0 || (currMB->b8pdir[i]==2 && currMB->b8mode[i]!=0)) // forward or bidirect
{
pRegion->mv[2] = (img->fw_refFrArr[jj][ii-4]-1+img->buf_cycle) % img->buf_cycle;
///???? is it right, not only "img->fw_refFrArr[jj][ii-4]"
}
else
{
pRegion->mv[2] = 0;
}
}
}
}
}
/*!
************************************************************************
* \brief
* decodes one slice
************************************************************************
*/
void decode_one_slice(struct img_par *img,struct inp_par *inp)
{
Boolean end_of_slice = FALSE;
int read_flag;
img->cod_counter=-1;
reset_ec_flags();
while (end_of_slice == FALSE) // loop over macroblocks
{
setMapMB_nr (img); //GB
#if TRACE
// Here was the slice nr from the img->mb_data used. This slice number is only set after
// the reconstruction of an MB and hence here not yet valid
// fprintf(p_trace,"\n*********** Pic: %i (I/P) MB: %i Slice: %i Type %d **********\n", img->tr, img->map_mb_nr, img->mb_data[img->map_mb_nr].slice_nr, img->type);
fprintf(p_trace,"\n*********** Pic: %i (I/P) MB: %i Slice: %i Type %d **********\n", img->tr, img->map_mb_nr, img->current_slice_nr, img->type);
#endif
// Initializes the current macroblock
start_macroblock(img,inp, img->current_mb_nr);
// Get the syntax elements from the NAL
read_flag = read_one_macroblock(img,inp);
if (img->mb_frame_field_flag)
init_super_macroblock(img,inp);
// decode one macroblock
if (img->mb_field)
decode_super_macroblock(img,inp);
else
decode_one_macroblock(img,inp);
if (img->mb_frame_field_flag)
exit_super_macroblock(img,inp);
if(img->mb_frame_field_flag && img->mb_field)
img->num_ref_pic_active_fwd >>= 1;
ercWriteMBMODEandMV(img,inp);
end_of_slice=exit_macroblock(img,inp,(!img->mb_frame_field_flag||img->current_mb_nr%2));
}
reset_ec_flags();
if(img->mb_frame_field_flag)
img->buf_cycle = inp->buf_cycle+1; // reset the img->buf_cycle, otherwise free will cause problems
}
void decode_frame_slice(struct img_par *img,struct inp_par *inp, int current_header)
{
Slice *currSlice = img->currentSlice;
if (active_pps->entropy_coding_mode == CABAC)
{
init_contexts (img);
}
// init new frame
if (current_header == SOP)
init_frame(img, inp);
// do reference frame buffer reordering
reorder_mref(img);
if ( (img->weighted_bipred_idc > 0 && (img->type == B_SLICE)) || (img->weighted_pred_flag && img->type !=I_SLICE))
fill_wp_params(img);
if (current_header == SOP)
{
if (img->number == 0)
ercInit(img->width, img->height, 1);
// reset all variables of the error concealmnet instance before decoding of every frame.
// here the third parameter should, if perfectly, be equal to the number of slices per frame.
// using little value is ok, the code will alloc more memory if the slice number is larger
ercReset(erc_errorVar, img->max_mb_nr, img->max_mb_nr, img->width);
erc_mvperMB = 0;
}
// decode main slice information
if ((current_header == SOP || current_header == SOS) && currSlice->ei_flag == 0)
decode_one_slice(img,inp);
// setMB-Nr in case this slice was lost
// if(currSlice->ei_flag)
// img->current_mb_nr = currSlice->last_mb_nr + 1;
//! This code doesn't work with FMO or a slice-lossy environment!
//! StW NEEDS FIXING
if(currSlice->next_eiflag && img->current_mb_nr != img->max_mb_nr)
currSlice->next_header = SOS;
}
void decode_field_slice(struct img_par *img,struct inp_par *inp, int current_header)
{
Slice *currSlice = img->currentSlice;
if (active_pps->entropy_coding_mode == CABAC)
{
init_contexts (img);
}
// init new frame
if (current_header == SOP)
{
if (img->structure == TOP_FIELD)
init_top(img, inp); // set up field buffer in this function
else
{
init_bottom(img, inp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -