|
|
|
@ -30,7 +30,6 @@
|
|
|
|
|
#include "encodemv.h"
|
|
|
|
|
|
|
|
|
|
//#define OUTPUT_FPF 1
|
|
|
|
|
#define FIRSTPASS_MM 1
|
|
|
|
|
|
|
|
|
|
#if CONFIG_RUNTIME_CPU_DETECT
|
|
|
|
|
#define IF_RTCD(x) (x)
|
|
|
|
@ -108,15 +107,6 @@ static void reset_fpf_position(VP8_COMP *cpi, FIRSTPASS_STATS *Position)
|
|
|
|
|
|
|
|
|
|
static int lookup_next_frame_stats(VP8_COMP *cpi, FIRSTPASS_STATS *next_frame)
|
|
|
|
|
{
|
|
|
|
|
/*FIRSTPASS_STATS * start_pos;
|
|
|
|
|
int ret_val;
|
|
|
|
|
|
|
|
|
|
start_pos = cpi->stats_in;
|
|
|
|
|
ret_val = vp8_input_stats(cpi, next_frame);
|
|
|
|
|
reset_fpf_position(cpi, start_pos);
|
|
|
|
|
|
|
|
|
|
return ret_val;*/
|
|
|
|
|
|
|
|
|
|
if (cpi->stats_in >= cpi->stats_in_end)
|
|
|
|
|
return EOF;
|
|
|
|
|
|
|
|
|
@ -127,7 +117,7 @@ static int lookup_next_frame_stats(VP8_COMP *cpi, FIRSTPASS_STATS *next_frame)
|
|
|
|
|
// Calculate a modified Error used in distributing bits between easier and harder frames
|
|
|
|
|
static double calculate_modified_err(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
|
|
|
|
{
|
|
|
|
|
double av_err = cpi->total_stats.ssim_weighted_pred_err;
|
|
|
|
|
double av_err = cpi->total_stats->ssim_weighted_pred_err;
|
|
|
|
|
double this_err = this_frame->ssim_weighted_pred_err;
|
|
|
|
|
double modified_err;
|
|
|
|
|
|
|
|
|
@ -238,7 +228,7 @@ int frame_max_bits(VP8_COMP *cpi)
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// For VBR base this on the bits and frames left plus the two_pass_vbrmax_section rate passed in by the user
|
|
|
|
|
max_bits = (int)(((double)cpi->bits_left / (cpi->total_stats.count - (double)cpi->common.current_video_frame)) * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
|
|
|
|
|
max_bits = (int)(((double)cpi->bits_left / (cpi->total_stats->count - (double)cpi->common.current_video_frame)) * ((double)cpi->oxcf.two_pass_vbrmax_section / 100.0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Trap case where we are out of bits
|
|
|
|
@ -248,13 +238,31 @@ int frame_max_bits(VP8_COMP *cpi)
|
|
|
|
|
return max_bits;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void vp8_output_stats(struct vpx_codec_pkt_list *pktlist,
|
|
|
|
|
|
|
|
|
|
extern size_t vp8_firstpass_stats_sz(unsigned int mb_count)
|
|
|
|
|
{
|
|
|
|
|
/* Calculate the size of a stats packet, which is dependent on the frame
|
|
|
|
|
* resolution. The FIRSTPASS_STATS struct has a single element array,
|
|
|
|
|
* motion_map, which is virtually expanded to have one element per
|
|
|
|
|
* macroblock.
|
|
|
|
|
*/
|
|
|
|
|
size_t stats_sz;
|
|
|
|
|
FIRSTPASS_STATS stats;
|
|
|
|
|
|
|
|
|
|
stats_sz = sizeof(FIRSTPASS_STATS) + mb_count;
|
|
|
|
|
stats_sz = (stats_sz + 7) & ~7;
|
|
|
|
|
return stats_sz;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void vp8_output_stats(const VP8_COMP *cpi,
|
|
|
|
|
struct vpx_codec_pkt_list *pktlist,
|
|
|
|
|
FIRSTPASS_STATS *stats)
|
|
|
|
|
{
|
|
|
|
|
struct vpx_codec_cx_pkt pkt;
|
|
|
|
|
pkt.kind = VPX_CODEC_STATS_PKT;
|
|
|
|
|
pkt.data.twopass_stats.buf = stats;
|
|
|
|
|
pkt.data.twopass_stats.sz = sizeof(*stats);
|
|
|
|
|
pkt.data.twopass_stats.sz = vp8_firstpass_stats_sz(cpi->common.MBs);
|
|
|
|
|
vpx_codec_pkt_list_add(pktlist, &pkt);
|
|
|
|
|
|
|
|
|
|
// TEMP debug code
|
|
|
|
@ -280,16 +288,24 @@ void vp8_output_stats(struct vpx_codec_pkt_list *pktlist,
|
|
|
|
|
stats->mv_in_out_count,
|
|
|
|
|
stats->count);
|
|
|
|
|
fclose(fpfile);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fpfile = fopen("fpmotionmap.stt", "a");
|
|
|
|
|
fwrite(cpi->fp_motion_map, 1, cpi->common.MBs, fpfile);
|
|
|
|
|
fclose(fpfile);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int vp8_input_stats(VP8_COMP *cpi, FIRSTPASS_STATS *fps)
|
|
|
|
|
{
|
|
|
|
|
size_t stats_sz = vp8_firstpass_stats_sz(cpi->common.MBs);
|
|
|
|
|
|
|
|
|
|
if (cpi->stats_in >= cpi->stats_in_end)
|
|
|
|
|
return EOF;
|
|
|
|
|
|
|
|
|
|
*fps = *cpi->stats_in++;
|
|
|
|
|
*fps = *cpi->stats_in;
|
|
|
|
|
cpi->stats_in = (void*)((char *)cpi->stats_in + stats_sz);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -352,59 +368,47 @@ void vp8_avg_stats(FIRSTPASS_STATS *section)
|
|
|
|
|
section->duration /= section->count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int vp8_fpmm_get_pos(VP8_COMP *cpi)
|
|
|
|
|
unsigned char *vp8_fpmm_get_pos(VP8_COMP *cpi)
|
|
|
|
|
{
|
|
|
|
|
return ftell(cpi->fp_motion_mapfile);
|
|
|
|
|
return cpi->fp_motion_map_stats;
|
|
|
|
|
}
|
|
|
|
|
void vp8_fpmm_reset_pos(VP8_COMP *cpi, int target_pos)
|
|
|
|
|
void vp8_fpmm_reset_pos(VP8_COMP *cpi, unsigned char *target_pos)
|
|
|
|
|
{
|
|
|
|
|
int Offset;
|
|
|
|
|
|
|
|
|
|
if (cpi->fp_motion_mapfile)
|
|
|
|
|
{
|
|
|
|
|
Offset = ftell(cpi->fp_motion_mapfile) - target_pos;
|
|
|
|
|
fseek(cpi->fp_motion_mapfile, (int) - Offset, SEEK_CUR);
|
|
|
|
|
}
|
|
|
|
|
cpi->fp_motion_map_stats = target_pos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void vp8_advance_fpmm(VP8_COMP *cpi, int count)
|
|
|
|
|
{
|
|
|
|
|
#if FIRSTPASS_MM
|
|
|
|
|
fseek(cpi->fp_motion_mapfile, (int)(count * cpi->common.MBs), SEEK_CUR);
|
|
|
|
|
#endif
|
|
|
|
|
cpi->fp_motion_map_stats = (void*)((char*)cpi->fp_motion_map_stats +
|
|
|
|
|
count * vp8_firstpass_stats_sz(cpi->common.MBs));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void vp8_input_fpmm(VP8_COMP *cpi)
|
|
|
|
|
{
|
|
|
|
|
#if FIRSTPASS_MM
|
|
|
|
|
unsigned char *fpmm = cpi->fp_motion_map;
|
|
|
|
|
int MBs = cpi->common.MBs;
|
|
|
|
|
int max_frames = cpi->active_arnr_frames;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
if (!cpi->fp_motion_mapfile)
|
|
|
|
|
return; // Error
|
|
|
|
|
|
|
|
|
|
// Read the specified number of frame motion maps
|
|
|
|
|
if (fread(cpi->fp_motion_map, 1,
|
|
|
|
|
max_frames * MBs,
|
|
|
|
|
cpi->fp_motion_mapfile) != max_frames*MBs)
|
|
|
|
|
for (i=0; i<max_frames; i++)
|
|
|
|
|
{
|
|
|
|
|
// Read error
|
|
|
|
|
return;
|
|
|
|
|
char *motion_map = (char*)cpi->fp_motion_map_stats
|
|
|
|
|
+ sizeof(FIRSTPASS_STATS);
|
|
|
|
|
|
|
|
|
|
memcpy(fpmm, motion_map, MBs);
|
|
|
|
|
fpmm += MBs;
|
|
|
|
|
vp8_advance_fpmm(cpi, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Flag the use of weights in the temporal filter
|
|
|
|
|
cpi->use_weighted_temporal_filter = 1;
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void vp8_init_first_pass(VP8_COMP *cpi)
|
|
|
|
|
{
|
|
|
|
|
vp8_zero_stats(&cpi->total_stats);
|
|
|
|
|
|
|
|
|
|
#ifdef FIRSTPASS_MM
|
|
|
|
|
cpi->fp_motion_mapfile = fopen("fpmotionmap.stt", "wb");
|
|
|
|
|
#endif
|
|
|
|
|
vp8_zero_stats(cpi->total_stats);
|
|
|
|
|
|
|
|
|
|
// TEMP debug code
|
|
|
|
|
#ifdef OUTPUT_FPF
|
|
|
|
@ -412,6 +416,8 @@ void vp8_init_first_pass(VP8_COMP *cpi)
|
|
|
|
|
FILE *fpfile;
|
|
|
|
|
fpfile = fopen("firstpass.stt", "w");
|
|
|
|
|
fclose(fpfile);
|
|
|
|
|
fpfile = fopen("fpmotionmap.stt", "wb");
|
|
|
|
|
fclose(fpfile);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
@ -419,16 +425,10 @@ void vp8_init_first_pass(VP8_COMP *cpi)
|
|
|
|
|
|
|
|
|
|
void vp8_end_first_pass(VP8_COMP *cpi)
|
|
|
|
|
{
|
|
|
|
|
vp8_output_stats(cpi->output_pkt_list, &cpi->total_stats);
|
|
|
|
|
|
|
|
|
|
#if FIRSTPASS_MM
|
|
|
|
|
|
|
|
|
|
if (cpi->fp_motion_mapfile)
|
|
|
|
|
fclose(cpi->fp_motion_mapfile);
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
vp8_output_stats(cpi, cpi->output_pkt_list, cpi->total_stats);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void vp8_zz_motion_search( VP8_COMP *cpi, MACROBLOCK * x, YV12_BUFFER_CONFIG * recon_buffer, int * best_motion_err, int recon_yoffset )
|
|
|
|
|
{
|
|
|
|
|
MACROBLOCKD * const xd = & x->e_mbd;
|
|
|
|
@ -839,19 +839,20 @@ void vp8_first_pass(VP8_COMP *cpi)
|
|
|
|
|
fps.duration = cpi->source_end_time_stamp - cpi->source_time_stamp;
|
|
|
|
|
|
|
|
|
|
// don't want to do outputstats with a stack variable!
|
|
|
|
|
cpi->this_frame_stats = fps;
|
|
|
|
|
vp8_output_stats(cpi->output_pkt_list, &cpi->this_frame_stats);
|
|
|
|
|
vp8_accumulate_stats(&cpi->total_stats, &fps);
|
|
|
|
|
|
|
|
|
|
#if FIRSTPASS_MM
|
|
|
|
|
fwrite(cpi->fp_motion_map, 1, cpi->common.MBs, cpi->fp_motion_mapfile);
|
|
|
|
|
#endif
|
|
|
|
|
memcpy(cpi->this_frame_stats,
|
|
|
|
|
&fps,
|
|
|
|
|
sizeof(FIRSTPASS_STATS));
|
|
|
|
|
memcpy((char*)cpi->this_frame_stats + sizeof(FIRSTPASS_STATS),
|
|
|
|
|
cpi->fp_motion_map,
|
|
|
|
|
sizeof(cpi->fp_motion_map[0]) * cpi->common.MBs);
|
|
|
|
|
vp8_output_stats(cpi, cpi->output_pkt_list, cpi->this_frame_stats);
|
|
|
|
|
vp8_accumulate_stats(cpi->total_stats, &fps);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Copy the previous Last Frame into the GF buffer if specific conditions for doing so are met
|
|
|
|
|
if ((cm->current_video_frame > 0) &&
|
|
|
|
|
(cpi->this_frame_stats.pcnt_inter > 0.20) &&
|
|
|
|
|
((cpi->this_frame_stats.intra_error / cpi->this_frame_stats.coded_error) > 2.0))
|
|
|
|
|
(cpi->this_frame_stats->pcnt_inter > 0.20) &&
|
|
|
|
|
((cpi->this_frame_stats->intra_error / cpi->this_frame_stats->coded_error) > 2.0))
|
|
|
|
|
{
|
|
|
|
|
vp8_yv12_copy_frame_ptr(lst_yv12, gld_yv12);
|
|
|
|
|
}
|
|
|
|
@ -1120,33 +1121,33 @@ void vp8_init_second_pass(VP8_COMP *cpi)
|
|
|
|
|
|
|
|
|
|
double two_pass_min_rate = (double)(cpi->oxcf.target_bandwidth * cpi->oxcf.two_pass_vbrmin_section / 100);
|
|
|
|
|
|
|
|
|
|
vp8_zero_stats(&cpi->total_stats);
|
|
|
|
|
vp8_zero_stats(cpi->total_stats);
|
|
|
|
|
|
|
|
|
|
if (!cpi->stats_in_end)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
cpi->total_stats = *cpi->stats_in_end;
|
|
|
|
|
*cpi->total_stats = *cpi->stats_in_end;
|
|
|
|
|
|
|
|
|
|
cpi->total_error_left = cpi->total_stats.ssim_weighted_pred_err;
|
|
|
|
|
cpi->total_intra_error_left = cpi->total_stats.intra_error;
|
|
|
|
|
cpi->total_coded_error_left = cpi->total_stats.coded_error;
|
|
|
|
|
cpi->total_error_left = cpi->total_stats->ssim_weighted_pred_err;
|
|
|
|
|
cpi->total_intra_error_left = cpi->total_stats->intra_error;
|
|
|
|
|
cpi->total_coded_error_left = cpi->total_stats->coded_error;
|
|
|
|
|
cpi->start_tot_err_left = cpi->total_error_left;
|
|
|
|
|
|
|
|
|
|
//cpi->bits_left = (long long)(cpi->total_stats.count * cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate));
|
|
|
|
|
//cpi->bits_left -= (long long)(cpi->total_stats.count * two_pass_min_rate / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate));
|
|
|
|
|
//cpi->bits_left = (long long)(cpi->total_stats->count * cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate));
|
|
|
|
|
//cpi->bits_left -= (long long)(cpi->total_stats->count * two_pass_min_rate / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate));
|
|
|
|
|
|
|
|
|
|
// each frame can have a different duration, as the frame rate in the source
|
|
|
|
|
// isn't guaranteed to be constant. The frame rate prior to the first frame
|
|
|
|
|
// encoded in the second pass is a guess. However the sum duration is not.
|
|
|
|
|
// Its calculated based on the actual durations of all frames from the first
|
|
|
|
|
// pass.
|
|
|
|
|
vp8_new_frame_rate(cpi, 10000000.0 * cpi->total_stats.count / cpi->total_stats.duration);
|
|
|
|
|
vp8_new_frame_rate(cpi, 10000000.0 * cpi->total_stats->count / cpi->total_stats->duration);
|
|
|
|
|
|
|
|
|
|
cpi->output_frame_rate = cpi->oxcf.frame_rate;
|
|
|
|
|
cpi->bits_left = (long long)(cpi->total_stats.duration * cpi->oxcf.target_bandwidth / 10000000.0) ;
|
|
|
|
|
cpi->bits_left -= (long long)(cpi->total_stats.duration * two_pass_min_rate / 10000000.0);
|
|
|
|
|
cpi->bits_left = (long long)(cpi->total_stats->duration * cpi->oxcf.target_bandwidth / 10000000.0) ;
|
|
|
|
|
cpi->bits_left -= (long long)(cpi->total_stats->duration * two_pass_min_rate / 10000000.0);
|
|
|
|
|
|
|
|
|
|
vp8_avg_stats(&cpi->total_stats);
|
|
|
|
|
vp8_avg_stats(cpi->total_stats);
|
|
|
|
|
|
|
|
|
|
// Scan the first pass file and calculate an average Intra / Inter error score ratio for the sequence
|
|
|
|
|
{
|
|
|
|
@ -1162,7 +1163,7 @@ void vp8_init_second_pass(VP8_COMP *cpi)
|
|
|
|
|
sum_iiratio += IIRatio;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cpi->avg_iiratio = sum_iiratio / DOUBLE_DIVIDE_CHECK((double)cpi->total_stats.count);
|
|
|
|
|
cpi->avg_iiratio = sum_iiratio / DOUBLE_DIVIDE_CHECK((double)cpi->total_stats->count);
|
|
|
|
|
|
|
|
|
|
// Reset file position
|
|
|
|
|
reset_fpf_position(cpi, start_pos);
|
|
|
|
@ -1184,21 +1185,11 @@ void vp8_init_second_pass(VP8_COMP *cpi)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if FIRSTPASS_MM
|
|
|
|
|
cpi->fp_motion_mapfile = 0;
|
|
|
|
|
cpi->fp_motion_mapfile = fopen("fpmotionmap.stt", "rb");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
cpi->fp_motion_map_stats = (unsigned char *)cpi->stats_in;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void vp8_end_second_pass(VP8_COMP *cpi)
|
|
|
|
|
{
|
|
|
|
|
#if FIRSTPASS_MM
|
|
|
|
|
|
|
|
|
|
if (cpi->fp_motion_mapfile)
|
|
|
|
|
fclose(cpi->fp_motion_mapfile);
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Analyse and define a gf/arf group .
|
|
|
|
@ -1231,18 +1222,14 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
|
|
|
|
|
|
|
|
|
int max_bits = frame_max_bits(cpi); // Max for a single frame
|
|
|
|
|
|
|
|
|
|
#if FIRSTPASS_MM
|
|
|
|
|
int fpmm_pos;
|
|
|
|
|
#endif
|
|
|
|
|
unsigned char *fpmm_pos;
|
|
|
|
|
|
|
|
|
|
cpi->gf_group_bits = 0;
|
|
|
|
|
cpi->gf_decay_rate = 0;
|
|
|
|
|
|
|
|
|
|
vp8_clear_system_state(); //__asm emms;
|
|
|
|
|
|
|
|
|
|
#if FIRSTPASS_MM
|
|
|
|
|
fpmm_pos = vp8_fpmm_get_pos(cpi);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
start_pos = cpi->stats_in;
|
|
|
|
|
|
|
|
|
@ -1494,7 +1481,7 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
|
|
|
|
// Note: this_frame->frame has been updated in the loop
|
|
|
|
|
// so it now points at the ARF frame.
|
|
|
|
|
half_gf_int = cpi->baseline_gf_interval >> 1;
|
|
|
|
|
frames_after_arf = cpi->total_stats.count - this_frame->frame - 1;
|
|
|
|
|
frames_after_arf = cpi->total_stats->count - this_frame->frame - 1;
|
|
|
|
|
|
|
|
|
|
switch (cpi->oxcf.arnr_type)
|
|
|
|
|
{
|
|
|
|
@ -1531,12 +1518,11 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
|
|
|
|
|
|
|
|
|
cpi->active_arnr_frames = frames_bwd + 1 + frames_fwd;
|
|
|
|
|
|
|
|
|
|
#if FIRSTPASS_MM
|
|
|
|
|
{
|
|
|
|
|
// Advance to & read in the motion map for those frames
|
|
|
|
|
// to be considered for filtering based on the position
|
|
|
|
|
// of the ARF
|
|
|
|
|
vp8_fpmm_reset_pos(cpi, cpi->fpmm_pos);
|
|
|
|
|
vp8_fpmm_reset_pos(cpi, cpi->fp_motion_map_stats_save);
|
|
|
|
|
|
|
|
|
|
// Position at the 'earliest' frame to be filtered
|
|
|
|
|
vp8_advance_fpmm(cpi,
|
|
|
|
@ -1545,7 +1531,6 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
|
|
|
|
// Read / create a motion map for the region of interest
|
|
|
|
|
vp8_input_fpmm(cpi);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -1581,7 +1566,7 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
|
|
|
|
// Now decide how many bits should be allocated to the GF group as a proportion of those remaining in the kf group.
|
|
|
|
|
// The final key frame group in the clip is treated as a special case where cpi->kf_group_bits is tied to cpi->bits_left.
|
|
|
|
|
// This is also important for short clips where there may only be one key frame.
|
|
|
|
|
if (cpi->frames_to_key >= (int)(cpi->total_stats.count - cpi->common.current_video_frame))
|
|
|
|
|
if (cpi->frames_to_key >= (int)(cpi->total_stats->count - cpi->common.current_video_frame))
|
|
|
|
|
{
|
|
|
|
|
cpi->kf_group_bits = (cpi->bits_left > 0) ? cpi->bits_left : 0;
|
|
|
|
|
}
|
|
|
|
@ -1781,10 +1766,8 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
|
|
|
|
reset_fpf_position(cpi, start_pos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if FIRSTPASS_MM
|
|
|
|
|
// Reset the First pass motion map file position
|
|
|
|
|
vp8_fpmm_reset_pos(cpi, fpmm_pos);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Allocate bits to a normal frame that is neither a gf an arf or a key frame.
|
|
|
|
@ -1798,7 +1781,7 @@ static void assign_std_frame_bits(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
|
|
|
|
int max_bits = frame_max_bits(cpi); // Max for a single frame
|
|
|
|
|
|
|
|
|
|
// The final few frames have special treatment
|
|
|
|
|
if (cpi->frames_till_gf_update_due >= (int)(cpi->total_stats.count - cpi->common.current_video_frame))
|
|
|
|
|
if (cpi->frames_till_gf_update_due >= (int)(cpi->total_stats->count - cpi->common.current_video_frame))
|
|
|
|
|
{
|
|
|
|
|
cpi->gf_group_bits = (cpi->bits_left > 0) ? cpi->bits_left : 0;;
|
|
|
|
|
}
|
|
|
|
@ -1843,7 +1826,7 @@ static void assign_std_frame_bits(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
|
|
|
|
void vp8_second_pass(VP8_COMP *cpi)
|
|
|
|
|
{
|
|
|
|
|
int tmp_q;
|
|
|
|
|
int frames_left = (int)(cpi->total_stats.count - cpi->common.current_video_frame);
|
|
|
|
|
int frames_left = (int)(cpi->total_stats->count - cpi->common.current_video_frame);
|
|
|
|
|
|
|
|
|
|
FIRSTPASS_STATS this_frame;
|
|
|
|
|
FIRSTPASS_STATS this_frame_copy;
|
|
|
|
@ -1866,14 +1849,12 @@ void vp8_second_pass(VP8_COMP *cpi)
|
|
|
|
|
if (EOF == vp8_input_stats(cpi, &this_frame))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
#if FIRSTPASS_MM
|
|
|
|
|
vpx_memset(cpi->fp_motion_map, 0,
|
|
|
|
|
cpi->oxcf.arnr_max_frames*cpi->common.MBs);
|
|
|
|
|
cpi->fpmm_pos = vp8_fpmm_get_pos(cpi);
|
|
|
|
|
cpi->fp_motion_map_stats_save = vp8_fpmm_get_pos(cpi);
|
|
|
|
|
|
|
|
|
|
// Step over this frame's first pass motion map
|
|
|
|
|
vp8_advance_fpmm(cpi, 1);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
this_frame_error = this_frame.ssim_weighted_pred_err;
|
|
|
|
|
this_frame_intra_error = this_frame.intra_error;
|
|
|
|
@ -2562,7 +2543,7 @@ void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
|
|
|
|
cpi->common.vert_scale = NORMAL;
|
|
|
|
|
|
|
|
|
|
// Calculate Average bits per frame.
|
|
|
|
|
//av_bits_per_frame = cpi->bits_left/(double)(cpi->total_stats.count - cpi->common.current_video_frame);
|
|
|
|
|
//av_bits_per_frame = cpi->bits_left/(double)(cpi->total_stats->count - cpi->common.current_video_frame);
|
|
|
|
|
av_bits_per_frame = cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate);
|
|
|
|
|
//if ( av_bits_per_frame < 0.0 )
|
|
|
|
|
// av_bits_per_frame = 0.0
|
|
|
|
@ -2625,7 +2606,7 @@ void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
long long clip_bits = (long long)(cpi->total_stats.count * cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate));
|
|
|
|
|
long long clip_bits = (long long)(cpi->total_stats->count * cpi->oxcf.target_bandwidth / DOUBLE_DIVIDE_CHECK((double)cpi->oxcf.frame_rate));
|
|
|
|
|
long long over_spend = cpi->oxcf.starting_buffer_level - cpi->buffer_level;
|
|
|
|
|
long long over_spend2 = cpi->oxcf.starting_buffer_level - projected_buffer_level;
|
|
|
|
|
|
|
|
|
|