/* * Copyright (c) 2010 The WebM project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include <assert.h>#include <stdlib.h> // qsort() #include "./vp9_rtcd.h"#include "./vpx_dsp_rtcd.h"#include "./vpx_scale_rtcd.h" #include "vpx_dsp/bitreader_buffer.h"#include "vpx_dsp/bitreader.h"#include "vpx_dsp/vpx_dsp_common.h"#include "vpx_mem/vpx_mem.h"#include "vpx_ports/mem.h"#include "vpx_ports/mem_ops.h"#include "vpx_scale/vpx_scale.h"#include "vpx_util/vpx_thread.h"#if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG#include "vpx_util/vpx_debug_util.h"#endif // CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG #include "vp9/common/vp9_alloccommon.h"#include "vp9/common/vp9_common.h"#include "vp9/common/vp9_entropy.h"#include "vp9/common/vp9_entropymode.h"#include "vp9/common/vp9_idct.h"#include "vp9/common/vp9_thread_common.h"#include "vp9/common/vp9_pred_common.h"#include "vp9/common/vp9_quant_common.h"#include "vp9/common/vp9_reconintra.h"#include "vp9/common/vp9_reconinter.h"#include "vp9/common/vp9_seg_common.h"#include "vp9/common/vp9_tile_common.h" #include "vp9/decoder/vp9_decodeframe.h"#include "vp9/decoder/vp9_detokenize.h"#include "vp9/decoder/vp9_decodemv.h"#include "vp9/decoder/vp9_decoder.h"#include "vp9/decoder/vp9_dsubexp.h"#include "vp9/decoder/vp9_job_queue.h" #define MAX_VP9_HEADER_SIZE 80 typedef int (*predict_recon_func)(TileWorkerData *twd, MODE_INFO *const mi, int plane, int row, int col, TX_SIZE tx_size); typedef void (*intra_recon_func)(TileWorkerData *twd, MODE_INFO *const mi, int plane, int row, int col, TX_SIZE tx_size); static int read_is_valid(const uint8_t *start, size_t len, const uint8_t *end) { return len != 0 && len <= (size_t)(end - start);} static int decode_unsigned_max(struct vpx_read_bit_buffer *rb, int max) { const int data = vpx_rb_read_literal(rb, get_unsigned_bits(max)); return data > max ? max : data;} static TX_MODE read_tx_mode(vpx_reader *r) { TX_MODE tx_mode = vpx_read_literal(r, 2); if (tx_mode == ALLOW_32X32) tx_mode += vpx_read_bit(r); return tx_mode;} static void read_tx_mode_probs(struct tx_probs *tx_probs, vpx_reader *r) { int i, j; for (i = 0; i < TX_SIZE_CONTEXTS; ++i) for (j = 0; j < TX_SIZES - 3; ++j) vp9_diff_update_prob(r, &tx_probs->p8x8[i][j]); for (i = 0; i < TX_SIZE_CONTEXTS; ++i) for (j = 0; j < TX_SIZES - 2; ++j) vp9_diff_update_prob(r, &tx_probs->p16x16[i][j]); for (i = 0; i < TX_SIZE_CONTEXTS; ++i) for (j = 0; j < TX_SIZES - 1; ++j) vp9_diff_update_prob(r, &tx_probs->p32x32[i][j]);} static void read_switchable_interp_probs(FRAME_CONTEXT *fc, vpx_reader *r) { int i, j; for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) for (i = 0; i < SWITCHABLE_FILTERS - 1; ++i) vp9_diff_update_prob(r, &fc->switchable_interp_prob[j][i]);} static void read_inter_mode_probs(FRAME_CONTEXT *fc, vpx_reader *r) { int i, j; for (i = 0; i < INTER_MODE_CONTEXTS; ++i) for (j = 0; j < INTER_MODES - 1; ++j) vp9_diff_update_prob(r, &fc->inter_mode_probs[i][j]);} static REFERENCE_MODE read_frame_reference_mode(const VP9_COMMON *cm, vpx_reader *r) { if (vp9_compound_reference_allowed(cm)) { return vpx_read_bit(r) ? (vpx_read_bit(r) ? REFERENCE_MODE_SELECT : COMPOUND_REFERENCE) : SINGLE_REFERENCE; } else { return SINGLE_REFERENCE; }} static void read_frame_reference_mode_probs(VP9_COMMON *cm, vpx_reader *r) { FRAME_CONTEXT *const fc = cm->fc; int i; if (cm->reference_mode == REFERENCE_MODE_SELECT) for (i = 0; i < COMP_INTER_CONTEXTS; ++i) vp9_diff_update_prob(r, &fc->comp_inter_prob[i]); if (cm->reference_mode != COMPOUND_REFERENCE) for (i = 0; i < REF_CONTEXTS; ++i) { vp9_diff_update_prob(r, &fc->single_ref_prob[i][0]); vp9_diff_update_prob(r, &fc->single_ref_prob[i][1]); } if (cm->reference_mode != SINGLE_REFERENCE) for (i = 0; i < REF_CONTEXTS; ++i) vp9_diff_update_prob(r, &fc->comp_ref_prob[i]);} static void update_mv_probs(vpx_prob *p, int n, vpx_reader *r) { int i; for (i = 0; i < n; ++i) if (vpx_read(r, MV_UPDATE_PROB)) p[i] = (vpx_read_literal(r, 7) << 1) | 1;} static void read_mv_probs(nmv_context *ctx, int allow_hp, vpx_reader *r) { int i, j; update_mv_probs(ctx->joints, MV_JOINTS - 1, r); for (i = 0; i < 2; ++i) { nmv_component *const comp_ctx = &ctx->comps[i]; update_mv_probs(&comp_ctx->sign, 1, r); update_mv_probs(comp_ctx->classes, MV_CLASSES - 1, r); update_mv_probs(comp_ctx->class0, CLASS0_SIZE - 1, r); update_mv_probs(comp_ctx->bits, MV_OFFSET_BITS, r); } for (i = 0; i < 2; ++i) { nmv_component *const comp_ctx = &ctx->comps[i]; for (j = 0; j < CLASS0_SIZE; ++j) update_mv_probs(comp_ctx->class0_fp[j], MV_FP_SIZE - 1, r); update_mv_probs(comp_ctx->fp, 3, r); } if (allow_hp) { for (i = 0; i < 2; ++i) { nmv_component *const comp_ctx = &ctx->comps[i]; update_mv_probs(&comp_ctx->class0_hp, 1, r); update_mv_probs(&comp_ctx->hp, 1, r); } }} static void inverse_transform_block_inter(MACROBLOCKD *xd, int plane, const TX_SIZE tx_size, uint8_t *dst, int stride, int eob) { struct macroblockd_plane *const pd = &xd->plane[plane]; tran_low_t *const dqcoeff = pd->dqcoeff; assert(eob > 0);#if CONFIG_VP9_HIGHBITDEPTH if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { uint16_t *const dst16 = CONVERT_TO_SHORTPTR(dst); if (xd->lossless) { vp9_highbd_iwht4x4_add(dqcoeff, dst16, stride, eob, xd->bd); } else { switch (tx_size) { case TX_4X4: vp9_highbd_idct4x4_add(dqcoeff, dst16, stride, eob, xd->bd); break; case TX_8X8: vp9_highbd_idct8x8_add(dqcoeff, dst16, stride, eob, xd->bd); break; case TX_16X16: vp9_highbd_idct16x16_add(dqcoeff, dst16, stride, eob, xd->bd); break; case TX_32X32: vp9_highbd_idct32x32_add(dqcoeff, dst16, stride, eob, xd->bd); break; default: assert(0 && "Invalid transform size"); } } } else { if (xd->lossless) { vp9_iwht4x4_add(dqcoeff, dst, stride, eob); } else { switch (tx_size) { case TX_4X4: vp9_idct4x4_add(dqcoeff, dst, stride, eob); break; case TX_8X8: vp9_idct8x8_add(dqcoeff, dst, stride, eob); break; case TX_16X16: vp9_idct16x16_add(dqcoeff, dst, stride, eob); break; case TX_32X32: vp9_idct32x32_add(dqcoeff, dst, stride, eob); break; default: assert(0 && "Invalid transform size"); return; } } }#else if (xd->lossless) { vp9_iwht4x4_add(dqcoeff, dst, stride, eob); } else { switch (tx_size) { case TX_4X4: vp9_idct4x4_add(dqcoeff, dst, stride, eob); break; case TX_8X8: vp9_idct8x8_add(dqcoeff, dst, stride, eob); break; case TX_16X16: vp9_idct16x16_add(dqcoeff, dst, stride, eob); break; case TX_32X32: vp9_idct32x32_add(dqcoeff, dst, stride, eob); break; default: assert(0 && "Invalid transform size"); return; } }#endif // CONFIG_VP9_HIGHBITDEPTH if (eob == 1) { dqcoeff[0] = 0; } else { if (tx_size <= TX_16X16 && eob <= 10) memset(dqcoeff, 0, 4 * (4 << tx_size) * sizeof(dqcoeff[0])); else if (tx_size == TX_32X32 && eob <= 34) memset(dqcoeff, 0, 256 * sizeof(dqcoeff[0])); else memset(dqcoeff, 0, (16 << (tx_size << 1)) * sizeof(dqcoeff[0])); }} static void inverse_transform_block_intra(MACROBLOCKD *xd, int plane, const TX_TYPE tx_type, const TX_SIZE tx_size, uint8_t *dst, int stride, int eob) { struct macroblockd_plane *const pd = &xd->plane[plane]; tran_low_t *const dqcoeff = pd->dqcoeff; assert(eob > 0);#if CONFIG_VP9_HIGHBITDEPTH if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { uint16_t *const dst16 = CONVERT_TO_SHORTPTR(dst); if (xd->lossless) { vp9_highbd_iwht4x4_add(dqcoeff, dst16, stride, eob, xd->bd); } else { switch (tx_size) { case TX_4X4: vp9_highbd_iht4x4_add(tx_type, dqcoeff, dst16, stride, eob, xd->bd); break; case TX_8X8: vp9_highbd_iht8x8_add(tx_type, dqcoeff, dst16, stride, eob, xd->bd); break; case TX_16X16: vp9_highbd_iht16x16_add(tx_type, dqcoeff, dst16, stride, eob, xd->bd); break; case TX_32X32: vp9_highbd_idct32x32_add(dqcoeff, dst16, stride, eob, xd->bd); break; default: assert(0 && "Invalid transform size"); } } } else { if (xd->lossless) { vp9_iwht4x4_add(dqcoeff, dst, stride, eob); } else { switch (tx_size) { case TX_4X4: vp9_iht4x4_add(tx_type, dqcoeff, dst, stride, eob); break; case TX_8X8: vp9_iht8x8_add(tx_type, dqcoeff, dst, stride, eob); break; case TX_16X16: vp9_iht16x16_add(tx_type, dqcoeff, dst, stride, eob); break; case TX_32X32: vp9_idct32x32_add(dqcoeff, dst, stride, eob); break; default: assert(0 && "Invalid transform size"); return; } } }#else if (xd->lossless) { vp9_iwht4x4_add(dqcoeff, dst, stride, eob); } else { switch (tx_size) { case TX_4X4: vp9_iht4x4_add(tx_type, dqcoeff, dst, stride, eob); break; case TX_8X8: vp9_iht8x8_add(tx_type, dqcoeff, dst, stride, eob); break; case TX_16X16: vp9_iht16x16_add(tx_type, dqcoeff, dst, stride, eob); break; case TX_32X32: vp9_idct32x32_add(dqcoeff, dst, stride, eob); break; default: assert(0 && "Invalid transform size"); return; } }#endif // CONFIG_VP9_HIGHBITDEPTH if (eob == 1) { dqcoeff[0] = 0; } else { if (tx_type == DCT_DCT && tx_size <= TX_16X16 && eob <= 10) memset(dqcoeff, 0, 4 * (4 << tx_size) * sizeof(dqcoeff[0])); else if (tx_size == TX_32X32 && eob <= 34) memset(dqcoeff, 0, 256 * sizeof(dqcoeff[0])); else memset(dqcoeff, 0, (16 << (tx_size << 1)) * sizeof(dqcoeff[0])); }} static void predict_and_reconstruct_intra_block(TileWorkerData *twd, MODE_INFO *const mi, int plane, int row, int col, TX_SIZE tx_size) { MACROBLOCKD *const xd = &twd->xd; struct macroblockd_plane *const pd = &xd->plane[plane]; PREDICTION_MODE mode = (plane == 0) ? mi->mode : mi->uv_mode; uint8_t *dst; dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col]; if (mi->sb_type < BLOCK_8X8) if (plane == 0) mode = xd->mi[0]->bmi[(row << 1) + col].as_mode; vp9_predict_intra_block(xd, pd->n4_wl, tx_size, mode, dst, pd->dst.stride, dst, pd->dst.stride, col, row, plane); if (!mi->skip) { const TX_TYPE tx_type = (plane || xd->lossless) ? DCT_DCT : intra_mode_to_tx_type_lookup[mode]; const scan_order *sc = (plane || xd->lossless) ? &vp9_default_scan_orders[tx_size] : &vp9_scan_orders[tx_size][tx_type]; const int eob = vp9_decode_block_tokens(twd, plane, sc, col, row, tx_size, mi->segment_id); if (eob > 0) { inverse_transform_block_intra(xd, plane, tx_type, tx_size, dst, pd->dst.stride, eob); } }} static void parse_intra_block_row_mt(TileWorkerData *twd, MODE_INFO *const mi, int plane, int row, int col, TX_SIZE tx_size) { MACROBLOCKD *const xd = &twd->xd; PREDICTION_MODE mode = (plane == 0) ? mi->mode : mi->uv_mode; if (mi->sb_type < BLOCK_8X8) if (plane == 0) mode = xd->mi[0]->bmi[(row << 1) + col].as_mode; if (!mi->skip) { struct macroblockd_plane *const pd = &xd->plane[plane]; const TX_TYPE tx_type = (plane || xd->lossless) ? DCT_DCT : intra_mode_to_tx_type_lookup[mode]; const scan_order *sc = (plane || xd->lossless) ? &vp9_default_scan_orders[tx_size] : &vp9_scan_orders[tx_size][tx_type]; *pd->eob = vp9_decode_block_tokens(twd, plane, sc, col, row, tx_size, mi->segment_id); /* Keep the alignment to 16 */ pd->dqcoeff += (16 << (tx_size << 1)); pd->eob++; }} static void predict_and_reconstruct_intra_block_row_mt(TileWorkerData *twd, MODE_INFO *const mi, int plane, int row, int col, TX_SIZE tx_size) { MACROBLOCKD *const xd = &twd->xd; struct macroblockd_plane *const pd = &xd->plane[plane]; PREDICTION_MODE mode = (plane == 0) ? mi->mode : mi->uv_mode; uint8_t *dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col]; if (mi->sb_type < BLOCK_8X8) if (plane == 0) mode = xd->mi[0]->bmi[(row << 1) + col].as_mode; vp9_predict_intra_block(xd, pd->n4_wl, tx_size, mode, dst, pd->dst.stride, dst, pd->dst.stride, col, row, plane); if (!mi->skip) { const TX_TYPE tx_type = (plane || xd->lossless) ? DCT_DCT : intra_mode_to_tx_type_lookup[mode]; if (*pd->eob > 0) { inverse_transform_block_intra(xd, plane, tx_type, tx_size, dst, pd->dst.stride, *pd->eob); } /* Keep the alignment to 16 */ pd->dqcoeff += (16 << (tx_size << 1)); pd->eob++; }} static int reconstruct_inter_block(TileWorkerData *twd, MODE_INFO *const mi, int plane, int row, int col, TX_SIZE tx_size, int mi_row, int mi_col) { MACROBLOCKD *const xd = &twd->xd; struct macroblockd_plane *const pd = &xd->plane[plane]; const scan_order *sc = &vp9_default_scan_orders[tx_size]; const int eob = vp9_decode_block_tokens(twd, plane, sc, col, row, tx_size, mi->segment_id); uint8_t *dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col]; if (eob > 0) { inverse_transform_block_inter(xd, plane, tx_size, dst, pd->dst.stride, eob); }#if CONFIG_MISMATCH_DEBUG { int pixel_c, pixel_r; int blk_w = 1 << (tx_size + TX_UNIT_SIZE_LOG2); int blk_h = 1 << (tx_size + TX_UNIT_SIZE_LOG2); mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, col, row, pd->subsampling_x, pd->subsampling_y); mismatch_check_block_tx(dst, pd->dst.stride, plane, pixel_c, pixel_r, blk_w, blk_h, xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH); }#else (void)mi_row; (void)mi_col;#endif return eob;} static int parse_inter_block_row_mt(TileWorkerData *twd, MODE_INFO *const mi, int plane, int row, int col, TX_SIZE tx_size) { MACROBLOCKD *const xd = &twd->xd; struct macroblockd_plane *const pd = &xd->plane[plane]; const scan_order *sc = &vp9_default_scan_orders[tx_size]; const int eob = vp9_decode_block_tokens(twd, plane, sc, col, row, tx_size, mi->segment_id); *pd->eob = eob; pd->dqcoeff += (16 << (tx_size << 1)); pd->eob++; return eob;} static int reconstruct_inter_block_row_mt(TileWorkerData *twd, MODE_INFO *const mi, int plane, int row, int col, TX_SIZE tx_size) { MACROBLOCKD *const xd = &twd->xd; struct macroblockd_plane *const pd = &xd->plane[plane]; const int eob = *pd->eob; (void)mi; if (eob > 0) { inverse_transform_block_inter( xd, plane, tx_size, &pd->dst.buf[4 * row * pd->dst.stride + 4 * col], pd->dst.stride, eob); } pd->dqcoeff += (16 << (tx_size << 1)); pd->eob++; return eob;} static void build_mc_border(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int x, int y, int b_w, int b_h, int w, int h) { // Get a pointer to the start of the real data for this row. const uint8_t *ref_row = src - x - y * src_stride; if (y >= h) ref_row += (h - 1) * src_stride; else if (y > 0) ref_row += y * src_stride; do { int right = 0, copy; int left = x < 0 ? -x : 0; if (left > b_w) left = b_w; if (x + b_w > w) right = x + b_w - w; if (right > b_w) right = b_w; copy = b_w - left - right; if (left) memset(dst, ref_row[0], left); if (copy) memcpy(dst + left, ref_row + x + left, copy); if (right) memset(dst + left + copy, ref_row[w - 1], right); dst += dst_stride; ++y; if (y > 0 && y < h) ref_row += src_stride; } while (--b_h);} #if CONFIG_VP9_HIGHBITDEPTHstatic void high_build_mc_border(const uint8_t *src8, int src_stride, uint16_t *dst, int dst_stride, int x, int y, int b_w, int b_h, int w, int h) { // Get a pointer to the start of the real data for this row. const uint16_t *src = CONVERT_TO_SHORTPTR(src8); const uint16_t *ref_row = src - x - y * src_stride; if (y >= h)Lines 1–500 of 3057. Load more
/* * Copyright (c) 2010 The WebM project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include <assert.h> #include <stdlib.h> // qsort() #include "./vp9_rtcd.h" #include "./vpx_dsp_rtcd.h" #include "./vpx_scale_rtcd.h" #include "vpx_dsp/bitreader_buffer.h" #include "vpx_dsp/bitreader.h" #include "vpx_dsp/vpx_dsp_common.h" #include "vpx_mem/vpx_mem.h" #include "vpx_ports/mem.h" #include "vpx_ports/mem_ops.h" #include "vpx_scale/vpx_scale.h" #include "vpx_util/vpx_thread.h" #if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG #include "vpx_util/vpx_debug_util.h" #endif // CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG #include "vp9/common/vp9_alloccommon.h" #include "vp9/common/vp9_common.h" #include "vp9/common/vp9_entropy.h" #include "vp9/common/vp9_entropymode.h" #include "vp9/common/vp9_idct.h" #include "vp9/common/vp9_thread_common.h" #include "vp9/common/vp9_pred_common.h" #include "vp9/common/vp9_quant_common.h" #include "vp9/common/vp9_reconintra.h" #include "vp9/common/vp9_reconinter.h" #include "vp9/common/vp9_seg_common.h" #include "vp9/common/vp9_tile_common.h" #include "vp9/decoder/vp9_decodeframe.h" #include "vp9/decoder/vp9_detokenize.h" #include "vp9/decoder/vp9_decodemv.h" #include "vp9/decoder/vp9_decoder.h" #include "vp9/decoder/vp9_dsubexp.h" #include "vp9/decoder/vp9_job_queue.h" #define MAX_VP9_HEADER_SIZE 80 typedef int (*predict_recon_func)(TileWorkerData *twd, MODE_INFO *const mi, int plane, int row, int col, TX_SIZE tx_size); typedef void (*intra_recon_func)(TileWorkerData *twd, MODE_INFO *const mi, int plane, int row, int col, TX_SIZE tx_size); static int read_is_valid(const uint8_t *start, size_t len, const uint8_t *end) { return len != 0 && len <= (size_t)(end - start); } static int decode_unsigned_max(struct vpx_read_bit_buffer *rb, int max) { const int data = vpx_rb_read_literal(rb, get_unsigned_bits(max)); return data > max ? max : data; } static TX_MODE read_tx_mode(vpx_reader *r) { TX_MODE tx_mode = vpx_read_literal(r, 2); if (tx_mode == ALLOW_32X32) tx_mode += vpx_read_bit(r); return tx_mode; } static void read_tx_mode_probs(struct tx_probs *tx_probs, vpx_reader *r) { int i, j; for (i = 0; i < TX_SIZE_CONTEXTS; ++i) for (j = 0; j < TX_SIZES - 3; ++j) vp9_diff_update_prob(r, &tx_probs->p8x8[i][j]); for (i = 0; i < TX_SIZE_CONTEXTS; ++i) for (j = 0; j < TX_SIZES - 2; ++j) vp9_diff_update_prob(r, &tx_probs->p16x16[i][j]); for (i = 0; i < TX_SIZE_CONTEXTS; ++i) for (j = 0; j < TX_SIZES - 1; ++j) vp9_diff_update_prob(r, &tx_probs->p32x32[i][j]); } static void read_switchable_interp_probs(FRAME_CONTEXT *fc, vpx_reader *r) { int i, j; for (j = 0; j < SWITCHABLE_FILTER_CONTEXTS; ++j) for (i = 0; i < SWITCHABLE_FILTERS - 1; ++i) vp9_diff_update_prob(r, &fc->switchable_interp_prob[j][i]); } static void read_inter_mode_probs(FRAME_CONTEXT *fc, vpx_reader *r) { int i, j; for (i = 0; i < INTER_MODE_CONTEXTS; ++i) for (j = 0; j < INTER_MODES - 1; ++j) vp9_diff_update_prob(r, &fc->inter_mode_probs[i][j]); } static REFERENCE_MODE read_frame_reference_mode(const VP9_COMMON *cm, vpx_reader *r) { if (vp9_compound_reference_allowed(cm)) { return vpx_read_bit(r) ? (vpx_read_bit(r) ? REFERENCE_MODE_SELECT : COMPOUND_REFERENCE) : SINGLE_REFERENCE; } else { return SINGLE_REFERENCE; } } static void read_frame_reference_mode_probs(VP9_COMMON *cm, vpx_reader *r) { FRAME_CONTEXT *const fc = cm->fc; int i; if (cm->reference_mode == REFERENCE_MODE_SELECT) for (i = 0; i < COMP_INTER_CONTEXTS; ++i) vp9_diff_update_prob(r, &fc->comp_inter_prob[i]); if (cm->reference_mode != COMPOUND_REFERENCE) for (i = 0; i < REF_CONTEXTS; ++i) { vp9_diff_update_prob(r, &fc->single_ref_prob[i][0]); vp9_diff_update_prob(r, &fc->single_ref_prob[i][1]); } if (cm->reference_mode != SINGLE_REFERENCE) for (i = 0; i < REF_CONTEXTS; ++i) vp9_diff_update_prob(r, &fc->comp_ref_prob[i]); } static void update_mv_probs(vpx_prob *p, int n, vpx_reader *r) { int i; for (i = 0; i < n; ++i) if (vpx_read(r, MV_UPDATE_PROB)) p[i] = (vpx_read_literal(r, 7) << 1) | 1; } static void read_mv_probs(nmv_context *ctx, int allow_hp, vpx_reader *r) { int i, j; update_mv_probs(ctx->joints, MV_JOINTS - 1, r); for (i = 0; i < 2; ++i) { nmv_component *const comp_ctx = &ctx->comps[i]; update_mv_probs(&comp_ctx->sign, 1, r); update_mv_probs(comp_ctx->classes, MV_CLASSES - 1, r); update_mv_probs(comp_ctx->class0, CLASS0_SIZE - 1, r); update_mv_probs(comp_ctx->bits, MV_OFFSET_BITS, r); } for (i = 0; i < 2; ++i) { nmv_component *const comp_ctx = &ctx->comps[i]; for (j = 0; j < CLASS0_SIZE; ++j) update_mv_probs(comp_ctx->class0_fp[j], MV_FP_SIZE - 1, r); update_mv_probs(comp_ctx->fp, 3, r); } if (allow_hp) { for (i = 0; i < 2; ++i) { nmv_component *const comp_ctx = &ctx->comps[i]; update_mv_probs(&comp_ctx->class0_hp, 1, r); update_mv_probs(&comp_ctx->hp, 1, r); } } } static void inverse_transform_block_inter(MACROBLOCKD *xd, int plane, const TX_SIZE tx_size, uint8_t *dst, int stride, int eob) { struct macroblockd_plane *const pd = &xd->plane[plane]; tran_low_t *const dqcoeff = pd->dqcoeff; assert(eob > 0); #if CONFIG_VP9_HIGHBITDEPTH if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { uint16_t *const dst16 = CONVERT_TO_SHORTPTR(dst); if (xd->lossless) { vp9_highbd_iwht4x4_add(dqcoeff, dst16, stride, eob, xd->bd); } else { switch (tx_size) { case TX_4X4: vp9_highbd_idct4x4_add(dqcoeff, dst16, stride, eob, xd->bd); break; case TX_8X8: vp9_highbd_idct8x8_add(dqcoeff, dst16, stride, eob, xd->bd); break; case TX_16X16: vp9_highbd_idct16x16_add(dqcoeff, dst16, stride, eob, xd->bd); break; case TX_32X32: vp9_highbd_idct32x32_add(dqcoeff, dst16, stride, eob, xd->bd); break; default: assert(0 && "Invalid transform size"); } } } else { if (xd->lossless) { vp9_iwht4x4_add(dqcoeff, dst, stride, eob); } else { switch (tx_size) { case TX_4X4: vp9_idct4x4_add(dqcoeff, dst, stride, eob); break; case TX_8X8: vp9_idct8x8_add(dqcoeff, dst, stride, eob); break; case TX_16X16: vp9_idct16x16_add(dqcoeff, dst, stride, eob); break; case TX_32X32: vp9_idct32x32_add(dqcoeff, dst, stride, eob); break; default: assert(0 && "Invalid transform size"); return; } } } #else if (xd->lossless) { vp9_iwht4x4_add(dqcoeff, dst, stride, eob); } else { switch (tx_size) { case TX_4X4: vp9_idct4x4_add(dqcoeff, dst, stride, eob); break; case TX_8X8: vp9_idct8x8_add(dqcoeff, dst, stride, eob); break; case TX_16X16: vp9_idct16x16_add(dqcoeff, dst, stride, eob); break; case TX_32X32: vp9_idct32x32_add(dqcoeff, dst, stride, eob); break; default: assert(0 && "Invalid transform size"); return; } } #endif // CONFIG_VP9_HIGHBITDEPTH if (eob == 1) { dqcoeff[0] = 0; } else { if (tx_size <= TX_16X16 && eob <= 10) memset(dqcoeff, 0, 4 * (4 << tx_size) * sizeof(dqcoeff[0])); else if (tx_size == TX_32X32 && eob <= 34) memset(dqcoeff, 0, 256 * sizeof(dqcoeff[0])); else memset(dqcoeff, 0, (16 << (tx_size << 1)) * sizeof(dqcoeff[0])); } } static void inverse_transform_block_intra(MACROBLOCKD *xd, int plane, const TX_TYPE tx_type, const TX_SIZE tx_size, uint8_t *dst, int stride, int eob) { struct macroblockd_plane *const pd = &xd->plane[plane]; tran_low_t *const dqcoeff = pd->dqcoeff; assert(eob > 0); #if CONFIG_VP9_HIGHBITDEPTH if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { uint16_t *const dst16 = CONVERT_TO_SHORTPTR(dst); if (xd->lossless) { vp9_highbd_iwht4x4_add(dqcoeff, dst16, stride, eob, xd->bd); } else { switch (tx_size) { case TX_4X4: vp9_highbd_iht4x4_add(tx_type, dqcoeff, dst16, stride, eob, xd->bd); break; case TX_8X8: vp9_highbd_iht8x8_add(tx_type, dqcoeff, dst16, stride, eob, xd->bd); break; case TX_16X16: vp9_highbd_iht16x16_add(tx_type, dqcoeff, dst16, stride, eob, xd->bd); break; case TX_32X32: vp9_highbd_idct32x32_add(dqcoeff, dst16, stride, eob, xd->bd); break; default: assert(0 && "Invalid transform size"); } } } else { if (xd->lossless) { vp9_iwht4x4_add(dqcoeff, dst, stride, eob); } else { switch (tx_size) { case TX_4X4: vp9_iht4x4_add(tx_type, dqcoeff, dst, stride, eob); break; case TX_8X8: vp9_iht8x8_add(tx_type, dqcoeff, dst, stride, eob); break; case TX_16X16: vp9_iht16x16_add(tx_type, dqcoeff, dst, stride, eob); break; case TX_32X32: vp9_idct32x32_add(dqcoeff, dst, stride, eob); break; default: assert(0 && "Invalid transform size"); return; } } } #else if (xd->lossless) { vp9_iwht4x4_add(dqcoeff, dst, stride, eob); } else { switch (tx_size) { case TX_4X4: vp9_iht4x4_add(tx_type, dqcoeff, dst, stride, eob); break; case TX_8X8: vp9_iht8x8_add(tx_type, dqcoeff, dst, stride, eob); break; case TX_16X16: vp9_iht16x16_add(tx_type, dqcoeff, dst, stride, eob); break; case TX_32X32: vp9_idct32x32_add(dqcoeff, dst, stride, eob); break; default: assert(0 && "Invalid transform size"); return; } } #endif // CONFIG_VP9_HIGHBITDEPTH if (eob == 1) { dqcoeff[0] = 0; } else { if (tx_type == DCT_DCT && tx_size <= TX_16X16 && eob <= 10) memset(dqcoeff, 0, 4 * (4 << tx_size) * sizeof(dqcoeff[0])); else if (tx_size == TX_32X32 && eob <= 34) memset(dqcoeff, 0, 256 * sizeof(dqcoeff[0])); else memset(dqcoeff, 0, (16 << (tx_size << 1)) * sizeof(dqcoeff[0])); } } static void predict_and_reconstruct_intra_block(TileWorkerData *twd, MODE_INFO *const mi, int plane, int row, int col, TX_SIZE tx_size) { MACROBLOCKD *const xd = &twd->xd; struct macroblockd_plane *const pd = &xd->plane[plane]; PREDICTION_MODE mode = (plane == 0) ? mi->mode : mi->uv_mode; uint8_t *dst; dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col]; if (mi->sb_type < BLOCK_8X8) if (plane == 0) mode = xd->mi[0]->bmi[(row << 1) + col].as_mode; vp9_predict_intra_block(xd, pd->n4_wl, tx_size, mode, dst, pd->dst.stride, dst, pd->dst.stride, col, row, plane); if (!mi->skip) { const TX_TYPE tx_type = (plane || xd->lossless) ? DCT_DCT : intra_mode_to_tx_type_lookup[mode]; const scan_order *sc = (plane || xd->lossless) ? &vp9_default_scan_orders[tx_size] : &vp9_scan_orders[tx_size][tx_type]; const int eob = vp9_decode_block_tokens(twd, plane, sc, col, row, tx_size, mi->segment_id); if (eob > 0) { inverse_transform_block_intra(xd, plane, tx_type, tx_size, dst, pd->dst.stride, eob); } } } static void parse_intra_block_row_mt(TileWorkerData *twd, MODE_INFO *const mi, int plane, int row, int col, TX_SIZE tx_size) { MACROBLOCKD *const xd = &twd->xd; PREDICTION_MODE mode = (plane == 0) ? mi->mode : mi->uv_mode; if (mi->sb_type < BLOCK_8X8) if (plane == 0) mode = xd->mi[0]->bmi[(row << 1) + col].as_mode; if (!mi->skip) { struct macroblockd_plane *const pd = &xd->plane[plane]; const TX_TYPE tx_type = (plane || xd->lossless) ? DCT_DCT : intra_mode_to_tx_type_lookup[mode]; const scan_order *sc = (plane || xd->lossless) ? &vp9_default_scan_orders[tx_size] : &vp9_scan_orders[tx_size][tx_type]; *pd->eob = vp9_decode_block_tokens(twd, plane, sc, col, row, tx_size, mi->segment_id); /* Keep the alignment to 16 */ pd->dqcoeff += (16 << (tx_size << 1)); pd->eob++; } } static void predict_and_reconstruct_intra_block_row_mt(TileWorkerData *twd, MODE_INFO *const mi, int plane, int row, int col, TX_SIZE tx_size) { MACROBLOCKD *const xd = &twd->xd; struct macroblockd_plane *const pd = &xd->plane[plane]; PREDICTION_MODE mode = (plane == 0) ? mi->mode : mi->uv_mode; uint8_t *dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col]; if (mi->sb_type < BLOCK_8X8) if (plane == 0) mode = xd->mi[0]->bmi[(row << 1) + col].as_mode; vp9_predict_intra_block(xd, pd->n4_wl, tx_size, mode, dst, pd->dst.stride, dst, pd->dst.stride, col, row, plane); if (!mi->skip) { const TX_TYPE tx_type = (plane || xd->lossless) ? DCT_DCT : intra_mode_to_tx_type_lookup[mode]; if (*pd->eob > 0) { inverse_transform_block_intra(xd, plane, tx_type, tx_size, dst, pd->dst.stride, *pd->eob); } /* Keep the alignment to 16 */ pd->dqcoeff += (16 << (tx_size << 1)); pd->eob++; } } static int reconstruct_inter_block(TileWorkerData *twd, MODE_INFO *const mi, int plane, int row, int col, TX_SIZE tx_size, int mi_row, int mi_col) { MACROBLOCKD *const xd = &twd->xd; struct macroblockd_plane *const pd = &xd->plane[plane]; const scan_order *sc = &vp9_default_scan_orders[tx_size]; const int eob = vp9_decode_block_tokens(twd, plane, sc, col, row, tx_size, mi->segment_id); uint8_t *dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col]; if (eob > 0) { inverse_transform_block_inter(xd, plane, tx_size, dst, pd->dst.stride, eob); } #if CONFIG_MISMATCH_DEBUG { int pixel_c, pixel_r; int blk_w = 1 << (tx_size + TX_UNIT_SIZE_LOG2); int blk_h = 1 << (tx_size + TX_UNIT_SIZE_LOG2); mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, col, row, pd->subsampling_x, pd->subsampling_y); mismatch_check_block_tx(dst, pd->dst.stride, plane, pixel_c, pixel_r, blk_w, blk_h, xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH); } #else (void)mi_row; (void)mi_col; #endif return eob; } static int parse_inter_block_row_mt(TileWorkerData *twd, MODE_INFO *const mi, int plane, int row, int col, TX_SIZE tx_size) { MACROBLOCKD *const xd = &twd->xd; struct macroblockd_plane *const pd = &xd->plane[plane]; const scan_order *sc = &vp9_default_scan_orders[tx_size]; const int eob = vp9_decode_block_tokens(twd, plane, sc, col, row, tx_size, mi->segment_id); *pd->eob = eob; pd->dqcoeff += (16 << (tx_size << 1)); pd->eob++; return eob; } static int reconstruct_inter_block_row_mt(TileWorkerData *twd, MODE_INFO *const mi, int plane, int row, int col, TX_SIZE tx_size) { MACROBLOCKD *const xd = &twd->xd; struct macroblockd_plane *const pd = &xd->plane[plane]; const int eob = *pd->eob; (void)mi; if (eob > 0) { inverse_transform_block_inter( xd, plane, tx_size, &pd->dst.buf[4 * row * pd->dst.stride + 4 * col], pd->dst.stride, eob); } pd->dqcoeff += (16 << (tx_size << 1)); pd->eob++; return eob; } static void build_mc_border(const uint8_t *src, int src_stride, uint8_t *dst, int dst_stride, int x, int y, int b_w, int b_h, int w, int h) { // Get a pointer to the start of the real data for this row. const uint8_t *ref_row = src - x - y * src_stride; if (y >= h) ref_row += (h - 1) * src_stride; else if (y > 0) ref_row += y * src_stride; do { int right = 0, copy; int left = x < 0 ? -x : 0; if (left > b_w) left = b_w; if (x + b_w > w) right = x + b_w - w; if (right > b_w) right = b_w; copy = b_w - left - right; if (left) memset(dst, ref_row[0], left); if (copy) memcpy(dst + left, ref_row + x + left, copy); if (right) memset(dst + left + copy, ref_row[w - 1], right); dst += dst_stride; ++y; if (y > 0 && y < h) ref_row += src_stride; } while (--b_h); } #if CONFIG_VP9_HIGHBITDEPTH static void high_build_mc_border(const uint8_t *src8, int src_stride, uint16_t *dst, int dst_stride, int x, int y, int b_w, int b_h, int w, int h) { // Get a pointer to the start of the real data for this row. const uint16_t *src = CONVERT_TO_SHORTPTR(src8); const uint16_t *ref_row = src - x - y * src_stride; if (y >= h)