email sol follow sol rss feed of the blog wishlist Sol::Code

ESCAPI

Extremely Simple Capture API

What?

Here you can find downloads and information on my "extremely simple capture API", or ESCAPI.

ESCAPI is a very simple DLL interface to use video capture devices (most commonly webcams, but also video in devices and other similar things).

Technically, it's just a simple wrapper over Media Foundation, DirectMedia (or DirectShow), but simplifies things as you don't need to link with the (more complex) SDKs. As such it does not do miracles. It only exposes the underlaying functionality in a very simple way; it cannot do what the underlaying API doesn't expose. This includes (but is not limited to) camera controls like white balance, contrast or color settings. Those are handled in device-by-device manner, unfortunately.

The miracle ESCAPI does do is turn the capture into a rather simple process.

The DLL is free for anyone to use as long as I'm not held responsible for anything.

Some uses that I know of include a store cataloging system (where it's used to take pictures of products), various machine-vision experiments, as well as a game for a science museum (where it's used to capture from three cameras at once). If you use it for something cool, tell me about it!

Troubleshooting

Make sure you include escapi.cpp in your project.

If you hit the "debugger detected - please close it down and restart" dialog, you may want to try to run:

regsvr32 /u "C:\Program Files\Common Files\Ahead\DSFilter\NeVideo.ax"

(at your own risk, naturally) - helped me.

I've received reports on several issues with a common element of 64bit windows - win2k, xp and vista. Since I've successfully run ESCAPI as is on 64bit win7 with a new webcam, I'm relatively certain it's a driver issue.

I've been involved in several projects that use ESCAPI, and webcam drivers do vary a lot. In some cases you couldn't run several cameras at once, even if they're from the same manufacturer; other times drivers would hang after running capture for about 8 hours straight.

Additionally, cameras vary a lot in performance, framerate, latency, and of course image quality.

Downloads

escapi3.zip

2375kB

Extremely Simple Capture API 3.0.

3.0 is a complete rewrite based on media foundation APIs, includes new interfaces for adjusting camera properties (such as brightness), comes with both 32 and 64 bit builds, and source code is in github. NOTE: does not work in windows XP.

escapi21.zip

481kB

Extremely Simple Capture API 2.1.

2.1 adds examples for BlitzMax, PureBasic, as well as an OpenGL-based "funny mirrors"-example. The only DLL change is that the 'alpha' bits now have value 0xff.

escapi20.zip

470kB

Extremely Simple Capture API 2.0.

2.0 also adds support for multiple capture devices.

escapi10.zip

274kB

Exceedingly Simple Capture API 1.0.

Torbjørn Haugen has made a C# wrapper for ESCAPI. You can find the wrapper at this repository, simple ascii art renderer test here and finally a GUI app that uses a bitmap here.

Simple Usage (in C)

Create a project, and include escapi.cpp in it.


#include "escapi.h" // DLL interface definitions

...

{
  /* Initialize ESCAPI */
  
  int devices = setupESCAPI();

  if (devices == 0)
  {
    printf("ESCAPI initialization failure or no devices found.\n");
    return;
  }

  /* Set up capture parameters.
   * ESCAPI will scale the data received from the camera 
   * (with point sampling) to whatever values you want. 
   * Typically the native resolution is 320*240.
   */

  struct SimpleCapParams capture;
  capture.mWidth = 320;
  capture.mHeight = 240;
  capture.mTargetBuf = new int[320 * 240];
  
  /* Initialize capture - only one capture may be active per device,
   * but several devices may be captured at the same time. 
   *
   * 0 is the first device.
   */
  
  if (initCapture(0, &capture) == 0)
  {
    printf("Capture failed - device may already be in use.\n");
    return;
  }
  
  /* request a capture */      
  doCapture(0);
    
  while (isCaptureDone(0) == 0)
  {
    /* Wait until capture is done. */       
  }
  
  /* now we have the data in capture.mTargetBuf 
   * If we want another frame, we'll just call doCapture(0) again.
   * When done, we'll shut down:
   */
  
  deinitCapture(0);  
}

Gotchas

While 0 is the first device found, it's not necessarily the most useful device. Some costier video cards include a "video in" device which may be the first one the system finds. You can query ESCAPI for the device names and let the user pick which one to capture from.

Internally, ESCAPI tries to request the most fitting resolution the camera offers and if needed, scales it using point-sampling to whatever resolution you requested.

Many cameras come with automatic gain control. Some of these can be turned off using the properties API in ESCAPI, but others may need to be changed using the camera manufacturer's control panels.

The API


struct SimpleCapParams
{
  /* Target buffer. 
   * Must be at least mWidth * mHeight * sizeof(int) of size! 
   */
  int * mTargetBuf;
  /* Buffer width */
  int mWidth;
  /* Buffer height */
  int mHeight;
};


/* Sets up the ESCAPI DLL and the function pointers below. Call this first! */
/* Returns number of capture devices found (same as countCaptureDevices, below) */
int setupESCAPI();

/* return the number of capture devices found */
int countCaptureDevices();

/* initCapture tries to open the video capture device. 
 * Returns 0 on failure, 1 on success. 
 * Note: Capture parameter values must not change while capture device
 *       is in use (i.e. between initCapture and deinitCapture).
 *       Do *not* free the target buffer, or change its pointer!
 */
int initCapture(unsigned int deviceno, struct SimpleCapParams *aParams);

/* deinitCapture closes the video capture device. */
void deinitCapture(unsigned int deviceno);

/* doCapture requests video frame to be captured. */
void doCapture(unsigned int deviceno);

/* isCaptureDone returns 1 when the requested frame has been captured.*/
int isCaptureDone(unsigned int deviceno);

/* Get the user-friendly name of a capture device. */
void getCaptureDeviceName(unsigned int deviceno, char *namebuffer, int bufferlength);

/* Returns the ESCAPI DLL version. 0x200 for 2.0 and later (for legacy support)*/
int ESCAPIDLLVersion();

/* Returns the ESCAPI version. 0x300 for 3.0.
   When checking the version, accept higher versions too. */
int ESCAPIVersionProc();

/* 
	On properties -
	- Not all cameras support properties at all.
	- Not all properties can be set to auto.
	- Not all cameras support all properties.
	- Messing around with camera properties may lead to weird results, so YMMV.
*/

/* Gets value (0..1) of a camera property (see CAPTURE_PROPERTIES, above) */
float getCapturePropertyValueProc(unsigned int deviceno, int prop);
/* Gets whether the property is set to automatic (see CAPTURE_PROPERTIES, above) */
int getCapturePropertyAutoProc(unsigned int deviceno, int prop);
/* Set camera property to a value (0..1) and whether it should be set to auto. */
int setCapturePropertyProc(unsigned int deviceno, int prop, float value, int autoval);

/*
	All error situations in ESCAPI are considered catastrophic. If such should
	occur, the following functions can be used to check which line reported the
	error, and what the HRESULT of the error was. These may help figure out
	what the problem is.
*/

/* Return line number of error, or 0 if no catastrophic error has occurred. */
int getCaptureErrorLineProc(unsigned int deviceno);
/* Return HRESULT of the catastrophic error, or 0 if none. */
int getCaptureErrorCodeProc(unsigned int deviceno);

Source Code

Source code is available at github, under unlicense.

Site design & Copyright © 2017 Jari Komppa
Possibly modified around: October 27 2015