This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TI816x dvrrdk350 SCD event get? Passive receiving event

Hi :

    I use scd alg have two question.

    1. scd support passive get the data(just like event or callback,if scd event (tamper or detect event happen auto call API to get the event data)

     2. I use Vsys_registerEventHandler(__demo_eventHandler,NULL); register a functon to handle the SCD event,but it never(but I can get the event data use the API Vcap_getAlgResultBuffer()

   my callback function:

  

static int __demo_eventHandler(unsigned int eventId,void *prm,void *appdata)
{
	if(eventId == VSYS_EVENT_TAMPER_DETECT)
	{
		AlgLink_ScdChStatus *pscdsat=(AlgLink_ScdChStatus *)prm;
		if(pscdsat->frmResult == ALG_LINK_SCD_DETECTOR_CHANGE)
		{
			xeLOG_WARNING("[TAMPER DETECT] channelId=%d",pscdsat->chId);

		}
		else if(pscdsat->frmResult == ALG_LINK_SCD_DETECTOR_NO_CHANGE)
		{
			xeLOG_WARNING("[TAMPER MOVED] channelId=%d",pscdsat->chId);
		}
		return 0;
	}

	if(eventId == VSYS_EVENT_MOTION_DETECT)
	{
		AlgLink_ScdResult *pscdresult=(AlgLink_ScdResult *)prm;
		xeLOG_WARNING("[MONTION DETECT] channelId=%d",pscdresult->chId);
		return 0;
	}

	return 0;
}

 current rdk350 not support register callback for event?

  • Event call back will work in 3.50

  • Hi:

       how the use event callback? could you give me some guide?

      my step is:  

       1. use Vsys_registerEventHandler() to register the event

        2. wait the event

       but when the event happen,I never saw the callback function wall called

  • HI :

      ALG_LINK_SCD_DETECTOR_CHANGE and ALG_LINK_SCD_DETECTOR_NO_CHANGE 

      this two event are not support in the RDK?

     I saw this at :http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/717/t/311088.aspx

     it's really true?

  • HI:

       I can recv the event now,but I have another question:

      if I use this frame:

    thread()
    {
    while()
    {
    Vcap_getAlgResultBuffer()
    .....
    Vcap_releaseAlgResultBuffer()
    }
    }

    event_handler()
    {
    ....
    VSYS_EVENT_MOTION_DETECT

    }

    the VSYS_EVENT_MOTION_DETECT will detect,and event_handler will called

    and like the demo frame:

    thread()
    {
    while()
    {
    pthread_cond_wait();
    Vcap_getAlgResultBuffer()
    .....
    Vcap_releaseAlgResultBuffer()
    }
    }

    event_handler()
    {
    ....
    VSYS_EVENT_MOTION_DETECT
    pthread_cond_signal();
    }

    the event_handler never called.what's the reason?

  • Does the event_handler get invoked atleast once in this approach?

    Event notification & buffer retrieval are done in different threads. Even then, this approach should work.

    Try to check how many times event notification occurs & if all buffers are aquired & released correctly.

  • HI:

        I have try many times,the event_handler never called ,so no signal was send.  it's just like buff is full,but I try delete the signal,just in the thread call Vcap_getAlgResultBuffer() and Vcap_releaseAlgResultBuffer(),the return value bitsBuf.numBufs=0,so the buff I think is empty if no event happen.

         maybe it's bug in DVRRDK350?

  • Hi:

        I don't know where the alglink send the VSYS_EVENT_MOTION_DETECT event to host.  maybe I can add some code to debug. and where the syscallback was called and where the host to recv the event. if you know,please told me.thanks very much!

  • 1. You should not do bitsBuf.numBufs=0. Refer the example usage.

    2. You can refer scLink_alg.c -> AlgLink_ScdalgProcess() for VSYS_EVENT_MOTION_DETECT

  • HI:

        I have see the scdLink_alg.c ,the main function is :AlgLink_ScdalgProcessData()

      the scd process data logic like this:

    in the logic picture: if buff require fail. no detective event will send. also if block changed num <= 0,also no event send. 

    but whether have event. the function will require a buff, so the buff will use out( just empty). 

    it's logic bug?

    I think if no event.should put back the buf  or every time send the event not judge the block changed num?

    I understand correctly ?

  • Hi:

      I have modify AlgLink_ScdalgProcess(),

    the original code is:

    Int32 AlgLink_ScdalgProcess(AlgLink_ScdObj *pScdAlgLinkObj, UInt32 chId, AlgLink_ScdResult * scdResultBuff)
    {
        SCD_Status      chanStatus;
        SCD_Result      scdResult;
        UInt32          chanID;
        SCD_chPrm       chanParam;
        AlgLink_ScdchPrm * chPrm;
        UInt32         blkIdx;
    
        chanID = pScdAlgLinkObj->chParams[chId].chId;
        chPrm = &(pScdAlgLinkObj->chParams[chId]);
    
        chanParam.chId                 = chPrm->chId;
        chanParam.mode                 = (SCD_Mode)(chPrm->mode & 0x2);
        chanParam.width                = chPrm->width;
        chanParam.height               = chPrm->height;
        chanParam.stride               = chPrm->width;//chPrm->stride;
        chanParam.curFrame             = chPrm->curFrame;
        chanParam.frmSensitivity       = (SCD_Sensitivity)chPrm->frmSensitivity;
        chanParam.frmIgnoreLightsON    = chPrm->frmIgnoreLightsON;
        chanParam.frmIgnoreLightsOFF   = chPrm->frmIgnoreLightsOFF;
        chanParam.frmEdgeThreshold     = chPrm->frmEdgeThreshold;
    
        if(chPrm->chBlkConfigUpdate == TRUE)
        {
            chanParam.blkConfig = (SCD_blkChngConfig *) chPrm->blkConfig;
        }
        else
        {
            chanParam.blkConfig = NULL;
        }
    
        chanStatus = SCD_TI_setPrms(pScdAlgLinkObj->algHndl, &chanParam, chanID);
    
        if(chanStatus != SCD_NO_ERROR)
        {
    #ifdef SYSTEM_DEBUG_SCD
            Vps_printf(" %d: SCD    : ERROR: Alg Set Params (chanID = %d) - 0x%08X !!!\n",
                      Utils_getCurTimeInMsec(), chanID, chanStatus);
    #endif
            return FVID2_EFAIL;
        }
    
    
        scdResult.frmResult = SCD_DETECTOR_NO_TAMPER;
        scdResult.blkResult = (SCD_blkChngMeta *)(scdResultBuff->blkResult);
    
        chanStatus = SCD_TI_process(pScdAlgLinkObj->algHndl, chanID, &scdResult);
    
        if(chanStatus != SCD_NO_ERROR)
        {
    #ifdef SYSTEM_DEBUG_SCD
            Vps_printf(" %d: SCD    : ERROR: Alg Process (chanID = %d) !!!\n",
                      Utils_getCurTimeInMsec(), chanID );
    #endif
    
            return FVID2_EFAIL;
        }
    
        scdResultBuff->frmResult = (AlgLink_ScdOutput) scdResult.frmResult;
        scdResultBuff->chId = chanID;
    
    
        /* Motion detect event notification. */
         UInt32 numBlkChg;
         UInt32 monitoredBlk;
         UInt32 numHorzBlks, numVertBlks, numBlksInFrame, blkHeight;
    
         monitoredBlk = 0;
         numBlkChg = 0;
         numHorzBlks     = ((pScdAlgLinkObj->chParams[chId].width + 0x1F ) & (~0x1F)) / 32;  /* Rounding to make divisible by 32 */
         if((pScdAlgLinkObj->chParams[chId].height%ALG_LINK_SCD_BLK_HEIGHT_MIN) == 0)        /* For Block height is divisible by 10 */
            blkHeight = ALG_LINK_SCD_BLK_HEIGHT_MIN;
         else   /* For Block height is divisible by 12 */
            blkHeight = ALG_LINK_SCD_BLK_HEIGHT;
         numVertBlks    = pScdAlgLinkObj->chParams[chId].height / blkHeight;
    
         numBlksInFrame = numHorzBlks * numVertBlks;
    
         /* Logic  to see how many blocks of total enabled blocks experienced change.
          * For each block, algorithm returns no. of pixels changed in the current
          * frame. This is compared against thresold determined using SCD sensitivity .
          * if changed pixels are more than the calculated thresold, block is marked as changed
          * i.e. motion is detected in the block.
          * Minimum value of thresold is 20% and then it is incrmented by 10% for
          * each sensitivity level change. Thresold can vary from 20% - 100%
          * At max sensitivity, thresold would be 20%. That means if 20% pixels
          * are changed block is marked as changed.
          * At minimu sensitivity, thresold would be 100%. That means if 100% pixels
          * are changed block is marked as changed */
    
         for(blkIdx = 0; blkIdx < numBlksInFrame; blkIdx++)
         {
             SCD_blkChngConfig * blockConfig;
    
             blockConfig = &pScdAlgLinkObj->chParams[chId].blkConfig[blkIdx];
             scdResultBuff->blkConfig[blkIdx].monitored   = blockConfig->monitored;
             scdResultBuff->blkConfig[blkIdx].sensitivity = blockConfig->sensitivity;
             if(blockConfig->monitored == 1)
             {
                 UInt32 threshold;
    
                 monitoredBlk++;
                 threshold = MOTION_DETECTION_SENSITIVITY(ALG_LINK_SCD_BLK_WIDTH, blkHeight) +
                                   (MOTION_DETECTION_SENSITIVITY_STEP * (SCD_SENSITIVITY_MAX - blockConfig->sensitivity));
    
                 if(scdResultBuff->blkResult[blkIdx].numPixelsChanged > threshold)
                 {
                     numBlkChg++;
                 }
             }
     
             /* If Motion detection mode ( **_MONITOR_BLOCK) is disabled of block is 
              * not monitor then set the values in the Result buff to zero to avoid 
              * false trigger/alarm. */
    
             if(((pScdAlgLinkObj->chParams[chId].mode & SCD_DETECTMODE_MONITOR_BLOCKS) == FALSE) || 
                  (blockConfig->monitored == 0))
             {
                  scdResultBuff->blkResult[blkIdx].numPixelsChanged  = 0;
                  scdResultBuff->blkResult[blkIdx].numFrmsBlkChanged = 0;
             }
         }
    
         /* Logic  to notify A8-host about motion detection.
          * Currently, if atleast 1 block is detected as changed A8 is notified.
          * User can use commented logic to chnage this behavior. 
          * if((monitoredBlk > 0) && (numBlkChg > (NUM_BLOCK_MOTION_DETECTION_THRESOLD(monitoredBlk)))) 
          */
    
        if(pScdAlgLinkObj->createArgs.enableMotionNotify)
        {
    		
            if((monitoredBlk > 0) && (numBlkChg > 0))
            {
    #ifdef SYSTEM_DEBUG_SCD_RT
                Vps_printf(" %d: SCD    : Motion Detected (chanID = %d),  !!!\n",
                       Utils_getCurTimeInMsec(), chanID );
    #endif
                System_linkControl(SYSTEM_LINK_ID_HOST, VSYS_EVENT_MOTION_DETECT, scdResultBuff, sizeof(AlgLink_ScdResult), TRUE);
    			Vps_rprintf("Robing: (%s)[%d] send VSYS_EVENT_MOTION_DETECT event\n",__FILE__,__LINE__);
    
            }
        }
    
        return FVID2_SOK;
    }

    after modify:

    Int32 AlgLink_ScdalgProcess(AlgLink_ScdObj *pScdAlgLinkObj, UInt32 chId, AlgLink_ScdResult * scdResultBuff)
    {
        SCD_Status      chanStatus;
        SCD_Result      scdResult;
        UInt32          chanID;
        SCD_chPrm       chanParam;
        AlgLink_ScdchPrm * chPrm;
        UInt32         blkIdx;
    
        chanID = pScdAlgLinkObj->chParams[chId].chId;
        chPrm = &(pScdAlgLinkObj->chParams[chId]);
    
        chanParam.chId                 = chPrm->chId;
        chanParam.mode                 = (SCD_Mode)(chPrm->mode & 0x2);
        chanParam.width                = chPrm->width;
        chanParam.height               = chPrm->height;
        chanParam.stride               = chPrm->width;//chPrm->stride;
        chanParam.curFrame             = chPrm->curFrame;
        chanParam.frmSensitivity       = (SCD_Sensitivity)chPrm->frmSensitivity;
        chanParam.frmIgnoreLightsON    = chPrm->frmIgnoreLightsON;
        chanParam.frmIgnoreLightsOFF   = chPrm->frmIgnoreLightsOFF;
        chanParam.frmEdgeThreshold     = chPrm->frmEdgeThreshold;
    
        if(chPrm->chBlkConfigUpdate == TRUE)
        {
            chanParam.blkConfig = (SCD_blkChngConfig *) chPrm->blkConfig;
        }
        else
        {
            chanParam.blkConfig = NULL;
        }
    
        chanStatus = SCD_TI_setPrms(pScdAlgLinkObj->algHndl, &chanParam, chanID);
    
        if(chanStatus != SCD_NO_ERROR)
        {
    #ifdef SYSTEM_DEBUG_SCD
            Vps_printf(" %d: SCD    : ERROR: Alg Set Params (chanID = %d) - 0x%08X !!!\n",
                      Utils_getCurTimeInMsec(), chanID, chanStatus);
    #endif
            return FVID2_EFAIL;
        }
    
    
        scdResult.frmResult = SCD_DETECTOR_NO_TAMPER;
        scdResult.blkResult = (SCD_blkChngMeta *)(scdResultBuff->blkResult);
    
        chanStatus = SCD_TI_process(pScdAlgLinkObj->algHndl, chanID, &scdResult);
    
        if(chanStatus != SCD_NO_ERROR)
        {
    #ifdef SYSTEM_DEBUG_SCD
            Vps_printf(" %d: SCD    : ERROR: Alg Process (chanID = %d) !!!\n",
                      Utils_getCurTimeInMsec(), chanID );
    #endif
    
            return FVID2_EFAIL;
        }
    
        scdResultBuff->frmResult = (AlgLink_ScdOutput) scdResult.frmResult;
        scdResultBuff->chId = chanID;
    
    
        /* Motion detect event notification. */
         UInt32 numBlkChg;
         UInt32 monitoredBlk;
         UInt32 numHorzBlks, numVertBlks, numBlksInFrame, blkHeight;
    
         monitoredBlk = 0;
         numBlkChg = 0;
         numHorzBlks     = ((pScdAlgLinkObj->chParams[chId].width + 0x1F ) & (~0x1F)) / 32;  /* Rounding to make divisible by 32 */
         if((pScdAlgLinkObj->chParams[chId].height%ALG_LINK_SCD_BLK_HEIGHT_MIN) == 0)        /* For Block height is divisible by 10 */
            blkHeight = ALG_LINK_SCD_BLK_HEIGHT_MIN;
         else   /* For Block height is divisible by 12 */
            blkHeight = ALG_LINK_SCD_BLK_HEIGHT;
         numVertBlks    = pScdAlgLinkObj->chParams[chId].height / blkHeight;
    
         numBlksInFrame = numHorzBlks * numVertBlks;
    
         /* Logic  to see how many blocks of total enabled blocks experienced change.
          * For each block, algorithm returns no. of pixels changed in the current
          * frame. This is compared against thresold determined using SCD sensitivity .
          * if changed pixels are more than the calculated thresold, block is marked as changed
          * i.e. motion is detected in the block.
          * Minimum value of thresold is 20% and then it is incrmented by 10% for
          * each sensitivity level change. Thresold can vary from 20% - 100%
          * At max sensitivity, thresold would be 20%. That means if 20% pixels
          * are changed block is marked as changed.
          * At minimu sensitivity, thresold would be 100%. That means if 100% pixels
          * are changed block is marked as changed */
    
         for(blkIdx = 0; blkIdx < numBlksInFrame; blkIdx++)
         {
             SCD_blkChngConfig * blockConfig;
    
             blockConfig = &pScdAlgLinkObj->chParams[chId].blkConfig[blkIdx];
             scdResultBuff->blkConfig[blkIdx].monitored   = blockConfig->monitored;
             scdResultBuff->blkConfig[blkIdx].sensitivity = blockConfig->sensitivity;
             if(blockConfig->monitored == 1)
             {
                 UInt32 threshold;
    
                 monitoredBlk++;
                 threshold = MOTION_DETECTION_SENSITIVITY(ALG_LINK_SCD_BLK_WIDTH, blkHeight) +
                                   (MOTION_DETECTION_SENSITIVITY_STEP * (SCD_SENSITIVITY_MAX - blockConfig->sensitivity));
    
                 if(scdResultBuff->blkResult[blkIdx].numPixelsChanged > threshold)
                 {
                     numBlkChg++;
                 }
             }
     
             /* If Motion detection mode ( **_MONITOR_BLOCK) is disabled of block is 
              * not monitor then set the values in the Result buff to zero to avoid 
              * false trigger/alarm. */
    
             if(((pScdAlgLinkObj->chParams[chId].mode & SCD_DETECTMODE_MONITOR_BLOCKS) == FALSE) || 
                  (blockConfig->monitored == 0))
             {
                  scdResultBuff->blkResult[blkIdx].numPixelsChanged  = 0;
                  scdResultBuff->blkResult[blkIdx].numFrmsBlkChanged = 0;
             }
         }
    
         /* Logic  to notify A8-host about motion detection.
          * Currently, if atleast 1 block is detected as changed A8 is notified.
          * User can use commented logic to chnage this behavior. 
          * if((monitoredBlk > 0) && (numBlkChg > (NUM_BLOCK_MOTION_DETECTION_THRESOLD(monitoredBlk)))) 
          */
    
        if(pScdAlgLinkObj->createArgs.enableMotionNotify)
        {
    		
     //       if((monitoredBlk > 0) && (numBlkChg > 0))
     //       {
    #ifdef SYSTEM_DEBUG_SCD_RT
                Vps_printf(" %d: SCD    : Motion Detected (chanID = %d),  !!!\n",
                       Utils_getCurTimeInMsec(), chanID );
    #endif
                System_linkControl(SYSTEM_LINK_ID_HOST, VSYS_EVENT_MOTION_DETECT, scdResultBuff, sizeof(AlgLink_ScdResult), TRUE);
    			Vps_rprintf("Robing: (%s)[%d] send VSYS_EVENT_MOTION_DETECT event\n",__FILE__,__LINE__);
    
     //       }
        }
    
        return FVID2_SOK;
    }

    the different is delete the condition,every time send the event. after modify, the thread can recv the signal ,also the event_handler was called.  but I don't think this modify is good. so wish you replay.thanks very much!

  • I was referring to a wrong code base and was wrong in few of my earlier comments.

    Refer demo app - demo_scd_bits_wr.c

    1. MOTION_DETECT is not sent per buffer basis. So, your app change is wrong - you are interpreting the implementation in a different way.

    2. Your app can wait on a callback and invoke Vcap_getAlgResultBuffer / Vcap_releaseAlgResultBuffer using the callback mode as used in demo app.

    3. Vcap_registerBitsCallback() is supported and the usage can be referred in demo app.

    Try to use demo app as is and see if it works fine and then proceed with your app changes.

  • HI:

        I have try the demo ,it's work not fine.  Vcap_registerBitsCallback() ,the callback also never called, in the RDK350 src, can't find any support about the Vcap_registerBitsCallback(). maybe you can give me some guide about this api work!

  • Hi:

        thanks very much, I have got the way to know the callback how to work. yes I make a mistake  to use the callback.