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.

H.264 HP encoder doesn't release all the input buffers

Hi,

I am using H.264 HP encoder for C6678 (100.V.H264HP.E.C6678.01.00). I noticed that HP encoder does not release all the input buffers when encoding stream with changing aspect ratio. This behaviour causes memory leak in my transcoder program.

I use the following configuration:

gopStructure = 0;
IDRFrameInterval = 3;
intraFrameInterval = 6;
interFrameInterval = 3;
aspectRatioInfoPresentFlag = 1;
aspectRatioIdc = 255;

I use sampleAspectRatioWidth and sampleAspectRatioHeight dynamic parameters to change aspect ratio (control call with XDM_SETPARAMS command). For tests I change aspect ratio from time to time.

I create new input buffer with new ID before each encoder process call (IDs go in output order of MPEG2 decoder) and free all buffers from freeBufID array after each encoder process call. The logic looks like:

// Create new input encoder buffer
printf("Creating input buffer %d\n", inputId);
inEncoderBufferDescriptor = BufferDescriptorManager_getUnusedBufferDescriptor(inEncoderBufferManager, inputId);
inEncoderArguments->inputID = inputId;


// Process
result = encoderFunctions->process(encoderHandle, &inEncoderBufferDescriptor, &outEncoderBufferDescriptor, inEncoderArguments, outEncoderArguments);

// Free input buffers
int* bufferIdToFreePointer = outEncoderArguments->freeBufID;

while (*bufferIdToFreePointer != 0) {
    printf("Free input buffer %d\n", *bufferIdToFreePointer);
    BufferDescriptorManager_releaseBufferDescriptor(inEncoderBufferManager, *bufferIdToFreePointer);
    bufferIdToFreePointer++;
}

Result:

Creating input buffer 2
Creating input buffer 1
Creating input buffer 4
Free input buffer 2
New aspect ratio: 2
Creating input buffer 3
Creating input buffer 6
Creating input buffer 5
Free input buffer 3
Creating input buffer 8
Free input buffer 8
Creating input buffer 7
Free input buffer 6
New aspect ratio: 3
Creating input buffer 10
Creating input buffer 9
Creating input buffer 12
Free input buffer 10
Creating input buffer 11
Free input buffer 11
Creating input buffer 14
Free input buffer 9
New aspect ratio: 2
Creating input buffer 13
Creating input buffer 16
Creating input buffer 15
Free input buffer 13
Creating input buffer 18
Free input buffer 18
Creating input buffer 17
Free input buffer 16
New aspect ratio: 3
Creating input buffer 20
Creating input buffer 19
Creating input buffer 22
Free input buffer 20
Creating input buffer 21
Free input buffer 21
Creating input buffer 24
Free input buffer 19
New aspect ratio: 2
Creating input buffer 23
Creating input buffer 26
Creating input buffer 25
Free input buffer 23
Creating input buffer 28
Free input buffer 28
Creating input buffer 27
Free input buffer 26
New aspect ratio: 3
Creating input buffer 30
Creating input buffer 29
Creating input buffer 32
Free input buffer 30
Creating input buffer 31
Free input buffer 31
Creating input buffer 34
Free input buffer 29
New aspect ratio: 2
Creating input buffer 33
Creating input buffer 36
Creating input buffer 35
Free input buffer 33
Creating input buffer 38
Free input buffer 38
Creating input buffer 37
Free input buffer 36
New aspect ratio: 3
Creating input buffer 40
Creating input buffer 39
Creating input buffer 42
Free input buffer 40
Creating input buffer 41
Free input buffer 41
Creating input buffer 44
Free input buffer 39
New aspect ratio: 2
Creating input buffer 43
Creating input buffer 46
Creating input buffer 45
Free input buffer 43
Creating input buffer 48
Free input buffer 48
Creating input buffer 47
Free input buffer 46

As you can see not all input buffers that are provided to encoder released.

When I disable functionality that changes aspect ratio, input buffers released correctly:

