diff options
Diffstat (limited to 'Src/h264dec/lcommon')
22 files changed, 5163 insertions, 0 deletions
diff --git a/Src/h264dec/lcommon/inc/ctx_tables.h b/Src/h264dec/lcommon/inc/ctx_tables.h new file mode 100644 index 00000000..28d622f3 --- /dev/null +++ b/Src/h264dec/lcommon/inc/ctx_tables.h @@ -0,0 +1,994 @@ + +/*! + ************************************************************************************* + * \file ctx_tables.h + * + * \brief + * CABAC context initialization tables + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Detlev Marpe <marpe@hhi.de> + * - Heiko Schwarz <hschwarz@hhi.de> + ************************************************************************************** + */ + +#define CTX_UNUSED {0,64} +#define CTX_UNDEF {0,63} + +#ifdef CONTEXT_INI_C + + +#define NUM_CTX_MODELS_I 1 +#define NUM_CTX_MODELS_P 3 + + +static const char INIT_MB_TYPE_I[1][3][11][2] = +{ + //----- model 0 ----- + { + { { 20, -15} , { 2, 54} , { 3, 74} , CTX_UNUSED , { -28, 127} , { -23, 104} , { -6, 53} , { -1, 54} , { 7, 51} , CTX_UNUSED , CTX_UNUSED }, + { { 20, -15} , { 2, 54} , { 3, 74} , { 20, -15} , { 2, 54} , { 3, 74} , { -28, 127} , { -23, 104} , { -6, 53} , { -1, 54} , { 7, 51} }, // SI (unused at the moment) + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + } +}; +static const char INIT_MB_TYPE_P[3][3][11][2] = +{ + //----- model 0 ----- + { + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 23, 33} , { 23, 2} , { 21, 0} , CTX_UNUSED , { 1, 9} , { 0, 49} , { -37, 118} , { 5, 57} , { -13, 78} , { -11, 65} , { 1, 62} }, + { { 26, 67} , { 16, 90} , { 9, 104} , CTX_UNUSED , { -46, 127} , { -20, 104} , { 1, 67} , { 18, 64} , { 9, 43} , { 29, 0} , CTX_UNUSED } + }, + //----- model 1 ----- + { + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 22, 25} , { 34, 0} , { 16, 0} , CTX_UNUSED , { -2, 9} , { 4, 41} , { -29, 118} , { 2, 65} , { -6, 71} , { -13, 79} , { 5, 52} }, + { { 57, 2} , { 41, 36} , { 26, 69} , CTX_UNUSED , { -45, 127} , { -15, 101} , { -4, 76} , { 26, 34} , { 19, 22} , { 40, 0} , CTX_UNUSED } + }, + //----- model 2 ----- + { + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 29, 16} , { 25, 0} , { 14, 0} , CTX_UNUSED , { -10, 51} , { -3, 62} , { -27, 99} , { 26, 16} , { -4, 85} , { -24, 102} , { 5, 57} }, + { { 54, 0} , { 37, 42} , { 12, 97} , CTX_UNUSED , { -32, 127} , { -22, 117} , { -2, 74} , { 20, 40} , { 20, 10} , { 29, 0} , CTX_UNUSED } + } +}; + +static const char INIT_B8_TYPE_I[1][2][9][2] = +{ + //----- model 0 ----- + { + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + } +}; + +static const char INIT_B8_TYPE_P[3][2][9][2] = +{ + //----- model 0 ----- + { + { CTX_UNUSED , { 12, 49} , CTX_UNUSED , { -4, 73} , { 17, 50} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -6, 86} , { -17, 95} , { -6, 61} , { 9, 45} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + }, + //----- model 1 ----- + { + { CTX_UNUSED , { 9, 50} , CTX_UNUSED , { -3, 70} , { 10, 54} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 6, 69} , { -13, 90} , { 0, 52} , { 8, 43} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + }, + //----- model 2 ----- + { + { CTX_UNUSED , { 6, 57} , CTX_UNUSED , { -17, 73} , { 14, 57} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -6, 93} , { -14, 88} , { -6, 44} , { 4, 55} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + } +}; + +static const char INIT_MV_RES_I[1][2][10][2] = +{ + //----- model 0 ----- + { + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + } +}; + +static const char INIT_MV_RES_P[3][2][10][2] = +{ + //----- model 0 ----- + { + { { -3, 69} , CTX_UNUSED , { -6, 81} , { -11, 96} , CTX_UNUSED , { 0, 58} , CTX_UNUSED , { -3, 76} , { -10, 94} , CTX_UNUSED }, + { { 6, 55} , { 7, 67} , { -5, 86} , { 2, 88} , CTX_UNUSED , { 5, 54} , { 4, 69} , { -3, 81} , { 0, 88} , CTX_UNUSED } + }, + //----- model 1 ----- + { + { { -2, 69} , CTX_UNUSED , { -5, 82} , { -10, 96} , CTX_UNUSED , { 1, 56} , CTX_UNUSED , { -3, 74} , { -6, 85} , CTX_UNUSED }, + { { 2, 59} , { 2, 75} , { -3, 87} , { -3, 100} , CTX_UNUSED , { 0, 59} , { -3, 81} , { -7, 86} , { -5, 95} , CTX_UNUSED } + }, + //----- model 2 ----- + { + { { -11, 89} , CTX_UNUSED , { -15, 103} , { -21, 116} , CTX_UNUSED , { 1, 63} , CTX_UNUSED , { -5, 85} , { -13, 106} , CTX_UNUSED }, + { { 19, 57} , { 20, 58} , { 4, 84} , { 6, 96} , CTX_UNUSED , { 5, 63} , { 6, 75} , { -3, 90} , { -1, 101} , CTX_UNUSED } + } +}; + +static const char INIT_REF_NO_I[1][2][6][2] = +{ + //----- model 0 ----- + { + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + } +}; + +static const char INIT_REF_NO_P[3][2][6][2] = +{ + //----- model 0 ----- + { + { { -7, 67} , { -5, 74} , { -4, 74} , { -5, 80} , { -7, 72} , { 1, 58} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + }, + //----- model 1 ----- + { + { { -1, 66} , { -1, 77} , { 1, 70} , { -2, 86} , { -5, 72} , { 0, 61} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + }, + //----- model 2 ----- + { + { { 3, 55} , { -4, 79} , { -2, 75} , { -12, 97} , { -7, 50} , { 1, 60} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + } +}; + + +static const char INIT_TRANSFORM_SIZE_I[1][1][3][2]= +{ + //----- model 0 ----- + { + { { 31, 21} , { 31, 31} , { 25, 50} }, +// { { 0, 41} , { 0, 63} , { 0, 63} }, + } +}; + +static const char INIT_TRANSFORM_SIZE_P[3][1][3][2]= +{ + //----- model 0 ----- + { + { { 12, 40} , { 11, 51} , { 14, 59} }, +// { { 0, 41} , { 0, 63} , { 0, 63} }, + }, + //----- model 1 ----- + { + { { 25, 32} , { 21, 49} , { 21, 54} }, +// { { 0, 41} , { 0, 63} , { 0, 63} }, + }, + //----- model 2 ----- + { + { { 21, 33} , { 19, 50} , { 17, 61} }, +// { { 0, 41} , { 0, 63} , { 0, 63} }, + } +}; + +static const char INIT_DELTA_QP_I[1][1][4][2]= +{ + //----- model 0 ----- + { + { { 0, 41} , { 0, 63} , { 0, 63} , { 0, 63} }, + } +}; +static const char INIT_DELTA_QP_P[3][1][4][2]= +{ + //----- model 0 ----- + { + { { 0, 41} , { 0, 63} , { 0, 63} , { 0, 63} }, + }, + //----- model 1 ----- + { + { { 0, 41} , { 0, 63} , { 0, 63} , { 0, 63} }, + }, + //----- model 2 ----- + { + { { 0, 41} , { 0, 63} , { 0, 63} , { 0, 63} }, + } +}; + +static const char INIT_MB_AFF_I[1][1][4][2] = +{ + //----- model 0 ----- + { + { { 0, 11} , { 1, 55} , { 0, 69} , CTX_UNUSED } + } +}; +static const char INIT_MB_AFF_P[3][1][4][2] = +{ + //----- model 0 ----- + { + { { 0, 45} , { -4, 78} , { -3, 96} , CTX_UNUSED } + }, + //----- model 1 ----- + { + { { 13, 15} , { 7, 51} , { 2, 80} , CTX_UNUSED } + }, + //----- model 2 ----- + { + { { 7, 34} , { -9, 88} , { -20, 127} , CTX_UNUSED } + } +}; + +static const char INIT_IPR_I[1][1][2][2] = +{ + //----- model 0 ----- + { + { { 13, 41} , { 3, 62} } + } +}; + +static const char INIT_IPR_P[3][1][2][2] = +{ + //----- model 0 ----- + { + { { 13, 41} , { 3, 62} } + }, + //----- model 1 ----- + { + { { 13, 41} , { 3, 62} } + }, + //----- model 2 ----- + { + { { 13, 41} , { 3, 62} } + } +}; + +static const char INIT_CIPR_I[1][1][4][2] = +{ + //----- model 0 ----- + { + { { -9, 83} , { 4, 86} , { 0, 97} , { -7, 72} } + } +}; + +static const char INIT_CIPR_P[3][1][4][2] = +{ + //----- model 0 ----- + { + { { -9, 83} , { 4, 86} , { 0, 97} , { -7, 72} } + }, + //----- model 1 ----- + { + { { -9, 83} , { 4, 86} , { 0, 97} , { -7, 72} } + }, + //----- model 2 ----- + { + { { -9, 83} , { 4, 86} , { 0, 97} , { -7, 72} } + } +}; + +static const char INIT_CBP_I[1][3][4][2] = +{ + //----- model 0 ----- + { + { { -17, 127} , { -13, 102} , { 0, 82} , { -7, 74} }, + { { -21, 107} , { -27, 127} , { -31, 127} , { -24, 127} }, + { { -18, 95} , { -27, 127} , { -21, 114} , { -30, 127} } + } +}; + +static const char INIT_CBP_P[3][3][4][2] = +{ + //----- model 0 ----- + { + { { -27, 126} , { -28, 98} , { -25, 101} , { -23, 67} }, + { { -28, 82} , { -20, 94} , { -16, 83} , { -22, 110} }, + { { -21, 91} , { -18, 102} , { -13, 93} , { -29, 127} } + }, + //----- model 1 ----- + { + { { -39, 127} , { -18, 91} , { -17, 96} , { -26, 81} }, + { { -35, 98} , { -24, 102} , { -23, 97} , { -27, 119} }, + { { -24, 99} , { -21, 110} , { -18, 102} , { -36, 127} } + }, + //----- model 2 ----- + { + { { -36, 127} , { -17, 91} , { -14, 95} , { -25, 84} }, + { { -25, 86} , { -12, 89} , { -17, 91} , { -31, 127} }, + { { -14, 76} , { -18, 103} , { -13, 90} , { -37, 127} } + } +}; + +static const char INIT_BCBP_I[1][22][4][2] = +{ + //----- model 0 ----- + { + { { -17, 123} , { -12, 115} , { -16, 122} , { -11, 115} }, + { { -12, 63} , { -2, 68} , { -15, 84} , { -13, 104} }, + { { -3, 70} , { -8, 93} , { -10, 90} , { -30, 127} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -3, 70} , { -8, 93} , { -10, 90} , { -30, 127} }, + { { -1, 74} , { -6, 97} , { -7, 91} , { -20, 127} }, + { { -4, 56} , { -5, 82} , { -7, 76} , { -22, 125} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + // Cb in the 4:4:4 common mode + { { -17, 123} , { -12, 115} , { -16, 122} , { -11, 115} }, + { { -12, 63} , { -2, 68} , { -15, 84} , { -13, 104} }, + { { -3, 70} , { -8, 93} , { -10, 90} , { -30, 127} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -3, 70} , { -8, 93} , { -10, 90} , { -30, 127} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + // Cr in the 4:4:4 common mode + { { -17, 123} , { -12, 115} , { -16, 122} , { -11, 115} }, + { { -12, 63} , { -2, 68} , { -15, 84} , { -13, 104} }, + { { -3, 70} , { -8, 93} , { -10, 90} , { -30, 127} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -3, 70} , { -8, 93} , { -10, 90} , { -30, 127} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + } +}; + +static const char INIT_BCBP_P[3][22][4][2] = +{ + //----- model 0 ----- + { + { { -7, 92} , { -5, 89} , { -7, 96} , { -13, 108} }, + { { -3, 46} , { -1, 65} , { -1, 57} , { -9, 93} }, + { { -3, 74} , { -9, 92} , { -8, 87} , { -23, 126} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -3, 74} , { -9, 92} , { -8, 87} , { -23, 126} }, + { { 5, 54} , { 6, 60} , { 6, 59} , { 6, 69} }, + { { -1, 48} , { 0, 68} , { -4, 69} , { -8, 88} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + // Cb in the 4:4:4 common mode + { { -7, 92} , { -5, 89} , { -7, 96} , { -13, 108} }, + { { -3, 46} , { -1, 65} , { -1, 57} , { -9, 93} }, + { { -3, 74} , { -9, 92} , { -8, 87} , { -23, 126} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -3, 74} , { -9, 92} , { -8, 87} , { -23, 126} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + // Cr in the 4:4:4 common mode + { { -7, 92} , { -5, 89} , { -7, 96} , { -13, 108} }, + { { -3, 46} , { -1, 65} , { -1, 57} , { -9, 93} }, + { { -3, 74} , { -9, 92} , { -8, 87} , { -23, 126} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -3, 74} , { -9, 92} , { -8, 87} , { -23, 126} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + }, + //----- model 1 ----- + { + { { 0, 80} , { -5, 89} , { -7, 94} , { -4, 92} }, + { { 0, 39} , { 0, 65} , { -15, 84} , { -35, 127} }, + { { -2, 73} , { -12, 104} , { -9, 91} , { -31, 127} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -2, 73} , { -12, 104} , { -9, 91} , { -31, 127} }, + { { 3, 55} , { 7, 56} , { 7, 55} , { 8, 61} }, + { { -3, 53} , { 0, 68} , { -7, 74} , { -9, 88} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + // Cb in the 4:4:4 common mode + { { 0, 80} , { -5, 89} , { -7, 94} , { -4, 92} }, + { { 0, 39} , { 0, 65} , { -15, 84} , { -35, 127} }, + { { -2, 73} , { -12, 104} , { -9, 91} , { -31, 127} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -2, 73} , { -12, 104} , { -9, 91} , { -31, 127} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + // Cr in the 4:4:4 common mode + { { 0, 80} , { -5, 89} , { -7, 94} , { -4, 92} }, + { { 0, 39} , { 0, 65} , { -15, 84} , { -35, 127} }, + { { -2, 73} , { -12, 104} , { -9, 91} , { -31, 127} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -2, 73} , { -12, 104} , { -9, 91} , { -31, 127} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + }, + //----- model 2 ----- + { + { { 11, 80} , { 5, 76} , { 2, 84} , { 5, 78} }, + { { -6, 55} , { 4, 61} , { -14, 83} , { -37, 127} }, + { { -5, 79} , { -11, 104} , { -11, 91} , { -30, 127} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -5, 79} , { -11, 104} , { -11, 91} , { -30, 127} }, + { { 0, 65} , { -2, 79} , { 0, 72} , { -4, 92} }, + { { -6, 56} , { 3, 68} , { -8, 71} , { -13, 98} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + // Cb in the 4:4:4 common mode + { { 11, 80} , { 5, 76} , { 2, 84} , { 5, 78} }, + { { -6, 55} , { 4, 61} , { -14, 83} , { -37, 127} }, + { { -5, 79} , { -11, 104} , { -11, 91} , { -30, 127} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -5, 79} , { -11, 104} , { -11, 91} , { -30, 127} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + // Cr in the 4:4:4 common mode + { { 11, 80} , { 5, 76} , { 2, 84} , { 5, 78} }, + { { -6, 55} , { 4, 61} , { -14, 83} , { -37, 127} }, + { { -5, 79} , { -11, 104} , { -11, 91} , { -30, 127} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -5, 79} , { -11, 104} , { -11, 91} , { -30, 127} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + } +}; + +static const char INIT_MAP_I[1][22][15][2] = +{ + //----- model 0 ----- + { + { { -7, 93} , { -11, 87} , { -3, 77} , { -5, 71} , { -4, 63} , { -4, 68} , { -12, 84} , { -7, 62} , { -7, 65} , { 8, 61} , { 5, 56} , { -2, 66} , { 1, 64} , { 0, 61} , { -2, 78} }, + { CTX_UNUSED , { 1, 50} , { 7, 52} , { 10, 35} , { 0, 44} , { 11, 38} , { 1, 45} , { 0, 46} , { 5, 44} , { 31, 17} , { 1, 51} , { 7, 50} , { 28, 19} , { 16, 33} , { 14, 62} }, + { { -17, 120} , { -20, 112} , { -18, 114} , { -11, 85} , { -15, 92} , { -14, 89} , { -26, 71} , { -15, 81} , { -14, 80} , { 0, 68} , { -14, 70} , { -24, 56} , { -23, 68} , { -24, 50} , { -11, 74} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -13, 108} , { -15, 100} , { -13, 101} , { -13, 91} , { -12, 94} , { -10, 88} , { -16, 84} , { -10, 86} , { -7, 83} , { -13, 87} , { -19, 94} , { 1, 70} , { 0, 72} , { -5, 74} , { 18, 59} }, + { { -8, 102} , { -15, 100} , { 0, 95} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , { -4, 75} , { 2, 72} , { -11, 75} , { -3, 71} , { 15, 46} , { -13, 69} , { 0, 62} , { 0, 65} , { 21, 37} , { -15, 72} , { 9, 57} , { 16, 54} , { 0, 62} , { 12, 72} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cb in the 4:4:4 common mode + { { -7, 93} , { -11, 87} , { -3, 77} , { -5, 71} , { -4, 63} , { -4, 68} , { -12, 84} , { -7, 62} , { -7, 65} , { 8, 61} , { 5, 56} , { -2, 66} , { 1, 64} , { 0, 61} , { -2, 78} }, + { CTX_UNUSED , { 1, 50} , { 7, 52} , { 10, 35} , { 0, 44} , { 11, 38} , { 1, 45} , { 0, 46} , { 5, 44} , { 31, 17} , { 1, 51} , { 7, 50} , { 28, 19} , { 16, 33} , { 14, 62} }, + { { -17, 120} , { -20, 112} , { -18, 114} , { -11, 85} , { -15, 92} , { -14, 89} , { -26, 71} , { -15, 81} , { -14, 80} , { 0, 68} , { -14, 70} , { -24, 56} , { -23, 68} , { -24, 50} , { -11, 74} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -13, 108} , { -15, 100} , { -13, 101} , { -13, 91} , { -12, 94} , { -10, 88} , { -16, 84} , { -10, 86} , { -7, 83} , { -13, 87} , { -19, 94} , { 1, 70} , { 0, 72} , { -5, 74} , { 18, 59} }, + //Cr in the 4:4:4 common mode + { { -7, 93} , { -11, 87} , { -3, 77} , { -5, 71} , { -4, 63} , { -4, 68} , { -12, 84} , { -7, 62} , { -7, 65} , { 8, 61} , { 5, 56} , { -2, 66} , { 1, 64} , { 0, 61} , { -2, 78} }, + { CTX_UNUSED , { 1, 50} , { 7, 52} , { 10, 35} , { 0, 44} , { 11, 38} , { 1, 45} , { 0, 46} , { 5, 44} , { 31, 17} , { 1, 51} , { 7, 50} , { 28, 19} , { 16, 33} , { 14, 62} }, + { { -17, 120} , { -20, 112} , { -18, 114} , { -11, 85} , { -15, 92} , { -14, 89} , { -26, 71} , { -15, 81} , { -14, 80} , { 0, 68} , { -14, 70} , { -24, 56} , { -23, 68} , { -24, 50} , { -11, 74} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -13, 108} , { -15, 100} , { -13, 101} , { -13, 91} , { -12, 94} , { -10, 88} , { -16, 84} , { -10, 86} , { -7, 83} , { -13, 87} , { -19, 94} , { 1, 70} , { 0, 72} , { -5, 74} , { 18, 59} } + } +}; + +static const char INIT_MAP_P[3][22][15][2] = +{ + //----- model 0 ----- + { + { { -2, 85} , { -6, 78} , { -1, 75} , { -7, 77} , { 2, 54} , { 5, 50} , { -3, 68} , { 1, 50} , { 6, 42} , { -4, 81} , { 1, 63} , { -4, 70} , { 0, 67} , { 2, 57} , { -2, 76} }, + { CTX_UNUSED , { 11, 35} , { 4, 64} , { 1, 61} , { 11, 35} , { 18, 25} , { 12, 24} , { 13, 29} , { 13, 36} , { -10, 93} , { -7, 73} , { -2, 73} , { 13, 46} , { 9, 49} , { -7, 100} }, + { { -4, 79} , { -7, 71} , { -5, 69} , { -9, 70} , { -8, 66} , { -10, 68} , { -19, 73} , { -12, 69} , { -16, 70} , { -15, 67} , { -20, 62} , { -19, 70} , { -16, 66} , { -22, 65} , { -20, 63} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 9, 53} , { 2, 53} , { 5, 53} , { -2, 61} , { 0, 56} , { 0, 56} , { -13, 63} , { -5, 60} , { -1, 62} , { 4, 57} , { -6, 69} , { 4, 57} , { 14, 39} , { 4, 51} , { 13, 68} }, + { { 3, 64} , { 1, 61} , { 9, 63} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , { 7, 50} , { 16, 39} , { 5, 44} , { 4, 52} , { 11, 48} , { -5, 60} , { -1, 59} , { 0, 59} , { 22, 33} , { 5, 44} , { 14, 43} , { -1, 78} , { 0, 60} , { 9, 69} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cb in the 4:4:4 common mode + { { -2, 85} , { -6, 78} , { -1, 75} , { -7, 77} , { 2, 54} , { 5, 50} , { -3, 68} , { 1, 50} , { 6, 42} , { -4, 81} , { 1, 63} , { -4, 70} , { 0, 67} , { 2, 57} , { -2, 76} }, + { CTX_UNUSED , { 11, 35} , { 4, 64} , { 1, 61} , { 11, 35} , { 18, 25} , { 12, 24} , { 13, 29} , { 13, 36} , { -10, 93} , { -7, 73} , { -2, 73} , { 13, 46} , { 9, 49} , { -7, 100} }, + { { -4, 79} , { -7, 71} , { -5, 69} , { -9, 70} , { -8, 66} , { -10, 68} , { -19, 73} , { -12, 69} , { -16, 70} , { -15, 67} , { -20, 62} , { -19, 70} , { -16, 66} , { -22, 65} , { -20, 63} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 9, 53} , { 2, 53} , { 5, 53} , { -2, 61} , { 0, 56} , { 0, 56} , { -13, 63} , { -5, 60} , { -1, 62} , { 4, 57} , { -6, 69} , { 4, 57} , { 14, 39} , { 4, 51} , { 13, 68} }, + //Cr in the 4:4:4 common mode + { { -2, 85} , { -6, 78} , { -1, 75} , { -7, 77} , { 2, 54} , { 5, 50} , { -3, 68} , { 1, 50} , { 6, 42} , { -4, 81} , { 1, 63} , { -4, 70} , { 0, 67} , { 2, 57} , { -2, 76} }, + { CTX_UNUSED , { 11, 35} , { 4, 64} , { 1, 61} , { 11, 35} , { 18, 25} , { 12, 24} , { 13, 29} , { 13, 36} , { -10, 93} , { -7, 73} , { -2, 73} , { 13, 46} , { 9, 49} , { -7, 100} }, + { { -4, 79} , { -7, 71} , { -5, 69} , { -9, 70} , { -8, 66} , { -10, 68} , { -19, 73} , { -12, 69} , { -16, 70} , { -15, 67} , { -20, 62} , { -19, 70} , { -16, 66} , { -22, 65} , { -20, 63} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 9, 53} , { 2, 53} , { 5, 53} , { -2, 61} , { 0, 56} , { 0, 56} , { -13, 63} , { -5, 60} , { -1, 62} , { 4, 57} , { -6, 69} , { 4, 57} , { 14, 39} , { 4, 51} , { 13, 68} } + }, + //----- model 1 ----- + { + { { -13, 103} , { -13, 91} , { -9, 89} , { -14, 92} , { -8, 76} , { -12, 87} , { -23, 110} , { -24, 105} , { -10, 78} , { -20, 112} , { -17, 99} , { -78, 127} , { -70, 127} , { -50, 127} , { -46, 127} }, + { CTX_UNUSED , { -4, 66} , { -5, 78} , { -4, 71} , { -8, 72} , { 2, 59} , { -1, 55} , { -7, 70} , { -6, 75} , { -8, 89} , { -34, 119} , { -3, 75} , { 32, 20} , { 30, 22} , { -44, 127} }, + { { -5, 85} , { -6, 81} , { -10, 77} , { -7, 81} , { -17, 80} , { -18, 73} , { -4, 74} , { -10, 83} , { -9, 71} , { -9, 67} , { -1, 61} , { -8, 66} , { -14, 66} , { 0, 59} , { 2, 59} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 0, 54} , { -5, 61} , { 0, 58} , { -1, 60} , { -3, 61} , { -8, 67} , { -25, 84} , { -14, 74} , { -5, 65} , { 5, 52} , { 2, 57} , { 0, 61} , { -9, 69} , { -11, 70} , { 18, 55} }, + { { -4, 71} , { 0, 58} , { 7, 61} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , { 9, 41} , { 18, 25} , { 9, 32} , { 5, 43} , { 9, 47} , { 0, 44} , { 0, 51} , { 2, 46} , { 19, 38} , { -4, 66} , { 15, 38} , { 12, 42} , { 9, 34} , { 0, 89} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cb in the 4:4:4 common mode + { { -13, 103} , { -13, 91} , { -9, 89} , { -14, 92} , { -8, 76} , { -12, 87} , { -23, 110} , { -24, 105} , { -10, 78} , { -20, 112} , { -17, 99} , { -78, 127} , { -70, 127} , { -50, 127} , { -46, 127} }, + { CTX_UNUSED , { -4, 66} , { -5, 78} , { -4, 71} , { -8, 72} , { 2, 59} , { -1, 55} , { -7, 70} , { -6, 75} , { -8, 89} , { -34, 119} , { -3, 75} , { 32, 20} , { 30, 22} , { -44, 127} }, + { { -5, 85} , { -6, 81} , { -10, 77} , { -7, 81} , { -17, 80} , { -18, 73} , { -4, 74} , { -10, 83} , { -9, 71} , { -9, 67} , { -1, 61} , { -8, 66} , { -14, 66} , { 0, 59} , { 2, 59} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 0, 54} , { -5, 61} , { 0, 58} , { -1, 60} , { -3, 61} , { -8, 67} , { -25, 84} , { -14, 74} , { -5, 65} , { 5, 52} , { 2, 57} , { 0, 61} , { -9, 69} , { -11, 70} , { 18, 55} }, + //Cr in the 4:4:4 common mode + { { -13, 103} , { -13, 91} , { -9, 89} , { -14, 92} , { -8, 76} , { -12, 87} , { -23, 110} , { -24, 105} , { -10, 78} , { -20, 112} , { -17, 99} , { -78, 127} , { -70, 127} , { -50, 127} , { -46, 127} }, + { CTX_UNUSED , { -4, 66} , { -5, 78} , { -4, 71} , { -8, 72} , { 2, 59} , { -1, 55} , { -7, 70} , { -6, 75} , { -8, 89} , { -34, 119} , { -3, 75} , { 32, 20} , { 30, 22} , { -44, 127} }, + { { -5, 85} , { -6, 81} , { -10, 77} , { -7, 81} , { -17, 80} , { -18, 73} , { -4, 74} , { -10, 83} , { -9, 71} , { -9, 67} , { -1, 61} , { -8, 66} , { -14, 66} , { 0, 59} , { 2, 59} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 0, 54} , { -5, 61} , { 0, 58} , { -1, 60} , { -3, 61} , { -8, 67} , { -25, 84} , { -14, 74} , { -5, 65} , { 5, 52} , { 2, 57} , { 0, 61} , { -9, 69} , { -11, 70} , { 18, 55} } + }, + //----- model 2 ----- + { + { { -4, 86} , { -12, 88} , { -5, 82} , { -3, 72} , { -4, 67} , { -8, 72} , { -16, 89} , { -9, 69} , { -1, 59} , { 5, 66} , { 4, 57} , { -4, 71} , { -2, 71} , { 2, 58} , { -1, 74} }, + { CTX_UNUSED , { -4, 44} , { -1, 69} , { 0, 62} , { -7, 51} , { -4, 47} , { -6, 42} , { -3, 41} , { -6, 53} , { 8, 76} , { -9, 78} , { -11, 83} , { 9, 52} , { 0, 67} , { -5, 90} }, + { { -3, 78} , { -8, 74} , { -9, 72} , { -10, 72} , { -18, 75} , { -12, 71} , { -11, 63} , { -5, 70} , { -17, 75} , { -14, 72} , { -16, 67} , { -8, 53} , { -14, 59} , { -9, 52} , { -11, 68} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 1, 67} , { -15, 72} , { -5, 75} , { -8, 80} , { -21, 83} , { -21, 64} , { -13, 31} , { -25, 64} , { -29, 94} , { 9, 75} , { 17, 63} , { -8, 74} , { -5, 35} , { -2, 27} , { 13, 91} }, + { { 3, 65} , { -7, 69} , { 8, 77} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , { -10, 66} , { 3, 62} , { -3, 68} , { -20, 81} , { 0, 30} , { 1, 7} , { -3, 23} , { -21, 74} , { 16, 66} , { -23, 124} , { 17, 37} , { 44, -18} , { 50, -34} , { -22, 127} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cb in the 4:4:4 common mode + { { -4, 86} , { -12, 88} , { -5, 82} , { -3, 72} , { -4, 67} , { -8, 72} , { -16, 89} , { -9, 69} , { -1, 59} , { 5, 66} , { 4, 57} , { -4, 71} , { -2, 71} , { 2, 58} , { -1, 74} }, + { CTX_UNUSED , { -4, 44} , { -1, 69} , { 0, 62} , { -7, 51} , { -4, 47} , { -6, 42} , { -3, 41} , { -6, 53} , { 8, 76} , { -9, 78} , { -11, 83} , { 9, 52} , { 0, 67} , { -5, 90} }, + { { -3, 78} , { -8, 74} , { -9, 72} , { -10, 72} , { -18, 75} , { -12, 71} , { -11, 63} , { -5, 70} , { -17, 75} , { -14, 72} , { -16, 67} , { -8, 53} , { -14, 59} , { -9, 52} , { -11, 68} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 1, 67} , { -15, 72} , { -5, 75} , { -8, 80} , { -21, 83} , { -21, 64} , { -13, 31} , { -25, 64} , { -29, 94} , { 9, 75} , { 17, 63} , { -8, 74} , { -5, 35} , { -2, 27} , { 13, 91} }, + //Cr in the 4:4:4 common mode + { { -4, 86} , { -12, 88} , { -5, 82} , { -3, 72} , { -4, 67} , { -8, 72} , { -16, 89} , { -9, 69} , { -1, 59} , { 5, 66} , { 4, 57} , { -4, 71} , { -2, 71} , { 2, 58} , { -1, 74} }, + { CTX_UNUSED , { -4, 44} , { -1, 69} , { 0, 62} , { -7, 51} , { -4, 47} , { -6, 42} , { -3, 41} , { -6, 53} , { 8, 76} , { -9, 78} , { -11, 83} , { 9, 52} , { 0, 67} , { -5, 90} }, + { { -3, 78} , { -8, 74} , { -9, 72} , { -10, 72} , { -18, 75} , { -12, 71} , { -11, 63} , { -5, 70} , { -17, 75} , { -14, 72} , { -16, 67} , { -8, 53} , { -14, 59} , { -9, 52} , { -11, 68} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 1, 67} , { -15, 72} , { -5, 75} , { -8, 80} , { -21, 83} , { -21, 64} , { -13, 31} , { -25, 64} , { -29, 94} , { 9, 75} , { 17, 63} , { -8, 74} , { -5, 35} , { -2, 27} , { 13, 91} } + } +}; + +static const char INIT_LAST_I[1][22][15][2] = +{ + //----- model 0 ----- + { + { { 24, 0} , { 15, 9} , { 8, 25} , { 13, 18} , { 15, 9} , { 13, 19} , { 10, 37} , { 12, 18} , { 6, 29} , { 20, 33} , { 15, 30} , { 4, 45} , { 1, 58} , { 0, 62} , { 7, 61} }, + { CTX_UNUSED , { 12, 38} , { 11, 45} , { 15, 39} , { 11, 42} , { 13, 44} , { 16, 45} , { 12, 41} , { 10, 49} , { 30, 34} , { 18, 42} , { 10, 55} , { 17, 51} , { 17, 46} , { 0, 89} }, + { { 23, -13} , { 26, -13} , { 40, -15} , { 49, -14} , { 44, 3} , { 45, 6} , { 44, 34} , { 33, 54} , { 19, 82} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 26, -19} , { 22, -17} , { 26, -17} , { 30, -25} , { 28, -20} , { 33, -23} , { 37, -27} , { 33, -23} , { 40, -28} , { 38, -17} , { 33, -11} , { 40, -15} , { 41, -6} , { 38, 1} , { 41, 17} }, + { { 30, -6} , { 27, 3} , { 26, 22} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , { 37, -16} , { 35, -4} , { 38, -8} , { 38, -3} , { 37, 3} , { 38, 5} , { 42, 0} , { 35, 16} , { 39, 22} , { 14, 48} , { 27, 37} , { 21, 60} , { 12, 68} , { 2, 97} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cb in the 4:4:4 common mode + { { 24, 0} , { 15, 9} , { 8, 25} , { 13, 18} , { 15, 9} , { 13, 19} , { 10, 37} , { 12, 18} , { 6, 29} , { 20, 33} , { 15, 30} , { 4, 45} , { 1, 58} , { 0, 62} , { 7, 61} }, + { CTX_UNUSED , { 12, 38} , { 11, 45} , { 15, 39} , { 11, 42} , { 13, 44} , { 16, 45} , { 12, 41} , { 10, 49} , { 30, 34} , { 18, 42} , { 10, 55} , { 17, 51} , { 17, 46} , { 0, 89} }, + { { 23, -13} , { 26, -13} , { 40, -15} , { 49, -14} , { 44, 3} , { 45, 6} , { 44, 34} , { 33, 54} , { 19, 82} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 26, -19} , { 22, -17} , { 26, -17} , { 30, -25} , { 28, -20} , { 33, -23} , { 37, -27} , { 33, -23} , { 40, -28} , { 38, -17} , { 33, -11} , { 40, -15} , { 41, -6} , { 38, 1} , { 41, 17} }, + //Cr in the 4:4:4 common mode + { { 24, 0} , { 15, 9} , { 8, 25} , { 13, 18} , { 15, 9} , { 13, 19} , { 10, 37} , { 12, 18} , { 6, 29} , { 20, 33} , { 15, 30} , { 4, 45} , { 1, 58} , { 0, 62} , { 7, 61} }, + { CTX_UNUSED , { 12, 38} , { 11, 45} , { 15, 39} , { 11, 42} , { 13, 44} , { 16, 45} , { 12, 41} , { 10, 49} , { 30, 34} , { 18, 42} , { 10, 55} , { 17, 51} , { 17, 46} , { 0, 89} }, + { { 23, -13} , { 26, -13} , { 40, -15} , { 49, -14} , { 44, 3} , { 45, 6} , { 44, 34} , { 33, 54} , { 19, 82} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 26, -19} , { 22, -17} , { 26, -17} , { 30, -25} , { 28, -20} , { 33, -23} , { 37, -27} , { 33, -23} , { 40, -28} , { 38, -17} , { 33, -11} , { 40, -15} , { 41, -6} , { 38, 1} , { 41, 17} } + } +}; + +static const char INIT_LAST_P[3][22][15][2] = +{ + //----- model 0 ----- + { + { { 11, 28} , { 2, 40} , { 3, 44} , { 0, 49} , { 0, 46} , { 2, 44} , { 2, 51} , { 0, 47} , { 4, 39} , { 2, 62} , { 6, 46} , { 0, 54} , { 3, 54} , { 2, 58} , { 4, 63} }, + { CTX_UNUSED , { 6, 51} , { 6, 57} , { 7, 53} , { 6, 52} , { 6, 55} , { 11, 45} , { 14, 36} , { 8, 53} , { -1, 82} , { 7, 55} , { -3, 78} , { 15, 46} , { 22, 31} , { -1, 84} }, + { { 9, -2} , { 26, -9} , { 33, -9} , { 39, -7} , { 41, -2} , { 45, 3} , { 49, 9} , { 45, 27} , { 36, 59} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 25, 7} , { 30, -7} , { 28, 3} , { 28, 4} , { 32, 0} , { 34, -1} , { 30, 6} , { 30, 6} , { 32, 9} , { 31, 19} , { 26, 27} , { 26, 30} , { 37, 20} , { 28, 34} , { 17, 70} }, + { { 1, 67} , { 5, 59} , { 9, 67} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , { 16, 30} , { 18, 32} , { 18, 35} , { 22, 29} , { 24, 31} , { 23, 38} , { 18, 43} , { 20, 41} , { 11, 63} , { 9, 59} , { 9, 64} , { -1, 94} , { -2, 89} , { -9, 108} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cb in the 4:4:4 common mode + { { 11, 28} , { 2, 40} , { 3, 44} , { 0, 49} , { 0, 46} , { 2, 44} , { 2, 51} , { 0, 47} , { 4, 39} , { 2, 62} , { 6, 46} , { 0, 54} , { 3, 54} , { 2, 58} , { 4, 63} }, + { CTX_UNUSED , { 6, 51} , { 6, 57} , { 7, 53} , { 6, 52} , { 6, 55} , { 11, 45} , { 14, 36} , { 8, 53} , { -1, 82} , { 7, 55} , { -3, 78} , { 15, 46} , { 22, 31} , { -1, 84} }, + { { 9, -2} , { 26, -9} , { 33, -9} , { 39, -7} , { 41, -2} , { 45, 3} , { 49, 9} , { 45, 27} , { 36, 59} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 25, 7} , { 30, -7} , { 28, 3} , { 28, 4} , { 32, 0} , { 34, -1} , { 30, 6} , { 30, 6} , { 32, 9} , { 31, 19} , { 26, 27} , { 26, 30} , { 37, 20} , { 28, 34} , { 17, 70} }, + //Cr in the 4:4:4 common mode + { { 11, 28} , { 2, 40} , { 3, 44} , { 0, 49} , { 0, 46} , { 2, 44} , { 2, 51} , { 0, 47} , { 4, 39} , { 2, 62} , { 6, 46} , { 0, 54} , { 3, 54} , { 2, 58} , { 4, 63} }, + { CTX_UNUSED , { 6, 51} , { 6, 57} , { 7, 53} , { 6, 52} , { 6, 55} , { 11, 45} , { 14, 36} , { 8, 53} , { -1, 82} , { 7, 55} , { -3, 78} , { 15, 46} , { 22, 31} , { -1, 84} }, + { { 9, -2} , { 26, -9} , { 33, -9} , { 39, -7} , { 41, -2} , { 45, 3} , { 49, 9} , { 45, 27} , { 36, 59} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 25, 7} , { 30, -7} , { 28, 3} , { 28, 4} , { 32, 0} , { 34, -1} , { 30, 6} , { 30, 6} , { 32, 9} , { 31, 19} , { 26, 27} , { 26, 30} , { 37, 20} , { 28, 34} , { 17, 70} } + }, + //----- model 1 ----- + { + { { 4, 45} , { 10, 28} , { 10, 31} , { 33, -11} , { 52, -43} , { 18, 15} , { 28, 0} , { 35, -22} , { 38, -25} , { 34, 0} , { 39, -18} , { 32, -12} , { 102, -94} , { 0, 0} , { 56, -15} }, + { CTX_UNUSED , { 33, -4} , { 29, 10} , { 37, -5} , { 51, -29} , { 39, -9} , { 52, -34} , { 69, -58} , { 67, -63} , { 44, -5} , { 32, 7} , { 55, -29} , { 32, 1} , { 0, 0} , { 27, 36} }, + { { 17, -10} , { 32, -13} , { 42, -9} , { 49, -5} , { 53, 0} , { 64, 3} , { 68, 10} , { 66, 27} , { 47, 57} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 33, -25} , { 34, -30} , { 36, -28} , { 38, -28} , { 38, -27} , { 34, -18} , { 35, -16} , { 34, -14} , { 32, -8} , { 37, -6} , { 35, 0} , { 30, 10} , { 28, 18} , { 26, 25} , { 29, 41} }, + { { 0, 75} , { 2, 72} , { 8, 77} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , { 14, 35} , { 18, 31} , { 17, 35} , { 21, 30} , { 17, 45} , { 20, 42} , { 18, 45} , { 27, 26} , { 16, 54} , { 7, 66} , { 16, 56} , { 11, 73} , { 10, 67} , { -10, 116} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cb in the 4:4:4 common mode + { { 4, 45} , { 10, 28} , { 10, 31} , { 33, -11} , { 52, -43} , { 18, 15} , { 28, 0} , { 35, -22} , { 38, -25} , { 34, 0} , { 39, -18} , { 32, -12} , { 102, -94} , { 0, 0} , { 56, -15} }, + { CTX_UNUSED , { 33, -4} , { 29, 10} , { 37, -5} , { 51, -29} , { 39, -9} , { 52, -34} , { 69, -58} , { 67, -63} , { 44, -5} , { 32, 7} , { 55, -29} , { 32, 1} , { 0, 0} , { 27, 36} }, + { { 17, -10} , { 32, -13} , { 42, -9} , { 49, -5} , { 53, 0} , { 64, 3} , { 68, 10} , { 66, 27} , { 47, 57} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 33, -25} , { 34, -30} , { 36, -28} , { 38, -28} , { 38, -27} , { 34, -18} , { 35, -16} , { 34, -14} , { 32, -8} , { 37, -6} , { 35, 0} , { 30, 10} , { 28, 18} , { 26, 25} , { 29, 41} }, + //Cr in the 4:4:4 common mode + { { 4, 45} , { 10, 28} , { 10, 31} , { 33, -11} , { 52, -43} , { 18, 15} , { 28, 0} , { 35, -22} , { 38, -25} , { 34, 0} , { 39, -18} , { 32, -12} , { 102, -94} , { 0, 0} , { 56, -15} }, + { CTX_UNUSED , { 33, -4} , { 29, 10} , { 37, -5} , { 51, -29} , { 39, -9} , { 52, -34} , { 69, -58} , { 67, -63} , { 44, -5} , { 32, 7} , { 55, -29} , { 32, 1} , { 0, 0} , { 27, 36} }, + { { 17, -10} , { 32, -13} , { 42, -9} , { 49, -5} , { 53, 0} , { 64, 3} , { 68, 10} , { 66, 27} , { 47, 57} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 33, -25} , { 34, -30} , { 36, -28} , { 38, -28} , { 38, -27} , { 34, -18} , { 35, -16} , { 34, -14} , { 32, -8} , { 37, -6} , { 35, 0} , { 30, 10} , { 28, 18} , { 26, 25} , { 29, 41} } + }, + //----- model 2 ----- + { + { { 4, 39} , { 0, 42} , { 7, 34} , { 11, 29} , { 8, 31} , { 6, 37} , { 7, 42} , { 3, 40} , { 8, 33} , { 13, 43} , { 13, 36} , { 4, 47} , { 3, 55} , { 2, 58} , { 6, 60} }, + { CTX_UNUSED , { 8, 44} , { 11, 44} , { 14, 42} , { 7, 48} , { 4, 56} , { 4, 52} , { 13, 37} , { 9, 49} , { 19, 58} , { 10, 48} , { 12, 45} , { 0, 69} , { 20, 33} , { 8, 63} }, + { { 9, -2} , { 30, -10} , { 31, -4} , { 33, -1} , { 33, 7} , { 31, 12} , { 37, 23} , { 31, 38} , { 20, 64} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 35, -18} , { 33, -25} , { 28, -3} , { 24, 10} , { 27, 0} , { 34, -14} , { 52, -44} , { 39, -24} , { 19, 17} , { 31, 25} , { 36, 29} , { 24, 33} , { 34, 15} , { 30, 20} , { 22, 73} }, + { { 20, 34} , { 19, 31} , { 27, 44} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , { 19, 16} , { 15, 36} , { 15, 36} , { 21, 28} , { 25, 21} , { 30, 20} , { 31, 12} , { 27, 16} , { 24, 42} , { 0, 93} , { 14, 56} , { 15, 57} , { 26, 38} , { -24, 127} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cb in the 4:4:4 common mode + { { 4, 39} , { 0, 42} , { 7, 34} , { 11, 29} , { 8, 31} , { 6, 37} , { 7, 42} , { 3, 40} , { 8, 33} , { 13, 43} , { 13, 36} , { 4, 47} , { 3, 55} , { 2, 58} , { 6, 60} }, + { CTX_UNUSED , { 8, 44} , { 11, 44} , { 14, 42} , { 7, 48} , { 4, 56} , { 4, 52} , { 13, 37} , { 9, 49} , { 19, 58} , { 10, 48} , { 12, 45} , { 0, 69} , { 20, 33} , { 8, 63} }, + { { 9, -2} , { 30, -10} , { 31, -4} , { 33, -1} , { 33, 7} , { 31, 12} , { 37, 23} , { 31, 38} , { 20, 64} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 35, -18} , { 33, -25} , { 28, -3} , { 24, 10} , { 27, 0} , { 34, -14} , { 52, -44} , { 39, -24} , { 19, 17} , { 31, 25} , { 36, 29} , { 24, 33} , { 34, 15} , { 30, 20} , { 22, 73} }, + //Cr in the 4:4:4 common mode + { { 4, 39} , { 0, 42} , { 7, 34} , { 11, 29} , { 8, 31} , { 6, 37} , { 7, 42} , { 3, 40} , { 8, 33} , { 13, 43} , { 13, 36} , { 4, 47} , { 3, 55} , { 2, 58} , { 6, 60} }, + { CTX_UNUSED , { 8, 44} , { 11, 44} , { 14, 42} , { 7, 48} , { 4, 56} , { 4, 52} , { 13, 37} , { 9, 49} , { 19, 58} , { 10, 48} , { 12, 45} , { 0, 69} , { 20, 33} , { 8, 63} }, + { { 9, -2} , { 30, -10} , { 31, -4} , { 33, -1} , { 33, 7} , { 31, 12} , { 37, 23} , { 31, 38} , { 20, 64} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 35, -18} , { 33, -25} , { 28, -3} , { 24, 10} , { 27, 0} , { 34, -14} , { 52, -44} , { 39, -24} , { 19, 17} , { 31, 25} , { 36, 29} , { 24, 33} , { 34, 15} , { 30, 20} , { 22, 73} } + } +}; + +static const char INIT_ONE_I[1][22][5][2] = +{ + //----- model 0 ----- + { + { { -3, 71} , { -6, 42} , { -5, 50} , { -3, 54} , { -2, 62} }, + { { -5, 67} , { -5, 27} , { -3, 39} , { -2, 44} , { 0, 46} }, + { { -3, 75} , { -1, 23} , { 1, 34} , { 1, 43} , { 0, 54} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -12, 92} , { -15, 55} , { -10, 60} , { -6, 62} , { -4, 65} }, + { { -11, 97} , { -20, 84} , { -11, 79} , { -6, 73} , { -4, 74} }, + { { -8, 78} , { -5, 33} , { -4, 48} , { -2, 53} , { -3, 62} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cb in the 4:4:4 common mode + { { -3, 71} , { -6, 42} , { -5, 50} , { -3, 54} , { -2, 62} }, + { { -5, 67} , { -5, 27} , { -3, 39} , { -2, 44} , { 0, 46} }, + { { -3, 75} , { -1, 23} , { 1, 34} , { 1, 43} , { 0, 54} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -12, 92} , { -15, 55} , { -10, 60} , { -6, 62} , { -4, 65} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cr in the 4:4:4 common mode + { { -3, 71} , { -6, 42} , { -5, 50} , { -3, 54} , { -2, 62} }, + { { -5, 67} , { -5, 27} , { -3, 39} , { -2, 44} , { 0, 46} }, + { { -3, 75} , { -1, 23} , { 1, 34} , { 1, 43} , { 0, 54} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -12, 92} , { -15, 55} , { -10, 60} , { -6, 62} , { -4, 65} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + } +}; + +static const char INIT_ONE_P[3][22][5][2] = +{ + //----- model 0 ----- + { + { { -6, 76} , { -2, 44} , { 0, 45} , { 0, 52} , { -3, 64} }, + { { -9, 77} , { 3, 24} , { 0, 42} , { 0, 48} , { 0, 55} }, + { { -6, 66} , { -7, 35} , { -7, 42} , { -8, 45} , { -5, 48} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 1, 58} , { -3, 29} , { -1, 36} , { 1, 38} , { 2, 43} }, + { { 0, 70} , { -4, 29} , { 5, 31} , { 7, 42} , { 1, 59} }, + { { 0, 58} , { 8, 5} , { 10, 14} , { 14, 18} , { 13, 27} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cb in the 4:4:4 common mode + { { -6, 76} , { -2, 44} , { 0, 45} , { 0, 52} , { -3, 64} }, + { { -9, 77} , { 3, 24} , { 0, 42} , { 0, 48} , { 0, 55} }, + { { -6, 66} , { -7, 35} , { -7, 42} , { -8, 45} , { -5, 48} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 1, 58} , { -3, 29} , { -1, 36} , { 1, 38} , { 2, 43} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cr in the 4:4:4 common mode + { { -6, 76} , { -2, 44} , { 0, 45} , { 0, 52} , { -3, 64} }, + { { -9, 77} , { 3, 24} , { 0, 42} , { 0, 48} , { 0, 55} }, + { { -6, 66} , { -7, 35} , { -7, 42} , { -8, 45} , { -5, 48} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 1, 58} , { -3, 29} , { -1, 36} , { 1, 38} , { 2, 43} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + }, + //----- model 1 ----- + { + { { -23, 112} , { -15, 71} , { -7, 61} , { 0, 53} , { -5, 66} }, + { { -21, 101} , { -3, 39} , { -5, 53} , { -7, 61} , { -11, 75} }, + { { -5, 71} , { 0, 24} , { -1, 36} , { -2, 42} , { -2, 52} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -11, 76} , { -10, 44} , { -10, 52} , { -10, 57} , { -9, 58} }, + { { 2, 66} , { -9, 34} , { 1, 32} , { 11, 31} , { 5, 52} }, + { { 3, 52} , { 7, 4} , { 10, 8} , { 17, 8} , { 16, 19} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cb in the 4:4:4 common mode + { { -23, 112} , { -15, 71} , { -7, 61} , { 0, 53} , { -5, 66} }, + { { -21, 101} , { -3, 39} , { -5, 53} , { -7, 61} , { -11, 75} }, + { { -5, 71} , { 0, 24} , { -1, 36} , { -2, 42} , { -2, 52} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -11, 76} , { -10, 44} , { -10, 52} , { -10, 57} , { -9, 58} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cr in the 4:4:4 common mode + { { -23, 112} , { -15, 71} , { -7, 61} , { 0, 53} , { -5, 66} }, + { { -21, 101} , { -3, 39} , { -5, 53} , { -7, 61} , { -11, 75} }, + { { -5, 71} , { 0, 24} , { -1, 36} , { -2, 42} , { -2, 52} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -11, 76} , { -10, 44} , { -10, 52} , { -10, 57} , { -9, 58} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + }, + //----- model 2 ----- + { + { { -24, 115} , { -22, 82} , { -9, 62} , { 0, 53} , { 0, 59} }, + { { -21, 100} , { -14, 57} , { -12, 67} , { -11, 71} , { -10, 77} }, + { { -9, 71} , { -7, 37} , { -8, 44} , { -11, 49} , { -10, 56} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -10, 82} , { -8, 48} , { -8, 61} , { -8, 66} , { -7, 70} }, + { { -4, 79} , { -22, 69} , { -16, 75} , { -2, 58} , { 1, 58} }, + { { -13, 81} , { -6, 38} , { -13, 62} , { -6, 58} , { -2, 59} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cb in the 4:4:4 common mode + { { -24, 115} , { -22, 82} , { -9, 62} , { 0, 53} , { 0, 59} }, + { { -21, 100} , { -14, 57} , { -12, 67} , { -11, 71} , { -10, 77} }, + { { -9, 71} , { -7, 37} , { -8, 44} , { -11, 49} , { -10, 56} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -10, 82} , { -8, 48} , { -8, 61} , { -8, 66} , { -7, 70} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cr in the 4:4:4 common mode + { { -24, 115} , { -22, 82} , { -9, 62} , { 0, 53} , { 0, 59} }, + { { -21, 100} , { -14, 57} , { -12, 67} , { -11, 71} , { -10, 77} }, + { { -9, 71} , { -7, 37} , { -8, 44} , { -11, 49} , { -10, 56} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -10, 82} , { -8, 48} , { -8, 61} , { -8, 66} , { -7, 70} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + } +}; + +static const char INIT_ABS_I[1][22][5][2] = +{ + //----- model 0 ----- + { + { { 0, 58} , { 1, 63} , { -2, 72} , { -1, 74} , { -9, 91} }, + { { -16, 64} , { -8, 68} , { -10, 78} , { -6, 77} , { -10, 86} }, + { { -2, 55} , { 0, 61} , { 1, 64} , { 0, 68} , { -9, 92} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -12, 73} , { -8, 76} , { -7, 80} , { -9, 88} , { -17, 110} }, + { { -13, 86} , { -13, 96} , { -11, 97} , { -19, 117} , CTX_UNUSED }, + { { -13, 71} , { -10, 79} , { -12, 86} , { -13, 90} , { -14, 97} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cb in the 4:4:4 common mode + { { 0, 58} , { 1, 63} , { -2, 72} , { -1, 74} , { -9, 91} }, + { { -16, 64} , { -8, 68} , { -10, 78} , { -6, 77} , { -10, 86} }, + { { -2, 55} , { 0, 61} , { 1, 64} , { 0, 68} , { -9, 92} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -12, 73} , { -8, 76} , { -7, 80} , { -9, 88} , { -17, 110} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cr in the 4:4:4 common mode + { { 0, 58} , { 1, 63} , { -2, 72} , { -1, 74} , { -9, 91} }, + { { -16, 64} , { -8, 68} , { -10, 78} , { -6, 77} , { -10, 86} }, + { { -2, 55} , { 0, 61} , { 1, 64} , { 0, 68} , { -9, 92} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -12, 73} , { -8, 76} , { -7, 80} , { -9, 88} , { -17, 110} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + } +}; + +static const char INIT_ABS_P[3][22][5][2] = +{ + //----- model 0 ----- + { + { { -2, 59} , { -4, 70} , { -4, 75} , { -8, 82} , { -17, 102} }, + { { -6, 59} , { -7, 71} , { -12, 83} , { -11, 87} , { -30, 119} }, + { { -12, 56} , { -6, 60} , { -5, 62} , { -8, 66} , { -8, 76} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -6, 55} , { 0, 58} , { 0, 64} , { -3, 74} , { -10, 90} }, + { { -2, 58} , { -3, 72} , { -3, 81} , { -11, 97} , CTX_UNUSED }, + { { 2, 40} , { 0, 58} , { -3, 70} , { -6, 79} , { -8, 85} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cb in the 4:4:4 common mode + { { -2, 59} , { -4, 70} , { -4, 75} , { -8, 82} , { -17, 102} }, + { { -6, 59} , { -7, 71} , { -12, 83} , { -11, 87} , { -30, 119} }, + { { -12, 56} , { -6, 60} , { -5, 62} , { -8, 66} , { -8, 76} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -6, 55} , { 0, 58} , { 0, 64} , { -3, 74} , { -10, 90} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cr in the 4:4:4 common mode + { { -2, 59} , { -4, 70} , { -4, 75} , { -8, 82} , { -17, 102} }, + { { -6, 59} , { -7, 71} , { -12, 83} , { -11, 87} , { -30, 119} }, + { { -12, 56} , { -6, 60} , { -5, 62} , { -8, 66} , { -8, 76} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -6, 55} , { 0, 58} , { 0, 64} , { -3, 74} , { -10, 90} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + }, + //----- model 1 ----- + { + { { -11, 77} , { -9, 80} , { -9, 84} , { -10, 87} , { -34, 127} }, + { { -15, 77} , { -17, 91} , { -25, 107} , { -25, 111} , { -28, 122} }, + { { -9, 57} , { -6, 63} , { -4, 65} , { -4, 67} , { -7, 82} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -16, 72} , { -7, 69} , { -4, 69} , { -5, 74} , { -9, 86} }, + { { -2, 55} , { -2, 67} , { 0, 73} , { -8, 89} , CTX_UNUSED }, + { { 3, 37} , { -1, 61} , { -5, 73} , { -1, 70} , { -4, 78} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cb in the 4:4:4 common mode + { { -11, 77} , { -9, 80} , { -9, 84} , { -10, 87} , { -34, 127} }, + { { -15, 77} , { -17, 91} , { -25, 107} , { -25, 111} , { -28, 122} }, + { { -9, 57} , { -6, 63} , { -4, 65} , { -4, 67} , { -7, 82} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -16, 72} , { -7, 69} , { -4, 69} , { -5, 74} , { -9, 86} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cr in the 4:4:4 common mode + { { -11, 77} , { -9, 80} , { -9, 84} , { -10, 87} , { -34, 127} }, + { { -15, 77} , { -17, 91} , { -25, 107} , { -25, 111} , { -28, 122} }, + { { -9, 57} , { -6, 63} , { -4, 65} , { -4, 67} , { -7, 82} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -16, 72} , { -7, 69} , { -4, 69} , { -5, 74} , { -9, 86} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + }, + //----- model 2 ----- + { + { { -14, 85} , { -13, 89} , { -13, 94} , { -11, 92} , { -29, 127} }, + { { -21, 85} , { -16, 88} , { -23, 104} , { -15, 98} , { -37, 127} }, + { { -12, 59} , { -8, 63} , { -9, 67} , { -6, 68} , { -10, 79} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -14, 75} , { -10, 79} , { -9, 83} , { -12, 92} , { -18, 108} }, + { { -13, 78} , { -9, 83} , { -4, 81} , { -13, 99} , CTX_UNUSED }, + { { -16, 73} , { -10, 76} , { -13, 86} , { -9, 83} , { -10, 87} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cb in the 4:4:4 common mode + { { -14, 85} , { -13, 89} , { -13, 94} , { -11, 92} , { -29, 127} }, + { { -21, 85} , { -16, 88} , { -23, 104} , { -15, 98} , { -37, 127} }, + { { -12, 59} , { -8, 63} , { -9, 67} , { -6, 68} , { -10, 79} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -14, 75} , { -10, 79} , { -9, 83} , { -12, 92} , { -18, 108} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + //Cr in the 4:4:4 common mode + { { -14, 85} , { -13, 89} , { -13, 94} , { -11, 92} , { -29, 127} }, + { { -21, 85} , { -16, 88} , { -23, 104} , { -15, 98} , { -37, 127} }, + { { -12, 59} , { -8, 63} , { -9, 67} , { -6, 68} , { -10, 79} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -14, 75} , { -10, 79} , { -9, 83} , { -12, 92} , { -18, 108} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED } + } +}; + + + +#if ENABLE_FIELD_CTX +static const char INIT_FLD_MAP_I[1][8][15][2] = +{ + //----- model 0 ----- + { + { { -6, 93} , { -6, 84} , { -8, 79} , { 0, 66} , { -1, 71} , { 0, 62} , { -2, 60} , { -2, 59} , { -5, 75} , { -3, 62} , { -4, 58} , { -9, 66} , { -1, 79} , { 0, 71} , { 3, 68} }, + { CTX_UNUSED , { 10, 44} , { -7, 62} , { 15, 36} , { 14, 40} , { 16, 27} , { 12, 29} , { 1, 44} , { 20, 36} , { 18, 32} , { 5, 42} , { 1, 48} , { 10, 62} , { 17, 46} , { 9, 64} }, + { { -14, 106} , { -13, 97} , { -15, 90} , { -12, 90} , { -18, 88} , { -10, 73} , { -9, 79} , { -14, 86} , { -10, 73} , { -10, 70} , { -10, 69} , { -5, 66} , { -9, 64} , { -5, 58} , { 2, 59} }, +// { { -1, 73} , { -7, 73} , { -6, 76} , { -7, 71} , { -9, 72} , { -5, 65} , { -14, 83} , { -8, 72} , { -10, 75} , { -5, 64} , { -4, 59} , { -13, 79} , { -9, 69} , { -8, 66} , { 3, 55} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -12, 104} , { -11, 97} , { -16, 96} , { -7, 88} , { -8, 85} , { -7, 85} , { -9, 85} , { -13, 88} , { 4, 66} , { -3, 77} , { -3, 76} , { -6, 76} , { 10, 58} , { -1, 76} , { -1, 83} }, + { { -7, 99} , { -14, 95} , { 2, 95} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , { 0, 76} , { -5, 74} , { 0, 70} , { -11, 75} , { 1, 68} , { 0, 65} , { -14, 73} , { 3, 62} , { 4, 62} , { -1, 68} , { -13, 75} , { 11, 55} , { 5, 64} , { 12, 70} } + } +}; + +static const char INIT_FLD_MAP_P[3][8][15][2] = +{ + //----- model 0 ----- + { + { { -13, 106} , { -16, 106} , { -10, 87} , { -21, 114} , { -18, 110} , { -14, 98} , { -22, 110} , { -21, 106} , { -18, 103} , { -21, 107} , { -23, 108} , { -26, 112} , { -10, 96} , { -12, 95} , { -5, 91} }, + { CTX_UNUSED , { -9, 93} , { -22, 94} , { -5, 86} , { 9, 67} , { -4, 80} , { -10, 85} , { -1, 70} , { 7, 60} , { 9, 58} , { 5, 61} , { 12, 50} , { 15, 50} , { 18, 49} , { 17, 54} }, + { { -5, 85} , { -6, 81} , { -10, 77} , { -7, 81} , { -17, 80} , { -18, 73} , { -4, 74} , { -10, 83} , { -9, 71} , { -9, 67} , { -1, 61} , { -8, 66} , { -14, 66} , { 0, 59} , { 2, 59} }, +// { { -4, 60} , { -3, 49} , { -2, 50} , { -4, 49} , { -5, 48} , { -2, 46} , { -7, 54} , { -1, 45} , { -4, 49} , { 4, 39} , { 0, 42} , { 2, 43} , { 0, 44} , { 5, 32} , { 15, 30} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 10, 41} , { 7, 46} , { -1, 51} , { 7, 49} , { 8, 52} , { 9, 41} , { 6, 47} , { 2, 55} , { 13, 41} , { 10, 44} , { 6, 50} , { 5, 53} , { 13, 49} , { 4, 63} , { 6, 64} }, + { { -2, 69} , { -2, 59} , { 6, 70} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , { 10, 44} , { 9, 31} , { 12, 43} , { 3, 53} , { 14, 34} , { 10, 38} , { -3, 52} , { 13, 40} , { 17, 32} , { 7, 44} , { 7, 38} , { 13, 50} , { 10, 57} , { 26, 43} } + }, + //----- model 1 ----- + { + { { -21, 126} , { -23, 124} , { -20, 110} , { -26, 126} , { -25, 124} , { -17, 105} , { -27, 121} , { -27, 117} , { -17, 102} , { -26, 117} , { -27, 116} , { -33, 122} , { -10, 95} , { -14, 100} , { -8, 95} }, + { CTX_UNUSED , { -17, 111} , { -28, 114} , { -6, 89} , { -2, 80} , { -4, 82} , { -9, 85} , { -8, 81} , { -1, 72} , { 5, 64} , { 1, 67} , { 9, 56} , { 0, 69} , { 1, 69} , { 7, 69} }, + { { -3, 81} , { -3, 76} , { -7, 72} , { -6, 78} , { -12, 72} , { -14, 68} , { -3, 70} , { -6, 76} , { -5, 66} , { -5, 62} , { 0, 57} , { -4, 61} , { -9, 60} , { 1, 54} , { 2, 58} }, +// { { -4, 60} , { -3, 49} , { -2, 50} , { -4, 49} , { -5, 48} , { -2, 46} , { -7, 54} , { -1, 45} , { -4, 49} , { 4, 39} , { 0, 42} , { 2, 43} , { 0, 44} , { 5, 32} , { 15, 30} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { -7, 69} , { -6, 67} , { -16, 77} , { -2, 64} , { 2, 61} , { -6, 67} , { -3, 64} , { 2, 57} , { -3, 65} , { -3, 66} , { 0, 62} , { 9, 51} , { -1, 66} , { -2, 71} , { -2, 75} }, + { { -1, 70} , { -9, 72} , { 14, 60} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , { 16, 37} , { 0, 47} , { 18, 35} , { 11, 37} , { 12, 41} , { 10, 41} , { 2, 48} , { 12, 41} , { 13, 41} , { 0, 59} , { 3, 50} , { 19, 40} , { 3, 66} , { 18, 50} } + }, + //----- model 2 ----- + { + { { -22, 127} , { -25, 127} , { -25, 120} , { -27, 127} , { -19, 114} , { -23, 117} , { -25, 118} , { -26, 117} , { -24, 113} , { -28, 118} , { -31, 120} , { -37, 124} , { -10, 94} , { -15, 102} , { -10, 99} }, + { CTX_UNUSED , { -13, 106} , { -50, 127} , { -5, 92} , { 17, 57} , { -5, 86} , { -13, 94} , { -12, 91} , { -2, 77} , { 0, 71} , { -1, 73} , { 4, 64} , { -7, 81} , { 5, 64} , { 15, 57} }, + { { -3, 78} , { -8, 74} , { -9, 72} , { -10, 72} , { -18, 75} , { -12, 71} , { -11, 63} , { -5, 70} , { -17, 75} , { -14, 72} , { -16, 67} , { -8, 53} , { -14, 59} , { -9, 52} , { -11, 68} }, +// { { -4, 60} , { -3, 49} , { -2, 50} , { -4, 49} , { -5, 48} , { -2, 46} , { -7, 54} , { -1, 45} , { -4, 49} , { 4, 39} , { 0, 42} , { 2, 43} , { 0, 44} , { 5, 32} , { 15, 30} }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 1, 67} , { 0, 68} , { -10, 67} , { 1, 68} , { 0, 77} , { 2, 64} , { 0, 68} , { -5, 78} , { 7, 55} , { 5, 59} , { 2, 65} , { 14, 54} , { 15, 44} , { 5, 60} , { 2, 70} }, + { { -2, 76} , { -18, 86} , { 12, 70} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , { 5, 64} , { -12, 70} , { 11, 55} , { 5, 56} , { 0, 69} , { 2, 65} , { -6, 74} , { 5, 54} , { 7, 54} , { -6, 76} , { -11, 82} , { -2, 77} , { -2, 77} , { 25, 42} } + } +}; + +static const char INIT_FLD_LAST_I[1][8][15][2] = +{ + //----- model 0 ----- + { + { { 15, 6} , { 6, 19} , { 7, 16} , { 12, 14} , { 18, 13} , { 13, 11} , { 13, 15} , { 15, 16} , { 12, 23} , { 13, 23} , { 15, 20} , { 14, 26} , { 14, 44} , { 17, 40} , { 17, 47} }, + { CTX_UNUSED , { 24, 17} , { 21, 21} , { 25, 22} , { 31, 27} , { 22, 29} , { 19, 35} , { 14, 50} , { 10, 57} , { 7, 63} , { -2, 77} , { -4, 82} , { -3, 94} , { 9, 69} , { -12, 109} }, + { { 21, -10} , { 24, -11} , { 28, -8} , { 28, -1} , { 29, 3} , { 29, 9} , { 35, 20} , { 29, 36} , { 14, 67} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, +// { { 12, 33} , { 5, 38} , { 9, 34} , { 18, 22} , { 19, 22} , { 23, 19} , { 26, 16} , { 14, 44} , { 40, 14} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 36, -35} , { 36, -34} , { 32, -26} , { 37, -30} , { 44, -32} , { 34, -18} , { 34, -15} , { 40, -15} , { 33, -7} , { 35, -5} , { 33, 0} , { 38, 2} , { 33, 13} , { 23, 35} , { 13, 58} }, + { { 29, -3} , { 26, 0} , { 22, 30} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , { 31, -7} , { 35, -15} , { 34, -3} , { 34, 3} , { 36, -1} , { 34, 5} , { 32, 11} , { 35, 5} , { 34, 12} , { 39, 11} , { 30, 29} , { 34, 26} , { 29, 39} , { 19, 66} } + } +}; + +static const char INIT_FLD_LAST_P[3][8][15][2] = +{ + //----- model 0 ----- + { + { { 14, 11} , { 11, 14} , { 9, 11} , { 18, 11} , { 21, 9} , { 23, -2} , { 32, -15} , { 32, -15} , { 34, -21} , { 39, -23} , { 42, -33} , { 41, -31} , { 46, -28} , { 38, -12} , { 21, 29} }, + { CTX_UNUSED , { 45, -24} , { 53, -45} , { 48, -26} , { 65, -43} , { 43, -19} , { 39, -10} , { 30, 9} , { 18, 26} , { 20, 27} , { 0, 57} , { -14, 82} , { -5, 75} , { -19, 97} , { -35, 125} }, + { { 21, -13} , { 33, -14} , { 39, -7} , { 46, -2} , { 51, 2} , { 60, 6} , { 61, 17} , { 55, 34} , { 42, 62} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, +// { { 17, 27} , { 23, 13} , { 24, 16} , { 22, 25} , { 23, 27} , { 23, 32} , { 17, 43} , { 17, 49} , { 2, 70} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 27, 0} , { 28, 0} , { 31, -4} , { 27, 6} , { 34, 8} , { 30, 10} , { 24, 22} , { 33, 19} , { 22, 32} , { 26, 31} , { 21, 41} , { 26, 44} , { 23, 47} , { 16, 65} , { 14, 71} }, + { { 8, 60} , { 6, 63} , { 17, 65} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , { 21, 24} , { 23, 20} , { 26, 23} , { 27, 32} , { 28, 23} , { 28, 24} , { 23, 40} , { 24, 32} , { 28, 29} , { 23, 42} , { 19, 57} , { 22, 53} , { 22, 61} , { 11, 86} } + }, + //----- model 1 ----- + { + { { 19, -6} , { 18, -6} , { 14, 0} , { 26, -12} , { 31, -16} , { 33, -25} , { 33, -22} , { 37, -28} , { 39, -30} , { 42, -30} , { 47, -42} , { 45, -36} , { 49, -34} , { 41, -17} , { 32, 9} }, + { CTX_UNUSED , { 69, -71} , { 63, -63} , { 66, -64} , { 77, -74} , { 54, -39} , { 52, -35} , { 41, -10} , { 36, 0} , { 40, -1} , { 30, 14} , { 28, 26} , { 23, 37} , { 12, 55} , { 11, 65} }, + { { 17, -10} , { 32, -13} , { 42, -9} , { 49, -5} , { 53, 0} , { 64, 3} , { 68, 10} , { 66, 27} , { 47, 57} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, +// { { 17, 27} , { 23, 13} , { 24, 16} , { 22, 25} , { 23, 27} , { 23, 32} , { 17, 43} , { 17, 49} , { 2, 70} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 37, -33} , { 39, -36} , { 40, -37} , { 38, -30} , { 46, -33} , { 42, -30} , { 40, -24} , { 49, -29} , { 38, -12} , { 40, -10} , { 38, -3} , { 46, -5} , { 31, 20} , { 29, 30} , { 25, 44} }, + { { 12, 48} , { 11, 49} , { 26, 45} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , { 22, 22} , { 23, 22} , { 27, 21} , { 33, 20} , { 26, 28} , { 30, 24} , { 27, 34} , { 18, 42} , { 25, 39} , { 18, 50} , { 12, 70} , { 21, 54} , { 14, 71} , { 11, 83} } + }, + //----- model 2 ----- + { + { { 17, -13} , { 16, -9} , { 17, -12} , { 27, -21} , { 37, -30} , { 41, -40} , { 42, -41} , { 48, -47} , { 39, -32} , { 46, -40} , { 52, -51} , { 46, -41} , { 52, -39} , { 43, -19} , { 32, 11} }, + { CTX_UNUSED , { 61, -55} , { 56, -46} , { 62, -50} , { 81, -67} , { 45, -20} , { 35, -2} , { 28, 15} , { 34, 1} , { 39, 1} , { 30, 17} , { 20, 38} , { 18, 45} , { 15, 54} , { 0, 79} }, + { { 9, -2} , { 30, -10} , { 31, -4} , { 33, -1} , { 33, 7} , { 31, 12} , { 37, 23} , { 31, 38} , { 20, 64} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, +// { { 17, 27} , { 23, 13} , { 24, 16} , { 22, 25} , { 23, 27} , { 23, 32} , { 17, 43} , { 17, 49} , { 2, 70} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { { 36, -16} , { 37, -14} , { 37, -17} , { 32, 1} , { 34, 15} , { 29, 15} , { 24, 25} , { 34, 22} , { 31, 16} , { 35, 18} , { 31, 28} , { 33, 41} , { 36, 28} , { 27, 47} , { 21, 62} }, + { { 18, 31} , { 19, 26} , { 36, 24} , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED , CTX_UNUSED }, + { CTX_UNUSED , { 24, 23} , { 27, 16} , { 24, 30} , { 31, 29} , { 22, 41} , { 22, 42} , { 16, 60} , { 15, 52} , { 14, 60} , { 3, 78} , { -16, 123} , { 21, 53} , { 22, 56} , { 25, 61} } + } +}; +#endif + + +#endif + diff --git a/Src/h264dec/lcommon/inc/enc_statistics.h b/Src/h264dec/lcommon/inc/enc_statistics.h new file mode 100644 index 00000000..534a7d4c --- /dev/null +++ b/Src/h264dec/lcommon/inc/enc_statistics.h @@ -0,0 +1,60 @@ +/*! + ************************************************************************** + * \file enc_statistics.h + * + * \brief + * statistics reports for the encoding process. + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Alexis Tourapis <alexismt@ieee.org> + * - Karsten Sühring <suehring@hhi.de> + * + ************************************************************************** + */ + +#ifndef _ENC_STATISTICS_H_ +#define _ENC_STATISTICS_H_ +#include "global.h" + +struct stat_parameters +{ + float bitr; //!< bit rate for current frame, used only for output til terminal + float bitrate; //!< average bit rate for the sequence except first frame + int64 bit_ctr; //!< counter for bit usage + int64 bit_ctr_n; //!< bit usage for the current frame + int64 bit_ctr_emulationprevention; //!< stored bits needed to prevent start code emulation + int bit_slice; //!< number of bits in current slice + int stored_bit_slice; //!< keep number of bits in current slice (to restore status in case of MB re-encoding) + int b8_mode_0_use [NUM_SLICE_TYPES][2]; + int64 mode_use_transform[NUM_SLICE_TYPES][MAXMODE][2]; + int64 intra_chroma_mode[4]; + + // B pictures + int NumberBFrames; + + int frame_counter; + int64 quant [NUM_SLICE_TYPES]; + int64 num_macroblocks [NUM_SLICE_TYPES]; + int frame_ctr [NUM_SLICE_TYPES]; + int64 bit_counter [NUM_SLICE_TYPES]; + float bitrate_st [NUM_SLICE_TYPES]; + int64 mode_use [NUM_SLICE_TYPES][MAXMODE]; //!< Macroblock mode usage for Intra frames + int64 bit_use_mode [NUM_SLICE_TYPES][MAXMODE]; //!< statistics of bit usage + int64 bit_use_mb_type [NUM_SLICE_TYPES]; + int64 bit_use_header [NUM_SLICE_TYPES]; + int64 tmp_bit_use_cbp [NUM_SLICE_TYPES]; + int64 bit_use_coeffC [NUM_SLICE_TYPES]; + int64 bit_use_coeff [3][NUM_SLICE_TYPES]; + int64 bit_use_delta_quant [NUM_SLICE_TYPES]; + int64 bit_use_stuffingBits[NUM_SLICE_TYPES]; + + int bit_ctr_parametersets; + int bit_ctr_parametersets_n; + int64 bit_ctr_filler_data; + int64 bit_ctr_filler_data_n; + +}; +typedef struct stat_parameters StatParameters; + +#endif diff --git a/Src/h264dec/lcommon/inc/frame.h b/Src/h264dec/lcommon/inc/frame.h new file mode 100644 index 00000000..25507d51 --- /dev/null +++ b/Src/h264dec/lcommon/inc/frame.h @@ -0,0 +1,50 @@ + +/*! + ************************************************************************ + * \file frame.h + * + * \brief + * headers for frame format related information + * + * \author + * + ************************************************************************ + */ +#ifndef H264_FRAME_H_ +#define H264_FRAME_H_ +#pragma once + +typedef enum { + CM_UNKNOWN = -1, + CM_YUV = 0, + CM_RGB = 1, + CM_XYZ = 2 +} ColorModel; + +typedef enum { + CF_UNKNOWN = -1, //!< Unknown color format + YUV400 = 0, //!< Monochrome + YUV420 = 1, //!< 4:2:0 + YUV422 = 2, //!< 4:2:2 + YUV444 = 3 //!< 4:4:4 +} ColorFormat; + +typedef struct frame_format +{ + ColorFormat yuv_format; //!< YUV format (0=4:0:0, 1=4:2:0, 2=4:2:2, 3=4:4:4) + int width; //!< luma component frame width + int height; //!< luma component frame height + int height_cr; //!< chroma component frame width + int width_cr; //!< chroma component frame height + int width_crop; //!< width after cropping consideration + int height_crop; //!< height after cropping consideration + int mb_width; //!< luma component frame width + int mb_height; //!< luma component frame height + int size_cmp[3]; //!< component sizes + int size; //!< total image size + int bit_depth[3]; //!< component bit depth + int max_value[3]; //!< component max value + int max_value_sq[3]; //!< component max value squared +} FrameFormat; + +#endif diff --git a/Src/h264dec/lcommon/inc/ifunctions.h b/Src/h264dec/lcommon/inc/ifunctions.h new file mode 100644 index 00000000..0d0e86d8 --- /dev/null +++ b/Src/h264dec/lcommon/inc/ifunctions.h @@ -0,0 +1,251 @@ + +/*! + ************************************************************************ + * \file + * ifunctions.h + * + * \brief + * define some inline functions that are used within the encoder. + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Karsten Sühring <suehring@hhi.de> + * - Alexis Tourapis <alexismt@ieee.org> + * + ************************************************************************ + */ +#ifndef _IFUNCTIONS_H_ +#define _IFUNCTIONS_H_ + +# if !defined(WIN32) && (__STDC_VERSION__ < 199901L) + #define static + #define inline +#endif +#include <math.h> +#include <limits.h> + + +static inline short smin(short a, short b) +{ + return (short) (((a) < (b)) ? (a) : (b)); +} + +static inline short smax(short a, short b) +{ + return (short) (((a) > (b)) ? (a) : (b)); +} + +static inline int imin(int a, int b) +{/* + int retu; + _asm + { + mov eax, a + mov edx, b + cmp edx, eax + cmovle eax, edx + mov retu, eax + } + return retu;*/ + return ((a) < (b)) ? (a) : (b); +} + +static inline int imax(int a, int b) +{ + return ((a) > (b)) ? (a) : (b); +} + +static inline double dmin(double a, double b) +{ + return ((a) < (b)) ? (a) : (b); +} + +static inline double dmax(double a, double b) +{ + return ((a) > (b)) ? (a) : (b); +} + +static inline int64 i64min(int64 a, int64 b) +{ + return ((a) < (b)) ? (a) : (b); +} + +static inline int64 i64max(int64 a, int64 b) +{ + return ((a) > (b)) ? (a) : (b); +} + + +static inline short sabs(short x) +{ + static const short SHORT_BITS = (sizeof(short) * CHAR_BIT) - 1; + short y = (short) (x >> SHORT_BITS); + return (short) ((x ^ y) - y); +} + +static inline int iabs(int x) +{ + static const int INT_BITS = (sizeof(int) * CHAR_BIT) - 1; + int y = x >> INT_BITS; + return (x ^ y) - y; +} + +static inline double dabs(double x) +{ + return ((x) < 0) ? -(x) : (x); +} + +static inline int64 i64abs(int64 x) +{ + static const int64 INT64_BITS = (sizeof(int64) * CHAR_BIT) - 1; + int64 y = x >> INT64_BITS; + return (x ^ y) - y; +} + +static inline double dabs2(double x) +{ + return (x) * (x); +} + +static inline int iabs2(int x) +{ + return (x) * (x); +} + +static inline int64 i64abs2(int64 x) +{ + return (x) * (x); +} + +static inline int isign(int x) +{ + return ( (x > 0) - (x < 0)); +} + +static inline int isignab(int a, int b) +{ + return ((b) < 0) ? -iabs(a) : iabs(a); +} + +static inline int rshift_rnd(int x, int a) +{ + return (a > 0) ? ((x + (1 << (a-1) )) >> a) : (x << (-a)); +} + +static inline int rshift_rnd_pos(int x, int a) +{ + return (x + (1 << (a-1) )) >> a; +} + +// flip a before calling +static inline int rshift_rnd_nonpos(int x, int a) +{ + return (x << a); +} + +static inline int rshift_rnd_sign(int x, int a) +{ + return (x > 0) ? ( ( x + (1 << (a-1)) ) >> a ) : (-( ( iabs(x) + (1 << (a-1)) ) >> a )); +} + +static inline unsigned int rshift_rnd_us(unsigned int x, unsigned int a) +{ + return (a > 0) ? ((x + (1 << (a-1))) >> a) : x; +} + +static inline int rshift_rnd_sf(int x, int a) +{ + return ((x + (1 << (a-1) )) >> a); +} + +static inline unsigned int rshift_rnd_us_sf(unsigned int x, unsigned int a) +{ + return ((x + (1 << (a-1))) >> a); +} + +static inline int iClip1(int high, int x) +{ + if (x < 0) + return 0; + if (x > high) + return high; + return x; + /* old: + x = imax(x, 0); + x = imin(x, high); + + return x;*/ +} + +static inline int iClip3(int low, int high, int x) +{ + if (x < low) + return low; + if (x > high) + return high; + return x; + /* old: + x = imax(x, low); + x = imin(x, high); + + return x;*/ +} + +static inline short sClip3(short low, short high, short x) +{ + x = smax(x, low); + x = smin(x, high); + + return x; +} + +static inline double dClip3(double low, double high, double x) +{ + x = dmax(x, low); + x = dmin(x, high); + + return x; +} + +static inline int weighted_cost(int factor, int bits) +{ + return (((factor)*(bits))>>LAMBDA_ACCURACY_BITS); +} + +static inline int RSD(int x) +{ + return ((x&2)?(x|1):(x&(~1))); +} + +static inline int power2(int x) +{ + return 1 << (x); +} + +static inline int float2int (float x) +{ + return (int)((x < 0) ? (x - 0.5f) : (x + 0.5f)); +} + + + +#if ZEROSNR +static inline float psnr(int max_sample_sq, int samples, float sse_distortion ) +{ + return (float) (10.0 * log10(max_sample_sq * (double) ((double) samples / (sse_distortion < 1.0 ? 1.0 : sse_distortion)))); +} +#else +static inline float psnr(int max_sample_sq, int samples, float sse_distortion ) +{ + return (float) (sse_distortion == 0.0 ? 0.0 : (10.0 * log10(max_sample_sq * (double) ((double) samples / sse_distortion)))); +} +#endif + + +# if !defined(WIN32) && (__STDC_VERSION__ < 199901L) + #undef static + #undef inline +#endif + +#endif + diff --git a/Src/h264dec/lcommon/inc/img_io.h b/Src/h264dec/lcommon/inc/img_io.h new file mode 100644 index 00000000..7d57d03f --- /dev/null +++ b/Src/h264dec/lcommon/inc/img_io.h @@ -0,0 +1,28 @@ +/*! + ************************************************************************************* + * \file img_io.h + * + * \brief + * image I/O related functions + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Alexis Michael Tourapis <alexismt@ieee.org> + ************************************************************************************* + */ +#include "global.h" + +#ifndef _IMG_IO_H_ +#define _IMG_IO_H_ + +#include "io_video.h" + +extern int ParseSizeFromString (VideoDataFile *input_file, int *xlen, int *ylen, double *fps); +extern void ParseFrameNoFormatFromString (VideoDataFile *input_file); +extern void OpenFrameFile (VideoDataFile *input_file, int FrameNumberInFile); +extern void OpenFiles (VideoDataFile *input_file); +extern void CloseFiles (VideoDataFile *input_file); +extern VideoFileType ParseVideoType (VideoDataFile *input_file); + +#endif + diff --git a/Src/h264dec/lcommon/inc/mb_access.h b/Src/h264dec/lcommon/inc/mb_access.h new file mode 100644 index 00000000..0bad3bca --- /dev/null +++ b/Src/h264dec/lcommon/inc/mb_access.h @@ -0,0 +1,70 @@ + +/*! + ************************************************************************************* + * \file mb_access.h + * + * \brief + * Functions for macroblock neighborhoods + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Karsten Sühring <suehring@hhi.de> + * - Alexis Michael Tourapis <alexismt@ieee.org> + ************************************************************************************* + */ + +#ifndef _MB_ACCESS_H_ +#define _MB_ACCESS_H_ + +extern void CheckAvailabilityOfNeighbors(Macroblock *currMB); + +/* MB Aff */ +extern void getAffNeighbour (const Macroblock *currMB, int xN, int yN, const int mb_size[2], PixelPos *pix); +extern void getAffNeighbourLuma (const Macroblock *currMB, int xN, int yN, PixelPos *pix); +extern void getAffNeighbourXPLuma (const Macroblock *currMB, int xN, int yN, PixelPos *pix); +extern void getAffNeighbourPPLumaNB (const Macroblock *currMB, int xN, int yN, PixelPos *pix); +extern void getAffNeighbourNPLuma (const Macroblock *currMB, int yN, PixelPos *pix); +extern void getAffNeighbourN0Luma (const Macroblock *currMB, PixelPos *pix); +extern void getAffNeighbourNXLuma (const Macroblock *currMB, int xN, PixelPos *pix); +extern void getAffNeighbour0X (const Macroblock *currMB, int yN, const int mb_size[2], PixelPos *pix); +extern void getAffNeighbour0XLuma (const Macroblock *currMB, int yN, PixelPos *pix); +extern void getAffNeighbour0N (const Macroblock *currMB, const int mb_size[2], PixelPos *pix); +extern void getAffNeighbourX0 (const Macroblock *currMB, int xN, const int mb_size[2], PixelPos *pix); +extern void getAffNeighbourNX (const Macroblock *currMB, int yN, const int mb_size[2], PixelPos *pix); +extern void getAffNeighbourN0 (const Macroblock *currMB, const int mb_size[2], PixelPos *pix); +extern void getAffNeighbour0NLuma (const Macroblock *currMB, PixelPos *pix); +extern void getAffNeighbourPXLumaNB(const Macroblock *currMB, int xN, int yN, PixelPos *pix); +extern void getAffNeighbourPXLumaNB_NoPos(const Macroblock *currMB, int yN, PixelPos *pix); +/* normal */ +extern void getNonAffNeighbour (const Macroblock *currMB, int xN, int yN, const int mb_size[2], PixelPos *pix); +extern void getNonAffNeighbourXP_NoPos(const Macroblock *currMB, int xN, int yN, const int mb_size[2], PixelPos *pix); +extern void getNonAffNeighbourPX_NoPos(const Macroblock *currMB, int xN, int yN, const int mb_size[2], PixelPos *pix); +extern void getNonAffNeighbourLuma (const Macroblock *currMB, int xN, int yN, PixelPos *pix); +extern void getNonAffNeighbourXPLuma(const Macroblock *currMB, int xN, int yN, PixelPos *pix); +extern void getNonAffNeighbourPXLuma(const Macroblock *currMB, int xN, int yN, PixelPos *pix); +extern void getNonAffNeighbourN0Luma(const Macroblock *currMB, PixelPos *pix); +extern void getNonAffNeighbourNXLuma(const Macroblock *currMB, int yN, PixelPos *pix); +extern void getNonAffNeighbourN0 (const Macroblock *currMB, const int mb_size[2], PixelPos *pix); +extern void getNonAffNeighbour0N (const Macroblock *currMB, const int mb_size[2], PixelPos *pix); +extern void getNonAffNeighbourNX (const Macroblock *currMB, int yN, const int mb_size[2], PixelPos *pix); +extern void getNonAffNeighbourNP (const Macroblock *currMB, int yN, const int mb_size[2], PixelPos *pix); +extern void getNonAffNeighbourNPChromaNB(const Macroblock *currMB, int yN, const int mb_size[2], PixelPos *pix); +extern void getNonAffNeighbour0X (const Macroblock *currMB, int yN, const int mb_size[2], PixelPos *pix); +extern void getNonAffNeighbour0XLuma(const Macroblock *currMB, int yN, PixelPos *pix); +extern void getNonAffNeighbourX0 (const Macroblock *currMB, int xN, const int mb_size[2], PixelPos *pix); +extern void getNonAffNeighbour0NLuma(const Macroblock *currMB, PixelPos *pix); +extern void getNonAffNeighbourNPLumaNB(const Macroblock *currMB, int yN, PixelPos *pix); +extern void getNonAffNeighbourXPLumaNB(const Macroblock *currMB, int xN, int yN, PixelPos *pix); +extern void getNonAffNeighbourPPLumaNB(const Macroblock *currMB, int xN, int yN, PixelPos *pix); +extern void getNonAffNeighbourXPLumaNB_NoPos(const Macroblock *currMB, int xN, int yN, PixelPos *pix); +extern void getNonAffNeighbourPXLumaNB(const Macroblock *currMB, int xN, int yN, PixelPos *pix); +extern void getNonAffNeighbourPXLumaNB_NoPos(const Macroblock *currMB, int yN, PixelPos *pix); +extern void get4x4Neighbour (const Macroblock *currMB, int xN, int yN, const int mb_size[2], PixelPos *pix); +extern void get4x4NeighbourLuma (const Macroblock *currMB, int block_x, int block_y, PixelPos *pix); +extern Boolean mb_is_available (int mbAddr, const Macroblock *currMB); +extern void get_mb_pos (VideoParameters *p_Vid, int mb_addr, const int mb_size[2], short *x, short *y); +extern void get_mb_block_pos_normal (const h264_pic_position *PicPos, int mb_addr, short *x, short *y); +extern void get_mb_block_pos_mbaff (const h264_pic_position *PicPos, int mb_addr, short *x, short *y); + + +#endif diff --git a/Src/h264dec/lcommon/inc/memalloc.h b/Src/h264dec/lcommon/inc/memalloc.h new file mode 100644 index 00000000..fb4c3132 --- /dev/null +++ b/Src/h264dec/lcommon/inc/memalloc.h @@ -0,0 +1,71 @@ + +/*! + ************************************************************************ + * \file memalloc.h + * + * \brief + * Memory allocation and free helper funtions + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Karsten Sühring <suehring@hhi.de> + * - Alexis Michael Tourapis <alexismt@ieee.org> + * + ************************************************************************ + */ + +#ifndef _MEMALLOC_H_ +#define _MEMALLOC_H_ + +#include "global.h" +#include "quant_params.h" + +#if defined(USEMMX) // && (IMGTYPE == 0) // MMX, SSE, SSE2 intrinsic support +#if defined(_MSC_VER) || defined(__INTEL_COMPILER) // ICC +# include <emmintrin.h> +# else +# include <xmmintrin.h> +# endif +#endif + +extern int get_mem2D(byte ***array2D, int dim0, int dim1); +extern int get_mem3D(byte ****array3D, int dim0, int dim1, int dim2); +extern int get_mem4D(byte *****array4D, int dim0, int dim1, int dim2, int dim3); + +extern int get_mem2Dint(int ***array2D, int rows, int columns); +extern int get_mem3Dint(int ****array3D, int frames, int rows, int columns); +extern int get_mem4Dint(int *****array4D, int idx, int frames, int rows, int columns ); + +extern int get_mem2DPicMotion(struct pic_motion ***array3D, int rows, int columns); +extern int get_mem3Dref(h264_ref_t ****array3D, int frames, int rows, int columns); + +extern int get_mem2Dshort(short ***array2D, int dim0, int dim1); +extern MotionVector ***get_mem3DMotionVector(int dim0, int dim1, int dim2); +extern int get_mem4Dshort(short *****array4D, int dim0, int dim1, int dim2, int dim3); +extern int get_mem2Dpel(imgpel ***array2D, int rows, int columns); + +extern struct video_image *get_memImage(int width, int height); +extern void free_memImage(struct video_image *image); + +extern void free_mem2D (byte **array2D); +extern void free_mem3D (byte ***array3D); +extern void free_mem4D (byte ****array4D); +// +extern void free_mem2Dint (int **array2D); +extern void free_mem3Dint (int ***array3D); + +extern void free_mem3Dref(h264_ref_t ***array3D); +extern void free_mem2DPicMotion(struct pic_motion **array3D); +// +extern void free_mem2Dshort(short **array2D); + +extern void free_mem3DMotionVector(MotionVector ***); + +extern void free_mem2Dpel (imgpel **array2D); +extern int init_top_bot_planes(imgpel **imgFrame, int height, imgpel ***imgTopField, imgpel ***imgBotField); +extern void free_top_bot_planes(imgpel **imgTopField, imgpel **imgBotField); + +extern void no_mem_exit(char *where); + + +#endif diff --git a/Src/h264dec/lcommon/inc/memcache.h b/Src/h264dec/lcommon/inc/memcache.h new file mode 100644 index 00000000..26131827 --- /dev/null +++ b/Src/h264dec/lcommon/inc/memcache.h @@ -0,0 +1,24 @@ +#pragma once +typedef struct image_cache +{ + int size_x, size_y; + struct video_image *head; +} ImageCache; + +void image_cache_set_dimensions(ImageCache *cache, int width, int height); +int image_cache_dimensions_match(ImageCache *cache, int width, int height); +void image_cache_add(ImageCache *cache, struct video_image *image); +struct video_image *image_cache_get(ImageCache *cache); +void image_cache_flush(ImageCache *cache); + +typedef struct motion_cache +{ + int size_x, size_y; + struct pic_motion **head; +} MotionCache; + +void motion_cache_set_dimensions(MotionCache *cache, int width, int height); +int motion_cache_dimensions_match(MotionCache *cache, int width, int height); +void motion_cache_add(MotionCache *cache, struct pic_motion **image); +struct pic_motion **motion_cache_get(MotionCache *cache); +void motion_cache_flush(MotionCache *cache);
\ No newline at end of file diff --git a/Src/h264dec/lcommon/inc/mv_prediction.h b/Src/h264dec/lcommon/inc/mv_prediction.h new file mode 100644 index 00000000..0f2a13e2 --- /dev/null +++ b/Src/h264dec/lcommon/inc/mv_prediction.h @@ -0,0 +1,19 @@ +/*! + ************************************************************************************* + * \file mv_prediction.h + * + * \brief + * Declarations for Motion Vector Prediction + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Alexis Michael Tourapis <alexismt@ieee.org> + ************************************************************************************* + */ + +#ifndef _MV_PREDICTION_H_ +#define _MV_PREDICTION_H_ + +extern void init_motion_vector_prediction(Macroblock *currMB, int MbaffFrameFlag); + +#endif diff --git a/Src/h264dec/lcommon/inc/nalucommon.h b/Src/h264dec/lcommon/inc/nalucommon.h new file mode 100644 index 00000000..f0288ac5 --- /dev/null +++ b/Src/h264dec/lcommon/inc/nalucommon.h @@ -0,0 +1,64 @@ + +/*! + ************************************************************************************** + * \file + * nalucommon.h + * \brief + * NALU handling common to encoder and decoder + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Stephan Wenger <stewe@cs.tu-berlin.de> + * - Karsten Suehring <suehring@hhi.de> + *************************************************************************************** + */ + +#ifndef _NALUCOMMON_H_ +#define _NALUCOMMON_H_ + +#define MAXRBSPSIZE 64000 +#define MAXNALUSIZE 64000 + +//! values for nal_unit_type +typedef enum { + NALU_TYPE_SLICE = 1, + NALU_TYPE_DPA = 2, + NALU_TYPE_DPB = 3, + NALU_TYPE_DPC = 4, + NALU_TYPE_IDR = 5, + NALU_TYPE_SEI = 6, + NALU_TYPE_SPS = 7, + NALU_TYPE_PPS = 8, + NALU_TYPE_AUD = 9, + NALU_TYPE_EOSEQ = 10, + NALU_TYPE_EOSTREAM = 11, + NALU_TYPE_FILL = 12 +} NaluType; + +//! values for nal_ref_idc +typedef enum { + NALU_PRIORITY_HIGHEST = 3, + NALU_PRIORITY_HIGH = 2, + NALU_PRIORITY_LOW = 1, + NALU_PRIORITY_DISPOSABLE = 0 +} NalRefIdc; + +//! NAL unit structure +typedef struct nalu_t +{ + int startcodeprefix_len; //!< 4 for parameter sets and first slice in picture, 3 for everything else (suggested) + unsigned len; //!< Length of the NAL unit (Excluding the start code, which does not belong to the NALU) + unsigned max_size; //!< NAL Unit Buffer size + int forbidden_bit; //!< should be always FALSE + NaluType nal_unit_type; //!< NALU_TYPE_xxxx + NalRefIdc nal_reference_idc; //!< NALU_PRIORITY_xxxx + byte *buf; //!< contains the first byte followed by the EBSP + uint16 lost_packets; //!< true, if packet loss is detected +} NALU_t; + +//! allocate one NAL Unit +extern NALU_t *AllocNALU(int); + +//! free one NAL Unit +extern void FreeNALU(NALU_t *n); + +#endif diff --git a/Src/h264dec/lcommon/inc/quant_params.h b/Src/h264dec/lcommon/inc/quant_params.h new file mode 100644 index 00000000..c35682c0 --- /dev/null +++ b/Src/h264dec/lcommon/inc/quant_params.h @@ -0,0 +1,55 @@ +/*! + *************************************************************************** + * \file + * quant_params.h + * + * \author + * Alexis Michael Tourapis + * + * \brief + * Headerfile for Quantization parameters + ************************************************************************** + */ + +#ifndef _QUANT_PARAMS_H_ +#define _QUANT_PARAMS_H_ + +struct level_quant_params { + int OffsetComp; + int ScaleComp; + int InvScaleComp; +}; + +typedef struct level_quant_params LevelQuantParams; + +struct quant_params { + int AdaptRndWeight; + int AdaptRndCrWeight; + + LevelQuantParams *****q_params_4x4; + LevelQuantParams *****q_params_8x8; + + int *qp_per_matrix; + int *qp_rem_matrix; + + short **OffsetList4x4input; + short **OffsetList8x8input; + short ***OffsetList4x4; + short ***OffsetList8x8; +}; + +struct quant_methods { + int block_y; + int block_x; + int qp; + int* ACLevel; + int* ACRun; + int **fadjust; + LevelQuantParams **q_params; + int *coeff_cost; + const byte (*pos_scan)[2]; + const byte *c_cost; +}; + +#endif + diff --git a/Src/h264dec/lcommon/inc/transform.h b/Src/h264dec/lcommon/inc/transform.h new file mode 100644 index 00000000..61942004 --- /dev/null +++ b/Src/h264dec/lcommon/inc/transform.h @@ -0,0 +1,27 @@ + +/*! + *************************************************************************** + * + * \file transform.h + * + * \brief + * prototypes of transform functions + * + * \date + * 10 July 2007 + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * Alexis Michael Tourapis + **************************************************************************/ + +#ifndef _TRANSFORM_H_ +#define _TRANSFORM_H_ + +#include "global.h" + +extern void forward4x4 (int **block , int **tblock, int pos_y, int pos_x); +extern void ihadamard4x4 (int block[4][4]); +extern void ihadamard2x2 (int block[4], int tblock[4]); + +#endif //_TRANSFORM_H_ diff --git a/Src/h264dec/lcommon/inc/typedefs.h b/Src/h264dec/lcommon/inc/typedefs.h new file mode 100644 index 00000000..58806bef --- /dev/null +++ b/Src/h264dec/lcommon/inc/typedefs.h @@ -0,0 +1,71 @@ +/*! + ************************************************************************************* + * \file typedefs.h + * + * \brief + * Common type definitions + * Currently only supports Windows and Linux operating systems. + * Need to add support for other "older systems such as VAX, DECC, Unix Alpha etc + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Alexis Michael Tourapis <alexismt@ieee.org> + ************************************************************************************* + */ + +#ifndef _TYPEDEFS_H_ +#define _TYPEDEFS_H_ + +#include "win32.h" + +typedef unsigned char byte; //!< byte type definition +typedef unsigned char uint8; //!< type definition for unsigned char (same as byte, 8 bits) +typedef unsigned short uint16; //!< type definition for unsigned short (16 bits) +typedef unsigned int uint32; //!< type definition for unsigned int (32 bits) + +typedef char int8; +typedef short int16; +typedef int int32; + +#if (IMGTYPE == 0) +typedef byte imgpel; +typedef uint16 distpel; +typedef int32 distblk; +#elif (IMGTYPE == 2) +typedef float imgpel; +typedef float distpel; +typedef float distblk; +#else +typedef uint16 imgpel; +typedef uint32 distpel; +typedef int64 distblk; +#endif + +//! Boolean Type +#ifdef FALSE +# define Boolean int +#else +typedef enum { + FALSE, + TRUE +} Boolean; +#endif + +/* +#define MAXUINT8 0xff +#define MAXUINT16 0xffff +#define MAXUINT32 0xffffffff +#define MAXUINT64 0xffffffffffffffff + +#define MAXINT8 0x7f +#define MININT8 (-MAXINT8) +#define MAXINT16 0x7fff +#define MININT16 (-MAXINT16) +#define MAXINT32 0x7fffffff +#define MININT32 (-MAXINT32) +#define MAXINT64 0x7fffffffffffffff +#define MININT64 (-MAXINT64) +*/ + +#endif + diff --git a/Src/h264dec/lcommon/inc/types.h b/Src/h264dec/lcommon/inc/types.h new file mode 100644 index 00000000..6088f8e4 --- /dev/null +++ b/Src/h264dec/lcommon/inc/types.h @@ -0,0 +1,204 @@ +/*! + ************************************************************************ + * \file + * types.h + * + * \brief + * type definitions. + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * + ************************************************************************ + */ +#ifndef _TYPES_H_ +#define _TYPES_H_ + +/*********************************************************************** + * T y p e d e f i n i t i o n s f o r T M L + *********************************************************************** + */ + +typedef enum +{ + // YUV + PLANE_Y = 0, // PLANE_Y + PLANE_U = 1, // PLANE_Cb + PLANE_V = 2, // PLANE_Cr + // RGB + PLANE_G = 0, + PLANE_B = 1, + PLANE_R = 2 +} ColorPlane; + +enum { + LIST_0 = 0, + LIST_1 = 1, + BI_PRED = 2, + BI_PRED_L0 = 3, + BI_PRED_L1 = 4 +}; + +enum { + ERROR_SAD = 0, + ERROR_SSE = 1, + ERROR_SATD = 2, + ERROR_PSATD = 3 +}; + +enum { + ME_Y_ONLY = 0, + ME_YUV_FP = 1, + ME_YUV_FP_SP = 2 +}; + + +enum { + DISTORTION_MSE = 0 +}; + + +//! Data Partitioning Modes +typedef enum +{ + PAR_DP_1, //!< no data partitioning is supported + PAR_DP_3 //!< data partitioning with 3 partitions +} PAR_DP_TYPE; + + +//! Output File Types +typedef enum +{ + PAR_OF_ANNEXB, //!< Annex B byte stream format + PAR_OF_RTP, //!< RTP packets in outfile + PAR_OF_MEMORY, //!< +} PAR_OF_TYPE; + +//! Field Coding Types +typedef enum +{ + FRAME_CODING, + FIELD_CODING, + ADAPTIVE_CODING, + FRAME_MB_PAIR_CODING +} CodingType; + +//! definition of H.264 syntax elements +typedef enum +{ + SE_HEADER, + SE_PTYPE, + SE_MBTYPE, + SE_REFFRAME, + SE_INTRAPREDMODE, + SE_MVD, + SE_CBP, + SE_LUM_DC_INTRA, + SE_CHR_DC_INTRA, + SE_LUM_AC_INTRA, + SE_CHR_AC_INTRA, + SE_LUM_DC_INTER, + SE_CHR_DC_INTER, + SE_LUM_AC_INTER, + SE_CHR_AC_INTER, + SE_DELTA_QUANT, + SE_BFRAME, + SE_EOS, + SE_MAX_ELEMENTS = 20 //!< number of maximum syntax elements +} SE_type; // substituting the definitions in elements.h + + +typedef enum +{ + NO_SLICES, + FIXED_MB, + FIXED_RATE, + CALL_BACK +} SliceMode; + + +typedef enum +{ + CAVLC, + CABAC +} SymbolMode; + +typedef enum +{ + FULL_SEARCH = -1, + FAST_FULL_SEARCH = 0, + UM_HEX = 1, + UM_HEX_SIMPLE = 2, + EPZS = 3 +} SearchType; + + +typedef enum +{ + FRAME, + TOP_FIELD, + BOTTOM_FIELD +} PictureStructure; //!< New enum for field processing + +typedef enum +{ + P_SLICE = 0, + B_SLICE = 1, + I_SLICE = 2, + SP_SLICE = 3, + SI_SLICE = 4, + NUM_SLICE_TYPES = 5 +} SliceType; + +//Motion Estimation levels +typedef enum +{ + F_PEL, //!< Full Pel refinement + H_PEL, //!< Half Pel refinement + Q_PEL //!< Quarter Pel refinement +} MELevel; + +typedef enum +{ + FAST_ACCESS = 0, //!< Fast/safe reference access + UMV_ACCESS = 1 //!< unconstrained reference access +} REF_ACCESS_TYPE; + +typedef enum +{ + IS_LUMA = 0, + IS_CHROMA = 1 +} Component_Type; + +typedef enum +{ + RC_MODE_0 = 0, + RC_MODE_1 = 1, + RC_MODE_2 = 2, + RC_MODE_3 = 3 +} RCModeType; + + +typedef enum { + SSE = 0, + SSE_RGB = 1, + PSNR = 2, + PSNR_RGB = 3, + SSIM = 4, + SSIM_RGB = 5, + MS_SSIM = 6, + MS_SSIM_RGB = 7, + TOTAL_DIST_TYPES = 8 +} distortion_types; + +typedef enum { + WP_MCPREC_PLUS0 = 4, + WP_MCPREC_PLUS1 = 5, + WP_MCPREC_MINUS0 = 6, + WP_MCPREC_MINUS1 = 7, + WP_MCPREC_MINUS_PLUS0 = 8, + WP_REGULAR = 9 +} weighted_prediction_types; + + +#endif diff --git a/Src/h264dec/lcommon/inc/win32.h b/Src/h264dec/lcommon/inc/win32.h new file mode 100644 index 00000000..09ffef61 --- /dev/null +++ b/Src/h264dec/lcommon/inc/win32.h @@ -0,0 +1,92 @@ + +/*! + ************************************************************************ + * \file + * win32.h + * + * \brief + * win32 definitions for H.264 encoder. + * + * \author + * + ************************************************************************ + */ +#ifndef _H264_WIN32_H_ +#define _H264_WIN32_H_ +#pragma once + +# include <fcntl.h> +# include <stdlib.h> +# include <stdio.h> +# include <string.h> +# include <assert.h> + +#if defined(WIN32) +# include <io.h> +# include <sys/types.h> +# include <sys/stat.h> +# include <windows.h> +#ifndef strcasecmp +# define strcasecmp _strcmpi +#endif + +# define snprintf _snprintf +# define open _open +# define close _close +# define read _read +# define write _write +#ifndef lseek +# define lseek _lseeki64 +#endif +# define fsync _commit +# define tell _telli64 +# define TIMEB _timeb +# define TIME_T LARGE_INTEGER +# define OPENFLAGS_WRITE _O_WRONLY|_O_CREAT|_O_BINARY|_O_TRUNC +# define OPEN_PERMISSIONS _S_IREAD | _S_IWRITE +# define OPENFLAGS_READ _O_RDONLY|_O_BINARY +# define inline _inline +# define forceinline __forceinline +#else +# include <unistd.h> +# include <sys/time.h> +# include <sys/stat.h> +# include <time.h> + +# define TIMEB timeb +# define TIME_T struct timeval +# define tell(fd) lseek(fd, 0, SEEK_CUR) +# define OPENFLAGS_WRITE O_WRONLY|O_CREAT|O_TRUNC +# define OPENFLAGS_READ O_RDONLY +# define OPEN_PERMISSIONS S_IRUSR | S_IWUSR + +# if __STDC_VERSION__ >= 199901L + /* "inline" is a keyword */ +# else +# define inline /* nothing */ +# endif +# define forceinline inline +#endif + +#if defined(WIN32) && !defined(__GNUC__) +typedef __int64 int64; +typedef unsigned __int64 uint64; +# define FORMAT_OFF_T "I64d" +# ifndef INT64_MIN +# define INT64_MIN (-9223372036854775807i64 - 1i64) +# endif +#else + +typedef long long int64; +typedef unsigned long long uint64; +# define FORMAT_OFF_T "lld" +# ifndef INT64_MIN +# define INT64_MIN (-9223372036854775807LL - 1LL) +# endif +#endif + +void gettime(TIME_T* time); +int64 timediff(TIME_T* start, TIME_T* end); +int64 timenorm(int64 cur_time); + +#endif diff --git a/Src/h264dec/lcommon/src/img_io.c b/Src/h264dec/lcommon/src/img_io.c new file mode 100644 index 00000000..c0520218 --- /dev/null +++ b/Src/h264dec/lcommon/src/img_io.c @@ -0,0 +1,327 @@ + +/*! + ************************************************************************************* + * \file img_io.c + * + * \brief + * image I/O related functions + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Alexis Michael Tourapis <alexismt@ieee.org> + ************************************************************************************* + */ +#include "contributors.h" +#include "global.h" +#include "img_io.h" +#include "report.h" + +static const VIDEO_SIZE VideoRes[] = { + { "qcif" , 176, 144}, + { "qqvga" , 160, 128}, + { "qvga" , 320, 240}, + { "sif" , 352, 240}, + { "cif" , 352, 288}, + { "vga" , 640, 480}, + { "sd1" , 720, 480}, + { "sd2" , 704, 576}, + { "sd3" , 720, 576}, + { "720p" , 1280, 720}, + { "1080p" , 1920, 1080}, + { NULL, 0, 0} +}; + +/*! + ************************************************************************ + * \brief + * Parse Size from from file name + * + ************************************************************************ + */ +int ParseSizeFromString (VideoDataFile *input_file, int *x_size, int *y_size, double *fps) +{ + char *p1, *p2, *tail; + char *fn = input_file->fname; + char c; + int i = 0; + + *x_size = *y_size = -1; + p1 = p2 = fn; + while (p1 != NULL && p2 != NULL) + { + // Search for first '_' + p1 = strstr( p1, "_"); + if (p1 == NULL) + break; + + // Search for end character of x_size (first 'x' after last '_') + p2 = strstr( p1, "x"); + + // If no 'x' is found, exit + if (p2 == NULL) + break; + + // Try conversion of number + *p2 = 0; + *x_size = strtol( p1 + 1, &tail, 10); + + // If there are characters left in the string, or the string is null, discard conversion + if (*tail != '\0' || *(p1 + 1) == '\0') + { + *p2 = 'x'; + p1 = tail; + continue; + } + + // Conversion was correct. Restore string + *p2 = 'x'; + + // Search for end character of y_size (first '_' or '.' after last 'x') + p1 = strpbrk( p2 + 1, "_."); + // If no '_' or '.' is found, try again from current position + if (p1 == NULL) + { + p1 = p2 + 1; + continue; + } + + // Try conversion of number + c = *p1; + *p1 = 0; + *y_size = strtol( p2 + 1, &tail, 10); + + // If there are characters left in the string, or the string is null, discard conversion + if (*tail != '\0' || *(p2 + 1) == '\0') + { + *p1 = c; + p1 = tail; + continue; + } + + // Conversion was correct. Restore string + *p1 = c; + + // Search for end character of y_size (first 'i' or 'p' after last '_') + p2 = strstr( p1 + 1, "ip"); + + // If no 'i' or 'p' is found, exit + if (p2 == NULL) + break; + + // Try conversion of number + c = *p2; + *p2 = 0; + *fps = strtod( p1 + 1, &tail); + + // If there are characters left in the string, or the string is null, discard conversion + if (*tail != '\0' || *(p1 + 1) == '\0') + { + *p2 = c; + p1 = tail; + continue; + } + + // Conversion was correct. Restore string + *p2 = c; + break; + } + + // Now lets test some common video file formats + if (p1 == NULL || p2 == NULL) + { + for (i = 0; VideoRes[i].name != NULL; i++) + { + if (strcasecmp (fn, VideoRes[i].name)) + { + *x_size = VideoRes[i].x_size; + *y_size = VideoRes[i].y_size; + // Should add frame rate support as well + break; + } + } + } + + return (*x_size == -1 || *y_size == -1) ? 0 : 1; +} + +/*! + ************************************************************************ + * \brief + * Parse Size from from file name + * + ************************************************************************ + */ +void ParseFrameNoFormatFromString (VideoDataFile *input_file) +{ + char *p1, *p2, *tail; + char *fn = input_file->fname; + char *fhead = input_file->fhead; + char *ftail = input_file->ftail; + int *zero_pad = &input_file->zero_pad; + int *num_digits = &input_file->num_digits; + + *zero_pad = 0; + *num_digits = -1; + p1 = p2 = fn; + while (p1 != NULL && p2 != NULL) + { + // Search for first '_' + p1 = strstr( p1, "%"); + if (p1 == NULL) + break; + + strncpy(fhead, fn, p1 - fn); + + // Search for end character of x_size (first 'x' after last '_') + p2 = strstr( p1, "d"); + + // If no 'x' is found, exit + if (p2 == NULL) + break; + + // Try conversion of number + *p2 = 0; + + if (*(p1 + 1) == '0') + *zero_pad = 1; + + *num_digits = strtol( p1 + 1, &tail, 10); + + // If there are characters left in the string, or the string is null, discard conversion + if (*tail != '\0' || *(p1 + 1) == '\0') + { + *p2 = 'd'; + p1 = tail; + continue; + } + + // Conversion was correct. Restore string + *p2 = 'd'; + + tail++; + strncpy(ftail, tail, strlen(tail)); + break; + } + + if (input_file->vdtype == VIDEO_TIFF) + { + input_file->is_concatenated = 0; + } + else + input_file->is_concatenated = (*num_digits == -1) ? 1 : 0; +} + +/*! + ************************************************************************ + * \brief + * Open file containing a single frame + ************************************************************************ + */ +void OpenFrameFile( VideoDataFile *input_file, int FrameNumberInFile) +{ + char infile [FILE_NAME_SIZE], in_number[16]; + int length = 0; + in_number[length]='\0'; + length = strlen(input_file->fhead); + strncpy(infile, input_file->fhead, length); + infile[length]='\0'; + if (input_file->zero_pad) + snprintf(in_number, 16, "%0*d", input_file->num_digits, FrameNumberInFile); + else + snprintf(in_number, 16, "%*d", input_file->num_digits, FrameNumberInFile); + + strncat(infile, in_number, sizeof(in_number)); + length += sizeof(in_number); + infile[length]='\0'; + strncat(infile, input_file->ftail, strlen(input_file->ftail)); + length += strlen(input_file->ftail); + infile[length]='\0'; + + if ((input_file->f_num = open(infile, OPENFLAGS_READ)) == -1) + { + printf ("OpenFrameFile: cannot open file %s\n", infile); + report_stats_on_error(); + } +} + +/*! + ************************************************************************ + * \brief + * Open file(s) containing the entire frame sequence + ************************************************************************ + */ +void OpenFiles( VideoDataFile *input_file) +{ + if (input_file->is_concatenated == 1) + { + if (strlen(input_file->fname) == 0) + { + snprintf(errortext, ET_SIZE, "No input sequence name was provided. Please check settings."); + error (errortext, 500); + } + + if ((input_file->f_num = open(input_file->fname, OPENFLAGS_READ)) == -1) + { + snprintf(errortext, ET_SIZE, "Input file %s does not exist",input_file->fname); + error (errortext, 500); + } + } +} + +/*! + ************************************************************************ + * \brief + * Close input file + ************************************************************************ + */ +void CloseFiles(VideoDataFile *input_file) +{ + if (input_file->f_num != -1) + close(input_file->f_num); + input_file->f_num = -1; +} + +/* ========================================================================== + * + * ParseVideoType + * + * ========================================================================== +*/ +VideoFileType ParseVideoType (VideoDataFile *input_file) +{ + char *format; + + format = input_file->fname + strlen(input_file->fname) - 3; + + if (strcasecmp (format, "yuv") == 0) + { + input_file->vdtype = VIDEO_YUV; + input_file->format.yuv_format = YUV420; + input_file->avi = NULL; + } + else if (strcasecmp (format, "rgb") == 0) + { + input_file->vdtype = VIDEO_RGB; + input_file->format.yuv_format = YUV444; + input_file->avi = NULL; + } + else if (strcasecmp (format, "tif") == 0) + { + input_file->vdtype = VIDEO_TIFF; + input_file->avi = NULL; + } + else if (strcasecmp (format, "avi") == 0) + { + input_file->vdtype = VIDEO_AVI; + } + else + { + //snprintf(errortext, ET_SIZE, "ERROR: video file format not supported"); + //error (errortext, 500); + input_file->vdtype = VIDEO_YUV; + input_file->format.yuv_format = YUV420; + input_file->avi = NULL; + } + + return input_file->vdtype; +} diff --git a/Src/h264dec/lcommon/src/memalloc.c b/Src/h264dec/lcommon/src/memalloc.c new file mode 100644 index 00000000..da5872ed --- /dev/null +++ b/Src/h264dec/lcommon/src/memalloc.c @@ -0,0 +1,1280 @@ + +/*! + ************************************************************************ + * \file memalloc.c + * + * \brief + * Memory allocation and free helper functions + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Alexis Michael Tourapis <alexismt@ieee.org> + * - Karsten Sühring <suehring@hhi.de> + * + ************************************************************************ + */ + +#include "global.h" +#include "memalloc.h" +#include "mbuffer.h" + +#define ROUNDUP16(size) (((size)+15) & ~15) + +#if !defined(USEMMX) + /*! + ************************************************************************ + * \brief + * Initialize 2-dimensional top and bottom field to point to the proper + * lines in frame + * + * \par Output: + * memory size in bytes + ************************************************************************/ +int init_top_bot_planes(imgpel **imgFrame, int dim0, imgpel ***imgTopField, imgpel ***imgBotField) +{ + int i; + + if((*imgTopField = (imgpel**) malloc((dim0>>1) * sizeof(imgpel*))) == NULL) + no_mem_exit("init_top_bot_planes: imgTopField"); + + if((*imgBotField = (imgpel**) malloc((dim0>>1) * sizeof(imgpel*))) == NULL) + no_mem_exit("init_top_bot_planes: imgBotField"); + + for(i = 0; i < (dim0>>1); i++) + { + (*imgTopField)[i] = imgFrame[2 * i ]; + (*imgBotField)[i] = imgFrame[2 * i + 1]; + } + + return dim0 * sizeof(imgpel*); +} + + /*! + ************************************************************************ + * \brief + * free 2-dimensional top and bottom fields without freeing target memory + * + * \par Output: + * memory size in bytes + ************************************************************************/ +void free_top_bot_planes(imgpel **imgTopField, imgpel **imgBotField) +{ + free (imgTopField); + free (imgBotField); +} + + +/*! + ************************************************************************ + * \brief + * Allocate 1D memory array -> imgpel array1D[dim0 + * + * \par Output: + * memory size in bytes + ************************************************************************/ +int get_mem1Dpel(imgpel **array1D, int dim0) +{ + if((*array1D = (imgpel*)calloc(dim0, sizeof(imgpel))) == NULL) + no_mem_exit("get_mem1Dpel: arra12D"); + + return (sizeof(imgpel*) + dim0 * sizeof(imgpel)); +} + +/*! + ************************************************************************ + * \brief + * Allocate 2D memory array -> imgpel array2D[dim0][dim1] + * + * \par Output: + * memory size in bytes + ************************************************************************/ +int get_mem2Dpel(imgpel ***array2D, int dim0, int dim1) +{ + int i; + + if((*array2D = (imgpel**)malloc(dim0 * sizeof(imgpel*))) == NULL) + no_mem_exit("get_mem2Dpel: array2D"); + if((*(*array2D) = (imgpel* )calloc(dim0 * dim1,sizeof(imgpel ))) == NULL) + no_mem_exit("get_mem2Dpel: array2D"); + + for(i = 1 ; i < dim0; i++) + (*array2D)[i] = (*array2D)[i-1] + dim1; + + return dim0 * (sizeof(imgpel*) + dim1 * sizeof(imgpel)); +} + +VideoImage *get_memImage(int width, int height) +{ + int i, stride; + VideoImage *image = (VideoImage *)calloc(1, sizeof(VideoImage)); + +#ifdef H264_IPP + + IppiSize roi = {width, height}; + if (!image) + return 0; + if((image->img = (imgpel**)malloc(height * sizeof(imgpel*))) == NULL) + return 0; + + image->base_address = (imgpel* )ippiMalloc_8u_C1(width, height+1, &stride); // height+1 so we can deal with overreading + if (!image->base_address) + return 0; + + image->stride=stride; + + for(i = 0 ; i < height; i++) + image->img[i] = image->base_address + stride*i; + + image->next = 0; + + return image; +#else + if (!image) + return 0; + stride = ROUNDUP16(width); + image->stride = stride; + + if((image->img = (imgpel**)malloc(height * sizeof(imgpel*))) == NULL) + return 0; + if((image->base_address = (imgpel* )malloc(stride * height* sizeof(imgpel))) == NULL) + return 0; + memset(image->base_address, 0, stride * height* sizeof(imgpel)); + + for(i = 0 ; i < height; i++) + image->img[i] = image->base_address + stride*i; + + return image; +#endif +} + +void free_memImage(VideoImage *image) +{ + free(image->img); + #ifdef H264_IPP + ippiFree(image->base_address); + #else + free(image->base_address); + #endif + free(image); +} + +/*! + ************************************************************************ + * \brief + * Allocate 3D memory array -> imgpel array3D[dim0][dim1][dim2] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem3Dpel(imgpel ****array3D, int dim0, int dim1, int dim2) +{ + int i, mem_size = dim0 * sizeof(imgpel**); + + if(((*array3D) = (imgpel***)malloc(dim0 * sizeof(imgpel**))) == NULL) + no_mem_exit("get_mem3Dpel: array3D"); + + mem_size += get_mem2Dpel(*array3D, dim0 * dim1, dim2); + + for(i = 1; i < dim0; i++) + (*array3D)[i] = (*array3D)[i - 1] + dim1; + + return mem_size; +} +/*! + ************************************************************************ + * \brief + * Allocate 4D memory array -> imgpel array4D[dim0][dim1][dim2][dim3] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem4Dpel(imgpel *****array4D, int dim0, int dim1, int dim2, int dim3) +{ + int i, mem_size = dim0 * sizeof(imgpel***); + + if(((*array4D) = (imgpel****)malloc(dim0 * sizeof(imgpel***))) == NULL) + no_mem_exit("get_mem4Dpel: array4D"); + + mem_size += get_mem3Dpel(*array4D, dim0 * dim1, dim2, dim3); + + for(i = 1; i < dim0; i++) + (*array4D)[i] = (*array4D)[i - 1] + dim1; + + return mem_size; +} + + + + +/*! + ************************************************************************ + * \brief + * free 1D memory array + * which was allocated with get_mem1Dpel() + ************************************************************************ + */ +void free_mem1Dpel(imgpel *array1D) +{ + if (array1D) + { + free (array1D); + } + else + { + error ("free_mem1Dpel: trying to free unused memory",100); + } +} + +/*! + ************************************************************************ + * \brief + * free 2D memory array + * which was allocated with get_mem2Dpel() + ************************************************************************ + */ +void free_mem2Dpel(imgpel **array2D) +{ + if (array2D) + { + if (*array2D) + free (*array2D); + else + error ("free_mem2Dpel: trying to free unused memory",100); + + free (array2D); + } + else + { + error ("free_mem2Dpel: trying to free unused memory",100); + } +} + + +/*! + ************************************************************************ + * \brief + * free 3D memory array + * which was allocated with get_mem3Dpel() + ************************************************************************ + */ +void free_mem3Dpel(imgpel ***array3D) +{ + if (array3D) + { + free_mem2Dpel(*array3D); + free (array3D); + } + else + { + error ("free_mem3Dpel: trying to free unused memory",100); + } +} +/*! + ************************************************************************ + * \brief + * free 4D memory array + * which was allocated with get_mem4Dpel() + ************************************************************************ + */ +void free_mem4Dpel(imgpel ****array4D) +{ + if (array4D) + { + free_mem3Dpel(*array4D); + free (array4D); + } + else + { + error ("free_mem4Dpel: trying to free unused memory",100); + } +} +/*! + ************************************************************************ + * \brief + * free 5D memory array + * which was allocated with get_mem5Dpel() + ************************************************************************ + */ +void free_mem5Dpel(imgpel *****array5D) +{ + if (array5D) + { + free_mem4Dpel(*array5D); + free (array5D); + } + else + { + error ("free_mem5Dpel: trying to free unused memory",100); + } +} + +/*! + ************************************************************************ + * \brief + * Allocate 2D memory array -> unsigned char array2D[dim0][dim1] + * + * \par Output: + * memory size in bytes + ************************************************************************/ +int get_mem2D(byte ***array2D, int dim0, int dim1) +{ + int i; + + if(( *array2D = (byte**)malloc(dim0 * sizeof(byte*))) == NULL) + no_mem_exit("get_mem2D: array2D"); + if((*(*array2D) = (byte* )calloc(dim0 * dim1,sizeof(byte ))) == NULL) + no_mem_exit("get_mem2D: array2D"); + + for(i = 1; i < dim0; i++) + (*array2D)[i] = (*array2D)[i-1] + dim1; + + return dim0 * (sizeof(byte*) + dim1 * sizeof(byte)); +} + +/*! + ************************************************************************ + * \brief + * Allocate 2D memory array -> int array2D[dim0][dim1] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem2Dint(int ***array2D, int dim0, int dim1) +{ + int i; + + if((*array2D = (int**)malloc(dim0 * sizeof(int*))) == NULL) + no_mem_exit("get_mem2Dint: array2D"); + if((*(*array2D) = (int* )calloc(dim0 * dim1, sizeof(int ))) == NULL) + no_mem_exit("get_mem2Dint: array2D"); + + for(i = 1 ; i < dim0; i++) + (*array2D)[i] = (*array2D)[i-1] + dim1; + + return dim0 * (sizeof(int*) + dim1 * sizeof(int)); +} + +/*! + ************************************************************************ + * \brief + * Allocate 2D memory array -> int64 array2D[dim0][dim1] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +static int get_mem2Dref(h264_ref_t ***array2D, int dim0, int dim1) +{ + int i; + size_t malloc_size = ROUNDUP16(dim0 * dim1*sizeof(h264_ref_t)); + if((*array2D = (h264_ref_t**)malloc(dim0 * sizeof(h264_ref_t*))) == NULL) + no_mem_exit("get_mem2Dint64: array2D"); + if((*(*array2D) = (h264_ref_t* )_aligned_malloc(malloc_size, 32)) == NULL) + no_mem_exit("get_mem2Dint64: array2D"); + memset((*array2D)[0], 0, malloc_size); + + for(i = 1; i < dim0; i++) + (*array2D)[i] = (*array2D)[i-1] + dim1; + + return dim0 * (sizeof(h264_ref_t*) + dim1 * sizeof(h264_ref_t)); +} + +int get_mem2DPicMotion(PicMotion ***array2D, int dim0, int dim1) +{ + // we allocate with one extra position in the first dimension + // so the motion_cache can use it as a next pointer + int i; + size_t malloc_size = ROUNDUP16(dim0 * dim1*sizeof(PicMotion)); + if((*array2D = (PicMotion**)malloc((dim0+1) * sizeof(PicMotion*))) == NULL) + no_mem_exit("get_mem2Dint64: array2D"); + if((*(*array2D) = (PicMotion* )_aligned_malloc(malloc_size, 32)) == NULL) + no_mem_exit("get_mem2Dint64: array2D"); + memset((*array2D)[0], 0, malloc_size); + + for(i = 1; i < dim0; i++) + (*array2D)[i] = (*array2D)[i-1] + dim1; + (*array2D)[dim0] = 0; + + return dim0 * (sizeof(PicMotion*) + dim1 * sizeof(PicMotion)); +} + +/*! + ************************************************************************ + * \brief + * Allocate 3D memory array -> unsigned char array3D[dim0][dim1][dim2] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem3D(byte ****array3D, int dim0, int dim1, int dim2) +{ + int i, mem_size = dim0 * sizeof(byte**); + + if(((*array3D) = (byte***)malloc(dim0 * sizeof(byte**))) == NULL) + no_mem_exit("get_mem3D: array3D"); + + mem_size += get_mem2D(*array3D, dim0 * dim1, dim2); + + for(i = 1; i < dim0; i++) + (*array3D)[i] = (*array3D)[i-1] + dim1; + + return mem_size; +} + +/*! + ************************************************************************ + * \brief + * Allocate 4D memory array -> unsigned char array4D[dim0][dim1][dim2][dim3] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem4D(byte *****array4D, int dim0, int dim1, int dim2, int dim3) +{ + int i, mem_size = dim0 * sizeof(byte***); + + if(((*array4D) = (byte****)malloc(dim0 * sizeof(byte***))) == NULL) + no_mem_exit("get_mem4D: array4D"); + + mem_size += get_mem3D(*array4D, dim0 * dim1, dim2, dim3); + + for(i = 1; i < dim0; i++) + (*array4D)[i] = (*array4D)[i-1] + dim1; + + return mem_size; +} + +/*! + ************************************************************************ + * \brief + * Allocate 3D memory array -> int array3D[dim0][dim1][dim2] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem3Dint(int ****array3D, int dim0, int dim1, int dim2) +{ + int i, mem_size = dim0 * sizeof(int**); + + if(((*array3D) = (int***)malloc(dim0 * sizeof(int**))) == NULL) + no_mem_exit("get_mem3Dint: array3D"); + + mem_size += get_mem2Dint(*array3D, dim0 * dim1, dim2); + + for(i = 1; i < dim0; i++) + (*array3D)[i] = (*array3D)[i-1] + dim1; + + return mem_size; +} + +/*! + ************************************************************************ + * \brief + * Allocate 3D memory array -> int64 array3D[dim0][dim1][dim2] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem3Dref(h264_ref_t ****array3D, int dim0, int dim1, int dim2) +{ + int i, mem_size = dim0 * sizeof(h264_ref_t**); + + if(((*array3D) = (h264_ref_t***)malloc(dim0 * sizeof(h264_ref_t**))) == NULL) + no_mem_exit("get_mem3Dint64: array3D"); + + mem_size += get_mem2Dref(*array3D, dim0 * dim1, dim2); + + for(i = 1; i < dim0; i++) + (*array3D)[i] = (*array3D)[i-1] + dim1; + + return mem_size; +} + +/*! + ************************************************************************ + * \brief + * Allocate 4D memory array -> int array4D[dim0][dim1][dim2][dim3] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem4Dint(int *****array4D, int dim0, int dim1, int dim2, int dim3) +{ + int i, mem_size = dim0 * sizeof(int***); + + if(((*array4D) = (int****)malloc(dim0 * sizeof(int***))) == NULL) + no_mem_exit("get_mem4Dint: array4D"); + + mem_size += get_mem3Dint(*array4D, dim0 * dim1, dim2, dim3); + + for(i = 1; i < dim0; i++) + (*array4D)[i] = (*array4D)[i-1] + dim1; + + return mem_size; +} + + + + +/*! + ************************************************************************ + * \brief + * free 2D memory array + * which was allocated with get_mem2D() + ************************************************************************ + */ +void free_mem2D(byte **array2D) +{ + if (array2D) + { + free (*array2D); + free (array2D); + } +} + +/*! + ************************************************************************ + * \brief + * free 2D memory array + * which was allocated with get_mem2Dint() + ************************************************************************ + */ +void free_mem2Dint(int **array2D) +{ + if (array2D) + { + free (*array2D); + free (array2D); + } +} + +/*! + ************************************************************************ + * \brief + * free 2D memory array + * which was allocated with get_mem2Dint64() + ************************************************************************ + */ +void free_mem2Dref(h264_ref_t **array2D) +{ + if (array2D) + { + _aligned_free (*array2D); + free (array2D); + } +} + +void free_mem2DPicMotion(PicMotion **array2D) +{ + if (array2D) + { + _aligned_free (*array2D); + free (array2D); + } +} + +/*! + ************************************************************************ + * \brief + * free 3D memory array + * which was allocated with get_mem3D() + ************************************************************************ + */ +void free_mem3D(byte ***array3D) +{ + if (array3D) + { + free_mem2D(*array3D); + free (array3D); + } +} + +/*! + ************************************************************************ + * \brief + * free 4D memory array + * which was allocated with get_mem3D() + ************************************************************************ + */ +void free_mem4D(byte ****array4D) +{ + if (array4D) + { + free_mem3D(*array4D); + free (array4D); + } +} + +/*! + ************************************************************************ + * \brief + * free 3D memory array + * which was allocated with get_mem3Dint() + ************************************************************************ + */ +void free_mem3Dint(int ***array3D) +{ + if (array3D) + { + free_mem2Dint(*array3D); + free (array3D); + } +} + + +/*! + ************************************************************************ + * \brief + * free 3D memory array + * which was allocated with get_mem3Dint64() + ************************************************************************ + */ +void free_mem3Dref(h264_ref_t ***array3D) +{ + if (array3D) + { + free_mem2Dref(*array3D); + free (array3D); + } +} + +void free_mem3DPicMotion(PicMotion ***array3D) +{ + if (array3D) + { + free_mem2DPicMotion(*array3D); + free (array3D); + } +} + +/*! + ************************************************************************ + * \brief + * free 4D memory array + * which was allocated with get_mem4Dint() + ************************************************************************ + */ +void free_mem4Dint(int ****array4D) +{ + if (array4D) + { + free_mem3Dint( *array4D); + free (array4D); + } +} + + +/*! + ************************************************************************ + * \brief + * Exit program if memory allocation failed (using error()) + * \param where + * string indicating which memory allocation failed + ************************************************************************ + */ +void no_mem_exit(char *where) +{ + snprintf(errortext, ET_SIZE, "Could not allocate memory: %s",where); + error (errortext, 100); +} + + +/*! + ************************************************************************ + * \brief + * Allocate 2D uint16 memory array -> uint16 array2D[dim0][dim1] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem2Duint16(uint16 ***array2D, int dim0, int dim1) +{ + int i; + + if(( *array2D = (uint16**)malloc(dim0 * sizeof(uint16*))) == NULL) + no_mem_exit("get_mem2Duint16: array2D"); + + if((*(*array2D) = (uint16* )calloc(dim0 * dim1,sizeof(uint16 ))) == NULL) + no_mem_exit("get_mem2Duint16: array2D"); + + for(i = 1; i < dim0; i++) + (*array2D)[i] = (*array2D)[i-1] + dim1; + + return dim0 * (sizeof(uint16*) + dim1 * sizeof(uint16)); +} + + +/*! + ************************************************************************ + * \brief + * Allocate 2D short memory array -> short array2D[dim0][dim1] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem2Dshort(short ***array2D, int dim0, int dim1) +{ + int i; + size_t malloc_size = ROUNDUP16(dim0 * dim1*sizeof(short)); + if(( *array2D = (short**)malloc(dim0 * sizeof(short*))) == NULL) + no_mem_exit("get_mem2Dshort: array2D"); + if((*(*array2D) = (short* )_aligned_malloc(malloc_size, 32)) == NULL) + no_mem_exit("get_mem2Dshort: array2D"); + memset((*array2D)[0], 0, malloc_size); + + for(i = 1; i < dim0; i++) + (*array2D)[i] = (*array2D)[i-1] + dim1; + + return dim0 * (sizeof(short*) + dim1 * sizeof(short)); +} + +/*! + ************************************************************************ + * \brief + * Allocate 3D memory short array -> short array3D[dim0][dim1][dim2] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem3Dshort(short ****array3D,int dim0, int dim1, int dim2) +{ + int i, mem_size = dim0 * sizeof(short**); + + if(((*array3D) = (short***)malloc(dim0 * sizeof(short**))) == NULL) + no_mem_exit("get_mem3Dshort: array3D"); + + mem_size += get_mem2Dshort(*array3D, dim0 * dim1, dim2); + + for(i = 1; i < dim0; i++) + (*array3D)[i] = (*array3D)[i-1] + dim1; + + return mem_size; +} + + +/*! + ************************************************************************ + * \brief + * Allocate 4D memory short array -> short array3D[dim0][dim1][dim2][dim3] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +static MotionVector **get_mem2DMotionVector(int dim0, int dim1) +{ + MotionVector **array2D; + int i; + size_t malloc_size = ROUNDUP16(dim0 * dim1)*sizeof(MotionVector); + if((array2D = (MotionVector**)malloc(dim0 * sizeof(MotionVector*))) == NULL) + return 0; + + if((array2D[0] = (MotionVector* )_aligned_malloc(malloc_size, 32)) == NULL) + { + free(array2D); + return 0; + } + memset(array2D[0], 0, malloc_size); + + for(i = 1; i < dim0; i++) + array2D[i] = array2D[i-1] + dim1; + + return array2D; +} + +MotionVector ***get_mem3DMotionVector(int dim0, int dim1, int dim2) +{ + MotionVector ***array3D; + int i; + + if((array3D = (MotionVector***)malloc(dim0 * sizeof(MotionVector **))) == NULL) + return 0; + + array3D[0] = get_mem2DMotionVector(dim0 * dim1, dim2); + if (!array3D[0]) + { + free(array3D); + return 0; + } + + for(i = 1; i < dim0; i++) + array3D[i] = array3D[i-1] + dim1; + + return array3D; +} + + + +/*! + ************************************************************************ + * \brief + * free 2D uint16 memory array + * which was allocated with get_mem2Duint16() + ************************************************************************ + */ +void free_mem2Duint16(uint16 **array2D) +{ + if (array2D) + { + free (*array2D); + free (array2D); + } + +} + +/*! + ************************************************************************ + * \brief + * free 2D short memory array + * which was allocated with get_mem2Dshort() + ************************************************************************ + */ +void free_mem2Dshort(short **array2D) +{ + if (array2D) + { + _aligned_free (*array2D); + free (array2D); + } +} + +/*! + ************************************************************************ + * \brief + * free 4D short memory array + * which was allocated with get_mem4Dshort() + ************************************************************************ + */ + +static void free_mem2DMotionVector(MotionVector **array2D) +{ + if (array2D) + { + _aligned_free(*array2D); + free (array2D); + } + +} + +void free_mem3DMotionVector(MotionVector ***array3D) +{ + if (array3D) + { + free_mem2DMotionVector( *array3D); + free (array3D); + } +} + + +/*! + ************************************************************************ + * \brief + * Allocate 2D memory array -> double array2D[dim0][dim1] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem2Ddouble(double ***array2D, int dim0, int dim1) +{ + int i; + + if((*array2D = (double**)malloc(dim0 * sizeof(double*))) == NULL) + no_mem_exit("get_mem2Ddouble: array2D"); + + if(((*array2D)[0] = (double* )calloc(dim0 * dim1,sizeof(double ))) == NULL) + no_mem_exit("get_mem2Ddouble: array2D"); + + for(i=1 ; i<dim0 ; i++) + (*array2D)[i] = (*array2D)[i-1] + dim1 ; + + return dim0 * (sizeof(double*) + dim1 * sizeof(double)); +} + +/*! + ************************************************************************ + * \brief + * Allocate 2D memory array -> double array2D[dim0][dim1] + * Note that array is shifted towards offset allowing negative values + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem2Dodouble(double ***array2D, int dim0, int dim1, int offset) +{ + int i; + + if((*array2D = (double**)malloc(dim0 * sizeof(double*))) == NULL) + no_mem_exit("get_mem2Dodouble: array2D"); + if(((*array2D)[0] = (double* )calloc(dim0 * dim1, sizeof(double ))) == NULL) + no_mem_exit("get_mem2Dodouble: array2D"); + + (*array2D)[0] += offset; + + for(i=1 ; i<dim0 ; i++) + (*array2D)[i] = (*array2D)[i-1] + dim1 ; + + return dim0 * (sizeof(double*) + dim1 * sizeof(double)); +} + +/*! + ************************************************************************ + * \brief + * Allocate 3D memory double array -> double array3D[dim0][dim1][dim2] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem3Dodouble(double ****array3D, int dim0, int dim1, int dim2, int offset) +{ + int i,j; + + if(((*array3D) = (double***)malloc(dim0 * sizeof(double**))) == NULL) + no_mem_exit("get_mem3Dodouble: array3D"); + + if(((*array3D)[0] = (double** )calloc(dim0 * dim1, sizeof(double*))) == NULL) + no_mem_exit("get_mem3Dodouble: array3D"); + + (*array3D) [0] += offset; + + for(i=1 ; i<dim0 ; i++) + (*array3D)[i] = (*array3D)[i-1] + dim1 ; + + for (i = 0; i < dim0; i++) + for (j = -offset; j < dim1 - offset; j++) + if(((*array3D)[i][j] = (double* )calloc(dim2, sizeof(double))) == NULL) + no_mem_exit("get_mem3Dodouble: array3D"); + + return dim0*( sizeof(double**) + dim1 * ( sizeof(double*) + dim2 * sizeof(double))); +} + + +/*! + ************************************************************************ + * \brief + * Allocate 2D memory array -> int array2D[dim0][dim1] + * Note that array is shifted towards offset allowing negative values + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_offset_mem2Dshort(short ***array2D, int dim0, int dim1, int offset_y, int offset_x) +{ + int i; + + if((*array2D = (short**)malloc(dim0 * sizeof(short*))) == NULL) + no_mem_exit("get_offset_mem2Dshort: array2D"); + + if(((*array2D)[0] = (short* )calloc(dim0 * dim1, sizeof(short))) == NULL) + no_mem_exit("get_offset_mem2Dshort: array2D"); + (*array2D)[0] += offset_x + offset_y * dim1; + + for(i=-1 ; i > -offset_y - 1; i--) + { + (*array2D)[i] = (*array2D)[i+1] - dim1; + } + + for(i=1 ; i < dim1 - offset_y; i++) + (*array2D)[i] = (*array2D)[i-1] + dim1; + + return dim0 * (sizeof(short*) + dim1 * sizeof(short)); +} + +/*! + ************************************************************************ + * \brief + * Allocate 3D memory int array -> int array3D[dim0][dim1][dim2] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem3Doint(int ****array3D, int dim0, int dim1, int dim2, int offset) +{ + int i,j; + + if(((*array3D) = (int***)malloc(dim0 * sizeof(int**))) == NULL) + no_mem_exit("get_mem3Doint: array3D"); + + if(((*array3D)[0] = (int** )calloc(dim0 * dim1, sizeof(int*))) == NULL) + no_mem_exit("get_mem3Doint: array3D"); + + (*array3D) [0] += offset; + + for(i=1 ; i<dim0 ; i++) + (*array3D)[i] = (*array3D)[i-1] + dim1 ; + + for (i = 0; i < dim0; i++) + for (j = -offset; j < dim1 - offset; j++) + if(((*array3D)[i][j] = (int* )calloc(dim2, sizeof(int))) == NULL) + no_mem_exit("get_mem3Doint: array3D"); + + return dim0 * (sizeof(int**) + dim1 * (sizeof(int*) + dim2 * sizeof(int))); +} + +/*! + ************************************************************************ + * \brief + * Allocate 2D memory array -> int array2D[dim0][dim1] + * Note that array is shifted towards offset allowing negative values + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +int get_mem2Doint(int ***array2D, int dim0, int dim1, int offset) +{ + int i; + + if((*array2D = (int**)malloc(dim0 * sizeof(int*))) == NULL) + no_mem_exit("get_mem2Dint: array2D"); + if(((*array2D)[0] = (int* )calloc(dim0 * dim1, sizeof(int))) == NULL) + no_mem_exit("get_mem2Dint: array2D"); + + (*array2D)[0] += offset; + + for(i=1 ; i<dim0 ; i++) + (*array2D)[i] = (*array2D)[i-1] + dim1 ; + + return dim0 * (sizeof(int*) + dim1 * sizeof(int)); +} + + +/*! + ************************************************************************ + * \brief + * Allocate 3D memory array -> int array3D[dim0][dim1][dim2] + * + * \par Output: + * memory size in bytes + ************************************************************************ + */ +// same change as in get_mem3Dint +int get_mem3Ddouble(double ****array3D, int dim0, int dim1, int dim2) +{ + int j, mem_size = dim0 * sizeof(double**); + + double **array2D; + + if(((*array3D) = (double***)malloc(dim0 * sizeof(double**))) == NULL) + no_mem_exit("get_mem3Ddouble: array3D"); + + mem_size += get_mem2Ddouble(&array2D, dim0 * dim1, dim2); + + for(j = 0; j < dim0; j++) + { + (*array3D)[j] = &array2D[j * dim1]; + } + + return mem_size; +} + +/*! + ************************************************************************ + * \brief + * free 2D double memory array + * which was allocated with get_mem2Ddouble() + ************************************************************************ + */ +void free_mem2Ddouble(double **array2D) +{ + if (array2D) + { + if (*array2D) + free (*array2D); + else + error ("free_mem2Ddouble: trying to free unused memory",100); + + free (array2D); + + } + else + { + error ("free_mem2Ddouble: trying to free unused memory",100); + } +} + + +/*! +************************************************************************ +* \brief +* free 2D double memory array (with offset) +* which was allocated with get_mem2Ddouble() +************************************************************************ +*/ +void free_mem2Dodouble(double **array2D, int offset) +{ + if (array2D) + { + array2D[0] -= offset; + if (array2D[0]) + free (array2D[0]); + else error ("free_mem2Dodouble: trying to free unused memory",100); + + free (array2D); + + } else + { + error ("free_mem2Dodouble: trying to free unused memory",100); + } +} + +/*! + ************************************************************************ + * \brief + * free 3D memory array with offset + ************************************************************************ + */ +void free_mem3Dodouble(double ***array3D, int dim0, int dim1, int offset) +{ + int i, j; + + if (array3D) + { + for (i = 0; i < dim0; i++) + { + for (j = -offset; j < dim1 - offset; j++) + { + if (array3D[i][j]) + free(array3D[i][j]); + else + error ("free_mem3Dodouble: trying to free unused memory",100); + } + } + array3D[0] -= offset; + if (array3D[0]) + free(array3D[0]); + else + error ("free_mem3Dodouble: trying to free unused memory",100); + free (array3D); + } + else + { + error ("free_mem3Dodouble: trying to free unused memory",100); + } +} + +/*! + ************************************************************************ + * \brief + * free 3D memory array with offset + ************************************************************************ + */ +void free_mem3Doint(int ***array3D, int dim0, int dim1, int offset) +{ + int i, j; + + if (array3D) + { + for (i = 0; i < dim0; i++) + { + for (j = -offset; j < dim1 - offset; j++) + { + if (array3D[i][j]) + free(array3D[i][j]); + else + error ("free_mem3Doint: trying to free unused memory",100); + } + } + array3D[0] -= offset; + if (array3D[0]) + free(array3D[0]); + else + error ("free_mem3Doint: trying to free unused memory",100); + free (array3D); + } + else + { + error ("free_mem3Doint: trying to free unused memory",100); + } +} + + +/*! +************************************************************************ +* \brief +* free 2D double memory array (with offset) +* which was allocated with get_mem2Ddouble() +************************************************************************ +*/ +void free_mem2Doint(int **array2D, int offset) +{ + if (array2D) + { + array2D[0] -= offset; + if (array2D[0]) + free (array2D[0]); + else + error ("free_mem2Doint: trying to free unused memory",100); + + free (array2D); + + } + else + { + error ("free_mem2Doint: trying to free unused memory",100); + } +} + +/*! +************************************************************************ +* \brief +* free 2D double memory array (with offset) +* which was allocated with get_mem2Ddouble() +************************************************************************ +*/ +void free_offset_mem2Dshort(short **array2D, int dim1, int offset_y, int offset_x) +{ + if (array2D) + { + array2D[0] -= offset_x + offset_y * dim1; + if (array2D[0]) + free (array2D[0]); + else + error ("free_offset_mem2Dshort: trying to free unused memory",100); + + free (array2D); + + } + else + { + error ("free_offset_mem2Dshort: trying to free unused memory",100); + } +} + +/*! + ************************************************************************ + * \brief + * free 3D memory array + * which was alocated with get_mem3Dint() + ************************************************************************ + */ +void free_mem3Ddouble(double ***array3D) +{ + if (array3D) + { + free_mem2Ddouble(*array3D); + free (array3D); + } + else + { + error ("free_mem3D: trying to free unused memory",100); + } +} + + +#endif diff --git a/Src/h264dec/lcommon/src/memcache.c b/Src/h264dec/lcommon/src/memcache.c new file mode 100644 index 00000000..ce3b29d1 --- /dev/null +++ b/Src/h264dec/lcommon/src/memcache.c @@ -0,0 +1,106 @@ +#include "memcache.h" +#include "mbuffer.h" +#include "memalloc.h" + +void image_cache_flush(ImageCache *cache) +{ + while (cache->head) + { + VideoImage *next = cache->head->next; + free_memImage(cache->head); + cache->head = next; + } + cache->size_x = 0; + cache->size_y = 0; +} + +void image_cache_set_dimensions(ImageCache *cache, int width, int height) +{ + if (width != cache->size_x || height != cache->size_y) + { + image_cache_flush(cache); + cache->size_x = width; + cache->size_y = height; + } +} + +int image_cache_dimensions_match(ImageCache *cache, int width, int height) +{ + if (width != cache->size_x || height != cache->size_y) + return 0; + + return 1; +} + +void image_cache_add(ImageCache *cache, VideoImage *image) +{ + image->next = cache->head; + cache->head = image; +} + +struct video_image *image_cache_get(ImageCache *cache) +{ + if (cache->head) + { + VideoImage *ret = cache->head; + cache->head = ret->next; + ret->next = 0; + return ret; + } + return 0; +} + +/* ------------- + +PicMotion arrays are allowed with one extra slot in the first dimension +which we use as the next pointer +------------- */ + + +void motion_cache_flush(MotionCache *cache) +{ + while (cache->head) + { + PicMotion **next = (PicMotion **)cache->head[cache->size_y]; + free_mem2DPicMotion(cache->head); + cache->head = next; + } + cache->size_x = 0; + cache->size_y = 0; +} + +void motion_cache_set_dimensions(MotionCache *cache, int width, int height) +{ + if (width != cache->size_x || height != cache->size_y) + { + motion_cache_flush(cache); + cache->size_x = width; + cache->size_y = height; + } +} + +int motion_cache_dimensions_match(MotionCache *cache, int width, int height) +{ + if (width != cache->size_x || height != cache->size_y) + return 0; + + return 1; +} + +void motion_cache_add(MotionCache *cache, PicMotion **image) +{ + image[cache->size_y] = (PicMotion *)cache->head; + cache->head = image; +} + +struct pic_motion **motion_cache_get(MotionCache *cache) +{ + if (cache->head) + { + PicMotion **ret = cache->head; + cache->head = (PicMotion **)ret[cache->size_y]; + ret[cache->size_y] = 0; + return ret; + } + return 0; +} diff --git a/Src/h264dec/lcommon/src/mv_prediction.c b/Src/h264dec/lcommon/src/mv_prediction.c new file mode 100644 index 00000000..b4638d6d --- /dev/null +++ b/Src/h264dec/lcommon/src/mv_prediction.c @@ -0,0 +1,250 @@ +/*! + ************************************************************************************* + * \file mv_prediction.c + * + * \brief + * Motion Vector Prediction Functions + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Alexis Michael Tourapis <alexismt@ieee.org> + * - Karsten Sühring <suehring@hhi.de> + ************************************************************************************* + */ + +#include "global.h" +#include "mbuffer.h" +/*! + ************************************************************************ + * \brief + * Get motion vector predictor + ************************************************************************ + */ +static void GetMotionVectorPredictorMBAFF (Macroblock *currMB, + PixelPos *block, // <--> block neighbors + short pmv[2], + short ref_frame, + PicMotion **motion, + int mb_x, + int mb_y, + int blockshape_x, + int blockshape_y) +{ + int mv_a, mv_b, mv_c, pred_vec=0; + int mvPredType, rFrameL, rFrameU, rFrameUR; + int hv; + VideoParameters *p_Vid = currMB->p_Vid; + + mvPredType = MVPRED_MEDIAN; + + + if (currMB->mb_field) + { + rFrameL = block[0].available + ? (p_Vid->mb_data[block[0].mb_addr].mb_field + ? motion[block[0].pos_y][block[0].pos_x].ref_idx + : motion[block[0].pos_y][block[0].pos_x].ref_idx * 2) : -1; + rFrameU = block[1].available + ? (p_Vid->mb_data[block[1].mb_addr].mb_field + ? motion[block[1].pos_y][block[1].pos_x].ref_idx + : motion[block[1].pos_y][block[1].pos_x].ref_idx * 2) : -1; + rFrameUR = block[2].available + ? (p_Vid->mb_data[block[2].mb_addr].mb_field + ? motion[block[2].pos_y][block[2].pos_x].ref_idx + : motion[block[2].pos_y][block[2].pos_x].ref_idx * 2) : -1; + } + else + { + rFrameL = block[0].available + ? (p_Vid->mb_data[block[0].mb_addr].mb_field + ? motion[block[0].pos_y][block[0].pos_x].ref_idx >>1 + : motion[block[0].pos_y][block[0].pos_x].ref_idx) : -1; + rFrameU = block[1].available + ? (p_Vid->mb_data[block[1].mb_addr].mb_field + ? motion[block[1].pos_y][block[1].pos_x].ref_idx >>1 + : motion[block[1].pos_y][block[1].pos_x].ref_idx) : -1; + rFrameUR = block[2].available + ? (p_Vid->mb_data[block[2].mb_addr].mb_field + ? motion[block[2].pos_y][block[2].pos_x].ref_idx >>1 + : motion[block[2].pos_y][block[2].pos_x].ref_idx) : -1; + } + + + /* Prediction if only one of the neighbors uses the reference frame + * we are checking + */ + if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame) + mvPredType = MVPRED_L; + else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame) + mvPredType = MVPRED_U; + else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame) + mvPredType = MVPRED_UR; + // Directional predictions + if(blockshape_x == 8 && blockshape_y == 16) + { + if(mb_x == 0) + { + if(rFrameL == ref_frame) + mvPredType = MVPRED_L; + } + else + { + if( rFrameUR == ref_frame) + mvPredType = MVPRED_UR; + } + } + else if(blockshape_x == 16 && blockshape_y == 8) + { + if(mb_y == 0) + { + if(rFrameU == ref_frame) + mvPredType = MVPRED_U; + } + else + { + if(rFrameL == ref_frame) + mvPredType = MVPRED_L; + } + } + + for (hv=0; hv < 2; hv++) + { + if (hv == 0) + { + mv_a = block[0].available ? motion[block[0].pos_y][block[0].pos_x].mv[hv] : 0; + mv_b = block[1].available ? motion[block[1].pos_y][block[1].pos_x].mv[hv] : 0; + mv_c = block[2].available ? motion[block[2].pos_y][block[2].pos_x].mv[hv] : 0; + } + else + { + if (currMB->mb_field) + { + mv_a = block[0].available ? p_Vid->mb_data[block[0].mb_addr].mb_field + ? motion[block[0].pos_y][block[0].pos_x].mv[hv] + : motion[block[0].pos_y][block[0].pos_x].mv[hv] / 2 + : 0; + mv_b = block[1].available ? p_Vid->mb_data[block[1].mb_addr].mb_field + ? motion[block[1].pos_y][block[1].pos_x].mv[hv] + : motion[block[1].pos_y][block[1].pos_x].mv[hv] / 2 + : 0; + mv_c = block[2].available ? p_Vid->mb_data[block[2].mb_addr].mb_field + ? motion[block[2].pos_y][block[2].pos_x].mv[hv] + : motion[block[2].pos_y][block[2].pos_x].mv[hv] / 2 + : 0; + } + else + { + mv_a = block[0].available ? p_Vid->mb_data[block[0].mb_addr].mb_field + ? motion[block[0].pos_y][block[0].pos_x].mv[hv] * 2 + : motion[block[0].pos_y][block[0].pos_x].mv[hv] + : 0; + mv_b = block[1].available ? p_Vid->mb_data[block[1].mb_addr].mb_field + ? motion[block[1].pos_y][block[1].pos_x].mv[hv] * 2 + : motion[block[1].pos_y][block[1].pos_x].mv[hv] + : 0; + mv_c = block[2].available ? p_Vid->mb_data[block[2].mb_addr].mb_field + ? motion[block[2].pos_y][block[2].pos_x].mv[hv] * 2 + : motion[block[2].pos_y][block[2].pos_x].mv[hv] + : 0; + } + } + + switch (mvPredType) + { + case MVPRED_MEDIAN: + if(!(block[1].available || block[2].available)) + { + pred_vec = mv_a; + } + else + { + pred_vec = mv_a + mv_b + mv_c - imin(mv_a, imin(mv_b, mv_c)) - imax(mv_a, imax(mv_b ,mv_c)); + } + break; + case MVPRED_L: + pred_vec = mv_a; + break; + case MVPRED_U: + pred_vec = mv_b; + break; + case MVPRED_UR: + pred_vec = mv_c; + break; + default: + break; + } + + pmv[hv] = (short) pred_vec; + } +} + +/*! + ************************************************************************ + * \brief + * Get motion vector predictor + ************************************************************************ + */ +// TODO: benski> make SSE3/MMX version +static void GetMotionVectorPredictorNormal (Macroblock *currMB, + PixelPos *block, // <--> block neighbors + short pmv[2], + short ref_frame, + PicMotion **motion, + int mb_x, + int mb_y, + int blockshape_x, + int blockshape_y) +{ + int rFrameL = block[0].available ? motion[block[0].pos_y][block[0].pos_x].ref_idx : -1; + int rFrameU = block[1].available ? motion[block[1].pos_y][block[1].pos_x].ref_idx : -1; + int rFrameUR = block[2].available ? motion[block[2].pos_y][block[2].pos_x].ref_idx : -1; + + /* Prediction if only one of the neighbors uses the reference frame + * we are checking + */ + if (rFrameL == ref_frame && + ((rFrameU != ref_frame && rFrameUR != ref_frame) || (blockshape_x == 8 && blockshape_y == 16 && mb_x == 0) || (blockshape_x == 16 && blockshape_y == 8 && mb_y != 0))) + { // left + pmv[0] = block[0].available ? motion[block[0].pos_y][block[0].pos_x].mv[0] : 0; + pmv[1] = block[0].available ? motion[block[0].pos_y][block[0].pos_x].mv[1] : 0; + } + else if (rFrameU == ref_frame && + ((rFrameL != ref_frame && rFrameUR != ref_frame) || (blockshape_x == 16 && blockshape_y == 8 && mb_y == 0))) + { // up + pmv[0] = block[1].available ? motion[block[1].pos_y][block[1].pos_x].mv[0] : 0; + pmv[1] = block[1].available ? motion[block[1].pos_y][block[1].pos_x].mv[1] : 0; + } + else if (rFrameUR == ref_frame && + ((rFrameL != ref_frame && rFrameU != ref_frame) || (blockshape_x == 8 && blockshape_y == 16 && mb_x != 0))) + { // upper right + pmv[0] = block[2].available ? motion[block[2].pos_y][block[2].pos_x].mv[0] : 0; + pmv[1] = block[2].available ? motion[block[2].pos_y][block[2].pos_x].mv[1] : 0; + } + else + { // median + if(!(block[1].available || block[2].available)) + { + pmv[0] = block[0].available ? motion[block[0].pos_y][block[0].pos_x].mv[0] : 0; + pmv[1] = block[0].available ? motion[block[0].pos_y][block[0].pos_x].mv[1] : 0; + } + else + { + int mv_a = block[0].available ? motion[block[0].pos_y][block[0].pos_x].mv[0] : 0; + int mv_b = block[1].available ? motion[block[1].pos_y][block[1].pos_x].mv[0] : 0; + int mv_c = block[2].available ? motion[block[2].pos_y][block[2].pos_x].mv[0] : 0; + pmv[0] = mv_a + mv_b + mv_c - imin(mv_a, imin(mv_b, mv_c)) - imax(mv_a, imax(mv_b ,mv_c)); + mv_a = block[0].available ? motion[block[0].pos_y][block[0].pos_x].mv[1] : 0; + mv_b = block[1].available ? motion[block[1].pos_y][block[1].pos_x].mv[1] : 0; + mv_c = block[2].available ? motion[block[2].pos_y][block[2].pos_x].mv[1] : 0; + pmv[1] = mv_a + mv_b + mv_c - imin(mv_a, imin(mv_b, mv_c)) - imax(mv_a, imax(mv_b ,mv_c)); + } + } +} + +void init_motion_vector_prediction(Macroblock *currMB, int mb_aff_frame_flag) +{ + if (mb_aff_frame_flag) + currMB->GetMVPredictor = GetMotionVectorPredictorMBAFF; + else + currMB->GetMVPredictor = GetMotionVectorPredictorNormal; +} diff --git a/Src/h264dec/lcommon/src/parsetcommon.c b/Src/h264dec/lcommon/src/parsetcommon.c new file mode 100644 index 00000000..fe3f0e9a --- /dev/null +++ b/Src/h264dec/lcommon/src/parsetcommon.c @@ -0,0 +1,244 @@ + +/*! + ************************************************************************************** + * \file + * parsetcommon.c + * \brief + * Picture and Sequence Parameter set generation and handling + * \date 25 November 2002 + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Stephan Wenger <stewe@cs.tu-berlin.de> + * + ************************************************************************************** + */ + +#include "global.h" +#include "parsetcommon.h" +#include "memalloc.h" +/*! + ************************************************************************************* + * \brief + * Allocates memory for a picture paramater set + * + * \return + * pointer to a pps + ************************************************************************************* + */ + +pic_parameter_set_rbsp_t *AllocPPS () + { + pic_parameter_set_rbsp_t *p; + + if ((p=calloc (sizeof (pic_parameter_set_rbsp_t), 1)) == NULL) + no_mem_exit ("AllocPPS: PPS"); + p->slice_group_id = NULL; + return p; + } + + +/*! + ************************************************************************************* + * \brief + * Allocates memory for am sequence paramater set + * + * \return + * pointer to a sps + ************************************************************************************* + */ + +seq_parameter_set_rbsp_t *AllocSPS () + { + seq_parameter_set_rbsp_t *p; + + if ((p=calloc (sizeof (seq_parameter_set_rbsp_t), 1)) == NULL) + no_mem_exit ("AllocSPS: SPS"); + return p; + } + + +/*! + ************************************************************************************* + * \brief + * Frees a picture parameter set + * + * \param pps to be freed + * Picture parameter set to be freed + ************************************************************************************* + */ + + void FreePPS (pic_parameter_set_rbsp_t *pps) + { + assert (pps != NULL); + if (pps->slice_group_id != NULL) + free (pps->slice_group_id); + free (pps); + } + + + /*! + ************************************************************************************* + * \brief + * Frees a sps + * + * \param sps + * Sequence parameter set to be freed + ************************************************************************************* + */ + + void FreeSPS (seq_parameter_set_rbsp_t *sps) + { + assert (sps != NULL); + free (sps); + } + + +int sps_is_equal(seq_parameter_set_rbsp_t *sps1, seq_parameter_set_rbsp_t *sps2) +{ + unsigned i; + int equal = 1; + + if ((!sps1->Valid) || (!sps2->Valid)) + return 0; + + equal &= (sps1->profile_idc == sps2->profile_idc); + equal &= (sps1->constrained_set0_flag == sps2->constrained_set0_flag); + equal &= (sps1->constrained_set1_flag == sps2->constrained_set1_flag); + equal &= (sps1->constrained_set2_flag == sps2->constrained_set2_flag); + equal &= (sps1->level_idc == sps2->level_idc); + equal &= (sps1->seq_parameter_set_id == sps2->seq_parameter_set_id); + equal &= (sps1->log2_max_frame_num_minus4 == sps2->log2_max_frame_num_minus4); + equal &= (sps1->pic_order_cnt_type == sps2->pic_order_cnt_type); + + if (!equal) return equal; + + if( sps1->pic_order_cnt_type == 0 ) + { + equal &= (sps1->log2_max_pic_order_cnt_lsb_minus4 == sps2->log2_max_pic_order_cnt_lsb_minus4); + } + + else if( sps1->pic_order_cnt_type == 1 ) + { + equal &= (sps1->delta_pic_order_always_zero_flag == sps2->delta_pic_order_always_zero_flag); + equal &= (sps1->offset_for_non_ref_pic == sps2->offset_for_non_ref_pic); + equal &= (sps1->offset_for_top_to_bottom_field == sps2->offset_for_top_to_bottom_field); + equal &= (sps1->num_ref_frames_in_pic_order_cnt_cycle == sps2->num_ref_frames_in_pic_order_cnt_cycle); + if (!equal) return equal; + + for ( i = 0 ; i< sps1->num_ref_frames_in_pic_order_cnt_cycle ;i ++) + equal &= (sps1->offset_for_ref_frame[i] == sps2->offset_for_ref_frame[i]); + } + + equal &= (sps1->num_ref_frames == sps2->num_ref_frames); + equal &= (sps1->gaps_in_frame_num_value_allowed_flag == sps2->gaps_in_frame_num_value_allowed_flag); + equal &= (sps1->pic_width_in_mbs_minus1 == sps2->pic_width_in_mbs_minus1); + equal &= (sps1->pic_height_in_map_units_minus1 == sps2->pic_height_in_map_units_minus1); + equal &= (sps1->frame_mbs_only_flag == sps2->frame_mbs_only_flag); + + if (!equal) return equal; + if( !sps1->frame_mbs_only_flag ) + equal &= (sps1->mb_adaptive_frame_field_flag == sps2->mb_adaptive_frame_field_flag); + + equal &= (sps1->direct_8x8_inference_flag == sps2->direct_8x8_inference_flag); + equal &= (sps1->frame_cropping_flag == sps2->frame_cropping_flag); + if (!equal) return equal; + if (sps1->frame_cropping_flag) + { + equal &= (sps1->frame_cropping_rect_left_offset == sps2->frame_cropping_rect_left_offset); + equal &= (sps1->frame_cropping_rect_right_offset == sps2->frame_cropping_rect_right_offset); + equal &= (sps1->frame_cropping_rect_top_offset == sps2->frame_cropping_rect_top_offset); + equal &= (sps1->frame_cropping_rect_bottom_offset == sps2->frame_cropping_rect_bottom_offset); + } + equal &= (sps1->vui_parameters_present_flag == sps2->vui_parameters_present_flag); + + return equal; +} + +int pps_is_equal(pic_parameter_set_rbsp_t *pps1, pic_parameter_set_rbsp_t *pps2) +{ + unsigned i, j; + int equal = 1; + + if ((!pps1->Valid) || (!pps2->Valid)) + return 0; + + equal &= (pps1->pic_parameter_set_id == pps2->pic_parameter_set_id); + equal &= (pps1->seq_parameter_set_id == pps2->seq_parameter_set_id); + equal &= (pps1->entropy_coding_mode_flag == pps2->entropy_coding_mode_flag); + equal &= (pps1->bottom_field_pic_order_in_frame_present_flag == pps2->bottom_field_pic_order_in_frame_present_flag); + equal &= (pps1->num_slice_groups_minus1 == pps2->num_slice_groups_minus1); + + if (!equal) return equal; + + if (pps1->num_slice_groups_minus1>0) + { + equal &= (pps1->slice_group_map_type == pps2->slice_group_map_type); + if (!equal) return equal; + if (pps1->slice_group_map_type == 0) + { + for (i=0; i<=pps1->num_slice_groups_minus1; i++) + equal &= (pps1->run_length_minus1[i] == pps2->run_length_minus1[i]); + } + else if( pps1->slice_group_map_type == 2 ) + { + for (i=0; i<pps1->num_slice_groups_minus1; i++) + { + equal &= (pps1->top_left[i] == pps2->top_left[i]); + equal &= (pps1->bottom_right[i] == pps2->bottom_right[i]); + } + } + else if( pps1->slice_group_map_type == 3 || pps1->slice_group_map_type==4 || pps1->slice_group_map_type==5 ) + { + equal &= (pps1->slice_group_change_direction_flag == pps2->slice_group_change_direction_flag); + equal &= (pps1->slice_group_change_rate_minus1 == pps2->slice_group_change_rate_minus1); + } + else if( pps1->slice_group_map_type == 6 ) + { + equal &= (pps1->pic_size_in_map_units_minus1 == pps2->pic_size_in_map_units_minus1); + if (!equal) return equal; + for (i=0; i<=pps1->pic_size_in_map_units_minus1; i++) + equal &= (pps1->slice_group_id[i] == pps2->slice_group_id[i]); + } + } + + equal &= (pps1->num_ref_idx_l0_active_minus1 == pps2->num_ref_idx_l0_active_minus1); + equal &= (pps1->num_ref_idx_l1_active_minus1 == pps2->num_ref_idx_l1_active_minus1); + equal &= (pps1->weighted_pred_flag == pps2->weighted_pred_flag); + equal &= (pps1->weighted_bipred_idc == pps2->weighted_bipred_idc); + equal &= (pps1->pic_init_qp_minus26 == pps2->pic_init_qp_minus26); + equal &= (pps1->pic_init_qs_minus26 == pps2->pic_init_qs_minus26); + equal &= (pps1->chroma_qp_index_offset == pps2->chroma_qp_index_offset); + equal &= (pps1->deblocking_filter_control_present_flag == pps2->deblocking_filter_control_present_flag); + equal &= (pps1->constrained_intra_pred_flag == pps2->constrained_intra_pred_flag); + equal &= (pps1->redundant_pic_cnt_present_flag == pps2->redundant_pic_cnt_present_flag); + + if (!equal) return equal; + + //Fidelity Range Extensions Stuff + //It is initialized to zero, so should be ok to check all the time. + equal &= (pps1->transform_8x8_mode_flag == pps2->transform_8x8_mode_flag); + equal &= (pps1->pic_scaling_matrix_present_flag == pps2->pic_scaling_matrix_present_flag); + if(pps1->pic_scaling_matrix_present_flag) + { + for(i = 0; i < (6 + ((unsigned)pps1->transform_8x8_mode_flag << 1)); i++) + { + equal &= (pps1->pic_scaling_list_present_flag[i] == pps2->pic_scaling_list_present_flag[i]); + if(pps1->pic_scaling_list_present_flag[i]) + { + if(i < 6) + { + for (j = 0; j < 16; j++) + equal &= (pps1->ScalingList4x4[i][j] == pps2->ScalingList4x4[i][j]); + } + else + { + for (j = 0; j < 64; j++) + equal &= (pps1->ScalingList8x8[i-6][j] == pps2->ScalingList8x8[i-6][j]); + } + } + } + } + equal &= (pps1->second_chroma_qp_index_offset == pps2->second_chroma_qp_index_offset); + + return equal; +} diff --git a/Src/h264dec/lcommon/src/transform.c b/Src/h264dec/lcommon/src/transform.c new file mode 100644 index 00000000..617ca7c1 --- /dev/null +++ b/Src/h264dec/lcommon/src/transform.c @@ -0,0 +1,809 @@ +/*! +*************************************************************************** +* \file transform.c +* +* \brief +* Transform functions +* +* \author +* Main contributors (see contributors.h for copyright, address and affiliation details) +* - Alexis Michael Tourapis +* \date +* 01. July 2007 +************************************************************************** +*/ +#include "global.h" +#include "transform.h" +#include <emmintrin.h> + +void forward4x4(int **block, int **tblock, int pos_y, int pos_x) +{ + int i, ii; + int tmp[16]; + int *pTmp = tmp, *pblock; + int p0,p1,p2,p3; + int t0,t1,t2,t3; + + // Horizontal + for (i=pos_y; i < pos_y + BLOCK_SIZE; i++) + { + pblock = &block[i][pos_x]; + p0 = *(pblock++); + p1 = *(pblock++); + p2 = *(pblock++); + p3 = *(pblock ); + + t0 = p0 + p3; + t1 = p1 + p2; + t2 = p1 - p2; + t3 = p0 - p3; + + *(pTmp++) = t0 + t1; + *(pTmp++) = (t3 << 1) + t2; + *(pTmp++) = t0 - t1; + *(pTmp++) = t3 - (t2 << 1); + } + + // Vertical + for (i=0; i < BLOCK_SIZE; i++) + { + pTmp = tmp + i; + p0 = *pTmp; + p1 = *(pTmp += BLOCK_SIZE); + p2 = *(pTmp += BLOCK_SIZE); + p3 = *(pTmp += BLOCK_SIZE); + + t0 = p0 + p3; + t1 = p1 + p2; + t2 = p1 - p2; + t3 = p0 - p3; + + ii = pos_x + i; + tblock[pos_y ][ii] = t0 + t1; + tblock[pos_y + 1][ii] = t2 + (t3 << 1); + tblock[pos_y + 2][ii] = t0 - t1; + tblock[pos_y + 3][ii] = t3 - (t2 << 1); + } +} + +static void inverse4x4(const h264_short_block_t tblock, h264_short_block_t block, int pos_y, int pos_x) +{ + int i; + short tmp[16]; + short *pTmp = tmp; + int p0,p1,p2,p3; + int t0,t1,t2,t3; + + // Horizontal + for (i = 0; i < BLOCK_SIZE; i++) + { + t0 = tblock[i][0]; + t1 = tblock[i][1]; + t2 = tblock[i][2]; + t3 = tblock[i][3]; + + p0 = t0 + t2; + p1 = t0 - t2; + p2 = (t1 >> 1) - t3; + p3 = t1 + (t3 >> 1); + + *(pTmp++) = p0 + p3; + *(pTmp++) = p1 + p2; + *(pTmp++) = p1 - p2; + *(pTmp++) = p0 - p3; + } + + // Vertical + for (i = 0; i < BLOCK_SIZE; i++) + { + pTmp = tmp + i; + t0 = *pTmp; + t1 = *(pTmp += BLOCK_SIZE); + t2 = *(pTmp += BLOCK_SIZE); + t3 = *(pTmp += BLOCK_SIZE); + + p0 = t0 + t2; + p1 = t0 - t2; + p2 =(t1 >> 1) - t3; + p3 = t1 + (t3 >> 1); + + block[0][i] = p0 + p3; + block[1][i] = p1 + p2; + block[2][i] = p1 - p2; + block[3][i] = p0 - p3; + } +} + +#ifdef _M_IX86 +// benski> this exists just for conformance testing. not used in production code +static void inverse4x4_sse2_x86(const h264_short_macroblock_t tblock, h264_short_macroblock_t block, int pos_y, int pos_x) +{ + __asm + { + mov edx, pos_y + shl edx, 4 // 16 step stride + add edx, pos_x + shl edx, 1 // * sizeof(short) + + // eax: pointer to the start of tblock (offset by passed pos_y, pos_x) + mov eax, edx + add eax, tblock + + // esi: results + mov esi, edx + add esi, block + + // load 4x4 matrix + movq mm0, MMWORD PTR 0[eax] + movq mm1, MMWORD PTR 32[eax] + movq mm2, MMWORD PTR 64[eax] + movq mm3, MMWORD PTR 96[eax] + + // rotate 4x4 matrix + movq mm4, mm0 // p0 = mm4 (copy) + punpcklwd mm0, mm2 // r0 = mm0 + punpckhwd mm4, mm2 // r2 = mm4 + movq mm5, mm1 // p1 = mm5 (copy) + punpcklwd mm1, mm3 // r1 = mm1 + punpckhwd mm5, mm3 // r3 = mm5 + movq mm6, mm0 // r0 = mm6 (copy) + punpcklwd mm0, mm1 // t0 = mm0 + punpckhwd mm6, mm1 // t1 = mm6 + movq mm1, mm4 // r2 = mm1 (copy) + punpcklwd mm1, mm5 // t2 = mm1 + punpckhwd mm4, mm5 // t3 = mm4 + + /* register state: + mm0: t0 + mm1: t2 + mm2: + mm3: + mm4: t3 + mm5: + mm6: t1 + mm7: + */ + + /* + p0 = t0 + t2; + p1 = t0 - t2; + p2 = (t1 >> 1) - t3; + p3 = t1 + (t3 >> 1); + */ + movq mm2, mm0 // mm2 = t0 (copy) + paddw mm0, mm1 // mm0 = p0 + psubw mm2, mm1 // mm2 = p1, mm1 available + movq mm5, mm6 // mm5 = t1 (copy) + psraw mm5, 1 // mm5 = (t1 >> 1) + psubw mm5, mm4 // mm5 = p2 + psraw mm4, 1 // mm4 = (t3 >> 1) + paddw mm6, mm4 // mm6 = p3 + + /* register state: + mm0: p0 + mm1: + mm2: p1 + mm3: + mm4: + mm5: p2 + mm6: p3 + mm7: + */ + + /* + *(pTmp++) = p0 + p3; + *(pTmp++) = p1 + p2; + *(pTmp++) = p1 - p2; + *(pTmp++) = p0 - p3; + */ + + movq mm3, mm0 // mm3 = p0 (copy) + paddw mm0, mm6 // mm0 = r0 + movq mm1, mm2 // mm1 = p1 (copy) + paddw mm1, mm5 // mm1 = r1 + psubw mm2, mm5 // mm2 = r2, mm5 available + psubw mm3, mm6 // mm3 = r3 + + /* register state: + mm0: r0 + mm1: r1 + mm2: r2 + mm3: r3 + mm4: + mm5: + mm6: + mm7: + */ + + // rotate 4x4 matrix to set up for vertical + movq mm4, mm0 // r0 = mm4 (copy) + punpcklwd mm0, mm2 // p0 = mm0 + punpckhwd mm4, mm2 // p2 = mm4 + movq mm5, mm1 // r1 = mm5 (copy) + punpcklwd mm1, mm3 // p1 = mm1 + punpckhwd mm5, mm3 // p3 = mm5 + movq mm6, mm0 // p0 = mm6 (copy) + punpcklwd mm0, mm1 // t0 = mm0 + punpckhwd mm6, mm1 // t1 = mm6 + movq mm1, mm4 // p2 = mm1 (copy) + punpcklwd mm1, mm5 // t2 = mm1 + punpckhwd mm4, mm5 // t3 = mm4 + + /* register state: + mm0: t0 + mm1: t2 + mm2: + mm3: + mm4: t3 + mm5: + mm6: t1 + mm7: + */ + /* + p0 = t0 + t2; + p1 = t0 - t2; + p2 = (t1 >> 1) - t3; + p3 = t1 + (t3 >> 1); + */ + movq mm2, mm0 // mm2 = t0 (copy) + paddw mm0, mm1 // mm0 = p0 + psubw mm2, mm1 // mm2 = p1, mm1 available + movq mm5, mm6 // mm5 = t1 (copy) + psraw mm5, 1 // mm5 = (t1 >> 1) + psubw mm5, mm4 // mm5 = p2 + psraw mm4, 1 // mm4 = (t3 >> 1) + paddw mm6, mm4 // mm6 = p3 + + /* register state: + mm0: p0 + mm1: + mm2: p1 + mm3: + mm4: + mm5: p2 + mm6: p3 + mm7: + */ + + /* + *(pTmp++) = p0 + p3; + *(pTmp++) = p1 + p2; + *(pTmp++) = p1 - p2; + *(pTmp++) = p0 - p3; + */ + + movq mm3, mm0 // mm3 = p0 (copy) + paddw mm0, mm6 // mm0 = r0 + movq mm1, mm2 // mm1 = p1 (copy) + paddw mm1, mm5 // mm1 = r1 + psubw mm2, mm5 // mm2 = r2, mm5 available + psubw mm3, mm6 // mm3 = r3 + + /* register state: + mm0: r0 + mm1: r1 + mm2: r2 + mm3: r3 + mm4: + mm5: + mm6: + mm7: + */ + movq XMMWORD PTR 0[esi], mm0 + movq XMMWORD PTR 32[esi], mm1 + movq XMMWORD PTR 64[esi], mm2 + movq XMMWORD PTR 96[esi], mm3 + } +} +#endif + +static void sample_reconstruct(h264_imgpel_macroblock_t curImg, const h264_imgpel_macroblock_t mpr, const h264_short_block_t tblock, int joff, int mb_x, int max_imgpel_value) +{ + #ifdef _M_IX86 + __asm + { + // mm0 : constant value 32 + mov edx, 0x00200020 + movd mm0, edx + punpckldq mm0, mm0 + + // ecx: y offset + mov ecx, joff + shl ecx, 4 // imgpel stuff is going to be 16 byte stride + add ecx, mb_x + + // eax: curImg + mov eax, curImg + add eax, ecx + + // edx: mpr + mov edx, mpr + add edx, ecx + + // ecx: tblock (which is short, not byte) + mov ecx, tblock + + // mm7: zero + pxor mm7, mm7 + + // load coefficients + movq mm1, MMWORD PTR 0[ecx] + movq mm2, MMWORD PTR 8[ecx] + movq mm3, MMWORD PTR 16[ecx] + movq mm4, MMWORD PTR 24[ecx] + paddw mm1, mm0 // rres + 32 + paddw mm2, mm0 // rres + 32 + paddw mm3, mm0 // rres + 32 + paddw mm0, mm4 // rres + 32 + psraw mm1, 6 // (rres + 32) >> 6 + psraw mm2, 6 // (rres + 32) >> 6 + psraw mm3, 6 // (rres + 32) >> 6 + psraw mm0, 6 // (rres + 32) >> 6 + // mm1-mm3: tblock[0] - tblock[2], mm0: tblock[3] + + // convert mpr from unsigned char to short + movd mm4, DWORD PTR 0[edx] + movd mm5, DWORD PTR 16[edx] + movd mm6, DWORD PTR 32[edx] + punpcklbw mm4, mm7 + punpcklbw mm5, mm7 + punpcklbw mm6, mm7 + paddsw mm4, mm1 // pred_row + rres_row + movd mm1, DWORD PTR 48[edx] // reuse mm1 for mpr[3] + paddsw mm5, mm2 // pred_row + rres_row + punpcklbw mm1, mm7 + paddsw mm6, mm3 // pred_row + rres_row + paddsw mm1, mm0 // pred_row + rres_row + // results in mm4, mm5, mm6, mm1 + + // move back to 8 bit + packuswb mm4, mm7 + packuswb mm5, mm7 + packuswb mm6, mm7 + packuswb mm1, mm7 + movd DWORD PTR 0[eax], mm4 + movd DWORD PTR 16[eax], mm5 + movd DWORD PTR 32[eax], mm6 + movd DWORD PTR 48[eax], mm1 + } +#else + int i, j; + + for (j = 0; j < BLOCK_SIZE; j++) + { + for (i=0;i<BLOCK_SIZE;i++) + curImg[j+joff][mb_x+i] = (imgpel) iClip1( max_imgpel_value, rshift_rnd_sf(tblock[j][i], DQ_BITS) + mpr[j+joff][mb_x+i]); + } +#endif +} + +#if defined(_M_IX86) && defined(_DEBUG) +void itrans4x4_sse2(const h264_short_macroblock_t tblock, const h264_imgpel_macroblock_t mb_pred, h264_imgpel_macroblock_t mb_rec, int pos_x, int pos_y) +{ + __declspec(align(32)) static const short const32[4] = {32, 32, 32, 32}; + __asm + { + mov edx, pos_y + shl edx, 4 // imgpel stuff is going to be 16 byte stride + add edx, pos_x + + // eax: tblock + lea eax, [edx*2] + add eax, tblock + + // ecx: mpr + mov ecx, mb_pred + add ecx, edx + + // edx: results + add edx, mb_rec + + // load 4x4 matrix + movq mm0, MMWORD PTR 0[eax] + movq mm1, MMWORD PTR 32[eax] + movq mm2, MMWORD PTR 64[eax] + movq mm3, MMWORD PTR 96[eax] + + // rotate 4x4 matrix + movq mm4, mm0 // p0 = mm4 (copy) + punpcklwd mm0, mm2 // r0 = mm0 + punpckhwd mm4, mm2 // r2 = mm4 + movq mm5, mm1 // p1 = mm5 (copy) + punpcklwd mm1, mm3 // r1 = mm1 + punpckhwd mm5, mm3 // r3 = mm5 + movq mm6, mm0 // r0 = mm6 (copy) + punpcklwd mm0, mm1 // t0 = mm0 + punpckhwd mm6, mm1 // t1 = mm6 + movq mm1, mm4 // r2 = mm1 (copy) + punpcklwd mm1, mm5 // t2 = mm1 + punpckhwd mm4, mm5 // t3 = mm4 + + /* register state: + mm0: t0 + mm1: t2 + mm2: + mm3: + mm4: t3 + mm5: + mm6: t1 + mm7: + */ + + /* + p0 = t0 + t2; + p1 = t0 - t2; + p2 = (t1 >> 1) - t3; + p3 = t1 + (t3 >> 1); + */ + movq mm2, mm0 // mm2 = t0 (copy) + paddw mm0, mm1 // mm0 = p0 + psubw mm2, mm1 // mm2 = p1, mm1 available + movq mm5, mm6 // mm5 = t1 (copy) + psraw mm5, 1 // mm5 = (t1 >> 1) + psubw mm5, mm4 // mm5 = p2 + psraw mm4, 1 // mm4 = (t3 >> 1) + paddw mm6, mm4 // mm6 = p3 + + /* register state: + mm0: p0 + mm1: + mm2: p1 + mm3: + mm4: + mm5: p2 + mm6: p3 + mm7: + */ + + /* + *(pTmp++) = p0 + p3; + *(pTmp++) = p1 + p2; + *(pTmp++) = p1 - p2; + *(pTmp++) = p0 - p3; + */ + + movq mm3, mm0 // mm3 = p0 (copy) + paddw mm0, mm6 // mm0 = r0 + movq mm1, mm2 // mm1 = p1 (copy) + paddw mm1, mm5 // mm1 = r1 + psubw mm2, mm5 // mm2 = r2, mm5 available + psubw mm3, mm6 // mm3 = r3 + + /* register state: + mm0: r0 + mm1: r1 + mm2: r2 + mm3: r3 + mm4: + mm5: + mm6: + mm7: + */ + + // rotate 4x4 matrix to set up for vertical + movq mm4, mm0 // r0 = mm4 (copy) + punpcklwd mm0, mm2 // p0 = mm0 + punpckhwd mm4, mm2 // p2 = mm4 + movq mm5, mm1 // r1 = mm5 (copy) + punpcklwd mm1, mm3 // p1 = mm1 + punpckhwd mm5, mm3 // p3 = mm5 + movq mm6, mm0 // p0 = mm6 (copy) + punpcklwd mm0, mm1 // t0 = mm0 + punpckhwd mm6, mm1 // t1 = mm6 + movq mm1, mm4 // p2 = mm1 (copy) + punpcklwd mm1, mm5 // t2 = mm1 + punpckhwd mm4, mm5 // t3 = mm4 + + /* register state: + mm0: t0 + mm1: t2 + mm2: + mm3: + mm4: t3 + mm5: + mm6: t1 + mm7: + */ + /* + p0 = t0 + t2; + p1 = t0 - t2; + p2 = (t1 >> 1) - t3; + p3 = t1 + (t3 >> 1); + */ + movq mm2, mm0 // mm2 = t0 (copy) + paddw mm0, mm1 // mm0 = p0 + psubw mm2, mm1 // mm2 = p1, mm1 available + movq mm5, mm6 // mm5 = t1 (copy) + psraw mm5, 1 // mm5 = (t1 >> 1) + psubw mm5, mm4 // mm5 = p2 + psraw mm4, 1 // mm4 = (t3 >> 1) + paddw mm6, mm4 // mm6 = p3 + + /* register state: + mm0: p0 + mm1: + mm2: p1 + mm3: + mm4: + mm5: p2 + mm6: p3 + mm7: + */ + + /* + *(pTmp++) = p0 + p3; + *(pTmp++) = p1 + p2; + *(pTmp++) = p1 - p2; + *(pTmp++) = p0 - p3; + */ + + movq mm3, mm0 // mm3 = p0 (copy) + paddw mm0, mm6 // mm0 = r0 + movq mm1, mm2 // mm1 = p1 (copy) + paddw mm1, mm5 // mm1 = r1 + psubw mm2, mm5 // mm2 = r2, mm5 available + psubw mm3, mm6 // mm3 = r3 + + /* register state: + mm0: r0 + mm1: r1 + mm2: r2 + mm3: r3 + mm4: + mm5: + mm6: + mm7: + */ +/* --- 4x4 iDCT done, now time to combine with mpr --- */ + // mm0 : constant value 32 + movq mm7, const32 + + paddw mm0, mm7 // rres + 32 + psraw mm0, 6 // (rres + 32) >> 6 + paddw mm1, mm7 // rres + 32 + psraw mm1, 6 // (rres + 32) >> 6 + paddw mm2, mm7 // rres + 32 + psraw mm2, 6 // (rres + 32) >> 6 + paddw mm3, mm7 // rres + 32 + psraw mm3, 6 // (rres + 32) >> 6 + + pxor mm7, mm7 + + // convert mpr from unsigned char to short + movd mm4, DWORD PTR 0[ecx] + movd mm5, DWORD PTR 16[ecx] + movd mm6, DWORD PTR 32[ecx] + punpcklbw mm4, mm7 + punpcklbw mm5, mm7 + punpcklbw mm6, mm7 + paddsw mm4, mm0 // pred_row + rres_row + movd mm0, DWORD PTR 48[ecx] // reuse mm0 for mpr[3] + paddsw mm5, mm1 // pred_row + rres_row + punpcklbw mm0, mm7 + paddsw mm6, mm2 // pred_row + rres_row + paddsw mm0, mm3 // pred_row + rres_row + // results in mm4, mm5, mm6, mm0 + + // move back to 8 bit + packuswb mm4, mm7 + packuswb mm5, mm7 + packuswb mm6, mm7 + packuswb mm0, mm7 + movd DWORD PTR 0[edx], mm4 + movd DWORD PTR 16[edx], mm5 + movd DWORD PTR 32[edx], mm6 + movd DWORD PTR 48[edx], mm0 + } +} +#elif defined(_M_X64) +static void itrans4x4_sse2(const h264_int_macroblock_t tblock, const h264_imgpel_macroblock_t mb_pred, h264_imgpel_macroblock_t mb_rec, int pos_x, int pos_y) +{ + __declspec(align(32)) static const int const32[4] = {32, 32, 32, 32}; + __m128i p0,p1,p2,p3; + __m128i t0,t1,t2,t3; + __m128i r0,r1,r2,r3; + __m128i c32, zero; + + // horizontal + // load registers in vertical mode, we'll rotate them next + p0 = _mm_loadu_si128((__m128i *)&tblock[pos_y][pos_x]); // 00 01 02 03 + p1 = _mm_loadu_si128((__m128i *)&tblock[pos_y+1][pos_x]); // 10 11 12 13 + p2 = _mm_loadu_si128((__m128i *)&tblock[pos_y+2][pos_x]); // 20 21 22 23 + p3 = _mm_loadu_si128((__m128i *)&tblock[pos_y+3][pos_x]); // 30 31 32 33 + + // rotate 4x4 matrix + r0 = _mm_unpacklo_epi32(p0, p2); // 00 20 01 21 + r1 = _mm_unpacklo_epi32(p1, p3); // 10 30 11 31 + r2 = _mm_unpackhi_epi32(p0, p2); // 02 22 03 23 + r3 = _mm_unpackhi_epi32(p1, p3); // 12 32 13 33 + t0 = _mm_unpacklo_epi32(r0, r1); // 00 10 20 30 + t1 = _mm_unpackhi_epi32(r0, r1); // 01 11 21 31 + t2 = _mm_unpacklo_epi32(r2, r3); // 02 12 22 32 + t3 = _mm_unpackhi_epi32(r2, r3); // 03 13 23 33 + + p0 = _mm_add_epi32(t0, t2); //t0 + t2; + p1 = _mm_sub_epi32(t0, t2); // t0 - t2; + p2 = _mm_srai_epi32(t1, 1); // t1 >> 1 + p2 = _mm_sub_epi32(p2, t3); // (t1 >> 1) - t3; + p3 = _mm_srai_epi32(t3, 1); // (t3 >> 1) + p3 = _mm_add_epi32(p3, t1); // t1 + (t3 >> 1); + + t0 = _mm_add_epi32(p0, p3); //p0 + p3; + t1 = _mm_add_epi32(p1, p2);//p1 + p2; + t2 = _mm_sub_epi32(p1, p2); //p1 - p2; + t3 = _mm_sub_epi32(p0, p3); //p0 - p3; + + // rotate 4x4 matrix to set up for vertical + r0 = _mm_unpacklo_epi32(t0, t2); + r1 = _mm_unpacklo_epi32(t1, t3); + r2 = _mm_unpackhi_epi32(t0, t2); + r3 = _mm_unpackhi_epi32(t1, t3); + t0 = _mm_unpacklo_epi32(r0, r1); + t1 = _mm_unpackhi_epi32(r0, r1); + t2 = _mm_unpacklo_epi32(r2, r3); + t3 = _mm_unpackhi_epi32(r2, r3); + + // vertical + p0 = _mm_add_epi32(t0, t2); //t0 + t2; + p3 = _mm_srai_epi32(t3, 1); // (t3 >> 1) + p3 = _mm_add_epi32(p3, t1); // t1 + (t3 >> 1); + r0 = _mm_add_epi32(p0, p3); //p0 + p3; + r3 = _mm_sub_epi32(p0, p3); //p0 - p3; + p1 = _mm_sub_epi32(t0, t2); // t0 - t2; + p2 = _mm_srai_epi32(t1, 1); // t1 >> 1 + p2 = _mm_sub_epi32(p2, t3); // (t1 >> 1) - t3; + r1 = _mm_add_epi32(p1, p2);//p1 + p2; + r2 = _mm_sub_epi32(p1, p2); //p1 - p2; + + c32 = _mm_load_si128((const __m128i *)const32); + zero = _mm_setzero_si128(); + + // (x + 32) >> 6 + r0 = _mm_add_epi32(r0, c32); + r0 = _mm_srai_epi32(r0, 6); + r1 = _mm_add_epi32(r1, c32); + r1 = _mm_srai_epi32(r1, 6); + r2 = _mm_add_epi32(r2, c32); + r2 = _mm_srai_epi32(r2, 6); + r3 = _mm_add_epi32(r3, c32); + r3 = _mm_srai_epi32(r3, 6); + + // convert to 16bit values + r0 = _mm_packs_epi32(r0, r1); + r2 = _mm_packs_epi32(r2, r3); + + // convert mpr from unsigned char to short + p0 = _mm_cvtsi32_si128(*(int32_t *)&mb_pred[pos_y][pos_x]); + p1 = _mm_cvtsi32_si128(*(int32_t *)&mb_pred[pos_y+1][pos_x]); + p0 = _mm_unpacklo_epi32(p0, p1); + p0 = _mm_unpacklo_epi8(p0, zero); // convert to short + r0 = _mm_add_epi16(r0, p0); + + p0 = _mm_cvtsi32_si128(*(int32_t *)&mb_pred[pos_y+2][pos_x]); + p1 = _mm_cvtsi32_si128(*(int32_t *)&mb_pred[pos_y+3][pos_x]); + p0 = _mm_unpacklo_epi32(p0, p1); + p0 = _mm_unpacklo_epi8(p0, zero); // convert to short + r2 = _mm_add_epi16(r2, p0); + + r0 = _mm_packus_epi16(r0, r2); // convert to unsigned char + *(int32_t *)&mb_rec[pos_y][pos_x] = _mm_cvtsi128_si32(r0); + r0 = _mm_srli_si128(r0, 4); + *(int32_t *)&mb_rec[pos_y+1][pos_x] = _mm_cvtsi128_si32(r0); + r0 = _mm_srli_si128(r0, 4); + *(int32_t *)&mb_rec[pos_y+2][pos_x] = _mm_cvtsi128_si32(r0); + r0 = _mm_srli_si128(r0, 4); + *(int32_t *)&mb_rec[pos_y+3][pos_x] = _mm_cvtsi128_si32(r0); +} +#endif + +void itrans4x4_c(const h264_short_block_t tblock, const h264_imgpel_macroblock_t mb_pred, h264_imgpel_macroblock_t mb_rec, int pos_x, int pos_y) +{ + inverse4x4(tblock, (h264_short_block_row_t *)tblock,pos_y,pos_x); + sample_reconstruct(mb_rec, mb_pred, tblock, pos_y, pos_x, 255); +} + +void ihadamard4x4(int block[4][4]) +{ + int i; + int tmp[16]; + int *pTmp = tmp; + int p0,p1,p2,p3; + int t0,t1,t2,t3; + + // Horizontal + for (i = 0; i < BLOCK_SIZE; i++) + { + t0 = block[i][0]; + t1 = block[i][1]; + t2 = block[i][2]; + t3 = block[i][3]; + + p0 = t0 + t2; + p1 = t0 - t2; + p2 = t1 - t3; + p3 = t1 + t3; + + *(pTmp++) = p0 + p3; + *(pTmp++) = p1 + p2; + *(pTmp++) = p1 - p2; + *(pTmp++) = p0 - p3; + } + + // Vertical + for (i = 0; i < BLOCK_SIZE; i++) + { + pTmp = tmp + i; + t0 = *pTmp; + t1 = *(pTmp += BLOCK_SIZE); + t2 = *(pTmp += BLOCK_SIZE); + t3 = *(pTmp += BLOCK_SIZE); + + p0 = t0 + t2; + p1 = t0 - t2; + p2 = t1 - t3; + p3 = t1 + t3; + + block[0][i] = p0 + p3; + block[1][i] = p1 + p2; + block[2][i] = p1 - p2; + block[3][i] = p0 - p3; + } +} + +void ihadamard4x2(int **tblock, int **block) +{ + int i; + int tmp[8]; + int *pTmp = tmp; + int p0,p1,p2,p3; + int t0,t1,t2,t3; + + // Horizontal + *(pTmp++) = tblock[0][0] + tblock[1][0]; + *(pTmp++) = tblock[0][1] + tblock[1][1]; + *(pTmp++) = tblock[0][2] + tblock[1][2]; + *(pTmp++) = tblock[0][3] + tblock[1][3]; + + *(pTmp++) = tblock[0][0] - tblock[1][0]; + *(pTmp++) = tblock[0][1] - tblock[1][1]; + *(pTmp++) = tblock[0][2] - tblock[1][2]; + *(pTmp ) = tblock[0][3] - tblock[1][3]; + + // Vertical + pTmp = tmp; + for (i = 0; i < 2; i++) + { + p0 = *(pTmp++); + p1 = *(pTmp++); + p2 = *(pTmp++); + p3 = *(pTmp++); + + t0 = p0 + p2; + t1 = p0 - p2; + t2 = p1 - p3; + t3 = p1 + p3; + + // coefficients (transposed) + block[0][i] = t0 + t3; + block[1][i] = t1 + t2; + block[2][i] = t1 - t2; + block[3][i] = t0 - t3; + } +} + +//following functions perform 8 additions, 8 assignments. Should be a bit faster +void ihadamard2x2(int tblock[4], int block[4]) +{ + int t0,t1,t2,t3; + + t0 = tblock[0] + tblock[1]; + t1 = tblock[0] - tblock[1]; + t2 = tblock[2] + tblock[3]; + t3 = tblock[2] - tblock[3]; + + block[0] = (t0 + t2); + block[1] = (t1 + t3); + block[2] = (t0 - t2); + block[3] = (t1 - t3); +} + diff --git a/Src/h264dec/lcommon/src/win32.c b/Src/h264dec/lcommon/src/win32.c new file mode 100644 index 00000000..7d921e1e --- /dev/null +++ b/Src/h264dec/lcommon/src/win32.c @@ -0,0 +1,67 @@ + +/*! + ************************************************************************************* + * \file win32.c + * + * \brief + * Platform dependent code + * + * \author + * Main contributors (see contributors.h for copyright, address and affiliation details) + * - Karsten Suehring <suehring@hhi.de> + ************************************************************************************* + */ + +#include "global.h" + + +#ifdef _WIN32 + +static LARGE_INTEGER freq; + +void gettime(TIME_T* time) +{ + QueryPerformanceCounter(time); +} + +int64 timediff(TIME_T* start, TIME_T* end) +{ + return (int64)((end->QuadPart - start->QuadPart)); +} + +int64 timenorm(int64 cur_time) +{ + static int first = 1; + + if(first) + { + QueryPerformanceFrequency(&freq); + first = 0; + } + + return (int64)(cur_time * 1000 /(freq.QuadPart)); +} + +#else + +static struct timezone tz; + +void gettime(TIME_T* time) +{ + gettimeofday(time, &tz); +} + +int64 timediff(TIME_T* start, TIME_T* end) +{ + int t1, t2; + + t1 = end->tv_sec - start->tv_sec; + t2 = end->tv_usec - start->tv_usec; + return (int64) t2 + (int64) t1 * (int64) 1000000; +} + +int64 timenorm(int64 cur_time) +{ + return (int64)(cur_time / (int64) 1000); +} +#endif |