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.

How to integrate our custom DSP algorithm in DVRRDK 4.0?

Other Parts Discussed in Thread: SYSBIOS

Hello,TI man.

In our case,we need a echo cancel algorithm.But in DVRRDK,we don't know how to integrate a specific algorithm.Are there some documents or Demo can be referrenced?

Such as algorithm related file,for example,aac enode package in DVRRDK,the .bld,.xdc,.xs file.how to generate them?

And,how to write interface function to make app of linux in A8 can call the algorithm function in DSP?

I have read a related thread in e2e,but we still can't integrate it.

Expecting for any reply.

  • What approach are you currently using to integrate the Echo canceller ? My opinion is it is best you create a new dvr rdk link and integrate your algorithm. You can use ipcBitsIn/ipcBitsOut to feed input/output data to your link from A8.

  • thanks for your reply.

    I don't quite understand your meaning.

    Create a new link between ARM and DSP?

    And use ipcBitsin and IpCBitsOut ?IPCBitsIn and IPCBitsOut move H264 data between ARM and M3 codec.They also can move audio PCM data?

    and,how can generate the .xdc,.xs.bld file?

  • No I mean create a new link ecuLink on c674 dsp similar to algLink.

    You data flow will be

    ipcBitsOutHLOS -> ipcBitsInRTOS( c674) -> ecuLink -> ipcBitsOutRTOS (c674) -> ipcBitsInHLOS.

    If your ecuLink operates on the input buffer by modifying its contents without using output buffer then you don't need

     ipcBitsOutRTOS (c674) -> ipcBitsInHLOS.

    Why do you want to generate xdc,xs,bld files ? You don't need any of these to integrate a library into a link.

  • Thanks for your suggestions!

    We will try this.

  • Hi Badri,

    According to your suggestion,I have done some try.Firstly,I create two chanins:

    (1)ipcBitsOutHost<------->ipcBitInRTOS(InDSP,processlink)------->algLink(aec)

    (2)ipcBitsOutHost-------->ipcBitsInRTOS(InDSP)-------->alg(aec)------->ipcBitsOutRTOS--------->ipcBitsInHost

    then,I create a thread to get empty buffer and put pull buffer to ipcBitsOutHostLink,but I am failed to run this simple demo.when debug it I find another problem,the ipcBitInRTOSLink is used for passing buffer between A8 Host & Video-M3,so maybe I cannot use it between A8 and DSP.For A8 and DSP I only find the ipcFramesInRTOS can passing buffer between them, but it seems to deliver the complete video frame,I am confused can it deliver audio PCM data.

    By the way,  I want to know is there any other way to implement echo remove.

    Thinks!

  • ipcBitsIn can run on any core. What linkID are you using for ipcBitsIn on DSP. Attach your usecase file where you are creating and connecting links.

    Other options are to use IUniversal APIs / RCM / RPE to implement RPC with component on DSP doing AEC but I am not familiar with them enough to provide guidance. You can check in BIOS forum if you want to pursue that path.

  •  

    My usecase is like this:

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    void audio_Chain_ES_ITC_0_02_00_2(P_CHANNEL_DISCRIPTOR pChannels)
    {
     IpcBitsOutLinkHLOS_CreateParams   audio_ipcBitsOutHostPrm;
     IpcBitsInLinkRTOS_CreateParams      audio_ipcBitsInDspPrm;
        HelloWorldLink_CreateParams         algPrm;

     UInt32 audio_ipcBitsOutHostId;
     UInt32 audio_ipcBitsInDspId;
        UInt32 algId;

        CHAINS_INIT_STRUCT(IpcBitsOutLinkHLOS_CreateParams,audio_ipcBitsOutHostPrm);
        CHAINS_INIT_STRUCT(IpcBitsInLinkRTOS_CreateParams,audio_ipcBitsInDspPrm);
        CHAINS_INIT_STRUCT(HelloWorldLink_CreateParams,algPrm);

        audio_ipcBitsOutHostId  = SYSTEM_HOST_LINK_ID_IPC_BITS_OUT_1;
        audio_ipcBitsInDspId    = ???????????????????????;   //I can't find a suitable linkId from DSPLINK ID
        algId                   = SYSTEM_LINK_ID_HELLOWORLD_0;

     //startAudioCaptEnc(pChannels);
     startIpc(pChannels);

        System_LinkQueInfo queInfo;
        queInfo.numCh = 1;
        {
            queInfo.chInfo[0].bufType           = SYSTEM_BUF_TYPE_VIDBITSTREAM;
            queInfo.chInfo[0].codingformat      = 0;
            queInfo.chInfo[0].height            = 4;
            queInfo.chInfo[0].width             = 256;
            queInfo.chInfo[0].memType           = SYSTEM_MT_TILEDMEM;
            queInfo.chInfo[0].dataFormat        = SYSTEM_DF_YUV420P;
            queInfo.chInfo[0].scanFormat        = SYSTEM_SF_PROGRESSIVE;
        }

        audio_ipcBitsOutHostPrm.baseCreateParams.numOutQue                    = 1;
        audio_ipcBitsOutHostPrm.baseCreateParams.numChPerOutQue[0]            = 1;
        audio_ipcBitsOutHostPrm.baseCreateParams.processLink                  = audio_ipcBitsInDspId;
        audio_ipcBitsOutHostPrm.bufPoolPerCh                                  = FALSE;
        audio_ipcBitsOutHostPrm.numBufPerCh[0]                                = 16;
        audio_ipcBitsOutHostPrm.baseCreateParams.noNotifyMode                 = FALSE;
        audio_ipcBitsOutHostPrm.baseCreateParams.notifyNextLink               = TRUE;
        audio_ipcBitsOutHostPrm.baseCreateParams.notifyPrevLink               = TRUE;
        audio_ipcBitsOutHostPrm.baseCreateParams.notifyProcessLink            = TRUE;
        audio_ipcBitsOutHostPrm.inQueInfo                                     = queInfo;

        audio_ipcBitsInDspPrm.baseCreateParams.inQueParams.prevLinkId       = audio_ipcBitsOutHostId;
        audio_ipcBitsInDspPrm.baseCreateParams.inQueParams.prevLinkQueId    = 0;
        audio_ipcBitsInDspPrm.baseCreateParams.numOutQue                    = 1;
        audio_ipcBitsInDspPrm.baseCreateParams.outQueParams[0].nextLink     = algId;
        audio_ipcBitsInDspPrm.baseCreateParams.noNotifyMode                 = FALSE;
        audio_ipcBitsInDspPrm.baseCreateParams.notifyPrevLink               = TRUE;
        audio_ipcBitsInDspPrm.baseCreateParams.notifyNextLink               = TRUE;

        algPrm.inQueParams.prevLinkId           = audio_ipcBitsInDspId;
        algPrm.inQueParams.prevLinkQueId        = 0;

        System_linkCreate(audio_ipcBitsOutHostId, &audio_ipcBitsOutHostPrm, sizeof(audio_ipcBitsOutHostPrm));
        System_linkCreate(audio_ipcBitsInDspId, &audio_ipcBitsInDspPrm, sizeof(audio_ipcBitsInDspPrm));
        System_linkCreate(algId, &algPrm, sizeof(algPrm));

        System_linkStart(audio_ipcBitsOutHostId);
        System_linkStart(audio_ipcBitsInDspId);
        System_linkStart(algId);
        while(1)
        {
         Char ch = Chains_getChar();
        }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    for the link ipcBitsInRTOS,I think it should be a DSPLINK,but from DSPLINK, there is not a link named like  SYSTEM_DSP_LINK_ID_IPC_BITS_IN_0,there is only SYSTEM_DSP_LINK_ID_IPC_FRAMES_IN_0 for DSP.

    which link id should I choose?

    thinks!

  • 1.In /dvr_rdk/mcfw/interfaces/link_api/system_linkId.h

    Add in enum SYSTEM_DSP_LINK_IDS

        SYSTEM_DSP_LINK_ID_IPC_BITS_IN_0  = DSP_LINK(SYSTEM_LINK_ID_IPC_BITS_IN_0),

    2. In /dvr_rdk/mcfw/src_bios6/links_c6xdsp/system/system_c6xdsp.c

    Int32 System_init()

    Add

    IpcBitsInLink_init(); and associate deInit in System_deInit.

    3.  audio_ipcBitsInDspId    = SYSTEM_DSP_LINK_ID_IPC_BITS_IN_0

    4. There are number of issues with your usecase

        for (i = 0;
             i < numCh;
             i++)
        {
            System_LinkChInfo *pChInfo;
    
            pChInfo = &ipcBitsOutHostPrm->inQueInfo.chInfo[i];
    
            pChInfo->bufType        = 0; // NOT USED
            pChInfo->codingformat   = 0; // NOT USED
            pChInfo->dataFormat     = 0; // NOT USED
            pChInfo->memType        = 0; // NOT USED
            pChInfo->startX         = 0; // NOT USED
            pChInfo->startY         = 0; // NOT USED
            pChInfo->width          = 352;
            pChInfo->height         = 288;
            pChInfo->pitch[0]       = 0; // NOT USED
            pChInfo->pitch[1]       = 0; // NOT USED
            pChInfo->pitch[2]       = 0; // NOT USED
            pChInfo->scanFormat     = SYSTEM_SF_PROGRESSIVE;
            ipcBitsOutHostPrm->maxQueueDepth[i] =
                MAX_BUFFERING_QUEUE_LEN_PER_CH;
            ipcBitsOutHostPrm->chMaxReqBufSize[i] =
                    352 * 288;
            numBufPerCh = NUM_BUFS_PER_CH_BITSOUT_AEC;
            ipcBitsOutHostPrm->totalBitStreamBufferSize[i] =
                    ipcBitsOutHostPrm->chMaxReqBufSize[i] *  numBufPerCh;
        }
        ipcBitsOutHostPrm->baseCreateParams.noNotifyMode = FALSE;
        ipcBitsOutHostPrm->baseCreateParams.notifyNextLink = TRUE;
        ipcBitsOutHostPrm->baseCreateParams.numOutQue = 1;
        ipcBitsOutHostPrm->inQueInfo.numCh = numCh;
    

    Also don't use processLink for ipcBitsOutHOST.It has no meaning.

    It should be

       audio_ipcBitsOutHostPrm.baseCreateParams.nextLink                  = audio_ipcBitsInDspId;

  • Hi Badri,

    Thanks for your reply,I have modifed my code as you suggest,but when I am compiling the usecase,it encounter that erro:

    # Invoking configuro...
    # Configuro done!
    # Making ti816x-evm:c6xdsp:debug:dvr_rdk_bios6...
    # Linking into /root/DVRRDK_03.00.00.00/dvr_rdk/../dvr_rdk/build/dvr_rdk/bin/ti816x-evm/dvr_rdk_c6xdsp_debug.xe674...
    #
    "/root/DVRRDK_03.00.00.00/dvr_rdk/../dvr_rdk/mcfw/src_bios6/cfg/ti816x/link_algs.cmd", line 12: warning:
       no matching section

     undefined            first referenced                                                                                                                    
      symbol                  in file                                                                                                                         
     ---------            ----------------                                                                                                                    
     IpcBitsInLink_deInit /root/DVRRDK_03.00.00.00/dvr_rdk/../dvr_rdk/build/mcfw/src_bios6/lib/ti816x-evm/c6xdsp/debug/dvr_rdk_bios6.ae674<system_c6xdsp.oe674>
     IpcBitsInLink_init   /root/DVRRDK_03.00.00.00/dvr_rdk/../dvr_rdk/build/mcfw/src_bios6/lib/ti816x-evm/c6xdsp/debug/dvr_rdk_bios6.ae674<system_c6xdsp.oe674>

    error: unresolved symbols remain
    warning: entry-point symbol other than "_c_int00" specified:
       "ti_sysbios_family_c64p_Hwi0"
    error: errors encountered during linking;
       "/root/DVRRDK_03.00.00.00/dvr_rdk/../dvr_rdk/build/dvr_rdk/bin/ti816x-evm/dv
       r_rdk_c6xdsp_debug.xe674" not built

    How can I do to avoid this mistake?

    Thanks!

  • Pls modify

    /dvr_rdk/mcfw/src_bios6/links_common/SRC_FILES_DSP.MK

    SRCDIR += links_common/system links_common/ipcFramesIn links_common/ipcFramesOut \
       links_common/dup links_common/null links_common/system \
       links_common/merge links_common/ipcBitsOut links_common/ipcBitsIn  \
       links_common/select

    SRCS_COMMON += dupLink_tsk.c nullLink_tsk.c system_linkApi.c system_linkApi_local.c system_common.c \
      system_ipc.c system_ipc_listMP.c system_ipc_msgq.c system_ipc_notify.c \
      mergeLink_tsk.c ipcFramesInLink_tsk.c ipcFramesOutLink_tsk.c ipcBitsOutLink_tsk.c ipcBitsInLink_tsk.c \
      selectLink_tsk.c system_tiler.c 

  • Thank you very much, i have compiled successfully,but I encounter another problem: when my usecase is running,On A8 I run a thread to get empty buffer from ipcBitOutHostLink and put full buffer to ipcBitOutHostLink.The problem is that I can't get empty buffer from  ipcBitOutHostLink after I have get 16 buffer(I set the buffer number is 16). I don't kown where is false.By the way,now,we use DVRRDK3.0,so it is differente to DVRRDK4.0 for the structure IpcBitsOutLinkHLOS_CreateParams,My usecase and erroare like the following now:

    What do you think where is the problem?

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /*
     * test_audio.c
     *
     *  Created on: Oct 9, 2013
     *      Author: mdm
     */

    static Void * audio_GetEmptyBuffersfromIPCBitsOutHLOSLINK(Void * Prm)
    {
     IpcBitsOutLinkHLOS_BitstreamBufReqInfo reqInfo;
     Bitstream_BufList emptyBufList;
     Bitstream_BufList BufList;
     Bitstream_Buf *pBuf;
     UInt32 linkId = SYSTEM_HOST_LINK_ID_IPC_BITS_OUT_0;
     Int i;
     Int status;
     UInt32 minBufSize = 288*352;
     P_CHANNEL_DISCRIPTOR  pChannels;
     pChannels = (P_CHANNEL_DISCRIPTOR)(Prm);

     FILE  *fp;
     fp = fopen("/mnt/picture/1","rb");

     reqInfo.numBufs   = 5;
     reqInfo.reqType   = IPC_BITSOUTHLOS_BITBUFREQTYPE_BUFSIZE;

     BufList.numBufs = 0;

     for (i = 0; i < reqInfo.numBufs; i++)
     {
      reqInfo.u[i].minBufSize = minBufSize;
     }

     while (1)
     {
      emptyBufList.numBufs = 0;
      IpcBitsOutLink_getEmptyVideoBitStreamBufs(linkId, &emptyBufList, &reqInfo);
      OSA_printf("line[%d],emptybuffNum[%d]\n",__LINE__,emptyBufList.numBufs);

      for (i = 0; i < emptyBufList.numBufs; i++)
      {
       pBuf = emptyBufList.bufs[i];
       pBuf->fillLength  = 288*352;
               fseek(fp,0,SEEK_SET);
                fread(pBuf->addr,pBuf->fillLength,1,fp);
      }
      IpcBitsOutLink_putFullVideoBitStreamBufs(linkId, &emptyBufList);
      usleep(200000);
     }
    }
    Int startIpc(P_CHANNEL_DISCRIPTOR pChannel)
    {
        OSA_ThrHndl                 getBuffThr;
        OSA_ThrHndl                 putBuffThr;
        Int32                       status;

     status = OSA_thrCreate(&getBuffThr, audio_GetEmptyBuffersfromIPCBitsOutHLOSLINK,
       AUDIO_TASK_PRI, AUDIO_TASK_STACK_SIZE, (void *) pChannel);

     //status = OSA_thrCreate(&putBuffThr, audio_PutFullBufferstoIPCBitsOutHLOSLINK,
      // AUDIO_TASK_PRI, AUDIO_TASK_STACK_SIZE, (void *) pChannel);
     return status;
    }
    void audio_Chain_ES_ITC_0_02_00_0(P_CHANNEL_DISCRIPTOR pChannels)
    {
     IpcBitsOutLinkHLOS_CreateParams   audio_ipcBitsOutHostPrm;
     IpcBitsInLinkRTOS_CreateParams      audio_ipcBitsInDspPrm;
        HelloWorldLink_CreateParams         algPrm;
        //NullLink_CreateParams    nullPrm;
        //IpcBitsOutLinkRTOS_CreateParams     audio_ipcBitsOutDspPrm;
        //IpcBitsInLinkHLOS_CreateParams      audio_ipcBitsInHostPrm;

     UInt32 audio_ipcBitsOutHostId;
     UInt32 audio_ipcBitsInDspId;
        UInt32 algId,audio_ipcBitsOutDspId,audio_ipcBitsInHostId;
        //UInt32 nullId;

        CHAINS_INIT_STRUCT(IpcBitsOutLinkHLOS_CreateParams,audio_ipcBitsOutHostPrm);
        CHAINS_INIT_STRUCT(IpcBitsInLinkRTOS_CreateParams,audio_ipcBitsInDspPrm);
        CHAINS_INIT_STRUCT(HelloWorldLink_CreateParams,algPrm);


        audio_ipcBitsOutHostId  = SYSTEM_HOST_LINK_ID_IPC_BITS_OUT_0;
        audio_ipcBitsInDspId    = SYSTEM_DSP_LINK_ID_IPC_BITS_IN_0;
        algId                   = SYSTEM_LINK_ID_HELLOWORLD_0;

     startIpc(pChannels);

    audio_ipcBitsOutHostPrm.inQueInfo.numCh = 1;
        int i = 0;
     for (i = 0;      i < audio_ipcBitsOutHostPrm.inQueInfo.numCh ;      i++) {
      System_LinkChInfo *pChInfo;
      pChInfo = &audio_ipcBitsOutHostPrm.inQueInfo.chInfo[i];
      pChInfo->bufType        = 0; // NOT USED
      pChInfo->codingformat   = 0; // NOT USED
      pChInfo->dataFormat     = 0; // NOT USED
      pChInfo->memType        = 0; // NOT USED
      pChInfo->startX         = 0; // NOT USED
      pChInfo->startY         = 0; // NOT USED
      pChInfo->width          = 352;
      pChInfo->height         = 288;
      pChInfo->pitch[0]       = 0; // NOT USED
      pChInfo->pitch[1]       = 0; // NOT USED
      pChInfo->pitch[2]       = 0; // NOT USED
      pChInfo->scanFormat     = SYSTEM_SF_PROGRESSIVE;
      //ipcBitsOutHostPrm->maxQueueDepth[i]   =         MAX_BUFFERING_QUEUE_LEN_PER_CH;
      //ipcBitsOutHostPrm->chMaxReqBufSize[i] =             352 * 288;
      //numBufPerCh = NUM_BUFS_PER_CH_BITSOUT_AEC;
      //ipcBitsOutHostPrm->totalBitStreamBufferSize[i] =  ipcBitsOutHostPrm->chMaxReqBufSize[i] *  numBufPerCh; } ipcBitsOutHostPrm->baseCreateParams.noNotifyMode = FALSE; ipcBitsOutHostPrm->baseCreateParams.notifyNextLink = TRUE; ipcBitsOutHostPrm->baseCreateParams.numOutQue = 1; ipcBitsOutHostPrm->inQueInfo.numCh = numCh;
     }

        audio_ipcBitsOutHostPrm.baseCreateParams.numOutQue                    = 1;
        audio_ipcBitsOutHostPrm.baseCreateParams.numChPerOutQue[0]            = 1;
        //audio_ipcBitsOutHostPrm.baseCreateParams.processLink                = audio_ipcBitsInDspId;
        audio_ipcBitsOutHostPrm.bufPoolPerCh                                  = FALSE;
        audio_ipcBitsOutHostPrm.numBufPerCh[0]                                = 16;
        audio_ipcBitsOutHostPrm.baseCreateParams.outQueParams[0].nextLink     = audio_ipcBitsInDspId;
        audio_ipcBitsOutHostPrm.baseCreateParams.noNotifyMode                 = FALSE;
        audio_ipcBitsOutHostPrm.baseCreateParams.notifyNextLink               = TRUE;
        audio_ipcBitsOutHostPrm.baseCreateParams.notifyPrevLink               = 0;
        audio_ipcBitsOutHostPrm.baseCreateParams.notifyProcessLink            = TRUE;

        audio_ipcBitsInDspPrm.baseCreateParams.inQueParams.prevLinkId       = audio_ipcBitsOutHostId;
        audio_ipcBitsInDspPrm.baseCreateParams.inQueParams.prevLinkQueId    = 0;
        audio_ipcBitsInDspPrm.baseCreateParams.numOutQue                    = 1;
        audio_ipcBitsInDspPrm.baseCreateParams.outQueParams[0].nextLink     = algId;
        audio_ipcBitsInDspPrm.baseCreateParams.noNotifyMode                 = FALSE;
        audio_ipcBitsInDspPrm.baseCreateParams.notifyPrevLink               = 0;
        audio_ipcBitsInDspPrm.baseCreateParams.notifyNextLink               = TRUE;

        algPrm.inQueParams.prevLinkId           = audio_ipcBitsInDspId;
        algPrm.inQueParams.prevLinkQueId        = 0;
        //algPrm.outQueParams.nextLink            = audio_ipcBitsOutDspId;

        System_linkCreate(audio_ipcBitsOutHostId, &audio_ipcBitsOutHostPrm, sizeof(audio_ipcBitsOutHostPrm));
        System_linkCreate(audio_ipcBitsInDspId, &audio_ipcBitsInDspPrm, sizeof(audio_ipcBitsInDspPrm));
        System_linkCreate(algId, &algPrm, sizeof(algPrm));

        System_linkStart(audio_ipcBitsOutHostId);
        System_linkStart(audio_ipcBitsInDspId);
        System_linkStart(algId);
        while(1)
        {
         Char ch = Chains_getChar();
        }
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    When it is running:

    [c6xdsp ]        Location = INTERNAL L1/2 MEM
     [c6xdsp ]  15987: HELLOWORLD    : Algorithm Create Done !!!
     [c6xdsp ]  15987: HELLOWORLD : Create Done !!!

    [host] line[38],emptybuffNum[5]

    [host] line[38],emptybuffNum[5]

     [host] line[38],emptybuffNum[5]

     [host] line[38],emptybuffNum[1]

     [host] line[38],emptybuffNum[0]

     [host] line[38],emptybuffNum[0]

     [host] line[38],emptybuffNum[0]

     [host] line[38],emptybuffNum[0]

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Look forward to your guidance!

    Thanks!

     

  • Pls try setting minBufSize and then check the bufSize return by ipcBitsOutLin,.It may not be of size 352x288.Ensure your application fillLength is less than bitstream bufSize

  • Thanks for your timely reply,I have ensure that the minbufsize is 288*352,and the bitbufsize returned from ipcBitsOutLInk is also 288*352.

    I also print some info in helloWorld link,and I'm lost for something,

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    [c6xdsp ]  17131: HELLOWORLD : Create Done !!!

     [host] empty buffer id [0],buffer size[101376]

     [host] empty buffer id [1],buffer size[101376]

     [host] empty buffer id [2],buffer size[101376]

     [host] empty buffer id [3],buffer size[101376]

     [host] empty buffer id [4],buffer size[101376]
     [c6xdsp ] HELLO WORLD ALG: get 10 frames
     [c6xdsp ] HELLO WORLD ALG: put 10 frames

    get 5 buffer

     [host] empty buffer id [0],buffer size[101376]

     [host] empty buffer id [1],buffer size[101376]

     [host] empty buffer id [2],buffer size[101376]

     [host] empty buffer id [3],buffer size[101376]

     [host] empty buffer id [4],buffer size[101376]


     [c6xdsp ] HELLO WORLD ALG: get 10 frames
     [c6xdsp ] HELLO WORLD ALG: put 10 frames

    get 5 buffer

     [host] empty buffer id [0],buffer size[101376]

     [host] empty buffer id [1],buffer size[101376]

     [host] empty buffer id [2],buffer size[101376]

     [host] empty buffer id [3],buffer size[101376]

     [host] empty buffer id [4],buffer size[101376]
     [c6xdsp ] HELLO WORLD ALG: get 10 frames
     [c6xdsp ] HELLO WORLD ALG: put 10 frames

     [host] empty buffer id [0],buffer size[101376]
     [c6xdsp ] HELLO WORLD ALG: get 10 frames
     [c6xdsp ] HELLO WORLD ALG: put 10 frames
    ^Z[1] + Stopped                    ./dvr_rdk_demo_link_api.out
    root@dm816x:/mnt/opt/dvr_rdk/ti816x/bin# reboot

     

    /*******************************************************************************
    *                                                                             *
    * Copyright (c) 2009 Texas Instruments Incorporated - http://www.ti.com/      *
    *                        ALL RIGHTS RESERVED                                  *
    *                                                                             *
    ******************************************************************************/
    
    #include "helloWorldLink_priv.h"
    #include "helloWorldAlg.h"
    #include "ti/sdo/fc/dskt2/dskt2.h"
    #include <mcfw/src_bios6/utils/utils_mem.h>
    
    static UInt8 gScratchId = 1;
    
    /* ===================================================================
    *  @func     HelloWorldLink_algDelete
    *
    *  @desc     Function creates the instance of hellow world algorithm
    *
    *  @modif    This function modifies the following structures
    *
    *  @inputs   This function takes the following inputs
    *            HelloWorldLink_Obj
    *            Object to hello world link
    *
    *  @outputs  
    *            
    *
    *  @return   Status
    *			  FVID2_SOK: If outout object created successfuly 
    *  ==================================================================
    */
    
    Int32 HelloWorldLink_algDelete(HelloWorldLink_Obj * pObj)
    {
        Int32 scratchId = gScratchId;
    
        Vps_printf(" %d: HELLOWORLD    : Algorithm Delete in progress !!!\n",
                   Utils_getCurTimeInMsec());
    
        if(pObj->algHndl == NULL)
            return FVID2_EFAIL;
    
        /* Deactivate algorithm */
        DSKT2_deactivateAlg(scratchId, (IALG_Handle)pObj->algHndl);
    
        DSKT2_freeAlg(scratchId, (IALG_Handle)pObj->algHndl);
    
        Vps_printf(" %d: HELLOWORLD    : Algorithm Delete Done !!!\n",
                   Utils_getCurTimeInMsec());
    
    	return FVID2_SOK;
    }
    
    /* ===================================================================
    *  @func     HelloWorldLink_algCreate
    *
    *  @desc     Function creates the instance of hellow world algorithm
    *
    *  @modif    This function modifies the following structures
    *
    *  @inputs   This function takes the following inputs
    *            HelloWorldLink_Obj
    *            Object to hello world link
    *
    *  @outputs  
    *            
    *
    *  @return   Status
    *			  FVID2_SOK: If outout object created successfuly 
    *  ==================================================================
    */
    
    static Int32 HelloWorldLink_algCreate(HelloWorldLink_Obj * pObj)
    {
        HELLOWORLDALG_createPrm       algCreatePrm;
        IALG_Fxns           *algFxns = (IALG_Fxns *)&HELLOWORLDALG_TI_IALG;
    
        Vps_printf(" %d: HELLOWORLD    : Algorithm Create in progress !!!\n",
                   Utils_getCurTimeInMsec());
    
        algCreatePrm.maxWidth    = pObj->createArgs.maxWidth;
        algCreatePrm.maxHeight   = pObj->createArgs.maxHeight;
        algCreatePrm.maxStride   = pObj->createArgs.maxStride;
        algCreatePrm.maxChannels = pObj->createArgs.maxChannels;
        /*************************************************************************/
    	/* Create algorithm instance and get hello world algo handle.            */
        /* DSKT2 is memory manager and creates instance for algorithm that has   */
    	/* XDAIS/Alg interface APIs implemented (numAlloc, memAlloc and algInit) */
        /*************************************************************************/
    
        pObj->algHndl = DSKT2_createAlg((Int)gScratchId,
                (IALG_Fxns *)algFxns, NULL,(IALG_Params *)&algCreatePrm);
    
        if(pObj->algHndl == NULL)
        {
            Vps_printf(" %d: HELLOWORLD    : Algorithm Create ERROR !!!\n",
                   Utils_getCurTimeInMsec());
            return FVID2_EFAIL;
        }
    
    
    	/*************************************************************************/
        /* Once algorithm instace is created, initialize channel specific        */
        /* parameters here                                                       */
        /*************************************************************************/
    	
        /* for(chNum = 0; chNum < algCreatePrm.maxChannels; chNum++)
    	{
    	    HELLOWORLDALG_TI_setPrms(pObj->algHndl, HELLOWORLDALG_chPrm, chNum)
    	} */
    	
    
        Vps_printf(" %d: HELLOWORLD    : Algorithm Create Done !!!\n",
                   Utils_getCurTimeInMsec());
    
     return FVID2_SOK;
    }
    
    
    
    /* ===================================================================
    *  @func     HelloWorldLink_createOutObj
    *
    *  @desc     Function creates the queue for output buffer and allocate
    *            the buffers. These buffers can be send as input to next
    *            links (running on any core)
    *
    *  @modif    This function modifies the following structures
    *
    *  @inputs   This function takes the following inputs
    *            HelloWorldLink_Obj
    *            Object to hello world link
    *
    *  @outputs  
    *            
    *
    *  @return   Status
    *			  FVID2_SOK: If outout object created successfuly 
    *  ==================================================================
    */
    
    static Int32 HelloWorldLink_createOutObj(HelloWorldLink_Obj * pObj)
    {
        HelloWorldLink_OutObj *pOutObj;
        System_LinkChInfo *pOutChInfo;
        Int32 status;
        UInt32 bufIdx;
        Int i,j,queueId,chId;
        UInt32 totalBufCnt;
    
        /*************************************************************************/
        /* One link can have multiple output queues with different/same output   */
        /* data queued to it's output queue. Create here outobj for all output   */
        /* queue                                                                 */
        /*************************************************************************/
        for(queueId = 0; queueId < HELLOWORLD_LINK_MAX_OUT_QUE; queueId++)
        {
    
            pOutObj = &pObj->outObj[queueId];    
    
            pObj->outObj[queueId].numAllocPools = 1;
    
            pOutObj->bufSize[0] = HELLOWORLD_LINK_OUT_BUF_SIZE;
    
            /*********************************************************************/
            /* Set the buffer alignment as per need. Typically 128 suggested for */
            /* better cache and DMA efficiency.                                  */
            /*********************************************************************/
            pOutObj->bufSize[0] = VpsUtils_align(pOutObj->bufSize[0], 
                HELLOWORLD_BUFFER_ALIGNMENT);
    
            /*********************************************************************/
            /* Create output queue                                               */
            /*********************************************************************/
            status = Utils_bitbufCreate(&pOutObj->bufOutQue, TRUE, FALSE,
                pObj->outObj[queueId].numAllocPools);
            UTILS_assert(status == FVID2_SOK);
    
            totalBufCnt = 0;
    
            /*********************************************************************/
            /* Allocate output buffers                                           */
            /*********************************************************************/
            for (i = 0; i < pOutObj->numAllocPools; i++)
            {
                /*****************************************************************/		
                /* Number of output buffers per channel. In this example hello   */
                /* world, outNumBufs set via user input.                         */
                /*****************************************************************/
                pOutObj->outNumBufs[i] = (pObj->createArgs.maxChannels * 
                    pObj->createArgs.numBufsPerCh);
    
                for (j = 0; j < pObj->createArgs.maxChannels; j++)
                {
                    pOutObj->ch2poolMap[j] =  i;
                }
    
                /*****************************************************************/		
                /* Allocate the buffer from shared memory pool for bitstream     */
                /* buffer. If you like to allocate memory for frame buffers,     */
                /* you can either call Utils_tilerFrameAlloc() to allocate       */
                /* memory from tiler memory or you can call Utils_memFrameAlloc  */
                /* to allocate memory from shared buffer pool                    */
                /*****************************************************************/			
                status = Utils_memBitBufAlloc(&(pOutObj->outBufs[totalBufCnt]),
                    pOutObj->bufSize[i],
                    pOutObj->outNumBufs[i]);
                UTILS_assert(status == FVID2_SOK);
    
                /*****************************************************************/		
                /* Push the buffers to the output queue that's just been created */
                /*****************************************************************/			
                for (bufIdx = 0; bufIdx < pOutObj->outNumBufs[i]; bufIdx++)
                {
                    UTILS_assert((bufIdx + totalBufCnt) < HELLOWORLD_LINK_MAX_OUT_FRAMES);
                    pOutObj->outBufs[bufIdx + totalBufCnt].allocPoolID = i;
                    pOutObj->outBufs[bufIdx + totalBufCnt].doNotDisplay =
                        FALSE;
                    status =
                        Utils_bitbufPutEmptyBuf(&pOutObj->bufOutQue,
                        &pOutObj->outBufs[bufIdx +
                        totalBufCnt]);
                    UTILS_assert(status == FVID2_SOK);
                }
                totalBufCnt += pOutObj->outNumBufs[i];
            }
        }
    
        pObj->info.numQue = HELLOWORLD_LINK_MAX_OUT_QUE;
    
        /*************************************************************************/
        /* queInfo is used by next link to create it's instance.                 */
        /* Set numCh - number of channel information                             */
        /*************************************************************************/
        for (queueId = 0u; queueId < HELLOWORLD_LINK_MAX_OUT_QUE; queueId++)
        {
            pObj->info.queInfo[queueId].numCh = pObj->inQueInfo.numCh;
        }
    
        /*************************************************************************/
        /* Set the information for output buffer of each channel. Again, next    */
        /* link  connected to hello world link will use this information to     */
        /* create it's own instance.                                             */
        /*************************************************************************/
        for (chId = 0u; chId < pObj->inQueInfo.numCh; chId++)
        {
            for (queueId = 0u; queueId < HELLOWORLD_LINK_MAX_OUT_QUE; queueId++)
            {
                pOutChInfo = &pObj->info.queInfo[queueId].chInfo[chId];
                pOutChInfo->bufType = SYSTEM_BUF_TYPE_VIDBITSTREAM;
                pOutChInfo->codingformat = NULL;
                pOutChInfo->memType = NULL;
                pOutChInfo->scanFormat = pObj->inQueInfo.chInfo[chId].scanFormat;
                pOutChInfo->width = pObj->inQueInfo.chInfo[chId].width;
                pOutChInfo->height = pObj->inQueInfo.chInfo[chId].height;
            }
        }
    
        return (status);
    }
    
    
    /* ===================================================================
    *  @func     HelloWorldLink_algCreate
    *
    *  @desc     Creates HelloWorld link instance
    *
    *  @modif    This function modifies the following structures
    *
    *  @inputs   This function takes the following inputs
    *            <HelloWorldLink_Obj>
    *            Object to hello world link
    *            <HelloWorldLink_CreateParams>
    *            Create time parameters passed by the user
    *
    *  @outputs  <argument name>
    *            Description of usage
    *
    *  @return   Status of instance creation
    *  ==================================================================
    */
    Int32 HelloWorldLink_create(HelloWorldLink_Obj * pObj, 
                                HelloWorldLink_CreateParams * pPrm)
    {
        Int32 status;
    
        Vps_printf(" %d: HELLOWORLD : Create in progress !!!\n", 
            Utils_getCurTimeInMsec());
    
        /*************************************************************************/
        /* copy the create time parameters passed from host to local object      */
        /*************************************************************************/
        memcpy(&pObj->createArgs, pPrm, sizeof(*pPrm));
    
        /*************************************************************************/
        /* Get frame header information from previous link input queue            */
        /*************************************************************************/
        status = System_linkGetInfo(pPrm->inQueParams.prevLinkId, &pObj->inTskInfo);
        UTILS_assert(status == FVID2_SOK);
    
        /*************************************************************************/
        /* Make sure queid information provided in create params is less then    */
        /* total number of queues in previous link (returned by                  */
        /* System_linkGetInfo module                                             */
        /*************************************************************************/
        UTILS_assert(pPrm->inQueParams.prevLinkQueId < pObj->inTskInfo.numQue);
    
        /*************************************************************************/
        /* Make a local copy of previous link queue number connected to          */
        /* helloWorld link                                                       */
        /*************************************************************************/
        memcpy(&pObj->inQueInfo,
            &pObj->inTskInfo.queInfo[pPrm->inQueParams.prevLinkQueId],
            sizeof(pObj->inQueInfo));
    
        /*************************************************************************/
        /* Check if helloWorld link instance can handle the number of channels   */
        /* from previous links                                                   */
        /*************************************************************************/
        UTILS_assert(pObj->inQueInfo.numCh <= HELLOWORLD_LINK_MAX_CH);
    
    
        /*************************************************************************/
        /* Create an instance to hello world algorithm                           */
        /*************************************************************************/
        status = HelloWorldLink_algCreate(pObj);
        UTILS_assert(status == FVID2_SOK);
    
        /*************************************************************************/
        /* If you have more algorithms that sequentially process upon the        */
        /* received input frame, you can create instances to those algorithms    */
        /* in series here                                                        */
        /*************************************************************************/
        //xxxLink_Create();
        //yyyLink_Create(); 
    
    
        /*************************************************************************/
        /* All links creates and manages the output buffers they produce. Input  */
        /* buffers managed by prior link that produced that buffer               */
        /* This is generic link and hence user input taken from A8 if link needs */
        /* to produce and hence create an output buffer.                         */
        /*************************************************************************/
        if (pObj->createArgs.createOutBuf1)
            HelloWorldLink_createOutObj(pObj);
    
        Vps_printf(" %d: HELLOWORLD : Create Done !!!\n", Utils_getCurTimeInMsec());
        return FVID2_SOK;
    }
    
    
    /* ===================================================================
    *  @func     HelloWorldLink_algDelete
    *
    *  @desc     Delete HelloWorld link instance
    *
    *  @modif    This function modifies the following structures
    *
    *  @inputs   This function takes the following inputs
    *            <HelloWorldLink_Obj>
    *            Object to hello world link
    *
    *  @outputs  <argument name>
    *            Description of usage
    *
    *  @return   Status of instance creation
    *  ==================================================================
    */
    Int32 HelloWorldLink_delete(HelloWorldLink_Obj * pObj)
    {    
        Int32 status;
        Int32 i,outId,bitbuf_index;
        HelloWorldLink_OutObj *pOutObj;
    
        Vps_printf(" %d: HELLOWORLD : Delete in progress !!!\n", 
            Utils_getCurTimeInMsec());
    
        /*************************************************************************/
        /* Make a call to your algrithm instance deletion here. At this place    */
        /* you should free memory and DMA resource (if any) held by your algo    */
        /*************************************************************************/
        //status = HelloWorldLink_algDelete(&pObj->Alg1);
        //UTILS_assert(status == FVID2_SOK);
    
        /*************************************************************************/
        /* Free the output buffer and it's queue created by helloWorld link      */
        /*************************************************************************/
        for (outId = 0; outId < HELLOWORLD_LINK_MAX_OUT_QUE; outId++)
        {
            {
                pOutObj = &pObj->outObj[outId];
    
                status = Utils_bitbufDelete(&pOutObj->bufOutQue);
                UTILS_assert(status == FVID2_SOK);
                bitbuf_index = 0;
    
                for (i = 0; i < pOutObj->numAllocPools; i++)
                {
                    UTILS_assert((pOutObj->outBufs[bitbuf_index].bufSize ==
                        pOutObj->bufSize[i]));
                    status = Utils_memBitBufFree(&pOutObj->outBufs[bitbuf_index],
                        pOutObj->outNumBufs[i]);
                    UTILS_assert(status == FVID2_SOK);
                    bitbuf_index += pOutObj->outNumBufs[i];
                }
            }
        }
    
        Vps_printf(" %d: HELLOWORLD : Delete Done !!!\n", Utils_getCurTimeInMsec());
    
        return FVID2_SOK;
    }
    
    /* ===================================================================
    *  @func     HelloWorldLink_algProcessData
    *
    *  @desc     Process upon the input frame received from previous link
    *            At this place, make a call to algorithm process call
    *
    *  @modif    This function modifies the following structures
    *
    *  @inputs   This function takes the following inputs
    *            <HelloWorldLink_Obj>
    *            Object to hello world link
    *
    *  @outputs  <argument name>
    *            Description of usage
    *
    *  @return   Status of process call
    *  ==================================================================
    */
    Int32 HelloWorldLink_processData(HelloWorldLink_Obj * pObj)
    {
        UInt32 frameId;
        System_LinkInQueParams *pInQueParams;
        FVID2_Frame *pFrame;
        FVID2_FrameList frameList;
        Bitstream_Buf *pOutBuf;
        Utils_BitBufHndl *bufOutQue;
        Int32 status;
        System_FrameInfo *pInFrameInfo;
        Bitstream_BufList outBitBufList;
    	HELLOWORLDALG_Result *pHelloWorldResult = NULL;
    
        status = FVID2_EFAIL;
        pInQueParams = &pObj->createArgs.inQueParams;
    
        bufOutQue = &pObj->outObj[0].bufOutQue;
    
        /*************************************************************************/
        /* Get input frames from previous link output queue                      */
        /*************************************************************************/
        System_getLinksFullFrames(pInQueParams->prevLinkId,
            pInQueParams->prevLinkQueId, &frameList);
        Vps_printf("HELLO WORLD ALG: get %d frames\n",frameList.numFrames);
        /*************************************************************************/
        /* If input frame received from queue, get the output buffer from out    */
        /* queue and process the frame                                           */
        /*************************************************************************/
    
        if (frameList.numFrames)
        {
            //pObj->totalFrameCount += frameList.numFrames;
    
            /*********************************************************************/
            /* Get the outout buffer for each input buffer and process the frame */
            /*                                                                   */
            /*********************************************************************/
            for(frameId=0; frameId< frameList.numFrames; frameId++)
            {
                Bool doFrameDrop = FALSE;
    
    			pFrame = frameList.frames[frameId];
    
                //pChObj = &pObj->chObj[chIdx];
    
                //pChObj->inFrameRecvCount++;
    
    
                /*********************************************************************/
                /* If current frame needs to be processed, get the output buffer     */
                /* from output queue                                                 */
                /*********************************************************************/
                if(pObj->createArgs.createOutBuf1)
                {
                    pOutBuf = NULL;
                    status = Utils_bitbufGetEmptyBuf(bufOutQue,
                        &pOutBuf,
                        0, //pObj->outObj.ch2poolMap[chIdx], /*Need to change later.*/
                        BIOS_NO_WAIT);
    
                    if(!((status == FVID2_SOK) && (pOutBuf)))
                    {
                        doFrameDrop = TRUE;
                    }
    
                    /*********************************************************************/
                    /* Captured YUV buffers time stamp is passed by all links to next    */
                    /* buffers bu copying the input buffer times stamp to it's output    */
                    /* buffer. This is used for benchmarking system latency.             */
                    /*********************************************************************/
                    pInFrameInfo = (System_FrameInfo *) pFrame->appData;
                    pOutBuf->lowerTimeStamp = (UInt32)(pInFrameInfo->ts64 & 0xFFFFFFFF);
                    pOutBuf->upperTimeStamp = (UInt32)(pInFrameInfo->ts64 >> 32);
                    pOutBuf->channelNum = pFrame->channelNum;
                    //pOutBuf->fillLength = ;
                    //pOutBuf->frameWidth = ;
                    //pOutBuf->frameHeight = ;
    
    				pHelloWorldResult = (HELLOWORLDALG_Result *) pOutBuf->addr;
                }
    
                /*********************************************************************/
                /* Now input and output buffers available and this frame need not be */
                /* skipped, make a call to the algorithm process call and process the*/
                /* frame.                                                            */
                /*********************************************************************/
                if(doFrameDrop == FALSE)
                {
                    /*********************************************************************/
                    /* Pointer to Luma buffer for processing.                            */
                    /*********************************************************************/
                    //pObj->chParams[chIdx].curFrame = pFrame->addr[0][0];
    
                    pInFrameInfo = (System_FrameInfo *) pFrame->appData;
    
                    //curTime = Utils_getCurTimeInMsec();
    
                    UInt8 *p = pFrame->addr[0][0];
                    UInt32 i;
                    UInt32 Btime, Etime;
    
                    Btime = Utils_getCurTimeInMsec();
                    //p++;
    //                for (i = 0; i < 1080*1920>>1; i++)
    //                {
    //                	*p++ = 2;
    //                	*p++ = 1;
    //                	//p = p+2;
    //                	p++;
    //                	*p++ = 1;
    //                	//p = p+2;
    //
    //                }
                    static int a=0;
                    memset(p,a, 200);
                    //memset(p+1080*1920,-a, 1080*1920);
                    a++;
    
    //                *p = pFrame->addr[0][0];
    //                p = p+3;
    //                for (i = 0; i < 1080*1920>>1; i++)
    //                {
    //                	*p = i/2;
    //                	p = p+4;
    //                }
    
                    Etime  = Utils_getCurTimeInMsec();
                    //Vps_printf("USE TIME = %d \r\n", Etime - Btime);
                    /*********************************************************************/
                    /* Make a call to algorithm process call here                        */
                    /*********************************************************************/
                    //HELLOWORLDALG_TI_process(pObj->algHndl, 0, pHelloWorldResult);//HelloWorldLink_algProcess();
    
                    /*********************************************************************/
                    /* Benchmark frame process time                                      */
                    /*********************************************************************/
                    //pChObj->inFrameProcessTime += (Utils_getCurTimeInMsec() - curTime);
    
                    //pChObj->inFrameProcessCount++;
                    outBitBufList.bufs[outBitBufList.numBufs] = pOutBuf;
                    outBitBufList.numBufs++;
    
                }
                else
                {
                    //pChObj->inFrameUserSkipCount++;
                }
            }
        }
    
        /*********************************************************************/
        /* Release the input buffer to previous link queue                   */
        /*********************************************************************/
    
        System_putLinksEmptyFrames(pInQueParams->prevLinkId,
            pInQueParams->prevLinkQueId, &frameList);
    
        Vps_printf("HELLO WORLD ALG: put %d frames\n",frameList.numFrames);
        /*********************************************************************/
        /* If output buffers available, push them to the output queue        */
        /*********************************************************************/
        if(pObj->createArgs.createOutBuf1)
        {
            if (outBitBufList.numBufs)
            {
                status = Utils_bitbufPutFull(bufOutQue,
                    &outBitBufList);
                UTILS_assert(status == FVID2_SOK);
    
                /*********************************************************************/
                /* Inform next link of output buffer availability                    */
                /*********************************************************************/
                System_sendLinkCmd(pObj->createArgs.outQueParams.nextLink,
                    SYSTEM_CMD_NEW_DATA);
                status = FVID2_SOK;        
            }
            else
            {
                status = FVID2_EFAIL; 
            } 
        }
        return status;
    }
    

    it seems that DSP get and put buffer nomorlly,but why A8 can't get empty buffer continuouly,how do you see for this phenomenon?

    in helloWorld I find that it get buffer use    

    System_getLinksFullFrames(pInQueParams->prevLinkId,
            pInQueParams->prevLinkQueId, &frameList);

    but I use the ipcbitsLink,so if I need to modify it to use

        System_getLinksFullBufs(pInQueParams->prevLinkId,
                                pInQueParams->prevLinkQueId, &bufList);

    Thanks!

  • I 'am sorry,I have found the reason, it must use

        System_getLinksFullBufs(pInQueParams->prevLinkId,
                                pInQueParams->prevLinkQueId, &bufList);

    for ipcBItLINK,it is my problem that I  neglect the issue.Sorry.