videoeditorengine/h263decoder/src/decmbdct_mpeg.cpp
changeset 0 951a5db380a0
--- /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