1257 lines · 40.1 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 "vpx_config.h"#include "vp8_rtcd.h"#include "./vpx_scale_rtcd.h"#include "onyxd_int.h"#include "vp8/common/header.h"#include "vp8/common/reconintra4x4.h"#include "vp8/common/reconinter.h"#include "detokenize.h"#include "vp8/common/common.h"#include "vp8/common/invtrans.h"#include "vp8/common/alloccommon.h"#include "vp8/common/entropymode.h"#include "vp8/common/quant_common.h"#include "vpx_scale/vpx_scale.h"#include "vp8/common/reconintra.h"#include "vp8/common/setupintrarecon.h" #include "decodemv.h"#include "vp8/common/extend.h"#if CONFIG_ERROR_CONCEALMENT#include "error_concealment.h"#endif#include "vpx_mem/vpx_mem.h"#include "vp8/common/threading.h"#include "decoderthreading.h"#include "dboolhuff.h"#include "vpx_dsp/vpx_dsp_common.h" #include <assert.h>#include <stdio.h> void vp8cx_init_de_quantizer(VP8D_COMP *pbi) {  int Q;  VP8_COMMON *const pc = &pbi->common;   for (Q = 0; Q < QINDEX_RANGE; ++Q) {    pc->Y1dequant[Q][0] = (short)vp8_dc_quant(Q, pc->y1dc_delta_q);    pc->Y2dequant[Q][0] = (short)vp8_dc2quant(Q, pc->y2dc_delta_q);    pc->UVdequant[Q][0] = (short)vp8_dc_uv_quant(Q, pc->uvdc_delta_q);     pc->Y1dequant[Q][1] = (short)vp8_ac_yquant(Q);    pc->Y2dequant[Q][1] = (short)vp8_ac2quant(Q, pc->y2ac_delta_q);    pc->UVdequant[Q][1] = (short)vp8_ac_uv_quant(Q, pc->uvac_delta_q);  }} void vp8_mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd) {  int i;  int QIndex;  MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;  VP8_COMMON *const pc = &pbi->common;   /* Decide whether to use the default or alternate baseline Q value. */  if (xd->segmentation_enabled) {    /* Abs Value */    if (xd->mb_segement_abs_delta == SEGMENT_ABSDATA) {      QIndex = xd->segment_feature_data[MB_LVL_ALT_Q][mbmi->segment_id];       /* Delta Value */    } else {      QIndex = pc->base_qindex +               xd->segment_feature_data[MB_LVL_ALT_Q][mbmi->segment_id];    }     QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ)                           : 0; /* Clamp to valid range */  } else {    QIndex = pc->base_qindex;  }   /* Set up the macroblock dequant constants */  xd->dequant_y1_dc[0] = 1;  xd->dequant_y1[0] = pc->Y1dequant[QIndex][0];  xd->dequant_y2[0] = pc->Y2dequant[QIndex][0];  xd->dequant_uv[0] = pc->UVdequant[QIndex][0];   for (i = 1; i < 16; ++i) {    xd->dequant_y1_dc[i] = xd->dequant_y1[i] = pc->Y1dequant[QIndex][1];    xd->dequant_y2[i] = pc->Y2dequant[QIndex][1];    xd->dequant_uv[i] = pc->UVdequant[QIndex][1];  }} static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,                              unsigned int mb_idx) {  MB_PREDICTION_MODE mode;  int i;#if CONFIG_ERROR_CONCEALMENT  int corruption_detected = 0;#else  (void)mb_idx;#endif   if (xd->mode_info_context->mbmi.mb_skip_coeff) {    vp8_reset_mb_tokens_context(xd);  } else if (!vp8dx_bool_error(xd->current_bc)) {    int eobtotal;    eobtotal = vp8_decode_mb_tokens(pbi, xd);     /* Special case:  Force the loopfilter to skip when eobtotal is zero */    xd->mode_info_context->mbmi.mb_skip_coeff = (eobtotal == 0);  }   mode = xd->mode_info_context->mbmi.mode;   if (xd->segmentation_enabled) vp8_mb_init_dequantizer(pbi, xd); #if CONFIG_ERROR_CONCEALMENT   if (pbi->ec_active) {    int throw_residual;    /* When we have independent partitions we can apply residual even     * though other partitions within the frame are corrupt.     */    throw_residual =        (!pbi->independent_partitions && pbi->frame_corrupt_residual);    throw_residual = (throw_residual || vp8dx_bool_error(xd->current_bc));     if ((mb_idx >= pbi->mvs_corrupt_from_mb || throw_residual)) {      /* MB with corrupt residuals or corrupt mode/motion vectors.       * Better to use the predictor as reconstruction.       */      pbi->frame_corrupt_residual = 1;      memset(xd->qcoeff, 0, sizeof(xd->qcoeff));       corruption_detected = 1;       /* force idct to be skipped for B_PRED and use the       * prediction only for reconstruction       * */      memset(xd->eobs, 0, 25);    }  }#endif   /* do prediction */  if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {    vp8_build_intra_predictors_mbuv_s(        xd, xd->recon_above[1], xd->recon_above[2], xd->recon_left[1],        xd->recon_left[2], xd->recon_left_stride[1], xd->dst.u_buffer,        xd->dst.v_buffer, xd->dst.uv_stride);     if (mode != B_PRED) {      vp8_build_intra_predictors_mby_s(          xd, xd->recon_above[0], xd->recon_left[0], xd->recon_left_stride[0],          xd->dst.y_buffer, xd->dst.y_stride);    } else {      short *DQC = xd->dequant_y1;      int dst_stride = xd->dst.y_stride;       /* clear out residual eob info */      if (xd->mode_info_context->mbmi.mb_skip_coeff) memset(xd->eobs, 0, 25);       intra_prediction_down_copy(xd, xd->recon_above[0] + 16);       for (i = 0; i < 16; ++i) {        BLOCKD *b = &xd->block[i];        unsigned char *dst = xd->dst.y_buffer + b->offset;        B_PREDICTION_MODE b_mode = xd->mode_info_context->bmi[i].as_mode;        unsigned char *Above = dst - dst_stride;        unsigned char *yleft = dst - 1;        int left_stride = dst_stride;        unsigned char top_left = Above[-1];         vp8_intra4x4_predict(Above, yleft, left_stride, b_mode, dst, dst_stride,                             top_left);         if (xd->eobs[i]) {          if (xd->eobs[i] > 1) {            vp8_dequant_idct_add(b->qcoeff, DQC, dst, dst_stride);          } else {            vp8_dc_only_idct_add(b->qcoeff[0] * DQC[0], dst, dst_stride, dst,                                 dst_stride);            memset(b->qcoeff, 0, 2 * sizeof(b->qcoeff[0]));          }        }      }    }  } else {    vp8_build_inter_predictors_mb(xd);  } #if CONFIG_ERROR_CONCEALMENT  if (corruption_detected) {    return;  }#endif   if (!xd->mode_info_context->mbmi.mb_skip_coeff) {    /* dequantization and idct */    if (mode != B_PRED) {      short *DQC = xd->dequant_y1;       if (mode != SPLITMV) {        BLOCKD *b = &xd->block[24];         /* do 2nd order transform on the dc block */        if (xd->eobs[24] > 1) {          vp8_dequantize_b(b, xd->dequant_y2);           vp8_short_inv_walsh4x4(&b->dqcoeff[0], xd->qcoeff);          memset(b->qcoeff, 0, 16 * sizeof(b->qcoeff[0]));        } else {          b->dqcoeff[0] = b->qcoeff[0] * xd->dequant_y2[0];          vp8_short_inv_walsh4x4_1(&b->dqcoeff[0], xd->qcoeff);          memset(b->qcoeff, 0, 2 * sizeof(b->qcoeff[0]));        }         /* override the dc dequant constant in order to preserve the         * dc components         */        DQC = xd->dequant_y1_dc;      }       vp8_dequant_idct_add_y_block(xd->qcoeff, DQC, xd->dst.y_buffer,                                   xd->dst.y_stride, xd->eobs);    }     vp8_dequant_idct_add_uv_block(xd->qcoeff + 16 * 16, xd->dequant_uv,                                  xd->dst.u_buffer, xd->dst.v_buffer,                                  xd->dst.uv_stride, xd->eobs + 16);  }} static int get_delta_q(vp8_reader *bc, int prev, int *q_update) {  int ret_val = 0;   if (vp8_read_bit(bc)) {    ret_val = vp8_read_literal(bc, 4);     if (vp8_read_bit(bc)) ret_val = -ret_val;  }   /* Trigger a quantizer update if the delta-q value has changed */  if (ret_val != prev) *q_update = 1;   return ret_val;} #ifdef PACKET_TESTING#include <stdio.h>FILE *vpxlog = 0;#endif static void yv12_extend_frame_top_c(YV12_BUFFER_CONFIG *ybf) {  int i;  unsigned char *src_ptr1;  unsigned char *dest_ptr1;   unsigned int Border;  int plane_stride;   /***********/  /* Y Plane */  /***********/  Border = ybf->border;  plane_stride = ybf->y_stride;  src_ptr1 = ybf->y_buffer - Border;  dest_ptr1 = src_ptr1 - (Border * plane_stride);   for (i = 0; i < (int)Border; ++i) {    memcpy(dest_ptr1, src_ptr1, plane_stride);    dest_ptr1 += plane_stride;  }   /***********/  /* U Plane */  /***********/  plane_stride = ybf->uv_stride;  Border /= 2;  src_ptr1 = ybf->u_buffer - Border;  dest_ptr1 = src_ptr1 - (Border * plane_stride);   for (i = 0; i < (int)(Border); ++i) {    memcpy(dest_ptr1, src_ptr1, plane_stride);    dest_ptr1 += plane_stride;  }   /***********/  /* V Plane */  /***********/   src_ptr1 = ybf->v_buffer - Border;  dest_ptr1 = src_ptr1 - (Border * plane_stride);   for (i = 0; i < (int)(Border); ++i) {    memcpy(dest_ptr1, src_ptr1, plane_stride);    dest_ptr1 += plane_stride;  }} static void yv12_extend_frame_bottom_c(YV12_BUFFER_CONFIG *ybf) {  int i;  unsigned char *src_ptr1, *src_ptr2;  unsigned char *dest_ptr2;   unsigned int Border;  int plane_stride;  int plane_height;   /***********/  /* Y Plane */  /***********/  Border = ybf->border;  plane_stride = ybf->y_stride;  plane_height = ybf->y_height;   src_ptr1 = ybf->y_buffer - Border;  src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;  dest_ptr2 = src_ptr2 + plane_stride;   for (i = 0; i < (int)Border; ++i) {    memcpy(dest_ptr2, src_ptr2, plane_stride);    dest_ptr2 += plane_stride;  }   /***********/  /* U Plane */  /***********/  plane_stride = ybf->uv_stride;  plane_height = ybf->uv_height;  Border /= 2;   src_ptr1 = ybf->u_buffer - Border;  src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;  dest_ptr2 = src_ptr2 + plane_stride;   for (i = 0; i < (int)(Border); ++i) {    memcpy(dest_ptr2, src_ptr2, plane_stride);    dest_ptr2 += plane_stride;  }   /***********/  /* V Plane */  /***********/   src_ptr1 = ybf->v_buffer - Border;  src_ptr2 = src_ptr1 + (plane_height * plane_stride) - plane_stride;  dest_ptr2 = src_ptr2 + plane_stride;   for (i = 0; i < (int)(Border); ++i) {    memcpy(dest_ptr2, src_ptr2, plane_stride);    dest_ptr2 += plane_stride;  }} static void yv12_extend_frame_left_right_c(YV12_BUFFER_CONFIG *ybf,                                           unsigned char *y_src,                                           unsigned char *u_src,                                           unsigned char *v_src) {  int i;  unsigned char *src_ptr1, *src_ptr2;  unsigned char *dest_ptr1, *dest_ptr2;   unsigned int Border;  int plane_stride;  int plane_height;  int plane_width;   /***********/  /* Y Plane */  /***********/  Border = ybf->border;  plane_stride = ybf->y_stride;  plane_height = 16;  plane_width = ybf->y_width;   /* copy the left and right most columns out */  src_ptr1 = y_src;  src_ptr2 = src_ptr1 + plane_width - 1;  dest_ptr1 = src_ptr1 - Border;  dest_ptr2 = src_ptr2 + 1;   for (i = 0; i < plane_height; ++i) {    memset(dest_ptr1, src_ptr1[0], Border);    memset(dest_ptr2, src_ptr2[0], Border);    src_ptr1 += plane_stride;    src_ptr2 += plane_stride;    dest_ptr1 += plane_stride;    dest_ptr2 += plane_stride;  }   /***********/  /* U Plane */  /***********/  plane_stride = ybf->uv_stride;  plane_height = 8;  plane_width = ybf->uv_width;  Border /= 2;   /* copy the left and right most columns out */  src_ptr1 = u_src;  src_ptr2 = src_ptr1 + plane_width - 1;  dest_ptr1 = src_ptr1 - Border;  dest_ptr2 = src_ptr2 + 1;   for (i = 0; i < plane_height; ++i) {    memset(dest_ptr1, src_ptr1[0], Border);    memset(dest_ptr2, src_ptr2[0], Border);    src_ptr1 += plane_stride;    src_ptr2 += plane_stride;    dest_ptr1 += plane_stride;    dest_ptr2 += plane_stride;  }   /***********/  /* V Plane */  /***********/   /* copy the left and right most columns out */  src_ptr1 = v_src;  src_ptr2 = src_ptr1 + plane_width - 1;  dest_ptr1 = src_ptr1 - Border;  dest_ptr2 = src_ptr2 + 1;   for (i = 0; i < plane_height; ++i) {    memset(dest_ptr1, src_ptr1[0], Border);    memset(dest_ptr2, src_ptr2[0], Border);    src_ptr1 += plane_stride;    src_ptr2 += plane_stride;    dest_ptr1 += plane_stride;    dest_ptr2 += plane_stride;  }} static void decode_mb_rows(VP8D_COMP *pbi) {  VP8_COMMON *const pc = &pbi->common;  MACROBLOCKD *const xd = &pbi->mb;   MODE_INFO *lf_mic = xd->mode_info_context;   int ibc = 0;  int num_part = 1 << pc->multi_token_partition;   int recon_yoffset, recon_uvoffset;  int mb_row, mb_col;  int mb_idx = 0;   YV12_BUFFER_CONFIG *yv12_fb_new = pbi->dec_fb_ref[INTRA_FRAME];   int recon_y_stride = yv12_fb_new->y_stride;  int recon_uv_stride = yv12_fb_new->uv_stride;   unsigned char *ref_buffer[MAX_REF_FRAMES][3];  unsigned char *dst_buffer[3];  unsigned char *lf_dst[3];  unsigned char *eb_dst[3];  int i;  int ref_fb_corrupted[MAX_REF_FRAMES];   ref_fb_corrupted[INTRA_FRAME] = 0;   for (i = 1; i < MAX_REF_FRAMES; ++i) {    YV12_BUFFER_CONFIG *this_fb = pbi->dec_fb_ref[i];     ref_buffer[i][0] = this_fb->y_buffer;    ref_buffer[i][1] = this_fb->u_buffer;    ref_buffer[i][2] = this_fb->v_buffer;     ref_fb_corrupted[i] = this_fb->corrupted;  }   /* Set up the buffer pointers */  eb_dst[0] = lf_dst[0] = dst_buffer[0] = yv12_fb_new->y_buffer;  eb_dst[1] = lf_dst[1] = dst_buffer[1] = yv12_fb_new->u_buffer;  eb_dst[2] = lf_dst[2] = dst_buffer[2] = yv12_fb_new->v_buffer;   xd->up_available = 0;   /* Initialize the loop filter for this frame. */  if (pc->filter_level) vp8_loop_filter_frame_init(pc, xd, pc->filter_level);   vp8_setup_intra_recon_top_line(yv12_fb_new);   /* Decode the individual macro block */  for (mb_row = 0; mb_row < pc->mb_rows; ++mb_row) {    if (num_part > 1) {      xd->current_bc = &pbi->mbc[ibc];      ibc++;       if (ibc == num_part) ibc = 0;    }     recon_yoffset = mb_row * recon_y_stride * 16;    recon_uvoffset = mb_row * recon_uv_stride * 8;     /* reset contexts */    xd->above_context = pc->above_context;    memset(xd->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)); 

Lines 1–500 of 1257.

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