How to use composite objects using spmd

10 views (last 30 days)
I am trying to implement video-on-demand using the spmd parallel computing function. I have a saved video encoded at 3 different qualities and segmented into 3second segments, and I am trying to save video frames to the video buffer (modelled as a structure) while simultaneously playing from the buffer at a constant rate of 24 frames per second. The quality of each segment must be selected based on the buffer level. However, I am getting the error "Error detected on worker 1. Subscripted assignment between dissimilar structures" from running the following code:
mov = struct; % video buffer
bufsize = length(mov); %buffer level
spmd
switch labindex
case 1
segnum = 0; %segment number
i=1;
c=1;
br = 20; %assumed channel bandwidth in Mbps
%Check last segment number and get segment names from file
res = ["low" "mid" "sample"]; %available resolutions
resnum = 1;
filename = sprintf('%sdash.m3u8',res(resnum));
s = importdata(filename);
lastseg = s{end-1,1};
[lastsegnum,n,err] = sscanf(lastseg,(res(resnum)+'dash%d.ts'));
%Get frame size for highest quality
vidobj = VideoReader("sampledash1.ts");
v = read(vidobj,1);
framesize = size(v);
%Get next segment with appropriate quality
while segnum<=lastsegnum
if bufsize<72 %24fps*3sec = 72 frames in one segment
resnum = 1;
elseif bufsize>=72 && br<216
resnum = 2;
elseif bufsize>=216
resnum = 3;
end
segment = sprintf('%sdash%d.ts',res(resnum),segnum);
vidobj = VideoReader(segment);
f = dir(segment);
fsz = f.bytes; %size of segment
x = rand;
delay = ((fsz*8)/(br*1e6)) + x; %network delay
pause(delay);
while hasFrame(vidobj)
mov(c) = im2frame(readFrame(vidobj));
mov(c).cdata = imresize(mov(c).cdata,[framesize(1) framesize(2)]);
labSend(mov(c).cdata,labindex+1,11);
bufsize = bufsize+1;
c = c+1;
end
labSend(segnum,labindex+1,12);
segnum=segnum+1;
end
case 2
depvid = vision.DeployableVideoPlayer('Size','Full-screen');
i=1;
while ~isempty(mov) %start playing the video only after the first two segments have been downloaded
frame = labReceive(labindex-1,11);
segnum = labReceive(labindex-1,12);
vid(i).cdata = frame;
i=i+1;
if segnum>1
step(depvid,vid(1).cdata)
pause(1/24)
vid(1) = [];
i = i-1;
end
end
end
end
I am a bit confused about why I am getting this error. I think it may be due to the Composite objects created by the function, but I'm not sure how.

Accepted Answer

Raymond Norris
Raymond Norris on 17 Oct 2022
It's not related to your parallel code, the issue is the initialization of mov. This can be reproduced by the following
function nagi
mov = struct();
%mov.cdata = [];
%mov.colormap = [];
M.cdata = ones(240,320,3,'uint8');
M.colormap = [];
mov(1) = M;
So it's getting tripped up here
mov(c) = im2frame(readFrame(vidobj));
If you initialize mov as I've commented it out, you'll be fine.
Side note: I'm assuming at some point, labindex 1 won't have anything else to send labindex 2, correct? If so, you're going to run into the issue that labindex 2 is continuing to wait to receive from labindex 1. Keep in mind, for labindex 2, mov is never empty. For all intents and purposes, it only sees
mov = struct;
(Or however you end up initializing it). Therefore, at somepoint, MATLAB will throw
A communication mismatch error was encountered:
The other lab became idle during labReceive.
"The other lab" in this case is labindex 1.
  3 Comments
Hala Nagi
Hala Nagi on 18 Oct 2022
That worked! Thank you so so much!!

Sign in to comment.

More Answers (0)

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!

Translated by