# videoReader

## PURPOSE

videoReader class constructor

## SYNOPSIS

function vr = videoReader(url, varargin)

## DESCRIPTION

     videoReader class constructor
       Creates a object that reads video streams.  We use a plugin
       architecture in the backend to do the actual reading.  For example,
       on Windows, DirectShow will typically be used and on Linux, the
       ffmpeg library is often used.

       vr = videoReader(url)
         Opens the given video file for reading using the default plugin.
         On Windows, 'DirectShow' is used by default and on Linux,
         'ffmpegPopen2' is used by default.  For most plugins, the url will
         really be a filename.

       vr = videoReader(url, ..., 'plugin',pluginName, ...)
       vr = videoReader(url,pluginName, ...)
         Opens the file using the manually specified plugin implementation.
         Available plugins include:

         'DirectShow': preferred method on Windows
           - Only available on Windows
           - See INSTALL.dshow.txt for installation instructions
           - Can load virtually any video file that can be played in
             Microsoft's Windows Media Player.  Note that the correct codec
             must be installed to read a file.  For example, to read
             tests/numbers.3ivx.avi, the user must have installed an MPEG4
             codec such as 3ivx (www.3ivx.com), DivX (www.divx.com), or XviD
             (www.xvid.org).
           - The URL parameter should be a filename.
             - As a convenience, all forward slashes ('/') are automatically
               converted to backslashes ('\')

         'ffmpegPopen2': safe method on Linux
           - Only supported on GNU/Linux (might work on BSD systems too like Mac
             OS X, but this is untested)
           - See INSTALL.ffmpeg.txt for installation instructions
           - Creates a separate server process to communicate with the
             ffmpeg libraries.
             - Works when the system's version of GCC is very different from
               the one that MathWorks used to compile Matlab.
             - Isolates ffmpeg errors so they typically cannot crash
               Matlab.
             - May allow for more flexible distribution terms for your code
               when it uses videoIO (ffmpeg may be compiled with either
               the LGPL or GPL license).

         'ffmpegDirect': low-overhead method on Linux
           - same as ffmpegPopen2, but the ffmpeg libraries are loaded
             directly by the MEX file.
             - May not work if MathWorks' and your version of GCC are
               incompatible.
             - Slightly faster than ffmpegPopen2 since there is no
               interprocess communication overhead.

       vr = videoReader(url, ..., param,arg,...)
         Allows the user to pass extra configuration arguments to plugin.
         Currently no plugin arguments are supported right now.  In the
         future, we may allow the user to do things like have DirectShow
         automatically convert to grayscale, or give options to trade off
         speed with seeking precision.

     Once you have created a videoReader object, you must next call NEXT,
     SEEK, or STEP at least once so that it will read some frame from disk.
     *After* calling one of these methods, you may call GETFRAME as many
     times as you would like and it will decode and return the current frame
     (without advancing to a different frame).  GETINFO may be called at any
     time (even before NEXT, SEEK, or STEP).  It returns basic information
     about the video stream.  Once you are done using the videoReader, make
     sure you call CLOSE so that any system resources allocated by the plugin
     may be released.  Here's a simple example of how you might use
     videoReader:

       % take us to the videoReader directory since we know there's a video
       % file there.
       chdir(fileparts(which('videoReaderWrapper.cpp')));

       % Construct a videoReader object
       vr = videoReader('tests/numbers.uncompressed.avi');

       % Do some processing on the video and display the results
       avgIntensity = [];
       i = 1;
       figure;
       while (next(vr))
         img = getframe(vr);
         avgIntensity(i) = mean(img(:));
         subplot(121); imshow(img);        title('current frame');
         subplot(122); plot(avgIntensity); title('avg. intensity vs. frame');
         drawnow;      pause(0.1);         i = i+1;
       end
       vr = close(vr);

     SEE ALSO:
       buildVideoMex
       videoReader/close
       videoReader/getframe
       videoReader/getinfo
       videoReader/getnext
       videoReader/next
       videoReader/seek
       videoReader/step
       videoWriter

    Copyright (c) 2006 Gerald Dalley
    See "MIT.txt" in the installation directory for licensing details (especially
    when using this library on GNU/Linux).

## CROSS-REFERENCE INFORMATION

This function calls:

- defaultVideoIOPlugin pluginName = defaultVideoIOPlugin
- defaultVideoIOPlugin pluginName = defaultVideoIOPlugin
- defaultVideoIOPlugin pluginName = defaultVideoIOPlugin

This function is called by:

- FTrack FTRACK
- FlyTracker FLYTRACKER
- videoread VIDEOREAD Read an video file in a mannter compatible with Matlab's
- videoread VIDEOREAD Read an video file in a mannter compatible with Matlab's
- videoread VIDEOREAD Read an video file in a mannter compatible with Matlab's

## SUBFUNCTIONS

- function n = mexName(plugin)
- function [plugin,pluginArgs] = parsePlugin(plugin, pluginArgs)

## SOURCE CODE

    0001 function vr = videoReader(url, varargin)
    0002 % videoReader class constructor
    0003 %   Creates a object that reads video streams.  We use a plugin
    0004 %   architecture in the backend to do the actual reading.  For example,
    0005 %   on Windows, DirectShow will typically be used and on Linux, the
    0006 %   ffmpeg library is often used.
    0007 %
    0008 %   vr = videoReader(url)
    0009 %     Opens the given video file for reading using the default plugin.
    0010 %     On Windows, 'DirectShow' is used by default and on Linux,
    0011 %     'ffmpegPopen2' is used by default.  For most plugins, the url will
    0012 %     really be a filename.
    0013 %
    0014 %   vr = videoReader(url, ..., 'plugin',pluginName, ...)
    0015 %   vr = videoReader(url,pluginName, ...)
    0016 %     Opens the file using the manually specified plugin implementation.
    0017 %     Available plugins include:
    0018 %
    0019 %     'DirectShow': preferred method on Windows
    0020 %       - Only available on Windows
    0021 %       - See INSTALL.dshow.txt for installation instructions
    0022 %       - Can load virtually any video file that can be played in
    0023 %         Microsoft's Windows Media Player.  Note that the correct codec
    0024 %         must be installed to read a file.  For example, to read
    0025 %         tests/numbers.3ivx.avi, the user must have installed an MPEG4
    0026 %         codec such as 3ivx (www.3ivx.com), DivX (www.divx.com), or XviD
    0027 %         (www.xvid.org).
    0028 %       - The URL parameter should be a filename.
    0029 %         - As a convenience, all forward slashes ('/') are automatically
    0030 %           converted to backslashes ('\')
    0031 %
    0032 %     'ffmpegPopen2': safe method on Linux
    0033 %       - Only supported on GNU/Linux (might work on BSD systems too like Mac
    0034 %         OS X, but this is untested)
    0035 %       - See INSTALL.ffmpeg.txt for installation instructions
    0036 %       - Creates a separate server process to communicate with the
    0037 %         ffmpeg libraries.
    0038 %         - Works when the system's version of GCC is very different from
    0039 %           the one that MathWorks used to compile Matlab.
    0040 %         - Isolates ffmpeg errors so they typically cannot crash
    0041 %           Matlab.
    0042 %         - May allow for more flexible distribution terms for your code
    0043 %           when it uses videoIO (ffmpeg may be compiled with either
    0044 %           the LGPL or GPL license).
    0045 %
    0046 %     'ffmpegDirect': low-overhead method on Linux
    0047 %       - same as ffmpegPopen2, but the ffmpeg libraries are loaded
    0048 %         directly by the MEX file.
    0049 %         - May not work if MathWorks' and your version of GCC are
    0050 %           incompatible.
    0051 %         - Slightly faster than ffmpegPopen2 since there is no
    0052 %           interprocess communication overhead.
    0053 %
    0054 %   vr = videoReader(url, ..., param,arg,...)
    0055 %     Allows the user to pass extra configuration arguments to plugin.
    0056 %     Currently no plugin arguments are supported right now.  In the
    0057 %     future, we may allow the user to do things like have DirectShow
    0058 %     automatically convert to grayscale, or give options to trade off
    0059 %     speed with seeking precision.
    0060 %
    0061 % Once you have created a videoReader object, you must next call NEXT,
    0062 % SEEK, or STEP at least once so that it will read some frame from disk.
    0063 % *After* calling one of these methods, you may call GETFRAME as many
    0064 % times as you would like and it will decode and return the current frame
    0065 % (without advancing to a different frame).  GETINFO may be called at any
    0066 % time (even before NEXT, SEEK, or STEP).  It returns basic information
    0067 % about the video stream.  Once you are done using the videoReader, make
    0068 % sure you call CLOSE so that any system resources allocated by the plugin
    0069 % may be released.  Here's a simple example of how you might use
    0070 % videoReader:
    0071 %
    0072 %   % take us to the videoReader directory since we know there's a video
    0073 %   % file there.
    0074 %   chdir(fileparts(which('videoReaderWrapper.cpp')));
    0075 %
    0076 %   % Construct a videoReader object
    0077 %   vr = videoReader('tests/numbers.uncompressed.avi');
    0078 %
    0079 %   % Do some processing on the video and display the results
    0080 %   avgIntensity = [];
    0081 %   i = 1;
    0082 %   figure;
    0083 %   while (next(vr))
    0084 %     img = getframe(vr);
    0085 %     avgIntensity(i) = mean(img(:));
    0086 %     subplot(121); imshow(img);        title('current frame');
    0087 %     subplot(122); plot(avgIntensity); title('avg. intensity vs. frame');
    0088 %     drawnow;      pause(0.1);         i = i+1;
    0089 %   end
    0090 %   vr = close(vr);
    0091 %
    0092 % SEE ALSO:
    0093 %   buildVideoMex
    0094 %   videoReader/close
    0095 %   videoReader/getframe
    0096 %   videoReader/getinfo
    0097 %   videoReader/getnext
    0098 %   videoReader/next
    0099 %   videoReader/seek
    0100 %   videoReader/step
    0101 %   videoWriter
    0102 %
    0103 %Copyright (c) 2006 Gerald Dalley
    0104 %See "MIT.txt" in the installation directory for licensing details (especially
    0105 %when using this library on GNU/Linux).
    0106
    0107 if (mod(length(varargin),2) == 0)
    0108   plugin     = defaultVideoIOPlugin;
    0109   pluginArgs = varargin;
    0110 else
    0111   plugin     = varargin{1};
    0112   pluginArgs = {varargin{2:end}};
    0113 end
    0114 [plugin,pluginArgs] = parsePlugin(plugin, pluginArgs);
    0115
    0116 vr = struct('plugin',mexName(plugin), 'handle',int32(-1));
    0117 vr = class(vr, 'videoReader');
    0118 [pathstr, name, ext, versn] = fileparts(url);
    0119 strArgs = cell(size(pluginArgs));
    0120 for i=1:numel(pluginArgs), strArgs{i} = num2str(pluginArgs{i}); end
    0121 vr.handle = feval(vr.plugin, 'open', vr.handle, ...
    0122   fullfile(pathstr,[name ext versn]), strArgs{:});
    0123
    0124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0125 function n = mexName(plugin)
    0126 n = ['videoReader_' plugin];
    0127
    0128 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0129 function [plugin,pluginArgs] = parsePlugin(plugin, pluginArgs)
    0130 if (length(pluginArgs) > 0)
    0131   [pluginSpecified,idx] = ismember('plugin', {pluginArgs{1:2:end}});
    0132   if pluginSpecified
    0133     plugin = pluginArgs{idx*2};
    0134     pluginArgs = { pluginArgs{1:idx*2-2}, pluginArgs{idx*2+1:end} };
    0135   end
    0136 end