どのようにJM 8で6コードの符号化端抽出残差(簡便化のため、I 4 x 4マクロブロックのみを例にとる)
13480 ワード
JM 8にする.6コードの中であるデータを探し出して、むやみにぶつかってはいけなくて、力を使うことができなくて、H.264の流れによって探します.例えば、符号化端で画素残差を見つけるには、以下のような考え方で探すことができる.(便宜上、I 4 x 4マクロブロックのみを例として)
前に一言言います:时には同じ量に対して、いくつかの地方が多く抽出することができて、だから考え方はあまり制限しないでください、重要なのはこの量が过去にどこから来て、将来またどこへ行くかを知っています.以下の考え方は、I 4 x 4マクロブロックの残差を抽出する考え方である.(うるさい一言:すべてのタイプのマクロブロックの残差をどのように抽出するかは、次の場所だけでは不十分です)
前述したように、オリジナルのYUV画素はimgY_に格納されているorgでは、符号化側は残差を変換符号化し、encode_one_macroblockはマクロブロックを符号化するキー関数であるため、符号化側で残差を抽出するにはencode_one_macroblockが存在するファイル検索imgY_org、検索すると、本当にありますが、たくさんあります.思い出してみると、残差はどのように形成されていますか.明らかに残差の形成は必然的に減少に関連し,すなわちコードの中で「imgY_org[]-...」を探すことに関連する.このような形式のコード.探して、本当にありますが、私たちが必要とする「imgY_org[]-...」形式のコードはMode_にありますDecision_for_4 x 4 IntraBlocks関数では、encode_one_macroblockがModeを呼び出しましたDecision_for_4 x 4 IntraBlocks関数
残差を抽出するコードは以下の通りである(残差を抽出するために使用されるコードは一部のみであり、I 4 x 4マクロブロックを例に挙げる).
結果:
**************************** 251 254 254 253 228 205 213 185 197 173 185 136 177 189 198 160 **************************** 238 238 238 238 205 205 205 205 167 167 167 167 160 160 160 160 **************************** 13 16 16 15 23 0 8 -20 30 6 18 -31 17 29 38 0
3つの行列はそれぞれ第1フレームの第1マクロブロックの第2の4*4ブロックの元の値、予測値、残差に対応し、上記の結果の正確性を検証するためにH.264 visaで分析することができ、結果は以下の通りである.
元の値は、(注意:H.264 visaでも元のYUVデータを読み取ることができる)========================================================================================================================================================================|142,176,177,135,| | 46,214,225,169,|177,189,198,160,|203,208,177,165,|173,196,191,156,| +----------------+----------------+----------------+----------------+ | 41,185,208,180,|203,228,226,200,|214,226,225,227,|228,225,224,210,| | 31,130,173,178,|215,230,221,212,|220,229,227,228,|229,227,226,226,| | 29,119,194,216,|211,213,219,222,|225,223,220,219,|218,218,218,218,| | 25,126,219,224,|217,224,227,227,|227,226,225,224,|220,220,221,222,| +----------------+----------------+----------------+----------------+ | 26,131,215,223,|226,225,225,225,|225,226,223,219,|221,221,219,220,| | 30,136,216,226,|223,224,225,225,|224,221,217,221,|222,219,220,226,| | 30,136,216,227,|224,224,225,223,|221,218,221,216,|211,224,224,211,| | 29,135,217,225,|222,221,222,222,|221,209,181,155,|186,210,186,164,| +----------------+----------------+----------------+----------------+ | 29,134,216,224,|226,230,230,227,|206,177,146,113,|149,162,147,150,| | 29,135,219,231,|225,201,190,185,|163,144,153,140,|127,143,165,184,| | 30,139,210,192,|165,142,134,133,|143,141,129,138,|150,178,201,207,| | 30,125,166,145,|144,154,132,111,|118,161,175,180,|204,214,213,209,| +----------------+----------------+----------------+----------------+
予測値は、(H.264 visaはデコーダに相当し、復号側の残差と符号化側の残差は必ず等しい)
====================== Y Data ====================== +----------------+----------------+----------------+----------------+ |128,128,128,128,|238,238,238,238,|255,255,255,255,|245,228,210,192,| |128,128,128,128,|205,205,205,205,|180,180,180,180,|210,192,174,170,| |128,128,128,128,|167,167,167,167,|137,137,137,137,|174,170,166,166,| |128,128,128,128,|160,160,160,160,|169,169,169,169,|166,166,166,166,| +----------------+----------------+----------------+----------------+ |161,161,161,161,|179,189,182,169,|201,201,201,201,|219,219,219,219,| |161,161,161,161,|184,185,175,169,|214,214,214,214,|227,227,227,227,| |161,161,161,161,|189,182,169,169,|216,216,216,216,|219,219,219,219,| |161,161,161,161,|185,175,169,169,|229,229,229,229,|227,227,227,227,| +----------------+----------------+----------------+----------------+ | 28,127,218,229,|224,224,224,224,|227,227,228,227,|224,224,224,224,| | 28,127,218,229,|224,224,224,224,|224,225,227,227,|214,214,214,214,| | 28,127,218,229,|224,224,224,224,|224,224,224,225,|212,212,212,212,| | 28,127,218,229,|224,224,224,224,|224,224,224,224,|165,165,165,165,| +----------------+----------------+----------------+----------------+ | 33,130,216,224,|231,223,215,194,|204,182,160,142,|127,133,139,147,| | 33,130,216,224,|215,194,173,162,|160,142,125,120,|139,147,154,165,| | 33,130,216,224,|173,162,150,150,|125,120,116,116,|154,165,176,176,| | 33,130,216,224,|150,150,150,150,|116,116,116,116,|176,176,176,176,| +----------------+----------------+----------------+----------------+
残差:(H.264 visaはデコーダに相当するが、復号側の残差と符号化側の残差は近似的で等しくない)
====================== Y Data ====================== +------------------------+------------------------+------------------------+------------------------+ | -78, 88, 132, 110,| 24, 14, 24, 19,| -8, 7, -3, -4,| 16, 31, 48, 51,| | -81, 63, 67, 77,| 30, 1, 11, -25,| 19, 24, 6, 59,| -12, 20, 32, 10,| | -83, 62, 48, 39,| 25, 6, 16, -30,| 54, 46, 4, 44,| -30, 7, 5, -32,| | -80, 87, 93, 32,| 14, 24, 34, 9,| 31, 37, 7, -3,| 6, 28, 21, -9,| +------------------------+------------------------+------------------------+------------------------+ | -117, 22, 51, 22,| 25, 35, 38, 32,| 18, 18, 18, 18,| 5, 5, 5, 5,| | -135, -22, 22, 19,| 32, 43, 50, 45,| 13, 13, 13, 13,| 3, 3, 3, 3,| | -131, -38, 38, 55,| 20, 35, 48, 47,| 3, 3, 3, 3,| -2, -2, -2, -2,| | -133, -34, 57, 68,| 27, 43, 60, 60,| -2, -2, -2, -2,| -5, -5, -5, -5,| +------------------------+------------------------+------------------------+------------------------+ | 5, 3, -2, -5,| 0, 0, 0, 0,| -4, -4, -3, -3,| -5, -6, -5, -2,| | 5, 3, -2, -5,| 0, 0, 0, 0,| -3, -5, -10, -13,| -2, 5, 14, 15,| | 5, 3, -2, -5,| 0, 0, 0, 0,| -3, -5, -10, -13,| 0, 14, 15, 3,| | 5, 3, -2, -5,| 0, 0, 0, 0,| 2, -13, -44, -59,| 23, 35, 24, 0,| +------------------------+------------------------+------------------------+------------------------+ | -4, -4, 0, 4,| 1, 5, 18, 26,| 0, 0, -2, -34,| 25, 20, 8, 3,| | 2, 7, 11, 10,| 13, 3, 9, 25,| 6, 7, 25, 26,| -9, -3, 9, 15,| | 0, 6, -8, -28,| -5, -11, -17, -17,| 16, 20, 12, 16,| -5, 4, 22, 31,| | -6, -5, -39, -74,| -9, 3, -10, -34,| 6, 43, 55, 60,| 33, 33, 35, 35,| +------------------------+------------------------+------------------------+------------------------+
最後に、上記のコードのif(2==controlFlag)がif(1==controlFlag)に変更された場合、結果は次のようになります.
**************************** 43 216 254 249 49 198 193 211 48 194 177 171 46 214 225 169 **************************** 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 **************************** -85 88 126 121 -79 70 65 83 -80 66 49 43 -82 86 97 41
以上のH.264 visaの結果と比較すると、すべてが一目瞭然であり、余計なことは言わない.
P.S.その後、上のプロセスに欠陥があることに気づきました.マクロブロックにとってMode_Decision_for_4 x 4 IntraBlocks関数は16回呼び出されるだけでなく、16個の4*4ブロックに対応していないのに、なぜこのようなことがあるのでしょうか.トレースコードの結果、従来の4*4ブロックについて、最終的に最も合理的なイントラ予測モードを選択するには、DCT変換回数が16回を超えることが分かった.したがって、実際に符号化側で画素残差を抽出するには、JM 8が何度も選択されるべきである.6コードは必ずこのような選択をして、探せばいいです.
前に一言言います:时には同じ量に対して、いくつかの地方が多く抽出することができて、だから考え方はあまり制限しないでください、重要なのはこの量が过去にどこから来て、将来またどこへ行くかを知っています.以下の考え方は、I 4 x 4マクロブロックの残差を抽出する考え方である.(うるさい一言:すべてのタイプのマクロブロックの残差をどのように抽出するかは、次の場所だけでは不十分です)
前述したように、オリジナルのYUV画素はimgY_に格納されているorgでは、符号化側は残差を変換符号化し、encode_one_macroblockはマクロブロックを符号化するキー関数であるため、符号化側で残差を抽出するにはencode_one_macroblockが存在するファイル検索imgY_org、検索すると、本当にありますが、たくさんあります.思い出してみると、残差はどのように形成されていますか.明らかに残差の形成は必然的に減少に関連し,すなわちコードの中で「imgY_org[]-...」を探すことに関連する.このような形式のコード.探して、本当にありますが、私たちが必要とする「imgY_org[]-...」形式のコードはMode_にありますDecision_for_4 x 4 IntraBlocks関数では、encode_one_macroblockがModeを呼び出しましたDecision_for_4 x 4 IntraBlocks関数
残差を抽出するコードは以下の通りである(残差を抽出するために使用されるコードは一部のみであり、I 4 x 4マクロブロックを例に挙げる).
int Mode_Decision_for_4x4IntraBlocks (int b8, int b4, double lambda, int* min_cost)
{
int ipmode, best_ipmode = 0, i, j, k, x, y, cost, dummy;
int c_nz, nonzero = 0, rec4x4[4][4], diff[16];
double rdcost;
int block_x = 8*(b8%2)+4*(b4%2);
int block_y = 8*(b8/2)+4*(b4/2);
int pic_pix_x = img->pix_x+block_x;
int pic_pix_y = img->pix_y+block_y;
int pic_opix_x = img->opix_x+block_x;
int pic_opix_y = img->opix_y+block_y;
int pic_block_x = pic_pix_x/4;
int pic_block_y = pic_pix_y/4;
double min_rdcost = 1e30;
int left_available, up_available, all_available;
int upMode;
int leftMode;
int mostProbableMode;
static int controlFlag = 0;
PixelPos left_block;
PixelPos top_block;
getLuma4x4Neighbour(img->current_mb_nr, block_x/4, block_y/4, -1, 0, &left_block);
getLuma4x4Neighbour(img->current_mb_nr, block_x/4, block_y/4, 0, -1, &top_block);
// constrained intra pred
if (input->UseConstrainedIntraPred)
{
left_block.available = left_block.available ? img->intra_block[left_block.mb_addr] : 0;
top_block.available = top_block.available ? img->intra_block[top_block.mb_addr] : 0;
}
upMode = top_block.available ? img->ipredmode[top_block.pos_x ][top_block.pos_y ] : -1;
leftMode = left_block.available ? img->ipredmode[left_block.pos_x][left_block.pos_y] : -1;
mostProbableMode = (upMode < 0 || leftMode < 0) ? DC_PRED : upMode < leftMode ? upMode : leftMode;
*min_cost = (1<<20);
//===== INTRA PREDICTION FOR 4x4 BLOCK =====
intrapred_luma (pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
//===== LOOP OVER ALL 4x4 INTRA PREDICTION MODES =====
for (ipmode=0; ipmode<NO_INTRA_PMODE; ipmode++)
{
int available_mode = (ipmode==DC_PRED) ||
((ipmode==VERT_PRED||ipmode==VERT_LEFT_PRED||ipmode==DIAG_DOWN_LEFT_PRED) && up_available ) ||
((ipmode==HOR_PRED||ipmode==HOR_UP_PRED) && left_available ) ||(all_available);
if( available_mode)
{
if (!input->rdopt)
{
for (k=j=0; j<4; j++)
for (i=0; i<4; i++, k++)
{
diff[k] = imgY_org[pic_opix_y+j][pic_opix_x+i] - img->mprr[ipmode][j][i];
}
cost = (ipmode == mostProbableMode) ? 0 : (int)floor(4 * lambda );
cost += SATD (diff, input->hadamard);
if (cost < *min_cost)
{
best_ipmode = ipmode;
*min_cost = cost;
}
}
else
{
// get prediction and prediction error
for (j=0; j<4; j++)
for (i=0; i<4; i++)
{
img->mpr[block_x+i][block_y+j] = img->mprr[ipmode][j][i];
img->m7[i][j] = imgY_org[pic_opix_y+j][pic_opix_x+i] - img->mprr[ipmode][j][i];
}
//**************************************************************
// ( , )
// controlFlag static int ,
// controlFlag 2, 4*4
controlFlag++;
if(2 == controlFlag)
{
printf("****************************
");
for (j = 0; j < 4; j++)
{
for (i = 0; i < 4; i++)
{
printf("%d\t",imgY_org[pic_opix_y+j][pic_opix_x+i]);
}
printf("
");
}
printf("****************************
");
for (j = 0; j < 4; j++)
{
for (i = 0; i < 4; i++)
{
printf("%d\t",img->mprr[ipmode][j][i]);
}
printf("
");
}
printf("****************************
");
for (j=0; j<4; j++)
{
for (i=0; i<4; i++)
{
printf("%d\t",img->m7[i][j]);
}
printf("
");
}
}
//**************************************************************
//===== store the coding state =====
store_coding_state (cs_cm);
// get and check rate-distortion cost
if ((rdcost = RDCost_for_4x4IntraBlocks (&c_nz, b8, b4, ipmode, lambda, min_rdcost, mostProbableMode)) < min_rdcost)
{
//--- set coefficients ---
for (j=0; j<2; j++)
for (i=0; i<18;i++) cofAC4x4[j][i]=img->cofAC[b8][b4][j][i];
//--- set reconstruction ---
for (y=0; y<4; y++)
for (x=0; x<4; x++) rec4x4[y][x] = enc_picture->imgY[pic_pix_y+y][pic_pix_x+x];
//--- flag if dct-coefficients must be coded ---
nonzero = c_nz;
//--- set best mode update minimum cost ---
min_rdcost = rdcost;
best_ipmode = ipmode;
}
reset_coding_state (cs_cm);
}
}
}
//===== set intra mode prediction =====
img->ipredmode[pic_block_x][pic_block_y] = best_ipmode;
img->mb_data[img->current_mb_nr].intra_pred_modes[4*b8+b4] = mostProbableMode == best_ipmode ? -1 : best_ipmode < mostProbableMode ? best_ipmode : best_ipmode-1;
if (!input->rdopt)
{
// get prediction and prediction error
for (j=0; j<4; j++)
for (i=0; i<4; i++)
{
img->mpr[block_x+i][block_y+j] = img->mprr[best_ipmode][j][i];
img->m7[i][j] = imgY_org[pic_opix_y+j][pic_opix_x+i] - img->mprr[best_ipmode][j][i];
}
nonzero = dct_luma (block_x, block_y, &dummy, 1);
}
else
{
//===== restore coefficients =====
for (j=0; j<2; j++)
for (i=0; i<18;i++) img->cofAC[b8][b4][j][i]=cofAC4x4[j][i];
//===== restore reconstruction and prediction (needed if single coeffs are removed) =====
for (y=0; y<4; y++)
for (x=0; x<4; x++)
{
enc_picture->imgY[pic_pix_y+y][pic_pix_x+x] = rec4x4[y][x];
img->mpr[block_x+x][block_y+y] = img->mprr[best_ipmode][y][x];
}
}
return nonzero;
}
結果:
**************************** 251 254 254 253 228 205 213 185 197 173 185 136 177 189 198 160 **************************** 238 238 238 238 205 205 205 205 167 167 167 167 160 160 160 160 **************************** 13 16 16 15 23 0 8 -20 30 6 18 -31 17 29 38 0
3つの行列はそれぞれ第1フレームの第1マクロブロックの第2の4*4ブロックの元の値、予測値、残差に対応し、上記の結果の正確性を検証するためにH.264 visaで分析することができ、結果は以下の通りである.
元の値は、(注意:H.264 visaでも元のYUVデータを読み取ることができる)========================================================================================================================================================================|142,176,177,135,| | 46,214,225,169,|177,189,198,160,|203,208,177,165,|173,196,191,156,| +----------------+----------------+----------------+----------------+ | 41,185,208,180,|203,228,226,200,|214,226,225,227,|228,225,224,210,| | 31,130,173,178,|215,230,221,212,|220,229,227,228,|229,227,226,226,| | 29,119,194,216,|211,213,219,222,|225,223,220,219,|218,218,218,218,| | 25,126,219,224,|217,224,227,227,|227,226,225,224,|220,220,221,222,| +----------------+----------------+----------------+----------------+ | 26,131,215,223,|226,225,225,225,|225,226,223,219,|221,221,219,220,| | 30,136,216,226,|223,224,225,225,|224,221,217,221,|222,219,220,226,| | 30,136,216,227,|224,224,225,223,|221,218,221,216,|211,224,224,211,| | 29,135,217,225,|222,221,222,222,|221,209,181,155,|186,210,186,164,| +----------------+----------------+----------------+----------------+ | 29,134,216,224,|226,230,230,227,|206,177,146,113,|149,162,147,150,| | 29,135,219,231,|225,201,190,185,|163,144,153,140,|127,143,165,184,| | 30,139,210,192,|165,142,134,133,|143,141,129,138,|150,178,201,207,| | 30,125,166,145,|144,154,132,111,|118,161,175,180,|204,214,213,209,| +----------------+----------------+----------------+----------------+
予測値は、(H.264 visaはデコーダに相当し、復号側の残差と符号化側の残差は必ず等しい)
====================== Y Data ====================== +----------------+----------------+----------------+----------------+ |128,128,128,128,|238,238,238,238,|255,255,255,255,|245,228,210,192,| |128,128,128,128,|205,205,205,205,|180,180,180,180,|210,192,174,170,| |128,128,128,128,|167,167,167,167,|137,137,137,137,|174,170,166,166,| |128,128,128,128,|160,160,160,160,|169,169,169,169,|166,166,166,166,| +----------------+----------------+----------------+----------------+ |161,161,161,161,|179,189,182,169,|201,201,201,201,|219,219,219,219,| |161,161,161,161,|184,185,175,169,|214,214,214,214,|227,227,227,227,| |161,161,161,161,|189,182,169,169,|216,216,216,216,|219,219,219,219,| |161,161,161,161,|185,175,169,169,|229,229,229,229,|227,227,227,227,| +----------------+----------------+----------------+----------------+ | 28,127,218,229,|224,224,224,224,|227,227,228,227,|224,224,224,224,| | 28,127,218,229,|224,224,224,224,|224,225,227,227,|214,214,214,214,| | 28,127,218,229,|224,224,224,224,|224,224,224,225,|212,212,212,212,| | 28,127,218,229,|224,224,224,224,|224,224,224,224,|165,165,165,165,| +----------------+----------------+----------------+----------------+ | 33,130,216,224,|231,223,215,194,|204,182,160,142,|127,133,139,147,| | 33,130,216,224,|215,194,173,162,|160,142,125,120,|139,147,154,165,| | 33,130,216,224,|173,162,150,150,|125,120,116,116,|154,165,176,176,| | 33,130,216,224,|150,150,150,150,|116,116,116,116,|176,176,176,176,| +----------------+----------------+----------------+----------------+
残差:(H.264 visaはデコーダに相当するが、復号側の残差と符号化側の残差は近似的で等しくない)
====================== Y Data ====================== +------------------------+------------------------+------------------------+------------------------+ | -78, 88, 132, 110,| 24, 14, 24, 19,| -8, 7, -3, -4,| 16, 31, 48, 51,| | -81, 63, 67, 77,| 30, 1, 11, -25,| 19, 24, 6, 59,| -12, 20, 32, 10,| | -83, 62, 48, 39,| 25, 6, 16, -30,| 54, 46, 4, 44,| -30, 7, 5, -32,| | -80, 87, 93, 32,| 14, 24, 34, 9,| 31, 37, 7, -3,| 6, 28, 21, -9,| +------------------------+------------------------+------------------------+------------------------+ | -117, 22, 51, 22,| 25, 35, 38, 32,| 18, 18, 18, 18,| 5, 5, 5, 5,| | -135, -22, 22, 19,| 32, 43, 50, 45,| 13, 13, 13, 13,| 3, 3, 3, 3,| | -131, -38, 38, 55,| 20, 35, 48, 47,| 3, 3, 3, 3,| -2, -2, -2, -2,| | -133, -34, 57, 68,| 27, 43, 60, 60,| -2, -2, -2, -2,| -5, -5, -5, -5,| +------------------------+------------------------+------------------------+------------------------+ | 5, 3, -2, -5,| 0, 0, 0, 0,| -4, -4, -3, -3,| -5, -6, -5, -2,| | 5, 3, -2, -5,| 0, 0, 0, 0,| -3, -5, -10, -13,| -2, 5, 14, 15,| | 5, 3, -2, -5,| 0, 0, 0, 0,| -3, -5, -10, -13,| 0, 14, 15, 3,| | 5, 3, -2, -5,| 0, 0, 0, 0,| 2, -13, -44, -59,| 23, 35, 24, 0,| +------------------------+------------------------+------------------------+------------------------+ | -4, -4, 0, 4,| 1, 5, 18, 26,| 0, 0, -2, -34,| 25, 20, 8, 3,| | 2, 7, 11, 10,| 13, 3, 9, 25,| 6, 7, 25, 26,| -9, -3, 9, 15,| | 0, 6, -8, -28,| -5, -11, -17, -17,| 16, 20, 12, 16,| -5, 4, 22, 31,| | -6, -5, -39, -74,| -9, 3, -10, -34,| 6, 43, 55, 60,| 33, 33, 35, 35,| +------------------------+------------------------+------------------------+------------------------+
最後に、上記のコードのif(2==controlFlag)がif(1==controlFlag)に変更された場合、結果は次のようになります.
**************************** 43 216 254 249 49 198 193 211 48 194 177 171 46 214 225 169 **************************** 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 **************************** -85 88 126 121 -79 70 65 83 -80 66 49 43 -82 86 97 41
以上のH.264 visaの結果と比較すると、すべてが一目瞭然であり、余計なことは言わない.
P.S.その後、上のプロセスに欠陥があることに気づきました.マクロブロックにとってMode_Decision_for_4 x 4 IntraBlocks関数は16回呼び出されるだけでなく、16個の4*4ブロックに対応していないのに、なぜこのようなことがあるのでしょうか.トレースコードの結果、従来の4*4ブロックについて、最終的に最も合理的なイントラ予測モードを選択するには、DCT変換回数が16回を超えることが分かった.したがって、実際に符号化側で画素残差を抽出するには、JM 8が何度も選択されるべきである.6コードは必ずこのような選択をして、探せばいいです.