JM模型中8x8块的色度分量帧内预测的代码 先保存下来 一边读一边注释
- void IntraChromaPrediction8x8 (int *mb_up, int *mb_left, int*mb_up_left)
- {
- Macroblock *currMB = &img->mb_data[img->current_mb_nr];
- int s, s0, s1, s2, s3, i, j, k;
- pel_t** image;
- int block_x, block_y;
- int mb_nr = img->current_mb_nr;
- int mb_available_up;
- int mb_available_left[2];
- int mb_available_up_left;
- int ih,iv;
- int ib,ic,iaa;
- int uv;
- int hline[8], vline[9];
- int mode;
- int best_mode = DC_PRED_8; //just an initilaization here, should always be overwritten
- int cost;
- int min_cost;
- int diff[16];
- PixelPos up; //!< pixel position p(0,-1)
- PixelPos left[9]; //!< pixel positions p(-1, -1..8)
- for (i=0;i<9;i++)
- {
- getNeighbour(mb_nr, -1 , i-1 , 0, &left[i]);
- }
- getNeighbour(mb_nr, 0 , -1 , 0, &up);
- mb_available_up = up.available;
- mb_available_up_left = left[0].available;
- mb_available_left[0] = mb_available_left[1] = left[1].available;
- if(input->UseConstrainedIntraPred)
- {
- mb_available_up = up.available ? img->intra_block[up.mb_addr] : 0;
- for (i=1, mb_available_left[0]=1; i<5;i++)
- mb_available_left[0] &= left[i].available ? img->intra_block[left[i].mb_addr]: 0;
- for (i=5, mb_available_left[1]=1; i<9;i++)
- mb_available_left[1] &= left[i].available ? img->intra_block[left[i].mb_addr]: 0;
- mb_available_up_left = left[0].available ? img->intra_block[left[0].mb_addr]: 0;
- }
- if (mb_up)
- *mb_up = mb_available_up;
- if (mb_left)
- *mb_left = mb_available_left[0] && mb_available_left[1];
- if( mb_up_left )
- *mb_up_left = mb_available_up_left;
- // compute all chroma intra prediction modes for both U and V
- for (uv=0; uv<2; uv++)
- {
- image = enc_picture->imgUV[uv];
- // DC prediction
- for (block_y=0; block_y<8; block_y+=4)
- for (block_x=0; block_x<8; block_x+=4)
- {
- s=128;
- s0=s1=s2=s3=0;
- //===== get prediction value =====
- switch ((block_y>>1) + (block_x>>2))
- {
- case 0: //===== TOP LEFT =====
- if (mb_available_up) for (i=0;i<4;i++) s0 += image[up.pos_y][up.pos_x + i];
- if (mb_available_left[0]) for (i=1;i<5;i++) s2 += image[left[i].pos_y][left[i].pos_x];
- if (mb_available_up && mb_available_left[0]) s = (s0+s2+4) >> 3;
- else if (mb_available_up) s = (s0 +2) >> 2;
- else if (mb_available_left[0]) s = (s2 +2) >> 2;
- break;
- case 1: //===== TOP RIGHT =====
- if (mb_available_up) for (i=4;i<8;i++) s1 += image[up.pos_y][up.pos_x + i];
- else if (mb_available_left[0]) for (i=1;i<5;i++) s2 += image[left[i].pos_y][left[i].pos_x];
- if (mb_available_up) s = (s1 +2) >> 2;
- else if (mb_available_left[0]) s = (s2 +2) >> 2;
- break;
- case 2: //===== BOTTOM LEFT =====
- if (mb_available_left[1]) for (i=5;i<9;i++) s3 += image[left[i].pos_y][left[i].pos_x];
- else if (mb_available_up) for (i=0;i<4;i++) s0 += image[up.pos_y][up.pos_x + i];
- if (mb_available_left[1]) s = (s3 +2) >> 2;
- else if (mb_available_up) s = (s0 +2) >> 2;
- break;
- case 3: //===== BOTTOM RIGHT =====
- if (mb_available_up) for (i=4;i<8;i++) s1 += image[up.pos_y][up.pos_x + i];
- if (mb_available_left[1]) for (i=5;i<9;i++) s3 += image[left[i].pos_y][left[i].pos_x];
- if (mb_available_up && mb_available_left[1]) s = (s1+s3+4) >> 3;
- else if (mb_available_up) s = (s1 +2) >> 2;
- else if (mb_available_left[1]) s = (s3 +2) >> 2;
- break;
- }
- //===== prediction =====
- for (j=block_y; j<block_y+4; j++)
- for (i=block_x; i<block_x+4; i++)
- {
- img->mprr_c[uv][DC_PRED_8][i][j] = s;
- }
- }
- // vertical prediction
- if (mb_available_up)
- {
- for (i=0; i<8; i++)
- hline[i] = image[up.pos_y][up.pos_x + i];
- for (i=0; i<8; i++)
- for (j=0; j<8; j++)
- img->mprr_c[uv][VERT_PRED_8][i][j] = hline[i];
- }
- // horizontal prediction
- if (mb_available_left[0] && mb_available_left[1])
- {
- for (i=1; i<9; i++)
- vline[i] = image[left[i].pos_y][left[i].pos_x];
- for (i=0; i<8; i++)
- for (j=0; j<8; j++)
- img->mprr_c[uv][HOR_PRED_8][i][j] = vline[j+1];
- }
- // plane prediction
- if (mb_available_left[0] && mb_available_left[1] && mb_available_up && mb_available_up_left)
- {
- ih = 4*(hline[7] - image[left[0].pos_y][left[0].pos_x]);
- iv = 4*(vline[7+1] - image[left[0].pos_y][left[0].pos_x]);
- for (i=1;i<4;i++)
- {
- ih += i*(hline[3+i] - hline[3-i]);
- iv += i*(vline[3+i+1] - vline[3-i+1]);
- }
- ib=(17*ih+16)>>5;
- ic=(17*iv+16)>>5;
- iaa=16*(hline[7]+vline[7+1]);
- for (j=0; j<8; j++)
- for (i=0; i<8; i++)
- img->mprr_c[uv][PLANE_8][i][j]=max(0,min(255,(iaa+(i-3)*ib +(j-3)*ic + 16)/32));// store plane prediction
- }
- }
- if (!input->rdopt) // the rd-opt part does not work correctly (see encode_one_macroblock)
- { // since ipredmodes could be overwritten => encoder-decoder-mismatches
- // pick lowest cost prediction mode
- min_cost = 1<<20;
- for (i=0;i<8;i++)
- {
- getNeighbour(mb_nr, 0 , i , 0, &left[i]);
- }
- for (mode=DC_PRED_8; mode<=PLANE_8; mode++)
- {
- if ((mode==VERT_PRED_8 && !mb_available_up) ||
- (mode==HOR_PRED_8 && (!mb_available_left[0] || !mb_available_left[1])) ||
- (mode==PLANE_8 && (!mb_available_left[0] || !mb_available_left[1] || !mb_available_up || !mb_available_up_left)))
- continue;
- cost = 0;
- for (uv=0; uv<2; uv++)
- {
- image = imgUV_org[uv];
- for (block_y=0; block_y<8; block_y+=4)
- for (block_x=0; block_x<8; block_x+=4)
- {
- for (k=0,j=block_y; j<block_y+4; j++)
- for (i=block_x; i<block_x+4; i++,k++)
- {
- diff[k] = image[left[j].pos_y][left[j].pos_x+i] - img->mprr_c[uv][mode][i][j];
- }
- cost += SATD(diff, input->hadamard);
- }
- }
- if (cost < min_cost)
- {
- best_mode = mode;
- min_cost = cost;
- }
- }
- currMB->c_ipred_mode = best_mode;
- }
- }