cabac.c 38.2 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 */
Loren Merritt's avatar
Loren Merritt committed
198
    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
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 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 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 337
{
    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;

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

    while( i_ref > 0 )
    {
345
        x264_cabac_encode_decision( cb, 54 + ctx, 1 );
346
        ctx = (ctx>>2)+4;
Laurent Aimar's avatar
Laurent Aimar committed
347 348
        i_ref--;
    }
349
    x264_cabac_encode_decision( cb, 54 + ctx, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
350 351
}

Fiona Glaser's avatar
Fiona Glaser committed
352
static inline void 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
353 354
{
    const int i_abs = abs( mvd );
Loren Merritt's avatar
Loren Merritt committed
355
    const int ctxbase = l ? 47 : 40;
Laurent Aimar's avatar
Laurent Aimar committed
356
    int i;
357
#if RDO_SKIP_BS
358 359
    if( i_abs == 0 )
        x264_cabac_encode_decision( cb, ctxbase + ctx, 0 );
360
    else
Laurent Aimar's avatar
Laurent Aimar committed
361
    {
362
        x264_cabac_encode_decision( cb, ctxbase + ctx, 1 );
363
        if( i_abs <= 3 )
364 365
        {
            for( i = 1; i < i_abs; i++ )
366 367
                x264_cabac_encode_decision( cb, ctxbase + i + 2, 1 );
            x264_cabac_encode_decision( cb, ctxbase + i_abs + 2, 0 );
368 369
            x264_cabac_encode_bypass( cb, mvd < 0 );
        }
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386
        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 );
            }
        }
387
    }
388
#else
389 390 391 392 393 394 395
    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 );
396 397 398 399 400 401 402 403 404 405 406 407
        if( i_abs < 9 )
        {
            for( i = 1; i < i_abs; i++ )
                x264_cabac_encode_decision( cb, ctxbase + ctxes[i-1], 1 );
            x264_cabac_encode_decision( cb, ctxbase + ctxes[i_abs-1], 0 );
        }
        else
        {
            for( i = 1; i < 9; i++ )
                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
408
        x264_cabac_encode_bypass( cb, mvd < 0 );
409
    }
410
#endif
Laurent Aimar's avatar
Laurent Aimar committed
411 412
}

413
static NOINLINE uint32_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] );
Fiona Glaser's avatar
Fiona Glaser committed
416
    uint32_t amvd;
Laurent Aimar's avatar
Laurent Aimar committed
417 418 419 420 421 422
    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];
Fiona Glaser's avatar
Fiona Glaser committed
423 424
    amvd = x264_cabac_amvd_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
425 426

    /* encode */
Fiona Glaser's avatar
Fiona Glaser committed
427 428
    x264_cabac_mb_mvd_cpn( h, cb, i_list, idx, 0, mdx, amvd&0xFFFF );
    x264_cabac_mb_mvd_cpn( h, cb, i_list, idx, 1, mdy, amvd>>16 );
Laurent Aimar's avatar
Laurent Aimar committed
429

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

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

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

466 467 468 469 470 471 472 473
/* 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
474
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
475
{
476 477
    int i_nza;
    int i_nzb;
Laurent Aimar's avatar
Laurent Aimar committed
478

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


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

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

Fiona Glaser's avatar
Fiona Glaser committed
554
#if !RDO_SKIP_BS
555
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
556
{
557 558
    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];
559
    const int i_ctx_level = coeff_abs_level_m1_offset[i_ctxBlockCat];
560
    const uint8_t *significant_coeff_flag_offset = significant_coeff_flag_offset_8x8[h->mb.b_interlaced];
561
    int i_coeff_abs_m1[64];
562
    int i_coeff_sign[64];
Laurent Aimar's avatar
Laurent Aimar committed
563
    int i_coeff = 0;
564
    int i_last;
565
    int node_ctx = 0;
566
    int i = 0;
Laurent Aimar's avatar
Laurent Aimar committed
567

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

570
#define WRITE_SIGMAP( l8x8 )\
571
    while(1)\
572 573 574 575
    {\
        if( l[i] )\
        {\
            i_coeff_abs_m1[i_coeff] = abs(l[i]) - 1;\
576
            i_coeff_sign[i_coeff] = l[i] < 0;\
577 578
            i_coeff++;\
            x264_cabac_encode_decision( cb, i_ctx_sig + (l8x8 ? significant_coeff_flag_offset[i] : i), 1 );\
579 580 581 582 583 584 585
            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 );\
586 587 588
        }\
        else\
            x264_cabac_encode_decision( cb, i_ctx_sig + (l8x8 ? significant_coeff_flag_offset[i] : i), 0 );\
589 590 591 592 593 594 595 596
        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
597 598
    }

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

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

Laurent Aimar's avatar
Laurent Aimar committed
615
        /* write coeff_abs - 1 */
