Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View file

@ -0,0 +1,257 @@
/****************************************************************************
*
* Module Title : PreProcOptFunctions.c
*
* Description : MMX or otherwise processor specific
* optimised versions of pre-processor functions
*
* AUTHOR : Paul Wilkins
*
*****************************************************************************
* Revision History
*
* 1.04 YWX 30-Nov-00 Added support for WMT cpu
* 1.03 PGW 24 Jul 00 Added Column SAD function.
* 1.02 YX 06/04/00 Optimized get row sad for xmm
* 1.01 PGW 12/07/99 Changes to reduce uneccessary dependancies.
* 1.00 PGW 14/06/99 Configuration baseline
*
*****************************************************************************
*/
/****************************************************************************
* Header Files
*****************************************************************************
*/
#define STRICT /* Strict type checking. */
#include "preproc.h"
#include "cpuidlib.h"
#pragma warning( disable : 4799 ) // Disable no emms instruction warning!
/****************************************************************************
* Module constants.
*****************************************************************************
*/
/****************************************************************************
* Imports.
*****************************************************************************
*/
/****************************************************************************
* Exported Global Variables
*****************************************************************************
*/
/****************************************************************************
* Exported Functions
*****************************************************************************
*/
/****************************************************************************
* Module Statics
*****************************************************************************
*/
/****************************************************************************
* Forward References
*****************************************************************************
*/
UINT32 MmxRowSAD( UINT8 * Src1, UINT8 * Src2 );
extern UINT32 XmmRowSAD( UINT8 * Src1, UINT8 * Src2 );
/****************************************************************************
*
* ROUTINE : MachineSpecificConfig
*
* INPUTS : None
*
* OUTPUTS : None
*
* RETURNS : None
*
* FUNCTION : Checks for machine specifc features such as MMX support
* sets approipriate flags and function pointers.
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
#define MMX_ENABLED 1
void MachineSpecificConfig(PP_INSTANCE *ppi)
{
UINT32 FeatureFlags = 0;
BOOL CPUID_Supported = TRUE; // Is the CPUID instruction supported
BOOL TestMmx = TRUE;
PROCTYPE CPUType = findCPUId();
switch(CPUType)
{
case X86 :
case PPRO :
case C6X86 :
case C6X86MX:
case AMDK5 :
case MACG3 :
case MAC68K :
ppi->MmxEnabled = FALSE;
ppi->XmmEnabled = FALSE;
break;
case PII :
case AMDK63D:
case AMDK6 :
case PMMX :
ppi->MmxEnabled = TRUE;
ppi->XmmEnabled = FALSE;
break;
case XMM :
case WMT :
ppi->MmxEnabled = TRUE;
ppi->XmmEnabled = TRUE;
break;
}
//To test We force the cpu type here
//ppi->MmxEnabled = FALSE;
//ppi->XmmEnabled = FALSE;
// If MMX supported then set to use MMX versions of functions else
// use original 'C' versions.
if (ppi->XmmEnabled)
{
ppi->RowSAD=XmmRowSAD;
ppi->ColSAD = ScalarColSAD;
}
else if ( ppi->MmxEnabled )
{
ppi->RowSAD = MmxRowSAD;
ppi->ColSAD = ScalarColSAD;
}
else
{
ppi->RowSAD = ScalarRowSAD;
ppi->ColSAD = ScalarColSAD;
}
}
/****************************************************************************
*
* ROUTINE : MmxRowSAD
*
* INPUTS : UINT8 * NewDataPtr (New Data)
* UINT8 * RefDataPtr
*
* OUTPUTS :
*
* RETURNS : Highest of two S.A.D. values.
*
*
* FUNCTION : Calculates the sum of the absolute differences for two groups of
* four pixels and returns the larger of the two.
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
UINT32 MmxRowSAD( UINT8 * NewDataPtr, UINT8 * RefDataPtr )
{
UINT32 SadValue;
UINT32 SadValue1;
UINT32 AbsValues[2];
// MMX code for calculating absolute difference values
__asm
{
pxor mm6, mm6 ; Blank mmx6
pxor mm7, mm7 ; Blank mmx6
mov eax,dword ptr [NewDataPtr] ; Load base addresses
mov ebx,dword ptr [RefDataPtr]
// Calculate eight ABS difference values.
movq mm0, [eax] ; Copy eight bytes to mm0
movq mm1, [ebx] ; Copy eight bytes to mm1
movq mm2, mm0 ; Take copy of MM0
psubusb mm0, mm1 ; A-B to MM0
psubusb mm1, mm2 ; B-A to MM1
por mm0, mm1 ; OR MM0 and MM1 gives abs differences in MM0
movq mm1, mm0 ; keep a copy
// Sum together the low four bytes and the high four bytes
punpcklbw mm0, mm6 ; unpack low four bytes to higher precision
punpckhbw mm1, mm7 ; unpack high four bytes to higher precision
movq mm2, mm0 ; take a copy
movq mm3, mm1 ; take a copy
punpcklwd mm0, mm6 ; unpack low two words to higher precision
punpcklwd mm1, mm7 ; unpack low two words to higher precision
punpckhwd mm2, mm6 ; unpack high low two words to higher precision
punpckhwd mm3, mm7 ; unpack high low two words to higher precision
paddd mm0, mm2 ; Accumulate intermediate results
paddd mm1, mm3 ; Accumulate intermediate results
movq mm2, mm0 ; take a copy
movq mm3, mm1 ; take a copy
punpckhdq mm0, mm6 ; Unpack and accumulate again
punpckhdq mm1, mm7 ; Unpack and accumulate again
punpckldq mm2, mm6
punpckldq mm3, mm7
paddd mm0, mm2 ; Accumulate final result
paddd mm1, mm3 ; Accumulate final result
// Interleave the two SAD results
punpckldq mm0, mm1
// Write back the abs values
movq dword ptr [AbsValues], mm0
}
SadValue = AbsValues[0];
SadValue1 = AbsValues[1];
SadValue = (SadValue > SadValue1) ? SadValue : SadValue1;
return SadValue;
}
/****************************************************************************
*
* ROUTINE : ClearMmxState()
*
*
* INPUTS : None
*
* OUTPUTS :
*
* RETURNS :
*
*
* FUNCTION : Clears down the MMX state
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
void ClearMmxState(PP_INSTANCE *ppi)
{
if ( ppi->MmxEnabled )
{
__asm
{
emms ; Clear the MMX state.
}
}
}

View file

@ -0,0 +1,43 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by PreprocParams.rc
//
#define IDD_VCAP_PARAMS 101
#define IDD_PREPROC_PARAMS 101
#define IDC_VCAP_P_TRESH_SB 1000
#define IDC_VCAP_NOISE_SUP_SB 1001
#define IDC_VCAP_TRIG_SB 1002
#define IDC_SRF_CHECK 1004
#define IDC_SRF_TEMPORAL_CHECK 1005
#define IDC_SC_TRADE_OFF_SB 1005
#define IDC_RSAD_LOW_SB 1006
#define IDC_VCAP_PUV_TRESH_SB 1007
#define IDC_SGC_TRESH_SB 1008
#define IDC_SGC_TRIGGER_SB 1009
#define IDC_SGC_UV_TRESH_SB 1010
#define IDC_VCAP_BAR_THRESH_SB 1011
#define IDC_VCAP_P_TRESH_ED 1012
#define IDC_VCAP_PUV_TRESH_ED 1013
#define IDC_VCAP_NOISE_SUP_ED 1014
#define IDC_VCAP_TRIG_ED 1015
#define IDC_VCAP_BAR_THRESH_ED 1016
#define IDC_SGC_TRESH_ED 1017
#define IDC_SGC_UV_TRESH_ED 1018
#define IDC_SGC_TRIGGER_ED 1019
#define IDC_SRF_MEDIAN_CHECK 1020
#define IDC_RSAD_HIGH_SB 1020
#define IDC_PAK_ENABLED_CHECK 1023
#define IDC_SC_TRADE_OFF_ED 1024
#define IDC_RSAD_LOW_ED 1025
#define IDC_RSAD_HIGH_ED 1026
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1021
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View file

@ -0,0 +1,765 @@
/****************************************************************************
*
* Module Title : RowDiffScan.c
*
* Description : Pre-processor row difference Scan
*
* AUTHOR : Paul Wilkins
*
*****************************************************************************
* Revision History
*
* 1.00 JBB 22 AUG 00 Configuration baseline
*
*****************************************************************************
*/
/****************************************************************************
* Header Frames
*****************************************************************************
*/
#define STRICT /* Strict type checking. */
#include "type_aliases.h"
#include "preproc.h"
/****************************************************************************
* Module constants.
*****************************************************************************
/****************************************************************************
*
* ROUTINE : RowDiffScan
*
* INPUTS : UINT8 * YuvPtr1, YuvPtr2
* Pointers into current and previous frame
* BOOL EdgeRow
* Is this row an edge row.
*
* OUTPUTS : UINT16 * YUVDiffsPtr
* Differnece map
* UINT8 * bits_map_ptr
* Pixels changed map
* UINT8 * SgcPtr
* Level change score.
* INT8 * DispFragPtr
* Block update map.
* INT32 * RowDiffsPtr
* Total sig changes for row
* UINT8 * ChLocalsPtr
* Changed locals data structure
*
*
* RETURNS :
*
* FUNCTION : Initial pixel differences scan
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
void RowDiffScan( PP_INSTANCE *ppi, UINT8 * YuvPtr1, UINT8 * YuvPtr2,
INT16 * YUVDiffsPtr, UINT8 * bits_map_ptr,
INT8 * SgcPtr, INT8 * DispFragPtr,
UINT8 * FDiffPixels, INT32 * RowDiffsPtr,
UINT8 * ChLocalsPtr, BOOL EdgeRow )
{
INT32 i;
INT32 FragChangedPixels;
INT16 Diff[8];
UINT32 ZeroData[2] = { 0,0 };
UINT8 OneData[8] = { 1,1,1,1,1,1,1,1 };
UINT8 ChlocalsDummyData[8] = { 8,8,8,8,8,8,8,8 };
// Cannot use kernel if at edge or if PAK disabled
if ( (!ppi->PAKEnabled) || EdgeRow )
{
for ( i = 0; i < ppi->PlaneWidth; i += ppi->HFragPixels )
{
// Reset count of pixels changed for the current fragment.
FragChangedPixels = 0;
// Test for break out conditions to save time.
if ((*DispFragPtr == CANDIDATE_BLOCK) )//|| !ppi->EarlyBreakAllowed)
{
__asm
{
movd esi, [YuvPtr1];
movd ebx, [YuvPtr2];
movd edx, FragChangedPixels
pxor mm7, mm7;
movq mm0, [esi] ;76543210
movq mm1, [ebx] ;76543210
movq mm2, mm0 ;make a copy
movq mm3, mm1 ;make a copy
punpcklbw mm0, mm7 ; 3 2 1 0
punpcklbw mm1, mm7 ; 3 2 1 0
punpckhbw mm2, mm7 ; 7 6 5 4
punpckhbw mm3, mm7 ; 7 6 5 4
psubw mm0 mm1 ; Diff[3,2,1,0]
psubw mm2, mm3 ; Diff[7,6,5,4]
movq QWORD PTR [YUVDiffsPtr], mm0
movq QWORD PTR [YUVDiffsPtr], mm2
;------------------------------------------------------
; mm0, mm1, mm3, mm4, m5, mm6, mm7, Free
; mm2, keep the Diff[7 6 5 4]
;------------------------------------------------------
movd eax, ppi->LevelThresh
movd mm1, eax ;
movd mm3, eax ;
packsdw mm1, mm3 ;
movq mm4, mm1 ;
psllw mm1, 16
por mm1, mm4 ;4 ppi->LevelThresh
;-------------------------------------------------------
; mm3, mm4, mm5, mm6, mm7 Free
;
;-------------------------------------------------------
movd eax, ppi->SrfThresh
movd mm3, eax ;
movd mm4, eax ;
packsdw mm3, mm4 ;
movq mm5, mm3 ;
psllw mm3, 16
por mm3, mm6 ;4 ppi->SrfThresh
;--------------------------------------------------------
; mm0 mm2 diff[0]-diff[7]
; mm1 ppi->LevelThresh
; mm3 ppi->SrfThresh
; mm4-mm7 free
; Note, ppi->NegLevelThresh = - ppi->LevelThresh
; ppi->NegSrfThresh = - ppi->SrfThresh
;--------------------------------------------------------
movq mm4, mm0 ; diff[0][1][2][3]
movq mm5, mm0 ;
psubsw mm4, mm1 ; if diff >= LevelThresh
psraw mm4, 15 ; 00s(True) and ffs (False)
pandn mm4, FFFFFFFFh ; ffs(True) and 00s (False)
psrlw mm4, 15 ; 01 (True) and 00 (False)
pcmpgtw mm5, mm3 ; if diff > SrfThresh
; ffs(True) and 00s (False)
psrlw mm5, 15 ; 01 (True) and 00 (False)
pand mm5, mm4 ;
movq mm7, mm0 ; save a copy of diff[0][1][2][3]
pxor mm6, mm6 ; clear MM6
psubsw mm6, mm1 ; mm6 = NegLevelThresh
pcmpgtw mm0, mm6 ; if diff > NegLevelThresh
; ffs(True) and 00s (False)
pandn mm0, FFFFFFFFh ; if diff <= NegLevelThresh
; ffs(True) and 00 (False)
psrlw mm0, 15 ; 01 (True) and 00 (False)
paddsw mm7, mm3 ; if diff < -NegSrfThresh
psraw mm7, 15 ; ffs(True) and 00s (False)
psrlw mm7, 15 ; 01 (True) and 00s (False)
pand mm7, mm0 ;
;----------------------------------------------------------------------------
; mm0, mm1, mm2, mm3, mm4, mm5, mm7 in use
; mm6 free
;----------------------------------------------------------------------------
por mm5, mm7 ; mm7 is free now
pxor mm6, mm6 ;
movq mm7, mm5 ;
punpcklwd mm5, mm6 ;
punpckhwd mm7, mm6 ;
paddw mm5, mm7 ;
movq mm7, mm5 ;
psrlq mm7, 32 ;
paddd mm7, mm5 ;
movd eax, mm7 ;
add eax, ebx
// Calculate the diference values and copy to YUVDiffsPtr
Diff[0] = ((INT16)YuvPtr1[0]) - ((INT16)YuvPtr2[0]);
Diff[1] = ((INT16)YuvPtr1[1]) - ((INT16)YuvPtr2[1]);
Diff[2] = ((INT16)YuvPtr1[2]) - ((INT16)YuvPtr2[2]);
Diff[3] = ((INT16)YuvPtr1[3]) - ((INT16)YuvPtr2[3]);
((INT32 *)YUVDiffsPtr)[0] = ((INT32 *)Diff)[0];
((INT32 *)YUVDiffsPtr)[1] = ((INT32 *)Diff)[1];
// Test against the Level and ppi->SRF thresholds and record the results
// Pixel 0
if ( Diff[0] >= ppi->LevelThresh )
{
SgcPtr[0]++;
if ( Diff[0] > ppi->SrfThresh )
{
bits_map_ptr[0] = 1;
FragChangedPixels++;
}
}
else if ( Diff[0] <= ppi->NegLevelThresh )
{
SgcPtr[0]--;
if ( Diff[0] < ppi->NegSrfThresh )
{
bits_map_ptr[0] = 1;
FragChangedPixels++;
}
}
// Pixel 1
if ( Diff[1] >= ppi->LevelThresh )
{
SgcPtr[0]++;
if ( Diff[1] > ppi->SrfThresh )
{
bits_map_ptr[1] = 1;
FragChangedPixels++;
}
}
else if ( Diff[1] <= ppi->NegLevelThresh )
{
SgcPtr[0]--;
if ( Diff[1] < ppi->NegSrfThresh )
{
bits_map_ptr[1] = 1;
FragChangedPixels++;
}
}
// Pixel 2
if ( Diff[2] >= ppi->LevelThresh )
{
SgcPtr[0]++;
if ( Diff[2] > ppi->SrfThresh )
{
bits_map_ptr[2] = 1;
FragChangedPixels++;
}
}
else if ( Diff[2] <= ppi->NegLevelThresh )
{
SgcPtr[0]--;
if ( Diff[2] < ppi->NegSrfThresh )
{
bits_map_ptr[2] = 1;
FragChangedPixels++;
}
}
// Pixel 3
if ( Diff[3] >= ppi->LevelThresh )
{
SgcPtr[0]++;
if ( Diff[3] > ppi->SrfThresh )
{
bits_map_ptr[3] = 1;
FragChangedPixels++;
}
}
else if ( Diff[3] <= ppi->NegLevelThresh )
{
SgcPtr[0]--;
if ( Diff[3] < ppi->NegSrfThresh )
{
bits_map_ptr[3] = 1;
FragChangedPixels++;
}
}
// Clear down entries in changed locals array
((UINT32 *)ChLocalsPtr)[0] = ((UINT32 *)ZeroData)[0];
// Calculate the diference values and copy to YUVDiffsPtr
Diff[4] = ((INT16)YuvPtr1[4]) - ((INT16)YuvPtr2[4]);
Diff[5] = ((INT16)YuvPtr1[5]) - ((INT16)YuvPtr2[5]);
Diff[6] = ((INT16)YuvPtr1[6]) - ((INT16)YuvPtr2[6]);
Diff[7] = ((INT16)YuvPtr1[7]) - ((INT16)YuvPtr2[7]);
((INT32 *)YUVDiffsPtr)[2] = ((INT32 *)Diff)[2];
((INT32 *)YUVDiffsPtr)[3] = ((INT32 *)Diff)[3];
// Test against the Level and ppi->SRF thresholds and record the results
// Pixel 4
if ( Diff[4] >= ppi->LevelThresh )
{
SgcPtr[0]++;
if ( Diff[4] > ppi->SrfThresh )
{
bits_map_ptr[4] = 1;
FragChangedPixels++;
}
}
else if ( Diff[4] <= ppi->NegLevelThresh )
{
SgcPtr[0]--;
if ( Diff[4] < ppi->NegSrfThresh )
{
bits_map_ptr[4] = 1;
FragChangedPixels++;
}
}
// Pixel 5
if ( Diff[5] >= ppi->LevelThresh )
{
SgcPtr[0]++;
if ( Diff[5] > ppi->SrfThresh )
{
bits_map_ptr[5] = 1;
FragChangedPixels++;
}
}
else if ( Diff[5] <= ppi->NegLevelThresh )
{
SgcPtr[0]--;
if ( Diff[5] < ppi->NegSrfThresh )
{
bits_map_ptr[5] = 1;
FragChangedPixels++;
}
}
// Pixel 6
if ( Diff[6] >= ppi->LevelThresh )
{
SgcPtr[0]++;
if ( Diff[6] > ppi->SrfThresh )
{
bits_map_ptr[6] = 1;
FragChangedPixels++;
}
}
else if ( Diff[6] <= ppi->NegLevelThresh )
{
SgcPtr[0]--;
if ( Diff[6] < ppi->NegSrfThresh )
{
bits_map_ptr[6] = 1;
FragChangedPixels++;
}
}
// Pixel 7
if ( Diff[7] >= ppi->LevelThresh )
{
SgcPtr[0]++;
if ( Diff[7] > ppi->SrfThresh )
{
bits_map_ptr[7] = 1;
FragChangedPixels++;
}
}
else if ( Diff[7] <= ppi->NegLevelThresh )
{
SgcPtr[0]--;
if ( Diff[7] < ppi->NegSrfThresh )
{
bits_map_ptr[7] = 1;
FragChangedPixels++;
}
}
// Clear down entries in changed locals array
((UINT32 *)ChLocalsPtr)[1] = ((UINT32 *)ZeroData)[1];
}
else
{
// For EBO coded blocks mark all pixels as changed.
if ( *DispFragPtr > BLOCK_NOT_CODED )
{
((UINT32 *)bits_map_ptr)[0] = ((UINT32 *)OneData)[0];
((UINT32 *)ChLocalsPtr)[0] = ((UINT32 *)ChlocalsDummyData)[0];
((UINT32 *)bits_map_ptr)[1] = ((UINT32 *)OneData)[1];
((UINT32 *)ChLocalsPtr)[1] = ((UINT32 *)ChlocalsDummyData)[1];
}
else
{
((UINT32 *)ChLocalsPtr)[0] = ((UINT32 *)ZeroData)[0];
((UINT32 *)ChLocalsPtr)[1] = ((UINT32 *)ZeroData)[1];
}
}
*RowDiffsPtr += FragChangedPixels;
*FDiffPixels += (UINT8)FragChangedPixels;
YuvPtr1 += ppi->HFragPixels;
YuvPtr2 += ppi->HFragPixels;
bits_map_ptr += ppi->HFragPixels;
ChLocalsPtr += ppi->HFragPixels;
YUVDiffsPtr += ppi->HFragPixels;
SgcPtr ++;
FDiffPixels ++;
// If we have a lot of changed pixels for this fragment on this row then
// the fragment is almost sure to be picked (e.g. through the line search) so we
// can mark it as selected and then ignore it.
// if ( ppi->EarlyBreakAllowed )
{
if (FragChangedPixels >= 7)
{
*DispFragPtr = BLOCK_CODED;
}
}
DispFragPtr++;
}
}
else
{
for ( i = 0; i < ppi->PlaneWidth; i += ppi->HFragPixels )
{
// Reset count of pixels changed for the current fragment.
FragChangedPixels = 0;
// Test for break out conditions to save time.
if ((*DispFragPtr == CANDIDATE_BLOCK) )//|| !ppi->EarlyBreakAllowed)
{
// Calculate the diference values and copy to YUVDiffsPtr
Diff[0] = ((INT16)YuvPtr1[0]) - ((INT16)YuvPtr2[0]);
Diff[1] = ((INT16)YuvPtr1[1]) - ((INT16)YuvPtr2[1]);
Diff[2] = ((INT16)YuvPtr1[2]) - ((INT16)YuvPtr2[2]);
Diff[3] = ((INT16)YuvPtr1[3]) - ((INT16)YuvPtr2[3]);
((INT32 *)YUVDiffsPtr)[0] = ((INT32 *)Diff)[0];
((INT32 *)YUVDiffsPtr)[1] = ((INT32 *)Diff)[1];
// Test against the Level and ppi->SRF thresholds and record the results
// Pixel 0
if ( Diff[0] >= ppi->LevelThresh )
{
SgcPtr[0]++;
// If the level change is still suspect then apply PAK kernel.
if ( (Diff[0] > ppi->SrfThresh) && (Diff[0] <= ppi->HighChange) )
Diff[0] = (int)ApplyPakLowPass( ppi, &YuvPtr1[0] ) -
(int)ApplyPakLowPass( ppi, &YuvPtr2[0] );
if ( Diff[0] > ppi->SrfThresh )
{
bits_map_ptr[0] = 1;
FragChangedPixels++;
}
}
else if ( Diff[0] <= ppi->NegLevelThresh )
{
SgcPtr[0]--;
// If the level change is still suspect then apply PAK kernel.
if ( (Diff[0] < ppi->NegSrfThresh) && (Diff[0] >= ppi->NegHighChange) )
Diff[0] = (int)ApplyPakLowPass( ppi, &YuvPtr1[0] ) -
(int)ApplyPakLowPass( ppi, &YuvPtr2[0] );
if ( Diff[0] < ppi->NegSrfThresh )
{
bits_map_ptr[0] = 1;
FragChangedPixels++;
}
}
// Pixel 1
if ( Diff[1] >= ppi->LevelThresh )
{
SgcPtr[0]++;
// If the level change is still suspect then apply PAK kernel.
if ( (Diff[1] > ppi->SrfThresh) && (Diff[1] <= ppi->HighChange) )
Diff[1] = (int)ApplyPakLowPass( ppi, &YuvPtr1[1] ) -
(int)ApplyPakLowPass( ppi, &YuvPtr2[1] );
if ( Diff[1] > ppi->SrfThresh )
{
bits_map_ptr[1] = 1;
FragChangedPixels++;
}
}
else if ( Diff[1] <= ppi->NegLevelThresh )
{
SgcPtr[0]--;
// If the level change is still suspect then apply PAK kernel.
if ( (Diff[1] < ppi->NegSrfThresh) && (Diff[1] >= ppi->NegHighChange) )
Diff[1] = (int)ApplyPakLowPass( ppi, &YuvPtr1[1] ) -
(int)ApplyPakLowPass( ppi, &YuvPtr2[1] );
if ( Diff[1] < ppi->NegSrfThresh )
{
bits_map_ptr[1] = 1;
FragChangedPixels++;
}
}
// Pixel 2
if ( Diff[2] >= ppi->LevelThresh )
{
SgcPtr[0]++;
// If the level change is still suspect then apply PAK kernel.
if ( (Diff[2] > ppi->SrfThresh) && (Diff[2] <= ppi->HighChange) )
Diff[2] = (int)ApplyPakLowPass( ppi, &YuvPtr1[2] ) -
(int)ApplyPakLowPass( ppi, &YuvPtr2[2] );
if ( Diff[2] > ppi->SrfThresh )
{
bits_map_ptr[2] = 1;
FragChangedPixels++;
}
}
else if ( Diff[2] <= ppi->NegLevelThresh )
{
SgcPtr[0]--;
// If the level change is still suspect then apply PAK kernel.
if ( (Diff[2] < ppi->NegSrfThresh) && (Diff[2] >= ppi->NegHighChange) )
Diff[2] = (int)ApplyPakLowPass( ppi, &YuvPtr1[2] ) -
(int)ApplyPakLowPass( ppi, &YuvPtr2[2] );
if ( Diff[2] < ppi->NegSrfThresh )
{
bits_map_ptr[2] = 1;
FragChangedPixels++;
}
}
// Pixel 3
if ( Diff[3] >= ppi->LevelThresh )
{
SgcPtr[0]++;
// If the level change is still suspect then apply PAK kernel.
if ( (Diff[3] > ppi->SrfThresh) && (Diff[3] <= ppi->HighChange) )
Diff[3] = (int)ApplyPakLowPass( ppi, &YuvPtr1[3] ) -
(int)ApplyPakLowPass( ppi, &YuvPtr2[3] );
if ( Diff[3] > ppi->SrfThresh )
{
bits_map_ptr[3] = 1;
FragChangedPixels++;
}
}
else if ( Diff[3] <= ppi->NegLevelThresh )
{
SgcPtr[0]--;
// If the level change is still suspect then apply PAK kernel.
if ( (Diff[3] < ppi->NegSrfThresh) && (Diff[3] >= ppi->NegHighChange) )
Diff[3] = (int)ApplyPakLowPass( ppi, &YuvPtr1[3] ) -
(int)ApplyPakLowPass( ppi, &YuvPtr2[3] );
if ( Diff[3] < ppi->NegSrfThresh )
{
bits_map_ptr[3] = 1;
FragChangedPixels++;
}
}
// Clear down entries in changed locals array
((UINT32 *)ChLocalsPtr)[0] = ((UINT32 *)ZeroData)[0];
// Calculate the diference values and copy to YUVDiffsPtr
Diff[4] = ((INT16)YuvPtr1[4]) - ((INT16)YuvPtr2[4]);
Diff[5] = ((INT16)YuvPtr1[5]) - ((INT16)YuvPtr2[5]);
Diff[6] = ((INT16)YuvPtr1[6]) - ((INT16)YuvPtr2[6]);
Diff[7] = ((INT16)YuvPtr1[7]) - ((INT16)YuvPtr2[7]);
((INT32 *)YUVDiffsPtr)[2] = ((INT32 *)Diff)[2];
((INT32 *)YUVDiffsPtr)[3] = ((INT32 *)Diff)[3];
// Test against the Level and ppi->SRF thresholds and record the results
// Pixel 4
if ( Diff[4] >= ppi->LevelThresh )
{
SgcPtr[0]++;
// If the level change is still suspect then apply PAK kernel.
if ( (Diff[4] > ppi->SrfThresh) && (Diff[4] <= ppi->HighChange) )
Diff[4] = (int)ApplyPakLowPass( ppi, &YuvPtr1[4] ) -
(int)ApplyPakLowPass( ppi, &YuvPtr2[4] );
if ( Diff[4] > ppi->SrfThresh )
{
bits_map_ptr[4] = 1;
FragChangedPixels++;
}
}
else if ( Diff[4] <= ppi->NegLevelThresh )
{
SgcPtr[0]--;
// If the level change is still suspect then apply PAK kernel.
if ( (Diff[4] < ppi->NegSrfThresh) && (Diff[4] >= ppi->NegHighChange) )
Diff[4] = (int)ApplyPakLowPass( ppi, &YuvPtr1[4] ) -
(int)ApplyPakLowPass( ppi, &YuvPtr2[4] );
if ( Diff[4] < ppi->NegSrfThresh )
{
bits_map_ptr[4] = 1;
FragChangedPixels++;
}
}
// Pixel 5
if ( Diff[5] >= ppi->LevelThresh )
{
SgcPtr[0]++;
// If the level change is still suspect then apply PAK kernel.
if ( (Diff[5] > ppi->SrfThresh) && (Diff[5] <= ppi->HighChange) )
Diff[5] = (int)ApplyPakLowPass( ppi, &YuvPtr1[5] ) -
(int)ApplyPakLowPass( ppi, &YuvPtr2[5] );
if ( Diff[5] > ppi->SrfThresh )
{
bits_map_ptr[5] = 1;
FragChangedPixels++;
}
}
else if ( Diff[5] <= ppi->NegLevelThresh )
{
SgcPtr[0]--;
// If the level change is still suspect then apply PAK kernel.
if ( (Diff[5] < ppi->NegSrfThresh) && (Diff[5] >= ppi->NegHighChange) )
Diff[5] = (int)ApplyPakLowPass( ppi, &YuvPtr1[5] ) -
(int)ApplyPakLowPass( ppi, &YuvPtr2[5] );
if ( Diff[5] < ppi->NegSrfThresh )
{
bits_map_ptr[5] = 1;
FragChangedPixels++;
}
}
// Pixel 6
if ( Diff[6] >= ppi->LevelThresh )
{
SgcPtr[0]++;
// If the level change is still suspect then apply PAK kernel.
if ( (Diff[6] > ppi->SrfThresh) && (Diff[6] <= ppi->HighChange) )
Diff[6] = (int)ApplyPakLowPass( ppi, &YuvPtr1[6] ) -
(int)ApplyPakLowPass( ppi, &YuvPtr2[6] );
if ( Diff[6] > ppi->SrfThresh )
{
bits_map_ptr[6] = 1;
FragChangedPixels++;
}
}
else if ( Diff[6] <= ppi->NegLevelThresh )
{
SgcPtr[0]--;
// If the level change is still suspect then apply PAK kernel.
if ( (Diff[6] < ppi->NegSrfThresh) && (Diff[6] >= ppi->NegHighChange) )
Diff[6] = (int)ApplyPakLowPass( ppi, &YuvPtr1[6] ) -
(int)ApplyPakLowPass( ppi, &YuvPtr2[6] );
if ( Diff[6] < ppi->NegSrfThresh )
{
bits_map_ptr[6] = 1;
FragChangedPixels++;
}
}
// Pixel 7
if ( Diff[7] >= ppi->LevelThresh )
{
SgcPtr[0]++;
// If the level change is still suspect then apply PAK kernel.
if ( (Diff[7] > ppi->SrfThresh) && (Diff[7] <= ppi->HighChange) )
Diff[7] = (int)ApplyPakLowPass( ppi, &YuvPtr1[7] ) -
(int)ApplyPakLowPass( ppi, &YuvPtr2[7] );
if ( Diff[7] > ppi->SrfThresh )
{
bits_map_ptr[7] = 1;
FragChangedPixels++;
}
}
else if ( Diff[7] <= ppi->NegLevelThresh )
{
SgcPtr[0]--;
// If the level change is still suspect then apply PAK kernel.
if ( (Diff[7] < ppi->NegSrfThresh) && (Diff[7] >= ppi->NegHighChange) )
Diff[7] = (int)ApplyPakLowPass( ppi, &YuvPtr1[7] ) -
(int)ApplyPakLowPass( ppi, &YuvPtr2[7] );
if ( Diff[7] < ppi->NegSrfThresh )
{
bits_map_ptr[7] = 1;
FragChangedPixels++;
}
}
// Clear down entries in changed locals array
((UINT32 *)ChLocalsPtr)[1] = ((UINT32 *)ZeroData)[1];
}
else
{
// For EBO coded blocks mark all pixels as changed.
if ( *DispFragPtr > BLOCK_NOT_CODED )
{
((UINT32 *)bits_map_ptr)[0] = ((UINT32 *)OneData)[0];
((UINT32 *)ChLocalsPtr)[0] = ((UINT32 *)ChlocalsDummyData)[0];
((UINT32 *)bits_map_ptr)[1] = ((UINT32 *)OneData)[1];
((UINT32 *)ChLocalsPtr)[1] = ((UINT32 *)ChlocalsDummyData)[1];
}
else
{
((UINT32 *)ChLocalsPtr)[0] = ((UINT32 *)ZeroData)[0];
((UINT32 *)ChLocalsPtr)[1] = ((UINT32 *)ZeroData)[1];
}
}
*RowDiffsPtr += FragChangedPixels;
*FDiffPixels += (UINT8)FragChangedPixels;
YuvPtr1 += ppi->HFragPixels;
YuvPtr2 += ppi->HFragPixels;
bits_map_ptr += ppi->HFragPixels;
ChLocalsPtr += ppi->HFragPixels;
YUVDiffsPtr += ppi->HFragPixels;
SgcPtr ++;
FDiffPixels ++;
// If we have a lot of changed pixels for this fragment on this row then
// the fragment is almost sure to be picked (e.g. through the line search) so we
// can mark it as selected and then ignore it.
// if ( ppi->EarlyBreakAllowed )
{
if (FragChangedPixels >= 7)
{
*DispFragPtr = BLOCK_CODED;
}
}
DispFragPtr++;
}
}
}

View file

@ -0,0 +1,88 @@
;------------------------------------------------
XmmRowSADParams STRUC
dd ? ;1 pushed regs
dd ? ;return address
NewDataPtr dd ?
RefDataPtr dd ?
XmmRowSADParams ENDS
;------------------------------------------------
INCLUDE iaxmm.inc
.586
.387
.MODEL flat, SYSCALL, os_dos
.MMX
; macros
.DATA
TORQ_CX_DATA SEGMENT PAGE PUBLIC USE32 'DATA'
ALIGN 32
.CODE
NAME XmmRowSAD
PUBLIC XmmRowSAD_
PUBLIC _XmmRowSAD
;------------------------------------------------
; local vars
LOCAL_SPACE EQU 0
;------------------------------------------------
;UINT32 XmmRowSAD( UINT8 * NewDataPtr, UINT8 * RefDataPtr)
;
XmmRowSAD_:
_XmmRowSAD:
push ebx
mov eax,(XmmRowSADParams PTR [esp]).NewDataPtr ; Load base addresses
mov ebx,(XmmRowSADParams PTR [esp]).RefDataPtr
;
; ESP = Stack Pointer MM0 = Free
; ESI = Free MM1 = Free
; EDI = Free MM2 = Free
; EBP = Free MM3 = Free
; EBX = RefDataPtr MM4 = Free
; ECX = PixelsPerLine MM5 = Free
; EDX = PixelsPerLine + STRIDE_EXTRA MM6 = Free
; EAX = NewDataPtr MM7 = Free
;
movq mm0, QWORD PTR [eax] ; copy eight bytes from NewDataPtr to mm0
movq mm3, QWORD PTR [ebx] ; copy eight bytes from ReconDataPtr to mm3
pxor mm1, mm1 ; clear mm1 for unpacking
movq mm2, mm0 ; make a copy
movq mm4, mm3 ; make a copy
punpcklbw mm0, mm1 ; unpack the lower four bytes
punpcklbw mm3, mm1 ; unpack the lower four bytes
psadbw mm0, mm3 ; sum of absolute difference of four bytes
punpckhbw mm2, mm1 ; unpack the higher four bytes
punpckhbw mm4, mm1 ; unpack the higher four bytes
psadbw mm2, mm4 ; sum of absolute difference of another four
pop ebx
pmaxsw mm0, mm2 ; get the max
movd eax, mm0 ; return value
ret
;************************************************
END
END

View file

@ -0,0 +1,391 @@
/****************************************************************************
*
* Module Title : BlockMap.c
*
* Description : Contains functions used to create the block map
*
* AUTHOR : Paul Wilkins
*
*****************************************************************************
* Revision History
*
* 1.08 PGW 28 Feb 01 Removal of history buffer mechanism.
* 1.07 PGW 04 Oct 00 Changes to RowBarEnhBlockMap()
* 1.06 JBB 03 Aug 00 Fixed Problem in which rownumber was compared to
* PlaneHFragments instead of PlaneVFragments, added
* statistic output functions
* 1.05 PGW 27/07/00 Experiments with motion score.
* 1.04 JBB 30/05/00 Removed hard coded size limits
* 1.03 PGW 18/02/00 Changed weighting for History blocks.
* Redundant functions deleted.
* Deglobalization.
* 1.02 PGW 12/07/99 Changes to reduce uneccessary dependancies.
* 1.01 PGW 21/06/99 Alter function of RowBarEnhBlockMap() for VFW codec.
* 1.00 PGW 14/06/99 Configuration baseline
*
*****************************************************************************
*/
/****************************************************************************
* Header Frames
*****************************************************************************
*/
#define STRICT /* Strict type checking. */
#include <string.h>
#include "preproc.h"
/****************************************************************************
* Module constants.
*****************************************************************************
*/
/****************************************************************************
* Module Types
*****************************************************************************
*/
/****************************************************************************
* Imported Global Variables
*****************************************************************************
*/
/****************************************************************************
* Exported Global Variables
*****************************************************************************
*/
/****************************************************************************
* Foreward References
*****************************************************************************
*/
/****************************************************************************
* Module Statics
*****************************************************************************
*/
/****************************************************************************
*
* ROUTINE : RowBarEnhBlockMap
*
* INPUTS : UINT32 * FragNoiseScorePtr
* INT8 * FragSgcPtr
* UINT32 RowNumber
*
* OUTPUTS : INT8 * UpdatedBlockMapPtr
* INT8 * BarBlockMapPtr
*
* RETURNS : None.
*
* FUNCTION : BAR Enhances block map on a row by row basis.
*
* SPECIAL NOTES : Note special cases for first and last row and first and last
* block in each row.
*
*
* ERRORS : None.
*
****************************************************************************/
void RowBarEnhBlockMap( PP_INSTANCE *ppi,
UINT32 * FragScorePtr,
INT8 * FragSgcPtr,
INT8 * UpdatedBlockMapPtr,
INT8 * BarBlockMapPtr,
UINT32 RowNumber )
{
// For boundary blocks relax thresholds
UINT32 BarBlockThresh = ppi->BlockThreshold / 10;
UINT32 BarSGCThresh = ppi->BlockSgcThresh / 2;
INT32 i;
// Start by blanking the row in the bar block map structure.
memset( BarBlockMapPtr, BLOCK_NOT_CODED, ppi->PlaneHFragments );
// First row
if ( RowNumber == 0 )
{
// For each fragment in the row.
for ( i = 0; i < ppi->PlaneHFragments; i ++ )
{
// Test for CANDIDATE_BLOCK or CANDIDATE_BLOCK_LOW
// Uncoded or coded blocks will be ignored.
if ( UpdatedBlockMapPtr[i] <= CANDIDATE_BLOCK )
{
// Is one of the immediate neighbours updated in the main map.
// Note special cases for blocks at the start and end of rows.
if ( i == 0 )
{
if ( (UpdatedBlockMapPtr[i+1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments+1] > BLOCK_NOT_CODED ) )
{
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}
}
else if ( i == (ppi->PlaneHFragments - 1) )
{
if ( (UpdatedBlockMapPtr[i-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments] > BLOCK_NOT_CODED ) )
{
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}
}
else
{
if ( (UpdatedBlockMapPtr[i-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments+1] > BLOCK_NOT_CODED ) )
{
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}
}
}
}
}
// Last row
// Used to read PlaneHFragments
else if ( RowNumber == (UINT32)(ppi->PlaneVFragments-1))
{
// For each fragment in the row.
for ( i = 0; i < ppi->PlaneHFragments; i ++ )
{
// Test for CANDIDATE_BLOCK or CANDIDATE_BLOCK_LOW
// Uncoded or coded blocks will be ignored.
if ( UpdatedBlockMapPtr[i] <= CANDIDATE_BLOCK )
{
// Is one of the immediate neighbours updated in the main map.
// Note special cases for blocks at the start and end of rows.
if ( i == 0 )
{
if ( (UpdatedBlockMapPtr[i+1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments+1] > BLOCK_NOT_CODED ) )
{
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}
}
else if ( i == (ppi->PlaneHFragments - 1) )
{
if ( (UpdatedBlockMapPtr[i-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments] > BLOCK_NOT_CODED ) )
{
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}
}
else
{
if ( (UpdatedBlockMapPtr[i-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments+1] > BLOCK_NOT_CODED ) )
{
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}
}
}
}
}
// All other rows
else
{
// For each fragment in the row.
for ( i = 0; i < ppi->PlaneHFragments; i ++ )
{
// Test for CANDIDATE_BLOCK or CANDIDATE_BLOCK_LOW
// Uncoded or coded blocks will be ignored.
if ( UpdatedBlockMapPtr[i] <= CANDIDATE_BLOCK )
{
// Is one of the immediate neighbours updated in the main map.
// Note special cases for blocks at the start and end of rows.
if ( i == 0 )
{
if ( (UpdatedBlockMapPtr[i+1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments+1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments+1] > BLOCK_NOT_CODED ) )
{
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}
}
else if ( i == (ppi->PlaneHFragments - 1) )
{
if ( (UpdatedBlockMapPtr[i-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments] > BLOCK_NOT_CODED ) )
{
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}
}
else
{
if ( (UpdatedBlockMapPtr[i-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i-ppi->PlaneHFragments+1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments-1] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments] > BLOCK_NOT_CODED ) ||
(UpdatedBlockMapPtr[i+ppi->PlaneHFragments+1] > BLOCK_NOT_CODED ) )
{
BarBlockMapPtr[i] = BLOCK_CODED_BAR;
}
}
}
}
}
}
/****************************************************************************
*
* ROUTINE : BarCopyBack
*
* INPUTS : INT8 * BarBlockMapPtr
*
* OUTPUTS : INT8 * UpdatedBlockMapPtr
*
* RETURNS : None.
*
* FUNCTION : Copies BAR blocks back into main block map.
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
void BarCopyBack( PP_INSTANCE *ppi,
INT8 * UpdatedBlockMapPtr,
INT8 * BarBlockMapPtr )
{
INT32 i;
// For each fragment in the row.
for ( i = 0; i < ppi->PlaneHFragments; i ++ )
{
if ( BarBlockMapPtr[i] > BLOCK_NOT_CODED )
{
UpdatedBlockMapPtr[i] = BarBlockMapPtr[i];
}
}
}
/****************************************************************************
*
* ROUTINE : CreateOutputDisplayMap
*
* INPUTS : INT8 * InternalFragmentsPtr
* Fragment list using internal format.
* INT8 * RecentHistoryPtr
* List of blocks that have been marked for update int he last few frames.
*
* UINT8 * ExternalFragmentsPtr
* Fragment list using external format.
*
* OUTPUTS : None.
*
* RETURNS : None.
*
* FUNCTION : Creates a block update map in the format expected by the caller.
*
* SPECIAL NOTES : The output block height and width must be an integer
* multiple of the internal value.
*
*
* ERRORS : None.
*
****************************************************************************/
void CreateOutputDisplayMap
(
PP_INSTANCE *ppi,
INT8 *InternalFragmentsPtr
)
{
UINT32 i;
UINT32 KFScore = 0;
UINT32 YBand = (ppi->ScanYPlaneFragments/8); // 1/8th of Y image.
//#define DISPLAY_STATS
#ifdef DISPLAY_STATS
#include <stdio.h>
{
FILE * StatsFilePtr;
StatsFilePtr = fopen( "c:\\display_stats.stt", "a" );
if ( StatsFilePtr )
{
int i;
for(i=0;i<ppi->ScanYPlaneFragments;i++)
{
if(i%ppi->ScanHFragments == 0 )
fprintf( StatsFilePtr , "\n");
fprintf( StatsFilePtr, "%2d",
InternalFragmentsPtr[i]);
}
fprintf( StatsFilePtr , "\n");
fclose( StatsFilePtr );
}
}
#endif
ppi->OutputBlocksUpdated = 0;
for ( i = 0; i < ppi->ScanFrameFragments; i++ )
{
if ( InternalFragmentsPtr[i] > BLOCK_NOT_CODED )
{
ppi->OutputBlocksUpdated ++;
setBlockCoded(i)
}
else
{
setBlockUncoded(i);
}
}
// Now calculate a key frame candidate indicator.
// This is based upon Y data only and only ignores the top and bottom 1/8 of the image.
// Also ignore history blocks and BAR blocks.
ppi->KFIndicator = 0;
for ( i = YBand; i < (ppi->ScanYPlaneFragments - YBand); i++ )
{
if ( InternalFragmentsPtr[i] > BLOCK_CODED_BAR )
{
ppi->KFIndicator ++;
}
}
// Convert the KF score to a range 0-100
ppi->KFIndicator = ((ppi->KFIndicator*100)/((ppi->ScanYPlaneFragments*3)/4));
}

View file

@ -0,0 +1,96 @@
/****************************************************************************
*
* Module Title : clamp.c
*
* Description : c
*
* AUTHOR : Jim Bankoski
*
*****************************************************************************
* Revision History
*
* 1.09 YWX 26-Sep-01 Changed the default bandHeight from 5 to 4
* 1.08 YWX 23-Jul-00 Changed horizontal scaling function names
* 1.07 JBB 04 Dec 00 Added new Center vs Scale Bits
* 1.06 YWX 01-Dec-00 Removed bi-cubic scale functions
* 1.05 YWX 18-Oct-00 Added 1-2 scale functions
* 1.04 YWX 11-Oct-00 Added ratio check to determine scaling or centering
* 1.03 YWX 09-Oct-00 Added functions that do differen scaling in horizontal
* and vertical directions
* 1.02 YWX 04-Oct-00 Added 3-5 scaling functions
* 1.01 YWX 03-Oct-00 Added a set of 4-5 scaling functions
* 1.00 JBB 15 Sep 00 New Configuration baseline.
*
*****************************************************************************
*/
/****************************************************************************
* Header Files
*****************************************************************************
*/
#include "postp.h"
#include <stdio.h>
/****************************************************************************
* Imported
*****************************************************************************
*/
void ClampLevels_C(
POSTPROC_INSTANCE *pbi,
INT32 BlackClamp, // number of values to clamp from 0
INT32 WhiteClamp, // number of values to clamp from 255
UINT8 *Src, // reconstruction buffer : passed in
UINT8 *Dst // postprocessing buffer : passed in
)
{
unsigned char clamped[255];
int width = pbi->HFragments*8;
int height = pbi->VFragments*8; // Y plane will be done in two passes
UINT8 *SrcPtr = Src + pbi->ReconYDataOffset;
UINT8 *DestPtr = Dst + pbi->ReconYDataOffset;
UINT32 LineLength = pbi->YStride * 2; // pitch is doubled for interlacing
// set up clamping table so we can avoid ifs while clamping
int i;
for(i=0;i<255;i++)
{
if(i<BlackClamp)
clamped[i] = BlackClamp;
if(i>WhiteClamp)
clamped[i] = WhiteClamp;
}
Block = 0;
// clamping is for y only!
for ( row = 0 ; row < height ; row ++)
{
for (col = 0; col < width ; col ++)
{
SrcPtr[col]=clamped[DestPtr[col]];
}
SrcPtr += LineLength;
DestPtr += LineLength;
}
}
/****************************************************************************
* Module constants.
*****************************************************************************
*/
/****************************************************************************
* Exported Global Variables
*****************************************************************************
*/
/****************************************************************************
* Module Static Variables
*****************************************************************************
*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,110 @@
/****************************************************************************
*
* Module Title : PreProcFunctions.c
*
* Description :
*
* AUTHOR : Paul Wilkins
*
*****************************************************************************
* Revision History
*
* 1.00 JBB 22 Aug 00 Configuration baseline
*
*****************************************************************************
*/
/****************************************************************************
* Header Files
*****************************************************************************
*/
#define STRICT /* Strict type checking. */
#include "preproc.h"
#ifdef _MSC_VER
#pragma warning( disable : 4799 ) // Disable no emms instruction warning!
#endif
/****************************************************************************
* Module constants.
*****************************************************************************
*/
/****************************************************************************
* Imports.
*****************************************************************************
*/
/****************************************************************************
* Exported Global Variables
*****************************************************************************
*/
/****************************************************************************
* Exported Functions
*****************************************************************************
*/
/****************************************************************************
* Module Statics
*****************************************************************************
*/
/****************************************************************************
* Forward References
*****************************************************************************
*/
/****************************************************************************
*
* ROUTINE : MachineSpecificConfig
*
* INPUTS : None
*
* OUTPUTS : None
*
* RETURNS : None
*
* FUNCTION : Checks for machine specifc features such as MMX support
* sets approipriate flags and function pointers.
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
#define MMX_ENABLED 1
void MachineSpecificConfig(PP_INSTANCE *ppi)
{
UINT32 FeatureFlags = 0;
ppi->RowSAD = ScalarRowSAD;
ppi->ColSAD = ScalarColSAD;
}
/****************************************************************************
*
* ROUTINE : ClearMmxState()
*
*
* INPUTS : None
*
* OUTPUTS :
*
* RETURNS :
*
*
* FUNCTION : Clears down the MMX state
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
void ClearMmxState(PP_INSTANCE *ppi)
{
return;
}

View file

@ -0,0 +1,501 @@
/****************************************************************************
*
* Module Title : PreProcGlobals
*
* Description : Pre-processor module globals.
*
* AUTHOR : Paul Wilkins
*
*****************************************************************************
* Revision History
*
* 1.07 PGW 20 Feb 01 Disable history buffer mechanism.
* 1.06 JBB 20 Sep 00 duck_ memory allocation calls
* 1.05 JBB 02 Aug 00 Checked duck_malloc return codes
* 1.04 PGW 24 Jul 00 Deleted BeThreshold & ShowVcapPramsDlg.
* 1.03 PGW 10 Jul 00 Added KFIndicator.
* 1.02 JBB 30/05/00 Removed hard coded size limits
* 1.01 PGW 12/07/99 Changes to reduce uneccessary dependancies.
* 1.00 PGW 14/06/99 Configuration baseline
*
*****************************************************************************
*/
/****************************************************************************
* Header Frames
*****************************************************************************
*/
#define STRICT /* Strict type checking. */
#include "preprocconf.h"
#include "preproc.h"
#include <stdlib.h>
#include "duck_mem.h"
/****************************************************************************
* Exported Global Variables
*****************************************************************************
*/
//PP_INSTANCE *ppi;
/****************************************************************************
*
* ROUTINE : PDeleteFragmentInfo
*
*
* INPUTS : Instance of PB to be initialized
*
* OUTPUTS :
*
* RETURNS :
*
*
* FUNCTION : Initializes the Playback instance passed in
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
void PDeleteFragmentInfo(PP_INSTANCE * ppi)
{
// duck_free prior allocs if present
}
/****************************************************************************
*
* ROUTINE : PAllocateFragmentInfo
*
*
* INPUTS : Instance of PB to be initialized
*
* OUTPUTS :
*
* RETURNS :
*
*
* FUNCTION : Initializes the Playback instance passed in
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
void PAllocateFragmentInfo(PP_INSTANCE * ppi)
{
// clear any existing info
PDeleteFragmentInfo(ppi);
// Perform Fragment Allocations
}
/****************************************************************************
*
* ROUTINE : PDeleteFrameInfo
*
*
* INPUTS : Instance of PB to be initialized
*
* OUTPUTS :
*
* RETURNS :
*
*
* FUNCTION : Initializes the Playback instance passed in
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
void PDeleteFrameInfo(PP_INSTANCE * ppi)
{
if( ppi->ScanPixelIndexTableAlloc )
duck_free(ppi->ScanPixelIndexTableAlloc);
ppi->ScanPixelIndexTableAlloc= 0;
ppi->ScanPixelIndexTable= 0;
if( ppi->ScanDisplayFragmentsAlloc )
duck_free(ppi->ScanDisplayFragmentsAlloc);
ppi->ScanDisplayFragmentsAlloc= 0;
ppi->ScanDisplayFragments= 0;
if( ppi->FragScoresAlloc )
duck_free(ppi->FragScoresAlloc);
ppi->FragScoresAlloc= 0;
ppi->FragScores= 0;
if( ppi->SameGreyDirPixelsAlloc )
duck_free(ppi->SameGreyDirPixelsAlloc);
ppi->SameGreyDirPixelsAlloc= 0;
ppi->SameGreyDirPixels= 0;
if( ppi->FragDiffPixelsAlloc )
duck_free(ppi->FragDiffPixelsAlloc);
ppi->FragDiffPixelsAlloc= 0;
ppi->FragDiffPixels= 0;
if( ppi->BarBlockMapAlloc )
duck_free(ppi->BarBlockMapAlloc);
ppi->BarBlockMapAlloc= 0;
ppi->BarBlockMap= 0;
if( ppi->TmpCodedMapAlloc )
duck_free(ppi->TmpCodedMapAlloc);
ppi->TmpCodedMapAlloc= 0;
ppi->TmpCodedMap= 0;
if( ppi->RowChangedPixelsAlloc )
duck_free(ppi->RowChangedPixelsAlloc);
ppi->RowChangedPixelsAlloc= 0;
ppi->RowChangedPixels= 0;
if( ppi->PixelScoresAlloc )
duck_free(ppi->PixelScoresAlloc);
ppi->PixelScoresAlloc= 0;
ppi->PixelScores= 0;
if( ppi->PixelChangedMapAlloc )
duck_free(ppi->PixelChangedMapAlloc);
ppi->PixelChangedMapAlloc= 0;
ppi->PixelChangedMap= 0;
if( ppi->ChLocalsAlloc )
duck_free(ppi->ChLocalsAlloc);
ppi->ChLocalsAlloc= 0;
ppi->ChLocals= 0;
if( ppi->yuv_differencesAlloc )
duck_free(ppi->yuv_differencesAlloc);
ppi->yuv_differencesAlloc= 0;
ppi->yuv_differences= 0;
}
#define ROUNDUP32(X) ( ( ( (unsigned long) X ) + 31 )&( 0xFFFFFFE0 ) )
/****************************************************************************
*
* ROUTINE : PAllocateFrameInfo
*
*
* INPUTS : Instance of PB to be initialized
*
* OUTPUTS :
*
* RETURNS :
*
*
* FUNCTION : Initializes the Playback instance passed in
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
BOOL PAllocateFrameInfo(PP_INSTANCE * ppi)
{
PDeleteFrameInfo(ppi);
ppi->ScanPixelIndexTableAlloc = duck_malloc(32 + ppi->ScanFrameFragments*sizeof(UINT32), DMEM_GENERAL);
if(!ppi->ScanPixelIndexTableAlloc) {PDeleteFrameInfo(ppi);return FALSE;}
ppi->ScanPixelIndexTable = (UINT32 *) ROUNDUP32(ppi->ScanPixelIndexTableAlloc);
ppi->ScanDisplayFragmentsAlloc = duck_malloc(32 + ppi->ScanFrameFragments*sizeof(INT8), DMEM_GENERAL);
if(!ppi->ScanDisplayFragmentsAlloc) {PDeleteFrameInfo(ppi);return FALSE;}
ppi->ScanDisplayFragments = (INT8 *) ROUNDUP32(ppi->ScanDisplayFragmentsAlloc);
ppi->FragScoresAlloc = duck_malloc(32 + ppi->ScanFrameFragments*sizeof(UINT32), DMEM_GENERAL);
if(!ppi->FragScoresAlloc) {PDeleteFrameInfo(ppi);return FALSE;}
ppi->FragScores = (UINT32 *) ROUNDUP32(ppi->FragScoresAlloc);
ppi->SameGreyDirPixelsAlloc = duck_malloc(32 + ppi->ScanFrameFragments*sizeof(INT8), DMEM_GENERAL);
if(!ppi->SameGreyDirPixelsAlloc) {PDeleteFrameInfo(ppi);return FALSE;}
ppi->SameGreyDirPixels = (INT8 *) ROUNDUP32(ppi->SameGreyDirPixelsAlloc);
ppi->FragDiffPixelsAlloc = duck_malloc(32 + ppi->ScanFrameFragments*sizeof(UINT8), DMEM_GENERAL);
if(!ppi->FragDiffPixelsAlloc) {PDeleteFrameInfo(ppi);return FALSE;}
ppi->FragDiffPixels = (UINT8 *) ROUNDUP32(ppi->FragDiffPixelsAlloc);
ppi->BarBlockMapAlloc = duck_malloc(32 + 3 * ppi->ScanHFragments*sizeof(INT8), DMEM_GENERAL);
if(!ppi->BarBlockMapAlloc) {PDeleteFrameInfo(ppi);return FALSE;}
ppi->BarBlockMap = (INT8 *) ROUNDUP32(ppi->BarBlockMapAlloc);
ppi->TmpCodedMapAlloc = duck_malloc(32 + ppi->ScanHFragments*sizeof(INT8), DMEM_GENERAL);
if(!ppi->TmpCodedMapAlloc) {PDeleteFrameInfo(ppi);return FALSE;}
ppi->TmpCodedMap = (INT8 *) ROUNDUP32(ppi->TmpCodedMapAlloc);
ppi->RowChangedPixelsAlloc = duck_malloc(32 + 3 * ppi->ScanConfig.VideoFrameHeight *sizeof(INT32), DMEM_GENERAL);
if(!ppi->RowChangedPixelsAlloc) {PDeleteFrameInfo(ppi);return FALSE;}
ppi->RowChangedPixels = (INT32 *) ROUNDUP32(ppi->RowChangedPixelsAlloc);
ppi->PixelScoresAlloc = duck_malloc(32 + ppi->ScanConfig.VideoFrameWidth* sizeof(UINT8) * PSCORE_CB_ROWS, DMEM_GENERAL);
if(!ppi->PixelScoresAlloc) {PDeleteFrameInfo(ppi);return FALSE;}
ppi->PixelScores = (UINT8 *) ROUNDUP32(ppi->PixelScoresAlloc);
ppi->PixelChangedMapAlloc = duck_malloc(32 + ppi->ScanConfig.VideoFrameWidth*sizeof(UINT8) * PMAP_CB_ROWS, DMEM_GENERAL);
if(!ppi->PixelChangedMapAlloc) {PDeleteFrameInfo(ppi);return FALSE;}
ppi->PixelChangedMap = ( UINT8 *) ROUNDUP32(ppi->PixelChangedMapAlloc);
ppi->ChLocalsAlloc = duck_malloc(32 + ppi->ScanConfig.VideoFrameWidth*sizeof(UINT8) * CHLOCALS_CB_ROWS, DMEM_GENERAL);
if(!ppi->ChLocalsAlloc) {PDeleteFrameInfo(ppi);return FALSE;}
ppi->ChLocals = (UINT8 *) ROUNDUP32(ppi->ChLocalsAlloc);
ppi->yuv_differencesAlloc = duck_malloc(32 + ppi->ScanConfig.VideoFrameWidth*sizeof(INT16) * YDIFF_CB_ROWS, DMEM_GENERAL);
if(!ppi->yuv_differencesAlloc) {PDeleteFrameInfo(ppi);return FALSE;}
ppi->yuv_differences = (INT16 *) ROUNDUP32(ppi->yuv_differencesAlloc);
return TRUE;
}
/****************************************************************************
*
* ROUTINE : DeletePPInstance
*
*
* INPUTS : Instance of PB to be deleted
*
* OUTPUTS :
*
* RETURNS :
*
*
* FUNCTION : frees the Playback instance passed in
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
void DeletePPInstance(PP_INSTANCE **ppi)
{
PDeleteFrameInfo(*ppi);
duck_free(*ppi);
*ppi=0;
}
/****************************************************************************
*
* ROUTINE : Createppinstance
*
*
* INPUTS : Instance of CP to be initialized
*
* OUTPUTS :
*
* RETURNS :
*
*
* FUNCTION : Create and Initializes the Compression instance
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
PP_INSTANCE * CreatePPInstance(void)
{
PP_INSTANCE *ppi;
/* The VCAP configuration. */
SCAN_CONFIG_DATA ScanConfigInit =
{
NULL, NULL, NULL, 0,0, NULL,
176, 144,
8,8,
};
// allocate structure
int ppi_size = sizeof(PP_INSTANCE);
ppi=duck_calloc(1,ppi_size, DMEM_GENERAL);
ppi->OutputBlocksUpdated = 0;
ppi->KFIndicator = 0;
// Initializations
ppi->VideoYPlaneWidth = 0;
ppi->VideoYPlaneHeight = 0;
ppi->VideoUVPlaneWidth = 0;
ppi->VideoUVPlaneHeight = 0;
ppi->VideoYPlaneStride = 0;
ppi->VideoUPlaneStride = 0;
ppi->VideoVPlaneStride = 0;
/* Scan control variables. */
ppi->HFragPixels = 8;
ppi->VFragPixels = 8;
ppi->ScanFrameFragments = 0 ;
ppi->ScanYPlaneFragments = 0;
ppi->ScanUVPlaneFragments= 0;
ppi->ScanHFragments= 0;
ppi->ScanVFragments= 0;
ppi->YFramePixels = 0;
ppi->UVFramePixels = 0;
ppi->TotFramePixels = 0;
ppi->SRFGreyThresh = 4;
ppi->SRFColThresh = 5;
ppi->NoiseSupLevel = 3;
ppi->SgcLevelThresh = 3;
ppi->SuvcLevelThresh = 4;
// Variables controlling S.A.D. break outs.
ppi->GrpLowSadThresh = 10;
ppi->GrpHighSadThresh = 64;
ppi->PrimaryBlockThreshold = 5;
ppi->SgcThresh = 16; // (Default values for 8x8 blocks).
ppi->PAKEnabled = FALSE; //TRUE;
ppi->LevelThresh = 0; // no initializaiton in Paul's
ppi->NegLevelThresh = 0; // no initializaiton in Paul's
ppi->SrfThresh = 0; // no initializaiton in Paul's
ppi->NegSrfThresh = 0; // no initializaiton in Paul's
ppi->HighChange = 0; // no initializaiton in Paul's
ppi->NegHighChange = 0; // no initializaiton in Paul's
ppi->ModifiedGrpLowSadThresh = 0;
ppi->ModifiedGrpHighSadThresh = 0; // no initializaiton in Paul's
ppi->PlaneHFragments = 0;
ppi->PlaneVFragments = 0;
ppi->PlaneHeight = 0;
ppi->PlaneWidth = 0;
ppi->PlaneStride = 0;
ppi->BlockThreshold = 0; // no initializaiton in Paul's
ppi->BlockSgcThresh = 0;
ppi->UVBlockThreshCorrection = 1.25;
ppi->UVSgcCorrection = 1.5;
ppi->SpeedCritical = 3;
// PC specific variables
ppi->MmxEnabled = FALSE;
ppi->YUVPlaneCorrectionFactor = 0; // no initialization in Paul's
ppi->MaxLineSearchLen = MAX_SEARCH_LINE_LEN;
ppi->YuvDiffsCircularBufferSize = 0; // no initializaiton in Paul's
ppi->ChLocalsCircularBufferSize = 0;
ppi->PixelMapCircularBufferSize = 0;
// Function pointers for mmx switches
ppi->RowSAD = 0;
ppi->ScanPixelIndexTableAlloc= 0;
ppi->ScanPixelIndexTable= 0;
ppi->ScanDisplayFragmentsAlloc= 0;
ppi->ScanDisplayFragments= 0;
ppi->FragScores= 0;
ppi->FragScores= 0;
ppi->ScanDisplayFragmentsAlloc= 0;
ppi->ScanDisplayFragments= 0;
ppi->SameGreyDirPixelsAlloc= 0;
ppi->SameGreyDirPixels= 0;
ppi->FragDiffPixelsAlloc= 0;
ppi->FragDiffPixels= 0;
ppi->BarBlockMapAlloc= 0;
ppi->BarBlockMap= 0;
ppi->TmpCodedMapAlloc= 0;
ppi->TmpCodedMap= 0;
ppi->RowChangedPixelsAlloc= 0;
ppi->RowChangedPixels= 0;
ppi->PixelScoresAlloc= 0;
ppi->PixelScores= 0;
ppi->PixelChangedMapAlloc= 0;
ppi->PixelChangedMap= 0;
ppi->ChLocalsAlloc= 0;
ppi->ChLocals= 0;
ppi->yuv_differencesAlloc= 0;
ppi->yuv_differences= 0;
return ppi;
}
/****************************************************************************
*
* ROUTINE : VPInitLibrary
*
*
* INPUTS : init VP library
*
* OUTPUTS :
*
* RETURNS :
*
*
* FUNCTION : Fully initializes the playback library
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
void VPPInitLibrary(void)
{
}
/*********************************************************/
/****************************************************************************
*
* ROUTINE : VPPDeinitLibrary
*
*
* INPUTS : init VP library
*
* OUTPUTS :
*
* RETURNS :
*
*
* FUNCTION : Fully initializes the playback library
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
void VPPDeInitLibrary(void)
{
}

View file

@ -0,0 +1,252 @@
/****************************************************************************
*
* Module Title : PreProcIf.c
*
* Description : Pre-processor dll interface module.
*
* AUTHOR : Paul Wilkins
*
*****************************************************************************
* Revision History
*
* 1.09 PGW 27 Apr 01 Changes to use last frame coded list passed in from codec.
* Removed code to set Y from UV.
* 1.08 PGW 28 Feb 01 Removal of history buffer functionality.
* 1.07 PGW 28 Feb 01 Removal of pre-processor output buffer.
* 1.06 JBB 03 Aug 00 Added Malloc Checks
* 1.05 PGW 27 Jul 00 Removed SetVcapParams() plus other housekeeping.
* 1.04 PGW 10 Jul 00 Removed unused functions GetBlockStats(), BlockChangeVariance()
* and GetBlockCategories().
* Change interface to YUVAnalyseFrame() to include KF indicator.
* 1.03 PGW 22/06/00 Removed speed specific code.
* 1.02 JBB 30/05/00 Removed hard coded size limits
* 1.01 PGW 12/07/99 Changes to reduce uneccessary dependancies.
* 1.00 PGW 14/06/99 Configuration baseline
*
*****************************************************************************
*/
/****************************************************************************
* Header Frames
*****************************************************************************
*/
#define STRICT /* Strict type checking. */
#include <string.h>
#include "type_aliases.h"
#include "preproc.h"
/****************************************************************************
* Module constants.
*****************************************************************************
*/
#define MIN_STEP_THRESH 6
#define VARIANCE_THRESH 200
#define LOW_VARIANCE_THRESH 100
#define HIGH_SCORE 400
/****************************************************************************
* Explicit Imports
*****************************************************************************
*/
/****************************************************************************
* Exported Global Variables
*****************************************************************************
*/
/****************************************************************************
* Foreward References
*****************************************************************************
*/
/****************************************************************************
* Module Statics
*****************************************************************************
*/
/****************************************************************************
*
* ROUTINE : ScanYUVInit
*
* INPUTS : SCAN_CONFIG_DATA * ScanConfigPtr
* Configuration data.
*
* OUTPUTS : None.
*
* RETURNS : None.
*
* FUNCTION : Initialises the scan process.
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
extern BOOL PAllocateFrameInfo(PP_INSTANCE * ppi);
BOOL ScanYUVInit( PP_INSTANCE * ppi, SCAN_CONFIG_DATA * ScanConfigPtr)
{
// Test machine specific features such as MMX support
MachineSpecificConfig(ppi);
/* Set up the various imported data structure pointers. */
ppi->ScanConfig.Yuv0ptr = ScanConfigPtr->Yuv0ptr;
ppi->ScanConfig.Yuv1ptr = ScanConfigPtr->Yuv1ptr;
ppi->ScanConfig.FragInfo = ScanConfigPtr->FragInfo;
ppi->ScanConfig.FragInfoElementSize = ScanConfigPtr->FragInfoElementSize;
ppi->ScanConfig.FragInfoCodedMask = ScanConfigPtr->FragInfoCodedMask ;
ppi->ScanConfig.RegionIndex = ScanConfigPtr->RegionIndex;
ppi->ScanConfig.HFragPixels = ScanConfigPtr->HFragPixels;
ppi->ScanConfig.VFragPixels = ScanConfigPtr->VFragPixels;
ppi->ScanConfig.VideoFrameWidth = ScanConfigPtr->VideoFrameWidth;
ppi->ScanConfig.VideoFrameHeight = ScanConfigPtr->VideoFrameHeight;
// UV plane sizes.
ppi->VideoUVPlaneWidth = ScanConfigPtr->VideoFrameWidth / 2;
ppi->VideoUVPlaneHeight = ScanConfigPtr->VideoFrameHeight / 2;
/* Note the size of the entire frame and plaes in pixels. */
ppi->YFramePixels = ppi->ScanConfig.VideoFrameWidth * ppi->ScanConfig.VideoFrameHeight;
ppi->UVFramePixels = ppi->VideoUVPlaneWidth * ppi->VideoUVPlaneHeight;
ppi->TotFramePixels = ppi->YFramePixels + (2 * ppi->UVFramePixels);
/* Work out various fragment related values. */
ppi->ScanYPlaneFragments = ppi->YFramePixels / (ppi->HFragPixels * ppi->VFragPixels);
ppi->ScanUVPlaneFragments = ppi->UVFramePixels / (ppi->HFragPixels * ppi->VFragPixels);;
ppi->ScanHFragments = ppi->ScanConfig.VideoFrameWidth / ppi->HFragPixels;
ppi->ScanVFragments = ppi->ScanConfig.VideoFrameHeight / ppi->VFragPixels;
ppi->ScanFrameFragments = ppi->ScanYPlaneFragments + (2 * ppi->ScanUVPlaneFragments);
if(!PAllocateFrameInfo(ppi))
return FALSE;
/* Set up the scan pixel index table. */
ScanCalcPixelIndexTable(ppi);
/* Initialise scan arrays */
InitScanMapArrays(ppi);
return TRUE;
}
/****************************************************************************
*
* ROUTINE : YUVAnalyseFrame
*
* INPUTS : None
*
* OUTPUTS : None.
*
* RETURNS : Number of "output" blocks to be updated.
*
* FUNCTION : Scores the fragments for the YUV planes
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
UINT32 YUVAnalyseFrame( PP_INSTANCE *ppi, UINT32 * KFIndicator )
{
UINT32 UpdatedYBlocks = 0;
UINT32 UpdatedUVBlocks = 0;
UINT32 i;
/* Initialise the map arrays. */
InitScanMapArrays(ppi);
/********** PGW 27/APR/2001 ***********/
// If the block is already marked as coded in the input block map then
// mark it as coded here to avoid unnecessary pre-processor work.
for ( i = 0; i < ppi->ScanFrameFragments; i++ )
{
if ( blockCoded(i) )
ppi->ScanDisplayFragments[i] = BLOCK_ALREADY_MARKED_FOR_CODING;
}
// If the motion level in the previous frame was high then adjust the high and low SAD
// thresholds to speed things up.
ppi->ModifiedGrpLowSadThresh = ppi->GrpLowSadThresh;
ppi->ModifiedGrpHighSadThresh = ppi->GrpHighSadThresh;
// testing force every block with any change to get coded
//ppi->ModifiedGrpHighSadThresh = 0;
// Set up the internal plane height and width variables.
ppi->VideoYPlaneWidth = ppi->ScanConfig.VideoFrameWidth;
ppi->VideoYPlaneHeight = ppi->ScanConfig.VideoFrameHeight;
ppi->VideoUVPlaneWidth = ppi->ScanConfig.VideoFrameWidth / 2;
ppi->VideoUVPlaneHeight = ppi->ScanConfig.VideoFrameHeight / 2;
// To start with *** TBD **** the stides will be set from the widths
ppi->VideoYPlaneStride = ppi->VideoYPlaneWidth;
ppi->VideoUPlaneStride = ppi->VideoUVPlaneWidth;
ppi->VideoVPlaneStride = ppi->VideoUVPlaneWidth;
// Set up the plane pointers
ppi->YPlanePtr0 = ppi->ScanConfig.Yuv0ptr;
ppi->YPlanePtr1 = ppi->ScanConfig.Yuv1ptr;
ppi->UPlanePtr0 = (ppi->ScanConfig.Yuv0ptr + ppi->YFramePixels);
ppi->UPlanePtr1 = (ppi->ScanConfig.Yuv1ptr + ppi->YFramePixels);
ppi->VPlanePtr0 = (ppi->ScanConfig.Yuv0ptr + ppi->YFramePixels + ppi->UVFramePixels);
ppi->VPlanePtr1 = (ppi->ScanConfig.Yuv1ptr + ppi->YFramePixels + ppi->UVFramePixels);
// Ananlyse the U and V palnes.
AnalysePlane( ppi, ppi->UPlanePtr0, ppi->UPlanePtr1, ppi->ScanYPlaneFragments, ppi->VideoUVPlaneWidth, ppi->VideoUVPlaneHeight, ppi->VideoUPlaneStride );
AnalysePlane( ppi, ppi->VPlanePtr0, ppi->VPlanePtr1, (ppi->ScanYPlaneFragments + ppi->ScanUVPlaneFragments), ppi->VideoUVPlaneWidth, ppi->VideoUVPlaneHeight, ppi->VideoVPlaneStride );
// Now analyse the Y plane.
AnalysePlane( ppi, ppi->YPlanePtr0, ppi->YPlanePtr1, 0, ppi->VideoYPlaneWidth, ppi->VideoYPlaneHeight, ppi->VideoYPlaneStride );
// Create an output block map for the calling process.
CreateOutputDisplayMap( ppi, ppi->ScanDisplayFragments);
// Set the candidate key frame indicator (0-100)
*KFIndicator = ppi->KFIndicator;
// Return the normalised block count (this is actually a motion level
// weighting not a true block count).
return ppi->OutputBlocksUpdated;
}
/****************************************************************************
*
* ROUTINE : SetScanParam
*
* INPUTS : ParamID
* ParamValue
*
* OUTPUTS : None.
*
* RETURNS : None.
*
* FUNCTION : Sets a scan parameter.
*
* SPECIAL NOTES : None.
*
*
* ERRORS : None.
*
****************************************************************************/
void SetScanParam( PP_INSTANCE *ppi, UINT32 ParamId, INT32 ParamValue )
{
switch (ParamId)
{
case SCP_SET_VCAP_LEVEL_OFFSET:
SetVcapLevelOffset(ppi, ParamValue);
break;
}
}

View file

@ -0,0 +1,343 @@
/****************************************************************************
*
* Module Title : preproc.h
*
* Description : Content analysis module header
*
* AUTHOR : Paul Wilkins
*
*****************************************************************************
* Revision History
*
* 1.08 PGW 27 Apr 01 Removed code to set Y from UV
* 1.07 PGW 28 Feb 01 Removal of history buffer functionality.
* 1.06 PGW 04 Oct 00 Added CANDIDATE_BLOCK_LOW.
* 1.05 PGW 24 Jul 00 Added Column SAD functions. Deleted BeThreshold.
* 1.04 PGW 13 Jul 00 Added BLOCK_CODED_LOW. Deleted BLOCK_CODED_EXTRA.
* 1.03 PGW 10 Jul 00 Added lookup tables to reduce number of conditionals
* in RowDiffScan(). Removed old "ifdef 0"ed code.
* Added KFIndicator.
* 1.02 JBB 30/05/00 Removed hard coded size limits
* 1.01 YX 06/04/00 Added XMMEnabled for optimizations
* 1.00 PGW 16/06/96 Configuration baseline.
*
*****************************************************************************
*/
#include "preprocconf.h"
#include "type_aliases.h"
#include "preprocif.h"
/* Constants. */
#define OUTPUT_BLOCK_HEIGHT 8
#define OUTPUT_BLOCK_WIDTH 8
#define INTERNAL_BLOCK_HEIGHT 8
#define INTERNAL_BLOCK_WIDTH 8
#define FILTER_BLOCK_SIZE (INTERNAL_BLOCK_WIDTH * INTERNAL_BLOCK_HEIGHT)
/* NEW Line search values. */
#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
/* Low Pass Filter levels. */
#define NO_LOW_PASS 0
#define VERY_LOW_LOW_PASS 1
#define LOW_LOW_PASS 2
#define MODERATE_LOW_PASS 5
#define HIGH_LOW_PASS 7
#define VERY_HIGH_LOW_PASS 9
#define FIRST_ROW 0
#define NOT_EDGE_ROW 1
#define LAST_ROW 2
#define YDIFF_CB_ROWS (INTERNAL_BLOCK_HEIGHT * 3)
#define CHLOCALS_CB_ROWS (INTERNAL_BLOCK_HEIGHT * 3)
#define PMAP_CB_ROWS (INTERNAL_BLOCK_HEIGHT * 3)
#define FRAG_PIXEL_DIFF_ROWS (INTERNAL_BLOCK_HEIGHT * 3)
#define PSCORE_CB_ROWS (INTERNAL_BLOCK_HEIGHT * 4)
#define PIXEL_SCORES_BUFFER_SIZE SCAN_MAX_LINE_LENGTH * PSCORE_CB_ROWS
#define YUV_DIFFS_CIRC_BUFFER_SIZE (SCAN_MAX_LINE_LENGTH * YDIFF_CB_ROWS)
#define CH_LOCALS_CIRC_BUFFER_SIZE (SCAN_MAX_LINE_LENGTH * CHLOCALS_CB_ROWS)
#define PIXEL_MAP_CIRC_BUFFER_SIZE (SCAN_MAX_LINE_LENGTH * PMAP_CB_ROWS)
// Status values in block coding map
#define CANDIDATE_BLOCK_LOW -2
#define CANDIDATE_BLOCK -1
#define BLOCK_NOT_CODED 0
#define BLOCK_CODED_BAR 3
#define BLOCK_ALREADY_MARKED_FOR_CODING 4
#define BLOCK_CODED_SGC 4
#define BLOCK_CODED_LOW 4
#define BLOCK_CODED 5
#define MAX_PREV_FRAMES 16
#define MAX_SEARCH_LINE_LEN 7
/******************************************************************/
/* Type definitions. */
/******************************************************************/
#define blockCoded(i) (ppi->ScanConfig.FragInfo[(i)*ppi->ScanConfig.FragInfoElementSize]&ppi->ScanConfig.FragInfoCodedMask)
#define setBlockCoded(i) ppi->ScanConfig.FragInfo[(i)*ppi->ScanConfig.FragInfoElementSize]|=ppi->ScanConfig.FragInfoCodedMask;
#define setBlockUncoded(i) ppi->ScanConfig.FragInfo[(i)*ppi->ScanConfig.FragInfoElementSize]&=(~ppi->ScanConfig.FragInfoCodedMask);
typedef struct PP_INSTANCE
{
UINT32 *ScanPixelIndexTableAlloc;
INT8 *ScanDisplayFragmentsAlloc;
UINT32 *FragScoresAlloc; // The individual frame difference ratings.
INT8 *SameGreyDirPixelsAlloc;
INT8 *BarBlockMapAlloc;
// Number of pixels changed by diff threshold in row of a fragment.
UINT8 *FragDiffPixelsAlloc;
UINT8 *PixelScoresAlloc;
UINT8 *PixelChangedMapAlloc;
UINT8 *ChLocalsAlloc;
INT16 *yuv_differencesAlloc;
INT32 *RowChangedPixelsAlloc;
INT8 *TmpCodedMapAlloc;
UINT32 *ScanPixelIndexTable;
INT8 *ScanDisplayFragments;
UINT32 *FragScores; // The individual frame difference ratings.
INT8 *SameGreyDirPixels;
INT8 *BarBlockMap;
// Number of pixels changed by diff threshold in row of a fragment.
UINT8 *FragDiffPixels;
UINT8 *PixelScores;
UINT8 *PixelChangedMap;
UINT8 *ChLocals;
INT16 *yuv_differences;
INT32 *RowChangedPixels;
INT8 *TmpCodedMap;
// Plane pointers and dimension variables
UINT8 * YPlanePtr0;
UINT8 * YPlanePtr1;
UINT8 * UPlanePtr0;
UINT8 * UPlanePtr1;
UINT8 * VPlanePtr0;
UINT8 * VPlanePtr1;
UINT32 VideoYPlaneWidth;
UINT32 VideoYPlaneHeight;
UINT32 VideoUVPlaneWidth;
UINT32 VideoUVPlaneHeight;
UINT32 VideoYPlaneStride;
UINT32 VideoUPlaneStride;
UINT32 VideoVPlaneStride;
/* Scan control variables. */
UINT8 HFragPixels;
UINT8 VFragPixels;
UINT32 ScanFrameFragments;
UINT32 ScanYPlaneFragments;
UINT32 ScanUVPlaneFragments;
UINT32 ScanHFragments;
UINT32 ScanVFragments;
UINT32 YFramePixels;
UINT32 UVFramePixels;
UINT32 TotFramePixels;
BOOL SgcOnOff;
UINT32 SgcThresh;
UINT32 OutputBlocksUpdated;
UINT32 KFIndicator;
BOOL ScanSRF_Enabled;
/* The VCAP scan configuration. */
SCAN_CONFIG_DATA ScanConfig;
BOOL VcapOn;
INT32 SRFGreyThresh;
INT32 SRFColThresh;
INT32 SgcLevelThresh;
INT32 SuvcLevelThresh;
INT32 SRFGreyThreshOffset;
INT32 SRFColThreshOffset;
INT32 SgcLevelThreshOffset;
INT32 SuvcLevelThreshOffset;
UINT32 NoiseSupLevel;
/* Block Thresholds. */
UINT32 PrimaryBlockThreshold;
INT32 SRFLevel;
INT32 SRFLevelOffset;
BOOL PAKEnabled;
BOOL EBO_Enabled;
BOOL CategorisationEnabled;
int LevelThresh;
int NegLevelThresh;
int SrfThresh;
int NegSrfThresh;
int HighChange;
int NegHighChange;
// Threshold lookup tables
UINT8 SrfPakThreshTable[512];
UINT8 * SrfPakThreshTablePtr;
UINT8 SrfThreshTable[512];
UINT8 * SrfThreshTablePtr;
UINT8 SgcThreshTable[512];
UINT8 * SgcThreshTablePtr;
// Variables controlling S.A.D. break outs.
UINT32 GrpLowSadThresh;
UINT32 GrpHighSadThresh;
UINT32 ModifiedGrpLowSadThresh;
UINT32 ModifiedGrpHighSadThresh;
INT32 PlaneHFragments;
INT32 PlaneVFragments;
INT32 PlaneHeight;
INT32 PlaneWidth;
INT32 PlaneStride;
UINT32 BlockThreshold;
UINT32 BlockSgcThresh;
double UVBlockThreshCorrection;
double UVSgcCorrection;
UINT32 SpeedCritical;
// Live test harness specific.
// PC specific variables
BOOL MmxEnabled;
BOOL XmmEnabled;
double YUVPlaneCorrectionFactor;
double AbsDiff_ScoreMultiplierTable[256];
UINT8 NoiseScoreBoostTable[256];
UINT8 MaxLineSearchLen;
INT32 YuvDiffsCircularBufferSize;
INT32 ChLocalsCircularBufferSize;
INT32 PixelMapCircularBufferSize;
// Temp stats variable
UINT32 TotBlocksUpdated;
// Function pointers for mmx switches
UINT32 (*RowSAD)(UINT8 *, UINT8 * );
UINT32 (*ColSAD)(xPP_INST ppi, UINT8 *, UINT8 * );
} PP_INSTANCE;
/******************************************************************/
/* Function prototypes. */
/******************************************************************/
INLINE UINT32 ScanGetFragIndex( PP_INSTANCE *ppi, UINT32 FragmentNo )
{
return ppi->ScanPixelIndexTable[ FragmentNo ];
}
extern void InitScanMapArrays
(
PP_INSTANCE *ppi
);
extern void AnalysePlane
(
PP_INSTANCE *ppi, UINT8 * PlanePtr0, UINT8 * PlanePtr1, UINT32 FragArrayOffset, UINT32 PWidth, UINT32 PHeight, UINT32 PStride
);
extern void ScanCalcPixelIndexTable
(
PP_INSTANCE *ppi
);
extern void CreateOutputDisplayMap
(
PP_INSTANCE *ppi,
INT8 *InternalFragmentsPtr
);
extern void SetVcapLevelOffset
(
PP_INSTANCE *ppi, INT32 LevelOffset
);
// Analysis functions
extern void RowBarEnhBlockMap
(
PP_INSTANCE *ppi,
UINT32 * FragScorePtr,
INT8 * FragSgcPtr,
INT8 * UpdatedBlockMapPtr,
INT8 * BarBlockMapPtr,
UINT32 RowNumber
);
extern void BarCopyBack
(
PP_INSTANCE *ppi,
INT8 * UpdatedBlockMapPtr,
INT8 * BarBlockMapPtr
);
// Secondary filter functions
extern UINT8 ApplyLowPass
(
PP_INSTANCE *ppi, UINT8 * SrcPtr, UINT32 PlaneLineLength, INT32 Level
);
// PC specific functions
extern void MachineSpecificConfig
(
);
extern void ClearMmx
(
PP_INSTANCE *ppi
);
extern UINT32 ScalarRowSAD
(
UINT8 * Src1, UINT8 * Src2
);
extern UINT32 ScalarColSAD
(
PP_INSTANCE *ppi, UINT8 * Src1, UINT8 * Src2
);
extern PP_INSTANCE * CreatePPInstance
(
void
);
extern void DeletePPInstance
(
PP_INSTANCE **ppi
);

View file

@ -0,0 +1,17 @@
/****************************************************************************
*
* Module Title : PreProcConf.H
*
* Description : Content analysis module configuration header
*
* AUTHOR : Paul Wilkins
*
*****************************************************************************
* Revision History
*
* 1.00 PGW 11/10/98 Header to control different configurations
*
*****************************************************************************
*/