Creating input buffer 2
Creating input buffer 1
Creating input buffer 4
Free input buffer 2
Creating input buffer 3
Free input buffer 3
Creating input buffer 6
Free input buffer 1
Creating input buffer 5
Free input buffer 4
Creating input buffer 8
Free input buffer 8
Creating input buffer 7
Free input buffer 6
Creating input buffer 10
Free input buffer 5
Creating input buffer 9
Free input buffer 9
Creating input buffer 12
Free input buffer 7
Creating input buffer 11
Free input buffer 10
Creating input buffer 14
Free input buffer 14
Creating input buffer 13
Free input buffer 12
Creating input buffer 16
Free input buffer 11
Creating input buffer 15
Free input buffer 15
Creating input buffer 18
Free input buffer 13
Creating input buffer 17
Free input buffer 16
Creating input buffer 20
Free input buffer 20
Creating input buffer 19
Free input buffer 18
Creating input buffer 22
Free input buffer 17
Creating input buffer 21
Free input buffer 21
Creating input buffer 24
Free input buffer 19
Creating input buffer 23
Free input buffer 22
Creating input buffer 26
Free input buffer 26
Creating input buffer 25
Free input buffer 24
Creating input buffer 28
Free input buffer 23
Creating input buffer 27
Free input buffer 27
Creating input buffer 30
Free input buffer 25
Creating input buffer 29
Free input buffer 28
Creating input buffer 32
Free input buffer 32
Creating input buffer 31
Free input buffer 30
Creating input buffer 34
Free input buffer 29
Creating input buffer 33
Free input buffer 33

Can you explain this behaviour please?

Regards,

