Writing video in a parfor fails

6 views (last 30 days)
David J. Mack
David J. Mack on 23 Mar 2015
Commented: Dima Lisin on 23 Mar 2015
Dear all,
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();
%Load video.
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');
open(VideoWriterObj);
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.
% open(VideoWriterObj);
writeVideo(VideoWriterObj,FrameFull);
end
close(VideoWriterObj);
delete(Pool);

Accepted Answer

Edric Ellis
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
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.
  2 Comments
David J. Mack
David J. Mack on 23 Mar 2015
That's what I feared. So I will proceed in serial. Thanks, for the answer!
Dima Lisin
Dima Lisin on 23 Mar 2015
You can try splitting up the problem differently:
  1. Use a serial loop to read n frames into memory, where n is reasonably large
  2. Use a parfor to insert the circles into the frames
  3. Use another serial loop to write the frames out into a video file
  4. Repeat until end of the input video file

Sign in to comment.

Categories

Find more on Startup and Shutdown in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!