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.

720p decoder for DM368 ipnc

Dear all:

    I increase decoder in DM368 ipnc and it can decoder D1 resolution.

Now I want to modify the resolution from D1 to 720p

But the video is no good, I print the decStatus.bytesUsed

In D1 resolution, it will the same as decPrm.inDataSize

In 720p resolution, it will some different with decPrm.inDataSize, maybe get more or only have 7( decStatus.outputBufId= -1).

Can any give me some advise ?

As follow is my setting:

1. Create

    createdecPrm.codec           = ALG_VID_CODEC_H264;
      createdecPrm.dataFormat      = DRV_DATA_FORMAT_YUV420;
      createdecPrm.maxWidth        = 1920;
      createdecPrm.maxHeight       = 1080;
    
   for(i=0; i<gAVSERVER_config.numEncodeStream; i++)
  {
     gVIDEO_ctrl.decodeStream[i].algDecHndl  = ALG_vidDecCreate(&createdecPrm);
  }

2. Decoder run:

    whOffset = 96;
    decodeId=0;
        decPrm.inAddr         = curInAddr;
        decPrm.outAddr        = outVirtAddr[bufId];

        decPrm.inDataSize=some_data.current_faddr_size;    //in data size
    

            decPrm.outOffsetH     = OSA_align(1280+whOffset, 32);    //if use 720, it can decode D1 well
            decPrm.outOffsetV     = 720+whOffset;                                   //if use 480, it can decode D1 well
            decPrm.inputBufId     = bufId;                                                     //I create 4 buff for decoder temp.
         OSA_prfBegin(&gAVSERVER_ctrl.decodePrf[decodeId]);


            status = ALG_vidDecRun(gVIDEO_ctrl.decodeStream[decodeId].algDecHndl, &decPrm, &decStatus);
            OSA_prfEnd(&gAVSERVER_ctrl.decodePrf[decodeId], 1);
 
        if(status==OSA_SOK) {
              totalDecSize += decStatus.bytesUsed;
    
            } else {
    
              OSA_printf(" ALG: VidDec: ALG_vidDecRun() ERROR !!!\n");
            }


    bufId += 1;
    if(bufId>3)
    bufId=0;
        
   

  • Hi,

    hirain hsieh said:
    In 720p resolution, it will some different with decPrm.inDataSize, maybe get more or only have 7( decStatus.outputBufId= -1).

    You mean Decoder consuming Only 7 bytes or its consuming decPrm.inDataSize +/- 7 bytes? can you please check it. And whats value of extended error value?

    To make it simple for debugging can you please run your 720p stream on standalone testapp provided with Release package.

    Thanks,

    Veeranna

  • Hi Veeranna Hanchinal,

        Thanks for your reply, My input source is 720p (h264), for example, key-frame size =80000, p-frame size = 20000,

    When I put the data in decoder with 30fps,

    1.first frame(key-frame)

    //in

    decPrm.inputBufId=0

    decPrm.inDataSize=80000

    //out

    decStatus.outputBufId=0

    decStatus.bytesUsed=80000

    2.  Second frames

    //in

    decPrm.inputBufId=1

    decPrm.inDataSize=20000

    //out

    decStatus.outputBufId=1

    decStatus.bytesUsed=20000

    3. Third frame

    //in

    decPrm.inputBufId=2

    decPrm.inDataSize=20000

    //out

    decStatus.outputBufId=2

    decStatus.bytesUsed=20000

    3.   Fourth frame

    //in

    decPrm.inputBufId=3

    decPrm.inDataSize=20000

    //out

    decStatus.outputBufId=3

    decStatus.bytesUsed=20000

    4.   Fifth frame (buifId will back to 0)

    //in

    decPrm.inputBufId=0

    decPrm.inDataSize=20000

    //out

    decStatus.outputBufId=0

    decStatus.bytesUsed=20000

    ...until to 29 frame then back to key-fame

    but it will get wrong data sometimes at three situation,

    1. only get 7 bytes data

    //in

    decPrm.inputBufId=0

    decPrm.inDataSize=20000

    //out

    decStatus.outputBufId=-1

    decStatus.bytesUsed=7

    2. get more data

    //in

    decPrm.inputBufId=0

    decPrm.inDataSize=20000

    //out

    decStatus.outputBufId=0

    decStatus.bytesUsed=20013 (for example)

    3. get less data

    //in

    decPrm.inputBufId=0

    decPrm.inDataSize=20000

    //out

    decStatus.outputBufId=0

    decStatus.bytesUsed=15984 (for example)

    so I can see a image but the image quality is bad

    sounds like my older question for D1 decoder

    http://e2e.ti.com/support/embedded/multimedia_software_codecs/f/356/p/117162/420578.aspx#420578

    Do you have any advice?

  • Hi,

    Your last issue was related to DPB, but in that case i don't think you are getting wrong byte consumed. So conform the codec behavior for given stream please stand-alone test app. then check bytes consumed. And can you share the stream also?

    Thanks,

    Veeranna

  • Dear Veeranna Hanchinal:

        Thanks for your reply so fast, I think it is not DPB problem too,

    The situation have a little close but the image is more bad.

    My stream source is getting from another ip cam (recive data from openRTSP)

    So I don't know how to get the h264 data and using stand-alone test app to test it.

    Now I am try to do this.

  • Hi,

    Your are feeding bitstream packet data to decoder, just before decode process call you can add fwrite of packet size of input buff.

    Regarding stand alone testapp running please have look at  Users Guide.

    When you say openRTSP does it uses encoder based on  TI's DM36x encoder or something else? if you are using other encoder make sure you are setting closed_loop_decoder = 0.

    Thanks,

    Veeranna

  • Hi Veeranna Hanchinal:

        My ipnc is using DM368 encoder, so my closed_loop_decoder=1,

    I save the 720p streaming and using alg_vidDen.c's test function to playback(for loop to decode file).

    The image is correct and no strange data. So I think decoder lib is correct.

    But if I send data into decoder each frame for real time streaming, it become bad,

    My decPrm.inAddr is using mmap to create.

    I use openRTSP to receive data and send physical to AV Server.

    When AV Server get message, and then using mmap to create a virtual address for decPrm.inAddr.

    Such as follow:

    curInAddr= mmap(0,                       // Preferred start address
                 1280*720, // Length to be mapped     
                 PROT_WRITE | PROT_READ,  // Read and write access
                 MAP_SHARED,              // Shared memory
                 cmem_fd,                 // File descriptor
                 some_data.current_faddr) ;    //physical address from openRTSP

    decPrm.inAddr=curInAddr;

    Do you have any advice?

  • Hi,

        I try to migrate decoder to lastest version .

    The image is still bad but when the outputBufId=-1

    the outArgs.bytesConsumed is become 0 byte, old version is 7 bytes

    Do you have any advice for me?

  • Hi, I post my alg_vidDec.c detail

    1. create  //max input size is 1920x1080

    void *ALG_vidDecCreate(ALG_VidDecCreate *create)
    {
      ALG_VidDecObj *pObj;

      pObj = OSA_memAlloc(sizeof(*pObj));

      if(pObj==NULL)
        return NULL;

      memset(pObj, 0, sizeof(*pObj));

      memcpy(&pObj->createPrm, create, sizeof(pObj->createPrm));

      switch(create->codec)
      {
        case ALG_VID_CODEC_H264:
          strcpy(pObj->algName, ALG_VID_CODEC_H264_DEC_NAME);
          break;
        case ALG_VID_CODEC_MPEG4:
          strcpy(pObj->algName, ALG_VID_CODEC_MPEG4_DEC_NAME);
          break;
        case ALG_VID_CODEC_MJPEG:
        {
          ALG_JpgDecCreate jpgDecCreate;

          jpgDecCreate.dataFormat = create->dataFormat;
          jpgDecCreate.maxWidth = create->maxWidth;
          jpgDecCreate.maxHeight = create->maxHeight;

          pObj->hJpgDecode = ALG_jpgDecCreate(&jpgDecCreate);

          if(pObj->hJpgDecode==NULL)
            return NULL;

          return pObj;
        }
          break;
        default:
          OSA_memFree(pObj);
          return NULL;
      }

        memcpy(&pObj->h264Params, &IH264VDEC_PARAMS, sizeof(pObj->h264Params));
        
      pObj->params.size               = sizeof(VIDDEC2_Params);
      pObj->params.maxHeight          = create->maxHeight;
      pObj->params.maxWidth           = create->maxWidth;
      pObj->params.maxFrameRate       = 0;                            //H.264 Decoder does not use                                    
      pObj->params.maxBitRate         = ALG_VID_DEC_MAX_BITRATE;        //H.264 Decoder does not use
      pObj->params.dataEndianness     = XDM_BYTE;
      pObj->params.forceChromaFormat  = XDM_YUV_420SP;

      pObj->h264Params.displayDelay = 0;
      pObj->h264Params.hdvicpHandle = NULL;
    //  pObj->h264Params.resetHDVICPeveryFrame = TRUE;
      pObj->h264Params.disableHDVICPeveryFrame = 0;
      pObj->h264Params.frame_closedloop_flag = 1;
      pObj->h264Params.inputDataMode = 1;
      pObj->h264Params.sliceFormat = 1;
      pObj->h264Params.viddecParams = pObj->params;
      pObj->h264Params.viddecParams.size = sizeof(pObj->h264Params);
      /* Create video decoder instance */
      pObj->hDecode = VIDDEC2_create(gALG_hEngine, pObj->algName, &pObj->h264Params);
      if (pObj->hDecode == NULL) {
        OSA_ERROR("Failed to open video decode algorithm (%s)\n", pObj->algName);
        OSA_memFree(pObj);
        return NULL;
      }

      return (void*)pObj;
    }

    2. decoder run

    int ALG_vidDecRun(void *hndl, ALG_VidDecRunPrm *prm, ALG_VidDecRunStatus *runStatus)
    {
      VIDDEC2_InArgs  inArgs;
      VIDDEC2_OutArgs outArgs;
      XDM1_BufDesc    inBufDesc;
      XDM_BufDesc     outBufDesc;
      XDAS_Int32      outBufSizeArray[2];    
      XDAS_Int32      status;
      XDAS_Int8            *outBufPtrs[2];    
      ALG_VidDecObj   *pObj;
      IH264VDEC_DynamicParams h264DynParams;

      pObj = (ALG_VidDecObj *)hndl;

      if(pObj==NULL)
        return OSA_EFAIL;

      if(pObj->createPrm.codec == ALG_VID_CODEC_MJPEG) {

        ALG_JpgDecRunPrm jpgDecRun;
        ALG_JpgDecRunStatus jpgDecStatus;

        jpgDecRun.inAddr = prm->inAddr;
        jpgDecRun.inDataSize = prm->inDataSize;
        jpgDecRun.outAddr = prm->outAddr;
        jpgDecRun.outOffsetH = prm->outOffsetH;
        jpgDecRun.outOffsetV = prm->outOffsetV;
        jpgDecRun.outStartX = 0;
        jpgDecRun.outStartY = 0;

        status = ALG_jpgDecRun(pObj->hJpgDecode, &jpgDecRun, &jpgDecStatus);
        if(status!=OSA_SOK)
          return OSA_EFAIL;

        runStatus->bytesUsed  = jpgDecStatus.bytesUsed;
        runStatus->isKeyFrame = TRUE;
        runStatus->frameWidth = jpgDecStatus.frameWidth;
        runStatus->frameHeight= jpgDecStatus.frameHeight;
        runStatus->outputBufId= prm->inputBufId;
        runStatus->freeBufId  = prm->inputBufId;
        runStatus->outStartX  = jpgDecRun.outStartX;
        runStatus->outStartY  = jpgDecRun.outStartY;
        runStatus->outOffsetH = jpgDecRun.outOffsetH;
        runStatus->outOffsetV = jpgDecRun.outOffsetV;

        return OSA_SOK;
      }

      if(pObj->hDecode==NULL)
        return OSA_EFAIL;

      if(pObj->curFrameNum==0)  

        pObj->dynamicParams.size          = sizeof(VIDDEC2_DynamicParams);
        pObj->dynamicParams.decodeHeader  = XDM_DECODE_AU;
        pObj->dynamicParams.displayWidth  = prm->outOffsetH;
        pObj->dynamicParams.frameSkipMode = IVIDEO_NO_SKIP;
        pObj->dynamicParams.frameOrder    = IVIDDEC2_DECODE_ORDER;

        pObj->decStatus.size     = sizeof(VIDDEC2_Status);
        pObj->decStatus.data.buf = NULL;
        h264DynParams.viddecDynamicParams = pObj->dynamicParams;
        h264DynParams.viddecDynamicParams.size = sizeof(h264DynParams);
        h264DynParams.resetHDVICPeveryFrame = 1;
        h264DynParams.dataSyncHandle = NULL;
        h264DynParams.getDataFxn = NULL;    

        
        status = VIDDEC2_control(pObj->hDecode, XDM_SETPARAMS, &h264DynParams, &pObj->decStatus);
        if (status != VIDDEC2_EOK) {
          OSA_ERROR("XDM_SETPARAMS failed, status=%ld\n", status);
          return OSA_EFAIL;
        }

        /* Get buffer information from video decoder */
        pObj->decStatus.size     = sizeof(VIDDEC2_Status);
        pObj->decStatus.data.buf = NULL;

        pObj->dynamicParams.size = sizeof(VIDDEC2_DynamicParams);


        if (status != VIDDEC2_EOK) {
          OSA_ERROR("XDM_GETBUFINFO failed, status=%ld\n", status);
          return OSA_EFAIL;
        }

        #ifdef ALG_VID_DEC_DEBUG
        OSA_printf(" ALG: VidDec: XDM_GETBUFINFO: min out bufs:%ld,size:%ld %ld\n",pObj->decStatus.bufInfo.minNumOutBufs,pObj->decStatus.bufInfo.minOutBufSize[0], pObj->decStatus.bufInfo.minOutBufSize[1]);
        #endif
      }

      pObj->dynamicParams.size      = sizeof(VIDDEC2_DynamicParams);

      pObj->decStatus.size          = sizeof(VIDDEC2_Status);
      pObj->decStatus.data.buf      = NULL;


     outBufSizeArray[0] = (prm->outOffsetH)*(prm->outOffsetV);    //Y data size
      outBufSizeArray[1] = outBufSizeArray[0]/2;                    //UV data size


      inBufDesc.descs[0].bufSize = prm->inDataSize;
      inBufDesc.descs[0].buf  = (XDAS_Int8 *)prm->inAddr;
      inBufDesc.numBufs       = 1;    

      outBufPtrs[0] = (XDAS_Int8 *)prm->outAddr;            
      outBufPtrs[1] = (XDAS_Int8 *)(prm->outAddr + outBufSizeArray[0]) ;


      outBufDesc.bufSizes     = outBufSizeArray;
      outBufDesc.bufs         = (XDAS_Int8 **) &outBufPtrs;
      outBufDesc.numBufs      = 2;    

      inArgs.size             = sizeof(VIDDEC2_InArgs);
      inArgs.numBytes         = prm->inDataSize;
      inArgs.inputID          = prm->inputBufId+1; // must be greater than 0

      outArgs.size            = sizeof(VIDDEC2_OutArgs);
      outArgs.outBufsInUseFlag=0;   

     
      status = VIDDEC2_process(pObj->hDecode, &inBufDesc, &outBufDesc, &inArgs, &outArgs);

      status = VIDDEC2_control(pObj->hDecode, XDM_GETSTATUS, &pObj->dynamicParams, &pObj->decStatus);
      if (status != VIDDEC2_EOK) {
        OSA_ERROR("XDM_GETSTATUS failed, status=%ld\n", status);
        return OSA_EFAIL;
      }
      runStatus->bytesUsed = outArgs.bytesConsumed;

      if (status != VIDDEC2_EOK) {
        OSA_ERROR("status=%ld\n", status);
        return OSA_EFAIL;
      }

      switch (outArgs.displayBufs[0].frameType) {
        case IVIDEO_I_FRAME:
          runStatus->isKeyFrame = TRUE;
          break;
        case IVIDEO_P_FRAME:
          runStatus->isKeyFrame = FALSE;
          break;
        case IVIDEO_B_FRAME:
          runStatus->isKeyFrame = FALSE;
          break;
        case IVIDEO_IDR_FRAME:
          runStatus->isKeyFrame = TRUE;
          break;
        case IVIDEO_II_FRAME:
          runStatus->isKeyFrame = TRUE;
          break;  
        case IVIDEO_PP_FRAME:
          runStatus->isKeyFrame = FALSE;
          break;      
        default:  
          runStatus->isKeyFrame = FALSE;
          break;
      }

    //  runStatus->frameWidth = pObj->decStatus.outputWidth;
    //  runStatus->frameHeight = pObj->decStatus.outputHeight;

    if(outArgs.outBufsInUseFlag == 1)
    {
        
      inBufDesc.descs[0].buf  = (XDAS_Int8 *)prm->inAddr + runStatus->bytesUsed;

      status = VIDDEC2_process(pObj->hDecode, &inBufDesc, &outBufDesc, &inArgs, &outArgs);

      runStatus->bytesUsed += outArgs.bytesConsumed;
      if (status != VIDDEC2_EOK) {
        OSA_ERROR("status=%ld\n", status);
    //    return OSA_EFAIL;
      }

        VIDDEC2_control(pObj->hDecode, XDM_GETSTATUS, &pObj->dynamicParams, &pObj->decStatus);
      if (status != VIDDEC2_EOK) {
        OSA_ERROR("XDM_GETSTATUS failed with error code = 0x%x , status=%ld\n", pObj->decStatus.extendedError,status);
    //    OSA_fileWriteFile("InputBitstream.dat", (XDAS_Int8 *)prm->inAddr, prm->inDataSize);
        OSA_printf("\r\n Bytes Consumed so far = %d ",runStatus->bytesUsed);
        return OSA_EFAIL;
      }
    }
    runStatus->bytesUsed,outArgs.outBufsInUseFlag);
      runStatus->frameWidth = pObj->decStatus.outputWidth;
      runStatus->frameHeight = pObj->decStatus.outputHeight;
      if(outArgs.displayBufs[0].bufDesc[0].buf == NULL) {
        return OSA_EFAIL;
      }
      else {
        runStatus->outputBufId = outArgs.outputID[0]-1; // to adjust for +1 done in inputID
        runStatus->freeBufId = outArgs.freeBufID[0]-1;

     outArgs.bytesConsumed);
        if(pObj->curFrameNum==0) {
          pObj->outStartY = ((Uint32)outArgs.displayBufs[0].bufDesc[0].buf - (Uint32)prm->outAddr)/prm->outOffsetH;
          pObj->outStartX = ((Uint32)outArgs.displayBufs[0].bufDesc[0].buf - (Uint32)prm->outAddr)%prm->outOffsetH;
        }
        runStatus->outStartX = pObj->outStartX;
        runStatus->outStartY = pObj->outStartY;
        runStatus->outOffsetH= prm->outOffsetH;
        runStatus->outOffsetV= prm->outOffsetV;
      }

      pObj->curFrameNum++;

      return OSA_SOK;
    }

  • Hi,

    As you said decoder consumes 0 byte or 7 byte, I feel data given to decoder is corrupted. Can you recheck this once? And I am sure decoder is setting extendedError, can you check what value it is getting set.?

    And when decoder consumes less bytes of frame you can't expect decoder return output buf of good quality.

    Thanks,

    Veeranna