📄 image.c
字号:
}
}
// 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, 2*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 or out-of-order slices
if(currSlice->next_eiflag && img->current_mb_nr != img->max_mb_nr)
currSlice->next_header = SOS;
}
/*!
************************************************************************
* \brief
* Initializes the parameters for a new field
************************************************************************
*/
void init_top(struct img_par *img, struct inp_par *inp)
{
static int first_P = TRUE;
int i,j;
img->buf_cycle *= 2;
img->number *= 2;
// img->current_mb_nr=-4714; // impossible value, 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_fld;
nextP_tr = nextP_tr_fld;
//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
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) // I or P pictures
{
#ifdef _ADAPT_LAST_GROUP_
for (i = img->buf_cycle; 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);
img->buf_cycle *= 2;
}
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;
}
img->ipredmode[0][0] = -1;
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
for(i=0; i<img->max_mb_nr; i++)
img->mb_data[i].slice_nr = -1;
fb = fld;
imgY = imgY_top;
imgUV = imgUV_top;
mref = mref_fld;
mcef = mcef_fld;
img->mv = img->mv_top;
refFrArr = refFrArr_top;
moving_block = moving_block_top;
img->fw_refFrArr = img->fw_refFrArr_top;
img->bw_refFrArr = img->bw_refFrArr_top;
}
/*!
************************************************************************
* \brief
* Initializes the parameters for a new field
************************************************************************
*/
void init_bottom(struct img_par *img, struct inp_par *inp)
{
static int first_P = TRUE;
int i,j;
img->number++;
// img->current_mb_nr=-4715; // impossible value, StW
img->current_slice_nr=0;
img->buf_cycle *= 2;
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_fld;
//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
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
*/
img->structure = TOP_FIELD; //for set parity
if(img->type==I_SLICE || img->type == P_SLICE || img->type == SP_SLICE || img->type == SI_SLICE || !img->disposable_flag)
copy2fb(img); // trying to match exit_frame() in frame mode
img->structure = BOTTOM_FIELD; //for set parity
if (!img->mb_frame_field_flag)
{
if((img->type==B_SLICE) && !img->disposable_flag)
{
// copy motion information of stored B-picture for direct mode
for (i=0 ; i<img->width/4+4 ; i++)
{
for (j=0 ; j<img->height/4 ; j++)
{
img->mv_top[i][j][0] = img->fw_mv[i][j][0];
img->mv_top[i][j][1] = img->fw_mv[i][j][1];
if (i<img->width/4)
{
refFrArr_top[j][i] = img->fw_refFrArr[j][i];
}
}
}
}
}
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) // I or P pictures
{
#ifdef _ADAPT_LAST_GROUP_
if (img->number==1)
{
for (i = img->buf_cycle; 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
}
}
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);
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;
}
img->ipredmode[0][0] = -1;
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
for(i=0; i<img->max_mb_nr; i++)
img->mb_data[i].slice_nr = -1;
imgY = imgY_bot;
imgUV = imgUV_bot;
img->mv = img->mv_bot;
moving_block = moving_block_bot;
refFrArr = refFrArr_bot;
mref = mref_fld;
mcef = mcef_fld;
img->fw_refFrArr = img->fw_refFrArr_bot;
img->bw_refFrArr = img->bw_refFrArr_bot;
}
/*!
************************************************************************
* \brief
* Prepare field and frame buffer after frame decoding
************************************************************************
*/
void frame_postprocessing(struct img_par *img, struct inp_par *inp)
{
int i;
img->height = img->height/2;
img->height_cr = img->height_cr/2;
img->number *= 2;
img->buf_cycle *= 2;
fb = fld;
mref = mref_fld;
mcef = mcef_fld;
imgY = imgY_top;
imgUV = imgUV_top;
img->structure = TOP_FIELD;//for set parity
if (img->type == I_SLICE || img->type == P_SLICE || img->type == SP_SLICE || img->type == SI_SLICE || !img->disposable_flag) // I or P pictures
{
split_field_top(img);
copy2fb(img);
}
img->number++;
imgY = imgY_bot;
imgUV = imgUV_bot;
img->structure = BOTTOM_FIELD;//for set parity
if (img->type == I_SLICE || img->type == P_SLICE || img->type == SP_SLICE || img->type == SI_SLICE || !img->disposable_flag) // I or P pictures
{
split_field_bot(img);
copy2fb(img);
}
fb = frm;
mref = mref_frm;
mcef = mcef_frm;
imgY = imgY_frm;
imgUV = imgUV_frm;
img->structure = FRAME;
img->height *= 2;
img->height_cr *= 2;
img->buf_cycle /= 2;
img->number /= 2;
if((img->number)&&(img->type==I_SLICE || img->type == P_SLICE || img->type == SP_SLICE || img->type == SI_SLICE || !img->disposable_flag))
{
for (i = img->buf_cycle; i > 2; i--)
{
last_P_no_fld[i] = last_P_no_fld[i-2];
last_P_no_fld[i-1] = last_P_no_fld[i-3];
}
last_P_no_fld[0] = nextP_tr_fld+1;
last_P_no_fld[1] = nextP_tr_fld;
nextP_tr_fld = nextP_tr * 2;
nextP_tr_frm = nextP_tr;
}
}
/*!
************************************************************************
* \brief
* Extract top field from a frame
************************************************************************
*/
void split_field_top(struct img_par *img)
{
int i;
for (i=0; i<img->height; i++)
{
memcpy(imgY[i], imgY_frm[i*2], img->width);
}
for (i=0; i<img->height_cr; i++)
{
memcpy(imgUV[0][i], imgUV_frm[0][i*2], img->width_cr);
memcpy(imgUV[1][i], imgUV_frm[1][i*2], img->width_cr);
}
}
/*!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -