/**************************************************************************** * * 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++; } } }
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++; } } }
/**************************************************************************** * * 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++; } } } }
/**************************************************************************** * * 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++; } } } }
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++; } } } }
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; } } }