~diresu/blender/blender-command-port

« back to all changes in this revision

Viewing changes to extern/x264/encoder/slicetype.c

  • Committer: theeth
  • Date: 2008-10-14 16:52:04 UTC
  • Revision ID: vcs-imports@canonical.com-20081014165204-r32w2gm6s0osvdhn
copy back trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 * slicetype.c: h264 encoder library
 
3
 *****************************************************************************
 
4
 * Copyright (C) 2005 Loren Merritt
 
5
 *
 
6
 * Authors: Loren Merritt <lorenm@u.washington.edu>
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License as published by
 
10
 * the Free Software Foundation; either version 2 of the License, or
 
11
 * (at your option) any later version.
 
12
 *
 
13
 * This program is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 * GNU General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License
 
19
 * along with this program; if not, write to the Free Software
 
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 
21
 *****************************************************************************/
 
22
 
 
23
#include <math.h>
 
24
#include <limits.h>
 
25
 
 
26
#include "common/common.h"
 
27
#include "common/cpu.h"
 
28
#include "macroblock.h"
 
29
#include "me.h"
 
30
 
 
31
 
 
32
static void x264_lowres_context_init( x264_t *h, x264_mb_analysis_t *a )
 
33
{
 
34
    a->i_qp = 12; // arbitrary, but low because SATD scores are 1/4 normal
 
35
    a->i_lambda = i_qp0_cost_table[ a->i_qp ];
 
36
    x264_mb_analyse_load_costs( h, a );
 
37
    h->mb.i_me_method = X264_MIN( X264_ME_HEX, h->param.analyse.i_me_method ); // maybe dia?
 
38
    h->mb.i_subpel_refine = 4; // 3 should be enough, but not tweaking for speed now
 
39
    h->mb.b_chroma_me = 0;
 
40
}
 
41
 
 
42
int x264_slicetype_mb_cost( x264_t *h, x264_mb_analysis_t *a,
 
43
                            x264_frame_t **frames, int p0, int p1, int b,
 
44
                            int dist_scale_factor )
 
