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 "rd_intra_jm444.h"
00040 #include "fmo.h"
00041 #include "macroblock.h"
00042 #include "symbol.h"
00043 #include "q_offsets.h"
00044 #include "conformance.h"
00045 #include "errdo.h"
00046 #include "mv_search.h"
00047 #include "md_common.h"
00048 #include "md_distortion.h"
00049
00050 #define FASTMODE 1
00051
00052 static void compute_sad4x4_cost (ImageParameters *p_Img, imgpel **cur_img, imgpel **prd_img, int pic_opix_x, int *cost, int min_cost);
00053 static void compute_sse4x4_cost (ImageParameters *p_Img, imgpel **cur_img, imgpel **prd_img, int pic_opix_x, int *cost, int min_cost);
00054 static void compute_satd4x4_cost(ImageParameters *p_Img, imgpel **cur_img, imgpel **prd_img, int pic_opix_x, int *cost, int min_cost);
00055 static void compute_comp4x4_cost(ImageParameters *p_Img, imgpel **cur_img, imgpel **prd_img, int pic_opix_x, int *cost, int min_cost);
00056 static void set_stored_macroblock_parameters (Macroblock *currMB);
00057 static void set_stored_macroblock_parameters_sp (Macroblock *currMB);
00058 static void set_stored_macroblock_parameters_mpass(Macroblock *currMB);
00059 static void set_ref_and_motion_vectors_P_slice (Macroblock *currMB, PicMotionParams *motion, Info8x8 *pred, int);
00060 static void set_ref_and_motion_vectors_B_slice (Macroblock *currMB, PicMotionParams *motion, Info8x8 *pred, int);
00061
00062
00063 static inline void copy_motion_vectors_MB (Slice *currSlice, RD_DATA *rdopt)
00064 {
00065 memcpy(&currSlice->all_mv [LIST_0][0][0][0][0][0], &rdopt->all_mv [LIST_0][0][0][0][0][0], 576 * currSlice->max_num_references * sizeof(short));
00066 }
00067
00068 void alloc_rd8x8data (RD_8x8DATA *rd_data)
00069 {
00070 get_mem2Dint(&rd_data->lrec, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00071 get_mem2Dpel(&rd_data->mpr8x8, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00072 get_mem3Dpel(&rd_data->mpr8x8CbCr, 2, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00073 get_mem2Dpel(&rd_data->rec_mbY8x8, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00074 get_mem3Dpel(&rd_data->rec_mb8x8_cr, 2, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00075 }
00076
00077 void free_rd8x8data (RD_8x8DATA *rd_data)
00078 {
00079 free_mem3Dpel(rd_data->rec_mb8x8_cr);
00080 free_mem2Dpel(rd_data->rec_mbY8x8);
00081 free_mem3Dpel(rd_data->mpr8x8CbCr);
00082 free_mem2Dpel(rd_data->mpr8x8);
00083 free_mem2Dint(rd_data->lrec);
00084 }
00085
00086
00087
00088
00089
00090
00091
00092 void clear_rdopt (Slice *currSlice)
00093 {
00094 ImageParameters *p_Img = currSlice->p_Img;
00095 InputParameters *p_Inp = currSlice->p_Inp;
00096 RDOPTStructure *p_RDO = currSlice->p_RDO;
00097
00098
00099 free_mem_DCcoeff (p_RDO->cofDC);
00100 free_mem_ACcoeff (p_RDO->cofAC);
00101 free_mem_ACcoeff (p_RDO->cofAC4x4intern);
00102 free_mem_ACcoeff_new(p_RDO->coefAC8x8);
00103 free_mem_ACcoeff_new(p_RDO->coefAC8x8intra);
00104
00105 if (p_Inp->Transform8x8Mode)
00106 {
00107 free_mem_ACcoeff_new(p_RDO->cofAC8x8ts);
00108 }
00109
00110 if (p_Img->P444_joined)
00111 {
00112 free_mem_ACcoeff_new(p_RDO->cofAC4x4CbCrintern);
00113 }
00114
00115
00116 free_rd8x8data(p_RDO->tr4x4);
00117 free(p_RDO->tr4x4);
00118 free_rd8x8data(p_RDO->tr8x8);
00119 free(p_RDO->tr8x8);
00120
00121 free_mem5Dshort(p_RDO->all_mv8x8);
00122
00123 free_mem3Dpel(p_RDO->rec4x4);
00124 free_mem3Dpel(p_RDO->rec8x8);
00125 free_mem2Dpel(p_RDO->pred);
00126 free_mem3Dpel(p_RDO->rec_mb);
00127
00128 if (p_Inp->ProfileIDC == EXTENDED)
00129 {
00130 free_mem2Dint(p_RDO->lrec_rec);
00131 free_mem3Dint(p_RDO->lrec_rec_uv);
00132 }
00133
00134 free_mem2D((byte **) p_RDO->l0_refframe);
00135 free_mem2D((byte **) p_RDO->l1_refframe);
00136
00137
00138 delete_coding_state (p_RDO->cs_mb);
00139 delete_coding_state (p_RDO->cs_b8);
00140 delete_coding_state (p_RDO->cs_cm);
00141 delete_coding_state (p_RDO->cs_tmp);
00142 }
00143
00144 void setupDistCost(Slice *currSlice, InputParameters *p_Inp)
00145 {
00146 switch(p_Inp->ModeDecisionMetric)
00147 {
00148 case ERROR_SAD:
00149 currSlice->compute_cost4x4 = compute_sad4x4_cost;
00150 currSlice->compute_cost8x8 = compute_sad8x8_cost;
00151 currSlice->distI16x16 = distI16x16_sad;
00152 break;
00153 case ERROR_SSE:
00154 currSlice->compute_cost4x4 = compute_sse4x4_cost;
00155 currSlice->compute_cost8x8 = compute_sse8x8_cost;
00156 currSlice->distI16x16 = distI16x16_sse;
00157 break;
00158 case ERROR_SATD:
00159 currSlice->compute_cost4x4 = compute_satd4x4_cost;
00160 currSlice->compute_cost8x8 = compute_satd8x8_cost;
00161 currSlice->distI16x16 = distI16x16_satd;
00162 break;
00163 default:
00164 currSlice->compute_cost4x4 = compute_comp4x4_cost;
00165 currSlice->compute_cost8x8 = compute_comp8x8_cost;
00166 currSlice->distI16x16 = distI16x16_satd;
00167 break;
00168 }
00169 }
00170
00171
00172
00173
00174
00175
00176
00177
00178 void init_rdopt (Slice *currSlice)
00179 {
00180 ImageParameters *p_Img = currSlice->p_Img;
00181 InputParameters *p_Inp = currSlice->p_Inp;
00182 RDOPTStructure *p_RDO = currSlice->p_RDO;
00183
00184 get_mem_DCcoeff (&p_RDO->cofDC);
00185 get_mem_ACcoeff (p_Img, &p_RDO->cofAC);
00186 get_mem_ACcoeff (p_Img, &p_RDO->cofAC4x4intern);
00187 p_RDO->cofAC4x4 = p_RDO->cofAC4x4intern[0][0];
00188 get_mem_ACcoeff_new(&p_RDO->coefAC8x8, 3);
00189 get_mem_ACcoeff_new(&p_RDO->coefAC8x8intra, 3);
00190
00191 if (p_Inp->Transform8x8Mode)
00192 {
00193 get_mem_ACcoeff_new(&p_RDO->cofAC8x8ts, 3);
00194 }
00195
00196 if (((p_RDO->tr4x4) = (RD_8x8DATA *) calloc(1, sizeof(RD_8x8DATA)))==NULL)
00197 no_mem_exit("init_rdopt: p_RDO->tr4x4");
00198 alloc_rd8x8data(p_RDO->tr4x4);
00199 if (((p_RDO->tr8x8) = (RD_8x8DATA *) calloc(1, sizeof(RD_8x8DATA)))==NULL)
00200 no_mem_exit("init_rdopt: p_RDO->tr4x4");
00201 alloc_rd8x8data(p_RDO->tr8x8);
00202
00203 get_mem2Dpel(&p_RDO->pred, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00204 get_mem3Dpel(&p_RDO->rec8x8, 3, BLOCK_SIZE_8x8, BLOCK_SIZE_8x8);
00205 get_mem3Dpel(&p_RDO->rec4x4, 3, BLOCK_SIZE, BLOCK_SIZE);
00206 get_mem3Dpel(&p_RDO->rec_mb, 3, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00207
00208 if (p_Inp->ProfileIDC == EXTENDED)
00209 {
00210 get_mem2Dint(&p_RDO->lrec_rec, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00211 get_mem3Dint(&p_RDO->lrec_rec_uv, 2, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
00212 }
00213
00214 get_mem2D((byte ***) &p_RDO->l0_refframe, 4, 4);
00215 get_mem2D((byte ***) &p_RDO->l1_refframe, 4, 4);
00216
00217 get_mem5Dshort(&p_RDO->all_mv8x8, 2, 2, 4, 4, 2);
00218
00219 if (p_Img->P444_joined)
00220 {
00221 get_mem_ACcoeff_new(&p_RDO->cofAC4x4CbCrintern, 2);
00222
00223 p_RDO->cofAC4x4CbCr[0] = p_RDO->cofAC4x4CbCrintern[0][0][0];
00224 p_RDO->cofAC4x4CbCr[1] = p_RDO->cofAC4x4CbCrintern[0][1][0];
00225 }
00226
00227 currSlice->SetLagrangianMultipliers = p_Inp->rdopt == 0 ? SetLagrangianMultipliersOff : SetLagrangianMultipliersOn;
00228
00229 switch (p_Inp->rdopt)
00230 {
00231 case 0:
00232 currSlice->encode_one_macroblock = encode_one_macroblock_low;
00233 break;
00234 case 1:
00235 default:
00236 currSlice->encode_one_macroblock = encode_one_macroblock_high;
00237 break;
00238 case 2:
00239 currSlice->encode_one_macroblock = encode_one_macroblock_highfast;
00240 break;
00241 case 3:
00242 currSlice->encode_one_macroblock = encode_one_macroblock_highloss;
00243 break;
00244 }
00245 if (currSlice->MbaffFrameFlag || (currSlice->UseRDOQuant && currSlice->RDOQ_QP_Num > 1))
00246 currSlice->set_stored_mb_parameters = set_stored_macroblock_parameters_mpass;
00247 else
00248 {
00249 if (currSlice->slice_type == SP_SLICE)
00250 currSlice->set_stored_mb_parameters = set_stored_macroblock_parameters_sp;
00251 else
00252 currSlice->set_stored_mb_parameters = set_stored_macroblock_parameters;
00253 }
00254
00255
00256 p_RDO->cs_mb = create_coding_state (p_Inp);
00257 p_RDO->cs_b8 = create_coding_state (p_Inp);
00258 p_RDO->cs_cm = create_coding_state (p_Inp);
00259 p_RDO->cs_tmp = create_coding_state (p_Inp);
00260 if (p_Inp->CtxAdptLagrangeMult == 1)
00261 {
00262 p_Img->mb16x16_cost = CALM_MF_FACTOR_THRESHOLD;
00263 p_RDO->lambda_mf_factor = 1.0;
00264 }
00265
00266 currSlice->rdcost_for_4x4_intra_blocks = (p_Img->yuv_format == YUV444) ? rdcost_for_4x4_intra_blocks_444 : rdcost_for_4x4_intra_blocks;
00267 currSlice->rdcost_for_8x8_intra_blocks = (p_Img->yuv_format == YUV444) ? rdcost_for_8x8_intra_blocks_444 : rdcost_for_8x8_intra_blocks;
00268
00269 if (p_Inp->rdopt == 0)
00270 {
00271 currSlice->Mode_Decision_for_8x8IntraBlocks = (p_Img->yuv_format == YUV444) ? Mode_Decision_for_8x8IntraBlocks_JM_Low444 : Mode_Decision_for_8x8IntraBlocks_JM_Low;
00272 currSlice->Mode_Decision_for_4x4IntraBlocks = (p_Img->yuv_format == YUV444) ? Mode_Decision_for_4x4IntraBlocks_JM_Low444 : Mode_Decision_for_4x4IntraBlocks_JM_Low;
00273 }
00274 else
00275 {
00276 currSlice->Mode_Decision_for_8x8IntraBlocks = (p_Img->yuv_format == YUV444) ? Mode_Decision_for_8x8IntraBlocks_JM_High444 : Mode_Decision_for_8x8IntraBlocks_JM_High;
00277 currSlice->Mode_Decision_for_4x4IntraBlocks = (p_Img->yuv_format == YUV444) ? Mode_Decision_for_4x4IntraBlocks_JM_High444 : Mode_Decision_for_4x4IntraBlocks_JM_High;
00278 }
00279 currSlice->find_sad_16x16 = find_sad_16x16_JM;
00280
00281
00282 if (currSlice->slice_type == B_SLICE)
00283 currSlice->set_ref_and_motion_vectors = set_ref_and_motion_vectors_B_slice;
00284 else
00285 currSlice->set_ref_and_motion_vectors = set_ref_and_motion_vectors_P_slice;
00286
00287 setupDistortion(currSlice);
00288 setupDistCost (currSlice, p_Inp);
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 void UpdatePixelMap(ImageParameters *p_Img, InputParameters *p_Inp)
00303 {
00304 int mx,my,y,x,i,j;
00305 if (p_Img->type==I_SLICE)
00306 {
00307 memset(p_Img->pixel_map, 1, p_Img->height * p_Img->width * sizeof(byte));
00308 }
00309 else
00310 {
00311 for (my=0; my<p_Img->height >> 3; my++)
00312 for (mx=0; mx<p_Img->width >> 3; mx++)
00313 {
00314 j = my*8 + 8;
00315 i = mx*8 + 8;
00316 if (p_Img->refresh_map[my][mx])
00317 {
00318 for (y=my*8; y<j; y++)
00319 memset(&p_Img->pixel_map[y][mx*8], 1, 8 * sizeof(byte));
00320 }
00321 else
00322 {
00323 for (y=my*8; y<j; y++)
00324 for (x=mx*8; x<i; x++)
00325 {
00326 p_Img->pixel_map[y][x] = (byte) imin(p_Img->pixel_map[y][x] + 1, p_Inp->num_ref_frames+1);
00327 }
00328 }
00329 }
00330 }
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 int CheckReliabilityOfRef (Macroblock *currMB, int block, int list_idx, int ref, int mode)
00352 {
00353 Slice *currSlice = currMB->p_slice;
00354 ImageParameters *p_Img = currMB->p_Img;
00355
00356 int y,x, block_y, block_x, dy, dx, y_pos, x_pos, yy, xx, pres_x, pres_y;
00357 int maxold_x = p_Img->width - 1;
00358 int maxold_y = p_Img->height - 1;
00359 int ref_frame = ref + 1;
00360
00361 int by0 = (mode>=4?2*(block >> 1):mode==2?2*block:0);
00362 int by1 = by0 + (mode>=4||mode==2?2:4);
00363 int bx0 = (mode>=4?2*(block & 0x01):mode==3?2*block:0);
00364 int bx1 = bx0 + (mode>=4||mode==3?2:4);
00365
00366 for (block_y=by0; block_y<by1; block_y++)
00367 {
00368 for (block_x=bx0; block_x<bx1; block_x++)
00369 {
00370 y_pos = currSlice->all_mv[list_idx][ref][mode][block_y][block_x][1];
00371 y_pos += (currMB->block_y + block_y) * BLOCK_SIZE * 4;
00372 x_pos = currSlice->all_mv[list_idx][ref][mode][block_y][block_x][0];
00373 x_pos += (currMB->block_x + block_x) * BLOCK_SIZE * 4;
00374
00375
00376
00377
00378
00379 dy = y_pos & 3;
00380 dx = x_pos & 3;
00381
00382 y_pos = (y_pos - dy) >> 2;
00383 x_pos = (x_pos - dx) >> 2;
00384
00385 if (dy==0 && dx==0)
00386 {
00387 for (y=y_pos ; y < y_pos + BLOCK_SIZE ; y++)
00388 for (x=x_pos ; x < x_pos + BLOCK_SIZE ; x++)
00389 if (p_Img->pixel_map[iClip3(0,maxold_y,y)][iClip3(0,maxold_x,x)] < ref_frame)
00390 return 0;
00391 }
00392 else
00393 {
00394 if (dy == 0)
00395 {
00396 for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
00397 {
00398 pres_y = iClip3(0, maxold_y, y);
00399 for (x = x_pos ; x < x_pos + BLOCK_SIZE ; x++)
00400 {
00401 for(xx = -2 ; xx < 4 ; xx++)
00402 {
00403 pres_x = iClip3(0, maxold_x, x + xx);
00404 if (p_Img->pixel_map[pres_y][pres_x] < ref_frame)
00405 return 0;
00406 }
00407 }
00408 }
00409 }
00410 else if (dx == 0)
00411 {
00412 for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
00413 for (x=x_pos ; x < x_pos + BLOCK_SIZE ; x++)
00414 {
00415 pres_x = iClip3(0,maxold_x,x);
00416 for(yy=-2;yy<4;yy++)
00417 {
00418 pres_y = iClip3(0,maxold_y, yy + y);
00419 if (p_Img->pixel_map[pres_y][pres_x] < ref_frame)
00420 return 0;
00421 }
00422 }
00423 }
00424 else if (dx == 2)
00425 {
00426 for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
00427 for (x = x_pos ; x < x_pos + BLOCK_SIZE ; x++)
00428 {
00429 for(yy=-2;yy<4;yy++)
00430 {
00431 pres_y = iClip3(0,maxold_y, yy + y);
00432 for(xx=-2;xx<4;xx++)
00433 {
00434 pres_x = iClip3(0,maxold_x, xx + x);
00435 if (p_Img->pixel_map[pres_y][pres_x] < ref_frame)
00436 return 0;
00437 }
00438 }
00439 }
00440 }
00441 else if (dy == 2)
00442 {
00443 for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
00444 for (x = x_pos ; x < x_pos + BLOCK_SIZE ; x++)
00445 {
00446 for(xx=-2;xx<4;xx++)
00447 {
00448 pres_x = iClip3(0,maxold_x, xx + x);
00449 for(yy=-2;yy<4;yy++)
00450 {
00451 pres_y = iClip3(0,maxold_y, yy + y);
00452 if (p_Img->pixel_map[pres_y][pres_x] < ref_frame)
00453 return 0;
00454 }
00455 }
00456 }
00457 }
00458 else
00459 {
00460 for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
00461 {
00462 for (x = x_pos ; x < x_pos + BLOCK_SIZE ; x++)
00463 {
00464 pres_y = dy == 1 ? y : y + 1;
00465 pres_y = iClip3(0,maxold_y,pres_y);
00466
00467 for(xx=-2;xx<4;xx++)
00468 {
00469 pres_x = iClip3(0,maxold_x,xx + x);
00470 if (p_Img->pixel_map[pres_y][pres_x] < ref_frame)
00471 return 0;
00472 }
00473
00474 pres_x = dx == 1 ? x : x + 1;
00475 pres_x = iClip3(0,maxold_x,pres_x);
00476
00477 for(yy=-2;yy<4;yy++)
00478 {
00479 pres_y = iClip3(0,maxold_y, yy + y);
00480 if (p_Img->pixel_map[pres_y][pres_x] < ref_frame)
00481 return 0;
00482 }
00483 }
00484 }
00485 }
00486 }
00487 }
00488 }
00489 return 1;
00490 }
00491
00492
00493
00494
00495
00496
00497
00498 double rdcost_for_4x4_intra_blocks (Macroblock *currMB,
00499 int* nonzero,
00500 int b8,
00501 int b4,
00502 int ipmode,
00503 double lambda,
00504 int mostProbableMode,
00505 double min_rdcost)
00506 {
00507 Slice *currSlice = currMB->p_slice;
00508 ImageParameters *p_Img = currMB->p_Img;
00509
00510 double rdcost;
00511 int dummy = 0, rate;
00512 int64 distortion = 0;
00513 int block_x = ((b8 & 0x01) << 3) + ((b4 & 0x01) << 2);
00514 int block_y = ((b8 >> 1) << 3) + ((b4 >> 1) << 2);
00515 int pic_pix_x = currMB->pix_x + block_x;
00516 int pic_pix_y = currMB->pix_y + block_y;
00517 int pic_opix_y = currMB->opix_y + block_y;
00518
00519 SyntaxElement se;
00520 const int *partMap = assignSE2partition[currSlice->partition_mode];
00521
00522 DataPartition *dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
00523
00524
00525
00526 *nonzero = currMB->trans_4x4 (currMB, PLANE_Y, block_x, block_y, &dummy, 1);
00527
00528
00529 distortion += compute_SSE4x4(&p_Img->pCurImg[pic_opix_y], &p_Img->enc_picture->imgY[pic_pix_y], pic_pix_x, pic_pix_x);
00530 #if INTRA_RDCOSTCALC_EARLY_TERMINATE
00531
00532 if ((double) distortion >= min_rdcost)
00533 {
00534 return ((double) distortion);
00535 }
00536 #endif
00537 currMB->ipmode_DPCM = NO_INTRA_PMODE;
00538
00539
00540 se.value1 = (mostProbableMode == ipmode) ? -1 : ipmode < mostProbableMode ? ipmode : ipmode - 1;
00541
00542
00543 se.context = (b8 << 2) + b4;
00544 se.type = SE_INTRAPREDMODE;
00545
00546
00547 currSlice->writeIntraPredMode (&se, dataPart);
00548 rate = se.len;
00549
00550
00551 if (currSlice->symbol_mode == CAVLC)
00552 {
00553 rate += currSlice->writeCoeff4x4_CAVLC (currMB, LUMA, b8, b4, 0);
00554 }
00555 else
00556 {
00557 rate += writeCoeff4x4_CABAC (currMB, PLANE_Y, b8, b4, 1);
00558 }
00559 rdcost = (double)distortion + lambda * (double) rate;
00560
00561 currSlice->reset_coding_state (currMB, currSlice->p_RDO->cs_cm);
00562
00563 return rdcost;
00564 }
00565
00566
00567
00568
00569
00570
00571
00572
00573 double rdcost_for_4x4_intra_blocks_444 (Macroblock *currMB,
00574 int* nonzero,
00575 int b8,
00576 int b4,
00577 int ipmode,
00578 double lambda,
00579 int mostProbableMode,
00580 double min_rdcost)
00581 {
00582 Slice *currSlice = currMB->p_slice;
00583 ImageParameters *p_Img = currMB->p_Img;
00584
00585 double rdcost;
00586 int dummy = 0, rate;
00587 int64 distortion = 0;
00588 int block_x = ((b8 & 0x01) << 3) + ((b4 & 0x01) << 2);
00589 int block_y = ((b8 >> 1) << 3) + ((b4 >> 1) << 2);
00590 int pic_pix_x = currMB->pix_x + block_x;
00591 int pic_pix_y = currMB->pix_y + block_y;
00592 int pic_opix_y = currMB->opix_y + block_y;
00593
00594 SyntaxElement se;
00595 const int *partMap = assignSE2partition[currSlice->partition_mode];
00596 DataPartition *dataPart;
00597 ColorPlane k;
00598
00599
00600
00601 *nonzero = currMB->trans_4x4 (currMB, PLANE_Y, block_x, block_y, &dummy, 1);
00602
00603
00604 distortion += compute_SSE4x4(&p_Img->pCurImg[pic_opix_y], &p_Img->enc_picture->imgY[pic_pix_y], pic_pix_x, pic_pix_x);
00605
00606 if(p_Img->P444_joined)
00607 {
00608 for (k = PLANE_U; k <= PLANE_V; k++)
00609 {
00610 select_plane(p_Img, k);
00611 currMB->c_nzCbCr[k] = currMB->trans_4x4(currMB, k, block_x, block_y, &dummy, 1);
00612 distortion += compute_SSE4x4(&p_Img->pCurImg[pic_opix_y], &p_Img->enc_picture->p_curr_img[pic_pix_y], pic_pix_x, pic_pix_x);
00613 }
00614 select_plane(p_Img, PLANE_Y);
00615 }
00616 currMB->ipmode_DPCM = NO_INTRA_PMODE;
00617
00618
00619 se.value1 = (mostProbableMode == ipmode) ? -1 : ipmode < mostProbableMode ? ipmode : ipmode - 1;
00620
00621
00622 se.context = (b8 << 2) + b4;
00623 se.type = SE_INTRAPREDMODE;
00624
00625
00626 dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
00627
00628 currSlice->writeIntraPredMode (&se, dataPart);
00629 rate = se.len;
00630
00631
00632 if (currSlice->symbol_mode == CAVLC)
00633 {
00634 rate += currSlice->writeCoeff4x4_CAVLC (currMB, LUMA, b8, b4, 0);
00635 if(p_Img->P444_joined)
00636 {
00637 rate += currSlice->writeCoeff4x4_CAVLC (currMB, CB, b8, b4, 0);
00638 rate += currSlice->writeCoeff4x4_CAVLC (currMB, CR, b8, b4, 0);
00639 }
00640 }
00641 else
00642 {
00643 rate += writeCoeff4x4_CABAC (currMB, PLANE_Y, b8, b4, 1);
00644 if(p_Img->P444_joined)
00645 {
00646 rate += writeCoeff4x4_CABAC (currMB, PLANE_U, b8, b4, 1);
00647 rate += writeCoeff4x4_CABAC (currMB, PLANE_V, b8, b4, 1);
00648 }
00649 }
00650
00651 rdcost = (double)distortion + lambda * (double) rate;
00652
00653 currSlice->reset_coding_state (currMB, currSlice->p_RDO->cs_cm);
00654
00655 return rdcost;
00656 }
00657
00658
00659
00660
00661
00662
00663
00664 double RDCost_for_8x8blocks (Macroblock *currMB,
00665 RD_8x8DATA *dataTr,
00666 int* cnt_nonz,
00667 int64* cbp_blk,
00668 double lambda,
00669 int block,
00670 short mode,
00671 Info8x8 *part,
00672 double min_rdcost)
00673 {
00674 Slice *currSlice = currMB->p_slice;
00675 ImageParameters *p_Img = currMB->p_Img;
00676 InputParameters *p_Inp = currMB->p_Inp;
00677 pic_parameter_set_rbsp_t *active_pps = p_Img->active_pps;
00678 int k;
00679 int rate=0;
00680 int64 distortion=0;
00681
00682 int dummy = 0, mrate;
00683 int list_mode[2];
00684 int cbp = 0;
00685 int pax = 8*(block & 0x01);
00686 int pay = 8*(block >> 1);
00687 int i0 = pax >> 2;
00688 int j0 = pay >> 2;
00689 int direct = (currSlice->slice_type == B_SLICE && mode==0);
00690 int b8value = B8Mode2Value (currSlice, (short) mode, part->pdir);
00691
00692 SyntaxElement se;
00693 DataPartition *dataPart;
00694 const int *partMap = assignSE2partition[currSlice->partition_mode];
00695
00696 EncodingEnvironmentPtr eep_dp;
00697
00698 short pdir = part->pdir;
00699 int l0_ref = part->ref[LIST_0];
00700 int l1_ref = part->ref[LIST_1];
00701
00702
00703
00704
00705 currMB->b8x8[block].bipred = part->bipred;
00706 currMB->ar_mode = (short) ((mode != 0)? mode: P8x8);
00707
00708
00709 if (direct)
00710 {
00711 if (currSlice->direct_pdir[currMB->block_y + j0][currMB->block_x + i0] < 0)
00712 return (1e20);
00713 else
00714 {
00715 int list_mode[2] = {0, 0};
00716 if (currSlice->P444_joined)
00717 {
00718 *cnt_nonz = luma_residual_coding_p444_8x8 (currMB, &cbp, cbp_blk, block, currSlice->direct_pdir[currMB->block_y+j0][currMB->block_x+i0], list_mode,
00719 currSlice->direct_ref_idx[currMB->block_y+j0][currMB->block_x+i0]);
00720 }
00721 else
00722 {
00723 *cnt_nonz = luma_residual_coding_8x8 (currMB, &cbp, cbp_blk, block, currSlice->direct_pdir[currMB->block_y+j0][currMB->block_x+i0], list_mode,
00724 currSlice->direct_ref_idx[currMB->block_y+j0][currMB->block_x+i0]);
00725 }
00726 }
00727 }
00728 else
00729 {
00730 if (pdir == 2 && active_pps->weighted_bipred_idc == 1)
00731 {
00732
00733 int weight_sum = (active_pps->weighted_bipred_idc == 1)? currSlice->wbp_weight[0][l0_ref][l1_ref][0] + currSlice->wbp_weight[1][l0_ref][l1_ref][0] : 0;
00734 if (weight_sum < -128 || weight_sum > 127)
00735 {
00736 return (1e20);
00737 }
00738 }
00739
00740 list_mode[0] = (pdir==0||pdir==2 ? mode : 0);
00741 list_mode[1] = (pdir==1||pdir==2 ? mode : 0);
00742 if (currSlice->P444_joined)
00743 {
00744 *cnt_nonz = luma_residual_coding_p444_8x8 (currMB, &cbp, cbp_blk, block, pdir, list_mode, part->ref);
00745 }
00746 else
00747 {
00748 *cnt_nonz = luma_residual_coding_8x8 (currMB, &cbp, cbp_blk, block, pdir, list_mode, part->ref);
00749 }
00750 }
00751
00752 if(p_Img->P444_joined)
00753 {
00754 *cnt_nonz += ( currSlice->coeff_cost_cr[1] + currSlice->coeff_cost_cr[2] );
00755 }
00756
00757
00758 if (p_Inp->rdopt==3)
00759 {
00760
00761
00762
00763 compute_residue_block (currMB, &p_Img->enc_picture->p_img[0][currMB->pix_y], p_Img->p_decs->res_img[0], currSlice->mb_pred[0], block, 8);
00764
00765
00766
00767
00768 for (k=0; k<p_Inp->NoOfDecoders ;k++)
00769 {
00770 decode_one_b8block (currMB, p_Img->enc_picture, k, block, mode, pdir);
00771 distortion += compute_SSE8x8(&p_Img->pCurImg[currMB->opix_y + pay], &p_Img->enc_picture->p_dec_img[0][k][currMB->opix_y + pay], currMB->pix_x + pax, currMB->pix_x + pax);
00772 }
00773 distortion /= p_Inp->NoOfDecoders;
00774 }
00775 else
00776 {
00777 distortion += compute_SSE8x8(&p_Img->pCurImg[currMB->opix_y + pay], &p_Img->enc_picture->imgY[currMB->pix_y + pay], currMB->pix_x + pax, currMB->pix_x + pax);
00778
00779 if (p_Img->P444_joined)
00780 {
00781 distortion += compute_SSE8x8(&p_Img->pImgOrg[1][currMB->opix_y + pay], &p_Img->enc_picture->imgUV[0][currMB->pix_y + pay], currMB->pix_x + pax, currMB->pix_x + pax);
00782 distortion += compute_SSE8x8(&p_Img->pImgOrg[2][currMB->opix_y + pay], &p_Img->enc_picture->imgUV[1][currMB->pix_y + pay], currMB->pix_x + pax, currMB->pix_x + pax);
00783 }
00784 }
00785
00786
00787 if ((double) distortion >= min_rdcost)
00788 return ((double)distortion);
00789
00790
00791 if(p_Img->P444_joined)
00792 {
00793 cbp |= currSlice->cmp_cbp[1];
00794 cbp |= currSlice->cmp_cbp[2];
00795
00796 currSlice->cmp_cbp[1] = cbp;
00797 currSlice->cmp_cbp[2] = cbp;
00798 }
00799
00800
00801
00802
00803
00804 if (currSlice->symbol_mode == CAVLC)
00805 {
00806 ue_linfo (b8value, dummy, &mrate, &dummy);
00807 rate += mrate;
00808 }
00809 else
00810 {
00811 se.value1 = b8value;
00812 se.type = SE_MBTYPE;
00813 dataPart = &(currSlice->partArr[partMap[se.type]]);
00814 currSlice->writeB8_typeInfo(&se, dataPart);
00815 rate += se.len;
00816 }
00817
00818
00819 if (!direct)
00820 {
00821 if ((currSlice->num_ref_idx_active[LIST_0] > 1 ) && (pdir==0 || pdir==2))
00822 rate += writeReferenceFrame (currMB, i0, j0, LIST_0, l0_ref);
00823
00824 if ((currSlice->num_ref_idx_active[LIST_1] > 1 && currSlice->slice_type == B_SLICE ) && (pdir==1 || pdir==2))
00825 {
00826 rate += writeReferenceFrame (currMB, i0, j0, LIST_1, l1_ref);
00827 }
00828
00829 if (pdir==0 || pdir==2)
00830 {
00831 rate += writeMotionVector8x8 (currMB, i0, j0, i0 + 2, j0 + 2, l0_ref, LIST_0, mode, currMB->b8x8[block].bipred);
00832 }
00833 if (pdir==1 || pdir==2)
00834 {
00835 rate += writeMotionVector8x8 (currMB, i0, j0, i0 + 2, j0 + 2, l1_ref, LIST_1, mode, currMB->b8x8[block].bipred);
00836 }
00837 }
00838
00839
00840 if (!currSlice->symbol_mode == CAVLC)
00841 {
00842 dataPart = &(currSlice->partArr[partMap[SE_CBP]]);
00843 eep_dp = &(dataPart->ee_cabac);
00844 mrate = arienco_bits_written (eep_dp);
00845 writeCBP_BIT_CABAC (currMB, block, ((*cnt_nonz>0)?1:0), dataTr->cbp8x8, eep_dp, currSlice->tex_ctx);
00846 mrate = arienco_bits_written (eep_dp) - mrate;
00847 rate += mrate;
00848 }
00849
00850
00851 if (*cnt_nonz)
00852 {
00853 rate += writeCoeff8x8 ( currMB, PLANE_Y, block, mode, currMB->luma_transform_size_8x8_flag);
00854 }
00855
00856 if(p_Img->P444_joined)
00857 {
00858 rate += writeCoeff8x8( currMB, PLANE_U, block, mode, currMB->luma_transform_size_8x8_flag );
00859 rate += writeCoeff8x8( currMB, PLANE_V, block, mode, currMB->luma_transform_size_8x8_flag );
00860 }
00861
00862 return (double)distortion + lambda * (double)rate;
00863 }
00864
00865
00866
00867
00868
00869
00870
00871
00872 short I16Offset (int cbp, short i16mode)
00873 {
00874 return (short) ((cbp & 15 ? 13 : 1) + i16mode + ((cbp & 0x30) >> 2));
00875 }
00876
00877
00878
00879
00880
00881
00882
00883
00884 void SetModesAndRefframeForBlocks (Macroblock *currMB, short mode)
00885 {
00886 Slice *currSlice = currMB->p_slice;
00887 ImageParameters *p_Img = currMB->p_Img;
00888
00889 int i,j,k;
00890 int block_x, block_y, block8x8, block4x4;
00891 int cur_ref;
00892 int clist;
00893 char curref, bestref;
00894 Block8x8Info *b8x8info = p_Img->b8x8info;
00895 PicMotionParams *motion = &p_Img->enc_picture->motion;
00896
00897
00898 currMB->mb_type = mode;
00899
00900 for( i = 0; i < 4; i++)
00901 {
00902 currMB->b8x8[i] = b8x8info->best[mode][i];
00903 }
00904
00905 currMB->ar_mode = mode;
00906
00907
00908 switch (mode)
00909 {
00910 case 0:
00911 currMB->b8x8[0].mode = 0;
00912 currMB->b8x8[1].mode = 0;
00913 currMB->b8x8[2].mode = 0;
00914 currMB->b8x8[3].mode = 0;
00915 if (currSlice->slice_type == B_SLICE)
00916 {
00917 for(i=0;i<4;i++)
00918 {
00919 currMB->b8x8[i].pdir = currSlice->direct_pdir[currMB->block_y + ((i >> 1)<<1)][currMB->block_x + ((i & 0x01)<<1)];
00920 }
00921 }
00922 else
00923 {
00924
00925 currMB->b8x8[0].pdir = 0;
00926 currMB->b8x8[1].pdir = 0;
00927 currMB->b8x8[2].pdir = 0;
00928 currMB->b8x8[3].pdir = 0;
00929 }
00930 break;
00931 case 1:
00932 case 2:
00933 case 3:
00934 for(i=0;i<4;i++)
00935 {
00936 currMB->b8x8[i].mode = (char) mode;
00937 }
00938 break;
00939 case P8x8:
00940 break;
00941 case I4MB:
00942 for(i=0;i<4;i++)
00943 {
00944 currMB->b8x8[i].mode = IBLOCK;
00945 currMB->b8x8[i].pdir = -1;
00946 }
00947 break;
00948 case I16MB:
00949
00950 currMB->b8x8[0].mode = 0;
00951 currMB->b8x8[1].mode = 0;
00952 currMB->b8x8[2].mode = 0;
00953 currMB->b8x8[3].mode = 0;
00954 for(i=0;i<4;i++)
00955 {
00956 currMB->b8x8[i].pdir = -1;
00957 }
00958 break;
00959 case I8MB:
00960 for(i=0;i<4;i++)
00961 {
00962 currMB->b8x8[i].mode = I8MB;
00963 currMB->b8x8[i].pdir = -1;
00964 }
00965
00966 currMB->luma_transform_size_8x8_flag = TRUE;
00967 break;
00968 case IPCM:
00969 for(i=0;i<4;i++)
00970 {
00971 currMB->b8x8[i].mode = IPCM;
00972 currMB->b8x8[i].pdir = -1;
00973 }
00974 currMB->luma_transform_size_8x8_flag = FALSE;
00975 break;
00976 default:
00977 printf ("Unsupported mode in SetModesAndRefframeForBlocks!\n");
00978 exit (1);
00979 }
00980
00981 #define IS_FW ((b8x8info->best[mode][k].pdir==0 || b8x8info->best[mode][k].pdir==2) && (mode!=P8x8 || b8x8info->best[mode][k].mode!=0 || currSlice->slice_type != B_SLICE))
00982 #define IS_BW ((b8x8info->best[mode][k].pdir==1 || b8x8info->best[mode][k].pdir==2) && (mode!=P8x8 || b8x8info->best[mode][k].mode!=0))
00983
00984
00985 if (mode==0 || mode==I4MB || mode==I16MB || mode==I8MB || mode == IPCM || mode == SI4MB)
00986 {
00987 if (currSlice->slice_type == B_SLICE)
00988 {
00989 if (!mode)
00990 {
00991 for (clist = LIST_0; clist <= LIST_1; clist++)
00992 {
00993 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
00994 {
00995 for (i = currMB->block_x; i < currMB->block_x + 4; i++)
00996 motion->ref_idx[clist][j][i] = currSlice->direct_ref_idx[j][i][clist];
00997 }
00998 }
00999 }
01000 else
01001 {
01002 for (clist = LIST_0; clist <= LIST_1; clist++)
01003 {
01004 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
01005 {
01006 memset(&motion->ref_idx[clist][j][currMB->block_x], -1, 4 * sizeof(char));
01007 }
01008 }
01009 }
01010 }
01011 else
01012 {
01013 if (!mode)
01014 {
01015 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
01016 memset(&motion->ref_idx[LIST_0][j][currMB->block_x],0, 4 * sizeof(char));
01017 }
01018 else
01019 {
01020 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
01021 memset(&motion->ref_idx[LIST_0][j][currMB->block_x],-1, 4 * sizeof(char));
01022 }
01023 }
01024 }
01025 else
01026 {
01027 if (currSlice->slice_type == B_SLICE)
01028 {
01029 if (mode == 1 || mode == 2 || mode == 3)
01030 {
01031 for (block8x8 = 0; block8x8 < 4; block8x8++)
01032 {
01033 for (clist = LIST_0; clist <= LIST_1; clist++)
01034 {
01035 bestref = b8x8info->best[mode][block8x8].ref[clist];
01036 if ( b8x8info->best[mode][block8x8].pdir == 2)
01037 {
01038 curref = (b8x8info->best[mode][block8x8].bipred) ? 0 : bestref;
01039 }
01040 else
01041 {
01042 curref = (clist == b8x8info->best[mode][block8x8].pdir) ? bestref : -1;
01043 }
01044
01045 for (block4x4 = 0; block4x4 < 4; block4x4++)
01046 {
01047 block_x = currMB->block_x + 2 * (block8x8 & 0x01) + (block4x4 & 0x01);
01048 block_y = currMB->block_y + 2 * (block8x8 >> 1) + (block4x4 >> 1);
01049 motion->ref_idx[clist][block_y][block_x] = curref;
01050 }
01051 }
01052 }
01053 }
01054 else
01055 {
01056 if (mode == P8x8)
01057 {
01058 for (j=0;j<4;j++)
01059 {
01060 block_y = currMB->block_y + j;
01061 for (i=0;i<4;i++)
01062 {
01063 block_x = currMB->block_x + i;
01064 k = 2*(j >> 1) + (i >> 1);
01065
01066 if(b8x8info->best[mode][k].mode==0)
01067 {
01068 motion->ref_idx[LIST_0][block_y][block_x] = currSlice->direct_ref_idx[block_y][block_x][LIST_0];
01069 motion->ref_idx[LIST_1][block_y][block_x] = currSlice->direct_ref_idx[block_y][block_x][LIST_1];
01070 }
01071 else
01072 {
01073 motion->ref_idx[LIST_0][block_y][block_x] = (IS_FW ? b8x8info->best[mode][k].ref[LIST_0] : -1);
01074 motion->ref_idx[LIST_1][block_y][block_x] = (IS_BW ? b8x8info->best[mode][k].ref[LIST_1] : -1);
01075 }
01076 }
01077 }
01078 }
01079 else
01080 {
01081 for (j=0;j<4;j++)
01082 {
01083 block_y = currMB->block_y + j;
01084 for (i=0;i<4;i++)
01085 {
01086 block_x = currMB->block_x + i;
01087 k = 2*(j >> 1) + (i >> 1);
01088
01089
01090 motion->ref_idx[LIST_0][block_y][block_x] = (IS_FW ? b8x8info->best[mode][k].ref[LIST_0] : -1);
01091 motion->ref_idx[LIST_1][block_y][block_x] = (IS_BW ? b8x8info->best[mode][k].ref[LIST_1] : -1);
01092 }
01093 }
01094 }
01095 }
01096 }
01097 else
01098 {
01099 if (mode == 1)
01100 {
01101 curref = b8x8info->best[mode][0].pdir == 0 ? b8x8info->best[mode][0].ref[LIST_0] : -1;
01102 j = currMB->block_y;
01103 memset(&motion->ref_idx[LIST_0][j++][currMB->block_x], curref, 4 * sizeof(char));
01104 memset(&motion->ref_idx[LIST_0][j++][currMB->block_x], curref, 4 * sizeof(char));
01105 memset(&motion->ref_idx[LIST_0][j++][currMB->block_x], curref, 4 * sizeof(char));
01106 memset(&motion->ref_idx[LIST_0][j ][currMB->block_x], curref, 4 * sizeof(char));
01107 }
01108 else if (mode == 2)
01109 {
01110 curref = b8x8info->best[mode][0].pdir == 0 ? b8x8info->best[mode][0].ref[LIST_0] : -1;
01111 j = currMB->block_y;
01112 memset(&motion->ref_idx[LIST_0][j++][currMB->block_x], curref, 4 * sizeof(char));
01113 memset(&motion->ref_idx[LIST_0][j++][currMB->block_x], curref, 4 * sizeof(char));
01114 curref = b8x8info->best[mode][2].pdir == 0 ? b8x8info->best[mode][2].ref[LIST_0] : -1;
01115 memset(&motion->ref_idx[LIST_0][j++][currMB->block_x], curref, 4 * sizeof(char));
01116 memset(&motion->ref_idx[LIST_0][j ][currMB->block_x], curref, 4 * sizeof(char));
01117 }
01118 else if (mode == 3)
01119 {
01120 j = currMB->block_y;
01121 i = currMB->block_x;
01122 curref = (b8x8info->best[mode][0].pdir == 0) ? b8x8info->best[mode][0].ref[LIST_0] : -1;
01123 motion->ref_idx[LIST_0][j ][i++] = curref;
01124 motion->ref_idx[LIST_0][j ][i++] = curref;
01125 curref = (b8x8info->best[mode][1].pdir == 0) ? b8x8info->best[mode][1].ref[LIST_0] : -1;
01126 motion->ref_idx[LIST_0][j ][i++] = curref;
01127 motion->ref_idx[LIST_0][j++][i ] = curref;
01128 memcpy(&motion->ref_idx[LIST_0][j++][currMB->block_x], &motion->ref_idx[LIST_0][currMB->block_y][currMB->block_x], 4 * sizeof(char));
01129 memcpy(&motion->ref_idx[LIST_0][j++][currMB->block_x], &motion->ref_idx[LIST_0][currMB->block_y][currMB->block_x], 4 * sizeof(char));
01130 memcpy(&motion->ref_idx[LIST_0][j ][currMB->block_x], &motion->ref_idx[LIST_0][currMB->block_y][currMB->block_x], 4 * sizeof(char));
01131 }
01132 else
01133 {
01134 for (j=0;j<4;j++)
01135 {
01136 block_y = currMB->block_y + j;
01137 for (i=0;i<4;i++)
01138 {
01139 k = 2*(j >> 1) + (i >> 1);
01140 motion->ref_idx[LIST_0][block_y][currMB->block_x + i] = (IS_FW ? b8x8info->best[mode][k].ref[LIST_0] : -1);
01141 }
01142 }
01143 }
01144 }
01145 }
01146
01147 if (currSlice->slice_type == B_SLICE)
01148 {
01149 for (clist = LIST_0; clist <= LIST_1; clist++)
01150 {
01151 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
01152 for (i = currMB->block_x; i < currMB->block_x + 4;i++)
01153 {
01154 cur_ref = (int) motion->ref_idx[clist][j][i];
01155 motion->ref_pic_id [clist][j][i] =
01156 (cur_ref>=0 ? p_Img->enc_picture->ref_pic_num[clist + currMB->list_offset][cur_ref] : -1);
01157 }
01158 }
01159 }
01160 else
01161 {
01162 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
01163 for (i = currMB->block_x; i < currMB->block_x + 4;i++)
01164 {
01165 cur_ref = (int) motion->ref_idx[LIST_0][j][i];
01166 motion->ref_pic_id [LIST_0][j][i] =
01167 (cur_ref>=0 ? p_Img->enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][cur_ref] : -1);
01168 }
01169 }
01170
01171 #undef IS_FW
01172 #undef IS_BW
01173 }
01174
01175
01176
01177
01178
01179
01180
01181 void SetCoeffAndReconstruction8x8 (Macroblock* currMB)
01182 {
01183 ImageParameters *p_Img = currMB->p_Img;
01184 InputParameters *p_Inp = currMB->p_Inp;
01185 Slice *currSlice = currMB->p_slice;
01186 RDOPTStructure *p_RDO = currSlice->p_RDO;
01187
01188 PicMotionParams *motion = &p_Img->enc_picture->motion;
01189 int block, k, j, i, uv;
01190 int cur_ref;
01191 int64 *ref_pic_num;
01192
01193
01194
01195 if (currMB->luma_transform_size_8x8_flag && (currMB->valid_8x8))
01196 {
01197
01198 memcpy(currMB->b8x8, p_RDO->tr8x8->part, 4 * sizeof(Info8x8));
01199
01200 if (currSlice->slice_type == B_SLICE)
01201 {
01202 for (j = 0;j<4;j++)
01203 {
01204 for (i = 0;i<4;i++)
01205 {
01206 k = 2*(j >> 1)+(i >> 1);
01207 motion->ref_idx[LIST_0][currMB->block_y+j][currMB->block_x+i] = ((currMB->b8x8[k].pdir & 0x01) == 0) ? p_RDO->tr8x8->part[k].ref[LIST_0] : - 1;
01208 motion->ref_idx[LIST_1][currMB->block_y+j][currMB->block_x+i] = (currMB->b8x8[k].pdir > 0) ? p_RDO->tr8x8->part[k].ref[LIST_1] : - 1;
01209 }
01210 }
01211 }
01212 else
01213 {
01214 for (j = 0;j<4;j++)
01215 {
01216 for (i = 0;i<4;i++)
01217 {
01218 k = 2*(j >> 1)+(i >> 1);
01219 motion->ref_idx[LIST_0][currMB->block_y+j][currMB->block_x+i] = p_RDO->tr8x8->part[k].ref[LIST_0];
01220 }
01221 }
01222 }
01223
01224
01225 ref_pic_num = p_Img->enc_picture->ref_pic_num[LIST_0 + currMB->list_offset];
01226 for (j = currMB->block_y;j<currMB->block_y + BLOCK_MULTIPLE;j++)
01227 {
01228 for (i = currMB->block_x;i<currMB->block_x + BLOCK_MULTIPLE;i++)
01229 {
01230 cur_ref = (int) motion->ref_idx[LIST_0][j][i];
01231 motion->ref_pic_id [LIST_0][j][i] =(cur_ref >= 0 ? ref_pic_num[cur_ref] : -1);
01232 }
01233 }
01234
01235 if (currSlice->slice_type == B_SLICE)
01236 {
01237 ref_pic_num = p_Img->enc_picture->ref_pic_num[LIST_1 + currMB->list_offset];
01238 for (j = currMB->block_y; j < currMB->block_y + BLOCK_MULTIPLE; j++)
01239 {
01240 for (i = currMB->block_x;i<currMB->block_x + BLOCK_MULTIPLE;i++)
01241 {
01242 cur_ref = (int) motion->ref_idx[LIST_1][j][i];
01243
01244 motion->ref_pic_id [LIST_1][j][i] = (cur_ref >= 0 ? ref_pic_num[cur_ref] : -1);
01245 }
01246
01247 }
01248 }
01249
01250
01251
01252 StoreMV8x8(currSlice, 1);
01253
01254 RestoreMV8x8(currSlice, 0);
01255
01256
01257
01258
01259 for (block = 0; block<4; block++)
01260 {
01261 memcpy (currSlice->cofAC[block][0][0],p_RDO->cofAC8x8ts[block][0][0][0], 4 * 2 * 65 * sizeof(int));
01262 }
01263
01264 if (p_Img->P444_joined)
01265 {
01266 for (uv=0; uv<2; uv++)
01267 {
01268 for (block = 0; block<4; block++)
01269 {
01270 memcpy (currSlice->cofAC[4+block+uv*4][0][0],p_RDO->cofAC8x8ts[block][uv + 1][0][0], 4 * 2 * 65 * sizeof(int));
01271 }
01272 }
01273 }
01274
01275
01276 if (p_RDO->tr8x8->cnt_nonz_8x8 <= _LUMA_8x8_COEFF_COST_ &&
01277 ((currMB->qp_scaled[0])!=0 || p_Img->lossless_qpprime_flag==0) &&
01278 (currSlice->slice_type != SP_SLICE))
01279 {
01280 currMB->cbp = 0;
01281 currMB->cbp_blk = 0;
01282
01283 copy_image_data_16x16(&p_Img->enc_picture->imgY[currMB->pix_y], p_RDO->tr8x8->mpr8x8, currMB->pix_x, 0);
01284
01285 if (p_Inp->rdopt == 3)
01286 {
01287 errdo_get_best_block(currMB, p_Img->enc_picture->p_dec_img[0], p_Img->p_decs->dec_mb_pred_best8x8[1], 0, MB_BLOCK_SIZE);
01288 }
01289
01290 if(currSlice->slice_type == SP_SLICE &&(!p_Img->si_frame_indicator && !p_Img->sp2_frame_indicator ))
01291 {
01292 for (j = 0; j < MB_BLOCK_SIZE; j++)
01293 {
01294 memcpy(&p_Img->lrec[currMB->pix_y+j][currMB->pix_x],p_RDO->tr8x8->lrec[j], MB_BLOCK_SIZE * sizeof(int));
01295 }
01296 }
01297
01298 memset( currSlice->cofAC[0][0][0], 0, 2080 * sizeof(int));
01299
01300 if(p_Img->P444_joined)
01301 {
01302 currSlice->cmp_cbp[1] = currSlice->cmp_cbp[2] = 0;
01303 copy_image_data_16x16(&p_Img->enc_picture->imgUV[0][currMB->pix_y], p_RDO->tr8x8->mpr8x8CbCr[0], currMB->pix_x, 0);
01304 copy_image_data_16x16(&p_Img->enc_picture->imgUV[1][currMB->pix_y], p_RDO->tr8x8->mpr8x8CbCr[1], currMB->pix_x, 0);
01305
01306 for (uv=0; uv<2; uv++)
01307 {
01308 for (block = 0; block<4; block++)
01309 {
01310 memset( currSlice->cofAC[4+block+uv*4][0][0], 0, 4 * 2 * 65 * sizeof(int));
01311 }
01312 }
01313 }
01314 }
01315 else
01316 {
01317 currMB->cbp = p_RDO->tr8x8->cbp8x8;
01318 currMB->cbp_blk = p_RDO->tr8x8->cbp_blk8x8;
01319
01320 copy_image_data_16x16(&p_Img->enc_picture->imgY[currMB->pix_y], p_RDO->tr8x8->rec_mbY8x8, currMB->pix_x, 0);
01321
01322 if (p_Inp->rdopt == 3)
01323 {
01324 errdo_get_best_block(currMB, p_Img->enc_picture->p_dec_img[0], p_Img->p_decs->dec_mbY_best8x8[1], 0, MB_BLOCK_SIZE);
01325 }
01326
01327 if(currSlice->slice_type == SP_SLICE &&(!p_Img->si_frame_indicator && !p_Img->sp2_frame_indicator))
01328 {
01329 for (j = 0; j < MB_BLOCK_SIZE; j++)
01330 {
01331 memcpy (&p_Img->lrec[currMB->pix_y+j][currMB->pix_x],p_RDO->tr8x8->lrec[j], MB_BLOCK_SIZE * sizeof(int));
01332 }
01333 }
01334
01335 if (p_Img->P444_joined)
01336 {
01337 currSlice->cmp_cbp[1] = currSlice->cmp_cbp[2] = p_RDO->tr8x8->cbp8x8;
01338 copy_image_data_16x16(&p_Img->enc_picture->imgUV[0][currMB->pix_y], p_RDO->tr8x8->rec_mb8x8_cr[0], currMB->pix_x, 0);
01339 copy_image_data_16x16(&p_Img->enc_picture->imgUV[1][currMB->pix_y], p_RDO->tr8x8->rec_mb8x8_cr[1], currMB->pix_x, 0);
01340 }
01341 }
01342 }
01343 else
01344 {
01345 if (currSlice->slice_type == B_SLICE && currMB->valid_8x8)
01346 {
01347 StoreMV8x8(currSlice, 1);
01348 }
01349
01350
01351
01352
01353 for (block = 0; block < 4; block ++)
01354 {
01355 memcpy (currSlice->cofAC[block][0][0],p_RDO->coefAC8x8[block][0][0][0], 4 * 2 * 65 * sizeof(int));
01356 }
01357
01358 if (currSlice->P444_joined)
01359 {
01360 for (block = 0; block<4; block++)
01361 {
01362 memcpy (currSlice->cofAC[block+4][0][0],p_RDO->coefAC8x8[block][1][0][0], 4 * 2 * 65 * sizeof(int));
01363 memcpy (currSlice->cofAC[block+8][0][0],p_RDO->coefAC8x8[block][2][0][0], 4 * 2 * 65 * sizeof(int));
01364 }
01365 }
01366
01367 if (((p_Inp->disthres && p_RDO->tr4x4->cnt_nonz_8x8 <= 0) || (p_RDO->tr4x4->cnt_nonz_8x8 <= 5)) && currSlice->slice_type != SP_SLICE &&
01368 ((currMB->qp_scaled[0])!=0 || p_Img->lossless_qpprime_flag==0))
01369 {
01370 currMB->cbp = 0;
01371 currMB->cbp_blk = 0;
01372
01373 copy_image_data_16x16(&p_Img->enc_picture->imgY[currMB->pix_y], p_RDO->tr4x4->mpr8x8, currMB->pix_x, 0);
01374
01375 if (p_Inp->rdopt == 3)
01376 {
01377 errdo_get_best_block(currMB, p_Img->enc_picture->p_dec_img[0], p_Img->p_decs->dec_mb_pred_best8x8[0], 0, MB_BLOCK_SIZE);
01378 }
01379
01380 if(currSlice->slice_type == SP_SLICE &&(!p_Img->si_frame_indicator && !p_Img->sp2_frame_indicator))
01381 {
01382 for (j = 0; j < MB_BLOCK_SIZE; j++)
01383 {
01384 memcpy (&p_Img->lrec[currMB->pix_y+j][currMB->pix_x],p_RDO->tr4x4->lrec[j], MB_BLOCK_SIZE * sizeof(int));
01385 }
01386 }
01387
01388 memset( currSlice->cofAC[0][0][0], 0, 2080 * sizeof(int));
01389
01390 if (currSlice->P444_joined)
01391 {
01392 currSlice->cmp_cbp[1] = currSlice->cmp_cbp[2] = 0;
01393
01394 copy_image_data_16x16(&p_Img->enc_picture->imgUV[0][currMB->pix_y], p_RDO->tr4x4->mpr8x8CbCr[0], currMB->pix_x, 0);
01395 copy_image_data_16x16(&p_Img->enc_picture->imgUV[1][currMB->pix_y], p_RDO->tr4x4->mpr8x8CbCr[1], currMB->pix_x, 0);
01396
01397 for (uv=0; uv<2; uv++)
01398 {
01399 for (block = 0; block<4; block++)
01400 {
01401 memset( currSlice->cofAC[4+block+uv*4][0][0], 0, 4 * 2 * 65 * sizeof(int));
01402 }
01403 }
01404 }
01405 }
01406 else
01407 {
01408 currMB->cbp = p_RDO->tr4x4->cbp8x8;
01409 currMB->cbp_blk = p_RDO->tr4x4->cbp_blk8x8;
01410
01411 copy_image_data_16x16(&p_Img->enc_picture->imgY[currMB->pix_y], p_RDO->tr4x4->rec_mbY8x8, currMB->pix_x, 0);
01412
01413 if (p_Inp->rdopt == 3)
01414 {
01415 errdo_get_best_block(currMB, p_Img->enc_picture->p_dec_img[0], p_Img->p_decs->dec_mbY_best8x8[0], 0, MB_BLOCK_SIZE);
01416 }
01417
01418 if(currSlice->slice_type == SP_SLICE &&(!p_Img->si_frame_indicator && !p_Img->sp2_frame_indicator))
01419 {
01420 for (j = 0; j < MB_BLOCK_SIZE; j++)
01421 {
01422 memcpy (&p_Img->lrec[currMB->pix_y+j][currMB->pix_x],p_RDO->tr4x4->lrec[j], MB_BLOCK_SIZE * sizeof(int));
01423 }
01424 }
01425 if (currSlice->P444_joined)
01426 {
01427 currSlice->cmp_cbp[1] = currSlice->cmp_cbp[2] = p_RDO->tr4x4->cbp8x8;
01428 copy_image_data_16x16(&p_Img->enc_picture->imgUV[0][currMB->pix_y], p_RDO->tr4x4->rec_mb8x8_cr[0], currMB->pix_x, 0);
01429 copy_image_data_16x16(&p_Img->enc_picture->imgUV[1][currMB->pix_y], p_RDO->tr4x4->rec_mb8x8_cr[1], currMB->pix_x, 0);
01430 }
01431 }
01432 }
01433 }
01434
01435
01436
01437
01438
01439
01440
01441 void restore_nz_coeff(Macroblock *currMB)
01442 {
01443 #ifdef BEST_NZ_COEFF
01444 ImageParameters *p_Img = currMB->p_Img;
01445 int i, j;
01446 int **nz_coeff = p_Img->nz_coeff[currMB->mbAddrX];
01447 for (j=0;j<4;j++)
01448 for (i=0; i<(4+p_Img->num_blk8x8_uv); i++)
01449 nz_coeff[j][i] = p_Img->gaaiMBAFF_NZCoeff[j][i];
01450 #endif
01451 }
01452
01453
01454
01455
01456
01457
01458
01459 int RDCost_for_macroblocks (Macroblock *currMB,
01460 double lambda,
01461 short mode)
01462 {
01463 Slice *currSlice = currMB->p_slice;
01464 RDOPTStructure *p_RDO = currSlice->p_RDO;
01465 ImageParameters *p_Img = currMB->p_Img;
01466 InputParameters *p_Inp = currMB->p_Inp;
01467 PicMotionParams *motion = &p_Img->enc_picture->motion;
01468
01469 seq_parameter_set_rbsp_t *active_sps = p_Img->active_sps;
01470
01471 int i, j, k;
01472 int rate = 0, coeff_rate = 0;
01473 int64 distortion = 0;
01474 double rdcost;
01475 Macroblock *prevMB = currMB->PrevMB;
01476 int tmp_cc;
01477
01478 int use_of_cc = (currSlice->slice_type != I_SLICE && currSlice->symbol_mode == CAVLC);
01479 int cc_rate, dummy;
01480 double dummy_d;
01481 imgpel **mb_pred = currSlice->mb_pred[0];
01482 imgpel ***curr_mpr_16x16 = currSlice->mpr_16x16[0];
01483
01484
01485 if ((currSlice->MbaffFrameFlag) && (!currMB->mb_field) && (currSlice->slice_type == P_SLICE) && (mode==0) )
01486 {
01487 if (out_of_bounds_mvs(p_Img, currSlice->all_mv[LIST_0][0][0][0][0]))
01488 return 0;
01489 }
01490
01491
01492
01493
01494 SetModesAndRefframeForBlocks (currMB, mode);
01495
01496
01497
01498 currSlice->SetMotionVectorsMB (currMB, motion);
01499
01500
01501
01502
01503 if (mode < P8x8)
01504 {
01505 if (currSlice->P444_joined)
01506 luma_residual_coding_p444 (currMB);
01507 else
01508 luma_residual_coding (currMB);
01509 }
01510 else if (mode == P8x8)
01511 {
01512 SetCoeffAndReconstruction8x8 (currMB);
01513 }
01514 else if (mode==I4MB)
01515 {
01516 currMB->cbp = Mode_Decision_for_Intra4x4Macroblock (currMB, lambda, &dummy_d);
01517 }
01518 else if (mode==I16MB)
01519 {
01520 if (active_sps->chroma_format_idc == YUV444)
01521 Intra16x16_Mode_Decision444 (currMB);
01522 else if(p_Inp->I16rdo)
01523 Intra16x16_Mode_Decision_RDopt (currMB, lambda);
01524 else
01525 Intra16x16_Mode_Decision_SAD (currMB);
01526 }
01527 else if(mode==I8MB)
01528 {
01529 currMB->cbp = Mode_Decision_for_Intra8x8Macroblock(currMB, lambda, &dummy_d);
01530 }
01531 else if(mode==IPCM)
01532 {
01533
01534 copy_image_data_16x16(&p_Img->enc_picture->imgY[currMB->pix_y], &p_Img->pCurImg[currMB->opix_y], currMB->pix_x, currMB->pix_x);
01535
01536
01537 if ((p_Img->yuv_format != YUV400) && !IS_INDEPENDENT(p_Inp))
01538 {
01539 copy_image_data(&p_Img->enc_picture->imgUV[0][currMB->pix_c_y], &p_Img->pImgOrg[1][currMB->opix_c_y], currMB->pix_c_x, currMB->pix_c_x, p_Img->mb_cr_size_x, p_Img->mb_cr_size_y);
01540 copy_image_data(&p_Img->enc_picture->imgUV[1][currMB->pix_c_y], &p_Img->pImgOrg[2][currMB->opix_c_y], currMB->pix_c_x, currMB->pix_c_x, p_Img->mb_cr_size_x, p_Img->mb_cr_size_y);
01541 }
01542
01543 for (j=0;j<4;j++)
01544 for (i=0; i<(4+p_Img->num_blk8x8_uv); i++)
01545 p_Img->nz_coeff[currMB->mbAddrX][j][i] = 16;
01546 }
01547
01548 if (p_Inp->rdopt == 3)
01549 {
01550
01551 compute_residue_block (currMB, &p_Img->enc_picture->p_curr_img[currMB->pix_y], p_Img->p_decs->res_img[0], mode == I16MB ? currSlice->mpr_16x16[0][ (short) currMB->i16mode] : currSlice->mb_pred[0], 0, 16);
01552 }
01553
01554
01555 if (p_Inp->RCEnable)
01556 {
01557 if (mode == I16MB)
01558 memcpy(p_RDO->pred[0], curr_mpr_16x16[ (short) currMB->i16mode][0], MB_PIXELS * sizeof(imgpel));
01559 else
01560 memcpy(p_RDO->pred[0], mb_pred[0], MB_PIXELS * sizeof(imgpel));
01561 }
01562
01563 currMB->i16offset = 0;
01564 dummy = 0;
01565
01566 if (((p_Img->yuv_format != YUV400) && (active_sps->chroma_format_idc != YUV444)) && (mode != IPCM))
01567 chroma_residual_coding (currMB);
01568
01569 if (mode==I16MB)
01570 currMB->i16offset = I16Offset (currMB->cbp, currMB->i16mode);
01571
01572
01573
01574
01575
01576 if (p_Inp->rdopt == 3)
01577 {
01578 double ddistortion = 0;
01579 if (mode != P8x8)
01580 {
01581 for (k = 0; k<p_Inp->NoOfDecoders ;k++)
01582 {
01583 decode_one_mb (currMB, p_Img->enc_picture, k);
01584 ddistortion += (double) compute_SSE16x16(&p_Img->pImgOrg[0][currMB->opix_y], &p_Img->enc_picture->p_dec_img[0][k][currMB->pix_y], currMB->pix_x, currMB->pix_x);
01585 if (ddistortion > currMB->min_rdcost * p_Inp->NoOfDecoders)
01586 return 0;
01587 }
01588 }
01589 else
01590 {
01591 for (k = 0; k<p_Inp->NoOfDecoders ;k++)
01592 {
01593 ddistortion += (double) compute_SSE16x16(&p_Img->pImgOrg[0][currMB->opix_y], &p_Img->enc_picture->p_dec_img[0][k][currMB->pix_y], currMB->pix_x, currMB->pix_x);
01594 if (ddistortion > currMB->min_rdcost * p_Inp->NoOfDecoders)
01595 return 0;
01596 }
01597 }
01598 distortion = (int64) ((ddistortion) / p_Inp->NoOfDecoders + 0.5);
01599
01600 if ((p_Img->yuv_format != YUV400) && (active_sps->chroma_format_idc != YUV444))
01601 {
01602
01603 distortion += compute_SSE_cr(&p_Img->pImgOrg[1][currMB->opix_c_y], &p_Img->enc_picture->imgUV[0][currMB->pix_c_y], currMB->pix_c_x, currMB->pix_c_x, p_Img->mb_cr_size_y, p_Img->mb_cr_size_x);
01604 distortion += compute_SSE_cr(&p_Img->pImgOrg[2][currMB->opix_c_y], &p_Img->enc_picture->imgUV[1][currMB->pix_c_y], currMB->pix_c_x, currMB->pix_c_x, p_Img->mb_cr_size_y, p_Img->mb_cr_size_x);
01605 }
01606 }
01607 else
01608 {
01609 distortion = currSlice->getDistortion(currMB);
01610 }
01611
01612 if ((double)distortion > currMB->min_rdcost)
01613 return 0;
01614
01615
01616 if (currMB->qp_scaled[0] == 0 && p_Img->lossless_qpprime_flag == 1 && distortion != 0)
01617 return 0;
01618
01619
01620
01621 currSlice->store_coding_state (currMB, currSlice->p_RDO->cs_cm);
01622
01623
01624
01625
01626
01627 if (use_of_cc)
01628 {
01629 if (currMB->mb_type!=0 || (currSlice->slice_type == B_SLICE && currMB->cbp!=0))
01630 {
01631
01632 tmp_cc = p_Img->cod_counter;
01633
01634 rate = currSlice->write_MB_layer (currMB, 1, &coeff_rate);
01635
01636
01637 ue_linfo (tmp_cc, dummy, &cc_rate, &dummy);
01638 rate -= cc_rate;
01639 p_Img->cod_counter = tmp_cc;
01640 }
01641 else
01642 {
01643
01644 ue_linfo (p_Img->cod_counter + 1, dummy, &rate, &dummy);
01645 ue_linfo (p_Img->cod_counter , dummy, &cc_rate, &dummy);
01646 rate -= cc_rate;
01647 }
01648 }
01649 else
01650 {
01651 rate = currSlice->write_MB_layer (currMB, 1, &coeff_rate);
01652 }
01653
01654
01655
01656 currSlice->reset_coding_state (currMB, currSlice->p_RDO->cs_cm);
01657
01658 if (p_Inp->ForceTrueRateRDO == 1)
01659 rdcost = (double)distortion + lambda * rate;
01660 else if (p_Inp->ForceTrueRateRDO == 2)
01661 rdcost = (double)distortion + lambda * (rate + IS_INTRA(currMB));
01662 else
01663 rdcost = (double)distortion + lambda * dmax(0.5,(double)rate);
01664
01665
01666 if (rdcost >= currMB->min_rdcost ||
01667 ((currMB->qp_scaled[0]) == 0 && p_Img->lossless_qpprime_flag == 1 && distortion != 0))
01668 {
01669 #if FASTMODE
01670
01671
01672
01673 if((currSlice->slice_type != P_SLICE || mode != 0 || rdcost != currMB->min_rdcost) || IS_FREXT_PROFILE(p_Inp->ProfileIDC))
01674 #endif
01675 return 0;
01676 }
01677
01678
01679 if ((currSlice->MbaffFrameFlag) && (mode ? 0: ((currSlice->slice_type == B_SLICE) ? !currMB->cbp:1)))
01680 {
01681 if (currMB->mbAddrX & 0x01)
01682 {
01683 if (prevMB->mb_type ? 0:((currSlice->slice_type == B_SLICE) ? !prevMB->cbp:1))
01684 {
01685 if (!(field_flag_inference(currMB) == currMB->mb_field))
01686 return 0;
01687 }
01688 }
01689 }
01690
01691
01692
01693 currMB->min_rdcost = rdcost;
01694 currMB->min_dcost = (double) distortion;
01695 currMB->min_rate = lambda * (double)coeff_rate;
01696
01697 #ifdef BEST_NZ_COEFF
01698 for (j=0;j<4;j++)
01699 memcpy(&p_Img->gaaiMBAFF_NZCoeff[j][0], &p_Img->nz_coeff[currMB->mbAddrX][j][0], (4 + p_Img->num_blk8x8_uv) * sizeof(int));
01700 #endif
01701
01702 return 1;
01703 }
01704
01705
01706
01707
01708
01709
01710
01711 void init_md_best(BestMode *best)
01712 {
01713 best->cbp = 0;
01714 best->cost = (1<<20);
01715 best->rdcost = 1e20;
01716 best->dcost = 1e20;
01717 best->rate = 1e20;
01718 best->c_imode = 0;
01719 best->i16offset = 0;
01720 best->mode = 10;
01721 }
01722
01723
01724
01725
01726
01727
01728
01729 void store_macroblock_parameters (Macroblock *currMB, int mode)
01730 {
01731 Slice *currSlice = currMB->p_slice;
01732 RDOPTStructure *p_RDO = currSlice->p_RDO;
01733 ImageParameters *p_Img = currMB->p_Img;
01734 InputParameters *p_Inp = currMB->p_Inp;
01735 PicMotionParams *motion = &p_Img->enc_picture->motion;
01736
01737 int j, ****i4p, ***i3p;
01738
01739
01740 currMB->best_mode = (short) mode;
01741 currMB->best_c_imode = currMB->c_ipred_mode;
01742 currMB->best_i16offset = currMB->i16offset;
01743 currMB->best_cbp = currMB->cbp;
01744
01745 memcpy(currSlice->p_RDO->best8x8, currMB->b8x8, BLOCK_MULTIPLE * sizeof(Info8x8));
01746
01747 memcpy(currSlice->b4_intra_pred_modes, currMB->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
01748 memcpy(currSlice->b8_intra_pred_modes8x8,currMB->intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
01749
01750 for (j = 0 ; j < BLOCK_MULTIPLE; j++)
01751 {
01752 memcpy(&currSlice->b4_ipredmode[j * BLOCK_MULTIPLE],&p_Img->ipredmode [currMB->block_y + j][currMB->block_x],BLOCK_MULTIPLE * sizeof(char));
01753 memcpy(&currSlice->b8_ipredmode8x8[j][0], &p_Img->ipredmode8x8[currMB->block_y + j][currMB->block_x],BLOCK_MULTIPLE * sizeof(char));
01754 }
01755
01756 copy_image_data_16x16(p_RDO->rec_mb[0], &p_Img->enc_picture->imgY[currMB->pix_y], 0, currMB->pix_x);
01757
01758 if((currSlice->slice_type == SP_SLICE) && (p_Img->si_frame_indicator==0 && p_Img->sp2_frame_indicator==0))
01759 {
01760 for (j = 0; j < MB_BLOCK_SIZE; j++)
01761 {
01762 memcpy(p_RDO->lrec_rec[j], &p_Img->lrec[currMB->pix_y+j][currMB->pix_x], MB_BLOCK_SIZE * sizeof(int));
01763 }
01764 }
01765
01766
01767 if (p_Img->AdaptiveRounding && (currSlice->slice_type == B_SLICE) && mode <= 1)
01768 {
01769 if (currMB->luma_transform_size_8x8_flag)
01770 store_adaptive_rounding_16x16( p_Img, p_Img->ARCofAdj8x8, mode);
01771 else
01772 store_adaptive_rounding_16x16( p_Img, p_Img->ARCofAdj4x4, mode);
01773 }
01774
01775 if (p_Img->yuv_format != YUV400)
01776 {
01777 int k;
01778 for (k = 0; k < 2; k++)
01779 {
01780 copy_image_data(p_RDO->rec_mb[k + 1], &p_Img->enc_picture->imgUV[k][currMB->pix_c_y], 0, currMB->pix_c_x, p_Img->mb_cr_size_x, p_Img->mb_cr_size_y);
01781 }
01782
01783 if((currSlice->slice_type == SP_SLICE) && (p_Img->si_frame_indicator==0 && p_Img->sp2_frame_indicator==0))
01784 {
01785
01786 for (k = 0; k < 2; k++)
01787 {
01788 for (j = 0; j<p_Img->mb_cr_size_y; j++)
01789 {
01790 memcpy(p_RDO->lrec_rec_uv[k][j],&p_Img->lrec_uv[k][currMB->pix_c_y + j][currMB->pix_c_x], p_Img->mb_cr_size_x * sizeof(int));
01791 }
01792 }
01793 }
01794 }
01795
01796
01797 if (p_Inp->rdopt == 3)
01798 {
01799 errdo_store_best_block(p_Inp, p_Img->p_decs->dec_mbY_best, p_Img->enc_picture->p_dec_img[0], 0, 0, currMB->pix_x, currMB->pix_y, MB_BLOCK_SIZE);
01800 }
01801
01802
01803 if (mode || currSlice->slice_type == B_SLICE)
01804 {
01805 i4p = p_RDO->cofAC;
01806 p_RDO->cofAC = currSlice->cofAC;
01807 currSlice->cofAC = i4p;
01808 i3p = p_RDO->cofDC;
01809 p_RDO->cofDC = currSlice->cofDC;
01810 currSlice->cofDC = i3p;
01811 p_RDO->cbp = currMB->cbp;
01812 currSlice->curr_cbp[0] = currSlice->cmp_cbp[1];
01813 currSlice->curr_cbp[1] = currSlice->cmp_cbp[2];
01814
01815 currSlice->cur_cbp_blk[0] = currMB->cbp_blk;
01816 }
01817 else
01818 {
01819 currSlice->cur_cbp_blk[0] = p_RDO->cbp = 0;
01820 currSlice->cmp_cbp[1] = currSlice->cmp_cbp[2] = 0;
01821 }
01822
01823
01824 currMB->temp_transform_size_8x8_flag = currMB->luma_transform_size_8x8_flag;
01825
01826 for (j = 0; j<4; j++)
01827 memcpy(p_RDO->l0_refframe[j],&motion->ref_idx[LIST_0][currMB->block_y+j][currMB->block_x], BLOCK_MULTIPLE * sizeof(char));
01828
01829 if (currSlice->slice_type == B_SLICE)
01830 {
01831 for (j = 0; j<4; j++)
01832 memcpy(p_RDO->l1_refframe[j],&motion->ref_idx[LIST_1][currMB->block_y+j][currMB->block_x], BLOCK_MULTIPLE * sizeof(char));
01833 }
01834 }
01835
01836
01837
01838
01839
01840
01841
01842 static void set_stored_macroblock_parameters_mpass (Macroblock *currMB)
01843 {
01844 Slice *currSlice = currMB->p_slice;
01845 RDOPTStructure *p_RDO = currSlice->p_RDO;
01846 ImageParameters *p_Img = currMB->p_Img;
01847 InputParameters *p_Inp = currMB->p_Inp;
01848
01849 imgpel **imgY = p_Img->enc_picture->imgY;
01850 imgpel ***imgUV = p_Img->enc_picture->imgUV;
01851
01852 int mode = currMB->best_mode;
01853 int i, j, k, ****i4p, ***i3p;
01854 int block_x, block_y;
01855 char **ipredmodes = p_Img->ipredmode;
01856 short *cur_mv;
01857 PicMotionParams *motion = &p_Img->enc_picture->motion;
01858
01859
01860
01861
01862 copy_image_data_16x16(&imgY[currMB->pix_y], p_RDO->rec_mb[0], currMB->pix_x, 0);
01863
01864
01865 copy_image_data_16x16(currSlice->rddata->rec_mb[0], p_RDO->rec_mb[0], 0, 0);
01866
01867 if((currSlice->slice_type == SP_SLICE) &&(p_Img->si_frame_indicator==0 && p_Img->sp2_frame_indicator==0 ))
01868 {
01869 for (j = 0; j < MB_BLOCK_SIZE; j++)
01870 memcpy(&p_Img->lrec[currMB->pix_y+j][currMB->pix_x], p_RDO->lrec_rec[j], MB_BLOCK_SIZE * sizeof(int));
01871 }
01872
01873 if (p_Img->AdaptiveRounding)
01874 {
01875 update_offset_params(currMB, mode, currMB->temp_transform_size_8x8_flag);
01876 }
01877
01878 if (p_Img->yuv_format != YUV400)
01879 {
01880 for (k = 0; k < 2; k++)
01881 {
01882 copy_image_data(&imgUV[k][currMB->pix_c_y], p_RDO->rec_mb[k + 1], currMB->pix_c_x, 0, p_Img->mb_cr_size_x, p_Img->mb_cr_size_y);
01883 }
01884
01885
01886 copy_image_data(currSlice->rddata->rec_mb[1], p_RDO->rec_mb[1], 0, 0, p_Img->mb_cr_size_x, p_Img->mb_cr_size_y);
01887 copy_image_data(currSlice->rddata->rec_mb[2], p_RDO->rec_mb[2], 0, 0, p_Img->mb_cr_size_x, p_Img->mb_cr_size_y);
01888
01889 if((currSlice->slice_type == SP_SLICE) &&(!p_Img->si_frame_indicator && !p_Img->sp2_frame_indicator))
01890 {
01891 for (k = 0; k < 2; k++)
01892 {
01893 for (j = 0; j<p_Img->mb_cr_size_y; j++)
01894 {
01895 memcpy(&p_Img->lrec_uv[k][currMB->pix_c_y + j][currMB->pix_c_x], p_RDO->lrec_rec_uv[k][j], p_Img->mb_cr_size_x * sizeof(int));
01896 }
01897 }
01898 }
01899 }
01900
01901
01902 i4p = p_RDO->cofAC;
01903 p_RDO->cofAC = currSlice->cofAC;
01904 currSlice->cofAC = i4p;
01905
01906 i3p = p_RDO->cofDC;
01907 p_RDO->cofDC = currSlice->cofDC;
01908 currSlice->cofDC = i3p;
01909 currMB->cbp = p_RDO->cbp;
01910 currMB->cbp_blk = currSlice->cur_cbp_blk[0];
01911 currMB->cbp |= currSlice->curr_cbp[0];
01912 currMB->cbp |= currSlice->curr_cbp[1];
01913 currSlice->cmp_cbp[1] = currMB->cbp;
01914 currSlice->cmp_cbp[2] = currMB->cbp;
01915
01916
01917 currMB->mb_type = (short) mode;
01918
01919 memcpy(currMB->b8x8, currSlice->p_RDO->best8x8, BLOCK_MULTIPLE * sizeof(Info8x8));
01920
01921
01922 currSlice->rddata->mode = mode;
01923 currSlice->rddata->i16offset = currMB->i16offset;
01924 currSlice->rddata->cbp = p_RDO->cbp;
01925 currSlice->rddata->cbp_blk = currSlice->cur_cbp_blk[0];
01926 currSlice->rddata->mb_type = (short) mode;
01927
01928 currSlice->rddata->prev_qp = currMB->prev_qp;
01929 currSlice->rddata->prev_dqp = currMB->prev_dqp;
01930 currSlice->rddata->qp = currMB->qp;
01931 currSlice->rddata->prev_cbp = currMB->prev_cbp;
01932
01933 memcpy(currSlice->rddata->cofAC[0][0][0], currSlice->cofAC[0][0][0], (4+p_Img->num_blk8x8_uv) * 4 * 2 * 65 * sizeof(int));
01934 memcpy(currSlice->rddata->cofDC[0][0], currSlice->cofDC[0][0], 3 * 2 * 18 * sizeof(int));
01935
01936 memcpy(currSlice->rddata->b8x8, currSlice->p_RDO->best8x8, BLOCK_MULTIPLE * sizeof(Info8x8));
01937
01938
01939 if (mode == P8x8 && !currMB->temp_transform_size_8x8_flag && p_Inp->Transform8x8Mode && (currMB->valid_8x8 == TRUE))
01940 {
01941 RestoreMV8x8(currSlice, 1);
01942 }
01943
01944
01945 if (p_Img->P444_joined)
01946 {
01947 if (((currMB->cbp == 0) && currSlice->cmp_cbp[1] == 0 && currSlice->cmp_cbp[2] == 0) && (currMB->mb_type != I4MB && currMB->mb_type != I8MB))
01948 currMB->luma_transform_size_8x8_flag = FALSE;
01949 else
01950 currMB->luma_transform_size_8x8_flag = currMB->temp_transform_size_8x8_flag;
01951 }
01952 else
01953 {
01954
01955 if (((currMB->cbp & 15) == 0) && (currMB->mb_type != I4MB && currMB->mb_type != I8MB))
01956 currMB->luma_transform_size_8x8_flag = FALSE;
01957 else
01958 currMB->luma_transform_size_8x8_flag = currMB->temp_transform_size_8x8_flag;
01959 }
01960
01961 currSlice->rddata->luma_transform_size_8x8_flag = currMB->luma_transform_size_8x8_flag;
01962
01963 if (p_Inp->rdopt == 3)
01964 {
01965 errdo_get_best_block(currMB, p_Img->enc_picture->p_dec_img[0], p_Img->p_decs->dec_mbY_best, 0, MB_BLOCK_SIZE);
01966 }
01967
01968
01969 for (j = 0; j < 4; j++)
01970 {
01971 block_y = currMB->block_y + j;
01972 for (i = 0; i < 4; i++)
01973 {
01974 block_x = currMB->block_x + i;
01975 k = 2*(j >> 1)+(i >> 1);
01976
01977
01978 if ((currMB->b8x8[k].pdir == 1) || IS_INTRA(currMB))
01979 {
01980 motion->ref_idx [LIST_0][block_y][block_x] = -1;
01981 motion->ref_pic_id [LIST_0][block_y][block_x] = -1;
01982 motion->mv [LIST_0][block_y][block_x][0] = 0;
01983 motion->mv [LIST_0][block_y][block_x][1] = 0;
01984
01985
01986 currSlice->rddata->refar[LIST_0][j][i] = -1;
01987 }
01988 else
01989 {
01990 if (currMB->b8x8[k].bipred && (currMB->b8x8[k].pdir == 2) && is_bipred_enabled(p_Inp, currMB->mb_type))
01991 {
01992 cur_mv = currSlice->bipred_mv[currMB->b8x8[k].bipred - 1][LIST_0][0][(short) currMB->b8x8[k].mode][j][i];
01993
01994 motion->ref_idx [LIST_0][block_y][block_x] = 0;
01995 motion->ref_pic_id [LIST_0][block_y][block_x] = p_Img->enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][0];
01996 motion->mv [LIST_0][block_y][block_x][0] = cur_mv[0];
01997 motion->mv [LIST_0][block_y][block_x][1] = cur_mv[1];
01998
01999
02000 currSlice->rddata->refar[LIST_0][j][i] = 0;
02001 }
02002 else
02003 {
02004 char cur_ref = p_RDO->l0_refframe[j][i];
02005 motion->ref_idx [LIST_0][block_y][block_x] = cur_ref;
02006 motion->ref_pic_id [LIST_0][block_y][block_x] = p_Img->enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][(short)cur_ref];
02007 memcpy(motion->mv [LIST_0][block_y][block_x], currSlice->all_mv[LIST_0][(short)cur_ref][(short) currMB->b8x8[k].mode][j][i], 2 * sizeof(short));
02008
02009
02010 currSlice->rddata->refar[LIST_0][j][i] = cur_ref;
02011 }
02012 }
02013
02014
02015 if ((currMB->b8x8[k].pdir == 0) || IS_INTRA(currMB))
02016 {
02017 motion->ref_idx [LIST_1][block_y][block_x] = -1;
02018 motion->ref_pic_id [LIST_1][block_y][block_x] = -1;
02019 motion->mv [LIST_1][block_y][block_x][0] = 0;
02020 motion->mv [LIST_1][block_y][block_x][1] = 0;
02021
02022
02023 currSlice->rddata->refar[LIST_1][j][i] = -1;
02024 }
02025 }
02026 }
02027
02028 if (currSlice->slice_type == B_SLICE)
02029 {
02030 for (j=0; j<4; j++)
02031 {
02032 block_y = currMB->block_y + j;
02033 for (i=0; i<4; i++)
02034 {
02035 block_x = currMB->block_x + i;
02036 k = 2*(j >> 1)+(i >> 1);
02037
02038
02039 if (IS_INTRA(currMB)||(currMB->b8x8[k].pdir == 0))
02040 {
02041 motion->ref_idx [LIST_1][block_y][block_x] = -1;
02042 motion->ref_pic_id [LIST_1][block_y][block_x] = -1;
02043 motion->mv [LIST_1][block_y][block_x][0] = 0;
02044 motion->mv [LIST_1][block_y][block_x][1] = 0;
02045
02046
02047 currSlice->rddata->refar[LIST_1][j][i] = -1;
02048 }
02049 else
02050 {
02051 if (currMB->b8x8[k].bipred && (currMB->b8x8[k].pdir == 2) && is_bipred_enabled(p_Inp, currMB->mb_type))
02052 {
02053 cur_mv = currSlice->bipred_mv[currMB->b8x8[k].bipred - 1][LIST_1][0][(short) currMB->b8x8[k].mode][j][i];
02054
02055 motion->ref_idx [LIST_1][block_y][block_x] = 0;
02056 motion->ref_pic_id [LIST_1][block_y][block_x] = p_Img->enc_picture->ref_pic_num[LIST_1 + currMB->list_offset][0];
02057 motion->mv [LIST_1][block_y][block_x][0] = cur_mv[0];
02058 motion->mv [LIST_1][block_y][block_x][1] = cur_mv[1];
02059
02060
02061 currSlice->rddata->refar[LIST_1][j][i] = 0;
02062 }
02063 else
02064 {
02065 motion->ref_idx [LIST_1][block_y][block_x] = p_RDO->l1_refframe[j][i];
02066 motion->ref_pic_id [LIST_1][block_y][block_x] = p_Img->enc_picture->ref_pic_num[LIST_1 + currMB->list_offset][(short)p_RDO->l1_refframe[j][i]];
02067 memcpy(motion->mv [LIST_1][block_y][block_x], currSlice->all_mv[LIST_1][(short)p_RDO->l1_refframe[j][i]][(short) currMB->b8x8[k].mode][j][i], 2 * sizeof(short));
02068
02069
02070 currSlice->rddata->refar[LIST_1][j][i] = p_RDO->l1_refframe[j][i];
02071 }
02072 }
02073 }
02074 }
02075 }
02076
02077
02078 currMB->c_ipred_mode = currMB->best_c_imode;
02079 currMB->i16offset = currMB->best_i16offset;
02080 currMB->cbp = currMB->best_cbp;
02081
02082 if(currMB->mb_type == I8MB)
02083 {
02084 memcpy(currMB->intra_pred_modes8x8,currSlice->b8_intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
02085 memcpy(currMB->intra_pred_modes ,currSlice->b8_intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
02086 for(j = 0; j < BLOCK_MULTIPLE; j++)
02087 {
02088 memcpy(&p_Img->ipredmode [currMB->block_y+j][currMB->block_x], currSlice->b8_ipredmode8x8[j], BLOCK_MULTIPLE * sizeof(char));
02089 memcpy(&p_Img->ipredmode8x8[currMB->block_y+j][currMB->block_x], currSlice->b8_ipredmode8x8[j], BLOCK_MULTIPLE * sizeof(char));
02090 }
02091 }
02092 else if (mode!=I4MB && mode!=I8MB)
02093 {
02094 memset(currMB->intra_pred_modes,DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));
02095 for(j = currMB->block_y; j < currMB->block_y + BLOCK_MULTIPLE; j++)
02096 memset(&p_Img->ipredmode[j][currMB->block_x], DC_PRED, BLOCK_MULTIPLE * sizeof(char));
02097 }
02098
02099 else if (mode == I4MB)
02100 {
02101 memcpy(currMB->intra_pred_modes,currSlice->b4_intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
02102 for(j = 0; j < BLOCK_MULTIPLE; j++)
02103 memcpy(&p_Img->ipredmode[currMB->block_y + j][currMB->block_x],&currSlice->b4_ipredmode[BLOCK_MULTIPLE * j], BLOCK_MULTIPLE * sizeof(char));
02104 }
02105
02106
02107 currSlice->rddata->c_ipred_mode = currMB->c_ipred_mode;
02108 currSlice->rddata->i16offset = currMB->i16offset;
02109 currSlice->rddata->cbp = currMB->cbp;
02110 currSlice->rddata->cbp_blk = currMB->cbp_blk;
02111 memcpy(currSlice->rddata->intra_pred_modes,currMB->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
02112 memcpy(currSlice->rddata->intra_pred_modes8x8,currMB->intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
02113 for(j = currMB->block_y; j < currMB->block_y + BLOCK_MULTIPLE; j++)
02114 memcpy(&currSlice->rddata->ipredmode[j][currMB->block_x],&ipredmodes[j][currMB->block_x], BLOCK_MULTIPLE * sizeof(char));
02115
02116
02117 currSlice->SetMotionVectorsMB (currMB, motion);
02118 }
02119
02120
02121
02122
02123
02124
02125
02126 static void set_stored_macroblock_parameters (Macroblock *currMB)
02127 {
02128 Slice *currSlice = currMB->p_slice;
02129 RDOPTStructure *p_RDO = currSlice->p_RDO;
02130 ImageParameters *p_Img = currMB->p_Img;
02131 InputParameters *p_Inp = currMB->p_Inp;
02132
02133 imgpel **imgY = p_Img->enc_picture->imgY;
02134 imgpel ***imgUV = p_Img->enc_picture->imgUV;
02135
02136 int mode = currMB->best_mode;
02137 int i, j, k, ****i4p, ***i3p;
02138 int block_x, block_y;
02139 short *cur_mv;
02140 PicMotionParams *motion = &p_Img->enc_picture->motion;
02141
02142
02143
02144
02145 copy_image_data_16x16(&imgY[currMB->pix_y], p_RDO->rec_mb[0], currMB->pix_x, 0);
02146
02147 if (p_Img->AdaptiveRounding)
02148 {
02149 update_offset_params(currMB, mode, currMB->temp_transform_size_8x8_flag);
02150 }
02151
02152 if (p_Img->yuv_format != YUV400)
02153 {
02154 for (k = 0; k < 2; k++)
02155 {
02156 copy_image_data(&imgUV[k][currMB->pix_c_y], p_RDO->rec_mb[k + 1], currMB->pix_c_x, 0, p_Img->mb_cr_size_x, p_Img->mb_cr_size_y);
02157 }
02158 }
02159
02160
02161 i4p = p_RDO->cofAC;
02162 p_RDO->cofAC = currSlice->cofAC;
02163 currSlice->cofAC = i4p;
02164
02165 i3p = p_RDO->cofDC;
02166 p_RDO->cofDC = currSlice->cofDC;
02167 currSlice->cofDC = i3p;
02168 currMB->cbp = p_RDO->cbp;
02169 currMB->cbp_blk = currSlice->cur_cbp_blk[0];
02170 currMB->cbp |= currSlice->curr_cbp[0];
02171 currMB->cbp |= currSlice->curr_cbp[1];
02172 currSlice->cmp_cbp[1] = currMB->cbp;
02173 currSlice->cmp_cbp[2] = currMB->cbp;
02174
02175
02176 currMB->mb_type = (short) mode;
02177
02178 memcpy(currMB->b8x8, currSlice->p_RDO->best8x8, BLOCK_MULTIPLE * sizeof(Info8x8));
02179
02180
02181
02182 if (mode == P8x8 && !currMB->temp_transform_size_8x8_flag && p_Inp->Transform8x8Mode && (currMB->valid_8x8 == TRUE))
02183 {
02184 RestoreMV8x8(currSlice, 1);
02185 }
02186
02187
02188 if (p_Img->P444_joined)
02189 {
02190 if (((currMB->cbp == 0) && currSlice->cmp_cbp[1] == 0 && currSlice->cmp_cbp[2] == 0) && (currMB->mb_type != I4MB && currMB->mb_type != I8MB))
02191 currMB->luma_transform_size_8x8_flag = FALSE;
02192 else
02193 currMB->luma_transform_size_8x8_flag = currMB->temp_transform_size_8x8_flag;
02194 }
02195 else
02196 {
02197
02198 if (((currMB->cbp & 15) == 0) && (currMB->mb_type != I4MB && currMB->mb_type != I8MB))
02199 currMB->luma_transform_size_8x8_flag = FALSE;
02200 else
02201 currMB->luma_transform_size_8x8_flag = currMB->temp_transform_size_8x8_flag;
02202 }
02203
02204 currSlice->rddata->luma_transform_size_8x8_flag = currMB->luma_transform_size_8x8_flag;
02205
02206 if (p_Inp->rdopt == 3)
02207 {
02208 errdo_get_best_block(currMB, p_Img->enc_picture->p_dec_img[0], p_Img->p_decs->dec_mbY_best, 0, MB_BLOCK_SIZE);
02209 }
02210
02211
02212 for (j = 0; j < 4; j++)
02213 {
02214 block_y = currMB->block_y + j;
02215 for (i = 0; i < 4; i++)
02216 {
02217 block_x = currMB->block_x + i;
02218 k = 2*(j >> 1)+(i >> 1);
02219
02220
02221 if ((currMB->b8x8[k].pdir == 1) || IS_INTRA(currMB))
02222 {
02223 motion->ref_idx [LIST_0][block_y][block_x] = -1;
02224 motion->ref_pic_id [LIST_0][block_y][block_x] = -1;
02225 motion->mv [LIST_0][block_y][block_x][0] = 0;
02226 motion->mv [LIST_0][block_y][block_x][1] = 0;
02227 }
02228 else
02229 {
02230 if (currMB->b8x8[k].bipred && (currMB->b8x8[k].pdir == 2) && is_bipred_enabled(p_Inp, currMB->mb_type))
02231 {
02232 cur_mv = currSlice->bipred_mv[currMB->b8x8[k].bipred - 1][LIST_0][0][(short) currMB->b8x8[k].mode][j][i];
02233
02234 motion->ref_idx [LIST_0][block_y][block_x] = 0;
02235 motion->ref_pic_id [LIST_0][block_y][block_x] = p_Img->enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][0];
02236 motion->mv [LIST_0][block_y][block_x][0] = cur_mv[0];
02237 motion->mv [LIST_0][block_y][block_x][1] = cur_mv[1];
02238 }
02239 else
02240 {
02241 char cur_ref = p_RDO->l0_refframe[j][i];
02242 motion->ref_idx [LIST_0][block_y][block_x] = cur_ref;
02243 motion->ref_pic_id [LIST_0][block_y][block_x] = p_Img->enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][(short)cur_ref];
02244 memcpy(motion->mv [LIST_0][block_y][block_x], currSlice->all_mv[LIST_0][(short)cur_ref][(short) currMB->b8x8[k].mode][j][i], 2 * sizeof(short));
02245 }
02246 }
02247
02248
02249 if ((currMB->b8x8[k].pdir == 0) || IS_INTRA(currMB))
02250 {
02251 motion->ref_idx [LIST_1][block_y][block_x] = -1;
02252 motion->ref_pic_id [LIST_1][block_y][block_x] = -1;
02253 motion->mv [LIST_1][block_y][block_x][0] = 0;
02254 motion->mv [LIST_1][block_y][block_x][1] = 0;
02255 }
02256 }
02257 }
02258
02259 if (currSlice->slice_type == B_SLICE)
02260 {
02261 for (j=0; j<4; j++)
02262 {
02263 block_y = currMB->block_y + j;
02264 for (i=0; i<4; i++)
02265 {
02266 block_x = currMB->block_x + i;
02267 k = 2*(j >> 1)+(i >> 1);
02268
02269
02270 if (IS_INTRA(currMB)||(currMB->b8x8[k].pdir == 0))
02271 {
02272 motion->ref_idx [LIST_1][block_y][block_x] = -1;
02273 motion->ref_pic_id [LIST_1][block_y][block_x] = -1;
02274 motion->mv [LIST_1][block_y][block_x][0] = 0;
02275 motion->mv [LIST_1][block_y][block_x][1] = 0;
02276 }
02277 else
02278 {
02279 if (currMB->b8x8[k].bipred && (currMB->b8x8[k].pdir == 2) && is_bipred_enabled(p_Inp, currMB->mb_type))
02280 {
02281 cur_mv = currSlice->bipred_mv[currMB->b8x8[k].bipred - 1][LIST_1][0][(short) currMB->b8x8[k].mode][j][i];
02282
02283 motion->ref_idx [LIST_1][block_y][block_x] = 0;
02284 motion->ref_pic_id [LIST_1][block_y][block_x] = p_Img->enc_picture->ref_pic_num[LIST_1 + currMB->list_offset][0];
02285 motion->mv [LIST_1][block_y][block_x][0] = cur_mv[0];
02286 motion->mv [LIST_1][block_y][block_x][1] = cur_mv[1];
02287 }
02288 else
02289 {
02290 motion->ref_idx [LIST_1][block_y][block_x] = p_RDO->l1_refframe[j][i];
02291 motion->ref_pic_id [LIST_1][block_y][block_x] = p_Img->enc_picture->ref_pic_num[LIST_1 + currMB->list_offset][(short)p_RDO->l1_refframe[j][i]];
02292 memcpy(motion->mv [LIST_1][block_y][block_x], currSlice->all_mv[LIST_1][(short)p_RDO->l1_refframe[j][i]][(short) currMB->b8x8[k].mode][j][i], 2 * sizeof(short));
02293 }
02294 }
02295 }
02296 }
02297 }
02298
02299
02300 currMB->c_ipred_mode = currMB->best_c_imode;
02301 currMB->i16offset = currMB->best_i16offset;
02302 currMB->cbp = currMB->best_cbp;
02303
02304 if(currMB->mb_type == I8MB)
02305 {
02306 memcpy(currMB->intra_pred_modes8x8,currSlice->b8_intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
02307 memcpy(currMB->intra_pred_modes ,currSlice->b8_intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
02308 for(j = 0; j < BLOCK_MULTIPLE; j++)
02309 {
02310 memcpy(&p_Img->ipredmode [currMB->block_y+j][currMB->block_x], currSlice->b8_ipredmode8x8[j], BLOCK_MULTIPLE * sizeof(char));
02311 memcpy(&p_Img->ipredmode8x8[currMB->block_y+j][currMB->block_x], currSlice->b8_ipredmode8x8[j], BLOCK_MULTIPLE * sizeof(char));
02312 }
02313 }
02314 else if (mode!=I4MB && mode!=I8MB)
02315 {
02316 memset(currMB->intra_pred_modes,DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));
02317 for(j = currMB->block_y; j < currMB->block_y + BLOCK_MULTIPLE; j++)
02318 memset(&p_Img->ipredmode[j][currMB->block_x], DC_PRED, BLOCK_MULTIPLE * sizeof(char));
02319 }
02320
02321 else if (mode == I4MB)
02322 {
02323 memcpy(currMB->intra_pred_modes,currSlice->b4_intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
02324 for(j = 0; j < BLOCK_MULTIPLE; j++)
02325 memcpy(&p_Img->ipredmode[currMB->block_y + j][currMB->block_x],&currSlice->b4_ipredmode[BLOCK_MULTIPLE * j], BLOCK_MULTIPLE * sizeof(char));
02326 }
02327
02328
02329 currSlice->SetMotionVectorsMB (currMB, motion);
02330 }
02331
02332
02333
02334
02335
02336
02337
02338
02339 static void set_stored_macroblock_parameters_sp (Macroblock *currMB)
02340 {
02341 Slice *currSlice = currMB->p_slice;
02342 RDOPTStructure *p_RDO = currSlice->p_RDO;
02343 ImageParameters *p_Img = currMB->p_Img;
02344 InputParameters *p_Inp = currMB->p_Inp;
02345
02346 imgpel **imgY = p_Img->enc_picture->imgY;
02347 imgpel ***imgUV = p_Img->enc_picture->imgUV;
02348
02349 int mode = currMB->best_mode;
02350 int i, j, k, ****i4p, ***i3p;
02351 int block_x, block_y;
02352 short *cur_mv;
02353 PicMotionParams *motion = &p_Img->enc_picture->motion;
02354
02355
02356
02357
02358 copy_image_data_16x16(&imgY[currMB->pix_y], p_RDO->rec_mb[0], currMB->pix_x, 0);
02359
02360 if((currSlice->slice_type == SP_SLICE) &&(p_Img->si_frame_indicator==0 && p_Img->sp2_frame_indicator==0 ))
02361 {
02362 for (j = 0; j < MB_BLOCK_SIZE; j++)
02363 memcpy(&p_Img->lrec[currMB->pix_y+j][currMB->pix_x], p_RDO->lrec_rec[j], MB_BLOCK_SIZE * sizeof(int));
02364 }
02365
02366 if (p_Img->AdaptiveRounding)
02367 {
02368 update_offset_params(currMB, mode, currMB->temp_transform_size_8x8_flag);
02369 }
02370
02371 if (p_Img->yuv_format != YUV400)
02372 {
02373 for (k = 0; k < 2; k++)
02374 {
02375 copy_image_data(&imgUV[k][currMB->pix_c_y], p_RDO->rec_mb[k + 1], currMB->pix_c_x, 0, p_Img->mb_cr_size_x, p_Img->mb_cr_size_y);
02376 }
02377
02378 if((currSlice->slice_type == SP_SLICE) &&(!p_Img->si_frame_indicator && !p_Img->sp2_frame_indicator))
02379 {
02380 for (k = 0; k < 2; k++)
02381 {
02382 for (j = 0; j<p_Img->mb_cr_size_y; j++)
02383 {
02384 memcpy(&p_Img->lrec_uv[k][currMB->pix_c_y + j][currMB->pix_c_x], p_RDO->lrec_rec_uv[k][j], p_Img->mb_cr_size_x * sizeof(int));
02385 }
02386 }
02387 }
02388 }
02389
02390
02391 i4p = p_RDO->cofAC;
02392 p_RDO->cofAC = currSlice->cofAC;
02393 currSlice->cofAC = i4p;
02394
02395 i3p = p_RDO->cofDC;
02396 p_RDO->cofDC = currSlice->cofDC;
02397 currSlice->cofDC = i3p;
02398 currMB->cbp = p_RDO->cbp;
02399 currMB->cbp_blk = currSlice->cur_cbp_blk[0];
02400 currMB->cbp |= currSlice->curr_cbp[0];
02401 currMB->cbp |= currSlice->curr_cbp[1];
02402 currSlice->cmp_cbp[1] = currMB->cbp;
02403 currSlice->cmp_cbp[2] = currMB->cbp;
02404
02405
02406 currMB->mb_type = (short) mode;
02407
02408 memcpy(currMB->b8x8, currSlice->p_RDO->best8x8, BLOCK_MULTIPLE * sizeof(Info8x8));
02409
02410
02411 if (mode == P8x8 && !currMB->temp_transform_size_8x8_flag && p_Inp->Transform8x8Mode && (currMB->valid_8x8 == TRUE))
02412 {
02413 RestoreMV8x8(currSlice, 1);
02414 }
02415
02416
02417 if (p_Img->P444_joined)
02418 {
02419 if (((currMB->cbp == 0) && currSlice->cmp_cbp[1] == 0 && currSlice->cmp_cbp[2] == 0) && (currMB->mb_type != I4MB && currMB->mb_type != I8MB))
02420 currMB->luma_transform_size_8x8_flag = FALSE;
02421 else
02422 currMB->luma_transform_size_8x8_flag = currMB->temp_transform_size_8x8_flag;
02423 }
02424 else
02425 {
02426
02427 if (((currMB->cbp & 15) == 0) && (currMB->mb_type != I4MB && currMB->mb_type != I8MB))
02428 currMB->luma_transform_size_8x8_flag = FALSE;
02429 else
02430 currMB->luma_transform_size_8x8_flag = currMB->temp_transform_size_8x8_flag;
02431 }
02432
02433 currSlice->rddata->luma_transform_size_8x8_flag = currMB->luma_transform_size_8x8_flag;
02434
02435 if (p_Inp->rdopt == 3)
02436 {
02437 errdo_get_best_block(currMB, p_Img->enc_picture->p_dec_img[0], p_Img->p_decs->dec_mbY_best, 0, MB_BLOCK_SIZE);
02438 }
02439
02440
02441 for (j = 0; j < 4; j++)
02442 {
02443 block_y = currMB->block_y + j;
02444 for (i = 0; i < 4; i++)
02445 {
02446 block_x = currMB->block_x + i;
02447 k = 2*(j >> 1)+(i >> 1);
02448
02449
02450 if ((currMB->b8x8[k].pdir == 1) || IS_INTRA(currMB))
02451 {
02452 motion->ref_idx [LIST_0][block_y][block_x] = -1;
02453 motion->ref_pic_id [LIST_0][block_y][block_x] = -1;
02454 motion->mv [LIST_0][block_y][block_x][0] = 0;
02455 motion->mv [LIST_0][block_y][block_x][1] = 0;
02456 }
02457 else
02458 {
02459 if (currMB->b8x8[k].bipred && (currMB->b8x8[k].pdir == 2) && is_bipred_enabled(p_Inp, currMB->mb_type))
02460 {
02461 cur_mv = currSlice->bipred_mv[currMB->b8x8[k].bipred - 1][LIST_0][0][(short) currMB->b8x8[k].mode][j][i];
02462
02463 motion->ref_idx [LIST_0][block_y][block_x] = 0;
02464 motion->ref_pic_id [LIST_0][block_y][block_x] = p_Img->enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][0];
02465 motion->mv [LIST_0][block_y][block_x][0] = cur_mv[0];
02466 motion->mv [LIST_0][block_y][block_x][1] = cur_mv[1];
02467 }
02468 else
02469 {
02470 char cur_ref = p_RDO->l0_refframe[j][i];
02471 motion->ref_idx [LIST_0][block_y][block_x] = cur_ref;
02472 motion->ref_pic_id [LIST_0][block_y][block_x] = p_Img->enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][(short)cur_ref];
02473 memcpy(motion->mv [LIST_0][block_y][block_x], currSlice->all_mv[LIST_0][(short)cur_ref][(short) currMB->b8x8[k].mode][j][i], 2 * sizeof(short));
02474 }
02475 }
02476
02477
02478 if ((currMB->b8x8[k].pdir == 0) || IS_INTRA(currMB))
02479 {
02480 motion->ref_idx [LIST_1][block_y][block_x] = -1;
02481 motion->ref_pic_id [LIST_1][block_y][block_x] = -1;
02482 motion->mv [LIST_1][block_y][block_x][0] = 0;
02483 motion->mv [LIST_1][block_y][block_x][1] = 0;
02484 }
02485 }
02486 }
02487
02488 if (currSlice->slice_type == B_SLICE)
02489 {
02490 for (j=0; j<4; j++)
02491 {
02492 block_y = currMB->block_y + j;
02493 for (i=0; i<4; i++)
02494 {
02495 block_x = currMB->block_x + i;
02496 k = 2*(j >> 1)+(i >> 1);
02497
02498
02499 if (IS_INTRA(currMB)||(currMB->b8x8[k].pdir == 0))
02500 {
02501 motion->ref_idx [LIST_1][block_y][block_x] = -1;
02502 motion->ref_pic_id [LIST_1][block_y][block_x] = -1;
02503 motion->mv [LIST_1][block_y][block_x][0] = 0;
02504 motion->mv [LIST_1][block_y][block_x][1] = 0;
02505 }
02506 else
02507 {
02508 if (currMB->b8x8[k].bipred && (currMB->b8x8[k].pdir == 2) && is_bipred_enabled(p_Inp, currMB->mb_type))
02509 {
02510 cur_mv = currSlice->bipred_mv[currMB->b8x8[k].bipred - 1][LIST_1][0][(short) currMB->b8x8[k].mode][j][i];
02511
02512 motion->ref_idx [LIST_1][block_y][block_x] = 0;
02513 motion->ref_pic_id [LIST_1][block_y][block_x] = p_Img->enc_picture->ref_pic_num[LIST_1 + currMB->list_offset][0];
02514 motion->mv [LIST_1][block_y][block_x][0] = cur_mv[0];
02515 motion->mv [LIST_1][block_y][block_x][1] = cur_mv[1];
02516 }
02517 else
02518 {
02519 motion->ref_idx [LIST_1][block_y][block_x] = p_RDO->l1_refframe[j][i];
02520 motion->ref_pic_id [LIST_1][block_y][block_x] = p_Img->enc_picture->ref_pic_num[LIST_1 + currMB->list_offset][(short)p_RDO->l1_refframe[j][i]];
02521 memcpy(motion->mv [LIST_1][block_y][block_x], currSlice->all_mv[LIST_1][(short)p_RDO->l1_refframe[j][i]][(short) currMB->b8x8[k].mode][j][i], 2 * sizeof(short));
02522 }
02523 }
02524 }
02525 }
02526 }
02527
02528
02529 currMB->c_ipred_mode = currMB->best_c_imode;
02530 currMB->i16offset = currMB->best_i16offset;
02531 currMB->cbp = currMB->best_cbp;
02532
02533 if(currMB->mb_type == I8MB)
02534 {
02535 memcpy(currMB->intra_pred_modes8x8,currSlice->b8_intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
02536 memcpy(currMB->intra_pred_modes ,currSlice->b8_intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
02537 for(j = 0; j < BLOCK_MULTIPLE; j++)
02538 {
02539 memcpy(&p_Img->ipredmode [currMB->block_y+j][currMB->block_x], currSlice->b8_ipredmode8x8[j], BLOCK_MULTIPLE * sizeof(char));
02540 memcpy(&p_Img->ipredmode8x8[currMB->block_y+j][currMB->block_x], currSlice->b8_ipredmode8x8[j], BLOCK_MULTIPLE * sizeof(char));
02541 }
02542 }
02543 else if (mode!=I4MB && mode!=I8MB)
02544 {
02545 memset(currMB->intra_pred_modes,DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));
02546 for(j = currMB->block_y; j < currMB->block_y + BLOCK_MULTIPLE; j++)
02547 memset(&p_Img->ipredmode[j][currMB->block_x], DC_PRED, BLOCK_MULTIPLE * sizeof(char));
02548 }
02549
02550 else if (mode == I4MB)
02551 {
02552 memcpy(currMB->intra_pred_modes,currSlice->b4_intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
02553 for(j = 0; j < BLOCK_MULTIPLE; j++)
02554 memcpy(&p_Img->ipredmode[currMB->block_y + j][currMB->block_x],&currSlice->b4_ipredmode[BLOCK_MULTIPLE * j], BLOCK_MULTIPLE * sizeof(char));
02555 }
02556
02557
02558 currSlice->SetMotionVectorsMB (currMB, motion);
02559 }
02560
02561
02562
02563
02564
02565
02566
02567
02568 void set_ref_and_motion_vectors_P_slice (Macroblock *currMB, PicMotionParams *motion, Info8x8 *part, int block)
02569 {
02570 Slice *currSlice = currMB->p_slice;
02571 ImageParameters *p_Img = currMB->p_Img;
02572
02573 int mode = part->mode;
02574 int k, j=0;
02575 int pmode = (mode==1||mode==2||mode==3 ? mode : 4);
02576 int part_size_x = part_size[pmode][0];
02577 int part_size_y = part_size[pmode][1];
02578 int j0 = ((block >> 1)<<1);
02579 int i0 = ((block & 0x01)<<1);
02580 int i1 = i0 + part_size_x;
02581 int j1 = j0 + part_size_y;
02582 int block_x, block_y;
02583
02584 if (part->pdir < 0)
02585 {
02586 for (k = LIST_0; k <= LIST_1; k++)
02587 {
02588 for (j = currMB->block_y + j0; j < currMB->block_y + j1; j++)
02589 {
02590 memset(&motion->ref_pic_id[k][j][currMB->block_x + i0], (int64) -1, part_size_x * sizeof(int64));
02591 memset(&motion->ref_idx [k][j][currMB->block_x + i0], -1, part_size_x * sizeof(char));
02592 memset(&motion->mv [k][j][currMB->block_x + i0][0], 0, 2 * part_size_x * sizeof(short));
02593 }
02594 }
02595 return;
02596 }
02597 else
02598 {
02599 int fwref = part->ref[LIST_0];
02600 int64 ref_pic_num = p_Img->enc_picture->ref_pic_num[LIST_0+currMB->list_offset][fwref];
02601 for (j = j0; j < j1; j++)
02602 {
02603 block_y = currMB->block_y + j;
02604 for (block_x = currMB->block_x + i0; block_x < currMB->block_x + i1; block_x++)
02605 motion->ref_pic_id[LIST_0][block_y][block_x] = ref_pic_num;
02606
02607 memset(&motion->ref_idx[LIST_0][block_y][currMB->block_x + i0], fwref, part_size_x * sizeof(char));
02608 memcpy(&motion->mv [LIST_0][block_y][currMB->block_x + i0][0], currSlice->all_mv[LIST_0][fwref][mode][j][i0], 2 * part_size_x * sizeof(short));
02609 }
02610 return;
02611 }
02612 }
02613
02614
02615
02616
02617
02618
02619
02620
02621 static void set_ref_and_motion_vectors_B_slice (Macroblock *currMB, PicMotionParams *motion, Info8x8 *part, int block)
02622 {
02623 Slice *currSlice = currMB->p_slice;
02624 ImageParameters *p_Img = currMB->p_Img;
02625 InputParameters *p_Inp = currMB->p_Inp;
02626
02627 int mode = part->mode;
02628 int k, i, j=0;
02629 int pmode = (mode==1||mode==2||mode==3 ? mode : 4);
02630 int part_size_x = part_size[pmode][0];
02631 int part_size_y = part_size[pmode][1];
02632 int j0 = ((block >> 1)<<1);
02633 int i0 = ((block & 0x01)<<1);
02634 int i1 = i0 + part_size_x;
02635 int j1 = j0 + part_size_y;
02636
02637
02638 if (part->pdir < 0)
02639 {
02640 for (k = LIST_0; k <= LIST_1; k++)
02641 {
02642 for (j = currMB->block_y + j0; j < currMB->block_y + j1; j++)
02643 {
02644 memset(&motion->ref_pic_id[k][j][currMB->block_x + i0], (int64) -1, part_size_x * sizeof(int64));
02645 memset(&motion->ref_idx [k][j][currMB->block_x + i0], -1, part_size_x * sizeof(char));
02646 memset(&motion->mv [k][j][currMB->block_x + i0][0], 0, 2 * part_size_x * sizeof(short));
02647 }
02648 }
02649 return;
02650 }
02651 else
02652 {
02653 short *cur_mv;
02654 int64 ref_pic_num;
02655 char *ref_idx;
02656 int block_x, block_y;
02657
02658 if ((part->pdir == 0 || part->pdir == 2))
02659 {
02660 if (part->bipred && (part->pdir == 2) && is_bipred_enabled(p_Inp, mode))
02661 {
02662 for (j=j0; j<j1; j++)
02663 {
02664 block_y = currMB->block_y + j;
02665 for (i=i0; i<i1; i++)
02666 {
02667 block_x = currMB->block_x + i;
02668
02669 cur_mv = currSlice->bipred_mv[part->bipred - 1][LIST_0][0][mode][j][i];
02670
02671 motion->mv [LIST_0][block_y][block_x][0] = cur_mv[0];
02672 motion->mv [LIST_0][block_y][block_x][1] = cur_mv[1];
02673 motion->ref_idx [LIST_0][block_y][block_x] = 0;
02674 motion->ref_pic_id[LIST_0][block_y][block_x] = p_Img->enc_picture->ref_pic_num[LIST_0 + currMB->list_offset][0];
02675 }
02676 }
02677 }
02678 else
02679 {
02680 if (mode==0)
02681 {
02682 int fwref = part->ref[LIST_0];
02683 for (j=j0; j<j1; j++)
02684 {
02685 block_y = currMB->block_y + j;
02686 ref_idx = motion->ref_idx[LIST_0][block_y];
02687 memcpy(&motion->mv[LIST_0][block_y][currMB->block_x + i0][0], currSlice->all_mv[LIST_0][fwref][mode][j][i0], 2 * part_size_x * sizeof(short));
02688 for (block_x = currMB->block_x + i0; block_x < currMB->block_x + i1; block_x++)
02689 {
02690 ref_idx[block_x] = currSlice->direct_ref_idx[block_y][block_x][LIST_0];
02691 motion->ref_pic_id[LIST_0][block_y][block_x] =
02692 p_Img->enc_picture->ref_pic_num[LIST_0+currMB->list_offset][(short)ref_idx[block_x]];
02693 }
02694 }
02695 }
02696 else
02697 {
02698 int fwref = part->ref[LIST_0];
02699 for (j=j0; j<j1; j++)
02700 {
02701 block_y = currMB->block_y + j;
02702 ref_pic_num = p_Img->enc_picture->ref_pic_num[LIST_0+currMB->list_offset][fwref];
02703 memcpy(&motion->mv[LIST_0][block_y][currMB->block_x + i0][0], currSlice->all_mv[LIST_0][fwref][mode][j][i0], 2 * part_size_x * sizeof(short));
02704 memset(&motion->ref_idx[LIST_0][block_y][currMB->block_x + i0], fwref, part_size_x * sizeof(char));
02705 for (block_x = currMB->block_x + i0; block_x < currMB->block_x + i1; block_x++)
02706 {
02707 motion->ref_pic_id[LIST_0][block_y][block_x] = ref_pic_num ;
02708 }
02709 }
02710 }
02711 }
02712 }
02713 else
02714 {
02715 for (j=currMB->block_y + j0; j < currMB->block_y + j1; j++)
02716 {
02717 memset(&motion->ref_pic_id[LIST_0][j][currMB->block_x + i0], -1, part_size_x * sizeof(int64));
02718 memset(&motion->ref_idx [LIST_0][j][currMB->block_x + i0], -1, part_size_x * sizeof(char));
02719 memset(motion->mv [LIST_0][j][currMB->block_x + i0], 0, 2 * part_size_x * sizeof(short));
02720 }
02721 }
02722
02723
02724 if ((part->pdir==1 || part->pdir==2))
02725 {
02726 if (part->bipred && (part->pdir == 2) && is_bipred_enabled(p_Inp, mode))
02727 {
02728 for (j=j0; j<j1; j++)
02729 {
02730 block_y = currMB->block_y + j;
02731
02732 for (i=i0; i<i1; i++)
02733 {
02734 block_x = currMB->block_x + i;
02735
02736 cur_mv = currSlice->bipred_mv[part->bipred - 1][LIST_1][0][mode][j][i];
02737
02738 motion->mv [LIST_1][block_y][block_x][0] = cur_mv[0];
02739 motion->mv [LIST_1][block_y][block_x][1] = cur_mv[1];
02740 motion->ref_idx [LIST_1][block_y][block_x] = 0;
02741 motion->ref_pic_id[LIST_1][block_y][block_x] = p_Img->enc_picture->ref_pic_num[LIST_1+currMB->list_offset][0];
02742 }
02743 }
02744 }
02745 else
02746 {
02747 if (mode==0)
02748 {
02749 int bwref = part->ref[LIST_1];
02750 for (j=j0; j<j1; j++)
02751 {
02752 block_y = currMB->block_y + j;
02753
02754 ref_idx = motion->ref_idx[LIST_1][block_y];
02755
02756
02757 memcpy(&motion->mv[LIST_1][block_y][currMB->block_x + i0][0], currSlice->all_mv[LIST_1][bwref][mode][j][i0], 2 * part_size_x * sizeof(short));
02758 for (block_x = currMB->block_x + i0; block_x < currMB->block_x + i1; block_x++)
02759 {
02760 ref_idx[block_x] = currSlice->direct_ref_idx[block_y][block_x][LIST_1];
02761 motion->ref_pic_id[LIST_1][block_y][block_x] = p_Img->enc_picture->ref_pic_num[LIST_1+currMB->list_offset][(short)ref_idx[block_x]];
02762 }
02763 }
02764 }
02765 else
02766 {
02767 int bwref = part->ref[LIST_1];
02768 for (j=j0; j<j1; j++)
02769 {
02770 block_y = currMB->block_y + j;
02771 ref_pic_num = p_Img->enc_picture->ref_pic_num[LIST_1+currMB->list_offset][bwref];
02772 memcpy(&motion->mv[LIST_1][block_y][currMB->block_x + i0][0], currSlice->all_mv[LIST_1][bwref][mode][j][i0], 2 * part_size_x * sizeof(short));
02773 memset(&motion->ref_idx[LIST_1][block_y][currMB->block_x + i0], bwref, part_size_x * sizeof(char));
02774 for (block_x = currMB->block_x + i0; block_x < currMB->block_x + i1; block_x++)
02775 {
02776 motion->ref_pic_id[LIST_1][block_y][block_x] = ref_pic_num ;
02777 }
02778 }
02779 }
02780 }
02781 }
02782 else
02783 {
02784 for (j=j0; j<j1; j++)
02785 {
02786 block_y = currMB->block_y + j;
02787 memset(motion->mv [LIST_1][block_y][currMB->block_x + i0], 0, 2 * part_size_x * sizeof(short));
02788 memset(&motion->ref_idx [LIST_1][block_y][currMB->block_x + i0], -1, part_size_x * sizeof(char));
02789 memset(&motion->ref_pic_id[LIST_1][block_y][currMB->block_x + i0], (int64) -1, part_size_x * sizeof(int64));
02790 }
02791 }
02792 }
02793 }
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803 byte field_flag_inference(Macroblock *currMB)
02804 {
02805 ImageParameters *p_Img = currMB->p_Img;
02806 byte mb_field;
02807
02808 if (currMB->mbAvailA)
02809 {
02810 mb_field = p_Img->mb_data[currMB->mbAddrA].mb_field;
02811 }
02812 else
02813 {
02814
02815 if (currMB->mbAvailB)
02816 mb_field = p_Img->mb_data[currMB->mbAddrB].mb_field;
02817 else
02818 mb_field = 0;
02819 }
02820
02821 return mb_field;
02822 }
02823
02824
02825
02826
02827
02828
02829
02830
02831 void StoreMVBlock8x8(Slice *currSlice, int dir, int block8x8, int mode, Info8x8 *B8x8Info)
02832 {
02833 RDOPTStructure *p_RDO = currSlice->p_RDO;
02834 int i0 = (block8x8 & 0x01) << 1;
02835 int j0 = (block8x8 >> 1) << 1;
02836 int j1 = j0 + 1;
02837
02838 short ******all_mv = currSlice->all_mv;
02839 short ***lc_l0_mv8x8 = p_RDO->all_mv8x8[dir][LIST_0];
02840 short ***lc_l1_mv8x8 = p_RDO->all_mv8x8[dir][LIST_1];
02841
02842 if (currSlice->slice_type != B_SLICE )
02843 {
02844 if (B8x8Info->pdir >= 0)
02845 {
02846 int l0_ref = B8x8Info->ref[LIST_0];
02847 memcpy(&lc_l0_mv8x8[j0][i0][0], &all_mv[LIST_0][l0_ref][mode][j0][i0][0], 4 * sizeof(short));
02848 memcpy(&lc_l0_mv8x8[j1][i0][0], &all_mv[LIST_0][l0_ref][mode][j1][i0][0], 4 * sizeof(short));
02849 }
02850 }
02851 else
02852 {
02853 int bipred_me = B8x8Info->bipred;
02854 int pdir8 = B8x8Info->pdir;
02855 if (bipred_me)
02856 {
02857 all_mv = currSlice->bipred_mv[bipred_me - 1];
02858 }
02859
02860 if (pdir8 == 0)
02861 {
02862 int l0_ref = B8x8Info->ref[LIST_0];
02863 memcpy(&lc_l0_mv8x8[j0][i0][0], &all_mv[LIST_0][l0_ref][mode][j0][i0][0], 4 * sizeof(short));
02864 memcpy(&lc_l0_mv8x8[j1][i0][0], &all_mv[LIST_0][l0_ref][mode][j1][i0][0], 4 * sizeof(short));
02865 }
02866 else if (pdir8 == 1)
02867 {
02868 int l1_ref = B8x8Info->ref[LIST_1];
02869 memcpy(&lc_l1_mv8x8[j0][i0][0], &all_mv[LIST_1][l1_ref][mode][j0][i0][0], 4 * sizeof(short));
02870 memcpy(&lc_l1_mv8x8[j1][i0][0], &all_mv[LIST_1][l1_ref][mode][j1][i0][0], 4 * sizeof(short));
02871 }
02872 else if (pdir8==2)
02873 {
02874 int l0_ref = B8x8Info->ref[LIST_0];
02875 int l1_ref = B8x8Info->ref[LIST_1];
02876 memcpy(&lc_l0_mv8x8[j0][i0][0], &all_mv[LIST_0][l0_ref][mode][j0][i0][0], 4 * sizeof(short));
02877 memcpy(&lc_l0_mv8x8[j1][i0][0], &all_mv[LIST_0][l0_ref][mode][j1][i0][0], 4 * sizeof(short));
02878 memcpy(&lc_l1_mv8x8[j0][i0][0], &all_mv[LIST_1][l1_ref][mode][j0][i0][0], 4 * sizeof(short));
02879 memcpy(&lc_l1_mv8x8[j1][i0][0], &all_mv[LIST_1][l1_ref][mode][j1][i0][0], 4 * sizeof(short));
02880 }
02881 else
02882 {
02883 error("invalid direction mode", 255);
02884 }
02885 }
02886 }
02887
02888
02889
02890
02891
02892
02893
02894 void StoreMV8x8(Slice *currSlice, int dir)
02895 {
02896 RDOPTStructure *p_RDO = currSlice->p_RDO;
02897 int block8x8;
02898
02899 for (block8x8=0; block8x8<4; block8x8++)
02900 StoreMVBlock8x8(currSlice, dir, block8x8, p_RDO->tr8x8->part[block8x8].mode, &p_RDO->tr8x8->part[block8x8]);
02901 }
02902
02903
02904
02905
02906
02907
02908
02909 void RestoreMVBlock8x8(Slice *currSlice, int dir, int block8x8, RD_8x8DATA *tr)
02910 {
02911 RDOPTStructure *p_RDO = currSlice->p_RDO;
02912 short ******all_mv = currSlice->all_mv;
02913 short ***lc_l0_mv8x8 = p_RDO->all_mv8x8[dir][LIST_0];
02914 short ***lc_l1_mv8x8 = p_RDO->all_mv8x8[dir][LIST_1];
02915
02916 short pdir8 = tr->part[block8x8].pdir;
02917 short mode = tr->part[block8x8].mode;
02918 short l0_ref = tr->part[block8x8].ref[LIST_0];
02919 short l1_ref = tr->part[block8x8].ref[LIST_1];
02920 short bipred_me = tr->part[block8x8].bipred;
02921
02922 int i0 = (block8x8 & 0x01) << 1;
02923 int j0 = (block8x8 >> 1) << 1;
02924 int j1 = j0 + 1;
02925
02926 if (currSlice->slice_type != B_SLICE)
02927 {
02928 if (pdir8>=0)
02929 {
02930 memcpy(&all_mv[LIST_0][l0_ref][4][j0][i0][0], &lc_l0_mv8x8[j0][i0][0], 4 * sizeof(short));
02931 memcpy(&all_mv[LIST_0][l0_ref][4][j1][i0][0], &lc_l0_mv8x8[j1][i0][0], 4 * sizeof(short));
02932 }
02933 }
02934 else
02935 {
02936 if (pdir8==0)
02937 {
02938 memcpy(&all_mv[LIST_0][l0_ref][mode][j0][i0][0], &lc_l0_mv8x8[j0][i0][0], 4 * sizeof(short));
02939 memcpy(&all_mv[LIST_0][l0_ref][mode][j1][i0][0], &lc_l0_mv8x8[j1][i0][0], 4 * sizeof(short));
02940 }
02941 else if (pdir8==1)
02942 {
02943 memcpy(&all_mv[LIST_1][l1_ref][mode][j0][i0][0], &lc_l1_mv8x8[j0][i0][0], 4 * sizeof(short));
02944 memcpy(&all_mv[LIST_1][l1_ref][mode][j1][i0][0], &lc_l1_mv8x8[j1][i0][0], 4 * sizeof(short));
02945 }
02946 else if (pdir8==2)
02947 {
02948 if(bipred_me)
02949 {
02950 all_mv = currSlice->bipred_mv[bipred_me - 1];
02951 }
02952
02953 memcpy(&all_mv[LIST_0][l0_ref][mode][j0][i0][0], &lc_l0_mv8x8[j0][i0][0], 4 * sizeof(short));
02954 memcpy(&all_mv[LIST_0][l0_ref][mode][j1][i0][0], &lc_l0_mv8x8[j1][i0][0], 4 * sizeof(short));
02955 memcpy(&all_mv[LIST_1][l1_ref][mode][j0][i0][0], &lc_l1_mv8x8[j0][i0][0], 4 * sizeof(short));
02956 memcpy(&all_mv[LIST_1][l1_ref][mode][j1][i0][0], &lc_l1_mv8x8[j1][i0][0], 4 * sizeof(short));
02957 }
02958 else
02959 {
02960 error("invalid direction mode", 255);
02961 }
02962 }
02963 }
02964
02965
02966
02967
02968
02969
02970
02971 void RestoreMV8x8(Slice *currSlice, int dir)
02972 {
02973 RDOPTStructure *p_RDO = currSlice->p_RDO;
02974 int block8x8;
02975
02976 for (block8x8=0; block8x8<4; block8x8++)
02977 RestoreMVBlock8x8(currSlice, dir, block8x8, p_RDO->tr8x8);
02978 }
02979
02980
02981
02982
02983
02984
02985
02986
02987 void StoreNewMotionVectorsBlock8x8(Slice *currSlice, int dir, int block8x8, Info8x8 *B8x8Info)
02988 {
02989 RDOPTStructure *p_RDO = currSlice->p_RDO;
02990 int mode = B8x8Info->mode;
02991 int i0 = (block8x8 & 0x01) << 1;
02992 int j0 = (block8x8 >> 1) << 1;
02993 int j1 = j0 + 1;
02994
02995 short *****all_mv_l0 = currSlice->all_mv[LIST_0];
02996 short *****all_mv_l1 = currSlice->all_mv[LIST_1];
02997 short ***lc_l0_mv8x8 = &p_RDO->all_mv8x8[dir][LIST_0][j0];
02998 short ***lc_l1_mv8x8 = &p_RDO->all_mv8x8[dir][LIST_1][j0];
02999
03000
03001 if (B8x8Info->pdir < 0)
03002 {
03003 memset(&lc_l0_mv8x8[0][i0][0], 0, 4 * sizeof(short));
03004 memset(&lc_l0_mv8x8[1][i0][0], 0, 4 * sizeof(short));
03005 memset(&lc_l1_mv8x8[0][i0][0], 0, 4 * sizeof(short));
03006 memset(&lc_l1_mv8x8[1][i0][0], 0, 4 * sizeof(short));
03007 return;
03008 }
03009
03010 if (currSlice->slice_type != B_SLICE)
03011 {
03012 int l0_ref = B8x8Info->ref[LIST_0];
03013 memcpy(&lc_l0_mv8x8[0][i0][0], &all_mv_l0[l0_ref][mode][j0][i0][0], 4 * sizeof(short));
03014 memcpy(&lc_l0_mv8x8[1][i0][0], &all_mv_l0[l0_ref][mode][j1][i0][0], 4 * sizeof(short));
03015 memset(&lc_l1_mv8x8[0][i0][0], 0, 4 * sizeof(short));
03016 memset(&lc_l1_mv8x8[1][i0][0], 0, 4 * sizeof(short));
03017 return;
03018 }
03019 else
03020 {
03021 int bipred_me = B8x8Info->bipred;
03022 int pdir8 = B8x8Info->pdir;
03023 if (bipred_me)
03024 {
03025 all_mv_l0 = currSlice->bipred_mv[bipred_me - 1][LIST_0];
03026 all_mv_l1 = currSlice->bipred_mv[bipred_me - 1][LIST_1];
03027 }
03028
03029 if ((pdir8==0 || pdir8==2))
03030 {
03031 int l0_ref = B8x8Info->ref[LIST_0];
03032 memcpy(&lc_l0_mv8x8[0][i0][0], &all_mv_l0[l0_ref][mode][j0][i0][0], 4 * sizeof(short));
03033 memcpy(&lc_l0_mv8x8[1][i0][0], &all_mv_l0[l0_ref][mode][j1][i0][0], 4 * sizeof(short));
03034 }
03035 else
03036 {
03037 memset(&lc_l0_mv8x8[0][i0][0], 0, 4 * sizeof(short));
03038 memset(&lc_l0_mv8x8[1][i0][0], 0, 4 * sizeof(short));
03039 }
03040
03041 if ((pdir8==1 || pdir8==2))
03042 {
03043 int l1_ref = B8x8Info->ref[LIST_1];
03044 memcpy(&lc_l1_mv8x8[0][i0][0], &all_mv_l1[l1_ref][mode][j0][i0][0], 4 * sizeof(short));
03045 memcpy(&lc_l1_mv8x8[1][i0][0], &all_mv_l1[l1_ref][mode][j1][i0][0], 4 * sizeof(short));
03046 }
03047 else
03048 {
03049 memset(&lc_l1_mv8x8[0][i0][0], 0, 4 * sizeof(short));
03050 memset(&lc_l1_mv8x8[1][i0][0], 0, 4 * sizeof(short));
03051 }
03052 }
03053 }
03054
03055
03056
03057
03058
03059
03060
03061 int GetBestTransformP8x8(Macroblock *currMB)
03062 {
03063 ImageParameters *p_Img = currMB->p_Img;
03064 InputParameters *p_Inp = currMB->p_Inp;
03065 RDOPTStructure *p_RDO = currMB->p_slice->p_RDO;
03066
03067 int diff4x4[64];
03068 int diff8x8[64];
03069
03070 int block_y, block_x, pic_pix_y, pic_pix_x, i, j, k;
03071 int mb_y, mb_x, block8x8;
03072 int cost8x8=0, cost4x4=0;
03073 int *diff_ptr;
03074
03075 if(p_Inp->Transform8x8Mode == 2)
03076 return 1;
03077
03078 for (block8x8=0; block8x8<4; block8x8++)
03079 {
03080 mb_y = (block8x8 >> 1) << 3;
03081 mb_x = (block8x8 & 0x01) << 3;
03082
03083 k=0;
03084 for (block_y = mb_y; block_y < mb_y + 8; block_y += 4)
03085 {
03086 pic_pix_y = currMB->opix_y + block_y;
03087
03088
03089 for (block_x = mb_x; block_x<mb_x + 8; block_x += 4)
03090 {
03091 pic_pix_x = currMB->pix_x + block_x;
03092
03093
03094 diff_ptr=&diff4x4[k];
03095 for (j=0; j<4; j++)
03096 {
03097 for (i=0; i<4; i++, k++)
03098 {
03099
03100 diff4x4[k] = p_Img->pCurImg[pic_pix_y+j][pic_pix_x+i] - p_RDO->tr4x4->mpr8x8[j+block_y][i+block_x];
03101
03102 diff8x8[k] = p_Img->pCurImg[pic_pix_y+j][pic_pix_x+i] - p_RDO->tr8x8->mpr8x8[j+block_y][i+block_x];
03103 }
03104 }
03105
03106 cost4x4 += p_Img->distortion4x4 (diff_ptr, INT_MAX);
03107 }
03108 }
03109 cost8x8 += p_Img->distortion8x8 (diff8x8, INT_MAX);
03110 }
03111 return (cost8x8 < cost4x4);
03112 }
03113
03114
03115
03116
03117
03118
03119
03120 void set_mbaff_parameters(Macroblock *currMB)
03121 {
03122 ImageParameters *p_Img = currMB->p_Img;
03123 InputParameters *p_Inp = currMB->p_Inp;
03124 Slice *currSlice = currMB->p_slice;
03125
03126 int j;
03127 int mode = currMB->best_mode;
03128 char **ipredmodes = p_Img->ipredmode;
03129 PicMotionParams *motion = &p_Img->enc_picture->motion;
03130 RD_DATA *rdopt = currSlice->rddata;
03131
03132
03133
03134 copy_image_data_16x16(rdopt->rec_mb[0], &p_Img->enc_picture->imgY[currMB->pix_y], 0, currMB->pix_x);
03135
03136 if (p_Img->yuv_format != YUV400)
03137 {
03138 copy_image_data(rdopt->rec_mb[1], &p_Img->enc_picture->imgUV[0][currMB->pix_c_y], 0, currMB->pix_c_x, p_Img->mb_cr_size_x, p_Img->mb_cr_size_y);
03139 copy_image_data(rdopt->rec_mb[2], &p_Img->enc_picture->imgUV[1][currMB->pix_c_y], 0, currMB->pix_c_x, p_Img->mb_cr_size_x, p_Img->mb_cr_size_y);
03140 }
03141
03142
03143 rdopt->mode = mode;
03144 rdopt->i16offset = currMB->i16offset;
03145 rdopt->cbp = currMB->cbp;
03146 rdopt->cbp_blk = currMB->cbp_blk;
03147 rdopt->mb_type = currMB->mb_type;
03148
03149 rdopt->luma_transform_size_8x8_flag = currMB->luma_transform_size_8x8_flag;
03150
03151 if(rdopt->mb_type == 0 && mode != 0)
03152 {
03153 mode=0;
03154 rdopt->mode=0;
03155 }
03156
03157 memcpy(rdopt->cofAC[0][0][0], currSlice->cofAC[0][0][0], (4+p_Img->num_blk8x8_uv) * 4 * 2 * 65 * sizeof(int));
03158 memcpy(rdopt->cofDC[0][0], currSlice->cofDC[0][0], 3 * 2 * 18 * sizeof(int));
03159
03160 memcpy(rdopt->b8x8, currMB->b8x8, BLOCK_MULTIPLE * sizeof(Info8x8));
03161
03162
03163 if (currSlice->slice_type == B_SLICE)
03164 {
03165 if (p_Inp->BiPredMERefinements == 1)
03166 {
03167 int i, j, k;
03168 for (j = 0; j < BLOCK_MULTIPLE; j++)
03169 {
03170 for (i = 0; i < BLOCK_MULTIPLE; i++)
03171 {
03172 k = 2*(j >> 1)+(i >> 1);
03173 if (currMB->b8x8[k].bipred == 0)
03174 {
03175 rdopt->refar[LIST_0][j][i] = motion->ref_idx[LIST_0][currMB->block_y + j][currMB->block_x + i];
03176 rdopt->refar[LIST_1][j][i] = motion->ref_idx[LIST_1][currMB->block_y + j][currMB->block_x + i];
03177 }
03178 else
03179 {
03180 rdopt->refar[LIST_0][j][i] = 0;
03181 rdopt->refar[LIST_1][j][i] = 0;
03182 }
03183 }
03184 }
03185 }
03186 else
03187 {
03188 for (j = 0; j < BLOCK_MULTIPLE; j++)
03189 {
03190 memcpy(rdopt->refar[LIST_0][j],&motion->ref_idx[LIST_0][currMB->block_y + j][currMB->block_x] , BLOCK_MULTIPLE * sizeof(char));
03191 memcpy(rdopt->refar[LIST_1][j],&motion->ref_idx[LIST_1][currMB->block_y + j][currMB->block_x] , BLOCK_MULTIPLE * sizeof(char));
03192 }
03193 }
03194 }
03195 else
03196 {
03197 for (j = 0; j < BLOCK_MULTIPLE; j++)
03198 memcpy(rdopt->refar[LIST_0][j],&motion->ref_idx[LIST_0][currMB->block_y + j][currMB->block_x] , BLOCK_MULTIPLE * sizeof(char));
03199 }
03200
03201 memcpy(rdopt->intra_pred_modes, currMB->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
03202 memcpy(rdopt->intra_pred_modes8x8,currMB->intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
03203 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
03204 {
03205 memcpy(&rdopt->ipredmode[j][currMB->block_x],&ipredmodes[j][currMB->block_x], BLOCK_MULTIPLE * sizeof(char));
03206 }
03207 }
03208
03209
03210 void assign_enc_picture_params (Macroblock *currMB, int mode, Info8x8 *best, int block)
03211 {
03212 int i,j;
03213 int block_x, block_y;
03214 int list, maxlist, bestref;
03215 short ***curr_mv = NULL;
03216 int64 curr_ref_idx = 0;
03217 int list_offset = currMB->list_offset;
03218 ImageParameters *p_Img = currMB->p_Img;
03219 Slice *currSlice = currMB->p_slice;
03220 PicMotionParams *motion = &p_Img->enc_picture->motion;
03221
03222 int start_x = 0, start_y = 0, end_x = BLOCK_MULTIPLE, end_y = BLOCK_MULTIPLE;
03223
03224 switch (mode)
03225 {
03226 case 1:
03227 start_x = 0;
03228 start_y = 0;
03229 end_x = BLOCK_MULTIPLE;
03230 end_y = BLOCK_MULTIPLE;
03231 break;
03232 case 2:
03233 start_x = 0;
03234 start_y = block;
03235 end_x = BLOCK_MULTIPLE;
03236 end_y = block + 2;
03237 break;
03238 case 3:
03239 start_x = block;
03240 start_y = 0;
03241 end_x = block + 2;
03242 end_y = BLOCK_MULTIPLE;
03243 break;
03244 case 4:
03245 default:
03246 start_x = ((block>>1) & 0x01)* 2;
03247 start_y = ((block>>1) & 0x02);
03248 end_x = start_x + 2;
03249 end_y = start_y + 2;
03250 break;
03251 }
03252
03253 maxlist = (currSlice->slice_type == B_SLICE) ? 1: 0;
03254
03255 for (list = 0; list <= maxlist; list++)
03256 {
03257 bestref = best->ref[list];
03258 switch (best->bipred)
03259 {
03260 case 0:
03261 curr_mv = currSlice->all_mv[list][bestref][mode];
03262 curr_ref_idx = p_Img->enc_picture->ref_pic_num[list + list_offset][bestref];
03263 break;
03264 case 1:
03265 curr_mv = currSlice->bipred_mv[0][list][0][mode] ;
03266 curr_ref_idx = p_Img->enc_picture->ref_pic_num[list + list_offset][0];
03267 break;
03268 case 2:
03269 curr_mv = currSlice->bipred_mv[1][list][0][mode] ;
03270 curr_ref_idx = p_Img->enc_picture->ref_pic_num[list + list_offset][0];
03271 break;
03272 default:
03273 break;
03274 }
03275
03276 for (j = start_y; j < end_y; j++)
03277 {
03278 block_y = currMB->block_y + j;
03279 for (i = start_x; i < end_x; i++)
03280 {
03281 block_x = currMB->block_x + i;
03282 if ((best->pdir != 2) && (best->pdir != list))
03283 {
03284 motion->ref_idx [list][block_y][block_x] = -1;
03285 motion->ref_pic_id [list][block_y][block_x] = -1;
03286 motion->mv [list][block_y][block_x][0] = 0;
03287 motion->mv [list][block_y][block_x][1] = 0;
03288 }
03289 else
03290 {
03291 motion->ref_pic_id [list][block_y][block_x] = curr_ref_idx;
03292 motion->mv [list][block_y][block_x][0] = curr_mv[j][i][0];
03293 motion->mv [list][block_y][block_x][1] = curr_mv[j][i][1];
03294 }
03295 }
03296 }
03297 }
03298 }
03299
03300
03301
03302
03303
03304
03305
03306 void set_block8x8_info(Block8x8Info *b8x8info, int mode, int block, Info8x8 *best)
03307 {
03308
03309 if (mode==3)
03310 {
03311 b8x8info->best[3][block ] = *best;
03312 b8x8info->best[3][block+2] = *best;
03313 }
03314 else if (mode==2)
03315 {
03316 b8x8info->best[2][2*block ] = *best;
03317 b8x8info->best[2][2*block + 1] = *best;
03318 }
03319 else if (mode==1)
03320 {
03321 b8x8info->best[1][0] = *best;
03322 b8x8info->best[1][1] = *best;
03323 b8x8info->best[1][2] = *best;
03324 b8x8info->best[1][3] = *best;
03325
03326 }
03327 else
03328 {
03329 b8x8info->best[mode][block] = *best;
03330 }
03331 }
03332
03333
03334
03335
03336
03337
03338
03339 void set_subblock8x8_info(Block8x8Info *b8x8info,int mode, int block, RD_8x8DATA *tr)
03340 {
03341 b8x8info->best [mode][block] = tr->part[block];
03342 }
03343
03344
03345
03346 void update_refresh_map(Macroblock *currMB, int intra, int intra1)
03347 {
03348 ImageParameters *p_Img = currMB->p_Img;
03349 InputParameters *p_Inp = currMB->p_Inp;
03350
03351 if (p_Inp->RestrictRef==1)
03352 {
03353
03354 if (p_Inp->rdopt<2)
03355 {
03356 p_Img->refresh_map[2*currMB->mb_y ][2*currMB->mb_x ] = (byte) (intra ? 1 : 0);
03357 p_Img->refresh_map[2*currMB->mb_y ][2*currMB->mb_x+1] = (byte) (intra ? 1 : 0);
03358 p_Img->refresh_map[2*currMB->mb_y + 1][2*currMB->mb_x ] = (byte) (intra ? 1 : 0);
03359 p_Img->refresh_map[2*currMB->mb_y + 1][2*currMB->mb_x+1] = (byte) (intra ? 1 : 0);
03360 }
03361 else if (p_Inp->rdopt == 3)
03362 {
03363 p_Img->refresh_map[2*currMB->mb_y ][2*currMB->mb_x ] = (byte) (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0);
03364 p_Img->refresh_map[2*currMB->mb_y ][2*currMB->mb_x+1] = (byte) (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0);
03365 p_Img->refresh_map[2*currMB->mb_y + 1][2*currMB->mb_x ] = (byte) (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0);
03366 p_Img->refresh_map[2*currMB->mb_y + 1][2*currMB->mb_x+1] = (byte) (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0);
03367 }
03368 }
03369 else if (p_Inp->RestrictRef==2)
03370 {
03371 p_Img->refresh_map[2*currMB->mb_y ][2*currMB->mb_x ] = (byte) (currMB->mb_type==I16MB || currMB->mb_type==I4MB ? 1 : 0);
03372 p_Img->refresh_map[2*currMB->mb_y ][2*currMB->mb_x+1] = (byte) (currMB->mb_type==I16MB || currMB->mb_type==I4MB ? 1 : 0);
03373 p_Img->refresh_map[2*currMB->mb_y + 1][2*currMB->mb_x ] = (byte) (currMB->mb_type==I16MB || currMB->mb_type==I4MB ? 1 : 0);
03374 p_Img->refresh_map[2*currMB->mb_y + 1][2*currMB->mb_x+1] = (byte) (currMB->mb_type==I16MB || currMB->mb_type==I4MB ? 1 : 0);
03375 }
03376 }
03377
03378 int valid_intra_mode(Slice *currSlice, int ipmode)
03379 {
03380 InputParameters *p_Inp = currSlice->p_Inp;
03381
03382 if (p_Inp->IntraDisableInterOnly==0 || currSlice->slice_type != I_SLICE)
03383 {
03384 if (p_Inp->Intra4x4ParDisable && (ipmode==VERT_PRED||ipmode==HOR_PRED))
03385 return 0;
03386
03387 if (p_Inp->Intra4x4DiagDisable && (ipmode==DIAG_DOWN_LEFT_PRED||ipmode==DIAG_DOWN_RIGHT_PRED))
03388 return 0;
03389
03390 if (p_Inp->Intra4x4DirDisable && ipmode>=VERT_RIGHT_PRED)
03391 return 0;
03392 }
03393 return 1;
03394 }
03395
03396
03397 void compute_sad4x4_cost(ImageParameters *p_Img, imgpel **cur_img, imgpel **prd_img, int pic_opix_x, int *cost, int min_cost)
03398 {
03399 int j, i;
03400 imgpel *cur_line, *prd_line;
03401
03402 for (j = 0; j < BLOCK_SIZE; j++)
03403 {
03404 cur_line = &cur_img[j][pic_opix_x];
03405 prd_line = prd_img[j];
03406
03407 for (i = 0; i < BLOCK_SIZE; i++)
03408 {
03409 *cost += iabs(*cur_line++ - *prd_line++);
03410 }
03411 if (*cost > min_cost)
03412 {
03413 break;
03414 }
03415 }
03416 }
03417
03418 void compute_sse4x4_cost(ImageParameters *p_Img, imgpel **cur_img, imgpel **prd_img, int pic_opix_x, int *cost, int min_cost)
03419 {
03420 int j, i;
03421 imgpel *cur_line, *prd_line;
03422
03423 for (j = 0; j < BLOCK_SIZE; j++)
03424 {
03425 cur_line = &cur_img[j][pic_opix_x];
03426 prd_line = prd_img[j];
03427
03428 for (i = 0; i < BLOCK_SIZE; i++)
03429 {
03430 *cost += iabs2(*cur_line++ - *prd_line++);
03431 }
03432 if (*cost > min_cost)
03433 {
03434 break;
03435 }
03436 }
03437 }
03438
03439 void compute_satd4x4_cost(ImageParameters *p_Img, imgpel **cur_img, imgpel **prd_img, int pic_opix_x, int *cost, int min_cost)
03440 {
03441 int j, i, *d;
03442 imgpel *cur_line, *prd_line;
03443 int diff[16];
03444
03445 d = &diff[0];
03446
03447 for (j = 0; j < BLOCK_SIZE; j++)
03448 {
03449 cur_line = &cur_img[j][pic_opix_x];
03450 prd_line = prd_img[j];
03451
03452 for (i = 0; i < BLOCK_SIZE; i++)
03453 {
03454 *d++ = *cur_line++ - *prd_line++;
03455 }
03456 }
03457 *cost += HadamardSAD4x4 (diff);
03458 }
03459
03460 static void compute_comp4x4_cost(ImageParameters *p_Img, imgpel **cur_img, imgpel **prd_img, int pic_opix_x, int *cost, int min_cost)
03461 {
03462 int j, i, *d;
03463 imgpel *cur_line, *prd_line;
03464 int diff[16];
03465
03466 d = &diff[0];
03467
03468 for (j = 0; j < BLOCK_SIZE; j++)
03469 {
03470 cur_line = &cur_img[j][pic_opix_x];
03471 prd_line = prd_img[j];
03472
03473 for (i = 0; i < BLOCK_SIZE; i++)
03474 {
03475 *d++ = *cur_line++ - *prd_line++;
03476 }
03477 }
03478 *cost += p_Img->distortion4x4 (diff, min_cost);
03479 }
03480
03481
03482 void generate_pred_error_4x4(imgpel **cur_img, imgpel **prd_img, imgpel **cur_prd,
03483 int **m7, int pic_opix_x, int block_x)
03484 {
03485 int j, i, *m7_line;
03486 imgpel *cur_line, *prd_line;
03487
03488 for (j = 0; j < BLOCK_SIZE; j++)
03489 {
03490 m7_line = &m7[j][block_x];
03491 cur_line = &cur_img[j][pic_opix_x];
03492 prd_line = prd_img[j];
03493 memcpy(&cur_prd[j][block_x], prd_line, BLOCK_SIZE * sizeof(imgpel));
03494
03495 for (i = 0; i < BLOCK_SIZE; i++)
03496 {
03497 *m7_line++ = (int) (*cur_line++ - *prd_line++);
03498 }
03499 }
03500 }
03501
03502 void generate_pred_error_8x8(imgpel **cur_img, imgpel **prd_img, imgpel **cur_prd,
03503 int **m7, int pic_opix_x, int block_x)
03504 {
03505 int j, i, *m7_line;
03506 imgpel *cur_line, *prd_line;
03507
03508 for (j=0; j < BLOCK_SIZE_8x8; j++)
03509 {
03510 prd_line = prd_img[j];
03511 memcpy(&cur_prd[j][block_x], prd_line, BLOCK_SIZE_8x8 * sizeof(imgpel));
03512 cur_line = &cur_img[j][pic_opix_x];
03513 m7_line = &m7[j][block_x];
03514 for (i = 0; i < BLOCK_SIZE_8x8; i++)
03515 {
03516 *m7_line++ = (int) (*cur_line++ - *prd_line++);
03517 }
03518 }
03519 }
03520
03521
03522 void update_qp_cbp_tmp(Macroblock *currMB, int cbp)
03523 {
03524 if (((cbp!=0 || currMB->best_mode==I16MB) && (currMB->best_mode!=IPCM) ))
03525 currMB->prev_cbp = 1;
03526 else if ((cbp==0) || (currMB->best_mode==IPCM))
03527 {
03528 currMB->prev_cbp = 0;
03529 currMB->qp = currMB->prev_qp;
03530 currMB->p_Img->qp = currMB->qp;
03531 update_qp(currMB);
03532 }
03533 }
03534
03535
03536
03537
03538
03539
03540
03541
03542 void update_qp_cbp(Macroblock *currMB)
03543 {
03544 ImageParameters *p_Img = currMB->p_Img;
03545 InputParameters *p_Inp = currMB->p_Inp;
03546
03547
03548 if ((currMB->cbp!=0 || currMB->best_mode == I16MB) && (currMB->best_mode != IPCM))
03549 currMB->prev_cbp = 1;
03550 else
03551 {
03552 currMB->prev_cbp = 0;
03553 currMB->qp = currMB->prev_qp;
03554 p_Img->qp = currMB->qp;
03555 update_qp(currMB);
03556 }
03557
03558 if (p_Inp->MbInterlace)
03559 {
03560 Slice *currSlice = currMB->p_slice;
03561
03562 currSlice->rddata->qp = currMB->qp;
03563 currSlice->rddata->prev_cbp = currMB->prev_cbp;
03564 }
03565 }
03566
03567
03568
03569
03570
03571
03572 void copy_rdopt_data (Macroblock *currMB)
03573 {
03574 Slice *currSlice = currMB->p_slice;
03575 ImageParameters *p_Img = currMB->p_Img;
03576 PicMotionParams *motion = &p_Img->enc_picture->motion;
03577 int i, j;
03578 RD_DATA *rdopt = currSlice->rddata;
03579
03580 int mode;
03581 short b8mode, b8pdir;
03582 int block_y;
03583
03584 int list_offset = currMB->list_offset;
03585
03586 mode = rdopt->mode;
03587 currMB->mb_type = rdopt->mb_type;
03588 currMB->cbp = rdopt->cbp;
03589 currMB->cbp_blk = rdopt->cbp_blk;
03590 currMB->i16offset = rdopt->i16offset;
03591
03592 currMB->prev_qp = rdopt->prev_qp;
03593 currMB->prev_dqp = rdopt->prev_dqp;
03594 currMB->prev_cbp = rdopt->prev_cbp;
03595 currMB->qp = rdopt->qp;
03596 update_qp (currMB);
03597
03598 currMB->c_ipred_mode = rdopt->c_ipred_mode;
03599
03600 memcpy(currSlice->cofAC[0][0][0],rdopt->cofAC[0][0][0], (4 + p_Img->num_blk8x8_uv) * 4 * 2 * 65 * sizeof(int));
03601 memcpy(currSlice->cofDC[0][0],rdopt->cofDC[0][0], 3 * 2 * 18 * sizeof(int));
03602
03603 for (j = 0; j < BLOCK_MULTIPLE; j++)
03604 {
03605 block_y = currMB->block_y + j;
03606 memcpy(&motion->ref_idx[LIST_0][block_y][currMB->block_x], rdopt->refar[LIST_0][j], BLOCK_MULTIPLE * sizeof(char));
03607 for (i = 0; i < BLOCK_MULTIPLE; i++)
03608 motion->ref_pic_id [LIST_0][block_y][currMB->block_x + i] =
03609 p_Img->enc_picture->ref_pic_num[LIST_0 + list_offset][(short)motion->ref_idx[LIST_0][block_y][currMB->block_x + i]];
03610 }
03611
03612 if (currSlice->slice_type == B_SLICE)
03613 {
03614 for (j = 0; j < BLOCK_MULTIPLE; j++)
03615 {
03616 block_y = currMB->block_y + j;
03617 memcpy(&motion->ref_idx[LIST_1][block_y][currMB->block_x], rdopt->refar[LIST_1][j], BLOCK_MULTIPLE * sizeof(char));
03618 for (i = 0; i < BLOCK_MULTIPLE; i++)
03619 motion->ref_pic_id [LIST_1][block_y][currMB->block_x + i] =
03620 p_Img->enc_picture->ref_pic_num[LIST_1 + list_offset][(short)motion->ref_idx[LIST_1][block_y][currMB->block_x + i]];
03621 }
03622 }
03623
03624
03625
03626 copy_image_data_16x16(&p_Img->enc_picture->imgY[currMB->pix_y], rdopt->rec_mb[0], currMB->pix_x, 0);
03627
03628 if (p_Img->yuv_format != YUV400)
03629 {
03630 copy_image_data(&p_Img->enc_picture->imgUV[0][currMB->pix_c_y], rdopt->rec_mb[1], currMB->pix_c_x, 0, p_Img->mb_cr_size_x, p_Img->mb_cr_size_y);
03631 copy_image_data(&p_Img->enc_picture->imgUV[1][currMB->pix_c_y], rdopt->rec_mb[2], currMB->pix_c_x, 0, p_Img->mb_cr_size_x, p_Img->mb_cr_size_y);
03632 }
03633
03634
03635 memcpy(currMB->b8x8, rdopt->b8x8, BLOCK_MULTIPLE * sizeof(Info8x8));
03636
03637 currMB->luma_transform_size_8x8_flag = rdopt->luma_transform_size_8x8_flag;
03638
03639
03640 if (mode == P8x8)
03641 {
03642 memcpy(currMB->intra_pred_modes,rdopt->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
03643 for (j = currMB->block_y; j < currMB->block_y + BLOCK_MULTIPLE; j++)
03644 memcpy(&p_Img->ipredmode[j][currMB->block_x],&rdopt->ipredmode[j][currMB->block_x], BLOCK_MULTIPLE * sizeof(char));
03645 }
03646 else if (mode != I4MB && mode != I8MB)
03647 {
03648 memset(currMB->intra_pred_modes,DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));
03649 for (j = currMB->block_y; j < currMB->block_y + BLOCK_MULTIPLE; j++)
03650 memset(&p_Img->ipredmode[j][currMB->block_x],DC_PRED, BLOCK_MULTIPLE * sizeof(char));
03651 }
03652 else if (mode == I4MB || mode == I8MB)
03653 {
03654 memcpy(currMB->intra_pred_modes,rdopt->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
03655 memcpy(currMB->intra_pred_modes8x8,rdopt->intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
03656 for (j = currMB->block_y; j < currMB->block_y + BLOCK_MULTIPLE; j++)
03657 {
03658 memcpy(&p_Img->ipredmode[j][currMB->block_x],&rdopt->ipredmode[j][currMB->block_x], BLOCK_MULTIPLE * sizeof(char));
03659 }
03660 }
03661
03662 if (currSlice->MbaffFrameFlag || (currSlice->UseRDOQuant && currSlice->RDOQ_QP_Num > 1))
03663 {
03664
03665 if (currSlice->slice_type != I_SLICE && currSlice->slice_type != SI_SLICE)
03666 copy_motion_vectors_MB (currSlice, rdopt);
03667
03668 if (!IS_INTRA(currMB))
03669 {
03670 currMB->b8x8[0].bipred = 0;
03671 currMB->b8x8[1].bipred = 0;
03672 currMB->b8x8[2].bipred = 0;
03673 currMB->b8x8[3].bipred = 0;
03674
03675 for (j = 0; j < 4; j++)
03676 for (i = 0; i < 4; i++)
03677 {
03678 b8mode = currMB->b8x8[(i >> 1) + 2 * (j >> 1)].mode;
03679 b8pdir = currMB->b8x8[(i >> 1) + 2 * (j >> 1)].pdir;
03680
03681 if (b8pdir!=1)
03682 {
03683 motion->mv[LIST_0][j+currMB->block_y][i+currMB->block_x][0] = rdopt->all_mv[LIST_0][(short)rdopt->refar[LIST_0][j][i]][b8mode][j][i][0];
03684 motion->mv[LIST_0][j+currMB->block_y][i+currMB->block_x][1] = rdopt->all_mv[LIST_0][(short)rdopt->refar[LIST_0][j][i]][b8mode][j][i][1];
03685 }
03686 else
03687 {
03688 motion->mv[LIST_0][j+currMB->block_y][i+currMB->block_x][0] = 0;
03689 motion->mv[LIST_0][j+currMB->block_y][i+currMB->block_x][1] = 0;
03690 }
03691 if (currSlice->slice_type == B_SLICE)
03692 {
03693 if (b8pdir!=0)
03694 {
03695 motion->mv[LIST_1][j+currMB->block_y][i+currMB->block_x][0] = rdopt->all_mv[LIST_1][(short)rdopt->refar[LIST_1][j][i]][b8mode][j][i][0];
03696 motion->mv[LIST_1][j+currMB->block_y][i+currMB->block_x][1] = rdopt->all_mv[LIST_1][(short)rdopt->refar[LIST_1][j][i]][b8mode][j][i][1];
03697 }
03698 else
03699 {
03700 motion->mv[LIST_1][j+currMB->block_y][i+currMB->block_x][0] = 0;
03701 motion->mv[LIST_1][j+currMB->block_y][i+currMB->block_x][1] = 0;
03702 }
03703 }
03704 }
03705 }
03706 else
03707 {
03708 for (j = 0; j < 4; j++)
03709 memset(motion->mv[LIST_0][j+currMB->block_y][currMB->block_x], 0, 2 * BLOCK_MULTIPLE * sizeof(short));
03710 if (currSlice->slice_type == B_SLICE)
03711 {
03712 for (j = 0; j < 4; j++)
03713 memset(motion->mv[LIST_1][j+currMB->block_y][currMB->block_x], 0, 2 * BLOCK_MULTIPLE * sizeof(short));
03714 }
03715 }
03716 }
03717 }
03718
03719
03720