Fiona Glaser's avatar
Fiona Glaser committed
616 617
        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
618

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

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

638 639
        x264_cabac_encode_bypass( cb, i_coeff_sign[i_coeff] );
    } while( i_coeff > 0 );
Laurent Aimar's avatar
Laurent Aimar committed
640
}
641
#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
642 643 644 645 646 647 648

#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. */
649
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
650 651 652 653 654
{
    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];
    const uint8_t *significant_coeff_flag_offset = significant_coeff_flag_offset_8x8[h->mb.b_interlaced];
655
    int i_last, i_coeff_abs, ctx, i, node_ctx;
Fiona Glaser's avatar
Fiona Glaser committed
656 657

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

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

662
    if( i_last != (b_8x8 ? 63 : count_cat_m1[i_ctxBlockCat]) )
Fiona Glaser's avatar
Fiona Glaser committed
663 664 665 666 667
    {
        x264_cabac_encode_decision( cb, i_ctx_sig + (b_8x8?significant_coeff_flag_offset[i_last]:i_last), 1 );
        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
668
    if( i_coeff_abs > 1 )
Fiona Glaser's avatar
Fiona Glaser committed
669 670 671
    {
        x264_cabac_encode_decision( cb, ctx, 1 );
        ctx = coeff_abs_levelgt1_ctx[0] + i_ctx_level;
Fiona Glaser's avatar
Fiona Glaser committed
672 673 674 675 676 677 678 679 680 681 682
        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
683 684 685 686 687 688 689 690 691 692 693 694 695
        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
    }

    for( i = i_last-1 ; i >= 0; i-- )
    {
        if( l[i] )
        {
Fiona Glaser's avatar
Fiona Glaser committed
696
            i_coeff_abs = abs(l[i]);
Fiona Glaser's avatar
Fiona Glaser committed
697 698 699 700
            x264_cabac_encode_decision( cb, i_ctx_sig + (b_8x8?significant_coeff_flag_offset[i]:i), 1 );
            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
701
            if( i_coeff_abs > 1 )
Fiona Glaser's avatar
Fiona Glaser committed
702 703 704
            {
                x264_cabac_encode_decision( cb, ctx, 1 );
                ctx = coeff_abs_levelgt1_ctx[node_ctx] + i_ctx_level;
Fiona Glaser's avatar
Fiona Glaser committed
705 706 707 708 709 710 711 712 713 714 715
                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
716 717 718 719 720 721 722 723 724 725 726 727 728 729
                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
            x264_cabac_encode_decision( cb, i_ctx_sig + (b_8x8?significant_coeff_flag_offset[i]:i), 0 );
    }
}

730
static void block_residual_write_cabac_8x8( x264_t *h, x264_cabac_t *cb, int16_t *l )
Fiona Glaser's avatar
Fiona Glaser committed
731
{
732
    block_residual_write_cabac_internal( h, cb, DCT_LUMA_8x8, l, 1 );
Fiona Glaser's avatar
Fiona Glaser committed
733
}
734
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
735
{
736
    block_residual_write_cabac_internal( h, cb, i_ctxBlockCat, l, 0 );
Fiona Glaser's avatar
Fiona Glaser committed
737 738
}
#endif
Laurent Aimar's avatar
Laurent Aimar committed
739

740
#define block_residual_write_cabac_cbf( h, cb, i_ctxBlockCat, i_idx, l, b_intra ) \
741
{ \
Fiona Glaser's avatar
Fiona Glaser committed
742
    int ctxidxinc = x264_cabac_mb_cbf_ctxidxinc( h, i_ctxBlockCat, i_idx, b_intra ); \
743 744 745 746 747 748 749
    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 );\
750 751
}

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

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

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

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

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

791
        h->stat.frame.i_tex_bits += x264_cabac_pos( cb ) - i_mb_pos_tex;
Laurent Aimar's avatar
Laurent Aimar committed
792 793
        return;
    }
