📄 errdo.c
字号:
{
int i,j,k;
int block_size_x, block_size_y;
int mv_mode, pred_dir;
static const byte decode_block_scan[16] = {0,1,4,5,2,3,6,7,8,9,12,13,10,11,14,15};
int block8x8;
int k_start, k_end, k_inc;
if (!currMB->mb_type)
{
block_size_x = MB_BLOCK_SIZE;
block_size_y = MB_BLOCK_SIZE;
pred_dir = LIST_0;
perform_mc_concealment(decoder, PLANE_Y, enc_pic, image, pred_dir, 0, 0, block_size_x, block_size_y);
}
else if (currMB->mb_type == 1)
{
block_size_x = MB_BLOCK_SIZE;
block_size_y = MB_BLOCK_SIZE;
pred_dir = currMB->b8pdir[0];
perform_mc_concealment(decoder, PLANE_Y, enc_pic, image, pred_dir, 0, 0, block_size_x, block_size_y);
}
else if (currMB->mb_type == 2)
{
block_size_x = MB_BLOCK_SIZE;
block_size_y = 8;
for (block8x8 = 0; block8x8 < 4; block8x8 += 2)
{
pred_dir = currMB->b8pdir[block8x8];
perform_mc_concealment(decoder, PLANE_Y, enc_pic, image, pred_dir, 0, block8x8, block_size_x, block_size_y);
}
}
else if (currMB->mb_type == 3)
{
block_size_x = 8;
block_size_y = 16;
for (block8x8 = 0; block8x8 < 2; block8x8++)
{
i = block8x8<<1;
j = 0;
pred_dir = currMB->b8pdir[block8x8];
assert (pred_dir<=2);
perform_mc_concealment(decoder, PLANE_Y, enc_pic, image, pred_dir, i, j, block_size_x, block_size_y);
}
}
else //Need to change to support B slices.
{
for (block8x8 = 0; block8x8 < 4; block8x8++)
{
mv_mode = currMB->b8mode[block8x8];
pred_dir = currMB->b8pdir[block8x8];
if ( mv_mode != 0 )
{
k_start = (block8x8 << 2);
k_inc = (mv_mode == 5) ? 2 : 1;
k_end = (mv_mode == 4) ? k_start + 1 : ((mv_mode == 7) ? k_start + 4 : k_start + k_inc + 1);
block_size_x = ( mv_mode == 5 || mv_mode == 4 ) ? 8 : 4;
block_size_y = ( mv_mode == 6 || mv_mode == 4 ) ? 8 : 4;
for (k = k_start; k < k_end; k += k_inc)
{
i = (decode_block_scan[k] & 3);
j = ((decode_block_scan[k] >> 2) & 3);
perform_mc_concealment(decoder, PLANE_Y, enc_pic, image, pred_dir, i, j, block_size_x, block_size_y);
}
}
}
}
}
/*!
*************************************************************************************
* \brief
* Performs copy error concealment for macroblocks with errors.
* Note: Currently assumes that the reference picture lists remain the same for all
* slices of a picture.
*
*************************************************************************************
*/
void copy_conceal_picture(ImageParameters *image, StorablePicture *enc_pic, int decoder)
{
unsigned int mb;
Macroblock* currMB;
int mb_error;
byte** mb_error_map = enc_pic->mb_error_map[decoder];
StorablePicture* refPic;
refPic = find_nearest_ref_picture(enc_pic->poc); //Used for concealment if actual reference pic is not known.
for (mb = 0; mb < image->PicSizeInMbs; mb++)
{
image->mb_x = PicPos[mb][0];
image->mb_y = PicPos[mb][1];
mb_error = mb_error_map[image->mb_y][image->mb_x];
if (mb_error)
{
currMB = &image->mb_data[mb];
image->block_x = image->mb_x << 2;
image->block_y = image->mb_y << 2;
image->pix_x = image->block_x << 2;
image->pix_y = image->block_y << 2;
copy_conceal_mb(enc_pic, image, decoder, mb_error, currMB, refPic);
}
}
}
/******************************************************************************************
*
* Perform copy error concealment for macroblock.
*
*******************************************************************************************
*/
static void copy_conceal_mb(StorablePicture *enc_pic, ImageParameters* image, int decoder, int mb_error, Macroblock* currMB, StorablePicture* refPic)
{
int j, i0 = img->pix_x;
imgpel** concealed_img = &(enc_pic->p_dec_img[0][decoder][image->pix_y]);
imgpel** ref_img;
if (mb_error == 1 || (mb_error != 3 && currMB->mb_type > P8x8)) //All partitions lost, or intra mb lost
{
if (refPic != NULL) //Use nearest reference picture for concealment
{
ref_img = &(refPic->p_dec_img[0][decoder][img->pix_y]);
for (j = 0; j < MB_BLOCK_SIZE; j++)
{
memcpy(&(concealed_img[j][i0]), &(ref_img[j][i0]), sizeof(imgpel)*MB_BLOCK_SIZE);
}
}
else //No ref picture available
{
for (j = 0; j < MB_BLOCK_SIZE; j++)
{
memset(&(concealed_img[j][i0]), 128, sizeof(imgpel)*MB_BLOCK_SIZE); //Only reliable if sizeof(imgpel) = 1
}
}
}
else if (mb_error != 2 && image->type == P_SLICE && currMB->mb_type && currMB->mb_type < P8x8) //Only partition 3 lost, and P macroblock and not skip
{
get_predicted_concealment_mb(enc_pic, image, decoder, currMB);
for(j = 0; j < MB_BLOCK_SIZE; j++)
{
memcpy(&(concealed_img[j][i0]), &(image->mb_pred[j][0]), MB_BLOCK_SIZE * sizeof(imgpel));
}
}
}
/******************************************************************************************
*
* Finds reference picture with nearest POC to current picture to use for error concealment
*
*******************************************************************************************
*/
static StorablePicture* find_nearest_ref_picture(int poc)
{
unsigned int i;
int min_poc_diff = 1000;
int poc_diff;
StorablePicture* refPic = NULL;
for (i = 0; i < dpb.ref_frames_in_buffer; i++)
{
if (dpb.fs_ref[i]->is_used==3)
{
if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
{
poc_diff = iabs(dpb.fs_ref[i]->frame->poc - poc);
if (poc_diff < min_poc_diff)
{
refPic = dpb.fs_ref[i]->frame;
min_poc_diff = poc_diff;
}
}
}
}
return refPic;
}
/*!
*************************************************************************************
* \brief
* Gives the prediction residue for a block
*************************************************************************************
*/
void compute_residue_block (ImageParameters *image, imgpel **imgY, int res_img[16][16], imgpel mb_pred[16][16], int b8block, int block_size)
{
int i,j;
int i0 = (b8block & 0x01)<<3, i1 = i0+block_size;
int j0 = (b8block >> 1)<<3, j1 = j0+block_size;
//imgpel (*mb_pred)[16] = (i16mode >= 0) ? image->mpr_16x16[0][i16mode] : image->mb_pred[0];;
for (i = i0; i < i1; i++)
{
for (j = j0; j < j1; j++)
{
res_img[j][i] = (int)imgY[j][image->pix_x + i] - mb_pred[j][i];
}
}
}
/*!
*************************************************************************************
* \brief
* Stores the pel values for the current best mode.
*************************************************************************************
*/
void errdo_store_best_block(ImageParameters* image, imgpel*** mbY, imgpel*** dec_img, int i0, int j0, int block_size)
{
int j, k;
int i = image->pix_x + i0;
int j1 = j0 + block_size;
for (k = 0; k < params->NoOfDecoders; k++)
{
for (j = j0; j < j1; j++)
{
memcpy(&mbY[k][j][i0], &dec_img[k][image->pix_y + j][i], block_size * sizeof(imgpel));
}
}
}
/*!
*************************************************************************************
* \brief
* Restores the pel values from the current best 8x8 mode.
*************************************************************************************
*/
void errdo_get_best_block(ImageParameters* image, imgpel*** dec_img, imgpel*** mbY, int j0, int block_size)
{
int j, k;
int j1 = j0 + block_size;
for (k = 0; k < params->NoOfDecoders; k++)
{
for (j = j0; j < j1; j++)
{
memcpy(&dec_img[k][image->pix_y + j][image->pix_x], mbY[k][j], block_size * sizeof(imgpel));
}
}
}
/*!
*************************************************************************************
* \brief
* Builds a random status map showing whether each MB is received or lost, based
* on the packet loss rate and the slice structure.
*
* \param s_map
* The status map to be filled
*************************************************************************************
*/
static void Build_Status_Map(byte **s_map)
{
int i,j,slice=-1,mb=0,jj,ii,packet_lost=0;
jj = img->height/MB_BLOCK_SIZE;
ii = img->width/MB_BLOCK_SIZE;
for (j = 0; j < jj; j++)
{
for (i = 0; i < ii; i++)
{
if (!params->slice_mode || img->mb_data[mb].slice_nr != slice) /* new slice */
{
packet_lost=0;
if ((double)rand()/(double)RAND_MAX*100 < params->LossRateC) packet_lost += 3;
if ((double)rand()/(double)RAND_MAX*100 < params->LossRateB) packet_lost += 2;
if ((double)rand()/(double)RAND_MAX*100 < params->LossRateA) packet_lost = 1;
slice++;
}
if (!packet_lost)
{
s_map[j][i]=0; //! Packet OK
}
else
{
s_map[j][i]=packet_lost;
if(params->partition_mode == 0) s_map[j][i]=1;
}
mb++;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -