function [Rec_Frames] = parallel_cs(Frames, A, scheme)
% parallel_cs.m
%   Encode and decode a group of frames (2 frames) using proposed compressed 
%   video sensing scheme
% 
% Requirement: 
%   ParallelCS, CVX toolbox
%   ZIGZAG_PERM, ZIGZAG_SCAN
% 
% Input:
%   Frames: orignal frames, with the first one being the reference frame
%   and the second one being the non-reference frame
%   A: measurement matrix
%   scheme: permutation scheme to be employed
%       - '0': apply no permutation scheme
%       - '1': apply zigzag-scan-based permutation to the reference frame
%
% Output:
%   Rec_Frames: reconstructed frames, with the first one being the reference frame
%   and the second one being the non-reference frame
%
% Written: Hao Fang
% Created: Mar. 2012
% Modified: Apr. 2013

% construct the measurement matrix for reference frames and non-reference
% frames, the ratio of measurements is 4:1
K = size(A, 1);
msr_ratio = 0.8;
Ref_K = ceil(K*msr_ratio);
A1 = A(1:Ref_K, :);
A2 = A(Ref_K+1:K, :);

% encode the reference frame
Ref_Frame = double(Frames{1});
DCT_Ref_Frame = dct2(Ref_Frame);
x1 = DCT_Ref_Frame;
if scheme == 0
    y1 = parallel_cs_encoder(x1, A1);
else
    y1 = parallel_cs_encoder(x1, A1, @perm_zigzag);
end

% encode the non-reference frame
Non_Ref_Frame = double(Frames{2});
Diff_Frame = (Non_Ref_Frame - Ref_Frame);
x2 = Diff_Frame;
y2 = parallel_cs_encoder(x2, A2);

% reconstruct reference frame
if scheme == 0
    rec_x1 = parallel_cs_decoder(y1, A1);
else
    rec_x1 = parallel_cs_decoder(y1, A1, @invperm_zigzag);
end
Rec_DCT_Ref_Frame = rec_x1;
Rec_Ref_Frame = idct2(Rec_DCT_Ref_Frame);
Rec_Frames{1} = Rec_Ref_Frame;

% reconstruct non-reference frame
rec_x2 = parallel_cs_decoder(y2, A2);
Rec_Diff_Frame = rec_x2;
Rec_Non_Ref_Frame = Rec_Diff_Frame + Rec_Ref_Frame;
Rec_Frames{2} = Rec_Non_Ref_Frame;
end