예제 #1
0
/****************************************************************************
 * 
 *  ROUTINE       :     UpRegulateMB
 *
 *  INPUTS        :     UINT32 RegulationQ
 *						(Q at which we are updating.)
 *
 *						UINT32 SB,MB 
 *                      (MB and SB indentifiers)
 *
 *						BOOL NoCheck
 *						(Should we check previous update Q)
 *
 *  OUTPUTS       :     None.
 *
 *  RETURNS       :     None.
 *
 *  FUNCTION      :     Up regulate specified MB
 *
 *  SPECIAL NOTES :     None. 
 *
 *
 *  ERRORS        :     None.
 *
 ****************************************************************************/
void UpRegulateMB( CP_INSTANCE *cpi, UINT32 RegulationQ, UINT32 SB, UINT32 MB, BOOL NoCheck )
{
	INT32  FragIndex;
	UINT32 B;							// Block indicex

	// Variables used in calculating corresponding row,col and index in UV planes
    UINT32 UVRow;
    UINT32 UVColumn;
    UINT32 UVFragOffset;

	// There may be MB's lying out of frame
	// which must be ignored. For these MB's
	// Top left block will have a negative Fragment Index.
	if ( QuadMapToMBTopLeft(cpi->pb.BlockMap, SB, MB ) >= 0 )
	{
		// Up regulate the component blocks Y then UV.
		for ( B=0; B<4; B++ )
		{
			FragIndex = QuadMapToIndex1( cpi->pb.BlockMap, SB, MB, B );

            if ( ( !cpi->pb.display_fragments[FragIndex] ) &&
				 ( (NoCheck) || (cpi->FragmentLastQ[FragIndex] > RegulationQ) ) )
			{
				cpi->pb.display_fragments[FragIndex] = 1;
				cpi->extra_fragments[FragIndex] = 1;
  				cpi->FragmentLastQ[FragIndex] = RegulationQ;
				cpi->MotionScore++;
			}
		}

		// Check the two UV blocks
		FragIndex = QuadMapToMBTopLeft(cpi->pb.BlockMap, SB, MB );

		UVRow = (FragIndex / (cpi->pb.HFragments * 2));
		UVColumn = (FragIndex % cpi->pb.HFragments) / 2;
		UVFragOffset = (UVRow * (cpi->pb.HFragments / 2)) + UVColumn;
				
		FragIndex = cpi->pb.YPlaneFragments + UVFragOffset;
		if ( ( !cpi->pb.display_fragments[FragIndex] ) &&
			 ( (NoCheck) || (cpi->FragmentLastQ[FragIndex] > RegulationQ) ) )
		{
			cpi->pb.display_fragments[FragIndex] = 1;
			cpi->extra_fragments[FragIndex] = 1;
  			cpi->FragmentLastQ[FragIndex] = RegulationQ;
			cpi->MotionScore++;
		}

		FragIndex += cpi->pb.UVPlaneFragments;
		if ( ( !cpi->pb.display_fragments[FragIndex] ) &&
			 ( (NoCheck) || (cpi->FragmentLastQ[FragIndex] > RegulationQ) ) )
		{
			cpi->pb.display_fragments[FragIndex] = 1;
			cpi->extra_fragments[FragIndex] = 1;
  			cpi->FragmentLastQ[FragIndex] = RegulationQ;
			cpi->MotionScore++;
		}
	}
}
예제 #2
0
static void UpRegulateMB( CP_INSTANCE *cpi, ogg_uint32_t RegulationQ,
                   ogg_uint32_t SB, ogg_uint32_t MB, int NoCheck ) {
  ogg_int32_t  FragIndex;
  ogg_uint32_t B;

  /* Variables used in calculating corresponding row,col and index in
     UV planes */
  ogg_uint32_t UVRow;
  ogg_uint32_t UVColumn;
  ogg_uint32_t UVFragOffset;

  /* There may be MB's lying out of frame which must be ignored. For
   these MB's Top left block will have a negative Fragment Index. */
  if ( QuadMapToMBTopLeft(cpi->pb.BlockMap, SB, MB ) >= 0 ) {
    /* Up regulate the component blocks Y then UV. */
    for ( B=0; B<4; B++ ){
      FragIndex = QuadMapToIndex1( cpi->pb.BlockMap, SB, MB, B );

      if ( ( !cpi->pb.display_fragments[FragIndex] ) &&
           ( (NoCheck) || (cpi->FragmentLastQ[FragIndex] > RegulationQ) ) ){
        cpi->pb.display_fragments[FragIndex] = 1;
        cpi->extra_fragments[FragIndex] = 1;
        cpi->FragmentLastQ[FragIndex] = RegulationQ;
        cpi->MotionScore++;
      }
    }

    /* Check the two UV blocks */
    FragIndex = QuadMapToMBTopLeft(cpi->pb.BlockMap, SB, MB );

    UVRow = (FragIndex / (cpi->pb.HFragments * 2));
    UVColumn = (FragIndex % cpi->pb.HFragments) / 2;
    UVFragOffset = (UVRow * (cpi->pb.HFragments / 2)) + UVColumn;

    FragIndex = cpi->pb.YPlaneFragments + UVFragOffset;
    if ( ( !cpi->pb.display_fragments[FragIndex] ) &&
         ( (NoCheck) || (cpi->FragmentLastQ[FragIndex] > RegulationQ) ) ) {
      cpi->pb.display_fragments[FragIndex] = 1;
      cpi->extra_fragments[FragIndex] = 1;
      cpi->FragmentLastQ[FragIndex] = RegulationQ;
      cpi->MotionScore++;
    }

    FragIndex += cpi->pb.UVPlaneFragments;
    if ( ( !cpi->pb.display_fragments[FragIndex] ) &&
         ( (NoCheck) || (cpi->FragmentLastQ[FragIndex] > RegulationQ) ) ) {
      cpi->pb.display_fragments[FragIndex] = 1;
      cpi->extra_fragments[FragIndex] = 1;
      cpi->FragmentLastQ[FragIndex] = RegulationQ;
      cpi->MotionScore++;
    }
  }
}
예제 #3
0
/****************************************************************************
 * 
 *  ROUTINE       :     QuadDeCodeDisplayFragments2
 *
 *  INPUTS        :     PB instance
 *
 *  OUTPUTS       :     Mapping table BlockMap[SuperBlock][MacroBlock][Block]
 *
 *  RETURNS       :     None.
 *
 *  FUNCTION      :     Creates mapping table between (SuperBlock, MacroBlock, Block)
 *						triplet and corresponding Fragment Index.
 *
 *  SPECIAL NOTES :     None. 
 *
 *
 *  ERRORS        :     None.
 *
 ****************************************************************************/
