/*****************************************************************************
* slicetype.c: lookahead analysis
*****************************************************************************
- * Copyright (C) 2005-2015 x264 project
+ * Copyright (C) 2005-2016 x264 project
*
* Authors: Fiona Glaser <fiona@x264.com>
* Loren Merritt <lorenm@u.washington.edu>
static const uint8_t delta_tfi_divisor[10] = { 0, 2, 1, 1, 2, 2, 3, 3, 4, 6 };
static int x264_slicetype_frame_cost( x264_t *h, x264_mb_analysis_t *a,
- x264_frame_t **frames, int p0, int p1, int b,
- int b_intra_penalty );
+ x264_frame_t **frames, int p0, int p1, int b );
void x264_weights_analyse( x264_t *h, x264_frame_t *fenc, x264_frame_t *ref, int b_lookahead );
{
x264_mb_analysis_t a;
x264_lowres_context_init( h, &a );
- x264_slicetype_frame_cost( h, &a, &fenc, 0, 0, 0, 0 );
+ x264_slicetype_frame_cost( h, &a, &fenc, 0, 0, 0 );
}
mcbuf = x264_weight_cost_init_luma( h, fenc, ref, h->mb.p_weight_buf[0] );
origscore = minscore = x264_weight_cost_luma( h, fenc, mcbuf, NULL );
}
}
- i_icost += intra_penalty + lowres_penalty;
+ i_icost = ((i_icost + intra_penalty) >> (BIT_DEPTH - 8)) + lowres_penalty;
fenc->i_intra_cost[i_mb_xy] = i_icost;
int i_icost_aq = i_icost;
if( h->param.rc.i_aq_mode )
output_intra[COST_EST_AQ] += i_icost_aq;
}
}
- i_bcost += lowres_penalty;
+ i_bcost = (i_bcost >> (BIT_DEPTH - 8)) + lowres_penalty;
/* forbid intra-mbs in B-frames, because it's rare and not worth checking */
/* FIXME: Should we still forbid them now that we cache intra scores? */
}
static int x264_slicetype_frame_cost( x264_t *h, x264_mb_analysis_t *a,
- x264_frame_t **frames, int p0, int p1, int b,
- int b_intra_penalty )
+ x264_frame_t **frames, int p0, int p1, int b )
{
int i_score = 0;
int do_search[2];
}
}
- if( b_intra_penalty )
- {
- // arbitrary penalty for I-blocks after B-frames
- int nmb = NUM_MBS;
- i_score += (uint64_t)i_score * fenc->i_intra_mbs[b-p0] / (nmb * 8);
- }
return i_score;
}
int i = num_frames;
if( b_intra )
- x264_slicetype_frame_cost( h, a, frames, 0, 0, 0, 0 );
+ x264_slicetype_frame_cost( h, a, frames, 0, 0, 0 );
while( i > 0 && IS_X264_TYPE_B( frames[i]->i_type ) )
i--;
cur_nonb--;
if( cur_nonb < idx )
break;
- x264_slicetype_frame_cost( h, a, frames, cur_nonb, last_nonb, last_nonb, 0 );
+ x264_slicetype_frame_cost( h, a, frames, cur_nonb, last_nonb, last_nonb );
memset( frames[cur_nonb]->i_propagate_cost, 0, h->mb.i_mb_count * sizeof(uint16_t) );
bframes = last_nonb - cur_nonb - 1;
if( h->param.i_bframe_pyramid && bframes > 1 )
{
int middle = (bframes + 1)/2 + cur_nonb;
- x264_slicetype_frame_cost( h, a, frames, cur_nonb, last_nonb, middle, 0 );
+ x264_slicetype_frame_cost( h, a, frames, cur_nonb, last_nonb, middle );
memset( frames[middle]->i_propagate_cost, 0, h->mb.i_mb_count * sizeof(uint16_t) );
while( i > cur_nonb )
{
int p1 = i < middle ? middle : last_nonb;
if( i != middle )
{
- x264_slicetype_frame_cost( h, a, frames, p0, p1, i, 0 );
+ x264_slicetype_frame_cost( h, a, frames, p0, p1, i );
x264_macroblock_tree_propagate( h, frames, average_duration, p0, p1, i, 0 );
}
i--;
{
while( i > cur_nonb )
{
- x264_slicetype_frame_cost( h, a, frames, cur_nonb, last_nonb, i, 0 );
+ x264_slicetype_frame_cost( h, a, frames, cur_nonb, last_nonb, i );
x264_macroblock_tree_propagate( h, frames, average_duration, cur_nonb, last_nonb, i, 0 );
i--;
}
if( !h->param.rc.i_lookahead )
{
- x264_slicetype_frame_cost( h, a, frames, 0, last_nonb, last_nonb, 0 );
+ x264_slicetype_frame_cost( h, a, frames, 0, last_nonb, last_nonb );
x264_macroblock_tree_propagate( h, frames, average_duration, 0, last_nonb, last_nonb, 1 );
XCHG( uint16_t*, frames[last_nonb]->i_propagate_cost, frames[0]->i_propagate_cost );
}
static int x264_vbv_frame_cost( x264_t *h, x264_mb_analysis_t *a, x264_frame_t **frames, int p0, int p1, int b )
{
- int cost = x264_slicetype_frame_cost( h, a, frames, p0, p1, b, 0 );
+ int cost = x264_slicetype_frame_cost( h, a, frames, p0, p1, b );
if( h->param.rc.i_aq_mode )
{
if( h->param.rc.b_mb_tree )
/* Add the cost of the non-B-frame found above */
if( path[next_nonb] == 'P' )
- cost += x264_slicetype_frame_cost( h, a, frames, cur_nonb, next_nonb, next_nonb, 0 );
+ cost += x264_slicetype_frame_cost( h, a, frames, cur_nonb, next_nonb, next_nonb );
else /* I-frame */
- cost += x264_slicetype_frame_cost( h, a, frames, next_nonb, next_nonb, next_nonb, 0 );
+ cost += x264_slicetype_frame_cost( h, a, frames, next_nonb, next_nonb, next_nonb );
/* Early terminate if the cost we have found is larger than the best path cost so far */
if( cost > threshold )
break;
if( h->param.i_bframe_pyramid && next_nonb - cur_nonb > 2 )
{
int middle = cur_nonb + (next_nonb - cur_nonb)/2;
- cost += x264_slicetype_frame_cost( h, a, frames, cur_nonb, next_nonb, middle, 0 );
+ cost += x264_slicetype_frame_cost( h, a, frames, cur_nonb, next_nonb, middle );
for( int next_b = loc; next_b < middle && cost < threshold; next_b++ )
- cost += x264_slicetype_frame_cost( h, a, frames, cur_nonb, middle, next_b, 0 );
+ cost += x264_slicetype_frame_cost( h, a, frames, cur_nonb, middle, next_b );
for( int next_b = middle+1; next_b < next_nonb && cost < threshold; next_b++ )
- cost += x264_slicetype_frame_cost( h, a, frames, middle, next_nonb, next_b, 0 );
+ cost += x264_slicetype_frame_cost( h, a, frames, middle, next_nonb, next_b );
}
else
for( int next_b = loc; next_b < next_nonb && cost < threshold; next_b++ )
- cost += x264_slicetype_frame_cost( h, a, frames, cur_nonb, next_nonb, next_b, 0 );
+ cost += x264_slicetype_frame_cost( h, a, frames, cur_nonb, next_nonb, next_b );
loc = next_nonb + 1;
cur_nonb = next_nonb;
if( real_scenecut && h->param.i_frame_packing == 5 && (frame->i_frame&1) )
return 0;
- x264_slicetype_frame_cost( h, a, frames, p0, p1, p1, 0 );
+ x264_slicetype_frame_cost( h, a, frames, p0, p1, p1 );
int icost = frame->i_cost_est[0][0];
int pcost = frame->i_cost_est[p1-p0][0];
x264_mb_analysis_t a;
x264_frame_t *frames[X264_LOOKAHEAD_MAX+3] = { NULL, };
int num_frames, orig_num_frames, keyint_limit, framecnt;
- int i_mb_count = NUM_MBS;
int i_max_search = X264_MIN( h->lookahead->next.i_size, X264_LOOKAHEAD_MAX );
int vbv_lookahead = h->param.rc.i_vbv_buffer_size && h->param.rc.i_lookahead;
/* For determinism we should limit the search to the number of frames lookahead has for sure
{
int last_nonb = 0;
int num_bframes = h->param.i_bframe;
+ char path[X264_LOOKAHEAD_MAX+1];
for( int j = 1; j < num_frames; j++ )
{
if( j-1 > 0 && IS_X264_TYPE_B( frames[j-1]->i_type ) )
continue;
}
- if( j - last_nonb <= 1 )
- {
- int cost2p1 = x264_slicetype_frame_cost( h, &a, frames, last_nonb+0, j+1, j+1, 1 );
- if( frames[j+1]->i_intra_mbs[2] > i_mb_count / 2 )
- {
- frames[j]->i_type = X264_TYPE_P;
- continue;
- }
+ int bframes = j - last_nonb - 1;
+ memset( path, 'B', bframes );
+ strcpy( path+bframes, "PP" );
+ int cost_p = x264_slicetype_path_cost( h, &a, frames+last_nonb, path, COST_MAX );
+ strcpy( path+bframes, "BP" );
+ int cost_b = x264_slicetype_path_cost( h, &a, frames+last_nonb, path, cost_p );
-#if HAVE_OPENCL
- if( h->param.b_opencl )
- {
- int b_work_done = 0;
- b_work_done |= x264_opencl_precalculate_frame_cost(h, frames, a.i_lambda, last_nonb+0, j+1, j+0 );
- b_work_done |= x264_opencl_precalculate_frame_cost(h, frames, a.i_lambda, last_nonb+0, j+0, j+0 );
- b_work_done |= x264_opencl_precalculate_frame_cost(h, frames, a.i_lambda, last_nonb+1, j+1, j+1 );
- if( b_work_done )
- x264_opencl_flush( h );
- }
-#endif
-
- int cost1b1 = x264_slicetype_frame_cost( h, &a, frames, last_nonb+0, j+1, j+0, 0 );
- int cost1p0 = x264_slicetype_frame_cost( h, &a, frames, last_nonb+0, j+0, j+0, 0 );
- int cost2p0 = x264_slicetype_frame_cost( h, &a, frames, last_nonb+1, j+1, j+1, 0 );
-
- if( cost1p0 + cost2p0 < cost1b1 + cost2p1 )
- {
- frames[j]->i_type = X264_TYPE_P;
- continue;
- }
+ if( cost_b < cost_p )
frames[j]->i_type = X264_TYPE_B;
- continue;
- }
-
- // arbitrary and untuned
- #define INTER_THRESH 300
- #define P_SENS_BIAS (50 - h->param.i_bframe_bias)
-
- int pthresh = X264_MAX(INTER_THRESH - P_SENS_BIAS * (j-last_nonb-1), INTER_THRESH/10);
- int pcost = x264_slicetype_frame_cost( h, &a, frames, last_nonb, j+1, j+1, 1 );
- if( pcost > pthresh*i_mb_count || frames[j+1]->i_intra_mbs[j-last_nonb+1] > i_mb_count/3 )
- frames[j]->i_type = X264_TYPE_P;
else
- frames[j]->i_type = X264_TYPE_B;
+ frames[j]->i_type = X264_TYPE_P;
}
}
else
/* insert a bref into the sequence */
if( h->param.i_bframe_pyramid && bframes > 1 && !brefs )
{
- h->lookahead->next.list[bframes/2]->i_type = X264_TYPE_BREF;
+ h->lookahead->next.list[(bframes-1)/2]->i_type = X264_TYPE_BREF;
brefs++;
}
else // P
p0 = 0;
- x264_slicetype_frame_cost( h, &a, frames, p0, p1, b, 0 );
+ x264_slicetype_frame_cost( h, &a, frames, p0, p1, b );
if( (p0 != p1 || bframes) && h->param.rc.i_vbv_buffer_size )
{
/* We need the intra costs for row SATDs. */
- x264_slicetype_frame_cost( h, &a, frames, b, b, b, 0 );
+ x264_slicetype_frame_cost( h, &a, frames, b, b, b );
/* We need B-frame costs for row SATDs. */
p0 = 0;
p1++;
else
p1 = bframes + 1;
- x264_slicetype_frame_cost( h, &a, frames, p0, p1, b, 0 );
+ x264_slicetype_frame_cost( h, &a, frames, p0, p1, b );
if( frames[b]->i_type == X264_TYPE_BREF )
p0 = b;
}
}
}
- if( BIT_DEPTH > 8 )
- for( int y = 0; y < h->mb.i_mb_height; y++ )
- h->fdec->i_row_satd[y] >>= (BIT_DEPTH - 8);
-
- return cost >> (BIT_DEPTH - 8);
+ return cost;
}