firstpass.c 112 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5
6
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
John Koleszar's avatar
John Koleszar committed
9
10
11
12
13
14
15
16
 */

#include "math.h"
#include "limits.h"
#include "block.h"
#include "onyx_int.h"
#include "variance.h"
#include "encodeintra.h"
John Koleszar's avatar
John Koleszar committed
17
#include "vp8/common/setupintrarecon.h"
John Koleszar's avatar
John Koleszar committed
18
#include "mcomp.h"
19
#include "firstpass.h"
John Koleszar's avatar
John Koleszar committed
20
21
#include "vpx_scale/vpxscale.h"
#include "encodemb.h"
John Koleszar's avatar
John Koleszar committed
22
23
#include "vp8/common/extend.h"
#include "vp8/common/systemdependent.h"
John Koleszar's avatar
John Koleszar committed
24
25
#include "vpx_scale/yv12extend.h"
#include "vpx_mem/vpx_mem.h"
John Koleszar's avatar
John Koleszar committed
26
#include "vp8/common/swapyv12buffer.h"
John Koleszar's avatar
John Koleszar committed
27
28
#include <stdio.h>
#include "rdopt.h"
Paul Wilkins's avatar
Paul Wilkins committed
29
#include "ratectrl.h"
John Koleszar's avatar
John Koleszar committed
30
#include "vp8/common/quant_common.h"
John Koleszar's avatar
John Koleszar committed
31
32
33
34
35
36
37
38
39
40
41
42
43
#include "encodemv.h"

//#define OUTPUT_FPF 1

#if CONFIG_RUNTIME_CPU_DETECT
#define IF_RTCD(x) (x)
#else
#define IF_RTCD(x) NULL
#endif

extern void vp8_build_block_offsets(MACROBLOCK *x);
extern void vp8_setup_block_ptrs(MACROBLOCK *x);
extern void vp8cx_frame_init_quantizer(VP8_COMP *cpi);
Scott LaVarnway's avatar
Scott LaVarnway committed
44
extern void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv);
John Koleszar's avatar
John Koleszar committed
45
46
extern void vp8_alloc_compressor_data(VP8_COMP *cpi);

47
#define IIFACTOR   1.5
John Koleszar's avatar
John Koleszar committed
48
49
#define IIKFACTOR1 1.40
#define IIKFACTOR2 1.5
50
51
#define RMAX       14.0
#define GF_RMAX    48.0
John Koleszar's avatar
John Koleszar committed
52

53
54
#define KF_MB_INTRA_MIN 300
#define GF_MB_INTRA_MIN 200
Paul Wilkins's avatar
CQ Mode    
Paul Wilkins committed
55

John Koleszar's avatar
John Koleszar committed
56
57
58
59
60
#define DOUBLE_DIVIDE_CHECK(X) ((X)<0?(X)-.000001:(X)+.000001)

#define POW1 (double)cpi->oxcf.two_pass_vbrbias/100.0
#define POW2 (double)cpi->oxcf.two_pass_vbrbias/100.0

61
62
#define NEW_BOOST 1

John Koleszar's avatar
John Koleszar committed
63
64
65
static int vscale_lookup[7] = {0, 1, 1, 2, 2, 3, 3};
static int hscale_lookup[7] = {0, 0, 1, 1, 2, 2, 3};

Paul Wilkins's avatar
Paul Wilkins committed
66
67
68
static void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame);

static int select_cq_level( int qindex )
Paul Wilkins's avatar
CQ Mode    
Paul Wilkins committed
69
{
Paul Wilkins's avatar
Paul Wilkins committed
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
    int ret_val = QINDEX_RANGE - 1;
    int i;

    double target_q = ( vp8_convert_qindex_to_q( qindex ) * 0.5847 ) + 1.0;

    for ( i = 0; i < QINDEX_RANGE; i++ )
    {
        if ( target_q <= vp8_convert_qindex_to_q( i ) )
        {
            ret_val = i;
            break;
        }
    }

    return ret_val;
}
Paul Wilkins's avatar
CQ Mode    
Paul Wilkins committed
86

John Koleszar's avatar
John Koleszar committed
87
88
89
90

// Resets the first pass file to the given position using a relative seek from the current position
static void reset_fpf_position(VP8_COMP *cpi, FIRSTPASS_STATS *Position)
{
91
    cpi->twopass.stats_in = Position;
John Koleszar's avatar
John Koleszar committed
92
93
94
95
}

static int lookup_next_frame_stats(VP8_COMP *cpi, FIRSTPASS_STATS *next_frame)
{
96
    if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end)
John Koleszar's avatar
John Koleszar committed
97
98
        return EOF;

99
    *next_frame = *cpi->twopass.stats_in;
John Koleszar's avatar
John Koleszar committed
100
101
102
    return 1;
}

103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Read frame stats at an offset from the current position
static int read_frame_stats( VP8_COMP *cpi,
                             FIRSTPASS_STATS *frame_stats,
                             int offset )
{
    FIRSTPASS_STATS * fps_ptr = cpi->twopass.stats_in;

    // Check legality of offset
    if ( offset >= 0 )
    {
        if ( &fps_ptr[offset] >= cpi->twopass.stats_in_end )
             return EOF;
    }
    else if ( offset < 0 )
    {
        if ( &fps_ptr[offset] < cpi->twopass.stats_in_start )
             return EOF;
    }

    *frame_stats = fps_ptr[offset];
    return 1;
}

static int input_stats(VP8_COMP *cpi, FIRSTPASS_STATS *fps)
{
    if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end)
        return EOF;

    *fps = *cpi->twopass.stats_in;
    cpi->twopass.stats_in =
         (void*)((char *)cpi->twopass.stats_in + sizeof(FIRSTPASS_STATS));
    return 1;
}

static void output_stats(const VP8_COMP            *cpi,
                         struct vpx_codec_pkt_list *pktlist,
                         FIRSTPASS_STATS            *stats)
{
    struct vpx_codec_cx_pkt pkt;
    pkt.kind = VPX_CODEC_STATS_PKT;
    pkt.data.twopass_stats.buf = stats;
    pkt.data.twopass_stats.sz = sizeof(FIRSTPASS_STATS);
    vpx_codec_pkt_list_add(pktlist, &pkt);

// TEMP debug code
#if OUTPUT_FPF

    {
        FILE *fpfile;
        fpfile = fopen("firstpass.stt", "a");

        fprintf(fpfile, "%12.0f %12.0f %12.0f %12.4f %12.4f %12.4f %12.4f"
                " %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f"
156
                " %12.0f %12.0f %12.4f\n",
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
                stats->frame,
                stats->intra_error,
                stats->coded_error,
                stats->ssim_weighted_pred_err,
                stats->pcnt_inter,
                stats->pcnt_motion,
                stats->pcnt_second_ref,
                stats->pcnt_neutral,
                stats->MVr,
                stats->mvr_abs,
                stats->MVc,
                stats->mvc_abs,
                stats->MVrv,
                stats->MVcv,
                stats->mv_in_out_count,
172
                stats->new_mv_count,
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
                stats->count,
                stats->duration);
        fclose(fpfile);
    }
#endif
}

static void zero_stats(FIRSTPASS_STATS *section)
{
    section->frame      = 0.0;
    section->intra_error = 0.0;
    section->coded_error = 0.0;
    section->ssim_weighted_pred_err = 0.0;
    section->pcnt_inter  = 0.0;
    section->pcnt_motion  = 0.0;
    section->pcnt_second_ref = 0.0;
    section->pcnt_neutral = 0.0;
    section->MVr        = 0.0;
    section->mvr_abs     = 0.0;
    section->MVc        = 0.0;
    section->mvc_abs     = 0.0;
    section->MVrv       = 0.0;
    section->MVcv       = 0.0;
    section->mv_in_out_count  = 0.0;
197
    section->new_mv_count = 0.0;
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
    section->count      = 0.0;
    section->duration   = 1.0;
}