void QuadDecodeDisplayFragments2 ( PB_INSTANCE *pbi )
{
	UINT32	SB, MB, B;	// Super-block, Macro-block and Block values
    BOOL    DataToDecode = FALSE; 

	INT32   dfIndex;
	UINT32  MBIndex = 0;

	UINT8 * MBFully;
	UINT8 * MBCoded;

	UINT8   BPattern;

	// Set up local pointers
	MBFully = pbi->MBFullyFlags;
	MBCoded = pbi->MBCodedFlags;

	// Reset various data structures common to key frames and inter frames.
	pbi->CodedBlockIndex = 0;
	memset( pbi->display_fragments, 0, pbi->UnitFragments );

    // For "Key frames" mark all blocks as coded and return.
    // Else initialise the ArrayPtr array to 0 (all blocks uncoded by default) 
	if ( GetFrameType(pbi) == BASE_FRAME )
    {
        memset( MBFully, 1, pbi->MacroBlocks );
    }
    else
    {
        memset( MBFully, 0, pbi->MacroBlocks );
	    memset( MBCoded, 0, pbi->MacroBlocks );

		// Un-pack MBlist1
		GetNextMbInit(pbi);
		for( MB = 0; MB < pbi->MacroBlocks; MB++)
		{
			MBFully[MB] = GetNextMbBit (pbi);
		}

		// If there are any macro blocks that are not fully coded then there is more to do.
		for( MB = 0; MB < pbi->MacroBlocks; MB++ )
		{
			if ( !MBFully[MB] )
			{
				DataToDecode = TRUE;
				break;
			}
		}

		// Build the coded MB list (Fully or partially coded)
		if ( DataToDecode )
		{
			// Un-pack MBlist2
			GetNextMbInit(pbi);
			for( MB = 0; MB < pbi->MacroBlocks; MB++)
			{
				if ( !MBFully[MB] )
					MBCoded[MB] = GetNextMbBit( pbi );
			}

		}
	}

	// Complete the block and macro block coded data structures.
	// Initialise the block pattern reader.
	ReadBlockPatternInit(pbi);

	// Follow the quad tree structure
	for ( SB=0; SB < pbi->SuperBlocks; SB++ )
	{
		for ( MB=0; MB<4; MB++ )
		{
            // If MB is in the frame
			if ( QuadMapToMBTopLeft(pbi->BlockMap, SB,MB) >= 0 )
            {
				// Set or read the block pattern for the macro block#
				if ( MBFully[MBIndex] )
				{
					MBCoded[MBIndex] = 1;
					BPattern = 0x0F;
				}
				else if ( MBCoded[MBIndex] )
				{
					BPattern = ReadNextBlockPattern(pbi);
				}
				else
				{
					BPattern = 0;
				}

				for ( B=0; B<4; B++ )
			    {
                    // If block is valid (in frame)...
                    dfIndex = QuadMapToIndex2( pbi->BlockMap, SB, MB, B );
				    if ( dfIndex >= 0 )
				    {
						// Work out if this block is coded or not.
						pbi->display_fragments[dfIndex] = (BPattern & BlockPatternMask[B]) ? 1 : 0;
				    }
			    }

				for ( B=0; B<4; B++ )
			    {
                    // If block is valid (in frame)...
                    dfIndex = QuadMapToIndex1( pbi->BlockMap, SB, MB, B );
				    if ( dfIndex >= 0 )
				    {
						if ( pbi->display_fragments[dfIndex] )
						{
							pbi->CodedBlockList[pbi->CodedBlockIndex] = dfIndex;
							pbi->CodedBlockIndex++;
						}
				    }
			    }

				// Increment the MB index.
				MBIndex++;
            }
		}
    }
}
예제 #4
0
/****************************************************************************
 * 
 *  ROUTINE       :     QuadDeCodeDisplayFragments
 *
 *  INPUTS        :     PB instance
 *
 *  OUTPUTS       :     Mapping table BlockMap[SuperBlock][MacroBlock][Block]
 *
 *  RETURNS       :     None.
 *
 *  FUNCTION      :     Creates mapping table between (SuperBlock, MacroBlock, Block)
 *						triplet and corresponding Fragment Index.
 *
 *  SPECIAL NOTES :     None. 
 *
 *
 *  ERRORS        :     None.
 *
 ****************************************************************************/