Andriy Lysnevych

  • Hi Andrey,

    It looks like there is some issue with this configuration when Aspect ratio is changed dynamically. We are working on fix for this.

    Meanwhile can you please check making IDR frame interval to zero? It should work fine.

    Regards

    Rama

  • Hi Andrey,

    Attached below please find the installers for an updated H264HP encoder. This encoder has fixed the issue with dynamic aspect ratio change as well as the memory leakage issue. 

    4010.HPEncoder.zip

    Please let us know how it works.

    Thanks,

    Hongmei

  • Hi Hongmei,

    I tested new build. Issue is fixed not fully. From the following log you can see that buffers 1,4,12 were not released:

    Create buffer: 2
    Create buffer: 1
    Create buffer: 4
    Release buffer: 2
    New aspect ratio: 2
    Create buffer: 3
    Create buffer: 6
    Create buffer: 5
    Release buffer: 3
    Create buffer: 8
    Release buffer: 8
    Create buffer: 7
    Release buffer: 6
    New aspect ratio: 3
    Create buffer: 10
    Create buffer: 9
    Create buffer: 12
    Release buffer: 10
    Create buffer: 11
    Release buffer: 11
    Create buffer: 14
    Release buffer: 9
    New aspect ratio: 2
    Create buffer: 13
    Create buffer: 16
    Create buffer: 15
    Release buffer: 13
    Create buffer: 18
    Release buffer: 18
    Create buffer: 17
    Release buffer: 16
    New aspect ratio: 3
    Create buffer: 20
    Create buffer: 19
    Create buffer: 22
    Release buffer: 20
    Create buffer: 21
    Release buffer: 21
    Create buffer: 24
    Release buffer: 19
    New aspect ratio: 2
    Create buffer: 23
    Create buffer: 26
    Create buffer: 25
    Release buffer: 23
    Create buffer: 28
    Release buffer: 28
    Create buffer: 27
    Release buffer: 26
    New aspect ratio: 3
    Create buffer: 30
    Create buffer: 29
    Create buffer: 32
    Release buffer: 30
    Create buffer: 31
    Release buffer: 31
    Create buffer: 34
    Release buffer: 29
    

    I use the following configuration:

    gopStructure = 0

    IDRFrameInterval = 3

    intraFrameInterval = 6

    interFrameInterval = maxInterFrameInterval = 3

    profile = 77

    level = 40

    Regards,

    Andriy Lysnevych

  • Hi Andrey,

    We were able to reproduce the memory leakage issue, we will update you shortly on this.

    Regards

    Rama

  • Hi Andrey,

    Dynamic aspect ratio change involves Reset in codec, and new IDR is inserted with SPS and PPS information.

    Since 2 B frames are used in this particular configuration, 2 frames are locked by codec. So when aspect ratio is changed we need to encode these locked frames by calling XDM_FLUSH command followed by process call before setting new aspect ratio.

    We have verified this sequence of commands in sample test application it is working, please find relevant example code under "DYN_ASPECT_RATIO" macro in attached file.

    Regards

    Rama

  • Since attachment is having problems Please find below code snippet.

    #ifdef DYN_ASPECT_RATIO
    /* Dynamic parameters can be changed after first 3 frames as 2 */
    /* frames are locked without encoding */
    if(ar_count0 == 3)
    {
    lDynamicParams.videnc2DynamicParams.sampleAspectRatioWidth += 32;
    }
    /* Change dynamic parameters for every 5th frame */
    if((ar_count1%5) == 0)
    {
    lDynamicParams.videnc2DynamicParams.sampleAspectRatioWidth += 32;
    }

    H264HPVENC_TI_Swbarr(lParams.ividmc->coreID,IVIDMC_SWBARR14,
    lParams.ividmc->ncores);

    if(ar_count0 == 3)
    ar_count1 = 0;

    H264HPVENC_TI_Swbarr(lParams.ividmc->coreID,IVIDMC_SWBARR12,
    lParams.ividmc->ncores);

    if(((ar_count0 == 3) || (ar_count1%5) == 0) )
    {
    /*--------------------------------------------------------------------*/
    /* XDM FLUSH */
    /*--------------------------------------------------------------------*/
    H264HPVENC_control(handle,XDM_FLUSH,
    (H264HPVENC_DynamicParams *)&lDynamicParams,
    (H264HPVENC_Status *)&lstatus);

    multiCoreSync[SYNC_CASE_2] = 0;

    H264HPVENC_TI_Swbarr(lParams.ividmc->coreID,IVIDMC_SWBARR13,
    lParams.ividmc->ncores);

    do
    {
    outputBufDesc.numBufs = 1;
    outputBufDesc.descs[0].buf = (XDAS_Int8*)gOutputData;
    outputBufDesc.descs[0].bufSize.bytes =
    lstatus.videnc2Status.bufInfo.minOutBufSize[0].bytes;

    if(lParams.ividmc->core_task_ID == IVIDMC_TASK_MASTER)
    {
    linArgs.videnc2InArgs.inputID = 1;
    lInputBufDesc.planeDesc->buf[0] = 0;
    lInputBufDesc.planeDesc->buf[1] = 0;
    lInputBufDesc.planeDesc->buf[2] = 0;
    }
    #ifdef C6600
    Cache_wbInvAll();
    #endif
    /* Sync all the cores before encode */
    H264HPVENC_TI_Swbarr(lParams.ividmc->coreID,IVIDMC_SWBARR14,
    lParams.ividmc->ncores);

    #ifdef TIMER_ENABLE
    timer_start = _TSC_read();
    #endif

    retValue = H264HPVENC_encodeFrame(handle,&lInputBufDesc,
    &outputBufDesc,&linArgs,
    &loutArgs);

    /* Sync all the cores after encode */
    H264HPVENC_TI_Swbarr(lParams.ividmc->coreID,IVIDMC_SWBARR15,
    lParams.ividmc->ncores);

    #ifdef C6600
    Cache_wbInvAll();
    #endif
    if(lParams.ividmc->core_task_ID == IVIDMC_TASK_MASTER)
    {

    if(loutArgs.videnc2OutArgs.extendedError)
    {
    printf("\n Flushing of frames completed");
    multiCoreSync[SYNC_CASE_2] = 1;
    #ifndef _WIN32
    Cache_wbInv((void*)&multiCoreSync,
    sizeof(multiCoreSync),
    Cache_Type_L2D,1);
    #endif
    }
    else
    {
    if(fTrace_file != NULL)
    H264HPVENC_TI_Print_Log(fTrace_file,
    loutArgs.videnc2OutArgs.encodedFrameType,
    lInputBufDesc.contentType,
    loutArgs.videnc2OutArgs.bytesGenerated,
    numFramesEncoded);
    /*------------------------------------------------------------*/
    /* Always release buffers - which are released from the */
    /* algorithm side -back to the buffer manager. */
    /* The freebufID array of outargs contains the sequence */
    /* of bufferIds which need to be freed. This gets populated */
    /* by the algorithm. The following function will do the */
    /* job of freeing up the buffers. */
    /*------------------------------------------------------------*/
    BUFFMGR_ReleaseBuffer(
    (XDAS_UInt32 *)loutArgs.videnc2OutArgs.freeBufID);
    }


    /*------------------------------------------------------------*/
    /* Write the Output Bitstream to a file. */
    /*------------------------------------------------------------*/
    if((loutArgs.videnc2OutArgs.bytesGenerated ) &&
    (foutFile != NULL))
    {
    TestApp_WriteOutputData(outputBufDesc.descs[0].buf,
    (loutArgs.videnc2OutArgs.bytesGenerated),
    foutFile);
    }
    /*------------------------------------------------------------*/
    /* Compare the output frames with the Reference File. */
    /*------------------------------------------------------------*/
    if(compareRefDataFlag)
    {
    retValue = TestApp_CompareOutputData(frefFile,
    &outputBufDesc,
    loutArgs.videnc2OutArgs.bytesGenerated);
    if(retValue != IVIDENC2_EOK)
    {
    /* Test Compliance Failed... Breaking...*/
    fprintf(stdout, "\nFrame Compliance Test: FAIL. \n");
    multiCoreSync[SYNC_CASE_0] = 1;
    #ifndef _WIN32
    Cache_wbInv((void*)&multiCoreSync,
    sizeof(multiCoreSync),
    Cache_Type_L2D,1);
    #endif
    }
    fprintf(stdout,"\nFrame Compliance Test: PASS. \n");
    }
    /*------------------------------------------------------------*/
    /* Increment the FramesEncoded count. */
    /*------------------------------------------------------------*/
    numFramesEncoded++;
    }
    /*----------------------------------------------------------------*/
    /* All the cores should reach this point before proceeding to */
    /* filewrite or next frame encoding */
    /*----------------------------------------------------------------*/
    H264HPVENC_TI_Swbarr(lParams.ividmc->coreID,IVIDMC_SWBARR13,
    lParams.ividmc->ncores);
    #ifndef _WIN32
    Cache_inv((void*)&multiCoreSync, sizeof(multiCoreSync),
    Cache_Type_L2D,1);
    #endif
    if(multiCoreSync[SYNC_CASE_0] == 1)
    {
    goto DELETE_INSTANCE;
    }

    if(multiCoreSync[SYNC_CASE_2] == 1)
    {
    break;
    }

    }while(1); //End of do while loop for XDM_FLUSH

    }

    H264HPVENC_TI_Swbarr(lParams.ividmc->coreID,IVIDMC_SWBARR9,
    lParams.ividmc->ncores);

    ++ar_count0;
    ++ar_count1;

    #endif

  • Thanks Rama,

    This solution require additional coding. I will write back after implementing it. It is also good to find similar instructions in User's Guide.

    Regards,

    Andrey Lisnevich

  • Fine We will take care of this in user guide in next formal release.

    Regards

    Rama

  • Thanks Rama,

    XDM_FLUSH to release all the encoder input buffers before aspect ratio change works. No buffer leaking any more.

    Andrey