1474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org/*
2474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *
4474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  Use of this source code is governed by a BSD-style license
5474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  that can be found in the LICENSE file in the root of the source
6474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  tree. An additional intellectual property rights grant can be found
7474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  in the file PATENTS.  All contributing project authors may
8474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  be found in the AUTHORS file in the root of the source tree.
9474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org */
10474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
115c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#include <math.h>
125c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#include <limits.h>
135c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#include <stdio.h>
145c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org
156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "./vpx_scale_rtcd.h"
16474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "block.h"
17474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "onyx_int.h"
185c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#include "vp8/common/variance.h"
19474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "encodeintra.h"
20474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "vp8/common/setupintrarecon.h"
215c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#include "vp8/common/systemdependent.h"
22474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "mcomp.h"
23474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "firstpass.h"
24d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#include "vpx_scale/vpx_scale.h"
25474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "encodemb.h"
26474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "vp8/common/extend.h"
27474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "vpx_mem/vpx_mem.h"
28474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "vp8/common/swapyv12buffer.h"
29474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "rdopt.h"
30474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "vp8/common/quant_common.h"
31474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "encodemv.h"
325c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org#include "encodeframe.h"
33474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
34ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/* #define OUTPUT_FPF 1 */
35474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
36474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgextern void vp8cx_frame_init_quantizer(VP8_COMP *cpi);
37474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgextern void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv);
38474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgextern void vp8_alloc_compressor_data(VP8_COMP *cpi);
39474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
40474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define GFQ_ADJUSTMENT vp8_gf_boost_qadjustment[Q]
41474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgextern int vp8_kf_boost_qadjustment[QINDEX_RANGE];
42474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
43474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgextern const int vp8_gf_boost_qadjustment[QINDEX_RANGE];
44474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
45474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define IIFACTOR   1.5
46474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define IIKFACTOR1 1.40
47474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define IIKFACTOR2 1.5
48474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define RMAX       14.0
49474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define GF_RMAX    48.0
50474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
51474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define KF_MB_INTRA_MIN 300
52474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define GF_MB_INTRA_MIN 200
53474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
54474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define DOUBLE_DIVIDE_CHECK(X) ((X)<0?(X)-.000001:(X)+.000001)
55474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
56474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define POW1 (double)cpi->oxcf.two_pass_vbrbias/100.0
57474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define POW2 (double)cpi->oxcf.two_pass_vbrbias/100.0
58474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
59474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#define NEW_BOOST 1
60474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
61474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic int vscale_lookup[7] = {0, 1, 1, 2, 2, 3, 3};
62474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic int hscale_lookup[7] = {0, 0, 1, 1, 2, 2, 3};
63474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
64474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
65474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const int cq_level[QINDEX_RANGE] =
66474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
67474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    0,0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,
68474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    9,10,11,11,12,13,13,14,15,15,16,17,17,18,19,20,
69474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    20,21,22,22,23,24,24,25,26,27,27,28,29,30,30,31,
70474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    32,33,33,34,35,36,36,37,38,39,39,40,41,42,42,43,
71474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    44,45,46,46,47,48,49,50,50,51,52,53,54,55,55,56,
72474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    57,58,59,60,60,61,62,63,64,65,66,67,67,68,69,70,
73474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    71,72,73,74,75,75,76,77,78,79,80,81,82,83,84,85,
74474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    86,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100
75474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org};
76474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
77474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame);
78474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
79ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/* Resets the first pass file to the given position using a relative seek
80ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org * from the current position
81ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org */
82474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void reset_fpf_position(VP8_COMP *cpi, FIRSTPASS_STATS *Position)
83474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
84474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    cpi->twopass.stats_in = Position;
85474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
86474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
87474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic int lookup_next_frame_stats(VP8_COMP *cpi, FIRSTPASS_STATS *next_frame)
88474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
89474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end)
90474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        return EOF;
91474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
92474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    *next_frame = *cpi->twopass.stats_in;
93474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return 1;
94474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
95474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
96ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/* Read frame stats at an offset from the current position */
97474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic int read_frame_stats( VP8_COMP *cpi,
98474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                             FIRSTPASS_STATS *frame_stats,
99474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                             int offset )
100474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
101474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    FIRSTPASS_STATS * fps_ptr = cpi->twopass.stats_in;
102474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
103ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Check legality of offset */
104474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if ( offset >= 0 )
105474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
106474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if ( &fps_ptr[offset] >= cpi->twopass.stats_in_end )
107474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org             return EOF;
108474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
109474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    else if ( offset < 0 )
110474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
111474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if ( &fps_ptr[offset] < cpi->twopass.stats_in_start )
112474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org             return EOF;
113474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
114474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
115474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    *frame_stats = fps_ptr[offset];
116474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return 1;
117474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
118474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
119474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic int input_stats(VP8_COMP *cpi, FIRSTPASS_STATS *fps)
120474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
121474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end)
122474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        return EOF;
123474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
124474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    *fps = *cpi->twopass.stats_in;
125474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    cpi->twopass.stats_in =
126474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org         (void*)((char *)cpi->twopass.stats_in + sizeof(FIRSTPASS_STATS));
127474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return 1;
128474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
129474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
130474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void output_stats(const VP8_COMP            *cpi,
131474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                         struct vpx_codec_pkt_list *pktlist,
132474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                         FIRSTPASS_STATS            *stats)
133474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
134474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    struct vpx_codec_cx_pkt pkt;
135474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    pkt.kind = VPX_CODEC_STATS_PKT;
136474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    pkt.data.twopass_stats.buf = stats;
137474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    pkt.data.twopass_stats.sz = sizeof(FIRSTPASS_STATS);
138474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    vpx_codec_pkt_list_add(pktlist, &pkt);
139474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
140ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/* TEMP debug code */
141474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if OUTPUT_FPF
142474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
143474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
144474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        FILE *fpfile;
145474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fpfile = fopen("firstpass.stt", "a");
146474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
147474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fprintf(fpfile, "%12.0f %12.0f %12.0f %12.4f %12.4f %12.4f %12.4f"
148474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                " %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f"
149167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                " %12.0f %12.0f %12.4f\n",
150474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                stats->frame,
151474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                stats->intra_error,
152474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                stats->coded_error,
153474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                stats->ssim_weighted_pred_err,
154474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                stats->pcnt_inter,
155474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                stats->pcnt_motion,
156474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                stats->pcnt_second_ref,
157474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                stats->pcnt_neutral,
158474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                stats->MVr,
159474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                stats->mvr_abs,
160474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                stats->MVc,
161474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                stats->mvc_abs,
162474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                stats->MVrv,
163474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                stats->MVcv,
164474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                stats->mv_in_out_count,
165167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                stats->new_mv_count,
166474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                stats->count,
167474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                stats->duration);
168474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fclose(fpfile);
169474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
170474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
171474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
172474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
173474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void zero_stats(FIRSTPASS_STATS *section)
174474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
175474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->frame      = 0.0;
176474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->intra_error = 0.0;
177474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->coded_error = 0.0;
178474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->ssim_weighted_pred_err = 0.0;
179474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->pcnt_inter  = 0.0;
180474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->pcnt_motion  = 0.0;
181474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->pcnt_second_ref = 0.0;
182474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->pcnt_neutral = 0.0;
183474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->MVr        = 0.0;
184474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->mvr_abs     = 0.0;
185474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->MVc        = 0.0;
186474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->mvc_abs     = 0.0;
187474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->MVrv       = 0.0;
188474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->MVcv       = 0.0;
189474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->mv_in_out_count  = 0.0;
190167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->new_mv_count = 0.0;
191474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->count      = 0.0;
192474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->duration   = 1.0;
193474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
194474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
195474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void accumulate_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame)
196474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
197474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->frame += frame->frame;
198474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->intra_error += frame->intra_error;
199474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->coded_error += frame->coded_error;
200474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->ssim_weighted_pred_err += frame->ssim_weighted_pred_err;
201474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->pcnt_inter  += frame->pcnt_inter;
202474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->pcnt_motion += frame->pcnt_motion;
203474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->pcnt_second_ref += frame->pcnt_second_ref;
204474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->pcnt_neutral += frame->pcnt_neutral;
205474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->MVr        += frame->MVr;
206474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->mvr_abs     += frame->mvr_abs;
207474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->MVc        += frame->MVc;
208474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->mvc_abs     += frame->mvc_abs;
209474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->MVrv       += frame->MVrv;
210474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->MVcv       += frame->MVcv;
211474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->mv_in_out_count  += frame->mv_in_out_count;
212167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->new_mv_count += frame->new_mv_count;
213474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->count      += frame->count;
214474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->duration   += frame->duration;
215474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
216474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
217167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.orgstatic void subtract_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame)
218167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org{
219167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->frame -= frame->frame;
220167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->intra_error -= frame->intra_error;
221167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->coded_error -= frame->coded_error;
222167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->ssim_weighted_pred_err -= frame->ssim_weighted_pred_err;
223167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->pcnt_inter  -= frame->pcnt_inter;
224167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->pcnt_motion -= frame->pcnt_motion;
225167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->pcnt_second_ref -= frame->pcnt_second_ref;
226167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->pcnt_neutral -= frame->pcnt_neutral;
227167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->MVr        -= frame->MVr;
228167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->mvr_abs     -= frame->mvr_abs;
229167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->MVc        -= frame->MVc;
230167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->mvc_abs     -= frame->mvc_abs;
231167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->MVrv       -= frame->MVrv;
232167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->MVcv       -= frame->MVcv;
233167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->mv_in_out_count  -= frame->mv_in_out_count;
234167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->new_mv_count -= frame->new_mv_count;
235167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->count      -= frame->count;
236167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    section->duration   -= frame->duration;
237167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org}
238167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
239474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void avg_stats(FIRSTPASS_STATS *section)
240474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
241474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (section->count < 1.0)
242474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        return;
243474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
244474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->intra_error /= section->count;
245474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->coded_error /= section->count;
246474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->ssim_weighted_pred_err /= section->count;
247474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->pcnt_inter  /= section->count;
248474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->pcnt_second_ref /= section->count;
249474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->pcnt_neutral /= section->count;
250474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->pcnt_motion /= section->count;
251474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->MVr        /= section->count;
252474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->mvr_abs     /= section->count;
253474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->MVc        /= section->count;
254474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->mvc_abs     /= section->count;
255474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->MVrv       /= section->count;
256474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->MVcv       /= section->count;
257474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->mv_in_out_count   /= section->count;
258474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    section->duration   /= section->count;
259474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
260474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
261ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/* Calculate a modified Error used in distributing bits between easier
262ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org * and harder frames
263ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org */
264474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic double calculate_modified_err(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
265474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
266167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double av_err = ( cpi->twopass.total_stats.ssim_weighted_pred_err /
267167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                      cpi->twopass.total_stats.count );
268474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double this_err = this_frame->ssim_weighted_pred_err;
269474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double modified_err;
270474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
271474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (this_err > av_err)
272474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        modified_err = av_err * pow((this_err / DOUBLE_DIVIDE_CHECK(av_err)), POW1);
273474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    else
274474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        modified_err = av_err * pow((this_err / DOUBLE_DIVIDE_CHECK(av_err)), POW2);
275474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
276474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return modified_err;
277474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
278474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
279474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const double weight_table[256] = {
280474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
281474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
282474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
283474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
284474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org0.020000, 0.031250, 0.062500, 0.093750, 0.125000, 0.156250, 0.187500, 0.218750,
285474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org0.250000, 0.281250, 0.312500, 0.343750, 0.375000, 0.406250, 0.437500, 0.468750,
286474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org0.500000, 0.531250, 0.562500, 0.593750, 0.625000, 0.656250, 0.687500, 0.718750,
287474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org0.750000, 0.781250, 0.812500, 0.843750, 0.875000, 0.906250, 0.937500, 0.968750,
288474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
289474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
290474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
291474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
292474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
293474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
294474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
295474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
296474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
297474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
298474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
299474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
300474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
301474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
302474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
303474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
304474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
305474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
306474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
307474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
308474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
309474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
310474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
311474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000
312474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org};
313474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
314474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic double simple_weight(YV12_BUFFER_CONFIG *source)
315474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
316474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int i, j;
317474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
318474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    unsigned char *src = source->y_buffer;
319474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double sum_weights = 0.0;
320474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
321ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Loop throught the Y plane raw examining levels and creating a weight
322ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * for the image
323ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
324474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    i = source->y_height;
325474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    do
326474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
327474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        j = source->y_width;
328474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        do
329474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
330474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            sum_weights += weight_table[ *src];
331474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            src++;
332474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }while(--j);
333474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        src -= source->y_width;
334474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        src += source->y_stride;
335474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }while(--i);
336474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
337474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    sum_weights /= (source->y_height * source->y_width);
338474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
339474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return sum_weights;
340474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
341474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
342474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
343ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/* This function returns the current per frame maximum bitrate target */
344474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic int frame_max_bits(VP8_COMP *cpi)
345474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
346ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Max allocation for a single frame based on the max section guidelines
347ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * passed in and how many bits are left
348ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
349474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int max_bits;
350474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
351ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* For CBR we need to also consider buffer fullness.
352ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * If we are running below the optimal level then we need to gradually
353ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * tighten up on max_bits.
354ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
355474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
356474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
357474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double buffer_fullness_ratio = (double)cpi->buffer_level / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.optimal_buffer_level);
358474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
359ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* For CBR base this on the target average bits per frame plus the
360ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * maximum sedction rate passed in by the user
361ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
362474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        max_bits = (int)(cpi->av_per_frame_bandwidth * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
363474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
364ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* If our buffer is below the optimum level */
365474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (buffer_fullness_ratio < 1.0)
366474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
367ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* The lower of max_bits / 4 or cpi->av_per_frame_bandwidth / 4. */
368474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            int min_max_bits = ((cpi->av_per_frame_bandwidth >> 2) < (max_bits >> 2)) ? cpi->av_per_frame_bandwidth >> 2 : max_bits >> 2;
369474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
370474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            max_bits = (int)(max_bits * buffer_fullness_ratio);
371474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
372ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Lowest value we will set ... which should allow the buffer to
373ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * refill.
374ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             */
375474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (max_bits < min_max_bits)
376ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                max_bits = min_max_bits;
377474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
378474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
379ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* VBR */
380474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    else
381474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
382ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* For VBR base this on the bits and frames left plus the
383ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * two_pass_vbrmax_section rate passed in by the user
384ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
385167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        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));
386474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
387474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
388ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Trap case where we are out of bits */
389474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (max_bits < 0)
390474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        max_bits = 0;
391474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
392474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return max_bits;
393474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
394474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
395474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvoid vp8_init_first_pass(VP8_COMP *cpi)
396474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
397167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    zero_stats(&cpi->twopass.total_stats);
398474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
399474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
400474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvoid vp8_end_first_pass(VP8_COMP *cpi)
401474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
402167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    output_stats(cpi, cpi->output_pkt_list, &cpi->twopass.total_stats);
403474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
404474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
4055c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.orgstatic void zz_motion_search( VP8_COMP *cpi, MACROBLOCK * x,
4065c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org                              YV12_BUFFER_CONFIG * raw_buffer,
4075c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org                              int * raw_motion_err,
4085c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org                              YV12_BUFFER_CONFIG * recon_buffer,
4095c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org                              int * best_motion_err, int recon_yoffset)
410474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
411474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    MACROBLOCKD * const xd = & x->e_mbd;
412474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    BLOCK *b = &x->block[0];
413474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    BLOCKD *d = &x->e_mbd.block[0];
414474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
415474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    unsigned char *src_ptr = (*(b->base_src) + b->src);
416474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int src_stride = b->src_stride;
4175c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org    unsigned char *raw_ptr;
4185c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org    int raw_stride = raw_buffer->y_stride;
419474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    unsigned char *ref_ptr;
4205c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org    int ref_stride = x->e_mbd.pre.y_stride;
4215c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org
422ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Set up pointers for this macro block raw buffer */
4235c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org    raw_ptr = (unsigned char *)(raw_buffer->y_buffer + recon_yoffset
4245c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org                                + d->offset);
4255c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org    vp8_mse16x16 ( src_ptr, src_stride, raw_ptr, raw_stride,
4265c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org                   (unsigned int *)(raw_motion_err));
427474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
428ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Set up pointers for this macro block recon buffer */
429474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    xd->pre.y_buffer = recon_buffer->y_buffer + recon_yoffset;
4305c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org    ref_ptr = (unsigned char *)(xd->pre.y_buffer + d->offset );
4315c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org    vp8_mse16x16 ( src_ptr, src_stride, ref_ptr, ref_stride,
4325c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org                   (unsigned int *)(best_motion_err));
433474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
434474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
435474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void first_pass_motion_search(VP8_COMP *cpi, MACROBLOCK *x,
436474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                     int_mv *ref_mv, MV *best_mv,
437474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                     YV12_BUFFER_CONFIG *recon_buffer,
438474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                     int *best_motion_err, int recon_yoffset )
439474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
440474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    MACROBLOCKD *const xd = & x->e_mbd;
441474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    BLOCK *b = &x->block[0];
442474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    BLOCKD *d = &x->e_mbd.block[0];
443474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int num00;
444474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
445474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int_mv tmp_mv;
446474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int_mv ref_mv_full;
447474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
448474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int tmp_err;
449ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    int step_param = 3; /* Dont search over full range for first pass */
450ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
451474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int n;
452474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    vp8_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[BLOCK_16X16];
453474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int new_mv_mode_penalty = 256;
454474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
455ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* override the default variance function to use MSE */
4565c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org    v_fn_ptr.vf    = vp8_mse16x16;
457474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
458ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Set up pointers for this macro block recon buffer */
459474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    xd->pre.y_buffer = recon_buffer->y_buffer + recon_yoffset;
460474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
461ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Initial step/diamond search centred on best mv */
462474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    tmp_mv.as_int = 0;
463474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    ref_mv_full.as_mv.col = ref_mv->as_mv.col>>3;
464474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    ref_mv_full.as_mv.row = ref_mv->as_mv.row>>3;
465474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    tmp_err = cpi->diamond_search_sad(x, b, d, &ref_mv_full, &tmp_mv, step_param,
466474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                      x->sadperbit16, &num00, &v_fn_ptr,
467474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                      x->mvcost, ref_mv);
468474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if ( tmp_err < INT_MAX-new_mv_mode_penalty )
469474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        tmp_err += new_mv_mode_penalty;
470474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
471474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (tmp_err < *best_motion_err)
472474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
473474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        *best_motion_err = tmp_err;
474474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        best_mv->row = tmp_mv.as_mv.row;
475474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        best_mv->col = tmp_mv.as_mv.col;
476474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
477474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
478ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Further step/diamond searches as necessary */
479474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    n = num00;
480474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    num00 = 0;
481474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
482474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    while (n < further_steps)
483474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
484474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        n++;
485474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
486474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (num00)
487474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            num00--;
488474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
489474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
490474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            tmp_err = cpi->diamond_search_sad(x, b, d, &ref_mv_full, &tmp_mv,
491474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                              step_param + n, x->sadperbit16,
492474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                              &num00, &v_fn_ptr, x->mvcost,
493474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                              ref_mv);
494474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if ( tmp_err < INT_MAX-new_mv_mode_penalty )
495474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                tmp_err += new_mv_mode_penalty;
496474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
497474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (tmp_err < *best_motion_err)
498474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            {
499474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                *best_motion_err = tmp_err;
500474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                best_mv->row = tmp_mv.as_mv.row;
501474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                best_mv->col = tmp_mv.as_mv.col;
502474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            }
503474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
504474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
505474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
506474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
507474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvoid vp8_first_pass(VP8_COMP *cpi)
508474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
509474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int mb_row, mb_col;
510474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    MACROBLOCK *const x = & cpi->mb;
511474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    VP8_COMMON *const cm = & cpi->common;
512474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    MACROBLOCKD *const xd = & x->e_mbd;
513474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
514474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int recon_yoffset, recon_uvoffset;
515474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    YV12_BUFFER_CONFIG *lst_yv12 = &cm->yv12_fb[cm->lst_fb_idx];
516474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    YV12_BUFFER_CONFIG *new_yv12 = &cm->yv12_fb[cm->new_fb_idx];
517474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    YV12_BUFFER_CONFIG *gld_yv12 = &cm->yv12_fb[cm->gld_fb_idx];
518474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int recon_y_stride = lst_yv12->y_stride;
519474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int recon_uv_stride = lst_yv12->uv_stride;
520474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int64_t intra_error = 0;
521474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int64_t coded_error = 0;
522474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
523474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int sum_mvr = 0, sum_mvc = 0;
524474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int sum_mvr_abs = 0, sum_mvc_abs = 0;
525474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int sum_mvrs = 0, sum_mvcs = 0;
526474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int mvcount = 0;
527474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int intercount = 0;
528474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int second_ref_count = 0;
529474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int intrapenalty = 256;
530474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int neutral_count = 0;
531167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    int new_mv_count = 0;
532474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int sum_in_vectors = 0;
533167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    uint32_t lastmv_as_int = 0;
534474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
535474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int_mv zero_ref_mv;
536474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
537474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    zero_ref_mv.as_int = 0;
538474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
539ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    vp8_clear_system_state();
540474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
541474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    x->src = * cpi->Source;
542474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    xd->pre = *lst_yv12;
543474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    xd->dst = *new_yv12;
544474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
545474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    x->partition_info = x->pi;
546474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
547474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    xd->mode_info_context = cm->mi;
548474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
549ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    if(!cm->use_bilinear_mc_filter)
550ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    {
551ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         xd->subpixel_predict        = vp8_sixtap_predict4x4;
552ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         xd->subpixel_predict8x4     = vp8_sixtap_predict8x4;
553ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         xd->subpixel_predict8x8     = vp8_sixtap_predict8x8;
554ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         xd->subpixel_predict16x16   = vp8_sixtap_predict16x16;
555ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     }
556ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     else
557ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     {
558ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         xd->subpixel_predict        = vp8_bilinear_predict4x4;
559ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         xd->subpixel_predict8x4     = vp8_bilinear_predict8x4;
560ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         xd->subpixel_predict8x8     = vp8_bilinear_predict8x8;
561ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         xd->subpixel_predict16x16   = vp8_bilinear_predict16x16;
562ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     }
563474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
564ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    vp8_build_block_offsets(x);
565474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
566ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* set up frame new frame for intra coded blocks */
567474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    vp8_setup_intra_recon(new_yv12);
568474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    vp8cx_frame_init_quantizer(cpi);
569474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
570ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Initialise the MV cost table to the defaults */
571474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
572474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int flag[2] = {1, 1};
573d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org        vp8_initialize_rd_consts(cpi, x, vp8_dc_quant(cm->base_qindex, cm->y1dc_delta_q));
574474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        vpx_memcpy(cm->fc.mvc, vp8_default_mv_context, sizeof(vp8_default_mv_context));
575474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        vp8_build_component_cost_table(cpi->mb.mvcost, (const MV_CONTEXT *) cm->fc.mvc, flag);
576474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
577474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
578ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* for each macroblock row in image */
579474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    for (mb_row = 0; mb_row < cm->mb_rows; mb_row++)
580474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
581474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int_mv best_ref_mv;
582474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
583474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        best_ref_mv.as_int = 0;
584474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
585ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* reset above block coeffs */
586474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        xd->up_available = (mb_row != 0);
587474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        recon_yoffset = (mb_row * recon_y_stride * 16);
588474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        recon_uvoffset = (mb_row * recon_uv_stride * 8);
589474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
590ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Set up limit values for motion vectors to prevent them extending
591ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * outside the UMV borders
592ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
593474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        x->mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 16));
594474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16) + (VP8BORDERINPIXELS - 16);
595474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
596474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
597ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* for each macroblock col in image */
598474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
599474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
600474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            int this_error;
601474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            int gf_motion_error = INT_MAX;
602474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
603474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
604474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            xd->dst.y_buffer = new_yv12->y_buffer + recon_yoffset;
605474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            xd->dst.u_buffer = new_yv12->u_buffer + recon_uvoffset;
606474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            xd->dst.v_buffer = new_yv12->v_buffer + recon_uvoffset;
607474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            xd->left_available = (mb_col != 0);
608474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
609ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Copy current mb to a buffer */
6105c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org            vp8_copy_mem16x16(x->src.y_buffer, x->src.y_stride, x->thismb, 16);
611474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
612ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* do intra 16x16 prediction */
613474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            this_error = vp8_encode_intra(cpi, x, use_dc_pred);
614474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
615ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* "intrapenalty" below deals with situations where the intra
616ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * and inter error scores are very low (eg a plain black frame)
617ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * We do not have special cases in first pass for 0,0 and
618ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * nearest etc so all inter modes carry an overhead cost
619ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * estimate fot the mv. When the error score is very low this
620ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * causes us to pick all or lots of INTRA modes and throw lots
621ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * of key frames. This penalty adds a cost matching that of a
622ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * 0,0 mv to the intra case.
623ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             */
624474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            this_error += intrapenalty;
625474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
626ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Cumulative intra error total */
627474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            intra_error += (int64_t)this_error;
628474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
629ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Set up limit values for motion vectors to prevent them
630ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * extending outside the UMV borders
631ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             */
632474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16));
633474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16) + (VP8BORDERINPIXELS - 16);
634474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
635ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Other than for the first frame do a motion search */
636474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (cm->current_video_frame > 0)
637474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            {
638474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                BLOCKD *d = &x->e_mbd.block[0];
639474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                MV tmp_mv = {0, 0};
640474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                int tmp_err;
641474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                int motion_error = INT_MAX;
6425c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org                int raw_motion_error = INT_MAX;
643474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
644ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                /* Simple 0,0 motion with no mv overhead */
6455c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org                zz_motion_search( cpi, x, cpi->last_frame_unscaled_source,
6465c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org                                  &raw_motion_error, lst_yv12, &motion_error,
6475c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org                                  recon_yoffset );
648474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                d->bmi.mv.as_mv.row = 0;
649474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                d->bmi.mv.as_mv.col = 0;
650474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
6515c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org                if (raw_motion_error < cpi->oxcf.encode_breakout)
6525c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org                    goto skip_motion_search;
6535c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org
654ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                /* Test last reference frame using the previous best mv as the
655ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                 * starting point (best reference) for the search
656ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                 */
657474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                first_pass_motion_search(cpi, x, &best_ref_mv,
658474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                        &d->bmi.mv.as_mv, lst_yv12,
659474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                        &motion_error, recon_yoffset);
660474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
661ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                /* If the current best reference mv is not centred on 0,0
662ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                 * then do a 0,0 based search as well
663ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                 */
664474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                if (best_ref_mv.as_int)
665474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                {
666474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                   tmp_err = INT_MAX;
667474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                   first_pass_motion_search(cpi, x, &zero_ref_mv, &tmp_mv,
668474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                     lst_yv12, &tmp_err, recon_yoffset);
669474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
670474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                   if ( tmp_err < motion_error )
671474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                   {
672474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        motion_error = tmp_err;
673474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        d->bmi.mv.as_mv.row = tmp_mv.row;
674474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        d->bmi.mv.as_mv.col = tmp_mv.col;
675474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                   }
676474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                }
677474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
678ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                /* Experimental search in a second reference frame ((0,0)
679ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                 * based only)
680ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                 */
681474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                if (cm->current_video_frame > 1)
682474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                {
683474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    first_pass_motion_search(cpi, x, &zero_ref_mv, &tmp_mv, gld_yv12, &gf_motion_error, recon_yoffset);
684474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
685474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    if ((gf_motion_error < motion_error) && (gf_motion_error < this_error))
686474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    {
687474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        second_ref_count++;
688474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    }
689474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
690ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                    /* Reset to last frame as reference buffer */
691474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    xd->pre.y_buffer = lst_yv12->y_buffer + recon_yoffset;
692474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    xd->pre.u_buffer = lst_yv12->u_buffer + recon_uvoffset;
693474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    xd->pre.v_buffer = lst_yv12->v_buffer + recon_uvoffset;
694474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                }
695474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
6965c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.orgskip_motion_search:
697474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                /* Intra assumed best */
698474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                best_ref_mv.as_int = 0;
699474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
700474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                if (motion_error <= this_error)
701474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                {
702ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                    /* Keep a count of cases where the inter and intra were
703ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                     * very close and very low. This helps with scene cut
704ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                     * detection for example in cropped clips with black bars
705ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                     * at the sides or top and bottom.
706ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                     */
707474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    if( (((this_error-intrapenalty) * 9) <=
708474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                         (motion_error*10)) &&
709474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        (this_error < (2*intrapenalty)) )
710474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    {
711474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        neutral_count++;
712474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    }
713474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
714085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org                    d->bmi.mv.as_mv.row *= 8;
715085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org                    d->bmi.mv.as_mv.col *= 8;
716474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    this_error = motion_error;
717474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    vp8_set_mbmode_and_mvs(x, NEWMV, &d->bmi.mv);
7185c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org                    vp8_encode_inter16x16y(x);
719474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    sum_mvr += d->bmi.mv.as_mv.row;
720474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    sum_mvr_abs += abs(d->bmi.mv.as_mv.row);
721474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    sum_mvc += d->bmi.mv.as_mv.col;
722474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    sum_mvc_abs += abs(d->bmi.mv.as_mv.col);
723474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    sum_mvrs += d->bmi.mv.as_mv.row * d->bmi.mv.as_mv.row;
724474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    sum_mvcs += d->bmi.mv.as_mv.col * d->bmi.mv.as_mv.col;
725474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    intercount++;
726474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
727474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    best_ref_mv.as_int = d->bmi.mv.as_int;
728474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
729ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                    /* Was the vector non-zero */
730474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    if (d->bmi.mv.as_int)
731474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    {
732474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        mvcount++;
733474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
734ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                        /* Was it different from the last non zero vector */
735167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                        if ( d->bmi.mv.as_int != lastmv_as_int )
736167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                            new_mv_count++;
737167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                        lastmv_as_int = d->bmi.mv.as_int;
738167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
739ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                        /* Does the Row vector point inwards or outwards */
740474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        if (mb_row < cm->mb_rows / 2)
741474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        {
742474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                            if (d->bmi.mv.as_mv.row > 0)
743474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                sum_in_vectors--;
744474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                            else if (d->bmi.mv.as_mv.row < 0)
745474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                sum_in_vectors++;
746474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        }
747474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        else if (mb_row > cm->mb_rows / 2)
748474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        {
749474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                            if (d->bmi.mv.as_mv.row > 0)
750474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                sum_in_vectors++;
751474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                            else if (d->bmi.mv.as_mv.row < 0)
752474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                sum_in_vectors--;
753474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        }
754474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
755ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                        /* Does the Row vector point inwards or outwards */
756474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        if (mb_col < cm->mb_cols / 2)
757474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        {
758474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                            if (d->bmi.mv.as_mv.col > 0)
759474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                sum_in_vectors--;
760474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                            else if (d->bmi.mv.as_mv.col < 0)
761474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                sum_in_vectors++;
762474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        }
763474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        else if (mb_col > cm->mb_cols / 2)
764474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        {
765474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                            if (d->bmi.mv.as_mv.col > 0)
766474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                sum_in_vectors++;
767474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                            else if (d->bmi.mv.as_mv.col < 0)
768474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                sum_in_vectors--;
769474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        }
770474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    }
771474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                }
772474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            }
773474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
774474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            coded_error += (int64_t)this_error;
775474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
776ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* adjust to the next column of macroblocks */
777474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            x->src.y_buffer += 16;
778474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            x->src.u_buffer += 8;
779474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            x->src.v_buffer += 8;
780474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
781474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            recon_yoffset += 16;
782474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            recon_uvoffset += 8;
783474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
784474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
785ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* adjust to the next row of mbs */
786474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        x->src.y_buffer += 16 * x->src.y_stride - 16 * cm->mb_cols;
787474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        x->src.u_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols;
788474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        x->src.v_buffer += 8 * x->src.uv_stride - 8 * cm->mb_cols;
789474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
790ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* extend the recon for intra prediction */
791474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        vp8_extend_mb_row(new_yv12, xd->dst.y_buffer + 16, xd->dst.u_buffer + 8, xd->dst.v_buffer + 8);
792ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        vp8_clear_system_state();
793474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
794474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
795ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    vp8_clear_system_state();
796474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
797474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double weight = 0.0;
798474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
799474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        FIRSTPASS_STATS fps;
800474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
801474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fps.frame      = cm->current_video_frame ;
802ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        fps.intra_error = (double)(intra_error >> 8);
803ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        fps.coded_error = (double)(coded_error >> 8);
804474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        weight = simple_weight(cpi->Source);
805474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
806474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
807474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (weight < 0.1)
808474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            weight = 0.1;
809474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
810474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fps.ssim_weighted_pred_err = fps.coded_error * weight;
811474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
812474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fps.pcnt_inter  = 0.0;
813474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fps.pcnt_motion = 0.0;
814474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fps.MVr        = 0.0;
815474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fps.mvr_abs     = 0.0;
816474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fps.MVc        = 0.0;
817474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fps.mvc_abs     = 0.0;
818474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fps.MVrv       = 0.0;
819474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fps.MVcv       = 0.0;
820474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fps.mv_in_out_count  = 0.0;
821167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        fps.new_mv_count = 0.0;
822474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fps.count      = 1.0;
823474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
824474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fps.pcnt_inter   = 1.0 * (double)intercount / cm->MBs;
825474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fps.pcnt_second_ref = 1.0 * (double)second_ref_count / cm->MBs;
826474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fps.pcnt_neutral = 1.0 * (double)neutral_count / cm->MBs;
827474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
828474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (mvcount > 0)
829474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
830474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            fps.MVr = (double)sum_mvr / (double)mvcount;
831474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            fps.mvr_abs = (double)sum_mvr_abs / (double)mvcount;
832474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            fps.MVc = (double)sum_mvc / (double)mvcount;
833474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            fps.mvc_abs = (double)sum_mvc_abs / (double)mvcount;
834474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            fps.MVrv = ((double)sum_mvrs - (fps.MVr * fps.MVr / (double)mvcount)) / (double)mvcount;
835474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            fps.MVcv = ((double)sum_mvcs - (fps.MVc * fps.MVc / (double)mvcount)) / (double)mvcount;
836474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            fps.mv_in_out_count = (double)sum_in_vectors / (double)(mvcount * 2);
837167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            fps.new_mv_count = new_mv_count;
838474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
839474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            fps.pcnt_motion = 1.0 * (double)mvcount / cpi->common.MBs;
840474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
841474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
842ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* TODO:  handle the case when duration is set to 0, or something less
843ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * than the full time between subsequent cpi->source_time_stamps
844ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
845ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        fps.duration = (double)(cpi->source->ts_end
846ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                       - cpi->source->ts_start);
847474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
848ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* don't want to do output stats with a stack variable! */
849167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        memcpy(&cpi->twopass.this_frame_stats,
850474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org               &fps,
851474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org               sizeof(FIRSTPASS_STATS));
852167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        output_stats(cpi, cpi->output_pkt_list, &cpi->twopass.this_frame_stats);
853167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        accumulate_stats(&cpi->twopass.total_stats, &fps);
854474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
855474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
856ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Copy the previous Last Frame into the GF buffer if specific
857ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * conditions for doing so are met
858ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
859474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if ((cm->current_video_frame > 0) &&
860167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        (cpi->twopass.this_frame_stats.pcnt_inter > 0.20) &&
8614b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org        ((cpi->twopass.this_frame_stats.intra_error /
8624b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org          DOUBLE_DIVIDE_CHECK(cpi->twopass.this_frame_stats.coded_error)) >
8634b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org         2.0))
864474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
8655c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org        vp8_yv12_copy_frame(lst_yv12, gld_yv12);
866474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
867474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
868ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* swap frame pointers so last frame refers to the frame we just
869ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * compressed
870ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
871474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    vp8_swap_yv12_buffer(lst_yv12, new_yv12);
872474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    vp8_yv12_extend_frame_borders(lst_yv12);
873474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
874ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Special case for the first frame. Copy into the GF buffer as a
875ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * second reference.
876ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
877474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cm->current_video_frame == 0)
878474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
8795c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org        vp8_yv12_copy_frame(lst_yv12, gld_yv12);
880474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
881474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
882474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
883ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* use this to see what the first pass reconstruction looks like */
884474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (0)
885474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
886474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        char filename[512];
887474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        FILE *recon_file;
888474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        sprintf(filename, "enc%04d.yuv", (int) cm->current_video_frame);
889474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
890474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cm->current_video_frame == 0)
891474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            recon_file = fopen(filename, "wb");
892474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
893474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            recon_file = fopen(filename, "ab");
894474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
895ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        (void) fwrite(lst_yv12->buffer_alloc, lst_yv12->frame_size, 1,
896ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                      recon_file);
897474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fclose(recon_file);
898474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
899474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
900474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    cm->current_video_frame++;
901474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
902474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
903474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgextern const int vp8_bits_per_mb[2][QINDEX_RANGE];
904474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
905ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/* Estimate a cost per mb attributable to overheads such as the coding of
906ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org * modes and motion vectors.
907ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org * Currently simplistic in its assumptions for testing.
908ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org */
909167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
9105c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.orgstatic double bitcost( double prob )
911167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org{
912085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  if (prob > 0.000122)
913085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    return -log(prob) / log(2.0);
914085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org  else
915085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    return 13.0;
916167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org}
917167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.orgstatic int64_t estimate_modemvcost(VP8_COMP *cpi,
918167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                                     FIRSTPASS_STATS * fpstats)
919167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org{
920167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    int mv_cost;
921085cab8fbb48aa8b9f7e3e6d5a2694afd0ffe2e0johannkoenig@chromium.org    int64_t mode_cost;
922167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
923167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double av_pct_inter = fpstats->pcnt_inter / fpstats->count;
924167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double av_pct_motion = fpstats->pcnt_motion / fpstats->count;
925167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double av_intra = (1.0 - av_pct_inter);
926167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
927167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double zz_cost;
928167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double motion_cost;
929167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double intra_cost;
930167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
931167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    zz_cost = bitcost(av_pct_inter - av_pct_motion);
932167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    motion_cost = bitcost(av_pct_motion);
933167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    intra_cost = bitcost(av_intra);
934167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
935ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Estimate of extra bits per mv overhead for mbs
936ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * << 9 is the normalization to the (bits * 512) used in vp8_bits_per_mb
937ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
938167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    mv_cost = ((int)(fpstats->new_mv_count / fpstats->count) * 8) << 9;
939167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
940ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Crude estimate of overhead cost from modes
941ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * << 9 is the normalization to (bits * 512) used in vp8_bits_per_mb
942ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
94376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org    mode_cost = (int64_t)((((av_pct_inter - av_pct_motion) * zz_cost) +
94476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                             (av_pct_motion * motion_cost) +
94576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                             (av_intra * intra_cost)) * cpi->common.MBs) * 512;
946167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
947167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    return mv_cost + mode_cost;
948167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org}
949167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
950167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.orgstatic double calc_correction_factor( double err_per_mb,
951167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                                      double err_devisor,
952167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                                      double pt_low,
953167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                                      double pt_high,
954167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                                      int Q )
955167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org{
956167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double power_term;
957167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double error_term = err_per_mb / err_devisor;
958167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double correction_factor;
959167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
960ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Adjustment based on Q to power term. */
961167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    power_term = pt_low + (Q * 0.01);
962167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    power_term = (power_term > pt_high) ? pt_high : power_term;
963167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
964ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Adjustments to error term */
965ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* TBD */
966167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
967ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Calculate correction factor */
968167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    correction_factor = pow(error_term, power_term);
969167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
970ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Clip range */
971167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    correction_factor =
972167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        (correction_factor < 0.05)
973167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            ? 0.05 : (correction_factor > 5.0) ? 5.0 : correction_factor;
974167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
975167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    return correction_factor;
976167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org}
977167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
978167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.orgstatic int estimate_max_q(VP8_COMP *cpi,
979167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                          FIRSTPASS_STATS * fpstats,
980167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                          int section_target_bandwitdh,
981167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                          int overhead_bits )
982474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
983474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int Q;
984474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int num_mbs = cpi->common.MBs;
985474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int target_norm_bits_per_mb;
986474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
987167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double section_err = (fpstats->coded_error / fpstats->count);
988474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double err_per_mb = section_err / num_mbs;
989167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double err_correction_factor;
990474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double speed_correction = 1.0;
991167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    int overhead_bits_per_mb;
992474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
993474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (section_target_bandwitdh <= 0)
994ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        return cpi->twopass.maxq_max_limit;       /* Highest value allowed */
995474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
996167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    target_norm_bits_per_mb =
997167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        (section_target_bandwitdh < (1 << 20))
998167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            ? (512 * section_target_bandwitdh) / num_mbs
999167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            : 512 * (section_target_bandwitdh / num_mbs);
1000474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1001ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Calculate a corrective factor based on a rolling ratio of bits spent
1002ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * vs target bits
1003ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1004167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    if ((cpi->rolling_target_bits > 0) &&
1005167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        (cpi->active_worst_quality < cpi->worst_quality))
1006474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1007167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        double rolling_ratio;
1008167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1009167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        rolling_ratio = (double)cpi->rolling_actual_bits /
1010167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                        (double)cpi->rolling_target_bits;
1011474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1012474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (rolling_ratio < 0.95)
1013474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->twopass.est_max_qcorrection_factor -= 0.005;
1014474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else if (rolling_ratio > 1.05)
1015474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->twopass.est_max_qcorrection_factor += 0.005;
1016474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1017474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.est_max_qcorrection_factor =
1018474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            (cpi->twopass.est_max_qcorrection_factor < 0.1)
1019474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                ? 0.1
1020474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                : (cpi->twopass.est_max_qcorrection_factor > 10.0)
1021474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    ? 10.0 : cpi->twopass.est_max_qcorrection_factor;
1022474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1023474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1024ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Corrections for higher compression speed settings
1025ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * (reduced compression expected)
1026ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1027474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1))
1028474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1029474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->oxcf.cpu_used <= 5)
1030474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
1031474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
1032474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            speed_correction = 1.25;
1033474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1034474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1035ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Estimate of overhead bits per mb */
1036ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Correction to overhead bits for min allowed Q. */
1037167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    overhead_bits_per_mb = overhead_bits / num_mbs;
1038ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    overhead_bits_per_mb = (int)(overhead_bits_per_mb *
1039ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                            pow( 0.98, (double)cpi->twopass.maxq_min_limit ));
1040474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1041ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Try and pick a max Q that will be high enough to encode the
1042ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * content at the given rate.
1043ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1044474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    for (Q = cpi->twopass.maxq_min_limit; Q < cpi->twopass.maxq_max_limit; Q++)
1045474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1046474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int bits_per_mb_at_this_q;
1047474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1048ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Error per MB based correction factor */
1049167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        err_correction_factor =
1050167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            calc_correction_factor(err_per_mb, 150.0, 0.40, 0.90, Q);
1051167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1052167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        bits_per_mb_at_this_q =
1053167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            vp8_bits_per_mb[INTER_FRAME][Q] + overhead_bits_per_mb;
1054474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1055167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        bits_per_mb_at_this_q = (int)(.5 + err_correction_factor
1056474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            * speed_correction * cpi->twopass.est_max_qcorrection_factor
1057474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            * cpi->twopass.section_max_qfactor
1058167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            * (double)bits_per_mb_at_this_q);
1059167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1060ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Mode and motion overhead */
1061ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* As Q rises in real encode loop rd code will force overhead down
1062ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * We make a crude adjustment for this here as *.98 per Q step.
1063ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
1064167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        overhead_bits_per_mb = (int)((double)overhead_bits_per_mb * 0.98);
1065474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1066474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
1067474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            break;
1068474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1069474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1070ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Restriction on active max q for constrained quality mode. */
1071474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if ( (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) &&
1072474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org         (Q < cpi->cq_target_quality) )
1073474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1074474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        Q = cpi->cq_target_quality;
1075474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1076474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1077ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Adjust maxq_min_limit and maxq_max_limit limits based on
1078ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * average q observed in clip for non kf/gf.arf frames
1079ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * Give average a chance to settle though.
1080ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1081474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if ( (cpi->ni_frames >
1082ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                  ((int)cpi->twopass.total_stats.count >> 8)) &&
1083474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org         (cpi->ni_frames > 150) )
1084474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1085474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.maxq_max_limit = ((cpi->ni_av_qi + 32) < cpi->worst_quality)
1086474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                  ? (cpi->ni_av_qi + 32) : cpi->worst_quality;
1087474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.maxq_min_limit = ((cpi->ni_av_qi - 32) > cpi->best_quality)
1088474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                  ? (cpi->ni_av_qi - 32) : cpi->best_quality;
1089474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1090474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1091474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return Q;
1092474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
1093167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1094ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/* For cq mode estimate a cq level that matches the observed
1095ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org * complexity and data rate.
1096ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org */
1097167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.orgstatic int estimate_cq( VP8_COMP *cpi,
1098167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                        FIRSTPASS_STATS * fpstats,
1099167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                        int section_target_bandwitdh,
1100167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                        int overhead_bits )
1101167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org{
1102167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    int Q;
1103167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    int num_mbs = cpi->common.MBs;
1104167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    int target_norm_bits_per_mb;
1105167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1106167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double section_err = (fpstats->coded_error / fpstats->count);
1107167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double err_per_mb = section_err / num_mbs;
1108167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double err_correction_factor;
1109167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double speed_correction = 1.0;
1110167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double clip_iiratio;
1111167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double clip_iifactor;
1112167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    int overhead_bits_per_mb;
1113167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1114167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    if (0)
1115167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    {
1116167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        FILE *f = fopen("epmp.stt", "a");
1117167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        fprintf(f, "%10.2f\n", err_per_mb );
1118167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        fclose(f);
1119167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    }
1120167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1121167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20))
1122167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                              ? (512 * section_target_bandwitdh) / num_mbs
1123167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                              : 512 * (section_target_bandwitdh / num_mbs);
1124167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1125ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Estimate of overhead bits per mb */
1126167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    overhead_bits_per_mb = overhead_bits / num_mbs;
1127167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1128ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Corrections for higher compression speed settings
1129ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * (reduced compression expected)
1130ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1131167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1))
1132167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    {
1133167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        if (cpi->oxcf.cpu_used <= 5)
1134167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
1135167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        else
1136167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            speed_correction = 1.25;
1137167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    }
1138167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1139ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* II ratio correction factor for clip as a whole */
1140167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    clip_iiratio = cpi->twopass.total_stats.intra_error /
1141167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                   DOUBLE_DIVIDE_CHECK(cpi->twopass.total_stats.coded_error);
1142167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    clip_iifactor = 1.0 - ((clip_iiratio - 10.0) * 0.025);
1143167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    if (clip_iifactor < 0.80)
1144167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        clip_iifactor = 0.80;
1145167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1146ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Try and pick a Q that can encode the content at the given rate. */
1147167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    for (Q = 0; Q < MAXQ; Q++)
1148167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    {
1149167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        int bits_per_mb_at_this_q;
1150167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1151ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Error per MB based correction factor */
1152167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        err_correction_factor =
1153167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            calc_correction_factor(err_per_mb, 100.0, 0.40, 0.90, Q);
1154167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1155167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        bits_per_mb_at_this_q =
1156167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            vp8_bits_per_mb[INTER_FRAME][Q] + overhead_bits_per_mb;
1157167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1158167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        bits_per_mb_at_this_q =
1159167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            (int)( .5 + err_correction_factor *
1160167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                        speed_correction *
1161167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                        clip_iifactor *
1162167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                        (double)bits_per_mb_at_this_q);
1163167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1164ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Mode and motion overhead */
1165ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* As Q rises in real encode loop rd code will force overhead down
1166ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * We make a crude adjustment for this here as *.98 per Q step.
1167ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
1168167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        overhead_bits_per_mb = (int)((double)overhead_bits_per_mb * 0.98);
1169167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1170167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
1171167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            break;
1172167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    }
1173167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1174ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Clip value to range "best allowed to (worst allowed - 1)" */
1175167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    Q = cq_level[Q];
1176167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    if ( Q >= cpi->worst_quality )
1177167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        Q = cpi->worst_quality - 1;
1178167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    if ( Q < cpi->best_quality )
1179167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        Q = cpi->best_quality;
1180167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1181167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    return Q;
1182167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org}
1183167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
1184474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic int estimate_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh)
1185474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
1186474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int Q;
1187474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int num_mbs = cpi->common.MBs;
1188474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int target_norm_bits_per_mb;
1189474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1190474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double err_per_mb = section_err / num_mbs;
1191167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    double err_correction_factor;
1192474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double speed_correction = 1.0;
1193474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1194474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    target_norm_bits_per_mb = (section_target_bandwitdh < (1 << 20)) ? (512 * section_target_bandwitdh) / num_mbs : 512 * (section_target_bandwitdh / num_mbs);
1195474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1196ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Corrections for higher compression speed settings
1197ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * (reduced compression expected)
1198ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1199474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1))
1200474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1201474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->oxcf.cpu_used <= 5)
1202474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
1203474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
1204474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            speed_correction = 1.25;
1205474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1206474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1207ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Try and pick a Q that can encode the content at the given rate. */
1208474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    for (Q = 0; Q < MAXQ; Q++)
1209474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1210474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int bits_per_mb_at_this_q;
1211474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1212ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Error per MB based correction factor */
1213167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        err_correction_factor =
1214167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            calc_correction_factor(err_per_mb, 150.0, 0.40, 0.90, Q);
1215474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1216167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        bits_per_mb_at_this_q =
1217167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            (int)( .5 + ( err_correction_factor *
1218167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                          speed_correction *
1219167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                          cpi->twopass.est_max_qcorrection_factor *
1220167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                          (double)vp8_bits_per_mb[INTER_FRAME][Q] / 1.0 ) );
1221474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1222474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
1223474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            break;
1224474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1225474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1226474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return Q;
1227474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
1228474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1229ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/* Estimate a worst case Q for a KF group */
1230474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic int estimate_kf_group_q(VP8_COMP *cpi, double section_err, int section_target_bandwitdh, double group_iiratio)
1231474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
1232474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int Q;
1233474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int num_mbs = cpi->common.MBs;
1234474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int target_norm_bits_per_mb = (512 * section_target_bandwitdh) / num_mbs;
1235474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int bits_per_mb_at_this_q;
1236474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1237474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double err_per_mb = section_err / num_mbs;
1238474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double err_correction_factor;
1239474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double speed_correction = 1.0;
1240474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double current_spend_ratio = 1.0;
1241474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1242474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double pow_highq = (POW1 < 0.6) ? POW1 + 0.3 : 0.90;
1243474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double pow_lowq = (POW1 < 0.7) ? POW1 + 0.1 : 0.80;
1244474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1245474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double iiratio_correction_factor = 1.0;
1246474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1247474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double combined_correction_factor;
1248474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1249ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Trap special case where the target is <= 0 */
1250474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (target_norm_bits_per_mb <= 0)
1251474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        return MAXQ * 2;
1252474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1253ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Calculate a corrective factor based on a rolling ratio of bits spent
1254ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     *  vs target bits
1255ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * This is clamped to the range 0.1 to 10.0
1256ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1257474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cpi->long_rolling_target_bits <= 0)
1258474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        current_spend_ratio = 10.0;
1259474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    else
1260474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1261474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        current_spend_ratio = (double)cpi->long_rolling_actual_bits / (double)cpi->long_rolling_target_bits;
1262474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        current_spend_ratio = (current_spend_ratio > 10.0) ? 10.0 : (current_spend_ratio < 0.1) ? 0.1 : current_spend_ratio;
1263474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1264474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1265ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Calculate a correction factor based on the quality of prediction in
1266ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * the sequence as indicated by intra_inter error score ratio (IIRatio)
1267ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * The idea here is to favour subsampling in the hardest sections vs
1268ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * the easyest.
1269ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1270474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    iiratio_correction_factor = 1.0 - ((group_iiratio - 6.0) * 0.1);
1271474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1272474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (iiratio_correction_factor < 0.5)
1273474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        iiratio_correction_factor = 0.5;
1274474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1275ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Corrections for higher compression speed settings
1276ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * (reduced compression expected)
1277ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1278474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if ((cpi->compressor_speed == 3) || (cpi->compressor_speed == 1))
1279474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1280474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->oxcf.cpu_used <= 5)
1281474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            speed_correction = 1.04 + (cpi->oxcf.cpu_used * 0.04);
1282474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
1283474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            speed_correction = 1.25;
1284474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1285474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1286ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Combine the various factors calculated above */
1287474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    combined_correction_factor = speed_correction * iiratio_correction_factor * current_spend_ratio;
1288474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1289ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Try and pick a Q that should be high enough to encode the content at
1290ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * the given rate.
1291ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1292474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    for (Q = 0; Q < MAXQ; Q++)
1293474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1294ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Error per MB based correction factor */
1295167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        err_correction_factor =
1296167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            calc_correction_factor(err_per_mb, 150.0, pow_lowq, pow_highq, Q);
1297474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1298167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        bits_per_mb_at_this_q =
1299167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            (int)(.5 + ( err_correction_factor *
1300167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                         combined_correction_factor *
1301167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                         (double)vp8_bits_per_mb[INTER_FRAME][Q]) );
1302474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1303474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (bits_per_mb_at_this_q <= target_norm_bits_per_mb)
1304474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            break;
1305474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1306474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1307ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* If we could not hit the target even at Max Q then estimate what Q
1308ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * would have been required
1309ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1310474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    while ((bits_per_mb_at_this_q > target_norm_bits_per_mb)  && (Q < (MAXQ * 2)))
1311474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1312474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1313474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        bits_per_mb_at_this_q = (int)(0.96 * bits_per_mb_at_this_q);
1314474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        Q++;
1315474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1316474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1317474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (0)
1318474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1319474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        FILE *f = fopen("estkf_q.stt", "a");
1320474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        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,
1321474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                target_norm_bits_per_mb, err_per_mb, err_correction_factor,
1322474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                current_spend_ratio, group_iiratio, iiratio_correction_factor,
1323474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                (double)cpi->buffer_level / (double)cpi->oxcf.optimal_buffer_level, Q);
1324474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fclose(f);
1325474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1326474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1327474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return Q;
1328474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
1329474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
133047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgextern void vp8_new_framerate(VP8_COMP *cpi, double framerate);
1331474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1332474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvoid vp8_init_second_pass(VP8_COMP *cpi)
1333474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
1334474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    FIRSTPASS_STATS this_frame;
1335474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    FIRSTPASS_STATS *start_pos;
1336474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1337474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth * cpi->oxcf.two_pass_vbrmin_section / 100);
1338474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1339167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    zero_stats(&cpi->twopass.total_stats);
1340167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    zero_stats(&cpi->twopass.total_left_stats);
1341474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1342474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (!cpi->twopass.stats_in_end)
1343474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        return;
1344474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1345167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    cpi->twopass.total_stats = *cpi->twopass.stats_in_end;
1346167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    cpi->twopass.total_left_stats = cpi->twopass.total_stats;
1347474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1348ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* each frame can have a different duration, as the frame rate in the
1349ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * source isn't guaranteed to be constant.   The frame rate prior to
1350ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * the first frame encoded in the second pass is a guess.  However the
1351ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * sum duration is not. Its calculated based on the actual durations of
1352ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * all frames from the first pass.
1353ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
135447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    vp8_new_framerate(cpi, 10000000.0 * cpi->twopass.total_stats.count / cpi->twopass.total_stats.duration);
1355474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
135647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    cpi->output_framerate = cpi->framerate;
1357167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    cpi->twopass.bits_left = (int64_t)(cpi->twopass.total_stats.duration * cpi->oxcf.target_bandwidth / 10000000.0) ;
1358167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    cpi->twopass.bits_left -= (int64_t)(cpi->twopass.total_stats.duration * two_pass_min_rate / 10000000.0);
1359474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1360ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Calculate a minimum intra value to be used in determining the IIratio
1361ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * scores used in the second pass. We have this minimum to make sure
1362ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * that clips that are static but "low complexity" in the intra domain
1363ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * are still boosted appropriately for KF/GF/ARF
1364ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1365474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    cpi->twopass.kf_intra_err_min = KF_MB_INTRA_MIN * cpi->common.MBs;
1366474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    cpi->twopass.gf_intra_err_min = GF_MB_INTRA_MIN * cpi->common.MBs;
1367474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1368ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Scan the first pass file and calculate an average Intra / Inter error
1369ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * score ratio for the sequence
1370ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1371474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1372474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double sum_iiratio = 0.0;
1373474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double IIRatio;
1374474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1375ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        start_pos = cpi->twopass.stats_in; /* Note starting "file" position */
1376474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1377474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        while (input_stats(cpi, &this_frame) != EOF)
1378474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
1379474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            IIRatio = this_frame.intra_error / DOUBLE_DIVIDE_CHECK(this_frame.coded_error);
1380474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            IIRatio = (IIRatio < 1.0) ? 1.0 : (IIRatio > 20.0) ? 20.0 : IIRatio;
1381474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            sum_iiratio += IIRatio;
1382474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
1383474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1384167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        cpi->twopass.avg_iiratio = sum_iiratio / DOUBLE_DIVIDE_CHECK((double)cpi->twopass.total_stats.count);
1385474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1386ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Reset file position */
1387474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        reset_fpf_position(cpi, start_pos);
1388474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1389474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1390ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Scan the first pass file and calculate a modified total error based
1391ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * upon the bias/power function used to allocate bits
1392ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1393474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1394ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        start_pos = cpi->twopass.stats_in;  /* Note starting "file" position */
1395474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1396474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.modified_error_total = 0.0;
1397474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.modified_error_used = 0.0;
1398474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1399474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        while (input_stats(cpi, &this_frame) != EOF)
1400474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
1401474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->twopass.modified_error_total += calculate_modified_err(cpi, &this_frame);
1402474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
1403474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.modified_error_left = cpi->twopass.modified_error_total;
1404474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1405ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        reset_fpf_position(cpi, start_pos);  /* Reset file position */
1406474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1407474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1408474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
1409474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1410474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvoid vp8_end_second_pass(VP8_COMP *cpi)
1411474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
1412474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
1413474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1414ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/* This function gives and estimate of how badly we believe the prediction
1415ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org * quality is decaying from frame to frame.
1416ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org */
1417474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic double get_prediction_decay_rate(VP8_COMP *cpi, FIRSTPASS_STATS *next_frame)
1418474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
1419474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double prediction_decay_rate;
1420474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double motion_decay;
1421474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double motion_pct = next_frame->pcnt_motion;
1422474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1423ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Initial basis is the % mbs inter coded */
1424474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    prediction_decay_rate = next_frame->pcnt_inter;
1425474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1426ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* High % motion -> somewhat higher decay rate */
1427474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    motion_decay = (1.0 - (motion_pct / 20.0));
1428474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (motion_decay < prediction_decay_rate)
1429474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        prediction_decay_rate = motion_decay;
1430474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1431ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Adjustment to decay rate based on speed of motion */
1432474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1433474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double this_mv_rabs;
1434474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double this_mv_cabs;
1435474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double distance_factor;
1436474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1437474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        this_mv_rabs = fabs(next_frame->mvr_abs * motion_pct);
1438474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        this_mv_cabs = fabs(next_frame->mvc_abs * motion_pct);
1439474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1440474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        distance_factor = sqrt((this_mv_rabs * this_mv_rabs) +
1441474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                               (this_mv_cabs * this_mv_cabs)) / 250.0;
1442474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        distance_factor = ((distance_factor > 1.0)
1443474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                ? 0.0 : (1.0 - distance_factor));
1444474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (distance_factor < prediction_decay_rate)
1445474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            prediction_decay_rate = distance_factor;
1446474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1447474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1448474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return prediction_decay_rate;
1449474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
1450474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1451ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/* Function to test for a condition where a complex transition is followed
1452ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org * by a static section. For example in slide shows where there is a fade
1453ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org * between slides. This is to help with more optimal kf and gf positioning.
1454ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org */
1455474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic int detect_transition_to_still(
1456474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    VP8_COMP *cpi,
1457474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int frame_interval,
1458474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int still_interval,
1459474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double loop_decay_rate,
1460474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double decay_accumulator )
1461474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
1462167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    int trans_to_still = 0;
1463474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1464ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Break clause to detect very still sections after motion
1465ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * For example a static image after a fade or other transition
1466ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * instead of a clean scene cut.
1467ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1468474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if ( (frame_interval > MIN_GF_INTERVAL) &&
1469474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org         (loop_decay_rate >= 0.999) &&
1470474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org         (decay_accumulator < 0.9) )
1471474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1472474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int j;
1473474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        FIRSTPASS_STATS * position = cpi->twopass.stats_in;
1474474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        FIRSTPASS_STATS tmp_next_frame;
1475474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double decay_rate;
1476474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1477ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Look ahead a few frames to see if static condition persists... */
1478474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        for ( j = 0; j < still_interval; j++ )
1479474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
1480474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (EOF == input_stats(cpi, &tmp_next_frame))
1481474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                break;
1482474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1483474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            decay_rate = get_prediction_decay_rate(cpi, &tmp_next_frame);
1484474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if ( decay_rate < 0.999 )
1485474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                break;
1486474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
1487ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Reset file position */
1488474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        reset_fpf_position(cpi, position);
1489474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1490ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Only if it does do we signal a transition to still */
1491474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if ( j == still_interval )
1492167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            trans_to_still = 1;
1493474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1494474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1495474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return trans_to_still;
1496474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
1497474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1498ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/* This function detects a flash through the high relative pcnt_second_ref
1499ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org * score in the frame following a flash frame. The offset passed in should
1500ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org * reflect this
1501ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org */
1502167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.orgstatic int detect_flash( VP8_COMP *cpi, int offset )
1503474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
1504474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    FIRSTPASS_STATS next_frame;
1505474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1506167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    int flash_detected = 0;
1507474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1508ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Read the frame data. */
1509ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* The return is 0 (no flash detected) if not a valid frame */
1510474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if ( read_frame_stats(cpi, &next_frame, offset) != EOF )
1511474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1512ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* What we are looking for here is a situation where there is a
1513ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * brief break in prediction (such as a flash) but subsequent frames
1514ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * are reasonably well predicted by an earlier (pre flash) frame.
1515ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * The recovery after a flash is indicated by a high pcnt_second_ref
1516ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * comapred to pcnt_inter.
1517ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
1518474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if ( (next_frame.pcnt_second_ref > next_frame.pcnt_inter) &&
1519474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org             (next_frame.pcnt_second_ref >= 0.5 ) )
1520474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
1521167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            flash_detected = 1;
1522474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1523474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            /*if (1)
1524474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            {
1525474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                FILE *f = fopen("flash.stt", "a");
1526474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                fprintf(f, "%8.0f %6.2f %6.2f\n",
1527474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    next_frame.frame,
1528474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    next_frame.pcnt_inter,
1529474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    next_frame.pcnt_second_ref);
1530474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                fclose(f);
1531474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            }*/
1532474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
1533474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1534474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1535474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return flash_detected;
1536474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
1537474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1538ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/* Update the motion related elements to the GF arf boost calculation */
1539474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void accumulate_frame_motion_stats(
1540474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    VP8_COMP *cpi,
1541474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    FIRSTPASS_STATS * this_frame,
1542474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double * this_frame_mv_in_out,
1543474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double * mv_in_out_accumulator,
1544474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double * abs_mv_in_out_accumulator,
1545474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double * mv_ratio_accumulator )
1546474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
1547474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double this_frame_mvr_ratio;
1548474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double this_frame_mvc_ratio;
1549474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double motion_pct;
1550474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1551ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Accumulate motion stats. */
1552474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    motion_pct = this_frame->pcnt_motion;
1553474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1554ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Accumulate Motion In/Out of frame stats */
1555474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    *this_frame_mv_in_out = this_frame->mv_in_out_count * motion_pct;
1556474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    *mv_in_out_accumulator += this_frame->mv_in_out_count * motion_pct;
1557474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    *abs_mv_in_out_accumulator +=
1558474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        fabs(this_frame->mv_in_out_count * motion_pct);
1559474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1560ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Accumulate a measure of how uniform (or conversely how random)
1561ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * the motion field is. (A ratio of absmv / mv)
1562ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1563474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (motion_pct > 0.05)
1564474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1565474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        this_frame_mvr_ratio = fabs(this_frame->mvr_abs) /
1566474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                               DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVr));
1567474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1568474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        this_frame_mvc_ratio = fabs(this_frame->mvc_abs) /
1569474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                               DOUBLE_DIVIDE_CHECK(fabs(this_frame->MVc));
1570474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1571474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org         *mv_ratio_accumulator +=
1572474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            (this_frame_mvr_ratio < this_frame->mvr_abs)
1573474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                ? (this_frame_mvr_ratio * motion_pct)
1574474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                : this_frame->mvr_abs * motion_pct;
1575474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1576474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        *mv_ratio_accumulator +=
1577474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            (this_frame_mvc_ratio < this_frame->mvc_abs)
1578474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                ? (this_frame_mvc_ratio * motion_pct)
1579474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                : this_frame->mvc_abs * motion_pct;
1580474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1581474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1582474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
1583474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1584ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/* Calculate a baseline boost number for the current frame. */
1585474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic double calc_frame_boost(
1586474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    VP8_COMP *cpi,
1587474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    FIRSTPASS_STATS * this_frame,
1588474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double this_frame_mv_in_out )
1589474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
1590474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double frame_boost;
1591474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1592ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Underlying boost factor is based on inter intra error ratio */
1593474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (this_frame->intra_error > cpi->twopass.gf_intra_err_min)
1594474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        frame_boost = (IIFACTOR * this_frame->intra_error /
1595474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                      DOUBLE_DIVIDE_CHECK(this_frame->coded_error));
1596474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    else
1597474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        frame_boost = (IIFACTOR * cpi->twopass.gf_intra_err_min /
1598474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                      DOUBLE_DIVIDE_CHECK(this_frame->coded_error));
1599474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1600ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Increase boost for frames where new data coming into frame
1601ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * (eg zoom out). Slightly reduce boost if there is a net balance
1602ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * of motion out of the frame (zoom in).
1603ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * The range for this_frame_mv_in_out is -1.0 to +1.0
1604ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1605474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (this_frame_mv_in_out > 0.0)
1606474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        frame_boost += frame_boost * (this_frame_mv_in_out * 2.0);
1607ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* In extreme case boost is halved */
1608474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    else
1609474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        frame_boost += frame_boost * (this_frame_mv_in_out / 2.0);
1610474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1611ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Clip to maximum */
1612474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (frame_boost > GF_RMAX)
1613474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        frame_boost = GF_RMAX;
1614474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1615474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return frame_boost;
1616474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
1617474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1618474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if NEW_BOOST
1619474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic int calc_arf_boost(
1620474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    VP8_COMP *cpi,
1621474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int offset,
1622474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int f_frames,
1623474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int b_frames,
1624474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int *f_boost,
1625474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int *b_boost )
1626474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
1627474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    FIRSTPASS_STATS this_frame;
1628474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1629474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int i;
1630474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double boost_score = 0.0;
1631474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double mv_ratio_accumulator = 0.0;
1632474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double decay_accumulator = 1.0;
1633474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double this_frame_mv_in_out = 0.0;
1634474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double mv_in_out_accumulator = 0.0;
1635474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double abs_mv_in_out_accumulator = 0.0;
1636474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double r;
1637167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    int flash_detected = 0;
1638474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1639ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Search forward from the proposed arf/next gf position */
1640474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    for ( i = 0; i < f_frames; i++ )
1641474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1642474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if ( read_frame_stats(cpi, &this_frame, (i+offset)) == EOF )
1643474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            break;
1644474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1645ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Update the motion related elements to the boost calculation */
1646474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        accumulate_frame_motion_stats( cpi, &this_frame,
1647474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            &this_frame_mv_in_out, &mv_in_out_accumulator,
1648474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            &abs_mv_in_out_accumulator, &mv_ratio_accumulator );
1649474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1650ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Calculate the baseline boost number for this frame */
1651474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        r = calc_frame_boost( cpi, &this_frame, this_frame_mv_in_out );
1652474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1653ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* We want to discount the the flash frame itself and the recovery
1654ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * frame that follows as both will have poor scores.
1655ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
1656474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        flash_detected = detect_flash(cpi, (i+offset)) ||
1657474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                         detect_flash(cpi, (i+offset+1));
1658474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1659ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Cumulative effect of prediction quality decay */
1660474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if ( !flash_detected )
1661474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
1662474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            decay_accumulator =
1663474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                decay_accumulator *
1664474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                get_prediction_decay_rate(cpi, &this_frame);
1665474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            decay_accumulator =
1666474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                decay_accumulator < 0.1 ? 0.1 : decay_accumulator;
1667474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
1668474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        boost_score += (decay_accumulator * r);
1669474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1670ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Break out conditions. */
1671474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if  ( (!flash_detected) &&
1672474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org              ((mv_ratio_accumulator > 100.0) ||
1673474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org               (abs_mv_in_out_accumulator > 3.0) ||
1674474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org               (mv_in_out_accumulator < -2.0) ) )
1675474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
1676474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            break;
1677474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
1678474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1679474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1680474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    *f_boost = (int)(boost_score * 100.0) >> 4;
1681474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1682ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Reset for backward looking loop */
1683474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    boost_score = 0.0;
1684474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    mv_ratio_accumulator = 0.0;
1685474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    decay_accumulator = 1.0;
1686474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    this_frame_mv_in_out = 0.0;
1687474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    mv_in_out_accumulator = 0.0;
1688474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    abs_mv_in_out_accumulator = 0.0;
1689474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1690ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Search forward from the proposed arf/next gf position */
1691474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    for ( i = -1; i >= -b_frames; i-- )
1692474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1693474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if ( read_frame_stats(cpi, &this_frame, (i+offset)) == EOF )
1694474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            break;
1695474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1696ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Update the motion related elements to the boost calculation */
1697474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        accumulate_frame_motion_stats( cpi, &this_frame,
1698474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            &this_frame_mv_in_out, &mv_in_out_accumulator,
1699474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            &abs_mv_in_out_accumulator, &mv_ratio_accumulator );
1700474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1701ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Calculate the baseline boost number for this frame */
1702474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        r = calc_frame_boost( cpi, &this_frame, this_frame_mv_in_out );
1703474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1704ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* We want to discount the the flash frame itself and the recovery
1705ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * frame that follows as both will have poor scores.
1706ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
1707474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        flash_detected = detect_flash(cpi, (i+offset)) ||
1708474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                         detect_flash(cpi, (i+offset+1));
1709474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1710ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Cumulative effect of prediction quality decay */
1711474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if ( !flash_detected )
1712474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
1713474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            decay_accumulator =
1714474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                decay_accumulator *
1715474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                get_prediction_decay_rate(cpi, &this_frame);
1716474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            decay_accumulator =
1717474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                decay_accumulator < 0.1 ? 0.1 : decay_accumulator;
1718474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
1719474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1720474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        boost_score += (decay_accumulator * r);
1721474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1722ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Break out conditions. */
1723474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if  ( (!flash_detected) &&
1724474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org              ((mv_ratio_accumulator > 100.0) ||
1725474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org               (abs_mv_in_out_accumulator > 3.0) ||
1726474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org               (mv_in_out_accumulator < -2.0) ) )
1727474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
1728474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            break;
1729474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
1730474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1731474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    *b_boost = (int)(boost_score * 100.0) >> 4;
1732474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1733474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return (*f_boost + *b_boost);
1734474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
1735474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
1736474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1737ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/* Analyse and define a gf/arf group . */
1738474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
1739474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
1740474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    FIRSTPASS_STATS next_frame;
1741474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    FIRSTPASS_STATS *start_pos;
1742474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int i;
1743474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double r;
1744474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double boost_score = 0.0;
1745474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double old_boost_score = 0.0;
1746474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double gf_group_err = 0.0;
1747474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double gf_first_frame_err = 0.0;
1748474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double mod_frame_err = 0.0;
1749474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1750474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double mv_ratio_accumulator = 0.0;
1751474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double decay_accumulator = 1.0;
1752474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1753ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    double loop_decay_rate = 1.00;          /* Starting decay rate */
1754474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1755474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double this_frame_mv_in_out = 0.0;
1756474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double mv_in_out_accumulator = 0.0;
1757474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double abs_mv_in_out_accumulator = 0.0;
1758474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double mod_err_per_mb_accumulator = 0.0;
1759474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1760ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    int max_bits = frame_max_bits(cpi);     /* Max for a single frame */
1761474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1762474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    unsigned int allow_alt_ref =
1763474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames;
1764474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1765474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int alt_boost = 0;
1766474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int f_boost = 0;
1767474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int b_boost = 0;
1768167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    int flash_detected;
1769474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1770474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    cpi->twopass.gf_group_bits = 0;
1771474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    cpi->twopass.gf_decay_rate = 0;
1772474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1773ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    vp8_clear_system_state();
1774474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1775474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    start_pos = cpi->twopass.stats_in;
1776474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1777ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    vpx_memset(&next_frame, 0, sizeof(next_frame)); /* assure clean */
1778474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1779ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Load stats for the current frame. */
1780474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    mod_frame_err = calculate_modified_err(cpi, this_frame);
1781474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1782ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Note the error of the frame at the start of the group (this will be
1783ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * the GF frame error if we code a normal gf
1784ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1785474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    gf_first_frame_err = mod_frame_err;
1786474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1787ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Special treatment if the current frame is a key frame (which is also
1788ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * a gf). If it is then its error score (and hence bit allocation) need
1789ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * to be subtracted out from the calculation for the GF group
1790ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1791474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cpi->common.frame_type == KEY_FRAME)
1792474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        gf_group_err -= gf_first_frame_err;
1793474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1794ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Scan forward to try and work out how many frames the next gf group
1795ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * should contain and what level of boost is appropriate for the GF
1796ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * or ARF that will be coded with the group
1797ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
1798474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    i = 0;
1799474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1800474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    while (((i < cpi->twopass.static_scene_max_gf_interval) ||
1801474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL)) &&
1802474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org           (i < cpi->twopass.frames_to_key))
1803474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1804ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        i++;
1805474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1806ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Accumulate error score of frames in this gf group */
1807474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        mod_frame_err = calculate_modified_err(cpi, this_frame);
1808474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1809474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        gf_group_err += mod_frame_err;
1810474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1811474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        mod_err_per_mb_accumulator +=
1812474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            mod_frame_err / DOUBLE_DIVIDE_CHECK((double)cpi->common.MBs);
1813474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1814474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (EOF == input_stats(cpi, &next_frame))
1815474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            break;
1816474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1817ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Test for the case where there is a brief flash but the prediction
1818ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * quality back to an earlier frame is then restored.
1819ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
1820474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        flash_detected = detect_flash(cpi, 0);
1821474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1822ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Update the motion related elements to the boost calculation */
1823474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        accumulate_frame_motion_stats( cpi, &next_frame,
1824474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            &this_frame_mv_in_out, &mv_in_out_accumulator,
1825474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            &abs_mv_in_out_accumulator, &mv_ratio_accumulator );
1826474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1827ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Calculate a baseline boost number for this frame */
1828474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        r = calc_frame_boost( cpi, &next_frame, this_frame_mv_in_out );
1829474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1830ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Cumulative effect of prediction quality decay */
1831474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if ( !flash_detected )
1832474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
1833474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame);
1834474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            decay_accumulator = decay_accumulator * loop_decay_rate;
1835474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            decay_accumulator =
1836474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                decay_accumulator < 0.1 ? 0.1 : decay_accumulator;
1837474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
1838474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        boost_score += (decay_accumulator * r);
1839474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1840ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Break clause to detect very still sections after motion
1841ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * For example a staic image after a fade or other transition.
1842ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
1843474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if ( detect_transition_to_still( cpi, i, 5,
1844474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                         loop_decay_rate,
1845474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                         decay_accumulator ) )
1846474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
1847167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            allow_alt_ref = 0;
1848474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            boost_score = old_boost_score;
1849474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            break;
1850474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
1851474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1852ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Break out conditions. */
1853474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if  (
1854ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Break at cpi->max_gf_interval unless almost totally static */
1855474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            (i >= cpi->max_gf_interval && (decay_accumulator < 0.995)) ||
1856474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            (
1857ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                /* Dont break out with a very short interval */
1858474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                (i > MIN_GF_INTERVAL) &&
1859ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                /* Dont break out very close to a key frame */
1860474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                ((cpi->twopass.frames_to_key - i) >= MIN_GF_INTERVAL) &&
1861474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                ((boost_score > 20.0) || (next_frame.pcnt_inter < 0.75)) &&
1862474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                (!flash_detected) &&
1863474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                ((mv_ratio_accumulator > 100.0) ||
1864474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                 (abs_mv_in_out_accumulator > 3.0) ||
1865474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                 (mv_in_out_accumulator < -2.0) ||
1866474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                 ((boost_score - old_boost_score) < 2.0))
1867474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            ) )
1868474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
1869474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            boost_score = old_boost_score;
1870474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            break;
1871474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
1872474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1873474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        vpx_memcpy(this_frame, &next_frame, sizeof(*this_frame));
1874474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1875474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        old_boost_score = boost_score;
1876474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1877474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1878474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    cpi->twopass.gf_decay_rate =
1879474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        (i > 0) ? (int)(100.0 * (1.0 - decay_accumulator)) / i : 0;
1880474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1881ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* When using CBR apply additional buffer related upper limits */
1882474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
1883474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1884474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double max_boost;
1885474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1886ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* For cbr apply buffer related limits */
1887474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->drop_frames_allowed)
1888474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
1889ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            int64_t df_buffer_level = cpi->oxcf.drop_frames_water_mark *
1890474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                  (cpi->oxcf.optimal_buffer_level / 100);
1891474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1892474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (cpi->buffer_level > df_buffer_level)
1893474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                max_boost = ((double)((cpi->buffer_level - df_buffer_level) * 2 / 3) * 16.0) / DOUBLE_DIVIDE_CHECK((double)cpi->av_per_frame_bandwidth);
1894474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            else
1895474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                max_boost = 0.0;
1896474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
1897474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else if (cpi->buffer_level > 0)
1898474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
1899474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            max_boost = ((double)(cpi->buffer_level * 2 / 3) * 16.0) / DOUBLE_DIVIDE_CHECK((double)cpi->av_per_frame_bandwidth);
1900474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
1901474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
1902474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
1903474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            max_boost = 0.0;
1904474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
1905474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1906474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (boost_score > max_boost)
1907474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            boost_score = max_boost;
1908474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1909474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1910ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Dont allow conventional gf too near the next kf */
1911474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if ((cpi->twopass.frames_to_key - i) < MIN_GF_INTERVAL)
1912474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1913474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        while (i < cpi->twopass.frames_to_key)
1914474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
1915474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            i++;
1916474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1917474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (EOF == input_stats(cpi, this_frame))
1918474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                break;
1919474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1920474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (i < cpi->twopass.frames_to_key)
1921474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            {
1922474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                mod_frame_err = calculate_modified_err(cpi, this_frame);
1923474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                gf_group_err += mod_frame_err;
1924474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            }
1925474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
1926474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
1927474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1928474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    cpi->gfu_boost = (int)(boost_score * 100.0) >> 4;
1929474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1930474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if NEW_BOOST
1931ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Alterrnative boost calculation for alt ref */
1932474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    alt_boost = calc_arf_boost( cpi, 0, (i-1), (i-1), &f_boost, &b_boost );
1933474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
1934474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1935ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Should we use the alternate refernce frame */
1936474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (allow_alt_ref &&
1937474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        (i >= MIN_GF_INTERVAL) &&
1938ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* dont use ARF very near next kf */
1939474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        (i <= (cpi->twopass.frames_to_key - MIN_GF_INTERVAL)) &&
1940474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if NEW_BOOST
1941474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        ((next_frame.pcnt_inter > 0.75) ||
1942474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org         (next_frame.pcnt_second_ref > 0.5)) &&
1943474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        ((mv_in_out_accumulator / (double)i > -0.2) ||
1944474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org         (mv_in_out_accumulator > -2.0)) &&
1945474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        (b_boost > 100) &&
1946474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        (f_boost > 100) )
1947474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#else
1948474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        (next_frame.pcnt_inter > 0.75) &&
1949474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        ((mv_in_out_accumulator / (double)i > -0.2) ||
1950474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org         (mv_in_out_accumulator > -2.0)) &&
1951474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        (cpi->gfu_boost > 100) &&
1952474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        (cpi->twopass.gf_decay_rate <=
1953474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            (ARF_DECAY_THRESH + (cpi->gfu_boost / 200))) )
1954474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
1955474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
1956474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int Boost;
1957474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int allocation_chunks;
1958474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int Q = (cpi->oxcf.fixed_q < 0)
1959474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
1960474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int tmp_q;
1961474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int arf_frame_bits = 0;
1962474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int group_bits;
1963474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1964474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if NEW_BOOST
1965474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->gfu_boost = alt_boost;
1966474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
1967474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1968ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Estimate the bits to be allocated to the group as a whole */
1969474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if ((cpi->twopass.kf_group_bits > 0) &&
1970474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            (cpi->twopass.kf_group_error_left > 0))
1971474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
1972474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            group_bits = (int)((double)cpi->twopass.kf_group_bits *
1973474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                (gf_group_err / (double)cpi->twopass.kf_group_error_left));
1974474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
1975474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
1976474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            group_bits = 0;
1977474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1978ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Boost for arf frame */
1979474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if NEW_BOOST
1980474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        Boost = (alt_boost * GFQ_ADJUSTMENT) / 100;
1981474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#else
1982474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        Boost = (cpi->gfu_boost * 3 * GFQ_ADJUSTMENT) / (2 * 100);
1983474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
1984474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        Boost += (i * 50);
1985474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1986ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Set max and minimum boost and hence minimum allocation */
1987474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (Boost > ((cpi->baseline_gf_interval + 1) * 200))
1988474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            Boost = ((cpi->baseline_gf_interval + 1) * 200);
1989474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else if (Boost < 125)
1990474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            Boost = 125;
1991474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1992474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        allocation_chunks = (i * 100) + Boost;
1993474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1994ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Normalize Altboost and allocations chunck down to prevent overflow */
1995474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        while (Boost > 1000)
1996474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
1997474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            Boost /= 2;
1998474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            allocation_chunks /= 2;
1999474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2000474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2001ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Calculate the number of bits to be spent on the arf based on the
2002ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * boost number
2003ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
2004474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        arf_frame_bits = (int)((double)Boost * (group_bits /
2005474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                               (double)allocation_chunks));
2006474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2007ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Estimate if there are enough bits available to make worthwhile use
2008ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * of an arf.
2009ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
2010474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        tmp_q = estimate_q(cpi, mod_frame_err, (int)arf_frame_bits);
2011474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2012ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Only use an arf if it is likely we will be able to code
2013ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * it at a lower Q than the surrounding frames.
2014ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
2015474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (tmp_q < cpi->worst_quality)
2016474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2017474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            int half_gf_int;
2018474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            int frames_after_arf;
2019474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            int frames_bwd = cpi->oxcf.arnr_max_frames - 1;
2020474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            int frames_fwd = cpi->oxcf.arnr_max_frames - 1;
2021474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2022167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            cpi->source_alt_ref_pending = 1;
2023474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2024ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /*
2025ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * For alt ref frames the error score for the end frame of the
2026ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * group (the alt ref frame) should not contribute to the group
2027ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * total and hence the number of bit allocated to the group.
2028ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * Rather it forms part of the next group (it is the GF at the
2029ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * start of the next group)
2030ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * gf_group_err -= mod_frame_err;
2031ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             *
2032ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * For alt ref frames alt ref frame is technically part of the
2033ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * GF frame for the next group but we always base the error
2034ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * calculation and bit allocation on the current group of frames.
2035ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             *
2036ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * Set the interval till the next gf or arf.
2037ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * For ARFs this is the number of frames to be coded before the
2038ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * future frame that is coded as an ARF.
2039ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * The future frame itself is part of the next group
2040ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             */
2041474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->baseline_gf_interval = i;
2042474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2043ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /*
2044ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * Define the arnr filter width for this group of frames:
2045ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * We only filter frames that lie within a distance of half
2046ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * the GF interval from the ARF frame. We also have to trap
2047ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * cases where the filter extends beyond the end of clip.
2048ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * Note: this_frame->frame has been updated in the loop
2049ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * so it now points at the ARF frame.
2050ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             */
2051474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            half_gf_int = cpi->baseline_gf_interval >> 1;
2052ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            frames_after_arf = (int)(cpi->twopass.total_stats.count -
2053ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                               this_frame->frame - 1);
2054474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2055474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            switch (cpi->oxcf.arnr_type)
2056474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            {
2057ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            case 1: /* Backward filter */
2058474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                frames_fwd = 0;
2059474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                if (frames_bwd > half_gf_int)
2060474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    frames_bwd = half_gf_int;
2061474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                break;
2062474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2063ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            case 2: /* Forward filter */
2064474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                if (frames_fwd > half_gf_int)
2065474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    frames_fwd = half_gf_int;
2066474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                if (frames_fwd > frames_after_arf)
2067474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    frames_fwd = frames_after_arf;
2068474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                frames_bwd = 0;
2069474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                break;
2070474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2071ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            case 3: /* Centered filter */
2072474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            default:
2073474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                frames_fwd >>= 1;
2074474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                if (frames_fwd > frames_after_arf)
2075474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    frames_fwd = frames_after_arf;
2076474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                if (frames_fwd > half_gf_int)
2077474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    frames_fwd = half_gf_int;
2078474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2079474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                frames_bwd = frames_fwd;
2080474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2081ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                /* For even length filter there is one more frame backward
2082ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                 * than forward: e.g. len=6 ==> bbbAff, len=7 ==> bbbAfff.
2083ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                 */
2084474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                if (frames_bwd < half_gf_int)
2085474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    frames_bwd += (cpi->oxcf.arnr_max_frames+1) & 0x1;
2086474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                break;
2087474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            }
2088474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2089474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->active_arnr_frames = frames_bwd + 1 + frames_fwd;
2090474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2091474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
2092474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2093167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            cpi->source_alt_ref_pending = 0;
2094474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->baseline_gf_interval = i;
2095474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2096474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2097474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    else
2098474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2099167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        cpi->source_alt_ref_pending = 0;
2100474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->baseline_gf_interval = i;
2101474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2102474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2103ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /*
2104ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * Now decide how many bits should be allocated to the GF group as  a
2105ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * proportion of those remaining in the kf group.
2106ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * The final key frame group in the clip is treated as a special case
2107ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * where cpi->twopass.kf_group_bits is tied to cpi->twopass.bits_left.
2108ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * This is also important for short clips where there may only be one
2109ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * key frame.
2110ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
2111167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    if (cpi->twopass.frames_to_key >= (int)(cpi->twopass.total_stats.count -
2112474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                            cpi->common.current_video_frame))
2113474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2114474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.kf_group_bits =
2115474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            (cpi->twopass.bits_left > 0) ? cpi->twopass.bits_left : 0;
2116474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2117474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2118ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Calculate the bits to be allocated to the group as a whole */
2119474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if ((cpi->twopass.kf_group_bits > 0) &&
2120474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        (cpi->twopass.kf_group_error_left > 0))
2121474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2122474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.gf_group_bits =
21234b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org            (int64_t)(cpi->twopass.kf_group_bits *
21244b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org                      (gf_group_err / cpi->twopass.kf_group_error_left));
2125474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2126474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    else
2127474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.gf_group_bits = 0;
2128474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
21294b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org    cpi->twopass.gf_group_bits =
2130474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        (cpi->twopass.gf_group_bits < 0)
2131474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            ? 0
2132474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            : (cpi->twopass.gf_group_bits > cpi->twopass.kf_group_bits)
21334b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org                ? cpi->twopass.kf_group_bits : cpi->twopass.gf_group_bits;
2134474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2135ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Clip cpi->twopass.gf_group_bits based on user supplied data rate
2136ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * variability limit (cpi->oxcf.two_pass_vbrmax_section)
2137ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
21384b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org    if (cpi->twopass.gf_group_bits >
21394b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org        (int64_t)max_bits * cpi->baseline_gf_interval)
21404b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org        cpi->twopass.gf_group_bits =
21414b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org            (int64_t)max_bits * cpi->baseline_gf_interval;
2142474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2143ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Reset the file position */
2144474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    reset_fpf_position(cpi, start_pos);
2145474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2146ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Update the record of error used so far (only done once per gf group) */
2147474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    cpi->twopass.modified_error_used += gf_group_err;
2148474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2149ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Assign  bits to the arf or gf. */
2150474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    for (i = 0; i <= (cpi->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME); i++) {
2151474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int Boost;
2152474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int allocation_chunks;
2153474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int Q = (cpi->oxcf.fixed_q < 0) ? cpi->last_q[INTER_FRAME] : cpi->oxcf.fixed_q;
2154474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int gf_bits;
2155474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2156ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* For ARF frames */
2157474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->source_alt_ref_pending && i == 0)
2158474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2159474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if NEW_BOOST
2160474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            Boost = (alt_boost * GFQ_ADJUSTMENT) / 100;
2161474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#else
2162474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            Boost = (cpi->gfu_boost * 3 * GFQ_ADJUSTMENT) / (2 * 100);
2163474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
2164474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            Boost += (cpi->baseline_gf_interval * 50);
2165474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2166ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Set max and minimum boost and hence minimum allocation */
2167474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (Boost > ((cpi->baseline_gf_interval + 1) * 200))
2168474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                Boost = ((cpi->baseline_gf_interval + 1) * 200);
2169474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            else if (Boost < 125)
2170474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                Boost = 125;
2171474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2172474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            allocation_chunks =
2173474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                ((cpi->baseline_gf_interval + 1) * 100) + Boost;
2174474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2175ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Else for standard golden frames */
2176474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
2177474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2178ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* boost based on inter / intra ratio of subsequent frames */
2179474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            Boost = (cpi->gfu_boost * GFQ_ADJUSTMENT) / 100;
2180474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2181ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Set max and minimum boost and hence minimum allocation */
2182474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (Boost > (cpi->baseline_gf_interval * 150))
2183474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                Boost = (cpi->baseline_gf_interval * 150);
2184474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            else if (Boost < 125)
2185474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                Boost = 125;
2186474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2187474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            allocation_chunks =
2188474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                (cpi->baseline_gf_interval * 100) + (Boost - 100);
2189474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2190474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2191ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Normalize Altboost and allocations chunck down to prevent overflow */
2192474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        while (Boost > 1000)
2193474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2194474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            Boost /= 2;
2195474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            allocation_chunks /= 2;
2196474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2197474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2198ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Calculate the number of bits to be spent on the gf or arf based on
2199ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * the boost number
2200ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
2201474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        gf_bits = (int)((double)Boost *
2202474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        (cpi->twopass.gf_group_bits /
2203474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                         (double)allocation_chunks));
2204474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2205ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* If the frame that is to be boosted is simpler than the average for
2206ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * the gf/arf group then use an alternative calculation
2207ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * based on the error score of the frame itself
2208ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
2209474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (mod_frame_err < gf_group_err / (double)cpi->baseline_gf_interval)
2210474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2211474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            double  alt_gf_grp_bits;
2212474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            int     alt_gf_bits;
2213474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2214474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            alt_gf_grp_bits =
2215474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                (double)cpi->twopass.kf_group_bits  *
2216474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                (mod_frame_err * (double)cpi->baseline_gf_interval) /
2217474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                DOUBLE_DIVIDE_CHECK((double)cpi->twopass.kf_group_error_left);
2218474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2219474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            alt_gf_bits = (int)((double)Boost * (alt_gf_grp_bits /
2220474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                                 (double)allocation_chunks));
2221474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2222474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (gf_bits > alt_gf_bits)
2223474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            {
2224474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                gf_bits = alt_gf_bits;
2225474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            }
2226474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2227ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Else if it is harder than other frames in the group make sure it at
2228ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * least receives an allocation in keeping with its relative error
2229ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * score, otherwise it may be worse off than an "un-boosted" frame
2230ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
2231474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
2232474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2233474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            int alt_gf_bits =
2234474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                (int)((double)cpi->twopass.kf_group_bits *
2235474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                      mod_frame_err /
2236474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                      DOUBLE_DIVIDE_CHECK((double)cpi->twopass.kf_group_error_left));
2237474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2238474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (alt_gf_bits > gf_bits)
2239474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            {
2240474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                gf_bits = alt_gf_bits;
2241474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            }
2242474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2243474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2244ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Apply an additional limit for CBR */
2245474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
2246474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2247ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            if (cpi->twopass.gf_bits > (int)(cpi->buffer_level >> 1))
2248ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                cpi->twopass.gf_bits = (int)(cpi->buffer_level >> 1);
2249474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2250474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2251ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Dont allow a negative value for gf_bits */
2252474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (gf_bits < 0)
2253474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            gf_bits = 0;
2254474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2255ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Add in minimum for a frame */
2256ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        gf_bits += cpi->min_frame_bandwidth;
2257474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2258474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (i == 0)
2259474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2260474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->twopass.gf_bits = gf_bits;
2261474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2262474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (i == 1 || (!cpi->source_alt_ref_pending && (cpi->common.frame_type != KEY_FRAME)))
2263474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2264ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Per frame bit target for this frame */
2265ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            cpi->per_frame_bandwidth = gf_bits;
2266474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2267474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2268474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2269474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2270ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Adjust KF group bits and error remainin */
2271ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        cpi->twopass.kf_group_error_left -= (int64_t)gf_group_err;
2272474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.kf_group_bits -= cpi->twopass.gf_group_bits;
2273474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2274474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->twopass.kf_group_bits < 0)
2275474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->twopass.kf_group_bits = 0;
2276474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2277ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Note the error score left in the remaining frames of the group.
2278ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * For normal GFs we want to remove the error score for the first
2279ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * frame of the group (except in Key frame case where this has
2280ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * already happened)
2281ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
2282474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (!cpi->source_alt_ref_pending && cpi->common.frame_type != KEY_FRAME)
2283ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            cpi->twopass.gf_group_error_left = (int)(gf_group_err -
2284ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                                                     gf_first_frame_err);
2285474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
2286ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            cpi->twopass.gf_group_error_left = (int) gf_group_err;
2287474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2288474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.gf_group_bits -= cpi->twopass.gf_bits - cpi->min_frame_bandwidth;
2289474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2290474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->twopass.gf_group_bits < 0)
2291474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->twopass.gf_group_bits = 0;
2292474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2293ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* This condition could fail if there are two kfs very close together
2294ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * despite (MIN_GF_INTERVAL) and would cause a devide by 0 in the
2295ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * calculation of cpi->twopass.alt_extra_bits.
2296ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
2297167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        if ( cpi->baseline_gf_interval >= 3 )
2298474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2299474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if NEW_BOOST
2300474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            int boost = (cpi->source_alt_ref_pending)
2301474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        ? b_boost : cpi->gfu_boost;
2302474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#else
2303474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            int boost = cpi->gfu_boost;
2304474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
2305167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            if ( boost >= 150 )
2306474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            {
2307167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                int pct_extra;
2308474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2309167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                pct_extra = (boost - 100) / 50;
2310167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                pct_extra = (pct_extra > 20) ? 20 : pct_extra;
2311167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
2312167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                cpi->twopass.alt_extra_bits =
231376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org                    (int)(cpi->twopass.gf_group_bits * pct_extra) / 100;
2314167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                cpi->twopass.gf_group_bits -= cpi->twopass.alt_extra_bits;
2315167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                cpi->twopass.alt_extra_bits /=
2316167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                    ((cpi->baseline_gf_interval-1)>>1);
2317474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            }
2318474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            else
2319167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                cpi->twopass.alt_extra_bits = 0;
2320474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2321167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        else
2322167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            cpi->twopass.alt_extra_bits = 0;
2323474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2324474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2325ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Adjustments based on a measure of complexity of the section */
2326474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cpi->common.frame_type != KEY_FRAME)
2327474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2328474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        FIRSTPASS_STATS sectionstats;
2329474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double Ratio;
2330474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2331474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        zero_stats(&sectionstats);
2332474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        reset_fpf_position(cpi, start_pos);
2333474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2334474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        for (i = 0 ; i < cpi->baseline_gf_interval ; i++)
2335474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2336474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            input_stats(cpi, &next_frame);
2337474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            accumulate_stats(&sectionstats, &next_frame);
2338474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2339474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2340474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        avg_stats(&sectionstats);
2341474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2342ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        cpi->twopass.section_intra_rating = (unsigned int)
2343ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            (sectionstats.intra_error /
2344ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            DOUBLE_DIVIDE_CHECK(sectionstats.coded_error));
2345474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2346474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        Ratio = sectionstats.intra_error / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
2347474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.section_max_qfactor = 1.0 - ((Ratio - 10.0) * 0.025);
2348474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2349474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->twopass.section_max_qfactor < 0.80)
2350474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->twopass.section_max_qfactor = 0.80;
2351474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2352474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        reset_fpf_position(cpi, start_pos);
2353474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2354474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
2355474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2356ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org/* Allocate bits to a normal frame that is neither a gf an arf or a key frame. */
2357474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void assign_std_frame_bits(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
2358474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
2359ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    int    target_frame_size;
2360474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2361474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double modified_err;
2362ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    double err_fraction;
2363474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2364ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    int max_bits = frame_max_bits(cpi);  /* Max for a single frame */
2365474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2366ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Calculate modified prediction error used in bit allocation */
2367474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    modified_err = calculate_modified_err(cpi, this_frame);
2368474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2369ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* What portion of the remaining GF group error is used by this frame */
2370474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cpi->twopass.gf_group_error_left > 0)
2371ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        err_fraction = modified_err / cpi->twopass.gf_group_error_left;
2372474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    else
2373474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        err_fraction = 0.0;
2374474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2375ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* How many of those bits available for allocation should we give it? */
2376ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    target_frame_size = (int)((double)cpi->twopass.gf_group_bits * err_fraction);
2377474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2378ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Clip to target size to 0 - max_bits (or cpi->twopass.gf_group_bits)
2379ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * at the top end.
2380ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
2381474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (target_frame_size < 0)
2382474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        target_frame_size = 0;
2383474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    else
2384474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2385474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (target_frame_size > max_bits)
2386474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            target_frame_size = max_bits;
2387474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2388474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (target_frame_size > cpi->twopass.gf_group_bits)
238976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org            target_frame_size = (int)cpi->twopass.gf_group_bits;
2390474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2391474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2392ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Adjust error and bits remaining */
2393ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    cpi->twopass.gf_group_error_left -= (int)modified_err;
2394ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    cpi->twopass.gf_group_bits -= target_frame_size;
2395474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2396474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cpi->twopass.gf_group_bits < 0)
2397474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.gf_group_bits = 0;
2398474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2399ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Add in the minimum number of bits that is set aside for every frame. */
2400ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    target_frame_size += cpi->min_frame_bandwidth;
2401474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2402ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Every other frame gets a few extra bits */
240347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    if ( (cpi->frames_since_golden & 0x01) &&
2404167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org         (cpi->frames_till_gf_update_due > 0) )
2405167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    {
2406167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        target_frame_size += cpi->twopass.alt_extra_bits;
2407167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    }
2408474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2409ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Per frame bit target for this frame */
2410ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    cpi->per_frame_bandwidth = target_frame_size;
2411474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
2412474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2413474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvoid vp8_second_pass(VP8_COMP *cpi)
2414474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
2415474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int tmp_q;
2416167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    int frames_left = (int)(cpi->twopass.total_stats.count - cpi->common.current_video_frame);
2417474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2418167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    FIRSTPASS_STATS this_frame = {0};
2419474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    FIRSTPASS_STATS this_frame_copy;
2420474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2421474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double this_frame_intra_error;
2422474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double this_frame_coded_error;
2423474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2424167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    int overhead_bits;
2425167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
2426474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (!cpi->twopass.stats_in)
2427474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2428474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        return ;
2429474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2430474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2431474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    vp8_clear_system_state();
2432474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2433474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (EOF == input_stats(cpi, &this_frame))
2434474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        return;
2435474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2436474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    this_frame_intra_error = this_frame.intra_error;
2437474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    this_frame_coded_error = this_frame.coded_error;
2438474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2439ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* keyframe and section processing ! */
2440474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cpi->twopass.frames_to_key == 0)
2441474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2442ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Define next KF group and assign bits to it */
2443474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
2444474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        find_next_key_frame(cpi, &this_frame_copy);
2445474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2446ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Special case: Error error_resilient_mode mode does not make much
2447411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org         * sense for two pass but with its current meaning this code is
2448ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * designed to stop outlandish behaviour if someone does set it when
2449ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * using two pass. It effectively disables GF groups. This is
2450411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org         * temporary code until we decide what should really happen in this
2451ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * case.
2452ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
2453474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->oxcf.error_resilient_mode)
2454474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
24554b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org            cpi->twopass.gf_group_bits = cpi->twopass.kf_group_bits;
2456ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            cpi->twopass.gf_group_error_left =
2457ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                                  (int)cpi->twopass.kf_group_error_left;
2458474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->baseline_gf_interval = cpi->twopass.frames_to_key;
2459474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->frames_till_gf_update_due = cpi->baseline_gf_interval;
2460167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            cpi->source_alt_ref_pending = 0;
2461474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2462474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2463474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2464474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2465ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Is this a GF / ARF (Note that a KF is always also a GF) */
2466474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cpi->frames_till_gf_update_due == 0)
2467474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2468ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Define next gf group and assign bits to it */
2469474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
2470474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        define_gf_group(cpi, &this_frame_copy);
2471474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2472ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* If we are going to code an altref frame at the end of the group
2473ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * and the current frame is not a key frame.... If the previous
2474ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * group used an arf this frame has already benefited from that arf
2475ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * boost and it should not be given extra bits If the previous
2476ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * group was NOT coded using arf we may want to apply some boost to
2477ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * this GF as well
2478ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
2479474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->source_alt_ref_pending && (cpi->common.frame_type != KEY_FRAME))
2480474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2481ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Assign a standard frames worth of bits from those allocated
2482ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * to the GF group
2483ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             */
2484474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            int bak = cpi->per_frame_bandwidth;
2485474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
2486474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            assign_std_frame_bits(cpi, &this_frame_copy);
2487474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->per_frame_bandwidth = bak;
2488474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2489474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2490474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2491ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Otherwise this is an ordinary frame */
2492474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    else
2493474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2494ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Special case: Error error_resilient_mode mode does not make much
2495ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * sense for two pass but with its current meaning but this code is
2496ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * designed to stop outlandish behaviour if someone does set it
2497ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * when using two pass. It effectively disables GF groups. This is
2498ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * temporary code till we decide what should really happen in this
2499ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * case.
2500ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
2501474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->oxcf.error_resilient_mode)
2502474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2503474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->frames_till_gf_update_due = cpi->twopass.frames_to_key;
2504474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2505474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (cpi->common.frame_type != KEY_FRAME)
2506474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            {
2507ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                /* Assign bits from those allocated to the GF group */
2508474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
2509474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                assign_std_frame_bits(cpi, &this_frame_copy);
2510474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            }
2511474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2512474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
2513474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2514ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Assign bits from those allocated to the GF group */
2515474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            vpx_memcpy(&this_frame_copy, &this_frame, sizeof(this_frame));
2516474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            assign_std_frame_bits(cpi, &this_frame_copy);
2517474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2518474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2519474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2520ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Keep a globally available copy of this and the next frame's iiratio. */
2521ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    cpi->twopass.this_iiratio = (unsigned int)(this_frame_intra_error /
2522ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                        DOUBLE_DIVIDE_CHECK(this_frame_coded_error));
2523474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2524474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        FIRSTPASS_STATS next_frame;
2525474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if ( lookup_next_frame_stats(cpi, &next_frame) != EOF )
2526474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2527ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            cpi->twopass.next_iiratio = (unsigned int)(next_frame.intra_error /
2528ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                                DOUBLE_DIVIDE_CHECK(next_frame.coded_error));
2529474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2530474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2531474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2532ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Set nominal per second bandwidth for this frame */
2533ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    cpi->target_bandwidth = (int)
253447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    (cpi->per_frame_bandwidth * cpi->output_framerate);
2535474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cpi->target_bandwidth < 0)
2536474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->target_bandwidth = 0;
2537474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2538167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
2539ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Account for mv, mode and other overheads. */
2540ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    overhead_bits = (int)estimate_modemvcost(
2541167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                        cpi, &cpi->twopass.total_left_stats );
2542167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
2543ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Special case code for first frame. */
2544474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cpi->common.current_video_frame == 0)
2545474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2546474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.est_max_qcorrection_factor = 1.0;
2547474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2548ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Set a cq_level in constrained quality mode. */
2549474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if ( cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY )
2550474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2551474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            int est_cq;
2552474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2553474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            est_cq =
2554474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                estimate_cq( cpi,
2555167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                             &cpi->twopass.total_left_stats,
2556167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                             (int)(cpi->twopass.bits_left / frames_left),
2557167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                             overhead_bits );
2558474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2559474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->cq_target_quality = cpi->oxcf.cq_level;
2560474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if ( est_cq > cpi->cq_target_quality )
2561474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                cpi->cq_target_quality = est_cq;
2562474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2563474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2564ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* guess at maxq needed in 2nd pass */
2565474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.maxq_max_limit = cpi->worst_quality;
2566474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.maxq_min_limit = cpi->best_quality;
2567167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
2568167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        tmp_q = estimate_max_q(
2569167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                    cpi,
2570167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                    &cpi->twopass.total_left_stats,
2571167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                    (int)(cpi->twopass.bits_left / frames_left),
2572167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                    overhead_bits );
2573474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2574ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Limit the maxq value returned subsequently.
2575ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * This increases the risk of overspend or underspend if the initial
2576ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * estimate for the clip is bad, but helps prevent excessive
2577ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * variation in Q, especially near the end of a clip
2578ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * where for example a small overspend may cause Q to crash
2579ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
2580474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.maxq_max_limit = ((tmp_q + 32) < cpi->worst_quality)
2581474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                  ? (tmp_q + 32) : cpi->worst_quality;
2582474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.maxq_min_limit = ((tmp_q - 32) > cpi->best_quality)
2583474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                  ? (tmp_q - 32) : cpi->best_quality;
2584474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2585474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->active_worst_quality         = tmp_q;
2586474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->ni_av_qi                     = tmp_q;
2587474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2588474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2589ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* The last few frames of a clip almost always have to few or too many
2590ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * bits and for the sake of over exact rate control we dont want to make
2591ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * radical adjustments to the allowed quantizer range just to use up a
2592ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * few surplus bits or get beneath the target rate.
2593ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
2594474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    else if ( (cpi->common.current_video_frame <
2595167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                 (((unsigned int)cpi->twopass.total_stats.count * 255)>>8)) &&
2596474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org              ((cpi->common.current_video_frame + cpi->baseline_gf_interval) <
2597167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                 (unsigned int)cpi->twopass.total_stats.count) )
2598474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2599474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (frames_left < 1)
2600474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            frames_left = 1;
2601474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2602167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        tmp_q = estimate_max_q(
2603167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                    cpi,
2604167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                    &cpi->twopass.total_left_stats,
2605167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                    (int)(cpi->twopass.bits_left / frames_left),
2606167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                    overhead_bits );
2607474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2608ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Move active_worst_quality but in a damped way */
2609474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (tmp_q > cpi->active_worst_quality)
2610474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->active_worst_quality ++;
2611474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else if (tmp_q < cpi->active_worst_quality)
2612474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->active_worst_quality --;
2613474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2614167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        cpi->active_worst_quality =
2615167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            ((cpi->active_worst_quality * 3) + tmp_q + 2) / 4;
2616474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2617474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2618474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    cpi->twopass.frames_to_key --;
2619167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
2620ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Update the total stats remaining sturcture */
2621167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    subtract_stats(&cpi->twopass.total_left_stats, &this_frame );
2622474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
2623474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2624474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2625167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.orgstatic int test_candidate_kf(VP8_COMP *cpi,  FIRSTPASS_STATS *last_frame, FIRSTPASS_STATS *this_frame, FIRSTPASS_STATS *next_frame)
2626474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
2627167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    int is_viable_kf = 0;
2628474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2629ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Does the frame satisfy the primary criteria of a key frame
2630ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     *      If so, then examine how well it predicts subsequent frames
2631ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
2632474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if ((this_frame->pcnt_second_ref < 0.10) &&
2633474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        (next_frame->pcnt_second_ref < 0.10) &&
2634474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        ((this_frame->pcnt_inter < 0.05) ||
2635474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org         (
2636474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org             ((this_frame->pcnt_inter - this_frame->pcnt_neutral) < .25) &&
2637474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org             ((this_frame->intra_error / DOUBLE_DIVIDE_CHECK(this_frame->coded_error)) < 2.5) &&
2638474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org             ((fabs(last_frame->coded_error - this_frame->coded_error) / DOUBLE_DIVIDE_CHECK(this_frame->coded_error) > .40) ||
2639474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org              (fabs(last_frame->intra_error - this_frame->intra_error) / DOUBLE_DIVIDE_CHECK(this_frame->intra_error) > .40) ||
2640474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org              ((next_frame->intra_error / DOUBLE_DIVIDE_CHECK(next_frame->coded_error)) > 3.5)
2641474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org             )
2642474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org         )
2643474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        )
2644474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org       )
2645474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2646474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int i;
2647474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        FIRSTPASS_STATS *start_pos;
2648474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2649474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        FIRSTPASS_STATS local_next_frame;
2650474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2651474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double boost_score = 0.0;
2652474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double old_boost_score = 0.0;
2653474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double decay_accumulator = 1.0;
2654474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double next_iiratio;
2655474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2656474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        vpx_memcpy(&local_next_frame, next_frame, sizeof(*next_frame));
2657474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2658ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Note the starting file position so we can reset to it */
2659474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        start_pos = cpi->twopass.stats_in;
2660474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2661ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Examine how well the key frame predicts subsequent frames */
2662474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        for (i = 0 ; i < 16; i++)
2663474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2664474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            next_iiratio = (IIKFACTOR1 * local_next_frame.intra_error / DOUBLE_DIVIDE_CHECK(local_next_frame.coded_error)) ;
2665474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2666474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (next_iiratio > RMAX)
2667474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                next_iiratio = RMAX;
2668474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2669ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Cumulative effect of decay in prediction quality */
2670474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (local_next_frame.pcnt_inter > 0.85)
2671474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                decay_accumulator = decay_accumulator * local_next_frame.pcnt_inter;
2672474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            else
2673474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                decay_accumulator = decay_accumulator * ((0.85 + local_next_frame.pcnt_inter) / 2.0);
2674474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2675ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Keep a running total */
2676474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            boost_score += (decay_accumulator * next_iiratio);
2677474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2678ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Test various breakout clauses */
2679474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if ((local_next_frame.pcnt_inter < 0.05) ||
2680474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                (next_iiratio < 1.5) ||
2681474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                (((local_next_frame.pcnt_inter -
2682474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                   local_next_frame.pcnt_neutral) < 0.20) &&
2683474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                 (next_iiratio < 3.0)) ||
2684474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                ((boost_score - old_boost_score) < 0.5) ||
2685474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                (local_next_frame.intra_error < 200)
2686474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org               )
2687474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            {
2688474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                break;
2689474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            }
2690474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2691474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            old_boost_score = boost_score;
2692474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2693ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Get the next frame details */
2694474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (EOF == input_stats(cpi, &local_next_frame))
2695474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                break;
2696474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2697474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2698ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* If there is tolerable prediction for at least the next 3 frames
2699ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * then break out else discard this pottential key frame and move on
2700ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
2701474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (boost_score > 5.0 && (i > 3))
2702167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            is_viable_kf = 1;
2703474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
2704474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2705ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Reset the file position */
2706474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            reset_fpf_position(cpi, start_pos);
2707474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2708167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            is_viable_kf = 0;
2709474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2710474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2711474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2712474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    return is_viable_kf;
2713474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
2714474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
2715474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org{
2716474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    int i,j;
2717474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    FIRSTPASS_STATS last_frame;
2718474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    FIRSTPASS_STATS first_frame;
2719474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    FIRSTPASS_STATS next_frame;
2720474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    FIRSTPASS_STATS *start_position;
2721474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2722474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double decay_accumulator = 1.0;
2723474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double boost_score = 0;
2724474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double old_boost_score = 0.0;
2725474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double loop_decay_rate;
2726474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2727474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double kf_mod_err = 0.0;
2728474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double kf_group_err = 0.0;
2729474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double kf_group_intra_err = 0.0;
2730474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double kf_group_coded_err = 0.0;
2731474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    double recent_loop_decay[8] = {1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0};
2732474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2733ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    vpx_memset(&next_frame, 0, sizeof(next_frame));
2734474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2735ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    vp8_clear_system_state();
2736474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    start_position = cpi->twopass.stats_in;
2737474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2738474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    cpi->common.frame_type = KEY_FRAME;
2739474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2740ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* is this a forced key frame by interval */
2741474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    cpi->this_key_frame_forced = cpi->next_key_frame_forced;
2742474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2743ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Clear the alt ref active flag as this can never be active on a key
2744ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * frame
2745ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
2746167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org    cpi->source_alt_ref_active = 0;
2747474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2748ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Kf is always a gf so clear frames till next gf counter */
2749474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    cpi->frames_till_gf_update_due = 0;
2750474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2751474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    cpi->twopass.frames_to_key = 1;
2752474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2753ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Take a copy of the initial frame details */
2754474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    vpx_memcpy(&first_frame, this_frame, sizeof(*this_frame));
2755474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2756ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    cpi->twopass.kf_group_bits = 0;
2757ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    cpi->twopass.kf_group_error_left = 0;
2758474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2759474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    kf_mod_err = calculate_modified_err(cpi, this_frame);
2760474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2761ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* find the next keyframe */
2762474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    i = 0;
2763474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    while (cpi->twopass.stats_in < cpi->twopass.stats_in_end)
2764474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2765ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Accumulate kf group error */
2766474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        kf_group_err += calculate_modified_err(cpi, this_frame);
2767474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2768ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* These figures keep intra and coded error counts for all frames
2769ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * including key frames in the group. The effect of the key frame
2770ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * itself can be subtracted out using the first_frame data
2771ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * collected above
2772ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
2773474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        kf_group_intra_err += this_frame->intra_error;
2774474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        kf_group_coded_err += this_frame->coded_error;
2775474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2776411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org        /* Load the next frame's stats. */
2777474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        vpx_memcpy(&last_frame, this_frame, sizeof(*this_frame));
2778474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        input_stats(cpi, this_frame);
2779474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2780ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Provided that we are not at the end of the file... */
2781474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->oxcf.auto_key
2782474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            && lookup_next_frame_stats(cpi, &next_frame) != EOF)
2783474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2784ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Normal scene cut check */
2785167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            if ( ( i >= MIN_GF_INTERVAL ) &&
2786167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                 test_candidate_kf(cpi, &last_frame, this_frame, &next_frame) )
2787167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            {
2788474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                break;
2789167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            }
2790474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2791ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* How fast is prediction quality decaying */
2792474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame);
2793474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2794ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* We want to know something about the recent past... rather than
2795ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * as used elsewhere where we are concened with decay in prediction
2796ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * quality since the last GF or KF.
2797ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             */
2798474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            recent_loop_decay[i%8] = loop_decay_rate;
2799474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            decay_accumulator = 1.0;
2800474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            for (j = 0; j < 8; j++)
2801474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            {
2802474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                decay_accumulator = decay_accumulator * recent_loop_decay[j];
2803474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            }
2804474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2805ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Special check for transition or high motion followed by a
2806ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * static scene.
2807ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             */
2808474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if ( detect_transition_to_still( cpi, i,
2809474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                             (cpi->key_frame_frequency-i),
2810474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                             loop_decay_rate,
2811474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                             decay_accumulator ) )
2812474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            {
2813474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                break;
2814474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            }
2815474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2816474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2817ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Step on to the next frame */
2818474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->twopass.frames_to_key ++;
2819474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2820ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* If we don't have a real key frame within the next two
2821ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * forcekeyframeevery intervals then break out of the loop.
2822ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             */
2823474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (cpi->twopass.frames_to_key >= 2 *(int)cpi->key_frame_frequency)
2824474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                break;
2825474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        } else
2826474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->twopass.frames_to_key ++;
2827474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2828474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        i++;
2829474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2830474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2831ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* If there is a max kf interval set by the user we must obey it.
2832ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * We already breakout of the loop above at 2x max.
2833ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * This code centers the extra kf if the actual natural
2834ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * interval is between 1x and 2x
2835ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
2836474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cpi->oxcf.auto_key
2837474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        && cpi->twopass.frames_to_key > (int)cpi->key_frame_frequency )
2838474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2839474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        FIRSTPASS_STATS *current_pos = cpi->twopass.stats_in;
2840474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        FIRSTPASS_STATS tmp_frame;
2841474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2842474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.frames_to_key /= 2;
2843474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2844ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Copy first frame details */
2845474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        vpx_memcpy(&tmp_frame, &first_frame, sizeof(first_frame));
2846474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2847ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Reset to the start of the group */
2848474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        reset_fpf_position(cpi, start_position);
2849474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2850474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        kf_group_err = 0;
2851474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        kf_group_intra_err = 0;
2852474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        kf_group_coded_err = 0;
2853474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2854ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Rescan to get the correct error data for the forced kf group */
2855474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        for( i = 0; i < cpi->twopass.frames_to_key; i++ )
2856474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2857ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Accumulate kf group errors */
2858474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            kf_group_err += calculate_modified_err(cpi, &tmp_frame);
2859474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            kf_group_intra_err += tmp_frame.intra_error;
2860474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            kf_group_coded_err += tmp_frame.coded_error;
2861474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2862ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Load a the next frame's stats */
2863474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            input_stats(cpi, &tmp_frame);
2864474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2865474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2866ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Reset to the start of the group */
2867474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        reset_fpf_position(cpi, current_pos);
2868474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2869167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        cpi->next_key_frame_forced = 1;
2870474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2871474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    else
2872167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        cpi->next_key_frame_forced = 0;
2873474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2874ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Special case for the last frame of the file */
2875474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cpi->twopass.stats_in >= cpi->twopass.stats_in_end)
2876474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2877ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Accumulate kf group error */
2878474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        kf_group_err += calculate_modified_err(cpi, this_frame);
2879474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2880ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* These figures keep intra and coded error counts for all frames
2881ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * including key frames in the group. The effect of the key frame
2882ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * itself can be subtracted out using the first_frame data
2883ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * collected above
2884ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
2885474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        kf_group_intra_err += this_frame->intra_error;
2886474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        kf_group_coded_err += this_frame->coded_error;
2887474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2888474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2889ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Calculate the number of bits that should be assigned to the kf group. */
2890474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if ((cpi->twopass.bits_left > 0) && (cpi->twopass.modified_error_left > 0.0))
2891474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2892ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Max for a single normal frame (not key frame) */
2893474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int max_bits = frame_max_bits(cpi);
2894474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2895ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Maximum bits for the kf group */
2896474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int64_t max_grp_bits;
2897474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2898ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Default allocation based on bits left and relative
2899ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * complexity of the section
2900ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
2901474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.kf_group_bits = (int64_t)( cpi->twopass.bits_left *
2902474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                          ( kf_group_err /
2903474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                            cpi->twopass.modified_error_left ));
2904474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2905ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Clip based on maximum per frame rate defined by the user. */
2906474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        max_grp_bits = (int64_t)max_bits * (int64_t)cpi->twopass.frames_to_key;
2907474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->twopass.kf_group_bits > max_grp_bits)
2908474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->twopass.kf_group_bits = max_grp_bits;
2909474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2910ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Additional special case for CBR if buffer is getting full. */
2911474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
2912474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2913ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            int64_t opt_buffer_lvl = cpi->oxcf.optimal_buffer_level;
2914ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            int64_t buffer_lvl = cpi->buffer_level;
2915474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2916ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* If the buffer is near or above the optimal and this kf group is
2917ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * not being allocated much then increase the allocation a bit.
2918ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             */
2919474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (buffer_lvl >= opt_buffer_lvl)
2920474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            {
2921ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                int64_t high_water_mark = (opt_buffer_lvl +
2922474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                       cpi->oxcf.maximum_buffer_size) >> 1;
2923474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2924474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                int64_t av_group_bits;
2925474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2926ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                /* Av bits per frame * number of frames */
2927474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                av_group_bits = (int64_t)cpi->av_per_frame_bandwidth *
2928474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                (int64_t)cpi->twopass.frames_to_key;
2929474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2930ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                /* We are at or above the maximum. */
2931474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                if (cpi->buffer_level >= high_water_mark)
2932474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                {
2933474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    int64_t min_group_bits;
2934474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2935474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    min_group_bits = av_group_bits +
2936474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                     (int64_t)(buffer_lvl -
2937474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                                 high_water_mark);
2938474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2939474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    if (cpi->twopass.kf_group_bits < min_group_bits)
2940474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        cpi->twopass.kf_group_bits = min_group_bits;
2941474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                }
2942ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                /* We are above optimal but below the maximum */
2943474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                else if (cpi->twopass.kf_group_bits < av_group_bits)
2944474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                {
2945474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    int64_t bits_below_av = av_group_bits -
2946474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                              cpi->twopass.kf_group_bits;
2947474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2948474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    cpi->twopass.kf_group_bits +=
2949474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                       (int64_t)((double)bits_below_av *
2950474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                   (double)(buffer_lvl - opt_buffer_lvl) /
2951474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                   (double)(high_water_mark - opt_buffer_lvl));
2952474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                }
2953474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            }
2954474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2955474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
2956474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    else
2957474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.kf_group_bits = 0;
2958474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2959ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Reset the first pass file position */
2960474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    reset_fpf_position(cpi, start_position);
2961474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2962ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* determine how big to make this keyframe based on how well the
2963ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * subsequent frames use inter blocks
2964ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
2965474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    decay_accumulator = 1.0;
2966474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    boost_score = 0.0;
2967ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    loop_decay_rate = 1.00;       /* Starting decay rate */
2968474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2969474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    for (i = 0 ; i < cpi->twopass.frames_to_key ; i++)
2970474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
2971474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double r;
2972474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2973474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (EOF == input_stats(cpi, &next_frame))
2974474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            break;
2975474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2976474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (next_frame.intra_error > cpi->twopass.kf_intra_err_min)
2977474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            r = (IIKFACTOR2 * next_frame.intra_error /
2978474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                     DOUBLE_DIVIDE_CHECK(next_frame.coded_error));
2979474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
2980474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            r = (IIKFACTOR2 * cpi->twopass.kf_intra_err_min /
2981474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                     DOUBLE_DIVIDE_CHECK(next_frame.coded_error));
2982474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2983474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (r > RMAX)
2984474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            r = RMAX;
2985474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2986ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* How fast is prediction quality decaying */
2987474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame);
2988474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2989474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        decay_accumulator = decay_accumulator * loop_decay_rate;
2990474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        decay_accumulator = decay_accumulator < 0.1 ? 0.1 : decay_accumulator;
2991474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2992474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        boost_score += (decay_accumulator * r);
2993474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2994474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if ((i > MIN_GF_INTERVAL) &&
2995474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            ((boost_score - old_boost_score) < 1.0))
2996474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
2997474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            break;
2998474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
2999474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3000474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        old_boost_score = boost_score;
3001474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
3002474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3003474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (1)
3004474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
3005474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        FIRSTPASS_STATS sectionstats;
3006474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double Ratio;
3007474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3008474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        zero_stats(&sectionstats);
3009474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        reset_fpf_position(cpi, start_position);
3010474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3011474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        for (i = 0 ; i < cpi->twopass.frames_to_key ; i++)
3012474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
3013474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            input_stats(cpi, &next_frame);
3014474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            accumulate_stats(&sectionstats, &next_frame);
3015474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3016474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3017474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        avg_stats(&sectionstats);
3018474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3019ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        cpi->twopass.section_intra_rating = (unsigned int)
3020ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            (sectionstats.intra_error
3021ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error));
3022474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3023474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        Ratio = sectionstats.intra_error / DOUBLE_DIVIDE_CHECK(sectionstats.coded_error);
3024474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.section_max_qfactor = 1.0 - ((Ratio - 10.0) * 0.025);
3025474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3026474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->twopass.section_max_qfactor < 0.80)
3027474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->twopass.section_max_qfactor = 0.80;
3028474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
3029474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3030ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* When using CBR apply additional buffer fullness related upper limits */
3031474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
3032474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
3033474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double max_boost;
3034474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3035474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->drop_frames_allowed)
3036474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
3037ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            int df_buffer_level = (int)(cpi->oxcf.drop_frames_water_mark
3038ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                                  * (cpi->oxcf.optimal_buffer_level / 100));
3039474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3040474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (cpi->buffer_level > df_buffer_level)
3041474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                max_boost = ((double)((cpi->buffer_level - df_buffer_level) * 2 / 3) * 16.0) / DOUBLE_DIVIDE_CHECK((double)cpi->av_per_frame_bandwidth);
3042474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            else
3043474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                max_boost = 0.0;
3044474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3045474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else if (cpi->buffer_level > 0)
3046474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
3047474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            max_boost = ((double)(cpi->buffer_level * 2 / 3) * 16.0) / DOUBLE_DIVIDE_CHECK((double)cpi->av_per_frame_bandwidth);
3048474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3049474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
3050474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
3051474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            max_boost = 0.0;
3052474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3053474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3054474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (boost_score > max_boost)
3055474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            boost_score = max_boost;
3056474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
3057474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3058ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Reset the first pass file position */
3059474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    reset_fpf_position(cpi, start_position);
3060474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3061ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Work out how many bits to allocate for the key frame itself */
3062474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (1)
3063474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
3064ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        int kf_boost = (int)boost_score;
3065474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int allocation_chunks;
3066474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int Counter = cpi->twopass.frames_to_key;
3067474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int alt_kf_bits;
3068474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        YV12_BUFFER_CONFIG *lst_yv12 = &cpi->common.yv12_fb[cpi->common.lst_fb_idx];
3069ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Min boost based on kf interval */
3070474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if 0
3071474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3072474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        while ((kf_boost < 48) && (Counter > 0))
3073474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
3074474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            Counter -= 2;
3075474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            kf_boost ++;
3076474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3077474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3078474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif
3079474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3080474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (kf_boost < 48)
3081474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
3082474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            kf_boost += ((Counter + 1) >> 1);
3083474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3084474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (kf_boost > 48) kf_boost = 48;
3085474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3086474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3087ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* bigger frame sizes need larger kf boosts, smaller frames smaller
3088ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * boosts...
3089ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
3090474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if ((lst_yv12->y_width * lst_yv12->y_height) > (320 * 240))
3091474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            kf_boost += 2 * (lst_yv12->y_width * lst_yv12->y_height) / (320 * 240);
3092474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else if ((lst_yv12->y_width * lst_yv12->y_height) < (320 * 240))
3093474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            kf_boost -= 4 * (320 * 240) / (lst_yv12->y_width * lst_yv12->y_height);
3094474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3095ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Min KF boost */
3096ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        kf_boost = (int)((double)kf_boost * 100.0) >> 4; /* Scale 16 to 100 */
3097ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        if (kf_boost < 250)
3098474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            kf_boost = 250;
3099474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3100ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /*
3101ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * We do three calculations for kf size.
3102ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * The first is based on the error score for the whole kf group.
3103ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * The second (optionaly) on the key frames own error if this is
3104ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * smaller than the average for the group.
3105ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * The final one insures that the frame receives at least the
3106ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * allocation it would have received based on its own error score vs
3107ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * the error score remaining
3108ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * Special case if the sequence appears almost totaly static
3109ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * as measured by the decay accumulator. In this case we want to
3110ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * spend almost all of the bits on the key frame.
3111ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * cpi->twopass.frames_to_key-1 because key frame itself is taken
3112ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * care of by kf_boost.
3113ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
31145c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org        if ( decay_accumulator >= 0.99 )
31155c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org        {
31165c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org            allocation_chunks =
31175c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org                ((cpi->twopass.frames_to_key - 1) * 10) + kf_boost;
31185c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org        }
31195c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org        else
31205c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org        {
31215c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org            allocation_chunks =
31225c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org                ((cpi->twopass.frames_to_key - 1) * 100) + kf_boost;
31235c1d3b27608a3f3f6028c069b9bf066a4de474b6hclam@chromium.org        }
3124474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3125ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Normalize Altboost and allocations chunck down to prevent overflow */
3126474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        while (kf_boost > 1000)
3127474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
3128474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            kf_boost /= 2;
3129474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            allocation_chunks /= 2;
3130474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3131474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3132474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.kf_group_bits = (cpi->twopass.kf_group_bits < 0) ? 0 : cpi->twopass.kf_group_bits;
3133474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3134ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Calculate the number of bits to be spent on the key frame */
3135474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.kf_bits  = (int)((double)kf_boost * ((double)cpi->twopass.kf_group_bits / (double)allocation_chunks));
3136474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3137ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Apply an additional limit for CBR */
3138474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
3139474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
3140ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            if (cpi->twopass.kf_bits > (int)((3 * cpi->buffer_level) >> 2))
3141ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                cpi->twopass.kf_bits = (int)((3 * cpi->buffer_level) >> 2);
3142474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3143474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3144ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* If the key frame is actually easier than the average for the
3145ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * kf group (which does sometimes happen... eg a blank intro frame)
3146ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * Then use an alternate calculation based on the kf error score
3147ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * which should give a smaller key frame.
3148ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
3149474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (kf_mod_err < kf_group_err / cpi->twopass.frames_to_key)
3150474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
3151474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            double  alt_kf_grp_bits =
3152474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                        ((double)cpi->twopass.bits_left *
3153474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                         (kf_mod_err * (double)cpi->twopass.frames_to_key) /
3154474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                         DOUBLE_DIVIDE_CHECK(cpi->twopass.modified_error_left));
3155474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3156474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            alt_kf_bits = (int)((double)kf_boost *
3157474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                                (alt_kf_grp_bits / (double)allocation_chunks));
3158474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3159474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (cpi->twopass.kf_bits > alt_kf_bits)
3160474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            {
3161474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                cpi->twopass.kf_bits = alt_kf_bits;
3162474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            }
3163474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3164ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Else if it is much harder than other frames in the group make sure
3165ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * it at least receives an allocation in keeping with its relative
3166ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * error score
3167ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
3168474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
3169474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
3170474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            alt_kf_bits =
3171474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                (int)((double)cpi->twopass.bits_left *
3172474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                      (kf_mod_err /
3173474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                       DOUBLE_DIVIDE_CHECK(cpi->twopass.modified_error_left)));
3174474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3175474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if (alt_kf_bits > cpi->twopass.kf_bits)
3176474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            {
3177474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                cpi->twopass.kf_bits = alt_kf_bits;
3178474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            }
3179474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3180474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3181474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->twopass.kf_group_bits -= cpi->twopass.kf_bits;
3182ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Add in the minimum frame allowance */
3183ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        cpi->twopass.kf_bits += cpi->min_frame_bandwidth;
3184ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org
3185ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Peer frame bit target for this frame */
3186ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        cpi->per_frame_bandwidth = cpi->twopass.kf_bits;
3187474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3188ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Convert to a per second bitrate */
3189ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        cpi->target_bandwidth = (int)(cpi->twopass.kf_bits *
319047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org                                      cpi->output_framerate);
3191474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
3192474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3193ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Note the total error score of the kf group minus the key frame itself */
3194474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    cpi->twopass.kf_group_error_left = (int)(kf_group_err - kf_mod_err);
3195474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3196ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org    /* Adjust the count of total modified error left. The count of bits left
3197ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     * is adjusted elsewhere based on real coded frame sizes
3198ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org     */
3199474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    cpi->twopass.modified_error_left -= kf_group_err;
3200474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3201474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (cpi->oxcf.allow_spatial_resampling)
3202474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    {
3203167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        int resample_trigger = 0;
3204167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org        int last_kf_resampled = 0;
3205474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int kf_q;
3206474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int scale_val = 0;
3207474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int hr, hs, vr, vs;
3208474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int new_width = cpi->oxcf.Width;
3209474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int new_height = cpi->oxcf.Height;
3210474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3211ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        int projected_buffer_level = (int)cpi->buffer_level;
3212474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        int tmp_q;
3213474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3214474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double projected_bits_perframe;
3215474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double group_iiratio = (kf_group_intra_err - first_frame.intra_error) / (kf_group_coded_err - first_frame.coded_error);
3216474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double err_per_frame = kf_group_err / cpi->twopass.frames_to_key;
3217474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double bits_per_frame;
3218474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double av_bits_per_frame;
3219474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        double effective_size_ratio;
3220474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3221474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if ((cpi->common.Width != cpi->oxcf.Width) || (cpi->common.Height != cpi->oxcf.Height))
3222167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org            last_kf_resampled = 1;
3223474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3224ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Set back to unscaled by defaults */
3225474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->common.horiz_scale = NORMAL;
3226474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        cpi->common.vert_scale = NORMAL;
3227474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3228ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Calculate Average bits per frame. */
322947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org        av_bits_per_frame = cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->framerate);
3230474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3231ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* CBR... Use the clip average as the target for deciding resample */
3232474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
3233474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
3234474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            bits_per_frame = av_bits_per_frame;
3235474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3236474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3237ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* In VBR we want to avoid downsampling in easy section unless we
3238ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * are under extreme pressure So use the larger of target bitrate
3239ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * for this section or average bitrate for sequence
3240ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
3241474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
3242474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
3243ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* This accounts for how hard the section is... */
3244ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            bits_per_frame = (double)
3245ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                (cpi->twopass.kf_group_bits / cpi->twopass.frames_to_key);
3246474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3247ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Dont turn to resampling in easy sections just because they
3248ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * have been assigned a small number of bits
3249ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             */
3250ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            if (bits_per_frame < av_bits_per_frame)
3251474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                bits_per_frame = av_bits_per_frame;
3252474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3253474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3254ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* bits_per_frame should comply with our minimum */
3255474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (bits_per_frame < (cpi->oxcf.target_bandwidth * cpi->oxcf.two_pass_vbrmin_section / 100))
3256474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            bits_per_frame = (cpi->oxcf.target_bandwidth * cpi->oxcf.two_pass_vbrmin_section / 100);
3257474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3258ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Work out if spatial resampling is necessary */
3259ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        kf_q = estimate_kf_group_q(cpi, err_per_frame,
3260ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                                  (int)bits_per_frame, group_iiratio);
3261474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3262ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* If we project a required Q higher than the maximum allowed Q then
3263ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * make a guess at the actual size of frames in this section
3264ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
3265474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        projected_bits_perframe = bits_per_frame;
3266474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        tmp_q = kf_q;
3267474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3268474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        while (tmp_q > cpi->worst_quality)
3269474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
3270474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            projected_bits_perframe *= 1.04;
3271474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            tmp_q--;
3272474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3273474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3274ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* Guess at buffer level at the end of the section */
3275ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        projected_buffer_level = (int)
3276ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                    (cpi->buffer_level - (int)
3277ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                    ((projected_bits_perframe - av_bits_per_frame) *
3278ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                    cpi->twopass.frames_to_key));
3279474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3280474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (0)
3281474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
3282474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            FILE *f = fopen("Subsamle.stt", "a");
3283474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            fprintf(f, " %8d %8d %8d %8d %12.0f %8d %8d %8d\n",  cpi->common.current_video_frame, kf_q, cpi->common.horiz_scale, cpi->common.vert_scale,  kf_group_err / cpi->twopass.frames_to_key, (int)(cpi->twopass.kf_group_bits / cpi->twopass.frames_to_key), new_height, new_width);
3284474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            fclose(f);
3285474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3286474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3287ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org        /* The trigger for spatial resampling depends on the various
3288ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         * parameters such as whether we are streaming (CBR) or VBR.
3289ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org         */
3290474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
3291474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
3292ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* Trigger resample if we are projected to fall below down
3293ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * sample level or resampled last time and are projected to
3294ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * remain below the up sample level
3295ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             */
3296474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            if ((projected_buffer_level < (cpi->oxcf.resample_down_water_mark * cpi->oxcf.optimal_buffer_level / 100)) ||
3297474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                (last_kf_resampled && (projected_buffer_level < (cpi->oxcf.resample_up_water_mark * cpi->oxcf.optimal_buffer_level / 100))))
3298167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                resample_trigger = 1;
3299474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            else
3300167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                resample_trigger = 0;
3301474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3302474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        else
3303474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
330447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org            int64_t clip_bits = (int64_t)(cpi->twopass.total_stats.count * cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->framerate));
3305474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            int64_t over_spend = cpi->oxcf.starting_buffer_level - cpi->buffer_level;
3306474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3307ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            /* If triggered last time the threshold for triggering again is
3308ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * reduced:
3309ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             *
3310ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * Projected Q higher than allowed and Overspend > 5% of total
3311ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             * bits
3312ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org             */
3313ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org            if ((last_kf_resampled && (kf_q > cpi->worst_quality)) ||
3314ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                ((kf_q > cpi->worst_quality) &&
3315ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                 (over_spend > clip_bits / 20)))
3316167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                resample_trigger = 1;
3317474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            else
3318167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org                resample_trigger = 0;
3319474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3320474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3321474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3322474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if (resample_trigger)
3323474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
3324474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            while ((kf_q >= cpi->worst_quality) && (scale_val < 6))
3325474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            {
3326474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                scale_val ++;
3327474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3328474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                cpi->common.vert_scale   = vscale_lookup[scale_val];
3329474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                cpi->common.horiz_scale  = hscale_lookup[scale_val];
3330474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3331474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                Scale2Ratio(cpi->common.horiz_scale, &hr, &hs);
3332474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                Scale2Ratio(cpi->common.vert_scale, &vr, &vs);
3333474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3334474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                new_width = ((hs - 1) + (cpi->oxcf.Width * hr)) / hs;
3335474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                new_height = ((vs - 1) + (cpi->oxcf.Height * vr)) / vs;
3336474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3337ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                /* Reducing the area to 1/4 does not reduce the complexity
3338ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                 * (err_per_frame) to 1/4... effective_sizeratio attempts
3339ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                 * to provide a crude correction for this
3340ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                 */
3341474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                effective_size_ratio = (double)(new_width * new_height) / (double)(cpi->oxcf.Width * cpi->oxcf.Height);
3342474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                effective_size_ratio = (1.0 + (3.0 * effective_size_ratio)) / 4.0;
3343474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3344ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                /* Now try again and see what Q we get with the smaller
3345ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                 * image size
3346ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                 */
3347ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                kf_q = estimate_kf_group_q(cpi,
3348ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                                          err_per_frame * effective_size_ratio,
3349ed759d81a39febed3a8a395386639d54307504aagrunell@chromium.org                                          (int)bits_per_frame, group_iiratio);
3350474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3351474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                if (0)
3352474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                {
3353474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    FILE *f = fopen("Subsamle.stt", "a");
3354474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    fprintf(f, "******** %8d %8d %8d %12.0f %8d %8d %8d\n",  kf_q, cpi->common.horiz_scale, cpi->common.vert_scale,  kf_group_err / cpi->twopass.frames_to_key, (int)(cpi->twopass.kf_group_bits / cpi->twopass.frames_to_key), new_height, new_width);
3355474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                    fclose(f);
3356474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                }
3357474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            }
3358474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3359474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
3360474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        if ((cpi->common.Width != new_width) || (cpi->common.Height != new_height))
3361474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        {
3362474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->common.Width = new_width;
3363474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            cpi->common.Height = new_height;
3364474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org            vp8_alloc_compressor_data(cpi);
3365474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org        }
3366474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
3367474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
3368