cabac.c 37.1 KB
Newer Older
Laurent Aimar's avatar
Laurent Aimar committed
1 2 3
/*****************************************************************************
 * cabac.c: h264 encoder library
 *****************************************************************************
4
 * Copyright (C) 2003-2008 x264 project
Laurent Aimar's avatar
Laurent Aimar committed
5 6
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7
 *          Loren Merritt <lorenm@u.washington.edu>
Laurent Aimar's avatar
Laurent Aimar committed
8 9 10 11 12 13 14 15 16 17 18 19 20
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
Laurent Aimar's avatar
Laurent Aimar committed
22 23
 *****************************************************************************/

24
#include "common/common.h"
Laurent Aimar's avatar
Laurent Aimar committed
25 26
#include "macroblock.h"

27
static inline void x264_cabac_mb_type_intra( x264_t *h, x264_cabac_t *cb, int i_mb_type,
Loren Merritt's avatar
Loren Merritt committed
28 29
                    int ctx0, int ctx1, int ctx2, int ctx3, int ctx4, int ctx5 )
{
30
    if( i_mb_type == I_4x4 || i_mb_type == I_8x8 )
Loren Merritt's avatar
Loren Merritt committed
31
    {
32
        x264_cabac_encode_decision( cb, ctx0, 0 );
Loren Merritt's avatar
Loren Merritt committed
33 34 35
    }
    else if( i_mb_type == I_PCM )
    {
36
        x264_cabac_encode_decision( cb, ctx0, 1 );
37
        x264_cabac_encode_flush( h, cb );
Loren Merritt's avatar
Loren Merritt committed
38 39 40
    }
    else
    {
41 42
        int i_pred = x264_mb_pred_mode16x16_fix[h->mb.i_intra16x16_pred_mode];

43
        x264_cabac_encode_decision( cb, ctx0, 1 );
44
        x264_cabac_encode_terminal( cb );
Loren Merritt's avatar
Loren Merritt committed
45

Loren Merritt's avatar
Loren Merritt committed
46
        x264_cabac_encode_decision( cb, ctx1, !!h->mb.i_cbp_luma );
Loren Merritt's avatar
Loren Merritt committed
47 48
        if( h->mb.i_cbp_chroma == 0 )
        {
49
            x264_cabac_encode_decision( cb, ctx2, 0 );
Loren Merritt's avatar
Loren Merritt committed
50 51 52
        }
        else
        {
53
            x264_cabac_encode_decision( cb, ctx2, 1 );
Loren Merritt's avatar
Loren Merritt committed
54
            x264_cabac_encode_decision( cb, ctx3, h->mb.i_cbp_chroma != 1 );
Loren Merritt's avatar
Loren Merritt committed
55
        }
Loren Merritt's avatar
Loren Merritt committed
56 57
        x264_cabac_encode_decision( cb, ctx4, i_pred>>1 );
        x264_cabac_encode_decision( cb, ctx5, i_pred&1 );
Loren Merritt's avatar
Loren Merritt committed
58 59 60
    }
}

