Writing video in a parfor fails
14 views (last 30 days)
I try to add a circle to each frame of a video. I do this in a PARFOR loop. The only problem is, that the loop fails if I do not call open(VidWriter) inside the loop. With my fairly limited knowledge of PARFOR, I suspect, that the VidWriter is separately initialized for each worker, which then causes the loop to fail, since only one of the workers has an initialized copy of the VidWriter. Is this correct, or is there some other problem. If it is correct, is there a better solution than calling OPEN in every loop iteration? Grateful about any suggestions!
Below a minimal working example (at least on Linux). close all; clear all;
Pool = gcp();
VideoObj = VideoReader('xylophone.mp4');
nFrames = VideoObj.NumberOfFrames;
%Init writer & shape inserter
VideoWriterObj = VideoWriter('xylophone_overlay.mp4','Motion JPEG AVI');
VideoWriterObj.FrameRate = VideoObj.FrameRate;
ShapeInserterObj = vision.ShapeInserter('Shape','Circles');
parfor i = 1:nFrames-1
FrameFull = read(VideoObj, i);
%Insert circle with some random jitter for demo purposes.
FrameFull = step(ShapeInserterObj,FrameFull,...
uint32([50*(1+rand()) 50*(1+rand()) 10]));
%If this OPEN call is no there, PARFOR will fail.
Edric Ellis on 23 Mar 2015
Firstly, when the VideoWriter object is passed to the workers, each worker gets a separate copy of that object (as if it has been saved to disk and then loaded again). I suspect that's why each worker needs to call the open method to ensure the object is ready for writing. In any case, I'm not sure this is really what you want - in your code as written, each worker is writing to the same output file at the same time, this is not likely to succeed terribly well - even if it worked, you'd be relying on the order of execution, which is not sequential for a PARFOR loop.
I'm not sure what your best option is here - it rather depends on how large the data is compared to how long it takes to process. You might need to save intermediate results somewhere, or else return the frames from the loop.
More Answers (1)
Dima Lisin on 23 Mar 2015
If you call open(...) once before the loop, then you would be trying to have multiple MATLAB workers write frames into the same video file, which is a bad idea.
If you open the video file in every loop iteration, then you also have a problem: the frames may be written out of order.
In summary, parallelizing at the level of video frames is not a good idea in this case. Do you have to process multiple videos? You would be better off having each worker process a different video file.