45
{
 
46
    x264_frame_t *fref0 = frames[p0];
 
47
    x264_frame_t *fref1 = frames[p1];
 
48
    x264_frame_t *fenc  = frames[b];
 
49
    const int b_bidir = (b < p1);
 
50
    const int i_mb_x = h->mb.i_mb_x;
 
51
    const int i_mb_y = h->mb.i_mb_y;
 
52
    const int i_mb_stride = h->sps->i_mb_width;
 
53
    const int i_mb_xy = i_mb_x + i_mb_y * i_mb_stride;
 
54
    const int i_stride = fenc->i_stride_lowres;
 
55
    const int i_pel_offset = 8 * ( i_mb_x + i_mb_y * i_stride );
 
56
 
 
57
    DECLARE_ALIGNED( uint8_t, pix1[9*FDEC_STRIDE], 8 );
 
58
    uint8_t *pix2 = pix1+8;
 
59
    x264_me_t m[2];
 
60
    int i_bcost = COST_MAX;
 
61
    int i_cost_bak;
 
62
    int l, i;
 
63
 
 
64
    h->mb.pic.p_fenc[0] = h->mb.pic.fenc_buf;
 
65
    h->mc.copy[PIXEL_8x8]( h->mb.pic.p_fenc[0], FENC_STRIDE, &fenc->lowres[0][i_pel_offset], i_stride, 8 );
 
66
 
 
67
    if( !p0 && !p1 && !b )
 
68
        goto lowres_intra_mb;
 
69
 
 
70
    // no need for h->mb.mv_min[]
 
71
    h->mb.mv_min_fpel[0] = -8*h->mb.i_mb_x - 4;
 
72
    h->mb.mv_max_fpel[0] = 8*( h->sps->i_mb_width - h->mb.i_mb_x - 1 ) + 4;
 
73
    h->mb.mv_min_spel[0] = 4*( h->mb.mv_min_fpel[0] - 8 );
 
74
    h->mb.mv_max_spel[0] = 4*( h->mb.mv_max_fpel[0] + 8 );
 
75
    if( h->mb.i_mb_x <= 1 )
 
76
    {
 
77
        h->mb.mv_min_fpel[1] = -8*h->mb.i_mb_y - 4;
 
78
        h->mb.mv_max_fpel[1] = 8*( h->sps->i_mb_height - h->mb.i_mb_y - 1 ) + 4;
 
79
        h->mb.mv_min_spel[1] = 4*( h->mb.mv_min_fpel[1] - 8 );
 
80
        h->mb.mv_max_spel[1] = 4*( h->mb.mv_max_fpel[1] + 8 );
 
81
    }
 
82
 
 
83
#define LOAD_HPELS_LUMA(dst, src) \
 
84
    { \
 
85
        (dst)[0] = &(src)[0][i_pel_offset]; \
 
86
        (dst)[1] = &(src)[1][i_pel_offset]; \
 
87
        (dst)[2] = &(src)[2][i_pel_offset]; \
 
88
        (dst)[3] = &(src)[3][i_pel_offset]; \
 
89
    }
 
90
#define SAVE_MVS( mv0, mv1 ) \
 
91
    { \
 
92
        fenc->mv[0][i_mb_xy][0] = mv0[0]; \
 
93
        fenc->mv[0][i_mb_xy][1] = mv0[1]; \
 
94
        if( b_bidir ) \
 
95
        { \
 
96
            fenc->mv[1][i_mb_xy][0] = mv1[0]; \
 
97
            fenc->mv[1][i_mb_xy][1] = mv1[1]; \
 
98
        } \
 
99
    }
 
100
#define CLIP_MV( mv ) \
 
101
    { \
 
102
        mv[0] = x264_clip3( mv[0], h->mb.mv_min_spel[0], h->mb.mv_max_spel[0] ); \
 
103
        mv[1] = x264_clip3( mv[1], h->mb.mv_min_spel[1], h->mb.mv_max_spel[1] ); \
 
104
    }
 
105
#define TRY_BIDIR( mv0, mv1, penalty ) \
 
106
    { \
 
107
        int stride2 = 16; \
 
108
        uint8_t *src2; \
 
109
        int i_cost; \
 
110
        h->mc.mc_luma( pix1, 16, m[0].p_fref, m[0].i_stride[0], \
 
111
                       (mv0)[0], (mv0)[1], 8, 8 ); \
 
112
        src2 = h->mc.get_ref( pix2, &stride2, m[1].p_fref, m[1].i_stride[0], \
 
113
                       (mv1)[0], (mv1)[1], 8, 8 ); \
 
114
        h->mc.avg[PIXEL_8x8]( pix1, 16, src2, stride2 ); \
 
115
        i_cost = penalty + h->pixf.mbcmp[PIXEL_8x8]( \
 
116
                           m[0].p_fenc[0], FENC_STRIDE, pix1, 16 ); \
 
117
        if( i_bcost > i_cost ) \
 
118
        { \
 
119
            i_bcost = i_cost; \
 
120
            SAVE_MVS( mv0, mv1 ); \
 
121
        } \
 
122
    }
 
123
 
 
124
    m[0].i_pixel = PIXEL_8x8;
 
125
    m[0].p_cost_mv = a->p_cost_mv;
 
126
    m[0].i_stride[0] = i_stride;
 
127
    m[0].p_fenc[0] = h->mb.pic.p_fenc[0];
 
128
    LOAD_HPELS_LUMA( m[0].p_fref, fref0->lowres );
 
129
 
 
130
    if( b_bidir )
 
131
    {
 
132
        int16_t *mvr = fref1->mv[0][i_mb_xy];
 
133
        int dmv[2][2];
 
134
        int mv0[2] = {0,0};
 
135
 
 
136
        m[1] = m[0];
 
137
        LOAD_HPELS_LUMA( m[1].p_fref, fref1->lowres );
 
138
 
 
139
        dmv[0][0] = ( mvr[0] * dist_scale_factor + 128 ) >> 8;
 
140
        dmv[0][1] = ( mvr[1] * dist_scale_factor + 128 ) >> 8;
 
141
        dmv[1][0] = dmv[0][0] - mvr[0];
 
142
        dmv[1][1] = dmv[0][1] - mvr[1];
 
143
        CLIP_MV( dmv[0] );
 
144
        CLIP_MV( dmv[1] );
 
145
 
 
146
        TRY_BIDIR( dmv[0], dmv[1], 0 );
 
147
        if( dmv[0][0] || dmv[0][1] || dmv[1][0] || dmv[1][1] )
 
148
           TRY_BIDIR( mv0, mv0, 0 );
 
149
//      if( i_bcost < 60 ) // arbitrary threshold
 
150
//          return i_bcost;
 
151
    }
 
152
 
 
153
    i_cost_bak = i_bcost;
 
154
    for( l = 0; l < 1 + b_bidir; l++ )
 
155
    {
 
156
        int mvc[4][2] = {{0}}, i_mvc;
 
157
        int16_t (*fenc_mv)[2] = &fenc->mv[l][i_mb_xy];
 
158
        i_mvc = 0;
 
159
#define MVC(mv) { mvc[i_mvc][0] = mv[0]; mvc[i_mvc][1] = mv[1]; i_mvc++; }
 
160
        if( i_mb_x > 0 )
 
161
            MVC(fenc_mv[-1]);
 
162
        if( i_mb_y > 0 )
 
163
        {
 
164
            MVC(fenc_mv[-i_mb_stride]);
 
165
            if( i_mb_x < h->sps->i_mb_width - 1 )
 
166
                MVC(fenc_mv[-i_mb_stride+1]);
 
167
            if( i_mb_x > 0 )
 
168
                MVC(fenc_mv[-i_mb_stride-1]);
 
169
        }
 
170
#undef MVC
 
171
        m[l].mvp[0] = x264_median( mvc[0][0], mvc[1][0], mvc[2][0] );
 
172
        m[l].mvp[1] = x264_median( mvc[0][1], mvc[1][1], mvc[2][1] );
 
173
 
 
174
        x264_me_search( h, &m[l], mvc, i_mvc );
 
175
 
 
176
        m[l].cost -= 2; // remove mvcost from skip mbs
 
177
        if( m[l].mv[0] || m[l].mv[1] )
 
178
            m[l].cost += 5;
 
179
        i_bcost = X264_MIN( i_bcost, m[l].cost );
 
180
    }
 
181
 
 
182
    if( b_bidir && (m[0].mv[0] || m[0].mv[1] || m[1].mv[0] || m[1].mv[1]) )
 
183
        TRY_BIDIR( m[0].mv, m[1].mv, 5 );
 
184
 
 
185
    if( i_bcost < i_cost_bak )
 
186
        SAVE_MVS( m[0].mv, m[1].mv );
 
187
 
 
188
    //FIXME intra part could be shared across multiple encodings of the frame
 
189
lowres_intra_mb:
 
190
    if( !b_bidir ) // forbid intra-mbs in B-frames, because it's rare and not worth checking
 
191
    {
 
192
        uint8_t *pix = &pix1[8+FDEC_STRIDE - 1];
 
193
        uint8_t *src = &fenc->lowres[0][i_pel_offset - 1];
 
194
        const int intra_penalty = 5;
 
195
        int satds[4], i_icost, b_intra;
 
196
 
 
197
        memcpy( pix-FDEC_STRIDE, src-i_stride, 17 );
 
198
        for( i=0; i<8; i++ )
 
199
            pix[i*FDEC_STRIDE] = src[i*i_stride];
 
200
        pix++;
 
201
 
 
202
        if( h->pixf.intra_satd_x3_8x8c && h->pixf.mbcmp[0] == h->pixf.satd[0] )
 
203
        {
 
204
            h->pixf.intra_satd_x3_8x8c( h->mb.pic.p_fenc[0], pix, satds );
 
205
            h->predict_8x8c[I_PRED_CHROMA_P]( pix );
 
206
            satds[I_PRED_CHROMA_P] =
 
207
                h->pixf.satd[PIXEL_8x8]( pix, FDEC_STRIDE, h->mb.pic.p_fenc[0], FENC_STRIDE );
 
208
        }
 
209
        else
 
210
        {
 
211
            for( i=0; i<4; i++ )
 
212
            {
 
213
                h->predict_8x8c[i]( pix );
 
214
                satds[i] = h->pixf.mbcmp[PIXEL_8x8]( pix, FDEC_STRIDE, h->mb.pic.p_fenc[0], FENC_STRIDE );
 
215
            }
 
216
        }
 
217
        i_icost = X264_MIN4( satds[0], satds[1], satds[2], satds[3] );
 
218
 
 
219
        if( i_icost < i_bcost * 2 )
 
220
        {
 
221
            DECLARE_ALIGNED( uint8_t, edge[33], 8 );
 
222
            x264_predict_8x8_filter( pix, edge, ALL_NEIGHBORS, ALL_NEIGHBORS );
 
223
            for( i=3; i<9; i++ )
 
224
            {
 
225
                int satd;
 
226
                h->predict_8x8[i]( pix, edge );
 
227
                satd = h->pixf.mbcmp[PIXEL_8x8]( pix, FDEC_STRIDE, h->mb.pic.p_fenc[0], FENC_STRIDE );
 
228
                i_icost = X264_MIN( i_icost, satd );
 
229
            }
 
230
        }
 
231
 
 
232
        i_icost += intra_penalty;
 
233
        b_intra = i_icost < i_bcost;
 
234
        if( b_intra )
 
235
            i_bcost = i_icost;
 
236
        if(    i_mb_x > 0 && i_mb_x < h->sps->i_mb_width - 1
 
237
            && i_mb_y > 0 && i_mb_y < h->sps->i_mb_height - 1 )
 
238
        {
 
239
            fenc->i_intra_mbs[b-p0] += b_intra;
 
240
            fenc->i_cost_est[0][0] += i_icost;
 
241
        }
 
242
    }
 
243
 
 
244
    return i_bcost;
 
245
}
 
