cabac.c 37.8 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>
8
 *          Fiona Glaser <fiona@x264.com>
Laurent Aimar's avatar
Laurent Aimar committed
9 10 11 12 13 14 15 16 17 18 19 20 21
 *
 * 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
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
Laurent Aimar's avatar
Laurent Aimar committed
23 24
 *****************************************************************************/

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

28 29 30 31
#ifndef RDO_SKIP_BS
#define RDO_SKIP_BS 0
#endif

32
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
33 34
                    int ctx0, int ctx1, int ctx2, int ctx3, int ctx4, int ctx5 )
{
35
    if( i_mb_type == I_4x4 || i_mb_type == I_8x8 )
Loren Merritt's avatar
Loren Merritt committed
36
    {
37
        x264_cabac_encode_decision_noup( cb, ctx0, 0 );
Loren Merritt's avatar
Loren Merritt committed
38
    }
39
#if !RDO_SKIP_BS
Loren Merritt's avatar
Loren Merritt committed
40 41
    else if( i_mb_type == I_PCM )
    {
42
        x264_cabac_encode_decision_noup( cb, ctx0, 1 );
43
        x264_cabac_encode_flush( h, cb );
Loren Merritt's avatar
Loren Merritt committed
44
    }
45
#endif
Loren Merritt's avatar
Loren Merritt committed
46 47
    else
    {
48 49
        int i_pred = x264_mb_pred_mode16x16_fix[h->mb.i_intra16x16_pred_mode];

50
        x264_cabac_encode_decision_noup( cb, ctx0, 1 );
51
        x264_cabac_encode_terminal( cb );
Loren Merritt's avatar
Loren Merritt committed
52

53
        x264_cabac_encode_decision_noup( cb, ctx1, !!h->mb.i_cbp_luma );
Loren Merritt's avatar
Loren Merritt committed
54
        if( h->mb.i_cbp_chroma == 0 )
55
            x264_cabac_encode_decision_noup( cb, ctx2, 0 );
Loren Merritt's avatar
Loren Merritt committed
56 57
        else
        {
58
            x264_cabac_encode_decision( cb, ctx2, 1 );
59
            x264_cabac_encode_decision_noup( cb, ctx3, h->mb.i_cbp_chroma>>1 );
Loren Merritt's avatar
Loren Merritt committed
60
        }
Loren Merritt's avatar
Loren Merritt committed
61
        x264_cabac_encode_decision( cb, ctx4, i_pred>>1 );
62
        x264_cabac_encode_decision_noup( cb, ctx5, i_pred&1 );
Loren Merritt's avatar
Loren Merritt committed
63 64 65
    }
}

66
static void x264_cabac_mb_type( x264_t *h, x264_cabac_t *cb )
Laurent Aimar's avatar
Laurent Aimar committed
67
{
68
    const int i_mb_type = h->mb.i_type;
Laurent Aimar's avatar
Laurent Aimar committed
69

70 71 72
    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])) )
    {
73
        x264_cabac_encode_decision_noup( cb, 70 + h->mb.cache.i_neighbour_interlaced, h->mb.b_interlaced );
74 75
    }

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

84
        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
