mirror of
https://github.com/webmproject/libwebp.git
synced 2025-02-13 15:32:53 +01:00
Merge "describe rd-opt levels introduce VP8RDLevel enum"
This commit is contained in:
commit
7648c3ccb8
@ -695,7 +695,7 @@ int VP8EncLoop(VP8Encoder* const enc) {
|
|||||||
VP8EncIterator it;
|
VP8EncIterator it;
|
||||||
VP8ModeScore info;
|
VP8ModeScore info;
|
||||||
const int dont_use_skip = !enc->proba_.use_skip_proba_;
|
const int dont_use_skip = !enc->proba_.use_skip_proba_;
|
||||||
const int rd_opt = enc->rd_opt_level_;
|
const VP8RDLevel rd_opt = enc->rd_opt_level_;
|
||||||
const int kAverageBytesPerMB = 5; // TODO: have a kTable[quality/10]
|
const int kAverageBytesPerMB = 5; // TODO: have a kTable[quality/10]
|
||||||
const int bytes_per_parts =
|
const int bytes_per_parts =
|
||||||
enc->mb_w_ * enc->mb_h_ * kAverageBytesPerMB / enc->num_parts_;
|
enc->mb_w_ * enc->mb_h_ * kAverageBytesPerMB / enc->num_parts_;
|
||||||
@ -762,8 +762,8 @@ int VP8EncLoop(VP8Encoder* const enc) {
|
|||||||
|
|
||||||
#define kHeaderSizeEstimate (15 + 20 + 10) // TODO: fix better
|
#define kHeaderSizeEstimate (15 + 20 + 10) // TODO: fix better
|
||||||
|
|
||||||
static int OneStatPass(VP8Encoder* const enc, float q, int rd_opt, int nb_mbs,
|
static int OneStatPass(VP8Encoder* const enc, float q, VP8RDLevel rd_opt,
|
||||||
float* const PSNR, int percent_delta) {
|
int nb_mbs, float* const PSNR, int percent_delta) {
|
||||||
VP8EncIterator it;
|
VP8EncIterator it;
|
||||||
uint64_t size = 0;
|
uint64_t size = 0;
|
||||||
uint64_t distortion = 0;
|
uint64_t distortion = 0;
|
||||||
@ -829,7 +829,7 @@ int VP8StatLoop(VP8Encoder* const enc) {
|
|||||||
// No target size: just do several pass without changing 'q'
|
// No target size: just do several pass without changing 'q'
|
||||||
if (!do_search) {
|
if (!do_search) {
|
||||||
for (pass = 0; pass < max_passes; ++pass) {
|
for (pass = 0; pass < max_passes; ++pass) {
|
||||||
const int rd_opt = (enc->method_ > 2);
|
const VP8RDLevel rd_opt = (enc->method_ > 2) ? RD_OPT_BASIC : RD_OPT_NONE;
|
||||||
if (!OneStatPass(enc, q, rd_opt, nb_mbs, NULL, percent_per_pass)) {
|
if (!OneStatPass(enc, q, rd_opt, nb_mbs, NULL, percent_per_pass)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -837,10 +837,9 @@ int VP8StatLoop(VP8Encoder* const enc) {
|
|||||||
} else {
|
} else {
|
||||||
// binary search for a size close to target
|
// binary search for a size close to target
|
||||||
for (pass = 0; pass < max_passes && (dqs[pass] > 0); ++pass) {
|
for (pass = 0; pass < max_passes && (dqs[pass] > 0); ++pass) {
|
||||||
const int rd_opt = 1;
|
|
||||||
float PSNR;
|
float PSNR;
|
||||||
int criterion;
|
int criterion;
|
||||||
const int size = OneStatPass(enc, q, rd_opt, nb_mbs, &PSNR,
|
const int size = OneStatPass(enc, q, RD_OPT_BASIC, nb_mbs, &PSNR,
|
||||||
percent_per_pass);
|
percent_per_pass);
|
||||||
#if DEBUG_SEARCH
|
#if DEBUG_SEARCH
|
||||||
printf("#%d size=%d PSNR=%.2f q=%.2f\n", pass, size, PSNR, q);
|
printf("#%d size=%d PSNR=%.2f q=%.2f\n", pass, size, PSNR, q);
|
||||||
|
@ -956,7 +956,8 @@ static void SimpleQuantize(VP8EncIterator* const it, VP8ModeScore* const rd) {
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Entry point
|
// Entry point
|
||||||
|
|
||||||
int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd, int rd_opt) {
|
int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd,
|
||||||
|
VP8RDLevel rd_opt) {
|
||||||
int is_skipped;
|
int is_skipped;
|
||||||
|
|
||||||
InitScore(rd);
|
InitScore(rd);
|
||||||
@ -966,16 +967,14 @@ int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd, int rd_opt) {
|
|||||||
VP8MakeLuma16Preds(it);
|
VP8MakeLuma16Preds(it);
|
||||||
VP8MakeChroma8Preds(it);
|
VP8MakeChroma8Preds(it);
|
||||||
|
|
||||||
// for rd_opt = 2, we perform trellis-quant on the final decision only.
|
if (rd_opt > RD_OPT_NONE) {
|
||||||
// for rd_opt > 2, we use it for every scoring (=much slower).
|
it->do_trellis_ = (rd_opt >= RD_OPT_TRELLIS_ALL);
|
||||||
if (rd_opt > 0) {
|
|
||||||
it->do_trellis_ = (rd_opt > 2);
|
|
||||||
PickBestIntra16(it, rd);
|
PickBestIntra16(it, rd);
|
||||||
if (it->enc_->method_ >= 2) {
|
if (it->enc_->method_ >= 2) {
|
||||||
PickBestIntra4(it, rd);
|
PickBestIntra4(it, rd);
|
||||||
}
|
}
|
||||||
PickBestUV(it, rd);
|
PickBestUV(it, rd);
|
||||||
if (rd_opt == 2) {
|
if (rd_opt == RD_OPT_TRELLIS) { // finish off with trellis-optim now
|
||||||
it->do_trellis_ = 1;
|
it->do_trellis_ = 1;
|
||||||
SimpleQuantize(it, rd);
|
SimpleQuantize(it, rd);
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,13 @@ enum { NUM_MB_SEGMENTS = 4,
|
|||||||
MAX_VARIABLE_LEVEL = 67 // last (inclusive) level with variable cost
|
MAX_VARIABLE_LEVEL = 67 // last (inclusive) level with variable cost
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum { // Rate-distortion optimization levels
|
||||||
|
RD_OPT_NONE = 0, // no rd-opt
|
||||||
|
RD_OPT_BASIC = 1, // basic scoring (no trellis)
|
||||||
|
RD_OPT_TRELLIS = 2, // perform trellis-quant on the final decision only
|
||||||
|
RD_OPT_TRELLIS_ALL = 3 // trellis-quant for every scoring (much slower)
|
||||||
|
} VP8RDLevel;
|
||||||
|
|
||||||
// YUV-cache parameters. Cache is 16-pixels wide.
|
// YUV-cache parameters. Cache is 16-pixels wide.
|
||||||
// The original or reconstructed samples can be accessed using VP8Scan[]
|
// The original or reconstructed samples can be accessed using VP8Scan[]
|
||||||
// The predicted blocks can be accessed using offsets to yuv_p_ and
|
// The predicted blocks can be accessed using offsets to yuv_p_ and
|
||||||
@ -406,7 +413,7 @@ struct VP8Encoder {
|
|||||||
|
|
||||||
// quality/speed settings
|
// quality/speed settings
|
||||||
int method_; // 0=fastest, 6=best/slowest.
|
int method_; // 0=fastest, 6=best/slowest.
|
||||||
int rd_opt_level_; // Deduced from method_.
|
VP8RDLevel rd_opt_level_; // Deduced from method_.
|
||||||
int max_i4_header_bits_; // partition #0 safeness factor
|
int max_i4_header_bits_; // partition #0 safeness factor
|
||||||
|
|
||||||
// Memory
|
// Memory
|
||||||
@ -486,7 +493,8 @@ int VP8EncAnalyze(VP8Encoder* const enc);
|
|||||||
// Sets up segment's quantization values, base_quant_ and filter strengths.
|
// Sets up segment's quantization values, base_quant_ and filter strengths.
|
||||||
void VP8SetSegmentParams(VP8Encoder* const enc, float quality);
|
void VP8SetSegmentParams(VP8Encoder* const enc, float quality);
|
||||||
// Pick best modes and fills the levels. Returns true if skipped.
|
// Pick best modes and fills the levels. Returns true if skipped.
|
||||||
int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd, int rd_opt);
|
int VP8Decimate(VP8EncIterator* const it, VP8ModeScore* const rd,
|
||||||
|
VP8RDLevel rd_opt);
|
||||||
|
|
||||||
// in alpha.c
|
// in alpha.c
|
||||||
void VP8EncInitAlpha(VP8Encoder* const enc); // initialize alpha compression
|
void VP8EncInitAlpha(VP8Encoder* const enc); // initialize alpha compression
|
||||||
|
@ -114,10 +114,10 @@ static void MapConfigToTools(VP8Encoder* const enc) {
|
|||||||
const int method = enc->config_->method;
|
const int method = enc->config_->method;
|
||||||
const int limit = 100 - enc->config_->partition_limit;
|
const int limit = 100 - enc->config_->partition_limit;
|
||||||
enc->method_ = method;
|
enc->method_ = method;
|
||||||
enc->rd_opt_level_ = (method >= 6) ? 3
|
enc->rd_opt_level_ = (method >= 6) ? RD_OPT_TRELLIS_ALL
|
||||||
: (method >= 5) ? 2
|
: (method >= 5) ? RD_OPT_TRELLIS
|
||||||
: (method >= 3) ? 1
|
: (method >= 3) ? RD_OPT_BASIC
|
||||||
: 0;
|
: RD_OPT_NONE;
|
||||||
enc->max_i4_header_bits_ =
|
enc->max_i4_header_bits_ =
|
||||||
256 * 16 * 16 * // upper bound: up to 16bit per 4x4 block
|
256 * 16 * 16 * // upper bound: up to 16bit per 4x4 block
|
||||||
(limit * limit) / (100 * 100); // ... modulated with a quadratic curve.
|
(limit * limit) / (100 * 100); // ... modulated with a quadratic curve.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user