static void accumulate_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame)
{
    section->frame += frame->frame;
    section->intra_error += frame->intra_error;
    section->coded_error += frame->coded_error;
    section->ssim_weighted_pred_err += frame->ssim_weighted_pred_err;
    section->pcnt_inter  += frame->pcnt_inter;
    section->pcnt_motion += frame->pcnt_motion;
    section->pcnt_second_ref += frame->pcnt_second_ref;
    section->pcnt_neutral += frame->pcnt_neutral;
    section->MVr        += frame->MVr;
    section->mvr_abs     += frame->mvr_abs;
    section->MVc        += frame->MVc;
    section->mvc_abs     += frame->mvc_abs;
    section->MVrv       += frame->MVrv;
    section->MVcv       += frame->MVcv;
    section->mv_in_out_count  += frame->mv_in_out_count;
219
    section->new_mv_count += frame->new_mv_count;
220
221
222
223
    section->count      += frame->count;
    section->duration   += frame->duration;
}

224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
static void subtract_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame)
{
    section->frame -= frame->frame;
    section->intra_error -= frame->intra_error;
    section->coded_error -= frame->coded_error;
    section->ssim_weighted_pred_err -= frame->ssim_weighted_pred_err;
    section->pcnt_inter  -= frame->pcnt_inter;
    section->pcnt_motion -= frame->pcnt_motion;
    section->pcnt_second_ref -= frame->pcnt_second_ref;
    section->pcnt_neutral -= frame->pcnt_neutral;
    section->MVr        -= frame->MVr;
    section->mvr_abs     -= frame->mvr_abs;
    section->MVc        -= frame->MVc;
    section->mvc_abs     -= frame->mvc_abs;
    section->MVrv       -= frame->MVrv;
    section->MVcv       -= frame->MVcv;
    section->mv_in_out_count  -= frame->mv_in_out_count;
    section->new_mv_count -= frame->new_mv_count;
    section->count      -= frame->count;
    section->duration   -= frame->duration;
}

246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
static void avg_stats(FIRSTPASS_STATS *section)
{
    if (section->count < 1.0)
        return;

    section->intra_error /= section->count;
    section->coded_error /= section->count;
    section->ssim_weighted_pred_err /= section->count;
    section->pcnt_inter  /= section->count;
    section->pcnt_second_ref /= section->count;
    section->pcnt_neutral /= section->count;
    section->pcnt_motion /= section->count;
    section->MVr        /= section->count;
    section->mvr_abs     /= section->count;
    section->MVc        /= section->count;
    section->mvc_abs     /= section->count;
    section->MVrv       /= section->count;
    section->MVcv       /= section->count;
    section->mv_in_out_count   /= section->count;
    section->duration   /= section->count;
}

