예제 #1
0
void decode_and_reconstruct_block_inter (uint8_t *rec, int stride, int size, int qp, uint8_t *pblock, int16_t *coeffq,int tb_split){

  int16_t *rcoeff = thor_alloc(2*MAX_TR_SIZE*MAX_TR_SIZE, 16);
  int16_t *rblock = thor_alloc(2*MAX_TR_SIZE*MAX_TR_SIZE, 16);
  int16_t *rblock2 = thor_alloc(2*MAX_TR_SIZE*MAX_TR_SIZE, 16);

  if (tb_split){
    int size2 = size/2;
    int i,j,k,index;
    for (i=0;i<size;i+=size2){
      for (j=0;j<size;j+=size2){
        index = 2*(i/size2) + (j/size2);
        dequantize (coeffq+index*size2*size2,rcoeff,qp,size2);
        inverse_transform (rcoeff, rblock2, size2);
        /* Copy from compact block of quarter size to full size */
        for (k=0;k<size2;k++){
          memcpy(rblock+(i+k)*size+j,rblock2+k*size2,size2*sizeof(int16_t));
        }
      }
    }
  }
  else{
    dequantize (coeffq,rcoeff,qp,size);
    inverse_transform (rcoeff, rblock, size);
  }
  reconstruct_block(rblock,pblock,rec,size,stride);

  thor_free(rcoeff);
  thor_free(rblock);
  thor_free(rblock2);
}
예제 #2
0
void decode_and_reconstruct_block_intra (uint8_t *rec, int stride, int size, int qp, uint8_t *pblock, int16_t *coeffq,
    int tb_split, int upright_available,int downleft_available, intra_mode_t intra_mode,int ypos,int xpos,int width,int comp, 
    qmtx_t ** iwmatrix){

  int16_t *rcoeff = thor_alloc(2*MAX_TR_SIZE*MAX_TR_SIZE, 16);
  int16_t *rblock = thor_alloc(2*MAX_TR_SIZE*MAX_TR_SIZE, 16);
  int16_t *rblock2 = thor_alloc(2*MAX_TR_SIZE*MAX_TR_SIZE, 16);

  uint8_t* left_data = (uint8_t*)thor_alloc(2*MAX_TR_SIZE+2,16)+1;
  uint8_t* top_data = (uint8_t*)thor_alloc(2*MAX_TR_SIZE+2,16)+1;
  uint8_t top_left;


  if (tb_split){
    int size2 = size/2;
    int i,j,index;
    for (i=0;i<size;i+=size2){
      for (j=0;j<size;j+=size2){
        make_top_and_left(left_data,top_data,&top_left,rec,stride,&rec[i*stride+j],stride,i,j,ypos,xpos,size2,upright_available,downleft_available,1);

        get_intra_prediction(left_data,top_data,top_left,ypos+i,xpos+j,size2,pblock,intra_mode);
        index = 2*(i/size2) + (j/size2);
        dequantize (coeffq+index*size2*size2, rcoeff, qp, size2, iwmatrix ? iwmatrix[log2i(size2/4)] : NULL, MAX_QUANT_SIZE);
        inverse_transform (rcoeff, rblock2, size2);
        reconstruct_block(rblock2,pblock,&rec[i*stride+j],size2,stride);
      }
    }
  }
  else{
    make_top_and_left(left_data,top_data,&top_left,rec,stride,NULL,0,0,0,ypos,xpos,size,upright_available,downleft_available,0);
    get_intra_prediction(left_data,top_data,top_left,ypos,xpos,size,pblock,intra_mode);
    dequantize (coeffq, rcoeff, qp, size, iwmatrix ? iwmatrix[log2i(size/4)] : NULL, MAX_QUANT_SIZE);
    inverse_transform (rcoeff, rblock, size);
    reconstruct_block(rblock,pblock,rec,size,stride);
  }

  thor_free(top_data - 1);
  thor_free(left_data - 1);
  thor_free(rcoeff);
  thor_free(rblock);
  thor_free(rblock2);
}
예제 #3
0
void decode_block(decoder_info_t *decoder_info,int size,int ypos,int xpos){

  int width = decoder_info->width;
  int height = decoder_info->height;
  int xposY = xpos;
  int yposY = ypos;
  int xposC = xpos/2;
  int yposC = ypos/2;
  int sizeY = size;
  int sizeC = size/2;

  block_mode_t mode;
  mv_t mv;
  intra_mode_t intra_mode;

  frame_type_t frame_type = decoder_info->frame_info.frame_type;
  int bipred = decoder_info->bipred;

  int qpY = decoder_info->frame_info.qpb;
  int qpC = chroma_qp[qpY];

  /* Intermediate block variables */
  uint8_t *pblock_y = thor_alloc(MAX_BLOCK_SIZE*MAX_BLOCK_SIZE, 16);
  uint8_t *pblock_u = thor_alloc(MAX_BLOCK_SIZE*MAX_BLOCK_SIZE, 16);
  uint8_t *pblock_v = thor_alloc(MAX_BLOCK_SIZE*MAX_BLOCK_SIZE, 16);
  int16_t *coeff_y = thor_alloc(2*MAX_TR_SIZE*MAX_TR_SIZE, 16);
  int16_t *coeff_u = thor_alloc(2*MAX_TR_SIZE*MAX_TR_SIZE, 16);
  int16_t *coeff_v = thor_alloc(2*MAX_TR_SIZE*MAX_TR_SIZE, 16);

  /* Block variables for bipred */
  uint8_t *pblock0_y = thor_alloc(MAX_BLOCK_SIZE*MAX_BLOCK_SIZE, 16);
  uint8_t *pblock0_u = thor_alloc(MAX_BLOCK_SIZE*MAX_BLOCK_SIZE, 16);
  uint8_t *pblock0_v = thor_alloc(MAX_BLOCK_SIZE*MAX_BLOCK_SIZE, 16);
  uint8_t *pblock1_y = thor_alloc(MAX_BLOCK_SIZE*MAX_BLOCK_SIZE, 16);
  uint8_t *pblock1_u = thor_alloc(MAX_BLOCK_SIZE*MAX_BLOCK_SIZE, 16);
  uint8_t *pblock1_v = thor_alloc(MAX_BLOCK_SIZE*MAX_BLOCK_SIZE, 16);
  yuv_frame_t *rec = decoder_info->rec;
  yuv_frame_t *ref = decoder_info->ref[0];

  /* Calculate position in padded reference frame */
  int ref_posY = yposY*ref->stride_y+xposY;
  int ref_posC = yposC*ref->stride_c+xposC;

  /* Pointers to current position in reconstructed frame*/
  uint8_t *rec_y = &rec->y[yposY*rec->stride_y+xposY];
  uint8_t *rec_u = &rec->u[yposC*rec->stride_c+xposC];
  uint8_t *rec_v = &rec->v[yposC*rec->stride_c+xposC];

  /* Pointers to colocated block position in reference frame */
  uint8_t *ref_y = ref->y + ref_posY;
  uint8_t *ref_u = ref->u + ref_posC;
  uint8_t *ref_v = ref->v + ref_posC;

  stream_t *stream = decoder_info->stream;

  /* Read data from bitstream */
  block_info_dec_t block_info;
  block_info.block_pos.size = size;
  block_info.block_pos.ypos = ypos;
  block_info.block_pos.xpos = xpos;
  block_info.coeffq_y = coeff_y;
  block_info.coeffq_u = coeff_u;
  block_info.coeffq_v = coeff_v;

  /* Used for rectangular skip blocks */
  int bwidth = min(size,width - xpos);
  int bheight = min(size,height - ypos);
  block_info.block_pos.bwidth = bwidth;
  block_info.block_pos.bheight = bheight;

  read_block(decoder_info,stream,&block_info,frame_type);
  mode = block_info.block_param.mode;

  if (mode == MODE_INTRA){
    /* Dequantize, inverse tranform, predict and reconstruct */
    intra_mode = block_info.block_param.intra_mode;
    int upright_available = get_upright_available(ypos,xpos,size,width);
    int downleft_available = get_downleft_available(ypos,xpos,size,height);
    int tb_split = block_info.block_param.tb_split;
    decode_and_reconstruct_block_intra(rec_y,rec->stride_y,sizeY,qpY,pblock_y,coeff_y,tb_split,upright_available,downleft_available,intra_mode,yposY,xposY,width,0);
    decode_and_reconstruct_block_intra(rec_u,rec->stride_c,sizeC,qpC,pblock_u,coeff_u,tb_split&&size>8,upright_available,downleft_available,intra_mode,yposC,xposC,width/2,1);
    decode_and_reconstruct_block_intra(rec_v,rec->stride_c,sizeC,qpC,pblock_v,coeff_v,tb_split&&size>8,upright_available,downleft_available,intra_mode,yposC,xposC,width/2,2);
  }
  else
  {
    if (mode==MODE_SKIP){
      if (block_info.block_param.dir==2){
        uint8_t *ref0_y,*ref0_u,*ref0_v;
        uint8_t *ref1_y,*ref1_u,*ref1_v;

        int r0 = decoder_info->frame_info.ref_array[block_info.block_param.ref_idx0];
        yuv_frame_t *ref0 = r0>=0 ? decoder_info->ref[r0] : decoder_info->interp_frames[0];
        ref0_y = ref0->y + ref_posY;
        ref0_u = ref0->u + ref_posC;
        ref0_v = ref0->v + ref_posC;

        int r1 = decoder_info->frame_info.ref_array[block_info.block_param.ref_idx1];
        yuv_frame_t *ref1 = r1>=0 ? decoder_info->ref[r1] : decoder_info->interp_frames[0];
        ref1_y = ref1->y + ref_posY;
        ref1_u = ref1->u + ref_posC;
        ref1_v = ref1->v + ref_posC;
        int sign0 = ref0->frame_num >= rec->frame_num;
        int sign1 = ref1->frame_num >= rec->frame_num;

        mv = block_info.block_param.mv_arr0[0];
        get_inter_prediction_luma  (pblock0_y, ref0_y, bwidth,   bheight,   ref->stride_y, sizeY, &mv, sign0, bipred);
        get_inter_prediction_chroma(pblock0_u, ref0_u, bwidth/2, bheight/2, ref->stride_c, sizeC, &mv, sign0);
        get_inter_prediction_chroma(pblock0_v, ref0_v, bwidth/2, bheight/2, ref->stride_c, sizeC, &mv, sign0);
        mv = block_info.block_param.mv_arr1[0];
        get_inter_prediction_luma  (pblock1_y, ref1_y, bwidth,   bheight,   ref->stride_y, sizeY, &mv, sign1, bipred);
        get_inter_prediction_chroma(pblock1_u, ref1_u, bwidth/2, bheight/2, ref->stride_c, sizeC, &mv, sign1);
        get_inter_prediction_chroma(pblock1_v, ref1_v, bwidth/2, bheight/2, ref->stride_c, sizeC, &mv, sign1);

        int i,j;
        for (i=0;i<bheight;i++){
          for (j=0;j<bwidth;j++){
            rec_y[i*rec->stride_y+j] = (uint8_t)(((int)pblock0_y[i*sizeY+j] + (int)pblock1_y[i*sizeY+j])>>1);
          }
        }

        for (i=0;i<bheight/2;i++){
          for (j=0;j<bwidth/2;j++){
            rec_u[i*rec->stride_c+j] = (uint8_t)(((int)pblock0_u[i*sizeC+j] + (int)pblock1_u[i*sizeC+j])>>1);
            rec_v[i*rec->stride_c+j] = (uint8_t)(((int)pblock0_v[i*sizeC+j] + (int)pblock1_v[i*sizeC+j])>>1);
          }
        }
        copy_deblock_data(decoder_info,&block_info);
      }
      else{
        mv = block_info.block_param.mv_arr0[0];
        int ref_idx = block_info.block_param.ref_idx0; //TODO: Move to top
        int r = decoder_info->frame_info.ref_array[ref_idx];
        ref = r>=0 ? decoder_info->ref[r] : decoder_info->interp_frames[0];
        int sign = ref->frame_num > rec->frame_num;
        ref_y = ref->y + ref_posY;
        ref_u = ref->u + ref_posC;
        ref_v = ref->v + ref_posC;
        get_inter_prediction_luma  (pblock_y, ref_y, bwidth, bheight, ref->stride_y, sizeY, &mv, sign, bipred);
        get_inter_prediction_chroma(pblock_u, ref_u, bwidth/2, bheight/2, ref->stride_c, sizeC, &mv, sign);
        get_inter_prediction_chroma(pblock_v, ref_v, bwidth/2, bheight/2, ref->stride_c, sizeC, &mv, sign);

        int j;
        for (j=0;j<bheight;j++){
          memcpy(&rec_y[j*rec->stride_y],&pblock_y[j*sizeY],bwidth*sizeof(uint8_t));
        }
        for (j=0;j<bheight/2;j++){
          memcpy(&rec_u[j*rec->stride_c],&pblock_u[j*sizeC],(bwidth/2)*sizeof(uint8_t));
          memcpy(&rec_v[j*rec->stride_c],&pblock_v[j*sizeC],(bwidth/2)*sizeof(uint8_t));
        }
        copy_deblock_data(decoder_info,&block_info);
      }
      return;
    }
예제 #4
0
static void motion_estimate_bi(mv_data_t* mv_data, mv_data_t** guide_mv_data, int num_guides, yuv_frame_t* indata0, yuv_frame_t* indata1, int k)
{
  // Estimate indata0 from indata1 and vice-versa


  const int bw=mv_data->bw;
  const int bh=mv_data->bh;

  if (num_guides==0) {
    memset(mv_data->mv[0], 0, sizeof(mv_t)*bw*bh);
    memset(mv_data->mv[1], 0, sizeof(mv_t)*bw*bh);
  }
  memset(mv_data->bgmap, 0, sizeof(int)*bw*bh);

  const int step=mv_data->step;
  mv_t cand_list[MAX_CANDS];


  yuv_frame_t* pic[2];
  pic[0] = mv_data->reversed ? indata1 : indata0;
  pic[1] = mv_data->reversed ? indata0 : indata1;

  for (int i=0; i<bh; i+=step) {
    for (int j=0; j<bw; j+=step) {
      make_skip_vector(mv_data, j, i, step, step);
      skip_test(mv_data, pic, j, i);
      int pos=i*bw+j;
      if (mv_data->bgmap[pos]==0) {

        int num_cands=get_cands(mv_data, cand_list, guide_mv_data, num_guides, j, i, MAX_CANDS, step, step);
        adaptive_search_v2(mv_data, num_guides!=0, cand_list, num_cands, pic, j, i, step, step);
      }
      // propagate
      const mv_t mv0=mv_data->mv[0][pos];
      const mv_t mv1=mv_data->mv[1][pos];
      int bgval=mv_data->bgmap[pos];
      for (int q=0; q<step; ++q) {
        for (int p=0; p<step; ++p) {
          mv_data->mv[0][pos+q*bw+p]=mv0;
          mv_data->mv[1][pos+q*bw+p]=mv1;
          mv_data->bgmap[pos+q*bw+p]=bgval;
        }
      }
    }
  }

  mv_t * mv0 = (mv_t*) thor_alloc(bw*bh*sizeof(mv_t), 16);
  mv_t * mv1 = (mv_t*) thor_alloc(bw*bh*sizeof(mv_t), 16);

  for (int i=0; i<bh; i++) {
    for (int j=0; j<bw; j++) {
      int num_cands=get_merge_cands(mv_data, cand_list, 1, j, i, MAX_CANDS);
      if (num_cands>1){
        merge_candidate_search(cand_list, num_cands, mv_data, mv0, mv1, pic, j, i);
      } else {
        mv0[i*bw+j]=mv_data->mv[0][i*bw+j];
        mv1[i*bw+j]=mv_data->mv[1][i*bw+j];
      }
    }
  }

  memcpy(mv_data->mv[0], mv0, bw*bh*sizeof(mv_t));
  memcpy(mv_data->mv[1], mv1, bw*bh*sizeof(mv_t));

  thor_free(mv0);
  thor_free(mv1);
}