void QuadDecodeDisplayFragments ( PB_INSTANCE *pbi )
{
	UINT32	SB, MB, B;		// Super-block, Macro-block and Block values
    BOOL    DataToDecode; 

    INT32   dfIndex;
	UINT32  MBIndex = 0;

	// Reset various data structures common to key frames and inter frames.
	pbi->CodedBlockIndex = 0;
	memset ( pbi->display_fragments, 0, pbi->UnitFragments );

    // For "Key frames" mark all blocks as coded and return.
    // Else initialise the ArrayPtr array to 0 (all blocks uncoded by default) 
	if ( GetFrameType(pbi) == BASE_FRAME )
    {
        memset( pbi->SBFullyFlags, 1, pbi->SuperBlocks );
        memset( pbi->SBCodedFlags, 1, pbi->SuperBlocks );
        memset( pbi->MBCodedFlags, 0, pbi->MacroBlocks );
    }
    else
    {
        memset( pbi->SBFullyFlags, 0, pbi->SuperBlocks );
        memset( pbi->MBCodedFlags, 0, pbi->MacroBlocks );

		// Un-pack the list of partially coded Super-Blocks
		GetNextSbInit(pbi);
		for( SB = 0; SB < pbi->SuperBlocks; SB++)
		{
			pbi->SBCodedFlags[SB] = GetNextSbBit (pbi);
		}

		// Scan through the list of super blocks. 
		// Unless all are marked as partially coded we have more to do.
		DataToDecode = FALSE; 
		for ( SB=0; SB<pbi->SuperBlocks; SB++ )
		{
			if ( !pbi->SBCodedFlags[SB] )
			{
				DataToDecode = TRUE;
				break;
			}
		}

		// Are there further block map bits to decode ?
		if ( DataToDecode )
		{
			// Un-pack the Super-Block fully coded flags.
			GetNextSbInit(pbi);
			for( SB = 0; SB < pbi->SuperBlocks; SB++)
			{
				// Skip blocks already marked as partially coded
				while( (SB < pbi->SuperBlocks) && pbi->SBCodedFlags[SB] )  
					SB++;

				if ( SB < pbi->SuperBlocks )
				{
					pbi->SBFullyFlags[SB] = GetNextSbBit (pbi);

					if ( pbi->SBFullyFlags[SB] )         // If SB is fully coded.
						pbi->SBCodedFlags[SB] = 1;       // Mark the SB as coded
				}
			}
		}

		// Scan through the list of coded super blocks.
		// If at least one is marked as partially coded then we have a block list to decode.
		for ( SB=0; SB<pbi->SuperBlocks; SB++ )
		{
			if ( pbi->SBCodedFlags[SB] && !pbi->SBFullyFlags[SB] )
			{
				// Initialise the block list decoder.
				GetNextBInit(pbi);
				break;
			}
		}
	}

	// Decode the block data from the bit stream.
	for ( SB=0; SB<pbi->SuperBlocks; SB++ )
	{
		for ( MB=0; MB<4; MB++ )
		{
            // If MB is in the frame
			if ( QuadMapToMBTopLeft(pbi->BlockMap, SB,MB) >= 0 )
            {
				// Only read block level data if SB was fully or partially coded
				if ( pbi->SBCodedFlags[SB] )
				{
					for ( B=0; B<4; B++ )
					{
						// If block is valid (in frame)...
						dfIndex = QuadMapToIndex1( pbi->BlockMap, SB, MB, B );
						if ( dfIndex >= 0 )
						{
							if ( pbi->SBFullyFlags[SB] )
								pbi->display_fragments[dfIndex] = 1;
							else
								pbi->display_fragments[dfIndex] = GetNextBBit(pbi);

							// Create linear list of coded block indices
							if ( pbi->display_fragments[dfIndex] )
							{
								pbi->MBCodedFlags[MBIndex] = 1;
								pbi->CodedBlockList[pbi->CodedBlockIndex] = dfIndex;
								pbi->CodedBlockIndex++;
							}
						}
					}
				}
				MBIndex++;

            }
		}
    }
}
예제 #5
0
void QuadDecodeDisplayFragments ( PB_INSTANCE *pbi ){
  ogg_uint32_t  SB, MB, B;
  int    DataToDecode;

  ogg_int32_t   dfIndex;
  ogg_uint32_t  MBIndex = 0;

  /* Reset various data structures common to key frames and inter frames. */
  pbi->CodedBlockIndex = 0;
  memset ( pbi->display_fragments, 0, pbi->UnitFragments );

  /* For "Key frames" mark all blocks as coded and return. */
  /* Else initialise the ArrayPtr array to 0 (all blocks uncoded by default) */
  if ( GetFrameType(pbi) == BASE_FRAME ) {
    memset( pbi->SBFullyFlags, 1, pbi->SuperBlocks );
    memset( pbi->SBCodedFlags, 1, pbi->SuperBlocks );
        memset( pbi->MBCodedFlags, 0, pbi->MacroBlocks );
  }else{
    memset( pbi->SBFullyFlags, 0, pbi->SuperBlocks );
    memset( pbi->MBCodedFlags, 0, pbi->MacroBlocks );

    /* Un-pack the list of partially coded Super-Blocks */
    GetNextSbInit(pbi);
    for( SB = 0; SB < pbi->SuperBlocks; SB++){
      pbi->SBCodedFlags[SB] = GetNextSbBit (pbi);
    }

    /* Scan through the list of super blocks.  Unless all are marked
       as partially coded we have more to do. */
    DataToDecode = 0;
    for ( SB=0; SB<pbi->SuperBlocks; SB++ ) {
      if ( !pbi->SBCodedFlags[SB] ) {
        DataToDecode = 1;
        break;
      }
    }

    /* Are there further block map bits to decode ? */
    if ( DataToDecode ) {
      /* Un-pack the Super-Block fully coded flags. */
      GetNextSbInit(pbi);
      for( SB = 0; SB < pbi->SuperBlocks; SB++) {
        /* Skip blocks already marked as partially coded */
        while( (SB < pbi->SuperBlocks) && pbi->SBCodedFlags[SB] )
          SB++;

        if ( SB < pbi->SuperBlocks ) {
          pbi->SBFullyFlags[SB] = GetNextSbBit (pbi);

          if ( pbi->SBFullyFlags[SB] )       /* If SB is fully coded. */
            pbi->SBCodedFlags[SB] = 1;       /* Mark the SB as coded */
        }
      }
    }

    /* Scan through the list of coded super blocks.  If at least one
       is marked as partially coded then we have a block list to
       decode. */
    for ( SB=0; SB<pbi->SuperBlocks; SB++ ) {
      if ( pbi->SBCodedFlags[SB] && !pbi->SBFullyFlags[SB] ) {
        /* Initialise the block list decoder. */
        GetNextBInit(pbi);
        break;
      }
    }
  }

  /* Decode the block data from the bit stream. */
  for ( SB=0; SB<pbi->SuperBlocks; SB++ ){
    for ( MB=0; MB<4; MB++ ){
      /* If MB is in the frame */
      if ( QuadMapToMBTopLeft(pbi->BlockMap, SB,MB) >= 0 ){
        /* Only read block level data if SB was fully or partially coded */
        if ( pbi->SBCodedFlags[SB] ) {
          for ( B=0; B<4; B++ ){
            /* If block is valid (in frame)... */
            dfIndex = QuadMapToIndex1( pbi->BlockMap, SB, MB, B );
            if ( dfIndex >= 0 ){
              if ( pbi->SBFullyFlags[SB] )
                pbi->display_fragments[dfIndex] = 1;
              else
                pbi->display_fragments[dfIndex] = GetNextBBit(pbi);

              /* Create linear list of coded block indices */
              if ( pbi->display_fragments[dfIndex] ) {
                pbi->MBCodedFlags[MBIndex] = 1;
                pbi->CodedBlockList[pbi->CodedBlockIndex] = dfIndex;
                pbi->CodedBlockIndex++;
              }
            }
          }
        }
        MBIndex++;

      }
    }
  }
}
예제 #6
0
void PackAndWriteDFArray( CP_INSTANCE *cpi ){
  ogg_uint32_t  i;
  unsigned char val;
  ogg_uint32_t  run_count;

  ogg_uint32_t  SB, MB, B;   /* Block, MB and SB loop variables */
  ogg_uint32_t  BListIndex = 0;
  ogg_uint32_t  LastSbBIndex = 0;
  ogg_int32_t   DfBlockIndex;  /* Block index in display_fragments */

  /* Initialise workspaces */
  memset( cpi->pb.SBFullyFlags, 1, cpi->pb.SuperBlocks);
  memset( cpi->pb.SBCodedFlags, 0, cpi->pb.SuperBlocks );
  memset( cpi->PartiallyCodedFlags, 0, cpi->pb.SuperBlocks );
  memset( cpi->BlockCodedFlags, 0, cpi->pb.UnitFragments);

  for( SB = 0; SB < cpi->pb.SuperBlocks; SB++ ) {
    /* Check for coded blocks and macro-blocks */
    for ( MB=0; MB<4; MB++ ) {
      /* If MB in frame */
      if ( QuadMapToMBTopLeft(cpi->pb.BlockMap,SB,MB) >= 0 ) {
        for ( B=0; B<4; B++ ) {
          DfBlockIndex = QuadMapToIndex1( cpi->pb.BlockMap,SB, MB, B );

          /* Does Block lie in frame: */
          if ( DfBlockIndex >= 0 ) {
            /* In Frame: If it is not coded then this SB is only
               partly coded.: */
            if ( cpi->pb.display_fragments[DfBlockIndex] ) {
              cpi->pb.SBCodedFlags[SB] = 1; /* SB at least partly coded */
              cpi->BlockCodedFlags[BListIndex] = 1; /* Block is coded */
            }else{
              cpi->pb.SBFullyFlags[SB] = 0; /* SB not fully coded */
              cpi->BlockCodedFlags[BListIndex] = 0; /* Block is not coded */
            }

            BListIndex++;
          }
        }
      }
    }

    /* Is the SB fully coded or uncoded.
       If so then backup BListIndex and MBListIndex */
    if ( cpi->pb.SBFullyFlags[SB] || !cpi->pb.SBCodedFlags[SB] ) {
      BListIndex = LastSbBIndex; /* Reset to values from previous SB */
    }else{
      cpi->PartiallyCodedFlags[SB] = 1; /* Set up list of partially
                                           coded SBs */
      LastSbBIndex = BListIndex;
    }
  }

  /* Code list of partially coded Super-Block.  */
  val = cpi->PartiallyCodedFlags[0];
  oggpackB_write( cpi->oggbuffer, (ogg_uint32_t)val, 1);
  i = 0;
  while ( i < cpi->pb.SuperBlocks ) {
    run_count = 0;
    while ( (i<cpi->pb.SuperBlocks) && (cpi->PartiallyCodedFlags[i]==val) ) {
      i++;
      run_count++;
    }

    /* Code the run */
    FrArrayCodeSBRun( cpi, run_count );
    val = ( val == 0 ) ? 1 : 0;
  }

  /* RLC Super-Block fully/not coded. */
  i = 0;

  /* Skip partially coded blocks */
  while( (i < cpi->pb.SuperBlocks) && cpi->PartiallyCodedFlags[i] )
    i++;

  if ( i < cpi->pb.SuperBlocks ) {
    val = cpi->pb.SBFullyFlags[i];
    oggpackB_write( cpi->oggbuffer, (ogg_uint32_t)val, 1);

    while ( i < cpi->pb.SuperBlocks ) {
      run_count = 0;
      while ( (i < cpi->pb.SuperBlocks) && (cpi->pb.SBFullyFlags[i] == val) ) {
        i++;
        /* Skip partially coded blocks */
        while( (i < cpi->pb.SuperBlocks) && cpi->PartiallyCodedFlags[i] )
          i++;
        run_count++;
      }

      /* Code the run */
      FrArrayCodeSBRun( cpi, run_count );
      val = ( val == 0 ) ? 1 : 0;
    }
  }

  /*  Now code the block flags */
  if ( BListIndex > 0 ) {
    /* Code the block flags start value */
    val = cpi->BlockCodedFlags[0];
    oggpackB_write( cpi->oggbuffer, (ogg_uint32_t)val, 1);

    /* Now code the block flags. */
    for ( i = 0; i < BListIndex; ) {
      run_count = 0;
      while ( (cpi->BlockCodedFlags[i] == val) && (i < BListIndex) ) {
        i++;
        run_count++;
      }

      FrArrayCodeBlockRun( cpi, run_count );
      val = ( val == 0 ) ? 1 : 0;

    }
  }
}
예제 #7
0
파일: DDecode.c 프로젝트: kazutomi/xiphqt
/****************************************************************************
 * 
 *  ROUTINE       :     DecodeMVectors
 *
 *  INPUTS        :     None. 
 *                      
 *  OUTPUTS       :     None.
 *
 *  RETURNS       :     None.
 *
 *  FUNCTION      :     Decodes the motion vectors for this frame.
 *
 *  SPECIAL NOTES :     None. 
 *
 *
 *  ERRORS        :     None.
 *
 ****************************************************************************/