John Koleszar's avatar
John Koleszar committed
268
269
270
// Calculate a modified Error used in distributing bits between easier and harder frames
static double calculate_modified_err(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
{
271
272
    double av_err = ( cpi->twopass.total_stats->ssim_weighted_pred_err /
                      cpi->twopass.total_stats->count );
John Koleszar's avatar
John Koleszar committed
273
274
275
276
277
278
279
280
281
282
283
    double this_err = this_frame->ssim_weighted_pred_err;
    double modified_err;

    if (this_err > av_err)
        modified_err = av_err * pow((this_err / DOUBLE_DIVIDE_CHECK(av_err)), POW1);
    else
        modified_err = av_err * pow((this_err / DOUBLE_DIVIDE_CHECK(av_err)), POW2);

    return modified_err;
}

284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
static const double weight_table[256] = {
0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
0.020000, 0.031250, 0.062500, 0.093750, 0.125000, 0.156250, 0.187500, 0.218750,
0.250000, 0.281250, 0.312500, 0.343750, 0.375000, 0.406250, 0.437500, 0.468750,
0.500000, 0.531250, 0.562500, 0.593750, 0.625000, 0.656250, 0.687500, 0.718750,
0.750000, 0.781250, 0.812500, 0.843750, 0.875000, 0.906250, 0.937500, 0.968750,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000
};

319
static double simple_weight(YV12_BUFFER_CONFIG *source)
John Koleszar's avatar
John Koleszar committed
320
321
322
323
324
325
326
{
    int i, j;

    unsigned char *src = source->y_buffer;
    double sum_weights = 0.0;

    // Loop throught the Y plane raw examining levels and creating a weight for the image
327
328
    i = source->y_height;
    do
John Koleszar's avatar
John Koleszar committed
329
    {
330
331
        j = source->y_width;
        do
John Koleszar's avatar
John Koleszar committed
332
        {
333
334
335
336
            sum_weights += weight_table[ *src];
            src++;
        }while(--j);
        src -= source->y_width;
John Koleszar's avatar
John Koleszar committed
337
        src += source->y_stride;
338
    }while(--i);
John Koleszar's avatar
John Koleszar committed
339
340
341
342
343
344

    sum_weights /= (source->y_height * source->y_width);

    return sum_weights;
}

345

John Koleszar's avatar
John Koleszar committed
346
// This function returns the current per frame maximum bitrate target
347
static int frame_max_bits(VP8_COMP *cpi)
John Koleszar's avatar
John Koleszar committed
348
349
350
351
{
    // Max allocation for a single frame based on the max section guidelines passed in and how many bits are left
    int max_bits;

352
353
    // For VBR base this on the bits and frames left plus the two_pass_vbrmax_section rate passed in by the user
    max_bits = (int)(((double)cpi->twopass.bits_left / (cpi->twopass.total_stats->count - (double)cpi->common.current_video_frame)) * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
John Koleszar's avatar
John Koleszar committed
354
355
356
357
358
359
360
361
362
363

    // Trap case where we are out of bits
    if (max_bits < 0)
        max_bits = 0;

    return max_bits;
}

void vp8_init_first_pass(VP8_COMP *cpi)
{
364
    zero_stats(cpi->twopass.total_stats);
John Koleszar's avatar
John Koleszar committed
365
366
367
368
}

void vp8_end_first_pass(VP8_COMP *cpi)
{
369
    output_stats(cpi, cpi->output_pkt_list, cpi->twopass.total_stats);
370
}
John Koleszar's avatar
John Koleszar committed
371

372
static void zz_motion_search( VP8_COMP *cpi, MACROBLOCK * x, YV12_BUFFER_CONFIG * recon_buffer, int * best_motion_err, int recon_yoffset )
John Koleszar's avatar
John Koleszar committed
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
{
    MACROBLOCKD * const xd = & x->e_mbd;
    BLOCK *b = &x->block[0];
    BLOCKD *d = &x->e_mbd.block[0];

    unsigned char *src_ptr = (*(b->base_src) + b->src);
    int src_stride = b->src_stride;
    unsigned char *ref_ptr;
    int ref_stride=d->pre_stride;

    // Set up pointers for this macro block recon buffer
    xd->pre.y_buffer = recon_buffer->y_buffer + recon_yoffset;

    ref_ptr = (unsigned char *)(*(d->base_pre) + d->pre );

    VARIANCE_INVOKE(IF_RTCD(&cpi->rtcd.variance), mse16x16) ( src_ptr, src_stride, ref_ptr, ref_stride, (unsigned int *)(best_motion_err));
}

Scott LaVarnway's avatar
Scott LaVarnway committed
391
392
393
394
static void first_pass_motion_search(VP8_COMP *cpi, MACROBLOCK *x,
                                     int_mv *ref_mv, MV *best_mv,
                                     YV12_BUFFER_CONFIG *recon_buffer,
                                     int *best_motion_err, int recon_yoffset )
John Koleszar's avatar
John Koleszar committed
395
396
397
398
399
400
{
    MACROBLOCKD *const xd = & x->e_mbd;
    BLOCK *b = &x->block[0];
    BLOCKD *d = &x->e_mbd.block[0];
    int num00;

Scott LaVarnway's avatar
Scott LaVarnway committed
401
    int_mv tmp_mv;
402
    int_mv ref_mv_full;
John Koleszar's avatar
John Koleszar committed
403
404
405
406
407

    int tmp_err;
    int step_param = 3;                                       //3;          // Dont search over full range for first pass
    int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param; //3;
    int n;
408
    vp8_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[BLOCK_16X16];
John Koleszar's avatar
John Koleszar committed
409
410
    int new_mv_mode_penalty = 256;

411
    // override the default variance function to use MSE
John Koleszar's avatar
John Koleszar committed
412
413
414
415
416
417
    v_fn_ptr.vf    = VARIANCE_INVOKE(IF_RTCD(&cpi->rtcd.variance), mse16x16);

    // Set up pointers for this macro block recon buffer
    xd->pre.y_buffer = recon_buffer->y_buffer + recon_yoffset;

    // Initial step/diamond search centred on best mv
Scott LaVarnway's avatar
Scott LaVarnway committed
418
    tmp_mv.as_int = 0;
419
420
421
    ref_mv_full.as_mv.col = ref_mv->as_mv.col>>3;
    ref_mv_full.as_mv.row = ref_mv->as_mv.row>>3;
    tmp_err = cpi->diamond_search_sad(x, b, d, &ref_mv_full, &tmp_mv, step_param,
422
423
                                      x->sadperbit16, &num00, &v_fn_ptr,
                                      x->mvcost, ref_mv);
John Koleszar's avatar
John Koleszar committed
424
425
426
427
428
429
    if ( tmp_err < INT_MAX-new_mv_mode_penalty )
        tmp_err += new_mv_mode_penalty;

    if (tmp_err < *best_motion_err)
    {
        *best_motion_err = tmp_err;
Scott LaVarnway's avatar
Scott LaVarnway committed
430
431
        best_mv->row = tmp_mv.as_mv.row;
        best_mv->col = tmp_mv.as_mv.col;
John Koleszar's avatar
John Koleszar committed
432
433
434
435
436
437
438
439
440
441
442
443
444
445
    }

    // Further step/diamond searches as necessary
    n = num00;
    num00 = 0;

    while (n < further_steps)
    {
        n++;

        if (num00)
            num00--;
        else
        {
446
            tmp_err = cpi->diamond_search_sad(x, b, d, &ref_mv_full, &tmp_mv,
447
448
449
                                              step_param + n, x->sadperbit16,
                                              &num00, &v_fn_ptr, x->mvcost,
                                              ref_mv);
John Koleszar's avatar
John Koleszar committed
450
451
452
453
454
455
            if ( tmp_err < INT_MAX-new_mv_mode_penalty )
                tmp_err += new_mv_mode_penalty;

            if (tmp_err < *best_motion_err)
            {
                *best_motion_err = tmp_err;
Scott LaVarnway's avatar
Scott LaVarnway committed
456
457
                best_mv->row = tmp_mv.as_mv.row;
                best_mv->col = tmp_mv.as_mv.col;
John Koleszar's avatar
John Koleszar committed
458
459
460
461
462
463
464
465
466
467
468
469
470
            }
        }
    }
}

void vp8_first_pass(VP8_COMP *cpi)
{
    int mb_row, mb_col;
    MACROBLOCK *const x = & cpi->mb;
    VP8_COMMON *const cm = & cpi->common;
    MACROBLOCKD *const xd = & x->e_mbd;

    int recon_yoffset, recon_uvoffset;
471
472
473
474
475
    YV12_BUFFER_CONFIG *lst_yv12 = &cm->yv12_fb[cm->lst_fb_idx];
    YV12_BUFFER_CONFIG *new_yv12 = &cm->yv12_fb[cm->new_fb_idx];
    YV12_BUFFER_CONFIG *gld_yv12 = &cm->yv12_fb[cm->gld_fb_idx];
    int recon_y_stride = lst_yv12->y_stride;
    int recon_uv_stride = lst_yv12->uv_stride;
476
477
    int64_t intra_error = 0;
    int64_t coded_error = 0;
John Koleszar's avatar
John Koleszar committed
478
479
480
481
482
483
484
485

    int sum_mvr = 0, sum_mvc = 0;
    int sum_mvr_abs = 0, sum_mvc_abs = 0;
    int sum_mvrs = 0, sum_mvcs = 0;
    int mvcount = 0;
    int intercount = 0;
    int second_ref_count = 0;
    int intrapenalty = 256;
Paul Wilkins's avatar
Paul Wilkins committed
486
    int neutral_count = 0;
487
    int new_mv_count = 0;
John Koleszar's avatar
John Koleszar committed
488
    int sum_in_vectors = 0;
489
    uint32_t lastmv_as_int = 0;
John Koleszar's avatar
John Koleszar committed
490

Scott LaVarnway's avatar
Scott LaVarnway committed
491
492
493
    int_mv zero_ref_mv;

    zero_ref_mv.as_int = 0;
John Koleszar's avatar
John Koleszar committed
494
495
496
497

    vp8_clear_system_state();  //__asm emms;

    x->src = * cpi->Source;
498
499
    xd->pre = *lst_yv12;
    xd->dst = *new_yv12;
John Koleszar's avatar
John Koleszar committed
500

501
502
    x->partition_info = x->pi;

503
504
    xd->mode_info_context = cm->mi;

John Koleszar's avatar
John Koleszar committed
505
506
507
508
509
510
511
    vp8_build_block_offsets(x);

    vp8_setup_block_dptrs(&x->e_mbd);

    vp8_setup_block_ptrs(x);

    // set up frame new frame for intra coded blocks
512
    vp8_setup_intra_recon(new_yv12);
John Koleszar's avatar
John Koleszar committed
513
514
515
516
517
518
519
    vp8cx_frame_init_quantizer(cpi);

    // Initialise the MV cost table to the defaults
    //if( cm->current_video_frame == 0)
    //if ( 0 )
    {
        int flag[2] = {1, 1};
520
        vp8_initialize_rd_consts(cpi, cm->base_qindex + cm->y1dc_delta_q);
John Koleszar's avatar
John Koleszar committed
521
        vpx_memcpy(cm->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context));
522
        vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cm->fc.mvc, flag);
John Koleszar's avatar
John Koleszar committed
523
524
525
526
527
    }

    // for each macroblock row in image
    for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
    {
528
529
530
        int_mv best_ref_mv;

        best_ref_mv.as_int = 0;
John Koleszar's avatar
John Koleszar committed
531
532
533
534
535
536

        // reset above block coeffs
        xd->up_available = (mb_row != 0);
        recon_yoffset = (mb_row * recon_y_stride * 16);
        recon_uvoffset = (mb_row * recon_uv_stride * 8);

537
538
539
540
541
        // Set up limit values for motion vectors to prevent them extending outside the UMV borders
        x->mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 16));
        x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16) + (VP8BORDERINPIXELS - 16);


John Koleszar's avatar
John Koleszar committed
542
543
544
545
546
547
548
        // for each macroblock col in image
        for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
        {
            int this_error;
            int gf_motion_error = INT_MAX;
            int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);

549
550
551
            xd->dst.y_buffer = new_yv12->y_buffer + recon_yoffset;
            xd->dst.u_buffer = new_yv12->u_buffer + recon_uvoffset;
            xd->dst.v_buffer = new_yv12->v_buffer + recon_uvoffset;
John Koleszar's avatar
John Koleszar committed
552
553
            xd->left_available = (mb_col != 0);

554
555
556
            //Copy current mb to a buffer
            RECON_INVOKE(&xd->rtcd->recon, copy16x16)(x->src.y_buffer, x->src.y_stride, x->thismb, 16);

John Koleszar's avatar
John Koleszar committed
557
            // do intra 16x16 prediction
Tero Rintaluoma's avatar
Tero Rintaluoma committed
558
            this_error = vp8_encode_intra(cpi, x, use_dc_pred);
John Koleszar's avatar
John Koleszar committed
559
560
561
562
563
564
565
566

            // "intrapenalty" below deals with situations where the intra and inter error scores are very low (eg a plain black frame)
            // We do not have special cases in first pass for 0,0 and nearest etc so all inter modes carry an overhead cost estimate fot the mv.
            // When the error score is very low this causes us to pick all or lots of INTRA modes and throw lots of key frames.
            // This penalty adds a cost matching that of a 0,0 mv to the intra case.
            this_error += intrapenalty;

            // Cumulative intra error total
