diff -r 000000000000 -r 951a5db380a0 videoeditorengine/h263decoder/src/decmbdct_mpeg.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/videoeditorengine/h263decoder/src/decmbdct_mpeg.cpp Fri Jan 29 14:08:33 2010 +0200 @@ -0,0 +1,381 @@ +/* +* Copyright (c) 2010 Ixonos Plc. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - Initial contribution +* +* Contributors: +* Ixonos Plc +* +* Description: +* Prediction error block decoding functions (MPEG-4). +* +*/ + + + +/* + * Includes + */ +#include "h263dConfig.h" +#include "decmbdct.h" +#include "decblock.h" +#include "block.h" +#include "viddemux.h" +/* MVE */ +#include "MPEG4Transcoder.h" + +/* + * Global functions + */ + +/* {{-output"dmdGetAndDecodeMPEGIMBBlocks.txt"}} */ +/* + * dmdGetAndDecodeMPEGIMBBlocks + * + * + * Parameters: + * param parameters needed in this function + * + * Function: + * This function gets the DCT coefficients of an INTRA macroblock + * from the bitstream, reconstructs the corresponding + * pixel-domain blocks and puts the blocks to the output frame. + * + * Returns: + * >= 0 the function was successful + * < 0 an error occured when accessing bit buffer + * + */ + +int dmdGetAndDecodeMPEGIMBBlocks( + dmdMPEGIParam_t *param, CMPEG4Transcoder *hTranscoder) +/* {{-output"dmdGetAndDecodeMPEGIMBBlocks.txt"}} */ +{ + bibBuffer_t *inBuffer; + + bibBuffer_t + *outBuffer; /* Output bit buffer instance */ + + bibBufferEdit_t + *bufEdit; + + int colorEffect; + TBool getDecodedFrame; + + int i, j, + block[64], cWidth, bitErrorIndication = 0, ret = 0; + u_char *yBlockInFrame; + int IntraDC_size, + IntraDC_delta, + DC_coeff; + + inBuffer = param->inBuffer; + outBuffer = param->outBuffer; + bufEdit = param->bufEdit; + colorEffect = param->iColorEffect; + getDecodedFrame = param->iGetDecodedFrame; + + if ( param->yMBInFrame ) + { + yBlockInFrame = param->yMBInFrame + + ((param->reversible_vlc && param->vlc_dec_direction) ? ((/*8 **/ param->yWidth<<3) + 8) : 0); + } + else + { + yBlockInFrame = NULL; + } + cWidth = (param->yWidth >>1 /*/ 2*/); + + + /* Loop through the 4 Luminance and the 2 Chrominance blocks */ + for (j=0; j<=5; j++) + { + + /* if reversible decoding, the block numbering is reverse */ + if (param->reversible_vlc && param->vlc_dec_direction) + { + i = 5-j; + } + else + { + i=j; + } + + /* MVE */ + hTranscoder->BeginOneBlock(i); + + bitErrorIndication = 0; + + /* Get Intra DC if not switched */ + if(!param->switched) { + if (param->data_partitioned) + IntraDC_delta = param->DC[i]; + else { + ret = vdxGetIntraDC(inBuffer, outBuffer, bufEdit, colorEffect, &(param->StartByteIndex), &(param->StartBitIndex), + i, &IntraDC_size, &IntraDC_delta, &bitErrorIndication); + + if ( ret < 0 ) + return DMD_ERR; + else if ( ret == VDX_OK_BUT_BIT_ERROR ) + goto corruptedMB; + } + block[0] = IntraDC_delta; + } + + /* Get DCT coefficients */ + if (((i<4) && (vdxIsYCoded(param->cbpy, i + 1))) || + ((i==4) && (vdxIsUCoded(param->cbpc))) || + ((i==5) && (vdxIsVCoded(param->cbpc)))) + { + /* if reversible VLC, also the direction of decoding is relevant */ + if (param->reversible_vlc) + { + if (!param->vlc_dec_direction) + ret = vdxGetRVLCDCTBlock(inBuffer, (!param->switched), 1, block, + &bitErrorIndication); + else + ret = vdxGetRVLCDCTBlockBackwards(inBuffer, (!param->switched), 1, block, + &bitErrorIndication); + } + else + { + ret = vdxGetMPEGIntraDCTBlock(inBuffer, (!param->switched), block, + &bitErrorIndication); + } + + if ( ret < 0 ) + return DMD_ERR; + else if ( ret == VDX_OK_BUT_BIT_ERROR ) + goto corruptedMB; + + } + /* if block is not coded */ + else + { + memset(block + (!param->switched), 0, (63 + (param->switched))* sizeof(int)); + } + + /* MVE */ + hTranscoder->AddOneBlockDataToMB(i, block); + + /* DC/AC prediction: reconstruct the Intra coefficients */ + aicDCACrecon(param->aicData, param->quant, + param->fTopOfVP, param->fLeftOfVP, param->fBBlockOut, + i, block, param->currMBNum); + + /* optimized nonlinear inverse quantization for Intra DC */ + DC_coeff = (block[0] *= aicDCScaler(param->quant,(i<4)?1:2)); + + hTranscoder->AddOneBlockDCACrecon(i, block); + + /* Update the AIC module data, with the current MB */ + aicBlockUpdate (param->aicData, param->currMBNum, i, block, + param->quant, DC_coeff); + + + if(getDecodedFrame || hTranscoder->NeedDecodedYUVFrame()) + { + /* inverse quantization and IDCT */ + dblIdctAndDequant(block, param->quant, 1); + + if (i<4) + { + blcBlockToFrame(block, yBlockInFrame, param->yWidth); + if (param->reversible_vlc && param->vlc_dec_direction) + { + yBlockInFrame -= 8; + if (i == 2) + yBlockInFrame -= ((/*8 **/ param->yWidth<<3) - 16); + } + else + { + yBlockInFrame += 8; + if (i & 1) + yBlockInFrame += ((/*8 **/ param->yWidth<<3) - 16); + } + } + else + { + blcBlockToFrame(block, ((i==4)? param->uBlockInFrame : param->vBlockInFrame) , cWidth); + } + + } + + } + /* for blocks */ + + if ( hTranscoder->TranscodingOneMB(NULL) != TX_OK ) + { + return DMD_ERR; + } + + return DMD_OK; + +corruptedMB: + + return DMD_BIT_ERR; +} + +/* {{-output"dmdGetAndDecodeMPEGPMBBlocks.txt"}} */ + +/* without the possibility to decode only Y component (#ifdef H263D_LUMINANCE_ONLY) */ +/* + * dmdGetAndDecodeMPEGPMBBlocks + * + * + * Parameters: + * param parameters needed in this function + * + * Function: + * This function gets the DCT coefficients of an INTER macroblock + * from the bitstream, reconstructs the corresponding + * pixel-domain blocks and adds the blocks to the prediction frame. + * + * Returns: + * >= 0 the function was successful + * < 0 an error occured when accessing bit buffer + * + */ + +int dmdGetAndDecodeMPEGPMBBlocks( + dmdPParam_t *param, CMPEG4Transcoder *hTranscoder) +/* {{-output"dmdGetAndDecodeMPEGPMBBlocks.txt"}} */ +{ + int i, j, + bitErrorIndication = 0, /* Carries bit error indication information returned + by the video demultiplexer module */ + ret = 0; + + bibBuffer_t *inBuffer; + + TBool getDecodedFrame; + + inBuffer = param->inBuffer; + getDecodedFrame = param->iGetDecodedFrame; + + int yWidth, block[64]; + u_char *yBlockInFrame; + int chrQuant; + + int fEscapeCodeUsed = 0; + + /* Find out the value of QP for chrominance block. */ + chrQuant = param->quant; + + yWidth = param->uvWidth <<1 /** 2*/; + if ( param->currYMBInFrame ) + { + yBlockInFrame = param->currYMBInFrame + + ((param->reversible_vlc && param->vlc_dec_direction) ? ((/*8 **/ yWidth<<3) + 8) : 0); + } + else + { + yBlockInFrame = NULL; + } + + /* Loop through the 4 Luminance and the 2 Chrominance blocks */ + for (j=0; j<=5; j++) { + + /* if reversible decoding, the block numbering is reverse */ + if (param->reversible_vlc && param->vlc_dec_direction) + { + i = 5-j; + } + else + { + i=j; + } + + /* MVE */ + hTranscoder->BeginOneBlock(i); + + if (((i<4) && (vdxIsYCoded(param->cbpy, i + 1))) || + ((i==4) && (vdxIsUCoded(param->cbpc))) || + ((i==5) && (vdxIsVCoded(param->cbpc)))) + { + + /* Get DCT coefficients */ + if (param->reversible_vlc) + { + if (!param->vlc_dec_direction) + ret = vdxGetRVLCDCTBlock(inBuffer, 0, 0, block, + &bitErrorIndication); + else + ret = vdxGetRVLCDCTBlockBackwards(inBuffer, 0, 0, block, + &bitErrorIndication); + } + else + { + ret = vdxGetDCTBlock(inBuffer, 0, 1, block, + &bitErrorIndication, 0, param->quant, &fEscapeCodeUsed); + } + if ( ret < 0 ) + return DMD_ERR; + else if ( ret == VDX_OK_BUT_BIT_ERROR ) + return DMD_BIT_ERR; + + hTranscoder->AddOneBlockDataToMB(i, block); + if(getDecodedFrame || hTranscoder->NeedDecodedYUVFrame()) // we need the YUV frames. + { + + /* IDCT & dequant */ + dblIdctAndDequant(block, ((i<4)?param->quant:chrQuant), 0); + + if (i<4) + { + + blcAddBlock(block, yBlockInFrame, + yWidth, 0, 0, 0); + } + else + { + /* U or V component */ + + blcAddBlock(block, ((i==4)? param->currUBlkInFrame : param->currVBlkInFrame), param->uvWidth, 0, 0, 0); + } + } + + } + + /* MVE */ + else + { + /* this block is not coded */ + hTranscoder->AddOneBlockDataToMB(i, NULL); + } + + + if ((i<4) && yBlockInFrame) + { + if (param->reversible_vlc && param->vlc_dec_direction) { + yBlockInFrame -= 8; + if (i == 2) + yBlockInFrame -= ((/*8 **/ yWidth<<3) - 16); + } else { + yBlockInFrame += 8; + if (i & 1) + yBlockInFrame += ((/*8 **/ yWidth<<3) - 16); + } + + } + else //u,v + { + /* nothing here */ + } + } + + + /* MVE */ + if ( hTranscoder->TranscodingOneMB(param) != TX_OK ) + { + return DMD_ERR; + } + return DMD_OK; +} +// End of File