246
#undef TRY_BIDIR
 
247
#undef SAVE_MVS
 
248
 
 
249
int x264_slicetype_frame_cost( x264_t *h, x264_mb_analysis_t *a,
 
250
                               x264_frame_t **frames, int p0, int p1, int b,
 
251
                               int b_intra_penalty )
 
252
{
 
253
    int i_score = 0;
 
254
 
 
255
    /* Check whether we already evaluated this frame
 
256
     * If we have tried this frame as P, then we have also tried
 
257
     * the preceding frames as B. (is this still true?) */
 
258
    if( frames[b]->i_cost_est[b-p0][p1-b] >= 0 )
 
259
    {
 
260
        i_score = frames[b]->i_cost_est[b-p0][p1-b];
 
261
    }
 
262
    else
 
263
    {
 
264
        int dist_scale_factor = 128;
 
265
        int *row_satd = frames[b]->i_row_satds[b-p0][p1-b];
 
266
 
 
267
        /* Init MVs so that we don't have to check edge conditions when loading predictors. */
 
268
        /* FIXME: not needed every time */
 
269
        memset( frames[b]->mv[0], 0, h->sps->i_mb_height * h->sps->i_mb_width * 2*sizeof(int16_t) );
 
270
        if( b != p1 )
 
271
            memset( frames[b]->mv[1], 0, h->sps->i_mb_height * h->sps->i_mb_width * 2*sizeof(int16_t) );
 
272
 
 
273
        if( b == p1 )
 
274
        {
 
275
            frames[b]->i_intra_mbs[b-p0] = 0;
 
276
            frames[b]->i_cost_est[0][0] = 0;
 
277
        }
 
278
        if( p1 != p0 )
 
279
            dist_scale_factor = ( ((b-p0) << 8) + ((p1-p0) >> 1) ) / (p1-p0);
 
280
 
 
281
        /* the edge mbs seem to reduce the predictive quality of the
 
282
         * whole frame's score, but are needed for a spatial distribution. */
 
283
        if( h->param.rc.i_vbv_buffer_size )
 
284
        {
 
285
            for( h->mb.i_mb_y = 0; h->mb.i_mb_y < h->sps->i_mb_height; h->mb.i_mb_y++ )
 
286
            {
 
287
                row_satd[ h->mb.i_mb_y ] = 0;
 
288
                for( h->mb.i_mb_x = 0; h->mb.i_mb_x < h->sps->i_mb_width; h->mb.i_mb_x++ )
 
289
                {
 
290
                    int i_mb_cost = x264_slicetype_mb_cost( h, a, frames, p0, p1, b, dist_scale_factor );
 
291
                    row_satd[ h->mb.i_mb_y ] += i_mb_cost;
 
292
                    if( h->mb.i_mb_y > 0 && h->mb.i_mb_y < h->sps->i_mb_height - 1 &&
 
293
                        h->mb.i_mb_x > 0 && h->mb.i_mb_x < h->sps->i_mb_width - 1 )
 
294
                    {
 
295
                        i_score += i_mb_cost;
 
296
                    }
 
297
                }
 
298
            }
 
299
        }
 
300
        else
 
301
        {
 
302
            for( h->mb.i_mb_y = 1; h->mb.i_mb_y < h->sps->i_mb_height - 1; h->mb.i_mb_y++ )
 
303
                for( h->mb.i_mb_x = 1; h->mb.i_mb_x < h->sps->i_mb_width - 1; h->mb.i_mb_x++ )
 
304
                    i_score += x264_slicetype_mb_cost( h, a, frames, p0, p1, b, dist_scale_factor );
 
305
        }
 
306
 
 
307
        if( b != p1 )
 
308
            i_score = i_score * 100 / (120 + h->param.i_bframe_bias);
 
309
 
 
310
        frames[b]->i_cost_est[b-p0][p1-b] = i_score;
 
311
//      fprintf( stderr, "frm %d %c(%d,%d): %6d %6d imb:%d  \n", frames[b]->i_frame,
 
312
//               (p1==0?'I':b<p1?'B':'P'), b-p0, p1-b, i_score, frames[b]->i_cost_est[0][0], frames[b]->i_intra_mbs[b-p0] );
 
313
        x264_cpu_restore( h->param.cpu );
 
314
    }
 
315
 
 
316
    if( b_intra_penalty )
 
317
    {
 
318
        // arbitrary penalty for I-blocks after B-frames
 
319
        int nmb = (h->sps->i_mb_width - 2) * (h->sps->i_mb_height - 2);
 
320
        i_score += i_score * frames[b]->i_intra_mbs[b-p0] / (nmb * 8);
 
321
    }
 
322
    return i_score;
 
323
}
 