567
            intra_error += (int64_t)this_error;
John Koleszar's avatar
John Koleszar committed
568
569
570
571
572
573
574
575
576
577
578
579
580
581

            // Set up limit values for motion vectors to prevent them extending outside the UMV borders
            x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16));
            x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16) + (VP8BORDERINPIXELS - 16);

            // Other than for the first frame do a motion search
            if (cm->current_video_frame > 0)
            {
                BLOCKD *d = &x->e_mbd.block[0];
                MV tmp_mv = {0, 0};
                int tmp_err;
                int motion_error = INT_MAX;

                // Simple 0,0 motion with no mv overhead
582
                zz_motion_search( cpi, x, lst_yv12, &motion_error, recon_yoffset );
John Koleszar's avatar
John Koleszar committed
583
584
585
                d->bmi.mv.as_mv.row = 0;
                d->bmi.mv.as_mv.col = 0;

586
587
                // Test last reference frame using the previous best mv as the
                // starting point (best reference) for the search
Scott LaVarnway's avatar
Scott LaVarnway committed
588
                first_pass_motion_search(cpi, x, &best_ref_mv,
589
                                        &d->bmi.mv.as_mv, lst_yv12,
590
                                        &motion_error, recon_yoffset);
John Koleszar's avatar
John Koleszar committed
591
592

                // If the current best reference mv is not centred on 0,0 then do a 0,0 based search as well
593
                if (best_ref_mv.as_int)
John Koleszar's avatar
John Koleszar committed
594
595
                {
                   tmp_err = INT_MAX;
596
                   first_pass_motion_search(cpi, x, &zero_ref_mv, &tmp_mv,
597
                                     lst_yv12, &tmp_err, recon_yoffset);
John Koleszar's avatar
John Koleszar committed
598
599
600
601
602
603
604
605
606
607
608
609

                   if ( tmp_err < motion_error )
                   {
                        motion_error = tmp_err;
                        d->bmi.mv.as_mv.row = tmp_mv.row;
                        d->bmi.mv.as_mv.col = tmp_mv.col;
                   }
                }

                // Experimental search in a second reference frame ((0,0) based only)
                if (cm->current_video_frame > 1)
                {
610
                    first_pass_motion_search(cpi, x, &zero_ref_mv, &tmp_mv, gld_yv12, &gf_motion_error, recon_yoffset);
John Koleszar's avatar
John Koleszar committed
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627

                    if ((gf_motion_error < motion_error) && (gf_motion_error < this_error))
                    {
                        second_ref_count++;
                        //motion_error = gf_motion_error;
                        //d->bmi.mv.as_mv.row = tmp_mv.row;
                        //d->bmi.mv.as_mv.col = tmp_mv.col;
                    }
                    /*else
                    {
                        xd->pre.y_buffer = cm->last_frame.y_buffer + recon_yoffset;
                        xd->pre.u_buffer = cm->last_frame.u_buffer + recon_uvoffset;
                        xd->pre.v_buffer = cm->last_frame.v_buffer + recon_uvoffset;
                    }*/


                    // Reset to last frame as reference buffer
628
629
630
                    xd->pre.y_buffer = lst_yv12->y_buffer + recon_yoffset;
                    xd->pre.u_buffer = lst_yv12->u_buffer + recon_uvoffset;
                    xd->pre.v_buffer = lst_yv12->v_buffer + recon_uvoffset;
John Koleszar's avatar
John Koleszar committed
631
632
                }

633
634
635
                /* Intra assumed best */
                best_ref_mv.as_int = 0;

John Koleszar's avatar
John Koleszar committed
636
637
                if (motion_error <= this_error)
                {
Paul Wilkins's avatar
Paul Wilkins committed
638
639
640
641
642
643
644
645
646
647
648
                    // Keep a count of cases where the inter and intra were
                    // very close and very low. This helps with scene cut
                    // detection for example in cropped clips with black bars
                    // at the sides or top and bottom.
                    if( (((this_error-intrapenalty) * 9) <=
                         (motion_error*10)) &&
                        (this_error < (2*intrapenalty)) )
                    {
                        neutral_count++;
                    }

John Koleszar's avatar
John Koleszar committed
649
650
651
                    d->bmi.mv.as_mv.row <<= 3;
                    d->bmi.mv.as_mv.col <<= 3;
                    this_error = motion_error;
Scott LaVarnway's avatar
Scott LaVarnway committed
652
                    vp8_set_mbmode_and_mvs(x, NEWMV, &d->bmi.mv);
John Koleszar's avatar
John Koleszar committed
653
654
655
656
657
658
659
660
661
                    vp8_encode_inter16x16y(IF_RTCD(&cpi->rtcd), x);
                    sum_mvr += d->bmi.mv.as_mv.row;
                    sum_mvr_abs += abs(d->bmi.mv.as_mv.row);
                    sum_mvc += d->bmi.mv.as_mv.col;
                    sum_mvc_abs += abs(d->bmi.mv.as_mv.col);
                    sum_mvrs += d->bmi.mv.as_mv.row * d->bmi.mv.as_mv.row;
                    sum_mvcs += d->bmi.mv.as_mv.col * d->bmi.mv.as_mv.col;
                    intercount++;

662
                    best_ref_mv.as_int = d->bmi.mv.as_int;
John Koleszar's avatar
John Koleszar committed
663
664

                    // Was the vector non-zero
665
                    if (d->bmi.mv.as_int)
John Koleszar's avatar
John Koleszar committed
666
667
668
                    {
                        mvcount++;

669
670
671
672
673
                        // Was it different from the last non zero vector
                        if ( d->bmi.mv.as_int != lastmv_as_int )
                            new_mv_count++;
                        lastmv_as_int = d->bmi.mv.as_int;

John Koleszar's avatar
John Koleszar committed
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
                        // Does the Row vector point inwards or outwards
                        if (mb_row < cm->mb_rows / 2)
                        {
                            if (d->bmi.mv.as_mv.row > 0)
                                sum_in_vectors--;
                            else if (d->bmi.mv.as_mv.row < 0)
                                sum_in_vectors++;
                        }
                        else if (mb_row > cm->mb_rows / 2)
                        {
                            if (d->bmi.mv.as_mv.row > 0)
                                sum_in_vectors++;
                            else if (d->bmi.mv.as_mv.row < 0)
                                sum_in_vectors--;
                        }

                        // Does the Row vector point inwards or outwards
                        if (mb_col < cm->mb_cols / 2)
                        {
                            if (d->bmi.mv.as_mv.col > 0)
                                sum_in_vectors--;
                            else if (d->bmi.mv.as_mv.col < 0)
                                sum_in_vectors++;
                        }
                        else if (mb_col > cm->mb_cols / 2)
                        {
                            if (d->bmi.mv.as_mv.col > 0)
                                sum_in_vectors++;
                            else if (d->bmi.mv.as_mv.col < 0)
                                sum_in_vectors--;
                        }
705
                    }
John Koleszar's avatar
John Koleszar committed
706
707
708
                }
            }

709
            coded_error += (int64_t)this_error;
John Koleszar's avatar
John Koleszar committed
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725

            // adjust to the next column of macroblocks
            x->src.y_buffer += 16;
            x->src.u_buffer += 8;
            x->src.v_buffer += 8;

            recon_yoffset += 16;
            recon_uvoffset += 8;
        }

        // adjust to the next row of mbs
        x->src.y_buffer += 16 * x->src.y_stride - 16 * cm->mb_cols;
        x->src.u_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols;
        x->src.v_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols;

        //extend the recon for intra prediction
726
        vp8_extend_mb_row(new_yv12, xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, xd->dst.v_buffer + 8);
