/Expectator/emoLabel (Video Annotation)/myplay.m
MATLAB | 1683 lines | 1001 code | 220 blank | 462 comment | 142 complexity | 191dfdb768e78322078a3fe8d2e2f7b1 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0
- function mov = myplay(varargin)
- %MPLAY Play a movie interactively.
- % MPLAY(A) opens a new movie player GUI and loads movie data
- % A into the player. Multiple players may be used at one time.
- %
- % MPLAY(A, FMT) explicity specifies a format string FMT for the
- % movie data, in case a warning from MPLAY(A) indicates ambiguity
- % in interpreting the format of A.
- %
- % MPLAY(A, FPS) or MPLAY(A, FMT, FPS) specifies the default
- % frame rate, FPS, for the movie, in frames per second. If
- % omitted, FPS defaults to 30. The GUI supports interactive
- % changes to FPS as well.
- %
- % M=MPLAY(...) returns a MoviePlayerAPI object, M, useful for
- % programmatic control of the movie player GUI. A list of
- % all available object methods is obtained from "methods(M)".
- %
- % Movie formats
- % -------------
- % Movie A may be one of the following formats:
- %
- % Standard MATLAB movie structure (FMT = 'structure' or 'S')
- % See 'help getframe' for more information on the MATLAB
- % movie structure. Only movies with empty .colormap field
- % entries are supported.
- %
- % Intensity video array (FMT = 'intensity' or 'I')
- % 3-D array organized as MxNxF, where each image is of size
- % MxN and there are F image frames. An input with size
- % exactly MxNx3 will be interpreted as a 3-frame intensity movie.
- %
- % RGB video array (FMT = 'RGB')
- % 4-D array organized as MxNx3xF, where the R, G, and B
- % are encoded in the 3rd dimension. Note that MxNx3 is
- % the usual MATLAB format for an RGB image.
- %
- % Video frame data type may be double, uint8, or uint16.
- %
- % Keyboard support
- % ----------------
- % P:Play F:FFwd Rt:StepFwd Up:First J:Jump X:FwdBkwd
- % S:Stop R:Rew Lt:StepRev Dn:Last L:Loop
- %
- % EXAMPLE: Playback of standard MATLAB movies.
- % Run 'crulspin' or 'logospin' from the command line.
- % These demos create a MATLAB movie structure in the
- % workspace in variable 'm'. Run "mplay(m)" and be
- % sure to turn on looping playback.
- %
- % See also MOVIE, INT2RGBM, INT2STRUCT, STRUCT2RGBM, IMVIEW.
-
- % Copyright 2003 The MathWorks, Inc.
- % Author: D. Orofino
- % $Revision: $ $Date: $
-
-
- % To do:
- % ------
- % - icon for export-to-imview
- % - API properties: colormap
- % - Interactive zoom
-
- % Note: The following input syntax has been disabled in the
- % CheckMovieFormat() function.
- %
- % Color video components (FMT = @user_fcn)
- % Cell array containing arrays reprsenting each color plane of a movie,
- % arranged in a form suitable for a pre-defined conversion function.
- % In this case, FMT specifies a function (string or function handle) that
- % converts from the color components to the 4-D RGB video format. The
- % function is invoked as: RGBM = user_fcn(A{:}). The function must
- % return a 4-D RGB movie array. If omitted, FMT defaults to @int2rgbm.
- %
- % Examples:
- % MPLAY({R,G,B},@int2rgbm) % converts RGB components to 4-D array
- % MPLAY({R,G,B},10) % uses int2rgbm by format, 10 frames/sec
- % MPLAY({Y,U,V},@yuv2rgbm,24) % 24 frames/sec, YUV data format
- %
-
-
- % GUI Data organization
- % ---------------------
- % Figure UserData
- % .hfig handle to figure window
- % .haxis handle to axis containing image object
- % .himage handle to image object
- % .htoolbar handle to GUI button toolbar
- % .htimer timer object associated with this player
- % .hStatusBar structure of handles to parts of status bar
- % .loopmode 0=no looping, 1=looping
- % .fbmode 0=no fwd/bkwd playback, 1=fwd/bkwd playback
- % .fbrev 1=currently in reverse-playback, only if fwd/bkwd flag true
- % .paused true/false flag indicating that we're in
- % pause mode --- set to false by pressing play or stop
- % .nextframe next frame number to display
- % .currframe current frame displayed in viewer
- % .jumpto_frame frame number to jump to for frame num edit
- % .fps requested frame rate (frames per second)
- % .varName name of variable passed in to player
- % .numFrames number of frames in movie
- % .frameRows number of rows in movie image
- % .frameCols number of columns in movie image
- % .cmapexpr colormap expr to use during movie playback
- % .cmap
- % .UpdateImageFcn function pointer to image update fcn
- % .Movie movie pixel data
- % .MovieFormat 'S' Standard movie structure
- % 'I' MxNxF
- % 'RGB' MxNx3xF
- %
- % Timer Object UserData
- % .hfig handle to corresponding figure window
-
- try,
- % dfmt: desired movie format, as specified by user
- [A,dfmt,fps,msg] = parse_inputs(varargin{:});
- error(msg);
-
- % fmt: actual movie format to use,
- % string normalized to proper spelling, capitalization, etc
- [A, fmt] = CheckMovieFormat(A, dfmt);
-
- % Create and load GUI with movie
- hfig = CreateGUI;
- LoadMovie(hfig, A, fmt, inputname(1), fps);
- UpdateGUIControls(hfig);
- AdjustPlayerSize(hfig);
-
- % Return object is LHS requested
- if nargout>0, mov=GetMoviePlayerAPI(hfig); end
-
- % Clean up
- set(hfig,'vis','on'); % time to show the player
-
- catch,
- rethrow(lasterror);
- end
-
- % --------------------------------------------------------
- function AdjustPlayerSize(hfig)
- % Adjust width of player window to be no narrower than
- % the extent needed to render the button and status bar
- %
- % Also, make sure it is no bigger than screen size
-
- min_width = 370; % min pixel width to render toolbar
- set(hfig,'units','pix');
- figpos = get(hfig,'pos');
-
- % Widen player to minimum width (if movie is very narrow)
- if figpos(3) < min_width,
- figpos(3) = min_width;
- end
-
- % Shrink movie to screen as needed:
- set(0,'units','pix');
- screenpos = get(0,'screensize');
- if figpos(3) > screenpos(3),
- figpos(3) = screenpos(3);
- end
- if figpos(4) > screenpos(4),
- figpos(4) = screenpos(4);
- end
-
- set(hfig,'pos',figpos);
-
- % --------------------------------------------------------
- function mov = GetMoviePlayerAPI(hfig)
-
- fcn.ffwd = @cb_ffwd;
- fcn.goto_end = @cb_goto_end;
- fcn.goto_start = @cb_goto_start;
- fcn.jumpto = @cb_jumpto;
- fcn.loop = @cb_loop;
- fcn.fbmode = @cb_fbmode;
- fcn.play = @cb_play;
- fcn.rewind = @cb_rewind;
- fcn.step_back = @cb_step_back;
- fcn.step_fwd = @cb_step_fwd;
- fcn.stop = @cb_stop;
- fcn.truesize = @cb_truesize;
- fcn.setfps = @ext_setFPS;
- fcn.getfps = @ext_getFPS;
- mov = mmovie.player(hfig,fcn);
-
- % --------------------------------------------------------
- function [A,fmt,fps,msg] = parse_inputs(varargin)
- %PARSE_INPUTS Parse input arguments
- % Valid calling syntax:
- % MPLAY(A)
- % MPLAY(A, FMT)
- % MPLAY(A, FPS)
- % MPLAY(A, FMT, FPS)
- %
- % Defaults:
- A=[];
- fmt=''; % no format specified
- fps=30; % 30 frames per second
- msg=''; % no errors
-
- % Check number of input args
- msg = nargchk(1,3,nargin);
- if ~isempty(msg), return; end
-
- A = varargin{1};
-
- if nargin > 2,
- % 3 or more inputs
- fmt = varargin{2};
- fps = varargin{3};
-
- elseif nargin==2
- % 2 inputs
- if ischar(varargin{2}),
- fmt = varargin{2};
- else
- % must disambiguate:
- % (A,@my_func) from (A,fps)
- if isnumeric(varargin{2}),
- fps = varargin{2};
- else
- fmt = varargin{2};
- end
- end
- end
-
- % Check and expand FMT
- % Expand the desired format string specified by user
- % Make it lower case, and complete any partial string specified.
- %
- % NOTE: If A is a cell-array, skip this
- % FMT could be a conversion function
- %
- if ~iscell(A),
- if ~isempty(fmt),
- if ~ischar(fmt),
- msg = 'FMT must be a string.';
- return
- end
- all_in={'intensity','rgb','structure'}; % user format strings
- all_out={'I','RGB','S'}; % internal format strings
- i=strmatch(lower(fmt), all_in);
- if isempty(i),
- msg='Unrecognized FMT string specified.';
- return
- end
- fmt=all_out{i};
- end
- end
-
- % Check FPS
- if ~isa(fps,'double') || numel(fps)~=1 || fps<=0,
- msg='FPS must be a scalar double-precision value > 0.';
- return
- end
-
- % --------------------------------------------------------
- function [A,fmt,msg] = CheckMovieFormat(A,dfmt)
- % DetermineMovieFormat
-
- % Rules to disambiguate inputs when no format is specified
- %
- % Is input a structure?
- % - 'struct' assumed
- % check for .colormap and .cdata present
- % check for empty .colormap entries
- % check for MxN or MxNx3 sizes in each frame
- % - otherwise, ERROR
- %
- % Is input numeric?
- % - if not, ERROR
- %
- % Is input 4-D?
- % Are both the 1st and 3rd dims ~= 3 (or empty)?
- % ERROR
- % Are both the 1st and 3rd dims == 3?
- % - assume 'rgb'
- % - WARN user of ambiguity, and to pass 'rgb' format string
- % to suppress warning next time
- % Is the 1st dim = 3 and the 3rd dim ~= 3?
- % - 'rgbp' assumed
- % Is the 1st dim ~= 3 and the 3rd dim = 3?
- % - 'rgb' assumed
- %
- % Is input 3-D?
- % Is the 3rd dim = 3?
- % WARN that this is being interpreted as a 3-frame intensity movie,
- % and to pass 'intensity' format string to suppress warning next time
- %
- % Is input 2-D?
- % - 'intensity' assumed, one frame
- %
- % Otherwise, ERROR
-
- fmt = ''; % default
- CR = sprintf('\n');
-
- % Check for movie structure format
- %
- if isstruct(A),
- fmt = 'S';
- if ~isempty(dfmt) && ~strcmp(fmt,dfmt),
- error('Movie format (%s) doesn''t match specified format (%s)',fmt,dfmt);
- end
-
- % Check for required fields
- if ~isfield(A, 'colormap') || ~isfield(A, 'cdata'),
- error('Invalid movie: structure format does not contain required fields.');
- end
-
- % Check for empty colormap fields and movie datatypes
- % - check all frames (thorough but time consuming)
- % - check just the first frame (quick but incomplete)
- %
- i=1; % just check first frame
- %for i=1:length(A), % check all entries in structure
- if ~isempty(A(i).colormap),
- error('All colormap fields in structure format must be empty.');
- end
- c=class(A(i).cdata);
- switch c,
- case {'uint8','double'},
- otherwise,
- error('Unsupported data type (%s) found in video frames.', c);
- end
- %end
- return
- end
-
- % Check for cell-array arguments
- %
- % NOTE: Disabled color conversion syntax
- if 0,
- if iscell(A),
- % Convert cell array of color components to 4-D RGB video array
- % using user-defined conversion function
-
- % Default if no conversion function specified: int2rgbm
- if isempty(dfmt),
- fmt = @int2rgbm;
- else
- fmt = dfmt;
- end
-
- % Try to invoke conversion function
- A = feval(fmt, A{:});
-
- % After the conversion, it is assumed that the video format is RGB
- fmt = 'RGB';
- dfmt = 'RGB';
-
- % Fall-through to standard checking-code for N-D array
- % after conversion function has completed
- end
- end
-
- if ~isnumeric(A),
- error('Unrecognized movie format.');
- end
-
- % Check for 3-D and 4-D RGB array formats
- %
- nd = ndims(A);
- sz = size(A);
- if nd==4,
- A33 = (sz(3)==3);
- if ~A33,
- error('Invalid movie format: 3rd dimension of array must be 3.');
- end
- fmt = 'RGB';
- if ~isempty(dfmt) && ~strcmp(fmt,dfmt),
- error('Movie format (%s) doesn''t match specified format (%s)',fmt,dfmt);
- end
- return
- elseif nd==3,
- A33 = (sz(3)==3);
- if A33 && isempty(dfmt),
- warning(['Ambiguous movie format: 3rd dimension of 3-D array is 3.' CR ...
- 'Assuming ''intensity'' format. Pass format string to suppress warning.']);
- end
- fmt='I';
- if ~isempty(dfmt) && ~strcmp(fmt,dfmt),
- error('Movie format (%s) doesn''t match specified format (%s)',fmt,dfmt);
- end
- return
- else % 2-D input
- fmt='I';
- if ~isempty(dfmt) && ~strcmp(fmt,dfmt),
- error('Movie format (%s) doesn''t match specified format (%s)',fmt,dfmt);
- end
- return
- end
-
- % --------------------------------------------------------
- function hfig = CreateGUI
-
- % Determine renderer mode
- if 0 & opengl('info'),
- renderer='opengl';
- else
- renderer='painters';
- end
-
- % Create figure
- defaultPos = [50 50 400 400];
- hfig = figure(...
- 'NumberTitle','off', ...
- 'MenuBar','none', ...
- 'Renderer',renderer, ...
- 'HandleVis','callback', ...
- 'IntegerHandle','off', ...
- 'KeyPressFcn', @KeypressFcn, ...
- 'Visible','off', ...
- 'CloseRequestFcn',@DeleteFcn, ...
- 'DeleteFcn',@DeleteFcn, ...
- 'Position',defaultPos, ...
- 'BackingStore','off', ...
- 'DoubleBuffer','off');
-
- % Setup movie area
- defaultN = 64;
- haxis = axes( ...
- 'parent',hfig, ...
- 'pos',[0 0 1 1], ...
- 'vis','off', ...
- 'xlim',[1 defaultN], ...
- 'ylim', [1 defaultN], ...
- 'ydir','reverse', ...
- 'xlimmode','manual',...
- 'ylimmode','manual',...
- 'zlimmode','manual',...
- 'climmode','manual',...
- 'alimmode','manual',...
- 'layer','bottom',...
- 'nextplot','add', ...
- 'dataaspectratio',[1 1 1], ...
- 'drawmode','fast');
- himage = image(...
- 'parent',haxis, ...
- 'cdata',zeros(defaultN), ...
- 'xdata',1:defaultN, ...
- 'ydata',1:defaultN, ...
- 'erase','none');
-
- % Setup default figure data
- %
- ud = get(hfig,'userdata');
- ud.hfig = hfig;
- ud.haxis = haxis;
- ud.himage = himage;
- ud.htoolbar = CreateButtonBar(hfig);
- ud.htimer = [];
- ud.hStatusBar = AddStatusBar(hfig);
- ud.loopmode = 0; % non-looping
- ud.fbmode = 0; % no fwd/bkwd playback
- ud.fbrev = 0; % not in rev-playback
- ud.paused = 0;
- ud.nextframe = 1;
- ud.currframe = 0;
- ud.jumpto_frame = 1;
- ud.fps = 0; % frames per second
- ud.varName = ''; % variable name passed to player
- ud.numFrames = 0;
- ud.frameRows = 0;
- ud.frameCols = 0;
- ud.cmapexpr = 'gray(256)'; % default
- ud.cmap = gray(256); % default
- ud.UpdateImageFcn = [];
- ud.Movie = [];
- ud.MovieFormat = '';
- set(hfig,'userdata', ud);
-
- % Finishing touches:
- % - show GUI
- % - enable resize fcn
- set(hfig, ...
- 'colormap', ud.cmap, ...
- 'resizefcn', @ResizeFcn);
-
- % -------------------------------------------------------------------------
- function KeypressFcn(hcb, eventStruct)
- % Handle keypresses in main window
-
- hfig = gcbf;
- key = get(hfig, 'CurrentChar');
- if ~isempty(key), % unix keyboard has an empty key
- switch lower(key)
- case char(29) % right
- cb_step_fwd(hfig,[]);
- case char(28) % left
- cb_step_back(hfig,[]);
- case 'f'
- cb_ffwd(hfig,[]);
- case 'r'
- cb_rewind(hfig,[]);
-
- case 's'
- cb_stop(hfig,[]);
- case 'p'
- cb_play(hfig,[]); % play/pause
- case char(30) % up
- cb_goto_start(hfig,[]);
- case char(31) % down
- cb_goto_end(hfig,[]);
-
- case 'j' % jump to
- EditFrameNum(hfig);
- case 'l' % loop
- cb_loop(hfig,[]);
- case 'x' % fwd/bkwd playback
- cb_fbmode(hfig,[]);
-
- case char(13) % Enter
- % Open parameters dialog
- EditProperties(hfig);
- end
- end
-
- % --------------------------------------------------------
- function DeleteFcn(hcb, eventStruct)
- % How to get here:
- % Close all force
- % delete(h)
- hfig=gcbf;
- ud = get(hfig,'userdata');
- if ~isempty(ud),
- stop(ud.htimer); % Shut off timer if running
- end
- delete(hfig); % Close window
-
- % --------------------------------------------------------
- function ResizeFcn(hcb, eventStruct)
-
- fd = get(hcb,'UserData'); % hcb = hfig
- hAll = fd.hStatusBar.All;
-
- % Get positions and compute resize offsets:
- fig_pos = get(hcb,'pos');
- frame_pos = get(fd.hStatusBar.Region,'pos');
- frame_rt = frame_pos(1)+frame_pos(3)-2;
- delta = fig_pos(3)-frame_rt;
-
- % Adjust positions:
- for i=1:length(hAll),
- pos = get(hAll(i),'pos');
- pos(1) = pos(1) + delta;
- set(hAll(i),'pos',pos);
- end
-
- % Separately adjust hStatusBar.Region
- % Grow it wider, don't move it:
- pos = frame_pos;
- pos(3)=pos(3)+delta;
- set(fd.hStatusBar.Region,'pos',pos);
-
- % --------------------------------------------------------
- function hStatusBar = AddStatusBar(hfig)
-
- hfig_pos = get(hfig,'pos');
- CR = sprintf('\n');
-
- % Status region frame
- bg = [1 1 1]*.8;
- pos=[0 0 hfig_pos(3)+2 22];
- hStatusBar.Region = uicontrol('parent',hfig, ...
- 'style','frame', ...
- 'units','pix', ...
- 'pos',pos, ...
- 'backgr', bg, ...
- 'foregr', [1 1 1]);
-
- % Render right after background frame, so when resizing occurs,
- % this will be "overwritten" by other data
- hStatusBar.StatusText = uicontrol('parent',hfig, ...
- 'style','text', ...
- 'units','pix', ...
- 'pos',[2 1 100 16], ...
- 'string','Ready', ...
- 'horiz','left', ...
- 'backgr',bg, ...
- 'foregr','k');
-
- % Indents for display/trace timing
- pos1 = [pos(3)-64 1 60 17];
- [hStatusBar.FPS, hAll1] = makeStatusBarIndent(hfig,bg,pos1);
- set(hStatusBar.FPS,'string','FPS: 0', ...
- 'tooltip' ,['Frames Per Second']);
- set(hAll1,'ButtonDownFcn',@cb_properties);
-
- pos2 = [pos(3)-128 1 60 17];
- [hStatusBar.FrameNum, hAll2] = makeStatusBarIndent(hfig,bg,pos2);
-
- set(hStatusBar.FrameNum,'string','0:0', ...
- 'tooltip', ['Current Frame : Total Frames']);
-
- set(hAll2,'ButtonDownFcn',@cb_jumpto);
-
- pos2 = [pos(3)-148-74 1 90 17];
- [hStatusBar.FrameSize, hAll3] = makeStatusBarIndent(hfig,bg,pos2);
- set(hStatusBar.FrameSize,'string','(FrameSize)', ...
- 'tooltip', '(framesize readout)');
- % set(hAll3,'ButtonDownFcn',@cb_properties);
-
- % Group all status bar widget handles together, for resizing:
- hStatusBar.All = [hAll1 hAll2 hAll3];
-
- % -------------------------------------------------------------------------
- function [h, hall] = makeStatusBarIndent(hfig,bg,pos1)
- hall(1)=uicontrol('parent',hfig, ...
- 'style','frame', ...
- 'units','pix', ...
- 'pos',pos1, ...
- 'backgr', bg, ...
- 'foregr', [1 1 1]*.4);
-
- pos2=pos1;
- pos2(4)=1;
- hall(2)=uicontrol('parent',hfig, ...
- 'style','frame', ...
- 'units','pix', ...
- 'pos',pos2, ...
- 'backgr', [1 1 1], ...
- 'foregr', [1 1 1]);
- pos2=[pos1(1)+pos1(3)-1 pos1(2) 1 pos1(4)];
- hall(3)=uicontrol('parent',hfig, ...
- 'style','frame', ...
- 'units','pix', ...
- 'pos',pos2, ...
- 'backgr', [1 1 1], ...
- 'foregr', [1 1 1]);
-
- hall(4) = uicontrol('parent',hfig, ...
- 'style','text', ...
- 'units','pix', ...
- 'horiz','left', ...
- 'fontweight','light', ...
- 'fontsize',8, ...
- 'pos',pos1+[2 2 -3 -3], ...
- 'string', 'test', ...
- 'backgr', bg, ...
- 'foregr', [0 0 0]);
- h=hall(4); % main text widget
-
- % -------------------------------------------------------------------------
- function UpdateStandardStatusText(hfig)
- % Setup some status bar text, indicating
- % current scope state
- %
- ud = get(hfig,'userdata');
- isRunning = strcmp(get(ud.htimer,'Running'),'on');
- isPaused = ~isRunning & ud.paused;
- isStopped = ~isRunning & ~ud.paused;
-
- if isStopped, str = 'Stopped';
- elseif isPaused, str = 'Paused';
- else str = 'Playing';
- end
-
- UpdateStatusText(hfig,str);
-
- % -------------------------------------------------------------------------
- function UpdateStatusText(hfig,str)
- % Set arbitrary text into status region
-
- if isempty(hfig), return; end
- fd = get(hfig,'UserData');
- set(fd.hStatusBar.StatusText,'string',str);
-
- % --------------------------------------------------------
- function UpdateGUIControls(hfig)
- % Update GUI state, including:
- % - button enable states/icons
- % - status bar text
-
- UpdateButtonEnables(hfig);
- UpdateStandardStatusText(hfig);
-
-
- % --------------------------------------------------------
- function UpdateButtonEnables(hfig)
- % Button states:
- % Enabled=1
- % Disabled=0
- % stopped paused running
- % Props (all 1)
- % Truesz (all 1)
- % Export (all 1)
- %
- % 1st (all 1)
- % Rew (all 1)
- % StepRev 1 1 0
- % Stop 0 1 1
- % Play 1 1 1
- % StepFwd 1 1 0
- % FFwd (all 1)
- % Last (all 1)
- %
- % JumpTo
- % Loop
- % Fwd/Bkwd Play
-
- ud = get(hfig,'userdata');
- isRunning = strcmp(get(ud.htimer,'Running'),'on');
- isPaused = ~isRunning && ud.paused;
- isStopped = ~isRunning && ~ud.paused;
-
- if isStopped, ena = [1 0 1 1];
- elseif isPaused, ena = [1 1 1 1];
- else ena = [0 1 1 0];
- end
-
- hchild = flipud(get(ud.htoolbar,'children'));
- for i=1:4,
- if ena(i), s='on'; else s='off'; end
- set(hchild(5+i),'enable',s);
- end
-
- % --------------------------------------------------------
- function htoolbar = CreateButtonBar(hfig)
- % Create button bar
-
- % Get a bunch of playback-related icons
- icons = mergefields(load('audiotoolbaricons'), load('mplay_icons'));
- CR = sprintf('\n');
- htoolbar = uitoolbar(hfig); % Create toolbar
- setappdata(htoolbar,'icons',icons); % Store icons in toolbar appdata
-
- uipushtool(htoolbar, ...
- 'cdata', icons.params, ...
- 'tooltip','Properties...', ...
- 'click', @cb_properties);
- uipushtool(htoolbar, ...
- 'cdata', icons.fit_to_view, ...
- 'tooltip','True size', ...
- 'click', @cb_truesize);
- hexp=uipushtool(htoolbar, ...
- 'cdata', icons.export_imview, ...
- 'tooltip','Export to IMVIEW', ...
- 'click', @cb_export_imview);
-
- % Check for IMVIEW
- if ~exist('imview','file'),
- % set(hexp,'enable','off');
- set(hexp,'tooltip', 'Export to Workspace');
- end
-
- uipushtool(htoolbar, ...
- 'cdata', icons.goto_start_default, ...
- 'tooltip','Go to start', ...
- 'separator','on', ...
- 'click', @cb_goto_start);
- uipushtool(htoolbar, ...
- 'cdata', icons.rewind_default, ...
- 'tooltip','Rewind', ...
- 'click', @cb_rewind);
- uipushtool(htoolbar, ...
- 'cdata', icons.step_back, ...
- 'tooltip','Step back', ...
- 'click', @cb_step_back);
- uipushtool(htoolbar, ...
- 'cdata', icons.stop_default, ...
- 'tooltip','Stop', ...
- 'click', @cb_stop);
- uipushtool(htoolbar, ...
- 'cdata', icons.play_on, ...
- 'tooltip','Play', ...
- 'tag','Play/Pause', ...
- 'click', @cb_play);
- uipushtool(htoolbar, ...
- 'cdata', icons.step_fwd, ...
- 'tooltip','Step forward', ...
- 'click', @cb_step_fwd);
- uipushtool(htoolbar, ...
- 'cdata', icons.ffwd_default, ...
- 'tooltip','Fast forward', ...
- 'click', @cb_ffwd);
- uipushtool(htoolbar, ...
- 'cdata', icons.goto_end_default, ...
- 'tooltip','Go to end', ...
- 'click', @cb_goto_end);
-
- uipushtool(htoolbar, ...
- 'cdata', icons.jump_to, ...
- 'separator','on', ...
- 'tooltip','Jump to...', ...
- 'click', @cb_jumpto);
- uipushtool(htoolbar, ...
- 'cdata', icons.loop_off, ...
- 'tooltip',['Repeat playback'], ...
- 'tag','loopbutton', ...
- 'click', @cb_loop);
- uipushtool(htoolbar, ...
- 'cdata', icons.fwdbk_play_off, ...
- 'tooltip',['<default>'], ...
- 'tag','fbbutton', ...
- 'click', @cb_fbmode);
-
- % --------------------------------------------------------
- function icons = get_icons_from_fig(hfig)
-
- udfig = get(hfig,'userdata');
- udtb = getappdata(udfig.htoolbar);
- icons = udtb.icons;
-
- % --------------------------------------------------------
- function cb_goto_start(hbutton, eventStruct, hfig)
- % goto start button callback
- % jump to frame 1, cancel bkwd playback (if on)
-
- if nargin<3, hfig = gcbf; end
- ud = get(hfig,'userdata');
- if ud.currframe ~= 1, % prevent repeated presses
- ud.currframe = 1;
- ud.nextframe = 1;
- ud.fbrev = 0; % cancel any bkwd playback
- set(hfig,'userdata',ud);
- ShowMovieFrame(hfig);
- end
-
- % --------------------------------------------------------
- function cb_rewind(hbutton, eventStruct, hfig)
- % Rewind button callback
- % Backup "stepsize" frames
- if nargin<3, hfig = gcbf; end
- ud = get(hfig,'userdata');
- stepsize = 10;
-
- if ud.fbmode,
- % fwd/back playback mode
- if ud.fbrev,
- % in reverse ... increment
- if ud.currframe >= ud.numFrames-stepsize,
- % hit last frame ... go to reverse
- ud.currframe = ud.numFrames;
- ud.fbrev=0; % no more reverse playback
- else
- ud.currframe = ud.currframe+stepsize;
- end
- else
- % not in reverse ... decrement
- if ud.currframe <= stepsize,
- ud.fbrev=1; % hit reverse playback
- ud.currframe = stepsize+1; % so next subtraction brings us to frame 1
- end
- ud.currframe = ud.currframe-stepsize;
- end
- else
- % Not fwd/back mode
-
- ud.currframe = ud.currframe - stepsize;
- % Check for backwards wraparound
- if ud.currframe < 1,
- if ~ud.loopmode,
- if ud.currframe == 1-stepsize,
- return
- end
- ud.currframe = 1;
- else
- ud.currframe = ud.currframe+ud.numFrames;
- end
- end
- end
-
- % Store for next time:
- ud.nextframe = ud.currframe;
- upd = ~ud.paused;
- ud.paused = 1; % assume we're starting from pause
- set(hfig,'userdata',ud);
- ShowMovieFrame(hfig);
- if upd, UpdateGUIControls(hfig); end
-
- % --------------------------------------------------------
- function cb_play(hbutton, eventStruct, hfig)
- % Play button callback
-
- if nargin<3, hfig = gcbf; end
-
- ud = get(hfig,'userdata');
- icons = get_icons_from_fig(hfig);
- hPlay = findobj(ud.htoolbar, 'tag','Play/Pause');
-
- % Check if timer is already running
- if strcmp(get(ud.htimer,'Running'),'on'),
- % Movie already playing
- % - Move to Pause mode
- % - Show Play icon (currently must be pause indicator)
-
- % Stop timer, set pause mode
- ud.paused = 1;
- set(hfig,'userdata',ud);
- stop(ud.htimer);
-
- % Flush changes
- ShowMovieFrame(hfig);
- %UpdateFrameReadout(ud);
-
- % Set play icon, darker
- set(hPlay, ...
- 'tooltip', 'Resume', ...
- 'cdata', icons.play_off);
- else
- % Not running
- if ud.paused,
- % Paused - move to play
- ud.nextframe = ud.currframe;
- else
- % Stopped - move to play
- ud.nextframe = 1; % Start from 1st frame when stopped
- ud.fbrev = 0; % Reset fwd/bkwd state to fwd
- end
- set(hfig,'userdata',ud);
-
- % Show pause icon
- set(hPlay, ...
- 'tooltip', 'Pause', ...
- 'cdata', icons.pause_default);
- start(ud.htimer);
- end
- UpdateGUIControls(hfig);
-
- % --------------------------------------------------------
- function cb_stop(hbutton, eventStruct, hfig)
- % Stop button callback
-
- if nargin<3, hfig = gcbf; end
-
- ud = get(hfig,'userdata');
- ud.paused = 0; % we're stopped, not paused
- set(hfig,'userdata',ud);
-
- isRunning = strcmp(get(ud.htimer,'Running'),'on');
- if isRunning,
- stop(ud.htimer);
- else
- % Allow stop even when movie not running
- % We could have been paused
- do_timer_stop(hfig);
- end
-
- % --------------------------------------------------------
- function cb_step_back(hbutton, eventStruct, hfig)
- % Step one frame backward callback
-
- if nargin<3, hfig = gcbf; end
- ud = get(hfig,'userdata');
-
- if ud.fbmode,
- % fwd/back playback mode
- if ud.fbrev,
- % in reverse ... increment
- if ud.currframe == ud.numFrames-1,
- % will hit last frame ... go to normal playback
- ud.fbrev=0; % normal playback
- end
- ud.currframe = ud.currframe+1;
- else
- % not in reverse ... decrement
- if ud.currframe == 1,
- % fwd/back hit when frame 2 displayed
- % move to frame 1 in non-reverse mode, then go to reverse
- % mode
- ud.fbrev=1; % enter reverse playback
- ud.currframe = 2;
- else
- ud.currframe = ud.currframe-1;
- end
- end
- else
- % Not fwd/back mode
- if ud.currframe <= 1,
- if ~ud.loopmode,
- return
- end
- ud.currframe = ud.numFrames;
- else
- ud.currframe = ud.currframe-1;
- end
- end
-
- ud.nextframe = ud.currframe;
- upd = ~ud.paused;
- ud.paused = 1; % assume we're starting from pause
- set(hfig,'userdata',ud);
- ShowMovieFrame(hfig);
- if upd, UpdateGUIControls(hfig); end
-
- % --------------------------------------------------------
- function cb_step_fwd(hbutton, eventStruct, hfig)
- % Step one frame forward callback
-
- % If in fwdbk mode,
- % Ignore looping mode
- % We always go from fwd to bkwd when step_fwd pressed at last frame
- % When we're at frame 1, we must continue to frame 2 regardless of the
- % looping setting since we don't know "how" we got there
-
- if nargin<3, hfig = gcbf; end
- ud = get(hfig,'userdata');
-
- if ud.fbmode,
- % fwd/back playback mode
- if ~ud.fbrev,
- % not in reverse ... increment fwd
- if ud.currframe >= ud.numFrames,
- % hit last frame ... go to reverse
- ud.currframe = ud.currframe-1;
- ud.fbrev=1; % reverse playback
- else
- ud.currframe = ud.currframe+1;
- end
- else
- % in reverse ... decrement
- if ud.currframe == 2,
- % fwd/back hit when frame 2 displayed
- % move to frame 1 in reverse mode
- ud.fbrev=0; % no more reverse playback
- end
- ud.currframe = ud.currframe-1;
- end
- else
- % Not fwd/back mode
- if ud.currframe >= ud.numFrames,
- if ~ud.loopmode,
- return
- end
- ud.currframe = 1;
- else
- ud.currframe = ud.currframe+1;
- end
- end
-
- ud.nextframe = ud.currframe;
- upd = ~ud.paused;
- ud.paused = 1; % assume we're starting from pause
- set(hfig,'userdata',ud);
- ShowMovieFrame(hfig);
- if upd, UpdateGUIControls(hfig); end
-
- % --------------------------------------------------------
- function cb_ffwd(hbutton, eventStruct, hfig)
- % Fast forward button callback
- if nargin<3, hfig = gcbf; end
- ud = get(hfig,'userdata');
- stepsize = 10; %(sazzad_ff)
-
- if ud.fbmode,
- % In fwd/rev playback mode
- if ~ud.fbrev,
- % not in reverse ... increment fwd
- if ud.currframe >= ud.numFrames-stepsize,
- % hit last frame ... go to reverse
- ud.currframe = ud.numFrames;
- ud.fbrev=1; % reverse playback
- else
- ud.currframe = ud.currframe+stepsize;
- end
- else
- % in reverse mode
- if ud.currframe <= stepsize,
- ud.fbrev=0; % no more reverse playback
- ud.currframe = stepsize+1; % so next subtraction brings us to frame 1
- end
- ud.currframe = ud.currframe-stepsize;
- end
- else
- % Not in fwd/rev playback mode
- ud.currframe = ud.currframe + stepsize;
- if ud.currframe > ud.numFrames,
- if ~ud.loopmode,
- if ud.currframe == ud.numFrames+stepsize,
- return
- end
- ud.currframe = ud.numFrames;
- else
- ud.currframe = ud.currframe-ud.numFrames;
- end
- end
- end
-
- ud.nextframe = ud.currframe;
- upd = ~ud.paused;
- ud.paused = 1; % assume we're starting from pause
- set(hfig,'userdata',ud);
- ShowMovieFrame(hfig);
- if upd, UpdateGUIControls(hfig); end
-
- % --------------------------------------------------------
- function cb_goto_end(hbutton, eventStruct, hfig)
- % Goto end button callback
- %
- % NOTE: For fwd/bkwd mode, goes to last frame as usual,
- % and enters bkwd playback. No special code needed.
-
- if nargin<3, hfig = gcbf; end
- ud = get(hfig,'userdata');
- if ud.currframe ~= ud.numFrames,
- ud.currframe = ud.numFrames;
- ud.nextframe = ud.currframe;
- set(hfig,'userdata',ud);
- ShowMovieFrame(hfig);
- end
-
- % --------------------------------------------------------
- function cb_loop(hbutton, eventStruct, hfig)
- % Loop button callback
- % Store loopmode state
- if nargin<3, hfig = gcbf; end
- ud = get(hfig,'userdata');
- ud.loopmode = ~ud.loopmode;
- set(hfig,'userdata',ud);
-
- ReactToStoredLoopMode(hfig);
-
-
- % --------------------------------------------------------
- function cb_fbmode(hbutton, eventStruct, hfig)
- % Fwd/Bkwd playback button callback
- % Store state
- if nargin<3, hfig = gcbf; end
- ud = get(hfig,'userdata');
- ud.fbmode = ~ud.fbmode;
- ud.fbrev = 0; % Reset direction when fb status changes
- set(hfig,'userdata',ud);
-
- ReactToStoredFBMode(hfig);
-
- % --------------------------------------------------------
- function cb_truesize(hco, eventStruct, hfig)
-
- if nargin<3, hfig=gcbf; end
- SetupMovieFrame(hfig);
-
- % --------------------------------------------------------
- function ReactToStoredLoopMode(hfig)
-
- icons = get_icons_from_fig(hfig);
- ud = get(hfig,'userdata');
- if ud.loopmode,
- icon = icons.loop_on;
- tip = 'Repeat: On';
- else
- icon = icons.loop_off;
- tip = 'Repeat: Off';
- end
- hLoopButton = findobj(hfig,'tag','loopbutton');
- set(hLoopButton,'cdata',icon,'tooltip',tip);
-
- % --------------------------------------------------------
- function ReactToStoredFBMode(hfig)
-
- % Update button icon/tip
- icons = get_icons_from_fig(hfig);
- ud = get(hfig,'userdata');
- if ud.fbmode,
- icon = icons.fwdbk_play_on;
- tip = 'Forward/backward playback';
- else
- icon = icons.fwdbk_play_off;
- tip = 'Normal playback';
- end
- hFBButton = findobj(hfig,'tag','fbbutton');
- set(hFBButton,'cdata',icon,'tooltip',tip);
-
- % Update frame readout and tooltip
- UpdateFrameReadout(ud);
- UpdateFrameReadoutTooltip(ud);
-
- % --------------------------------------------------------
- function [r,c,f] = MovieSizeInfo(A, fmt)
- % Determine rows, columns, and frames for each movie format
- % 'S' Standard Movie structure
- % 'I' MxNxF
- % 'RGB' MxNx3xF
-
- switch fmt
- case 'I'
- r=size(A,1);
- c=size(A,2);
- f=size(A,3);
- case 'RGB'
- r=size(A,1);
- c=size(A,2);
- f=size(A,4);
- case 'S'
- r=size(A(1).cdata,1);
- c=size(A(1).cdata,2);
- f=length(A);
- end
-
- % --------------------------------------------------------
- function LoadMovie(hfig, A, fmt, varname, fps)
-
- % Store basic movie info:
- %
- ud = get(hfig,'userdata');
- ud.MovieFormat = fmt;
- ud.Movie = A;
- ud.fps = fps;
- ud.varName = varname;
- [r,c,f] = MovieSizeInfo(A,fmt);
- ud.frameRows = r;
- ud.frameCols = c;
- ud.numFrames = f;
- ud.currframe = 1;
- ud.nextframe = 1;
-
- % Store data, set name in figure title
- set(hfig, ...
- 'userdata', ud, ...
- 'name', sprintf('Movie Player: %s', ud.varName));
-
- % Update viewer
- %
- set(hfig,'name', sprintf('Movie Player: %s', ud.varName));
- SetupUpdateFunction(hfig); % Select playback function
- SetupMovieFrame(hfig); % Shrink figure to movie size
- SetupTimer(hfig); % Updates FPS status readout via SetFPS
- ShowMovieFrame(hfig); % Updates frame counter status readout
- UpdateFrameSizeReadout(hfig); % Updates frame size readout
- ReactToStoredLoopMode(hfig); % Initial update of button icon
- ReactToStoredFBMode(hfig); % Initial update of button icon
-
- % --------------------------------------------------------
- function SetupMovieFrame(hfig)
- % Sets up frame sizes, window sizes, etc
- % Leaves existing image in display
-
- ud = get(hfig,'userdata');
- rows=ud.frameRows;
- cols=ud.frameCols;
-
- % Adjust image limits and axis limits appropriately
- set(ud.himage,'xdata', 1:cols, 'ydata', 1:rows);
- % Do a "truesize" like operation
- set(ud.haxis, ...
- 'xlim',[1 cols], ...
- 'ylim',[1 rows], ...
- 'units','pix', ...
- 'pos',[1 1 cols rows]);
-
- % Set figure to be an exact fit around the axis
- set(ud.hfig,'units','pix');
- figpos = get(ud.hfig,'pos');
- newpos = [figpos(1:2) cols rows];
- set(ud.hfig,'pos',newpos);
-
- set(ud.haxis,'units','norm'); % allow stretching again
-
-
- % --------------------------------------------------------
- function ShowMovieFrame(hfig, fast)
-
- % Update video image
- ud = get(hfig,'userdata');
- feval(ud.UpdateImageFcn, ud);
-
- % Update frame counter
- if (nargin > 1) && fast,
- if (ud.currframe==1) || (rem(ud.currframe,10)==0),
- UpdateFrameReadout(ud);
- end
- else
- UpdateFrameReadout(ud);
- end
-
- % --------------------------------------------------------
- function y = GetExportFrame(ud)
- switch ud.MovieFormat
- case 'I'
- y = ud.Movie(:,:,ud.currframe);
- case 'RGB'
- y = ud.Movie(:,:,:,ud.currframe);
- case 'S'
- y = ud.Movie(ud.currframe).cdata;
- otherwise
- error('Unrecognized movie format.');
- end
-
- % --------------------------------------------------------
- function UpdateIntensityImage(ud)
- set(ud.himage,'cdata', ud.Movie(:,:,ud.currframe));
-
- function UpdateRGBImage(ud)
- set(ud.himage,'cdata', ud.Movie(:,:,:,ud.currframe));
-
- function UpdateStructImage(ud)
- set(ud.himage,'cdata', ud.Movie(ud.currframe).cdata);
-
- % --------------------------------------------------------
- function SetupUpdateFunction(hfig)
- % Register image update function
-
- ud = get(hfig,'userdata');
- switch ud.MovieFormat
- case 'I'
- ud.UpdateImageFcn = @UpdateIntensityImage;
- case 'RGB'
- ud.UpdateImageFcn = @UpdateRGBImage;
- case 'S'
- ud.UpdateImageFcn = @UpdateStructImage;
- otherwise
- error('Unrecognized movie format.');
- end
- set(hfig,'userdata',ud);
-
-
- % --------------------------------------------------------
- function SetupTimer(hfig)
-
- % Setup timer
- h = timer( ...
- 'ExecutionMode','fixedRate', ...
- 'TimerFcn', @TimerTickFcn, ...
- 'StopFcn', @TimerStopFcn, ...
- 'BusyMode', 'drop', ...
- 'TasksToExecute', inf);
-
- % Store fig handle in timer
- udtimer.hfig = hfig;
- set(h,'userdata',udtimer);
-
- % Store timer handle in figure
- ud = get(hfig,'userdata');
- ud.htimer = h;
- set(hfig,'userdata', ud);
-
- SetFPS(hfig);
-
- % --------------------------------------------------------
- function y = ext_getFPS(hfig)
- ud = get(hfig,'userdata');
- y = ud.fps;
-
- % --------------------------------------------------------
- function ext_setFPS(hfig, fps)
-
- ud = get(hfig,'userdata');
- ud.fps = fps;
- set(hfig,'userdata',ud);
- SetFPS(hfig);
-
-
- % --------------------------------------------------------
- function SetFPS(hfig)
- % Set frames per second for playback
-
- % Cannot change period while movie is running
- % Must stop timer, change frame rate, then restart timer
-
- ud = get(hfig,'userdata');
- isRunning = strcmp(get(ud.htimer,'Running'),'on');
- % isPaused = ud.paused;
- if isRunning,
- cb_play([],[],ud.hfig); % pause
- end
- set(ud.htimer,'Period', 1./ud.fps);
- if isRunning,
- cb_play([],[],ud.hfig);
- % ud = get(hfig,'userdata');
- % ud.paused = isPaused;
- % set(hfig,'userdata',ud);
- end
- UpdateFPSReadout(hfig);
-
- % -------------------------------------------------------------------------
- function UpdateFrameSizeReadout(hfig)
- % Update current frame size readout in status bar
-
- ud = get(hfig,'UserData');
- sizeStr = sprintf('%dx%d', ud.frameRows, ud.frameCols);
- readoutStr = sprintf('%s:%s', ud.MovieFormat, sizeStr);
-
- % Build tooltip for frame format/size status bar readout
- switch ud.MovieFormat
- case 'I', s='Intensity';
- case 'S', s='Structure';
- case 'RGB', s='RGB';
- end
- CR = sprintf('\n');
- tipStr = [s ' format' CR sprintf('%d rows x %d cols', ud.frameRows, ud.frameCols)];
-
- set(ud.hStatusBar.FrameSize,'string',readoutStr,'tooltip',tipStr);
-
- % -------------------------------------------------------------------------
- function currentFrame=UpdateFrameReadout(ud)
- % Update current frame number readout in status bar
- % If fwd/bkwd mode not on,
- % show "current frame : total frames"
- % If on,
- % show "+/- current frame : total frames"
- % where + means fwd play, - means bkwd play
-
- %current frame value: currframe, total frame value: numFrames (sazzad)
- str = sprintf('%d:%d',ud.currframe,ud.numFrames);
-
- if ud.fbmode,
- if ud.fbrev,
- dir='-';
- else
- dir='+';
- end
- str = [dir str];
- end
-
- getCurrFrame(ud.currframe); % pass current frame number to external func
-
- set(ud.hStatusBar.FrameNum, 'string', str);
-
- % -------------------------------------------------------------------------
- function UpdateFrameReadoutTooltip(ud)
-
- tStr = 'Current Frame : Total Frames';
- if ud.fbmode,
- tStr = [tStr sprintf('\n') '+: Fwd dir, -:Bkwd dir'];
- end
- set(ud.hStatusBar.FrameNum, 'tooltip', tStr);
-
- % -------------------------------------------------------------------------
- function UpdateFPSReadout(hfig)
- % Update frames per second readout in status bar
-
- ud = get(hfig,'UserData');
- str = sprintf('FPS: %d',ud.fps);
- set(ud.hStatusBar.FPS,'string',str);
-
- % --------------------------------------------------------
- function EditProperties(hfig)
- % Get frames per second in dialog box
-
- ud = get(hfig,'userdata');
-
- while 1, % infinite loop in case user enters invalid information
- % Get dialog
- prompt={'Desired playback rate (fps):', ...
- 'Colormap expression:'};
- def={num2str(ud.fps), ud.cmapexpr};
- dlgTitle='Movie Player Properties';
- lineNo=1;
- AddOpts.Resize='off';
- AddOpts.WindowStyle='modal';
- AddOpts.Interpreter='none';
- answer=inputdlg(prompt,dlgTitle,lineNo,def,AddOpts);
-
- if ~isempty(answer), % cancel pressed?
- % Error check
-
- % Frame rate:
- %
- new_fps = str2num(answer{1});
- if new_fps > 0,
- if ~isequal(new_fps, ud.fps), % change made?
- % Grab userdata now in case changes were made
- % while dialog was open
- ext_setFPS(hfig,new_fps);
- end
- else
- hwarn = warndlg({'Invalid frames/second entered.','Must be > 0.'}, 'Movie Player Error','modal');
- waitfor(hwarn);
- continue;
- end
-
- % Colormap:
- %
- new_cmapexpr = deblank(answer{2});
- new_cmap = eval(new_cmapexpr, '[]');
- if isempty(new_cmap),
- hwarn = warndlg('Invalid colormap expression.','Movie Player Error','modal');
- waitfor(hwarn);
- continue;
- else
- if ~isequal(new_cmapexpr, ud.cmapexpr), % change made?
- % Grab userdata now in case changes were made
- % while dialog was open
- ud = get(hfig,'userdata');
- ud.cmapexpr = new_cmapexpr;
- ud.cmap = new_cmap;
- set(hfig, 'userdata',ud, 'colormap',new_cmap);
- end
- end
- end
- break % stop infinite loop
- end
-
- % --------------------------------------------------------
- function EditFrameNum(hfig)
- % Get manually specified frame number in dialog box
- % "Jump to" operation
-
- % Initialize to last "jump to" value, NOT to the current frame
- % This way, the edit operation becomes useful for continually
- % jumping to a particular frame
-
- ud = get(hfig,'userdata');
-
- while 1, % infinite loop in case user enters invalid information
- % Show dialog
- prompt = {'Jump to frame:'};
- def = {num2str(ud.jumpto_frame)};
- dlgTitle = 'Movie Player Properties';
- lineNo = 1;
- AddOpts.Resize = 'off';
- AddOpts.WindowStyle = 'normal';
- AddOpts.Interpreter = 'none';
- answer = inputdlg(prompt,dlgTitle,lineNo,def,AddOpts);
-
- if ~isempty(answer), % cancel pressed?
- % Error check
-
- % Currently Displayed Frame:
- %
- new_jumpto = str2num(answer{1});
- if (new_jumpto > 0) && (new_jumpto <= ud.numFrames),
- % Note: always perform update, even if value remains the same
- % That's because the currently displayed frame may have
- % changed behind our backs. Even if we re-grab userdata,
- % it's changing all the time.
-
- % Get properties again, in case something has
- % changed behind our backs while dialog was open
- ud = get(hfig,'userdata');
- ud.currframe = new_jumpto;
- ud.nextframe = new_jumpto;
- ud.jumpto_frame = new_jumpto;
-
- % jump puts player in pause mode if currently stopped
- isRunning = strcmp(get(ud.htimer,'Running'),'on');
- isStopped = ~isRunning && ~ud.paused;
- ud.paused = 1;
-
- set(hfig,'userdata',ud);
- ShowMovieFrame(hfig);
- if isStopped, UpdateGUIControls(hfig); end
- else
- hwarn = warndlg({'Invalid frame number.'}, 'Movie Player Error','modal');
- waitfor(hwarn);
- continue
- end
- end
- break % stop infinite loop
- end
-
- % --------------------------------------------------------
- function cb_properties(hco, eventStruct)
- EditProperties(gcbf);
-
- function cb_jumpto(hco, eventStruct)
- EditFrameNum(gcbf);
-
- % --------------------------------------------------------
- function cb_export_imview(hco, eventStruct)
- % Export current image frame to IMVIEW or base workspace.
-
- hfig = gcbf;
- ud = get(hfig,'userdata');
- v = GetExportFrame(ud);
- if exist('imview','file'),
- try
- imview(v);
- catch
- warndlg(sprintf('Failed when calling IMVIEW:\n\n%s', lasterr), ...
- 'MPLAY Export Error', 'modal');
- end
- else
- % Export to workspace
- varname = 'mplay_export';
- fprintf(['Exported current image frame to base workspace\n' ...
- 'Variable name: %s\n\n'], varname);
- assignin('base',varname,v);
- end
-
- % --------------------------------------------------------
- function TimerTickFcn(hco, user)
-
- ud = get(hco,'userdata'); % hco = timer object
- hfig = ud.hfig;
- ud = get(hfig,'userdata');
- ud.currframe = ud.nextframe;
- ShowMovieFrame(hfig, 1); % "fast" display
-
- % Increment frame or stop playback if finished
- if (ud.currframe == ud.numFrames),
- % Last frame of movie just displayed
-
- if ud.fbmode % && ~ud.fbrev, % unnecessary qualifier --- always will be false here
- ud.fbrev = 1; % going into reverse playback mode
- ud.nextframe = ud.currframe-1;
- shouldStop = 0;
-
- % elseif ud.fbmode && ud.fbrev,
- % error('how did this happen? ==end');
- % shouldStop = 1;
-
- else
- ud.nextframe = 1; % loop back to beginning
- shouldStop = 1;
- end
-
- % If we hit this point, the timer ran us to the end of
- % the movie. In particular, the user did not hit stop.
- % Now, if pause is on, it's due to manual interaction with
- % the fwd/back buttons, and not due to actual pausing,
- % obvious since we're still running and is why we're here.
- % Turn off pause:
- ud.paused = 0;
-
- elseif (ud.currframe == 1),
- % First frame of movie just displayed
- if ud.fbmode && ud.fbrev,
- ud.fbrev = 0; % going into fwd playback mode
- ud.nextframe = ud.currframe+1;
- shouldStop = 1;
- else
- ud.nextframe = 2; % ud.currframe+1
- shouldStop = 0;
- end
-
- else
- if ud.fbmode && ud.fbrev,
- ud.nextframe = ud.nextframe - 1; % next frame, reverse play
- else
- ud.nextframe = ud.nextframe + 1; % next frame, fwd play
- end
- shouldStop = 0;
- end
- set(hfig,'userdata',ud);
-
- if shouldStop && ~ud.loopmode, % no looping - stop now
- stop(ud.htimer); % stop playback
- end
-
- % --------------------------------------------------------
- function TimerStopFcn(hco, user)
- % Keep this here, not in cb_stop
- % Could have stopped from stop button (eg, gone thru cb_stop)
- % but also could have stopped here due to end of movie
-
- ud = get(hco,'userdata');
- do_timer_stop(ud.hfig);
-
- % --------------------------------------------------------
- function do_timer_stop(hfig)
-
- ud = get(hfig,'userdata');
- % ShowMovieFrame(hfig);
- UpdateFrameReadout(ud);
-
- % Set play icon, brighter
- icons = get_icons_from_fig(hfig);
- hPlay = findobj(ud.htoolbar, 'tag','Play/Pause');
- set(hPlay, ...
- 'tooltip', 'Play', ...
- 'cdata', icons.play_on);
- UpdateGUIControls(hfig);
-
- % --------------------------------------------------------
- function z = mergefields(varargin)
- %MERGEFIELDS Merge fields into one structure
- % Z = MERGEFIELDS(A,B,C,...) merges all fields of input structures
- % into one structure Z. If common field names exist across input
- % structures, values from later input arguments prevail.
- %
- % Example:
- % x.one=1; x.two=2; % Define structures
- % y.two=-2; y.three=3; % containing a common field (.two)
- % z=mergefields(x,y) % => .one=1, .two=-2, .three=3
- % z=mergefields(y,x) % => .one=1, .two=2, .three=3
- %
- % See also SETFIELD, GETFIELD, RMFIELD, ISFIELD, FIELDNAMES.
-
- % Copyright 1984-2003 The MathWorks, Inc.
- % $Revision: $ $Date: $
-
- z=varargin{1};
- for i=2:nargin,
- f=fieldnames(varargin{i});
- for j=1:length(f),
- z.(f{j}) = varargin{i}.(f{j});
- end
- end
-
-
-