Ejemplo n.º 1
0
/****************************************************************************
 * 
 *  ROUTINE       :     ReadNextBlockPattern
 *
 *  INPUTS        :     None. 
 *                      
 *  OUTPUTS       :     None.
 *
 *  RETURNS       :     A pattern of coded or uncoded blocks for a macro block.
 *
 *  FUNCTION      :     Returns the block pattern for the next macro block.
 *
 *  SPECIAL NOTES :     None. 
 *
 *
 *  ERRORS        :     None.
 *
 ****************************************************************************/
UINT8 ReadNextBlockPattern (PB_INSTANCE *pbi)
{
	UINT8 BlockPattern = 0;
	UINT8 Bitpattern = 0;
	UINT32 BitCount = 3;

	// Read three bits and test to see if we have a valid token.
	Bitpattern = bitread(&pbi->br, 3);

	// Test pattern to see if is a valid token.
	BlockPattern = BlockDecode1[pbi->BlockPatternPredictor][Bitpattern];

	// if pattern was not a valid token
	if ( !BlockPattern )
	{
		BitCount++;
		Bitpattern = (Bitpattern << 1) + bitread1(&pbi->br);

		// Test pattern to see if is a valid token.
		BlockPattern = BlockDecode2[pbi->BlockPatternPredictor][Bitpattern];

		if ( !BlockPattern )
		{
			BitCount++;
			Bitpattern = (Bitpattern << 1) + bitread1(&pbi->br);
			BlockPattern = BlockDecode3[pbi->BlockPatternPredictor][Bitpattern];
		}
	}

	// Update the entropy predictor for next time.
	pbi->BlockPatternPredictor = BPPredictor[BlockPattern];

	return BlockPattern;
}
Ejemplo n.º 2
0
/****************************************************************************
 * 
 *  ROUTINE       :     GetNextSbInitSb
 *
 *  INPUTS        :     None. 
 *                      
 *  OUTPUTS       :     None.
 *
 *  RETURNS       :     None
 *
 *  FUNCTION      :     Initialises decode process for an SB RLC stream.
 *
 *  SPECIAL NOTES :     None. 
 *
 *
 *  ERRORS        :     None.
 *
 ****************************************************************************/
void GetNextSbInit(PB_INSTANCE *pbi)
{
	pbi->NextBit = bitread1(&pbi->br);

	// Read run length
	FrArrayDeCodeInit(pbi);               
	while ( FrArrayDeCodeSBRun( pbi,bitread1(&pbi->br), &pbi->BitsLeft ) == FALSE );
}
Ejemplo n.º 3
0
/****************************************************************************
 * 
 *  ROUTINE       :     ExtractMVectorComponentA
 *
 *  INPUTS        :     None. 
 *                      
 *  OUTPUTS       :     None.
 *
 *  RETURNS       :     None.
 *
 *  FUNCTION      :     Extracts a motion vector component coded with method A.
 *
 *  SPECIAL NOTES :     None. 
 *
 *
 *  ERRORS        :     None.
 *
 ****************************************************************************/