void DecodeMVectors ( PB_INSTANCE *pbi, UINT32 SBRows, UINT32 SBCols, UINT32 HExtra, UINT32 VExtra )
{
	INT32	FragIndex;			// Fragment number
	UINT32	MB;		    		// Macro-Block, Block indices
	UINT32	SBrow;				// Super-Block row number
	UINT32	SBcol;				// Super-Block row number
	UINT32	SB=0;			    // Super-Block index
    UINT32  CodingMethod;       // Temp Storage for coding mode.

    MOTION_VECTOR MVect[6];     // temp storage for motion vector
    MOTION_VECTOR TmpMVect;
    MOTION_VECTOR LastInterMV;      // storage for last used Inter frame MB motion vector
    MOTION_VECTOR PriorLastInterMV; // storage for previous last used Inter frame MB motion vector
	INT32 (*ExtractMVectorComponent)(PB_INSTANCE *pbi);

    UINT32  UVRow;
    UINT32  UVColumn;
    UINT32  UVFragOffset;

    UINT32  MBListIndex = 0;

    UINT32  MVCode = 0;         // Temporary storage while decoding the MV

    // Should not be decoding motion vectors if in INTRA only mode.
    if ( GetFrameType(pbi) == BASE_FRAME )
    {
        return;
    }

    // set the default motion vector to 0,0
    MVect[0].x = 0;
    MVect[0].y = 0;
    LastInterMV.x = 0;
    LastInterMV.y = 0;
    PriorLastInterMV.x = 0;
    PriorLastInterMV.y = 0;

    // Read the entropy method used and set up the appropriate decode option
    if ( bitread1( &pbi->br) == 0 )
        ExtractMVectorComponent = ExtractMVectorComponentA;
    else
        ExtractMVectorComponent = ExtractMVectorComponentB;

    // Unravel the quad-tree
	for ( SBrow=0; SBrow<SBRows; SBrow++ )
	{
		for ( SBcol=0; SBcol<SBCols; SBcol++ )
		{
			for ( MB=0; MB<4; MB++ )
			{
				// There may be MB's lying out of frame
				// which must be ignored. For these MB's
				// the top left block will have a negative Fragment Index.
				if ( QuadMapToMBTopLeft(pbi->BlockMap, SB,MB) >= 0 )
				{
					// Is the Macro-Block further coded:
					if ( pbi->MBCodedFlags[MBListIndex++] )
					{
                        // Upack the block level modes and motion vectors
                        FragIndex = QuadMapToMBTopLeft( pbi->BlockMap, SB, MB );

                        // Clear the motion vector before we start.
                        MVect[0].x = 0;
                        MVect[0].y = 0;
                            
                        // Unpack the mode (and motion vectors if necessary).
   		                CodingMethod = pbi->FragCodingMethod[FragIndex];

                        // Read the motion vector or vectors if present. 
                        if ( (CodingMethod == CODE_INTER_PLUS_MV) || 
                             (CodingMethod == CODE_GOLDEN_MV) )
                        {
                            MVect[0].x = ExtractMVectorComponent(pbi); 
                            MVect[1].x = MVect[0].x;
                            MVect[2].x = MVect[0].x;
                            MVect[3].x = MVect[0].x;
                            MVect[4].x = MVect[0].x;
                            MVect[5].x = MVect[0].x;
                            MVect[0].y = ExtractMVectorComponent(pbi); 
                            MVect[1].y = MVect[0].y;
                            MVect[2].y = MVect[0].y;
                            MVect[3].y = MVect[0].y;
                            MVect[4].y = MVect[0].y;
                            MVect[5].y = MVect[0].y;
                        }
                        else if ( CodingMethod == CODE_INTER_FOURMV )
                        {
                            // Extrac the 4 Y MVs
                            MVect[0].x = ExtractMVectorComponent(pbi);
                            MVect[0].y = ExtractMVectorComponent(pbi);

                            MVect[1].x = ExtractMVectorComponent(pbi);
                            MVect[1].y = ExtractMVectorComponent(pbi);
                            
                            MVect[2].x = ExtractMVectorComponent(pbi);
                            MVect[2].y = ExtractMVectorComponent(pbi);
                            
                            MVect[3].x = ExtractMVectorComponent(pbi);
                            MVect[3].y = ExtractMVectorComponent(pbi);

                            // Calculate the U and V plane MVs as the average of the Y plane MVs.
                            // First .x component
                            MVect[4].x = MVect[0].x + MVect[1].x + MVect[2].x + MVect[3].x;
                            if ( MVect[4].x >= 0 )
                                MVect[4].x = (MVect[4].x + 2) / 4;
                            else
                                MVect[4].x = (MVect[4].x - 2) / 4;
                            MVect[5].x = MVect[4].x;
                            // Then .y component
                            MVect[4].y = MVect[0].y + MVect[1].y + MVect[2].y + MVect[3].y;
                            if ( MVect[4].y >= 0 )
                                MVect[4].y = (MVect[4].y + 2) / 4;
                            else
                                MVect[4].y = (MVect[4].y - 2) / 4;
                            MVect[5].y = MVect[4].y;
                        }

                        // Keep track of last and prior last inter motion vectors.
                        if ( CodingMethod == CODE_INTER_PLUS_MV )
                        {
                            PriorLastInterMV.x = LastInterMV.x;
                            PriorLastInterMV.y = LastInterMV.y;
                            LastInterMV.x = MVect[0].x;
                            LastInterMV.y = MVect[0].y;
                        }
                        else if ( CodingMethod == CODE_INTER_LAST_MV )
                        {
                            // Use the last coded Inter motion vector.
                            MVect[0].x = LastInterMV.x;
                            MVect[1].x = MVect[0].x;
                            MVect[2].x = MVect[0].x;
                            MVect[3].x = MVect[0].x;
                            MVect[4].x = MVect[0].x;
                            MVect[5].x = MVect[0].x;
                            MVect[0].y = LastInterMV.y;
                            MVect[1].y = MVect[0].y;
                            MVect[2].y = MVect[0].y;
                            MVect[3].y = MVect[0].y;
                            MVect[4].y = MVect[0].y;
                            MVect[5].y = MVect[0].y;
                        }
                        else if ( CodingMethod == CODE_INTER_PRIOR_LAST )
                        {
                            // Use the last coded Inter motion vector.
                            MVect[0].x = PriorLastInterMV.x;
                            MVect[1].x = MVect[0].x;
                            MVect[2].x = MVect[0].x;
                            MVect[3].x = MVect[0].x;
                            MVect[4].x = MVect[0].x;
                            MVect[5].x = MVect[0].x;
                            MVect[0].y = PriorLastInterMV.y;
                            MVect[1].y = MVect[0].y;
                            MVect[2].y = MVect[0].y;
                            MVect[3].y = MVect[0].y;
                            MVect[4].y = MVect[0].y;
                            MVect[5].y = MVect[0].y;

                            // Swap the prior and last MV cases over
                            TmpMVect.x = PriorLastInterMV.x;
                            TmpMVect.y = PriorLastInterMV.y;
                            PriorLastInterMV.x = LastInterMV.x;
                            PriorLastInterMV.y = LastInterMV.y;
                            LastInterMV.x = TmpMVect.x;
                            LastInterMV.y = TmpMVect.y;
                        }
                        else if ( CodingMethod == CODE_INTER_FOURMV )
                        {
                            // Update last MV and prior last mv
                            PriorLastInterMV.x = LastInterMV.x;
                            PriorLastInterMV.y = LastInterMV.y;
                            LastInterMV.x = MVect[3].x;
                            LastInterMV.y = MVect[3].y;
                        }

                        // Note the coding mode and vector for each block in the current macro block.
                        pbi->FragMVect[FragIndex].x = MVect[0].x;
                        pbi->FragMVect[FragIndex].y = MVect[0].y;
                
                        pbi->FragMVect[FragIndex + 1].x = MVect[1].x;
                        pbi->FragMVect[FragIndex + 1].y = MVect[1].y;

                        pbi->FragMVect[FragIndex + pbi->HFragments].x = MVect[2].x;
                        pbi->FragMVect[FragIndex + pbi->HFragments].y = MVect[2].y;

                        pbi->FragMVect[FragIndex + pbi->HFragments + 1].x = MVect[3].x;
                        pbi->FragMVect[FragIndex + pbi->HFragments + 1].y = MVect[3].y;

                        // Matching fragments in the U and V planes
                        UVRow = (FragIndex / (pbi->HFragments * 2));
                        UVColumn = (FragIndex % pbi->HFragments) / 2;
                        UVFragOffset = (UVRow * (pbi->HFragments / 2)) + UVColumn;

                        pbi->FragMVect[pbi->YPlaneFragments + UVFragOffset].x = MVect[4].x;
                        pbi->FragMVect[pbi->YPlaneFragments + UVFragOffset].y = MVect[4].y;

                        pbi->FragMVect[pbi->YPlaneFragments + pbi->UVPlaneFragments + UVFragOffset].x = MVect[5].x;
                        pbi->FragMVect[pbi->YPlaneFragments + pbi->UVPlaneFragments + UVFragOffset].y = MVect[5].y;
					}
				}
			}

			// Next Super-Block
			SB++;
		}
	}
}
예제 #8
0
파일: DDecode.c 프로젝트: kazutomi/xiphqt
/****************************************************************************
 * 
 *  ROUTINE       :     DecodeModes
 *
 *  INPUTS        :     None. 
 *                      
 *  OUTPUTS       :     Reconstructed frame.
 *
 *  RETURNS       :     None.
 *
 *  FUNCTION      :     Decodes the coding mode list for this frame.
 *
 *  SPECIAL NOTES :     None. 
 *
 *
 *  ERRORS        :     None.
 *
 ****************************************************************************/
