summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vp8/encoder/firstpass.c185
-rw-r--r--vp8/encoder/firstpass.h1
-rw-r--r--vp8/encoder/onyx_if.c20
-rw-r--r--vp8/encoder/onyx_int.h8
-rw-r--r--vp8/vp8_cx_iface.c18
5 files changed, 114 insertions, 118 deletions
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c
index 13633e9a4..607c3d236 100644
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -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);
+ vp8_output_stats(cpi, cpi->output_pkt_list, cpi->total_stats);
+}
-#endif
-}
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;
diff --git a/vp8/encoder/firstpass.h b/vp8/encoder/firstpass.h
index c7f3e0e45..95e1e5463 100644
--- a/vp8/encoder/firstpass.h
+++ b/vp8/encoder/firstpass.h
@@ -20,4 +20,5 @@ extern void vp8_init_second_pass(VP8_COMP *cpi);
extern void vp8_second_pass(VP8_COMP *cpi);
extern void vp8_end_second_pass(VP8_COMP *cpi);
+extern size_t vp8_firstpass_stats_sz(unsigned int mb_count);
#endif
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 382a9de58..27964f97b 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -330,6 +330,8 @@ void vp8_dealloc_compressor_data(VP8_COMP *cpi)
cpi->mb.pip = 0;
+ vpx_free(cpi->total_stats);
+ vpx_free(cpi->this_frame_stats);
}
static void enable_segmentation(VP8_PTR ptr)
@@ -1392,6 +1394,12 @@ void vp8_alloc_compressor_data(VP8_COMP *cpi)
CHECK_MEM_ERROR(cpi->gf_active_flags, vpx_calloc(1, cm->mb_rows * cm->mb_cols));
cpi->gf_active_count = cm->mb_rows * cm->mb_cols;
+
+ cpi->total_stats = vpx_calloc(1, vp8_firstpass_stats_sz(cpi->common.MBs));
+ cpi->this_frame_stats = vpx_calloc(1, vp8_firstpass_stats_sz(cpi->common.MBs));
+ if(!cpi->total_stats || !cpi->this_frame_stats)
+ vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
+ "Failed to allocate firstpass stats");
}
@@ -2290,10 +2298,12 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
}
else if (cpi->pass == 2)
{
+ size_t packet_sz = vp8_firstpass_stats_sz(cpi->common.MBs);
+ int packets = oxcf->two_pass_stats_in.sz / packet_sz;
+
cpi->stats_in = oxcf->two_pass_stats_in.buf;
- cpi->stats_in_end = cpi->stats_in
- + oxcf->two_pass_stats_in.sz / sizeof(FIRSTPASS_STATS)
- - 1;
+ cpi->stats_in_end = (void*)((char *)cpi->stats_in
+ + (packets - 1) * packet_sz);
vp8_init_second_pass(cpi);
}
@@ -3481,7 +3491,7 @@ static void apply_temporal_filter
modifier = 16 - modifier;
#endif
modifier *= filter_weight;
-
+
count[k] += modifier;
accumulator[k] += modifier * pixel_value;
@@ -3656,7 +3666,7 @@ static void vp8cx_temp_blur1_c
YV12_BUFFER_CONFIG *f = cpi->frames[alt_ref_index];
unsigned char *dst1, *dst2;
DECLARE_ALIGNED(16, unsigned char, predictor[384]);
-
+
// Save input state
unsigned char *y_buffer = mbd->pre.y_buffer;
unsigned char *u_buffer = mbd->pre.u_buffer;
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index 8a34a1f3a..51b62c6eb 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -461,14 +461,14 @@ typedef struct
int target_bandwidth;
long long bits_left;
- FIRSTPASS_STATS total_stats;
- FIRSTPASS_STATS this_frame_stats;
+ FIRSTPASS_STATS *total_stats;
+ FIRSTPASS_STATS *this_frame_stats;
FIRSTPASS_STATS *stats_in, *stats_in_end;
struct vpx_codec_pkt_list *output_pkt_list;
int first_pass_done;
unsigned char *fp_motion_map;
- FILE *fp_motion_mapfile;
- int fpmm_pos;
+
+ unsigned char *fp_motion_map_stats, *fp_motion_map_stats_save;
#if 0
// Experimental code for lagged and one pass
diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c
index 499bc503a..b4bb679b5 100644
--- a/vp8/vp8_cx_iface.c
+++ b/vp8/vp8_cx_iface.c
@@ -14,6 +14,7 @@
#include "vpx_version.h"
#include "onyx_int.h"
#include "vpx/vp8e.h"
+#include "vp8/encoder/firstpass.h"
#include "onyx.h"
#include <stdlib.h>
#include <string.h>
@@ -189,22 +190,25 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
if (cfg->g_pass == VPX_RC_LAST_PASS)
{
- int n_doubles = cfg->rc_twopass_stats_in.sz / sizeof(double);
- int n_packets = cfg->rc_twopass_stats_in.sz / sizeof(FIRSTPASS_STATS);
- double frames;
+ int mb_r = (cfg->g_h + 15) / 16;
+ int mb_c = (cfg->g_w + 15) / 16;
+ size_t packet_sz = vp8_firstpass_stats_sz(mb_r * mb_c);
+ int n_packets = cfg->rc_twopass_stats_in.sz / packet_sz;
+ FIRSTPASS_STATS *stats;
if (!cfg->rc_twopass_stats_in.buf)
ERROR("rc_twopass_stats_in.buf not set.");
- if (cfg->rc_twopass_stats_in.sz % sizeof(FIRSTPASS_STATS))
+ if (cfg->rc_twopass_stats_in.sz % packet_sz)
ERROR("rc_twopass_stats_in.sz indicates truncated packet.");
- if (cfg->rc_twopass_stats_in.sz < 2 * sizeof(FIRSTPASS_STATS))
+ if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz)
ERROR("rc_twopass_stats_in requires at least two packets.");
- frames = ((double *)cfg->rc_twopass_stats_in.buf)[n_doubles - 1];
+ stats = (void*)((char *)cfg->rc_twopass_stats_in.buf
+ + (n_packets - 1) * packet_sz);
- if ((int)(frames + 0.5) != n_packets - 1)
+ if ((int)(stats->count + 0.5) != n_packets - 1)
ERROR("rc_twopass_stats_in missing EOS stats packet");
}