H.264
H.264の8x8整数DCTを、改訂三版H.264/AVC教科書のP265-269に載っているやり方で書いて、forward DCT => inverse DCT を行うと値が10くらい変わってしまって狼狽して結構悩んでいた。全然わからなくてIRCのx264チャンネルで質問したところ量子化処理に正規化の値が掛け合わされてるとの答えを頂いた。
x264のソースや H264_4x4_transform_whitepaper_Jan09.pdf というドキュメントを参考にして以下のように確認する処理を書いて確認。
そのうち量子化テーブルの値を変えれるように改造しよう…。
static const int quant8_scan[16] = { 0,3,4,3, 3,1,5,1, 4,5,2,5, 3,1,5,1 }; static const int dequant8_scale[6][6] = { { 20, 18, 32, 19, 25, 24 }, { 22, 19, 35, 21, 28, 26 }, { 26, 23, 42, 24, 33, 31 }, { 28, 25, 45, 26, 35, 33 }, { 32, 28, 51, 30, 40, 38 }, { 36, 32, 58, 34, 46, 43 }, }; static const int quant8_scale[6][6] = { { 13107, 11428, 20972, 12222, 16777, 15481 }, { 11916, 10826, 19174, 11058, 14980, 14290 }, { 10082, 8943, 15978, 9675, 12710, 11985 }, { 9362, 8228, 14913, 8931, 11984, 11259 }, { 8192, 7346, 13159, 7740, 10486, 9777 }, { 7282, 6428, 11570, 6830, 9118, 8640 } }; int quant8_table[64]; int dequant8_table[64]; for (size_t i=0; i<64; ++i) { int j = quant8_scan[((i>>1)&12) | (i&3)]; printf("%d,", j); quant8_table[i] = quant8_scale[0][j]; dequant8_table[i] = dequant8_scale[0][j]; } int tmps[8][8]; dct_8x8(values, tmps); for (size_t i=0; i<8; ++i) { for (size_t j=0; j<8; ++j) { values[i][j] *= quant8_table[i*8+j]; values[i][j] += 0x800; values[i][j] >>= 12; } } for (size_t i=0; i<8; ++i) { for (size_t j=0; j<8; ++j) { values[i][j] *= dequant8_table[i*8+j]; } } idct_8x8(values, tmps); for (size_t i=0; i<8; ++i) { for (size_t j=0; j<8; ++j) { values[i][j] += 0x800; values[i][j] >>= 12; } }