[vlc-commits] shm: use block_File() instead of custom mmap() code

Rémi Denis-Courmont git at videolan.org
Sat Nov 24 21:31:57 CET 2012


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Nov 24 22:30:45 2012 +0200| [e307581ddcff7ca6f8a83bb2ccf0a087014ffb8f] | committer: Rémi Denis-Courmont

shm: use block_File() instead of custom mmap() code

This should let the kernel do the copy-on-write, only if required.
VLC does not memory copy the frames anymore.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=e307581ddcff7ca6f8a83bb2ccf0a087014ffb8f
---

 modules/access/Modules.am |    4 --
 modules/access/shm.c      |  110 ++++++++++++++++++++++++---------------------
 2 files changed, 58 insertions(+), 56 deletions(-)

diff --git a/modules/access/Modules.am b/modules/access/Modules.am
index 01dc11e..3f0c337 100644
--- a/modules/access/Modules.am
+++ b/modules/access/Modules.am
@@ -122,11 +122,7 @@ endif
 libshm_plugin_la_SOURCES = shm.c
 libshm_plugin_la_CFLAGS = $(AM_CFLAGS)
 libshm_plugin_la_LIBADD = $(AM_LIBADD)
-if !HAVE_WIN32
-if !HAVE_OS2
 libvlc_LTLIBRARIES += libshm_plugin.la
-endif
-endif
 
 libv4l2_plugin_la_SOURCES = \
 	v4l2/videodev2.h \
diff --git a/modules/access/shm.c b/modules/access/shm.c
index 9de49a0..9de1603 100644
--- a/modules/access/shm.c
+++ b/modules/access/shm.c
@@ -30,7 +30,6 @@
 # include <sys/ipc.h>
 # include <sys/shm.h>
 #endif
-#include <sys/mman.h>
 
 #include <vlc_common.h>
 #include <vlc_demux.h>
@@ -107,20 +106,27 @@ vlc_module_begin ()
     add_shortcut ("shm")
 vlc_module_end ()
 
-static void Demux (void *);
 static int Control (demux_t *, int, va_list);
-static void map_detach (demux_sys_t *);
+static void DemuxFile (void *);
+static void CloseFile (demux_sys_t *);
 #ifdef HAVE_SYS_SHM_H
-static void sysv_detach (demux_sys_t *);
+static void DemuxIPC (void *);
+static void CloseIPC (demux_sys_t *);
 #endif
 static void no_detach (demux_sys_t *);
 
 struct demux_sys_t
 {
     /* Everything is read-only when timer is armed. */
-    const void  *addr;
-    size_t       length;
-    size_t       size;
+    union
+    {
+        int fd;
+        struct
+        {
+             const void  *addr;
+             size_t       length;
+        } mem;
+    };
     es_out_id_t *es;
     mtime_t      interval;
     vlc_timer_t  timer;
@@ -130,11 +136,6 @@ struct demux_sys_t
 static int Open (vlc_object_t *obj)
 {
     demux_t *demux = (demux_t *)obj;
-
-    long pagesize = sysconf (_SC_PAGE_SIZE);
-    if (pagesize == -1)
-        return VLC_EGENERIC;
-    
     demux_sys_t *sys = malloc (sizeof (*sys));
     if (unlikely(sys == NULL))
         return VLC_ENOMEM;
@@ -165,38 +166,28 @@ static int Open (vlc_object_t *obj)
             goto error;
     }
 
-    sys->length = width * height * (bpp >> 3);
-    if (sys->length == 0)
-        goto error;
-    pagesize--;
-    sys->size = (sys->length + pagesize) & ~pagesize; /* pad */
+    static void (*Demux) (void *);
 
     char *path = var_InheritString (demux, "shm-file");
     if (path != NULL)
     {
-        int fd = vlc_open (path, O_RDONLY);
-        if (fd == -1)
-        {
+        sys->fd = vlc_open (path, O_RDONLY);
+        if (sys->fd == -1)
             msg_Err (demux, "cannot open file %s: %m", path);
-            free (path);
+        free (path);
+        if (sys->fd == -1)
             goto error;
-        }
 
-        void *mem = mmap (NULL, sys->size, PROT_READ, MAP_SHARED, fd, 0);
-        close (fd);
-        if (mem == MAP_FAILED)
-        {
-            msg_Err (demux, "cannot map file %s: %m", path);
-            free (path);
-            goto error;
-        }
-        free (path);
-        sys->addr = mem;
-        sys->detach = map_detach;
+        sys->detach = CloseFile;
+        Demux = DemuxFile;
     }
     else
     {
 #ifdef HAVE_SYS_SHM_H
+        sys->mem.length = width * height * (bpp >> 3);
+        if (sys->mem.length == 0)
+            goto error;
+
         int id = var_InheritInteger (demux, "shm-id");
         if (id == IPC_PRIVATE)
             goto error;
@@ -207,8 +198,9 @@ static int Open (vlc_object_t *obj)
             msg_Err (demux, "cannot attach segment %d: %m", id);
             goto error;
         }
-        sys->addr = mem;
-        sys->detach = sysv_detach;
+        sys->mem.addr = mem;
+        sys->detach = CloseIPC;
+        Demux = DemuxIPC;
 #else
         goto error;
 #endif
@@ -265,19 +257,6 @@ static void Close (vlc_object_t *obj)
     free (sys);
 }
 
-
-static void map_detach (demux_sys_t *sys)
-{
-    munmap ((void *)sys->addr, sys->size);
-}
-
-#ifdef HAVE_SYS_SHM_H
-static void sysv_detach (demux_sys_t *sys)
-{
-    shmdt (sys->addr);
-}
-#endif
-
 static void no_detach (demux_sys_t *sys)
 {
     (void) sys;
@@ -342,23 +321,50 @@ static int Control (demux_t *demux, int query, va_list args)
     return VLC_EGENERIC;
 }
 
-
 /**
  * Processing callback
  */
-static void Demux (void *data)
+static void DemuxFile (void *data)
 {
     demux_t *demux = data;
     demux_sys_t *sys = demux->p_sys;
 
     /* Copy frame */
-    block_t *block = block_Alloc (sys->length);
+    block_t *block = block_File (sys->fd);
     if (block == NULL)
         return;
-    memcpy (block->p_buffer, sys->addr, sys->length);
     block->i_pts = block->i_dts = mdate ();
 
     /* Send block */
     es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts);
     es_out_Send (demux->out, sys->es, block);
 }
+
+static void CloseFile (demux_sys_t *sys)
+{
+    close (sys->fd);
+}
+
+#ifdef HAVE_SYS_SHM_H
+static void DemuxIPC (void *data)
+{
+    demux_t *demux = data;
+    demux_sys_t *sys = demux->p_sys;
+
+    /* Copy frame */
+    block_t *block = block_Alloc (sys->mem.length);
+    if (block == NULL)
+        return;
+    memcpy (block->p_buffer, sys->mem.addr, sys->mem.length);
+    block->i_pts = block->i_dts = mdate ();
+
+    /* Send block */
+    es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts);
+    es_out_Send (demux->out, sys->es, block);
+}
+
+static void CloseIPC (demux_sys_t *sys)
+{
+    shmdt (sys->mem.addr);
+}
+#endif



More information about the vlc-commits mailing list