John Koleszar's avatar
John Koleszar committed
727
728
729
730
731
732
733
734
735
736
737
738
        vp8_clear_system_state();  //__asm emms;
    }

    vp8_clear_system_state();  //__asm emms;
    {
        double weight = 0.0;

        FIRSTPASS_STATS fps;

        fps.frame      = cm->current_video_frame ;
        fps.intra_error = intra_error >> 8;
        fps.coded_error = coded_error >> 8;
739
        weight = simple_weight(cpi->Source);
John Koleszar's avatar
John Koleszar committed
740

741

John Koleszar's avatar
John Koleszar committed
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
        if (weight < 0.1)
            weight = 0.1;

        fps.ssim_weighted_pred_err = fps.coded_error * weight;

        fps.pcnt_inter  = 0.0;
        fps.pcnt_motion = 0.0;
        fps.MVr        = 0.0;
        fps.mvr_abs     = 0.0;
        fps.MVc        = 0.0;
        fps.mvc_abs     = 0.0;
        fps.MVrv       = 0.0;
        fps.MVcv       = 0.0;
        fps.mv_in_out_count  = 0.0;
        fps.count      = 1.0;

        fps.pcnt_inter   = 1.0 * (double)intercount / cm->MBs;
        fps.pcnt_second_ref = 1.0 * (double)second_ref_count / cm->MBs;
Paul Wilkins's avatar
Paul Wilkins committed
760
        fps.pcnt_neutral = 1.0 * (double)neutral_count / cm->MBs;
John Koleszar's avatar
John Koleszar committed
761
762
763
764
765
766
767
768
769
770

        if (mvcount > 0)
        {
            fps.MVr = (double)sum_mvr / (double)mvcount;
            fps.mvr_abs = (double)sum_mvr_abs / (double)mvcount;
            fps.MVc = (double)sum_mvc / (double)mvcount;
            fps.mvc_abs = (double)sum_mvc_abs / (double)mvcount;
            fps.MVrv = ((double)sum_mvrs - (fps.MVr * fps.MVr / (double)mvcount)) / (double)mvcount;
            fps.MVcv = ((double)sum_mvcs - (fps.MVc * fps.MVc / (double)mvcount)) / (double)mvcount;
            fps.mv_in_out_count = (double)sum_in_vectors / (double)(mvcount * 2);
771
            fps.new_mv_count = new_mv_count;
John Koleszar's avatar
John Koleszar committed
772
773
774
775
776
777

            fps.pcnt_motion = 1.0 * (double)mvcount / cpi->common.MBs;
        }

        // TODO:  handle the case when duration is set to 0, or something less
        // than the full time between subsequent cpi->source_time_stamp s  .
John Koleszar's avatar
John Koleszar committed
778
779
        fps.duration = cpi->source->ts_end
                       - cpi->source->ts_start;
John Koleszar's avatar
John Koleszar committed
780

Adrian Grange's avatar
Adrian Grange committed
781
        // don't want to do output stats with a stack variable!
782
        memcpy(cpi->twopass.this_frame_stats,
783
784
               &fps,
               sizeof(FIRSTPASS_STATS));
785
786
        output_stats(cpi, cpi->output_pkt_list, cpi->twopass.this_frame_stats);
        accumulate_stats(cpi->twopass.total_stats, &fps);
John Koleszar's avatar
John Koleszar committed
787
788
789
790
    }

    // Copy the previous Last Frame into the GF buffer if specific conditions for doing so are met
    if ((cm->current_video_frame > 0) &&
791
792
        (cpi->twopass.this_frame_stats->pcnt_inter > 0.20) &&
        ((cpi->twopass.this_frame_stats->intra_error / cpi->twopass.this_frame_stats->coded_error) > 2.0))
John Koleszar's avatar
John Koleszar committed
793
    {
794
        vp8_yv12_copy_frame_ptr(lst_yv12, gld_yv12);
John Koleszar's avatar
John Koleszar committed
795
796
797
    }

    // swap frame pointers so last frame refers to the frame we just compressed
798
799
    vp8_swap_yv12_buffer(lst_yv12, new_yv12);
    vp8_yv12_extend_frame_borders(lst_yv12);
John Koleszar's avatar
John Koleszar committed
800
801
802
803

    // Special case for the first frame. Copy into the GF buffer as a second reference.
    if (cm->current_video_frame == 0)
    {
804
        vp8_yv12_copy_frame_ptr(lst_yv12, gld_yv12);
John Koleszar's avatar
John Koleszar committed
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
    }


    // use this to see what the first pass reconstruction looks like
    if (0)
    {
        char filename[512];
        FILE *recon_file;
        sprintf(filename, "enc%04d.yuv", (int) cm->current_video_frame);

        if (cm->current_video_frame == 0)
            recon_file = fopen(filename, "wb");
        else
            recon_file = fopen(filename, "ab");

820
        if(fwrite(lst_yv12->buffer_alloc, lst_yv12->frame_size, 1, recon_file));
John Koleszar's avatar
John Koleszar committed
821
822
823
824
825
826
827
        fclose(recon_file);
    }

    cm->current_video_frame++;

}

828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
// Estimate a cost per mb attributable to overheads such as the coding of
// modes and motion vectors.
// Currently simplistic in its assumptions for testing.
//


double bitcost( double prob )
{
    return -(log( prob ) / log( 2.0 ));
}
static long long estimate_modemvcost(VP8_COMP *cpi,
                                     FIRSTPASS_STATS * fpstats)
{
    int mv_cost;
    int mode_cost;

    double av_pct_inter = fpstats->pcnt_inter / fpstats->count;
    double av_pct_motion = fpstats->pcnt_motion / fpstats->count;
    double av_intra = (1.0 - av_pct_inter);

    double zz_cost;
    double motion_cost;
    double intra_cost;

    zz_cost = bitcost(av_pct_inter - av_pct_motion);
    motion_cost = bitcost(av_pct_motion);
    intra_cost = bitcost(av_intra);

    // Estimate of extra bits per mv overhead for mbs
    // << 9 is the normalization to the (bits * 512) used in vp8_bits_per_mb
    mv_cost = ((int)(fpstats->new_mv_count / fpstats->count) * 8) << 9;

    // Crude estimate of overhead cost from modes
    // << 9 is the normalization to (bits * 512) used in vp8_bits_per_mb
    mode_cost =
        (int)( ( ((av_pct_inter - av_pct_motion) * zz_cost) +
                 (av_pct_motion * motion_cost) +
                 (av_intra * intra_cost) ) * cpi->common.MBs ) << 9;

Paul Wilkins's avatar
Paul Wilkins committed
867
868
869
    //return mv_cost + mode_cost;
    // TODO PGW Fix overhead costs for extended Q range
    return 0;
870
871
872
873
874
875
876
877
878
879
880
881
}

static double calc_correction_factor( double err_per_mb,
                                      double err_devisor,
                                      double pt_low,
                                      double pt_high,
                                      int Q )
{
    double power_term;
    double error_term = err_per_mb / err_devisor;
    double correction_factor;

882
    // Adjustment based on actual quantizer to power term.
883
    power_term = (vp8_convert_qindex_to_q(Q) * 0.01) + pt_low;
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
    power_term = (power_term > pt_high) ? pt_high : power_term;

    // Adjustments to error term
    // TBD

    // Calculate correction factor
    correction_factor = pow(error_term, power_term);

    // Clip range
    correction_factor =
        (correction_factor < 0.05)
            ? 0.05 : (correction_factor > 5.0) ? 5.0 : correction_factor;

    return correction_factor;
}

