% encodes a movie to an MPEG stream
% it creates a file named [stream_to_encode '_enc'] 
stream_to_encode = 'foreman';

load(stream_to_encode);
load('Q.mat');                      % Contains Q matrices for I and P/B blocks
%% Parameters
GOP_structure = 'IBBBP';        % Group of pictures sequence
B_size = 8;                         % Block size ( DCT and quantizer )
MB_size = 16;                       % Macro-block size ( Motion prediction )
Wq = 1;                             % Quantizer scale
search_width = 8;                   % Width of search area in pixels ( search area: MB_size + 2*search_width square )

%% Encoder
Qi = Wq * interp_Q(Qi,B_size);
Qp = Wq * interp_Q(Qp,B_size);
Qb = Qp;

GOP_length = length(GOP_structure);
order = get_enc_order( GOP_structure );
encode_order =  GOP_structure( order );

encoded_stream = struct('frame_data',0,'frame_type',0,'motion_vector_x',0,'motion_vector_y',0);
ref_past = [];
ref_future = [];

wb = waitbar(0,'Encoding frames');
for n = 1 : length(frames)
    waitbar(n/length(frames),wb);
    m = mod(n-1,GOP_length)+1;
    frame_num_to_encode =  floor((n-1)/GOP_length)*GOP_length+order(m);
    if (frame_num_to_encode > length(frames))
        encode_order(m) = 'I';
        frame_num_to_encode = n;
    end
    frame_in = crop_pic( frames(frame_num_to_encode).cdata , MB_size );
    
    switch encode_order(m)
        case 'I'
            % This part has to be completed
            encoded_stream = add_frame(encoded_stream, frame_encoded, 'I', [], [], n);
        case 'P'
            % This part has to be completed
            encoded_stream = add_frame(encoded_stream, frame_encoded, 'P', u, v, n);
        case 'B'
            % This part has to be completed
            encoded_stream = add_frame(encoded_stream, frame_encoded, 'B', [u_p;u_f], [v_p;v_f], n);
    end
    
end
close(wb);

save([stream_to_encode '_enc'], 'encoded_stream', 'GOP_structure', 'MB_size', 'B_size', 'Wq')
%get_statistics(frames, encoded_stream)

%% Decoding
MPEG_decode([stream_to_encode '_enc'])

%% Comparing
MPEG_playback_w_compare(stream_to_encode, [stream_to_encode '_enc_dec'])

