diff --git a/codec.m b/codec.m new file mode 100644 index 0000000000000000000000000000000000000000..8db25ca08c5643eb9bc68f1e5bcdfa483eb45c02 --- /dev/null +++ b/codec.m @@ -0,0 +1,142 @@ +function [nbBits,peaksnr] = codec(varargin) +%CODEC Summary of this function goes here +% Detailed explanation goes here + +[HEVCDir,~,~] = fileparts(mfilename('fullpath')); +defaultCfg = fullfile(HEVCDir,'cfg','intra.cfg'); + +%% Parse coding choice +codecp = inputParser; codecp.KeepUnmatched = true; codecp.StructExpand = true; +codecp.addParameter('encode', true, @islogical); +codecp.addParameter('decode', true, @islogical); + +codecp.parse(varargin{:}); +encode = codecp.Results.encode; +decode = codecp.Results.decode; + +%% Select executable according to coding choice and OS +if encode + if ispc + TApp = fullfile(HEVCDir,'bin','TAppEncoder.exe'); + elseif isunix + TApp = fullfile(HEVCDir,'bin','TAppEncoderStatic'); + else + error('Platform not supported') + end +elseif decode + if ispc + TApp = fullfile(HEVCDir,'bin','TAppDecoder.exe'); + elseif isunix + TApp = fullfile(HEVCDir,'bin','TAppDecoderStatic'); + else + error('Platform not supported') + end +else + warning('Nothing to do'); + [nbBits,peaksnr] = deal(NaN); + return; +end + +%% Select HEVC parameters to match according to coding choice +HEVCp = inputParser; HEVCp.KeepUnmatched = true; HEVCp.StructExpand = true; + +if encode + HEVCp.addParameter('ConfigFile' ,defaultCfg,@ischar); + HEVCp.addParameter('InputFile' ,'ref.yuv' ,@ischar); + HEVCp.addParameter('BitstreamFile' ,'bit.hevc',@ischar); + HEVCp.addParameter('SourceWidth' ,'512' ,@ischar); + HEVCp.addParameter('SourceHeight' ,'512' ,@ischar); + HEVCp.addParameter('InputBitDepth' ,'8' ,@ischar); + HEVCp.addParameter('InternalBitDepth' ,'8' ,@ischar); + HEVCp.addParameter('InputChromaFormat' ,'420' ,@ischar); + HEVCp.addParameter('FrameRate' ,'60' ,@ischar); + HEVCp.addParameter('FrameSkip' ,'0' ,@ischar); + HEVCp.addParameter('FramesToBeEncoded' ,'1' ,@ischar); + HEVCp.addParameter('QP' ,'30' ,@ischar); + HEVCp.addParameter('WarnUnknowParameter','0' ,@ischar); + if decode + HEVCp.addParameter('ReconFile' ,'rec.yuv' ,@ischar); + end +elseif decode + HEVCp.addParameter('BitstreamFile' ,'bit.hevc',@ischar); + HEVCp.addParameter('ReconFile' ,'rec.yuv' ,@ischar); + HEVCp.addParameter('SkipFrames' ,'0' ,@ischar); + HEVCp.addParameter('WarnUnknowParameter','0' ,@ischar); +end + +%% Parse HEVC arguments +HEVCp.parse(codecp.Unmatched); + +HEVCParams = HEVCp.Results; +extraHEVCParams = HEVCp.Unmatched; + +% Make sure ConfigFile is the first parameter to set default values +if encode + perm = 1:numel(HEVCp.Parameters); + indconf = find(strcmp('ConfigFile',HEVCp.Parameters)); + perm(1) = indconf; perm(indconf) = 1; + HEVCParams = orderfields(HEVCParams,perm); +end + +% Make sure to create output folders before running executable +[folder,~,~] = fileparts(HEVCp.Results.BitstreamFile); +if ~exist(folder,'dir') + mkdir(folder); +end +if decode + [folder,~,~] = fileparts(HEVCp.Results.ReconFile); + if ~exist(folder,'dir') + mkdir(folder); + end +end + +[LogFolder,LogName,~] = fileparts(HEVCp.Results.BitstreamFile); +LogFileEnc = fullfile(LogFolder,[LogName,'_enc.rtf']); +LogFileDec = fullfile(LogFolder,[LogName,'_dec.rtf']); + +%% Execute command +HEVCArgList = paramToArgList(HEVCParams); +extraHEVCArgList = paramToArgList(extraHEVCParams); + +if ispc + redirect = @(logfile) ['> ',logfile,' | type ' logfile]; +elseif isunix + redirect = @(logfile) ['| tee ' ,LogFile]; +end + +if encode + command = [TApp,' ',HEVCArgList,' ',extraHEVCArgList,' ',redirect(LogFileEnc)]; +elseif decode + command = [TApp,' ',HEVCArgList,' ',extraHEVCArgList,' ',redirect(LogFileDec)]; +end + +disp(command) +status = system(command); + +if status + if encode + command = [TApp,' ',HEVCArgList,' ',redirect(LogFileEnc)]; + elseif decode + command = [TApp,' ',HEVCArgList,' ',redirect(LogFileDec)]; + end + + disp(command) + status = system(command); + + if status + error('HEVC Error'); + end +end + +[nbBits,peaksnr] = HEVC.parseLog(LogFileEnc); + +end + +function argList = paramToArgList(Params) +parameters = fieldnames (Params); +values = struct2cell(Params); + +argList = cellfun(@(param,val) ['--',param,'=',val],parameters,values,'UniformOutput',false); + +argList = strjoin(argList(:)); +end \ No newline at end of file