Paul Wilkins's avatar
Paul Wilkins committed
900
901
902
903
// Given a current maxQ value sets a range for future values.
// PGW TODO..
// This code removes direct dependency on QIndex to determin the range
// (now uses the actual quantizer) but has not been tuned.
904
static double adjust_maxq_qrange(VP8_COMP *cpi)
Paul Wilkins's avatar
Paul Wilkins committed
905
906
{
    int i;
907
    double q;
Paul Wilkins's avatar
Paul Wilkins committed
908

909
910
    // Set the max corresponding to cpi->avg_q * 2.0
    q = cpi->avg_q * 2.0;
Paul Wilkins's avatar
Paul Wilkins committed
911
    cpi->twopass.maxq_max_limit = cpi->worst_quality;
912
    for ( i = cpi->best_quality; i <= cpi->worst_quality; i++ )
Paul Wilkins's avatar
Paul Wilkins committed
913
    {
914
915
916
        cpi->twopass.maxq_max_limit = i;
        if ( vp8_convert_qindex_to_q(i) >= q )
            break;
Paul Wilkins's avatar
Paul Wilkins committed
917
918
    }

919
920
    // Set the min corresponding to cpi->avg_q * 0.5
    q = cpi->avg_q * 0.5;
Paul Wilkins's avatar
Paul Wilkins committed
921
    cpi->twopass.maxq_min_limit = cpi->best_quality;
922
    for ( i = cpi->worst_quality; i >= cpi->best_quality; i-- )
Paul Wilkins's avatar
Paul Wilkins committed
923
    {
924
925
926
        cpi->twopass.maxq_min_limit = i;
        if ( vp8_convert_qindex_to_q(i) <= q )
            break;
Paul Wilkins's avatar
Paul Wilkins committed
927
928
    }
}
Paul Wilkins's avatar
Paul Wilkins committed
929
#define ERR_DEVISOR   150.0
930
931
932
933
static int estimate_max_q(VP8_COMP *cpi,
                          FIRSTPASS_STATS * fpstats,
                          int section_target_bandwitdh,
                          int overhead_bits )
John Koleszar's avatar
John Koleszar committed
934
935
{
    int Q;
936
    int num_mbs = cpi->common.MBs;
John Koleszar's avatar
John Koleszar committed
937
938
    int target_norm_bits_per_mb;

939
    double section_err = (fpstats->coded_error / fpstats->count);
John Koleszar's avatar
John Koleszar committed
940
    double err_per_mb = section_err / num_mbs;
941
    double err_correction_factor;
John Koleszar's avatar
John Koleszar committed
942
943
    double corr_high;
    double speed_correction = 1.0;
944
945
946
    double inter_pct = (fpstats->pcnt_inter / fpstats->count);
    double intra_pct = 1.0 - inter_pct;
    int overhead_bits_per_mb;
John Koleszar's avatar
John Koleszar committed
947
948

    if (section_target_bandwitdh <= 0)
949
        return cpi->twopass.maxq_max_limit;          // Highest value allowed
John Koleszar's avatar
John Koleszar committed
950

951
952
953
954
    target_norm_bits_per_mb =
        (section_target_bandwitdh < (1 << 20))
            ? (512 * section_target_bandwitdh) / num_mbs
            : 512 * (section_target_bandwitdh / num_mbs);
John Koleszar's avatar
John Koleszar committed
955

956
957
958
959
    // Calculate a corrective factor based on a rolling ratio of bits spent
    // vs target bits
    if ((cpi->rolling_target_bits > 0) &&
        (cpi->active_worst_quality < cpi->worst_quality))
John Koleszar's avatar
John Koleszar committed
960
    {
961
962
        double rolling_ratio;

963
964
        rolling_ratio = (double)cpi->rolling_actual_bits /
                        (double)cpi->rolling_target_bits;
John Koleszar's avatar
John Koleszar committed
965
966

        if (rolling_ratio < 0.95)
967
            cpi->twopass.est_max_qcorrection_factor -= 0.005;
John Koleszar's avatar
John Koleszar committed
968
        else if (rolling_ratio > 1.05)
969
            cpi->twopass.est_max_qcorrection_factor += 0.005;
John Koleszar's avatar
John Koleszar committed
970

971
972
973
974
975
        cpi->twopass.est_max_qcorrection_factor =
            (cpi->twopass.est_max_qcorrection_factor < 0.1)
                ? 0.1
                : (cpi->twopass.est_max_qcorrection_factor > 10.0)
                    ? 10.0 : cpi->twopass.est_max_qcorrection_factor;
John Koleszar's avatar
John Koleszar committed
976
977
    }

978
979
    // Corrections for higher compression speed settings
    // (reduced compression expected)
Paul Wilkins's avatar
Paul Wilkins committed
980
    if (cpi->compressor_speed == 1)
John Koleszar's avatar
John Koleszar committed
981
982
983
984
985
986
987
    {
        if (cpi->oxcf.cpu_used <= 5)
            speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
        else
            speed_correction = 1.25;
    }

988
989
    // Estimate of overhead bits per mb
    // Correction to overhead bits for min allowed Q.
990
    // PGW TODO.. This code is broken for the extended Q range
Paul Wilkins's avatar
Paul Wilkins committed
991
    //            for now overhead set to 0.
992
993
    overhead_bits_per_mb = overhead_bits / num_mbs;
    overhead_bits_per_mb *= pow( 0.98, (double)cpi->twopass.maxq_min_limit );
John Koleszar's avatar
John Koleszar committed
994

Paul Wilkins's avatar
CQ Mode    
Paul Wilkins committed
995
    // Try and pick a max Q that will be high enough to encode the
996
    // content at the given rate.
997
    for (Q = cpi->twopass.maxq_min_limit; Q < cpi->twopass.maxq_max_limit; Q++)
John Koleszar's avatar
John Koleszar committed
998
999
1000
    {
        int bits_per_mb_at_this_q;

1001
1002
        // Error per MB based correction factor
        err_correction_factor =
Paul Wilkins's avatar
Paul Wilkins committed
1003
            calc_correction_factor(err_per_mb, ERR_DEVISOR, 0.36, 0.90, Q);
John Koleszar's avatar
John Koleszar committed
1004

1005
1006
1007
1008
        bits_per_mb_at_this_q =
            vp8_bits_per_mb(INTER_FRAME, Q) + overhead_bits_per_mb;

        bits_per_mb_at_this_q = (int)(.5 + err_correction_factor
1009
1010
            * speed_correction * cpi->twopass.est_max_qcorrection_factor
            * cpi->twopass.section_max_qfactor
1011
1012
1013
1014
1015
            * (double)bits_per_mb_at_this_q);

        // Mode and motion overhead
        // As Q rises in real encode loop rd code will force overhead down
        // We make a crude adjustment for this here as *.98 per Q step.
Paul Wilkins's avatar
Paul Wilkins committed
1016
1017
        // PGW TODO.. This code is broken for the extended Q range
        //            for now overhead set to 0.
1018
        overhead_bits_per_mb = (int)((double)overhead_bits_per_mb * 0.98);
John Koleszar's avatar
John Koleszar committed
1019
1020
1021
1022
1023

        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
            break;
    }

Paul Wilkins's avatar
CQ Mode    
Paul Wilkins committed
1024
1025
1026
1027
1028
1029
1030
    // Restriction on active max q for constrained quality mode.
    if ( (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
         (Q < cpi->cq_target_quality) )
    {
        Q = cpi->cq_target_quality;
    }

Paul Wilkins's avatar
Paul Wilkins committed
1031
    // Adjust maxq_min_limit and maxq_max_limit limits based on
Paul Wilkins's avatar
Paul Wilkins committed
1032
    // averaga q observed in clip for non kf/gf/arf frames
Paul Wilkins's avatar
Paul Wilkins committed
1033
    // Give average a chance to settle though.
1034
    // PGW TODO.. This code is broken for the extended Q range
Paul Wilkins's avatar
Paul Wilkins committed
1035
    if ( (cpi->ni_frames >
1036
                  ((unsigned int)cpi->twopass.total_stats->count >> 8)) &&
Paul Wilkins's avatar
Paul Wilkins committed
1037
1038
         (cpi->ni_frames > 150) )
    {
1039
        adjust_maxq_qrange( cpi );
Paul Wilkins's avatar
Paul Wilkins committed
1040
    }
Paul Wilkins's avatar
Paul Wilkins committed
1041

John Koleszar's avatar
John Koleszar committed
1042
1043
    return Q;
}
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082

// For cq mode estimate a cq level that matches the observed
// complexity and data rate.
static int estimate_cq( VP8_COMP *cpi,
                        FIRSTPASS_STATS * fpstats,
                        int section_target_bandwitdh,
                        int overhead_bits )
{
    int Q;
    int num_mbs = cpi->common.MBs;
    int target_norm_bits_per_mb;

    double section_err = (fpstats->coded_error / fpstats->count);
    double err_per_mb = section_err / num_mbs;
    double err_correction_factor;
    double corr_high;
    double speed_correction = 1.0;
    double clip_iiratio;
    double clip_iifactor;
    double inter_pct = (fpstats->pcnt_inter / fpstats->count);
    double intra_pct = 1.0 - inter_pct;
    int overhead_bits_per_mb;

    if (0)
    {
        FILE *f = fopen("epmp.stt", "a");
        fprintf(f, "%10.2f\n", err_per_mb );
        fclose(f);
    }

    target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20))
                              ? (512 * section_target_bandwitdh) / num_mbs
                              : 512 * (section_target_bandwitdh / num_mbs);

    // Estimate of overhead bits per mb
    overhead_bits_per_mb = overhead_bits / num_mbs;

    // Corrections for higher compression speed settings
    // (reduced compression expected)
