summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vp8/encoder/firstpass.c24
-rw-r--r--vp8/encoder/mbgraph.c8
-rw-r--r--vp8/encoder/onyx_if.c79
-rw-r--r--vp8/encoder/onyx_int.h7
-rw-r--r--vp8/encoder/quantize.c26
-rw-r--r--vp8/encoder/ratectrl.c10
6 files changed, 106 insertions, 48 deletions
diff --git a/vp8/encoder/firstpass.c b/vp8/encoder/firstpass.c
index 901404617..19ae70684 100644
--- a/vp8/encoder/firstpass.c
+++ b/vp8/encoder/firstpass.c
@@ -3032,10 +3032,26 @@ static void find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
// We do three calculations for kf size.
// The first is based on the error score for the whole kf group.
- // The second (optionaly) on the key frames own error if this is smaller than the average for the group.
- // The final one insures that the frame receives at least the allocation it would have received based on its own error score vs the error score remaining
-
- allocation_chunks = ((cpi->twopass.frames_to_key - 1) * 100) + kf_boost; // cpi->twopass.frames_to_key-1 because key frame itself is taken care of by kf_boost
+ // The second (optionaly) on the key frames own error if this is
+ // smaller than the average for the group.
+ // The final one insures that the frame receives at least the
+ // allocation it would have received based on its own error score vs
+ // the error score remaining
+ // Special case if the sequence appears almost totaly static
+ // as measured by the decay accumulator. In this case we want to
+ // spend almost all of the bits on the key frame.
+ // cpi->twopass.frames_to_key-1 because key frame itself is taken
+ // care of by kf_boost.
+ if ( decay_accumulator >= 0.99 )
+ {
+ allocation_chunks =
+ ((cpi->twopass.frames_to_key - 1) * 10) + kf_boost;
+ }
+ else
+ {
+ allocation_chunks =
+ ((cpi->twopass.frames_to_key - 1) * 100) + kf_boost;
+ }
// Normalize Altboost and allocations chunck down to prevent overflow
while (kf_boost > 1000)
diff --git a/vp8/encoder/mbgraph.c b/vp8/encoder/mbgraph.c
index ad40c9e33..4f9ba125b 100644
--- a/vp8/encoder/mbgraph.c
+++ b/vp8/encoder/mbgraph.c
@@ -477,12 +477,16 @@ void separate_arf_mbs
//if ( ncnt[1] && (ncnt[0] / ncnt[1] < 10) )
if ( 1 )
{
- cpi->mbgraph_use_arf_segmentation = ncnt[1];
+ // Note % of blocks that are marked as static
+ cpi->static_mb_pct =
+ (ncnt[1] * 100) / cm->MBs;
+
vp8_enable_segmentation((VP8_PTR) cpi);
}
else
{
- cpi->mbgraph_use_arf_segmentation = 0;
+ cpi->static_mb_pct = 0;
+
vp8_disable_segmentation((VP8_PTR) cpi);
}
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index b60d996a8..25b56691d 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -492,6 +492,7 @@ static void init_seg_features(VP8_COMP *cpi)
vpx_memset( cpi->segmentation_map, 0, (cm->mb_rows * cm->mb_cols));
xd->update_mb_segmentation_map = 0;
xd->update_mb_segmentation_data = 0;
+ cpi->static_mb_pct = 0;
// Disable segmentation
vp8_disable_segmentation((VP8_PTR)cpi);
@@ -507,6 +508,7 @@ static void init_seg_features(VP8_COMP *cpi)
vpx_memset( cpi->segmentation_map, 0, (cm->mb_rows * cm->mb_cols));
xd->update_mb_segmentation_map = 0;
xd->update_mb_segmentation_data = 0;
+ cpi->static_mb_pct = 0;
// Disable segmentation and individual segment features by default
vp8_disable_segmentation((VP8_PTR)cpi);
@@ -557,7 +559,7 @@ static void init_seg_features(VP8_COMP *cpi)
set_segdata( xd, 1, SEG_LVL_ALT_LF, -2 );
enable_segfeature(xd, 1, SEG_LVL_ALT_LF);
- if ( high_q )
+ if ( high_q || (cpi->static_mb_pct == 100) )
{
set_segref(xd, 1, ALTREF_FRAME);
enable_segfeature(xd, 1, SEG_LVL_REF_FRAME);
@@ -1973,6 +1975,8 @@ static void init_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
cpi->total_actual_bits = 0;
cpi->total_target_vs_actual = 0;
+ cpi->static_mb_pct = 0;
+
#if VP8_TEMPORAL_ALT_REF
{
int i;
@@ -2233,6 +2237,7 @@ void vp8_change_config(VP8_PTR ptr, VP8_CONFIG *oxcf)
{
cpi->last_q[0] = cpi->oxcf.fixed_q;
cpi->last_q[1] = cpi->oxcf.fixed_q;
+ cpi->last_boosted_qindex = cpi->oxcf.fixed_q;
}
cpi->Speed = cpi->oxcf.cpu_used;
@@ -2694,6 +2699,9 @@ void vp8_remove_compressor(VP8_PTR *ptr)
fprintf(f, "%7.3f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t%8.0f\n",
dr, cpi->total / cpi->count, total_psnr, cpi->totalp / cpi->count, total_psnr2, total_ssim,
total_encode_time);
+// fprintf(f, "%7.3f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t%8.0f %10ld\n",
+// dr, cpi->total / cpi->count, total_psnr, cpi->totalp / cpi->count, total_psnr2, total_ssim,
+// total_encode_time, cpi->tot_recode_hits);
}
if (cpi->b_calculate_ssimg)
@@ -2702,6 +2710,9 @@ void vp8_remove_compressor(VP8_PTR *ptr)
fprintf(f, "%7.3f\t%6.4f\t%6.4f\t%6.4f\t%6.4f\t%8.0f\n", dr,
cpi->total_ssimg_y / cpi->count, cpi->total_ssimg_u / cpi->count,
cpi->total_ssimg_v / cpi->count, cpi->total_ssimg_all / cpi->count, total_encode_time);
+// fprintf(f, "%7.3f\t%6.4f\t%6.4f\t%6.4f\t%6.4f\t%8.0f %10ld\n", dr,
+// cpi->total_ssimg_y / cpi->count, cpi->total_ssimg_u / cpi->count,
+// cpi->total_ssimg_v / cpi->count, cpi->total_ssimg_all / cpi->count, total_encode_time, cpi->tot_recode_hits);
}
fclose(f);
@@ -4134,10 +4145,15 @@ static void encode_frame_to_data_rate
// based on the ambient Q to reduce the risk of popping
if ( cpi->this_key_frame_forced )
{
- if ( cpi->active_best_quality > cpi->avg_frame_qindex * 7/8)
- cpi->active_best_quality = cpi->avg_frame_qindex * 7/8;
- else if ( cpi->active_best_quality < cpi->avg_frame_qindex >> 2 )
- cpi->active_best_quality = cpi->avg_frame_qindex >> 2;
+ int delta_qindex;
+ int qindex = cpi->last_boosted_qindex;
+
+ delta_qindex = compute_qdelta( cpi, qindex,
+ (qindex * 0.75) );
+
+ cpi->active_best_quality = qindex + delta_qindex;
+ if (cpi->active_best_quality < cpi->best_quality)
+ cpi->active_best_quality = cpi->best_quality;
}
}
// One pass more conservative
@@ -4248,8 +4264,16 @@ static void encode_frame_to_data_rate
if ( cpi->active_worst_quality < cpi->active_best_quality )
cpi->active_worst_quality = cpi->active_best_quality;
- // Determine initial Q to try
- Q = vp8_regulate_q(cpi, cpi->this_frame_target);
+ // Specuial case code to try and match quality with forced key frames
+ if ( (cm->frame_type == KEY_FRAME) && cpi->this_key_frame_forced )
+ {
+ Q = cpi->last_boosted_qindex;
+ }
+ else
+ {
+ // Determine initial Q to try
+ Q = vp8_regulate_q(cpi, cpi->this_frame_target);
+ }
last_zbin_oq = cpi->zbin_over_quant;
// Set highest allowed value for Zbin over quant
@@ -4527,23 +4551,32 @@ static void encode_frame_to_data_rate
&cm->yv12_fb[cm->new_fb_idx],
IF_RTCD(&cpi->rtcd.variance));
+ int high_err_target = cpi->ambient_err;
+ int low_err_target = ((cpi->ambient_err * 3) >> 2);
+
// The key frame is not good enough
- if ( kf_err > ((cpi->ambient_err * 7) >> 3) )
+ if ( (kf_err > high_err_target) &&
+ (cpi->projected_frame_size <= frame_over_shoot_limit) )
{
// Lower q_high
q_high = (Q > q_low) ? (Q - 1) : q_low;
// Adjust Q
- Q = (q_high + q_low) >> 1;
+ Q = (Q * high_err_target) / kf_err;
+ if ( Q < ((q_high + q_low) >> 1))
+ Q = (q_high + q_low) >> 1;
}
// The key frame is much better than the previous frame
- else if ( kf_err < (cpi->ambient_err >> 1) )
+ else if ( (kf_err < low_err_target) &&
+ (cpi->projected_frame_size >= frame_under_shoot_limit) )
{
// Raise q_low
q_low = (Q < q_high) ? (Q + 1) : q_high;
// Adjust Q
- Q = (q_high + q_low + 1) >> 1;
+ Q = (Q * low_err_target) / kf_err;
+ if ( Q > ((q_high + q_low + 1) >> 1))
+ Q = (q_high + q_low + 1) >> 1;
}
// Clamp Q to upper and lower limits:
@@ -4569,14 +4602,12 @@ static void encode_frame_to_data_rate
// Frame is too large
if (cpi->projected_frame_size > cpi->this_frame_target)
{
- //if ( cpi->zbin_over_quant == 0 )
q_low = (Q < q_high) ? (Q + 1) : q_high; // Raise Qlow as to at least the current value
if (cpi->zbin_over_quant > 0) // If we are using over quant do the same for zbin_oq_low
zbin_oq_low = (cpi->zbin_over_quant < zbin_oq_high) ? (cpi->zbin_over_quant + 1) : zbin_oq_high;
- //if ( undershoot_seen || (Q == MAXQ) )
- if (undershoot_seen)
+ if ( undershoot_seen || (loop_count > 1) )
{
// Update rate_correction_factor unless cpi->active_worst_quality has changed.
if (!active_worst_qchanged)
@@ -4619,7 +4650,7 @@ static void encode_frame_to_data_rate
else // else lower zbin_oq_high
zbin_oq_high = (cpi->zbin_over_quant > zbin_oq_low) ? (cpi->zbin_over_quant - 1) : zbin_oq_low;
- if (overshoot_seen)
+ if ( overshoot_seen || (loop_count > 1) )
{
// Update rate_correction_factor unless cpi->active_worst_quality has changed.
if (!active_worst_qchanged)
@@ -4845,6 +4876,20 @@ static void encode_frame_to_data_rate
cpi->last_q[cm->frame_type] = cm->base_qindex;
+ // Keep record of last boosted (KF/KF/ARF) Q value.
+ // If the current frame is coded at a lower Q then we also update it.
+ // If all mbs in this group are skipped only update if the Q value is
+ // better than that already stored.
+ // This is used to help set quality in forced key frames to reduce popping
+ if ( (cm->base_qindex < cpi->last_boosted_qindex) ||
+ ( (cpi->static_mb_pct < 100) &&
+ ( (cm->frame_type == KEY_FRAME) ||
+ cm->refresh_alt_ref_frame ||
+ (cm->refresh_golden_frame && !cpi->is_src_frame_alt_ref) ) ) )
+ {
+ cpi->last_boosted_qindex = cm->base_qindex;
+ }
+
if (cm->frame_type == KEY_FRAME)
{
vp8_adjust_key_frame_context(cpi);
@@ -4991,7 +5036,7 @@ static void encode_frame_to_data_rate
if (cpi->twopass.total_left_stats->coded_error != 0.0)
fprintf(f, "%10d %10d %10d %10d %10d %10d %10d"
- "%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f"
+ "%7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f"
"%6d %5d %5d %5d %8d %8.2f %10d %10.3f"
"%10.3f %8d\n",
cpi->common.current_video_frame, cpi->this_frame_target,
@@ -5023,7 +5068,7 @@ static void encode_frame_to_data_rate
cpi->tot_recode_hits);
else
fprintf(f, "%10d %10d %10d %10d %10d %10d %10d"
- "%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f"
+ "%7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f"
"%6d %5d %5d %5d %8d %8.2f %10d %10.3f"
"%8d\n",
cpi->common.current_video_frame,
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index f47a46408..002f30a97 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -383,6 +383,7 @@ typedef struct VP8_COMP
int this_frame_target;
int projected_frame_size;
int last_q[2]; // Separate values for Intra/Inter
+ int last_boosted_qindex; // Last boosted GF/KF/ARF q
double rate_correction_factor;
double key_frame_rate_correction_factor;
@@ -483,11 +484,7 @@ typedef struct VP8_COMP
#endif
MBGRAPH_FRAME_STATS mbgraph_stats[MAX_LAG_BUFFERS];
int mbgraph_n_frames; // number of frames filled in the above
- int mbgraph_use_arf_segmentation; // set if part of an ARF is considered to be a
- // poor predictor, and thus coeffs are skipped
- // or coded at a higher Q using MB-segmentation
- // this value is the number of MBs that are
- // poor predictors (> 0 and < common.MBs)
+ int static_mb_pct; // % forced skip mbs by segmentation
int decimation_factor;
int decimation_count;
diff --git a/vp8/encoder/quantize.c b/vp8/encoder/quantize.c
index 68b10cc4c..d7316f74e 100644
--- a/vp8/encoder/quantize.c
+++ b/vp8/encoder/quantize.c
@@ -1271,30 +1271,18 @@ void vp8cx_frame_init_quantizer(VP8_COMP *cpi)
void vp8_set_quantizer(struct VP8_COMP *cpi, int Q)
{
VP8_COMMON *cm = &cpi->common;
- int update = 0;
- int new_delta_q;
- cm->base_qindex = Q;
-
- /* if any of the delta_q values are changing update flag has to be set */
- /* currently only y2dc_delta_q may change */
+ // if any of the delta_q values are changing update flag will
+ // have to be set.
cm->y1dc_delta_q = 0;
cm->y2ac_delta_q = 0;
cm->uvdc_delta_q = 0;
cm->uvac_delta_q = 0;
+ cm->y2dc_delta_q = 0;
- if (Q < 4)
- {
- new_delta_q = 4-Q;
- }
- else
- new_delta_q = 0;
-
- update |= cm->y2dc_delta_q != new_delta_q;
- cm->y2dc_delta_q = new_delta_q;
-
- /* quantizer has to be reinitialized for any delta_q changes */
- if(update)
- vp8cx_init_quantizer(cpi);
+ // quantizer has to be reinitialized if any delta_q changes.
+ // As there are not any here for now this is inactive code.
+ //if(update)
+ // vp8cx_init_quantizer(cpi);
}
diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c
index d2e680f89..fd3f8d7b2 100644
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -24,7 +24,7 @@
#include "encodemv.h"
-#define MIN_BPB_FACTOR 0.01
+#define MIN_BPB_FACTOR 0.005
#define MAX_BPB_FACTOR 50
extern const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES];
@@ -1477,6 +1477,14 @@ void vp8_compute_frame_size_bounds(VP8_COMP *cpi, int *frame_under_shoot_limit,
}
}
}
+
+ // For very small rate targets where the fractional adjustment
+ // (eg * 7/8) may be tiny make sure there is at least a minimum
+ // range.
+ *frame_over_shoot_limit += 200;
+ *frame_under_shoot_limit -= 200;
+ if ( *frame_under_shoot_limit < 0 )
+ *frame_under_shoot_limit = 0;
}
}