function varargout = nrvqt(varargin)
% NRVQT M-file for nrvqt.fig
%      NRVQT, by itself, creates a new NRVQT or raises the existing
%      singleton*.
%
%      H = NRVQT returns the handle to a new NRVQT or the handle to
%      the existing singleton*.
% 
%      NRVQT('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in NRVQT.M with the given input arguments.
%
%      NRVQT('Property','Value',...) creates a new NRVQT or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before nrvqt_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to nrvqt_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help nrvqt

% Last Modified by GUIDE v2.5 16-May-2013 18:01:01

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @nrvqt_OpeningFcn, ...
                   'gui_OutputFcn',  @nrvqt_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before nrvqt is made visible.
function nrvqt_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to nrvqt (see VARARGIN)

% Choose default command line output for nrvqt
handles.output = hObject;
handles.metricBut=[handles.GBIMbut handles.MarzilianoBut]; % definition of vector of handles for metric buttons

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes nrvqt wait for user response (see UIRESUME)
% uiwait(handles.mainWindow);


% --- Outputs from this function are returned to the command line.
function varargout = nrvqt_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;

%% --- Open button callback ---
function openbut_Callback(hObject, eventdata, handles)
% hObject    handle to openbut (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[file,path]=uigetfile({'*.mpg;*.avi;*.mp4;*.264;*.h264', 'Video file (*.mpg, *.avi, *.mp4, *.264, *.h264)'},...
                        'Open video file'); % definition of opening file, 
if isequal(file,0) || isequal(path,0) % if file is not selected
    return;  %return
else set(handles.FileNameEdit, 'string', [path file]) % set chosen file
     set(handles.Infobut, 'Enable', 'On'); % and enable Get Info button
end

set([handles.metricBut, handles.readBut handles.h264but handles.psnrbut handles.temppoolbut], 'enable', 'off');
set(handles.AllFramesRadioBut, 'value', 1);
set([handles.FramesEdit handles.ResultsStatic, handles.OverallScoreStatic], 'string', '');



%% --- Get file information ---
function Infobut_Callback(hObject, eventdata, handles)
% hObject    handle to Infobut (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
ffstring=sprintf('ffmpeg\\ffprobe -i "%s" -show_streams -count_frames',...
         get(handles.FileNameEdit, 'string'));  % definition of ffprobe command
[status, result]=system(ffstring); % run ffprobe command
if status==0    % if command is successful
   [W, H, nFrames, h264Flag]=resfind(result); % get video info from command results
   if h264Flag==1
   params=sprintf('Frames:     %d\nWidth:        %d\nHeight:       %d\nH.264 coding detected, PSNR estimation available.'...
       , nFrames, W, H);
   set(handles.h264but,'Enable', 'on');% formating video params
   else
   params=sprintf('Frames:     %d\nWidth:        %d\nHeight:       %d', nFrames, W, H); % formating video params
   set(handles.h264but,'Enable', 'off');
   end
   set(handles.FileParamList, 'String', params); % set video params in File Paramters Static Text
   set(handles.readBut,'Enable', 'on') %enables button for Reading data from video file
   handles.nFrames=nFrames; %saving number of frames in handles struct.
   handles.width=W; %saving width in handles struct.
   handles.height=H; %saving height in handles struct.
   clear W H nFrames status result ffstring % deleting variables
   
else
    set(handles.FileParamList, 'String', 'Not valid Video file or codec not supported/ not available.')
    set([handles.metricBut, handles.readBut], 'Enable', 'off')  %else show warning and disable buttons
end
guidata(hObject, handles); %updating handles structure




%% --- Read luma callback ---
function readBut_Callback(hObject, eventdata, handles)
% hObject    handle to readBut (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
FramesEdit=get(handles.FramesEdit, 'String');   % saving value from Edit variable

if get(handles.AllFramesRadioBut, 'value')==1   % if 1st option is set, take all frames
  handles.setFrames=handles.nFrames; 
else
    % -----2nd option is set (other)------
    if isempty(str2num(FramesEdit)) || length(str2num(FramesEdit)) > 1  % if given value is not a valid number
      warndlg('Value must be a positive integer.', 'Wrong value')        % show warning
      return
    elseif str2num(FramesEdit) > handles.nFrames || str2num(FramesEdit) < 1 % if value is not in given range
      warndlg('Value must be in range <1; Frames>.', 'Wrong value')  % shows warning 
      return
    else handles.setFrames=floor(str2num(FramesEdit)); % set given number of frames as setFrames
    end
end
[Y statt]=getLuma(get(handles.FileNameEdit, 'string'), handles.setFrames, handles.width, handles.height); %get luma from video file
handles.Y=Y; %save luma to handles struct.
if statt==1
    set(handles.metricBut, 'enable', 'on'); %enable  metric buttons
    helpdlg('Video file successfully read.', 'Success'); %show dialog that file was successfuly read
else
    return
end
guidata(hObject, handles); %update handles structure



% --- Decode H.264 Callback ---.
function h264but_Callback(hObject, eventdata, handles)
% hObject    handle to h264but (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
FramesEdit=get(handles.FramesEdit, 'String');   % saving value from Edit variable

if get(handles.AllFramesRadioBut, 'value')==1   % if 1st option is set, take all frames
  handles.setFrames=handles.nFrames; 
else
    % -----2nd option is set (other)------
    if isempty(str2num(FramesEdit)) || length(str2num(FramesEdit)) > 1  % if given value is not a valid number
      warndlg('Value must be a positive integer.', 'Wrong value')        % show warning
      return
    elseif str2num(FramesEdit) > handles.nFrames || str2num(FramesEdit) < 1 % if value is not in given range
      warndlg('Value must be in range <1; Frames>.', 'Wrong value')  % shows warning 
      return
    else handles.setFrames=floor(str2num(FramesEdit)); % set given number of frames as setFrames
    end
end

ffstring=sprintf('ffmpeg\\ffmpeg -i "%s" -vcodec copy -vframes %d -bsf:v h264_mp4toannexb -an -y annexb.h264',get(handles.FileNameEdit, 'string'),handles.setFrames);
[status results]=system(ffstring);
clear results;
if status==0
    [status2 results2]=system('ldecod -i annexb.h264 -xmltrace trace.xml');
    clear results2;
    if status2==0
    helpdlg('H.264 bitstream successfully decoded.', 'Success')
    set(handles.psnrbut,'Enable', 'on')
    else
    warndlg('Unknown error occured (ldecod).', 'Error')
    return
    end
else
    warndlg('Unknown error occured (ffmpeg).', 'Error')
    return
end
guidata(hObject, handles);



% --- GBIM button callback ---
function GBIMbut_Callback(hObject, eventdata, handles)
% hObject    handle to GBIMbut (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

resultGBIM=GBIM(handles.Y, 8, handles.setFrames); % computing metric
result=[mean(resultGBIM) median(resultGBIM) max(resultGBIM) min(resultGBIM)]; % computes statistical values of data
file=get(handles.FileNameEdit, 'string');
metric='Generalized Block-Edge Impairment Metric';
typical='Typical value <1.0-2.0>, lower is better.';
String2=sprintf('%s\n%s\n%d frames used for evaluation\n\nMean value:     %.4f\nMedian value:  %.4f\nMaximum:         %.4f\nMinimum:          %.4f', ...
     metric,typical, handles.setFrames, result(1), result(2), result(3), result(4)); 
set(handles.ResultsStatic, 'string', String2);
score=minkowski(resultGBIM);
StringScore=sprintf('Overall Score\n\n %.4f', score);
set(handles.OverallScoreStatic, 'string', StringScore);
set(handles.temppoolbut, 'Enable', 'on');
handles.score=resultGBIM;
guidata(hObject, handles);

    
    % --- Marziliano button callback ---
function MarzilianoBut_Callback(hObject, eventdata, handles)
% hObject    handle to MarzilianoBut (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

resultMarz=0;  %initialization of Marz. results
[M N]=size(handles.Y(:,:,1)); % get size of file
h = waitbar(0,'Please wait...'); %create progress bar
resultMarz=zeros(1,handles.setFrames);
for k=1:handles.setFrames                  % computing metric for every frame
    resultMarz(k)=marziliano(handles.Y(:,:,k), M, N); %saving value of Marz. metric for each frame
    waitbar(k / handles.setFrames, h); %update progress bar
   
end
close(h) % close progress bar
result=[mean(resultMarz) median(resultMarz) max(resultMarz) min(resultMarz)];   % computes statistical values of data

file=get(handles.FileNameEdit, 'string');
metric='Marziliano No-Reference Perceptual Blur Metric';
typical='Typical value <2.0-4.0>, lower is better.';
String2=sprintf('%s\n%s\n%d frames used for evaluation\n\nMean value:     %.4f\nMedian value:  %.4f\nMaximum:         %.4f\nMinimum:          %.4f', ...
     metric,typical, handles.setFrames, result(1), result(2), result(3), result(4)); 
set(handles.ResultsStatic, 'string', String2);
score=minkowski(resultMarz);
StringScore=sprintf('Overall Score\n\n %.4f', score);
set(handles.OverallScoreStatic, 'string', StringScore);
set(handles.temppoolbut, 'Enable', 'on');
handles.score=resultMarz;
guidata(hObject, handles);


% --- H.264 PSNR estimator ---
function psnrbut_Callback(hObject, eventdata, handles)
% hObject    handle to psnrbut (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
PSNR=xml2psnr('trace.xml', handles.width, handles.height);

metric='Simple PSNR Estimator for H.264 coded videos.';
typical='Typical value 40 dB and higher, higher is better.';
String2=sprintf('%s\n%s\n%d frames used for evaluation', ...
     metric,typical, handles.setFrames );  %handles.setFrames
set(handles.ResultsStatic, 'string', String2);
StringScore=sprintf('Total PSNR [dB]\n\n %.4f', PSNR);
set(handles.OverallScoreStatic, 'string', StringScore);



function FileNameEdit_Callback(hObject, eventdata, handles)
% hObject    handle to FileNameEdit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --- Executes during object creation, after setting all properties.
function FileNameEdit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to FileNameEdit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end




% --------------------------------------------------------------------

% --- Executes during object creation, after setting all properties.
function FileParamList_CreateFcn(hObject, eventdata, handles)
% hObject    handle to FileParamList (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called



function FramesEdit_Callback(hObject, eventdata, handles)
% hObject    handle to FramesEdit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of FramesEdit as text
%        str2double(get(hObject,'String')) returns contents of FramesEdit as a double


% --- Executes during object creation, after setting all properties.
function FramesEdit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to FramesEdit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes when selected object is changed in InfoUIpanel.
function InfoUIpanel_SelectionChangeFcn(hObject, eventdata, handles)
% hObject    handle to the selected object in InfoUIpanel 
% eventdata  structure with the following fields (see UIBUTTONGROUP)
%	EventName: string 'SelectionChanged' (read only)
%	OldValue: handle of the previously selected object or empty if none was selected
%	NewValue: handle of the currently selected object
% handles    structure with handles and user data (see GUIDATA)
if get(handles.AllFramesRadioBut, 'value')==1  % If all frames radio button is selected
   set(handles.FramesEdit, 'Enable', 'off'); % number of frames edit is disabled
else 
    set(handles.FramesEdit, 'Enable', 'on'); % otherwise is enabled
end


% --- About button callback.
function aboutbut_Callback(hObject, eventdata, handles)
% hObject    handle to aboutbut (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
about           % Opens About window...

% --- Exit button callback.
function exitbut_Callback(hObject, eventdata, handles)
close all       % Close all programme windows
% hObject    handle to exitbut (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --- Executes during object deletion, before destroying properties.
function mainWindow_DeleteFcn(hObject, eventdata, handles)
% hObject    handle to mainWindow (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
if exist('temp.yuv', 'file') % if the temporary yuv file exists, delete it
   delete('temp.yuv');
else
end
if exist('annexb.h264', 'file') % if the temporary yuv file exists, delete it
   delete('annexb.h264');
else
    
end
if exist('trace.xml', 'file') % if the temporary yuv file exists, delete it
   delete('trace.xml');
else
    
end
if exist('test_dec.yuv', 'file') % if the temporary yuv file exists, delete it
   delete('test_dec.yuv');
else
    
end
close all
%% end of NR VQT


% --- Executes on button press in temppoolbut.
function temppoolbut_Callback(hObject, eventdata, handles)
% hObject    handle to temppoolbut (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
score=temppool(handles.score);
more_temp(score);
