00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <math.h>
00019 #include <limits.h>
00020
00021 #include "global.h"
00022
00023 #include "rdopt.h"
00024 #include "q_around.h"
00025 #include "rdopt_coding_state.h"
00026 #include "memalloc.h"
00027 #include "mb_access.h"
00028 #include "elements.h"
00029 #include "intrarefresh.h"
00030 #include "image.h"
00031 #include "transform8x8.h"
00032 #include "cabac.h"
00033 #include "biariencode.h"
00034 #include "vlc.h"
00035 #include "me_umhex.h"
00036 #include "ratectl.h"
00037 #include "mode_decision.h"
00038 #include "rd_intra_jm.h"
00039 #include "fmo.h"
00040 #include "macroblock.h"
00041 #include "symbol.h"
00042 #include "q_offsets.h"
00043 #include "conformance.h"
00044 #include "errdo.h"
00045 #include "mv-search.h"
00046 #include "md_common.h"
00047
00048 #define FASTMODE 1
00049
00050 static int diff[16];
00051 static int diff4x4[64];
00052 static int diff8x8[64];
00053 RD_8x8DATA tr4x4, tr8x8;
00054 imgpel ***rec8x8 = NULL;
00055 imgpel ***rec4x4 = NULL;
00056 imgpel ***rec4x4CbCr = NULL;
00057 imgpel **pred = NULL;
00058 imgpel **rec_mbY = NULL, ***rec_mb_cr = NULL;
00059 static int **lrec_rec = NULL, ***lrec_rec_uv = NULL;
00060
00061
00062 int ****cofAC = NULL;
00063 int ***cofDC = NULL;
00064 int **cofAC4x4 = NULL, ****cofAC4x4intern = NULL;
00065 int cbp, cbp8x8, cnt_nonz_8x8;
00066 int cbp_blk8x8;
00067 char **l0_refframe, **l1_refframe;
00068 short b8mode[4], b8pdir[4], b8bipred_me[4];
00069
00070 CSptr cs_mb=NULL, cs_b8=NULL, cs_cm=NULL, cs_ib8=NULL, cs_ib4=NULL;
00071 int best_c_imode;
00072 int best_i16offset;
00073 short best_mode;
00074
00075
00076
00077 int luma_transform_size_8x8_flag;
00078
00079 short *****all_mv8x8 = NULL;
00080
00081 int *****cofAC4x4CbCrintern = NULL;
00082 int *****cofAC8x8ts = NULL;
00083 int *****coefAC8x8 = NULL;
00084 int **cofAC4x4CbCr[2];
00085
00086
00087 int64 cbp_blk8_8x8ts;
00088 int cbp8_8x8ts;
00089 int cost8_8x8ts;
00090 int cnt_nonz8_8x8ts;
00091
00092
00093 double mb16x16_cost;
00094 double lambda_mf_factor;
00095
00096 void StoreMV8x8(int dir);
00097 void RestoreMV8x8(int dir);
00098
00099
00100 char b4_ipredmode[16], b4_intra_pred_modes[16];
00101
00102
00103 void alloc_rd8x8data (RD_8x8DATA *rd_data)
00104 {
00105 get_mem2Dint(&rd_data->lrec, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00106 get_mem2Dpel(&rd_data->mpr8x8, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00107 get_mem3Dpel(&rd_data->mpr8x8CbCr, 2, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00108 get_mem2Dpel(&rd_data->rec_mbY8x8, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00109 get_mem3Dpel(&rd_data->rec_mb8x8_cr, 2, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00110 }
00111
00112 void free_rd8x8data (RD_8x8DATA *rd_data)
00113 {
00114 free_mem3Dpel(rd_data->rec_mb8x8_cr);
00115 free_mem2Dpel(rd_data->rec_mbY8x8);
00116 free_mem3Dpel(rd_data->mpr8x8CbCr);
00117 free_mem2Dpel(rd_data->mpr8x8);
00118 free_mem2Dint(rd_data->lrec);
00119 }
00120
00121
00122
00123
00124
00125
00126
00127 void clear_rdopt (InputParameters *params)
00128 {
00129 free_mem_DCcoeff (cofDC);
00130 free_mem_ACcoeff (cofAC);
00131 free_mem_ACcoeff (cofAC4x4intern);
00132 free_mem_ACcoeff_new(coefAC8x8);
00133
00134 if (params->Transform8x8Mode)
00135 {
00136 free_mem_ACcoeff_new(cofAC8x8ts);
00137 }
00138
00139 {
00140
00141 free_mem_ACcoeff_new(cofAC4x4CbCrintern);
00142 }
00143
00144
00145 free_rd8x8data(&tr4x4);
00146 free_rd8x8data(&tr8x8);
00147
00148 free_mem5Dshort(all_mv8x8);
00149
00150 free_mem3Dpel(rec4x4CbCr);
00151 free_mem3Dpel(rec4x4);
00152 free_mem3Dpel(rec8x8);
00153 free_mem2Dpel(pred);
00154 free_mem2Dpel(rec_mbY);
00155 free_mem3Dpel(rec_mb_cr);
00156
00157 free_mem2Dint(lrec_rec);
00158 free_mem3Dint(lrec_rec_uv);
00159 free_mem2D((byte **) l0_refframe);
00160 free_mem2D((byte **) l1_refframe);
00161
00162
00163 delete_coding_state (cs_mb);
00164 delete_coding_state (cs_b8);
00165 delete_coding_state (cs_cm);
00166 delete_coding_state (cs_ib8);
00167 delete_coding_state (cs_ib4);
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177 void init_rdopt (InputParameters *params)
00178 {
00179 rdopt = NULL;
00180
00181 get_mem_DCcoeff (&cofDC);
00182 get_mem_ACcoeff (&cofAC);
00183 get_mem_ACcoeff (&cofAC4x4intern);
00184 cofAC4x4 = cofAC4x4intern[0][0];
00185 get_mem_ACcoeff_new(&coefAC8x8, 3);
00186
00187 if (params->Transform8x8Mode)
00188 {
00189 get_mem_ACcoeff_new(&cofAC8x8ts, 3);
00190 }
00191
00192 alloc_rd8x8data(&tr4x4);
00193 alloc_rd8x8data(&tr8x8);
00194
00195 get_mem2Dpel(&pred, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00196 get_mem3Dpel(&rec8x8, 3, BLOCK_SIZE_8x8, BLOCK_SIZE_8x8);
00197 get_mem3Dpel(&rec4x4, 3, BLOCK_SIZE, BLOCK_SIZE);
00198 get_mem3Dpel(&rec4x4CbCr, 2, BLOCK_SIZE, BLOCK_SIZE);
00199 get_mem2Dpel(&rec_mbY, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00200 get_mem3Dpel(&rec_mb_cr, 2, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00201 get_mem2Dint(&lrec_rec, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00202 get_mem3Dint(&lrec_rec_uv, 2, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00203 get_mem2D((byte ***) &l0_refframe, 4, 4);
00204 get_mem2D((byte ***) &l1_refframe, 4, 4);
00205
00206 get_mem5Dshort(&all_mv8x8, 2, 2, 4, 4, 2);
00207
00208
00209 {
00210
00211 get_mem_ACcoeff_new(&cofAC4x4CbCrintern, 2);
00212
00213 cofAC4x4CbCr[0] = cofAC4x4CbCrintern[0][0][0];
00214 cofAC4x4CbCr[1] = cofAC4x4CbCrintern[0][1][0];
00215 }
00216
00217 SetLagrangianMultipliers = params->rdopt == 0 ? SetLagrangianMultipliersOff : SetLagrangianMultipliersOn;
00218
00219 switch (params->rdopt)
00220 {
00221 case 0:
00222 encode_one_macroblock = encode_one_macroblock_low;
00223 break;
00224 case 1:
00225 default:
00226 encode_one_macroblock = encode_one_macroblock_high;
00227 break;
00228 case 2:
00229 encode_one_macroblock = encode_one_macroblock_highfast;
00230 break;
00231 case 3:
00232 encode_one_macroblock = encode_one_macroblock_highloss;
00233 break;
00234 }
00235
00236
00237 cs_mb = create_coding_state ();
00238 cs_b8 = create_coding_state ();
00239 cs_cm = create_coding_state ();
00240 cs_ib8 = create_coding_state ();
00241 cs_ib4 = create_coding_state ();
00242
00243 if (params->CtxAdptLagrangeMult == 1)
00244 {
00245 mb16x16_cost = CALM_MF_FACTOR_THRESHOLD;
00246 lambda_mf_factor = 1.0;
00247 }
00248
00249 if (params->rdopt == 0)
00250 {
00251 Mode_Decision_for_8x8IntraBlocks = Mode_Decision_for_8x8IntraBlocks_JM_Low;
00252 Mode_Decision_for_4x4IntraBlocks = Mode_Decision_for_4x4IntraBlocks_JM_Low;
00253 }
00254 else
00255 {
00256 Mode_Decision_for_8x8IntraBlocks = Mode_Decision_for_8x8IntraBlocks_JM_High;
00257 Mode_Decision_for_4x4IntraBlocks = Mode_Decision_for_4x4IntraBlocks_JM_High;
00258 }
00259 find_sad_16x16 = find_sad_16x16_JM;
00260 getDistortion = distortionSSE;
00261
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 void UpdatePixelMap()
00276 {
00277 int mx,my,y,x,i,j;
00278 if (img->type==I_SLICE)
00279 {
00280 memset(pixel_map, 1, img->height * img->width * sizeof(byte));
00281 }
00282 else
00283 {
00284 for (my=0; my<img->height >> 3; my++)
00285 for (mx=0; mx<img->width >> 3; mx++)
00286 {
00287 j = my*8 + 8;
00288 i = mx*8 + 8;
00289 if (refresh_map[my][mx])
00290 {
00291 for (y=my*8; y<j; y++)
00292 memset(&pixel_map[y][mx*8], 1, 8 * sizeof(byte));
00293 }
00294 else
00295 {
00296 for (y=my*8; y<j; y++)
00297 for (x=mx*8; x<i; x++)
00298 {
00299 pixel_map[y][x] = imin(pixel_map[y][x] + 1, params->num_ref_frames+1);
00300 }
00301 }
00302 }
00303 }
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 int CheckReliabilityOfRef (int block, int list_idx, int ref, int mode)
00325 {
00326 int y,x, block_y, block_x, dy, dx, y_pos, x_pos, yy, xx, pres_x, pres_y;
00327 int maxold_x = img->width-1;
00328 int maxold_y = img->height-1;
00329 int ref_frame = ref + 1;
00330
00331 int by0 = (mode>=4?2*(block >> 1):mode==2?2*block:0);
00332 int by1 = by0 + (mode>=4||mode==2?2:4);
00333 int bx0 = (mode>=4?2*(block & 0x01):mode==3?2*block:0);
00334 int bx1 = bx0 + (mode>=4||mode==3?2:4);
00335
00336 for (block_y=by0; block_y<by1; block_y++)
00337 {
00338 for (block_x=bx0; block_x<bx1; block_x++)
00339 {
00340 y_pos = img->all_mv[list_idx][ref][mode][block_y][block_x][1];
00341 y_pos += (img->block_y + block_y) * BLOCK_SIZE * 4;
00342 x_pos = img->all_mv[list_idx][ref][mode][block_y][block_x][0];
00343 x_pos += (img->block_x + block_x) * BLOCK_SIZE * 4;
00344
00345
00346
00347
00348
00349 dy = y_pos & 3;
00350 dx = x_pos & 3;
00351
00352 y_pos = (y_pos - dy) >> 2;
00353 x_pos = (x_pos - dx) >> 2;
00354
00355 if (dy==0 && dx==0)
00356 {
00357 for (y=y_pos ; y < y_pos + BLOCK_SIZE ; y++)
00358 for (x=x_pos ; x < x_pos + BLOCK_SIZE ; x++)
00359 if (pixel_map[iClip3(0,maxold_y,y)][iClip3(0,maxold_x,x)] < ref_frame)
00360 return 0;
00361 }
00362 else
00363 {
00364 if (dy == 0)
00365 {
00366 for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
00367 {
00368 pres_y = iClip3(0, maxold_y, y);
00369 for (x = x_pos ; x < x_pos + BLOCK_SIZE ; x++)
00370 {
00371 for(xx = -2 ; xx < 4 ; xx++)
00372 {
00373 pres_x = iClip3(0, maxold_x, x + xx);
00374 if (pixel_map[pres_y][pres_x] < ref_frame)
00375 return 0;
00376 }
00377 }
00378 }
00379 }
00380 else if (dx == 0)
00381 {
00382 for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
00383 for (x=x_pos ; x < x_pos + BLOCK_SIZE ; x++)
00384 {
00385 pres_x = iClip3(0,maxold_x,x);
00386 for(yy=-2;yy<4;yy++)
00387 {
00388 pres_y = iClip3(0,maxold_y, yy + y);
00389 if (pixel_map[pres_y][pres_x] < ref_frame)
00390 return 0;
00391 }
00392 }
00393 }
00394 else if (dx == 2)
00395 {
00396 for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
00397 for (x = x_pos ; x < x_pos + BLOCK_SIZE ; x++)
00398 {
00399 for(yy=-2;yy<4;yy++)
00400 {
00401 pres_y = iClip3(0,maxold_y, yy + y);
00402 for(xx=-2;xx<4;xx++)
00403 {
00404 pres_x = iClip3(0,maxold_x, xx + x);
00405 if (pixel_map[pres_y][pres_x] < ref_frame)
00406 return 0;
00407 }
00408 }
00409 }
00410 }
00411 else if (dy == 2)
00412 {
00413 for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
00414 for (x = x_pos ; x < x_pos + BLOCK_SIZE ; x++)
00415 {
00416 for(xx=-2;xx<4;xx++)
00417 {
00418 pres_x = iClip3(0,maxold_x, xx + x);
00419 for(yy=-2;yy<4;yy++)
00420 {
00421 pres_y = iClip3(0,maxold_y, yy + y);
00422 if (pixel_map[pres_y][pres_x] < ref_frame)
00423 return 0;
00424 }
00425 }
00426 }
00427 }
00428 else
00429 {
00430 for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
00431 {
00432 for (x = x_pos ; x < x_pos + BLOCK_SIZE ; x++)
00433 {
00434 pres_y = dy == 1 ? y : y + 1;
00435 pres_y = iClip3(0,maxold_y,pres_y);
00436
00437 for(xx=-2;xx<4;xx++)
00438 {
00439 pres_x = iClip3(0,maxold_x,xx + x);
00440 if (pixel_map[pres_y][pres_x] < ref_frame)
00441 return 0;
00442 }
00443
00444 pres_x = dx == 1 ? x : x + 1;
00445 pres_x = iClip3(0,maxold_x,pres_x);
00446
00447 for(yy=-2;yy<4;yy++)
00448 {
00449 pres_y = iClip3(0,maxold_y, yy + y);
00450 if (pixel_map[pres_y][pres_x] < ref_frame)
00451 return 0;
00452 }
00453 }
00454 }
00455 }
00456 }
00457 }
00458 }
00459 return 1;
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 double RDCost_for_4x4IntraBlocks (Slice *currSlice,
00471 Macroblock *currMB,
00472 int* nonzero,
00473 int b8,
00474 int b4,
00475 int ipmode,
00476 double lambda,
00477 int mostProbableMode,
00478 int c_nzCbCr[3],
00479 int is_cavlc)
00480 {
00481 double rdcost;
00482 int dummy = 0, rate;
00483 int64 distortion = 0;
00484 int block_x = ((b8 & 0x01) << 3) + ((b4 & 0x01) << 2);
00485 int block_y = ((b8 >> 1) << 3) + ((b4 >> 1) << 2);
00486 int pic_pix_x = img->pix_x + block_x;
00487 int pic_pix_y = img->pix_y + block_y;
00488 int pic_opix_y = img->opix_y + block_y;
00489
00490 SyntaxElement se;
00491 const int *partMap = assignSE2partition[params->partition_mode];
00492 DataPartition *dataPart;
00493
00494
00495
00496 *nonzero = pDCT_4x4 (currMB, PLANE_Y, block_x, block_y, &dummy, 1, is_cavlc);
00497
00498
00499 distortion += compute_SSE(&pCurImg[pic_opix_y], &enc_picture->imgY[pic_pix_y], pic_pix_x, pic_pix_x, 4, 4);
00500
00501 if(img->P444_joined)
00502 {
00503 ColorPlane k;
00504 for (k = PLANE_U; k <= PLANE_V; k++)
00505 {
00506 select_plane(k);
00507 c_nzCbCr[k] = pDCT_4x4(currMB, k, block_x, block_y, &dummy, 1, is_cavlc);
00508 distortion += compute_SSE(&pCurImg[pic_opix_y], &enc_picture->p_curr_img[pic_pix_y], pic_pix_x, pic_pix_x, 4, 4);
00509 }
00510 select_plane(PLANE_Y);
00511 }
00512 ipmode_DPCM=NO_INTRA_PMODE;
00513
00514
00515 se.value1 = (mostProbableMode == ipmode) ? -1 : ipmode < mostProbableMode ? ipmode : ipmode - 1;
00516
00517
00518 se.context = (b8 << 2) + b4;
00519 se.type = SE_INTRAPREDMODE;
00520
00521
00522 dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
00523
00524 writeIntraPredMode (&se, dataPart);
00525 rate = se.len;
00526
00527
00528 if (is_cavlc)
00529 {
00530 rate += writeCoeff4x4_CAVLC (currSlice, currMB, LUMA, b8, b4, 0);
00531 if(img->P444_joined)
00532 {
00533 rate += writeCoeff4x4_CAVLC (currSlice, currMB, CB, b8, b4, 0);
00534 rate += writeCoeff4x4_CAVLC (currSlice, currMB, CR, b8, b4, 0);
00535 }
00536 }
00537 else
00538 {
00539 rate += writeCoeff4x4_CABAC (currSlice, currMB, PLANE_Y, b8, b4, 1);
00540 if(img->P444_joined)
00541 {
00542 rate += writeCoeff4x4_CABAC (currSlice, currMB, PLANE_U, b8, b4, 1);
00543 rate += writeCoeff4x4_CABAC (currSlice, currMB, PLANE_V, b8, b4, 1);
00544 }
00545 }
00546
00547 rdcost = (double)distortion + lambda * (double) rate;
00548
00549 return rdcost;
00550 }
00551
00552
00553
00554
00555
00556
00557
00558 double RDCost_for_8x8blocks (Slice *currSlice,
00559 Macroblock *currMB,
00560 int* cnt_nonz,
00561 int64* cbp_blk,
00562 double lambda,
00563 int block,
00564 int mode,
00565 short pdir,
00566 short l0_ref,
00567 short l1_ref,
00568 short bipred_me,
00569 int is_cavlc
00570 )
00571 {
00572 int k;
00573 int rate=0;
00574 int64 distortion=0;
00575 int dummy = 0, mrate;
00576 int fw_mode, bw_mode;
00577 int cbp = 0;
00578 int pax = 8*(block & 0x01);
00579 int pay = 8*(block >> 1);
00580 int i0 = pax >> 2;
00581 int j0 = pay >> 2;
00582 int bslice = (img->type==B_SLICE);
00583 int direct = (bslice && mode==0);
00584 int b8value = B8Mode2Value (mode, pdir);
00585
00586 SyntaxElement se;
00587 DataPartition *dataPart;
00588 const int *partMap = assignSE2partition[params->partition_mode];
00589
00590 EncodingEnvironmentPtr eep_dp;
00591
00592
00593
00594
00595 currMB->bipred_me[block] = bipred_me;
00596 currMB->ar_mode = (mode != 0)? mode: P8x8;
00597
00598
00599 if (direct)
00600 {
00601 if (direct_pdir[img->block_y + j0][img->block_x + i0] < 0)
00602 return (1e20);
00603 else
00604 *cnt_nonz = LumaResidualCoding8x8 (currMB, &cbp, cbp_blk, block, direct_pdir[img->block_y+j0][img->block_x+i0], 0, 0,
00605 (short)imax(0,direct_ref_idx[LIST_0][img->block_y+j0][img->block_x+i0]),
00606 direct_ref_idx[LIST_1][img->block_y+j0][img->block_x+i0], is_cavlc);
00607 }
00608 else
00609 {
00610 if (pdir == 2 && active_pps->weighted_bipred_idc == 1)
00611 {
00612 int weight_sum = (active_pps->weighted_bipred_idc == 1)? wbp_weight[0][l0_ref][l1_ref][0] + wbp_weight[1][l0_ref][l1_ref][0] : 0;
00613 if (weight_sum < -128 || weight_sum > 127)
00614 {
00615 return (1e20);
00616 }
00617 }
00618
00619 fw_mode = (pdir==0||pdir==2 ? mode : 0);
00620 bw_mode = (pdir==1||pdir==2 ? mode : 0);
00621 *cnt_nonz = LumaResidualCoding8x8 (currMB, &cbp, cbp_blk, block, pdir, fw_mode, bw_mode, l0_ref, l1_ref, is_cavlc);
00622 }
00623
00624 if(img->P444_joined)
00625 {
00626 *cnt_nonz += ( coeff_cost_cr[1] + coeff_cost_cr[2] );
00627 }
00628
00629
00630 if (params->rdopt==3)
00631 {
00632
00633
00634
00635 compute_residue_block (img, &enc_picture->p_img[0][img->pix_y], decs->res_img[0], img->mb_pred[0], block, 8);
00636
00637
00638
00639
00640 for (k=0; k<params->NoOfDecoders ;k++)
00641 {
00642 decode_one_b8block (img, enc_picture, currMB, k, block, mode, pdir);
00643 distortion += compute_SSE(&pCurImg[img->opix_y+pay], &enc_picture->p_dec_img[0][k][img->opix_y+pay], img->opix_x+pax, img->opix_x+pax, 8, 8);
00644 }
00645 distortion /= params->NoOfDecoders;
00646 }
00647 else
00648 {
00649 distortion += compute_SSE(&pCurImg[img->opix_y + pay], &enc_picture->imgY[img->pix_y + pay], img->opix_x + pax, img->pix_x + pax, 8, 8);
00650
00651 if (img->P444_joined)
00652 {
00653 distortion += compute_SSE(&pImgOrg[1][img->opix_y + pay], &enc_picture->imgUV[0][img->pix_y + pay], img->opix_x + pax, img->pix_x + pax, 8, 8);
00654 distortion += compute_SSE(&pImgOrg[2][img->opix_y + pay], &enc_picture->imgUV[1][img->pix_y + pay], img->opix_x + pax, img->pix_x + pax, 8, 8);
00655 }
00656 }
00657
00658 if(img->P444_joined)
00659 {
00660 cbp |= cmp_cbp[1];
00661 cbp |= cmp_cbp[2];
00662
00663 cmp_cbp[1] = cbp;
00664 cmp_cbp[2] = cbp;
00665 }
00666
00667
00668
00669
00670
00671 if (is_cavlc)
00672 {
00673 ue_linfo (b8value, dummy, &mrate, &dummy);
00674 rate += mrate;
00675 }
00676 else
00677 {
00678 se.value1 = b8value;
00679 se.type = SE_MBTYPE;
00680 dataPart = &(currSlice->partArr[partMap[se.type]]);
00681 writeB8_typeInfo(&se, dataPart);
00682 rate += se.len;
00683 }
00684
00685
00686 if (!direct)
00687 {
00688 if ((img->num_ref_idx_l0_active > 1 ) && (pdir==0 || pdir==2))
00689 rate += writeReferenceFrame (currSlice, currMB, mode, i0, j0, 1, l0_ref);
00690
00691 if ((img->num_ref_idx_l1_active > 1 && img->type== B_SLICE ) && (pdir==1 || pdir==2))
00692 {
00693 rate += writeReferenceFrame (currSlice, currMB, mode, i0, j0, 0, l1_ref);
00694 }
00695
00696 if (pdir==0 || pdir==2)
00697 {
00698 rate += writeMotionVector8x8 (currSlice, currMB, i0, j0, i0 + 2, j0 + 2, l0_ref, LIST_0, mode, currMB->bipred_me[block]);
00699 }
00700 if (pdir==1 || pdir==2)
00701 {
00702 rate += writeMotionVector8x8 (currSlice, currMB, i0, j0, i0 + 2, j0 + 2, l1_ref, LIST_1, mode, currMB->bipred_me[block]);
00703 }
00704 }
00705
00706
00707 if (!is_cavlc)
00708 {
00709 dataPart = &(currSlice->partArr[partMap[SE_CBP]]);
00710 eep_dp = &(dataPart->ee_cabac);
00711 mrate = arienco_bits_written (eep_dp);
00712 writeCBP_BIT_CABAC (currMB, block, ((*cnt_nonz>0)?1:0), cbp8x8, 1, eep_dp, img->currentSlice->tex_ctx);
00713 mrate = arienco_bits_written (eep_dp) - mrate;
00714 rate += mrate;
00715 }
00716
00717
00718 if (*cnt_nonz)
00719 {
00720 rate += writeCoeff8x8 ( currSlice, currMB, PLANE_Y, block, mode, currMB->luma_transform_size_8x8_flag);
00721 }
00722
00723 if(img->P444_joined)
00724 {
00725 rate += writeCoeff8x8( currSlice, currMB, PLANE_U, block, mode, currMB->luma_transform_size_8x8_flag );
00726 rate += writeCoeff8x8( currSlice, currMB, PLANE_V, block, mode, currMB->luma_transform_size_8x8_flag );
00727 }
00728
00729 return (double)distortion + lambda * (double)rate;
00730 }
00731
00732
00733
00734
00735
00736
00737
00738
00739 int I16Offset (int cbp, int i16mode)
00740 {
00741 return (cbp&15?13:1) + i16mode + ((cbp&0x30)>>2);
00742 }
00743
00744
00745
00746
00747
00748
00749
00750
00751 void SetModesAndRefframeForBlocks (Macroblock *currMB, int mode)
00752 {
00753 int i,j,k,l;
00754 int bslice = (img->type==B_SLICE);
00755 int block_x, block_y, block8x8, block4x4;
00756 int cur_ref;
00757 int clist;
00758 char cref[2], curref, bestref;
00759 Block8x8Info *b8x8info = img->b8x8info;
00760 PicMotionParams *motion = &enc_picture->motion;
00761
00762
00763 currMB->mb_type = mode;
00764
00765 for( i = 0; i < 4; i++)
00766 {
00767 currMB->bipred_me[i] = b8x8info->bipred8x8me[mode][i];
00768 }
00769
00770 currMB->ar_mode = mode;
00771
00772
00773 switch (mode)
00774 {
00775 case 0:
00776 memset(currMB->b8mode, 0, 4 * sizeof(short));
00777 if (bslice)
00778 {
00779 for(i=0;i<4;i++)
00780 {
00781 currMB->b8pdir[i] = direct_pdir[img->block_y + ((i >> 1)<<1)][img->block_x + ((i & 0x01)<<1)];
00782 }
00783 }
00784 else
00785 {
00786 memset(currMB->b8pdir, 0, 4 * sizeof(short));
00787 }
00788 break;
00789 case 1:
00790 case 2:
00791 case 3:
00792 for(i=0;i<4;i++)
00793 {
00794 currMB->b8mode[i] = mode;
00795 currMB->b8pdir[i] = b8x8info->best8x8pdir[mode][i];
00796 }
00797 break;
00798 case P8x8:
00799 memcpy(currMB->b8mode, b8x8info->best8x8mode, 4 * sizeof(short));
00800 for(i=0;i<4;i++)
00801 {
00802 currMB->b8pdir[i] = b8x8info->best8x8pdir[mode][i];
00803 }
00804 break;
00805 case I4MB:
00806 for(i=0;i<4;i++)
00807 {
00808 currMB->b8mode[i] = IBLOCK;
00809 currMB->b8pdir[i] = -1;
00810 }
00811 break;
00812 case I16MB:
00813 memset(currMB->b8mode, 0, 4 * sizeof(short));
00814 for(i=0;i<4;i++)
00815 {
00816 currMB->b8pdir[i] = -1;
00817 }
00818 break;
00819 case I8MB:
00820 for(i=0;i<4;i++)
00821 {
00822 currMB->b8mode[i] = I8MB;
00823 currMB->b8pdir[i] = -1;
00824 }
00825
00826 currMB->luma_transform_size_8x8_flag = 1;
00827 break;
00828 case IPCM:
00829 for(i=0;i<4;i++)
00830 {
00831 currMB->b8mode[i] = IPCM;
00832 currMB->b8pdir[i] = -1;
00833 }
00834 currMB->luma_transform_size_8x8_flag = 0;
00835 break;
00836 default:
00837 printf ("Unsupported mode in SetModesAndRefframeForBlocks!\n");
00838 exit (1);
00839 }
00840
00841 #define IS_FW ((b8x8info->best8x8pdir[mode][k]==0 || b8x8info->best8x8pdir[mode][k]==2) && (mode!=P8x8 || b8x8info->best8x8mode[k]!=0 || !bslice))
00842 #define IS_BW ((b8x8info->best8x8pdir[mode][k]==1 || b8x8info->best8x8pdir[mode][k]==2) && (mode!=P8x8 || b8x8info->best8x8mode[k]!=0))
00843
00844
00845 if (mode==0 || mode==I4MB || mode==I16MB || mode==I8MB)
00846 {
00847 if (bslice)
00848 {
00849 if (!mode)
00850 {
00851 for (clist = LIST_0; clist <= LIST_1; clist++)
00852 {
00853 for (j = img->block_y; j < img->block_y + 4; j++)
00854 {
00855 memcpy(&motion->ref_idx[clist][j][img->block_x], &direct_ref_idx[clist][j][img->block_x], 4 * sizeof(char));
00856 }
00857 }
00858 }
00859 else
00860 {
00861 for (clist = LIST_0; clist <= LIST_1; clist++)
00862 {
00863 for (j = img->block_y; j < img->block_y + 4; j++)
00864 {
00865 memset(&motion->ref_idx[clist][j][img->block_x],-1, 4 * sizeof(char));
00866 }
00867 }
00868 }
00869 }
00870 else
00871 {
00872 if (!mode)
00873 {
00874 for (j = img->block_y; j < img->block_y + 4; j++)
00875 memset(&motion->ref_idx[LIST_0][j][img->block_x],0, 4 * sizeof(char));
00876 }
00877 else
00878 {
00879 for (j = img->block_y; j < img->block_y + 4; j++)
00880 memset(&motion->ref_idx[LIST_0][j][img->block_x],-1, 4 * sizeof(char));
00881 }
00882 }
00883 }
00884 else
00885 {
00886 if (bslice)
00887 {
00888 if (mode == 1 || mode == 2 || mode == 3)
00889 {
00890 for (block8x8 = 0; block8x8 < 4; block8x8++)
00891 {
00892 for (clist = LIST_0; clist <= LIST_1; clist++)
00893 {
00894 bestref = (clist == LIST_0) ? b8x8info->best8x8l0ref[mode][block8x8] : b8x8info->best8x8l1ref[mode][block8x8];
00895 if ( b8x8info->best8x8pdir[mode][block8x8] == 2)
00896 {
00897 if (b8x8info->bipred8x8me[mode][block8x8])
00898 curref = 0;
00899 else
00900 curref = bestref;
00901 }
00902 else
00903 {
00904 curref = (clist == b8x8info->best8x8pdir[mode][block8x8]) ? bestref : -1;
00905 }
00906 for (block4x4 = 0; block4x4 < 4; block4x4++)
00907 {
00908 block_x = img->block_x + 2 * (block8x8 & 0x01) + (block4x4 & 0x01);
00909 block_y = img->block_y + 2 * (block8x8 >> 1) + (block4x4 >> 1);
00910 motion->ref_idx[clist][block_y][block_x] = curref;
00911 }
00912 }
00913 }
00914 }
00915 else
00916 {
00917 for (j=0;j<4;j++)
00918 {
00919 block_y = img->block_y + j;
00920 for (i=0;i<4;i++)
00921 {
00922 block_x = img->block_x + i;
00923 k = 2*(j >> 1) + (i >> 1);
00924 l = 2*(j & 0x01) + (i & 0x01);
00925
00926 if(mode == P8x8 && b8x8info->best8x8mode[k]==0)
00927 {
00928 motion->ref_idx[LIST_0][block_y][block_x] = direct_ref_idx[LIST_0][block_y][block_x];
00929 motion->ref_idx[LIST_1][block_y][block_x] = direct_ref_idx[LIST_1][block_y][block_x];
00930 }
00931 else
00932 {
00933 motion->ref_idx[LIST_0][block_y][block_x] = (IS_FW ? b8x8info->best8x8l0ref[mode][k] : -1);
00934 motion->ref_idx[LIST_1][block_y][block_x] = (IS_BW ? b8x8info->best8x8l1ref[mode][k] : -1);
00935 }
00936 }
00937 }
00938 }
00939 }
00940 else
00941 {
00942 if (mode == 1)
00943 {
00944 cref[0] = b8x8info->best8x8pdir[mode][0] == 0 ? b8x8info->best8x8l0ref[mode][0] : -1;
00945 j = img->block_y;
00946 memset(&motion->ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char));
00947 memset(&motion->ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char));
00948 memset(&motion->ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char));
00949 memset(&motion->ref_idx[LIST_0][j ][img->block_x], cref[0], 4 * sizeof(char));
00950 }
00951 else if (mode == 2)
00952 {
00953 cref[0] = b8x8info->best8x8pdir[mode][0] == 0 ? b8x8info->best8x8l0ref[mode][0] : -1;
00954 j = img->block_y;
00955 memset(&motion->ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char));
00956 memset(&motion->ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char));
00957 cref[0] = b8x8info->best8x8pdir[mode][2] == 0 ? b8x8info->best8x8l0ref[mode][2] : -1;
00958 memset(&motion->ref_idx[LIST_0][j++][img->block_x], cref[0], 4 * sizeof(char));
00959 memset(&motion->ref_idx[LIST_0][j ][img->block_x], cref[0], 4 * sizeof(char));
00960 }
00961 else if (mode == 3)
00962 {
00963 j = img->block_y;
00964 i = img->block_x;
00965 cref[0] = (b8x8info->best8x8pdir[mode][0] == 0) ? b8x8info->best8x8l0ref[mode][0] : -1;
00966 motion->ref_idx[LIST_0][j ][i++] = cref[0];
00967 motion->ref_idx[LIST_0][j ][i++] = cref[0];
00968 cref[0] = (b8x8info->best8x8pdir[mode][1] == 0) ? b8x8info->best8x8l0ref[mode][1] : -1;
00969 motion->ref_idx[LIST_0][j ][i++] = cref[0];
00970 motion->ref_idx[LIST_0][j++][i ] = cref[0];
00971 memcpy(&motion->ref_idx[LIST_0][j++][img->block_x], &motion->ref_idx[LIST_0][img->block_y][img->block_x], 4 * sizeof(char));
00972 memcpy(&motion->ref_idx[LIST_0][j++][img->block_x], &motion->ref_idx[LIST_0][img->block_y][img->block_x], 4 * sizeof(char));
00973 memcpy(&motion->ref_idx[LIST_0][j ][img->block_x], &motion->ref_idx[LIST_0][img->block_y][img->block_x], 4 * sizeof(char));
00974 }
00975 else
00976 {
00977 for (j=0;j<4;j++)
00978 {
00979 block_y = img->block_y + j;
00980 for (i=0;i<4;i++)
00981 {
00982 block_x = img->block_x + i;
00983 k = 2*(j >> 1) + (i >> 1);
00984 l = 2*(j & 0x01) + (i & 0x01);
00985 motion->ref_idx[LIST_0][block_y][block_x] = (IS_FW ? b8x8info->best8x8l0ref[mode][k] : -1);
00986 }
00987 }
00988 }
00989 }
00990 }
00991
00992 if (bslice)
00993 {
00994 for (clist = LIST_0; clist <= LIST_1; clist++)
00995 {
00996 for (j = img->block_y; j < img->block_y + 4; j++)
00997 for (i = img->block_x; i < img->block_x + 4;i++)
00998 {
00999 cur_ref = (int) motion->ref_idx[clist][j][i];
01000 motion->ref_pic_id [clist][j][i] = (cur_ref>=0
01001 ? enc_picture->ref_pic_num[clist + currMB->list_offset][cur_ref]
01002 : -1);
01003 }
01004 }
01005 }
01006 else
01007 {
01008 for (j = img->block_y; j < img->block_y + 4; j++)
01009 for (i = img->block_x; i < img->block_x + 4;i++)
01010 {
01011 cur_ref = (int) motion->ref_idx[LIST_0][j][i];
01012 motion->ref_pic_id [LIST_0][j][i] = (cur_ref>=0
01013 ? enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][cur_ref]
01014 : -1);
01015 }
01016 }
01017
01018 #undef IS_FW
01019 #undef IS_BW
01020 }
01021
01022
01023
01024
01025
01026
01027
01028 void SetCoeffAndReconstruction8x8 (Macroblock* currMB)
01029 {
01030 PicMotionParams *motion = &enc_picture->motion;
01031 int block, k, j, i, uv;
01032 int cur_ref;
01033
01034
01035
01036 int bslice = img->type==B_SLICE;
01037
01038 if (currMB->luma_transform_size_8x8_flag && (currMB->valid_8x8))
01039 {
01040
01041 memcpy(currMB->b8mode, tr8x8.part8x8mode, 4 * sizeof(short));
01042 memcpy(currMB->bipred_me, tr8x8.part8x8bipred, 4 * sizeof(short));
01043 for(i = 0;i<4;i++)
01044 {
01045 currMB->b8pdir[i] = tr8x8.part8x8pdir[i];
01046 }
01047
01048 if (bslice)
01049 {
01050 for (j = 0;j<4;j++)
01051 {
01052 for (i = 0;i<4;i++)
01053 {
01054 k = 2*(j >> 1)+(i >> 1);
01055 motion->ref_idx[LIST_0][img->block_y+j][img->block_x+i] = ((currMB->b8pdir[k] & 0x01) == 0) ? tr8x8.part8x8l0ref[k] : - 1;
01056 motion->ref_idx[LIST_1][img->block_y+j][img->block_x+i] = (currMB->b8pdir[k] > 0) ? tr8x8.part8x8l1ref[k] : - 1;
01057 }
01058 }
01059 }
01060 else
01061 {
01062 for (j = 0;j<4;j++)
01063 {
01064 for (i = 0;i<4;i++)
01065 {
01066 k = 2*(j >> 1)+(i >> 1);
01067 motion->ref_idx[LIST_0][img->block_y+j][img->block_x+i] = tr8x8.part8x8l0ref[k];
01068 }
01069 }
01070 }
01071
01072
01073 for (j = img->block_y;j<img->block_y + BLOCK_MULTIPLE;j++)
01074 {
01075 for (i = img->block_x;i<img->block_x + BLOCK_MULTIPLE;i++)
01076 {
01077 cur_ref = (int) motion->ref_idx[LIST_0][j][i];
01078
01079 motion->ref_pic_id [LIST_0][j][i] =(cur_ref>=0
01080 ? enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][cur_ref]
01081 : -1);
01082 }
01083 }
01084
01085 if (bslice)
01086 {
01087 for (j = img->block_y; j < img->block_y + BLOCK_MULTIPLE; j++)
01088 {
01089 for (i = img->block_x;i<img->block_x + BLOCK_MULTIPLE;i++)
01090 {
01091 cur_ref = (int) motion->ref_idx[LIST_1][j][i];
01092
01093 motion->ref_pic_id [LIST_1][j][i] = (cur_ref>=0
01094 ? enc_picture->ref_pic_num[LIST_1 + currMB->list_offset][cur_ref]
01095 : -1);
01096 }
01097
01098 }
01099 }
01100
01101
01102
01103 StoreMV8x8(1);
01104
01105 RestoreMV8x8(0);
01106
01107
01108
01109
01110 for (block = 0; block<4; block++)
01111 {
01112 memcpy (img->cofAC[block][0][0],cofAC8x8ts[block][0][0][0], 4 * 2 * 65 * sizeof(int));
01113 }
01114
01115 if (img->P444_joined)
01116 {
01117 for (uv=0; uv<2; uv++)
01118 {
01119 for (block = 0; block<4; block++)
01120 {
01121 memcpy (img->cofAC[4+block+uv*4][0][0],cofAC8x8ts[block][uv + 1][0][0], 4 * 2 * 65 * sizeof(int));
01122 }
01123 }
01124 }
01125
01126 if (cnt_nonz8_8x8ts <= _LUMA_8x8_COEFF_COST_ &&
01127 ((currMB->qp_scaled[0])!=0 || img->lossless_qpprime_flag==0) &&
01128 (img->type!=SP_SLICE))
01129 {
01130 currMB->cbp = 0;
01131 currMB->cbp_blk = 0;
01132
01133 for (j = 0; j < MB_BLOCK_SIZE; j++)
01134 {
01135 memcpy(&enc_picture->imgY[img->pix_y+j][img->pix_x], tr8x8.mpr8x8[j], MB_BLOCK_SIZE * sizeof(imgpel));
01136 }
01137
01138 if (params->rdopt == 3)
01139 {
01140 errdo_get_best_block(img, enc_picture->p_dec_img[0], decs->dec_mb_pred_best8x8[1], 0, MB_BLOCK_SIZE);
01141 }
01142
01143 if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator ))
01144 {
01145 for (j = 0; j < MB_BLOCK_SIZE; j++)
01146 {
01147 memcpy(&lrec[img->pix_y+j][img->pix_x],tr8x8.lrec[j], MB_BLOCK_SIZE * sizeof(int));
01148 }
01149 }
01150
01151 memset( img->cofAC[0][0][0], 0, 4 * 4 * 2 * 65 * sizeof(int));
01152
01153 if(img->P444_joined)
01154 {
01155 cmp_cbp[1] = cmp_cbp[2] = 0;
01156 for (j = 0; j < MB_BLOCK_SIZE; j++)
01157 {
01158 memcpy(&enc_picture->imgUV[0][img->pix_y+j][img->pix_x], tr8x8.mpr8x8CbCr[0][j], MB_BLOCK_SIZE * sizeof(imgpel));
01159 memcpy(&enc_picture->imgUV[1][img->pix_y+j][img->pix_x], tr8x8.mpr8x8CbCr[1][j], MB_BLOCK_SIZE * sizeof(imgpel));
01160 }
01161 for (uv=0; uv<2; uv++)
01162 {
01163 for (block = 0; block<4; block++)
01164 {
01165 memset( img->cofAC[4+block+uv*4][0][0], 0, 4 * 2 * 65 * sizeof(int));
01166 }
01167 }
01168 }
01169 }
01170 else
01171 {
01172 currMB->cbp = cbp8_8x8ts;
01173 currMB->cbp_blk = cbp_blk8_8x8ts;
01174 for (j = 0; j < MB_BLOCK_SIZE; j++)
01175 {
01176 memcpy (&enc_picture->imgY[img->pix_y+j][img->pix_x], tr8x8.rec_mbY8x8[j], MB_BLOCK_SIZE * sizeof(imgpel));
01177 }
01178
01179 if (params->rdopt == 3)
01180 {
01181 errdo_get_best_block(img, enc_picture->p_dec_img[0], decs->dec_mbY_best8x8[1], 0, MB_BLOCK_SIZE);
01182 }
01183
01184 if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
01185 {
01186 for (j = 0; j < MB_BLOCK_SIZE; j++)
01187 {
01188 memcpy (&lrec[img->pix_y+j][img->pix_x],tr8x8.lrec[j], MB_BLOCK_SIZE * sizeof(int));
01189 }
01190 }
01191
01192 if (img->P444_joined)
01193 {
01194 cmp_cbp[1] = cmp_cbp[2] = cbp8_8x8ts;
01195 for (j = 0; j < MB_BLOCK_SIZE; j++)
01196 {
01197 memcpy (&enc_picture->imgUV[0][img->pix_y+j][img->pix_x],tr8x8.rec_mb8x8_cr[0][j], MB_BLOCK_SIZE * sizeof(imgpel));
01198 memcpy (&enc_picture->imgUV[1][img->pix_y+j][img->pix_x],tr8x8.rec_mb8x8_cr[1][j], MB_BLOCK_SIZE * sizeof(imgpel));
01199 }
01200 }
01201 }
01202 }
01203 else
01204 {
01205 if (bslice && currMB->valid_8x8)
01206 {
01207 StoreMV8x8(1);
01208 }
01209
01210
01211
01212
01213
01214 for (block = 0; block < 4; block ++)
01215 {
01216 memcpy (img->cofAC[block][0][0],coefAC8x8[block][0][0][0], 4 * 2 * 65 * sizeof(int));
01217 }
01218
01219 if (img->P444_joined)
01220 {
01221 for (block = 0; block<4; block++)
01222 {
01223 memcpy (img->cofAC[block+4][0][0],coefAC8x8[block][1][0][0], 4 * 2 * 65 * sizeof(int));
01224 memcpy (img->cofAC[block+8][0][0],coefAC8x8[block][2][0][0], 4 * 2 * 65 * sizeof(int));
01225 }
01226 }
01227
01228 if (cnt_nonz_8x8<=5 && img->type!=SP_SLICE &&
01229 ((currMB->qp_scaled[0])!=0 || img->lossless_qpprime_flag==0))
01230 {
01231 currMB->cbp = 0;
01232 currMB->cbp_blk = 0;
01233 for (j = 0; j < MB_BLOCK_SIZE; j++)
01234 {
01235 memcpy (&enc_picture->imgY[img->pix_y+j][img->pix_x],tr4x4.mpr8x8[j], MB_BLOCK_SIZE * sizeof(imgpel));
01236 }
01237
01238 if (params->rdopt == 3)
01239 {
01240 errdo_get_best_block(img, enc_picture->p_dec_img[0], decs->dec_mb_pred_best8x8[0], 0, MB_BLOCK_SIZE);
01241 }
01242
01243 if(img->type ==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
01244 {
01245 for (j = 0; j < MB_BLOCK_SIZE; j++)
01246 {
01247 memcpy (&lrec[img->pix_y+j][img->pix_x],tr4x4.lrec[j], MB_BLOCK_SIZE * sizeof(int));
01248 }
01249 }
01250
01251 memset( img->cofAC[0][0][0], 0, 4 * 4 * 2 * 65 * sizeof(int));
01252
01253 if (img->P444_joined)
01254 {
01255 cmp_cbp[1] = cmp_cbp[2] = 0;
01256 for (j = 0; j < MB_BLOCK_SIZE; j++)
01257 {
01258 memcpy (&enc_picture->imgUV[0][img->pix_y+j][img->pix_x],tr4x4.mpr8x8CbCr[0][j], MB_BLOCK_SIZE * sizeof(imgpel));
01259 memcpy (&enc_picture->imgUV[1][img->pix_y+j][img->pix_x],tr4x4.mpr8x8CbCr[1][j], MB_BLOCK_SIZE * sizeof(imgpel));
01260 }
01261 for (uv=0; uv<2; uv++)
01262 {
01263 for (block = 0; block<4; block++)
01264 {
01265 memset( img->cofAC[4+block+uv*4][0][0], 0, 4 * 2 * 65 * sizeof(int));
01266 }
01267 }
01268 }
01269 }
01270 else
01271 {
01272 currMB->cbp = cbp8x8;
01273 currMB->cbp_blk = cbp_blk8x8;
01274 for (j = 0; j < MB_BLOCK_SIZE; j++)
01275 {
01276 memcpy (&enc_picture->imgY[img->pix_y+j][img->pix_x],tr4x4.rec_mbY8x8[j], MB_BLOCK_SIZE * sizeof(imgpel));
01277 }
01278
01279 if (params->rdopt == 3)
01280 {
01281 errdo_get_best_block(img, enc_picture->p_dec_img[0], decs->dec_mbY_best8x8[0], 0, MB_BLOCK_SIZE);
01282 }
01283
01284 if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
01285 {
01286 for (j = 0; j < MB_BLOCK_SIZE; j++)
01287 {
01288 memcpy (&lrec[img->pix_y+j][img->pix_x],tr4x4.lrec[j], MB_BLOCK_SIZE * sizeof(int));
01289 }
01290 }
01291 if (img->P444_joined)
01292 {
01293 cmp_cbp[1] = cmp_cbp[2] = cbp8x8;
01294 for (j = 0; j < MB_BLOCK_SIZE; j++)
01295 {
01296 memcpy (&enc_picture->imgUV[0][img->pix_y+j][img->pix_x],tr4x4.rec_mb8x8_cr[0][j], MB_BLOCK_SIZE * sizeof(imgpel));
01297 memcpy (&enc_picture->imgUV[1][img->pix_y+j][img->pix_x],tr4x4.rec_mb8x8_cr[1][j], MB_BLOCK_SIZE * sizeof(imgpel));
01298 }
01299 }
01300 }
01301 }
01302 }
01303
01304
01305
01306
01307
01308
01309
01310 int RDCost_for_macroblocks (Slice *currSlice,
01311 Macroblock *currMB,
01312 double lambda,
01313 int mode,
01314 double* min_rdcost,
01315 double* min_dcost,
01316 double* min_rate,
01317 int i16mode,
01318 int is_cavlc)
01319 {
01320 int i, j, k;
01321 int j1, j2;
01322 int rate = 0, coeff_rate = 0;
01323 int64 distortion = 0;
01324 double rdcost;
01325 Macroblock *prevMB = currMB->PrevMB;
01326 int bslice = (img->type==B_SLICE);
01327 int tmp_cc;
01328 int use_of_cc = (img->type!=I_SLICE && is_cavlc);
01329 int cc_rate, dummy;
01330 double dummy_d;
01331 imgpel **mb_pred = img->mb_pred[0];
01332 imgpel ***curr_mpr_16x16 = img->mpr_16x16[0];
01333
01334
01335
01336 if (bslice && mode==0)
01337 {
01338 for (j = img->block_y; j < img->block_y + 4;j++)
01339 {
01340 for (i = img->block_x; i < img->block_x + 4;i++)
01341 {
01342 if (direct_pdir[j][i] < 0)
01343 return 0;
01344 }
01345 }
01346 }
01347
01348
01349
01350 if ((img->MbaffFrameFlag) && (!currMB->mb_field) && (img->type==P_SLICE) && (mode==0) )
01351 {
01352 if (out_of_bounds_mvs(img, img->all_mv[LIST_0][0][0][0][0]))
01353 return 0;
01354 }
01355
01356
01357
01358
01359 SetModesAndRefframeForBlocks (currMB, mode);
01360
01361
01362
01363 SetMotionVectorsMB (img, &enc_picture->motion, currMB);
01364
01365
01366
01367
01368 if (mode<P8x8)
01369 {
01370 LumaResidualCoding (currMB, is_cavlc);
01371 }
01372 else if (mode == P8x8)
01373 {
01374 SetCoeffAndReconstruction8x8 (currMB);
01375 }
01376 else if (mode==I4MB)
01377 {
01378 currMB->cbp = Mode_Decision_for_Intra4x4Macroblock (currSlice, currMB, lambda, &dummy_d, is_cavlc);
01379 }
01380 else if (mode==I16MB)
01381 {
01382 Intra16x16_Mode_Decision (currMB, &i16mode, is_cavlc);
01383 }
01384 else if(mode==I8MB)
01385 {
01386 currMB->cbp = Mode_Decision_for_Intra8x8Macroblock(currSlice, currMB, lambda, &dummy_d);
01387 }
01388 else if(mode==IPCM)
01389 {
01390 for (j = 0; j < MB_BLOCK_SIZE; j++)
01391 {
01392 memcpy(&enc_picture->imgY[j + img->pix_y][img->opix_x], &pCurImg[j + img->opix_y][img->opix_x], MB_BLOCK_SIZE * sizeof(imgpel));
01393 }
01394 if ((img->yuv_format != YUV400) && !IS_INDEPENDENT(params))
01395 {
01396
01397 for (j = 0; j<img->mb_cr_size_y; j++)
01398 {
01399 j1 = j + img->opix_c_y;
01400 j2 = j + img->pix_c_y;
01401 memcpy(&enc_picture->imgUV[0][j2][img->opix_c_x], &pImgOrg[1][j1][img->opix_c_x], img->mb_cr_size_x * sizeof(imgpel));
01402 memcpy(&enc_picture->imgUV[1][j2][img->opix_c_x], &pImgOrg[2][j1][img->opix_c_x], img->mb_cr_size_x * sizeof(imgpel));
01403 }
01404 }
01405 for (j=0;j<4;j++)
01406 for (i=0; i<(4+img->num_blk8x8_uv); i++)
01407 img->nz_coeff[currMB->mb_nr][j][i] = 16;
01408 }
01409
01410 if (params->rdopt == 3)
01411 {
01412
01413 compute_residue_block (img, &enc_picture->p_curr_img[img->pix_y], decs->res_img[0], mode == I16MB ? img->mpr_16x16[0][i16mode] : img->mb_pred[0], 0, 16);
01414 }
01415
01416
01417 if (params->RCEnable)
01418 {
01419 if (mode == I16MB)
01420 memcpy(pred[0], curr_mpr_16x16[i16mode][0], MB_PIXELS * sizeof(imgpel));
01421 else
01422 memcpy(pred[0], mb_pred[0], MB_PIXELS * sizeof(imgpel));
01423 }
01424
01425 img->i16offset = 0;
01426 dummy = 0;
01427
01428 if (((img->yuv_format != YUV400) && (active_sps->chroma_format_idc != YUV444)) && (mode != IPCM))
01429 ChromaResidualCoding (currMB, is_cavlc);
01430
01431 if (mode==I16MB)
01432 img->i16offset = I16Offset (currMB->cbp, i16mode);
01433
01434
01435
01436
01437
01438 if (params->rdopt == 3)
01439 {
01440 if (mode != P8x8)
01441 {
01442 for (k = 0; k<params->NoOfDecoders ;k++)
01443 {
01444 decode_one_mb (img, enc_picture, k, currMB);
01445 distortion += compute_SSE(&pCurImg[img->opix_y], &enc_picture->p_dec_img[0][k][img->opix_y], img->opix_x, img->opix_x, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
01446 }
01447 }
01448 else
01449 {
01450 for (k = 0; k<params->NoOfDecoders ;k++)
01451 {
01452 distortion += compute_SSE(&pCurImg[img->opix_y], &enc_picture->p_dec_img[0][k][img->opix_y], img->opix_x, img->opix_x, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
01453 }
01454 }
01455 distortion /= params->NoOfDecoders;
01456
01457 if ((img->yuv_format != YUV400) && (active_sps->chroma_format_idc != YUV444))
01458 {
01459
01460 distortion += compute_SSE(&pImgOrg[1][img->opix_c_y], &enc_picture->imgUV[0][img->pix_c_y], img->opix_c_x, img->pix_c_x, img->mb_cr_size_y, img->mb_cr_size_x);
01461 distortion += compute_SSE(&pImgOrg[2][img->opix_c_y], &enc_picture->imgUV[1][img->pix_c_y], img->opix_c_x, img->pix_c_x, img->mb_cr_size_y, img->mb_cr_size_x);
01462 }
01463 }
01464 else
01465 {
01466 distortion = getDistortion(currMB);
01467
01468 }
01469
01470 if (currMB->qp_scaled[0] == 0 && img->lossless_qpprime_flag == 1 && distortion != 0)
01471 return 0;
01472
01473
01474
01475 store_coding_state (currSlice, currMB, cs_cm);
01476
01477
01478
01479
01480
01481 if (use_of_cc)
01482 {
01483 if (currMB->mb_type!=0 || (bslice && currMB->cbp!=0))
01484 {
01485
01486 tmp_cc = img->cod_counter;
01487 rate = writeMBLayer (currSlice, currMB, 1, &coeff_rate);
01488 ue_linfo (tmp_cc, dummy, &cc_rate, &dummy);
01489 rate -= cc_rate;
01490 img->cod_counter = tmp_cc;
01491 }
01492 else
01493 {
01494
01495 ue_linfo (img->cod_counter + 1, dummy, &rate, &dummy);
01496 ue_linfo (img->cod_counter , dummy, &cc_rate, &dummy);
01497 rate -= cc_rate;
01498 }
01499 }
01500 else
01501 {
01502 rate = writeMBLayer (currSlice, currMB, 1, &coeff_rate);
01503 }
01504
01505
01506
01507 reset_coding_state (currSlice, currMB, cs_cm);
01508
01509 rdcost = (double)distortion + lambda * dmax(0.5,(double)rate);
01510
01511 if (rdcost >= *min_rdcost ||
01512 ((currMB->qp_scaled[0]) == 0 && img->lossless_qpprime_flag == 1 && distortion != 0))
01513 {
01514 #if FASTMODE
01515
01516
01517
01518 if((img->type!=P_SLICE || mode != 0 || rdcost != *min_rdcost) || IS_FREXT_PROFILE(params->ProfileIDC))
01519 #endif
01520 return 0;
01521 }
01522
01523
01524 if ((img->MbaffFrameFlag) && (mode ? 0: ((img->type == B_SLICE) ? !currMB->cbp:1)))
01525 {
01526 if (currMB->mb_nr & 0x01)
01527 {
01528 if (prevMB->mb_type ? 0:((img->type == B_SLICE) ? !prevMB->cbp:1))
01529 {
01530 if (!(field_flag_inference(currMB) == currMB->mb_field))
01531 return 0;
01532 }
01533 }
01534 }
01535
01536
01537
01538 *min_rdcost = rdcost;
01539 *min_dcost = (double) distortion;
01540 *min_rate = lambda * (double)coeff_rate;
01541
01542 #ifdef BEST_NZ_COEFF
01543 for (j=0;j<4;j++)
01544 memcpy(&gaaiMBAFF_NZCoeff[j][0], &img->nz_coeff[currMB->mb_nr][j][0], (4 + img->num_blk8x8_uv) * sizeof(int));
01545 #endif
01546
01547 return 1;
01548 }
01549
01550
01551
01552
01553
01554
01555
01556
01557 void store_macroblock_parameters (Macroblock *currMB, int mode)
01558 {
01559 int j, ****i4p, ***i3p;
01560 int bslice = (img->type==B_SLICE);
01561
01562
01563 best_mode = mode;
01564 best_c_imode = currMB->c_ipred_mode;
01565 best_i16offset = img->i16offset;
01566
01567
01568 memcpy(b8mode, currMB->b8mode, BLOCK_MULTIPLE * sizeof(short));
01569 memcpy(b8bipred_me, currMB->bipred_me, BLOCK_MULTIPLE * sizeof(short));
01570 memcpy(b8pdir, currMB->b8pdir, BLOCK_MULTIPLE * sizeof(short));
01571 memcpy(b4_intra_pred_modes, currMB->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
01572 memcpy(b8_intra_pred_modes8x8,currMB->intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
01573
01574 for (j = 0 ; j < BLOCK_MULTIPLE; j++)
01575 {
01576 memcpy(&b4_ipredmode[j * BLOCK_MULTIPLE],&img->ipredmode [img->block_y + j][img->block_x],BLOCK_MULTIPLE * sizeof(char));
01577 memcpy(&b8_ipredmode8x8[j][0], &img->ipredmode8x8[img->block_y + j][img->block_x],BLOCK_MULTIPLE * sizeof(char));
01578 }
01579
01580 for (j = 0; j < MB_BLOCK_SIZE; j++)
01581 {
01582 memcpy(rec_mbY[j], &enc_picture->imgY[img->pix_y+j][img->pix_x], MB_BLOCK_SIZE * sizeof(imgpel));
01583 }
01584 if((img->type==SP_SLICE) && (si_frame_indicator==0 && sp2_frame_indicator==0))
01585 {
01586 for (j = 0; j < MB_BLOCK_SIZE; j++)
01587 {
01588 memcpy(lrec_rec[j], &lrec[img->pix_y+j][img->pix_x], MB_BLOCK_SIZE * sizeof(int));
01589 }
01590 }
01591
01592
01593 if (img->AdaptiveRounding && bslice && mode <= 1)
01594 {
01595 if (currMB->luma_transform_size_8x8_flag)
01596 store_adaptive_rounding_16x16( img, img->ARCofAdj8x8, mode);
01597 else
01598 store_adaptive_rounding_16x16( img, img->ARCofAdj4x4, mode);
01599 }
01600
01601 if (img->yuv_format != YUV400)
01602 {
01603 int k;
01604 for (k = 0; k < 2; k++)
01605 {
01606 for (j = 0; j<img->mb_cr_size_y; j++)
01607 {
01608 memcpy(&rec_mb_cr[k][j][0], &enc_picture->imgUV[k][img->pix_c_y+j][img->pix_c_x], img->mb_cr_size_x * sizeof(imgpel));
01609 }
01610 }
01611
01612 if((img->type==SP_SLICE) && (si_frame_indicator==0 && sp2_frame_indicator==0))
01613 {
01614
01615 for (k = 0; k < 2; k++)
01616 {
01617 for (j = 0; j<img->mb_cr_size_y; j++)
01618 {
01619 memcpy(lrec_rec_uv[k][j],&lrec_uv[k][img->pix_c_y+j][img->pix_c_x], img->mb_cr_size_x * sizeof(int));
01620 }
01621 }
01622 }
01623 }
01624
01625
01626 if (params->rdopt == 3)
01627 {
01628 errdo_store_best_block(decs->dec_mbY_best, enc_picture->p_dec_img[0], 0, 0, img->pix_x, img->pix_y, MB_BLOCK_SIZE);
01629 }
01630
01631
01632 if (mode || bslice)
01633 {
01634 i4p=cofAC; cofAC=img->cofAC; img->cofAC=i4p;
01635 i3p=cofDC; cofDC=img->cofDC; img->cofDC=i3p;
01636 cbp = currMB->cbp;
01637 curr_cbp[0] = cmp_cbp[1];
01638 curr_cbp[1] = cmp_cbp[2];
01639
01640 cur_cbp_blk[0] = currMB->cbp_blk;
01641 }
01642 else
01643 {
01644 cur_cbp_blk[0] = cbp = 0;
01645 cmp_cbp[1] = cmp_cbp[2] = 0;
01646 }
01647
01648
01649 luma_transform_size_8x8_flag = currMB->luma_transform_size_8x8_flag;
01650
01651
01652 for (j = 0; j<4; j++)
01653 memcpy(l0_refframe[j],&enc_picture->motion.ref_idx[LIST_0][img->block_y+j][img->block_x], BLOCK_MULTIPLE * sizeof(char));
01654
01655 if (bslice)
01656 {
01657 for (j = 0; j<4; j++)
01658 memcpy(l1_refframe[j],&enc_picture->motion.ref_idx[LIST_1][img->block_y+j][img->block_x], BLOCK_MULTIPLE * sizeof(char));
01659 }
01660 }
01661
01662
01663
01664
01665
01666
01667
01668
01669 void set_stored_macroblock_parameters (Macroblock *currMB)
01670 {
01671 imgpel **imgY = enc_picture->imgY;
01672 imgpel ***imgUV = enc_picture->imgUV;
01673
01674 int mode = best_mode;
01675 int bslice = (img->type==B_SLICE);
01676 int i, j, k, ****i4p, ***i3p;
01677 int block_x, block_y;
01678 char **ipredmodes = img->ipredmode;
01679 short *cur_mv;
01680 PicMotionParams *motion = &enc_picture->motion;
01681
01682
01683
01684
01685 for (j = 0; j < MB_BLOCK_SIZE; j++)
01686 {
01687 memcpy(&imgY[img->pix_y+j][img->pix_x],&rec_mbY[j][0], MB_BLOCK_SIZE * sizeof(imgpel));
01688 }
01689
01690 if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
01691 {
01692 for (j = 0; j < MB_BLOCK_SIZE; j++)
01693 memcpy(rdopt->rec_mbY[j],rec_mbY[j], MB_BLOCK_SIZE * sizeof(imgpel));
01694 }
01695
01696 if((img->type==SP_SLICE) &&(si_frame_indicator==0 && sp2_frame_indicator==0 ))
01697 {
01698 for (j = 0; j < MB_BLOCK_SIZE; j++)
01699 memcpy(&lrec[img->pix_y+j][img->pix_x],lrec_rec[j], MB_BLOCK_SIZE * sizeof(int));
01700 }
01701
01702 if (img->AdaptiveRounding)
01703 {
01704 update_offset_params(currMB, mode,luma_transform_size_8x8_flag);
01705 }
01706
01707 if (img->yuv_format != YUV400)
01708 {
01709 int k;
01710 for (k = 0; k < 2; k++)
01711 {
01712 for (j = 0; j<img->mb_cr_size_y; j++)
01713 {
01714 memcpy(&imgUV[k][img->pix_c_y+j][img->pix_c_x], rec_mb_cr[k][j], img->mb_cr_size_x * sizeof(imgpel));
01715 }
01716 }
01717
01718 if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
01719 {
01720 for (k = 0; k < 2; k++)
01721 {
01722 for (j = 0; j<img->mb_cr_size_y; j++)
01723 {
01724 memcpy(rdopt->rec_mb_cr[k][j],rec_mb_cr[k][j], img->mb_cr_size_x * sizeof(imgpel));
01725 }
01726 }
01727 }
01728
01729 if((img->type==SP_SLICE) &&(!si_frame_indicator && !sp2_frame_indicator))
01730 {
01731 for (k = 0; k < 2; k++)
01732 {
01733 for (j = 0; j<img->mb_cr_size_y; j++)
01734 {
01735 memcpy(&lrec_uv[k][img->pix_c_y+j][img->pix_c_x],lrec_rec_uv[k][j], img->mb_cr_size_x * sizeof(int));
01736 }
01737 }
01738 }
01739 }
01740
01741
01742 i4p=cofAC; cofAC=img->cofAC; img->cofAC=i4p;
01743 i3p=cofDC; cofDC=img->cofDC; img->cofDC=i3p;
01744 currMB->cbp = cbp;
01745 currMB->cbp_blk = cur_cbp_blk[0];
01746 cmp_cbp[1] = curr_cbp[0];
01747 cmp_cbp[2] = curr_cbp[1];
01748 currMB->cbp |= cmp_cbp[1];
01749 currMB->cbp |= cmp_cbp[2];
01750 cmp_cbp[1] = currMB->cbp;
01751 cmp_cbp[2] = currMB->cbp;
01752
01753
01754 currMB->mb_type = mode;
01755
01756 memcpy(currMB->b8mode, b8mode, BLOCK_MULTIPLE * sizeof(short));
01757 memcpy(currMB->b8pdir, b8pdir, BLOCK_MULTIPLE * sizeof(short));
01758 memcpy(currMB->bipred_me, b8bipred_me, BLOCK_MULTIPLE * sizeof(short));
01759
01760 if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
01761 {
01762 rdopt->mode = mode;
01763 rdopt->i16offset = img->i16offset;
01764 rdopt->cbp = cbp;
01765 rdopt->cbp_blk = cur_cbp_blk[0];
01766 rdopt->mb_type = mode;
01767
01768 rdopt->prev_qp = currMB->prev_qp;
01769 rdopt->prev_dqp = currMB->prev_dqp;
01770 rdopt->delta_qp = currMB->delta_qp;
01771 rdopt->qp = currMB->qp;
01772 rdopt->prev_cbp = currMB->prev_cbp;
01773
01774 memcpy(rdopt->cofAC[0][0][0], img->cofAC[0][0][0], (4+img->num_blk8x8_uv) * 4 * 2 * 65 * sizeof(int));
01775 memcpy(rdopt->cofDC[0][0], img->cofDC[0][0], 3 * 2 * 18 * sizeof(int));
01776
01777 memcpy(rdopt->b8mode,b8mode, BLOCK_MULTIPLE * sizeof(short));
01778 memcpy(rdopt->b8pdir,b8pdir, BLOCK_MULTIPLE * sizeof(short));
01779 }
01780
01781
01782 if (mode == P8x8 && !luma_transform_size_8x8_flag && params->Transform8x8Mode && (currMB->valid_8x8 == TRUE))
01783 {
01784 RestoreMV8x8(1);
01785 }
01786
01787
01788 if (img->P444_joined)
01789 {
01790 if (((currMB->cbp == 0) && cmp_cbp[1] == 0 && cmp_cbp[2] == 0) && (currMB->mb_type != I4MB && currMB->mb_type != I8MB))
01791 currMB->luma_transform_size_8x8_flag = 0;
01792 else
01793 currMB->luma_transform_size_8x8_flag = luma_transform_size_8x8_flag;
01794 }
01795 else
01796 {
01797
01798 if (((currMB->cbp & 15) == 0) && (currMB->mb_type != I4MB && currMB->mb_type != I8MB))
01799 currMB->luma_transform_size_8x8_flag = 0;
01800 else
01801 currMB->luma_transform_size_8x8_flag = luma_transform_size_8x8_flag;
01802 }
01803
01804 rdopt->luma_transform_size_8x8_flag = currMB->luma_transform_size_8x8_flag;
01805
01806 if (params->rdopt == 3)
01807 {
01808 errdo_get_best_block(img, enc_picture->p_dec_img[0], decs->dec_mbY_best, 0, MB_BLOCK_SIZE);
01809 }
01810
01811
01812 for (j = 0; j < 4; j++)
01813 {
01814 block_y = img->block_y + j;
01815 for (i = 0; i < 4; i++)
01816 {
01817 block_x = img->block_x + i;
01818 k = 2*(j >> 1)+(i >> 1);
01819
01820
01821 if ((currMB->b8pdir[k] == 1) || IS_INTRA(currMB))
01822 {
01823 motion->ref_idx [LIST_0][block_y][block_x] = -1;
01824 motion->ref_pic_id [LIST_0][block_y][block_x] = -1;
01825 motion->mv [LIST_0][block_y][block_x][0] = 0;
01826 motion->mv [LIST_0][block_y][block_x][1] = 0;
01827
01828 if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
01829 rdopt->refar[LIST_0][j][i] = -1;
01830 }
01831 else
01832 {
01833 if (currMB->bipred_me[k] && (currMB->b8pdir[k] == 2) && is_bipred_enabled(currMB->mb_type))
01834 {
01835 cur_mv = img->bipred_mv[currMB->bipred_me[k] - 1][LIST_0][0][currMB->b8mode[k]][j][i];
01836
01837 motion->ref_idx [LIST_0][block_y][block_x] = 0;
01838 motion->ref_pic_id [LIST_0][block_y][block_x] = enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][0];
01839 motion->mv [LIST_0][block_y][block_x][0] = cur_mv[0];
01840 motion->mv [LIST_0][block_y][block_x][1] = cur_mv[1];
01841
01842 if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
01843 rdopt->refar[LIST_0][j][i] = 0;
01844 }
01845 else
01846 {
01847 char cur_ref = l0_refframe[j][i];
01848 motion->ref_idx [LIST_0][block_y][block_x] = cur_ref;
01849 motion->ref_pic_id [LIST_0][block_y][block_x] = enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][(short)cur_ref];
01850 memcpy(motion->mv [LIST_0][block_y][block_x], img->all_mv[LIST_0][(short)cur_ref][currMB->b8mode[k]][j][i], 2 * sizeof(short));
01851
01852 if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
01853 rdopt->refar[LIST_0][j][i] = cur_ref;
01854 }
01855 }
01856
01857
01858 if ((currMB->b8pdir[k] == 0) || IS_INTRA(currMB))
01859 {
01860 motion->ref_idx [LIST_1][block_y][block_x] = -1;
01861 motion->ref_pic_id [LIST_1][block_y][block_x] = -1;
01862 motion->mv [LIST_1][block_y][block_x][0] = 0;
01863 motion->mv [LIST_1][block_y][block_x][1] = 0;
01864
01865 if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
01866 rdopt->refar[LIST_1][j][i] = -1;
01867 }
01868 }
01869 }
01870
01871 if (bslice)
01872 {
01873 for (j=0; j<4; j++)
01874 {
01875 block_y = img->block_y + j;
01876 for (i=0; i<4; i++)
01877 {
01878 block_x = img->block_x + i;
01879 k = 2*(j >> 1)+(i >> 1);
01880
01881
01882 if (IS_INTRA(currMB)||(currMB->b8pdir[k] == 0))
01883 {
01884 motion->ref_idx [LIST_1][block_y][block_x] = -1;
01885 motion->ref_pic_id [LIST_1][block_y][block_x] = -1;
01886 motion->mv [LIST_1][block_y][block_x][0] = 0;
01887 motion->mv [LIST_1][block_y][block_x][1] = 0;
01888
01889 if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
01890 rdopt->refar[LIST_1][j][i] = -1;
01891 }
01892 else
01893 {
01894 if (currMB->bipred_me[k] && (currMB->b8pdir[k] == 2) && is_bipred_enabled(currMB->mb_type))
01895 {
01896 cur_mv = img->bipred_mv[currMB->bipred_me[k] - 1][LIST_1][0][currMB->b8mode[k]][j][i];
01897
01898 motion->ref_idx [LIST_1][block_y][block_x] = 0;
01899 motion->ref_pic_id [LIST_1][block_y][block_x] = enc_picture->ref_pic_num[LIST_1 + currMB->list_offset][0];
01900 motion->mv [LIST_1][block_y][block_x][0] = cur_mv[0];
01901 motion->mv [LIST_1][block_y][block_x][1] = cur_mv[1];
01902
01903 if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
01904 rdopt->refar[LIST_1][j][i] = 0;
01905 }
01906 else
01907 {
01908 motion->ref_idx [LIST_1][block_y][block_x] = l1_refframe[j][i];
01909 motion->ref_pic_id [LIST_1][block_y][block_x] = enc_picture->ref_pic_num[LIST_1 + currMB->list_offset][(short)l1_refframe[j][i]];
01910 memcpy(motion->mv [LIST_1][block_y][block_x], img->all_mv[LIST_1][(short)l1_refframe[j][i]][currMB->b8mode[k]][j][i], 2 * sizeof(short));
01911
01912 if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
01913 rdopt->refar[LIST_1][j][i] = l1_refframe[j][i];
01914 }
01915 }
01916 }
01917 }
01918 }
01919
01920
01921 currMB->c_ipred_mode = best_c_imode;
01922 img->i16offset = best_i16offset;
01923
01924 if(currMB->mb_type == I8MB)
01925 {
01926 memcpy(currMB->intra_pred_modes8x8,b8_intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
01927 memcpy(currMB->intra_pred_modes,b8_intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
01928 for(j = 0; j < BLOCK_MULTIPLE; j++)
01929 {
01930 memcpy(&img->ipredmode[img->block_y+j][img->block_x], b8_ipredmode8x8[j], BLOCK_MULTIPLE * sizeof(char));
01931 memcpy(&img->ipredmode8x8[img->block_y+j][img->block_x], b8_ipredmode8x8[j], BLOCK_MULTIPLE * sizeof(char));
01932 }
01933 }
01934 else if (mode!=I4MB && mode!=I8MB)
01935 {
01936 memset(currMB->intra_pred_modes,DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));
01937 for(j = img->block_y; j < img->block_y + BLOCK_MULTIPLE; j++)
01938 memset(&img->ipredmode[j][img->block_x], DC_PRED, BLOCK_MULTIPLE * sizeof(char));
01939 }
01940
01941 else if (mode == I4MB)
01942 {
01943 memcpy(currMB->intra_pred_modes,b4_intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
01944 for(j = 0; j < BLOCK_MULTIPLE; j++)
01945 memcpy(&img->ipredmode[img->block_y + j][img->block_x],&b4_ipredmode[BLOCK_MULTIPLE * j], BLOCK_MULTIPLE * sizeof(char));
01946 }
01947
01948 if (img->MbaffFrameFlag || (params->UseRDOQuant && params->RDOQ_QP_Num > 1))
01949 {
01950 rdopt->c_ipred_mode = currMB->c_ipred_mode;
01951 rdopt->i16offset = img->i16offset;
01952 memcpy(rdopt->intra_pred_modes,currMB->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
01953 memcpy(rdopt->intra_pred_modes8x8,currMB->intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
01954 for(j = img->block_y; j < img->block_y +BLOCK_MULTIPLE; j++)
01955 memcpy(&rdopt->ipredmode[j][img->block_x],&ipredmodes[j][img->block_x], BLOCK_MULTIPLE * sizeof(char));
01956 }
01957
01958
01959 SetMotionVectorsMB (img, &enc_picture->motion, currMB);
01960 }
01961
01962
01963
01964
01965
01966
01967
01968 void SetRefAndMotionVectors (PicMotionParams *motion, Macroblock *currMB, int block, int mode, int pdir, int fwref, int bwref, short bipred_me)
01969 {
01970 int k, i, j=0;
01971 int bslice = (img->type==B_SLICE);
01972 int pmode = (mode==1||mode==2||mode==3?mode:4);
01973 int j0 = ((block >> 1)<<1);
01974 int i0 = ((block & 0x01)<<1);
01975 int j1 = j0 + (params->part_size[pmode][1]);
01976 int i1 = i0 + (params->part_size[pmode][0]);
01977 int block_x, block_y;
01978 short *cur_mv;
01979 int64 ref_pic_num;
01980 char *ref_idx;
01981
01982 if (pdir < 0)
01983 {
01984 for (k = LIST_0; k <= LIST_1; k++)
01985 {
01986 for (j = img->block_y + j0; j < img->block_y + j1; j++)
01987 {
01988 for (i=img->block_x + i0; i<img->block_x +i1; i++)
01989 motion->ref_pic_id[k][j][i] = -1;
01990
01991 memset(&motion->ref_idx[k][j][img->block_x + i0], -1, (params->part_size[pmode][0]) * sizeof(char));
01992 memset(&motion->mv [k][j][img->block_x + i0][0], 0, 2*(params->part_size[pmode][0]) * sizeof(short));
01993 }
01994 }
01995 return;
01996 }
01997
01998 if (!bslice)
01999 {
02000 int64 ref_pic_num = enc_picture->ref_pic_num[LIST_0+currMB->list_offset][fwref];
02001 for (j = j0; j < j1; j++)
02002 {
02003 block_y = img->block_y + j;
02004 for (block_x = img->block_x + i0; block_x < img->block_x + i1; block_x++)
02005 motion->ref_pic_id[LIST_0][block_y][block_x] = ref_pic_num;
02006
02007 memset(&motion->ref_idx[LIST_0][block_y][img->block_x + i0], fwref, (params->part_size[pmode][0]) * sizeof(char));
02008 memcpy(&motion->mv [LIST_0][block_y][img->block_x + i0][0], img->all_mv[LIST_0][fwref][mode][j][i0], 2 * (i1 - i0) * sizeof(short));
02009 }
02010 return;
02011 }
02012 else
02013 {
02014 if ((pdir == 0 || pdir == 2))
02015 {
02016 if (bipred_me && (pdir == 2) && is_bipred_enabled(mode))
02017 {
02018 for (j=j0; j<j1; j++)
02019 {
02020 block_y = img->block_y + j;
02021 for (i=i0; i<i1; i++)
02022 {
02023 block_x = img->block_x + i;
02024
02025 cur_mv = img->bipred_mv[bipred_me - 1][LIST_0][0][mode][j][i];
02026
02027 motion->mv [LIST_0][block_y][block_x][0] = cur_mv[0];
02028 motion->mv [LIST_0][block_y][block_x][1] = cur_mv[1];
02029 motion->ref_idx [LIST_0][block_y][block_x] = 0;
02030 motion->ref_pic_id[LIST_0][block_y][block_x] = enc_picture->ref_pic_num[LIST_0+currMB->list_offset][0];
02031 }
02032 }
02033 }
02034 else
02035 {
02036 if (mode==0)
02037 {
02038 for (j=j0; j<j1; j++)
02039 {
02040 block_y = img->block_y + j;
02041 ref_idx = motion->ref_idx[LIST_0][block_y];
02042 memcpy(&ref_idx[img->block_x + i0], &direct_ref_idx[LIST_0][block_y][img->block_x + i0], (i1 - i0) * sizeof(char));
02043 memcpy(&motion->mv[LIST_0][block_y][img->block_x + i0][0], img->all_mv[LIST_0][fwref][mode][j][i0], 2 * (i1 - i0) * sizeof(short));
02044 for (block_x = img->block_x + i0; block_x < img->block_x + i1; block_x++)
02045 {
02046 motion->ref_pic_id[LIST_0][block_y][block_x] =
02047 enc_picture->ref_pic_num[LIST_0+currMB->list_offset][(short)ref_idx[block_x]];
02048 }
02049 }
02050 }
02051 else
02052 {
02053 for (j=j0; j<j1; j++)
02054 {
02055 block_y = img->block_y + j;
02056 ref_pic_num = enc_picture->ref_pic_num[LIST_0+currMB->list_offset][fwref];
02057 memcpy(&motion->mv[LIST_0][block_y][img->block_x + i0][0], img->all_mv[LIST_0][fwref][mode][j][i0], 2 * (i1 - i0) * sizeof(short));
02058 memset(&motion->ref_idx[LIST_0][block_y][img->block_x + i0], fwref, (i1 - i0) * sizeof(char));
02059 for (block_x = img->block_x + i0; block_x < img->block_x + i1; block_x++)
02060 {
02061 motion->ref_pic_id[LIST_0][block_y][block_x] = ref_pic_num ;
02062 }
02063 }
02064 }
02065 }
02066 }
02067 else
02068 {
02069 for (j=j0; j<j1; j++)
02070 {
02071 block_y = img->block_y + j;
02072 for (i=img->block_x + i0; i<img->block_x +i1; i++)
02073 motion->ref_pic_id[LIST_0][block_y][i] = -1;
02074
02075 memset(&motion->ref_idx[LIST_0][block_y][img->block_x + i0], -1, (i1 - i0) * sizeof(char));
02076 memset(motion->mv[LIST_0][block_y][img->block_x + i0], 0, 2 * (i1 - i0) * sizeof(short));
02077 }
02078 }
02079
02080
02081 if ((pdir==1 || pdir==2))
02082 {
02083 if (bipred_me && (pdir == 2) && is_bipred_enabled(mode))
02084 {
02085 for (j=j0; j<j1; j++)
02086 {
02087 block_y = img->block_y + j;
02088
02089 for (i=i0; i<i1; i++)
02090 {
02091 block_x = img->block_x + i;
02092
02093 cur_mv = img->bipred_mv[bipred_me - 1][LIST_1][0][mode][j][i];
02094
02095 motion->mv [LIST_1][block_y][block_x][0] = cur_mv[0];
02096 motion->mv [LIST_1][block_y][block_x][1] = cur_mv[1];
02097 motion->ref_idx [LIST_1][block_y][block_x] = 0;
02098 motion->ref_pic_id[LIST_1][block_y][block_x] = enc_picture->ref_pic_num[LIST_1+currMB->list_offset][0];
02099 }
02100 }
02101 }
02102 else
02103 {
02104 if (mode==0)
02105 {
02106 for (j=j0; j<j1; j++)
02107 {
02108 block_y = img->block_y + j;
02109
02110 ref_idx = motion->ref_idx[LIST_1][block_y];
02111 memcpy(&ref_idx[img->block_x + i0], &direct_ref_idx[LIST_1][block_y][img->block_x + i0], (i1 - i0) * sizeof(char));
02112 memcpy(&motion->mv[LIST_1][block_y][img->block_x + i0][0], img->all_mv[LIST_1][(int) ref_idx[img->block_x + i0]][mode][j][i0], 2 * (i1 - i0) * sizeof(short));
02113 for (i=i0; i<i1; i++)
02114 {
02115 block_x = img->block_x + i;
02116 motion->ref_pic_id[LIST_1][block_y][block_x] = enc_picture->ref_pic_num[LIST_1+currMB->list_offset][(short)ref_idx[block_x]];
02117 }
02118 }
02119 }
02120 else
02121 {
02122 for (j=j0; j<j1; j++)
02123 {
02124 block_y = img->block_y + j;
02125 ref_pic_num = enc_picture->ref_pic_num[LIST_1+currMB->list_offset][bwref];
02126 memcpy(&motion->mv[LIST_1][block_y][img->block_x + i0][0], img->all_mv[LIST_1][bwref][mode][j][i0], 2 * (i1 - i0) * sizeof(short));
02127 memset(&motion->ref_idx[LIST_1][block_y][img->block_x + i0], bwref, (i1 - i0) * sizeof(char));
02128 for (block_x = img->block_x + i0; block_x < img->block_x + i1; block_x++)
02129 {
02130 motion->ref_pic_id[LIST_1][block_y][block_x] = ref_pic_num ;
02131 }
02132 }
02133 }
02134 }
02135 }
02136 else
02137 {
02138 for (j=j0; j<j1; j++)
02139 {
02140 block_y = img->block_y + j;
02141 memset(motion->mv[LIST_1][block_y][img->block_x + i0], 0, 2 * (i1 - i0) * sizeof(short));
02142 memset(&motion->ref_idx[LIST_1][block_y][img->block_x + i0], -1, (i1 - i0) * sizeof(char));
02143 for (block_x = img->block_x + i0; block_x < img->block_x + i1; block_x++)
02144 {
02145 motion->ref_pic_id[LIST_1][block_y][block_x] = -1;
02146 }
02147 }
02148 }
02149 }
02150 }
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160 byte field_flag_inference(Macroblock *currMB)
02161 {
02162 byte mb_field;
02163
02164 if (currMB->mbAvailA)
02165 {
02166 mb_field = img->mb_data[currMB->mbAddrA].mb_field;
02167 }
02168 else
02169 {
02170
02171 if (currMB->mbAvailB)
02172 mb_field = img->mb_data[currMB->mbAddrB].mb_field;
02173 else
02174 mb_field = 0;
02175 }
02176
02177 return mb_field;
02178 }
02179
02180
02181
02182
02183
02184
02185
02186
02187 void StoreMVBlock8x8(int dir, int block8x8, int mode, int l0_ref, int l1_ref, int pdir8, int bipred_me, int bslice)
02188 {
02189 int i0 = (block8x8 & 0x01) << 1;
02190 int j0 = (block8x8 >> 1) << 1;
02191 int j1 = j0 + 1;
02192
02193 short ******all_mv = img->all_mv;
02194 short ***lc_l0_mv8x8 = all_mv8x8[dir][LIST_0];
02195 short ***lc_l1_mv8x8 = all_mv8x8[dir][LIST_1];
02196
02197 if (!bslice)
02198 {
02199 if (pdir8>=0)
02200 {
02201 memcpy(&lc_l0_mv8x8[j0][i0][0], &all_mv[LIST_0][l0_ref][mode][j0][i0][0], 2 * 2 * sizeof(short));
02202 memcpy(&lc_l0_mv8x8[j1][i0][0], &all_mv[LIST_0][l0_ref][mode][j1][i0][0], 2 * 2 * sizeof(short));
02203 }
02204 }
02205 else
02206 {
02207 if (bslice && bipred_me)
02208 {
02209 all_mv = img->bipred_mv[bipred_me - 1];
02210 }
02211
02212 if (pdir8 == 0)
02213 {
02214 memcpy(&lc_l0_mv8x8[j0][i0][0], &all_mv[LIST_0][l0_ref][mode][j0][i0][0], 2 * 2 * sizeof(short));
02215 memcpy(&lc_l0_mv8x8[j1][i0][0], &all_mv[LIST_0][l0_ref][mode][j1][i0][0], 2 * 2 * sizeof(short));
02216 }
02217 else if (pdir8 == 1)
02218 {
02219 memcpy(&lc_l1_mv8x8[j0][i0][0], &all_mv[LIST_1][l1_ref][mode][j0][i0][0], 2 * 2 * sizeof(short));
02220 memcpy(&lc_l1_mv8x8[j1][i0][0], &all_mv[LIST_1][l1_ref][mode][j1][i0][0], 2 * 2 * sizeof(short));
02221 }
02222 else if (pdir8==2)
02223 {
02224 memcpy(&lc_l0_mv8x8[j0][i0][0], &all_mv[LIST_0][l0_ref][mode][j0][i0][0], 2 * 2 * sizeof(short));
02225 memcpy(&lc_l0_mv8x8[j1][i0][0], &all_mv[LIST_0][l0_ref][mode][j1][i0][0], 2 * 2 * sizeof(short));
02226 memcpy(&lc_l1_mv8x8[j0][i0][0], &all_mv[LIST_1][l1_ref][mode][j0][i0][0], 2 * 2 * sizeof(short));
02227 memcpy(&lc_l1_mv8x8[j1][i0][0], &all_mv[LIST_1][l1_ref][mode][j1][i0][0], 2 * 2 * sizeof(short));
02228 }
02229 else
02230 {
02231 error("invalid direction mode", 255);
02232 }
02233 }
02234 }
02235
02236
02237
02238
02239
02240
02241
02242 void StoreMV8x8(int dir)
02243 {
02244 int block8x8;
02245
02246 int bslice = (img->type == B_SLICE);
02247
02248 for (block8x8=0; block8x8<4; block8x8++)
02249 StoreMVBlock8x8(dir, block8x8, tr8x8.part8x8mode[block8x8], tr8x8.part8x8l0ref[block8x8],
02250 tr8x8.part8x8l1ref[block8x8], tr8x8.part8x8pdir[block8x8], tr8x8.part8x8bipred[block8x8], bslice);
02251 }
02252
02253
02254
02255
02256
02257
02258
02259 void RestoreMVBlock8x8(int dir, int block8x8, RD_8x8DATA *tr, int bslice)
02260 {
02261 short ******all_mv = img->all_mv;
02262 short ***lc_l0_mv8x8 = all_mv8x8[dir][LIST_0];
02263 short ***lc_l1_mv8x8 = all_mv8x8[dir][LIST_1];
02264
02265 short pdir8 = tr->part8x8pdir [block8x8];
02266 short mode = tr->part8x8mode [block8x8];
02267 short l0_ref = tr->part8x8l0ref[block8x8];
02268 short l1_ref = tr->part8x8l1ref[block8x8];
02269 short bipred_me = tr->part8x8bipred[block8x8];
02270
02271 int i0 = (block8x8 & 0x01) << 1;
02272 int j0 = (block8x8 >> 1) << 1;
02273 int j1 = j0 + 1;
02274
02275 if (!bslice)
02276 {
02277 if (pdir8>=0)
02278 {
02279 memcpy(&all_mv[LIST_0][l0_ref][4][j0][i0][0], &lc_l0_mv8x8[j0][i0][0], 2 * 2 * sizeof(short));
02280 memcpy(&all_mv[LIST_0][l0_ref][4][j1][i0][0], &lc_l0_mv8x8[j1][i0][0], 2 * 2 * sizeof(short));
02281 }
02282 }
02283 else
02284 {
02285 if (pdir8==0)
02286 {
02287 memcpy(&all_mv[LIST_0][l0_ref][mode][j0][i0][0], &lc_l0_mv8x8[j0][i0][0], 2 * 2 * sizeof(short));
02288 memcpy(&all_mv[LIST_0][l0_ref][mode][j1][i0][0], &lc_l0_mv8x8[j1][i0][0], 2 * 2 * sizeof(short));
02289 }
02290 else if (pdir8==1)
02291 {
02292 memcpy(&all_mv[LIST_1][l1_ref][mode][j0][i0][0], &lc_l1_mv8x8[j0][i0][0], 2 * 2 * sizeof(short));
02293 memcpy(&all_mv[LIST_1][l1_ref][mode][j1][i0][0], &lc_l1_mv8x8[j1][i0][0], 2 * 2 * sizeof(short));
02294 }
02295 else if (pdir8==2)
02296 {
02297 if(bipred_me)
02298 {
02299 all_mv = img->bipred_mv[bipred_me - 1];
02300 }
02301
02302 memcpy(&all_mv[LIST_0][l0_ref][mode][j0][i0][0], &lc_l0_mv8x8[j0][i0][0], 2 * 2 * sizeof(short));
02303 memcpy(&all_mv[LIST_0][l0_ref][mode][j1][i0][0], &lc_l0_mv8x8[j1][i0][0], 2 * 2 * sizeof(short));
02304 memcpy(&all_mv[LIST_1][l1_ref][mode][j0][i0][0], &lc_l1_mv8x8[j0][i0][0], 2 * 2 * sizeof(short));
02305 memcpy(&all_mv[LIST_1][l1_ref][mode][j1][i0][0], &lc_l1_mv8x8[j1][i0][0], 2 * 2 * sizeof(short));
02306 }
02307 else
02308 {
02309 error("invalid direction mode", 255);
02310 }
02311 }
02312 }
02313
02314
02315
02316
02317
02318
02319
02320 void RestoreMV8x8(int dir)
02321 {
02322 int block8x8;
02323
02324 int bslice = (img->type == B_SLICE);
02325
02326 for (block8x8=0; block8x8<4; block8x8++)
02327 RestoreMVBlock8x8(dir, block8x8, &tr8x8, bslice);
02328 }
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338 void StoreNewMotionVectorsBlock8x8(int dir, int block8x8, int mode, int l0_ref, int l1_ref, int pdir8, int bipred_me, int bslice)
02339 {
02340 int i0 = (block8x8 & 0x01) << 1;
02341 int j0 = (block8x8 >> 1) << 1;
02342 int j1 = j0 + 1;
02343
02344 short *****all_mv_l0 = img->all_mv[LIST_0];
02345 short *****all_mv_l1 = img->all_mv[LIST_1];
02346 short ***lc_l0_mv8x8 = &all_mv8x8[dir][LIST_0][j0];
02347 short ***lc_l1_mv8x8 = &all_mv8x8[dir][LIST_1][j0];
02348
02349
02350 if (pdir8<0)
02351 {
02352 memset(&lc_l0_mv8x8[0][i0][0], 0, 4 * sizeof(short));
02353 memset(&lc_l0_mv8x8[1][i0][0], 0, 4 * sizeof(short));
02354 memset(&lc_l1_mv8x8[0][i0][0], 0, 4 * sizeof(short));
02355 memset(&lc_l1_mv8x8[1][i0][0], 0, 4 * sizeof(short));
02356 return;
02357 }
02358
02359 if (!bslice)
02360 {
02361 memcpy(&lc_l0_mv8x8[0][i0][0], &all_mv_l0[l0_ref][mode][j0][i0][0], 4 * sizeof(short));
02362 memcpy(&lc_l0_mv8x8[1][i0][0], &all_mv_l0[l0_ref][mode][j1][i0][0], 4 * sizeof(short));
02363 memset(&lc_l1_mv8x8[0][i0][0], 0, 4 * sizeof(short));
02364 memset(&lc_l1_mv8x8[1][i0][0], 0, 4 * sizeof(short));
02365 return;
02366 }
02367 else
02368 {
02369 if (bslice && bipred_me)
02370 {
02371 all_mv_l0 = img->bipred_mv[bipred_me - 1][LIST_0];
02372 all_mv_l1 = img->bipred_mv[bipred_me - 1][LIST_1];
02373 }
02374
02375 if ((pdir8==0 || pdir8==2))
02376 {
02377 memcpy(&lc_l0_mv8x8[0][i0][0], &all_mv_l0[l0_ref][mode][j0][i0][0], 4 * sizeof(short));
02378 memcpy(&lc_l0_mv8x8[1][i0][0], &all_mv_l0[l0_ref][mode][j1][i0][0], 4 * sizeof(short));
02379 }
02380 else
02381 {
02382 memset(&lc_l0_mv8x8[0][i0][0], 0, 4 * sizeof(short));
02383 memset(&lc_l0_mv8x8[1][i0][0], 0, 4 * sizeof(short));
02384 }
02385
02386 if ((pdir8==1 || pdir8==2))
02387 {
02388 memcpy(&lc_l1_mv8x8[0][i0][0], &all_mv_l1[l1_ref][mode][j0][i0][0], 4 * sizeof(short));
02389 memcpy(&lc_l1_mv8x8[1][i0][0], &all_mv_l1[l1_ref][mode][j1][i0][0], 4 * sizeof(short));
02390 }
02391 else
02392 {
02393 memset(&lc_l1_mv8x8[0][i0][0], 0, 4 * sizeof(short));
02394 memset(&lc_l1_mv8x8[1][i0][0], 0, 4 * sizeof(short));
02395 }
02396 }
02397 }
02398
02399
02400
02401
02402
02403
02404
02405 int GetBestTransformP8x8()
02406 {
02407 int block_y, block_x, pic_pix_y, pic_pix_x, i, j, k;
02408 int mb_y, mb_x, block8x8;
02409 int cost8x8=0, cost4x4=0;
02410 int *diff_ptr;
02411
02412 if(params->Transform8x8Mode==2)
02413 return 1;
02414
02415 for (block8x8=0; block8x8<4; block8x8++)
02416 {
02417 mb_y = (block8x8 >> 1) << 3;
02418 mb_x = (block8x8 & 0x01) << 3;
02419
02420 k=0;
02421 for (block_y = mb_y; block_y < mb_y + 8; block_y += 4)
02422 {
02423 pic_pix_y = img->opix_y + block_y;
02424
02425
02426 for (block_x = mb_x; block_x<mb_x + 8; block_x += 4)
02427 {
02428 pic_pix_x = img->opix_x + block_x;
02429
02430
02431 diff_ptr=&diff4x4[k];
02432 for (j=0; j<4; j++)
02433 {
02434 for (i=0; i<4; i++, k++)
02435 {
02436
02437 diff4x4[k] = pCurImg[pic_pix_y+j][pic_pix_x+i] - tr4x4.mpr8x8[j+block_y][i+block_x];
02438
02439 diff8x8[k] = pCurImg[pic_pix_y+j][pic_pix_x+i] - tr8x8.mpr8x8[j+block_y][i+block_x];
02440 }
02441 }
02442
02443 cost4x4 += distortion4x4 (diff_ptr);
02444 }
02445 }
02446 cost8x8 += distortion8x8 (diff8x8);
02447 }
02448 return (cost8x8 < cost4x4);
02449 }
02450
02451
02452
02453
02454
02455
02456
02457 void set_mbaff_parameters(Macroblock *currMB)
02458 {
02459 int j;
02460 int mode = best_mode;
02461 int bslice = (img->type==B_SLICE);
02462 char **ipredmodes = img->ipredmode;
02463 PicMotionParams *motion = &enc_picture->motion;
02464
02465
02466
02467 for (j=0; j < MB_BLOCK_SIZE; j++)
02468 memcpy(rdopt->rec_mbY[j],&enc_picture->imgY[img->pix_y + j][img->pix_x], MB_BLOCK_SIZE * sizeof(imgpel));
02469
02470 if (img->yuv_format != YUV400)
02471 {
02472 for (j=0; j<img->mb_cr_size_y; j++)
02473 {
02474 memcpy(rdopt->rec_mb_cr[0][j], &enc_picture->imgUV[0][img->pix_c_y + j][img->pix_c_x], img->mb_cr_size_x * sizeof(imgpel));
02475 }
02476 for (j=0; j<img->mb_cr_size_y; j++)
02477 {
02478 memcpy(rdopt->rec_mb_cr[1][j], &enc_picture->imgUV[1][img->pix_c_y + j][img->pix_c_x], img->mb_cr_size_x * sizeof(imgpel));
02479 }
02480 }
02481
02482
02483 rdopt->mode = mode;
02484 rdopt->i16offset = img->i16offset;
02485 rdopt->cbp = currMB->cbp;
02486 rdopt->cbp_blk = currMB->cbp_blk;
02487 rdopt->mb_type = currMB->mb_type;
02488
02489 rdopt->luma_transform_size_8x8_flag = currMB->luma_transform_size_8x8_flag;
02490
02491 if(rdopt->mb_type == 0 && mode != 0)
02492 {
02493 mode=0;
02494 rdopt->mode=0;
02495 }
02496
02497 memcpy(rdopt->cofAC[0][0][0], img->cofAC[0][0][0], (4+img->num_blk8x8_uv) * 4 * 2 * 65 * sizeof(int));
02498 memcpy(rdopt->cofDC[0][0], img->cofDC[0][0], 3 * 2 * 18 * sizeof(int));
02499
02500 memcpy(rdopt->b8mode, currMB->b8mode, BLOCK_MULTIPLE * sizeof(short));
02501 memcpy(rdopt->b8pdir, currMB->b8pdir, BLOCK_MULTIPLE * sizeof(short));
02502
02503
02504 if (bslice)
02505 {
02506 if (params->BiPredMERefinements == 1)
02507 {
02508 int i, j, k;
02509 for (j = 0; j < BLOCK_MULTIPLE; j++)
02510 {
02511 for (i = 0; i < BLOCK_MULTIPLE; i++)
02512 {
02513 k = 2*(j >> 1)+(i >> 1);
02514 if (currMB->bipred_me[k] == 0)
02515 {
02516 rdopt->refar[LIST_0][j][i] = motion->ref_idx[LIST_0][img->block_y + j][img->block_x + i];
02517 rdopt->refar[LIST_1][j][i] = motion->ref_idx[LIST_1][img->block_y + j][img->block_x + i];
02518 }
02519 else
02520 {
02521 rdopt->refar[LIST_0][j][i] = 0;
02522 rdopt->refar[LIST_1][j][i] = 0;
02523 }
02524 }
02525 }
02526 }
02527 else
02528 {
02529 for (j = 0; j < BLOCK_MULTIPLE; j++)
02530 {
02531 memcpy(rdopt->refar[LIST_0][j],&motion->ref_idx[LIST_0][img->block_y + j][img->block_x] , BLOCK_MULTIPLE * sizeof(char));
02532 memcpy(rdopt->refar[LIST_1][j],&motion->ref_idx[LIST_1][img->block_y + j][img->block_x] , BLOCK_MULTIPLE * sizeof(char));
02533 }
02534 }
02535 }
02536 else
02537 {
02538 for (j = 0; j < BLOCK_MULTIPLE; j++)
02539 memcpy(rdopt->refar[LIST_0][j],&motion->ref_idx[LIST_0][img->block_y + j][img->block_x] , BLOCK_MULTIPLE * sizeof(char));
02540 }
02541
02542 memcpy(rdopt->intra_pred_modes,currMB->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
02543 memcpy(rdopt->intra_pred_modes8x8,currMB->intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
02544 for (j = img->block_y; j < img->block_y + 4; j++)
02545 {
02546 memcpy(&rdopt->ipredmode[j][img->block_x],&ipredmodes[j][img->block_x], BLOCK_MULTIPLE * sizeof(char));
02547 }
02548 }
02549
02550
02551
02552
02553
02554
02555
02556 void store_coding_state_cs_cm(Slice *currSlice, Macroblock *currMB)
02557 {
02558 store_coding_state(currSlice, currMB, cs_cm);
02559 }
02560
02561
02562
02563
02564
02565
02566
02567 void reset_coding_state_cs_cm(Slice *currSlice, Macroblock *currMB)
02568 {
02569 reset_coding_state(currSlice, currMB, cs_cm);
02570 }
02571
02572 void assign_enc_picture_params(int mode, char best_pdir, int block, int list_offset, int best_l0_ref, int best_l1_ref, int bslice, short bipred_me)
02573 {
02574 int i,j;
02575 int block_x, block_y;
02576 int list, maxlist, bestref;
02577 short ***curr_mv = NULL;
02578 int64 curr_ref_idx = 0;
02579 PicMotionParams *motion = &enc_picture->motion;
02580
02581 static int start_x = 0, start_y = 0, end_x = BLOCK_MULTIPLE, end_y = BLOCK_MULTIPLE;
02582
02583 switch (mode)
02584 {
02585 case 1:
02586 start_x = 0;
02587 start_y = 0;
02588 end_x = BLOCK_MULTIPLE;
02589 end_y = BLOCK_MULTIPLE;
02590 break;
02591 case 2:
02592 start_x = 0;
02593 start_y = block;
02594 end_x = BLOCK_MULTIPLE;
02595 end_y = block + 2;
02596 break;
02597 case 3:
02598 start_x = block;
02599 start_y = 0;
02600 end_x = block + 2;
02601 end_y = BLOCK_MULTIPLE;
02602 break;
02603 case 4:
02604 default:
02605 start_x = ((block>>1) & 0x01)* 2;
02606 start_y = ((block>>1) & 0x02);
02607 end_x = start_x + 2;
02608 end_y = start_y + 2;
02609 break;
02610 }
02611
02612 maxlist = bslice ? 1: 0;
02613 for (list = 0; list <= maxlist; list++)
02614 {
02615 bestref = (list == 0) ? best_l0_ref : best_l1_ref;
02616 switch (bipred_me)
02617 {
02618 case 0:
02619 curr_mv = img->all_mv[list][bestref][mode];
02620 curr_ref_idx = enc_picture->ref_pic_num[list + list_offset][bestref];
02621 break;
02622 case 1:
02623 curr_mv = img->bipred_mv[0][list][0][mode] ;
02624 curr_ref_idx = enc_picture->ref_pic_num[list + list_offset][0];
02625 break;
02626 case 2:
02627 curr_mv = img->bipred_mv[1][list][0][mode] ;
02628 curr_ref_idx = enc_picture->ref_pic_num[list + list_offset][0];
02629 break;
02630 default:
02631 break;
02632 }
02633
02634 for (j = start_y; j < end_y; j++)
02635 {
02636 block_y = img->block_y + j;
02637 for (i = start_x; i < end_x; i++)
02638 {
02639 block_x = img->block_x + i;
02640 if ((best_pdir != 2) && (best_pdir != list))
02641 {
02642 motion->ref_idx [list][block_y][block_x] = -1;
02643 motion->ref_pic_id [list][block_y][block_x] = -1;
02644 motion->mv [list][block_y][block_x][0] = 0;
02645 motion->mv [list][block_y][block_x][1] = 0;
02646 }
02647 else
02648 {
02649 motion->ref_pic_id [list][block_y][block_x] = curr_ref_idx;
02650 motion->mv [list][block_y][block_x][0] = curr_mv[j][i][0];
02651 motion->mv [list][block_y][block_x][1] = curr_mv[j][i][1];
02652 }
02653 }
02654 }
02655 }
02656 }
02657
02658
02659
02660
02661
02662
02663
02664 void copy_4x4block(imgpel **oblock, imgpel **iblock, int o_xoffset, int i_xoffset)
02665 {
02666 int y;
02667 for (y = 0; y < BLOCK_SIZE; y++)
02668 {
02669 memcpy(&oblock[y][o_xoffset],&iblock[y][i_xoffset], BLOCK_SIZE * sizeof(imgpel));
02670 }
02671 }
02672
02673
02674
02675
02676
02677
02678
02679 void set_block8x8_info(Block8x8Info *b8x8info, int mode, int block, char best_ref[2], char best_pdir, short bipred_me)
02680 {
02681 int i;
02682
02683 if (mode==3)
02684 {
02685 b8x8info->best8x8l0ref [3][block ] = b8x8info->best8x8l0ref [3][ block+2] = best_ref[LIST_0];
02686 b8x8info->best8x8pdir [3][block ] = b8x8info->best8x8pdir [3][ block+2] = best_pdir;
02687 b8x8info->best8x8l1ref [3][block ] = b8x8info->best8x8l1ref [3][ block+2] = best_ref[LIST_1];
02688 b8x8info->bipred8x8me [3][block ] = b8x8info->bipred8x8me [3][ block+2] = bipred_me;
02689 }
02690 else if (mode==2)
02691 {
02692 b8x8info->best8x8l0ref [2][2*block] = b8x8info->best8x8l0ref [2][2*block+1] = best_ref[LIST_0];
02693 b8x8info->best8x8pdir [2][2*block] = b8x8info->best8x8pdir [2][2*block+1] = best_pdir;
02694 b8x8info->best8x8l1ref [2][2*block] = b8x8info->best8x8l1ref [2][2*block+1] = best_ref[LIST_1];
02695 b8x8info->bipred8x8me [2][2*block] = b8x8info->bipred8x8me [2][2*block+1] = bipred_me;
02696 }
02697 else if (mode==1)
02698 {
02699 memset(&b8x8info->best8x8l0ref [1][0], best_ref[LIST_0], 4 * sizeof(char));
02700 memset(&b8x8info->best8x8l1ref [1][0], best_ref[LIST_1], 4 * sizeof(char));
02701 memset(&b8x8info->best8x8pdir [1][0], best_pdir, 4 * sizeof(char));
02702 for (i = 0; i< 4; i++)
02703 b8x8info->bipred8x8me [1][i] = bipred_me;
02704 }
02705 else
02706 {
02707 b8x8info->best8x8l0ref [mode][block] = best_ref[LIST_0];
02708 b8x8info->best8x8pdir [mode][block] = best_pdir;
02709 b8x8info->best8x8l1ref [mode][block] = best_ref[LIST_1];
02710 b8x8info->bipred8x8me [mode][block] = bipred_me;
02711 }
02712 }
02713
02714
02715
02716
02717
02718
02719
02720 void set_subblock8x8_info(Block8x8Info *b8x8info,int mode, int block, RD_8x8DATA *tr)
02721 {
02722 b8x8info->best8x8mode [block] = tr->part8x8mode [block];
02723 b8x8info->best8x8pdir [mode][block] = tr->part8x8pdir [block];
02724 b8x8info->best8x8l0ref [mode][block] = tr->part8x8l0ref [block];
02725 b8x8info->best8x8l1ref [mode][block] = tr->part8x8l1ref [block];
02726 b8x8info->bipred8x8me [mode][block] = tr->part8x8bipred[block];
02727 }
02728
02729
02730
02731 void update_refresh_map(int intra, int intra1, Macroblock *currMB)
02732 {
02733 if (params->RestrictRef==1)
02734 {
02735
02736 if (params->rdopt<2)
02737 {
02738 refresh_map[2*img->mb_y ][2*img->mb_x ] = (intra ? 1 : 0);
02739 refresh_map[2*img->mb_y ][2*img->mb_x+1] = (intra ? 1 : 0);
02740 refresh_map[2*img->mb_y+1][2*img->mb_x ] = (intra ? 1 : 0);
02741 refresh_map[2*img->mb_y+1][2*img->mb_x+1] = (intra ? 1 : 0);
02742 }
02743 else if (params->rdopt == 3)
02744 {
02745 refresh_map[2*img->mb_y ][2*img->mb_x ] = (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0);
02746 refresh_map[2*img->mb_y ][2*img->mb_x+1] = (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0);
02747 refresh_map[2*img->mb_y+1][2*img->mb_x ] = (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0);
02748 refresh_map[2*img->mb_y+1][2*img->mb_x+1] = (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0);
02749 }
02750 }
02751 else if (params->RestrictRef==2)
02752 {
02753 refresh_map[2*img->mb_y ][2*img->mb_x ] = (currMB->mb_type==I16MB || currMB->mb_type==I4MB ? 1 : 0);
02754 refresh_map[2*img->mb_y ][2*img->mb_x+1] = (currMB->mb_type==I16MB || currMB->mb_type==I4MB ? 1 : 0);
02755 refresh_map[2*img->mb_y+1][2*img->mb_x ] = (currMB->mb_type==I16MB || currMB->mb_type==I4MB ? 1 : 0);
02756 refresh_map[2*img->mb_y+1][2*img->mb_x+1] = (currMB->mb_type==I16MB || currMB->mb_type==I4MB ? 1 : 0);
02757 }
02758 }
02759
02760 int valid_intra_mode(int ipmode)
02761 {
02762 if (params->IntraDisableInterOnly==0 || img->type != I_SLICE)
02763 {
02764 if (params->Intra4x4ParDisable && (ipmode==VERT_PRED||ipmode==HOR_PRED))
02765 return 0;
02766
02767 if (params->Intra4x4DiagDisable && (ipmode==DIAG_DOWN_LEFT_PRED||ipmode==DIAG_DOWN_RIGHT_PRED))
02768 return 0;
02769
02770 if (params->Intra4x4DirDisable && ipmode>=VERT_RIGHT_PRED)
02771 return 0;
02772 }
02773 return 1;
02774 }
02775
02776 void compute_comp_cost(imgpel **cur_img, imgpel **prd_img, int pic_opix_x, int *cost)
02777 {
02778 int j, i, *d;
02779 imgpel *cur_line, *prd_line;
02780 d = &diff[0];
02781
02782 for (j = 0; j < BLOCK_SIZE; j++)
02783 {
02784 cur_line = &cur_img[j][pic_opix_x];
02785 prd_line = prd_img[j];
02786
02787 for (i = 0; i < BLOCK_SIZE; i++)
02788 {
02789 *d++ = *cur_line++ - *prd_line++;
02790 }
02791 }
02792 *cost += distortion4x4 (diff);
02793 }
02794
02795
02796 void generate_pred_error(imgpel **cur_img, imgpel **prd_img, imgpel **cur_prd,
02797 int **m7, int pic_opix_x, int block_x)
02798 {
02799 int j, i, *m7_line;
02800 imgpel *cur_line, *prd_line;
02801
02802 for (j = 0; j < BLOCK_SIZE; j++)
02803 {
02804 m7_line = &m7[j][block_x];
02805 cur_line = &cur_img[j][pic_opix_x];
02806 prd_line = prd_img[j];
02807 memcpy(&cur_prd[j][block_x], prd_line, BLOCK_SIZE * sizeof(imgpel));
02808
02809 for (i = 0; i < BLOCK_SIZE; i++)
02810 {
02811 *m7_line++ = (int) (*cur_line++ - *prd_line++);
02812 }
02813 }
02814 }
02815
02816
02817 void update_qp_cbp_tmp(Macroblock *currMB, int cbp, int best_mode)
02818 {
02819 if (((cbp!=0 || best_mode==I16MB) && (best_mode!=IPCM) ))
02820 currMB->prev_cbp = 1;
02821 else if ((cbp==0) || (best_mode==IPCM))
02822 {
02823 currMB->prev_cbp = 0;
02824 currMB->delta_qp = 0;
02825 currMB->qp = currMB->prev_qp;
02826 img->qp = currMB->qp;
02827 update_qp(img, currMB);
02828 }
02829 }
02830
02831
02832
02833
02834
02835
02836
02837
02838 void update_qp_cbp(Macroblock *currMB, short best_mode)
02839 {
02840
02841 if ((currMB->cbp!=0 || best_mode == I16MB) && (best_mode != IPCM))
02842 currMB->prev_cbp = 1;
02843 else
02844 {
02845 currMB->prev_cbp = 0;
02846 currMB->delta_qp = 0;
02847 currMB->qp = currMB->prev_qp;
02848 img->qp = currMB->qp;
02849 update_qp(img, currMB);
02850
02851 }
02852
02853 if (params->MbInterlace)
02854 {
02855
02856 rdopt->qp = currMB->qp;
02857 rdopt->delta_qp = currMB->delta_qp;
02858 rdopt->prev_cbp = currMB->prev_cbp;
02859 }
02860 }
02861
02862