Paul Wilkins's avatar
Paul Wilkins committed
1083
    if (cpi->compressor_speed == 1)
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
    {
        if (cpi->oxcf.cpu_used <= 5)
            speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
        else
            speed_correction = 1.25;
    }

    // II ratio correction factor for clip as a whole
    clip_iiratio = cpi->twopass.total_stats->intra_error /
                   DOUBLE_DIVIDE_CHECK(cpi->twopass.total_stats->coded_error);
    clip_iifactor = 1.0 - ((clip_iiratio - 10.0) * 0.025);
    if (clip_iifactor < 0.80)
        clip_iifactor = 0.80;

    // Try and pick a Q that can encode the content at the given rate.
    for (Q = 0; Q < MAXQ; Q++)
    {
        int bits_per_mb_at_this_q;

        // Error per MB based correction factor
        err_correction_factor =
1105
            calc_correction_factor(err_per_mb, 100.0, 0.36, 0.90, Q);
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118

        bits_per_mb_at_this_q =
            vp8_bits_per_mb(INTER_FRAME, Q) + overhead_bits_per_mb;

        bits_per_mb_at_this_q =
            (int)( .5 + err_correction_factor *
                        speed_correction *
                        clip_iifactor *
                        (double)bits_per_mb_at_this_q);

        // Mode and motion overhead
        // As Q rises in real encode loop rd code will force overhead down
        // We make a crude adjustment for this here as *.98 per Q step.
Paul Wilkins's avatar
Paul Wilkins committed
1119
1120
        // PGW TODO.. This code is broken for the extended Q range
        //            for now overhead set to 0.
1121
1122
1123
1124
1125
1126
1127
        overhead_bits_per_mb = (int)((double)overhead_bits_per_mb * 0.98);

        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
            break;
    }

    // Clip value to range "best allowed to (worst allowed - 1)"
Paul Wilkins's avatar
Paul Wilkins committed
1128
    Q = select_cq_level( Q );
1129
1130
1131
1132
1133
1134
1135
1136
    if ( Q >= cpi->worst_quality )
        Q = cpi->worst_quality - 1;
    if ( Q < cpi->best_quality )
        Q = cpi->best_quality;

    return Q;
}

1137
static int estimate_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh)
John Koleszar's avatar
John Koleszar committed
1138
1139
{
    int Q;
1140
    int num_mbs = cpi->common.MBs;
John Koleszar's avatar
John Koleszar committed
1141
1142
1143
    int target_norm_bits_per_mb;

    double err_per_mb = section_err / num_mbs;
1144
    double err_correction_factor;
John Koleszar's avatar
John Koleszar committed
1145
1146
1147
1148
1149
1150
    double corr_high;
    double speed_correction = 1.0;

    target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) ? (512 * section_target_bandwitdh) / num_mbs : 512 * (section_target_bandwitdh / num_mbs);

    // Corrections for higher compression speed settings (reduced compression expected)
Paul Wilkins's avatar
Paul Wilkins committed
1151
    if (cpi->compressor_speed == 1)
John Koleszar's avatar
John Koleszar committed
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
    {
        if (cpi->oxcf.cpu_used <= 5)
            speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
        else
            speed_correction = 1.25;
    }

    // Try and pick a Q that can encode the content at the given rate.
    for (Q = 0; Q < MAXQ; Q++)
    {
        int bits_per_mb_at_this_q;

1164
1165
        // Error per MB based correction factor
        err_correction_factor =
Paul Wilkins's avatar
Paul Wilkins committed
1166
            calc_correction_factor(err_per_mb, ERR_DEVISOR, 0.36, 0.90, Q);
John Koleszar's avatar
John Koleszar committed
1167

Paul Wilkins's avatar
Paul Wilkins committed
1168
        bits_per_mb_at_this_q =
1169
1170
1171
1172
            (int)( .5 + ( err_correction_factor *
                          speed_correction *
                          cpi->twopass.est_max_qcorrection_factor *
                          (double)vp8_bits_per_mb(INTER_FRAME, Q) / 1.0 ) );
John Koleszar's avatar
John Koleszar committed
1173
1174
1175
1176
1177
1178
1179
1180
1181

        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
            break;
    }

    return Q;
}

// Estimate a worst case Q for a KF group
1182
static int estimate_kf_group_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh, double group_iiratio)
John Koleszar's avatar
John Koleszar committed
1183
1184
{
    int Q;
1185
    int num_mbs = cpi->common.MBs;
John Koleszar's avatar
John Koleszar committed
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
    int target_norm_bits_per_mb = (512 * section_target_bandwitdh) / num_mbs;
    int bits_per_mb_at_this_q;

    double err_per_mb = section_err / num_mbs;
    double err_correction_factor;
    double corr_high;
    double speed_correction = 1.0;
    double current_spend_ratio = 1.0;

    double pow_highq = (POW1 < 0.6) ? POW1 + 0.3 : 0.90;
    double pow_lowq = (POW1 < 0.7) ? POW1 + 0.1 : 0.80;

    double iiratio_correction_factor = 1.0;

    double combined_correction_factor;

    // Trap special case where the target is <= 0
    if (target_norm_bits_per_mb <= 0)
        return MAXQ * 2;

    // Calculate a corrective factor based on a rolling ratio of bits spent vs target bits
    // This is clamped to the range 0.1 to 10.0
    if (cpi->long_rolling_target_bits <= 0)
        current_spend_ratio = 10.0;
    else
    {
        current_spend_ratio = (double)cpi->long_rolling_actual_bits / (double)cpi->long_rolling_target_bits;
        current_spend_ratio = (current_spend_ratio > 10.0) ? 10.0 : (current_spend_ratio < 0.1) ? 0.1 : current_spend_ratio;
    }

    // Calculate a correction factor based on the quality of prediction in the sequence as indicated by intra_inter error score ratio (IIRatio)
    // The idea here is to favour subsampling in the hardest sections vs the easyest.
    iiratio_correction_factor = 1.0 - ((group_iiratio - 6.0) * 0.1);

    if (iiratio_correction_factor < 0.5)
        iiratio_correction_factor = 0.5;

    // Corrections for higher compression speed settings (reduced compression expected)
Paul Wilkins's avatar
Paul Wilkins committed
1224
    if (cpi->compressor_speed == 1)
John Koleszar's avatar
John Koleszar committed
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
    {
        if (cpi->oxcf.cpu_used <= 5)
            speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
        else
            speed_correction = 1.25;
    }

    // Combine the various factors calculated above
    combined_correction_factor = speed_correction * iiratio_correction_factor * current_spend_ratio;

    // Try and pick a Q that should be high enough to encode the content at the given rate.
    for (Q = 0; Q < MAXQ; Q++)
    {
1238
1239
        // Error per MB based correction factor
        err_correction_factor =
Paul Wilkins's avatar
Paul Wilkins committed
1240
            calc_correction_factor(err_per_mb, ERR_DEVISOR, pow_lowq, pow_highq, Q);
John Koleszar's avatar
John Koleszar committed
1241

Paul Wilkins's avatar
Paul Wilkins committed
1242
        bits_per_mb_at_this_q =
1243
1244
1245
            (int)(.5 + ( err_correction_factor *
                         combined_correction_factor *
                         (double)vp8_bits_per_mb(INTER_FRAME, Q)) );
John Koleszar's avatar
John Koleszar committed
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270

        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
            break;
    }

    // If we could not hit the target even at Max Q then estimate what Q would have bee required
    while ((bits_per_mb_at_this_q > target_norm_bits_per_mb)  && (Q < (MAXQ * 2)))
    {

        bits_per_mb_at_this_q = (int)(0.96 * bits_per_mb_at_this_q);
        Q++;
    }

    if (0)
    {
        FILE *f = fopen("estkf_q.stt", "a");
        fprintf(f, "%8d %8d %8d %8.2f %8.3f %8.2f %8.3f %8.3f %8.3f %8d\n", cpi->common.current_video_frame, bits_per_mb_at_this_q,
                target_norm_bits_per_mb, err_per_mb, err_correction_factor,
                current_spend_ratio, group_iiratio, iiratio_correction_factor,
                (double)cpi->buffer_level / (double)cpi->oxcf.optimal_buffer_level, Q);
        fclose(f);
    }

    return Q;
}
Paul Wilkins's avatar
CQ Mode    
Paul Wilkins committed
1271

