cabac.c 38.7 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 40
    }
    else if( i_mb_type == I_PCM )
    {
41
        x264_cabac_encode_decision_noup( cb, ctx0, 1 );
42
        x264_cabac_encode_flush( h, cb );
Loren Merritt's avatar
Loren Merritt committed
43 44 45
    }
    else
    {
46 47
        int i_pred = x264_mb_pred_mode16x16_fix[h->mb.i_intra16x16_pred_mode];

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

51
        x264_cabac_encode_decision_noup( cb, ctx1, !!h->mb.i_cbp_luma );
Loren Merritt's avatar
Loren Merritt committed
52 53
        if( h->mb.i_cbp_chroma == 0 )
        {
54
            x264_cabac_encode_decision_noup( cb, ctx2, 0 );
Loren Merritt's avatar
Loren Merritt committed
55 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 81 82
        {
            ctx++;
        }
Loren Merritt's avatar
Loren Merritt committed
83
        if( h->mb.i_mb_type_top >= 0 && h->mb.i_mb_type_top != I_4x4 )
Laurent Aimar's avatar
Laurent Aimar committed
84 85 86 87
        {
            ctx++;
        }

88
        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
89 90 91 92 93 94 95 96
    }
    else if( h->sh.i_type == SLICE_TYPE_P )
    {
        /* prefix: 14, suffix: 17 */
        if( i_mb_type == P_L0 )
        {
            if( h->mb.i_partition == D_16x16 )
            {
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, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
100 101 102
            }
            else if( h->mb.i_partition == D_16x8 )
            {
103 104 105
                x264_cabac_encode_decision_noup( cb, 14, 0 );
                x264_cabac_encode_decision_noup( cb, 15, 1 );
                x264_cabac_encode_decision_noup( cb, 17, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
106 107 108
            }
            else if( h->mb.i_partition == D_8x16 )
            {
109 110 111
                x264_cabac_encode_decision_noup( cb, 14, 0 );
                x264_cabac_encode_decision_noup( cb, 15, 1 );
                x264_cabac_encode_decision_noup( cb, 17, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
112 113 114 115
            }
        }
        else if( i_mb_type == P_8x8 )
        {
116 117 118
            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
119
        }
Loren Merritt's avatar
Loren Merritt committed
120
        else /* intra */
Laurent Aimar's avatar
Laurent Aimar committed
121 122
        {
            /* prefix */
123
            x264_cabac_encode_decision_noup( cb, 14, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
124 125

            /* suffix */
126
            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
127 128 129 130 131
        }
    }
    else if( h->sh.i_type == SLICE_TYPE_B )
    {
        int ctx = 0;
Loren Merritt's avatar
Loren Merritt committed
132
        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
133 134 135
        {
            ctx++;
        }
Loren Merritt's avatar
Loren Merritt committed
136
        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
137 138 139 140 141 142
        {
            ctx++;
        }

        if( i_mb_type == B_DIRECT )
        {
143
            x264_cabac_encode_decision_noup( cb, 27+ctx, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
144 145 146
        }
        else if( i_mb_type == B_8x8 )
        {
147 148 149
            x264_cabac_encode_decision_noup( cb, 27+ctx, 1 );
            x264_cabac_encode_decision_noup( cb, 27+3,   1 );
            x264_cabac_encode_decision_noup( cb, 27+4,   1 );
150 151
            x264_cabac_encode_decision( cb, 27+5,   1 );
            x264_cabac_encode_decision( cb, 27+5,   1 );
152
            x264_cabac_encode_decision_noup( cb, 27+5,   1 );
Laurent Aimar's avatar
Laurent Aimar committed
153 154 155 156
        }
        else if( IS_INTRA( i_mb_type ) )
        {
            /* prefix */
157 158 159
            x264_cabac_encode_decision_noup( cb, 27+ctx, 1 );
            x264_cabac_encode_decision_noup( cb, 27+3,   1 );
            x264_cabac_encode_decision_noup( cb, 27+4,   1 );
160 161 162
            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
163

Loren Merritt's avatar
Loren Merritt committed
164
            /* suffix */
165
            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
166 167 168
        }
        else
        {
169
            static const int i_mb_len[9*3] =
Laurent Aimar's avatar
Laurent Aimar committed
170
            {
171 172 173 174 175 176 177 178 179
                6, 6, 3,    /* L0 L0 */
                6, 6, 0,    /* L0 L1 */
                7, 7, 0,    /* L0 BI */
                6, 6, 0,    /* L1 L0 */
                6, 6, 3,    /* L1 L1 */
                7, 7, 0,    /* L1 BI */
                7, 7, 0,    /* BI L0 */
                7, 7, 0,    /* BI L1 */
                7, 7, 6,    /* BI BI */
Laurent Aimar's avatar
Laurent Aimar committed
180
            };
181
            static const int i_mb_bits[9*3][7] =
Laurent Aimar's avatar
Laurent Aimar committed
182
            {
183
                { 1,1,0,0,0,1   }, { 1,1,0,0,1,0,  }, { 1,0,0 },       /* L0 L0 */
Loren Merritt's avatar
Loren Merritt committed
184 185 186
                { 1,1,0,1,0,1   }, { 1,1,0,1,1,0   }, {0},             /* L0 L1 */
                { 1,1,1,0,0,0,0 }, { 1,1,1,0,0,0,1 }, {0},             /* L0 BI */
                { 1,1,0,1,1,1   }, { 1,1,1,1,1,0   }, {0},             /* L1 L0 */
187
                { 1,1,0,0,1,1   }, { 1,1,0,1,0,0   }, { 1,0,1 },       /* L1 L1 */
Loren Merritt's avatar
Loren Merritt committed
188 189 190
                { 1,1,1,0,0,1,0 }, { 1,1,1,0,0,1,1 }, {0},             /* L1 BI */
                { 1,1,1,0,1,0,0 }, { 1,1,1,0,1,0,1 }, {0},             /* BI L0 */
                { 1,1,1,0,1,1,0 }, { 1,1,1,0,1,1,1 }, {0},             /* BI L1 */
191
                { 1,1,1,1,0,0,0 }, { 1,1,1,1,0,0,1 }, { 1,1,0,0,0,0 }, /* BI BI */
Laurent Aimar's avatar
Laurent Aimar committed
192 193
            };

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

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

210
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
211 212 213 214
{
    if( i_pred == i_mode )
    {
        /* b_prev_intra4x4_pred_mode */
215
        x264_cabac_encode_decision( cb, 68, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
216 217 218 219
    }
    else
    {
        /* b_prev_intra4x4_pred_mode */
220
        x264_cabac_encode_decision( cb, 68, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
221 222 223 224
        if( i_mode > i_pred  )
        {
            i_mode--;
        }
225 226 227
        x264_cabac_encode_decision( cb, 69, (i_mode     )&0x01 );
        x264_cabac_encode_decision( cb, 69, (i_mode >> 1)&0x01 );
        x264_cabac_encode_decision( cb, 69, (i_mode >> 2)&0x01 );
Laurent Aimar's avatar
Laurent Aimar committed
228 229
    }
}
230

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

    /* No need to test for I4x4 or I_16x16 as cache_save handle that */
Loren Merritt's avatar
Loren Merritt committed
237
    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
238 239 240
    {
        ctx++;
    }
241
    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
242 243 244 245
    {
        ctx++;
    }

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

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

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

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

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

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

        ctx = 4;
        if( cbp_a == 2 ) ctx++;
        if( cbp_b == 2 ) ctx += 2;
299
        x264_cabac_encode_decision_noup( cb, 77 + ctx, h->mb.i_cbp_chroma > 1 );
Laurent Aimar's avatar
Laurent Aimar committed
300 301 302
    }
}

303
static void x264_cabac_mb_qp_delta( x264_t *h, x264_cabac_t *cb )
Laurent Aimar's avatar
Laurent Aimar committed
304
{
305
    int i_mbn_xy = h->mb.i_mb_prev_xy;
306
    int i_dqp = h->mb.i_qp - h->mb.i_last_qp;
Laurent Aimar's avatar
Laurent Aimar committed
307 308
    int ctx;

309 310 311
    /* 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] )
    {
312
#if !RDO_SKIP_BS
313 314 315 316 317
        h->mb.i_qp = h->mb.i_last_qp;
#endif
        i_dqp = 0;
    }

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

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

343
#if !RDO_SKIP_BS
Laurent Aimar's avatar
Laurent Aimar committed
344 345
void x264_cabac_mb_skip( x264_t *h, int b_skip )
{
Loren Merritt's avatar
Loren Merritt committed
346 347 348
    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
349
    x264_cabac_encode_decision( &h->cabac, ctx, b_skip );
Laurent Aimar's avatar
Laurent Aimar committed
350
}
Loren Merritt's avatar
Loren Merritt committed
351
#endif
Laurent Aimar's avatar
Laurent Aimar committed
352

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

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

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

421
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
422 423 424 425 426 427 428
{
    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;

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

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

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

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

457 458 459
    if( i_abs == 0 )
        x264_cabac_encode_decision( cb, ctxbase + ctx, 0 );
    else if( i_abs < 9 )
Laurent Aimar's avatar
Laurent Aimar committed
460
    {
461
        x264_cabac_encode_decision( cb, ctxbase + ctx, 1 );
462
#if RDO_SKIP_BS
463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
        if( i_abs > 4 )
        {
            for( i = 1; i < 4; i++ )
                x264_cabac_encode_decision( cb, ctxbase + ctxes[i], 1 );
            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
#endif
        {
            for( i = 1; i < i_abs; i++ )
                x264_cabac_encode_decision( cb, ctxbase + ctxes[i], 1 );
            x264_cabac_encode_decision( cb, ctxbase + ctxes[i_abs], 0 );
            x264_cabac_encode_bypass( cb, mvd < 0 );
        }
Laurent Aimar's avatar
Laurent Aimar committed
478
    }
479
    else
480 481
    {
        x264_cabac_encode_decision( cb, ctxbase + ctx, 1 );
482
#if RDO_SKIP_BS
483 484 485 486 487 488 489 490
        for( i = 1; i < 4; i++ )
            x264_cabac_encode_decision( cb, ctxbase + ctxes[i], 1 );
        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 );
#else
        for( i = 1; i < 9; i++ )
            x264_cabac_encode_decision( cb, ctxbase + ctxes[i], 1 );
491
        x264_cabac_encode_ue_bypass( cb, 3, i_abs - 9 );
Loren Merritt's avatar
Loren Merritt committed
492
        x264_cabac_encode_bypass( cb, mvd < 0 );
493 494
#endif
    }
Laurent Aimar's avatar
Laurent Aimar committed
495 496
}

497
static inline void x264_cabac_mb_mvd( x264_t *h, x264_cabac_t *cb, int i_list, int idx, int width, int height )
Laurent Aimar's avatar
Laurent Aimar committed
498
{
499
    DECLARE_ALIGNED_4( int16_t mvp[2] );
Laurent Aimar's avatar
Laurent Aimar committed
500 501 502 503 504 505 506 507
    int mdx, mdy;

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

    /* encode */
508 509
    x264_cabac_mb_mvd_cpn( h, cb, i_list, idx, 0, mdx );
    x264_cabac_mb_mvd_cpn( h, cb, i_list, idx, 1, mdy );
Laurent Aimar's avatar
Laurent Aimar committed
510 511

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

515
static inline void x264_cabac_mb8x8_mvd( x264_t *h, x264_cabac_t *cb, int i_list, int i )
516
{
517 518
    if( !x264_mb_partition_listX_table[i_list][ h->mb.i_sub_partition[i] ] )
        return;
519

520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546
    switch( h->mb.i_sub_partition[i] )
    {
        case D_L0_8x8:
        case D_L1_8x8:
        case D_BI_8x8:
            x264_cabac_mb_mvd( h, cb, i_list, 4*i, 2, 2 );
            break;
        case D_L0_8x4:
        case D_L1_8x4:
        case D_BI_8x4:
            x264_cabac_mb_mvd( h, cb, i_list, 4*i+0, 2, 1 );
            x264_cabac_mb_mvd( h, cb, i_list, 4*i+2, 2, 1 );
            break;
        case D_L0_4x8:
        case D_L1_4x8:
        case D_BI_4x8:
            x264_cabac_mb_mvd( h, cb, i_list, 4*i+0, 1, 2 );
            x264_cabac_mb_mvd( h, cb, i_list, 4*i+1, 1, 2 );
            break;
        case D_L0_4x4:
        case D_L1_4x4:
        case D_BI_4x4:
            x264_cabac_mb_mvd( h, cb, i_list, 4*i+0, 1, 1 );
            x264_cabac_mb_mvd( h, cb, i_list, 4*i+1, 1, 1 );
            x264_cabac_mb_mvd( h, cb, i_list, 4*i+2, 1, 1 );
            x264_cabac_mb_mvd( h, cb, i_list, 4*i+3, 1, 1 );
            break;
547 548 549
    }
}

Laurent Aimar's avatar
Laurent Aimar committed
550 551
static int x264_cabac_mb_cbf_ctxidxinc( x264_t *h, int i_cat, int i_idx )
{
Loren Merritt's avatar
Loren Merritt committed
552 553 554 555 556 557 558 559
    /* i_ctxBlockCat: 0-> DC 16x16  i_idx = 0
     *                1-> AC 16x16  i_idx = luma4x4idx
     *                2-> Luma4x4   i_idx = luma4x4idx
     *                3-> DC Chroma i_idx = iCbCr
     *                4-> AC Chroma i_idx = 4 * iCbCr + chroma4x4idx
     *                5-> Luma8x8   i_idx = luma8x8idx
     */

Laurent Aimar's avatar
Laurent Aimar committed
560 561
    int i_mba_xy = -1;
    int i_mbb_xy = -1;
Loren Merritt's avatar
Loren Merritt committed
562 563
    int i_nza = 0;
    int i_nzb = 0;
Laurent Aimar's avatar
Laurent Aimar committed
564

565
    switch( i_cat )
Laurent Aimar's avatar
Laurent Aimar committed
566
    {
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598
        case DCT_LUMA_DC:
            if( h->mb.i_neighbour & MB_LEFT )
            {
                i_mba_xy = h->mb.i_mb_xy - 1;
                i_nza = h->mb.cbp[i_mba_xy] & 0x100;
            }
            if( h->mb.i_neighbour & MB_TOP )
            {
                i_mbb_xy = h->mb.i_mb_top_xy;
                i_nzb = h->mb.cbp[i_mbb_xy] & 0x100;
            }
            break;
        case DCT_LUMA_AC:
        case DCT_LUMA_4x4:
            if( i_idx & ~10 ) // block_idx_x > 0
                i_mba_xy = h->mb.i_mb_xy;
            else if( h->mb.i_neighbour & MB_LEFT )
                i_mba_xy = h->mb.i_mb_xy - 1;

            if( i_idx & ~5 ) // block_idx_y > 0
                i_mbb_xy = h->mb.i_mb_xy;
            else if( h->mb.i_neighbour & MB_TOP )
                i_mbb_xy = h->mb.i_mb_top_xy;

            /* no need to test for skip/pcm */
            if( i_mba_xy >= 0 )
                i_nza = h->mb.cache.non_zero_count[x264_scan8[i_idx] - 1];
            if( i_mbb_xy >= 0 )
                i_nzb = h->mb.cache.non_zero_count[x264_scan8[i_idx] - 8];
            break;
        case DCT_CHROMA_DC:
            /* no need to test skip/pcm */
599
            i_idx -= 25;
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
            if( h->mb.i_neighbour & MB_LEFT )
            {
                i_mba_xy = h->mb.i_mb_xy - 1;
                i_nza = h->mb.cbp[i_mba_xy] & (0x200 << i_idx);
            }
            if( h->mb.i_neighbour & MB_TOP )
            {
                i_mbb_xy = h->mb.i_mb_top_xy;
                i_nzb = h->mb.cbp[i_mbb_xy] & (0x200 << i_idx);
            }
            break;
        case DCT_CHROMA_AC:
            if( i_idx & 1 )
                i_mba_xy = h->mb.i_mb_xy;
            else if( h->mb.i_neighbour & MB_LEFT )
                i_mba_xy = h->mb.i_mb_xy - 1;

            if( i_idx & 2 )
                i_mbb_xy = h->mb.i_mb_xy;
            else if( h->mb.i_neighbour & MB_TOP )
                i_mbb_xy = h->mb.i_mb_top_xy;

            /* no need to test skip/pcm */
            if( i_mba_xy >= 0 )
                i_nza = h->mb.cache.non_zero_count[x264_scan8[i_idx] - 1];
            if( i_mbb_xy >= 0 )
                i_nzb = h->mb.cache.non_zero_count[x264_scan8[i_idx] - 8];
Laurent Aimar's avatar
Laurent Aimar committed
627 628
    }

Loren Merritt's avatar
Loren Merritt committed
629
    if( IS_INTRA( h->mb.i_type ) )
Laurent Aimar's avatar
Laurent Aimar committed
630
    {
Loren Merritt's avatar
Loren Merritt committed
631 632
        i_nza |= i_mba_xy < 0;
        i_nzb |= i_mbb_xy < 0;
Laurent Aimar's avatar
Laurent Aimar committed
633 634
    }

Loren Merritt's avatar
Loren Merritt committed
635
    return 4*i_cat + 2*!!i_nzb + !!i_nza;
Laurent Aimar's avatar
Laurent Aimar committed
636 637 638
}


Fiona Glaser's avatar
Fiona Glaser committed
639
static const uint16_t significant_coeff_flag_offset[2][6] = {
640 641 642
    { 105, 120, 134, 149, 152, 402 },
    { 277, 292, 306, 321, 324, 436 }
};
Fiona Glaser's avatar
Fiona Glaser committed
643
static const uint16_t last_coeff_flag_offset[2][6] = {
644 645 646
    { 166, 181, 195, 210, 213, 417 },
    { 338, 353, 367, 382, 385, 451 }
};
Fiona Glaser's avatar
Fiona Glaser committed
647
static const uint16_t coeff_abs_level_m1_offset[6] =
648
    { 227, 237, 247, 257, 266, 426 };
Fiona Glaser's avatar
Fiona Glaser committed
649
static const uint8_t significant_coeff_flag_offset_8x8[2][63] =
650
{{
Loren Merritt's avatar
Loren Merritt committed
651 652 653 654
    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
655 656 657 658 659 660
},{
    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
661
static const uint8_t last_coeff_flag_offset_8x8[63] = {
Loren Merritt's avatar
Loren Merritt committed
662 663 664 665 666
    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
667

668 669 670 671 672 673
// 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
674
static const uint8_t coeff_abs_level_transition[2][8] = {
675 676 677 678 679
/* update node ctx after coding a level=1 */
    { 1, 2, 3, 3, 4, 5, 6, 7 },
/* update node ctx after coding a level>1 */
    { 4, 4, 4, 4, 5, 6, 7, 7 }
};
Loren Merritt's avatar
Loren Merritt committed
680

681
static void block_residual_write_cabac( x264_t *h, x264_cabac_t *cb, int i_ctxBlockCat, int i_idx, int16_t *l, int i_count )
Laurent Aimar's avatar
Laurent Aimar committed
682
{
683 684
    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];
685
    const int i_ctx_level = coeff_abs_level_m1_offset[i_ctxBlockCat];
686
    const uint8_t *significant_coeff_flag_offset = significant_coeff_flag_offset_8x8[h->mb.b_interlaced];
687

688
    int i_coeff_abs_m1[64];
689
    int i_coeff_sign[64];
Laurent Aimar's avatar
Laurent Aimar committed
690
    int i_coeff = 0;
691
    int i_last;
692
    int i_sigmap_size;
693
    int node_ctx = 0;
694
    int i;
Laurent Aimar's avatar
Laurent Aimar committed
695

696
    if( i_count != 64 )
Laurent Aimar's avatar
Laurent Aimar committed
697
    {
698
        /* coded block flag */
Fiona Glaser's avatar
Fiona Glaser committed
699
        int ctx = 85 + x264_cabac_mb_cbf_ctxidxinc( h, i_ctxBlockCat, i_idx );
700
        if( h->mb.cache.non_zero_count[x264_scan8[i_idx]] )
Fiona Glaser's avatar
Fiona Glaser committed
701 702 703 704
            x264_cabac_encode_decision( cb, ctx, 1 );
        else
        {
            x264_cabac_encode_decision( cb, ctx, 0 );
705
            return;
Fiona Glaser's avatar
Fiona Glaser committed
706
        }
Laurent Aimar's avatar
Laurent Aimar committed
707 708
    }

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

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

713 714 715 716 717 718 719
#define WRITE_SIGMAP( l8x8 )\
    for( i = 0; i < i_sigmap_size; i++ )\
    {\
        if( l[i] )\
        {\
            i_coeff_abs_m1[i_coeff] = abs(l[i]) - 1;\
            if( !RDO_SKIP_BS )\
720
                i_coeff_sign[i_coeff] = l[i] < 0;\
721 722 723 724 725 726
            i_coeff++;\
            x264_cabac_encode_decision( cb, i_ctx_sig + (l8x8 ? significant_coeff_flag_offset[i] : i), 1 );\
            x264_cabac_encode_decision( cb, i_ctx_last + (l8x8 ? last_coeff_flag_offset_8x8[i] : i), i == i_last );\
        }\
        else\
            x264_cabac_encode_decision( cb, i_ctx_sig + (l8x8 ? significant_coeff_flag_offset[i] : i), 0 );\
Fiona Glaser's avatar
Fiona Glaser committed
727 728
    }

729 730 731 732 733
    if( i_ctxBlockCat == DCT_LUMA_8x8 )
        WRITE_SIGMAP( 1 )
    else
        WRITE_SIGMAP( 0 )

Fiona Glaser's avatar
Fiona Glaser committed
734 735 736
    if( i == i_last )
    {
        i_coeff_abs_m1[i_coeff] = abs(l[i]) - 1;
737
#if !RDO_SKIP_BS
Fiona Glaser's avatar
Fiona Glaser committed
738 739 740
        i_coeff_sign[i_coeff]   = l[i] < 0;
#endif
        i_coeff++;
Laurent Aimar's avatar
Laurent Aimar committed
741 742
    }

743
    do
Laurent Aimar's avatar
Laurent Aimar committed
744
    {
Fiona Glaser's avatar
Fiona Glaser committed
745
        int i_prefix, ctx;
746
        i_coeff--;
Fiona Glaser's avatar
Fiona Glaser committed
747

Laurent Aimar's avatar
Laurent Aimar committed
748
        /* write coeff_abs - 1 */
Fiona Glaser's avatar
Fiona Glaser committed
749 750
        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
751

Fiona Glaser's avatar
Fiona Glaser committed
752
        if( i_prefix )
Laurent Aimar's avatar
Laurent Aimar committed
753
        {
Fiona Glaser's avatar
Fiona Glaser committed
754 755
            x264_cabac_encode_decision( cb, ctx, 1 );
            ctx = coeff_abs_levelgt1_ctx[node_ctx] + i_ctx_level;
756
#if RDO_SKIP_BS
757 758
            cb->f8_bits_encoded += cabac_size_unary[i_prefix][cb->state[ctx]];
            cb->state[ctx] = cabac_transition_unary[i_prefix][cb->state[ctx]];
759
#else
760
            for( i = 0; i < i_prefix - 1; i++ )
Fiona Glaser's avatar
Fiona Glaser committed
761
                x264_cabac_encode_decision( cb, ctx, 1 );
Laurent Aimar's avatar
Laurent Aimar committed
762
            if( i_prefix < 14 )
Fiona Glaser's avatar
Fiona Glaser committed
763
                x264_cabac_encode_decision( cb, ctx, 0 );
764 765
#endif
            if( i_prefix >= 14 )
766
                x264_cabac_encode_ue_bypass( cb, 0, i_coeff_abs_m1[i_coeff] - 14 );
Laurent Aimar's avatar
Laurent Aimar committed
767

768
            node_ctx = coeff_abs_level_transition[1][node_ctx];
Laurent Aimar's avatar
Laurent Aimar committed
769
        }
770
        else
Fiona Glaser's avatar
Fiona Glaser committed
771 772
        {
            x264_cabac_encode_decision( cb, ctx, 0 );
773
            node_ctx = coeff_abs_level_transition[0][node_ctx];
774
#if RDO_SKIP_BS
Fiona Glaser's avatar
Fiona Glaser committed
775
            x264_cabac_encode_bypass( cb, 0 ); // sign
776
#endif
Fiona Glaser's avatar
Fiona Glaser committed
777 778
        }

779
#if !RDO_SKIP_BS
780
        x264_cabac_encode_bypass( cb, i_coeff_sign[i_coeff] );
Fiona Glaser's avatar
Fiona Glaser committed
781
#endif
782
    } while( i_coeff > 0 );
Laurent Aimar's avatar
Laurent Aimar committed
783 784 785 786
}



787
void x264_macroblock_write_cabac( x264_t *h, x264_cabac_t *cb )
Laurent Aimar's avatar
Laurent Aimar committed
788 789
{
    const int i_mb_type = h->mb.i_type;
790
    int i_list;
Laurent Aimar's avatar
Laurent Aimar committed
791 792
    int i;

793
#if !RDO_SKIP_BS
794 795 796 797
    const int i_mb_pos_start = x264_cabac_pos( cb );
    int       i_mb_pos_tex;
#endif

Laurent Aimar's avatar
Laurent Aimar committed
798
    /* Write the MB type */
799
    x264_cabac_mb_type( h, cb );
Laurent Aimar's avatar
Laurent Aimar committed
800

801
#if !RDO_SKIP_BS
Laurent Aimar's avatar
Laurent Aimar committed
802 803
    if( i_mb_type == I_PCM )
    {
804
        i_mb_pos_tex = x264_cabac_pos( cb );
805
        h->stat.frame.i_mv_bits += i_mb_pos_tex - i_mb_pos_start;
806 807 808

        memcpy( cb->p, h->mb.pic.p_fenc[0], 256 );
        cb->p += 256;
809
        for( i = 0; i < 8; i++ )
810 811
            memcpy( cb->p + i*8, h->mb.pic.p_fenc[1] + i*FENC_STRIDE, 8 );
        cb->p += 64;
812
        for( i = 0; i < 8; i++ )
813 814 815 816 817 818 819 820 821 822 823 824 825
            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 );

826
        h->stat.frame.i_tex_bits += x264_cabac_pos( cb ) - i_mb_pos_tex;
Laurent Aimar's avatar
Laurent Aimar committed
827 828
        return;
    }
829
#endif
Laurent Aimar's avatar
Laurent Aimar committed
830 831 832

    if( IS_INTRA( i_mb_type ) )
    {
833
        if( h->pps->b_transform_8x8_mode && i_mb_type != I_16x16 )
834
            x264_cabac_mb_transform_size( h, cb );
835 836

        if( i_mb_type != I_16x16 )
Laurent Aimar's avatar
Laurent Aimar committed
837
        {
838 839
            int di = (i_mb_type == I_8x8) ? 4 : 1;
            for( i = 0; i < 16; i += di )
Laurent Aimar's avatar
Laurent Aimar committed
840 841
            {
                const int i_pred = x264_mb_predict_intra4x4_mode( h, i );
842
                const int i_mode = x264_mb_pred_mode4x4_fix( h->mb.cache.intra4x4_pred_mode[x264_scan8[i]] );
843
                x264_cabac_mb_intra4x4_pred_mode( cb, i_pred, i_mode );
Laurent Aimar's avatar
Laurent Aimar committed
844 845
            }
        }
846

847
        x264_cabac_mb_intra_chroma_pred_mode( h, cb );
Laurent Aimar's avatar
Laurent Aimar committed
848 849 850 851 852
    }
    else if( i_mb_type == P_L0 )
    {
        if( h->mb.i_partition == D_16x16 )
        {
853
            if( h->mb.pic.i_fref[0] > 1 )
Laurent Aimar's avatar
Laurent Aimar committed
854
            {
855
                x264_cabac_mb_ref( h, cb, 0, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
856
            }
857
            x264_cabac_mb_mvd( h, cb, 0, 0, 4, 4 );
Laurent Aimar's avatar
Laurent Aimar committed
858 859 860
        }
        else if( h->mb.i_partition == D_16x8 )
        {
861
            if( h->mb.pic.i_fref[0] > 1 )
Laurent Aimar's avatar
Laurent Aimar committed
862
            {
863 864
                x264_cabac_mb_ref( h, cb, 0, 0 );
                x264_cabac_mb_ref( h, cb, 0, 8 );
Laurent Aimar's avatar
Laurent Aimar committed
865
            }
866 867
            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
868 869 870
        }
        else if( h->mb.i_partition == D_8x16 )
        {
871
            if( h->mb.pic.i_fref[0] > 1 )
Laurent Aimar's avatar
Laurent Aimar committed
872
            {
873 874
                x264_cabac_mb_ref( h, cb, 0, 0 );
                x264_cabac_mb_ref( h, cb, 0, 4 );
Laurent Aimar's avatar
Laurent Aimar committed
875
            }
876 877
            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
878 879 880 881 882
        }
    }
    else if( i_mb_type == P_8x8 )
    {
        /* sub mb type */
883 884 885 886
        x264_cabac_mb_sub_p_partition( cb, h->mb.i_sub_partition[0] );
        x264_cabac_mb_sub_p_partition( cb, h->mb.i_sub_partition[1] );
        x264_cabac_mb_sub_p_partition( cb, h->mb.i_sub_partition[2] );
        x264_cabac_mb_sub_p_partition( cb, h->mb.i_sub_partition[3] );
Laurent Aimar's avatar
Laurent Aimar committed
887 888

        /* ref 0 */
889
        if( h->mb.pic.i_fref[0] > 1 )
Laurent Aimar's avatar
Laurent Aimar committed
890
        {
891 892 893 894
            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
895 896
        }

897 898
        for( i = 0; i < 4; i++ )
            x264_cabac_mb8x8_mvd( h, cb, 0, i );
899 900 901 902
    }
    else if( i_mb_type == B_8x8 )
    {
        /* sub mb type */
903 904 905 906
        x264_cabac_mb_sub_b_partition( cb, h->mb.i_sub_partition[0] );
        x264_cabac_mb_sub_b_partition( cb, h->mb.i_sub_partition[1] );
        x264_cabac_mb_sub_b_partition( cb, h->mb.i_sub_partition[2] );
        x264_cabac_mb_sub_b_partition( cb, h->mb.i_sub_partition[3] );
907 908 909

        /* ref */
        for( i_list = 0; i_list < 2; i_list++ )
Laurent Aimar's avatar
Laurent Aimar committed
910
        {
911
            if( ( i_list ? h->mb.pic.i_fref[1] : h->mb.pic.i_fref[0] ) == 1 )
912 913
                continue;
            for( i = 0; i < 4; i++ )
914
                if( x264_mb_partition_listX_table[i_list][ h->mb.i_sub_partition[i] ] )
915
                    x264_cabac_mb_ref( h, cb, i_list, 4*i );
Laurent Aimar's avatar
Laurent Aimar committed
916
        }
917

918 919 920 921
        for( i = 0; i < 4; i++ )
            x264_cabac_mb8x8_mvd( h, cb, 0, i );
        for( i = 0; i < 4; i++ )
            x264_cabac_mb8x8_mvd( h, cb, 1, i );
Laurent Aimar's avatar
Laurent Aimar committed
922 923 924 925 926 927 928 929 930 931 932 933 934 935 936
    }
    else if( i_mb_type != B_DIRECT )
    {
        /* All B mode */
        int b_list[2][2];

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

        for( i_list = 0; i_list < 2; i_list++ )
        {
937
            const int i_ref_max = i_list == 0 ? h->mb.pic.i_fref[0] : h->mb.pic.i_fref[1];
Laurent Aimar's avatar
Laurent Aimar committed
938 939 940 941 942

            if( i_ref_max > 1 )
            {
                if( h->mb.i_partition == D_16x16 )
                {
943
                    if( b_list[i_list][0] ) x264_cabac_mb_ref( h, cb, i_list, 0 );
Laurent Aimar's avatar
Laurent Aimar committed
944 945 946
                }
                else if( h->mb.i_partition == D_16x8 )
                {
947 948
                    if( b_list[i_list][0] ) x264_cabac_mb_ref( h, cb, i_list, 0 );
                    if( b_list[i_list][1] ) x264_cabac_mb_ref( h, cb, i_list, 8 );
Laurent Aimar's avatar
Laurent Aimar committed
949 950 951
                }
                else if( h->mb.i_partition == D_8x16 )
                {
952 953
                    if( b_list[i_list][0] ) x264_cabac_mb_ref( h, cb, i_list, 0 );
                    if( b_list[i_list][1] ) x264_cabac_mb_ref( h, cb, i_list, 4 );
Laurent Aimar's avatar
Laurent Aimar committed
954 955 956 957 958 959 960
                }
            }
        }
        for( i_list = 0; i_list < 2; i_list++ )
        {
            if( h->mb.i_partition == D_16x16 )
            {
961
                if( b_list[i_list][0] ) x264_cabac_mb_mvd( h, cb, i_list, 0, 4, 4 );
Laurent Aimar's avatar
Laurent Aimar committed
962 963 964
            }
            else if( h->mb.i_partition == D_16x8 )
            {
965 966
                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
967 968 969
            }
            else if( h->mb.i_partition == D_8x16 )
            {
970 971
                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
972 973 974 975
            }
        }
    }

976
#if !RDO_SKIP_BS
977
    i_mb_pos_tex = x264_cabac_pos( cb );
978
    h->stat.frame.i_mv_bits += i_mb_pos_tex - i_mb_pos_start;
979
#endif
980

Laurent Aimar's avatar
Laurent Aimar committed
981 982
    if( i_mb_type != I_16x16 )
    {
983 984
        x264_cabac_mb_cbp_luma( h, cb );
        x264_cabac_mb_cbp_chroma( h, cb );
Laurent Aimar's avatar
Laurent Aimar committed
985 986
    }

987
    if( x264_mb_transform_8x8_allowed( h ) && h->mb.i_cbp_luma )
988
    {
989
        x264_cabac_mb_transform_size( h, cb );
990 991
    }

Laurent Aimar's avatar
Laurent Aimar committed
992 993
    if( h->mb.i_cbp_luma > 0 || h->mb.i_cbp_chroma > 0 || i_mb_type == I_16x16 )
    {
994
        x264_cabac_mb_qp_delta( h, cb );
Laurent Aimar's avatar
Laurent Aimar committed
995 996 997 998 999

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

1002
            /* AC Luma */
Laurent Aimar's avatar
Laurent Aimar committed
1003 1004
            if( h->mb.i_cbp_luma != 0 )
                for( i = 0; i < 16; i++ )
1005
                    block_residual_write_cabac( h, cb, DCT_LUMA_AC, i, h->dct.luma4x4[i]+1, 15 );
1006 1007 1008 1009 1010
        }
        else if( h->mb.b_transform_8x8 )
        {
            for( i = 0; i < 4; i++ )
                if( h->mb.i_cbp_luma & ( 1 << i ) )
1011
                    block_residual_write_cabac( h, cb, DCT_LUMA_8x8, i, h->dct.luma8x8[i], 64 );
Laurent Aimar's avatar
Laurent Aimar committed
1012 1013 1014 1015 1016
        }
        else
        {
            for( i = 0; i < 16; i++ )
                if( h->mb.i_cbp_luma & ( 1 << ( i / 4 ) ) )
1017
                    block_residual_write_cabac( h, cb, DCT_LUMA_4x4, i, h->dct.luma4x4[i], 16 );
Laurent Aimar's avatar
Laurent Aimar committed
1018 1019 1020 1021
        }

        if( h->mb.i_cbp_chroma &0x03 )    /* Chroma DC residual present */
        {
1022 1023
            block_residual_write_cabac( h, cb, DCT_CHROMA_DC, 25, h->dct.chroma_dc[0], 4 );
            block_residual_write_cabac( h, cb, DCT_CHROMA_DC, 26, h->dct.chroma_dc[1], 4 );
Laurent Aimar's avatar
Laurent Aimar committed
1024 1025 1026
        }
        if( h->mb.i_cbp_chroma&0x02 ) /* Chroma AC residual present */
        {
Loren Merritt's avatar
Loren Merritt committed
1027
            for( i = 16; i < 24; i++ )
1028
                block_residual_write_cabac( h, cb, DCT_CHROMA_AC, i, h->dct.luma4x4[i]+1, 15 );
Laurent Aimar's avatar
Laurent Aimar committed
1029 1030
        }
    }
1031

1032
#if !RDO_SKIP_BS
1033
    h->stat.frame.i_tex_bits += x264_cabac_pos( cb ) - i_mb_pos_tex;
1034
#endif
Laurent Aimar's avatar
Laurent Aimar committed
1035 1036
}

1037
#if RDO_SKIP_BS
1038 1039 1040
/*****************************************************************************
 * RD only; doesn't generate a valid bitstream
 * doesn't write cbp or chroma dc (I don't know how much this matters)
1041
 * doesn't write ref or subpartition (never varies between calls, so no point in doing so)
1042 1043 1044
 * works on all partition sizes except 16x16
 * for sub8x8, call once per 8x8 block
 *****************************************************************************/
1045
static void x264_partition_size_cabac( x264_t *h, x264_cabac_t *cb, int i8, int i_pixel )
1046 1047
{
    const int i_mb_type = h->mb.i_type;
1048
    int b_8x16 = h->mb.i_partition == D_8x16;
1049 1050 1051 1052 1053
    int j;

    if( i_mb_type == P_8x8 )
        x264_cabac_mb8x8_mvd( h, cb, 0, i8 );
    else