61
static void x264_cabac_mb_type( x264_t *h, x264_cabac_t *cb )
Laurent Aimar's avatar
Laurent Aimar committed
62
{
63
    const int i_mb_type = h->mb.i_type;
Laurent Aimar's avatar
Laurent Aimar committed
64

65 66 67 68 69 70
    if( h->sh.b_mbaff &&
        (!(h->mb.i_mb_y & 1) || IS_SKIP(h->mb.type[h->mb.i_mb_xy - h->mb.i_mb_stride])) )
    {
        x264_cabac_encode_decision( cb, 70 + h->mb.cache.i_neighbour_interlaced, h->mb.b_interlaced );
    }

Laurent Aimar's avatar
Laurent Aimar committed
71 72 73
    if( h->sh.i_type == SLICE_TYPE_I )
    {
        int ctx = 0;
Loren Merritt's avatar
Loren Merritt committed
74
        if( h->mb.i_mb_type_left >= 0 && h->mb.i_mb_type_left != I_4x4 )
Laurent Aimar's avatar
Laurent Aimar committed
75 76 77
        {
            ctx++;
        }
Loren Merritt's avatar
Loren Merritt committed
78
        if( h->mb.i_mb_type_top >= 0 && h->mb.i_mb_type_top != I_4x4 )
Laurent Aimar's avatar
Laurent Aimar committed
79 80 81 82
        {
            ctx++;
        }

83
        x264_cabac_mb_type_intra( h, cb, i_mb_type, 3+ctx, 3+3, 3+4, 3+5, 3+6, 3+7 );
Laurent Aimar's avatar
Laurent Aimar committed
84 85 86 87 88 89 90 91
    }
    else if( h->sh.i_type == SLICE_TYPE_P )
    {
        /* prefix: 14, suffix: 17 */
        if( i_mb_type == P_L0 )
        {
            if( h->mb.i_partition == D_16x16 )
            {
92 93 94
                x264_cabac_encode_decision( cb, 14, 0 );
                x264_cabac_encode_decision( cb, 15, 0 );
                x264_cabac_encode_decision( cb, 16, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
95 96 97
            }
            else if( h->mb.i_partition == D_16x8 )
            {
98 99 100
                x264_cabac_encode_decision( cb, 14, 0 );
                x264_cabac_encode_decision( cb, 15, 1 );
                x264_cabac_encode_decision( cb, 17, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
101 102 103
            }
            else if( h->mb.i_partition == D_8x16 )
            {
104 105 106
                x264_cabac_encode_decision( cb, 14, 0 );
                x264_cabac_encode_decision( cb, 15, 1 );
                x264_cabac_encode_decision( cb, 17, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
107 108 109 110
            }
        }
        else if( i_mb_type == P_8x8 )
        {
111 112 113
            x264_cabac_encode_decision( cb, 14, 0 );
            x264_cabac_encode_decision( cb, 15, 0 );
            x264_cabac_encode_decision( cb, 16, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
114
        }
Loren Merritt's avatar
Loren Merritt committed
115
        else /* intra */
Laurent Aimar's avatar
Laurent Aimar committed
116 117
        {
            /* prefix */
118
            x264_cabac_encode_decision( cb, 14, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
119 120

            /* suffix */
121
            x264_cabac_mb_type_intra( h, cb, i_mb_type, 17+0, 17+1, 17+2, 17+2, 17+3, 17+3 );
Laurent Aimar's avatar
Laurent Aimar committed
122 123 124 125 126
        }
    }
    else if( h->sh.i_type == SLICE_TYPE_B )
    {
        int ctx = 0;
Loren Merritt's avatar
Loren Merritt committed
127
        if( h->mb.i_mb_type_left >= 0 && h->mb.i_mb_type_left != B_SKIP && h->mb.i_mb_type_left != B_DIRECT )
Laurent Aimar's avatar
Laurent Aimar committed
128 129 130
        {
            ctx++;
        }
Loren Merritt's avatar
Loren Merritt committed
131
        if( h->mb.i_mb_type_top >= 0 && h->mb.i_mb_type_top != B_SKIP && h->mb.i_mb_type_top != B_DIRECT )
Laurent Aimar's avatar
Laurent Aimar committed
132 133 134 135 136 137
        {
            ctx++;
        }

        if( i_mb_type == B_DIRECT )
        {
138
            x264_cabac_encode_decision( cb, 27+ctx, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
139 140 141
        }
        else if( i_mb_type == B_8x8 )
        {
142 143 144
            x264_cabac_encode_decision( cb, 27+ctx, 1 );
            x264_cabac_encode_decision( cb, 27+3,   1 );
            x264_cabac_encode_decision( cb, 27+4,   1 );
Laurent Aimar's avatar
Laurent Aimar committed
145

146 147 148
            x264_cabac_encode_decision( cb, 27+5,   1 );
            x264_cabac_encode_decision( cb, 27+5,   1 );
            x264_cabac_encode_decision( cb, 27+5,   1 );
Laurent Aimar's avatar
Laurent Aimar committed
149 150 151 152
        }
        else if( IS_INTRA( i_mb_type ) )
        {
            /* prefix */
153 154 155
            x264_cabac_encode_decision( cb, 27+ctx, 1 );
            x264_cabac_encode_decision( cb, 27+3,   1 );
            x264_cabac_encode_decision( cb, 27+4,   1 );
Laurent Aimar's avatar
Laurent Aimar committed
156

157 158 159
            x264_cabac_encode_decision( cb, 27+5,   1 );
            x264_cabac_encode_decision( cb, 27+5,   0 );
            x264_cabac_encode_decision( cb, 27+5,   1 );
Laurent Aimar's avatar
Laurent Aimar committed
160

Loren Merritt's avatar
Loren Merritt committed
161
            /* suffix */
162
            x264_cabac_mb_type_intra( h, cb, i_mb_type, 32+0, 32+1, 32+2, 32+2, 32+3, 32+3 );
Laurent Aimar's avatar
Laurent Aimar committed
163 164 165
        }
        else
        {
166
            static const int i_mb_len[9*3] =
Laurent Aimar's avatar
Laurent Aimar committed
167
            {
168 169 170 171 172 173 174 175 176
                6, 6, 3,    /* L0 L0 */
                6, 6, 0,    /* L0 L1 */
                7, 7, 0,    /* L0 BI */
                6, 6, 0,    /* L1 L0 */
                6, 6, 3,    /* L1 L1 */
                7, 7, 0,    /* L1 BI */
                7, 7, 0,    /* BI L0 */
                7, 7, 0,    /* BI L1 */
                7, 7, 6,    /* BI BI */
Laurent Aimar's avatar
Laurent Aimar committed
177
            };
178
            static const int i_mb_bits[9*3][7] =
Laurent Aimar's avatar
Laurent Aimar committed
179
            {
180
                { 1,1,0,0,0,1   }, { 1,1,0,0,1,0,  }, { 1,0,0 },       /* L0 L0 */
Loren Merritt's avatar
Loren Merritt committed
181 182 183
                { 1,1,0,1,0,1   }, { 1,1,0,1,1,0   }, {0},             /* L0 L1 */
                { 1,1,1,0,0,0,0 }, { 1,1,1,0,0,0,1 }, {0},             /* L0 BI */
                { 1,1,0,1,1,1   }, { 1,1,1,1,1,0   }, {0},             /* L1 L0 */
184
                { 1,1,0,0,1,1   }, { 1,1,0,1,0,0   }, { 1,0,1 },       /* L1 L1 */
Loren Merritt's avatar
Loren Merritt committed
185 186 187
                { 1,1,1,0,0,1,0 }, { 1,1,1,0,0,1,1 }, {0},             /* L1 BI */
                { 1,1,1,0,1,0,0 }, { 1,1,1,0,1,0,1 }, {0},             /* BI L0 */
                { 1,1,1,0,1,1,0 }, { 1,1,1,0,1,1,1 }, {0},             /* BI L1 */
188
                { 1,1,1,1,0,0,0 }, { 1,1,1,1,0,0,1 }, { 1,1,0,0,0,0 }, /* BI BI */
Laurent Aimar's avatar
Laurent Aimar committed
189 190
            };

191
            const int idx = (i_mb_type - B_L0_L0) * 3 + (h->mb.i_partition - D_16x8);
Laurent Aimar's avatar
Laurent Aimar committed
192 193
            int i;

194 195
            x264_cabac_encode_decision( cb, 27+ctx, i_mb_bits[idx][0] );
            x264_cabac_encode_decision( cb, 27+3,   i_mb_bits[idx][1] );
196
            x264_cabac_encode_decision( cb, 27+5-i_mb_bits[idx][1], i_mb_bits[idx][2] );
Laurent Aimar's avatar
Laurent Aimar committed
197
            for( i = 3; i < i_mb_len[idx]; i++ )
198
                x264_cabac_encode_decision( cb, 27+5, i_mb_bits[idx][i] );
Laurent Aimar's avatar
Laurent Aimar committed
199 200 201 202
        }
    }
    else
    {
203
        x264_log(h, X264_LOG_ERROR, "unknown SLICE_TYPE unsupported in x264_macroblock_write_cabac\n" );
Laurent Aimar's avatar
Laurent Aimar committed
204 205 206
    }
}

207
static void x264_cabac_mb_intra4x4_pred_mode( x264_cabac_t *cb, int i_pred, int i_mode )
Laurent Aimar's avatar
Laurent Aimar committed
208 209 210 211
{
    if( i_pred == i_mode )
    {
        /* b_prev_intra4x4_pred_mode */
212
        x264_cabac_encode_decision( cb, 68, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
213 214 215 216
    }
    else
    {
        /* b_prev_intra4x4_pred_mode */
217
        x264_cabac_encode_decision( cb, 68, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
218 219 220 221
        if( i_mode > i_pred  )
        {
            i_mode--;
        }
222 223 224
        x264_cabac_encode_decision( cb, 69, (i_mode     )&0x01 );
        x264_cabac_encode_decision( cb, 69, (i_mode >> 1)&0x01 );
        x264_cabac_encode_decision( cb, 69, (i_mode >> 2)&0x01 );
Laurent Aimar's avatar
Laurent Aimar committed
225 226
    }
}
227

228
static void x264_cabac_mb_intra_chroma_pred_mode( x264_t *h, x264_cabac_t *cb )
Laurent Aimar's avatar
Laurent Aimar committed
229
{
230
    const int i_mode = x264_mb_pred_mode8x8c_fix[ h->mb.i_chroma_pred_mode ];
Laurent Aimar's avatar
Laurent Aimar committed
231 232 233
    int       ctx = 0;

    /* No need to test for I4x4 or I_16x16 as cache_save handle that */
Loren Merritt's avatar
Loren Merritt committed
234
    if( (h->mb.i_neighbour & MB_LEFT) && h->mb.chroma_pred_mode[h->mb.i_mb_xy - 1] != 0 )
Laurent Aimar's avatar
Laurent Aimar committed
235 236 237
    {
        ctx++;
    }
238
    if( (h->mb.i_neighbour & MB_TOP) && h->mb.chroma_pred_mode[h->mb.i_mb_top_xy] != 0 )
Laurent Aimar's avatar
Laurent Aimar committed
239 240 241 242
    {
        ctx++;
    }

Loren Merritt's avatar
Loren Merritt committed
243 244
    x264_cabac_encode_decision( cb, 64 + ctx, i_mode > 0 );
    if( i_mode > 0 )
Laurent Aimar's avatar
Laurent Aimar committed
245
    {
Loren Merritt's avatar
Loren Merritt committed
246
        x264_cabac_encode_decision( cb, 64 + 3, i_mode > 1 );
Laurent Aimar's avatar
Laurent Aimar committed
247 248
        if( i_mode > 1 )
        {
Loren Merritt's avatar
Loren Merritt committed
249
            x264_cabac_encode_decision( cb, 64 + 3, i_mode > 2 );
Laurent Aimar's avatar
Laurent Aimar committed
250 251 252 253
        }
    }
}

254
static void x264_cabac_mb_cbp_luma( x264_t *h, x264_cabac_t *cb )
Laurent Aimar's avatar
Laurent Aimar committed
255
{
Fiona Glaser's avatar
Fiona Glaser committed
256 257 258 259 260 261 262
    int cbp = h->mb.i_cbp_luma;
    int cbp_l = h->mb.i_neighbour & MB_LEFT ? h->mb.cbp[h->mb.i_mb_xy - 1] : -1;
    int cbp_t = h->mb.i_neighbour & MB_TOP ? h->mb.cbp[h->mb.i_mb_top_xy] : -1;
    x264_cabac_encode_decision( cb, 76 - ((cbp_l >> 1) & 1) - ((cbp_t >> 1) & 2), (h->mb.i_cbp_luma >> 0) & 1 );
    x264_cabac_encode_decision( cb, 76 - ((cbp   >> 0) & 1) - ((cbp_t >> 2) & 2), (h->mb.i_cbp_luma >> 1) & 1 );
    x264_cabac_encode_decision( cb, 76 - ((cbp_l >> 3) & 1) - ((cbp   << 1) & 2), (h->mb.i_cbp_luma >> 2) & 1 );
    x264_cabac_encode_decision( cb, 76 - ((cbp   >> 2) & 1) - ((cbp   >> 0) & 2), (h->mb.i_cbp_luma >> 3) & 1 );
Laurent Aimar's avatar
Laurent Aimar committed
263 264
}

265
static void x264_cabac_mb_cbp_chroma( x264_t *h, x264_cabac_t *cb )
Laurent Aimar's avatar
Laurent Aimar committed
266 267 268 269 270 271
{
    int cbp_a = -1;
    int cbp_b = -1;
    int ctx;

    /* No need to test for SKIP/PCM */
Loren Merritt's avatar
Loren Merritt committed
272
    if( h->mb.i_neighbour & MB_LEFT )
Laurent Aimar's avatar
Laurent Aimar committed
273 274 275 276
    {
        cbp_a = (h->mb.cbp[h->mb.i_mb_xy - 1] >> 4)&0x3;
    }

Loren Merritt's avatar
Loren Merritt committed
277
    if( h->mb.i_neighbour & MB_TOP )
Laurent Aimar's avatar
Laurent Aimar committed
278
    {
279
        cbp_b = (h->mb.cbp[h->mb.i_mb_top_xy] >> 4)&0x3;
Laurent Aimar's avatar
Laurent Aimar committed
280 281 282 283 284 285 286
    }

    ctx = 0;
    if( cbp_a > 0 ) ctx++;
    if( cbp_b > 0 ) ctx += 2;
    if( h->mb.i_cbp_chroma == 0 )
    {
287
        x264_cabac_encode_decision( cb, 77 + ctx, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
288 289 290
    }
    else
    {
291
        x264_cabac_encode_decision( cb, 77 + ctx, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
292 293 294 295

        ctx = 4;
        if( cbp_a == 2 ) ctx++;
        if( cbp_b == 2 ) ctx += 2;
Loren Merritt's avatar
Loren Merritt committed
296
        x264_cabac_encode_decision( cb, 77 + ctx, h->mb.i_cbp_chroma > 1 );
Laurent Aimar's avatar
Laurent Aimar committed
297 298 299 300
    }
}

/* TODO check it with != qp per mb */
301
static void x264_cabac_mb_qp_delta( x264_t *h, x264_cabac_t *cb )
Laurent Aimar's avatar
Laurent Aimar committed
302
{
303
    int i_mbn_xy = h->mb.i_mb_prev_xy;
304
    int i_dqp = h->mb.i_qp - h->mb.i_last_qp;
Laurent Aimar's avatar
Laurent Aimar committed
305 306
    int ctx;

307 308 309
    /* Avoid writing a delta quant if we have an empty i16x16 block, e.g. in a completely flat background area */
    if( h->mb.i_type == I_16x16 && !h->mb.cbp[h->mb.i_mb_xy] )
    {
Fiona Glaser's avatar
Fiona Glaser committed
310
#ifndef RDO_SKIP_BS
311 312 313 314 315
        h->mb.i_qp = h->mb.i_last_qp;
#endif
        i_dqp = 0;
    }

Laurent Aimar's avatar
Laurent Aimar committed
316
    /* No need to test for PCM / SKIP */
317
    if( h->mb.i_last_dqp &&
Laurent Aimar's avatar
Laurent Aimar committed
318 319 320 321 322
        ( h->mb.type[i_mbn_xy] == I_16x16 || (h->mb.cbp[i_mbn_xy]&0x3f) ) )
        ctx = 1;
    else
        ctx = 0;

Loren Merritt's avatar
Loren Merritt committed
323
    if( i_dqp != 0 )
Laurent Aimar's avatar
Laurent Aimar committed
324
    {
Loren Merritt's avatar
Loren Merritt committed
325 326
        int val = i_dqp <= 0 ? (-2*i_dqp) : (2*i_dqp - 1);
        /* dqp is interpreted modulo 52 */
327
        if( val >= 51 && val != 52 )
Loren Merritt's avatar
Loren Merritt committed
328 329 330 331 332 333 334 335 336
            val = 103 - val;
        while( val-- )
        {
            x264_cabac_encode_decision( cb, 60 + ctx, 1 );
            if( ctx < 2 )
                ctx = 2;
            else
                ctx = 3;
        }
Laurent Aimar's avatar
Laurent Aimar committed
337
    }
338
    x264_cabac_encode_decision( cb, 60 + ctx, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
339 340
}

Loren Merritt's avatar
Loren Merritt committed
341
#ifndef RDO_SKIP_BS
Laurent Aimar's avatar
Laurent Aimar committed
342 343
void x264_cabac_mb_skip( x264_t *h, int b_skip )
{
Loren Merritt's avatar
Loren Merritt committed
344 345 346
    int ctx = (h->mb.i_mb_type_left >= 0 && !IS_SKIP( h->mb.i_mb_type_left ))
            + (h->mb.i_mb_type_top >= 0 && !IS_SKIP( h->mb.i_mb_type_top ))
            + (h->sh.i_type == SLICE_TYPE_P ? 11 : 24);
Loren Merritt's avatar
Loren Merritt committed
347
    x264_cabac_encode_decision( &h->cabac, ctx, b_skip );
Laurent Aimar's avatar
Laurent Aimar committed
348
}
Loren Merritt's avatar
Loren Merritt committed
349
#endif
Laurent Aimar's avatar
Laurent Aimar committed
350

351
static inline void x264_cabac_mb_sub_p_partition( x264_cabac_t *cb, int i_sub )
Laurent Aimar's avatar
Laurent Aimar committed
352 353 354
{
    if( i_sub == D_L0_8x8 )
    {
355
        x264_cabac_encode_decision( cb, 21, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
356 357 358
    }
    else if( i_sub == D_L0_8x4 )
    {
359 360
        x264_cabac_encode_decision( cb, 21, 0 );
        x264_cabac_encode_decision( cb, 22, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
361 362 363
    }
    else if( i_sub == D_L0_4x8 )
    {
364 365 366
        x264_cabac_encode_decision( cb, 21, 0 );
        x264_cabac_encode_decision( cb, 22, 1 );
        x264_cabac_encode_decision( cb, 23, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
367 368 369
    }
    else if( i_sub == D_L0_4x4 )
    {
370 371 372
        x264_cabac_encode_decision( cb, 21, 0 );
        x264_cabac_encode_decision( cb, 22, 1 );
        x264_cabac_encode_decision( cb, 23, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
373 374 375
    }
}

Loren Merritt's avatar
Loren Merritt committed
376
static NOINLINE void x264_cabac_mb_sub_b_partition( x264_cabac_t *cb, int i_sub )
Laurent Aimar's avatar
Laurent Aimar committed
377
{
Loren Merritt's avatar
Loren Merritt committed
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
    static const uint8_t part_bits[12][7] = {
        {6,1,1,1,0,1,1}, // D_L0_4x4
        {5,1,1,0,0,1},   // D_L0_8x4
        {5,1,1,0,1,0},   // D_L0_4x8
        {3,1,0,0},       // D_L0_8x8
        {5,1,1,1,1,0},   // D_L1_4x4
        {5,1,1,0,1,1},   // D_L1_8x4
        {6,1,1,1,0,0,0}, // D_L1_4x8
        {3,1,0,1},       // D_L1_8x8
        {5,1,1,1,1,1},   // D_BI_4x4
        {6,1,1,1,0,0,1}, // D_BI_8x4
        {6,1,1,1,0,1,0}, // D_BI_4x8
        {5,1,1,0,0,0},   // D_BI_8x8
    };
    int len;
    if( i_sub == D_DIRECT_8x8 )
    {
        x264_cabac_encode_decision( cb, 36, 0 );
        return;
Loren Merritt's avatar
Loren Merritt committed
397
    }
Loren Merritt's avatar
Loren Merritt committed
398 399 400 401 402 403
    len = part_bits[i_sub][0];
    x264_cabac_encode_decision( cb, 36, part_bits[i_sub][1] );
    x264_cabac_encode_decision( cb, 37, part_bits[i_sub][2] );
    if( len == 3 )
        x264_cabac_encode_decision( cb, 39, part_bits[i_sub][3] );
    else
Loren Merritt's avatar
Loren Merritt committed
404
    {
Loren Merritt's avatar
Loren Merritt committed
405 406 407 408 409
        x264_cabac_encode_decision( cb, 38, part_bits[i_sub][3] );
        x264_cabac_encode_decision( cb, 39, part_bits[i_sub][4] );
        x264_cabac_encode_decision( cb, 39, part_bits[i_sub][5] );
        if( len == 6 )
            x264_cabac_encode_decision( cb, 39, part_bits[i_sub][6] );
Laurent Aimar's avatar
Laurent Aimar committed
410 411 412
    }
}

413
static inline void x264_cabac_mb_transform_size( x264_t *h, x264_cabac_t *cb )
414
{
415
    int ctx = 399 + h->mb.cache.i_neighbour_transform_size;
416
    x264_cabac_encode_decision( cb, ctx, h->mb.b_transform_8x8 );
417 418
}

419
static inline void x264_cabac_mb_ref( x264_t *h, x264_cabac_t *cb, int i_list, int idx )
Laurent Aimar's avatar
Laurent Aimar committed
420 421 422 423 424 425 426
{
    const int i8 = x264_scan8[idx];
    const int i_refa = h->mb.cache.ref[i_list][i8 - 1];
    const int i_refb = h->mb.cache.ref[i_list][i8 - 8];
    int i_ref  = h->mb.cache.ref[i_list][i8];
    int ctx  = 0;

427
    if( i_refa > 0 && !h->mb.cache.skip[i8 - 1])
Laurent Aimar's avatar
Laurent Aimar committed
428
        ctx++;
429
    if( i_refb > 0 && !h->mb.cache.skip[i8 - 8])
Laurent Aimar's avatar
Laurent Aimar committed
430 431 432 433
        ctx += 2;

    while( i_ref > 0 )
    {
434
        x264_cabac_encode_decision( cb, 54 + ctx, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
435 436 437 438 439 440 441
        if( ctx < 4 )
            ctx = 4;
        else
            ctx = 5;

        i_ref--;
    }
442
    x264_cabac_encode_decision( cb, 54 + ctx, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
443 444 445 446
}



447
static inline void x264_cabac_mb_mvd_cpn( x264_t *h, x264_cabac_t *cb, int i_list, int idx, int l, int mvd )
Laurent Aimar's avatar
Laurent Aimar committed
448
{
Loren Merritt's avatar
Loren Merritt committed
449
    static const uint8_t transition[7] = { 3,3,3,4,5,6,6 };
Laurent Aimar's avatar
Laurent Aimar committed
450 451 452 453
    const int amvd = abs( h->mb.cache.mvd[i_list][x264_scan8[idx] - 1][l] ) +
                     abs( h->mb.cache.mvd[i_list][x264_scan8[idx] - 8][l] );
    const int i_abs = abs( mvd );
    const int i_prefix = X264_MIN( i_abs, 9 );
Loren Merritt's avatar
Loren Merritt committed
454 455
    const int ctxbase = l ? 47 : 40;
    int ctx = (amvd>2) + (amvd>32);
Laurent Aimar's avatar
Laurent Aimar committed
456 457 458 459
    int i;

    for( i = 0; i < i_prefix; i++ )
    {
460
        x264_cabac_encode_decision( cb, ctxbase + ctx, 1 );
Loren Merritt's avatar
Loren Merritt committed
461
        ctx = transition[ctx];
Laurent Aimar's avatar
Laurent Aimar committed
462 463
    }
    if( i_prefix < 9 )
464
        x264_cabac_encode_decision( cb, ctxbase + ctx, 0 );
465 466
    else
        x264_cabac_encode_ue_bypass( cb, 3, i_abs - 9 );
Laurent Aimar's avatar
Laurent Aimar committed
467 468

    /* sign */
Loren Merritt's avatar
Loren Merritt committed
469 470
    if( mvd )
        x264_cabac_encode_bypass( cb, mvd < 0 );
Laurent Aimar's avatar
Laurent Aimar committed
471 472
}

473
static inline void x264_cabac_mb_mvd( x264_t *h, x264_cabac_t *cb, int i_list, int idx, int width, int height )
Laurent Aimar's avatar
Laurent Aimar committed
474
{
475
    DECLARE_ALIGNED_4( int16_t mvp[2] );
Laurent Aimar's avatar
Laurent Aimar committed
476 477 478 479 480 481 482 483
    int mdx, mdy;

    /* Calculate mvd */
    x264_mb_predict_mv( h, i_list, idx, width, mvp );
    mdx = h->mb.cache.mv[i_list][x264_scan8[idx]][0] - mvp[0];
    mdy = h->mb.cache.mv[i_list][x264_scan8[idx]][1] - mvp[1];

    /* encode */
484 485
    x264_cabac_mb_mvd_cpn( h, cb, i_list, idx, 0, mdx );
    x264_cabac_mb_mvd_cpn( h, cb, i_list, idx, 1, mdy );
Laurent Aimar's avatar
Laurent Aimar committed
486 487

    /* save value */
488
    x264_macroblock_cache_mvd( h, block_idx_x[idx], block_idx_y[idx], width, height, i_list, pack16to32_mask(mdx,mdy) );
Laurent Aimar's avatar
Laurent Aimar committed
489 490
}

491
static inline void x264_cabac_mb8x8_mvd( x264_t *h, x264_cabac_t *cb, int i_list, int i )
492
{
493 494
    if( !x264_mb_partition_listX_table[i_list][ h->mb.i_sub_partition[i] ] )
        return;
495

496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
    switch( h->mb.i_sub_partition[i] )
    {
        case D_L0_8x8:
        case D_L1_8x8:
        case D_BI_8x8:
            x264_cabac_mb_mvd( h, cb, i_list, 4*i, 2, 2 );
            break;
        case D_L0_8x4:
        case D_L1_8x4:
        case D_BI_8x4:
            x264_cabac_mb_mvd( h, cb, i_list, 4*i+0, 2, 1 );
            x264_cabac_mb_mvd( h, cb, i_list, 4*i+2, 2, 1 );
            break;
        case D_L0_4x8:
        case D_L1_4x8:
        case D_BI_4x8:
            x264_cabac_mb_mvd( h, cb, i_list, 4*i+0, 1, 2 );
            x264_cabac_mb_mvd( h, cb, i_list, 4*i+1, 1, 2 );
            break;
        case D_L0_4x4:
        case D_L1_4x4:
        case D_BI_4x4:
            x264_cabac_mb_mvd( h, cb, i_list, 4*i+0, 1, 1 );
            x264_cabac_mb_mvd( h, cb, i_list, 4*i+1, 1, 1 );
            x264_cabac_mb_mvd( h, cb, i_list, 4*i+2, 1, 1 );
            x264_cabac_mb_mvd( h, cb, i_list, 4*i+3, 1, 1 );
            break;
523 524 525
    }
}

Laurent Aimar's avatar
Laurent Aimar committed
526 527
static int x264_cabac_mb_cbf_ctxidxinc( x264_t *h, int i_cat, int i_idx )
{
Loren Merritt's avatar
Loren Merritt committed
528 529 530 531 532 533 534 535
    /* i_ctxBlockCat: 0-> DC 16x16  i_idx = 0
     *                1-> AC 16x16  i_idx = luma4x4idx
     *                2-> Luma4x4   i_idx = luma4x4idx
     *                3-> DC Chroma i_idx = iCbCr
     *                4-> AC Chroma i_idx = 4 * iCbCr + chroma4x4idx
     *                5-> Luma8x8   i_idx = luma8x8idx
     */

Laurent Aimar's avatar
Laurent Aimar committed
536 537
    int i_mba_xy = -1;
    int i_mbb_xy = -1;
Loren Merritt's avatar
Loren Merritt committed
538 539
    int i_nza = 0;
    int i_nzb = 0;
Laurent Aimar's avatar
Laurent Aimar committed
540

541
    if( i_cat == DCT_LUMA_DC )
Laurent Aimar's avatar
Laurent Aimar committed
542
    {
Loren Merritt's avatar
Loren Merritt committed
543
        if( h->mb.i_neighbour & MB_LEFT )
Laurent Aimar's avatar
Laurent Aimar committed
544
        {
Loren Merritt's avatar
Loren Merritt committed
545
            i_mba_xy = h->mb.i_mb_xy - 1;
546
            i_nza = h->mb.cbp[i_mba_xy] & 0x100;
Laurent Aimar's avatar
Laurent Aimar committed
547
        }
Loren Merritt's avatar
Loren Merritt committed
548
        if( h->mb.i_neighbour & MB_TOP )
Laurent Aimar's avatar
Laurent Aimar committed
549
        {
550
            i_mbb_xy = h->mb.i_mb_top_xy;
551
            i_nzb = h->mb.cbp[i_mbb_xy] & 0x100;
Laurent Aimar's avatar
Laurent Aimar committed
552 553
        }
    }
554
    else if( i_cat == DCT_LUMA_AC || i_cat == DCT_LUMA_4x4 )
Laurent Aimar's avatar
Laurent Aimar committed
555
    {
Loren Merritt's avatar
Loren Merritt committed
556
        if( i_idx & ~10 ) // block_idx_x > 0
Laurent Aimar's avatar
Laurent Aimar committed
557
            i_mba_xy = h->mb.i_mb_xy;
Loren Merritt's avatar
Loren Merritt committed
558
        else if( h->mb.i_neighbour & MB_LEFT )
Loren Merritt's avatar
Loren Merritt committed
559
            i_mba_xy = h->mb.i_mb_xy - 1;
Laurent Aimar's avatar
Laurent Aimar committed
560

Loren Merritt's avatar
Loren Merritt committed
561
        if( i_idx & ~5 ) // block_idx_y > 0
Laurent Aimar's avatar
Laurent Aimar committed
562
            i_mbb_xy = h->mb.i_mb_xy;
Loren Merritt's avatar
Loren Merritt committed
563
        else if( h->mb.i_neighbour & MB_TOP )
564
            i_mbb_xy = h->mb.i_mb_top_xy;
Laurent Aimar's avatar
Laurent Aimar committed
565 566 567

        /* no need to test for skip/pcm */
        if( i_mba_xy >= 0 )
Loren Merritt's avatar
Loren Merritt committed
568
            i_nza = h->mb.cache.non_zero_count[x264_scan8[i_idx] - 1];
Laurent Aimar's avatar
Laurent Aimar committed
569
        if( i_mbb_xy >= 0 )
Loren Merritt's avatar
Loren Merritt committed
570
            i_nzb = h->mb.cache.non_zero_count[x264_scan8[i_idx] - 8];
Laurent Aimar's avatar
Laurent Aimar committed
571
    }
572
    else if( i_cat == DCT_CHROMA_DC )
Laurent Aimar's avatar
Laurent Aimar committed
573 574
    {
        /* no need to test skip/pcm */
Loren Merritt's avatar
Loren Merritt committed
575
        if( h->mb.i_neighbour & MB_LEFT )
Laurent Aimar's avatar
Laurent Aimar committed
576
        {
Loren Merritt's avatar
Loren Merritt committed
577 578
            i_mba_xy = h->mb.i_mb_xy - 1;
            i_nza = h->mb.cbp[i_mba_xy] & (0x200 << i_idx);
Laurent Aimar's avatar
Laurent Aimar committed
579
        }
Loren Merritt's avatar
Loren Merritt committed
580
        if( h->mb.i_neighbour & MB_TOP )
Laurent Aimar's avatar
Laurent Aimar committed
581
        {
582
            i_mbb_xy = h->mb.i_mb_top_xy;
Loren Merritt's avatar
Loren Merritt committed
583
            i_nzb = h->mb.cbp[i_mbb_xy] & (0x200 << i_idx);
Laurent Aimar's avatar
Laurent Aimar committed
584 585
        }
    }
586
    else if( i_cat == DCT_CHROMA_AC )
Laurent Aimar's avatar
Laurent Aimar committed
587
    {
588
        if( i_idx & 1 )
Laurent Aimar's avatar
Laurent Aimar committed
589
            i_mba_xy = h->mb.i_mb_xy;
Loren Merritt's avatar
Loren Merritt committed
590
        else if( h->mb.i_neighbour & MB_LEFT )
Laurent Aimar's avatar
Laurent Aimar committed
591 592
            i_mba_xy = h->mb.i_mb_xy - 1;

593
        if( i_idx & 2 )
Laurent Aimar's avatar
Laurent Aimar committed
594
            i_mbb_xy = h->mb.i_mb_xy;
Loren Merritt's avatar
Loren Merritt committed
595
        else if( h->mb.i_neighbour & MB_TOP )
596
            i_mbb_xy = h->mb.i_mb_top_xy;
Laurent Aimar's avatar
Laurent Aimar committed
597 598

        /* no need to test skip/pcm */
Loren Merritt's avatar
Loren Merritt committed
599
        if( i_mba_xy >= 0 )
Loren Merritt's avatar
Loren Merritt committed
600
            i_nza = h->mb.cache.non_zero_count[x264_scan8[i_idx] - 1];
Loren Merritt's avatar
Loren Merritt committed
601
        if( i_mbb_xy >= 0 )
Loren Merritt's avatar
Loren Merritt committed
602
            i_nzb = h->mb.cache.non_zero_count[x264_scan8[i_idx] - 8];
Laurent Aimar's avatar
Laurent Aimar committed
603 604
    }

Loren Merritt's avatar
Loren Merritt committed
605
    if( IS_INTRA( h->mb.i_type ) )
Laurent Aimar's avatar
Laurent Aimar committed
606
    {
Loren Merritt's avatar
Loren Merritt committed
607 608
        i_nza |= i_mba_xy < 0;
        i_nzb |= i_mbb_xy < 0;
Laurent Aimar's avatar
Laurent Aimar committed
609 610
    }

Loren Merritt's avatar
Loren Merritt committed
611
    return 4*i_cat + 2*!!i_nzb + !!i_nza;
Laurent Aimar's avatar
Laurent Aimar committed
612 613 614
}


Fiona Glaser's avatar
Fiona Glaser committed
615
static const uint16_t significant_coeff_flag_offset[2][6] = {
616 617 618
    { 105, 120, 134, 149, 152, 402 },
    { 277, 292, 306, 321, 324, 436 }
};
Fiona Glaser's avatar
Fiona Glaser committed
619
static const uint16_t last_coeff_flag_offset[2][6] = {
620 621 622
    { 166, 181, 195, 210, 213, 417 },
    { 338, 353, 367, 382, 385, 451 }
};
Fiona Glaser's avatar
Fiona Glaser committed
623
static const uint16_t coeff_abs_level_m1_offset[6] =
624
    { 227, 237, 247, 257, 266, 426 };
Fiona Glaser's avatar
Fiona Glaser committed
625
static const uint8_t significant_coeff_flag_offset_8x8[2][63] =
626
{{
Loren Merritt's avatar
Loren Merritt committed
627 628 629 630
    0, 1, 2, 3, 4, 5, 5, 4, 4, 3, 3, 4, 4, 4, 5, 5,
    4, 4, 4, 4, 3, 3, 6, 7, 7, 7, 8, 9,10, 9, 8, 7,
    7, 6,11,12,13,11, 6, 7, 8, 9,14,10, 9, 8, 6,11,
   12,13,11, 6, 9,14,10, 9,11,12,13,11,14,10,12
631 632 633 634 635 636
},{
    0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 7, 8, 4, 5,
    6, 9,10,10, 8,11,12,11, 9, 9,10,10, 8,11,12,11,
    9, 9,10,10, 8,11,12,11, 9, 9,10,10, 8,13,13, 9,
    9,10,10, 8,13,13, 9, 9,10,10,14,14,14,14,14
}};
Fiona Glaser's avatar
Fiona Glaser committed
637
static const uint8_t last_coeff_flag_offset_8x8[63] = {
Loren Merritt's avatar
Loren Merritt committed
638 639 640 641 642
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
    3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
    5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8
};
Fiona Glaser's avatar
Fiona Glaser committed
643
static const uint8_t identity[16] =
644
    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Loren Merritt's avatar
Loren Merritt committed
645

646 647 648 649 650 651
// node ctx: 0..3: abslevel1 (with abslevelgt1 == 0).
//           4..7: abslevelgt1 + 3 (and abslevel1 doesn't matter).
/* map node ctx => cabac ctx for level=1 */
static const int coeff_abs_level1_ctx[8] = { 1, 2, 3, 4, 0, 0, 0, 0 };
/* map node ctx => cabac ctx for level>1 */
static const int coeff_abs_levelgt1_ctx[8] = { 5, 5, 5, 5, 6, 7, 8, 9 };
Fiona Glaser's avatar
Fiona Glaser committed
652
static const uint8_t coeff_abs_level_transition[2][8] = {
653 654 655 656 657
/* update node ctx after coding a level=1 */
    { 1, 2, 3, 3, 4, 5, 6, 7 },
/* update node ctx after coding a level>1 */
    { 4, 4, 4, 4, 5, 6, 7, 7 }
};
Loren Merritt's avatar
Loren Merritt committed
658

659
static void block_residual_write_cabac( x264_t *h, x264_cabac_t *cb, int i_ctxBlockCat, int i_idx, int16_t *l, int i_count )
Laurent Aimar's avatar
Laurent Aimar committed
660
{
661 662
    const int i_ctx_sig = significant_coeff_flag_offset[h->mb.b_interlaced][i_ctxBlockCat];
    const int i_ctx_last = last_coeff_flag_offset[h->mb.b_interlaced][i_ctxBlockCat];
663 664
    const int i_ctx_level = coeff_abs_level_m1_offset[i_ctxBlockCat];

665
    int i_coeff_abs_m1[64];
Fiona Glaser's avatar
Fiona Glaser committed
666
    int UNUSED i_coeff_sign[64];
Laurent Aimar's avatar
Laurent Aimar committed
667 668
    int i_coeff = 0;
    int i_last  = 0;
669
    int i_sigmap_size;
670
    int node_ctx = 0;
Loren Merritt's avatar
Loren Merritt committed
671
    int i, j;
Laurent Aimar's avatar
Laurent Aimar committed
672

Fiona Glaser's avatar
Fiona Glaser committed
673 674
    const uint8_t *significant_coeff_flag_offset;
    const uint8_t *last_coeff_flag_offset;
675

Fiona Glaser's avatar
Fiona Glaser committed
676 677
    /* yes this is always aligned, and l[-1] exists in the cases where it's used (ac) */
    for( j = i_count - 4; j >= -1; j -= 4 )
Loren Merritt's avatar
Loren Merritt committed
678 679
        if( *(uint64_t*)(l+j) )
            break;
Laurent Aimar's avatar
Laurent Aimar committed
680

681
    if( i_count != 64 )
Laurent Aimar's avatar
Laurent Aimar committed
682
    {
683
        /* coded block flag */
Fiona Glaser's avatar
Fiona Glaser committed
684 685 686 687 688 689
        int ctx = 85 + x264_cabac_mb_cbf_ctxidxinc( h, i_ctxBlockCat, i_idx );
        if( j >= -1 )
            x264_cabac_encode_decision( cb, ctx, 1 );
        else
        {
            x264_cabac_encode_decision( cb, ctx, 0 );
690
            return;
Fiona Glaser's avatar
Fiona Glaser committed
691
        }
Laurent Aimar's avatar
Laurent Aimar committed
692 693
    }

694 695 696 697 698 699
    significant_coeff_flag_offset = (i_ctxBlockCat == DCT_LUMA_8x8)
                                  ? significant_coeff_flag_offset_8x8[h->mb.b_interlaced]
                                  : identity;
    last_coeff_flag_offset = (i_ctxBlockCat == DCT_LUMA_8x8)
                           ? last_coeff_flag_offset_8x8 : identity;

Fiona Glaser's avatar
Fiona Glaser committed
700 701 702 703
    for( i = j; i < j+4; i++)
        if( l[i] )
            i_last = i;

704
    i_sigmap_size = X264_MIN( i_last+1, i_count-1 );
Fiona Glaser's avatar
Fiona Glaser committed
705

706
    for( i = 0; i < i_sigmap_size; i++ )
Laurent Aimar's avatar
Laurent Aimar committed
707
    {
Fiona Glaser's avatar
Fiona Glaser committed
708 709 710 711 712 713 714 715
        if( l[i] )
        {
            i_coeff_abs_m1[i_coeff] = abs(l[i]) - 1;
#ifndef RDO_SKIP_BS
            i_coeff_sign[i_coeff]   = l[i] < 0;
#endif
            i_coeff++;
            x264_cabac_encode_decision( cb, i_ctx_sig + significant_coeff_flag_offset[i], 1 );
716
            x264_cabac_encode_decision( cb, i_ctx_last + last_coeff_flag_offset[i], i == i_last );
Fiona Glaser's avatar
Fiona Glaser committed
717 718 719 720 721 722 723 724 725 726 727 728
        }
        else
            x264_cabac_encode_decision( cb, i_ctx_sig + significant_coeff_flag_offset[i], 0 );
    }

    if( i == i_last )
    {
        i_coeff_abs_m1[i_coeff] = abs(l[i]) - 1;
#ifndef RDO_SKIP_BS
        i_coeff_sign[i_coeff]   = l[i] < 0;
#endif
        i_coeff++;
Laurent Aimar's avatar
Laurent Aimar committed
729 730 731 732 733
    }

    for( i = i_coeff - 1; i >= 0; i-- )
    {
        /* write coeff_abs - 1 */
Fiona Glaser's avatar
Fiona Glaser committed
734 735
        int i_prefix = X264_MIN( i_coeff_abs_m1[i], 14 );
        int ctx = coeff_abs_level1_ctx[node_ctx] + i_ctx_level;
Laurent Aimar's avatar
Laurent Aimar committed
736

Fiona Glaser's avatar
Fiona Glaser committed
737
        if( i_prefix )
Laurent Aimar's avatar
Laurent Aimar committed
738
        {
Fiona Glaser's avatar
Fiona Glaser committed
739 740
            x264_cabac_encode_decision( cb, ctx, 1 );
            ctx = coeff_abs_levelgt1_ctx[node_ctx] + i_ctx_level;
741
#ifdef RDO_SKIP_BS
Fiona Glaser's avatar
Fiona Glaser committed
742 743
            cb->f8_bits_encoded += cabac_prefix_size[i_prefix][cb->state[ctx]];
            cb->state[ctx] = cabac_prefix_transition[i_prefix][cb->state[ctx]];
744
#else
Laurent Aimar's avatar
Laurent Aimar committed
745
            for( j = 0; j < i_prefix - 1; j++ )
Fiona Glaser's avatar
Fiona Glaser committed
746
                x264_cabac_encode_decision( cb, ctx, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
747
            if( i_prefix < 14 )
Fiona Glaser's avatar
Fiona Glaser committed
748
                x264_cabac_encode_decision( cb, ctx, 0 );
749 750
#endif
            if( i_prefix >= 14 )
751
                x264_cabac_encode_ue_bypass( cb, 0, i_coeff_abs_m1[i] - 14 );
Laurent Aimar's avatar
Laurent Aimar committed
752

753
            node_ctx = coeff_abs_level_transition[1][node_ctx];
Laurent Aimar's avatar
Laurent Aimar committed
754
        }
755
        else
Fiona Glaser's avatar
Fiona Glaser committed
756 757
        {
            x264_cabac_encode_decision( cb, ctx, 0 );
758
            node_ctx = coeff_abs_level_transition[0][node_ctx];
759
#ifdef RDO_SKIP_BS
Fiona Glaser's avatar
Fiona Glaser committed
760
            x264_cabac_encode_bypass( cb, 0 ); // sign
761
#endif
Fiona Glaser's avatar
Fiona Glaser committed
762 763 764
        }

#ifndef RDO_SKIP_BS
765
        x264_cabac_encode_bypass( cb, i_coeff_sign[i] );
Fiona Glaser's avatar
Fiona Glaser committed
766
#endif
Laurent Aimar's avatar
Laurent Aimar committed
767 768 769 770 771
    }
}



772
void x264_macroblock_write_cabac( x264_t *h, x264_cabac_t *cb )
Laurent Aimar's avatar
Laurent Aimar committed
773 774
{
    const int i_mb_type = h->mb.i_type;
775
    int i_list;
Laurent Aimar's avatar
Laurent Aimar committed
776 777
    int i;

778 779 780 781 782
#ifndef RDO_SKIP_BS
    const int i_mb_pos_start = x264_cabac_pos( cb );
    int       i_mb_pos_tex;
#endif

Laurent Aimar's avatar
Laurent Aimar committed
783
    /* Write the MB type */
784
    x264_cabac_mb_type( h, cb );
Laurent Aimar's avatar
Laurent Aimar committed
785

786
#ifndef RDO_SKIP_BS
Laurent Aimar's avatar
Laurent Aimar committed
787 788
    if( i_mb_type == I_PCM )
    {
789 790 791 792 793
        i_mb_pos_tex = x264_cabac_pos( cb );
        h->stat.frame.i_hdr_bits += i_mb_pos_tex - i_mb_pos_start;

        memcpy( cb->p, h->mb.pic.p_fenc[0], 256 );
        cb->p += 256;
794
        for( i = 0; i < 8; i++ )
795 796
            memcpy( cb->p + i*8, h->mb.pic.p_fenc[1] + i*FENC_STRIDE, 8 );
        cb->p += 64;
797
        for( i = 0; i < 8; i++ )
798 799 800 801 802 803 804 805 806 807 808 809 810 811
            memcpy( cb->p + i*8, h->mb.pic.p_fenc[2] + i*FENC_STRIDE, 8 );
        cb->p += 64;

        cb->i_low   = 0;
        cb->i_range = 0x01FE;
        cb->i_queue = -1;
        cb->i_bytes_outstanding = 0;

        /* if PCM is chosen, we need to store reconstructed frame data */
        h->mc.copy[PIXEL_16x16]( h->mb.pic.p_fdec[0], FDEC_STRIDE, h->mb.pic.p_fenc[0], FENC_STRIDE, 16 );
        h->mc.copy[PIXEL_8x8]  ( h->mb.pic.p_fdec[1], FDEC_STRIDE, h->mb.pic.p_fenc[1], FENC_STRIDE, 8 );
        h->mc.copy[PIXEL_8x8]  ( h->mb.pic.p_fdec[2], FDEC_STRIDE, h->mb.pic.p_fenc[2], FENC_STRIDE, 8 );

        h->stat.frame.i_itex_bits += x264_cabac_pos( cb ) - i_mb_pos_tex;
Laurent Aimar's avatar
Laurent Aimar committed
812 813
        return;
    }
814
#endif
Laurent Aimar's avatar
Laurent Aimar committed
815 816 817

    if( IS_INTRA( i_mb_type ) )
    {
818
        if( h->pps->b_transform_8x8_mode && i_mb_type != I_16x16 )
819
            x264_cabac_mb_transform_size( h, cb );
820 821

        if( i_mb_type != I_16x16 )
Laurent Aimar's avatar
Laurent Aimar committed
822
        {
823 824
            int di = (i_mb_type == I_8x8) ? 4 : 1;
            for( i = 0; i < 16; i += di )
Laurent Aimar's avatar
Laurent Aimar committed
825 826
            {
                const int i_pred = x264_mb_predict_intra4x4_mode( h, i );
827
                const int i_mode = x264_mb_pred_mode4x4_fix( h->mb.cache.intra4x4_pred_mode[x264_scan8[i]] );
828
                x264_cabac_mb_intra4x4_pred_mode( cb, i_pred, i_mode );
Laurent Aimar's avatar
Laurent Aimar committed
829 830
            }
        }
831

832
        x264_cabac_mb_intra_chroma_pred_mode( h, cb );
Laurent Aimar's avatar
Laurent Aimar committed
833 834 835 836 837
    }
    else if( i_mb_type == P_L0 )
    {
        if( h->mb.i_partition == D_16x16 )
        {
838
            if( h->mb.pic.i_fref[0] > 1 )
Laurent Aimar's avatar
Laurent Aimar committed
839
            {
840
                x264_cabac_mb_ref( h, cb, 0, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
841
            }
842
            x264_cabac_mb_mvd( h, cb, 0, 0, 4, 4 );
Laurent Aimar's avatar
Laurent Aimar committed
843 844 845
        }
        else if( h->mb.i_partition == D_16x8 )
        {
846
            if( h->mb.pic.i_fref[0] > 1 )
Laurent Aimar's avatar
Laurent Aimar committed
847
            {
848 849
                x264_cabac_mb_ref( h, cb, 0, 0 );
                x264_cabac_mb_ref( h, cb, 0, 8 );
Laurent Aimar's avatar
Laurent Aimar committed
850
            }
851 852
            x264_cabac_mb_mvd( h, cb, 0, 0, 4, 2 );
            x264_cabac_mb_mvd( h, cb, 0, 8, 4, 2 );
Laurent Aimar's avatar
Laurent Aimar committed
853 854 855
        }
        else if( h->mb.i_partition == D_8x16 )
        {
856
            if( h->mb.pic.i_fref[0] > 1 )
Laurent Aimar's avatar
Laurent Aimar committed
857
            {
858 859
                x264_cabac_mb_ref( h, cb, 0, 0 );
                x264_cabac_mb_ref( h, cb, 0, 4 );
Laurent Aimar's avatar
Laurent Aimar committed
860
            }
861 862
            x264_cabac_mb_mvd( h, cb, 0, 0, 2, 4 );
            x264_cabac_mb_mvd( h, cb, 0, 4, 2, 4 );
Laurent Aimar's avatar
Laurent Aimar committed
863 864 865 866 867
        }
    }
    else if( i_mb_type == P_8x8 )
    {
        /* sub mb type */
868 869 870 871
        x264_cabac_mb_sub_p_partition( cb, h->mb.i_sub_partition[0] );
        x264_cabac_mb_sub_p_partition( cb, h->mb.i_sub_partition[1] );
        x264_cabac_mb_sub_p_partition( cb, h->mb.i_sub_partition[2] );
        x264_cabac_mb_sub_p_partition( cb, h->mb.i_sub_partition[3] );
Laurent Aimar's avatar
Laurent Aimar committed
872 873

        /* ref 0 */
874
        if( h->mb.pic.i_fref[0] > 1 )
Laurent Aimar's avatar
Laurent Aimar committed
875
        {
876 877 878 879
            x264_cabac_mb_ref( h, cb, 0, 0 );
            x264_cabac_mb_ref( h, cb, 0, 4 );
            x264_cabac_mb_ref( h, cb, 0, 8 );
            x264_cabac_mb_ref( h, cb, 0, 12 );
Laurent Aimar's avatar
Laurent Aimar committed
880 881
        }

882 883
        for( i = 0; i < 4; i++ )
            x264_cabac_mb8x8_mvd( h, cb, 0, i );
884 885 886 887
    }
    else if( i_mb_type == B_8x8 )
    {
        /* sub mb type */
888 889 890 891
        x264_cabac_mb_sub_b_partition( cb, h->mb.i_sub_partition[0] );
        x264_cabac_mb_sub_b_partition( cb, h->mb.i_sub_partition[1] );
        x264_cabac_mb_sub_b_partition( cb, h->mb.i_sub_partition[2] );
        x264_cabac_mb_sub_b_partition( cb, h->mb.i_sub_partition[3] );
892 893 894

        /* ref */
        for( i_list = 0; i_list < 2; i_list++ )
Laurent Aimar's avatar
Laurent Aimar committed
895
        {
896
            if( ( i_list ? h->mb.pic.i_fref[1] : h->mb.pic.i_fref[0] ) == 1 )
897 898
                continue;
            for( i = 0; i < 4; i++ )
899
                if( x264_mb_partition_listX_table[i_list][ h->mb.i_sub_partition[i] ] )
900
                    x264_cabac_mb_ref( h, cb, i_list, 4*i );
Laurent Aimar's avatar
Laurent Aimar committed
901
        }
902

903 904 905 906
        for( i = 0; i < 4; i++ )
            x264_cabac_mb8x8_mvd( h, cb, 0, i );
        for( i = 0; i < 4; i++ )
            x264_cabac_mb8x8_mvd( h, cb, 1, i );
Laurent Aimar's avatar
Laurent Aimar committed
907 908 909 910 911 912 913 914 915 916 917 918 919 920 921
    }
    else if( i_mb_type != B_DIRECT )
    {
        /* All B mode */
        int b_list[2][2];

        /* init ref list utilisations */
        for( i = 0; i < 2; i++ )
        {
            b_list[0][i] = x264_mb_type_list0_table[i_mb_type][i];
            b_list[1][i] = x264_mb_type_list1_table[i_mb_type][i];
        }

        for( i_list = 0; i_list < 2; i_list++ )
        {
922
            const int i_ref_max = i_list == 0 ? h->mb.pic.i_fref[0] : h->mb.pic.i_fref[1];
Laurent Aimar's avatar
Laurent Aimar committed
923 924 925 926 927

            if( i_ref_max > 1 )
            {
                if( h->mb.i_partition == D_16x16 )
                {
928
                    if( b_list[i_list][0] ) x264_cabac_mb_ref( h, cb, i_list, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
929 930 931
                }
                else if( h->mb.i_partition == D_16x8 )
                {
932 933
                    if( b_list[i_list][0] ) x264_cabac_mb_ref( h, cb, i_list, 0 );
                    if( b_list[i_list][1] ) x264_cabac_mb_ref( h, cb, i_list, 8 );
Laurent Aimar's avatar
Laurent Aimar committed
934 935 936
                }
                else if( h->mb.i_partition == D_8x16 )
                {
937 938
                    if( b_list[i_list][0] ) x264_cabac_mb_ref( h, cb, i_list, 0 );
                    if( b_list[i_list][1] ) x264_cabac_mb_ref( h, cb, i_list, 4 );
Laurent Aimar's avatar
Laurent Aimar committed
939 940 941 942 943 944 945
                }
            }
        }
        for( i_list = 0; i_list < 2; i_list++ )
        {
            if( h->mb.i_partition == D_16x16 )
            {
946
                if( b_list[i_list][0] ) x264_cabac_mb_mvd( h, cb, i_list, 0, 4, 4 );
Laurent Aimar's avatar
Laurent Aimar committed
947 948 949
            }
            else if( h->mb.i_partition == D_16x8 )
            {
950 951
                if( b_list[i_list][0] ) x264_cabac_mb_mvd( h, cb, i_list, 0, 4, 2 );
                if( b_list[i_list][1] ) x264_cabac_mb_mvd( h, cb, i_list, 8, 4, 2 );
Laurent Aimar's avatar
Laurent Aimar committed
952 953 954
            }
            else if( h->mb.i_partition == D_8x16 )
            {
955 956
                if( b_list[i_list][0] ) x264_cabac_mb_mvd( h, cb, i_list, 0, 2, 4 );
                if( b_list[i_list][1] ) x264_cabac_mb_mvd( h, cb, i_list, 4, 2, 4 );
Laurent Aimar's avatar
Laurent Aimar committed
957 958 959 960
            }
        }
    }

961 962 963 964
#ifndef RDO_SKIP_BS
    i_mb_pos_tex = x264_cabac_pos( cb );
    h->stat.frame.i_hdr_bits += i_mb_pos_tex - i_mb_pos_start;
#endif
965

Laurent Aimar's avatar
Laurent Aimar committed
966 967
    if( i_mb_type != I_16x16 )
    {
968 969
        x264_cabac_mb_cbp_luma( h, cb );
        x264_cabac_mb_cbp_chroma( h, cb );
Laurent Aimar's avatar
Laurent Aimar committed
970 971
    }

972
    if( x264_mb_transform_8x8_allowed( h ) && h->mb.i_cbp_luma )
973
    {
974
        x264_cabac_mb_transform_size( h, cb );
975 976
    }

Laurent Aimar's avatar
Laurent Aimar committed
977 978
    if( h->mb.i_cbp_luma > 0 || h->mb.i_cbp_chroma > 0 || i_mb_type == I_16x16 )
    {
979
        x264_cabac_mb_qp_delta( h, cb );
Laurent Aimar's avatar
Laurent Aimar committed
980 981 982 983 984

        /* write residual */
        if( i_mb_type == I_16x16 )
        {
            /* DC Luma */
985
            block_residual_write_cabac( h, cb, DCT_LUMA_DC, 0, h->dct.luma16x16_dc, 16 );
Laurent Aimar's avatar
Laurent Aimar committed
986

987
            /* AC Luma */
Laurent Aimar's avatar
Laurent Aimar committed
988 989
            if( h->mb.i_cbp_luma != 0 )
                for( i = 0; i < 16; i++ )
990
                    block_residual_write_cabac( h, cb, DCT_LUMA_AC, i, h->dct.luma4x4[i]+1, 15 );
991 992 993 994 995
        }
        else if( h->mb.b_transform_8x8 )
        {
            for( i = 0; i < 4; i++ )
                if( h->mb.i_cbp_luma & ( 1 << i ) )
996
                    block_residual_write_cabac( h, cb, DCT_LUMA_8x8, i, h->dct.luma8x8[i], 64 );
Laurent Aimar's avatar
Laurent Aimar committed
997 998 999 1000 1001
        }
        else
        {
            for( i = 0; i < 16; i++ )
                if( h->mb.i_cbp_luma & ( 1 << ( i / 4 ) ) )
1002
                    block_residual_write_cabac( h, cb, DCT_LUMA_4x4, i, h->dct.luma4x4[i], 16 );
Laurent Aimar's avatar
Laurent Aimar committed
1003 1004 1005 1006
        }

        if( h->mb.i_cbp_chroma &0x03 )    /* Chroma DC residual present */
        {
1007 1008
            block_residual_write_cabac( h, cb, DCT_CHROMA_DC, 0, h->dct.chroma_dc[0], 4 );
            block_residual_write_cabac( h, cb, DCT_CHROMA_DC, 1, h->dct.chroma_dc[1], 4 );
Laurent Aimar's avatar
Laurent Aimar committed
1009 1010 1011
        }
        if( h->mb.i_cbp_chroma&0x02 ) /* Chroma AC residual present */
        {
Loren Merritt's avatar
Loren Merritt committed
1012
            for( i = 16; i < 24; i++ )
1013
                block_residual_write_cabac( h, cb, DCT_CHROMA_AC, i, h->dct.luma4x4[i]+1, 15 );
Laurent Aimar's avatar
Laurent Aimar committed
1014 1015
        }
    }
1016

1017 1018 1019 1020 1021 1022
#ifndef RDO_SKIP_BS
    if( IS_INTRA( i_mb_type ) )
        h->stat.frame.i_itex_bits += x264_cabac_pos( cb ) - i_mb_pos_tex;
    else
        h->stat.frame.i_ptex_bits += x264_cabac_pos( cb ) - i_mb_pos_tex;
#endif
Laurent Aimar's avatar
Laurent Aimar committed
1023 1024
}

1025 1026 1027 1028 1029