/*************************************************************************** mosc.c - time average a video stream in a central fovea area This program will apply a recursive filter to time average the video data. The filter that will be applied is: y(n) = K*x(n) + (1 - K)*y(n - 1) where K is a constant between 0 and 1 y(n) is the current averaged frame y(n-1) is the previous averaged frame x(n) is the current input frame The area of the image where the filter will be applied is controlled by a MOSC element from a mask in memory. ***************************************************************************/ #include #include /* define the display size */ #define DISPLAYXSIZE 512L #define DISPLAYYSIZE 484L dqLimitIPDevSet(AB AM AS AG AU); main() { DqSystem oSystem; DqIPDev oAb00, oAm00, oAm01, oAm02, oAm05, oAg00, oAs00, oAu00; DqSurf oDispSrcSurf, oDispDstSurf, oAcqSrcSurf, oAcqDstSurf; DqSurf oProcSrcSurf,oProcDstSurfs[3]; DqSurf FoveaMask, LastFrameSrc; DqPipe oDispPipe, oAcqPipe, oProcPipe; /* initialize the hardware and ImageFlow software */ dqInitEnv(); /* get handles for the system and all devices being used */ oSystem = dqCreateStdSys(); oAb00 = dqFindIPDev(oSystem, "ab00"); oAs00 = dqFindIPDev(oSystem, "as00"); oAg00 = dqFindIPDev(oSystem, "ag00"); oAu00 = dqFindIPDev(oSystem, "au00"); oAm00 = dqFindIPDev(oSystem, "ab00:am00"); oAm01 = dqFindIPDev(oSystem, "ab00:am01"); oAm02 = dqFindIPDev(oSystem, "ab00:am02"); oAm05 = dqFindIPDev(oSystem, "ab00:am05"); /* set the data type checking to tolerant */ dqSetDTPDogma(DQ_DTP_TOLERANT); /********************* ACQUISITION PIPE *****************************/ oAcqSrcSurf = dqCreateStdSizeSurf(oAs00, AS_ADC); dqAttachSurf(oAcqSrcSurf, AS_XMT); dqConnect(oAb00, DQ_CSG, AB_OP05); /* use unsigned output of AS */ amSetRcvGateway20MHz(oAm05); oAcqDstSurf = dqCreateSameSizeSurf(oAm05, AM_MEM_R8,oAcqSrcSurf); dqAttachSurf(oAcqDstSurf,AM_RCV); /* create a continuously running pipe, arm and fire it */ oAcqPipe = dqCreatePipe(oAcqDstSurf, DQ_TRG_CONTINUOUS); dqArmPipe(oAcqPipe, DQ_DSM_PIPE); dqFirePipe(oAcqPipe); /*********************** PROCESSING PIPE *****************************/ /* start the video side of the process pipe with a dup of the acquisition pipe destination */ oProcSrcSurf = dqDupSurf(oAcqDstSurf); dqAttachSurf(oProcSrcSurf, AM_XMT); amSetXmtGateway20MHz(oAm05); dqSetSurfBaseDT(oProcSrcSurf,DQ_DT_UNSIGNED); /* across the cross point to the time filter */ dqConnect(oAb00,DQ_IMX5,AB_OP08); /* current frame into Moe */ dqSetKVal(oAb00,AB_OP09,0); dqConnect(oAu00,AU_I_SEP_MOE,AU_I_MOE); dqConnect(oAu00,AU_I_MOE_X0,AU_G_OP8); /* create K * x(n) K set in AU_L_K1 */ dqConnect(oAu00,AU_L_EXT0,AU_L_MULT1_BOP); dqSetKBaseDT(oAu00,AU_L_K1,DQ_DT_SIGNED); dqConnect(oAu00,AU_L_K1,AU_L_MULT1_AOP); /* create surface to save the last frame */ LastFrameSrc = dqCreateSameSizeSurf(oAm01,AM_MEM_R8,oProcSrcSurf); dqSetSurfBaseDT(LastFrameSrc,DQ_DT_UNSIGNED); dqAttachSurf(LastFrameSrc,AM_XMT); amSetXmtGateway20MHz(oAm01); /* bring last frame across the cross point to the time filter */ dqConnect(oAb00,DQ_IMX1,AB_OP10); /* last frame into Larry */ dqSetKVal(oAb00,AB_OP11,0); dqConnect(oAu00,AU_I_SEP_LARRY,AU_I_LARRY); dqConnect(oAu00,AU_I_LARRY_X0,AU_G_OP9); /* create (1 - K) * y(n - 1) (1 - K) set in AU_L_K0 */ dqConnect(oAu00,AU_L_EXT1,AU_L_MULT0_AOP); dqSetKBaseDT(oAu00,AU_L_K0,DQ_DT_SIGNED); dqConnect(oAu00,AU_L_K0,AU_L_MULT0_BOP); /* zero down the AU_L_MULT2 and AU_L_MULT3 chains */ dqSetKVal(oAu00,AU_L_K2,0x00); dqConnect(oAu00,AU_L_K2,AU_L_MULT2_AOP); dqConnect(oAu00,AU_L_K2,AU_L_MULT2_BOP); dqSetKVal(oAu00,AU_L_K3,0x00); dqConnect(oAu00,AU_L_K3,AU_L_MULT3_AOP); dqConnect(oAu00,AU_L_K3,AU_L_MULT3_BOP); /* Combine to get K*x(n) + (1 - K)*y(n - 1) Calculations are performed with binary point at bit 7-8 This shift moves binary point to bit 0-1 when leaving AU_L_SHIFT3 */ dqSpecShift(oAu00,AU_L_SHIFT3,DQ_SHIFT_ARITHMETIC,-7); /* Then effect rounding by adding 1 before AU_L_ADD3 tosses the LSB */ dqSetKVal(oAu00,AU_L_K4,1); dqConnect(oAu00,AU_L_K4,AU_L_ADD3_BOP); /* now straight shot to AU_L_RESULT */ dqConnect(oAu00,AU_L_CLIP,AU_L_P_RES); dqConnect(oAu00,AU_L_P_RES,AU_L_RESULT); /* pass result back through the AU cross point */ dqConnect(oAu00,AU_L_RESULT_X0,AU_G_OP1); dqConnect(oAu00,AU_O_CLIP1,AU_O_C7_SRC); /* across cross point to display and last frame surface */ dqConnect(oAb00,DQ_CU07,AB_OP01); dqConnect(oAb00,DQ_CU07,AB_OP00); /* create surface to save this frame for next time */ oProcDstSurfs[0] = dqDupSurf(LastFrameSrc); dqAttachSurf(oProcDstSurfs[0],AM_RCV); amSetRcvGateway20MHz(oAm01); /* create surface for the display output */ oProcDstSurfs[1] = dqCreateSameSizeSurf(oAm00,AM_MEM_R8,oProcSrcSurf); dqAttachSurf(oProcDstSurfs[1],AM_RCV); amSetRcvGateway20MHz(oAm00); /*********************************************************************/ /* */ /* BEGIN ADDED CODE FOR MOSC CONTROL */ /* */ /*********************************************************************/ /* create the surface for the fovea mask image */ FoveaMask = dqCreateSameSizeSurf(oAm02,AM_MEM_R8,oProcSrcSurf); dqSetSurfBaseDT(FoveaMask,DQ_DT_UNSIGNED); dqAttachSurf(FoveaMask,AM_XMT); amSetXmtGateway20MHz(oAm02); /* fovea mask across the cross point to AU binary input section */ dqConnect(oAb00,DQ_IMX2,AB_OP12); dqConnect(oAu00,DQ_CU04_D0,AU_I_BIN0_PRE); dqConnect(oAu00,AU_I_BIN0_PRE,AU_I_BIN0); /* through binary cross point to control AU_L_MOSC0 + 1 */ dqConnect(oAu00,AU_I_BIN0,AU_B_OP3); /*********************************************************************/ /* */ /* END ADDED CODE FOR MOSC CONTROL */ /* */ /*********************************************************************/ /* terminate surface list and create pipe */ oProcDstSurfs[2] = 0; oProcPipe = dqCreateMultiDstPipe(oProcDstSurfs,DQ_TRG_CONTINUOUS); dqArmPipe(oProcPipe,DQ_DSM_PIPE); dqFirePipe(oProcPipe); /*********************** DISPLAY PIPE ********************************/ oDispSrcSurf = dqDupSurf(oProcDstSurfs[1]); dqAttachSurf(oDispSrcSurf,AM_XMT); dqSpecXmtExpansion(oAm00,AM_XMT,4,1); amSetDispGateway40MHz(oAm00); dqConnect(oAg00, AG_RED, AG_DAC_LUT_SRC); dqConnect(oAg00, AG_DAC_LUT, AG_DAC_SRC); oDispDstSurf = dqCreateSurf(oAg00, AG_DAC,DISPLAYXSIZE,DISPLAYYSIZE); dqAttachSurfGate(oDispDstSurf, AG_RCV); dqSpecRcvShrinkage(oAg00,AG_RCV,4,1); /* create the display pipe, arm and fire it */ oDispPipe = dqCreatePipe(oDispDstSurf, DQ_TRG_CONTINUOUS); dqArmPipe(oDispPipe, DQ_DSM_PIPE); dqFirePipe(oDispPipe); /* loop for input of K and Radius values */ do { float NewK; int K,OneMinusK; int Radius; printf("Enter K between 0.0 and 1.0 (<0 to stop): "); scanf("%f",&NewK); if(NewK < 0.0) break; if(NewK > 1.0) continue; K = irint(256.0 * NewK); OneMinusK = irint(256.0 * (1.0 - NewK)); /*********************************************************************/ /* */ /* BEGIN ADDED CODE FOR MOSC CONTROL */ /* */ /*********************************************************************/ printf("Enter radius of central area: "); scanf("%d",&Radius); /* stop the pipe to set these values */ dqHaltPipe(oProcPipe); /* fill the mask with 0's and center region with 1's */ gsClearView(FoveaMask,0x00); gsSetFillStyle(FoveaMask,GS_SOLID); gsSetFillColor(FoveaMask,0x01); gsCircle(FoveaMask,DISPLAYXSIZE/2,DISPLAYYSIZE/2,Radius); /* MOSC state 1 => fovea; state 0 = periphery */ /* AU_L_MOSC1 controls k * x(n) */ dqSetMoscState(oAu00,AU_L_MOSC1,1); dqSetKVal(oAu00,AU_L_K1,K); dqSetMoscState(oAu00,AU_L_MOSC1,0); dqSetKVal(oAu00,AU_L_K1,256); /* AU_L_MOSC0 controls (1 - K) * y(n - 1) */ dqSetMoscState(oAu00,AU_L_MOSC0,1); dqSetKVal(oAu00,AU_L_K0,OneMinusK); dqSetMoscState(oAu00,AU_L_MOSC0,0); dqSetKVal(oAu00,AU_L_K0,0); /* get the pipe running again. No changes made to topology or delays */ dqArmPipe(oProcPipe,DQ_DSM_NONE); dqFirePipe(oProcPipe); /*********************************************************************/ /* */ /* END ADDED CODE FOR MOSC CONTROL */ /* */ /*********************************************************************/ } while(1); dqDisposeSys(oSystem); } /* auxiliary functions to set up the AM gateways to the correct speed */ amSetRcvGateway20MHz(oAmDev) DqIPDev oAmDev; { dqConnect(oAmDev,AM_SPUP0,AM_INPUT0); dqConnect(oAmDev,AM_INPUT0,AM_OP0); dqSpecLogic(oAmDev,AM_LOGIC4,0,1); dqSpecLogic(oAmDev,AM_LOGIC0,0xffffffff,0); amSetGateSysClkMult(oAmDev,AM_RCV,2); } amSetXmtGateway20MHz(oAmDev) DqIPDev oAmDev; { amSetGateSysClkMult(oAmDev,AM_XMT,2); dqConnect(oAmDev,AM_XMT_OUT,AM_OP3); dqSpecLogic(oAmDev,AM_LOGIC3,0xffffffff,0); dqConnect(oAmDev,AM_SLDN0_T0,AM_OUTPUT0); dqConnect(oAmDev,AM_XMT,AM_XMT_OUT); } amSetDispGateway40MHz(oAmDev) DqIPDev oAmDev; { amSetGateSysClkMult(oAmDev,AM_XMT,4); dqConnect(oAmDev,AM_XMT_OUT,AM_OP3); dqSpecLogic(oAmDev,AM_LOGIC3,0xff,0); dqConnect(oAmDev,AM_LOGIC3,AM_OUTPUT0); dqConnect(oAmDev,AM_XMT,AM_XMT_OUT); }