-- M module extracted from ITU-T J.249 (01/2010)
function [one,two,three,four] = dll_video(control, fn, varargin); % DLL_VIDEO % This function implements video file read. % SYNTAX % [...] = dll_video(control, fn, ...); % DESCRIPTION % 'fn' is either 1 for original, or 2 for processed % 'control' is one of the following strings. Additional parameters may % be required, as specified below: % % dll_video('initialize', fn, file_name, 'uyvy', video_standard, rows, cols, fps); % 'video_standard' is 'progressive', % 'interlace_lower_field_first', or 'interlace_upper_field_first' % % dll_video('set_tslice', fn, tslice_len); % % Set durration retrieved by command 'tslice' % % [rows,cols,fps,durration] = dll_video('size', fn); % % return image size, frames per second, TOTAL file durration % % [fps] = dll_video('fps', fn); % [fps] = dll_video('fps'); % % return frames per second % % [video_standard] = dll_video('get_video_standard', fn); % % return video standard: 'progressive', % 'interlace_lower_field_first' or 'interlace_upper_field_first' % % dll_video('set_rewind', fn); % % Set 'rewind'to go to current point in the file % % dll_video('rewind', fn); % % Go to point in file specified by 'set_rewind' % % dll_video('discard', fn, durration); % % Discard the next 'durration' seconds of images from the buffer. % % [y,cb,cr] = dll_video('tslice', fn, reframe); % % read [Y,Cb,Cr] images, the next tslice in durration, % % previously specified via 'set_tslice' % % [y,cb,cr] = dll_video('sec', fn, reframe, durration); % [y] = dll_video('sec', fn, reframe durration); % % read [Y,Cb,Cr] images, 'durration' seconds. % % [y] = dll_video('peek', fn, reframe durration); Get the Y % images without removing them from the buffer. So, the next % call with 'sec' or 'tslice' will get these same frames. % 'reframe' is 1 if ONE extra farme neede for reframing, 0 otherwise % % [total] = dll_video('total_frames',fn); % % return the total number of frames left in the file, after the % % current "read" point. % % [total] = dll_video('total_sec',fn); % % return the total number of seconds left in the file, after the % % current "read" point. % % [boolean] = dll_video('exist',fn); % % return 1 (true) if file defined/exists, 0 (false) otherwise. % % [code] = dll_set_align('delay_8s', delay); % % Works only for files exactly 8seconds long. % % With delay=0, discard first 0.8s start and last 0.2s. % % Delays around that allowed, from (-0.2) sec to (0.2sec - 1frame). % % For original, delay must be set to 0. % % After this option is chosen, 'size' will always return a % % durration of '7 seconds'. % % "code" will be 0 on success, 1 if file was longer than 8sec % % and 2 if file is shorter than 8sec -- in which case, the % % request cannot be accomodated! persistent data1; persistent data2; % Don't need 'fn' to get 'fps' value. Return value from whichever % structure is defined. Must always be equal, so doesn't matter. if strcmp(control,'fps') && ~exist('fn'), if exist('data1') && isfield(data1,'fps'), one = data1.fps; elseif exist('data2') && isfield(data2,'fps'), one = data2.fps; else error('function dll_video: no ''fps'' to retreive'); end return; end % otherwise, always need 'fn' value, to say if working from source or % processed video. if fn == 1, if exist('data1','var') data = data1; end elseif fn == 2, if exist('data2','var') data = data2; end else error('function dll_video: fn must be either 1 or 2'); end % if strcmp(control, 'initialize'), [data] = dll_video__initialize(varargin); data.sec7 = 0; elseif strcmp(control,'exist'), if exist('data','var'), one = 1; else one = 0; end elseif strcmp(control, 'set_tslice'), [data.tslice_frames, data.over_sec] = tslice_conversion(varargin{1}, data.fps); elseif strcmp(control,'size'), one = data.rows; two = data.cols; three = data.fps; four = data.durration; % if demanding 7-second length, return that length instead of actual % length. if data.sec7 == 1, four = 7; end elseif strcmp(control,'fps'), one = data.fps; elseif strcmp(control,'get_video_standard'), one = data.video_standard; elseif strcmp(control,'set_rewind'), data.rewind_curr_frame = data.curr_frame; data.rewind_overby = data.overby; elseif strcmp(control,'rewind'), data.curr_frame = data.rewind_curr_frame; data.overby = data.rewind_overby; elseif strcmp(control,'discard'), [tslice_frames, over_sec] = tslice_conversion(varargin{1}, data.fps); data.curr_frame = data.curr_frame + tslice_frames; data.overby = data.overby + over_sec; if data.overby >= 1.0, data.curr_frame = data.curr_frame - 1; data.overby = data.overby - 1.0; end elseif strcmp(control, 'tslice'), if length(varargin) == 0, [one, two, three, data] = dll_video__next_tslice(data); elseif length(varargin) == 1, [one, two, three, data] = dll_video__next_tslice(data, varargin{1}); else error('not sure what the second argument is!?!'); end elseif strcmp(control,'peek'), [one] = dll_video__peek_tslice(data, varargin{1}, varargin{2}); elseif strcmp(control, 'sec'), if nargout == 1, [one, data] = dll_video__next_tslice(data, varargin{1}, varargin{2}, 0); else [one, two, three, data] = dll_video__next_tslice(data, varargin{1}, varargin{2}, 1); end elseif strcmp(control, 'total_frames'), one = data.total_frames - data.curr_frame + 1; elseif strcmp(control, 'total_sec'), one = (data.total_frames - data.curr_frame + 1) / data.fps; elseif strcmp(control, 'delay_8s'), delay_value = varargin{1}; % can't have delays beyond +/- 0.2 % leave one extra at end for re-framing delay_value = min(round(0.2 * data.fps)-1, delay_value); delay_value = max(round(-0.2 * data.fps), delay_value); % initialize processed video segment to be used: 7 sec + 1frame for % re-framing data.curr_frame = round(0.8 * data.fps) + 1 + delay_value; data.rewind_curr_frame = data.curr_frame; data.overby = 0; data.sec7 = 1; % set return code. See help above. if data.durration < 8, one = 2; elseif data.durration > 8, one = 1; else one = 0; end else error('function dll_video: control value not recognized'); end % copy back to persistent variable if fn == 1, data1 = data; elseif fn == 2, data2 = data; end %%%%%%%%%%%%%%%%%%%%%%%% function [data] = dll_video__initialize(list); % Organize all of the data that will be needed. data.file_name = list{1}; data.file_type = list{2}; data.video_standard = list{3}; data.curr_frame = 1; data.overby = 0; if strcmp(data.file_type,'uyvy'), data.rows = list{4}; data.cols = list{5}; data.fps = list{6}; fid = fopen(data.file_name,'r'); fseek(fid,0, 'eof'); data.total_frames = ftell(fid)./(data.rows*data.cols*2); fclose(fid); else error('file type not recognized. Use ''uyvy'' '); end data.durration = data.total_frames / data.fps; %%%%%%%%%%%%%%%%%%%%%%%% function [y] = dll_video__peek_tslice(data, reframe, durration); if reframe ~=1 & reframe ~= 0, error('CALL WRONG -- go back & add reframing argument'); end [tslice_frames, over_sec] = tslice_conversion(durration, data.fps); start = data.curr_frame; stop = data.curr_frame + tslice_frames + reframe - 1; stop = min(stop, data.total_frames); % don't try to read past end of file! if strcmp(data.file_type,'uyvy'), [y] = read_bigyuv(data.file_name, 'frames', start, stop, ... '128','size',data.rows,data.cols); end %%%%%%%%%%%%%%%%%%%%%%%% function [y, cb, cr, data ] = dll_video__next_tslice( data, reframe, durration, get_color); % by default, get color & luminance if nargin < 4, get_color = 1; end if nargin == 1, reframe = 0; end if reframe ~=1 & reframe ~= 0, error('CALL WRONG -- go back & add reframing argument'); end % if optional 'durration' argument exists, override the default values for % data.tslice_frames and data.over_sec. if exist('durration', 'var'), [tslice_frames, over_sec] = tslice_conversion(durration, data.fps); else tslice_frames = data.tslice_frames; over_sec = data.over_sec; end if tslice_frames == 0, error('Request made to read zero (0) frames of video.'); end if strcmp(data.file_type,'uyvy'), % read video from file. if get_color, [y,cb,cr] = read_bigyuv(data.file_name, 'frames', data.curr_frame, ... data.curr_frame + tslice_frames + reframe - 1, ... '128','size',data.rows,data.cols); else [y] = read_bigyuv(data.file_name, 'frames', data.curr_frame, ... data.curr_frame + tslice_frames + reframe - 1, ... '128','size',data.rows,data.cols); cb=0; cr=0; end end % handle overlap data.curr_frame = data.curr_frame + tslice_frames; data.overby = data.overby + over_sec; if data.overby >= 1.0, data.curr_frame = data.curr_frame - 1; data.overby = data.overby - 1.0; end % convert to double -- everything! y = double(y); if get_color, cb = double(cb); cr = double(cr); end if ~get_color, cb = data; end