4

Recently I am building the software for a DVR.

It will be installed on a x86 pc server with 2 or more PCIE x4 video encoder card plugged in.

We have 2 seperated proces, one has to get encoded video data from these encoder card, the other has to save these data to hard driver. Why we have 2 process? Some histroy problem.

So, what kind of IPC should we use? Socket, Pipe, or shared memory?

Currently we are using socket.

lilyonwind
  • 159
  • 1
  • 5
  • 2
    I'd vote for shared memory, since it has least overhead. You will have to implement some kind of circular buffer (boost has one I think). – Eugene Aug 29 '09 at 03:39

2 Answers2

11

With pipes on linux, you could use the splice functionality to get zero-copy moves of the data from one process to the other. For example, the sending process uses vmsplice() with SPICE_F_GIFT to gift the data into a pipe, then the receiving processes uses splice() with SPLICE_F_MOVE to move the data straight from the pipe into the disk file without touching it. Note that there are naturally some alignment and length restrictions around this.

Depending on how the driver for your encoder card works, potentially you could arrange things to get zero-copy all the way from the driver to the disk - the encoder card DMAs into memory and the disk DMAs it back out, without the CPU ever needing to look at it (in this case you would splice() the data from the encoder card into the pipe, then splice() it back out of the pipe to the disk file).

caf
  • 233,326
  • 40
  • 323
  • 462
  • I didn't consider DMA because I know the driver do not support that. – lilyonwind Sep 02 '09 at 09:30
  • Nonetheless, the disk almost certainly does, so it'd still be a win. The less copying the better. – caf Sep 02 '09 at 10:41
  • @caf: I do not understand how zero-copy moves can be implemented with `vmsplice`. I asked this particular question on stackoverflow, but didn't get any useful answers up to now: http://stackoverflow.com/q/10639559/1305501 – nosid May 19 '12 at 14:22
  • @nosid: In the context of this particular question, the recieving process will be writing the copied data to a disk file. So my suggestion here is that the sending process uses `vmsplice(SPLICE_F_GIFT)` to splice the data into a pipe, and the recieving process use `splice(SPLICE_F_MOVE)` to move the gifted pages straight to the disk file. You are right that if you wanted the data in the address space of the receiving process that a copy is currently involved (it's still better than the plain `read()`/`write()` pipe case, because it's one-copy rather than two-copy). – caf May 20 '12 at 00:35
-1

Use IPC:

  • One shared memory region: A low overhead shared buffer between the two processes (see shmat()).
  • One semaphore: Its counter would be the numbers of frames available (see semop()). The process that pumps video data from the camera would put a frame in the shared memory region, and put() on the semaphore. The process that record the frames to the disk would get() on the semaphore, and a frame would be in the shared memory.

It's a bit like implementing a queue with a semphore as a counter.

Nicolas Viennot
  • 3,921
  • 1
  • 21
  • 22