324
 
 
325
static int scenecut( x264_t *h, x264_frame_t *frame, int pdist )
 
326
{
 
327
    int icost = frame->i_cost_est[0][0];
 
328
    int pcost = frame->i_cost_est[pdist][0];
 
329
    float f_bias;
 
330
    int i_gop_size = frame->i_frame - h->frames.i_last_idr;
 
331
    float f_thresh_max = h->param.i_scenecut_threshold / 100.0;
 
332
    /* magic numbers pulled out of thin air */
 
333
    float f_thresh_min = f_thresh_max * h->param.i_keyint_min
 
334
                         / ( h->param.i_keyint_max * 4 );
 
335
    int res;
 
336
 
 
337
    if( h->param.i_keyint_min == h->param.i_keyint_max )
 
338
        f_thresh_min= f_thresh_max;
 
339
    if( i_gop_size < h->param.i_keyint_min / 4 )
 
340
        f_bias = f_thresh_min / 4;
 
341
    else if( i_gop_size <= h->param.i_keyint_min )
 
342
        f_bias = f_thresh_min * i_gop_size / h->param.i_keyint_min;
 
343
    else
 
344
    {
 
345
        f_bias = f_thresh_min
 
346
                 + ( f_thresh_max - f_thresh_min )
 
347
                   * ( i_gop_size - h->param.i_keyint_min )
 
348
                   / ( h->param.i_keyint_max - h->param.i_keyint_min );
 
349
    }
 
350
 
 
351
    res = pcost >= (1.0 - f_bias) * icost;
 
352
    if( res )
 
353
    {
 
354
        int imb = frame->i_intra_mbs[pdist];
 
355
        int pmb = (h->sps->i_mb_width - 2) * (h->sps->i_mb_height - 2) - imb;
 
356
        x264_log( h, X264_LOG_DEBUG, "scene cut at %d Icost:%d Pcost:%d ratio:%.4f bias:%.4f gop:%d (imb:%d pmb:%d)\n",
 
357
                  frame->i_frame,
 
358
                  icost, pcost, 1. - (double)pcost / icost,
 
359
                  f_bias, i_gop_size, imb, pmb );
 
360
    }
 
361
    return res;
 
362
}
 
