www.pudn.com > Lab534-VideoMotionDetect.rar > cellDiff.c


/* 
 *  Copyright 2002 by Texas Instruments Incorporated. 
 *  All rights reserved. Property of Texas Instruments Incorporated. 
 *  Restricted rights to use, duplicate or disclose this code are 
 *  granted through contract. 
 *   
 */ 
/* 
 *  ======== celldiff.c ======== 
 */                                           
                         
#include  
#include  
#include  
#include  
#include  
 
#include "cellDiff.h" 
#include "appResources.h" 
#include "appThreads.h" 
 
#pragma DATA_SECTION(yOutBuff, ".EXTPROCBUFF"); 
#pragma DATA_SECTION(crOutBuff, ".EXTPROCBUFF"); 
#pragma DATA_SECTION(cbOutBuff, ".EXTPROCBUFF"); 
#pragma DATA_ALIGN(yOutBuff, MEMALIGN); 
#pragma DATA_ALIGN(crOutBuff, MEMALIGN); 
#pragma DATA_ALIGN(cbOutBuff, MEMALIGN); 
 
//Temporary frame buffers to hold output data 
static Char yOutBuff[PROCF_SIZE_IN_PIXELS]; 
static Char crOutBuff[PROCF_SIZE_IN_PIXELS << 2]; 
static Char cbOutBuff[PROCF_SIZE_IN_PIXELS << 2]; 
 
static void runDIFF( IDIFF_Handle handle, Short **inData, 
                       Uint32 **outData, DIFF_Env * env); 
 
// v-table for this cell 
ICELL_Fxns DIFF_CELLFXNS = {  
    NULL,                  // cellClose 
    NULL,                  // cellControl 
    DIFF_cellExecute,      // cellExecute 
    NULL                   // cellOpen 
}; 
 
/* 
 *  ======== DIFF_cellExecute ======== 
 * 
 */ 
Bool DIFF_cellExecute( ICELL_Handle handle, Arg arg ) 
{     
    IDIFF_Handle diffHandle = (IDIFF_Handle)handle->algHandle; 
 
    // activate instance object 
    ALGRF_activate( handle->algHandle ); 
 
    runDIFF(diffHandle, 
              (Short **)handle->inputIcc[0]->buffer, 
              (Uint32 **)handle->outputIcc[0]->buffer, 
              (DIFF_Env *)handle->cellEnv); 
 
    // deactivate instance object 
    ALGRF_deactivate( handle->algHandle ); 
 
    return(TRUE); 
}     
 
/* 
 *  ======== runDIFF ======== 
 *  Run DIFF algorithm. 
 */ 
static void runDIFF(IDIFF_Handle handle, Short **inData,  
                      Uint32 **outData, DIFF_Env *env) 
{    
    Int toggle = 0;       // used for double buffering      
    Int yInId, crInId, cbInId; // ids for current DMA transfers 
    Int yOutId, crOutId, cbOutId; // ids for current DMA transfers 
    Int yPrevInId, crPrevInId, cbPrevInId; // prev. submitted transfers 
    Int yPrevOutId, crPrevOutId, cbPrevOutId; // prev. submitted transfers 
    int finalOutId; // final transfer to display buffer 
    Int i; 
     
    // Data pointers for incoming data 
    Char *yInData  = (Char *)inData[0]; 
    Char *crInData = (Char *)inData[1]; 
    Char *cbInData = (Char *)inData[2]; 
 
    // Data pointers for outgoing data 
    Char *yOutData; 
    Char *crOutData; 
    Char *cbOutData; 
     
    // Data pointers for intermediate data 
    Char *intYBuf  = env->intYBuf; 
    Char *intCrBuf = env->intCrBuf; 
    Char *intCbBuf = env->intCbBuf; 
     
    // Data pointers for previous frame (reference frame) 
    Char *ptrPrevY = env->prevY; 
    Char *ptrPrevCr = env->prevCr; 
    Char *ptrPrevCb = env->prevCb; 
 
	// Processing block parameters 
    Uns numBlocks       = env->numBlocks; 
    Uns ySingleBufSize  = env->yBufSize >> 1; 
    Uns crSingleBufSize = env->crBufSize >> 1; 
    Uns cbSingleBufSize = env->cbBufSize >> 1; 
	Int linePitch		= env->linePitch; 
    
	// Point output data to intermediate buffers 
	yOutData = yOutBuff;  
	crOutData = crOutBuff; 
	cbOutData = cbOutBuff; 
 
     
    // Prime the DMA to get initial transfer ids 
    yPrevInId   = DAT_copy((Void *)yInData,  (Void *)intYBuf,  ySingleBufSize); 
    crPrevInId  = DAT_copy((Void *)crInData, (Void *)intCrBuf, crSingleBufSize); 
    cbPrevInId  = DAT_copy((Void *)cbInData, (Void *)intCbBuf, cbSingleBufSize); 
         
    // Needed for the first operation in a pipelined copy sequence. 
    yPrevOutId  = DAT_XFRID_WAITNONE; 
    crPrevOutId = DAT_XFRID_WAITNONE; 
    cbPrevOutId = DAT_XFRID_WAITNONE; 
 
    for ( i = 0; i < numBlocks; i++) { 
 
        /* 
         *  Update external input buffer pointers 
         *  Note: One of the transfers was initiated before this 
         *        for loop. Therefore you need only numBlocks - 1 
         *        transfers in this loop. 
         */ 
        if (i < (numBlocks - 1)) { 
            yInData  += ySingleBufSize; 
            crInData += crSingleBufSize; 
            cbInData += cbSingleBufSize; 
     
            // DMA next set of input data into internal buffers 
            yInId  = DAT_copy((Void *)yInData,  
                        (Void *)(intYBuf + ((toggle ^ 1) * ySingleBufSize)), 
                        ySingleBufSize); 
            crInId = DAT_copy((Void *)crInData, 
                        (Void *)(intCrBuf + ((toggle ^ 1) * crSingleBufSize)), 
                        crSingleBufSize); 
            cbInId = DAT_copy((Void *)cbInData, 
                        (Void *)(intCbBuf + ((toggle ^ 1) * cbSingleBufSize)), 
                        cbSingleBufSize); 
        } 
 
        // Wait on previous DMA transfer 
        DAT_wait(yPrevInId); 
        DAT_wait(crPrevInId); 
        DAT_wait(cbPrevInId); 
         
        // Now for the real work...call the algorithm. 
        handle->fxns->apply(handle,  
            (unsigned char *)(intYBuf  + (toggle * ySingleBufSize)), 
            (unsigned char *)(intCrBuf + (toggle * crSingleBufSize)), 
            (unsigned char *)(intCbBuf + (toggle * cbSingleBufSize)), 
            (unsigned char *)ptrPrevY, (unsigned char *)ptrPrevCr, 
            (unsigned char *)ptrPrevCb, ySingleBufSize, crSingleBufSize, 
            env->yValue, env->crValue, env->cbValue, PROCF_WIDTH); 
 
        // DMA decompressed data out to external memory 
        yOutId = DAT_copy((Void *)(intYBuf + (toggle * ySingleBufSize)), 
                          (Void *) yOutData, ySingleBufSize); 
        crOutId = DAT_copy((Void *)(intCrBuf + (toggle * crSingleBufSize)), 
                           (Void *) crOutData, crSingleBufSize); 
        cbOutId = DAT_copy((Void *)(intCbBuf + (toggle * cbSingleBufSize)), 
                           (Void *) cbOutData, cbSingleBufSize); 
        
        // Update external output buffer pointers 
        yOutData  += ySingleBufSize; 
        crOutData += crSingleBufSize; 
        cbOutData += cbSingleBufSize; 
         
        // Update reference frame pointers 
        ptrPrevY += ySingleBufSize; 
        ptrPrevCr += crSingleBufSize; 
        ptrPrevCb += cbSingleBufSize; 
 
        toggle ^= 1; 
 
        /* 
         *  Wait on previous DMA transfers.   
         *  Note: The first time, there is no previous transfer to wait on. 
         *        The last set of DAT_wait is outside the for loop. 
         */  
        DAT_wait(yPrevOutId); 
        DAT_wait(crPrevOutId); 
        DAT_wait(cbPrevOutId); 
         
        yPrevInId   = yInId; 
        crPrevInId  = crInId; 
        cbPrevInId  = cbInId; 
 
        yPrevOutId  = yOutId; 
        crPrevOutId = crOutId; 
        cbPrevOutId = cbOutId; 
    } 
 
    // Wait on last set of DMA transfers     
    DAT_wait(yPrevOutId); 
    DAT_wait(crPrevOutId); 
    DAT_wait(cbPrevOutId); 
     
	DAT_copy2d(DAT_1D2D, yOutBuff, outData[0], PROCF_WIDTH, PROCF_HEIGHT,linePitch); 
	DAT_copy2d(DAT_1D2D, crOutBuff, outData[1], PROCF_WIDTH>>1, PROCF_HEIGHT>>1,linePitch>>1); 
	finalOutId = DAT_copy2d(DAT_1D2D, cbOutBuff, outData[2], PROCF_WIDTH>>1, PROCF_HEIGHT>>1,linePitch>>1); 
     
	DAT_wait(finalOutId); 
}