diff options
-rw-r--r-- | examples/decode_to_md5.c | 106 | ||||
-rw-r--r-- | vp9/encoder/vp9_encodeframe.c | 144 | ||||
-rw-r--r-- | vp9/encoder/vp9_firstpass.c | 87 | ||||
-rw-r--r-- | vp9/encoder/vp9_mbgraph.c | 21 | ||||
-rw-r--r-- | vp9/encoder/vp9_mcomp.c | 63 | ||||
-rw-r--r-- | vp9/encoder/vp9_onyx_if.c | 60 | ||||
-rw-r--r-- | vp9/encoder/vp9_onyx_int.h | 4 | ||||
-rw-r--r-- | vp9/encoder/vp9_ratectrl.c | 2 | ||||
-rw-r--r-- | vp9/encoder/vp9_rdopt.c | 103 | ||||
-rw-r--r-- | vp9/encoder/vp9_rdopt.h | 4 | ||||
-rw-r--r-- | vp9/encoder/vp9_tokenize.c | 78 | ||||
-rw-r--r-- | vpxdec.c | 42 |
12 files changed, 330 insertions, 384 deletions
diff --git a/examples/decode_to_md5.c b/examples/decode_to_md5.c index bfa931e75..01e487170 100644 --- a/examples/decode_to_md5.c +++ b/examples/decode_to_md5.c @@ -66,81 +66,83 @@ static void die_codec(vpx_codec_ctx_t *ctx, const char *s) { exit(EXIT_FAILURE); } +static void get_image_md5(const vpx_image_t *img, unsigned char md5_sum[16]) { + int plane, y; + MD5Context md5; + + MD5Init(&md5); + + for (plane = 0; plane < 3; ++plane) { + const unsigned char *buf = img->planes[plane]; + const int stride = img->stride[plane]; + const int w = plane ? (img->d_w + 1) >> 1 : img->d_w; + const int h = plane ? (img->d_h + 1) >> 1 : img->d_h; + + for (y = 0; y < h; ++y) { + MD5Update(&md5, buf, w); + buf += stride; + } + } + + MD5Final(md5_sum, &md5); +} int main(int argc, char **argv) { - FILE *infile, *outfile; - vpx_codec_ctx_t codec; - int flags = 0, frame_cnt = 0; - unsigned char file_hdr[IVF_FILE_HDR_SZ]; - unsigned char frame_hdr[IVF_FRAME_HDR_SZ]; - unsigned char frame[256*1024]; - vpx_codec_err_t res; - - (void)res; - /* Open files */ - if(argc!=3) + FILE *infile, *outfile; + vpx_codec_ctx_t codec; + int flags = 0, frame_cnt = 0; + unsigned char file_hdr[IVF_FILE_HDR_SZ]; + unsigned char frame_hdr[IVF_FRAME_HDR_SZ]; + unsigned char frame[256 * 1024]; + + if (argc != 3) die("Usage: %s <infile> <outfile>\n", argv[0]); - if(!(infile = fopen(argv[1], "rb"))) + + if (!(infile = fopen(argv[1], "rb"))) die("Failed to open %s for reading", argv[1]); - if(!(outfile = fopen(argv[2], "wb"))) + + if (!(outfile = fopen(argv[2], "wb"))) die("Failed to open %s for writing", argv[2]); - /* Read file header */ - if(!(fread(file_hdr, 1, IVF_FILE_HDR_SZ, infile) == IVF_FILE_HDR_SZ - && file_hdr[0]=='D' && file_hdr[1]=='K' && file_hdr[2]=='I' - && file_hdr[3]=='F')) + if (!(fread(file_hdr, 1, IVF_FILE_HDR_SZ, infile) == IVF_FILE_HDR_SZ && + file_hdr[0] == 'D' && file_hdr[1] == 'K' && + file_hdr[2] == 'I' && file_hdr[3] == 'F')) die("%s is not an IVF file.", argv[1]); printf("Using %s\n",vpx_codec_iface_name(interface)); - /* Initialize codec */ - if(vpx_codec_dec_init(&codec, interface, NULL, flags)) + + if (vpx_codec_dec_init(&codec, interface, NULL, flags)) die_codec(&codec, "Failed to initialize decoder"); - /* Read each frame */ - while(fread(frame_hdr, 1, IVF_FRAME_HDR_SZ, infile) == IVF_FRAME_HDR_SZ) { - int frame_sz = mem_get_le32(frame_hdr); - vpx_codec_iter_t iter = NULL; - vpx_image_t *img; + while (fread(frame_hdr, 1, IVF_FRAME_HDR_SZ, infile) == IVF_FRAME_HDR_SZ) { + const int frame_size = mem_get_le32(frame_hdr); + vpx_codec_iter_t iter = NULL; + vpx_image_t *img; frame_cnt++; - if(frame_sz > sizeof(frame)) - die("Frame %d data too big for example code buffer", frame_sz); - if(fread(frame, 1, frame_sz, infile) != frame_sz) + if (frame_size > sizeof(frame)) + die("Frame %d data too big for example code buffer", frame_size); + + if (fread(frame, 1, frame_size, infile) != frame_size) die("Frame %d failed to read complete frame", frame_cnt); - /* Decode the frame */ - if(vpx_codec_decode(&codec, frame, frame_sz, NULL, 0)) + if (vpx_codec_decode(&codec, frame, frame_size, NULL, 0)) die_codec(&codec, "Failed to decode frame"); - /* Write decoded data to disk */ - while((img = vpx_codec_get_frame(&codec, &iter))) { - unsigned int plane, y; - - unsigned char md5_sum[16]; - MD5Context md5; - int i; - - MD5Init(&md5); - - for(plane=0; plane < 3; plane++) { - unsigned char *buf =img->planes[plane]; - - for (y=0; y < (plane ? (img->d_h + 1) >> 1 : img->d_h); y++) { - MD5Update(&md5, buf, (plane ? (img->d_w + 1) >> 1 : img->d_w)); - buf += img->stride[plane]; - } - } + while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL) { + int i; + unsigned char md5_sum[16]; - MD5Final(md5_sum, &md5); - for (i = 0; i < 16; i++) - fprintf(outfile, "%02x",md5_sum[i]); + get_image_md5(img, md5_sum); + for (i = 0; i < 16; ++i) + fprintf(outfile, "%02x", md5_sum[i]); fprintf(outfile, " img-%dx%d-%04d.i420\n", img->d_w, img->d_h, frame_cnt); } } - printf("Processed %d frames.\n",frame_cnt); - if(vpx_codec_destroy(&codec)) + printf("Processed %d frames.\n", frame_cnt); + if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec"); fclose(outfile); diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 6894f553f..4c66c2075 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -27,6 +27,7 @@ #include "vp9/common/vp9_reconintra.h" #include "vp9/common/vp9_reconinter.h" #include "vp9/common/vp9_seg_common.h" +#include "vp9/common/vp9_systemdependent.h" #include "vp9/common/vp9_tile_common.h" #include "vp9/encoder/vp9_encodeframe.h" #include "vp9/encoder/vp9_encodemb.h" @@ -35,11 +36,9 @@ #include "vp9/encoder/vp9_onyx_int.h" #include "vp9/encoder/vp9_rdopt.h" #include "vp9/encoder/vp9_segmentation.h" -#include "vp9/common/vp9_systemdependent.h" #include "vp9/encoder/vp9_tokenize.h" #include "vp9/encoder/vp9_vaq.h" - #define DBG_PRNT_SEGMAP 0 @@ -78,21 +77,19 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled, static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x); -/* activity_avg must be positive, or flat regions could get a zero weight - * (infinite lambda), which confounds analysis. - * This also avoids the need for divide by zero checks in - * vp9_activity_masking(). - */ +// activity_avg must be positive, or flat regions could get a zero weight +// (infinite lambda), which confounds analysis. +// This also avoids the need for divide by zero checks in +// vp9_activity_masking(). #define ACTIVITY_AVG_MIN (64) -/* Motion vector component magnitude threshold for defining fast motion. */ +// Motion vector component magnitude threshold for defining fast motion. #define FAST_MOTION_MV_THRESH (24) -/* This is used as a reference when computing the source variance for the - * purposes of activity masking. - * Eventually this should be replaced by custom no-reference routines, - * which will be faster. - */ +// This is used as a reference when computing the source variance for the +// purposes of activity masking. +// Eventually this should be replaced by custom no-reference routines, +// which will be faster. static const uint8_t VP9_VAR_OFFS[64] = { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, @@ -114,7 +111,6 @@ static unsigned int get_sby_perpixel_variance(VP9_COMP *cpi, MACROBLOCK *x, // Original activity measure from Tim T's code. static unsigned int tt_activity_measure(MACROBLOCK *x) { - unsigned int act; unsigned int sse; /* TODO: This could also be done over smaller areas (8x8), but that would * require extensive changes elsewhere, as lambda is assumed to be fixed @@ -123,13 +119,12 @@ static unsigned int tt_activity_measure(MACROBLOCK *x) { * lambda using a non-linear combination (e.g., the smallest, or second * smallest, etc.). */ - act = vp9_variance16x16(x->plane[0].src.buf, x->plane[0].src.stride, - VP9_VAR_OFFS, 0, &sse); - act <<= 4; - - /* If the region is flat, lower the activity some more. */ - if (act < 8 << 12) - act = act < 5 << 12 ? act : 5 << 12; + unsigned int act = vp9_variance16x16(x->plane[0].src.buf, + x->plane[0].src.stride, + VP9_VAR_OFFS, 0, &sse) << 4; + // If the region is flat, lower the activity some more. + if (act < (8 << 12)) + act = MIN(act, 5 << 12); return act; } @@ -146,7 +141,7 @@ static unsigned int mb_activity_measure(MACROBLOCK *x, int mb_row, int mb_col) { unsigned int mb_activity; if (ALT_ACT_MEASURE) { - int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row); + const int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row); // Or use and alternative. mb_activity = alt_activity_measure(x, use_dc_pred); @@ -155,10 +150,7 @@ static unsigned int mb_activity_measure(MACROBLOCK *x, int mb_row, int mb_col) { mb_activity = tt_activity_measure(x); } - if (mb_activity < ACTIVITY_AVG_MIN) - mb_activity = ACTIVITY_AVG_MIN; - - return mb_activity; + return MAX(mb_activity, ACTIVITY_AVG_MIN); } // Calculate an "average" mb activity value for the frame @@ -340,13 +332,11 @@ void vp9_activity_masking(VP9_COMP *cpi, MACROBLOCK *x) { x->errorperbit = x->rdmult * 100 / (110 * x->rddiv); x->errorperbit += (x->errorperbit == 0); #else - int64_t a; - int64_t b; - int64_t act = *(x->mb_activity_ptr); + const int64_t act = *(x->mb_activity_ptr); // Apply the masking to the RD multiplier. - a = act + (2 * cpi->activity_avg); - b = (2 * act) + cpi->activity_avg; + const int64_t a = act + (2 * cpi->activity_avg); + const int64_t b = (2 * act) + cpi->activity_avg; x->rdmult = (unsigned int) (((int64_t) x->rdmult * b + (a >> 1)) / a); x->errorperbit = x->rdmult * 100 / (110 * x->rddiv); @@ -415,7 +405,7 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, MB_MODE_INFO *const mbmi = &xd->mi_8x8[0]->mbmi; MODE_INFO *mi_addr = xd->mi_8x8[0]; - int mb_mode_index = ctx->best_mode_index; + const int mb_mode_index = ctx->best_mode_index; const int mis = cm->mode_info_stride; const int mi_width = num_8x8_blocks_wide_lookup[bsize]; const int mi_height = num_8x8_blocks_high_lookup[bsize]; @@ -506,8 +496,8 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx, } else { // Note how often each mode chosen as best cpi->mode_chosen_counts[mb_mode_index]++; - if (is_inter_block(mbmi) - && (mbmi->sb_type < BLOCK_8X8 || mbmi->mode == NEWMV)) { + if (is_inter_block(mbmi) && + (mbmi->sb_type < BLOCK_8X8 || mbmi->mode == NEWMV)) { int_mv best_mv[2]; const MV_REFERENCE_FRAME rf1 = mbmi->ref_frame[0]; const MV_REFERENCE_FRAME rf2 = mbmi->ref_frame[1]; @@ -560,7 +550,6 @@ static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile, VP9_COMMON *const cm = &cpi->common; MACROBLOCKD *const xd = &x->e_mbd; MB_MODE_INFO *mbmi; - const int dst_fb_idx = cm->new_fb_idx; const int idx_str = xd->mode_info_stride * mi_row + mi_col; const int mi_width = num_8x8_blocks_wide_lookup[bsize]; const int mi_height = num_8x8_blocks_high_lookup[bsize]; @@ -587,7 +576,7 @@ static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile, mbmi = &xd->mi_8x8[0]->mbmi; // Set up destination pointers - setup_dst_planes(xd, &cm->yv12_fb[dst_fb_idx], mi_row, mi_col); + setup_dst_planes(xd, get_frame_new_buffer(cm), mi_row, mi_col); // Set up limit values for MV components // mv beyond the range do not produce new/different prediction block @@ -611,15 +600,15 @@ static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile, /* segment ID */ if (seg->enabled) { if (cpi->oxcf.aq_mode != VARIANCE_AQ) { - uint8_t *map = seg->update_map ? cpi->segmentation_map - : cm->last_frame_seg_map; + const uint8_t *const map = seg->update_map ? cpi->segmentation_map + : cm->last_frame_seg_map; mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col); } vp9_mb_init_quantizer(cpi, x); - if (seg->enabled && cpi->seg0_cnt > 0 - && !vp9_segfeature_active(seg, 0, SEG_LVL_REF_FRAME) - && vp9_segfeature_active(seg, 1, SEG_LVL_REF_FRAME)) { + if (seg->enabled && cpi->seg0_cnt > 0 && + !vp9_segfeature_active(seg, 0, SEG_LVL_REF_FRAME) && + vp9_segfeature_active(seg, 1, SEG_LVL_REF_FRAME)) { cpi->seg0_progress = (cpi->seg0_idx << 16) / cpi->seg0_cnt; } else { const int y = mb_row & ~3; @@ -688,13 +677,8 @@ static void pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile, x->source_variance = get_sby_perpixel_variance(cpi, x, bsize); if (cpi->oxcf.aq_mode == VARIANCE_AQ) { - int energy; - if (bsize <= BLOCK_16X16) { - energy = x->mb_energy; - } else { - energy = vp9_block_energy(cpi, x, bsize); - } - + const int energy = bsize <= BLOCK_16X16 ? x->mb_energy + : vp9_block_energy(cpi, x, bsize); xd->mi_8x8[0]->mbmi.segment_id = vp9_vaq_segment_id(energy); rdmult_ratio = vp9_vaq_rdmult_ratio(energy); vp9_mb_init_quantizer(cpi, x); @@ -958,7 +942,7 @@ static void encode_sb(VP9_COMP *cpi, const TileInfo *const tile, static BLOCK_SIZE find_partition_size(BLOCK_SIZE bsize, int rows_left, int cols_left, int *bh, int *bw) { - if ((rows_left <= 0) || (cols_left <= 0)) { + if (rows_left <= 0 || cols_left <= 0) { return MIN(bsize, BLOCK_8X8); } else { for (; bsize > 0; --bsize) { @@ -985,7 +969,7 @@ static void set_partitioning(VP9_COMP *cpi, const TileInfo *const tile, int row8x8_remaining = tile->mi_row_end - mi_row; int col8x8_remaining = tile->mi_col_end - mi_col; int block_row, block_col; - MODE_INFO * mi_upper_left = cm->mi + mi_row * mis + mi_col; + MODE_INFO *mi_upper_left = cm->mi + mi_row * mis + mi_col; int bh = num_8x8_blocks_high_lookup[bsize]; int bw = num_8x8_blocks_wide_lookup[bsize]; @@ -1024,12 +1008,10 @@ static void copy_partitioning(VP9_COMMON *cm, MODE_INFO **mi_8x8, for (block_row = 0; block_row < 8; ++block_row) { for (block_col = 0; block_col < 8; ++block_col) { - MODE_INFO *prev_mi = prev_mi_8x8[block_row * mis + block_col]; - BLOCK_SIZE sb_type = prev_mi ? prev_mi->mbmi.sb_type : 0; - ptrdiff_t offset; - + MODE_INFO *const prev_mi = prev_mi_8x8[block_row * mis + block_col]; + const BLOCK_SIZE sb_type = prev_mi ? prev_mi->mbmi.sb_type : 0; if (prev_mi) { - offset = prev_mi - cm->prev_mi; + const ptrdiff_t offset = prev_mi - cm->prev_mi; mi_8x8[block_row * mis + block_col] = cm->mi + offset; mi_8x8[block_row * mis + block_col]->mbmi.sb_type = sb_type; } @@ -1037,14 +1019,14 @@ static void copy_partitioning(VP9_COMMON *cm, MODE_INFO **mi_8x8, } } -static int sb_has_motion(VP9_COMMON *cm, MODE_INFO **prev_mi_8x8) { +static int sb_has_motion(const VP9_COMMON *cm, MODE_INFO **prev_mi_8x8) { const int mis = cm->mode_info_stride; int block_row, block_col; if (cm->prev_mi) { for (block_row = 0; block_row < 8; ++block_row) { for (block_col = 0; block_col < 8; ++block_col) { - MODE_INFO * prev_mi = prev_mi_8x8[block_row * mis + block_col]; + const MODE_INFO *prev_mi = prev_mi_8x8[block_row * mis + block_col]; if (prev_mi) { if (abs(prev_mi->mbmi.mv[0].as_mv.row) >= 8 || abs(prev_mi->mbmi.mv[0].as_mv.col) >= 8) @@ -1065,12 +1047,12 @@ static void rd_use_partition(VP9_COMP *cpi, VP9_COMMON *const cm = &cpi->common; MACROBLOCK *const x = &cpi->mb; const int mis = cm->mode_info_stride; - int bsl = b_width_log2(bsize); + const int bsl = b_width_log2(bsize); const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[bsize]; const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; - int ms = num_4x4_blocks_wide / 2; - int mh = num_4x4_blocks_high / 2; - int bss = (1 << bsl) / 4; + const int ms = num_4x4_blocks_wide / 2; + const int mh = num_4x4_blocks_high / 2; + const int bss = (1 << bsl) / 4; int i, pl; PARTITION_TYPE partition = PARTITION_NONE; BLOCK_SIZE subsize; @@ -1092,7 +1074,6 @@ static void rd_use_partition(VP9_COMP *cpi, return; partition = partition_lookup[bsl][bs_type]; - subsize = get_subsize(bsize, partition); if (bsize < BLOCK_8X8) { @@ -2262,16 +2243,14 @@ static void reset_skip_txfm_size(VP9_COMMON *cm, TX_SIZE txfm_max) { } static int get_frame_type(VP9_COMP *cpi) { - int frame_type; if (frame_is_intra_only(&cpi->common)) - frame_type = 0; + return 0; else if (cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame) - frame_type = 3; + return 3; else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) - frame_type = 1; + return 1; else - frame_type = 2; - return frame_type; + return 2; } static void select_tx_mode(VP9_COMP *cpi) { @@ -2312,10 +2291,10 @@ void vp9_encode_frame(VP9_COMP *cpi) { // side behavior is where the ALT ref buffer has opposite sign bias to // the other two. if (!frame_is_intra_only(cm)) { - if ((cm->ref_frame_sign_bias[ALTREF_FRAME] - == cm->ref_frame_sign_bias[GOLDEN_FRAME]) - || (cm->ref_frame_sign_bias[ALTREF_FRAME] - == cm->ref_frame_sign_bias[LAST_FRAME])) { + if ((cm->ref_frame_sign_bias[ALTREF_FRAME] == + cm->ref_frame_sign_bias[GOLDEN_FRAME]) || + (cm->ref_frame_sign_bias[ALTREF_FRAME] == + cm->ref_frame_sign_bias[LAST_FRAME])) { cm->allow_comp_inter_inter = 0; } else { cm->allow_comp_inter_inter = 1; @@ -2398,8 +2377,7 @@ void vp9_encode_frame(VP9_COMP *cpi) { int64_t pd = cpi->rd_tx_select_diff[i]; int diff; if (i == TX_MODE_SELECT) - pd -= RDCOST(cpi->mb.rdmult, cpi->mb.rddiv, - 2048 * (TX_SIZES - 1), 0); + pd -= RDCOST(cpi->mb.rdmult, cpi->mb.rddiv, 2048 * (TX_SIZES - 1), 0); diff = (int) (pd / cm->MBs); cpi->rd_tx_select_threshes[frame_type][i] += diff; cpi->rd_tx_select_threshes[frame_type][i] /= 2; @@ -2463,12 +2441,12 @@ void vp9_encode_frame(VP9_COMP *cpi) { } } -static void sum_intra_stats(VP9_COMMON *cm, const MODE_INFO *mi) { +static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi) { const MB_PREDICTION_MODE y_mode = mi->mbmi.mode; const MB_PREDICTION_MODE uv_mode = mi->mbmi.uv_mode; const BLOCK_SIZE bsize = mi->mbmi.sb_type; - ++cm->counts.uv_mode[y_mode][uv_mode]; + ++counts->uv_mode[y_mode][uv_mode]; if (bsize < BLOCK_8X8) { int idx, idy; @@ -2476,9 +2454,9 @@ static void sum_intra_stats(VP9_COMMON *cm, const MODE_INFO *mi) { const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[bsize]; for (idy = 0; idy < 2; idy += num_4x4_blocks_high) for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) - ++cm->counts.y_mode[0][mi->bmi[idy * 2 + idx].as_mode]; + ++counts->y_mode[0][mi->bmi[idy * 2 + idx].as_mode]; } else { - ++cm->counts.y_mode[size_group_lookup[bsize]][y_mode]; + ++counts->y_mode[size_group_lookup[bsize]][y_mode]; } } @@ -2503,7 +2481,7 @@ static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x) { #endif } -static int get_zbin_mode_boost(MB_MODE_INFO *mbmi, int enabled) { +static int get_zbin_mode_boost(const MB_MODE_INFO *mbmi, int enabled) { if (enabled) { if (is_inter_block(mbmi)) { if (mbmi->mode == ZEROMV) { @@ -2523,9 +2501,9 @@ static int get_zbin_mode_boost(MB_MODE_INFO *mbmi, int enabled) { static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled, int mi_row, int mi_col, BLOCK_SIZE bsize) { - VP9_COMMON * const cm = &cpi->common; - MACROBLOCK * const x = &cpi->mb; - MACROBLOCKD * const xd = &x->e_mbd; + VP9_COMMON *const cm = &cpi->common; + MACROBLOCK *const x = &cpi->mb; + MACROBLOCKD *const xd = &x->e_mbd; MODE_INFO **mi_8x8 = xd->mi_8x8; MODE_INFO *mi = mi_8x8[0]; MB_MODE_INFO *mbmi = &mi->mbmi; @@ -2568,7 +2546,7 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled, vp9_encode_intra_block_y(x, MAX(bsize, BLOCK_8X8)); vp9_encode_intra_block_uv(x, MAX(bsize, BLOCK_8X8)); if (output_enabled) - sum_intra_stats(cm, mi); + sum_intra_stats(&cm->counts, mi); } else { int ref; const int is_compound = has_second_ref(mbmi); diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 812ffa96d..9dfb44222 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -714,7 +714,7 @@ void vp9_first_pass(VP9_COMP *cpi) { mv.as_mv.row *= 8; mv.as_mv.col *= 8; this_error = motion_error; - vp9_set_mbmode_and_mvs(x, NEWMV, &mv); + vp9_set_mbmode_and_mvs(xd, NEWMV, &mv.as_mv); xd->mi_8x8[0]->mbmi.tx_size = TX_4X4; xd->mi_8x8[0]->mbmi.ref_frame[0] = LAST_FRAME; xd->mi_8x8[0]->mbmi.ref_frame[1] = NONE; @@ -793,58 +793,48 @@ void vp9_first_pass(VP9_COMP *cpi) { vp9_clear_system_state(); // __asm emms; { - double weight = 0.0; - FIRSTPASS_STATS fps; - fps.frame = cm->current_video_frame; - fps.intra_error = (double)(intra_error >> 8); - fps.coded_error = (double)(coded_error >> 8); - fps.sr_coded_error = (double)(sr_coded_error >> 8); - weight = simple_weight(cpi->Source); - - - if (weight < 0.1) - weight = 0.1; - - fps.ssim_weighted_pred_err = fps.coded_error * weight; - - fps.pcnt_inter = 0.0; + fps.frame = cm->current_video_frame; + fps.intra_error = intra_error >> 8; + fps.coded_error = coded_error >> 8; + fps.sr_coded_error = sr_coded_error >> 8; + fps.ssim_weighted_pred_err = fps.coded_error * + MAX(0.1, simple_weight(cpi->Source)); + fps.pcnt_inter = 0.0; fps.pcnt_motion = 0.0; - fps.MVr = 0.0; - fps.mvr_abs = 0.0; - fps.MVc = 0.0; - fps.mvc_abs = 0.0; - fps.MVrv = 0.0; - fps.MVcv = 0.0; - fps.mv_in_out_count = 0.0; + fps.MVr = 0.0; + fps.mvr_abs = 0.0; + fps.MVc = 0.0; + fps.mvc_abs = 0.0; + fps.MVrv = 0.0; + fps.MVcv = 0.0; + fps.mv_in_out_count = 0.0; fps.new_mv_count = 0.0; - fps.count = 1.0; + fps.count = 1.0; - fps.pcnt_inter = 1.0 * (double)intercount / cm->MBs; - fps.pcnt_second_ref = 1.0 * (double)second_ref_count / cm->MBs; - fps.pcnt_neutral = 1.0 * (double)neutral_count / cm->MBs; + fps.pcnt_inter = (double)intercount / cm->MBs; + fps.pcnt_second_ref = (double)second_ref_count / cm->MBs; + fps.pcnt_neutral = (double)neutral_count / cm->MBs; if (mvcount > 0) { - fps.MVr = (double)sum_mvr / (double)mvcount; - fps.mvr_abs = (double)sum_mvr_abs / (double)mvcount; - fps.MVc = (double)sum_mvc / (double)mvcount; - fps.mvc_abs = (double)sum_mvc_abs / (double)mvcount; - fps.MVrv = ((double)sum_mvrs - (fps.MVr * fps.MVr / (double)mvcount)) / - (double)mvcount; - fps.MVcv = ((double)sum_mvcs - (fps.MVc * fps.MVc / (double)mvcount)) / - (double)mvcount; - fps.mv_in_out_count = (double)sum_in_vectors / (double)(mvcount * 2); + fps.MVr = (double)sum_mvr / mvcount; + fps.mvr_abs = (double)sum_mvr_abs / mvcount; + fps.MVc = (double)sum_mvc / mvcount; + fps.mvc_abs = (double)sum_mvc_abs / mvcount; + fps.MVrv = ((double)sum_mvrs - (fps.MVr * fps.MVr / mvcount)) / + mvcount; + fps.MVcv = ((double)sum_mvcs - (fps.MVc * fps.MVc / mvcount)) / + mvcount; + fps.mv_in_out_count = (double)sum_in_vectors / (mvcount * 2); fps.new_mv_count = new_mv_count; - fps.pcnt_motion = 1.0 * (double)mvcount / cpi->common.MBs; } // TODO(paulwilkins): Handle the case when duration is set to 0, or // something less than the full time between subsequent values of // cpi->source_time_stamp. - fps.duration = (double)(cpi->source->ts_end - - cpi->source->ts_start); + fps.duration = (double)(cpi->source->ts_end - cpi->source->ts_start); // don't want to do output stats with a stack variable! cpi->twopass.this_frame_stats = fps; @@ -1825,7 +1815,8 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // If the frame that is to be boosted is simpler than the average for // the gf/arf group then use an alternative calculation // based on the error score of the frame itself - if (mod_frame_err < gf_group_err / (double)cpi->rc.baseline_gf_interval) { + if (cpi->rc.baseline_gf_interval < 1 || + mod_frame_err < gf_group_err / (double)cpi->rc.baseline_gf_interval) { double alt_gf_grp_bits = (double)cpi->twopass.kf_group_bits * (mod_frame_err * (double)cpi->rc.baseline_gf_interval) / @@ -1932,12 +1923,9 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // Allocate bits to a normal frame that is neither a gf an arf or a key frame. static void assign_std_frame_bits(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { int target_frame_size; - double modified_err; double err_fraction; - - // Max for a single frame. - int max_bits = frame_max_bits(cpi); + const int max_bits = frame_max_bits(cpi); // Max for a single frame. // Calculate modified prediction error used in bit allocation. modified_err = calculate_modified_err(cpi, this_frame); @@ -1953,15 +1941,8 @@ static void assign_std_frame_bits(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) { // Clip target size to 0 - max_bits (or cpi->twopass.gf_group_bits) at // the top end. - if (target_frame_size < 0) { - target_frame_size = 0; - } else { - if (target_frame_size > max_bits) - target_frame_size = max_bits; - - if (target_frame_size > cpi->twopass.gf_group_bits) - target_frame_size = (int)cpi->twopass.gf_group_bits; - } + target_frame_size = clamp(target_frame_size, 0, + MIN(max_bits, (int)cpi->twopass.gf_group_bits)); // Adjust error and bits remaining. cpi->twopass.gf_group_error_left -= (int64_t)modified_err; diff --git a/vp9/encoder/vp9_mbgraph.c b/vp9/encoder/vp9_mbgraph.c index f3ddd39b6..c50098678 100644 --- a/vp9/encoder/vp9_mbgraph.c +++ b/vp9/encoder/vp9_mbgraph.c @@ -23,7 +23,7 @@ static unsigned int do_16x16_motion_iteration(VP9_COMP *cpi, const MV *ref_mv, - int_mv *dst_mv, + MV *dst_mv, int mb_row, int mb_col) { MACROBLOCK *const x = &cpi->mb; @@ -35,7 +35,7 @@ static unsigned int do_16x16_motion_iteration(VP9_COMP *cpi, const int tmp_col_max = x->mv_col_max; const int tmp_row_min = x->mv_row_min; const int tmp_row_max = x->mv_row_max; - int_mv ref_full; + MV ref_full; // Further step/diamond searches as necessary int step_param = cpi->sf.reduce_first_step_size + @@ -44,12 +44,12 @@ static unsigned int do_16x16_motion_iteration(VP9_COMP *cpi, vp9_set_mv_search_range(x, ref_mv); - ref_full.as_mv.col = ref_mv->col >> 3; - ref_full.as_mv.row = ref_mv->row >> 3; + ref_full.col = ref_mv->col >> 3; + ref_full.row = ref_mv->row >> 3; /*cpi->sf.search_method == HEX*/ - best_err = vp9_hex_search(x, &ref_full.as_mv, step_param, x->errorperbit, - 0, &v_fn_ptr, 0, ref_mv, &dst_mv->as_mv); + best_err = vp9_hex_search(x, &ref_full, step_param, x->errorperbit, + 0, &v_fn_ptr, 0, ref_mv, dst_mv); // Try sub-pixel MC // if (bestsme > error_thresh && bestsme < INT_MAX) @@ -57,15 +57,14 @@ static unsigned int do_16x16_motion_iteration(VP9_COMP *cpi, int distortion; unsigned int sse; best_err = cpi->find_fractional_mv_step( - x, - &dst_mv->as_mv, ref_mv, + x, dst_mv, ref_mv, cpi->common.allow_high_precision_mv, x->errorperbit, &v_fn_ptr, 0, cpi->sf.subpel_iters_per_step, NULL, NULL, & distortion, &sse); } - vp9_set_mbmode_and_mvs(x, NEWMV, dst_mv); + vp9_set_mbmode_and_mvs(xd, NEWMV, dst_mv); vp9_build_inter_predictors_sby(xd, mb_row, mb_col, BLOCK_16X16); best_err = vp9_sad16x16(x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].dst.buf, xd->plane[0].dst.stride, @@ -96,7 +95,7 @@ static int do_16x16_motion_search(VP9_COMP *cpi, const int_mv *ref_mv, // Test last reference frame using the previous best mv as the // starting point (best reference) for the search - tmp_err = do_16x16_motion_iteration(cpi, &ref_mv->as_mv, &tmp_mv, + tmp_err = do_16x16_motion_iteration(cpi, &ref_mv->as_mv, &tmp_mv.as_mv, mb_row, mb_col); if (tmp_err < err) { err = tmp_err; @@ -110,7 +109,7 @@ static int do_16x16_motion_search(VP9_COMP *cpi, const int_mv *ref_mv, int_mv zero_ref_mv, tmp_mv; zero_ref_mv.as_int = 0; - tmp_err = do_16x16_motion_iteration(cpi, &zero_ref_mv.as_mv, &tmp_mv, + tmp_err = do_16x16_motion_iteration(cpi, &zero_ref_mv.as_mv, &tmp_mv.as_mv, mb_row, mb_col); if (tmp_err < err) { dst_mv->as_int = tmp_mv.as_int; diff --git a/vp9/encoder/vp9_mcomp.c b/vp9/encoder/vp9_mcomp.c index c199dff0c..efb5ce16d 100644 --- a/vp9/encoder/vp9_mcomp.c +++ b/vp9/encoder/vp9_mcomp.c @@ -1371,23 +1371,18 @@ int vp9_full_search_sad_c(MACROBLOCK *x, MV *ref_mv, int *mvcost[2], const MV *center_mv, int n) { const MACROBLOCKD* const xd = &x->e_mbd; - uint8_t *what = x->plane[0].src.buf; - int what_stride = x->plane[0].src.stride; - uint8_t *in_what; - int in_what_stride = xd->plane[0].pre[0].stride; - int mv_stride = xd->plane[0].pre[0].stride; - uint8_t *bestaddress; + const uint8_t *const what = x->plane[0].src.buf; + const int what_stride = x->plane[0].src.stride; + const uint8_t *const in_what = xd->plane[0].pre[0].buf; + const int in_what_stride = xd->plane[0].pre[0].stride; + const uint8_t *bestaddress; MV *best_mv = &x->e_mbd.mi_8x8[0]->bmi[n].as_mv[0].as_mv; MV this_mv; int bestsad = INT_MAX; int r, c; - - uint8_t *check_here; int thissad; - int ref_row = ref_mv->row; int ref_col = ref_mv->col; - int row_min = ref_row - distance; int row_max = ref_row + distance; int col_min = ref_col - distance; @@ -1401,8 +1396,7 @@ int vp9_full_search_sad_c(MACROBLOCK *x, MV *ref_mv, fcenter_mv.col = center_mv->col >> 3; // Work out the mid point for the search - in_what = xd->plane[0].pre[0].buf; - bestaddress = in_what + (ref_row * xd->plane[0].pre[0].stride) + ref_col; + bestaddress = &in_what[ref_row * in_what_stride + ref_col]; best_mv->row = ref_row; best_mv->col = ref_col; @@ -1421,8 +1415,8 @@ int vp9_full_search_sad_c(MACROBLOCK *x, MV *ref_mv, row_max = MIN(row_max, x->mv_row_max); for (r = row_min; r < row_max; r++) { + const uint8_t *check_here = &in_what[r * in_what_stride + col_min]; this_mv.row = r; - check_here = r * mv_stride + in_what + col_min; for (c = col_min; c < col_max; c++) { thissad = fn_ptr->sdf(what, what_stride, check_here, in_what_stride, @@ -1460,31 +1454,24 @@ int vp9_full_search_sadx3(MACROBLOCK *x, MV *ref_mv, vp9_variance_fn_ptr_t *fn_ptr, int *mvjcost, int *mvcost[2], const MV *center_mv, int n) { const MACROBLOCKD* const xd = &x->e_mbd; - uint8_t *what = x->plane[0].src.buf; - int what_stride = x->plane[0].src.stride; - uint8_t *in_what; - int in_what_stride = xd->plane[0].pre[0].stride; - int mv_stride = xd->plane[0].pre[0].stride; - uint8_t *bestaddress; + const uint8_t *const what = x->plane[0].src.buf; + const int what_stride = x->plane[0].src.stride; + const uint8_t *const in_what = xd->plane[0].pre[0].buf; + const int in_what_stride = xd->plane[0].pre[0].stride; + const uint8_t *bestaddress; MV *best_mv = &x->e_mbd.mi_8x8[0]->bmi[n].as_mv[0].as_mv; MV this_mv; unsigned int bestsad = INT_MAX; int r, c; - - uint8_t *check_here; unsigned int thissad; - int ref_row = ref_mv->row; int ref_col = ref_mv->col; - int row_min = ref_row - distance; int row_max = ref_row + distance; int col_min = ref_col - distance; int col_max = ref_col + distance; - unsigned int sad_array[3]; MV fcenter_mv; - int *mvjsadcost = x->nmvjointsadcost; int *mvsadcost[2] = {x->nmvsadcost[0], x->nmvsadcost[1]}; @@ -1492,8 +1479,7 @@ int vp9_full_search_sadx3(MACROBLOCK *x, MV *ref_mv, fcenter_mv.col = center_mv->col >> 3; // Work out the mid point for the search - in_what = xd->plane[0].pre[0].buf; - bestaddress = in_what + (ref_row * xd->plane[0].pre[0].stride) + ref_col; + bestaddress = &in_what[ref_row * in_what_stride + ref_col]; best_mv->row = ref_row; best_mv->col = ref_col; @@ -1512,8 +1498,8 @@ int vp9_full_search_sadx3(MACROBLOCK *x, MV *ref_mv, row_max = MIN(row_max, x->mv_row_max); for (r = row_min; r < row_max; r++) { + const uint8_t *check_here = &in_what[r * in_what_stride + col_min]; this_mv.row = r; - check_here = r * mv_stride + in_what + col_min; c = col_min; while ((c + 2) < col_max && fn_ptr->sdx3f != NULL) { @@ -1582,28 +1568,22 @@ int vp9_full_search_sadx8(MACROBLOCK *x, MV *ref_mv, int *mvjcost, int *mvcost[2], const MV *center_mv, int n) { const MACROBLOCKD* const xd = &x->e_mbd; - uint8_t *what = x->plane[0].src.buf; - int what_stride = x->plane[0].src.stride; - uint8_t *in_what; - int in_what_stride = xd->plane[0].pre[0].stride; - int mv_stride = xd->plane[0].pre[0].stride; - uint8_t *bestaddress; + const uint8_t *const what = x->plane[0].src.buf; + const int what_stride = x->plane[0].src.stride; + const uint8_t *const in_what = xd->plane[0].pre[0].buf; + const int in_what_stride = xd->plane[0].pre[0].stride; + const uint8_t *bestaddress; MV *best_mv = &x->e_mbd.mi_8x8[0]->bmi[n].as_mv[0].as_mv; MV this_mv; unsigned int bestsad = INT_MAX; int r, c; - - uint8_t *check_here; unsigned int thissad; - int ref_row = ref_mv->row; int ref_col = ref_mv->col; - int row_min = ref_row - distance; int row_max = ref_row + distance; int col_min = ref_col - distance; int col_max = ref_col + distance; - DECLARE_ALIGNED_ARRAY(16, uint32_t, sad_array8, 8); unsigned int sad_array[3]; MV fcenter_mv; @@ -1615,8 +1595,7 @@ int vp9_full_search_sadx8(MACROBLOCK *x, MV *ref_mv, fcenter_mv.col = center_mv->col >> 3; // Work out the mid point for the search - in_what = xd->plane[0].pre[0].buf; - bestaddress = in_what + (ref_row * xd->plane[0].pre[0].stride) + ref_col; + bestaddress = &in_what[ref_row * in_what_stride + ref_col]; best_mv->row = ref_row; best_mv->col = ref_col; @@ -1635,8 +1614,8 @@ int vp9_full_search_sadx8(MACROBLOCK *x, MV *ref_mv, row_max = MIN(row_max, x->mv_row_max); for (r = row_min; r < row_max; r++) { + const uint8_t *check_here = &in_what[r * in_what_stride + col_min]; this_mv.row = r; - check_here = r * mv_stride + in_what + col_min; c = col_min; while ((c + 7) < col_max) { diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 8e60bc96d..abdcf2f83 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -1844,9 +1844,6 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) { cpi->diamond_search_sad = vp9_diamond_search_sad; cpi->refining_search_sad = vp9_refining_search_sad; - // make sure frame 1 is okay - cpi->error_bins[0] = cm->MBs; - /* vp9_init_quantizer() is first called here. Add check in * vp9_frame_init_quantizer() so that vp9_init_quantizer is only * called later when needed. This will avoid unnecessary calls of @@ -2193,27 +2190,33 @@ int vp9_update_reference(VP9_PTR ptr, int ref_frame_flags) { return 0; } -int vp9_copy_reference_enc(VP9_PTR ptr, VP9_REFFRAME ref_frame_flag, - YV12_BUFFER_CONFIG *sd) { - VP9_COMP *cpi = (VP9_COMP *)(ptr); - YV12_BUFFER_CONFIG *cfg; - +static YV12_BUFFER_CONFIG *get_vp9_ref_frame_buffer(VP9_COMP *cpi, + VP9_REFFRAME ref_frame_flag) { + MV_REFERENCE_FRAME ref_frame = NONE; if (ref_frame_flag == VP9_LAST_FLAG) - cfg = get_ref_frame_buffer(cpi, LAST_FRAME); + ref_frame = LAST_FRAME; else if (ref_frame_flag == VP9_GOLD_FLAG) - cfg = get_ref_frame_buffer(cpi, GOLDEN_FRAME); + ref_frame = GOLDEN_FRAME; else if (ref_frame_flag == VP9_ALT_FLAG) - cfg = get_ref_frame_buffer(cpi, ALTREF_FRAME); - else - return -1; + ref_frame = ALTREF_FRAME; - vp8_yv12_copy_frame(cfg, sd); + return ref_frame == NONE ? NULL : get_ref_frame_buffer(cpi, ref_frame); +} - return 0; +int vp9_copy_reference_enc(VP9_PTR ptr, VP9_REFFRAME ref_frame_flag, + YV12_BUFFER_CONFIG *sd) { + VP9_COMP *const cpi = (VP9_COMP *)ptr; + YV12_BUFFER_CONFIG *cfg = get_vp9_ref_frame_buffer(cpi, ref_frame_flag); + if (cfg) { + vp8_yv12_copy_frame(cfg, sd); + return 0; + } else { + return -1; + } } int vp9_get_reference_enc(VP9_PTR ptr, int index, YV12_BUFFER_CONFIG **fb) { - VP9_COMP *cpi = (VP9_COMP *)(ptr); + VP9_COMP *cpi = (VP9_COMP *)ptr; VP9_COMMON *cm = &cpi->common; if (index < 0 || index >= REF_FRAMES) @@ -2225,23 +2228,14 @@ int vp9_get_reference_enc(VP9_PTR ptr, int index, YV12_BUFFER_CONFIG **fb) { int vp9_set_reference_enc(VP9_PTR ptr, VP9_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd) { - VP9_COMP *cpi = (VP9_COMP *)(ptr); - VP9_COMMON *cm = &cpi->common; - - int ref_fb_idx; - - if (ref_frame_flag == VP9_LAST_FLAG) - ref_fb_idx = cm->ref_frame_map[cpi->lst_fb_idx]; - else if (ref_frame_flag == VP9_GOLD_FLAG) - ref_fb_idx = cm->ref_frame_map[cpi->gld_fb_idx]; - else if (ref_frame_flag == VP9_ALT_FLAG) - ref_fb_idx = cm->ref_frame_map[cpi->alt_fb_idx]; - else + VP9_COMP *cpi = (VP9_COMP *)ptr; + YV12_BUFFER_CONFIG *cfg = get_vp9_ref_frame_buffer(cpi, ref_frame_flag); + if (cfg) { + vp8_yv12_copy_frame(sd, cfg); + return 0; + } else { return -1; - - vp8_yv12_copy_frame(sd, &cm->yv12_fb[ref_fb_idx]); - - return 0; + } } int vp9_update_entropy(VP9_PTR comp, int update) { @@ -3420,7 +3414,7 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags, #endif frames_to_arf = cpi->rc.frames_till_gf_update_due; - assert(frames_to_arf < cpi->rc.frames_to_key); + assert(frames_to_arf <= cpi->rc.frames_to_key); if ((cpi->source = vp9_lookahead_peek(cpi->lookahead, frames_to_arf))) { #if CONFIG_MULTIPLE_ARF diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index a5be0f424..b1969f380 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -623,7 +623,6 @@ typedef struct VP9_COMP { int ref_frame_flags; SPEED_FEATURES sf; - int error_bins[1024]; unsigned int max_mv_magnitude; int mv_step_param; @@ -740,9 +739,6 @@ typedef struct VP9_COMP { int dummy_packing; /* flag to indicate if packing is dummy */ - unsigned int switchable_interp_count[SWITCHABLE_FILTER_CONTEXTS] - [SWITCHABLE_FILTERS]; - unsigned int tx_stepdown_count[TX_SIZES]; int initial_width; diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 939a7f998..aefef5319 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -965,5 +965,5 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) { void vp9_rc_postencode_update_drop_frame(VP9_COMP *cpi) { cpi->rc.frames_since_key++; - // cpi->rc.frames_to_key--; + cpi->rc.frames_to_key--; } diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 64d8cf86d..8155922e7 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -134,27 +134,27 @@ static int16_t* raster_block_offset_int16(BLOCK_SIZE plane_bsize, return base + raster_block_offset(plane_bsize, raster_block, stride); } -static void fill_mode_costs(VP9_COMP *c) { - VP9_COMMON *const cm = &c->common; +static void fill_mode_costs(VP9_COMP *cpi) { + VP9_COMMON *const cm = &cpi->common; + MACROBLOCK *const x = &cpi->mb; + FRAME_CONTEXT *const fc = &cm->fc; int i, j; for (i = 0; i < INTRA_MODES; i++) for (j = 0; j < INTRA_MODES; j++) - vp9_cost_tokens((int *)c->mb.y_mode_costs[i][j], vp9_kf_y_mode_prob[i][j], + vp9_cost_tokens((int *)x->y_mode_costs[i][j], vp9_kf_y_mode_prob[i][j], vp9_intra_mode_tree); // TODO(rbultje) separate tables for superblock costing? - vp9_cost_tokens(c->mb.mbmode_cost, cm->fc.y_mode_prob[1], - vp9_intra_mode_tree); - vp9_cost_tokens(c->mb.intra_uv_mode_cost[1], - cm->fc.uv_mode_prob[INTRA_MODES - 1], vp9_intra_mode_tree); - vp9_cost_tokens(c->mb.intra_uv_mode_cost[0], - vp9_kf_uv_mode_prob[INTRA_MODES - 1], - vp9_intra_mode_tree); + vp9_cost_tokens(x->mbmode_cost, fc->y_mode_prob[1], vp9_intra_mode_tree); + vp9_cost_tokens(x->intra_uv_mode_cost[1], + fc->uv_mode_prob[INTRA_MODES - 1], vp9_intra_mode_tree); + vp9_cost_tokens(x->intra_uv_mode_cost[0], + vp9_kf_uv_mode_prob[INTRA_MODES - 1], vp9_intra_mode_tree); for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i) - vp9_cost_tokens((int *)c->mb.switchable_interp_costs[i], - cm->fc.switchable_interp_prob[i], + vp9_cost_tokens((int *)x->switchable_interp_costs[i], + fc->switchable_interp_prob[i], vp9_switchable_interp_tree); } @@ -198,9 +198,9 @@ void vp9_init_me_luts() { // This is to make it easier to resolve the impact of experimental changes // to the quantizer tables. for (i = 0; i < QINDEX_RANGE; i++) { - sad_per_bit16lut[i] = - (int)((0.0418 * vp9_convert_qindex_to_q(i)) + 2.4107); - sad_per_bit4lut[i] = (int)(0.063 * vp9_convert_qindex_to_q(i) + 2.742); + const double q = vp9_convert_qindex_to_q(i); + sad_per_bit16lut[i] = (int)(0.0418 * q + 2.4107); + sad_per_bit4lut[i] = (int)(0.063 * q + 2.742); } } @@ -234,36 +234,30 @@ void vp9_initialize_me_consts(VP9_COMP *cpi, int qindex) { static void set_block_thresholds(VP9_COMP *cpi) { int i, bsize, segment_id; VP9_COMMON *cm = &cpi->common; + SPEED_FEATURES *sf = &cpi->sf; for (segment_id = 0; segment_id < MAX_SEGMENTS; ++segment_id) { - int q; - int segment_qindex = vp9_get_qindex(&cm->seg, segment_id, cm->base_qindex); - segment_qindex = clamp(segment_qindex + cm->y_dc_delta_q, 0, MAXQ); - q = compute_rd_thresh_factor(segment_qindex); + const int qindex = clamp(vp9_get_qindex(&cm->seg, segment_id, + cm->base_qindex) + cm->y_dc_delta_q, + 0, MAXQ); + const int q = compute_rd_thresh_factor(qindex); for (bsize = 0; bsize < BLOCK_SIZES; ++bsize) { // Threshold here seem unecessarily harsh but fine given actual // range of values used for cpi->sf.thresh_mult[] - int thresh_max = INT_MAX / (q * rd_thresh_block_size_factor[bsize]); + const int t = q * rd_thresh_block_size_factor[bsize]; + const int thresh_max = INT_MAX / t; - for (i = 0; i < MAX_MODES; ++i) { - if (cpi->sf.thresh_mult[i] < thresh_max) { - cpi->rd_threshes[segment_id][bsize][i] = - cpi->sf.thresh_mult[i] * q * - rd_thresh_block_size_factor[bsize] / 4; - } else { - cpi->rd_threshes[segment_id][bsize][i] = INT_MAX; - } - } + for (i = 0; i < MAX_MODES; ++i) + cpi->rd_threshes[segment_id][bsize][i] = + sf->thresh_mult[i] < thresh_max ? sf->thresh_mult[i] * t / 4 + : INT_MAX; for (i = 0; i < MAX_REFS; ++i) { - if (cpi->sf.thresh_mult_sub8x8[i] < thresh_max) { - cpi->rd_thresh_sub8x8[segment_id][bsize][i] = - cpi->sf.thresh_mult_sub8x8[i] * q * - rd_thresh_block_size_factor[bsize] / 4; - } else { - cpi->rd_thresh_sub8x8[segment_id][bsize][i] = INT_MAX; - } + cpi->rd_thresh_sub8x8[segment_id][bsize][i] = + sf->thresh_mult_sub8x8[i] < thresh_max + ? sf->thresh_mult_sub8x8[i] * t / 4 + : INT_MAX; } } } @@ -271,6 +265,7 @@ static void set_block_thresholds(VP9_COMP *cpi) { void vp9_initialize_rd_consts(VP9_COMP *cpi) { VP9_COMMON *cm = &cpi->common; + MACROBLOCK *x = &cpi->mb; int qindex, i; vp9_clear_system_state(); // __asm emms; @@ -284,35 +279,32 @@ void vp9_initialize_rd_consts(VP9_COMP *cpi) { cpi->RDDIV = RDDIV_BITS; // in bits (to multiply D by 128) cpi->RDMULT = vp9_compute_rd_mult(cpi, qindex); - cpi->mb.errorperbit = cpi->RDMULT / RD_MULT_EPB_RATIO; - cpi->mb.errorperbit += (cpi->mb.errorperbit == 0); + x->errorperbit = cpi->RDMULT / RD_MULT_EPB_RATIO + (x->errorperbit == 0); vp9_set_speed_features(cpi); - cpi->mb.select_txfm_size = (cpi->sf.tx_size_search_method == USE_LARGESTALL && - cm->frame_type != KEY_FRAME) ? - 0 : 1; + x->select_txfm_size = (cpi->sf.tx_size_search_method == USE_LARGESTALL && + cm->frame_type != KEY_FRAME) ? 0 : 1; set_block_thresholds(cpi); - fill_token_costs(cpi->mb.token_costs, cm->fc.coef_probs); + fill_token_costs(x->token_costs, cm->fc.coef_probs); for (i = 0; i < PARTITION_CONTEXTS; i++) - vp9_cost_tokens(cpi->mb.partition_cost[i], get_partition_probs(cm, i), + vp9_cost_tokens(x->partition_cost[i], get_partition_probs(cm, i), vp9_partition_tree); - /*rough estimate for costing*/ fill_mode_costs(cpi); if (!frame_is_intra_only(cm)) { - vp9_build_nmv_cost_table( - cpi->mb.nmvjointcost, - cm->allow_high_precision_mv ? cpi->mb.nmvcost_hp : cpi->mb.nmvcost, - &cm->fc.nmvc, - cm->allow_high_precision_mv, 1, 1); + vp9_build_nmv_cost_table(x->nmvjointcost, + cm->allow_high_precision_mv ? x->nmvcost_hp + : x->nmvcost, + &cm->fc.nmvc, + cm->allow_high_precision_mv, 1, 1); for (i = 0; i < INTER_MODE_CONTEXTS; ++i) - vp9_cost_tokens((int *)cpi->mb.inter_mode_cost[i], + vp9_cost_tokens((int *)x->inter_mode_cost[i], cm->fc.inter_mode_probs[i], vp9_inter_mode_tree); } } @@ -464,8 +456,8 @@ static void model_rd_for_sb_y_tx(VP9_COMP *cpi, BLOCK_SIZE bsize, BLOCK_SIZE bs; struct macroblock_plane *const p = &x->plane[0]; struct macroblockd_plane *const pd = &xd->plane[0]; - const int width = 4 << num_4x4_blocks_wide_lookup[bsize]; - const int height = 4 << num_4x4_blocks_high_lookup[bsize]; + const int width = 4 * num_4x4_blocks_wide_lookup[bsize]; + const int height = 4 * num_4x4_blocks_high_lookup[bsize]; int rate_sum = 0; int64_t dist_sum = 0; const int t = 4 << tx_size; @@ -1418,9 +1410,10 @@ static int cost_mv_ref(VP9_COMP *cpi, MB_PREDICTION_MODE mode, } } -void vp9_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv) { - x->e_mbd.mi_8x8[0]->mbmi.mode = mb; - x->e_mbd.mi_8x8[0]->mbmi.mv[0].as_int = mv->as_int; +void vp9_set_mbmode_and_mvs(MACROBLOCKD *xd, MB_PREDICTION_MODE mode, + const MV *mv) { + xd->mi_8x8[0]->mbmi.mode = mode; + xd->mi_8x8[0]->mbmi.mv[0].as_mv = *mv; } static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, diff --git a/vp9/encoder/vp9_rdopt.h b/vp9/encoder/vp9_rdopt.h index 5732c2b2d..4b244a50a 100644 --- a/vp9/encoder/vp9_rdopt.h +++ b/vp9/encoder/vp9_rdopt.h @@ -60,8 +60,8 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, void vp9_init_me_luts(); -void vp9_set_mbmode_and_mvs(MACROBLOCK *x, - MB_PREDICTION_MODE mb, int_mv *mv); +void vp9_set_mbmode_and_mvs(MACROBLOCKD *xd, MB_PREDICTION_MODE mode, + const MV *mv); void vp9_get_entropy_contexts(TX_SIZE tx_size, ENTROPY_CONTEXT t_above[16], ENTROPY_CONTEXT t_left[16], diff --git a/vp9/encoder/vp9_tokenize.c b/vp9/encoder/vp9_tokenize.c index 970a27a46..4ccead834 100644 --- a/vp9/encoder/vp9_tokenize.c +++ b/vp9/encoder/vp9_tokenize.c @@ -175,6 +175,18 @@ static void set_entropy_context_b(int plane, int block, BLOCK_SIZE plane_bsize, set_contexts(xd, pd, plane_bsize, tx_size, p->eobs[block] > 0, aoff, loff); } +static INLINE void add_token(TOKENEXTRA **t, const vp9_prob *context_tree, + int16_t extra, uint8_t token, + uint8_t skip_eob_node, + unsigned int *counts) { + (*t)->token = token; + (*t)->extra = extra; + (*t)->context_tree = context_tree; + (*t)->skip_eob_node = skip_eob_node; + (*t)++; + ++counts[token]; +} + static void tokenize_b(int plane, int block, BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) { struct tokenize_b_args* const args = arg; @@ -186,9 +198,9 @@ static void tokenize_b(int plane, int block, BLOCK_SIZE plane_bsize, struct macroblockd_plane *pd = &xd->plane[plane]; MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; int pt; /* near block/prev token context index */ - int c = 0, rc = 0; + int c = 0; TOKENEXTRA *t = *tp; /* store tokens starting here */ - const int eob = p->eobs[block]; + int eob = p->eobs[block]; const PLANE_TYPE type = pd->plane_type; const int16_t *qcoeff_ptr = BLOCK_OFFSET(p->qcoeff, block); const int segment_id = mbmi->segment_id; @@ -197,51 +209,53 @@ static void tokenize_b(int plane, int block, BLOCK_SIZE plane_bsize, vp9_coeff_count *const counts = cpi->coef_counts[tx_size]; vp9_coeff_probs_model *const coef_probs = cpi->common.fc.coef_probs[tx_size]; const int ref = is_inter_block(mbmi); - const uint8_t *const band_translate = get_band_translate(tx_size); + const uint8_t *const band = get_band_translate(tx_size); const int seg_eob = get_tx_eob(&cpi->common.seg, segment_id, tx_size); int aoff, loff; txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &aoff, &loff); - assert((!type && !plane) || (type && plane)); - pt = get_entropy_context(tx_size, pd->above_context + aoff, - pd->left_context + loff); + pd->left_context + loff); so = get_scan(xd, tx_size, type, block); scan = so->scan; nb = so->neighbors; - c = 0; - do { - const int band = band_translate[c]; - int token; + while (c < eob) { int v = 0; - rc = scan[c]; - if (c) - pt = get_coef_context(nb, token_cache, c); - if (c < eob) { - v = qcoeff_ptr[rc]; - assert(-DCT_MAX_VALUE <= v && v < DCT_MAX_VALUE); - - t->extra = vp9_dct_value_tokens_ptr[v].extra; - token = vp9_dct_value_tokens_ptr[v].token; - } else { - token = EOB_TOKEN; - } + int skip_eob = 0; + v = qcoeff_ptr[scan[c]]; + + while (!v) { + add_token(&t, coef_probs[type][ref][band[c]][pt], 0, ZERO_TOKEN, skip_eob, + counts[type][ref][band[c]][pt]); - t->token = token; - t->context_tree = coef_probs[type][ref][band][pt]; - t->skip_eob_node = (c > 0) && (token_cache[scan[c - 1]] == 0); + cpi->common.counts.eob_branch[tx_size][type][ref][band[c]][pt] += + !skip_eob; - assert(vp9_coef_encodings[t->token].len - t->skip_eob_node > 0); + skip_eob = 1; + token_cache[scan[c]] = 0; + ++c; + pt = get_coef_context(nb, token_cache, c); + v = qcoeff_ptr[scan[c]]; + } + add_token(&t, coef_probs[type][ref][band[c]][pt], + vp9_dct_value_tokens_ptr[v].extra, + vp9_dct_value_tokens_ptr[v].token, skip_eob, + counts[type][ref][band[c]][pt]); - ++counts[type][ref][band][pt][token]; - if (!t->skip_eob_node) - ++cpi->common.counts.eob_branch[tx_size][type][ref][band][pt]; + cpi->common.counts.eob_branch[tx_size][type][ref][band[c]][pt] += !skip_eob; - token_cache[rc] = vp9_pt_energy_class[token]; - ++t; - } while (c < eob && ++c < seg_eob); + token_cache[scan[c]] = + vp9_pt_energy_class[vp9_dct_value_tokens_ptr[v].token]; + ++c; + pt = get_coef_context(nb, token_cache, c); + } + if (c < seg_eob) { + add_token(&t, coef_probs[type][ref][band[c]][pt], 0, EOB_TOKEN, 0, + counts[type][ref][band[c]][pt]); + ++cpi->common.counts.eob_branch[tx_size][type][ref][band[c]][pt]; + } *tp = t; @@ -453,6 +453,8 @@ int main_loop(int argc, const char **argv_) { int num_external_frame_buffers = 0; int fb_lru_cache = 0; vpx_codec_frame_buffer_t *frame_buffers = NULL; + int display_width = 0; + int display_height = 0; struct VpxDecInputContext input = {0}; struct VpxInputContext vpx_input_ctx = {0}; @@ -822,23 +824,31 @@ int main_loop(int argc, const char **argv_) { out_put(out, (const unsigned char*)color, strlen(color), do_md5); } - if (do_scale) { - int stream_w = 0, stream_h = 0; - if (img && frame_out == 1) { - int display_size[2]; - if (vpx_codec_control(&decoder, VP9D_GET_DISPLAY_SIZE, - display_size)) { - // Fallback to use raw image size if display size not available. - stream_w = img->d_w; - stream_h = img->d_h; - } else { - stream_w = display_size[0]; - stream_h = display_size[1]; + if (img && do_scale) { + if (frame_out == 1) { + // If the output frames are to be scaled to a fixed display size then + // use the width and height specified in the container. If either of + // these is set to 0, use the display size set in the first frame + // header. + display_width = vpx_input_ctx.width; + display_height = vpx_input_ctx.height; + if (!display_width || !display_height) { + int display_size[2]; + if (vpx_codec_control(&decoder, VP9D_GET_DISPLAY_SIZE, + display_size)) { + // As last resort use size of first frame as display size. + display_width = img->d_w; + display_height = img->d_h; + } else { + display_width = display_size[0]; + display_height = display_size[1]; + } } - scaled_img = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, - stream_w, stream_h, 16); + scaled_img = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, display_width, + display_height, 16); } - if (img && (img->d_w != stream_w || img->d_h != stream_h)) { + + if (img->d_w != display_width || img->d_h != display_height) { assert(img->fmt == VPX_IMG_FMT_I420); I420Scale(img->planes[VPX_PLANE_Y], img->stride[VPX_PLANE_Y], img->planes[VPX_PLANE_U], img->stride[VPX_PLANE_U], @@ -850,7 +860,7 @@ int main_loop(int argc, const char **argv_) { scaled_img->stride[VPX_PLANE_U], scaled_img->planes[VPX_PLANE_V], scaled_img->stride[VPX_PLANE_V], - stream_w, stream_h, + display_width, display_height, kFilterBox); img = scaled_img; } |