794
#endif
Laurent Aimar's avatar
Laurent Aimar committed
795 796 797

    if( IS_INTRA( i_mb_type ) )
    {
798
        if( h->pps->b_transform_8x8_mode && i_mb_type != I_16x16 )
799
            x264_cabac_mb_transform_size( h, cb );
800 801

        if( i_mb_type != I_16x16 )
Laurent Aimar's avatar
Laurent Aimar committed
802
        {
803
            int di = h->mb.b_transform_8x8 ? 4 : 1;
804
            for( i = 0; i < 16; i += di )
Laurent Aimar's avatar
Laurent Aimar committed
805 806
            {
                const int i_pred = x264_mb_predict_intra4x4_mode( h, i );
807
                const int i_mode = x264_mb_pred_mode4x4_fix( h->mb.cache.intra4x4_pred_mode[x264_scan8[i]] );
808
                x264_cabac_mb_intra4x4_pred_mode( cb, i_pred, i_mode );
Laurent Aimar's avatar
Laurent Aimar committed
809 810
            }
        }
811

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

        /* ref 0 */
852
        if( h->mb.pic.i_fref[0] > 1 )
Laurent Aimar's avatar
Laurent Aimar committed
853
        {
854 855 856 857
            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
858 859
        }

860
        for( i = 0; i < 4; i++ )
861
            x264_cabac_mb8x8_mvd( h, cb, i );
862 863 864 865
    }
    else if( i_mb_type == B_8x8 )
    {
        /* sub mb type */
866 867
        for( i = 0; i < 4; i++ )
            x264_cabac_mb_sub_b_partition( cb, h->mb.i_sub_partition[i] );
868 869

        /* ref */
870
        if( h->mb.pic.i_fref[0] > 1 )
871
            for( i = 0; i < 4; i++ )
872 873 874 875 876 877 878
                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 )
            for( i = 0; i < 4; i++ )
                if( x264_mb_partition_listX_table[1][ h->mb.i_sub_partition[i] ] )
                    x264_cabac_mb_ref( h, cb, 1, 4*i );
879

880
        for( i = 0; i < 4; i++ )
881 882 883
            if( x264_mb_partition_listX_table[0][ h->mb.i_sub_partition[i] ] )
                x264_cabac_mb_mvd( h, cb, 0, 4*i, 2, 2 );

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

925
#if !RDO_SKIP_BS
926
    i_mb_pos_tex = x264_cabac_pos( cb );
927
    h->stat.frame.i_mv_bits += i_mb_pos_tex - i_mb_pos_start;
928
#endif
929

Laurent Aimar's avatar
Laurent Aimar committed
930 931
    if( i_mb_type != I_16x16 )
    {
932 933
        x264_cabac_mb_cbp_luma( h, cb );
        x264_cabac_mb_cbp_chroma( h, cb );
Laurent Aimar's avatar
Laurent Aimar committed
934 935
    }

936
    if( x264_mb_transform_8x8_allowed( h ) && h->mb.i_cbp_luma )
937
    {
938
        x264_cabac_mb_transform_size( h, cb );
939 940
    }

Laurent Aimar's avatar
Laurent Aimar committed
941 942
    if( h->mb.i_cbp_luma > 0 || h->mb.i_cbp_chroma > 0 || i_mb_type == I_16x16 )
    {
Fiona Glaser's avatar
Fiona Glaser committed
943
        const int b_intra = IS_INTRA( i_mb_type );
944
        x264_cabac_mb_qp_delta( h, cb );
Laurent Aimar's avatar
Laurent Aimar committed
945 946 947 948 949

        /* write residual */
        if( i_mb_type == I_16x16 )
        {
            /* DC Luma */
950
            block_residual_write_cabac_cbf( h, cb, DCT_LUMA_DC, 24, h->dct.luma16x16_dc, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
951

952
            /* AC Luma */
Laurent Aimar's avatar
Laurent Aimar committed
953 954
            if( h->mb.i_cbp_luma != 0 )
                for( i = 0; i < 16; i++ )
955
                    block_residual_write_cabac_cbf( h, cb, DCT_LUMA_AC, i, h->dct.luma4x4[i]+1, 1 );