85 86 87 88 89 90
    }
    else if( h->sh.i_type == SLICE_TYPE_P )
    {
        /* prefix: 14, suffix: 17 */
        if( i_mb_type == P_L0 )
        {
91 92 93
            x264_cabac_encode_decision_noup( cb, 14, 0 );
            x264_cabac_encode_decision_noup( cb, 15, h->mb.i_partition != D_16x16 );
            x264_cabac_encode_decision_noup( cb, 17-(h->mb.i_partition == D_16x16), h->mb.i_partition == D_16x8 );
Laurent Aimar's avatar
Laurent Aimar committed
94 95 96
        }
        else if( i_mb_type == P_8x8 )
        {
97 98 99
            x264_cabac_encode_decision_noup( cb, 14, 0 );
            x264_cabac_encode_decision_noup( cb, 15, 0 );
            x264_cabac_encode_decision_noup( cb, 16, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
100
        }
Loren Merritt's avatar
Loren Merritt committed
101
        else /* intra */
Laurent Aimar's avatar
Laurent Aimar committed
102 103
        {
            /* prefix */
104
            x264_cabac_encode_decision_noup( cb, 14, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
105 106

            /* suffix */
107
            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
108 109
        }
    }
110
    else //if( h->sh.i_type == SLICE_TYPE_B )
Laurent Aimar's avatar
Laurent Aimar committed
111 112
    {
        int ctx = 0;
Loren Merritt's avatar
Loren Merritt committed
113
        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
114
            ctx++;
Loren Merritt's avatar
Loren Merritt committed
115
        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
116 117 118
            ctx++;

        if( i_mb_type == B_DIRECT )
119
        {
120
            x264_cabac_encode_decision_noup( cb, 27+ctx, 0 );
121 122 123 124 125
            return;
        }
        x264_cabac_encode_decision_noup( cb, 27+ctx, 1 );

        if( i_mb_type == B_8x8 )
Laurent Aimar's avatar
Laurent Aimar committed
126
        {
127 128
            x264_cabac_encode_decision_noup( cb, 27+3,   1 );
            x264_cabac_encode_decision_noup( cb, 27+4,   1 );
129 130
            x264_cabac_encode_decision( cb, 27+5,   1 );
            x264_cabac_encode_decision( cb, 27+5,   1 );
131
            x264_cabac_encode_decision_noup( cb, 27+5,   1 );
Laurent Aimar's avatar
Laurent Aimar committed
132 133 134 135
        }
        else if( IS_INTRA( i_mb_type ) )
        {
            /* prefix */
136 137
            x264_cabac_encode_decision_noup( cb, 27+3,   1 );
            x264_cabac_encode_decision_noup( cb, 27+4,   1 );
138 139 140
            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
141

Loren Merritt's avatar
Loren Merritt committed
142
            /* suffix */
143
            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
144 145 146
        }
        else
        {
147
            static const uint8_t i_mb_bits[9*3] =
Laurent Aimar's avatar
Laurent Aimar committed
148
            {
149 150 151 152 153 154 155 156 157
                0x31, 0x29, 0x4, /* L0 L0 */
                0x35, 0x2d, 0,   /* L0 L1 */
                0x43, 0x63, 0,   /* L0 BI */
                0x3d, 0x2f, 0,   /* L1 L0 */
                0x39, 0x25, 0x6, /* L1 L1 */
                0x53, 0x73, 0,   /* L1 BI */
                0x4b, 0x6b, 0,   /* BI L0 */
                0x5b, 0x7b, 0,   /* BI L1 */
                0x47, 0x67, 0x21 /* BI BI */
Laurent Aimar's avatar
Laurent Aimar committed
158 159
            };

160
            const int idx = (i_mb_type - B_L0_L0) * 3 + (h->mb.i_partition - D_16x8);
161
            int bits = i_mb_bits[idx];
Laurent Aimar's avatar
Laurent Aimar committed
162

163 164 165
            x264_cabac_encode_decision_noup( cb, 27+3, bits&1 );
            x264_cabac_encode_decision( cb, 27+5-(bits&1), (bits>>1)&1 ); bits >>= 2;
            if( bits != 1 )
166
            {
167 168 169 170 171
                x264_cabac_encode_decision( cb, 27+5, bits&1 ); bits >>= 1;
                x264_cabac_encode_decision( cb, 27+5, bits&1 ); bits >>= 1;
                x264_cabac_encode_decision( cb, 27+5, bits&1 ); bits >>= 1;
                if( bits != 1 )
                    x264_cabac_encode_decision_noup( cb, 27+5, bits&1 );
172
            }
Laurent Aimar's avatar
Laurent Aimar committed
173 174 175 176
        }
    }
}

177
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
178 179
{
    if( i_pred == i_mode )
180
        x264_cabac_encode_decision( cb, 68, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
181 182
    else
    {
183
        x264_cabac_encode_decision( cb, 68, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
184 185
        if( i_mode > i_pred  )
            i_mode--;
186 187
        x264_cabac_encode_decision( cb, 69, (i_mode     )&0x01 );
        x264_cabac_encode_decision( cb, 69, (i_mode >> 1)&0x01 );
188
        x264_cabac_encode_decision( cb, 69, (i_mode >> 2)      );
Laurent Aimar's avatar
Laurent Aimar committed
189 190
    }
}
191

192
static void x264_cabac_mb_intra_chroma_pred_mode( x264_t *h, x264_cabac_t *cb )
Laurent Aimar's avatar
Laurent Aimar committed
193
{
194
    const int i_mode = x264_mb_pred_mode8x8c_fix[h->mb.i_chroma_pred_mode];
Laurent Aimar's avatar
Laurent Aimar committed
195 196 197
    int       ctx = 0;

    /* No need to test for I4x4 or I_16x16 as cache_save handle that */
198
    if( (h->mb.i_neighbour & MB_LEFT) && h->mb.chroma_pred_mode[h->mb.i_mb_left_xy] != 0 )
Laurent Aimar's avatar
Laurent Aimar committed
199
        ctx++;
200
    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
201 202
        ctx++;

203
    x264_cabac_encode_decision_noup( cb, 64 + ctx, i_mode > 0 );
Loren Merritt's avatar
Loren Merritt committed
204
    if( i_mode > 0 )
Laurent Aimar's avatar
Laurent Aimar committed
205
    {
Loren Merritt's avatar
Loren Merritt committed
206
        x264_cabac_encode_decision( cb, 64 + 3, i_mode > 1 );
Laurent Aimar's avatar
Laurent Aimar committed
207
        if( i_mode > 1 )
208
            x264_cabac_encode_decision_noup( cb, 64 + 3, i_mode > 2 );
Laurent Aimar's avatar
Laurent Aimar committed
209 210 211
    }
}

212
static void x264_cabac_mb_cbp_luma( x264_t *h, x264_cabac_t *cb )
Laurent Aimar's avatar
Laurent Aimar committed
213
{
Fiona Glaser's avatar
Fiona Glaser committed
214
    int cbp = h->mb.i_cbp_luma;
215 216
    int cbp_l = h->mb.cache.i_cbp_left;
    int cbp_t = h->mb.cache.i_cbp_top;
217 218 219 220
    x264_cabac_encode_decision     ( cb, 76 - ((cbp_l >> 1) & 1) - ((cbp_t >> 1) & 2), (cbp >> 0) & 1 );
    x264_cabac_encode_decision     ( cb, 76 - ((cbp   >> 0) & 1) - ((cbp_t >> 2) & 2), (cbp >> 1) & 1 );
    x264_cabac_encode_decision     ( cb, 76 - ((cbp_l >> 3) & 1) - ((cbp   << 1) & 2), (cbp >> 2) & 1 );
    x264_cabac_encode_decision_noup( cb, 76 - ((cbp   >> 2) & 1) - ((cbp   >> 0) & 2), (cbp >> 3) & 1 );
Laurent Aimar's avatar
Laurent Aimar committed
221 222
}

223
static void x264_cabac_mb_cbp_chroma( x264_t *h, x264_cabac_t *cb )
Laurent Aimar's avatar
Laurent Aimar committed
224
{
225 226 227
    int cbp_a = h->mb.cache.i_cbp_left & 0x30;
    int cbp_b = h->mb.cache.i_cbp_top  & 0x30;
    int ctx = 0;
Laurent Aimar's avatar
Laurent Aimar committed
228

229 230
    if( cbp_a && h->mb.cache.i_cbp_left != -1 ) ctx++;
    if( cbp_b && h->mb.cache.i_cbp_top  != -1 ) ctx+=2;
Laurent Aimar's avatar
Laurent Aimar committed
231
    if( h->mb.i_cbp_chroma == 0 )
232
        x264_cabac_encode_decision_noup( cb, 77 + ctx, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
233 234
    else
    {
235
        x264_cabac_encode_decision_noup( cb, 77 + ctx, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
236 237

        ctx = 4;
238 239
        if( cbp_a == 0x20 ) ctx++;
        if( cbp_b == 0x20 ) ctx += 2;
240
        x264_cabac_encode_decision_noup( cb, 77 + ctx, h->mb.i_cbp_chroma > 1 );
Laurent Aimar's avatar
Laurent Aimar committed
241 242 243
    }
}

244
static void x264_cabac_mb_qp_delta( x264_t *h, x264_cabac_t *cb )
Laurent Aimar's avatar
Laurent Aimar committed
245
{
246
    int i_dqp = h->mb.i_qp - h->mb.i_last_qp;
Laurent Aimar's avatar
Laurent Aimar committed
247 248
    int ctx;

249 250 251
    /* 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] )
    {
252
#if !RDO_SKIP_BS
253 254 255 256 257
        h->mb.i_qp = h->mb.i_last_qp;
#endif
        i_dqp = 0;
    }

258 259 260
    /* Since, per the above, empty-CBP I16x16 blocks never have delta quants,
     * we don't have to check for them. */
    ctx = h->mb.i_last_dqp && h->mb.cbp[h->mb.i_mb_prev_xy];
Laurent Aimar's avatar
Laurent Aimar committed
261

Loren Merritt's avatar
Loren Merritt committed
262
    if( i_dqp != 0 )
Laurent Aimar's avatar
Laurent Aimar committed
263
    {
Loren Merritt's avatar
Loren Merritt committed
264 265
        int val = i_dqp <= 0 ? (-2*i_dqp) : (2*i_dqp - 1);
        /* dqp is interpreted modulo 52 */
266
        if( val >= 51 && val != 52 )
Loren Merritt's avatar
Loren Merritt committed
267
            val = 103 - val;
268
        do
Loren Merritt's avatar
Loren Merritt committed
269 270
        {
            x264_cabac_encode_decision( cb, 60 + ctx, 1 );
271
            ctx = 2+(ctx>>1);
272
        } while( --val );
Laurent Aimar's avatar
Laurent Aimar committed
273
    }
274
    x264_cabac_encode_decision_noup( cb, 60 + ctx, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
275 276
}

277
#if !RDO_SKIP_BS
Laurent Aimar's avatar
Laurent Aimar committed
278 279
void x264_cabac_mb_skip( x264_t *h, int b_skip )
{
Loren Merritt's avatar
Loren Merritt committed
280 281 282
    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
283
    x264_cabac_encode_decision( &h->cabac, ctx, b_skip );
Laurent Aimar's avatar
Laurent Aimar committed
284
}
Loren Merritt's avatar
Loren Merritt committed
285
#endif
Laurent Aimar's avatar
Laurent Aimar committed
286

287
static inline void x264_cabac_mb_sub_p_partition( x264_cabac_t *cb, int i_sub )
Laurent Aimar's avatar
Laurent Aimar committed
288 289 290
{
    if( i_sub == D_L0_8x8 )
    {
291 292
        x264_cabac_encode_decision( cb, 21, 1 );
        return;
Laurent Aimar's avatar
Laurent Aimar committed
293
    }
294 295 296 297
    x264_cabac_encode_decision( cb, 21, 0 );
    if( i_sub == D_L0_8x4 )
        x264_cabac_encode_decision( cb, 22, 0 );
    else
Laurent Aimar's avatar
Laurent Aimar committed
298
    {
299
        x264_cabac_encode_decision( cb, 22, 1 );
300
        x264_cabac_encode_decision( cb, 23, i_sub == D_L0_4x8 );
Laurent Aimar's avatar
Laurent Aimar committed
301 302 303
    }
}

304
static ALWAYS_INLINE void x264_cabac_mb_sub_b_partition( x264_cabac_t *cb, int i_sub )
Laurent Aimar's avatar
Laurent Aimar committed
305
{
Loren Merritt's avatar
Loren Merritt committed
306 307 308 309
    if( i_sub == D_DIRECT_8x8 )
    {
        x264_cabac_encode_decision( cb, 36, 0 );
        return;
Loren Merritt's avatar
Loren Merritt committed
310
    }
311 312
    x264_cabac_encode_decision( cb, 36, 1 );
    if( i_sub == D_BI_8x8 )
Loren Merritt's avatar
Loren Merritt committed
313
    {
314 315 316 317 318
        x264_cabac_encode_decision( cb, 37, 1 );
        x264_cabac_encode_decision( cb, 38, 0 );
        x264_cabac_encode_decision( cb, 39, 0 );
        x264_cabac_encode_decision( cb, 39, 0 );
        return;
Laurent Aimar's avatar
Laurent Aimar committed
319
    }
320 321
    x264_cabac_encode_decision( cb, 37, 0 );
    x264_cabac_encode_decision( cb, 39, i_sub == D_L1_8x8 );
Laurent Aimar's avatar
Laurent Aimar committed
322 323
}

324
static ALWAYS_INLINE void x264_cabac_mb_transform_size( x264_t *h, x264_cabac_t *cb )
325
{
326
    int ctx = 399 + h->mb.cache.i_neighbour_transform_size;
327
    x264_cabac_encode_decision_noup( cb, ctx, h->mb.b_transform_8x8 );
328 329
}

330
static void x264_cabac_mb_ref( x264_t *h, x264_cabac_t *cb, int i_list, int idx )
Laurent Aimar's avatar
Laurent Aimar committed
331 332 333 334 335 336
{
    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 ctx  = 0;

337
    if( i_refa > 0 && !h->mb.cache.skip[i8 - 1] )
Laurent Aimar's avatar
Laurent Aimar committed
338
        ctx++;
339
    if( i_refb > 0 && !h->mb.cache.skip[i8 - 8] )
Laurent Aimar's avatar
Laurent Aimar committed
340 341
        ctx += 2;

342
    for( int i_ref = h->mb.cache.ref[i_list][i8]; i_ref > 0; i_ref-- )
Laurent Aimar's avatar
Laurent Aimar committed
343
    {
344
        x264_cabac_encode_decision( cb, 54 + ctx, 1 );
345
        ctx = (ctx>>2)+4;
Laurent Aimar's avatar
Laurent Aimar committed
346
    }
347
    x264_cabac_encode_decision( cb, 54 + ctx, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
348 349
}

350
static ALWAYS_INLINE int x264_cabac_mb_mvd_cpn( x264_t *h, x264_cabac_t *cb, int i_list, int idx, int l, int mvd, int ctx )
Laurent Aimar's avatar
Laurent Aimar committed
351 352
{
    const int i_abs = abs( mvd );
Loren Merritt's avatar
Loren Merritt committed
353
    const int ctxbase = l ? 47 : 40;
354
#if RDO_SKIP_BS
355 356
    if( i_abs == 0 )
        x264_cabac_encode_decision( cb, ctxbase + ctx, 0 );
357
    else
Laurent Aimar's avatar
Laurent Aimar committed
358
    {
359
        x264_cabac_encode_decision( cb, ctxbase + ctx, 1 );
360
        if( i_abs <= 3 )
361
        {
362
            for( int i = 1; i < i_abs; i++ )
363 364
                x264_cabac_encode_decision( cb, ctxbase + i + 2, 1 );
            x264_cabac_encode_decision( cb, ctxbase + i_abs + 2, 0 );
365 366
            x264_cabac_encode_bypass( cb, mvd < 0 );
        }
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
        else
        {
            x264_cabac_encode_decision( cb, ctxbase + 3, 1 );
            x264_cabac_encode_decision( cb, ctxbase + 4, 1 );
            x264_cabac_encode_decision( cb, ctxbase + 5, 1 );
            if( i_abs < 9 )
            {
                cb->f8_bits_encoded += cabac_size_unary[i_abs - 3][cb->state[ctxbase+6]];
                cb->state[ctxbase+6] = cabac_transition_unary[i_abs - 3][cb->state[ctxbase+6]];
            }
            else
            {
                cb->f8_bits_encoded += cabac_size_5ones[cb->state[ctxbase+6]];
                cb->state[ctxbase+6] = cabac_transition_5ones[cb->state[ctxbase+6]];
                x264_cabac_encode_ue_bypass( cb, 3, i_abs - 9 );
            }
        }
384
    }
385
#else
386 387 388 389 390 391 392
    static const uint8_t ctxes[8] = { 3,4,5,6,6,6,6,6 };

    if( i_abs == 0 )
        x264_cabac_encode_decision( cb, ctxbase + ctx, 0 );
    else
    {
        x264_cabac_encode_decision( cb, ctxbase + ctx, 1 );
393 394
        if( i_abs < 9 )
        {
395
            for( int i = 1; i < i_abs; i++ )
396 397 398 399 400
                x264_cabac_encode_decision( cb, ctxbase + ctxes[i-1], 1 );
            x264_cabac_encode_decision( cb, ctxbase + ctxes[i_abs-1], 0 );
        }
        else
        {
401
            for( int i = 1; i < 9; i++ )
402 403 404
                x264_cabac_encode_decision( cb, ctxbase + ctxes[i-1], 1 );
            x264_cabac_encode_ue_bypass( cb, 3, i_abs - 9 );
        }
Loren Merritt's avatar
Loren Merritt committed
405
        x264_cabac_encode_bypass( cb, mvd < 0 );
406
    }
407
#endif
408 409 410
    /* Since we don't need to keep track of MVDs larger than 33, just cap the value.
     * This lets us store MVDs as 8-bit values instead of 16-bit. */
    return X264_MIN( i_abs, 33 );
Laurent Aimar's avatar
Laurent Aimar committed
411 412
}

413
static NOINLINE uint16_t x264_cabac_mb_mvd( x264_t *h, x264_cabac_t *cb, int i_list, int idx, int width )
Laurent Aimar's avatar
Laurent Aimar committed
414
{
415
    ALIGNED_4( int16_t mvp[2] );
Laurent Aimar's avatar
Laurent Aimar committed
416 417 418 419 420 421
    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];
422 423
    uint16_t amvd = x264_cabac_mvd_sum(h->mb.cache.mvd[i_list][x264_scan8[idx] - 1],
                                       h->mb.cache.mvd[i_list][x264_scan8[idx] - 8]);
Laurent Aimar's avatar
Laurent Aimar committed
424 425

    /* encode */
426 427
    mdx = x264_cabac_mb_mvd_cpn( h, cb, i_list, idx, 0, mdx, amvd&0xFF );
    mdy = x264_cabac_mb_mvd_cpn( h, cb, i_list, idx, 1, mdy, amvd>>8 );
Laurent Aimar's avatar
Laurent Aimar committed
428

429
    return pack8to16(mdx,mdy);
Fiona Glaser's avatar
Fiona Glaser committed
430 431 432
}

#define x264_cabac_mb_mvd(h,cb,i_list,idx,width,height)\
433
do\
Fiona Glaser's avatar
Fiona Glaser committed
434
{\
435
    uint16_t mvd = x264_cabac_mb_mvd(h,cb,i_list,idx,width);\
Fiona Glaser's avatar
Fiona Glaser committed
436
    x264_macroblock_cache_mvd( h, block_idx_x[idx], block_idx_y[idx], width, height, i_list, mvd );\
437
} while(0)
Laurent Aimar's avatar
Laurent Aimar committed
438

439
static inline void x264_cabac_mb8x8_mvd( x264_t *h, x264_cabac_t *cb, int i )
440
{
441 442 443
    switch( h->mb.i_sub_partition[i] )
    {
        case D_L0_8x8:
444
            x264_cabac_mb_mvd( h, cb, 0, 4*i, 2, 2 );
445 446
            break;
        case D_L0_8x4:
447 448
            x264_cabac_mb_mvd( h, cb, 0, 4*i+0, 2, 1 );
            x264_cabac_mb_mvd( h, cb, 0, 4*i+2, 2, 1 );
449 450
            break;
        case D_L0_4x8:
451 452
            x264_cabac_mb_mvd( h, cb, 0, 4*i+0, 1, 2 );
            x264_cabac_mb_mvd( h, cb, 0, 4*i+1, 1, 2 );
453 454
            break;
        case D_L0_4x4:
455 456 457 458
            x264_cabac_mb_mvd( h, cb, 0, 4*i+0, 1, 1 );
            x264_cabac_mb_mvd( h, cb, 0, 4*i+1, 1, 1 );
            x264_cabac_mb_mvd( h, cb, 0, 4*i+2, 1, 1 );
            x264_cabac_mb_mvd( h, cb, 0, 4*i+3, 1, 1 );
459
            break;
460 461
        default:
            assert(0);
462 463 464
    }
}

465 466 467 468 469 470 471 472
/* 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
 */

Fiona Glaser's avatar
Fiona Glaser committed
473
static int ALWAYS_INLINE x264_cabac_mb_cbf_ctxidxinc( x264_t *h, int i_cat, int i_idx, int b_intra )
Laurent Aimar's avatar
Laurent Aimar committed
474
{
475 476
    int i_nza;
    int i_nzb;
Laurent Aimar's avatar
Laurent Aimar committed
477

478
    switch( i_cat )
Laurent Aimar's avatar
Laurent Aimar committed
479
    {
480 481
        case DCT_LUMA_AC:
        case DCT_LUMA_4x4:
482
        case DCT_CHROMA_AC:
483
            /* no need to test for skip/pcm */
484 485
            i_nza = h->mb.cache.non_zero_count[x264_scan8[i_idx] - 1];
            i_nzb = h->mb.cache.non_zero_count[x264_scan8[i_idx] - 8];
486 487 488 489 490 491 492 493
            if( x264_constant_p(b_intra) && !b_intra )
                return 85 + 4*i_cat + ((2*i_nzb + i_nza)&0x7f);
            else
            {
                i_nza &= 0x7f + (b_intra << 7);
                i_nzb &= 0x7f + (b_intra << 7);
                return 85 + 4*i_cat + 2*!!i_nzb + !!i_nza;
            }
494
        case DCT_LUMA_DC:
495 496
            i_nza = (h->mb.cache.i_cbp_left >> 8) & 1;
            i_nzb = (h->mb.cache.i_cbp_top  >> 8) & 1;
497
            return 85 + 4*i_cat + 2*i_nzb + i_nza;
498 499
        case DCT_CHROMA_DC:
            /* no need to test skip/pcm */
500
            i_idx -= 25;
501 502
            i_nza = h->mb.cache.i_cbp_left != -1 ? (h->mb.cache.i_cbp_left >> (9 + i_idx)) & 1 : b_intra;
            i_nzb = h->mb.cache.i_cbp_top  != -1 ? (h->mb.cache.i_cbp_top  >> (9 + i_idx)) & 1 : b_intra;
503
            return 85 + 4*i_cat + 2*i_nzb + i_nza;
Fiona Glaser's avatar
Fiona Glaser committed
504 505
        default:
            return 0;
Laurent Aimar's avatar
Laurent Aimar committed
506 507 508 509
    }
}


Fiona Glaser's avatar
Fiona Glaser committed
510
static const uint16_t significant_coeff_flag_offset[2][6] = {
511 512 513
    { 105, 120, 134, 149, 152, 402 },
    { 277, 292, 306, 321, 324, 436 }
};
Fiona Glaser's avatar
Fiona Glaser committed
514
static const uint16_t last_coeff_flag_offset[2][6] = {
515 516 517
    { 166, 181, 195, 210, 213, 417 },
    { 338, 353, 367, 382, 385, 451 }
};
Fiona Glaser's avatar
Fiona Glaser committed
518
static const uint16_t coeff_abs_level_m1_offset[6] =
519
    { 227, 237, 247, 257, 266, 426 };
Fiona Glaser's avatar
Fiona Glaser committed
520
static const uint8_t significant_coeff_flag_offset_8x8[2][63] =
521
{{
Loren Merritt's avatar
Loren Merritt committed
522 523 524 525
    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
526 527 528 529 530 531
},{
    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
532
static const uint8_t last_coeff_flag_offset_8x8[63] = {
Loren Merritt's avatar
Loren Merritt committed
533 534 535 536 537
    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
};
Loren Merritt's avatar
Loren Merritt committed
538

539 540 541 542 543 544
// 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
545
static const uint8_t coeff_abs_level_transition[2][8] = {
546 547 548 549 550
/* 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 }
};
551
static const int count_cat_m1[5] = {15, 14, 15, 3, 14};
Loren Merritt's avatar
Loren Merritt committed
552

Fiona Glaser's avatar
Fiona Glaser committed
553
#if !RDO_SKIP_BS
554
static void block_residual_write_cabac( x264_t *h, x264_cabac_t *cb, int i_ctxBlockCat, int16_t *l )
Laurent Aimar's avatar
Laurent Aimar committed
555
{
556 557
    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];
558
    const int i_ctx_level = coeff_abs_level_m1_offset[i_ctxBlockCat];
559
    const uint8_t *sig_offset = significant_coeff_flag_offset_8x8[h->mb.b_interlaced];
560
    int i_coeff_abs_m1[64];
561
    int i_coeff_sign[64];
Laurent Aimar's avatar
Laurent Aimar committed
562
    int i_coeff = 0;
563
    int i_last;
564
    int node_ctx = 0;
565
    int i = 0;
Laurent Aimar's avatar
Laurent Aimar committed
566

567
    i_last = h->quantf.coeff_last[i_ctxBlockCat](l);
Fiona Glaser's avatar
Fiona Glaser committed
568

569
#define WRITE_SIGMAP( l8x8 )\
570
    while(1)\
571 572 573 574
    {\
        if( l[i] )\
        {\
            i_coeff_abs_m1[i_coeff] = abs(l[i]) - 1;\
575
            i_coeff_sign[i_coeff] = l[i] < 0;\
576
            i_coeff++;\
577
            x264_cabac_encode_decision( cb, i_ctx_sig + (l8x8 ? sig_offset[i] : i), 1 );\
578 579 580 581 582 583 584
            if( i == i_last )\
            {\
                x264_cabac_encode_decision( cb, i_ctx_last + (l8x8 ? last_coeff_flag_offset_8x8[i] : i), 1 );\
                break;\
            }\
            else\
                x264_cabac_encode_decision( cb, i_ctx_last + (l8x8 ? last_coeff_flag_offset_8x8[i] : i), 0 );\
585 586
        }\
        else\
587
            x264_cabac_encode_decision( cb, i_ctx_sig + (l8x8 ? sig_offset[i] : i), 0 );\
588 589 590 591 592 593 594 595
        i++;\
        if( i == i_count_m1 )\
        {\
            i_coeff_abs_m1[i_coeff] = abs(l[i]) - 1;\
            i_coeff_sign[i_coeff]   = l[i] < 0;\
            i_coeff++;\
            break;\
        }\
Fiona Glaser's avatar
Fiona Glaser committed
596 597
    }

598
    if( i_ctxBlockCat == DCT_LUMA_8x8 )
599 600
    {
        const int i_count_m1 = 63;
601
        WRITE_SIGMAP( 1 )
602
    }
603
    else
Fiona Glaser's avatar
Fiona Glaser committed
604
    {
605 606
        const int i_count_m1 = count_cat_m1[i_ctxBlockCat];
        WRITE_SIGMAP( 0 )
Laurent Aimar's avatar
Laurent Aimar committed
607 608
    }

609
    do
Laurent Aimar's avatar
Laurent Aimar committed
610
    {
Fiona Glaser's avatar
Fiona Glaser committed
611
        int i_prefix, ctx;
612
        i_coeff--;
Fiona Glaser's avatar
Fiona Glaser committed
613

Laurent Aimar's avatar
Laurent Aimar committed
614
        /* write coeff_abs - 1 */
Fiona Glaser's avatar
Fiona Glaser committed
615 616
        i_prefix = X264_MIN( i_coeff_abs_m1[i_coeff], 14 );
        ctx = coeff_abs_level1_ctx[node_ctx] + i_ctx_level;
Laurent Aimar's avatar
Laurent Aimar committed
617

Fiona Glaser's avatar
Fiona Glaser committed
618
        if( i_prefix )
Laurent Aimar's avatar
Laurent Aimar committed
619
        {
Fiona Glaser's avatar
Fiona Glaser committed
620 621
            x264_cabac_encode_decision( cb, ctx, 1 );
            ctx = coeff_abs_levelgt1_ctx[node_ctx] + i_ctx_level;
622
            for( i = 0; i < i_prefix - 1; i++ )
Fiona Glaser's avatar
Fiona Glaser committed
623
                x264_cabac_encode_decision( cb, ctx, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
624
            if( i_prefix < 14 )
Fiona Glaser's avatar
Fiona Glaser committed
625
                x264_cabac_encode_decision( cb, ctx, 0 );
Fiona Glaser's avatar
Fiona Glaser committed
626
            else
627
                x264_cabac_encode_ue_bypass( cb, 0, i_coeff_abs_m1[i_coeff] - 14 );
Laurent Aimar's avatar
Laurent Aimar committed
628

629
            node_ctx = coeff_abs_level_transition[1][node_ctx];
Laurent Aimar's avatar
Laurent Aimar committed
630
        }
631
        else
Fiona Glaser's avatar
Fiona Glaser committed
632 633
        {
            x264_cabac_encode_decision( cb, ctx, 0 );
634
            node_ctx = coeff_abs_level_transition[0][node_ctx];
Fiona Glaser's avatar
Fiona Glaser committed
635 636
        }

637 638
        x264_cabac_encode_bypass( cb, i_coeff_sign[i_coeff] );
    } while( i_coeff > 0 );
Laurent Aimar's avatar
Laurent Aimar committed
639
}
640
#define block_residual_write_cabac_8x8( h, cb, l ) block_residual_write_cabac( h, cb, DCT_LUMA_8x8, l )
Fiona Glaser's avatar
Fiona Glaser committed
641 642 643 644 645 646 647

#else

/* Faster RDO by merging sigmap and level coding.  Note that for 8x8dct
 * this is slightly incorrect because the sigmap is not reversible
 * (contexts are repeated).  However, there is nearly no quality penalty
 * for this (~0.001db) and the speed boost (~30%) is worth it. */
648
static void ALWAYS_INLINE block_residual_write_cabac_internal( x264_t *h, x264_cabac_t *cb, int i_ctxBlockCat, int16_t *l, int b_8x8 )
Fiona Glaser's avatar
Fiona Glaser committed
649 650 651 652
{
    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];
    const int i_ctx_level = coeff_abs_level_m1_offset[i_ctxBlockCat];
653 654
    const uint8_t *sig_offset = significant_coeff_flag_offset_8x8[h->mb.b_interlaced];
    int i_last, i_coeff_abs, ctx, node_ctx;
Fiona Glaser's avatar
Fiona Glaser committed
655 656

    i_last = h->quantf.coeff_last[i_ctxBlockCat](l);
Laurent Aimar's avatar
Laurent Aimar committed
657

Fiona Glaser's avatar
Fiona Glaser committed
658
    i_coeff_abs = abs(l[i_last]);
Fiona Glaser's avatar
Fiona Glaser committed
659
    ctx = coeff_abs_level1_ctx[0] + i_ctx_level;
Laurent Aimar's avatar
Laurent Aimar committed
660

661
    if( i_last != (b_8x8 ? 63 : count_cat_m1[i_ctxBlockCat]) )
Fiona Glaser's avatar
Fiona Glaser committed
662
    {
663
        x264_cabac_encode_decision( cb, i_ctx_sig + (b_8x8?sig_offset[i_last]:i_last), 1 );
Fiona Glaser's avatar
Fiona Glaser committed
664 665 666
        x264_cabac_encode_decision( cb, i_ctx_last + (b_8x8?last_coeff_flag_offset_8x8[i_last]:i_last), 1 );
    }

Fiona Glaser's avatar
Fiona Glaser committed
667
    if( i_coeff_abs > 1 )
Fiona Glaser's avatar
Fiona Glaser committed
668 669 670
    {
        x264_cabac_encode_decision( cb, ctx, 1 );
        ctx = coeff_abs_levelgt1_ctx[0] + i_ctx_level;
Fiona Glaser's avatar
Fiona Glaser committed
671 672 673 674 675 676 677 678 679 680 681
        if( i_coeff_abs < 15 )
        {
            cb->f8_bits_encoded += cabac_size_unary[i_coeff_abs-1][cb->state[ctx]];
            cb->state[ctx] = cabac_transition_unary[i_coeff_abs-1][cb->state[ctx]];
        }
        else
        {
            cb->f8_bits_encoded += cabac_size_unary[14][cb->state[ctx]];
            cb->state[ctx] = cabac_transition_unary[14][cb->state[ctx]];
            x264_cabac_encode_ue_bypass( cb, 0, i_coeff_abs - 15 );
        }
Fiona Glaser's avatar
Fiona Glaser committed
682 683 684 685 686 687 688 689 690
        node_ctx = coeff_abs_level_transition[1][0];
    }
    else
    {
        x264_cabac_encode_decision( cb, ctx, 0 );
        node_ctx = coeff_abs_level_transition[0][0];
        x264_cabac_encode_bypass( cb, 0 ); // sign
    }

691
    for( int i = i_last-1 ; i >= 0; i-- )
Fiona Glaser's avatar
Fiona Glaser committed
692 693 694
    {
        if( l[i] )
        {
Fiona Glaser's avatar
Fiona Glaser committed
695
            i_coeff_abs = abs(l[i]);
696
            x264_cabac_encode_decision( cb, i_ctx_sig + (b_8x8?sig_offset[i]:i), 1 );
Fiona Glaser's avatar
Fiona Glaser committed
697 698 699
            x264_cabac_encode_decision( cb, i_ctx_last + (b_8x8?last_coeff_flag_offset_8x8[i]:i), 0 );
            ctx = coeff_abs_level1_ctx[node_ctx] + i_ctx_level;

Fiona Glaser's avatar
Fiona Glaser committed
700
            if( i_coeff_abs > 1 )
Fiona Glaser's avatar
Fiona Glaser committed
701 702 703
            {
                x264_cabac_encode_decision( cb, ctx, 1 );
                ctx = coeff_abs_levelgt1_ctx[node_ctx] + i_ctx_level;
Fiona Glaser's avatar
Fiona Glaser committed
704 705 706 707 708 709 710 711 712 713 714
                if( i_coeff_abs < 15 )
                {
                    cb->f8_bits_encoded += cabac_size_unary[i_coeff_abs-1][cb->state[ctx]];
                    cb->state[ctx] = cabac_transition_unary[i_coeff_abs-1][cb->state[ctx]];
                }
                else
                {
                    cb->f8_bits_encoded += cabac_size_unary[14][cb->state[ctx]];
                    cb->state[ctx] = cabac_transition_unary[14][cb->state[ctx]];
                    x264_cabac_encode_ue_bypass( cb, 0, i_coeff_abs - 15 );
                }
Fiona Glaser's avatar
Fiona Glaser committed
715 716 717 718 719 720 721 722 723 724
                node_ctx = coeff_abs_level_transition[1][node_ctx];
            }
            else
            {
                x264_cabac_encode_decision( cb, ctx, 0 );
                node_ctx = coeff_abs_level_transition[0][node_ctx];
                x264_cabac_encode_bypass( cb, 0 );
            }
        }
        else
725
            x264_cabac_encode_decision( cb, i_ctx_sig + (b_8x8?sig_offset[i]:i), 0 );
Fiona Glaser's avatar
Fiona Glaser committed
726 727 728
    }
}

729
static void block_residual_write_cabac_8x8( x264_t *h, x264_cabac_t *cb, int16_t *l )
Fiona Glaser's avatar
Fiona Glaser committed
730
{
731
    block_residual_write_cabac_internal( h, cb, DCT_LUMA_8x8, l, 1 );
Fiona Glaser's avatar
Fiona Glaser committed
732
}
733
static void block_residual_write_cabac( x264_t *h, x264_cabac_t *cb, int i_ctxBlockCat, int16_t *l )
Fiona Glaser's avatar
Fiona Glaser committed
734
{
735
    block_residual_write_cabac_internal( h, cb, i_ctxBlockCat, l, 0 );
Fiona Glaser's avatar
Fiona Glaser committed
736 737
}
#endif
Laurent Aimar's avatar
Laurent Aimar committed
738

739
#define block_residual_write_cabac_cbf( h, cb, i_ctxBlockCat, i_idx, l, b_intra ) \
740
{ \
Fiona Glaser's avatar
Fiona Glaser committed
741
    int ctxidxinc = x264_cabac_mb_cbf_ctxidxinc( h, i_ctxBlockCat, i_idx, b_intra ); \
742 743 744 745 746 747 748
    if( h->mb.cache.non_zero_count[x264_scan8[i_idx]] )\
    {\
        x264_cabac_encode_decision( cb, ctxidxinc, 1 );\
        block_residual_write_cabac( h, cb, i_ctxBlockCat, l ); \
    }\
    else\
        x264_cabac_encode_decision( cb, ctxidxinc, 0 );\
749 750
}

751
void x264_macroblock_write_cabac( x264_t *h, x264_cabac_t *cb )
Laurent Aimar's avatar
Laurent Aimar committed
752 753
{
    const int i_mb_type = h->mb.i_type;
754
    int i_list;
Laurent Aimar's avatar
Laurent Aimar committed
755

756
#if !RDO_SKIP_BS
757 758 759 760
    const int i_mb_pos_start = x264_cabac_pos( cb );
    int       i_mb_pos_tex;
#endif

Laurent Aimar's avatar
Laurent Aimar committed
761
    /* Write the MB type */
762
    x264_cabac_mb_type( h, cb );
Laurent Aimar's avatar
Laurent Aimar committed
763

764
#if !RDO_SKIP_BS
Laurent Aimar's avatar
Laurent Aimar committed
765 766
    if( i_mb_type == I_PCM )
    {
767
        i_mb_pos_tex = x264_cabac_pos( cb );
768
        h->stat.frame.i_mv_bits += i_mb_pos_tex - i_mb_pos_start;
769 770 771

        memcpy( cb->p, h->mb.pic.p_fenc[0], 256 );
        cb->p += 256;
772
        for( int i = 0; i < 8; i++ )
773 774
            memcpy( cb->p + i*8, h->mb.pic.p_fenc[1] + i*FENC_STRIDE, 8 );
        cb->p += 64;
775
        for( int i = 0; i < 8; i++ )
776 777 778 779 780 781 782 783
            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;

784
        h->stat.frame.i_tex_bits += x264_cabac_pos( cb ) - i_mb_pos_tex;
Laurent Aimar's avatar
Laurent Aimar committed
785 786
        return;
    }
787
#endif
Laurent Aimar's avatar
Laurent Aimar committed
788 789 790

    if( IS_INTRA( i_mb_type ) )
    {
791
        if( h->pps->b_transform_8x8_mode && i_mb_type != I_16x16 )
792
            x264_cabac_mb_transform_size( h, cb );
793 794

        if( i_mb_type != I_16x16 )
Laurent Aimar's avatar
Laurent Aimar committed
795
        {
796
            int di = h->mb.b_transform_8x8 ? 4 : 1;
797
            for( int i = 0; i < 16; i += di )
Laurent Aimar's avatar
Laurent Aimar committed
798 799
            {
                const int i_pred = x264_mb_predict_intra4x4_mode( h, i );
800
                const int i_mode = x264_mb_pred_mode4x4_fix( h->mb.cache.intra4x4_pred_mode[x264_scan8[i]] );
801
                x264_cabac_mb_intra4x4_pred_mode( cb, i_pred, i_mode );
Laurent Aimar's avatar
Laurent Aimar committed
802 803
            }
        }
804

805
        x264_cabac_mb_intra_chroma_pred_mode( h, cb );
Laurent Aimar's avatar
Laurent Aimar committed
806 807 808 809 810
    }
    else if( i_mb_type == P_L0 )
    {
        if( h->mb.i_partition == D_16x16 )
        {
811
            if( h->mb.pic.i_fref[0] > 1 )
Laurent Aimar's avatar
Laurent Aimar committed
812
            {
813
                x264_cabac_mb_ref( h, cb, 0, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
814
            }
815
            x264_cabac_mb_mvd( h, cb, 0, 0, 4, 4 );
Laurent Aimar's avatar
Laurent Aimar committed
816 817 818
        }
        else if( h->mb.i_partition == D_16x8 )
        {
819
            if( h->mb.pic.i_fref[0] > 1 )
Laurent Aimar's avatar
Laurent Aimar committed
820
            {
821 822
                x264_cabac_mb_ref( h, cb, 0, 0 );
                x264_cabac_mb_ref( h, cb, 0, 8 );
Laurent Aimar's avatar
Laurent Aimar committed
823
            }
824 825
            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
826
        }
827
        else //if( h->mb.i_partition == D_8x16 )
Laurent Aimar's avatar
Laurent Aimar committed
828
        {
829
            if( h->mb.pic.i_fref[0] > 1 )
Laurent Aimar's avatar
Laurent Aimar committed
830
            {
831 832
                x264_cabac_mb_ref( h, cb, 0, 0 );
                x264_cabac_mb_ref( h, cb, 0, 4 );
Laurent Aimar's avatar
Laurent Aimar committed
833
            }
834 835
            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
836 837 838 839 840
        }
    }
    else if( i_mb_type == P_8x8 )
    {
        /* sub mb type */
841
        for( int i = 0; i < 4; i++ )
842
            x264_cabac_mb_sub_p_partition( cb, h->mb.i_sub_partition[i] );
Laurent Aimar's avatar
Laurent Aimar committed
843 844

        /* ref 0 */
845
        if( h->mb.pic.i_fref[0] > 1 )
Laurent Aimar's avatar
Laurent Aimar committed
846
        {
847 848 849 850
            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
851 852
        }

853
        for( int i = 0; i < 4; i++ )
854
            x264_cabac_mb8x8_mvd( h, cb, i );
855 856 857 858
    }
    else if( i_mb_type == B_8x8 )
    {
        /* sub mb type */
859
        for( int i = 0; i < 4; i++ )
860
            x264_cabac_mb_sub_b_partition( cb, h->mb.i_sub_partition[i] );
861 862

        /* ref */
863
        if( h->mb.pic.i_fref[0] > 1 )
864
            for( int i = 0; i < 4; i++ )
865 866 867 868
                if( x264_mb_partition_listX_table[0][ h->mb.i_sub_partition[i] ] )
                    x264_cabac_mb_ref( h, cb, 0, 4*i );

        if( h->mb.pic.i_fref[1] > 1 )
869
            for( int i = 0; i < 4; i++ )
870 871
                if( x264_mb_partition_listX_table[1][ h->mb.i_sub_partition[i] ] )
                    x264_cabac_mb_ref( h, cb, 1, 4*i );
872

873
        for( int i = 0; i < 4; i++ )
874 875 876
            if( x264_mb_partition_listX_table[0][ h->mb.i_sub_partition[i] ] )
                x264_cabac_mb_mvd( h, cb, 0, 4*i, 2, 2 );

877
        for( int i = 0; i < 4; i++ )
878 879
            if( x264_mb_partition_listX_table[1][ h->mb.i_sub_partition[i] ] )
                x264_cabac_mb_mvd( h, cb, 1, 4*i, 2, 2 );
Laurent Aimar's avatar
Laurent Aimar committed
880 881 882 883
    }
    else if( i_mb_type != B_DIRECT )
    {
        /* All B mode */
884
        const uint8_t (*b_list)[2] = x264_mb_type_list_table[i_mb_type];
885
        if( h->mb.pic.i_fref[0] > 1 )
Laurent Aimar's avatar
Laurent Aimar committed
886
        {
887 888 889 890 891 892 893 894 895 896 897
            if( b_list[0][0] )
                x264_cabac_mb_ref( h, cb, 0, 0 );
            if( b_list[0][1] && h->mb.i_partition != D_16x16 )
                x264_cabac_mb_ref( h, cb, 0, 8 >> (h->mb.i_partition == D_8x16) );
        }
        if( h->mb.pic.i_fref[1] > 1 )
        {
            if( b_list[1][0] )
                x264_cabac_mb_ref( h, cb, 1, 0 );
            if( b_list[1][1] && h->mb.i_partition != D_16x16 )
                x264_cabac_mb_ref( h, cb, 1, 8 >> (h->mb.i_partition == D_8x16) );
Laurent Aimar's avatar
Laurent Aimar committed
898 899 900 901 902
        }
        for( i_list = 0; i_list < 2; i_list++ )
        {
            if( h->mb.i_partition == D_16x16 )
            {
903
                if( b_list[i_list][0] ) x264_cabac_mb_mvd( h, cb, i_list, 0, 4, 4 );
Laurent Aimar's avatar
Laurent Aimar committed
904 905 906
            }
            else if( h->mb.i_partition == D_16x8 )
            {
907 908
                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
909
            }
910
            else //if( h->mb.i_partition == D_8x16 )
Laurent Aimar's avatar
Laurent Aimar committed
911
            {
912 913
                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
914 915 916 917
            }
        }
    }

918
#if !RDO_SKIP_BS
919
    i_mb_pos_tex = x264_cabac_pos( cb );
920
    h->stat.frame.i_mv_bits += i_mb_pos_tex - i_mb_pos_start;
921
#endif
922

Laurent Aimar's avatar
Laurent Aimar committed
923 924
    if( i_mb_type != I_16x16 )
    {
925 926
        x264_cabac_mb_cbp_luma( h, cb );
        x264_cabac_mb_cbp_chroma( h, cb );
Laurent Aimar's avatar
Laurent Aimar committed
927 928
    }

929
    if( x264_mb_transform_8x8_allowed( h ) && h->mb.i_cbp_luma )