INT32 ExtractMVectorComponentA(PB_INSTANCE *pbi)
{
    INT32   MVectComponent;     // temp storage for motion vector
    UINT32  MVCode = 0;         // Temporary storage while decoding the MV
    UINT32  ExtraBits = 0;

    // Get group to which coded component belongs
    MVCode = bitread( &pbi->br,  3 ); 

    //  Now extract the appropriate number of bits to identify the component
    switch ( MVCode )
    {
    case 0:
        MVectComponent = 0;
        break;
    case 1:
        MVectComponent = 1;
        break;
    case 2:
        MVectComponent = -1;
        break;
    case 3:
        if ( bitread1( &pbi->br ))
            MVectComponent = -2;
        else 
            MVectComponent = 2;
        break;
    case 4:
        if ( bitread1( &pbi->br ) )
            MVectComponent = -3;
        else 
            MVectComponent = 3;
        break;
    case 5:
        ExtraBits = bitread( &pbi->br,  2 ); 
        MVectComponent = 4 + ExtraBits;
        if ( bitread1( &pbi->br ) )
            MVectComponent = -MVectComponent;
        break;
    case 6:
        ExtraBits = bitread( &pbi->br,  3 ); 
        MVectComponent = 8 + ExtraBits;
        if ( bitread1( &pbi->br ))
            MVectComponent = -MVectComponent;
        break;
    case 7:
        ExtraBits = bitread( &pbi->br,  4 ); 
        MVectComponent = 16 + ExtraBits;
        if ( bitread1( &pbi->br ) )
            MVectComponent = -MVectComponent;
        break;
    }

    return MVectComponent;
}
Ejemplo n.º 4
0
BOOL LoadFrameHeader(PB_INSTANCE *pbi)
{
	UINT8  VersionByte0;    // Must be 0 for VP30b and later
    UINT8  DctQMask;
    UINT8  SpareBits;       // Spare cfg bits
	UINT8  Unused;

    BOOL   RetVal = TRUE;

    // Is the frame and inter frame or a key frame
    pbi->FrameType = bitread1(&pbi->br);
    
	// unused bit
    Unused = bitread1(&pbi->br);

    // Quality (Q) index
    DctQMask = (UINT8)bitread( &pbi->br,   6 );

	// If the frame was a base frame then read the frame dimensions and build a bitmap structure. 
	if ( (pbi->FrameType == BASE_FRAME) )
	{
        // Read the frame dimensions bytes (0,0 indicates vp31 or later)
    	VersionByte0 = (UINT8)bitread( &pbi->br,   8 );
	    pbi->Vp3VersionNo = (UINT8)bitread( &pbi->br,   5 );

		if(pbi->Vp3VersionNo > CURRENT_DECODE_VERSION)
		{
			RetVal = FALSE;
			return RetVal;
		}
		// Initialise version specific quantiser values
		InitQTables( pbi );

        // Read the type / coding method for the key frame.
        pbi->KeyFrameType = (UINT8)bitread( &pbi->br,   1 );

        SpareBits = (UINT8)bitread( &pbi->br,   2 );


        // Select huffman tables
		SelectHuffmanSet( pbi );

    }
	
	// Set this frame quality value from Q Index
    pbi->ThisFrameQualityValue = pbi->QThreshTable[DctQMask];

    return RetVal;                    
}
Ejemplo n.º 5
0
/****************************************************************************
 * 
 *  ROUTINE       :     ExtractMVectorComponentB
 *
 *  INPUTS        :     None. 
 *                      
 *  OUTPUTS       :     None.
 *
 *  RETURNS       :     None.
 *
 *  FUNCTION      :     Extracts an MV component coded using the fallback method
 *
 *  SPECIAL NOTES :     None. 
 *
 *
 *  ERRORS        :     None.
 *
 ****************************************************************************/
INT32 ExtractMVectorComponentB(PB_INSTANCE *pbi)
{
    INT32   MVectComponent;     // temp storage for motion vector

    // Get group to which coded component belongs
    MVectComponent = bitread( &pbi->br,  5 ); 
    if ( bitread1( &pbi->br ) )
        MVectComponent = -MVectComponent;

    return MVectComponent;
}
Ejemplo n.º 6
0
/****************************************************************************
 * 
 *  ROUTINE       :     ExtractToken
 *
 *  INPUTS        :     INT8 * ExpandedBlock
 *                             Pointer to block structure into which the token
 *                             should be expanded.
 *
 *                      UINT32 * CoeffIndex
 *                             Where we are in the current block.
 *
 *  OUTPUTS       :     
 *
 *  RETURNS       :     The number of bits decoded
 *
 *  FUNCTION      :     Unpacks and expands an DC DCT token.
 *
 *  SPECIAL NOTES :     PROBLEM !!!!!!!!!!!   right now handles only left 
 *                      justified bits in bitreader.  the c version keeps every
 *                      thing in place so I can't use it!!
 *                      
 *
 *
 *  ERRORS        :     None.
 *
 ****************************************************************************/
UINT32 ExtractToken(BITREADER *br, HUFF_ENTRY * CurrentRoot)
{
	UINT32 Token;
    // Loop searches down through tree based upon bits read from the bitstream 
    // until it hits a leaf at which point we have decoded a token
	while ( CurrentRoot->Value < 0 )
    {
		
		if ( bitread1(br) )
            CurrentRoot = (HUFF_ENTRY *)(CurrentRoot->OneChild);
        else
            CurrentRoot = (HUFF_ENTRY *)(CurrentRoot->ZeroChild);

    }
    Token = CurrentRoot->Value; 
	return Token;
}
Ejemplo n.º 7
0
/****************************************************************************
 * 
 *  ROUTINE       :     GetNextSbBit
 *
 *  INPUTS        :     None. 
 *                      
 *  OUTPUTS       :     None.
 *
 *  RETURNS       :     Value of next bit in stream.
 *
 *  FUNCTION      :     Returns next available bit value from an SB RLC stream.
 *
 *  SPECIAL NOTES :     None. 
 *
 *
 *  ERRORS        :     None.
 *
 ****************************************************************************/
