On 5 Jul 2016, at 13:36, Jonathan Taylor <jonathan.tay...@glasgow.ac.uk> wrote:
> 
> This is a long shot, but I thought I would ask in case an API exists to do 
> what I want. One of the roles of my code is to record video to disk as it is 
> received from a camera. A magnetic hard disk can normally keep up with this, 
> but if the user is also doing other things on the computer (e.g. long file 
> copy in the Finder) then we are unable to keep up, and accumulate an 
> ever-increasing backlog of frames waiting to be saved. This eventually leads 
> to running out of memory, thrashing, and an unresponsive computer. Dropping 
> frames is not an option. In this case, the computer is a dedicated 
> workstation running my code, so it *is* correct for me to consider my code to 
> be the number 1 priority on the computer.

Let’s start this again, because I think the fundamental problem here is that 
you’re going about this the wrong way.  Whether you use Cocoa or not is, I 
think, largely an irrelevance (I *wouldn’t* for this kind of task, but I see no 
fundamental reason why performance should be a problem just because you choose 
to e.g. use NSMutableData to manage your buffer space, *provided* you do it 
right).

The first thing to state is that you *can’t* write code of this type with the 
attitude that “dropping frames is not an option”.  Fundamentally, the problem 
you have is that if you generate video data faster than it can be saved to 
disk, there is only so much video data you can buffer up before you start 
swapping, and if you swap you will be dead in the water --- it will kill 
performance to the extent that you will not be able to save data as quickly as 
you could before and the result will be catastrophic, with far more frames 
dropped than if you simply accepted that there was the possibility the machine 
you were on was not fast enough and would have to occasionally drop a frame.

The right way to approach this type of real time encoding problem is as follows:

1. Use statically allocated buffers (or dynamically allocated once at encoder 
or program startup).  DO NOT dynamically allocate buffers as you generate data.

2. Knowing the rate at which you generate video data, decide on the maximum 
write latency you need to be able to tolerate.  This (plus a bit as you need 
some free to encode into) will tell you the total size of buffer(s) you need.

3. *Either*

   (i)  Allocate a ring buffer of the size required, then interleave encoding 
and issuing I/O requests.  You should keep track of where the as-yet-unwritten 
data starts in your buffer, so you know when your encoder is about to hit that 
point.  Or

   (ii) Allocate a ring *of* fixed size buffers totalling the size required; 
start encoding into the first one, then when finished, issue an I/O request for 
that buffer and continue encoding into the next one.  You should keep track of 
which buffers are in use, so you can detect when you run out.

4. When issuing I/O requests, DO NOT use blocking I/O from the encoder thread.  
You want to be able to continue to fetch video from your camera and generate 
data *while* I/O takes place.  GCD is a good option here, or you could use a 
separate I/O thread with a semaphore, or any other asynchronous I/O mechanism 
(e.g. POSIX air, libuv and so on).

5. If you find yourself running out of buffers, drop frames until buffer space 
is available, and display the number of frame drops to the user.  This is 
*much* better than attempting to use dynamic buffers and then ending up 
swapping, which is I think what’s happening to you (having read your later 
e-mails).

Without knowing exactly how much video data you’re generating and what encoder 
you’re using (if any), it’s difficult to be any more specific, but hopefully 
this gives you some useful pointers.

Kind regards,

Alastair.

--
http://alastairs-place.net


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to