363
 
 
364
void x264_slicetype_analyse( x264_t *h )
 
365
{
 
366
    x264_mb_analysis_t a;
 
367
    x264_frame_t *frames[X264_BFRAME_MAX+3] = { NULL, };
 
368
    int num_frames;
 
369
    int keyint_limit;
 
370
    int j;
 
371
    int i_mb_count = (h->sps->i_mb_width - 2) * (h->sps->i_mb_height - 2);
 
372
    int cost1p0, cost2p0, cost1b1, cost2p1;
 
373
    int idr_frame_type;
 
374
 
 
375
    assert( h->frames.b_have_lowres );
 
376
 
 
377
    if( !h->frames.last_nonb )
 
378
        return;
 
379
    frames[0] = h->frames.last_nonb;
 
380
    for( j = 0; h->frames.next[j]; j++ )
 
381
        frames[j+1] = h->frames.next[j];
 
382
    keyint_limit = h->param.i_keyint_max - frames[0]->i_frame + h->frames.i_last_idr - 1;
 
383
    num_frames = X264_MIN( j, keyint_limit );
 
384
    if( num_frames == 0 )
 
385
        return;
 
386
 
 
387
    x264_lowres_context_init( h, &a );
 
388
    idr_frame_type = frames[1]->i_frame - h->frames.i_last_idr >= h->param.i_keyint_min ? X264_TYPE_IDR : X264_TYPE_I;
 
389
 
 
390
    if( num_frames == 1 )
 
391
    {
 
392
no_b_frames:
 
393
        frames[1]->i_type = X264_TYPE_P;
 
394
        if( h->param.b_pre_scenecut )
 
395
        {
 
396
            x264_slicetype_frame_cost( h, &a, frames, 0, 1, 1, 0 );
 
397
            if( scenecut( h, frames[1], 1 ) )
 
398
                frames[1]->i_type = idr_frame_type;
 
399
        }
 
400
        return;
 
401
    }
 
402
 
 
403
    cost2p1 = x264_slicetype_frame_cost( h, &a, frames, 0, 2, 2, 1 );
 
404
    if( frames[2]->i_intra_mbs[2] > i_mb_count / 2 )
 
405
        goto no_b_frames;
 
406
 
 
407
    cost1b1 = x264_slicetype_frame_cost( h, &a, frames, 0, 2, 1, 0 );
 
408
    cost1p0 = x264_slicetype_frame_cost( h, &a, frames, 0, 1, 1, 0 );
 
409
    cost2p0 = x264_slicetype_frame_cost( h, &a, frames, 1, 2, 2, 0 );
 
410
//  fprintf( stderr, "PP: %d + %d <=> BP: %d + %d \n",
 
411
//           cost1p0, cost2p0, cost1b1, cost2p1 );
 
412
    if( cost1p0 + cost2p0 < cost1b1 + cost2p1 )
 
413
        goto no_b_frames;
 
414
 
 
415
// arbitrary and untuned
 
416
#define INTER_THRESH 300
 
417
#define P_SENS_BIAS (50 - h->param.i_bframe_bias)
 
418
    frames[1]->i_type = X264_TYPE_B;
 
419
 
 
420
    for( j = 2; j <= X264_MIN( h->param.i_bframe, num_frames-1 ); j++ )
 
421
    {
 
422
        int pthresh = X264_MAX(INTER_THRESH - P_SENS_BIAS * (j-1), INTER_THRESH/10);
 
423
        int pcost = x264_slicetype_frame_cost( h, &a, frames, 0, j+1, j+1, 1 );
 
424
//      fprintf( stderr, "frm%d+%d: %d <=> %d, I:%d/%d \n",
 
425
//               frames[0]->i_frame, j-1, pthresh, pcost/i_mb_count,
 
426
//               frames[j+1]->i_intra_mbs[j+1], i_mb_count );
 
427
        if( pcost > pthresh*i_mb_count || frames[j+1]->i_intra_mbs[j+1] > i_mb_count/3 )
 
428
        {
 
429
            frames[j]->i_type = X264_TYPE_P;
 
430
            break;
 
431
        }
 
432
        else
 
433
            frames[j]->i_type = X264_TYPE_B;
 
434
    }
 
435
}
 
