classdef BVQMVideoMetricItem < MetricItem
    
    
    methods
        % public
        function obj=BVQMVideoMetricItem
            addpath('Bvqm');
            obj=obj@MetricItem('VQM');
        end
        
        function [refname,avi1name,avi2name]=convert_to_avi(obj,item1,item2)
            
            if isa(item1,'ReferenceItem')
                refname=item1.getfilename;
            else
                error('Item1 %s is not a reference item',item1.getfilename);
            end
            [~,refname,EXT1] = fileparts(refname);
            
            avi1name=sprintf('bvqm/temp/%s_original.avi',refname);
            avi2name=sprintf('bvqm/temp/%s_processed.avi',refname);
            
            if ~exist('bvqm/temp','dir')
                mkdir('bvqm/temp');
            end
            
            if ~exist(avi1name,'file')
                dos(sprintf('ffmpeg -y -i %s -c:v rawvideo -pix_fmt uyvy422 %s',item1.getfilename,avi1name));
            end
            
            dos(sprintf('ffmpeg -y -i %s -c:v rawvideo -pix_fmt uyvy422 %s',item2.getfilename,avi2name));
            
            
        end
        
        function [test_structs, clip_structs, feature_base_dir]=create_bvqm_structs(obj,avi1name,avi2name,refname)
            
            dos(sprintf('ffmpeg -y -i %s -c:v  libx264 -qp 0 -pix_fmt yuv422p bvqm/temp/dummy.avi',avi1name));
            
            refvidinfo = VideoReader('bvqm/temp/dummy.avi');
            
            nF = refvidinfo.NumberOfFrames;
            H = refvidinfo.Height;
            W = refvidinfo.Width;
            FPS=refvidinfo.FrameRate;
            
            
            feature_base_dir = 'BVQM/res'
            test_structs.name={'bvqm'};;
            test_structs.path={''}
            test_structs.scenes= {refname};
            test_structs.hrc= {'original'  'processed'};
            test_structs.viewers= 0;
            
            clip_structs(1).test={'bvqm'};
            clip_structs(1).scene= {refname};
            clip_structs(1).hrc = {'original'};
            clip_structs(1).image_size.rows=H;
            clip_structs(1).image_size.cols=W;
            clip_structs(1).spatial.horizontal=0;
            clip_structs(1).spatial.vertical=0;
            clip_structs(1).luminance_gain=1;
            clip_structs(1).luminance_offset=0;
            clip_structs(1).video_standard='progressive';
            clip_structs(1).fps=FPS;
            clip_structs(1).subj_system={''};
            clip_structs(1).mos= NaN;
            clip_structs(1).stdev= NaN;
            clip_structs(1).inlsa_mos=NaN;
            clip_structs(1).file_name={avi1name};
            clip_structs(1).loc_start=1;
            clip_structs(1).loc_stop=nF;
            clip_structs(1).align_start=1;
            clip_structs(1).align_stop=nF;
            clip_structs(1).cvr.top=1;
            clip_structs(1).cvr.left=1;
            clip_structs(1).cvr.bottom=H;
            clip_structs(1).cvr.right=W;
            clip_structs(1).viewers=0;
            clip_structs(1).hrc_definition={''};
            clip_structs(1).scene_definition={''};
            clip_structs(1).inlsa_mos_2003= NaN;
            clip_structs(1).scale.horizontal=1000;
            clip_structs(1).scale.vertical=1000;
            
            clip_structs(2).test={'bvqm'};
            clip_structs(2).scene= {refname};
            clip_structs(2).hrc = {'processed'};
            clip_structs(2).image_size.rows=H;
            clip_structs(2).image_size.cols=W;
            clip_structs(2).spatial.horizontal=0;
            clip_structs(2).spatial.vertical=0;
            clip_structs(2).luminance_gain=1;
            clip_structs(2).luminance_offset=0;
            clip_structs(2).video_standard='progressive';
            clip_structs(2).fps=FPS;
            clip_structs(2).subj_system={''};
            clip_structs(2).mos= NaN;
            clip_structs(2).stdev= NaN;
            clip_structs(2).inlsa_mos=NaN;
            clip_structs(2).file_name={avi2name};
            clip_structs(2).loc_start=1;
            clip_structs(2).loc_stop=nF;
            clip_structs(2).align_start=1;
            clip_structs(2).align_stop=nF;
            clip_structs(2).cvr.top=1;
            clip_structs(2).cvr.left=1;
            clip_structs(2).cvr.bottom=H;
            clip_structs(2).cvr.right=W;
            clip_structs(2).viewers=0;
            clip_structs(2).hrc_definition={''};
            clip_structs(2).scene_definition={''};
            clip_structs(2).inlsa_mos_2003= NaN;
            clip_structs(2).scale.horizontal=1000;
            clip_structs(2).scale.vertical=1000;
        end
        
        
        
        function val=calc(obj,item1,item2)
            [val,isCached]=obj.CheckCache(item1,item2);
            if ~isCached
                fprintf('Extracting to uncompressed avi ...\n');
                [refname,avi1name,avi2name]=obj.convert_to_avi(item1,item2);
                [test_structs, clip_structs, feature_base_dir]=obj.create_bvqm_structs(avi1name,avi2name,refname);
                fprintf('VQM analysis ...\n');
                [pars, status] = model_general(test_structs, clip_structs, feature_base_dir, 'quiet');
                val=pars.data(1);
                obj.StoreToCache(item1,item2,val);
            end
        end
        
    end
    
end