00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "contributors.h"
00015 #include "global.h"
00016 #include "mc_prediction.h"
00017 #include "md_common.h"
00018 #include "rdopt.h"
00019 #include "macroblock.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 int luma_residual_coding_p444_16x16 (Macroblock* currMB,
00032 int block8x8,
00033 short p_dir,
00034 int list_mode[2],
00035 char *ref_idx)
00036 {
00037
00038 int *cbp = &(currMB->cbp);
00039 int64 *cbp_blk = &(currMB->cbp_blk);
00040 Slice *currSlice = currMB->p_slice;
00041 ImageParameters *p_Img = currMB->p_Img;
00042 int i, j, nonzero = 0, cbp_blk_mask;
00043 int coeff_cost = 0;
00044 int mb_y = (block8x8 >> 1) << 3;
00045 int mb_x = (block8x8 & 0x01) << 3;
00046 int cbp_mask = 1 << block8x8;
00047
00048 int skipped = (list_mode[0] == 0 && list_mode[1] == 0 && (currSlice->slice_type != B_SLICE));
00049 ColorPlane uv;
00050
00051 char bipred_me = currMB->b8x8[block8x8].bipred;
00052 currSlice->coeff_cost_cr[1] = currSlice->coeff_cost_cr[2] = 0;
00053
00054
00055
00056
00057 luma_prediction (currMB, mb_x, mb_y, 8, 8, p_dir, list_mode, ref_idx, bipred_me);
00058
00059
00060 compute_residue (&p_Img->pCurImg[currMB->opix_y + mb_y], &currSlice->mb_pred[0][mb_y], &currSlice->mb_ores[0][mb_y], mb_x, currMB->pix_x + mb_x, 8, 8);
00061
00062 for (uv = PLANE_U; uv <= PLANE_V; ++uv)
00063 {
00064 select_plane(p_Img, uv);
00065 chroma_prediction (currMB, uv - 1, mb_x, mb_y, 8, 8, p_dir, list_mode[0], list_mode[1], ref_idx[0], ref_idx[1], bipred_me);
00066
00067
00068 compute_residue(&p_Img->pImgOrg[uv][currMB->opix_y + mb_y], &currSlice->mb_pred[uv][mb_y], &currSlice->mb_ores[uv][mb_y], mb_x, currMB->pix_x + mb_x, 8, 8);
00069 }
00070 select_plane(p_Img, PLANE_Y);
00071
00072
00073 if(!currMB->luma_transform_size_8x8_flag)
00074 {
00075
00076 if (!skipped && ( (currSlice->NoResidueDirect != 1) || (currMB->qp_scaled[0] == 0 && p_Img->lossless_qpprime_flag == 1) ))
00077 {
00078 int block_y, block_x;
00079
00080 for (block_y=mb_y; block_y<mb_y + 8; block_y += 4)
00081 {
00082 for (block_x=mb_x; block_x<mb_x + 8; block_x += 4)
00083 {
00084
00085 nonzero = currMB->trans_4x4 (currMB, PLANE_Y, block_x, block_y, &coeff_cost, 0);
00086
00087 if (nonzero)
00088 {
00089 cbp_blk_mask = (block_x >> 2) + block_y;
00090 (*cbp_blk) |= (int64) 1 << cbp_blk_mask;
00091 (*cbp) |= cbp_mask;
00092 }
00093
00094 if (currSlice->slice_type != SP_SLICE)
00095 {
00096 for (uv = PLANE_U; uv <= PLANE_V; ++uv)
00097 {
00098 select_plane(p_Img, (ColorPlane) uv);
00099 nonzero = currMB->trans_4x4( currMB, (ColorPlane) uv, block_x, block_y, &currSlice->coeff_cost_cr[uv], 0);
00100 if (nonzero)
00101 {
00102 cbp_blk_mask = (block_x >> 2) + block_y;
00103 (currSlice->cur_cbp_blk[uv]) |= (int64) 1 << cbp_blk_mask;
00104 (currSlice->cmp_cbp[uv]) |= cbp_mask;
00105 }
00106 }
00107 select_plane(p_Img, PLANE_Y);
00108 }
00109 else
00110 {
00111 assert(currSlice->slice_type == SP_SLICE);
00112 }
00113 }
00114 }
00115 }
00116 }
00117 else
00118 {
00119 if (currSlice->NoResidueDirect != 1 && !skipped)
00120 {
00121 if (currSlice->slice_type != SP_SLICE)
00122 nonzero = currMB->trans_8x8 (currMB, PLANE_Y, block8x8, &coeff_cost, 0);
00123
00124 if (nonzero)
00125 {
00126 (*cbp_blk) |= 51 << (4*block8x8 - 2*(block8x8 & 0x01));
00127 (*cbp) |= cbp_mask;
00128 }
00129
00130 if (currSlice->slice_type != SP_SLICE)
00131 {
00132 for (uv = PLANE_U; uv <= PLANE_V; ++uv)
00133 {
00134 select_plane(p_Img, (ColorPlane) uv);
00135 nonzero = currMB->trans_8x8( currMB, (ColorPlane) uv, block8x8, &currSlice->coeff_cost_cr[uv], 0);
00136 if (nonzero)
00137 {
00138 (currSlice->cur_cbp_blk[uv]) |= 51 << (4*block8x8-2*(block8x8 & 0x01));
00139 (currSlice->cmp_cbp[uv]) |= cbp_mask;
00140 }
00141 }
00142 select_plane(p_Img, PLANE_Y);
00143 }
00144 }
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 if (currSlice->NoResidueDirect != 1 && !skipped && coeff_cost <= _LUMA_COEFF_COST_ &&
00168 ((currMB->qp_scaled[0])!=0 || p_Img->lossless_qpprime_flag==0)&&
00169 !(currSlice->slice_type == SP_SLICE && (p_Img->si_frame_indicator == TRUE || p_Img->sp2_frame_indicator == TRUE )))
00170
00171 {
00172 coeff_cost = 0;
00173 (*cbp) &= (63 - cbp_mask);
00174 (*cbp_blk) &= ~(51 << (4 * block8x8 - 2 * (block8x8 & 0x01)));
00175
00176 memset( currSlice->cofAC[block8x8][0][0], 0, 4 * 2 * 65 * sizeof(int));
00177
00178 copy_image_data_8x8(&p_Img->enc_picture->imgY[currMB->pix_y + mb_y], &currSlice->mb_pred[0][mb_y], currMB->pix_x + mb_x, mb_x);
00179
00180 if (currSlice->slice_type == SP_SLICE)
00181 {
00182 for (i = mb_x; i < mb_x + BLOCK_SIZE_8x8; i += BLOCK_SIZE)
00183 for (j = mb_y; j < mb_y + BLOCK_SIZE_8x8; j += BLOCK_SIZE)
00184 copyblock_sp(currMB, PLANE_Y, i, j);
00185 }
00186 }
00187
00188 for (uv = PLANE_U; uv <= PLANE_V; ++uv)
00189 {
00190 if (currSlice->NoResidueDirect != 1 && !skipped && currSlice->coeff_cost_cr[uv] <= _LUMA_COEFF_COST_ &&
00191 (currMB->qp_scaled[uv]!=0 || p_Img->lossless_qpprime_flag==0))
00192 {
00193 currSlice->coeff_cost_cr[uv] = 0;
00194 currSlice->cmp_cbp[uv] &= (63 - cbp_mask);
00195 currSlice->cur_cbp_blk[uv] &= ~(51 << (4*block8x8-2*(block8x8 & 0x01)));
00196
00197 memset( currSlice->cofAC[block8x8 + 4 * uv][0][0], 0, 4 * 2 * 65 * sizeof(int));
00198
00199 copy_image_data_8x8(&p_Img->enc_picture->imgUV[uv - 1][currMB->pix_y + mb_y], &currSlice->mb_pred[uv][mb_y], currMB->pix_x + mb_x, mb_x);
00200 }
00201 }
00202
00203 return coeff_cost;
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 int luma_residual_coding_p444_8x8 (Macroblock* currMB,
00217 int *cbp,
00218 int64 *cbp_blk,
00219 int block8x8,
00220 short p_dir,
00221 int list_mode[2],
00222 char *ref_idx)
00223 {
00224 Slice *currSlice = currMB->p_slice;
00225 ImageParameters *p_Img = currSlice->p_Img;
00226 int block_y, block_x, pic_pix_x, i, j, nonzero = 0, cbp_blk_mask;
00227 int coeff_cost = 0;
00228 int mb_y = (block8x8 >> 1) << 3;
00229 int mb_x = (block8x8 & 0x01) << 3;
00230 int cbp_mask = 1 << block8x8;
00231 int bxx, byy;
00232 int skipped = (list_mode[0] == 0 && list_mode[1] == 0 && (currSlice->slice_type != B_SLICE));
00233 ColorPlane uv;
00234
00235 char bipred_me = currMB->b8x8[block8x8].bipred;
00236 currSlice->coeff_cost_cr[1] = currSlice->coeff_cost_cr[2] = 0;
00237
00238
00239
00240
00241 if(!currMB->luma_transform_size_8x8_flag)
00242 {
00243 if (((p_dir == 0 || p_dir == 2 )&& list_mode[0] < 5) || ((p_dir == 1 || p_dir == 2 ) && list_mode[1] < 5))
00244 {
00245 luma_prediction (currMB, mb_x, mb_y, 8, 8, p_dir, list_mode, ref_idx, bipred_me);
00246
00247
00248 compute_residue (&p_Img->pCurImg[currMB->opix_y + mb_y], &currSlice->mb_pred[0][mb_y], &currSlice->mb_ores[0][mb_y], mb_x, currMB->pix_x + mb_x, 8, 8);
00249 }
00250
00251 for (byy=0, block_y=mb_y; block_y<mb_y+8; byy+=4, block_y+=4)
00252 {
00253 for (bxx=0, block_x=mb_x; block_x<mb_x+8; bxx+=4, block_x+=4)
00254 {
00255 pic_pix_x = currMB->pix_x + block_x;
00256 cbp_blk_mask = (block_x >> 2) + block_y;
00257
00258
00259 if (!(((p_dir == 0 || p_dir == 2 )&& list_mode[0] < 5) || ((p_dir == 1 || p_dir == 2 ) && list_mode[1] < 5)))
00260 {
00261 luma_prediction (currMB, block_x, block_y, 4, 4, p_dir, list_mode, ref_idx, bipred_me);
00262
00263
00264 compute_residue(&p_Img->pCurImg[currMB->opix_y + block_y], &currSlice->mb_pred[0][block_y], &currSlice->mb_ores[0][block_y], block_x, pic_pix_x, 4, 4);
00265 }
00266
00267 for (uv = PLANE_U; uv <= PLANE_V; ++uv)
00268 {
00269 select_plane(p_Img, uv);
00270 chroma_prediction (currMB, uv - 1, block_x, block_y, 4, 4, p_dir, list_mode[0], list_mode[1], ref_idx[0], ref_idx[1], bipred_me);
00271
00272
00273 compute_residue(&p_Img->pImgOrg[uv][currMB->opix_y + block_y], &currSlice->mb_pred[uv][block_y], &currSlice->mb_ores[uv][block_y], block_x, pic_pix_x, 4, 4);
00274 }
00275 select_plane(p_Img, PLANE_Y);
00276
00277
00278 if (!skipped && ( (currSlice->NoResidueDirect != 1) || (currMB->qp_scaled[0] == 0 && p_Img->lossless_qpprime_flag == 1) ))
00279 {
00280
00281 nonzero = currMB->trans_4x4 (currMB, PLANE_Y, block_x, block_y, &coeff_cost, 0);
00282
00283 if (nonzero)
00284 {
00285 (*cbp_blk) |= (int64)1 << cbp_blk_mask;
00286 (*cbp) |= cbp_mask;
00287 }
00288
00289 if (currSlice->slice_type != SP_SLICE)
00290 {
00291 for (uv = PLANE_U; uv <= PLANE_V; ++uv)
00292 {
00293 select_plane(p_Img, (ColorPlane) uv);
00294 nonzero = currMB->trans_4x4( currMB, (ColorPlane) uv, block_x, block_y, &currSlice->coeff_cost_cr[uv], 0);
00295 if (nonzero)
00296 {
00297 (currSlice->cur_cbp_blk[uv]) |= (int64) 1 << cbp_blk_mask;
00298 (currSlice->cmp_cbp[uv]) |= cbp_mask;
00299 }
00300 }
00301 select_plane(p_Img, PLANE_Y);
00302 }
00303 else
00304 {
00305 assert(currSlice->slice_type == SP_SLICE);
00306 }
00307 }
00308 }
00309 }
00310 }
00311 else
00312 {
00313 block_y = mb_y;
00314 block_x = mb_x;
00315
00316 pic_pix_x = currMB->pix_x + block_x;
00317
00318 cbp_blk_mask = (block_x>>2) + block_y;
00319
00320
00321 luma_prediction (currMB, block_x, block_y, 8, 8, p_dir, list_mode, ref_idx, bipred_me);
00322
00323
00324 compute_residue (&p_Img->pCurImg[currMB->opix_y + block_y], &currSlice->mb_pred[0][block_y], &currSlice->mb_ores[0][block_y], block_x, pic_pix_x, 8, 8);
00325
00326 for (uv = PLANE_U; uv <= PLANE_V; ++uv)
00327 {
00328 select_plane(p_Img, (ColorPlane) uv);
00329 chroma_prediction (currMB, uv - 1, block_x, block_y, 8, 8, p_dir, list_mode[0], list_mode[1], ref_idx[0], ref_idx[1], bipred_me);
00330
00331
00332 compute_residue (&p_Img->pImgOrg[uv][currMB->opix_y + block_y], &currSlice->mb_pred[uv][block_y], &currSlice->mb_ores[uv][block_y], block_x, pic_pix_x, 8, 8);
00333 }
00334 select_plane(p_Img, PLANE_Y);
00335
00336 if (currSlice->NoResidueDirect != 1 && !skipped)
00337 {
00338 if (currSlice->slice_type != SP_SLICE)
00339 nonzero = currMB->trans_8x8 (currMB, PLANE_Y, block8x8, &coeff_cost, 0);
00340
00341 if (nonzero)
00342 {
00343 (*cbp_blk) |= 51 << (4*block8x8 - 2*(block8x8 & 0x01));
00344 (*cbp) |= cbp_mask;
00345 }
00346
00347 if (currSlice->slice_type != SP_SLICE)
00348 {
00349 for (uv = PLANE_U; uv <= PLANE_V; ++uv)
00350 {
00351 select_plane(p_Img, (ColorPlane) uv);
00352 nonzero = currMB->trans_8x8( currMB, (ColorPlane) uv, block8x8, &currSlice->coeff_cost_cr[uv], 0);
00353 if (nonzero)
00354 {
00355 (currSlice->cur_cbp_blk[uv]) |= 51 << (4*block8x8-2*(block8x8 & 0x01));
00356 (currSlice->cmp_cbp[uv]) |= cbp_mask;
00357 }
00358 }
00359 select_plane(p_Img, PLANE_Y);
00360 }
00361 }
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 if (currSlice->NoResidueDirect != 1 && !skipped && coeff_cost <= _LUMA_COEFF_COST_ &&
00385 ((currMB->qp_scaled[0])!=0 || p_Img->lossless_qpprime_flag==0)&&
00386 !(currSlice->slice_type == SP_SLICE && (p_Img->si_frame_indicator == TRUE || p_Img->sp2_frame_indicator == TRUE )))
00387
00388 {
00389 coeff_cost = 0;
00390 (*cbp) &= (63 - cbp_mask);
00391 (*cbp_blk) &= ~(51 << (4 * block8x8 - 2 * (block8x8 & 0x01)));
00392
00393 memset( currSlice->cofAC[block8x8][0][0], 0, 4 * 2 * 65 * sizeof(int));
00394
00395 copy_image_data_8x8(&p_Img->enc_picture->imgY[currMB->pix_y + mb_y], &currSlice->mb_pred[0][mb_y], currMB->pix_x + mb_x, mb_x);
00396
00397 if (currSlice->slice_type == SP_SLICE)
00398 {
00399 for (i=mb_x; i < mb_x + BLOCK_SIZE_8x8; i+=BLOCK_SIZE)
00400 for (j=mb_y; j < mb_y + BLOCK_SIZE_8x8; j+=BLOCK_SIZE)
00401 copyblock_sp(currMB, PLANE_Y, i, j);
00402 }
00403 }
00404
00405 for (uv = PLANE_U; uv <= PLANE_V; ++uv)
00406 {
00407 if (currSlice->NoResidueDirect != 1 && !skipped && currSlice->coeff_cost_cr[uv] <= _LUMA_COEFF_COST_ &&
00408 (currMB->qp_scaled[uv]!=0 || p_Img->lossless_qpprime_flag==0))
00409 {
00410 currSlice->coeff_cost_cr[uv] = 0;
00411 currSlice->cmp_cbp[uv] &= (63 - cbp_mask);
00412 currSlice->cur_cbp_blk[uv] &= ~(51 << (4*block8x8-2*(block8x8 & 0x01)));
00413
00414 memset( currSlice->cofAC[block8x8 + 4 * uv][0][0], 0, 4 * 2 * 65 * sizeof(int));
00415
00416 copy_image_data_8x8(&p_Img->enc_picture->imgUV[uv - 1][currMB->pix_y + mb_y], &currSlice->mb_pred[uv][mb_y], currMB->pix_x + mb_x, mb_x);
00417 }
00418 }
00419
00420 return coeff_cost;
00421 }
00422
00423
00424
00425
00426
00427
00428
00429
00430 void luma_residual_coding_p444 (Macroblock *currMB)
00431 {
00432 Slice *currSlice = currMB->p_slice;
00433 ImageParameters *p_Img = currMB->p_Img;
00434
00435 int uv, i,j,block8x8,b8_x,b8_y;
00436 int list_mode[2];
00437 char list_ref_idx[2];
00438 short p_dir;
00439 int sum_cnt_nonz[3] = {0 ,0, 0};
00440 int is_skip = currSlice->slice_type == P_SLICE && currMB->mb_type == PSKIP;
00441
00442 currMB->cbp = 0;
00443 currMB->cbp_blk = 0;
00444 currSlice->cmp_cbp[1] = currSlice->cmp_cbp[2] = 0;
00445 currSlice->cur_cbp_blk[1] = currSlice->cur_cbp_blk[2] = 0;
00446
00447 if (is_skip || currMB->mb_type == 1)
00448 {
00449
00450 for (block8x8=0; block8x8<4; ++block8x8)
00451 {
00452 currSlice->set_modes_and_reframe (currMB, block8x8, &p_dir, list_mode, list_ref_idx);
00453
00454 sum_cnt_nonz[0] += luma_residual_coding_p444_16x16 (currMB, block8x8, p_dir, list_mode, list_ref_idx);
00455 sum_cnt_nonz[1] += currSlice->coeff_cost_cr[1];
00456 sum_cnt_nonz[2] += currSlice->coeff_cost_cr[2];
00457 }
00458 }
00459 else
00460 {
00461 for (block8x8=0; block8x8<4; ++block8x8)
00462 {
00463 currSlice->set_modes_and_reframe (currMB, block8x8, &p_dir, list_mode, list_ref_idx);
00464
00465 sum_cnt_nonz[0] += luma_residual_coding_p444_8x8 (currMB, &(currMB->cbp), &(currMB->cbp_blk), block8x8, p_dir, list_mode, list_ref_idx);
00466
00467 if(p_Img->P444_joined)
00468 {
00469 sum_cnt_nonz[1] += currSlice->coeff_cost_cr[1];
00470 sum_cnt_nonz[2] += currSlice->coeff_cost_cr[2];
00471 }
00472 }
00473 }
00474
00475 if ((is_skip ||
00476 (sum_cnt_nonz[0] <= _LUMA_MB_COEFF_COST_ && ((currMB->qp_scaled[0])!=0 || p_Img->lossless_qpprime_flag==0))) &&
00477 !(currSlice->slice_type == SP_SLICE && (p_Img->si_frame_indicator == TRUE || p_Img->sp2_frame_indicator == TRUE)))
00478
00479 {
00480 currMB->cbp &= 0xfffff0 ;
00481 currMB->cbp_blk &= 0xff0000 ;
00482
00483 copy_image_data_16x16(&p_Img->enc_picture->imgY[currMB->pix_y], currSlice->mb_pred[0], currMB->pix_x, 0);
00484
00485 memset( currSlice->cofAC[0][0][0], 0, 2080 * sizeof(int));
00486
00487 if (currSlice->slice_type == SP_SLICE)
00488 {
00489 for(block8x8=0;block8x8<4; ++block8x8)
00490 {
00491 b8_x=(block8x8&1)<<3;
00492 b8_y=(block8x8&2)<<2;
00493 for (i = b8_x; i < b8_x + BLOCK_SIZE_8x8; i += 4)
00494 for (j = b8_y; j < b8_y + BLOCK_SIZE_8x8;j += 4)
00495 copyblock_sp(currMB, PLANE_Y, i, j);
00496 }
00497 }
00498 }
00499
00500 for (uv = PLANE_U; uv <= PLANE_V; ++uv)
00501 {
00502 if(is_skip || (sum_cnt_nonz[uv] <= _LUMA_MB_COEFF_COST_ &&
00503 ((currMB->qp_scaled[uv])!=0 ||p_Img->lossless_qpprime_flag==0)))
00504 {
00505 currSlice->cmp_cbp[uv] &= 0xfffff0 ;
00506 currSlice->cur_cbp_blk[uv] &= 0xff0000 ;
00507
00508 copy_image_data_16x16(&p_Img->enc_picture->p_img[uv][currMB->pix_y], currSlice->mb_pred[uv], currMB->pix_x, 0);
00509
00510 memset( currSlice->cofAC[4 * uv][0][0], 0, 2080 * sizeof(int));
00511 }
00512 currMB->cbp |= currSlice->cmp_cbp[uv];
00513 }
00514 }
00515
00516
00517