videoeditorengine/h263decoder/src/decmbdct_mpeg.cpp
changeset 0 951a5db380a0
equal deleted inserted replaced
-1:000000000000 0:951a5db380a0
       
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - Initial contribution
       
    11 *
       
    12 * Contributors:
       
    13 * Ixonos Plc
       
    14 *
       
    15 * Description:  
       
    16 * Prediction error block decoding functions (MPEG-4).
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 
       
    22 /* 
       
    23  * Includes 
       
    24  */
       
    25 #include "h263dConfig.h"
       
    26 #include "decmbdct.h"
       
    27 #include "decblock.h"
       
    28 #include "block.h"
       
    29 #include "viddemux.h"
       
    30 /* MVE */
       
    31 #include "MPEG4Transcoder.h"
       
    32 
       
    33 /*
       
    34  * Global functions
       
    35  */
       
    36 
       
    37 /* {{-output"dmdGetAndDecodeMPEGIMBBlocks.txt"}} */
       
    38 /*
       
    39  * dmdGetAndDecodeMPEGIMBBlocks
       
    40  *    
       
    41  *
       
    42  * Parameters:
       
    43  *    param                   parameters needed in this function
       
    44  *
       
    45  * Function:
       
    46  *    This function gets the DCT coefficients of an INTRA macroblock
       
    47  *    from the bitstream, reconstructs the corresponding
       
    48  *    pixel-domain blocks and puts the blocks to the output frame.
       
    49  *
       
    50  * Returns:
       
    51  *    >= 0                       the function was successful
       
    52  *    < 0                        an error occured when accessing bit buffer
       
    53  *
       
    54  */
       
    55 
       
    56 int dmdGetAndDecodeMPEGIMBBlocks(
       
    57    dmdMPEGIParam_t *param, CMPEG4Transcoder *hTranscoder)
       
    58 /* {{-output"dmdGetAndDecodeMPEGIMBBlocks.txt"}} */
       
    59 {
       
    60    bibBuffer_t *inBuffer;
       
    61 
       
    62    bibBuffer_t 
       
    63       *outBuffer;        /* Output bit buffer instance */
       
    64 
       
    65    bibBufferEdit_t 
       
    66       *bufEdit; 
       
    67 
       
    68    int colorEffect;
       
    69    TBool getDecodedFrame;
       
    70 
       
    71    int i, j,
       
    72       block[64], cWidth, bitErrorIndication = 0, ret = 0;
       
    73    u_char *yBlockInFrame;
       
    74    int IntraDC_size, 
       
    75         IntraDC_delta,
       
    76         DC_coeff;
       
    77 
       
    78    inBuffer = param->inBuffer;
       
    79    outBuffer = param->outBuffer;
       
    80    bufEdit = param->bufEdit;
       
    81    colorEffect = param->iColorEffect; 
       
    82    getDecodedFrame = param->iGetDecodedFrame;
       
    83 
       
    84    if ( param->yMBInFrame )
       
    85     {
       
    86         yBlockInFrame = param->yMBInFrame +
       
    87             ((param->reversible_vlc && param->vlc_dec_direction) ? ((/*8 **/ param->yWidth<<3) + 8) : 0);
       
    88     }
       
    89    else
       
    90     {
       
    91         yBlockInFrame = NULL;
       
    92     }
       
    93    cWidth = (param->yWidth >>1 /*/ 2*/);
       
    94    
       
    95 
       
    96     /* Loop through the 4 Luminance and the 2 Chrominance blocks */
       
    97    for (j=0; j<=5; j++) 
       
    98    {
       
    99 
       
   100       /* if reversible decoding, the block numbering is reverse */
       
   101       if (param->reversible_vlc && param->vlc_dec_direction) 
       
   102       {
       
   103          i = 5-j;
       
   104       }
       
   105       else 
       
   106       {
       
   107          i=j;
       
   108       }
       
   109 
       
   110       /* MVE */
       
   111       hTranscoder->BeginOneBlock(i);
       
   112 
       
   113       bitErrorIndication = 0;
       
   114 
       
   115       /* Get Intra DC if not switched */
       
   116       if(!param->switched) {
       
   117          if (param->data_partitioned)
       
   118             IntraDC_delta = param->DC[i];
       
   119          else {
       
   120             ret = vdxGetIntraDC(inBuffer, outBuffer, bufEdit, colorEffect, &(param->StartByteIndex), &(param->StartBitIndex), 
       
   121                             i, &IntraDC_size, &IntraDC_delta, &bitErrorIndication);
       
   122 
       
   123             if ( ret < 0 )
       
   124                return DMD_ERR;
       
   125             else if ( ret == VDX_OK_BUT_BIT_ERROR )
       
   126                goto corruptedMB;
       
   127          }
       
   128          block[0] = IntraDC_delta;
       
   129       }
       
   130 
       
   131       /* Get DCT coefficients */
       
   132       if (((i<4) && (vdxIsYCoded(param->cbpy, i + 1))) ||
       
   133          ((i==4) && (vdxIsUCoded(param->cbpc))) ||
       
   134          ((i==5) && (vdxIsVCoded(param->cbpc))))
       
   135       {
       
   136          /* if reversible VLC, also the direction of decoding is relevant */
       
   137          if (param->reversible_vlc) 
       
   138          {
       
   139             if (!param->vlc_dec_direction)
       
   140                ret = vdxGetRVLCDCTBlock(inBuffer, (!param->switched), 1, block,
       
   141                                  &bitErrorIndication);
       
   142             else
       
   143                ret = vdxGetRVLCDCTBlockBackwards(inBuffer, (!param->switched), 1, block,
       
   144                                         &bitErrorIndication);
       
   145          } 
       
   146          else 
       
   147          {
       
   148             ret = vdxGetMPEGIntraDCTBlock(inBuffer, (!param->switched), block,
       
   149                                   &bitErrorIndication);
       
   150          }
       
   151          
       
   152          if ( ret < 0 )
       
   153             return DMD_ERR;
       
   154          else if ( ret == VDX_OK_BUT_BIT_ERROR )
       
   155             goto corruptedMB;
       
   156 
       
   157       } 
       
   158       /* if block is not coded */
       
   159       else 
       
   160       {
       
   161          memset(block + (!param->switched), 0, (63 + (param->switched))* sizeof(int));
       
   162       }
       
   163 
       
   164       /* MVE */
       
   165       hTranscoder->AddOneBlockDataToMB(i, block);            
       
   166 
       
   167       /* DC/AC prediction: reconstruct the Intra coefficients */
       
   168       aicDCACrecon(param->aicData, param->quant,
       
   169          param->fTopOfVP, param->fLeftOfVP, param->fBBlockOut,
       
   170          i, block, param->currMBNum);
       
   171 
       
   172       /* optimized nonlinear inverse quantization for Intra DC */
       
   173       DC_coeff = (block[0] *= aicDCScaler(param->quant,(i<4)?1:2));
       
   174 
       
   175       hTranscoder->AddOneBlockDCACrecon(i, block);           
       
   176 
       
   177       /* Update the AIC module data, with the current MB */
       
   178       aicBlockUpdate (param->aicData, param->currMBNum, i, block, 
       
   179          param->quant, DC_coeff);
       
   180       
       
   181 
       
   182       if(getDecodedFrame || hTranscoder->NeedDecodedYUVFrame())
       
   183       {
       
   184          /* inverse quantization and IDCT */
       
   185          dblIdctAndDequant(block, param->quant, 1);
       
   186             
       
   187           if (i<4)
       
   188           {
       
   189                blcBlockToFrame(block, yBlockInFrame, param->yWidth);
       
   190                if (param->reversible_vlc && param->vlc_dec_direction) 
       
   191                {
       
   192                    yBlockInFrame -= 8;
       
   193                    if (i == 2)
       
   194                        yBlockInFrame -= ((/*8 **/ param->yWidth<<3) - 16);
       
   195                } 
       
   196                else 
       
   197                {
       
   198                    yBlockInFrame += 8;
       
   199                    if (i & 1)
       
   200                        yBlockInFrame += ((/*8 **/ param->yWidth<<3) - 16);
       
   201                }
       
   202           }
       
   203           else
       
   204           {
       
   205               blcBlockToFrame(block, ((i==4)? param->uBlockInFrame : param->vBlockInFrame) , cWidth);   
       
   206           }
       
   207           
       
   208       }
       
   209             
       
   210    }
       
   211    /* for blocks */
       
   212    
       
   213    if ( hTranscoder->TranscodingOneMB(NULL) != TX_OK )
       
   214    {
       
   215       return DMD_ERR;
       
   216    }
       
   217     
       
   218    return DMD_OK;
       
   219    
       
   220 corruptedMB:
       
   221 
       
   222    return DMD_BIT_ERR;
       
   223 }
       
   224 
       
   225 /* {{-output"dmdGetAndDecodeMPEGPMBBlocks.txt"}} */
       
   226 
       
   227 /* without the possibility to decode only Y component (#ifdef H263D_LUMINANCE_ONLY) */
       
   228 /*
       
   229  * dmdGetAndDecodeMPEGPMBBlocks
       
   230  *    
       
   231  *
       
   232  * Parameters:
       
   233  *    param                      parameters needed in this function
       
   234  *
       
   235  * Function:
       
   236  *    This function gets the DCT coefficients of an INTER macroblock
       
   237  *    from the bitstream, reconstructs the corresponding
       
   238  *    pixel-domain blocks and adds the blocks to the prediction frame.
       
   239  *
       
   240  * Returns:
       
   241  *    >= 0                       the function was successful
       
   242  *    < 0                        an error occured when accessing bit buffer
       
   243  *
       
   244  */
       
   245 
       
   246 int dmdGetAndDecodeMPEGPMBBlocks(
       
   247    dmdPParam_t *param, CMPEG4Transcoder *hTranscoder)
       
   248 /* {{-output"dmdGetAndDecodeMPEGPMBBlocks.txt"}} */
       
   249 {
       
   250    int i, j, 
       
   251       bitErrorIndication = 0, /* Carries bit error indication information returned
       
   252                                  by the video demultiplexer module */
       
   253       ret = 0;
       
   254       
       
   255    bibBuffer_t *inBuffer;
       
   256 
       
   257    TBool getDecodedFrame;
       
   258 
       
   259    inBuffer = param->inBuffer;
       
   260    getDecodedFrame = param->iGetDecodedFrame;
       
   261 
       
   262    int yWidth, block[64];
       
   263    u_char *yBlockInFrame;
       
   264    int chrQuant;
       
   265 
       
   266    int fEscapeCodeUsed = 0;
       
   267 
       
   268    /* Find out the value of QP for chrominance block. */
       
   269    chrQuant = param->quant;
       
   270 
       
   271    yWidth = param->uvWidth <<1 /** 2*/;
       
   272    if ( param->currYMBInFrame )
       
   273     {
       
   274         yBlockInFrame = param->currYMBInFrame + 
       
   275             ((param->reversible_vlc && param->vlc_dec_direction) ? ((/*8 **/ yWidth<<3) + 8) : 0);
       
   276     }
       
   277    else
       
   278     {
       
   279         yBlockInFrame = NULL;
       
   280     }
       
   281 
       
   282    /* Loop through the 4 Luminance and the 2 Chrominance blocks */
       
   283    for (j=0; j<=5; j++) {
       
   284          
       
   285          /* if reversible decoding, the block numbering is reverse */
       
   286          if (param->reversible_vlc && param->vlc_dec_direction) 
       
   287          {
       
   288             i = 5-j;
       
   289          }
       
   290          else 
       
   291          {
       
   292             i=j;
       
   293          }
       
   294          
       
   295      /* MVE */
       
   296          hTranscoder->BeginOneBlock(i);
       
   297          
       
   298          if (((i<4) && (vdxIsYCoded(param->cbpy, i + 1))) ||
       
   299              ((i==4) && (vdxIsUCoded(param->cbpc))) ||
       
   300              ((i==5) && (vdxIsVCoded(param->cbpc))))
       
   301          {
       
   302              
       
   303              /* Get DCT coefficients */
       
   304              if (param->reversible_vlc) 
       
   305              {
       
   306                 if (!param->vlc_dec_direction)
       
   307                     ret = vdxGetRVLCDCTBlock(inBuffer, 0, 0, block,
       
   308                     &bitErrorIndication);
       
   309                 else
       
   310                     ret = vdxGetRVLCDCTBlockBackwards(inBuffer, 0, 0, block,
       
   311                     &bitErrorIndication);
       
   312              } 
       
   313              else 
       
   314              {
       
   315                 ret = vdxGetDCTBlock(inBuffer, 0, 1, block, 
       
   316                      &bitErrorIndication, 0, param->quant, &fEscapeCodeUsed);
       
   317              }
       
   318              if ( ret < 0 )
       
   319                 return DMD_ERR;
       
   320              else if ( ret == VDX_OK_BUT_BIT_ERROR )
       
   321                 return DMD_BIT_ERR;
       
   322              
       
   323             hTranscoder->AddOneBlockDataToMB(i, block);          
       
   324             if(getDecodedFrame || hTranscoder->NeedDecodedYUVFrame()) // we need the YUV frames.
       
   325             {
       
   326                  
       
   327                 /* IDCT & dequant */
       
   328                 dblIdctAndDequant(block, ((i<4)?param->quant:chrQuant), 0);
       
   329 
       
   330                 if (i<4)
       
   331                 {
       
   332                      
       
   333                     blcAddBlock(block, yBlockInFrame,
       
   334                         yWidth, 0, 0, 0);
       
   335                 } 
       
   336                 else 
       
   337                 {
       
   338                     /* U or V component */
       
   339 
       
   340                     blcAddBlock(block, ((i==4)? param->currUBlkInFrame : param->currVBlkInFrame), param->uvWidth, 0, 0, 0);
       
   341                 }
       
   342             }
       
   343              
       
   344         }
       
   345          
       
   346          /* MVE */
       
   347          else
       
   348          {
       
   349              /* this block is not coded */
       
   350              hTranscoder->AddOneBlockDataToMB(i, NULL);          
       
   351          }
       
   352 
       
   353          
       
   354          if ((i<4) && yBlockInFrame)
       
   355          {
       
   356              if (param->reversible_vlc && param->vlc_dec_direction) {
       
   357                  yBlockInFrame -= 8;
       
   358                  if (i == 2)
       
   359                      yBlockInFrame -= ((/*8 **/ yWidth<<3) - 16);
       
   360              } else {
       
   361                  yBlockInFrame += 8;
       
   362                  if (i & 1)
       
   363                      yBlockInFrame += ((/*8 **/ yWidth<<3) - 16);
       
   364              }
       
   365              
       
   366          }
       
   367          else   //u,v
       
   368          {
       
   369              /* nothing here */
       
   370          }
       
   371    }
       
   372 
       
   373      
       
   374      /* MVE */
       
   375    if ( hTranscoder->TranscodingOneMB(param) != TX_OK )
       
   376     {
       
   377     return DMD_ERR;
       
   378     }
       
   379    return DMD_OK;
       
   380 }
       
   381 // End of File