Removed firstpass motion map
The firstpass motion map consists of an 8-bit flag for each MB indicating how strongly the firstpass code believes it should be filtered during the second pass ARNR filtering. For long or large format material the motion map can become extremely large and hamper the operation of the encoding process. This change removes the motion map altogether, leaving the second pass to rely on the magnitude of the motion compensated error to determine the filter weight to use for the MB during ARNR filtering. Tests on the derf set indicate that the effect of this change is neutral, with some small wins and losses. The motion map has therefore been removed based on a cost/benefit evaluation. Change-Id: I53e07d236f5ce09a6f0c54e7c4ffbb490fb870f6
This commit is contained in:
parent
a0306ea660
commit
ed40ff9e2d
@ -281,21 +281,6 @@ int frame_max_bits(VP8_COMP *cpi)
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
@ -303,7 +288,7 @@ void vp8_output_stats(const VP8_COMP *cpi,
|
||||
struct vpx_codec_cx_pkt pkt;
|
||||
pkt.kind = VPX_CODEC_STATS_PKT;
|
||||
pkt.data.twopass_stats.buf = stats;
|
||||
pkt.data.twopass_stats.sz = vp8_firstpass_stats_sz(cpi->common.MBs);
|
||||
pkt.data.twopass_stats.sz = sizeof(FIRSTPASS_STATS);
|
||||
vpx_codec_pkt_list_add(pktlist, &pkt);
|
||||
|
||||
// TEMP debug code
|
||||
@ -333,24 +318,17 @@ void vp8_output_stats(const VP8_COMP *cpi,
|
||||
stats->count,
|
||||
stats->duration);
|
||||
fclose(fpfile);
|
||||
|
||||
|
||||
fpfile = fopen("fpmotionmap.stt", "a");
|
||||
if(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;
|
||||
cpi->stats_in = (void*)((char *)cpi->stats_in + stats_sz);
|
||||
cpi->stats_in = (void*)((char *)cpi->stats_in + sizeof(FIRSTPASS_STATS));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -416,57 +394,9 @@ void vp8_avg_stats(FIRSTPASS_STATS *section)
|
||||
section->duration /= section->count;
|
||||
}
|
||||
|
||||
unsigned char *vp8_fpmm_get_pos(VP8_COMP *cpi)
|
||||
{
|
||||
return cpi->fp_motion_map_stats;
|
||||
}
|
||||
void vp8_fpmm_reset_pos(VP8_COMP *cpi, unsigned char *target_pos)
|
||||
{
|
||||
cpi->fp_motion_map_stats = target_pos;
|
||||
}
|
||||
|
||||
void vp8_advance_fpmm(VP8_COMP *cpi, int count)
|
||||
{
|
||||
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)
|
||||
{
|
||||
unsigned char *fpmm = cpi->fp_motion_map;
|
||||
int MBs = cpi->common.MBs;
|
||||
int max_frames = cpi->active_arnr_frames;
|
||||
int i;
|
||||
|
||||
for (i=0; i<max_frames; i++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void vp8_init_first_pass(VP8_COMP *cpi)
|
||||
{
|
||||
vp8_zero_stats(cpi->total_stats);
|
||||
|
||||
// TEMP debug code
|
||||
#ifdef OUTPUT_FPF
|
||||
{
|
||||
FILE *fpfile;
|
||||
fpfile = fopen("firstpass.stt", "w");
|
||||
fclose(fpfile);
|
||||
fpfile = fopen("fpmotionmap.stt", "wb");
|
||||
fclose(fpfile);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void vp8_end_first_pass(VP8_COMP *cpi)
|
||||
@ -583,8 +513,6 @@ void vp8_first_pass(VP8_COMP *cpi)
|
||||
|
||||
MV zero_ref_mv = {0, 0};
|
||||
|
||||
unsigned char *fp_motion_map_ptr = cpi->fp_motion_map;
|
||||
|
||||
vp8_clear_system_state(); //__asm emms;
|
||||
|
||||
x->src = * cpi->Source;
|
||||
@ -636,7 +564,6 @@ void vp8_first_pass(VP8_COMP *cpi)
|
||||
for (mb_col = 0; mb_col < cm->mb_cols; mb_col++)
|
||||
{
|
||||
int this_error;
|
||||
int zero_error;
|
||||
int zz_to_best_ratio;
|
||||
int gf_motion_error = INT_MAX;
|
||||
int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
|
||||
@ -658,9 +585,6 @@ void vp8_first_pass(VP8_COMP *cpi)
|
||||
// Cumulative intra error total
|
||||
intra_error += (long long)this_error;
|
||||
|
||||
// Indicate default assumption of intra in the motion map
|
||||
*fp_motion_map_ptr = 0;
|
||||
|
||||
// Set up limit values for motion vectors to prevent them extending outside the UMV borders
|
||||
x->mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 16));
|
||||
x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16) + (VP8BORDERINPIXELS - 16);
|
||||
@ -679,9 +603,6 @@ void vp8_first_pass(VP8_COMP *cpi)
|
||||
d->bmi.mv.as_mv.row = 0;
|
||||
d->bmi.mv.as_mv.col = 0;
|
||||
|
||||
// Save (0,0) error for later use
|
||||
zero_error = motion_error;
|
||||
|
||||
// Test last reference frame using the previous best mv as the
|
||||
// starting point (best reference) for the search
|
||||
vp8_first_pass_motion_search(cpi, x, &best_ref_mv.as_mv,
|
||||
@ -796,25 +717,6 @@ void vp8_first_pass(VP8_COMP *cpi)
|
||||
else if (d->bmi.mv.as_mv.col < 0)
|
||||
sum_in_vectors--;
|
||||
}
|
||||
|
||||
// Compute how close (0,0) predictor is to best
|
||||
// predictor in terms of their prediction error
|
||||
zz_to_best_ratio = (10*zero_error + this_error/2)
|
||||
/ (this_error+!this_error);
|
||||
|
||||
if ((zero_error < 50000) &&
|
||||
(zz_to_best_ratio <= 11) )
|
||||
*fp_motion_map_ptr = 1;
|
||||
else
|
||||
*fp_motion_map_ptr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 0,0 mv was best
|
||||
if( zero_error<50000 )
|
||||
*fp_motion_map_ptr = 2;
|
||||
else
|
||||
*fp_motion_map_ptr = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -828,9 +730,6 @@ void vp8_first_pass(VP8_COMP *cpi)
|
||||
|
||||
recon_yoffset += 16;
|
||||
recon_uvoffset += 8;
|
||||
|
||||
// Update the motion map
|
||||
fp_motion_map_ptr++;
|
||||
}
|
||||
|
||||
// adjust to the next row of mbs
|
||||
@ -892,13 +791,10 @@ void vp8_first_pass(VP8_COMP *cpi)
|
||||
// than the full time between subsequent cpi->source_time_stamp s .
|
||||
fps.duration = cpi->source_end_time_stamp - cpi->source_time_stamp;
|
||||
|
||||
// don't want to do outputstats with a stack variable!
|
||||
// don't want to do output stats with a stack variable!
|
||||
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);
|
||||
}
|
||||
@ -1351,8 +1247,6 @@ void vp8_init_second_pass(VP8_COMP *cpi)
|
||||
cpi->clip_bpe = cpi->bits_left /
|
||||
DOUBLE_DIVIDE_CHECK(cpi->modified_error_total);
|
||||
cpi->observed_bpe = cpi->clip_bpe;
|
||||
|
||||
cpi->fp_motion_map_stats = (unsigned char *)cpi->stats_in;
|
||||
}
|
||||
|
||||
void vp8_end_second_pass(VP8_COMP *cpi)
|
||||
@ -1360,7 +1254,7 @@ void vp8_end_second_pass(VP8_COMP *cpi)
|
||||
}
|
||||
|
||||
// This function gives and estimate of how badly we believe
|
||||
// the predicition quality is decaying from frame to frame.
|
||||
// the prediction quality is decaying from frame to frame.
|
||||
double get_prediction_decay_rate(VP8_COMP *cpi, FIRSTPASS_STATS *next_frame)
|
||||
{
|
||||
double prediction_decay_rate;
|
||||
@ -1472,8 +1366,6 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
||||
|
||||
int max_bits = frame_max_bits(cpi); // Max for a single frame
|
||||
|
||||
unsigned char *fpmm_pos;
|
||||
|
||||
unsigned int allow_alt_ref =
|
||||
cpi->oxcf.play_alternate && cpi->oxcf.lag_in_frames;
|
||||
|
||||
@ -1482,8 +1374,6 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
||||
|
||||
vp8_clear_system_state(); //__asm emms;
|
||||
|
||||
fpmm_pos = vp8_fpmm_get_pos(cpi);
|
||||
|
||||
start_pos = cpi->stats_in;
|
||||
|
||||
vpx_memset(&next_frame, 0, sizeof(next_frame)); // assure clean
|
||||
@ -1780,20 +1670,6 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
||||
}
|
||||
|
||||
cpi->active_arnr_frames = frames_bwd + 1 + frames_fwd;
|
||||
|
||||
{
|
||||
// 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->fp_motion_map_stats_save);
|
||||
|
||||
// Position at the 'earliest' frame to be filtered
|
||||
vp8_advance_fpmm(cpi,
|
||||
cpi->baseline_gf_interval - frames_bwd);
|
||||
|
||||
// Read / create a motion map for the region of interest
|
||||
vp8_input_fpmm(cpi);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2023,9 +1899,6 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
|
||||
|
||||
reset_fpf_position(cpi, start_pos);
|
||||
}
|
||||
|
||||
// Reset the First pass motion map file position
|
||||
vp8_fpmm_reset_pos(cpi, fpmm_pos);
|
||||
}
|
||||
|
||||
// Allocate bits to a normal frame that is neither a gf an arf or a key frame.
|
||||
@ -2107,13 +1980,6 @@ void vp8_second_pass(VP8_COMP *cpi)
|
||||
if (EOF == vp8_input_stats(cpi, &this_frame))
|
||||
return;
|
||||
|
||||
vpx_memset(cpi->fp_motion_map, 0,
|
||||
cpi->oxcf.arnr_max_frames*cpi->common.MBs);
|
||||
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);
|
||||
|
||||
this_frame_error = this_frame.ssim_weighted_pred_err;
|
||||
this_frame_intra_error = this_frame.intra_error;
|
||||
this_frame_coded_error = this_frame.coded_error;
|
||||
|
@ -281,12 +281,6 @@ void vp8_dealloc_compressor_data(VP8_COMP *cpi)
|
||||
vpx_free(cpi->active_map);
|
||||
cpi->active_map = 0;
|
||||
|
||||
#if !(CONFIG_REALTIME_ONLY)
|
||||
// Delete first pass motion map
|
||||
vpx_free(cpi->fp_motion_map);
|
||||
cpi->fp_motion_map = 0;
|
||||
#endif
|
||||
|
||||
vp8_de_alloc_frame_buffers(&cpi->common);
|
||||
|
||||
vp8_yv12_de_alloc_frame_buffer(&cpi->last_frame_uf);
|
||||
@ -1360,11 +1354,11 @@ void vp8_alloc_compressor_data(VP8_COMP *cpi)
|
||||
#if !(CONFIG_REALTIME_ONLY)
|
||||
vpx_free(cpi->total_stats);
|
||||
|
||||
cpi->total_stats = vpx_calloc(1, vp8_firstpass_stats_sz(cpi->common.MBs));
|
||||
cpi->total_stats = vpx_calloc(1, sizeof(FIRSTPASS_STATS));
|
||||
|
||||
vpx_free(cpi->this_frame_stats);
|
||||
|
||||
cpi->this_frame_stats = vpx_calloc(1, vp8_firstpass_stats_sz(cpi->common.MBs));
|
||||
cpi->this_frame_stats = vpx_calloc(1, sizeof(FIRSTPASS_STATS));
|
||||
|
||||
if(!cpi->total_stats || !cpi->this_frame_stats)
|
||||
vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
|
||||
@ -1543,8 +1537,6 @@ void vp8_init_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
|
||||
|
||||
#if VP8_TEMPORAL_ALT_REF
|
||||
|
||||
cpi->use_weighted_temporal_filter = 0;
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -1927,12 +1919,6 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
|
||||
vpx_memset(cpi->active_map , 1, (cpi->common.mb_rows * cpi->common.mb_cols));
|
||||
cpi->active_map_enabled = 0;
|
||||
|
||||
#if !(CONFIG_REALTIME_ONLY)
|
||||
// Create the first pass motion map structure and set to 0
|
||||
// Allocate space for maximum of 15 buffers
|
||||
CHECK_MEM_ERROR(cpi->fp_motion_map, vpx_calloc(15*cpi->common.MBs, 1));
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// Experimental code for lagged and one pass
|
||||
// Initialise one_pass GF frames stats
|
||||
@ -2082,7 +2068,7 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf)
|
||||
}
|
||||
else if (cpi->pass == 2)
|
||||
{
|
||||
size_t packet_sz = vp8_firstpass_stats_sz(cpi->common.MBs);
|
||||
size_t packet_sz = sizeof(FIRSTPASS_STATS);
|
||||
int packets = oxcf->two_pass_stats_in.sz / packet_sz;
|
||||
|
||||
cpi->stats_in = oxcf->two_pass_stats_in.buf;
|
||||
|
@ -496,11 +496,6 @@ typedef struct
|
||||
struct vpx_codec_pkt_list *output_pkt_list;
|
||||
int first_pass_done;
|
||||
|
||||
#if !(CONFIG_REALTIME_ONLY)
|
||||
unsigned char *fp_motion_map;
|
||||
unsigned char *fp_motion_map_stats, *fp_motion_map_stats_save;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// Experimental code for lagged and one pass
|
||||
ONEPASS_FRAMESTATS one_pass_frame_stats[MAX_LAG_BUFFERS];
|
||||
@ -642,8 +637,6 @@ typedef struct
|
||||
YV12_BUFFER_CONFIG *frames[MAX_LAG_BUFFERS];
|
||||
int fixed_divide[512];
|
||||
#endif
|
||||
// Flag to indicate temporal filter method
|
||||
int use_weighted_temporal_filter;
|
||||
|
||||
#if CONFIG_PSNR
|
||||
int count;
|
||||
|
@ -287,8 +287,7 @@ static void vp8_temporal_filter_iterate_c
|
||||
int byte;
|
||||
int frame;
|
||||
int mb_col, mb_row;
|
||||
unsigned int filter_weight[MAX_LAG_BUFFERS];
|
||||
unsigned char *mm_ptr = cpi->fp_motion_map;
|
||||
unsigned int filter_weight;
|
||||
int mb_cols = cpi->common.mb_cols;
|
||||
int mb_rows = cpi->common.mb_rows;
|
||||
int MBs = cpi->common.MBs;
|
||||
@ -306,13 +305,6 @@ static void vp8_temporal_filter_iterate_c
|
||||
unsigned char *u_buffer = mbd->pre.u_buffer;
|
||||
unsigned char *v_buffer = mbd->pre.v_buffer;
|
||||
|
||||
if (!cpi->use_weighted_temporal_filter)
|
||||
{
|
||||
// Temporal filtering is unweighted
|
||||
for (frame = 0; frame < frame_count; frame++)
|
||||
filter_weight[frame] = 1;
|
||||
}
|
||||
|
||||
for (mb_row = 0; mb_row < mb_rows; mb_row++)
|
||||
{
|
||||
#if ALT_REF_MC_ENABLED
|
||||
@ -338,34 +330,9 @@ static void vp8_temporal_filter_iterate_c
|
||||
+ (VP8BORDERINPIXELS - 19);
|
||||
#endif
|
||||
|
||||
// Read & process macroblock weights from motion map
|
||||
if (cpi->use_weighted_temporal_filter)
|
||||
{
|
||||
weight_cap = 2;
|
||||
|
||||
for (frame = alt_ref_index-1; frame >= 0; frame--)
|
||||
{
|
||||
w = *(mm_ptr + (frame+1)*MBs);
|
||||
filter_weight[frame] = w < weight_cap ? w : weight_cap;
|
||||
weight_cap = w;
|
||||
}
|
||||
|
||||
filter_weight[alt_ref_index] = 2;
|
||||
|
||||
weight_cap = 2;
|
||||
|
||||
for (frame = alt_ref_index+1; frame < frame_count; frame++)
|
||||
{
|
||||
w = *(mm_ptr + frame*MBs);
|
||||
filter_weight[frame] = w < weight_cap ? w : weight_cap;
|
||||
weight_cap = w;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (frame = 0; frame < frame_count; frame++)
|
||||
{
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
if (cpi->frames[frame] == NULL)
|
||||
continue;
|
||||
@ -374,28 +341,25 @@ static void vp8_temporal_filter_iterate_c
|
||||
mbd->block[0].bmi.mv.as_mv.col = 0;
|
||||
|
||||
#if ALT_REF_MC_ENABLED
|
||||
//if (filter_weight[frame] == 0)
|
||||
{
|
||||
#define THRESH_LOW 10000
|
||||
#define THRESH_HIGH 20000
|
||||
|
||||
// Correlation has been lost try MC
|
||||
err = vp8_temporal_filter_find_matching_mb_c
|
||||
(cpi,
|
||||
cpi->frames[alt_ref_index],
|
||||
cpi->frames[frame],
|
||||
mb_y_offset,
|
||||
THRESH_LOW);
|
||||
// Find best match in this frame by MC
|
||||
err = vp8_temporal_filter_find_matching_mb_c
|
||||
(cpi,
|
||||
cpi->frames[alt_ref_index],
|
||||
cpi->frames[frame],
|
||||
mb_y_offset,
|
||||
THRESH_LOW);
|
||||
|
||||
if (filter_weight[frame] < 2)
|
||||
{
|
||||
// Set weight depending on error
|
||||
filter_weight[frame] = err<THRESH_LOW
|
||||
? 2 : err<THRESH_HIGH ? 1 : 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (filter_weight[frame] != 0)
|
||||
// Assign higher weight to matching MB if it's error
|
||||
// score is lower. If not applying MC default behavior
|
||||
// is to weight all MBs equal.
|
||||
filter_weight = err<THRESH_LOW
|
||||
? 2 : err<THRESH_HIGH ? 1 : 0;
|
||||
|
||||
if (filter_weight != 0)
|
||||
{
|
||||
// Construct the predictors
|
||||
vp8_temporal_filter_predictors_mb_c
|
||||
@ -415,7 +379,7 @@ static void vp8_temporal_filter_iterate_c
|
||||
predictor,
|
||||
16,
|
||||
strength,
|
||||
filter_weight[frame],
|
||||
filter_weight,
|
||||
accumulator,
|
||||
count);
|
||||
|
||||
@ -425,7 +389,7 @@ static void vp8_temporal_filter_iterate_c
|
||||
predictor + 256,
|
||||
8,
|
||||
strength,
|
||||
filter_weight[frame],
|
||||
filter_weight,
|
||||
accumulator + 256,
|
||||
count + 256);
|
||||
|
||||
@ -435,7 +399,7 @@ static void vp8_temporal_filter_iterate_c
|
||||
predictor + 320,
|
||||
8,
|
||||
strength,
|
||||
filter_weight[frame],
|
||||
filter_weight,
|
||||
accumulator + 320,
|
||||
count + 320);
|
||||
}
|
||||
@ -491,7 +455,6 @@ static void vp8_temporal_filter_iterate_c
|
||||
byte += stride - 8;
|
||||
}
|
||||
|
||||
mm_ptr++;
|
||||
mb_y_offset += 16;
|
||||
mb_uv_offset += 8;
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
|
||||
{
|
||||
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);
|
||||
size_t packet_sz = sizeof(FIRSTPASS_STATS);
|
||||
int n_packets = cfg->rc_twopass_stats_in.sz / packet_sz;
|
||||
FIRSTPASS_STATS *stats;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user