Fixed Memory leak in display pipeline
authorChandramohan C <chandramohan.c@ti.com>
Fri, 6 Sep 2013 06:41:56 +0000 (06:41 +0000)
committerChandramohan <a0131763@ti.com>
Fri, 6 Sep 2013 07:46:57 +0000 (13:16 +0530)
Earlier, all output buffers were not being freed
in the display path. Due this, the system will run out
of buffers and app would eventually not get memory resulting
in crash.

This patch fixes this issue of memory leak.
It is also ensured that Buffers are unlocked before freeing.

Signed-off-by: Chandramohan C <chandramohan.c@ti.com>
util/display-kms.c
util/util.c
util/util.h
viddec3test.c

index 3af3195165c7a899b801ab6e578507abd26b97af..8fc38a1d6820f5160c973618727d563191feb76f 100644 (file)
@@ -20,6 +20,7 @@
 #endif
 
 #include "util.h"
+#include <libdce.h>
 
 #include <xf86drmMode.h>
 
@@ -184,6 +185,21 @@ fail:
        return NULL;
 }
 
+void
+free_buffers(struct display *disp, uint32_t n)
+{
+       uint32_t i;
+       for (i = 0; i < n; i++) {
+                if (disp->buf[i]) {
+                       omap_bo_del(disp->buf[i]->bo[0]);
+                       if(disp->multiplanar){
+                               omap_bo_del(disp->buf[i]->bo[1]);
+                       }
+                }
+        }
+free(disp->buf);
+}
+
 static struct buffer **
 alloc_buffers(struct display *disp, uint32_t n,
                uint32_t fourcc, uint32_t w, uint32_t h)
@@ -204,7 +220,7 @@ alloc_buffers(struct display *disp, uint32_t n,
                        goto fail;
                }
        }
-
+       disp->buf=bufs;
        return bufs;
 
 fail:
@@ -492,7 +508,7 @@ disp_kms_open(int argc, char **argv)
        disp->post_buffer = post_buffer;
        disp->post_vid_buffer = post_vid_buffer;
        disp->close = close_kms;
-
+       disp->disp_free_buf = free_buffers ;
        disp_kms->resources = drmModeGetResources(disp->fd);
        if (!disp_kms->resources) {
                ERROR("drmModeGetResources failed: %s", strerror(errno));
index 0c260f2f707c82a363b649a2324b15fb942e30fa..f9487c701c65236280e0db6aca24d38bcda6129a 100644 (file)
@@ -154,6 +154,12 @@ disp_get_vid_buffers(struct display *disp, uint32_t n,
        return buffers;
 }
 
+void
+disp_free_buffers(struct display *disp, uint32_t n)
+{
+        disp->disp_free_buf(disp, n);
+}
+
 struct buffer *
 disp_get_vid_buffer(struct display *disp)
 {
index 6ab000c44775dbe86636c7508a6d629b1f74ca23..6b2b357f3492a0650d6f717f26d3a448d8a3dea1 100644 (file)
@@ -57,7 +57,7 @@ struct buffer {
        uint32_t pitches[4];
        struct list unlocked;
        bool multiplanar;       /* True when Y and U/V are in separate buffers. */
-       int fd[4];              /* dmabuf */ 
+       int fd[4];              /* dmabuf */
 };
 
 /* State variables, used to maintain the playback rate. */
@@ -82,8 +82,10 @@ struct display {
        int (*post_vid_buffer)(struct display *disp, struct buffer *buf,
                        uint32_t x, uint32_t y, uint32_t w, uint32_t h);
        void (*close)(struct display *disp);
+       void (*disp_free_buf) (struct display *disp, uint32_t n);
 
        bool multiplanar;       /* True when Y and U/V are in separate buffers. */
+       struct buffer **buf;
 };
 
 /* Print display related help */
@@ -94,6 +96,8 @@ void disp_usage(void);
  */
 struct display * disp_open(int argc, char **argv);
 
+/* free allocated buffer */
+void disp_free_buffers(struct display *disp, uint32_t n);
 /* Close display */
 static inline void
 disp_close(struct display *disp)
index ac93ceeb5bf6cdf83c0862f0b4127cc6b4087cf8..630674218fac8193ee50fd29ce78eb140b1b986b 100644 (file)
@@ -79,6 +79,16 @@ usage(char *name)
 static void
 decoder_close(struct decoder *decoder)
 {
+       int i;
+       /* fix me: all the output buffers are not unlocked in process.So calling unlock
+        * for all the buffers */
+       for(i=0;i<decoder->num_outBuf;i++){
+               dce_buf_unlock(1,&decoder->disp->buf[i]->fd[0]);
+               if(decoder->disp->multiplanar)
+                       dce_buf_unlock(1,&decoder->disp->buf[i]->fd[1]);
+       }
+       /* free output buffers allocated by display */
+       disp_free_buffers(decoder->disp,decoder->num_outBuf);
 
        if (decoder->codec)          VIDDEC3_delete(decoder->codec);
        if (decoder->engine)         Engine_close(decoder->engine);
@@ -154,7 +164,7 @@ decoder_open(int argc, char **argv)
        decoder->padded_height = padded_height;
        MSG("%p: padded_width=%d, padded_height=%d, num_buffers=%d",
                        decoder, padded_width, padded_height, decoder->num_outBuf);
+
        if (!decoder->disp->multiplanar) {
                decoder->uv_offset = padded_width * padded_height;
                decoder->outBuf_fd = malloc(sizeof(int)*decoder->num_outBuf);
@@ -258,7 +268,7 @@ decoder_open(int argc, char **argv)
        decoder->outBufs->numBufs = 2;
        decoder->outBufs->descs[0].memType = XDM_MEMTYPE_RAW;
        decoder->outBufs->descs[1].memType = XDM_MEMTYPE_RAW;
-       
+
        decoder->inArgs = dce_alloc(sizeof(IVIDDEC3_InArgs));
        decoder->inArgs->size = sizeof(IVIDDEC3_InArgs);
 
@@ -316,10 +326,10 @@ decoder_process(struct decoder *decoder)
                                MSG("%p: rewound.", decoder);
                                continue;
                        }
-
-                       /* Not in loop or second try: end. */
                        inBufs->numBufs = 0;
                        inArgs->inputID = 0;
+                       inArgs->numBytes =0;
+
                }
                break;
        }
@@ -392,7 +402,7 @@ decoder_process(struct decoder *decoder)
        }
 
        if(freeBufCount){
-               dce_buf_unlock(freeBufCount,decoder->outBuf_fd);        
+               dce_buf_unlock(freeBufCount,decoder->outBuf_fd);
                freeBufCount =0;
        }
        if (outArgs->outBufsInUseFlag) {