%   tsevideo computes the TSE between two YUV-Files.
%
%	tsevideo('Filename1','Filename1', width, height, format,parameter) reads
%	the specified files using width and height for resolution and format 
%   for YUV-subsampling. With parameter you can chose if you want to
%   compute the TSE between the y, the u, the v, or the yuv part of the
%   videos
%	
%	Filename1 --> Name of File one (e.g. 'Test1.yuv')
%   Filename2 --> Name of File two (e.g. 'Test2.yuv')
%   width    --> width of a frame  (e.g. 352)
%   height   --> height of a frame (e.g. 280)
%   format   --> subsampling rate ('400','411','420','422' or '444')
%   parameter -->chose the components of the video which are used to compute 
%                 the psnr ('y', 'u', 'v', 'yuv') 
%
%   example: tse = tsevideo('Test1.yuv','Test2.yuv',352,288,'420','y');

function tse = tsevideo(orig_videofn, deg_videofn, width,height,format,parameter)

% Adjust width and height according to YUV sampling format 
    fwidth = 0.5;
    fheight= 0.5;
    if strcmp(format,'400')
        fwidth = 0;
        fheight= 0;
    elseif strcmp(format,'411')
        fwidth = 0.25;
        fheight= 1;
    elseif strcmp(format,'420')
        fwidth = 0.5;
        fheight= 0.5;
    elseif strcmp(format,'422')
        fwidth = 0.5;
        fheight= 1;
    elseif strcmp(format,'444')
        fwidth = 1;
        fheight= 1;
    else
        display('Error: wrong format');
    end
%%%%%%%%

% Estimate the Filesize and the Framenumber
    filep = dir(orig_videofn); 
    fileBytes = filep.bytes; %Filesize of orig_videofn
    clear filep
    framenumber1 = fileBytes/(width*height*(1+2*fheight*fwidth)); %Framenumber of orig_videofn
    
    filep = dir(deg_videofn); 
    fileBytes = filep.bytes; %Filesize of deg_videofn
    clear filep
    framenumber2 = fileBytes/(width*height*(1+2*fheight*fwidth)); %Framenumber of deg_videofn
%%%%%%%%%%

    if mod(framenumber1,1) ~= 0 | mod(framenumber2,1) ~= 0 | framenumber1~=framenumber2
        display('Error: wrong resolution, format, filesize or different video lengths');
    else

% open original and degraded video
fid_o = fopen(orig_videofn,'r');
fid_d = fopen(deg_videofn,'r');
if ((fid_o == -1)||(fid_d == -1)),
   error('Could not open video file.');
end

% calculate length of files
l=length(orig_videofn);
ld=length(deg_videofn);

% initialize variables
lastframe=framenumber1;
total_error = 0;
for i=1:lastframe,
%     disp(['Processing Frame# ' num2str(i)])
    J_o = fread(fid_o,len,'uint8')'; % read frame i
    J_d = fread(fid_d,len,'uint8')'; % read frame i

    if (i>=frame)
%         disp(['Processing Frame# ' num2str(i)])
        % read frame i from original video
        Y_o = J_o(2:2:length(J_o)); % Read Y component
        C_o =  J_o(1:2:length(J_o)); % Read UV component
        
        % read frame i from degraded video
        Y_d = J_d(2:2:length(J_d)); % upsample matrix to create a Y matrix
        C_d =  J_d(1:2:length(J_d)); % upsample matrix to create a Y matrix
        
        TSE_Y = sum(sum((Y_d-Y_o).^2));
        TSE_C = sum(sum((C_d-C_o).^2));
        total_error = total_error + TSE_Y + TSE_C; 
    end;  
end;
tse = total_error/nframes;
fclose(fid_o);
fclose(fid_d);
% disp(['Finished'])
    end

