Library for Raw Video Processing

This project is built to be used as a library to perform image processing on AVI files through exclusive use of Microsoft AVIFile API. The main task this library is built for is defined below:

  • Open AVI file on a disk
  • Read AVI video stream, frame by frame, as raw RGB data
  • Perform some processing on raw image data
  • Save the resulting video, frame by frame, into another AVI file

The main limitation in this library is that the result of AVI file generation can only be uncompressed video, which is somewhat expensive in terms of disk-space. As an attempt to make it somewhat useful, we add a stand along function to compress the video from one file into another.

The library consists of a single implementation file "RawAVIStream.cpp" and a single header file "RawAVIStream.h". In advance to the core files there is a sample code that uses this library in "test.cpp".

The code is built with "Microsoft Visual Studio 2008, 9.0.30729.1 SP" and "Microsoft Platform SDK for Windows XP SP2". All the relevant files are included, except codecs, MSVCRT redistributable, etc.

Following is an explanation on how the API is used.

Reading from an AVI File

Here is the minimal code needed to open an AVI file and initiate reading raw data:
	// Error handling is intentionally leaved out for clarity
	PAVISTREAM ppavi;
	AVIFileInit();
	AVIStreamOpenFromFile(&ppavi, filename, streamtypeVIDEO, 0, OF_READ, NULL);

	BITMAPINFOHEADER bi;
	long format_length = sizeof(bi);
	AVIStreamReadFormat(ppavi, 0, &bi, &format_length);
	bi.biBitCount = 24;
	bi.biCompression = BI_RGB;
	bi.biSizeImage = 0;
	PGETFRAME getframe = AVIStreamGetFrameOpen(ppavi, avi->bi);

	AVIStreamRelease(ppavi);

The main function in this code block is AVIStreamGetFrameOpen. In case this function runs successfully, we have a pointer that allows us to read video data, frame by frame, like this:

	void *buffer = AVIStreamGetFrame(avi->getframe, index);
	CopyMemory(target, (BYTE*)buffer + ((BITMAPINFOHEADER*)buffer)->biSize, ((BITMAPINFOHEADER*)buffer)->biSizeImage);

The auxiliary function used is AVIStreamReadFormat. Obviously, we can fill-in BITMAPINFOHEADER without this function. However, we have to determine the frame size somehow. In this code we use AVIStreamOpenFromFile because we are only interested in video processing. The alternative to this call is AVIFileOpen/AVIFileGetStream.

Writing into an AVI File

Creating an uncompressed AVI file from a set of raw data frames is performed using the same API:

	// Error handling is intentionally leaved out for clarity
	BITMAPINFOHEADER bi;
	PAVIFILE pavifile;
	AVISTREAMINFO info;
	PAVISTREAM ppavi;
	AVIFileInit();

	// Create empty AVI file
	AVIFileOpen(&pavifile, filename, OF_WRITE | OF_CREATE, NULL);

	// Create a video stream with minimum data needed.
	ZeroMemory(&info, sizeof(info));
	info.fccType = streamtypeVIDEO;
	info.dwScale = 1;
	info.dwRate = 25;	// This is rather arbitrary, although inspired by PAL TV standard
	AVIFileCreateStream(pavifile, &ppavi, &info);
	AVIFileRelease(pavifile);

	// Set data format to raw RGB, compatible to the format specified in RawAVIReader above.
	// Unfortunately, we can't specify MPEG compression, although MPEG schema is designed
	// for streaming. If we do specify compression, it must be done outside somehow.
	// We specify only minimal data needed to render a valid AVI video.
	ZeroMemory(&bi, sizeof(bi));
	bi.biSize = sizeof(bi);
	bi.biWidth = width;
	bi.biHeight = height;
	bi.biPlanes = 1;
	bi.biBitCount = 24;
	bi.biCompression = BI_RGB;
	bi.biXPelsPerMeter = 1000;
	bi.biYPelsPerMeter = 1000;
	AVIStreamSetFormat(ppavi, 0, &bi, sizeof(bi));

After this code is performed, we have a variable 'ppavi' pointing into a valid AVI stream handler. Having this handler, we do:

	BYTE *frameRGB = new BYTE[3 * width * height];
	...
	fillInTheFrame(frameRGB, width, height); // What-ever does it mean
	AVIStreamWrite(ppavi, index, 1, frameRGB,
		3 * width * height,
		0, NULL, NULL);

MPEG Encoder

In advance of the core task of encoding/decoding raw AVI data, this library implements a stand-alone function that compresses one file into another using the Microsoft implemented MPEG codec. The choice

options.fccHandler = mmioFOURCC('M','S','V','C');

is taken from MSDN and is thought to be found on most Windows machines. The simplest use of this codec is:

	AVICOMPRESSOPTIONS options;
	PAVISTREAM ppavi;
	AVIStreamOpenFromFile(&ppavi, source, streamtypeVIDEO, 0, OF_READ, NULL);

	memset(&options, 0, sizeof(options));
	options.fccType = streamtypeVIDEO;
	options.fccHandler = mmioFOURCC('M','S','V','C');
	options.dwKeyFrameEvery = 2;
	options.dwQuality = 1;
	options.dwFlags = AVICOMPRESSF_KEYFRAMES;
	AVISave(target, NULL, NULL, 1, ppavi, &options);

The codec to be used with this API must be registered through Video Compression Manager as defined in Video Compression Manager and ICInstall Function



Downloads

Comments

  • Clarification

    Posted by arkadi on 06/19/2011 04:42pm

    The purpose of this article & library is to read *non-raw* video frame by frame.
    Any meaningful processing is out of scope.
    The library is intended for users who *know* what is a meaningful processing for them.

    • How to read the raw AVI?

      Posted by Jinwei Feng on 01/15/2014 02:13pm

      Is there any particular reason that it cannot read the raw AVI? I have to read the raw AVI files. How to do that? Thanks

      Reply
    Reply
  • Missing the point...

    Posted by PeejAvery on 06/19/2011 03:23pm

    The title is misleading. This is not reading any RAW video format. It's frame-by-frame video conversion of non-RAW video encodings.
    
    The whole premise of this article is to read frame-by-frame in order to do editing with each individual frame. However, nowhere in the article is anything discussed about what is being done to the frames. In essence, the article only shows how to duplicate encoded video to a non-compressed copy of the exact same video. Which...if you started with compressed video in the first place...is just wasting disk space.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • This ESG study by Mark Peters evaluated a common industry-standard disk VTl deduplication system (with 15:1 reduction ratio) versus a tape library with LTO-5, drives with full nightly backups, over a five-year period.  The scenarios included replicated systems and offsite tape vaults.  In all circumstances, the TCO for VTL with deduplication ranged from about 2 to 4 times more expensive than the LTO-5 tape library TCO. The paper shares recent ESG research and lots more. 

  • The explosion in mobile devices and applications has generated a great deal of interest in APIs. Today's businesses are under increased pressure to make it easy to build apps, supply tools to help developers work more quickly, and deploy operational analytics so they can track users, developers, application performance, and more. Apigee Edge provides comprehensive API delivery tools and both operational and business-level analytics in an integrated platform. It is available as on-premise software or through …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds