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.

RTSP streaming of mosaic

We use DVR_RDK 03.00.00.00 with usecase VSYS_USECASE_MULTICHN_PROGRESSIVE_VCAP_VDIS_VENC_VDEC.
RTSP streaming of single video channels is running well in ths usecase.

But we also need the possibility stream Mosaic of the connected video inputs via RTSP.
This means we have to create mosaic before encoding happens.

But my fear is that we can not create another mosaic because of the limitation with the scalars.
and we have 2 mosaics in use to for display outputs.
I already discussed this here in this forum with Badri.

My primary idea was the following approch:
The layout of this mosaic must be set-able in the same way as it is possible for display mosaic.
The mosaic shall be composed from the 16 D1 input channels.
One of the 16 D1 encoder channels shall be used to encode this D1 mosaic.
A schematic of this approach to modify  mcfw/src_linux/mcfw_api/usecases/ti816x/multich_progressive_vcap_venc_vdec_vdis.c
is shown in attached files.
The mosaic shall be created in a chain Dup Link -> SWMS Link -> Merger Link –> Selector Link.
The Selector Link currently only can be used to map input channels to a output channels queue.
The Selector Link must be modified to get a component for real channel selection.
In our case we must be able to select 16 output channels form 17 input channels.
The last one of the select-able channels shall contain the mosaic or channel 16.

But now I am not sure if this is feasible, with the awareness of the scalar limitations.
Another idea would be to use CIF encoded stream, but a mosaic must created in this version too.

Has anybody a idea how to solve this task ?

5140.multich_progressive_vcap_venc_vdec_vdis.txt
           +----------------------+
           |   Capture (YUV422I)  |
           |                      |
           |   16 CH D1 60fps     |
           +----------+-----------+
                      |
           +----------v-----------+
           | CAPTURE_DISPLAY_DUP  |
           +--+------------+------+
     +--------+            |          <Process Link>
     |                +----v---------+              +---------------+      +---------+
     |                |IPC Frames Out+------------->|IPC Frames In  +----->| AlgLink |
     |                |    (M3)      <--------------+    (DSP)      <------+  (SWOSD)|
     |                +---+-------+--+              +---------------+      +---------+
     |              8CH D1|       |8CH D1
     |              YUV422|       |YUV422
     |                    |       +---------------------+
     |                    |                             |
     |              +-----v-------+              +------v-------+
     |              |   DEIH      |              |    DEI       |
     |              |             |              |              |
     |              |DEI_SC VIP_SC|              |DEI_SC  VIP_SC|
     |              +-------------+              +--------------+
     |           8CH D1|    |  |8CH D1          8CH D1|   |  |8CH D1
     |           YUV422|    |  |YUV420          YUV422|   |  |YUV420
     |                 |    |  |                      |   |  +---------------+
     |                 |    |  +----------------------|---|-------+          |
     |                 |    |8CH CIF               8CH|CIF|       |          |
     |       +---------+    |YUV420                YUV|420|      +v----------v----+
     |       |              |                         |   |      |MERGE_VIP_SC_D1 |
     |       |     +----------------------------------+   |      |                |
     |       |     |        |                             |      +---------+------+
     |       |     |        +---------+    +--------------+                |16CH D1
     |       |     |                  |    |                               +----------+
     |       |     |                  |    |                                          |
     |       |     |                  |    |                                    +-----v------+
     |       |     |                  |    |                                    |  DUP LINK  |
     |       |     |                  |    |                                    |            |
     |       |     |                  |    |                                    +---+----+---+
     |       |     |                  |    |                                        |    |
     |       |     |                  |    |                               +--------+    +--------+
     |       |     |                  |    |                               |                      |
     |       |     |                  |    |                               |                +-----v------+
     |       |     |                  |    |                               |                |    SWMS    |
     |       |     |                  |    |                               |                |            |
     |       |     |                  |    |                               |                +-----+------+
     |       |     |                  |    |                               |                      |
     |       |     |                  |    |                               |                +-----v------+
     |       |     |                  |    |                               |                |    NSF     |
     |       |     |                  |    |                               |                |            |
     |       |     |                  |    |                               |                +-----+------+
     |       |     |                  |    |                               |          +-------+   |
     |       |     |                  |    |                               |          |       |   |
     |       |     |                  |    |                               |          |   +---v---v----+
     |       |     |                  |    |                               |          |   |    MERGE   |
     |       |     |                  |    |                               |          |   |            |
     |       |     |                  |    |                               |          |   +------+-----+
     |       |     |                  |    |                               |          |          |
     |       |     |                  |    |                               |          |    API   |
     |       |     |                  |    |                               |          |     |    |17CH D1
     |       |     |                  |    |                               |          |   +-v----v------+
     |       |     |                  |    |                               v          |   |             |
     |       |     |                  |    |                      +---------------+   |   | Customized  |
     |       |     |                  |    |                      |   DUP_D1_LINK |   |   |  Selector   |
     |       |     |                  v    v                      |               |   |   |    Link     |
     |       |     |            +----------------+                +-------+--+----+   |   |             |
     |       |     |            |MERGE_VIP_SC_   |                 16CH D1|  |16CH D1 |   +------+------+
     |       |     |            |SECONDARY_OUT   |                  YUV420|  |YUV420  |          |16CH D1
     |       |     |            +-------+--------+                  MJPEG |  |PRI     |          |
     |       |     |                    |16CH CIF                         |  |        |          |
     |       |     |                    |YUV420                           |  +--------+          |
     |       |     |                    |                                 |                      |
     |       |     |                    |                                 |     +----------------+
     |       |     |                    |              +--------------+   |     |
     |       |     |            +-------v---------+    |    16CH CIF  |   |     |
     |       |     |            |  CIF DUP LINK   |    |    YUV420    v   v     v
     |       |     |            |                 |    |             +----------------+
     |       |     |            +--+----+------+--+    |             | MERGE_D1_CIF   |
     |       |     |               |    |      |       |             |                |
     |       |     |               |    |      +-------+             +---------+------+
     |       |     |    +----------+    |                                      |            48CH YUV420
     |   8CH | 8CH |    |               |                                      +-------------------+
     |   D1  |  D1 |    |16CH           v                                                          |
     |       |     |    |CIF       +-------------+       +------------+        +----------+        |
     |       v     v    v          |IPC FramesOut+------>|IPC FramesIn+------->| AlgLink  |        |
     |    +--------------+         |   (M3)      <------+|   (DSP)    |<------+|  (SCD)   |        |
     |    |              |<---+    +-------------+       +------------+        +----------+        |
     |    | LIVE_DECODE  | 16CH                                                                    |
     |    |  MERGE       | D1 |                                                                    |
     |    |              |Play|     +------------+          +--------+         +--------+          |
     |    +-----+--------+    |     |            |          |IPCBits |         |IPCBits |          |
     |          |             +-----+ DecLink    |<---------|Out (A8)|         |In(A8)  |          |
+----v-----+    |                   +------------+  IPCBits +--------+         +--------+          v
|SDTV Disp |    |48CH                               In(M3)                         ^        +------------+
|          |    |                                                           IPCBits|        |  IPCM3OUT  |
+----------+    |                                                           Out(M3)|        +------+-----+
                v                                                              +---+-----+         |
          +--------------+                                                     |EncLink  |         |
          | LIVE_DECODE  |                                                     +---------+         v
          |  DUP         |                                                          ^       +------------+
          +-+----------+-+                                                          |       |  IPCM3IN   |
            |          |                                                            |       +------+-----+
            |          |                                                            |              |
     +------v--+    +--v--------+                                                   +--------------+
     |SWMS0    |    |SWMS1      |
     |         |    |           |
     +----+----+    +----+------+
          |              |
          v              v
      On-chip          Off-chip  HDDAC
      HDMI             HDMI     + (VGA)



  • Pls attach your latest usecase file .

  • I went back to this topic after some investigation.
    Our problem is, that mosaic is frozen if  vsysParams.enableScd = TRUE;
    But we need blind camera detection for the customers and the RTSP streaming of D1 mosaic.

    I found out that the problem with the frozen mosaic only occurs if
    I use the display combination HDMI/SD or HDCOMP/SD. If I use the old setting
    HDMI_MOSAIC__HDCOMP_MOSAIC__SD_BYPASS is works fine.
    And it is independant from the using of define MOSAIC_VIA_RTSP and the extra encoder channel. I can enable MOSAIC_VIA_RTSP and set HDMI_MOSAIC__HDCOMP_MOSAIC__SD_BYPASS and the mosaic is not frozen. In this case, I do not have content for the extra encoder channel but SCD
    and the rest is running.

    I also tested video playback. It is running without problems. But if I go back to live preview mosaic, the mosaic contains the frozen pictures.

    I investigated the places in source code where I use  "display_mosaic_combination" HDMI_MOSAIC__SD_MOSAIC / HDCOMP_MOSAIC__SD_MOSAIC
    but this looks not dangerous for SCD.

    The D1 mosaic encoder channel uses channel # 16 - the first CIF channel.
    I also tested to use one of the MJPEG channels for the replacement of the 17 th D1 channel.
    But this has no effect to the behavior if SCD is enabled.




  • I think you have to change as below in the enableSdtv = FALSE case:

     

                dupPrm[CAPTURE_DISPLAY_DUP_LINK_IDX].numOutQue = 3;
                dupPrm[CAPTURE_DISPLAY_DUP_LINK_IDX].outQueParams[2].nextLink = gVcapModuleContext.sclrId[0];

                sclrPrm.inQueParams.prevLinkId             = dupId[CAPTURE_DISPLAY_DUP_LINK_IDX];
                sclrPrm.inQueParams.prevLinkQueId          = 2;

    to

                dupPrm[CAPTURE_DISPLAY_DUP_LINK_IDX].numOutQue = 2;
                dupPrm[CAPTURE_DISPLAY_DUP_LINK_IDX].outQueParams[1].nextLink = gVcapModuleContext.sclrId[0];

                sclrPrm.inQueParams.prevLinkId             = dupId[CAPTURE_DISPLAY_DUP_LINK_IDX];
                sclrPrm.inQueParams.prevLinkQueId          = 1;

     

  • Yes that was the solution. SCD is running now.

    Thank You Badri for the solution.

    In the context with SCD I found the define USE_SCLR_FOR_SCD.

    I have a question:

    Does it realy work with OSD inserted ? Or is a changing in OSD detected like a motion ?

    I ask this because we must record a running clock in every captured channel.

    This means we can not detect blind camera if every second the clock changes

    the time value.

  • SCD will work with OSD enabled including changing OSD content.The default dvr rdk demo has a ticking date/time counter for OSD and we have not seen any false motion detection. In RDK 3.0 the data flow is modified so that SCD happens first and OSD is applied later and only on encode channels. This is the reason you dont see OSD on preview channels in RDK 3.0 compared to older versions.

  • I am  a little bit confused, DVRRDK 03.00.00.00 Demo dont show capture OSD but my application is based on DVRRDK03.00.00.00

    I have enabled  vsysParams.enableOsd  = TRUE; and I have a thread running for maintaining the clock display on capture side.

    (Capture OSD.txt). I can show YUV graphics at all the 16 captured channels and this time value window is also encoded and recorded.

    How can we explan this behavior.

    1033.Capture OSD.txt
    
    
    #define OSD_BUF_HEAP_SR_ID          (0)
    
    AlgLink_OsdChWinParams g_osdChParam[ALG_LINK_OSD_MAX_CH];
    AlgLink_OsdChBlindWinParams g_osdChBlindParam[ALG_LINK_OSD_MAX_CH];
    CaptureLink_BlindInfo g_blindAreaChParam[CAPTURE_LINK_MAX_CH_PER_OUT_QUE];
    
    static UInt8 *osdBufBaseVirtAddr = NULL;
    static UInt32 osdTotalBufSize = 0;
    static OSA_ThrHndl osd_task;
    static int osd_thread_exit_flag = FALSE;
    static void *osd_capture_process(void);
    static Vsys_AllocBufInfo bufInfo;
    static UInt32 osdBufSize, osdBufSizeY, bufAlign;
    static Bool camera_info;
    
    
    int osd_capture_Init(int numCh)
    {
        int chId;
        int winId;
        int status;
        UInt32 bufOffset;
    
    
        FUNCTION_ENTRY_LOG();
    
        if( vsysParams.enableOsd == FALSE )  /* OSD in VCAP subsystem enabled ? */
        {
            LOG(LOG_ERR, "%s: Capture OSD not enabled!",__FUNCTION__);
            return(-1);
        }
    
        if( (numCh <= 0) || (numCh > ALG_LINK_OSD_MAX_CH) )  /* Valid number of channels ? Note: We only use 16 channels */
        {
            LOG(LOG_ERR, "%s: Invalid channel number!",__FUNCTION__);
            return(-1);
        }
    
    
        osdBufSizeY = OSD_WIN_PITCH * OSD_WIN_HEIGHT;
    
        osdBufSize = osdBufSizeY * 2 ;
    
        osdTotalBufSize = osdBufSize * numCh * OSD_NUM_WINDOWS;
        bufAlign = 128;
    
        status = Vsys_allocBuf(OSD_BUF_HEAP_SR_ID, osdTotalBufSize, bufAlign, &bufInfo);
        if( status != OSA_SOK )
        {
            LOG(LOG_ERR, "%s: Allocate buffer failed!",__FUNCTION__);
            return(-1);
        }
    
        osdBufBaseVirtAddr = bufInfo.virtAddr;
    
    
        for(chId = 0; chId < numCh; chId++)
        {
            AlgLink_OsdChWinParams* chWinPrm = &g_osdChParam[chId];
    //        AlgLink_OsdChBlindWinParams* chBlindWinPrm = &g_osdChBlindParam[chId];
    
            chWinPrm->chId        = chId;
            chWinPrm->numWindows  = OSD_NUM_WINDOWS;
            chWinPrm->colorKey[0] = 0xfa; /* Y */
            chWinPrm->colorKey[1] = 0x7d; /* U */
            chWinPrm->colorKey[2] = 0x7e; /* V */
    
    //        chBlindWinPrm->chId       = chId;
    //        chBlindWinPrm->numWindows = OSD_NUM_WINDOWS;
    
            for(winId=0; winId < chWinPrm->numWindows; winId++)
            {
                /* Setup constant position of capture side OSD window */
                chWinPrm->winPrm[winId].startX             = OSD_WIN0_STARTX;
                chWinPrm->winPrm[winId].startY             = OSD_WIN0_STARTY;
                chWinPrm->winPrm[winId].width              = OSD_WIN_WIDTH;
                chWinPrm->winPrm[winId].height             = OSD_WIN_HEIGHT;
                chWinPrm->winPrm[winId].lineOffset         = OSD_WIN_PITCH;
                chWinPrm->winPrm[winId].globalAlpha        = 30;
                chWinPrm->winPrm[winId].transperencyEnable = OSD_TRANSPARENCY;
                chWinPrm->winPrm[winId].enableWin          = OSD_ENABLE_WIN;
                chWinPrm->winPrm[winId].format             = SYSTEM_DF_YUV422I_YUYV;
                chWinPrm->winPrm[winId].addr[0][1]         = NULL;
                bufOffset = osdBufSize * chId;
                chWinPrm->winPrm[winId].addr[0][0]         = (bufInfo.physAddr + bufOffset);
    
                /* Setup constant position of blind area */
    //            chBlindWinPrm->winPrm[winId].startX        = OSD_WIN0_STARTX;
    //            chBlindWinPrm->winPrm[winId].startY        = OSD_WIN0_STARTY;
    //            chBlindWinPrm->winPrm[winId].width         = OSD_WIN_WIDTH;
    //            chBlindWinPrm->winPrm[winId].height        = OSD_WIN_HEIGHT;
    //            chBlindWinPrm->winPrm[winId].fillColorYUYV = 0x80008000;
    //            chBlindWinPrm->winPrm[winId].enableWin     = OSD_ENABLE_WIN;
            }
        }
    
        CFONT_Initalize();
    
        OSA_thrCreate(&osd_task, (OSA_ThrEntryFunc)osd_capture_process, OSA_THR_PRI_DEFAULT, OSA_THR_STACK_SIZE_DEFAULT, NULL);
    
        camera_info = TRUE;
    
        FUNCTION_EXIT_LOG();
        return(status);
    }
    
    
    void osd_capture_Deinit(void)
    {
        FUNCTION_ENTRY_LOG();
    
    
        osd_thread_exit_flag = TRUE;
        OSA_thrDelete(&osd_task);
    
        if(osdBufBaseVirtAddr != NULL)
        {
            Vsys_freeBuf(OSD_BUF_HEAP_SR_ID, osdBufBaseVirtAddr, osdTotalBufSize);
        }
    
        FUNCTION_EXIT_LOG();
    }
    
    
    static void *osd_capture_process(void)
    {
        UInt8 *curVirtAddr = NULL;
        char string_buffer[CFONT_MAX_STRING_LENGTH];
        int chId;
        int winId;
        UInt32 bufOffset;
        unsigned short string_width;
    #define LEFT  36
    
        FUNCTION_ENTRY_LOG();
    
        memset((char*)&string_buffer,0,sizeof(string_buffer));
    
        while (osd_thread_exit_flag != TRUE)
        {
            time_t now = time(NULL);
            struct tm *time = localtime(&now);
    
            for(chId = 0; chId < VCAP_CHN_MAX; chId++)
            {
    
                AlgLink_OsdChWinParams * chWinPrm = &g_osdChParam[chId];
    
                chWinPrm->chId = chId;
                chWinPrm->numWindows = OSD_NUM_WINDOWS;
    
                winId = 0; /* We use only one window per channel */
    
                bufOffset = osdBufSize * chId;
                chWinPrm->winPrm[winId].addr[0][0] = (bufInfo.physAddr + bufOffset);
                curVirtAddr = bufInfo.virtAddr + bufOffset;
    
                if(camera_info)
                {
                    YUV_SetupBackground(C_OSD_WIDTH, C_OSD_HEIGHT, YUV422_COLOR_WHITE);
                    YUV_DrawBitmap((unsigned char*) &camera_32x32_yuv, 0, 0, 32, 32);
    
                    /* Draw channel # */
                    sprintf((char*)&string_buffer,"#%d", chId + 1);
                    string_width = CFONT_GetStringWidth((char*)&string_buffer, CFONT_SIZE_NORMAL);
                    CFONT_DrawString((char*)&string_buffer, LEFT, 2, YUV422_COLOR_BLACK, CFONT_SIZE_NORMAL);
    
                    /* Draw date and time */
                    sprintf((char*)&string_buffer,"%02d.%02d.%d %02d:%02d:%02d", time->tm_mday, time->tm_mon + 1, time->tm_year - 100,  time->tm_hour, time->tm_min, time->tm_sec);
                    CFONT_DrawString((char*)&string_buffer, LEFT + 8 + string_width, 2, YUV422_COLOR_BLACK, CFONT_SIZE_NORMAL);
                }
    
                memcpy(curVirtAddr, &osd_capture_buffer, OSD_WIN_WIDTH * OSD_WIN_HEIGHT * sizeof(unsigned short));
            }
    
            OSA_waitMsecs(1000); /* Refresh capture side OSD windows every second */
        }
    
        FUNCTION_EXIT_LOG();
        return(NULL);
    }
    
    
    
    int osd_capture_show_camera_info(Bool enable)
    {
        camera_info = enable;
    
        /* Flush last content */
        OSA_waitMsecs(100);
        YUV_SetupBackground(C_OSD_WIDTH, C_OSD_HEIGHT, YUV422_COLOR_WHITE);
        return(0);
    }
    

  • I don't understand the problem. Are you saying in your app you are seeing OSD on preview channels also but in RDK demo the OSD is not seen in preview ? What is the osdFormat you are setting ? In the mcfw demo it is 1 (indicating  SYSTEM_DF_YUV420SP_UV format) as we want OSD applied only on encode channels

     

  • I think we have some misunderstanding here.
    In our app we need capture OSD with a running clock that is maintained every second.
    This is running fine. No problem.
    The next issue is, that our customer needs also blind camera detection.
    That is for me the thing I do not understand. We insert OSD on capure side
    and we have SCD active. If the second value of the clock is changing every second
    is this detected as a motion ?

  • SCD will _not_ detect OSD content change as motion. Data flow is :

    Capture -> Dup -> DEI -> Merge -> OSD -> Encode

                              -> Scale -> NSF -> SCD.

    As you can see the original captured content is dup-ed and given to DEI and Scaler. OSD is applied later . So SCD operates on orginal capture data and OSD content has no effect on SCD. Are you seeing wrong motion detection with OSD enabled ?

  • Currently I get ALG_LINK_SCD_DETECTOR_CHANGE events.
    If I cover the camera and wait I expect ALG_LINK_SCD_DETECTOR_NO_CHANGE events. But these events do not occur.

    The ALG_LINK_SCD_DETECTOR_CHANGE events stops in this case, so I can also process the ALG_LINK_SCD_DETECTOR_CHANGE events.


    Parameter for SCD are set:


      if (enableScdAlgLink)
        {
            Int32   numBlksInFrame;
            Int32   numHorzBlks, numVertBlks, chIdx;
            Uint32  x, y, i;

            dspAlgPrm[1].enableOSDAlg = FALSE;
            dspAlgPrm[1].enableSCDAlg = TRUE;
            dspAlgPrm[1].outQueParams[ALG_LINK_SCD_OUT_QUE].nextLink    = ipcBitsOutDSPId;

            dspAlgPrm[1].scdCreateParams.maxWidth                  = 352;
            if(Vcap_isPalMode())
               dspAlgPrm[1].scdCreateParams.maxHeight              = 288;
            else
               dspAlgPrm[1].scdCreateParams.maxHeight              = 240;
            dspAlgPrm[1].scdCreateParams.maxStride                 = 352;
            dspAlgPrm[1].scdCreateParams.numValidChForSCD          = 16;

            dspAlgPrm[1].scdCreateParams.numSecs2WaitB4Init        = 30;
            dspAlgPrm[1].scdCreateParams.numSecs2WaitB4FrmAlert    = 2; //ALG_LINK_TIME_TO_WAIT_BEFORE_TAMPER_ALERT_THRESOLD;
            dspAlgPrm[1].scdCreateParams.inputFrameRate            = 1;
            dspAlgPrm[1].scdCreateParams.outputFrameRate           = 1;
            dspAlgPrm[1].scdCreateParams.numSecs2WaitAfterFrmAlert = 3; //ALG_LINK_TIME_TO_WAIT_AFTER_TAMPER_ALERT_THRESOLD;
            dspAlgPrm[1].scdCreateParams.numBufPerCh               = 2;

            dspAlgPrm[1].scdCreateParams.enableMotionNotify        = FALSE;
            dspAlgPrm[1].scdCreateParams.enableTamperNotify        = TRUE;

           /* Configure array to monitor scene changes in all frame blocks, i.e., motion detection.
               Each block is fixed to be 32x10 in size when height is 240,
               Each block is fixed to be 32x11 in size when height is 288 */
            numHorzBlks    = dspAlgPrm[1].scdCreateParams.maxWidth / 32;
            if((dspAlgPrm[1].scdCreateParams.maxHeight%10) == 0)
               numVertBlks    = dspAlgPrm[1].scdCreateParams.maxHeight / 10;
            else   /* For 288 Block height becomes 12 */
               numVertBlks    = dspAlgPrm[1].scdCreateParams.maxHeight / 12;

            numBlksInFrame = numHorzBlks * numVertBlks;

            for(chIdx = 0; chIdx < dspAlgPrm[1].scdCreateParams.numValidChForSCD; chIdx++)
            {
               AlgLink_ScdChParams * chPrm = &dspAlgPrm[1].scdCreateParams.chDefaultParams[chIdx];

               chPrm->blkNumBlksInFrame  = numBlksInFrame;
               chPrm->chId               = SCDChannelMonitor[chIdx];
               chPrm->mode               = ALG_LINK_SCD_DETECTMODE_MONITOR_BLOCKS_AND_FRAME;
               chPrm->frmIgnoreLightsON  = FALSE;
               chPrm->frmIgnoreLightsOFF = FALSE;
               chPrm->frmSensitivity     = ALG_LINK_SCD_SENSITIVITY_VERYLOW;
               chPrm->frmEdgeThreshold   = 100;
               i = 0;
               for(y = 0; y < numVertBlks; y++)
               {
                 for(x = 0; x < numHorzBlks; x++)
                 {
                   chPrm->blkConfig[i].sensitivity = ALG_LINK_SCD_SENSITIVITY_LOW;
                   chPrm->blkConfig[i].monitored   = 0;
                   i++;
                 }
               }
            }


  • Hi,

    Could you clarify your question? I could not understand it? I have listed few question, pls answer them

    1. Which release your are working on?

    2. When you cover camera, do you see tamper event?

    3. When you cover it for longer time, do you see tamper event always? or do you see only for initial few seconds?

    4. When you uncover the camera after long time, what behavior you see.

    Through above questions, can you clarify what you are expecting from algorithm?


  • 1. Which release your are working on?
    -> We have DVRRDK 03.00.00.00 / UdWorks platform.

    2. When you cover camera, do you see tamper event?
    ->   If I cover the camera I get VSYS_EVENT_TAMPER_DETECT.
       Then I can use Vcap_getDynamicParamChn(0, &vcap_dynamic_parameter, VCAP_SCDGETALLCHFRAMESTATUS);
       to detect what kind of tamper event occurs. I alswas get ALG_LINK_SCD_DETECTOR_CHANGE.

    3. When you cover it for longer time, do you see tamper event always? or do you see only for initial few seconds?
    ->   If I cover the camera the tamper events stop after some seconds. I get no new events.

    4. When you uncover the camera after long time, what behavior you see.
    -> If I uncover the camera after a long time I get ALG_LINK_SCD_DETECTOR_CHANGE again.

       Through above questions, can you clarify what you are expecting from algorithm.
    -> In my opinion I would expect ALG_LINK_SCD_DETECTOR_NO_CHANGE after a wait time if I cover the camera
       (The goal is to detect if the camera is covered in a range 5...10 minutes.)





  • Hi,

    Thanks for answering.

    So in my understanding, you are seeing the behavior as expected when there is ALG_LINK_SCD_DETECTOR_CHANGE event.

    In the release version that you have (DVRRDK 03.00.00.00), we dont send a event in case of ALG_LINK_SCD_DETECTOR_NO_CHANGE event.

    This has been added in DVRRDK 03.50.00.00 release. If you want you can merge changes from DVRRDK 03.50.00.00 release. Please take the changes in scdLink_alg.c file where event send command is present. This is minor change. Changes needs to be done at around line no 940 in DVRRDK 03.00.00.00 release.

  • Thanks for Your advice. I changed Tamper detect event notification like in version 03.5. in sdLink_alg.c.
    Now I get also ALG_LINK_SCD_DETECTOR_NO_CHANGE.
    But the behavior is not as I expected.
    With the following settings in multich_progressive_vcap_venc_vdec_vdis.c - I expect that a blind camera event occurs
    after 30 seconds.
    But I get the event immediately if I cover the camera.
    If I uncover - the event ALG_LINK_SCD_DETECTOR_CHANGE occurs.

    Sometimes I get ALG_LINK_SCD_DETECTOR_CHANGE if I cover and
    ALG_LINK_SCD_DETECTOR_NO_CHANGE I get if I cover.




        if (enableScdAlgLink)
        {
            Int32   numBlksInFrame;
            Int32   numHorzBlks, numVertBlks, chIdx;
            Uint32  x, y, i;

            dspAlgPrm[1].enableOSDAlg = FALSE;
            dspAlgPrm[1].enableSCDAlg = TRUE;
            dspAlgPrm[1].outQueParams[ALG_LINK_SCD_OUT_QUE].nextLink    = ipcBitsOutDSPId;

            dspAlgPrm[1].scdCreateParams.maxWidth                  = 352;
            if(Vcap_isPalMode())
               dspAlgPrm[1].scdCreateParams.maxHeight              = 288;
            else
               dspAlgPrm[1].scdCreateParams.maxHeight              = 240;
            dspAlgPrm[1].scdCreateParams.maxStride                 = 352;
            dspAlgPrm[1].scdCreateParams.numValidChForSCD          = 16;

            /* Set the number of seconds to wait before initializing SCD monitoring.
               This wait time occurs when the algorithm instance first starts and allows video input to stabilize. */
            dspAlgPrm[1].scdCreateParams.numSecs2WaitB4Init        = 60;

            /* Set the number of seconds to wait before signaling a frame-level scene change event. */
            dspAlgPrm[1].scdCreateParams.numSecs2WaitB4FrmAlert    = 30;

            /* Frames per second fed to the SCD */
            dspAlgPrm[1].scdCreateParams.inputFrameRate            = 1;

            /* Frames per second algorithm is operated at */
            dspAlgPrm[1].scdCreateParams.outputFrameRate           = 1;

            /* Set to 1 to n for the maximum number of seconds to wait for pre-tamper conditions to return following a tamper event */
            dspAlgPrm[1].scdCreateParams.numSecs2WaitAfterFrmAlert = 30;

            dspAlgPrm[1].scdCreateParams.numBufPerCh               = 2;

            /* Set to 1 to n for the maximum number of seconds to mark new scene as non-tamper condition.
               If Tamper persist for these many frames,  current frame will be mark as stable scene. */
            dspAlgPrm[1].scdCreateParams.numSecs2Wait2MarkStableFrame = 10;


            dspAlgPrm[1].scdCreateParams.enableMotionNotify        = FALSE;
            dspAlgPrm[1].scdCreateParams.enableTamperNotify        = TRUE;

           /* Configure array to monitor scene changes in all frame blocks, i.e., motion detection.
               Each block is fixed to be 32x10 in size when height is 240,
               Each block is fixed to be 32x11 in size when height is 288 */
            numHorzBlks    = dspAlgPrm[1].scdCreateParams.maxWidth / 32;
            if((dspAlgPrm[1].scdCreateParams.maxHeight%10) == 0)
               numVertBlks    = dspAlgPrm[1].scdCreateParams.maxHeight / 10;
            else   /* For 288 Block height becomes 12 */
               numVertBlks    = dspAlgPrm[1].scdCreateParams.maxHeight / 12;

            numBlksInFrame = numHorzBlks * numVertBlks;

            for(chIdx = 0; chIdx < dspAlgPrm[1].scdCreateParams.numValidChForSCD; chIdx++)
            {
               AlgLink_ScdChParams * chPrm = &dspAlgPrm[1].scdCreateParams.chDefaultParams[chIdx];

               chPrm->blkNumBlksInFrame  = numBlksInFrame;
               chPrm->chId               = SCDChannelMonitor[chIdx];
               chPrm->mode               = ALG_LINK_SCD_DETECTMODE_MONITOR_FULL_FRAME;
               chPrm->frmIgnoreLightsON  = TRUE;
               chPrm->frmIgnoreLightsOFF = TRUE;
               chPrm->frmSensitivity     = ALG_LINK_SCD_SENSITIVITY_VERYLOW;
               chPrm->frmEdgeThreshold   = 100;
               i = 0;
               for(y = 0; y < numVertBlks; y++)
               {
                 for(x = 0; x < numHorzBlks; x++)
                 {
                   chPrm->blkConfig[i].sensitivity = ALG_LINK_SCD_SENSITIVITY_LOW;
                   chPrm->blkConfig[i].monitored   = 0;
                   i++;
                 }
               }
            }

  • I did try to solve the tamper detection goal in an alternative way.
    I created a thread that gets the tamper status every 10 second.
    We use Vcap_getDynamicParamChn(0, &vcap_dynamic_parameter, VCAP_SCDGETALLCHFRAMESTATUS); for this.
    We increment a counter if tamper detection status indicates a covered camera.
    I have connected a DVD player with a movie. If I stop the movie -> the counter is incremented.
    If I connect a real camera and the camera captures only the environment with no moving objects -> this is detected as a tampering.
    I did try to change the parameters frmSensitivity, numSecs2WaitB4Init, numSecs2WaitAfterFrmAlert
    but in my opinion I this has only minor effect to the tamper processing.

    The problem for me is the differentiation between tampering by covering and camera input without movement.

    Any ideas for this ?

  • Hi,

    For DM816x, we have deprecated these two parameters (numSecs2WaitB4Init, numSecs2WaitAfterFrmAlert)  from v3.00 release. We have done some modification in tamper detection algorithm. So you would not see effect of changes in these two params. We would be removing them in future release.

    We have not noticed this scenario of camera tamper alert in static environment. we have done testing with both DVD player and camera. Are you sure the content that is fed from  camera is captured correctly. What I mean here is no flicker etc. Check the configuration again, camera input type NTSC/PAL etc.

  • Thank You Ritesh for Your answer.

    I did some modification in getting the tamper status.
    I collect the VSYS_EVENT_TAMPER_DETECT events for every channel
    and process the events in a thread. This gives better results then reading
    the tamper status every 10 seconds.


    But I also want to get information of the motion status.
    So I enabled scdCreateParams.enableMotionNotify, set chPrm->mode = ALG_LINK_SCD_DETECTMODE_MONITOR_BLOCKS_AND_FRAME;
    and enabled monitored blocks in multich_progressive_vcap_venc_vdec_vdis.c.

    Now I expect VSYS_EVENT_MOTION_DETECT events. But the events do not occur.
    I found that Utils_bitbufGetEmptyBuf in /src_bios6/links_c6xdsp/alg_link/sdcLink_alg.c failed.(status = -1)
    If doFrameDrop is TRUE - then AlgLink_ScdalgProcess will not called and we never get VSYS_EVENT_MOTION_DETECT events.
    I also did try Utils_bitbufGetEmptyBuf with BIOS_WAIT_FOREVER, but this blocks.

     status = Utils_bitbufGetEmptyBuf(bufOutQue,
                                      &pOutBuf,
                                      0, //pObj->outObj.ch2poolMap[chIdx], /*Need to change later.*/
                                      BIOS_NO_WAIT);

      if(!((status == FVID2_SOK) && (pOutBuf)))
      {
         doFrameDrop = TRUE;
         Vps_printf("status %d ",status);
      }
     

  • Hi,

    In case of motion detection, we sent motion detection result to A8 also.  For this we have an o/p queue at scd link from which buffers are fetch, results are populated and then sent to next link (in our case it is A8). Now once A8 consumes these buffers, it is supposed to retun back all the buffers to scd LInk. If A8 does not send back those buffers , SCD link wil run out of buffers and hence you would see errors which you are currently seeing.

    Please check if you are correctly releasing  buffers.

  • I understand this, but for me it is not clear where this buffer normaly is released.

  • Ok, one problem is solved, Motion detection events VSYS_EVENT_MOTION_DETECT occur now.
    VcapVencVdecVdis_ipcBitsInit(ipcbits_resArray, FALSE, FALSE) was disabled by mistake.

    But now I get another problem.
    My video playback was running fine in the past (with VcapVencVdecVdis_ipcBitsInit disabled by mistake).
    Now I get error log "VdecVdis_bitsRdFillEmptyBuf: Frame size[xxxx] exceeds buffer size [0]"

    It seems that Vdec_requestBitstreamBuffer(&reqInfo, emptyBufList, 0); retrieves a buffer with a size of 0.

    This occurs only if  the module VcapVencVdecVdis_ipcBits... is running.

    I also did try  ipcBitsOutHostPrm.bufPoolPerCh = FALSE;  and reqInfo.reqType = VDEC_BUFREQTYPE_CHID.
    But this is not the solution for this problem.


    Here are my functions. For playback they are called in the following order:

       /* A new frame to decode */
       VdecVdis_bitsRdGetEmptyBitBufs(&emptyBufList);
       VdecVdis_bitsRdReadData(&emptyBufList);
       VdecVdis_bitsRdSendFullBitBufs(&emptyBufList);



    static void VdecVdis_bitsRdGetEmptyBitBufs(VCODEC_BITSBUF_LIST_S *emptyBufList)
    {
        VDEC_BUF_REQUEST_S reqInfo;


        if( emptyBufList == NULL )
        {
            LOG(LOG_ERR, "%s: Invalid buffer list!", __FUNCTION__);
            return;
        }

        emptyBufList->numBufs = 0;
        reqInfo.numBufs       = 1;
        reqInfo.reqType       = VDEC_BUFREQTYPE_BUFSIZE;
        reqInfo.u[0].chNum    = 0;

        /* Get empty buffer */
        Vdec_requestBitstreamBuffer(&reqInfo, emptyBufList, 0);
    }



    static void VdecVdis_bitsRdReadData(VCODEC_BITSBUF_LIST_S  *emptyBufList)
    {
        VCODEC_BITSBUF_S *pEmptyBuf;

        if( emptyBufList == NULL )
        {
            LOG(LOG_ERR, "%s: Invalid buffer list!", __FUNCTION__);
            return;
        }

        pEmptyBuf = &emptyBufList->bitsBuf[0];
        VdecVdis_bitsRdFillEmptyBuf(pEmptyBuf);

        /* Wait for first frame */
        if(pEmptyBuf->filledBufSize > 0)
        {
            if( vsysParams.enableAVsync ) /* If AVSync is enabled  */
                VdecVdis_setFrameTimeStamp(pEmptyBuf);
        }
    }



    static void VdecVdis_bitsRdFillEmptyBuf(VCODEC_BITSBUF_S *pEmptyBuf)
    {

        if( pEmptyBuf == NULL )
        {
            LOG(LOG_ERR, "%s: Invalid buffer!", __FUNCTION__);
            return;
        }

        pEmptyBuf->chnId = VIDEO_PLAYBACK_DECODER_CHANNEL;
        pEmptyBuf->filledBufSize = packet.size;

        if (pEmptyBuf->filledBufSize > pEmptyBuf->bufSize)
        {
            LOG(LOG_ERR, "%s: Frame size[%d] exceeds buffer size [%d]", __FUNCTION__, pEmptyBuf->filledBufSize, pEmptyBuf->bufSize);
        }
        else
        {
            memcpy(pEmptyBuf->bufVirtAddr, packet.data, packet.size);
        }

        av_free_packet(&packet);
        av_init_packet(&packet);
    }

  • The following issue with the code above:

    1.

        reqInfo.reqType       = VDEC_BUFREQTYPE_BUFSIZE;
        reqInfo.u[0].chNum    = 0;

    This is wrong. reqInfo is a union of chNum and bufSize. If your reqType is BUFSIZE you should populate reqInfo.u[0].bufSize = <size of buffer required>

    2.In function VdecVdis_bitsRdGetEmptyBitBufs , the call to Vdec_requestBitstreamBuffer may return
    emptyBufList->numBufs as zero. So you should check the return value of
    Vdec_requestBitstreamBuffer for no errors (return value 0) and also check if
    emptyBufList->numBufs is zero. If it is zero and you require
    VdecVdis_bitsRdGetEmptyBitBufs to always return a buffer you should sleep for sometime and retry,


  • I have changed VdecVdis_bitsRdGetEmptyBitBufs.
    But the Problem is not solved.
    If I disable VcapVencVdecVdis_ipcBitsInit(ipcbits_resArray, FALSE, FALSE) retrieving the buffer works well
    but with calling VcapVencVdecVdis_ipcBitsInit() in VcapVencVdecVdis_start() the return value of
    Vdec_requestBitstreamBuffer is zero and emptyBufList->numBufs also is zero and we stay in the while loop
    and never get a buffer.



    static void VdecVdis_bitsRdGetEmptyBitBufs(VCODEC_BITSBUF_LIST_S *emptyBufList)
    {
        VDEC_BUF_REQUEST_S reqInfo;
        int r;

        if( emptyBufList == NULL )
        {
            LOG(LOG_ERR, "%s: Invalid buffer list!", __FUNCTION__);
            return;
        }

        emptyBufList->numBufs = 0;
        reqInfo.numBufs       = 1;
        reqInfo.reqType       = VDEC_BUFREQTYPE_BUFSIZE;
        //reqInfo.u[0].chNum    = 0;
        reqInfo.u[0].minBufSize    = packet.size;
        printf("\n packet.size; %d",packet.size);

        /* Get empty buffer */
        while(1)
        {
          r = Vdec_requestBitstreamBuffer(&reqInfo, emptyBufList, 0);
          if( (emptyBufList->numBufs > 0) && (r == 0) )
            break;
          printf("\n r=%d",r);
          printf("\n emptyBufList->numBufs =%d",emptyBufList->numBufs );
          MS_SLEEP(1);
        }
    }

  • What are you populating the ipcResArray with.


  •    
         ipcbits_resArray[0].width  = MCFW_IPCBITS_D1_WIDTH;
         ipcbits_resArray[0].height = MCFW_IPCBITS_D1_HEIGHT;

         ipcbits_resArray[1].width  = 0;
         ipcbits_resArray[1].height = 0;

         VcapVencVdecVdis_ipcBitsInit(ipcbits_resArray, FALSE, FALSE);

  • VcapVencVdecVdis_ipcBitsInit  is demo code meant for direct loopback between encoder to decoder. If you are doing playback by reading from hdd or network you should not use this. If you invoke this function a thread will be created which will allocate all Vdec buffers and put it into a emptyQueue for the encode thread to fill. Also your app will no longer get Venc callbacks to notify new frame available. VcapVencVdecVdis_ipcBitsInit has nothing to do with SCD bits export. Scd_bitsWriteCreate should be used as reference to receive the motion detect data from dsp alg.


  • Thank You for this advice. The main goal of VcapVencVdecVdis_ipcBits... was not realy clear for me.
    I disabled this module - now motion detection + the main tasks of our board are running.

    Main functions of our board are:
      Video recording in D1 of 16 anlouge cameras,
      video playback of a single h264 file on demand from HDD,
      IP camera live view ,
      RTSP streaming of single Channels and one mosaic,
      Audio Record and playback (2 channels),
      Tamper and motion detection


    Video playback and ip camera view is based on demo_vdec_vdis_bits_rd.c
    Video record is based on demo_vcap_venc_vdis_bits_wr.c
    RTSP streaming uses the same frames that are recorded.

    The functions are well tested, but now I am not sure if I need anything from
    demo_vdec_vdis_frames_send.c and demo_vcap_venc_vdis_ipc_frames_exch.c, demo_vcap_venc_vdec_vdis_bits_rdwr.c ?



  • demo_vdec_vdis_frames_send.c and demo_vcap_venc_vdis_ipc_frames_exch.c

     - These are needed only if you export raw video frames to application. You can disregard it .

    demo_vcap_venc_vdec_vdis_bits_rdwr.c

     - This does loopback from encode->decode. As you have already taken care of encode and decode sides separately you don't need to use anything from this file.

     

     

  • Thanks Badri and other fellows from TI for the nice support.
    For me this was a good souce to make our project applicable.
    Best regards Holger

  • Hi Holger,

    Can you please share what is the observed latency you got with the streamer ?
    I want to choose streamer and I wander if wis-streamer is best choice (in compare to gstreamer) ?

    Thank you very much,
    Ran
  • Hi RAn,

    what latency do You mean ?

    Do You mention the time from capture until displaying in VLC or any other RTSP player ?

    Best regards Holger

  • Hi,

    I mean end to end latency.
    Yes, until displaying.


    Regards,
    Ran

  • Hi,

    Ran I have measured approx. 1.2 seconds end to end.

    This means from analog camera to VLC.

    Pls find attached screen shot. I have captured a running clock on PC desktop and VLC playing RTSP.

    Best regards Holger

    Latency_test.docx

     

     

  • Hi Holger,

    Thank you very much!
    There are several components in the system that take process time: capture, scale, encode,ethernet,wis-streamer.
    Do you think wis-streamer also have large latency ? I ask because I think it might consume time, and therefore  I consider using other streamers (maybe libav)

    Thanks,
    Ran

  • Hi Ran,

    some times ago we made some measurment for glas to glas latency.

    Our results are equal to the times of TI.

    I think You spent max. approx. 200 ms for this chain.

    This means the rest of 1 second is used from RTSP server, Ethernet and VLC in my measurememnt.

    If You investigate Wisstreamer and Live555 - You will find the same components of FFMPEG or LibAV inside.

    But LibAV / FFMPEG are more compact then WisStreamer/Live555.

    I am not familiar with Gstreamer.

     

    Best regards Holger

     

     

    latenz.pdf

  • Hi Ran,

    have You made a decision of using GStreamer / WisStreamer ?

    I have found an interesting alternative:

    stackoverflow.com/.../ffmpeg-to-send-rtsp-encoded-stream-c

     

    Currently I try to build FFPlay.

    Best regards Holger

     

  • Hi Holger,

    I first finish the demux->decoding->display (I haven't yet started it, just made some "studying" on this issue)

    As to the encoder->mux, I believe that the best alternatives are one of the following:
    1. live555 /wis-streamer - already comes with rtsp support, and integrated partly in dvr rdp (usworks version) but using wisstreamer.
    2. ffmpeg

    I'm not sure I'll need rtsp, but might only do mpeg-ts over udp. I think this is what we prefer as system requirement, but I have some flexibility to consider alternatives.

    As to wis-streamer/live5555, I'm not sure it is the best choice in terms opf performance and code complexity. I might try to work with live555 directly (without wis-streamer) or use ffmpeg. I haven't decided yet , though I think I prefer ffmpeg.

    Thanks,
    Ran
  • As to gstreamer, I'm not sure it is supported in dvr rdk, so that's not a choice, as far as I know.
  • Anyway, I think it is best to start with wis-streamer, becuase it is already integrated into dvrrdk and should work.
  • Ran, I agree using Wis-Streamer.

    Best regards Holger

  • Hi Holger,

    Did you start working on encoder->mux ?
    I am going to start it soon, and I wander if you made any progress.

    Keep in touch...
    Ran
  • Hi Ran,

    not started, have some hardware problems.

    Best regards Holger