00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "global.h"
00023 #include "memalloc.h"
00024 #include "refbuf.h"
00025 #include "image.h"
00026 #include "errdo.h"
00027 #include "errdo_mc_prediction.h"
00028
00029 Decoders *decs = NULL;
00030
00031 static StorablePicture* find_nearest_ref_picture(int poc);
00032 static void copy_conceal_mb (StorablePicture *enc_pic, ImageParameters* image, int decoder, int mb_error, Macroblock* currMB, StorablePicture* refPic);
00033 static void get_predicted_mb(StorablePicture *enc_pic, ImageParameters* image, int decoder, Macroblock* currMB);
00034 static void add_residue (StorablePicture *enc_pic, ImageParameters* image, int decoder, int pl, int block8x8, int x_size, int y_size);
00035 static void Build_Status_Map(byte **s_map);
00036
00037 extern void DeblockFrame(ImageParameters *img, imgpel **, imgpel ***);
00038
00039
00040
00041
00042
00043
00044
00045 int allocate_errdo_mem(InputParameters *pparams)
00046 {
00047 int memory_size = 0;
00048
00049 decs = (Decoders *) malloc(sizeof(Decoders));
00050
00051 decs->dec_mb_pred = NULL;
00052 decs->dec_mbY_best = NULL;
00053 decs->dec_mb_pred_best8x8 = NULL;
00054 decs->dec_mbY_best8x8 = NULL;
00055 decs->res_img = NULL;
00056 memory_size += get_mem3Dpel(&decs->dec_mb_pred, pparams->NoOfDecoders, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00057 memory_size += get_mem3Dpel(&decs->dec_mbY_best, pparams->NoOfDecoders, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00058 memory_size += get_mem4Dpel(&decs->dec_mbY_best8x8, 2, pparams->NoOfDecoders, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00059 memory_size += get_mem4Dpel(&decs->dec_mb_pred_best8x8, 2, pparams->NoOfDecoders, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00060 memory_size += get_mem3Dint(&decs->res_img, MAX_PLANE, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00061
00062 return memory_size;
00063 }
00064
00065
00066
00067
00068
00069
00070
00071 void free_errdo_mem(void)
00072 {
00073 if (decs->res_img)
00074 {
00075 free_mem3Dint(decs->res_img);
00076 }
00077 if (decs->dec_mb_pred)
00078 {
00079 free_mem3Dpel(decs->dec_mb_pred);
00080 }
00081 if (decs->dec_mbY_best)
00082 {
00083 free_mem3Dpel(decs->dec_mbY_best);
00084 }
00085 if (decs->dec_mbY_best8x8)
00086 {
00087 free_mem4Dpel(decs->dec_mbY_best8x8);
00088 }
00089 if (decs->dec_mb_pred_best8x8)
00090 {
00091 free_mem4Dpel(decs->dec_mb_pred_best8x8);
00092 }
00093
00094 if ( decs != NULL )
00095 free( decs );
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 void decode_one_mb (ImageParameters *image, StorablePicture *enc_pic, int decoder, Macroblock* currMB)
00110 {
00111 int i0, j;
00112 static imgpel** curComp;
00113 static imgpel** oldComp;
00114
00115 if (currMB->mb_type > P8x8)
00116 {
00117 curComp = &enc_pic->p_dec_img[0][decoder][image->pix_y];
00118 oldComp = &enc_pic->p_curr_img[image->pix_y];
00119 i0 = image->pix_x;
00120 for (j = 0; j < MB_BLOCK_SIZE; j++)
00121 {
00122 memcpy(&(curComp[j][i0]), &(oldComp[j][i0]), MB_BLOCK_SIZE*sizeof(imgpel));
00123 }
00124 }
00125 else if ((currMB->mb_type == 0) && (img->type != B_SLICE))
00126 {
00127 get_predicted_mb(enc_pic, image, decoder, currMB);
00128 curComp = &enc_pic->p_dec_img[0][decoder][image->pix_y];
00129 for(j = 0; j < image->mb_size[0][1]; j++)
00130 {
00131 memcpy(&(curComp[j][image->pix_x]), &(decs->dec_mb_pred[decoder][j][0]), image->mb_size[0][0] * sizeof(imgpel));
00132 }
00133 }
00134 else
00135 {
00136 get_predicted_mb(enc_pic, image, decoder, currMB);
00137 add_residue(enc_pic, image, decoder, PLANE_Y, 0, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00138 }
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148 static void get_predicted_mb(StorablePicture *enc_pic, ImageParameters* image, int decoder, Macroblock* currMB)
00149 {
00150 int i,j,k;
00151 int block_size_x, block_size_y;
00152 int mv_mode, pred_dir;
00153 static const byte decode_block_scan[16] = {0,1,4,5,2,3,6,7,8,9,12,13,10,11,14,15};
00154 int block8x8;
00155 int k_start, k_end, k_inc;
00156
00157 if (img->type == P_SLICE && !currMB->mb_type)
00158 {
00159 block_size_x = MB_BLOCK_SIZE;
00160 block_size_y = MB_BLOCK_SIZE;
00161 perform_mc(decoder, PLANE_Y, enc_pic, image, currMB, LIST_0, 0, 0, enc_pic->motion.ref_idx, 0, 0, block_size_x, block_size_y, 0);
00162 }
00163 else if (currMB->mb_type == 1)
00164 {
00165 block_size_x = MB_BLOCK_SIZE;
00166 block_size_y = MB_BLOCK_SIZE;
00167 pred_dir = currMB->b8pdir[0];
00168 perform_mc(decoder, PLANE_Y, enc_pic, image, currMB, pred_dir, 1, 1, enc_pic->motion.ref_idx, 0, 0, block_size_x, block_size_y, currMB->bipred_me[0]);
00169 }
00170 else if (currMB->mb_type == 2)
00171 {
00172 block_size_x = MB_BLOCK_SIZE;
00173 block_size_y = 8;
00174
00175 for (block8x8 = 0; block8x8 < 4; block8x8 += 2)
00176 {
00177 pred_dir = currMB->b8pdir[block8x8];
00178 perform_mc(decoder, PLANE_Y, enc_pic, image, currMB, pred_dir, 2, 2, enc_pic->motion.ref_idx, 0, block8x8, block_size_x, block_size_y, currMB->bipred_me[block8x8]);
00179 }
00180 }
00181 else if (currMB->mb_type == 3)
00182 {
00183 block_size_x = 8;
00184 block_size_y = 16;
00185
00186 for (block8x8 = 0; block8x8 < 2; block8x8++)
00187 {
00188 i = block8x8<<1;
00189 j = 0;
00190 pred_dir = currMB->b8pdir[block8x8];
00191 perform_mc(decoder, PLANE_Y, enc_pic, image, currMB, pred_dir, 3, 3, enc_pic->motion.ref_idx, i, j, block_size_x, block_size_y, currMB->bipred_me[block8x8]);
00192 }
00193 }
00194 else
00195 {
00196 for (block8x8 = 0; block8x8 < 4; block8x8++)
00197 {
00198 mv_mode = currMB->b8mode[block8x8];
00199 pred_dir = currMB->b8pdir[block8x8];
00200
00201 k_start = (block8x8 << 2);
00202 k_inc = (mv_mode == 5) ? 2 : 1;
00203
00204 if (mv_mode == 0)
00205 {
00206 k_end = k_start + 1;
00207 block_size_x = 8;
00208 block_size_y = 8;
00209 }
00210 else
00211 {
00212 k_end = (mv_mode == 4) ? k_start + 1 : ((mv_mode == 7) ? k_start + 4 : k_start + k_inc + 1);
00213 block_size_x = ( mv_mode == 5 || mv_mode == 4 ) ? 8 : 4;
00214 block_size_y = ( mv_mode == 6 || mv_mode == 4 ) ? 8 : 4;
00215 }
00216
00217 for (k = k_start; k < k_end; k += k_inc)
00218 {
00219 i = (decode_block_scan[k] & 3);
00220 j = ((decode_block_scan[k] >> 2) & 3);
00221 perform_mc(decoder, PLANE_Y, enc_pic, image, currMB, pred_dir, mv_mode, mv_mode, enc_pic->motion.ref_idx, i, j, block_size_x, block_size_y, currMB->bipred_me[block8x8]);
00222 }
00223 }
00224 }
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 void decode_one_b8block (ImageParameters *image, StorablePicture *enc_pic, Macroblock* currMB, int decoder, int block8x8, short mv_mode, int pred_dir)
00240 {
00241 int i,j,k;
00242 int block_size_x, block_size_y;
00243 int i0 = (block8x8 & 0x01)<<3;
00244 int j0 = (block8x8 >> 1)<<3, j1 = j0+8;
00245 char*** ref_idx_buf = enc_pic->motion.ref_idx;
00246 imgpel **curComp;
00247 imgpel **oldComp;
00248 int k_start, k_end, k_inc;
00249 static const byte decode_block_scan[16] = {0,1,4,5,2,3,6,7,8,9,12,13,10,11,14,15};
00250
00251 if (mv_mode > 8)
00252 {
00253 for(j = j0; j < j1; j++)
00254 {
00255 curComp = &enc_pic->p_dec_img[0][decoder][image->pix_y];
00256 oldComp = &enc_pic->p_curr_img[image->pix_y];
00257 memcpy(&(curComp[j][i0]), &(oldComp[j][i0]), sizeof(imgpel)*8);
00258 }
00259 }
00260 else
00261 {
00262 k_start = (block8x8 << 2);
00263
00264 if (mv_mode == 0)
00265 {
00266 k_inc = 1;
00267 k_end = k_start+1;
00268 block_size_x = 8;
00269 block_size_y = 8;
00270 ref_idx_buf = direct_ref_idx;
00271 }
00272 else
00273 {
00274 k_inc = (mv_mode == 5) ? 2 : 1;
00275 k_end = (mv_mode == 4) ? k_start + 1 : ((mv_mode == 7) ? k_start + 4 : k_start + k_inc + 1);
00276
00277 block_size_x = ( mv_mode == 5 || mv_mode == 4 ) ? 8 : 4;
00278 block_size_y = ( mv_mode == 6 || mv_mode == 4 ) ? 8 : 4;
00279 }
00280
00281 for (k = k_start; k < k_end; k += k_inc)
00282 {
00283 i = (decode_block_scan[k] & 3);
00284 j = ((decode_block_scan[k] >> 2) & 3);
00285 perform_mc(decoder, PLANE_Y, enc_pic, image, currMB, pred_dir, mv_mode, mv_mode, ref_idx_buf, i, j, block_size_x, block_size_y, currMB->bipred_me[block8x8]);
00286 }
00287
00288 add_residue(enc_pic, image, decoder, PLANE_Y, block8x8, 8, 8);
00289 }
00290 }
00291
00292
00293
00294
00295
00296
00297
00298 static void add_residue (StorablePicture *enc_pic, ImageParameters* image, int decoder, int pl, int block8x8, int x_size, int y_size)
00299 {
00300 int i,j;
00301 int i0 = (block8x8 & 0x01)<<3, i1 = i0 + x_size;
00302 int j0 = (block8x8 >> 1)<<3, j1 = j0 + y_size;
00303
00304 imgpel **p_dec_img = &enc_pic->p_dec_img[pl][decoder][image->pix_y];
00305 int **res_img = decs->res_img[0];
00306 imgpel** mpr = decs->dec_mb_pred[decoder];
00307
00308 for (j = j0; j < j1; j++)
00309 {
00310 for (i = i0; i < i1; i++)
00311 {
00312 p_dec_img[j][image->pix_x+i] = iClip3(0, image->max_imgpel_value_comp[pl], (mpr[j][i] + res_img[j][i]));
00313 }
00314 }
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 void UpdateDecoders(InputParameters *params, ImageParameters *image, StorablePicture *enc_pic)
00326 {
00327 int k;
00328 for (k = 0; k < params->NoOfDecoders; k++)
00329 {
00330 Build_Status_Map(enc_pic->mb_error_map[k]);
00331 error_conceal_picture(image, enc_pic, k);
00332 DeblockFrame (image, enc_pic->p_dec_img[0][k], NULL);
00333 }
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 void init_error_conceal(int concealment_type)
00346 {
00347 error_conceal_picture = copy_conceal_picture;
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 static void get_predicted_concealment_mb(StorablePicture* enc_pic, ImageParameters* image, int decoder, Macroblock* currMB)
00360 {
00361 int i,j,k;
00362 int block_size_x, block_size_y;
00363 int mv_mode, pred_dir;
00364 static const byte decode_block_scan[16] = {0,1,4,5,2,3,6,7,8,9,12,13,10,11,14,15};
00365 int block8x8;
00366 int k_start, k_end, k_inc;
00367
00368 if (img->type == P_SLICE && !currMB->mb_type)
00369 {
00370 block_size_x = MB_BLOCK_SIZE;
00371 block_size_y = MB_BLOCK_SIZE;
00372 perform_mc_concealment(decoder, PLANE_Y, enc_pic, image, currMB, LIST_0, 0, 0, enc_pic->motion.ref_idx, 0, 0, block_size_x, block_size_y);
00373 }
00374 else if (currMB->mb_type == 1)
00375 {
00376 block_size_x = MB_BLOCK_SIZE;
00377 block_size_y = MB_BLOCK_SIZE;
00378 pred_dir = currMB->b8pdir[0];
00379 perform_mc_concealment(decoder, PLANE_Y, enc_pic, image, currMB, pred_dir, 1, 1, enc_pic->motion.ref_idx, 0, 0, block_size_x, block_size_y);
00380 }
00381 else if (currMB->mb_type == 2)
00382 {
00383 block_size_x = MB_BLOCK_SIZE;
00384 block_size_y = 8;
00385
00386 for (block8x8 = 0; block8x8 < 4; block8x8 += 2)
00387 {
00388 pred_dir = currMB->b8pdir[block8x8];
00389 perform_mc_concealment(decoder, PLANE_Y, enc_pic, image, currMB, pred_dir, 2, 2, enc_pic->motion.ref_idx, 0, block8x8, block_size_x, block_size_y);
00390 }
00391 }
00392 else if (currMB->mb_type == 3)
00393 {
00394 block_size_x = 8;
00395 block_size_y = 16;
00396
00397 for (block8x8 = 0; block8x8 < 2; block8x8++)
00398 {
00399 i = block8x8<<1;
00400 j = 0;
00401 pred_dir = currMB->b8pdir[block8x8];
00402 perform_mc_concealment(decoder, PLANE_Y, enc_pic, image, currMB, pred_dir, 3, 3, enc_pic->motion.ref_idx, i, j, block_size_x, block_size_y);
00403 }
00404 }
00405 else
00406 {
00407 for (block8x8 = 0; block8x8 < 4; block8x8++)
00408 {
00409 mv_mode = currMB->b8mode[block8x8];
00410 pred_dir = currMB->b8pdir[block8x8];
00411
00412 k_start = (block8x8 << 2);
00413 k_inc = (mv_mode == 5) ? 2 : 1;
00414
00415 if (mv_mode == 0)
00416 {
00417 k_end = k_start + 1;
00418 block_size_x = 8;
00419 block_size_y = 8;
00420 }
00421 else
00422 {
00423 k_end = (mv_mode == 4) ? k_start + 1 : ((mv_mode == 7) ? k_start + 4 : k_start + k_inc + 1);
00424 block_size_x = ( mv_mode == 5 || mv_mode == 4 ) ? 8 : 4;
00425 block_size_y = ( mv_mode == 6 || mv_mode == 4 ) ? 8 : 4;
00426 }
00427
00428 for (k = k_start; k < k_end; k += k_inc)
00429 {
00430 i = (decode_block_scan[k] & 3);
00431 j = ((decode_block_scan[k] >> 2) & 3);
00432 perform_mc_concealment(decoder, PLANE_Y, enc_pic, image, currMB, pred_dir, mv_mode, mv_mode, enc_pic->motion.ref_idx, i, j, block_size_x, block_size_y);
00433 }
00434 }
00435 }
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 void copy_conceal_picture(ImageParameters *image, StorablePicture *enc_pic, int decoder)
00448 {
00449 unsigned int mb;
00450 Macroblock* currMB;
00451 int mb_error;
00452 byte** mb_error_map = enc_pic->mb_error_map[decoder];
00453 StorablePicture* refPic;
00454
00455 refPic = find_nearest_ref_picture(enc_pic->poc);
00456
00457 for (mb = 0; mb < image->PicSizeInMbs; mb++)
00458 {
00459 image->mb_x = PicPos[mb][0];
00460 image->mb_y = PicPos[mb][1];
00461 mb_error = mb_error_map[image->mb_y][image->mb_x];
00462 if (mb_error)
00463 {
00464 currMB = &image->mb_data[mb];
00465 image->block_x = image->mb_x << 2;
00466 image->block_y = image->mb_y << 2;
00467 image->pix_x = image->block_x << 2;
00468 image->pix_y = image->block_y << 2;
00469 copy_conceal_mb(enc_pic, image, decoder, mb_error, currMB, refPic);
00470 }
00471 }
00472 }
00473
00474
00475
00476
00477
00478
00479
00480 static void copy_conceal_mb(StorablePicture *enc_pic, ImageParameters* image, int decoder, int mb_error, Macroblock* currMB, StorablePicture* refPic)
00481 {
00482 int j, i0 = img->pix_x;
00483 imgpel** concealed_img = &(enc_pic->p_dec_img[0][decoder][image->pix_y]);
00484 imgpel** ref_img;
00485
00486 if (mb_error == 1 || (mb_error != 3 && currMB->mb_type > P8x8))
00487 {
00488 if (refPic != NULL)
00489 {
00490 ref_img = &(refPic->p_dec_img[0][decoder][img->pix_y]);
00491 for (j = 0; j < MB_BLOCK_SIZE; j++)
00492 {
00493 memcpy(&(concealed_img[j][i0]), &(ref_img[j][i0]), sizeof(imgpel)*MB_BLOCK_SIZE);
00494 }
00495 }
00496 else
00497 {
00498 for (j = 0; j < MB_BLOCK_SIZE; j++)
00499 {
00500 memset(&(concealed_img[j][i0]), 128, sizeof(imgpel)*MB_BLOCK_SIZE);
00501 }
00502 }
00503 }
00504 else if (mb_error != 2 && image->type != I_SLICE && currMB->mb_type < P8x8)
00505 {
00506 get_predicted_concealment_mb(enc_pic, image, decoder, currMB);
00507 for(j = 0; j < MB_BLOCK_SIZE; j++)
00508 {
00509 memcpy(&(concealed_img[j][i0]), &(decs->dec_mb_pred[decoder][j][0]), MB_BLOCK_SIZE * sizeof(imgpel));
00510 }
00511 }
00512 }
00513
00514
00515
00516
00517
00518
00519
00520 static StorablePicture* find_nearest_ref_picture(int poc)
00521 {
00522 unsigned int i;
00523 int min_poc_diff = 1000;
00524 int poc_diff;
00525 StorablePicture* refPic = NULL;
00526
00527 for (i = 0; i < dpb.ref_frames_in_buffer; i++)
00528 {
00529 if (dpb.fs_ref[i]->is_used==3)
00530 {
00531 if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
00532 {
00533 poc_diff = iabs(dpb.fs_ref[i]->frame->poc - poc);
00534 if (poc_diff < min_poc_diff)
00535 {
00536 refPic = dpb.fs_ref[i]->frame;
00537 min_poc_diff = poc_diff;
00538 }
00539 }
00540 }
00541 }
00542 return refPic;
00543 }
00544
00545
00546
00547
00548
00549
00550
00551 void compute_residue_block (ImageParameters *image, imgpel **imgY, int **res_img, imgpel **mb_pred, int b8block, int block_size)
00552 {
00553 int i,j;
00554 int i0 = (b8block & 0x01)<<3, i1 = i0+block_size;
00555 int j0 = (b8block >> 1)<<3, j1 = j0+block_size;
00556
00557 for (i = i0; i < i1; i++)
00558 {
00559 for (j = j0; j < j1; j++)
00560 {
00561 res_img[j][i] = (int)imgY[j][image->pix_x + i] - mb_pred[j][i];
00562 }
00563 }
00564 }
00565
00566
00567
00568
00569
00570
00571
00572 void errdo_store_best_block(imgpel*** mbY, imgpel*** dec_img, int block_i, int block_j, int img_i, int img_j, int block_size)
00573
00574 {
00575 int j, k;
00576 int j1 = block_j + block_size;
00577
00578 for (k = 0; k < params->NoOfDecoders; k++)
00579 {
00580 for (j = block_j; j < j1; j++)
00581 {
00582 memcpy(&mbY[k][j][block_i], &dec_img[k][img_j+j][img_i], block_size * sizeof(imgpel));
00583 }
00584 }
00585 }
00586
00587
00588
00589
00590
00591
00592
00593 void errdo_get_best_block(ImageParameters* image, imgpel*** dec_img, imgpel*** mbY, int j0, int block_size)
00594 {
00595 int j, k;
00596 int j1 = j0 + block_size;
00597
00598 for (k = 0; k < params->NoOfDecoders; k++)
00599 {
00600 for (j = j0; j < j1; j++)
00601 {
00602 memcpy(&dec_img[k][image->pix_y + j][image->pix_x], mbY[k][j], block_size * sizeof(imgpel));
00603 }
00604 }
00605 }
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617 static void Build_Status_Map(byte **s_map)
00618 {
00619 int i,j,slice=-1,mb=0,jj,ii,packet_lost=0;
00620
00621 jj = img->height/MB_BLOCK_SIZE;
00622 ii = img->width/MB_BLOCK_SIZE;
00623
00624 for (j = 0; j < jj; j++)
00625 {
00626 for (i = 0; i < ii; i++)
00627 {
00628 if (!params->slice_mode || img->mb_data[mb].slice_nr != slice)
00629 {
00630 packet_lost=0;
00631 if ((double)rand()/(double)RAND_MAX*100 < params->LossRateC) packet_lost += 3;
00632 if ((double)rand()/(double)RAND_MAX*100 < params->LossRateB) packet_lost += 2;
00633 if ((double)rand()/(double)RAND_MAX*100 < params->LossRateA) packet_lost = 1;
00634 slice++;
00635 }
00636 if (!packet_lost)
00637 {
00638 s_map[j][i]=0;
00639 }
00640 else
00641 {
00642 s_map[j][i]=packet_lost;
00643 if(params->partition_mode == 0) s_map[j][i]=1;
00644 }
00645 mb++;
00646 }
00647 }
00648 }
00649