UINT8 GetNextSbBit (PB_INSTANCE *pbi)
{
	if ( !pbi->BitsLeft )
	{
		// Toggle the value.  
		pbi->NextBit = ( pbi->NextBit == 1 ) ? 0 : 1;

        // Read next run
		FrArrayDeCodeInit(pbi);               
    	while ( FrArrayDeCodeSBRun( pbi, bitread1(&pbi->br), &pbi->BitsLeft ) == FALSE );
	}

	// Have  read a bit
	pbi->BitsLeft--;
	
	// Return next bit value
	return pbi->NextBit;
}
Ejemplo n.º 8
0
/****************************************************************************
 * 
 *  ROUTINE       :     GetNextSbBit
 *
 *  INPUTS        :     None. 
 *                      
 *  OUTPUTS       :     None.
 *
 *  RETURNS       :     Value of next bit in stream.
 *
 *  FUNCTION      :     Returns next available bit value from a MB RLC stream.
 *
 *  SPECIAL NOTES :     None. 
 *
 *
 *  ERRORS        :     None.
 *
 ****************************************************************************/
UINT8 GetNextMbBit (PB_INSTANCE *pbi)
{
	if ( !pbi->BitsLeft )
	{
		// Toggle the value.  
		pbi->NextBit = ( pbi->NextBit == 1 ) ? 0 : 1;

        // Read next run
		FrArrayDeCodeInit(pbi);       
    	while ( FrArrayDeCodeMBRun( pbi, bitread1(&pbi->br), &pbi->BitsLeft ) == FALSE );
	}

	// Decrement bits left in run counter
	pbi->BitsLeft--;
	
	// Return next bit value
	return pbi->NextBit;
}
Ejemplo n.º 9
0
/****************************************************************************
 * 
 *  ROUTINE       :     FrArrayUnpackMode
 *
 *  INPUTS        :     None
 *
 *  OUTPUTS       :     None
 *
 *  RETURNS       :     A decoded mode token
 *
 *  FUNCTION      :     Unpacks a mode token
 *
 *  SPECIAL NOTES :     None. 
 *
 *
 *  ERRORS        :     None.
 *
 ****************************************************************************/
CODING_MODE FrArrayUnpackMode(PB_INSTANCE *pbi)
{
    // Coding scheme:
	//	Token                       Codeword	    Bits
	//	Entry   0 (most frequent)   0               1
	//	Entry   1       	        10 			    2
	//	Entry   2       	        110 		    3
	//	Entry   3       	        1110 		    4
	//	Entry   4       	        11110 		    5
	//	Entry   5       	        111110 	        6
	//	Entry   6       	        1111110 	    7
	//	Entry   7       	        1111111 	    7

    // Initialise the decoding.
    pbi->bit_pattern = 0;
    pbi->bits_so_far = 0; 

	pbi->bit_pattern = bitread1(&pbi->br);

    // Do we have a match 
    if ( pbi->bit_pattern == 0 )
		return (CODING_MODE)0;

    // Get the next bit
	pbi->bit_pattern = (pbi->bit_pattern << 1) | bitread1(&pbi->br);

    // Do we have a match 
    if ( pbi->bit_pattern == 0x0002 )
		return (CODING_MODE)1;

	pbi->bit_pattern = (pbi->bit_pattern << 1) | bitread1(&pbi->br);

    // Do we have a match 
    if ( pbi->bit_pattern == 0x0006 )
		return (CODING_MODE)2;

	pbi->bit_pattern = (pbi->bit_pattern << 1) | bitread1(&pbi->br);

    // Do we have a match 
    if ( pbi->bit_pattern == 0x000E )
		return (CODING_MODE)3;

	pbi->bit_pattern = (pbi->bit_pattern << 1) | bitread1(&pbi->br);

    // Do we have a match 
    if ( pbi->bit_pattern == 0x001E )
		return (CODING_MODE)4;

	pbi->bit_pattern = (pbi->bit_pattern << 1) | bitread1(&pbi->br);

    // Do we have a match 
    if ( pbi->bit_pattern == 0x003E )
		return (CODING_MODE)5;

	pbi->bit_pattern = (pbi->bit_pattern << 1) | bitread1(&pbi->br);

    // Do we have a match 
    if ( pbi->bit_pattern == 0x007E )
		return (CODING_MODE)6;
    else
		return (CODING_MODE)7;
}
Ejemplo n.º 10
0
/****************************************************************************
 * 
 *  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++;
		}
	}
}