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 encoder 1.10.00.08 cmem buffer leak

Hi,

 

My encode application creates & destroys H.264 encoder many times during one run. I have noticed that each time  I call Venc1_delete one CMEM buffer (pool size 4096) is left busy. Eventually my application will abort on Venc1_create because all buffers from this pool are left busy. I have run my application with CE_DEBUG=1 and it prints this message inside Venc1_delete:

@172,823,819us: [+7 T:0x409329b0] OM - Memory_contigFree> Error: buffer (addr=1096044544, size=50) not found in translation cache

Does anyone know how to fix this? I'm running DM368 based board and I use DVSDK 3.10.

Thanks,

Semek

 

  • Semek,

    The Memory_contigFree() error happens when you pass parameters to it that are different than those used for the Memory_contigAlloc().  I realize that you're not calling it directly and are instead seeing this as a result of calling Venc1_delete(), but since I don't know the details inside Venc1_delete() I can't really comment on the "why".

    When you see this error, that means that the buffer was not found in the translation cache of the Memory module and that the CMEM buffer did not get freed, hence you see your memory leak accumulate to the point that you can't allocate from CMEM any more.

    In order to determine further what's going on, you should track the Memory_contigAlloc() calls, looking for the address 0x41545000 (hex of 1096044544) being returned and noting the size that is requested for that allocation.  If it's different than the size used in the Memory_contigFree() that errors, there's the problem and you need to track why it's different.  You will probably need CE_DEBUG=3 (or maybe 2, which is a little quieter than 3) to see the Memory_contigAlloc() calls.

    It's possible that the base pointer to the Memory_contigFree() is wrong (i.e., not an address returned by Memory_contigAlloc()) instead of the size being wrong (and it will be one or the other or both that are wrong), in which case you won't ever see the address printed in the error being returned from an allocation.  It will be a little harder to track that case.

    Regards,

    - Rob

     

  •  

    Rob,

     

    Thanks for info. You are right about different buffer size. I found place where this buffer is allocated and it's size is 146:

    @0,421,524us: [+0 T:0x409329b0 S:0xbe87e324] OM - Memory_alloc> Enter(0x92)
    @0,421,684us: [+0 T:0x409329b0 S:0xbe87e2dc] OM - Memory_contigAlloc> Enter(size=146, align=4, cached=FALSE, heap=FALSE)
    @0,421,966us: [+4 T:0x409329b0 S:0xbe87e2dc] OM - Memory_contigAlloc> CMEM_alloc(146) = 0x41553000.
    @0,422,182us: [+4 T:0x409329b0 S:0xbe87e2dc] OM - Memory_contigAlloc> CMEM_getPhys(0x41553000) = 0x8fffb000.
    @0,422,359us: [+1 T:0x409329b0 S:0xbe87e294] OM - Memory__addContigBuf> Enter(virtAddr=0x41553000, size=146, physAddr=0x8fffb000)
    @0,422,531us: [+1 T:0x409329b0 S:0xbe87e294] OM - Memory__addContigBuf> creating new contigBuf object
    @0,422,686us: [+0 T:0x409329b0 S:0xbe87e27c] OM - Memory_alloc> Enter(0x10)
    @0,422,849us: [+0 T:0x409329b0 S:0xbe87e27c] OM - Memory_alloc> return (0x1a220)
    @0,423,002us: [+1 T:0x409329b0 S:0xbe87e294] OM - Memory__addContigBuf> returning: cb->phys=0x8fffb000, cb->size=146, cb->virt=0x41553000
    @0,423,169us: [+0 T:0x409329b0 S:0xbe87e2dc] OM - Memory_contigAlloc> return (0x41553000)
    @0,423,324us: [+0 T:0x409329b0 S:0xbe87e324] OM - Memory_alloc> return (0x41553000)

    and when I call Venc1_delete it tries to free it but buffer size is 50:

    @9,946,862us: [+0 T:0x409329b0 S:0xbe87e9d4] OM - Memory_free> Enter(0x41553000, 0x32)
    @9,947,024us: [+0 T:0x409329b0 S:0xbe87e99c] OM - Memory_contigFree> Enter(addr=1096101888, size=50)
    @9,947,188us: [+1 T:0x409329b0 S:0xbe87e974] OM - Memory__removeContigBuf> Enter(virtAddr=0x41553000, size=50)
    @9,947,353us: [+1 T:0x409329b0 S:0xbe87e974] OM - Memory__removeContigBuf> ERROR: Failed to find matching cb.
    @9,947,510us: [+7 T:0x409329b0 S:0xbe87e99c] OM - Memory_contigFree> Error: buffer (addr=1096101888, size=50) not found in translation cache
    @9,947,671us: [+0 T:0x409329b0 S:0xbe87e99c] OM - Memory_contigFree> return (0x0)
    @9,947,827us: [+0 T:0x409329b0 S:0xbe87e9d4] OM - Memory_free> return (0x0)

    I must note that this leak is not related to my code. I see the same thing when I run video_encode_io1 example from DVSDK. Also when I use MPEG-4 encoder I don't see this leak. That's why I suspect this leak is inside H.264 encoder.

    My priority is to fix it and it could be ugly fix. Can I free this buffer myself somehow? I tried to patch Memory_contigFree function in codec_engine (change size from 50 to 146) and recompiled DVSDK but it didn't work.

    Semek

     

  • Semek,

    Semek said:

    My priority is to fix it and it could be ugly fix. Can I free this buffer myself somehow? I tried to patch Memory_contigFree function in codec_engine (change size from 50 to 146) and recompiled DVSDK but it didn't work.

    You want an ugly fix?  You've come to the right place :)

    I don't know why your hack didn't work.  I assume you're doing something like:
        if (size == 50)
            size = 146;
    at the beginning of Memory_contigFree(), which I would expect to work, but perhaps you have other mismatched sizes that are also failing.  Perhaps you're not actually linking in your hacked code, and instead are getting the normal Memory_contigFree() from somewhere else?  Might try to look if that's the case.

    Another hack...in Memory_cmem.c, funciton removeContigBuf, there's this clause:
            if (cb->virtualAddress == virtualAddress &&
                cb->sizeInBytes    == sizeInBytes) {
    You could just remove the sizeInBytes compare:
            if (cb->virtualAddress == virtualAddress) {
    and the function would proceed using the correct value saved during the allocation.  This function would then return success to Memory_contigFree(), which will then proceed to call CMEM_free(), which doesn't need any size parameter so the incorrect size would not be a problem.

    As I'm sure you know, hacking Codec Engine is a dangerous path on which to embark, and that you should never deliver hacked 3rd party code to a customer, but you're free to do as you see fit for the current situation.

    Is there some codec forum, or a DVSDK forum on which you could post this thread?

    Regards,

    - Rob

  • Robert Tivy said:


    I don't know why your hack didn't work.  I assume you're doing something like:

        if (size == 50)
            size = 146;
    at the beginning of Memory_contigFree(), which I would expect to work, but perhaps you have other mismatched sizes that are also failing.  Perhaps you're not actually linking in your hacked code, and instead are getting the normal Memory_contigFree() from somewhere else?  Might try to look if that's the case.



    I found that my hack didn't work because Codec Engine is not recompiling when I recompile DVSDK. It turns out it's not so easy to recompile Codec Engine.


    Robert Tivy said:


    Is there some codec forum, or a DVSDK forum on which you could post this thread?



    I posted it on Multimedia Software Codecs forum but it was moved here.


    Semek

  • Hello,

    Can you try changing this line in Buffer_create():

            hBuf->physPtr = Memory_getBufferPhysicalAddress(hBuf->userPtr,
                                                            4, NULL);

    to read:

            hBuf->physPtr = Memory_getBufferPhysicalAddress(hBuf->userPtr,
                                                            size, NULL);

    and recompiling DMAI?

    Regards, Niclas

  • Niclas,

    Thanks for your idea. I have already workaround for this problem. I free leaked CMEM buffer myself after closing encoder. The only problem was obtaining buffer address. I found that  this buffer is allocated and freed by Framework Components package but I don't know how to recompile it.

    Semek

     

  • Semek said:
    The only problem was obtaining buffer address. I found that  this buffer is allocated and freed by Framework Components package but I don't know how to recompile it.

    Semek,

    Can you expand on your statement about the buffer being alloc'ed/freed by Framework Components?  My group also handles FC  (but not me personally), and if there is a problem somewhere, we'd like to investigate.

    Regards,

    - Rob