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); }
static void psqLoad(ThreadState *state, Instruction instr) { uint32_t ea, ls, c, i, w; QuantizedDataType lt; if ((flags & PsqLoadZeroRA) && instr.rA == 0) { ea = 0; } else { ea = state->gpr[instr.rA]; } if (flags & PsqLoadIndexed) { ea += state->gpr[instr.rB]; } else { ea += sign_extend<12, int32_t>(instr.qd); } if (flags & PsqLoadIndexed) { i = instr.qi; w = instr.qw; } else { i = instr.i; w = instr.w; } c = 4; lt = static_cast<QuantizedDataType>(state->gqr[i].ld_type); ls = state->gqr[i].ld_scale; if (lt == QuantizedDataType::Unsigned8 || lt == QuantizedDataType::Signed8) { c = 1; } else if (lt == QuantizedDataType::Unsigned16 || lt == QuantizedDataType::Signed16) { c = 2; } if (w == 0) { state->fpr[instr.frD].paired0 = dequantize(ea, lt, ls); state->fpr[instr.frD].paired1 = dequantize(ea + c, lt, ls); } else { state->fpr[instr.frD].paired0 = dequantize(ea, lt, ls); state->fpr[instr.frD].paired1 = 1.0f; } if (flags & PsqLoadUpdate) { state->gpr[instr.rA] = ea; } }
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); }
static IplImage* splat(int *coeffs, CvSize size, int *plane_coeffs) { IplImage *g = cvCreateImage(size, IPL_DEPTH_16S, 1); IplImage *b = cvCreateImage(size, IPL_DEPTH_16S, 1); IplImage *r = cvCreateImage(size, IPL_DEPTH_16S, 1); IplImage *rgb = cvCreateImage(size, IPL_DEPTH_16S, 3); IplImage *img = cvCreateImage(size, IPL_DEPTH_8U, 3); IplImage *trans = cvCreateImage(size, IPL_DEPTH_16S, 1); int dim = plane_coeffs[0] + plane_coeffs[1] + plane_coeffs[2]; unsigned *order_p0 = build_path(plane_coeffs[0], KERNS); unsigned *order_p1 = build_path(plane_coeffs[1], KERNS); unsigned *order_p2 = build_path(plane_coeffs[2], KERNS); memset(trans->imageData, 0, trans->imageSize); dequantize(trans, plane_coeffs[0], order_p0, KERNS, coeffs, dim); iwht2d(trans, g); memset(trans->imageData, 0, trans->imageSize); dequantize(trans, plane_coeffs[1], order_p1, KERNS, coeffs+plane_coeffs[0], dim); iwht2d(trans, b); memset(trans->imageData, 0, trans->imageSize); dequantize(trans, plane_coeffs[2], order_p2, KERNS, coeffs+plane_coeffs[0]+plane_coeffs[1], dim); iwht2d(trans, r); cvMerge(g, b, r, NULL, rgb); cvConvertScale(rgb, img, 1, 0); cvReleaseImage(&g); cvReleaseImage(&b); cvReleaseImage(&r); cvReleaseImage(&rgb); cvReleaseImage(&trans); free(order_p0); free(order_p1); free(order_p2); return img; }
static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { MscEncoderContext * mscEncoderContext; MscCodecContext * mscContext; uint32_t arithBytesEncoded; PutBitContext pb; int mb_y, mb_x, value, lastNonZero, max, arithCoderIndex = -1, keyFrame; // initialize arithmetic encoder registers initialize_arithmetic_encoder(); mscEncoderContext = avctx->priv_data; mscContext = &mscEncoderContext->mscContext; init_put_bits(&pb, mscEncoderContext->arithBuff, mscEncoderContext->arithBuffSize); keyFrame = isKeyFrame(avctx->frame_number); if (avctx->frame_number == 0) { av_image_alloc(mscContext->referenceFrame->data, mscContext->referenceFrame->linesize, frame->width, frame->height, frame->format, 128); } avctx->coded_frame->reference = 0; avctx->coded_frame->key_frame = 1; avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; int * qmatrix = keyFrame ? mscContext->q_intra_matrix : mscContext->q_non_intra_matrix; for (mb_x = 0; mb_x < mscContext->mb_width; mb_x++) { for (mb_y = 0; mb_y < mscContext->mb_height; mb_y++) { get_blocks(mscEncoderContext, frame, mb_x, mb_y, mscContext->block); if (!keyFrame) { get_blocks(mscEncoderContext, mscContext->referenceFrame, mb_x, mb_y, mscContext->tmpBlock); diff_blocks(mscContext->block, mscContext->tmpBlock); } for (int n = 0; n < 6; ++n) { // if (avctx->frame_number == 1 && mb_x == 0 && mb_y == 0) { // av_log(avctx, AV_LOG_INFO, "Block x=%d, y=%d, n=%d\n", mb_x, mb_y, n); // print_debug_block(avctx, mscContext->block[n]); // } mscContext->dsp.fdct(mscContext->block[n]); // if (avctx->frame_number == 0 && mb_x == 0 && mb_y == 0) { // av_log(avctx, AV_LOG_INFO, "DCT block x=%d, y=%d, n=%d\n", mb_x, mb_y, n); // print_debug_block(avctx, mscContext->block[n]); // } lastNonZero = quantize(mscContext->block[n], qmatrix, &max); av_assert1(lastNonZero < 64); // if (overflow) { // clip_coeffs(m, m->block[n], m->block_last_index[n]); // av_log(avctx, AV_LOG_WARNING, "Overflow detected, frame: %d, mb_x: %d, mb_y: %d, n: %d\n", // avctx->frame_number, mb_x, mb_y, n); // } // if (avctx->frame_number == 0 && mb_x == 3 && mb_y == 0) { // av_log(avctx, AV_LOG_INFO, "DCT quantized block x=%d, y=%d, n=%d\n", mb_x, mb_y, n); // print_debug_block(avctx, mscContext->block[n]); // } encode_arith_symbol(&mscContext->lastZeroCodingModel, &pb, lastNonZero); if (lastNonZero > 0) { arithCoderIndex = get_arith_model_index(max); encode_arith_symbol(&mscContext->arithModelIndexCodingModel, &pb, arithCoderIndex); } for (int i = 0; i <= lastNonZero; ++i) { int arithCoderBits = i == 0 ? ARITH_CODER_BITS : arithCoderIndex; value = mscContext->block[n][scantab[i]] + mscContext->arithModelAddValue[arithCoderBits]; encode_arith_symbol(&mscContext->arithModels[arithCoderBits], &pb, value); } dequantize(mscContext->block[n], mscContext, keyFrame); } if (keyFrame) { idct_put_block(mscContext, mscContext->referenceFrame, mb_x, mb_y); } else { idct_add_block(mscContext, mscContext->referenceFrame, mb_x, mb_y); } } } emms_c(); // flush arithmetic encoder flush_arithmetic_encoder(&pb); flush_put_bits(&pb); arithBytesEncoded = pb.buf_ptr - pb.buf; // alocate packet if ((value = ff_alloc_packet(avpkt, arithBytesEncoded)) < 0) { return value; } avpkt->flags |= AV_PKT_FLAG_KEY; // store encoded data memcpy(avpkt->data, mscEncoderContext->arithBuff, arithBytesEncoded); *got_packet_ptr = 1; return 0; }
static int decode(AVCodecContext * avctx, void *outdata, int *outdata_size, AVPacket *avpkt) { AVFrame *frame = avctx->coded_frame; MscDecoderContext * mscDecoderContext; MscCodecContext * mscContext; GetBitContext gb; int lastNonZero, value, arithCoderIndex = -1, keyFrame; mscDecoderContext = avctx->priv_data; mscContext = &mscDecoderContext->mscContext; if (frame->data[0]) { avctx->release_buffer(avctx, frame); } frame->reference = 0; if (avctx->get_buffer(avctx, frame) < 0) { av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); return AVERROR(ENOMEM); } keyFrame = isKeyFrame(avctx->frame_number); if (avctx->frame_number == 0) { av_image_alloc(mscContext->referenceFrame->data, mscContext->referenceFrame->linesize, frame->width, frame->height, PIX_FMT_YUV420P, 128); } if (!keyFrame) { av_image_copy(frame->data, frame->linesize, mscContext->referenceFrame->data, mscContext->referenceFrame->linesize, PIX_FMT_YUV420P, frame->width, frame->height); } frame->key_frame = 1; frame->pict_type = AV_PICTURE_TYPE_I; // init encoded data bit buffer init_get_bits(&gb, avpkt->data, avpkt->size * 8); initialize_arithmetic_decoder(&gb); for (int mb_x = 0; mb_x < mscContext->mb_width; mb_x++) { for (int mb_y = 0; mb_y < mscContext->mb_height; mb_y++) { for (int n = 0; n < 6; ++n) { mscContext->dsp.clear_block(mscContext->block[n]); lastNonZero = decode_arith_symbol(&mscContext->lastZeroCodingModel, &gb); if (lastNonZero > 0) { arithCoderIndex = decode_arith_symbol(&mscContext->arithModelIndexCodingModel, &gb); } for (int i = 0; i <= lastNonZero; ++i) { int arithCoderBits = i == 0 ? ARITH_CODER_BITS : arithCoderIndex; value = decode_arith_symbol(&mscContext->arithModels[arithCoderBits], &gb); mscContext->block[n][scantab[i]] = value - mscContext->arithModelAddValue[arithCoderBits]; } // if (avctx->frame_number == 0 && mb_x == 3 && mb_y == 0) { // av_log(avctx, AV_LOG_INFO, "Quantized x=%d, y=%d, n=%d\n", mb_x, mb_y, n); // print_debug_block(avctx, mscContext->block[n]); // } dequantize(mscContext->block[n], mscContext, keyFrame); // if (avctx->frame_number == 0 && mb_x == 0 && mb_y == 0) { // av_log(avctx, AV_LOG_INFO, "Dequantized x=%d, y=%d, n=%d\n", mb_x, mb_y, n); // print_debug_block(avctx, mscContext->block[n]); // } } // if (avctx->frame_number == 0 && mb_x == 0 && mb_y == 0) { // av_log(avctx, AV_LOG_INFO, "IDCT x=%d, y=%d, n=%d\n", mb_x, mb_y, 0); // print_debug_block(avctx, mscContext->block[0]); // } if (keyFrame) { idct_put_block(mscContext, frame, mb_x, mb_y); } else { idct_add_block(mscContext, frame, mb_x, mb_y); } copy_macroblock(frame, mscContext->referenceFrame, mb_x, mb_y); } } emms_c(); *outdata_size = sizeof(AVFrame); *(AVFrame *) outdata = *frame; return avpkt->size; }
int DCTCoder::decode(BitStream& bs, YuvFrame& frame, uint quantization){ int err; int v; int block[SIZE] = {0}; float dctC[SIZE] = {.0f}; int qBlock[SIZE] = {0}; int yRowBlocks = (frame.getYRows() + H - 1)/H; // ceil() int yColBlocks = (frame.getYCols() + W - 1)/W; int uRowBlocks = (frame.getURows() + H - 1)/H; int uColBlocks = (frame.getUCols() + W - 1)/W; int vRowBlocks = (frame.getVRows() + H - 1)/H; int vColBlocks = (frame.getVCols() + W - 1)/W; // Y for (int i = 0; i < yRowBlocks; i++){ for (int j = 0; j < yColBlocks; j++){ for (int c = 0; c < SIZE; c++){ if ((err = Golomb::decode(M, &v, bs)) != 0){ return err; } qBlock[c] = v; } dequantize(qBlock, quantization, LUMINANCE, dctC); invdct(dctC, block); shift(block, 128); for (int k = 0; k < H; k++){ for (int l = 0; l < W; l++){ frame.putYPixel(i*H+k,j*W+l, clamp(block[k*W+l])); } } } } //U for (int i = 0; i < uRowBlocks; i++){ for (int j = 0; j < uColBlocks; j++){ for (int c = 0; c < SIZE; c++){ if ((err = Golomb::decode(M, &v, bs)) != 0){ return err; } qBlock[c] = v; } dequantize(qBlock, quantization, CROMINANCE, dctC); invdct(dctC, block); shift(block, 128); for (int k = 0; k < H; k++){ for (int l = 0; l < W; l++){ frame.putUPixel(i*H+k,j*W+l, clamp(block[k*W+l])); } } } } //V for (int i = 0; i < vRowBlocks; i++){ for (int j = 0; j < vColBlocks; j++){ for (int c = 0; c < SIZE; c++){ if ((err = Golomb::decode(M, &v, bs)) != 0){ return err; } qBlock[c] = v; } dequantize(qBlock, quantization, CROMINANCE, dctC); invdct(dctC, block); shift(block, 128); for (int k = 0; k < H; k++){ for (int l = 0; l < W; l++){ frame.putVPixel(i*H+k,j*W+l, clamp(block[k*W+l])); } } } } return 0; }