void DecodeModes( PB_INSTANCE *pbi, UINT32 SBRows, UINT32 SBCols, UINT32 HExtra, UINT32 VExtra )
{
	INT32	FragIndex;			// Fragment number
	UINT32	MB;	    			// Macro-Block, Block indices
	UINT32	SBrow;				// Super-Block row number
	UINT32	SBcol;				// Super-Block row number
	UINT32	SB=0;			    // Super-Block index
    CODING_MODE  CodingMethod;  // Temp Storage for coding mode.

    UINT32  UVRow;
    UINT32  UVColumn;
    UINT32  UVFragOffset;
    
    UINT32  CodingScheme;       // Coding scheme used to code modes.

    UINT32  MBListIndex = 0;

    UINT32  i;

    // If the frame is an intra frame then all blocks have mode intra.
    if ( GetFrameType(pbi) == BASE_FRAME )
    {
        for ( i = 0; i < pbi->UnitFragments; i++ )
        {
            pbi->FragCodingMethod[i] = CODE_INTRA;
        }
    }
    else
    {
        UINT32  ModeEntry;                            // Mode bits read  

        // Read the coding method
        CodingScheme = bitread( &pbi->br,  MODE_METHOD_BITS );  

        // If the coding method is method 0 then we have to read in a custom coding scheme
        if ( CodingScheme == 0 )
        {
            // Read the coding scheme.
            for ( i = 0; i < MAX_MODES; i++ )
            {
                ModeAlphabet[0][ bitread( &pbi->br,  MODE_BITS) ] = (CODING_MODE)i;
            }
        }

	    // Unravel the quad-tree
	    for ( SBrow=0; SBrow<SBRows; SBrow++ )
	    {
		    for ( SBcol=0; SBcol<SBCols; SBcol++ )
		    {
				for ( MB=0; MB<4; MB++ )
				{
					// There may be MB's lying out of frame
					// which must be ignored. For these MB's
					// top left block will have a negative Fragment Index.
    				if ( QuadMapToMBTopLeft(pbi->BlockMap, SB,MB) >= 0 )
					{
						// Is the Macro-Block coded:
						if ( pbi->MBCodedFlags[MBListIndex++] )
						{
                            // Upack the block level modes and motion vectors
                            FragIndex = QuadMapToMBTopLeft( pbi->BlockMap, SB, MB );
                        
                            // Unpack the mode.
                            if ( CodingScheme == (MODE_METHODS-1) )
                            {
                                // This is the fall back coding scheme.
                                // Simply MODE_BITS bits per mode entry.
                                CodingMethod = (CODING_MODE)bitread( &pbi->br,  MODE_BITS );
                            }
                            else
                            {
                                ModeEntry = FrArrayUnpackMode(pbi);
                                CodingMethod =  ModeAlphabet[CodingScheme][ ModeEntry ];
                            }

                            // Note the coding mode for each block in macro block.
                            pbi->FragCodingMethod[FragIndex] = CodingMethod;
                            pbi->FragCodingMethod[FragIndex + 1] = CodingMethod;
                            pbi->FragCodingMethod[FragIndex + pbi->HFragments] = CodingMethod;
                            pbi->FragCodingMethod[FragIndex + pbi->HFragments + 1] = CodingMethod;

                            // Matching fragments in the U and V planes
                            UVRow = (FragIndex / (pbi->HFragments * 2));
                            UVColumn = (FragIndex % pbi->HFragments) / 2;
                            UVFragOffset = (UVRow * (pbi->HFragments / 2)) + UVColumn;

                            pbi->FragCodingMethod[pbi->YPlaneFragments + UVFragOffset] = CodingMethod;
                            pbi->FragCodingMethod[pbi->YPlaneFragments + pbi->UVPlaneFragments + UVFragOffset] = CodingMethod;

						}
					}
			    }

			    // Next Super-Block
			    SB++;
		    }
	    }
    }
}