John Koleszar's avatar
John Koleszar committed
1272
1273
1274
1275
1276
1277
1278
1279
1280
extern void vp8_new_frame_rate(VP8_COMP *cpi, double framerate);

void vp8_init_second_pass(VP8_COMP *cpi)
{
    FIRSTPASS_STATS this_frame;
    FIRSTPASS_STATS *start_pos;

    double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth * cpi->oxcf.two_pass_vbrmin_section / 100);

1281
    zero_stats(cpi->twopass.total_stats);
1282
    zero_stats(cpi->twopass.total_left_stats);
John Koleszar's avatar
John Koleszar committed
1283

1284
    if (!cpi->twopass.stats_in_end)
John Koleszar's avatar
John Koleszar committed
1285
1286
        return;

1287
    *cpi->twopass.total_stats = *cpi->twopass.stats_in_end;
1288
    *cpi->twopass.total_left_stats = *cpi->twopass.total_stats;
John Koleszar's avatar
John Koleszar committed
1289
1290
1291
1292
1293
1294

    // each frame can have a different duration, as the frame rate in the source
    // isn't guaranteed to be constant.   The frame rate prior to the first frame
    // encoded in the second pass is a guess.  However the sum duration is not.
    // Its calculated based on the actual durations of all frames from the first
    // pass.
1295
    vp8_new_frame_rate(cpi, 10000000.0 * cpi->twopass.total_stats->count / cpi->twopass.total_stats->duration);
John Koleszar's avatar
John Koleszar committed
1296
1297

    cpi->output_frame_rate = cpi->oxcf.frame_rate;
1298
1299
    cpi->twopass.bits_left = (int64_t)(cpi->twopass.total_stats->duration * cpi->oxcf.target_bandwidth / 10000000.0) ;
    cpi->twopass.bits_left -= (int64_t)(cpi->twopass.total_stats->duration * two_pass_min_rate / 10000000.0);
John Koleszar's avatar
John Koleszar committed
1300

1301
1302
1303
1304
    // Calculate a minimum intra value to be used in determining the IIratio
    // scores used in the second pass. We have this minimum to make sure
    // that clips that are static but "low complexity" in the intra domain
    // are still boosted appropriately for KF/GF/ARF
1305
1306
    cpi->twopass.kf_intra_err_min = KF_MB_INTRA_MIN * cpi->common.MBs;
    cpi->twopass.gf_intra_err_min = GF_MB_INTRA_MIN * cpi->common.MBs;
1307

John Koleszar's avatar
John Koleszar committed
1308
1309
1310
1311
1312
    // Scan the first pass file and calculate an average Intra / Inter error score ratio for the sequence
    {
        double sum_iiratio = 0.0;
        double IIRatio;

1313
        start_pos = cpi->twopass.stats_in;               // Note starting "file" position
John Koleszar's avatar
John Koleszar committed
1314

1315
        while (input_stats(cpi, &this_frame) != EOF)
John Koleszar's avatar
John Koleszar committed
1316
1317
1318
1319
1320
1321
        {
            IIRatio = this_frame.intra_error / DOUBLE_DIVIDE_CHECK(this_frame.coded_error);
            IIRatio = (IIRatio < 1.0) ? 1.0 : (IIRatio > 20.0) ? 20.0 : IIRatio;
            sum_iiratio += IIRatio;
        }

1322
        cpi->twopass.avg_iiratio = sum_iiratio / DOUBLE_DIVIDE_CHECK((double)cpi->twopass.total_stats->count);
John Koleszar's avatar
John Koleszar committed
1323
1324
1325
1326
1327
1328
1329
1330

        // Reset file position
        reset_fpf_position(cpi, start_pos);
    }

    // Scan the first pass file and calculate a modified total error based upon the bias/power function
    // used to allocate bits
    {
1331
        start_pos = cpi->twopass.stats_in;               // Note starting "file" position
John Koleszar's avatar
John Koleszar committed
1332

1333
1334
        cpi->twopass.modified_error_total = 0.0;
        cpi->twopass.modified_error_used = 0.0;
John Koleszar's avatar
John Koleszar committed
1335

1336
        while (input_stats(cpi, &this_frame) != EOF)
John Koleszar's avatar
John Koleszar committed
1337
        {
1338
            cpi->twopass.modified_error_total += calculate_modified_err(cpi, &this_frame);
John Koleszar's avatar
John Koleszar committed
1339
        }
1340
        cpi->twopass.modified_error_left = cpi->twopass.modified_error_total;
John Koleszar's avatar
John Koleszar committed
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350

        reset_fpf_position(cpi, start_pos);            // Reset file position

    }
}

void vp8_end_second_pass(VP8_COMP *cpi)
{
}

Paul Wilkins's avatar
Paul Wilkins committed
1351
// This function gives and estimate of how badly we believe
Adrian Grange's avatar
Adrian Grange committed
1352
// the prediction quality is decaying from frame to frame.
1353
static double get_prediction_decay_rate(VP8_COMP *cpi, FIRSTPASS_STATS *next_frame)
Paul Wilkins's avatar
Paul Wilkins committed
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
{
    double prediction_decay_rate;
    double motion_decay;
    double motion_pct = next_frame->pcnt_motion;

    // Initial basis is the % mbs inter coded
    prediction_decay_rate = next_frame->pcnt_inter;

    // High % motion -> somewhat higher decay rate
    motion_decay = (1.0 - (motion_pct / 20.0));
    if (motion_decay < prediction_decay_rate)
        prediction_decay_rate = motion_decay;

    // Adjustment to decay rate based on speed of motion
    {
        double this_mv_rabs;
        double this_mv_cabs;
        double distance_factor;

        this_mv_rabs = fabs(next_frame->mvr_abs * motion_pct);
        this_mv_cabs = fabs(next_frame->mvc_abs * motion_pct);

        distance_factor = sqrt((this_mv_rabs * this_mv_rabs) +
                               (this_mv_cabs * this_mv_cabs)) / 250.0;
        distance_factor = ((distance_factor > 1.0)
                                ? 0.0 : (1.0 - distance_factor));
        if (distance_factor < prediction_decay_rate)
            prediction_decay_rate = distance_factor;
    }

    return prediction_decay_rate;
}

Paul Wilkins's avatar
Paul Wilkins committed
1387
// Function to test for a condition where a complex transition is followed
1388
1389
// by a static section. For example in slide shows where there is a fade
// between slides. This is to help with more optimal kf and gf positioning.
1390
static int detect_transition_to_still(
1391
1392
1393
1394
1395
1396
1397
1398
1399
    VP8_COMP *cpi,
    int frame_interval,
    int still_interval,
    double loop_decay_rate,
    double decay_accumulator )
{
    BOOL trans_to_still = FALSE;

    // Break clause to detect very still sections after motion
Paul Wilkins's avatar
Paul Wilkins committed
1400
    // For example a static image after a fade or other transition