# videoWriter

## PURPOSE

videoWriter class constructor

## SYNOPSIS

function vw = videoWriter(url, varargin)

## DESCRIPTION

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

       vw = videoWriter(url)
         Opens the given video file for writing 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.

       vw = videoWriter(url,..., 'plugin',pluginName, ...)
       vw = videoWriter(url,pluginName)
         Opens the file using the specified plugin implementation.
         Available plugins include:

         'DirectShow': preferred method on Windows
           - Only available on Windows
           - See INSTALL.dshow.txt for installation instructions
           - 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.

       vw = videoWriter(url, ..., param,arg,...)
         Allows the user to pass extra configuration arguments to plugin.
         At present, all parameter names are case sensitive (but in the
         future they may become case-insensitive).

         The following parameters are supported by current plugins:

                            Plugin
         Parameter      ffmpeg* DShow  Implementation Notes
         ---------      ------- -----  -----------------------------
         width             X      X    Width of the encoded video.  Most
                                       codecs require width to be divisible
                                       by 2, 4, or 8.  Most users will want
                                       to explicitly pass this parameter.
                                       The addframe method will
                                       automatically resize any images
                                       according to the value chosen here
                                       (or a default value if none is
                                       specified here).

         height            X      X    Height of the encoded video.  Most
                                       codecs require height to be divisible
                                       by 2, 4, or 8.  Most users will want
                                       to explicitly pass this parameter.
                                       The addframe method will
                                       automatically resize any images
                                       according to the value chosen here
                                       (or a default value if none is
                                       specified here).

         codec             X      X    A string specifying the encoder to
                                       use.  The exact set of possible
                                       codecs is highly system-dependent.
                                       Most users will want to explicitly
                                       pass this parameter.  To see a list
                                       of available codecs on a specific
                                       machine, run:
                                         codecs = videoWriter([],'codecs');

         fourcc                   X    For the DirectShow plugin, this is a
                                       synonym for 'codec'.

         fps               X      X    Frame rate of the recorded video.
                                       Note that some codecs only work with
                                       some frame rates. 15, 24, 25, 29.97,
                                       and 30 should work with most codecs.

         framesPerSecond   X      X    An alias for fps.

         fpsNum, fpsDenom  X      X    This pair of parameters allows frames
                                       per second to be specified as a
                                       rational number.  Either both or
                                       neither parameter must be given.

         framesPerSecond_num           Alias for fpsNum, fpsDenom pair.
         framesPerSecond_denom
                           X      X

         bitRateTolerance  X           For supporting codecs, the actual
                                       bit rate is allowed to vary by +/-
                                       this value.

         showCompressionDialog    X    If true (a non-zero number), a dialog
                                       box is presented to the user allowing
                                       precise manual selection of the codec
                                       and its parameters.  Note: sometimes
                                       the dialog does not received focus
                                       automatically so you'll need to
                                       ALT-TAB to get to it.

         codecParams              X    A MIME Base64-encoded string describing
                                       the codec setup parameters for a
                                       DirectShow codec.  The contents of this
                                       string are very codec-specific.  Often,
                                       The best ways to come up with a string
                                       like this are to first create a
                                       videoWriter with the
                                       'showCompressionDialog' option enabled,
                                       choose the desired settings, then use
                                       the GETINFO method to extract the
                                       'codecParams' value.  Note that this
                                       representation is the same as used by
                                       VirtualDub 1.6 and 1.7 in its Sylia
                                       Script files.  Nearly all useful
                                       DirectShow codecs can only be
                                       configured with 'codecParams' and they
                                       ignore the separate 'bitRate' and
                                       'gopSize' parameters given below.

         bitRate           X      x    Target bits/sec of the encoded video.
                                       Supported by most ffmpeg codecs.
                                       To see whether a particular codec uses
                                       the bitRate parameter, run the
                                       testBitRate function in the tests/
                                       subdirectory (NOTE: very few DirectShow
                                       codecs support it).

         gopSize           X      x    Maximum period between keyframes.  GOP
                                       stands for  "group of pictures" in MPEG
                                       lingo.  Supported by most ffmpeg
                                       codecs.  To see whether a particular
                                       codec uses the gopSize parameter, run
                                       the testGopSize function in the tests/
                                       subdirectory (NOTE: very few DirectShow
                                       codecs support it).

         maxBFrames        X           For MPEG codecs, gives the max
                                       number of bidirectional frames in a
                                       group of pictures (GOP).

      codecs = videoWriter([],'codecs')
      codecs = videoWriter([],pluginName,'codecs')
      codecs = videoWriter([],'codecs','plugin',pluginName)
        Queries the backend for a list of the valid codecs that may be used
        with the 'codec' plugin parameter.

     Once you are done using the videoWriter, 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 videoWriter to create
     a video of continually adding more motion blur to an image:

       % Construct a videoWriter object
       vw = videoWriter('writertest.avi', ...
                        'width',320, 'height',240, 'codec','xvid');
       img = imread('peppers.png');
       h = fspecial('motion',10,5);
       for i=1:100
         addframe(vw, img);
         img = imfilter(img, h);
       end
       vw=close(vw);

     SEE ALSO:
       buildVideoMex
       videoWriter/addframe
       videoWriter/close
       videoReader

    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:

