Sharing CFObjects/NSObjects between main application and helpers

Is this even possible?

I have an application that processes video using Apple’s API, and while I can achieve about 150~200 FPS (with HD video, it drops significantly for 4K), activity monitor shows it uses about 130~190% of my CPU, which leaves about 75% doing nothing. My guess is that it’s maxing out one or two cores, leaving the other 6 idling.

There’s several steps in processing a video.

  1. Reading each frame from the video (First time the HDD causes this to be the slowest part).
  2. Applying effects to each frame (I’m using Core Image for this, so it’s using mainly GPU processing, but does jump in and out of the main CPU for some of the processing that Core Image simply isn’t able to do).
  3. Writing the frames back out (sometimes end up waiting for the writer).

The most consuming part is processing the frames, and being GPU based I am not sure that I can speed that up significantly. So what I am hoping is that I can separate the three tasks.

  1. The reader, loads up frames and sticks them into a queue called “In”.
  2. The processor monitors the “In” queue and when there’s more than zero frames in the queue, it gets to work and then pushes the processed frames into a “Out” queue (and removes them from the “In” queue).
  3. The writer monitors the “Out” queue and you’ve guessed it, writes the frames to the movie file and removes them from the queue.

This way the processor spends no time reading or writing and therefore more time actually processing the frames.

What you can do is share memory between main app and helper app. You can guess which plugin does that. It’s called FileMappingMBS. Majorly cool. I had a helper app in mind to get data out of Mail with AppleScript. That itself worked fine but I could see that transporting the data and parsing the data took longer than the original situation without helper app. FileMappingMBS made this so much faster.

Thanks for the tip about sharing memory, I might not quite understand exactly what you mean.

I’m looking to share CMSampleBuffers and probably a unrendered CIImages, without rendering and storing to disk first.

Have a look at the example that comes with the plugin. My apps communicate via json data (code from Kem I think). This tells me when data has arrived and the amount of data. Then you put the data into a memoryblock. The code isn’t quite finished, yet:

[code]dim JsonResult as JSONItem = Response.Value(“params”)
if not JsonResult.IsArray then
'do error here
end if
dim theLength as string = JsonResult.Value(0)
dim theName as string = JsonResult.Value(1)

if s = nil then s = new FileMappingMBS

if s.OpenSharedMemory(theName) then
// ok

v = s.MapView(0, val(theLength))
if v = nil then
  MsgBox "Failed to map shared memory region."
end if

else
MsgBox “Failed to create shared memory region.”
end if

dim m as MemoryBlock = v.Memory
if not s.DeleteSharedMemory(theName) then Break
lastResult = DefineEncoding(m.CString(0), encodings.UTF8)
[/code]

I don’t think you can share objects, just data.

sounds like you better write this in Xcode as you need multiple preemptive threads in an app to really get things working faster.

CF/NS objects can’t be shared between processes.

Darn it!

I could implement CFMessagePort for my plugins ,but I fear it does not provide better support than the IPCSocket.

Thanks for the information, I’ve had a quick skim, but I’ll spend some time reading more indepth.

For the time being, I’ll continue to profile the process and see if I can optimize it some more. I was able to get a 20% improvement yesterday, but also then ran into problems later…