436
 
 
437
void x264_slicetype_decide( x264_t *h )
 
438
{
 
439
    x264_frame_t *frm;
 
440
    int bframes;
 
441
    int i;
 
442
 
 
443
    if( h->frames.next[0] == NULL )
 
444
        return;
 
445
 
 
446
    if( h->param.rc.b_stat_read )
 
447
    {
 
448
        /* Use the frame types from the first pass */
 
449
        for( i = 0; h->frames.next[i] != NULL; i++ )
 
450
            h->frames.next[i]->i_type =
 
451
                x264_ratecontrol_slice_type( h, h->frames.next[i]->i_frame );
 
452
    }
 
453
    else if( (h->param.i_bframe && h->param.b_bframe_adaptive)
 
454
             || h->param.b_pre_scenecut )
 
455
        x264_slicetype_analyse( h );
 
456
 
 
457
    for( bframes = 0;; bframes++ )
 
458
    {
 
459
        frm = h->frames.next[bframes];
 
460
 
 
461
        /* Limit GOP size */
 
462
        if( frm->i_frame - h->frames.i_last_idr >= h->param.i_keyint_max )
 
463
        {
 
464
            if( frm->i_type == X264_TYPE_AUTO )
 
465
                frm->i_type = X264_TYPE_IDR;
 
466
            if( frm->i_type != X264_TYPE_IDR )
 
467
                x264_log( h, X264_LOG_WARNING, "specified frame type (%d) is not compatible with keyframe interval\n", frm->i_type );
 
468
        }
 
469
        if( frm->i_type == X264_TYPE_IDR )
 
470
        {
 
471
            /* Close GOP */
 
472
            if( bframes > 0 )
 
473
            {
 
474
                bframes--;
 
475
                h->frames.next[bframes]->i_type = X264_TYPE_P;
 
476
            }
 
477
            else
 
478
            {
 
479
                h->i_frame_num = 0;
 
480
            }
 
481
        }
 
482
 
 
483
        if( bframes == h->param.i_bframe
 
484
            || h->frames.next[bframes+1] == NULL )
 
485
        {
 
486
            if( IS_X264_TYPE_B( frm->i_type ) )
 
487
                x264_log( h, X264_LOG_WARNING, "specified frame type is not compatible with max B-frames\n" );
 
488
            if( frm->i_type == X264_TYPE_AUTO
 
489
                || IS_X264_TYPE_B( frm->i_type ) )
 
490
                frm->i_type = X264_TYPE_P;
 
491
        }
 
492
 
 
493
        if( frm->i_type != X264_TYPE_AUTO && frm->i_type != X264_TYPE_B && frm->i_type != X264_TYPE_BREF )
 
494
            break;
 
495
 
 
496
        frm->i_type = X264_TYPE_B;
 
497
    }
 
498
}
 