## SUBFUNCTIONS

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

## SOURCE CODE

    0001 function vw = videoWriter(url, varargin)
    0002 % videoWriter class constructor
    0003 %   Creates a object that writes video files.  We use a plugin
    0004 %   architecture in the backend to do the actual writing.  For example,
    0005 %   on Windows, DirectShow will typically be used and on Linux, the
    0006 %   ffmpeg library is often used.
    0007 %
    0008 %   vw = videoWriter(url)
    0009 %     Opens the given video file for writing 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 %   vw = videoWriter(url,..., 'plugin',pluginName, ...)
    0015 %   vw = videoWriter(url,pluginName)
    0016 %     Opens the file using the 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 %       - The URL parameter should be a filename.
    0023 %         - As a convenience, all forward slashes ('/') are automatically
    0024 %           converted to backslashes ('\')
    0025 %
    0026 %     'ffmpegPopen2': safe method on Linux
    0027 %       - Only supported on GNU/Linux (might work on BSD systems too like Mac
    0028 %         OS X, but this is untested)
    0029 %       - See INSTALL.ffmpeg.txt for installation instructions
    0030 %       - Creates a separate server process to communicate with the
    0031 %         ffmpeg libraries.
    0032 %         - Works when the system's version of GCC is very different from
    0033 %           the one that MathWorks used to compile Matlab.
    0034 %         - Isolates ffmpeg errors so they typically cannot crash
    0035 %           Matlab.
    0036 %         - May allow for more flexible distribution terms for your code
    0037 %           when it uses videoIO (ffmpeg may be compiled with either
    0038 %           the LGPL or GPL license).
    0039 %
    0040 %     'ffmpegDirect': low-overhead method on Linux
    0041 %       - same as ffmpegPopen2, but the ffmpeg libraries are loaded
    0042 %         directly by the MEX file.
    0043 %         - May not work if MathWorks' and your version of GCC are
    0044 %           incompatible.
    0045 %         - Slightly faster than ffmpegPopen2 since there is no
    0046 %           interprocess communication overhead.
    0047 %
    0048 %   vw = videoWriter(url, ..., param,arg,...)
    0049 %     Allows the user to pass extra configuration arguments to plugin.
    0050 %     At present, all parameter names are case sensitive (but in the
    0051 %     future they may become case-insensitive).
    0052 %
    0053 %     The following parameters are supported by current plugins:
    0054 %
    0055 %                        Plugin
    0056 %     Parameter      ffmpeg* DShow  Implementation Notes
    0057 %     ---------      ------- -----  -----------------------------
    0058 %     width             X      X    Width of the encoded video.  Most
    0059 %                                   codecs require width to be divisible
    0060 %                                   by 2, 4, or 8.  Most users will want
    0061 %                                   to explicitly pass this parameter.
    0062 %                                   The addframe method will
    0063 %                                   automatically resize any images
    0064 %                                   according to the value chosen here
    0065 %                                   (or a default value if none is
    0066 %                                   specified here).
    0067 %
    0068 %     height            X      X    Height of the encoded video.  Most
    0069 %                                   codecs require height to be divisible
    0070 %                                   by 2, 4, or 8.  Most users will want
    0071 %                                   to explicitly pass this parameter.
    0072 %                                   The addframe method will
    0073 %                                   automatically resize any images
    0074 %                                   according to the value chosen here
    0075 %                                   (or a default value if none is
    0076 %                                   specified here).
    0077 %
    0078 %     codec             X      X    A string specifying the encoder to
    0079 %                                   use.  The exact set of possible
    0080 %                                   codecs is highly system-dependent.
    0081 %                                   Most users will want to explicitly
    0082 %                                   pass this parameter.  To see a list
    0083 %                                   of available codecs on a specific
    0084 %                                   machine, run:
    0085 %                                     codecs = videoWriter([],'codecs');
    0086 %
    0087 %     fourcc                   X    For the DirectShow plugin, this is a
    0088 %                                   synonym for 'codec'.
    0089 %
    0090 %     fps               X      X    Frame rate of the recorded video.
    0091 %                                   Note that some codecs only work with
    0092 %                                   some frame rates. 15, 24, 25, 29.97,
    0093 %                                   and 30 should work with most codecs.
    0094 %
    0095 %     framesPerSecond   X      X    An alias for fps.
    0096 %
    0097 %     fpsNum, fpsDenom  X      X    This pair of parameters allows frames
    0098 %                                   per second to be specified as a
    0099 %                                   rational number.  Either both or
    0100 %                                   neither parameter must be given.
    0101 %
    0102 %     framesPerSecond_num           Alias for fpsNum, fpsDenom pair.
    0103 %     framesPerSecond_denom
    0104 %                       X      X
    0105 %
    0106 %     bitRateTolerance  X           For supporting codecs, the actual
    0107 %                                   bit rate is allowed to vary by +/-
    0108 %                                   this value.
    0109 %
    0110 %     showCompressionDialog    X    If true (a non-zero number), a dialog
    0111 %                                   box is presented to the user allowing
    0112 %                                   precise manual selection of the codec
    0113 %                                   and its parameters.  Note: sometimes
    0114 %                                   the dialog does not received focus
    0115 %                                   automatically so you'll need to
    0116 %                                   ALT-TAB to get to it.
    0117 %
    0118 %     codecParams              X    A MIME Base64-encoded string describing
    0119 %                                   the codec setup parameters for a
    0120 %                                   DirectShow codec.  The contents of this
    0121 %                                   string are very codec-specific.  Often,
    0122 %                                   The best ways to come up with a string
    0123 %                                   like this are to first create a
    0124 %                                   videoWriter with the
    0125 %                                   'showCompressionDialog' option enabled,
    0126 %                                   choose the desired settings, then use
    0127 %                                   the GETINFO method to extract the
    0128 %                                   'codecParams' value.  Note that this
    0129 %                                   representation is the same as used by
    0130 %                                   VirtualDub 1.6 and 1.7 in its Sylia
    0131 %                                   Script files.  Nearly all useful
    0132 %                                   DirectShow codecs can only be
    0133 %                                   configured with 'codecParams' and they
    0134 %                                   ignore the separate 'bitRate' and
    0135 %                                   'gopSize' parameters given below.
    0136 %
    0137 %     bitRate           X      x    Target bits/sec of the encoded video.
    0138 %                                   Supported by most ffmpeg codecs.
    0139 %                                   To see whether a particular codec uses
    0140 %                                   the bitRate parameter, run the
    0141 %                                   testBitRate function in the tests/
    0142 %                                   subdirectory (NOTE: very few DirectShow
    0143 %                                   codecs support it).
    0144 %
    0145 %     gopSize           X      x    Maximum period between keyframes.  GOP
    0146 %                                   stands for  "group of pictures" in MPEG
    0147 %                                   lingo.  Supported by most ffmpeg
    0148 %                                   codecs.  To see whether a particular
    0149 %                                   codec uses the gopSize parameter, run
    0150 %                                   the testGopSize function in the tests/
    0151 %                                   subdirectory (NOTE: very few DirectShow
    0152 %                                   codecs support it).
    0153 %
    0154 %     maxBFrames        X           For MPEG codecs, gives the max
    0155 %                                   number of bidirectional frames in a
    0156 %                                   group of pictures (GOP).
    0157 %
    0158 %  codecs = videoWriter([],'codecs')
    0159 %  codecs = videoWriter([],pluginName,'codecs')
    0160 %  codecs = videoWriter([],'codecs','plugin',pluginName)
    0161 %    Queries the backend for a list of the valid codecs that may be used
    0162 %    with the 'codec' plugin parameter.
    0163 %
    0164 % Once you are done using the videoWriter, make sure you call CLOSE so
    0165 % that any system resources allocated by the plugin may be released.
    0166 % Here's a simple example of how you might use videoWriter to create
    0167 % a video of continually adding more motion blur to an image:
    0168 %
    0169 %   % Construct a videoWriter object
    0170 %   vw = videoWriter('writertest.avi', ...
    0171 %                    'width',320, 'height',240, 'codec','xvid');
    0172 %   img = imread('peppers.png');
    0173 %   h = fspecial('motion',10,5);
    0174 %   for i=1:100
    0175 %     addframe(vw, img);
    0176 %     img = imfilter(img, h);
    0177 %   end
    0178 %   vw=close(vw);
    0179 %
    0180 % SEE ALSO:
    0181 %   buildVideoMex
    0182 %   videoWriter/addframe
    0183 %   videoWriter/close
    0184 %   videoReader
    0185 %
    0186 %Copyright (c) 2006 Gerald Dalley
    0187 %See "MIT.txt" in the installation directory for licensing details (especially
    0188 %when using this library on GNU/Linux).
    0189
    0190 if (numel(url)==0)
    0191   % static method call
    0192   if (mod(length(varargin),2) == 0)
    0193     plugin       = varargin{1};
    0194     staticMethod = varargin{2};
    0195     methodArgs   = {varargin{3:end}};
    0196   else
    0197     plugin       = defaultVideoIOPlugin;
    0198     staticMethod = varargin{1};
    0199     methodArgs   = {varargin{2:end}};
    0200   end
    0201   [plugin,methodArgs] = parsePlugin(plugin, methodArgs);
    0202
    0203   vw = feval(mexName(plugin), staticMethod, int32(-1), methodArgs{:});
    0204
    0205 else
    0206   % constructor call
    0207   if (mod(length(varargin),2) == 0)
    0208     plugin     = defaultVideoIOPlugin;
    0209     pluginArgs = varargin;
    0210   else
    0211     plugin     = varargin{1};
    0212     pluginArgs = {varargin{2:end}};
    0213   end
    0214   plugin = parsePlugin(plugin, pluginArgs);
    0215
    0216   vw = struct('plugin',mexName(plugin), 'handle',int32(-1), ...
    0217               'w',int32(-1), 'h',int32(-1));
    0218   vw = class(vw, 'videoWriter');
    0219   [pathstr, name, ext, versn] = fileparts(url);
    0220   strArgs = cell(size(pluginArgs));
    0221   for i=1:numel(pluginArgs), strArgs{i} = num2str(pluginArgs{i}); end
    0222   [vw.handle,vw.w,vw.h] = feval(vw.plugin, 'open', vw.handle, ...
    0223                                 fullfile(pathstr,[name ext versn]), ...
    0224                                 strArgs{:});
    0225 end
    0226
    0227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0228 function n = mexName(plugin)
    0229 n = ['videoWriter_' plugin];
    0230
    0231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0232 function [plugin,pluginArgs] = parsePlugin(plugin, pluginArgs)
    0233 if (length(pluginArgs) > 0)
    0234   [pluginSpecified,idx] = ismember('plugin', {pluginArgs{1:2:end}});
    0235   if pluginSpecified
    0236     plugin = pluginArgs{idx*2};
    0237     pluginArgs = { pluginArgs{1:idx*2-2}, pluginArgs{idx*2+1:end} };
    0238   end
    0239 end