diff options
Diffstat (limited to 'vp9')
-rw-r--r-- | vp9/encoder/vp9_encoder.c | 126 | ||||
-rw-r--r-- | vp9/encoder/vp9_encoder.h | 1 | ||||
-rw-r--r-- | vp9/simple_encode.cc | 225 | ||||
-rw-r--r-- | vp9/simple_encode.h | 48 |
4 files changed, 398 insertions, 2 deletions
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index c0cd80598..9b03b2099 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -7100,11 +7100,130 @@ static void init_encode_frame_result(ENCODE_FRAME_RESULT *encode_frame_result) { } #if !CONFIG_REALTIME_ONLY +#if CONFIG_RATE_CTRL +static void copy_frame_counts(const FRAME_COUNTS *input_counts, + FRAME_COUNTS *output_counts) { + int i, j, k, l, m, n; + for (i = 0; i < BLOCK_SIZE_GROUPS; ++i) { + for (j = 0; j < INTRA_MODES; ++j) { + output_counts->y_mode[i][j] = input_counts->y_mode[i][j]; + } + } + for (i = 0; i < INTRA_MODES; ++i) { + for (j = 0; j < INTRA_MODES; ++j) { + output_counts->uv_mode[i][j] = input_counts->uv_mode[i][j]; + } + } + for (i = 0; i < PARTITION_CONTEXTS; ++i) { + for (j = 0; j < PARTITION_TYPES; ++j) { + output_counts->partition[i][j] = input_counts->partition[i][j]; + } + } + for (i = 0; i < TX_SIZES; ++i) { + for (j = 0; j < PLANE_TYPES; ++j) { + for (k = 0; k < REF_TYPES; ++k) { + for (l = 0; l < COEF_BANDS; ++l) { + for (m = 0; m < COEFF_CONTEXTS; ++m) { + output_counts->eob_branch[i][j][k][l][m] = + input_counts->eob_branch[i][j][k][l][m]; + for (n = 0; n < UNCONSTRAINED_NODES + 1; ++n) { + output_counts->coef[i][j][k][l][m][n] = + input_counts->coef[i][j][k][l][m][n]; + } + } + } + } + } + } + for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) { + for (j = 0; j < SWITCHABLE_FILTERS; ++j) { + output_counts->switchable_interp[i][j] = + input_counts->switchable_interp[i][j]; + } + } + for (i = 0; i < INTER_MODE_CONTEXTS; ++i) { + for (j = 0; j < INTER_MODES; ++j) { + output_counts->inter_mode[i][j] = input_counts->inter_mode[i][j]; + } + } + for (i = 0; i < INTRA_INTER_CONTEXTS; ++i) { + for (j = 0; j < 2; ++j) { + output_counts->intra_inter[i][j] = input_counts->intra_inter[i][j]; + } + } + for (i = 0; i < COMP_INTER_CONTEXTS; ++i) { + for (j = 0; j < 2; ++j) { + output_counts->comp_inter[i][j] = input_counts->comp_inter[i][j]; + } + } + for (i = 0; i < REF_CONTEXTS; ++i) { + for (j = 0; j < 2; ++j) { + for (k = 0; k < 2; ++k) { + output_counts->single_ref[i][j][k] = input_counts->single_ref[i][j][k]; + } + } + } + for (i = 0; i < REF_CONTEXTS; ++i) { + for (j = 0; j < 2; ++j) { + output_counts->comp_ref[i][j] = input_counts->comp_ref[i][j]; + } + } + for (i = 0; i < SKIP_CONTEXTS; ++i) { + for (j = 0; j < 2; ++j) { + output_counts->skip[i][j] = input_counts->skip[i][j]; + } + } + for (i = 0; i < TX_SIZE_CONTEXTS; i++) { + for (j = 0; j < TX_SIZES; j++) { + output_counts->tx.p32x32[i][j] = input_counts->tx.p32x32[i][j]; + } + for (j = 0; j < TX_SIZES - 1; j++) { + output_counts->tx.p16x16[i][j] = input_counts->tx.p16x16[i][j]; + } + for (j = 0; j < TX_SIZES - 2; j++) { + output_counts->tx.p8x8[i][j] = input_counts->tx.p8x8[i][j]; + } + } + for (i = 0; i < TX_SIZES; i++) { + output_counts->tx.tx_totals[i] = input_counts->tx.tx_totals[i]; + } + for (i = 0; i < MV_JOINTS; i++) { + output_counts->mv.joints[i] = input_counts->mv.joints[i]; + } + for (k = 0; k < 2; k++) { + nmv_component_counts *const comps = &output_counts->mv.comps[k]; + const nmv_component_counts *const comps_t = &input_counts->mv.comps[k]; + for (i = 0; i < 2; i++) { + comps->sign[i] = comps_t->sign[i]; + comps->class0_hp[i] = comps_t->class0_hp[i]; + comps->hp[i] = comps_t->hp[i]; + } + for (i = 0; i < MV_CLASSES; i++) { + comps->classes[i] = comps_t->classes[i]; + } + for (i = 0; i < CLASS0_SIZE; i++) { + comps->class0[i] = comps_t->class0[i]; + for (j = 0; j < MV_FP_SIZE; j++) { + comps->class0_fp[i][j] = comps_t->class0_fp[i][j]; + } + } + for (i = 0; i < MV_OFFSET_BITS; i++) { + for (j = 0; j < 2; j++) { + comps->bits[i][j] = comps_t->bits[i][j]; + } + } + for (i = 0; i < MV_FP_SIZE; i++) { + comps->fp[i] = comps_t->fp[i]; + } + } +} +#endif // CONFIG_RATE_CTRL + static void update_encode_frame_result( int show_idx, FRAME_UPDATE_TYPE update_type, const YV12_BUFFER_CONFIG *source_frame, const YV12_BUFFER_CONFIG *coded_frame, int quantize_index, - uint32_t bit_depth, uint32_t input_bit_depth, + uint32_t bit_depth, uint32_t input_bit_depth, const FRAME_COUNTS *counts, ENCODE_FRAME_RESULT *encode_frame_result) { #if CONFIG_RATE_CTRL PSNR_STATS psnr; @@ -7118,11 +7237,13 @@ static void update_encode_frame_result( #endif // CONFIG_VP9_HIGHBITDEPTH encode_frame_result->psnr = psnr.psnr[0]; encode_frame_result->sse = psnr.sse[0]; + copy_frame_counts(counts, &encode_frame_result->frame_counts); #else // CONFIG_RATE_CTRL (void)bit_depth; (void)input_bit_depth; (void)source_frame; (void)coded_frame; + (void)counts; #endif // CONFIG_RATE_CTRL encode_frame_result->show_idx = show_idx; encode_frame_result->update_type = update_type; @@ -7424,7 +7545,8 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags, source->show_idx, cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index], cpi->Source, get_frame_new_buffer(cm), vp9_get_quantizer(cpi), - cpi->oxcf.input_bit_depth, cm->bit_depth, encode_frame_result); + cpi->oxcf.input_bit_depth, cm->bit_depth, cpi->td.counts, + encode_frame_result); vp9_twopass_postencode_update(cpi); } else if (cpi->use_svc) { SvcEncode(cpi, size, dest, frame_flags); diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index 7db1e7334..c2bdebb4d 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -856,6 +856,7 @@ typedef struct ENCODE_FRAME_RESULT { #if CONFIG_RATE_CTRL double psnr; uint64_t sse; + FRAME_COUNTS frame_counts; #endif // CONFIG_RATE_CTRL int quantize_index; } ENCODE_FRAME_RESULT; diff --git a/vp9/simple_encode.cc b/vp9/simple_encode.cc index 34d08573c..a290704d5 100644 --- a/vp9/simple_encode.cc +++ b/vp9/simple_encode.cc @@ -9,6 +9,8 @@ */ #include <vector> +#include "vp9/common/vp9_entropymode.h" +#include "vp9/common/vp9_enums.h" #include "vp9/common/vp9_onyxc_int.h" #include "vp9/vp9_iface_common.h" #include "vp9/encoder/vp9_encoder.h" @@ -99,6 +101,227 @@ get_frame_type_from_update_type(FRAME_UPDATE_TYPE update_type) { } } +static void update_frame_counts(const FRAME_COUNTS *input_counts, + FrameCounts *output_counts) { + // Init array sizes. + output_counts->y_mode.resize(BLOCK_SIZE_GROUPS); + for (int i = 0; i < BLOCK_SIZE_GROUPS; ++i) { + output_counts->y_mode[i].resize(INTRA_MODES); + } + + output_counts->uv_mode.resize(INTRA_MODES); + for (int i = 0; i < INTRA_MODES; ++i) { + output_counts->uv_mode[i].resize(INTRA_MODES); + } + + output_counts->partition.resize(PARTITION_CONTEXTS); + for (int i = 0; i < PARTITION_CONTEXTS; ++i) { + output_counts->partition[i].resize(PARTITION_TYPES); + } + + output_counts->coef.resize(TX_SIZES); + output_counts->eob_branch.resize(TX_SIZES); + for (int i = 0; i < TX_SIZES; ++i) { + output_counts->coef[i].resize(PLANE_TYPES); + output_counts->eob_branch[i].resize(PLANE_TYPES); + for (int j = 0; j < PLANE_TYPES; ++j) { + output_counts->coef[i][j].resize(REF_TYPES); + output_counts->eob_branch[i][j].resize(REF_TYPES); + for (int k = 0; k < REF_TYPES; ++k) { + output_counts->coef[i][j][k].resize(COEF_BANDS); + output_counts->eob_branch[i][j][k].resize(COEF_BANDS); + for (int l = 0; l < COEF_BANDS; ++l) { + output_counts->coef[i][j][k][l].resize(COEFF_CONTEXTS); + output_counts->eob_branch[i][j][k][l].resize(COEFF_CONTEXTS); + for (int m = 0; m < COEFF_CONTEXTS; ++m) { + output_counts->coef[i][j][k][l][m].resize(UNCONSTRAINED_NODES + 1); + } + } + } + } + } + + output_counts->switchable_interp.resize(SWITCHABLE_FILTER_CONTEXTS); + for (int i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) { + output_counts->switchable_interp[i].resize(SWITCHABLE_FILTERS); + } + + output_counts->inter_mode.resize(INTER_MODE_CONTEXTS); + for (int i = 0; i < INTER_MODE_CONTEXTS; ++i) { + output_counts->inter_mode[i].resize(INTER_MODES); + } + + output_counts->intra_inter.resize(INTRA_INTER_CONTEXTS); + for (int i = 0; i < INTRA_INTER_CONTEXTS; ++i) { + output_counts->intra_inter[i].resize(2); + } + + output_counts->comp_inter.resize(COMP_INTER_CONTEXTS); + for (int i = 0; i < COMP_INTER_CONTEXTS; ++i) { + output_counts->comp_inter[i].resize(2); + } + + output_counts->single_ref.resize(REF_CONTEXTS); + for (int i = 0; i < REF_CONTEXTS; ++i) { + output_counts->single_ref[i].resize(2); + for (int j = 0; j < 2; ++j) { + output_counts->single_ref[i][j].resize(2); + } + } + + output_counts->comp_ref.resize(REF_CONTEXTS); + for (int i = 0; i < REF_CONTEXTS; ++i) { + output_counts->comp_ref[i].resize(2); + } + + output_counts->skip.resize(SKIP_CONTEXTS); + for (int i = 0; i < SKIP_CONTEXTS; ++i) { + output_counts->skip[i].resize(2); + } + + output_counts->tx.p32x32.resize(TX_SIZE_CONTEXTS); + output_counts->tx.p16x16.resize(TX_SIZE_CONTEXTS); + output_counts->tx.p8x8.resize(TX_SIZE_CONTEXTS); + for (int i = 0; i < TX_SIZE_CONTEXTS; i++) { + output_counts->tx.p32x32[i].resize(TX_SIZES); + output_counts->tx.p16x16[i].resize(TX_SIZES - 1); + output_counts->tx.p8x8[i].resize(TX_SIZES - 2); + } + output_counts->tx.tx_totals.resize(TX_SIZES); + + output_counts->mv.joints.resize(MV_JOINTS); + output_counts->mv.comps.resize(2); + for (int i = 0; i < 2; ++i) { + output_counts->mv.comps[i].sign.resize(2); + output_counts->mv.comps[i].classes.resize(MV_CLASSES); + output_counts->mv.comps[i].class0.resize(CLASS0_SIZE); + output_counts->mv.comps[i].bits.resize(MV_OFFSET_BITS); + for (int j = 0; j < MV_OFFSET_BITS; ++j) { + output_counts->mv.comps[i].bits[j].resize(2); + } + output_counts->mv.comps[i].class0_fp.resize(CLASS0_SIZE); + for (int j = 0; j < CLASS0_SIZE; ++j) { + output_counts->mv.comps[i].class0_fp[j].resize(MV_FP_SIZE); + } + output_counts->mv.comps[i].fp.resize(MV_FP_SIZE); + output_counts->mv.comps[i].class0_hp.resize(2); + output_counts->mv.comps[i].hp.resize(2); + } + + // Populate counts. + for (int i = 0; i < BLOCK_SIZE_GROUPS; ++i) { + for (int j = 0; j < INTRA_MODES; ++j) { + output_counts->y_mode[i][j] = input_counts->y_mode[i][j]; + } + } + for (int i = 0; i < INTRA_MODES; ++i) { + for (int j = 0; j < INTRA_MODES; ++j) { + output_counts->uv_mode[i][j] = input_counts->uv_mode[i][j]; + } + } + for (int i = 0; i < PARTITION_CONTEXTS; ++i) { + for (int j = 0; j < PARTITION_TYPES; ++j) { + output_counts->partition[i][j] = input_counts->partition[i][j]; + } + } + for (int i = 0; i < TX_SIZES; ++i) { + for (int j = 0; j < PLANE_TYPES; ++j) { + for (int k = 0; k < REF_TYPES; ++k) { + for (int l = 0; l < COEF_BANDS; ++l) { + for (int m = 0; m < COEFF_CONTEXTS; ++m) { + output_counts->eob_branch[i][j][k][l][m] = + input_counts->eob_branch[i][j][k][l][m]; + for (int n = 0; n < UNCONSTRAINED_NODES + 1; n++) { + output_counts->coef[i][j][k][l][m][n] = + input_counts->coef[i][j][k][l][m][n]; + } + } + } + } + } + } + for (int i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) { + for (int j = 0; j < SWITCHABLE_FILTERS; ++j) { + output_counts->switchable_interp[i][j] = + input_counts->switchable_interp[i][j]; + } + } + for (int i = 0; i < INTER_MODE_CONTEXTS; ++i) { + for (int j = 0; j < INTER_MODES; ++j) { + output_counts->inter_mode[i][j] = input_counts->inter_mode[i][j]; + } + } + for (int i = 0; i < INTRA_INTER_CONTEXTS; ++i) { + for (int j = 0; j < 2; ++j) { + output_counts->intra_inter[i][j] = input_counts->intra_inter[i][j]; + } + } + for (int i = 0; i < COMP_INTER_CONTEXTS; ++i) { + for (int j = 0; j < 2; ++j) { + output_counts->comp_inter[i][j] = input_counts->comp_inter[i][j]; + } + } + for (int i = 0; i < REF_CONTEXTS; ++i) { + for (int j = 0; j < 2; ++j) { + for (int k = 0; k < 2; ++k) { + output_counts->single_ref[i][j][k] = input_counts->single_ref[i][j][k]; + } + } + } + for (int i = 0; i < REF_CONTEXTS; ++i) { + for (int j = 0; j < 2; ++j) { + output_counts->comp_ref[i][j] = input_counts->comp_ref[i][j]; + } + } + for (int i = 0; i < SKIP_CONTEXTS; ++i) { + for (int j = 0; j < 2; ++j) { + output_counts->skip[i][j] = input_counts->skip[i][j]; + } + } + for (int i = 0; i < TX_SIZE_CONTEXTS; i++) { + for (int j = 0; j < TX_SIZES; j++) { + output_counts->tx.p32x32[i][j] = input_counts->tx.p32x32[i][j]; + } + for (int j = 0; j < TX_SIZES - 1; j++) { + output_counts->tx.p16x16[i][j] = input_counts->tx.p16x16[i][j]; + } + for (int j = 0; j < TX_SIZES - 2; j++) { + output_counts->tx.p8x8[i][j] = input_counts->tx.p8x8[i][j]; + } + } + for (int i = 0; i < TX_SIZES; i++) { + output_counts->tx.tx_totals[i] = input_counts->tx.tx_totals[i]; + } + for (int i = 0; i < MV_JOINTS; i++) { + output_counts->mv.joints[i] = input_counts->mv.joints[i]; + } + for (int k = 0; k < 2; k++) { + const nmv_component_counts *const comps_t = &input_counts->mv.comps[k]; + for (int i = 0; i < 2; i++) { + output_counts->mv.comps[k].sign[i] = comps_t->sign[i]; + output_counts->mv.comps[k].class0_hp[i] = comps_t->class0_hp[i]; + output_counts->mv.comps[k].hp[i] = comps_t->hp[i]; + } + for (int i = 0; i < MV_CLASSES; i++) { + output_counts->mv.comps[k].classes[i] = comps_t->classes[i]; + } + for (int i = 0; i < CLASS0_SIZE; i++) { + output_counts->mv.comps[k].class0[i] = comps_t->class0[i]; + for (int j = 0; j < MV_FP_SIZE; j++) { + output_counts->mv.comps[k].class0_fp[i][j] = comps_t->class0_fp[i][j]; + } + } + for (int i = 0; i < MV_OFFSET_BITS; i++) { + for (int j = 0; j < 2; j++) { + output_counts->mv.comps[k].bits[i][j] = comps_t->bits[i][j]; + } + } + for (int i = 0; i < MV_FP_SIZE; i++) { + output_counts->mv.comps[k].fp[i] = comps_t->fp[i]; + } + } +} + static void update_encode_frame_result( EncodeFrameResult *encode_frame_result, const ENCODE_FRAME_RESULT *encode_frame_info) { @@ -110,6 +333,8 @@ static void update_encode_frame_result( encode_frame_result->psnr = encode_frame_info->psnr; encode_frame_result->sse = encode_frame_info->sse; encode_frame_result->quantize_index = encode_frame_info->quantize_index; + update_frame_counts(&encode_frame_info->frame_counts, + &encode_frame_result->frame_counts); } static void IncreaseGroupOfPictureIndex(GroupOfPicture *group_of_picture) { diff --git a/vp9/simple_encode.h b/vp9/simple_encode.h index 4bee7c757..72281cdea 100644 --- a/vp9/simple_encode.h +++ b/vp9/simple_encode.h @@ -30,6 +30,53 @@ struct EncodeFrameInfo { FrameType frame_type; }; +// This structure is a copy of vp9 |nmv_component_counts|. +struct NewMotionvectorComponentCounts { + std::vector<unsigned int> sign; + std::vector<unsigned int> classes; + std::vector<unsigned int> class0; + std::vector<std::vector<unsigned int>> bits; + std::vector<std::vector<unsigned int>> class0_fp; + std::vector<unsigned int> fp; + std::vector<unsigned int> class0_hp; + std::vector<unsigned int> hp; +}; + +// This structure is a copy of vp9 |nmv_context_counts|. +struct NewMotionVectorContextCounts { + std::vector<unsigned int> joints; + std::vector<NewMotionvectorComponentCounts> comps; +}; + +// This structure is a copy of vp9 |tx_counts|. +struct TransformSizeCounts { + std::vector<std::vector<unsigned int>> p32x32; + std::vector<std::vector<unsigned int>> p16x16; + std::vector<std::vector<unsigned int>> p8x8; + std::vector<unsigned int> tx_totals; +}; + +// This structure is a copy of vp9 |FRAME_COUNTS|. +struct FrameCounts { + std::vector<std::vector<unsigned int>> y_mode; + std::vector<std::vector<unsigned int>> uv_mode; + std::vector<std::vector<unsigned int>> partition; + std::vector<std::vector< + std::vector<std::vector<std::vector<std::vector<unsigned int>>>>>> + coef; + std::vector<std::vector<std::vector<std::vector<std::vector<unsigned int>>>>> + eob_branch; + std::vector<std::vector<unsigned int>> switchable_interp; + std::vector<std::vector<unsigned int>> inter_mode; + std::vector<std::vector<unsigned int>> intra_inter; + std::vector<std::vector<unsigned int>> comp_inter; + std::vector<std::vector<std::vector<unsigned int>>> single_ref; + std::vector<std::vector<unsigned int>> comp_ref; + std::vector<std::vector<unsigned int>> skip; + TransformSizeCounts tx; + NewMotionVectorContextCounts mv; +}; + struct EncodeFrameResult { int show_idx; FrameType frame_type; @@ -41,6 +88,7 @@ struct EncodeFrameResult { double psnr; uint64_t sse; int quantize_index; + FrameCounts frame_counts; }; struct GroupOfPicture { |