499
 
 
500
int x264_rc_analyse_slice( x264_t *h )
 
501
{
 
502
    x264_mb_analysis_t a;
 
503
    x264_frame_t *frames[X264_BFRAME_MAX+2] = { NULL, };
 
504
    int p0=0, p1, b;
 
505
    int cost;
 
506
 
 
507
    x264_lowres_context_init( h, &a );
 
508
 
 
509
    if( IS_X264_TYPE_I(h->fenc->i_type) )
 
510
    {
 
511
        p1 = b = 0;
 
512
    }
 
513
    else if( X264_TYPE_P == h->fenc->i_type )
 
514
    {
 
515
        p1 = 0;
 
516
        while( h->frames.current[p1] && IS_X264_TYPE_B( h->frames.current[p1]->i_type ) )
 
517
            p1++;
 
518
        p1++;
 
519
        b = p1;
 
520
    }
 
521
    else //B
 
522
    {
 
523
        p1 = (h->fref1[0]->i_poc - h->fref0[0]->i_poc)/2;
 
524
        b  = (h->fref1[0]->i_poc - h->fenc->i_poc)/2;
 
525
        frames[p1] = h->fref1[0];
 
526
    }
 
527
    frames[p0] = h->fref0[0];
 
528
    frames[b] = h->fenc;
 
529
 
 
530
    cost = x264_slicetype_frame_cost( h, &a, frames, p0, p1, b, 0 );
 
531
    h->fenc->i_row_satd = h->fenc->i_row_satds[b-p0][p1-b];
 
532
    h->fdec->i_row_satd = h->fdec->i_row_satds[b-p0][p1-b];
 
533
    h->fdec->i_satd = cost;
 
534
    memcpy( h->fdec->i_row_satd, h->fenc->i_row_satd, h->sps->i_mb_height * sizeof(int) );
 
535
    return cost;
 
536
}