3057 lines · 112.0 KB · C
RawDownload
/* *  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.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t