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); }
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); }
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; }
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); }