Copyright: Video For Windows, Beta Version 1.00.154


Introduction to Video for Windows


About Video for Windows

The Microsoft Video for Windows application programming interface (API) provides the features and capabilities you need to develop applications that play, edit, and capture video. The Video for Windows API, part of the Microsoft Win32 application programming interface, let you create applications that incorporate and display video sequences and give users video processing capabilities. This document provides detailed descriptions of the Video for Windows API. This chapter gives an overview of the Video for Windows API and explains in general terms how to develop video applications.

The information in this document is intended to be used in conjunction with the development tools and information in the Microsoft Win32 Software Development Kit (SDK). The tools, header files, libraries, and samples that you need to create video applications are installed when you install the SDK.


Understanding Video for Windows

The Video for Windows API is designed to help you incorporate different types of video processing into your applications. It provides window classes and examples that help get you started, as well as methods for extending your application beyond the built-in functionality. The Win32 API provides the following:

•	A data container. Applications use the AVI file format for capturing, editing, and playing back audio-video sequences. In general, AVI files contain multiple streams of different types of data, though multiple streams of any data type are supported. A simple AVI file might contain an audio voice stream, a MIDI stream, and a video stream. A file containing two audio streams, each in a different language, is an example of a single file that serves a dual purpose.

•	A set of APIs. Other functionality that might be included in your application is addressed by APIs that enable you to manipulate AVI files, create and work with audio and video codecs and capture device drivers, and communicate with Media Control Interface (MCI) devices.

•	Predefined classes and controls. The Video for Windows API provides window classes for creating capture and playback applications. For example, the AVICap window class functions provide some features that appear in the VidCap tool. The MCIWnd window class functions provide features that appear in the playback window of the VidEdit tool.

•	Flexibility. The Video for Windows API is designed to be extensible. Developers can add run-time capabilities by adding their own custom stream and file handlers that incorporate new types of data into the AVI file format. Audio and video codecs can be added to provide additional options for software compression and decompression. New capture device drivers can be incorporated to take advantage of advances in hardware development.

You use the Video for Windows API to do the following:

•	Include video in your applications. Use Video for Windows to create applications that capture, preview, edit, and play back video sequences. Video sequences can be included in applications that support object linking and embedding (OLE). For example, AVI files can be inserted into Microsoft PowerPoint® presentations, Microsoft Word documents, and Microsoft Access® databases.

•	Create editing and capture tools. You can create an editing application that provides users with basic editing functions, video preview, audio and video compression and decompression, and custom video effects, such as creating transitions between frames and applying color.

The Video for Windows API provides a video-capture window class, AVICap, that enables you to incorporate video-capture capabilities into your application.

•	Extend the AVI file format with custom streams. You can create custom stream and file handlers to support data types other than audio and video. The AVIFile functions provide a consistent interface when working with streams, regardless of their content (video, audio, text, or custom), so that your new stream format is accessed in the same manner as any other stream.

•	Play AVI files using MCI. With the MCIWnd window class, your application can use the MCIAVI driver to play AVI movies and manage a playback window.


Writing Video Applications

The Video for Windows API provides tools for creating your own presentation, capture, and editing applications. The following sections provide a brief introduction to writing several different types of applications, and the features that you can incorporate in the applications.


Video-Playback Applications

The Video for Windows API provides several ways to create a playback application. The window class library, MCIWnd, provides a way to quickly build a complete playback application with a minimum amount of development time. You can use an MCIWnd window to play back any MCI media, simply by responding to the messages sent to the window by the MCI device. Your application automatically has full MCI command capability, which means that it (or the user, if you choose to display built-in controls) can control one or more MCI devices.

The MCIWnd window class library is designed for applications that control MCI devices, such as wave, MIDI, videodisk, VCR, and CD audio devices. With this library, you can easily incorporate playback features in your application and still have access to extensibility provided by other Video for Windows APIs. In addition, simple, single-command macros have been provided to replace message-sending to the MCIWnd window.

After your application creates an MCIWnd window, it can send control messages directly to an MCI device. Or, your application can display a toolbar, track bar (scroll bar), and pop-up menu that enable the user to control the device during playback and recording.

By simply setting flags in MCIWnd window commands, your application can perform the following tasks:

•	Control autosizing of the playback window and image.

•	Display a toolbar and track bar.

•	Display a pop-up menu.

•	Add error and notification capabilities to inform the user or application about playback progress.

•	Add a Record button to the toolbar (the MCI device must support recording).

In addition, MCIWnd macros enable your application to do the following:

•	Specify the start and stop positions used for playback and for playing in reverse. Applications can continuously repeat a sequence and pause playback and recording.

•	Display an Open dialog box that enables the user to specify a file for playback or recording. If the MCI device supports recording, the application can display a Save File dialog box, where the user can specify a filename for the data.

You can also build your own interface to the MCI AVI driver. In this case, you can directly manage the AVI file and display window, as well as communication with MCI devices. MCI AVI can play video sequences containing images, audio, and palettes, and performs the synchronization of audio and video automatically. This can be done using command messages or a string-command interface.


Video-Capture Applications

The Video for Windows API provides several ways to create capture applications. The AVICap window class provides a set of powerful and versatile functions to capture video.

The AVICap window class supports three forms of video capture: streaming video capture, streaming video capture with MCI control, and step video capture with MCI control. Streaming video capture acquires data when your application starts recording. The two other forms of video capture control MCI devices to acquire the data at a specified time interval from the prerecorded media (such as a videodisk or videotape). Streaming video capture positions the MCI device and acquires the data nonstop over the specified time period. Step capture with MCI control positions the MCI device and acquires the data frame-by-frame over the specified time period. By capturing data frame-by-frame, the hardware and software control the pace of video capture.

The Video for Windows API options enable you to make the best use of the available hardware to perform video capture. Because many users must compromise the quality of the video supported, the Video for Windows API supports a wide range of quality levels, which means your application can capture sequences at a very high quality and play them back on machines with fewer capabilities.

With the AVICap window class, you can easily incorporate video-capture capabilities into your application. The AVICap window class provides you with a robust set of functions that handle the more tedious window management required in a capture application, while also retaining complete control over the entire capture process. AVICap provides functionality in the form of a simple, message-based interface to access video and wave-audio acquisition hardware, and control the process of streaming video capture to disk. Use this functionality as the basis for a capture application that can perform the following tasks:

•	Control audio and video capture independently.

•	Display live video using either overlay or preview methods.

•	Work with the Installable Compression Manager (ICM) and the Audio Compression Manager (ACM) to build audio and video compression directly into your application. This is useful during MCI step capture for capturing and compressing frames in a single operation.

•	Capture audio and video streams directly to an AVI file (AVICap insulates you from the details of the AVI file format).

•	Dynamically connect and disconnect video- and audio-input devices.

•	Create, save, and load palettes.

•	Copy images and palettes onto the Clipboard.

•	Control the MCI devices used as the source for the capture data.

AVICap provides methods for handling each step in the capture process that users of your application encounter. A window created using the AVICap window class provides basic functionality, such as live-video preview, dialog boxes for specifying capture settings, and individual control of audio and video capture. With AVICap, you can give users the ability to dynamically connect and disconnect video- and audio-input devices, manipulate palettes, and provide Clipboard access.

The callback functions in AVICap enable your application to provide information about the status of the capture, including the progress made and any errors that have occurred. Because you can also set a flag indicating when either audio or video data is captured, you can use the data directly instead of writing it to an AVI file. For example, videoconferencing applications might use this technique to obtain streaming video frames, which would be transferred to the remote computer by the callback functions.

Initially, if an application is capturing palettized video, the AVICap window uses the palette supplied by the video-capture device driver. Your application can replace the supplied palette with an existing palette, or create a custom palette by sampling images from the captured video sequence. AVICap functions also provide support for the transfer of palettes between sequences.

The AVICap functions enable you to create a full-featured capture application with a minimal development investment. The AVICap functions are high-level, optimized, and provide you with the versatility needed to build in unique features.


Editing Applications

The Video for Windows API provides you with the same extensibility and versatility when creating an editing application as when creating a playback application. Your editing application can incorporate all of the features of a playback application (because your user will most likely want to preview changes made to captured sequences), as well as the editing features you want to provide.

Basic editing functions, such as cut, copy, and paste, are supported by the AVIFile functions. Your editing application works with the AVIFile services to read and write AVI files, but can also be extended to import and export other file formats, such as device-independent bitmap (DIB) sequences. This extensibility enables you build an application that supports custom stream and file handlers that work with data other than audio and video data. The AVIFile services also enable your application to write to AVI files without detailed information about the AVI file format.

The Installable Compression Manager (ICM) provides services for an application to compress or decompress video-image data stored in AVI files. The ICM is the intermediary between the application and the actual video compression and decompression drivers. You can access these services directly if you decide not to use MCIAVI to control video decompression.

The ICM can compress and decompress video using any installed codec. You can also send the decompressed video data directly to display memory, bypassing MCIAVI.

The DrawDib functions provide much of the functionality of StretchDIBits and add ICM support and improved stretching capabilities. The DrawDib functions efficiently dither true-color images to 256 colors, and significantly improve the speed and quality of displaying such images on many display adapters.

Additional graphics support is provided by the Video for Windows API custom draw procedures. These features let you add simple (yet interesting) special effect tools to your editing application. For example, you can create tools to stretch or compress images in one or more directions simultaneously, perform simple morphing of objects, or provide transition effects between frames. You might also provide tools to colorize a monochrome video sequence by letting the user apply a palette from a set of defaults, and then customize it by combining palettes or importing a range of colors from another palette.

Compression and decompression of audio is performed by the Audio Compression Manager (ACM). Whether you use the ACM depends on the format requested by your application. If the hardware devices in the system support the requested format, compressing or decompressing directly to the hardware results in better performance. However, if hardware in the system cannot support the requested format, the ACM will still let your application play or record the data. The ACM can convert the unsupported format into one that is supported by installed hardware, so the application can use compressed data even when the format is not directly supported.


Specialized Applications

Because the Video for Windows API provides a way to incorporate data other than simple audio and video into an application, you have the ability to create applications that do more than play back audio and video data. For example, the text stream supported in the AVI file format could contain instructions that are executed when played back, or could be used to store title or credit information used at the beginning and end of presentations.

Authors, animators, and other people in the creative arts can use video as another medium to deliver their ideas and information. You can mix digital video with text, graphics, or other data to provide several methods of communicating a concept. Reference works, such as travel guides, can combine video, audio, and text to more fully describe an area's atmosphere. Several tracks of audio data can appear in a single title, each in a different language, or geared toward different audiences.

Multimedia slide shows, electronic product brochures, and interactive-video product demonstrations are effective components of sales and marketing applications, presentations, and advertising. You can incorporate video captured during live product demonstrations or tours of manufacturing facilities into a multimedia presentation that combines background information with interactive training on a basic level. You can also include animation to explain complex issues or features.


Further Reading

Use the following table to locate chapters that correspond to the type of application you are developing. In some cases, not all topics in each chapter will apply to the type of application you are writing, depending on the features you are implementing in your application.

If you are developing this application or driver	See these chapters
Presentation (or title) application	MCI Windows: MCIWnd AVI Files Using MCI
Video-capture application	AVI File Capture: AVICap MCI VCR Services
Editing application	AVI Files Installable Compression Manager Audio Compression Manager Bitmap Drawing: DrawDib
Application based on custom file formats	Custom File Handlers AVI File Structure
For information about the Win32 Multimedia API and about MCI devices and commands, see the Microsoft Win32 Programmer's Reference.


MCI Windows: MCIWnd


About the MCI Windows

MCIWnd is a window class library for controlling MCI devices, such as wave, MIDI, digital video, VCR, and CD audio devices. Your application needs only to create a window of this class, and then send it a message to open and control an MCI device. An application can directly use the library services to control the MCI devices, or it can have MCIWnd display a toolbar, a scroll bar, and menus that let the user control the device.

The MCIWnd library provides the following features:

•	A toolbar with Play, Stop, Record, and Menu buttons.

•	A track bar (scroll bar) to control file positioning and seeking.

•	A pop-up track menu containing common commands. The menu pops up when the right mouse button is clicked over the window.

•	Simple, single-command macros for many of the common MCI commands. Applications can use these macros to replace multiline procedures based on mciSendCommand and mciSendString.


Understanding the MCIWnd Window Class and Its Options

The following sections explain the styles, messages, and macros you use to control MCI devices using the MCIWnd window class.


Creating an MCIWnd Window

Applications gain access to MCIWnd services by creating a window with the class MCIWND_WINDOW_CLASS. Your application can use a combination of MCIWndRegisterClass and CreateWindow to create the MCIWnd window. The MCIWndRegisterClass function registers the MCIWND_WINDOW_CLASS. Once this class is registered, your application can use the standard CreateWindow function to create the MCIWnd window.

Alternatively, your application can use MCIWndCreate to create the window. This function is equivalent to the previous combination of functions. The MCIWndCreate function has the following syntax:

HWND MCIWndCreate(hwndParent, hInst, dwStyle, szFile)

The hwndParent parameter specifies a handle to the parent or owner of the window being created.

The hInst parameter specifies a handle to the instance of the module associated with the window.

The szFile parameter specifies a zero-terminated string indicating the name of an MCI-device element. For compound devices, this name typically identifies the file the MCI device will play or record into. For simple devices, or if your application will associate a device element with the window later, your application can set this parameter to NULL.

The dwStyle parameter contains the flags defining the window style. Applications usually use the WS_VISIBLE and WS_CHILD flags for MCIWnd windows. If your window does not use any controls and the MCI device does not display images in the window (for example, the MCI sequencer playing a MIDI file), you might want to omit the WS_VISIBLE flag to leave the window invisible. MCIWnd creates a set of new styles in addition to those defined for CreateWindow.

The MCIWnd messages and macros require the window handle returned from MCIWndCreate or CreateWindow to identify the destination window.


MCIWnd Messages and Macros

Your application can obtain MCIWnd services by sending MCIWnd messages to it with SendMessage. These messages have a corresponding set of equivalent macros. These macros require basic information (such as the MCIWnd handle and the media position) for operation.

Unless otherwise specified, the MCIWnd macros return the same information returned by mciSendString if your application used it to send the equivalent command string.


Setting MCIWnd Window Styles

The MCIWnd library adds more styles to those defined for CreateWindow. The new MCIWnd styles:

•	Govern the automatic sizing for the window and image

•	Add toolbar, track bar, and menus

•	Add error and notification capabilities

•	Display window text

Your application can set the window style when it is created with MCIWndCreate or CreateWindow, or it can change the window style later with MCIWndChangeStyles.


Controlling Autosizing of the Window and Image

Your application can use the MCIWNDF_NOAUTOSIZEWINDOW and MCIWNDF_NOAUTOSIZEMOVIE styles to govern how the window responds to changes in the window and image sizes. The MCIWNDF_NOAUTOSIZEWINDOW style prevents automatic resizing of the window. The MCIWNDF_NOAUTOSIZEMOVIE style prevents automatic resizing of the playback image to adjust to changes in the window size.

Use these styles when your application must control when the size of image or window changes. Without these styles, the window and image size changes dynamically.


Displaying Play Bars, Menus, and Buttons

Your application can use the MCIWNDF_NOPLAYBAR, MCIWNDF_RECORD, and MCIWNDF_NOMENU styles to control the display of toolbars, track bars, menus, and recording buttons.

The MCIWNDF_NOMENU style governs a pop-up menu. If not inhibited, this menu pops up when the user presses the right mouse button and the mouse cursor is over the MCIWnd window.

By default, a toolbar and track bar appear as the play bar. The MCIWNDF_NOPLAYBAR style inhibits display of the play bar. The toolbar can contain the Play, Stop, Record and Menu buttons. The track bar on the play bar is used to seek through the file.

The characteristics of the Play button are altered by the shift and ctrl keys. Holding down shift while pressing the Play button plays the media backwards if the device supports it. Holding down ctrl while pressing the Play button displays images in the full-screen mode on window-oriented devices.

The Record button appears on the toolbar only if the window is using the MCIWNDF_RECORD style and the MCI device supports recording. The MCIWNDF_RECORD style also adds commands to the window menus. Unless your application specifies otherwise, only nondestructive commands appear on the play bar and menu.


Getting Notification and Error Messages from MCIWnd

The MCIWNDF_NOERRORDLG style prevents MCIWND from displaying an Error dialog box whenever an MCI command fails. Unless your application assigns this style to the MCIWnd window, MCIWnd displays a dialog box advising the user of MCI errors. Your application can obtain the most recent error with MCIWndGetError.

The MCIWNDF_NOTIFYMODE, MCIWNDF_NOTIFYPOS, MCIWNDF_NOTIFYMEDIA, and MCIWNDF_NOTIFYSIZE styles have MCIWnd send notification messages to the main message handler of the parent of the MCIWnd window. If your application uses these styles, it must have message handlers corresponding to the style.

Specify this style	To
MCIWNDF_NOTIFYMODE	Enable sending the MCIWNDM_NOTIFYMODE message when the state of the device changes (for example, from stop to play).
MCIWNDF_NOTIFYPOS	Enable sending the MCIWNDM_NOTIFYPOS message when the position of the device changes (for example, as a device is playing).
MCIWNDF_NOTIFYMEDIA	Enable sending the MCIWNDM_NOTIFYMEDIA message when a file is opened or closed, or a new device is loaded.
MCIWNDF_NOTIFYMODE	Enable sending the MCIWNDM_NOTIFYMODE message when the state of the device changes (for example, from stop to play).
MCIWNDF_NOTIFYSIZE	Enable sending the MCIWNDM_NOTIFYSIZE message when the size of the window changes.
MCIWNDF_NOTIFYERROR	Enable sending the MCIWNDM_NOTIFYERROR message when an error occurs.
MCIWNDF_NOTIFYALL	Enable sending all messages.


Displaying the Window Name and Position

Your application can use the MCIWNDF_SHOWNAME, MCIWNDF_SHOWPOS, and MCIWNDF_SHOWMODE styles to display information in the window text. The MCIWNDF_SHOWNAME style sets the window text of the window to the filename of the MCI file opened in this window. The MCIWNDF_SHOWPOS style sets the window text of the window to include the position of the device. The MCIWNDF_SHOWMODE style sets the window text of the window to the mode of the MCI device (for example, playing or stopped). Your application can combine these styles to display multiple characteristics. It can use MCIWNDF_SHOWALL to display all the characteristics.


Changing Window Styles

Your application can use MCIWndChangeStyles to change a window style after it has been created. To obtain the current style of the MCIWnd window, your application can use MCIWndGetStyles. The return value is the bitwise or of the current flags used to define the window style.


Specifying File Elements

The MCIWndOpen, MCIWndOpenDialog, and MCIWndNew macros associate an MCI device or device element with an MCIWnd window. The MCIWndOpen macro directly opens an MCI device or device element, while the MCIWndOpenDialog macro displays an Open File dialog box to let the user specify the file to open. The MCIWndNew macro opens a new (empty) file for recording.

Each of these macros implicitly closes the MCI device currently associated with the window without closing the window. Thus, your application does not need to close any open devices before using these macros.


Closing Files and the MCIWnd Window

Once your application is finished with a file or the MCIWnd window, it uses the MCIWndClose or MCIWndDestroy macro to close the device. Use MCIWndClose to close an MCI device or device element when your application will open another device or device element in the same window. If your application will open the new device or device element immediately after closing the old one, it can skip closing the old one. Opening the new device or device element automatically closes the old one.

Use MCIWndDestroy to destroy a window. This macro also closes the current MCI device or device element if it is still open. Once your application uses this macro, the handle to the window is invalid. This macro does not return any data.


Determining Device Capabilities

A set of macros lets your application determine some of the capabilities of an MCI device. The MCIWndCanPlay and MCIWndCanRecord macros determine if the device supports the Play and Record commands. The MCIWndCanWindow macro determines if the device supports window commands. The MCIWndCanSave macro determines if the device can save data. The MCIWndCanEject macro determines if a device can eject its media. The MCIWndCanConfig macro determines if the device supports configuration.


Playback Options

A set of macros lets your application easily specify the start and stop positions used for playback and for playing in reverse. The MCIWndPlay and MCIWndPlayReverse macros specify the direction of play, starting at the current position.

The MCIWndPlayFrom, MCIWndPlayTo, and MCIWndPlayFromTo macros use position values as arguments to control playback. The MCIWndPlayFrom macro plays the file forward starting at the specified position. The MCIWndPlayTo macro plays from the current position to the specified position. The MCIWndPlayFromTo macro uses values for both a starting position and a stopping position to control playback.

Applications can use MCIWndSetRepeat to continuously repeat play of a sequence controlled by the Toolbar buttons. Use MCIWndGetRepeat to obtain a Boolean value indicating the status of the repeat operation.


Stopping and Pausing Playback and Recording

Three macros are used to stop and pause playback and recording operation. The MCIWndStop macro stops the device. The MCIWndPause and MCIWndResume macros pause the device and resume playing or recording.


Controlling the Media Position

Your application can use the positioning macros to position the media for playback and recording. The MCIWndHome and MCIWndEnd macros seek to the beginning and end of the media.

The MCIWndSeek macro seeks to a specified position in the file. The units specified for the seek position depend on the current-time format of the device.

The MCIWndStep macro steps playback through a file. The time format determines if the step units are frames or milliseconds. A positive value is a step forward. A negative value steps backward.


Determining Media Position

A set of four macros lets your application determine position information about the media. The MCIWndGetPosition macro returns the current position in the file. The MCIWndGetStart macro returns the starting position of the file. The MCIWndGetLength macro returns the length of the file. The MCIWndGetEnd macro returns the end position of the file. All of these macros return position information for the return value. The units for the return value depend on the current time format.

If an application requires position information in a string format, it can use MCIWndGetPositionString. If a device supports the track format, this macro returns the information in the TT:MM:SS:FF format, where TT corresponds to tracks, MM and SS correspond to minutes and seconds, and FF corresponds to frames.


Recording Data

On MCI devices that have recording capabilities, the MCIWndRecord command starts recording at the current position. If your application is recording into an existing file, it can set the recording position to the start of the file with MCIWndHome, or it can set the recording position to the end of the file with MCIWndEnd. Your application can use MCIWndSeek to move to an arbitrary position in the file.

Your application can stop recording with MCIWndStop or MCIWndPause.


Saving Data

If an MCI device can record or edit data, the MCIWndSave and MCIWndSaveDialog macros save the recorded or edited data. The MCIWndSave macro saves data using the filename specified for the device element. The MCIWndSaveDialog macro displays a File dialog box to let the user specify the filename used for saving data.


Setting Playback Attributes

For window-oriented devices, MCIWndSetZoom sets the size of the device's playback window. This macro uses a zoom value to set the size. The zoom value is specified as a percentage of the original size of the image. Thus, 100 indicates the image is displayed as authored. A value of 200 indicates the image is shown at twice the original size, and 50 indicates the image is shown at half the original size. Your application can use MCIWndGetZoom to obtain the last value set with MCIWndSetZoom. It returns the zoom value.

If an MCI device supports volume changes, your application can use MCIWndSetVolume to adjust the volume. A volume level of 1000 corresponds to the reference volume level. Higher values indicate louder volume levels and lower values indicate softer volume levels. If your application needs to determine the current volume level, it can use MCIWndGetVolume to obtain it. This macro returns the volume level and uses the window handle as its only parameter.

If an MCI device supports variable playback speeds, your application can use MCIWndSetSpeed to set it. A speed value of 1000 indicates normal speed while higher values are faster and lower values are slower. The MCIWndGetSpeed macro returns the current value.


Changing Time Formats

The MCIWndSetTimeFormat macro lets your application specify the time format of an MCI device as a string argument. While your application can use this macro to set any time format string defined for an MCI device, it can use the MCIWndUseTime and MCIWndUseFrames macros to set the time format to milliseconds or frames. The MCIWndGetTimeFormat macro lets your application obtain the current time format of a device.

If your application changes the time format of a device without using an MCIWnd macro, the starting and ending position of the media, as well as the track bar, continue to use the old format. Use the MCIWndValidateMedia macro to update these values. In general, you should not need to use this macro.


Adjusting the Update Period for Position Information and Notification Messages

MCIWnd uses timers to periodically update information in the scroll bar and window caption, and send notification messages to the parent window. Your application can use the MCIWnd timer macros to set the timers and determine their current settings.

The MCIWndSetActiveTimer macro sets the period used by MCIWnd to update the scroll bar, update the position reported in the window caption, or notify the parent of some change to the media when the MCIWnd window is the active window. The value specified for the period is specified in milliseconds. The default value for the active timer is 500 milliseconds. Similarly, the MCIWndSetInactiveTimer macro sets the update period used by MCIWnd when its window is an inactive window. The default value for the inactive timer is 2000 milliseconds.

Your application can simultaneously set the values for both the active and inactive windows with MCIWndSetTimers. This macro's timer values are limited to 16-bit quantities.

Your application can retrieve the values set for the timers with the MCIWndGetActiveTimer and MCIWndGetInactiveTimer macros. MCIWndGetActiveTimer returns the value of the timer controlling the updating of the MCIWnd window when it is the active window, and MCIWndGetInactiveTimer returns the value of the timer controlling the updating of the MCIWnd window when it is the inactive window.


Setting the Source and Destination Rectangles

Applications can use the MCIWndPutSource, MCIWndGetSource, MCIWndPutDest, and MCIWndGetDest macros to crop the source image and change the display area to be updated. The MCIWndPutSource macro sets the source area of the image used that will be displayed. The MCIWndGetSource macro returns the current rectangle.

The MCIWndPutDest macro specifies the area of the window used to display the image. Images can be stretched to fit the destination rectangle. The MCIWndGetDest macro returns the current-destination rectangle.


Obtaining and Setting the Palette

If the MCI device uses palettes, your application can use the MCIWndRealize, MCIWndGetPalette, and MCIWndSetPalette macros to obtain a handle to them and update them.

The MCIWndRealize macro has a window-oriented device realize the palette of the image it is displaying. Use this macro in your application's WM_PALETTECHANGED and WM_QUERYNEWPALETTE message handlers instead of using the standard windows function RealizePalette. When MCIWnd processes this macro, it calls RealizePalette with the palette of the MCI device. If calling this macro or calling RealizePalette is the only function performed by the WM_PALETTECHANGED and WM_QUERYNEWPALETTE message handlers, your application can just pass the WM_PALETTECHANGED or WM_QUERYNEWPALETTE messages on to the MCI window and this will happen automatically

The MCIWndGetPalette macro returns a handle to the palette being used by the window-oriented device to display its image. If your application uses this macro, you should be aware that it does not have exclusive use of the handle. Thus, your application should not free the palette when it is done, and it should anticipate that some other application can invalidate the handle.

If you want the MCI device to use a new palette for displaying its images, use the MCIWndSetPalette macro to specify the handle to the palette.


Ejecting the Media

Applications can use the MCIWndEject macro to eject the media of MCI devices that have removable media (such as a CD audio device).


Obtaining Error Descriptions

The MCIWndGetError macro returns the text description for the most recently executed command. This macro returns the error in an application-supplied buffer. If the error string is longer than the buffer, MCIWnd truncates the error string.


Obtaining the MCI-Device Mode

An application can determine the mode of an MCI device with the MCIWndGetMode macro. The return values for MCIWndGetMode correspond to the MCI mode constants.


Sending String and Message Commands to MCI Devices

If your application requires more control over MCI devices than is available from the MCIWnd library, your application can send MCI commands directly to the MCI device, as well as use the MCIWnd services.

The MCIWndSendString macro lets your application send string commands to an MCI device opened through MCIWnd. This macro is equivalent to using mciSendString(sz, NULL, 0, NULL). The parameters of MCIWndSendString include only the window handle and string command. When specifying the string command used with this macro, exclude the device alias. The MCIWnd library adds this alias when it sends the string command to the MCI device. Applications can get the information returned for a string command with the MCIWndReturnString macro.

The MCIWndGetDeviceID, MCIWndGetAlias, MCIWndGetFileName, and MCIWndGetDevice macros get information identifying an MCI device or device element. The MCIWndGetDeviceID macro returns the device ID of the open file. Your application can use this ID to send MCI message commands with mciSendCommand.

If your application uses mciSendString to send MCI string commands, it can get the MCI alias used to open the device with the MCIWndGetAlias macro.

The MCIWndGetFileName and MCIWndGetDevice macros return the device-element name and MCI-device name in an application-supplied buffer.


Using MCI Windows

The following sections provide information about using the MCIWnd window class.


Changing Window Styles: An Example

Your application can use MCIWndChangeStyles to change window styles after they have been created. This macro has the following syntax:

MCIWndChangeStyles(hwnd, mask, value)

The mask parameter specifies the styles that your application will allow to change—styles not specified are exempt from changes. Create the mask by using the bitwise or to combine the MCIWNDF styles your application will allow to change. Your application sets styles by using the bitwise or to combine the MCIWNDF styles it wants to set and specifying the result in the value parameter. Any flags specified in mask that are not specified in value are cleared. The following example turns the play bar off and the track menu on:

MCIWndChangeStyles(hwnd, MCIWNDF_NOPLAYBAR | MCIWNDF_NOMENU, MCIWNDF_NOPLAYBAR)


Changing Time Formats: An Example

The time format of the device determines how to interpret a position in the file. The following example sets the time format to frames:

MCIWndSetTimeFormat(hWnd, "frames")


Sending String Commands and Message Commands to MCI Devices

The following example uses MCIWndSendString to set the time format to frames:

MCIWndSendString(hWnd, "set time format frames")


Reference

This section is an alphabetic reference to the functions, macros, and messages provided for applications using the MCIWnd services.

The MCIWnd macros communicate with MCIWnd devices through messages sent to the library. (Definitions of the messages used in the MCIWnd macros are included with the macro definition.) The MCIWnd macros are based upon SendMessage.

MCIWnd macros and functions are identified by the prefix MCIWnd. MCIWnd messages are identified by the prefix MCIWNDM.

For information about	See these functions, macros, or messages
Creating an MCIWnd window	MCIWndCreate MCIWndRegisterClass
MCIWnd messages and macros	MCIWndSendString MCIWndReturnString
Getting notification and error messages from MCIWnd	MCIWndGetError MCIWNDM_NOTIFYERROR MCIWNDM_NOTIFYMEDIA MCIWNDM_NOTIFYMODE MCIWNDM_NOTIFYPOS MCIWNDM_NOTIFYSIZE
Changing window styles	MCIWndChangeStyles MCIWndGetStyles
Creating an MCIWnd window	MCIWndCreate3 MCIWndRegisterClass
Specifying file elements	MCIWndOpen MCIWndOpenDialog MCIWndNew
Closing files and the MCIWnd window	MCIWndClose MCIWndDestroy
Determining device capabilities	MCIWndCanConfig MCIWndCanEject MCIWndCanPlay MCIWndCanRecord MCIWndCanSave MCIWndCanWindow
Creating an MCIWnd window	MCIWndCreate MCIWndRegisterClass
Playback options	MCIWndGetRepeat MCIWndPlay MCIWndPlayFrom MCIWndPlayFromTo MCIWndPlayReverse MCIWndPlayTo MCIWndSetRepeat
Stopping and pausing playback and recording	MCIWndPause MCIWndResume MCIWndStop
Recording data	MCIWndEnd MCIWndHome MCIWndPause MCIWndRecord MCIWndSeek MCIWndStop
Saving data	MCIWndSave MCIWndSaveDialog
Controlling the media position	MCIWndEnd MCIWndHome MCIWndSeek MCIWndStep
Determining media position	MCIWndGetEnd MCIWndGetLength MCIWndGetPosition MCIWndGetPositionString MCIWndGetStart
Creating an MCIWnd window	MCIWndCreate MCIWndRegisterClass
Setting playback attributes	MCIWndGetSpeed MCIWndGetVolume MCIWndGetZoom MCIWndSetSpeed MCIWndSetVolume3 MCIWndSetZoom
Changing time formats	MCIWndGetTimeFormat MCIWndSetTimeFormat MCIWndUseFrames MCIWndUseTime MCIWndValidateMedia
Creating an MCIWnd window	MCIWndCreate MCIWndRegisterClass
Adjusting the update period for position information and notification messages	MCIWndGetActiveTimer MCIWndGetInactiveTimer MCIWndSetActiveTimer MCIWndSetInactiveTimer MCIWndSetTimers
Setting the source and destination rectangles	MCIWndGetDest MCIWndGetSource MCIWndPutDest MCIWndPutSource
Obtaining and setting the palette	MCIWndGetPalette MCIWndRealize MCIWndSetPalette
Ejecting the media	MCIWndEject
Obtaining error descriptions	MCIWndGetError
Obtaining the MCI device mode	MCIWndGetMode
Sending string commands and message commands to MCI devices	MCIWndGetAlias MCIWndGetDevice MCIWndGetDeviceID MCIWndGetFileName MCIWndSendString


MCIWndCanConfig

This macro determines if an MCI device supports configuration.

LRESULT MCIWndCanConfig(HWND hwnd)

•	Returns TRUE if the device supports configuration. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

This macro is defined with the MCIWNDM_CAN_CONFIG message. The wParam and lParam parameters for the message are set to zero.


MCIWndCanEject

This macro determines if an MCI device can eject its media.

LRESULT MCIWndCanEject(HWND hwnd)

•	Returns TRUE if the device can eject its media. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

This macro is defined with the MCIWNDM_CAN_EJECT message. The wParam and lParam parameters for the message are set to zero.


MCIWndCanPlay

This macro determines if an MCI device supports playing a sequence.

LRESULT MCIWndCanPlay(HWND hwnd)

•	Returns TRUE if the device supports playing data. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

This macro is defined with the MCIWNDM_CAN_PLAY message. The wParam and lParam parameters for the message are set to zero.


MCIWndCanRecord

This MCIWnd macro determines if an MCI device supports recording.

LRESULT MCIWndCanRecord(HWND hwnd)

•	Returns TRUE if the device supports recording. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

This macro is defined with the MCIWNDM_CAN_RECORD message. The wParam and lParam parameters for the message are set to zero.


MCIWndCanSave

This macro determines if an MCI device can save data.

LRESULT MCIWndCanSave(HWND hwnd)

•	Returns TRUE if the device supports saving data. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

This macro is defined with the MCIWNDM_CAN_SAVE message. The wParam and lParam parameters for the message are set to zero.


MCIWndCanWindow

This macro determines if an MCI device supports window commands.

LRESULT MCIWndCanWindow(HWND hwnd)

•	Returns TRUE if the device supports window-oriented operations. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.


MCIWndChangeStyles

This MCIWnd macro changes the styles used for its window.

LONG MCIWndChangeStyles(HWND hwnd, int mask, int value)

•	Returns zero.

hwnd

Specifies the handle to the MCIWnd window.

mask

Specifies a mask for value. This mask is the bitwise or of all styles that will be permitted to change.

value

Specifies the styles used for the window. For the available styles, see MCIWndCreate.

This macro is defined with the MCIWNDM_CHANGESTYLES message. The wParam parameter for the message has the same definition as mask, and the lParam parameter has the same definition as value.


MCIWndClose

This macro closes an MCI device or device element.

LONG MCIWndClose(HWND hwnd)

•	Returns zero.

hwnd

Specifies the handle to the MCIWnd window.

Use this macro to close an MCI device without destroying the MCIWnd window. Use MCIWndDestroy to simultaneously close the MCI device and destroy the MCIWnd window.

If your application will immediately open a new MCI device in the MCIWnd window, use MCIWndOpen to simultaneously close the current MCI device and open a new one.

This macro is defined with the MCI_CLOSE message. The wParam and lParam parameters for the message are set to zero.


MCIWndCreate

This function creates an MCIWnd window for using MCI services.

HWND MCIWndCreate(HWND hwndParent, HINSTANCE hInstance, DWORD dwStyle, LPSTR szFile)

•	Returns a handle to an MCIWnd window if successful. Otherwise, it returns zero.

hwndParent

Specifies a handle to the parent window.

hInstance

Specifies the window instance.

dwStyle

Specifies any flags for the window style. If you do not specify any of the WS_ styles, your window will use WS_CHILD, WS_BORDER, and WS_VISIBLE if you specify a non-NULL parent window, and WS_OVERLAPPEDWINDOW and WS_VISIBLE otherwise. Thus, to create an invisible child window, specify WS_CHILD to prevent the default flags from being used.

The following styles are defined in addition to those defined for CreateWindow.

MCIWNDF_NOAUTOSIZEWINDOW

Inhibits the changing of the window size when the image size changes. By default, the window size changes automatically to reflect changes in image size. The window also automatically resizes when a new file opens or closes.

MCIWNDF_NOAUTOSIZEMOVIE

Prevents stretching the image when a window size changes. For MCI devices that display video in a window, MCIWnd usually resizes the image to fill the window.

MCIWNDF_NOPLAYBAR

Inhibits the display of the play bar. By default, a play bar is displayed. The default controls on the play bar include the Play, Stop, and Menu buttons, as well as a track bar to set the media position.

For non-window-oriented devices, applications need a window to display the toolbar and track bar. Applications that access non-window-oriented devices (such as a waveform audio device), and do not display any controls, can leave the window invisible.

MCIWNDF_NOMENU

Inhibits the display of a menu button on the play bar and inhibits display of the pop-up menu that is usually available when the right mouse button is pressed when the cursor is over the window.

MCIWNDF_RECORD

Displays a Record button on the play bar or menu, and adds a new File command to the menu. By default, only nondestructive commands are available on the play bar and menu.

MCIWNDF_NOERRORDLG

Inhibits display of an Error dialog box for MCI errors. Applications can use MCIWndGetError to determine the most recent error.

MCIWNDF_NOTIFYMODE

Has MCIWnd notify the parent window when the mode of the MCI device changes. Whenever the mode changes (for example, from stop to play) the parent window receives an MCIWNDM_NOTIFYMODE message. The lParam of the message contains the new state of the device (for example, MCI_MODE_STOP). The application can get the text string of the new mode with the MCIWndGetMode macro.

MCIWNDF_NOTIFYPOS

Has MCIWnd notify the parent window when the position of the media changes. MCIWnd sends the MCIWNDM_NOTIFYPOS message to inform the parent window of changes. The lParam of the message contains the new position in the media.

MCIWNDF_NOTIFYMEDIA

Has MCIWnd notify the parent window when the media changes. Whenever a file is opened or closed, or a new device is loaded, MCIWnd sends the MCIWNDM_NOTIFYMEDIA message. The lParam of the message contains a pointer to the new filename.

MCIWNDF_NOTIFYSIZE

Has MCIWnd notify the parent window when the size of the window changes.

MCIWNDF_NOTIFYERROR

Has MCIWnd notify the parent window when an error occurs.

MCIWNDF_NOTIFYALL

Has MCIWnd notify parent window of all changes.

MCIWNDF_SHOWNAME

Displays the name of the open MCI-device element in the window caption.

MCIWNDF_SHOWPOS

Displays the position of the MCI device in the window caption.

MCIWNDF_SHOWMODE

Displays the mode of the MCI device in the window caption.

MCIWNDF_SHOWALL

Displays all window features.

szFile

Specifies a zero-terminated string indicating the name of an MCI device or device element to open.

Use the window handle returned by this function for the window handle in the MCIWnd macros. If your application uses this macro, it does not need to use MCIWndRegisterClass.

Holding a shift key down while pressing the Play button plays the media backward (if supported). For window-oriented devices, holding the ctrl key down while pressing the Play button plays the device in full-screen mode if supported.


MCIWndDestroy

This MCIWnd macro closes an MCI device or device element and destroys the MCIWnd window.

VOID MCIWndDestroy(HWND hwnd)

hwnd

Specifies the handle to the MCI window.

This macro is defined with the WM_CLOSE message. The wParam and lParam parameters for the message are set to zero.


MCIWndEject

This MCIWnd macro has an MCI device eject its media.

LONG MCIWndEject(HWND hwnd)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCIWnd window.

This macro is defined with the MCIWNDM_EJECT message. The wParam and lParam parameters for the message are set to zero.


MCIWndEnd

This MCIWnd macro has an MCI device seek to the end of the media.

LONG MCIWndEnd(HWND hwnd)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCIWnd window.

This macro is defined with the MCIWND_END message. The wParam and lParam parameters for the message are set to zero.


MCIWndGetActiveTimer

This MCIWnd macro returns the timer period used when the MCIWnd window is the active window.

UINT MCIWndGetActiveTimer(HWND hwnd)

•	Returns the update period in milliseconds. The default is 500 milliseconds.

hwnd

Specifies the handle to the MCIWnd window.

This macro is defined with the MCIWNDM_GETACTIVETIMER message. The wParam and lParam parameters for the message are set to zero.


MCIWndGetAlias

This MCIWnd macro returns the alias used to open an MCI device or device element.

UINT MCIWndGetAlias(HWND hwnd)

•	Returns the device alias. Use this macro to obtain the alias needed to use mciSendString.

hwnd

Specifies the handle to the MCI window.

This macro is defined with the MCIWNDM_GETALIAS message. The wParam and lParam parameters for the message are set to zero.


MCIWndGetDest

This MCIWnd macro has an MCI device return the rectangle used for the image destination.

LONG MCIWndGetDest(HWND hwnd, LPRECT prc)

•	Returns zero if successful. Otherwise, it returns an error.

hwnd

Specifies the handle to the MCI window.

prc

Specifies a pointer to a RECT data type used to return the destination rectangle.

This macro is defined with the MCIWNDM_GET_DEST message. The wParam parameter is set to zero and the lParam has the same definition as prc.


MCIWndGetDevice

This MCIWnd macro returns the name of the currently opened MCI device.

LONG MCIWndGetDevice(HWND hwnd, LPARAM lp, int len)

•	Returns zero if successful. Otherwise, it returns 42.

hwnd

Specifies the handle to the MCIWnd window.

lp

Specifies a pointer to the application-supplied data buffer used to return the device name.

len

Specifies the size of the data buffer.

If the zero-terminated string containing the device name is longer than the buffer, MCIWnd truncates it.

This macro is defined with the MCIWNDM_GETDEVICE message. The wParam parameter for the message has the same definition as len, and the lParam parameter has the same definition as lp.


MCIWndGetDeviceID

This MCIWnd macro has an MCI device return its device ID.

UINT MCIWndGetDeviceID(HWND hwnd)

•	Returns the device ID. Use this macro to get the device ID needed to use mciSendCommand.

hwnd

Specifies the handle to the MCI window.

This macro is defined with the MCIWNDM_GETDEVICEID message. The wParam and lParam parameters for the message are set to zero.


MCIWndGetEnd

This MCIWnd macro returns the ending position of an MCI-device element.

LONG MCIWndGetEnd(HWND hwnd)

•	Returns the ending position.

hwnd

Specifies the handle to the MCI window.

This macro is defined with the MCIWNDM_GETEND message. The wParam and lParam parameters for the message are set to zero.


MCIWndGetError

This MCIWnd macro returns the last MCI error encountered.

LONG MCIWndGetError(HWND hwnd, LPARAM lp, int iLen)

•	Returns the integer error code.

hwnd

Specifies the handle to the MCIWnd window.

lp

Specifies a pointer to an application-supplied buffer used to return the error string.

iLen

Specifies the size of the error data buffer.

If lp is a valid pointer, a zero-terminated string corresponding to the error is returned in its buffer. If the error string is longer than the buffer, MCIWnd truncates it.

This macro is defined with the MCIWNDM_GETERROR message. The wParam parameter for the message has the same definition as iLen, and the lParam parameter has the same definition as lp.


MCIWndGetFileName

This MCIWnd macro returns the filename used by an MCI-device element.

LONG MCIWndGetFileName(HWND hwnd, LPARAM lp, int iLen)

•	Returns zero if successful. Otherwise, it returns 1.

hwnd

Specifies the handle to the MCI window.

lp

Specifies a pointer to the application-supplied data buffer used to return the filename.

iLen

Specifies the size of the data buffer.

If the zero-terminated string containing the filename is longer than the buffer, MCIWnd truncates it.

This macro is defined with the MCIWNDM_GETFILENAME message. The wParam parameter for the message has the same definition as iLen, and the lParam parameter has the same definition as lp.


MCIWndGetInactiveTimer

This MCIWnd macro returns the timer period used when the MCIWnd window is the inactive window.

UINT MCIWndGetInactiveTimer(HWND hwnd)

•	Returns the timer period in milliseconds. The default is 2000 milliseconds.

hwnd

Specifies the handle to the MCIWnd window.

This macro is defined with the MCIWNDM_GETINACTIVETIMER message. The wParam and lParam parameters for the message are set to zero.


MCIWndGetLength

This MCIWnd macro returns the length of an MCI-device element.

LONG MCIWndGetLength(HWND hwnd)

•	Returns the length of the device element.

hwnd

Specifies the handle to the MCI window.

This value plus the value returned for MCIWndGetStart equals the end of the media.

This macro is defined with the MCIWNDM_GETLENGTH message. The wParam and lParam parameters for the message are set to zero.


MCIWndGetMode

This MCIWnd macro has an MCI device return its mode.

LONG MCIWndGetMode(HWND hwnd, LPARAM lp, int iLen)

•	Returns an integer corresponding to the MCI constant defining the mode.

hwnd

Specifies the handle to the MCI window.

lp

Specifies a pointer to the application-supplied buffer used to return the mode.

iLen

Specifies the size of the data buffer.

If the zero-terminated string describing the mode is longer than the buffer, it is truncated.

This macro is defined with the MCIWNDM_GETMODE message. The wParam parameter for the message has the same definition as iLen, and the lParam parameter has the same definition as lp.


MCIWndGetPalette

This MCIWnd macro returns a handle to the palette used by an MCI device.

HPALETTE MCIWndGetPalette(HWND hwnd)

•	Returns the handle to the palette.

hwnd

Specifies the handle to the MCIWnd window.

This macro is defined with the MCIWNDM_GETPALETTE message. The wParam and lParam parameters for the message are set to zero.


MCIWndGetPosition

This MCIWnd macro returns the current position of the MCI-device element.

LONG MCIWndGetPosition(HWND hwnd)

•	Returns the current position.

hwnd

Specifies the handle to the MCI window.

The units for the position value depend on the current time format.

This macro is defined with the MCIWNDM_GETPOSITION message. The wParam and lParam parameters for the message are set to zero.


MCIWndGetPositionString

This MCIWnd macro returns the current position of the MCI-device element in a string format.

LONG MCIWndGetPositionString(HWND hwnd, LPARAM lp, int iLen)

•	Returns an integer corresponding to the position.

hwnd

Specifies the handle to the MCI window.

lp

Specifies a pointer to the application-supplied buffer used to return the zero-terminated string.

iLen

Specifies the size of the data buffer.

If the device supports tracks, the position information is returned in the TT:MM:SS:FF format where TT corresponds to tracks, MM and SS correspond to minutes and seconds, and FF corresponds to frames.

If the zero-terminated string is longer than the buffer, it is truncated.

This macro is defined with the MCIWNDM_GETPOSITION message. The wParam parameter for the message has the same definition as iLen, and the lParam parameter has the same definition as lp.

The units for the position value depend on the current time format.


MCIWndGetRepeat

This MCIWnd macro returns the status of the MCIWnd repeat flag.

BOOL MCIWndGetRepeat(HWND hwnd)

•	Returns TRUE if the flag is set.

hwnd

Specifies the handle to the MCI window.

This macro is defined with the MCIWNDM_GETREPEAT message. The wParam and lParam parameters are set to zero.


MCIWndGetSource

This MCIWnd macro has an MCI device return the rectangle used for the source of the image.

LONG MCIWndGetSource(HWND hwnd, LPRECT prc)

•	Returns zero if successful. Otherwise, it returns an error.

hwnd

Specifies the handle to the MCI window.

prc

Specifies a pointer to a RECT data type used to return the source rectangle.

This macro is defined with the MCIWNDM_GET_SOURCE message. The wParam parameter is set to zero and the lParam has the same definition as prc.


MCIWndGetSpeed

This MCIWnd macro returns the playback speed of an MCI device.

LONG MCIWndGetSpeed(HWND hwnd)

•	Returns the playback speed.

hwnd

Specifies the handle to the MCIWnd window.

This macro is defined with the MCIWNDM_GETSPEED message. The wParam and lParam parameters for the message are set to zero.


MCIWndGetStart

This MCIWnd macro returns the starting position of an MCI-device element.

LONG MCIWndGetStart(HWND hwnd)

•	Returns the starting position of the device element.

hwnd

Specifies the handle to the MCI window.

Typically, the return value is zero, but some devices use a nonzero starting position for the device element. Seeking to this position sets the device to the start of the media.

This macro is defined with the MCIWNDM_GETSTART message. The wParam and lParam parameters for the message are set to zero.


MCIWndGetStyles

This MCIWnd macro returns the flags specifying the styles used for the MCI window.

UINT MCIWndGetStyles(HWND hwnd)

•	Returns the flags specifying the styles used for the window. This value is the bitwise or of the MCIWNDF flags.

hwnd

Specifies the handle to the MCI window.

This macro is defined with the MCIWNDM_GETSTYLES message. The wParam and lParam parameters for the message are set to zero.


MCIWndGetTimeFormat

This MCIWnd macro returns the time format of an MCI device in an application-supplied buffer.

LONG MCIWndGetTimeFormat(HWND hwnd, LPARAM lp, int iLen)

•	Returns an integer corresponding to the MCI constant defining the time format.

hwnd

Specifies the handle to the MCIWnd window.

lp

Specifies a pointer to the data buffer used to return the zero-terminated string indicating time format.

iLen

Specifies the size of the data buffer.

If the time format string is longer than the return buffer, MCIWnd truncates the string.

This macro is defined with the MCIWNDM_GETTIMEFORMAT message. The wParam parameter for the message has the same definition as iLen, and the lParam parameter has the same definition as lp.


MCIWndGetVolume

This MCIWnd macro returns the volume level of an MCI device.

LONG MCIWndGetVolume(HWND hwnd)

•	Returns the volume level.

hwnd

Specifies the handle to the MCI window.

This macro is defined with the MCIWNDM_GETVOLUME message. The wParam and lParam parameters for the message are set to zero.


MCIWndGetZoom

This MCIWnd macro has an MCI device return the zoom factor it is using.

UINT MCIWndGetZoom(HWND hwnd)

•	Returns an integer corresponding to the zoom factor. A value of 100 indicates the image is not zoomed. A value of 200 indicates the image is zoomed to twice its original size. A value of 50 indicates the image is reduced to half its original size.

hwnd

Specifies the handle to the MCI window.

This macro is defined with the MCIWNDM_GETZOOM message. The wParam and lParam parameters for the message are set to zero.


MCIWndHome

This MCIWnd macro sends the MCI_SEEK message to an MCI device to seek to the start of the media.

LONG MCIWndHome(HWND hwnd)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCIWnd window.

This macro is defined with the MCIWND_START message. The wParam and lParam parameters for the message are set to zero.


MCIWNDM_NOTIFYERROR

MCIWND sends this message to the parent window of an application to send it an error from MCI.

wParam

Specifies the window handle.

lParam

Specifies a pointer to a zero-terminated string indicating the error.


MCIWNDM_NOTIFYMEDIA

MCIWND sends this message to the parent window of an application to notify it that the media has changed.

wParam

Not used.

lParam

Specifies a pointer to a zero-terminated string containing the new filename or device. If the media is closing, it specifies a NULL string.


MCIWNDM_NOTIFYMODE

MCIWND sends this message to the parent window of an application to notify it that device mode has changed.

wParam

Not used.

lParam

Specifies an integer corresponding to the MCI mode.


MCIWNDM_NOTIFYPOS

MCIWND sends this message to the parent window of an application to notify it that the window position has changed.

wParam

Not used.

lParam

Specifies the new position.


MCIWNDM_NOTIFYSIZE

MCIWND sends this message to the parent window of an application to notify it that the window size has changed.

wParam

Specifies a handle to the MCIWnd window that has changed size.

lParam

Not used; set to zero.


MCIWndNew

This MCIWnd macro has an MCI device create a new file.

LONG MCIWndNew(HWND hwnd, LPARAM lpstr)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCIWnd window.

lpstr

Points to the name of the device used to create the new file.

This macro is defined with the MCIWNDM_NEW message. The wParam parameter for the message is set to zero, and the lParam parameter is set to lp.


MCIWndOpen

This MCIWnd macro has MCIWnd open an MCI device.

LONG MCIWndOpen(HWND hwnd, LPSTR szFile, WORD wFlags)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCIWnd window.

szFile

Specifies a zero-terminated string for the file name. Specifying −1 for this parameter has the MCI device display a dialog box used to specify the filename.

wFlags

Specifies applicable flags for the open operation. The following flag is defined:

MCIWNDOPENF_NEW

Indicates the szFile parameter specifies the device name to open.

This MCIWnd macro is defined with the MCI_OPEN message. The wParam parameter for the message is set to wFlags, and the lParam parameter for the message is set to szFile.


MCIWndOpenDialog

This MCIWnd macro has MCIWnd display a dialog box for specifying the filename MCIWnd uses to open an MCI device.

LONG MCIWndOpenDialog(HWND hwnd)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

This macro is defined with the MCI_OPEN message. The wParam parameter for the message is set to 1, and the lParam parameter for the message is set to zero.


MCIWndPause

This MCIWnd macro has an MCI device pause playing or recording.

LONG MCIWndPause(HWND hwnd)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

This macro is defined with the MCI_PAUSE message. The wParam and lParam parameters for the message are set to zero.


MCIWndPlay

This MCIWnd macro has the MCI device start playing.

LONG MCIWndPlay(HWND hwnd)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCIWnd window.

This macro starts playing from the current position.

This macro is defined with the MCI_PLAY message. The wParam and lParam parameters for the message are set to zero.


MCIWndPlayFrom

This MCIWnd macro specifies the starting position for playing and has the MCI device start playing.

LONG MCIWndPlayFrom(HWND hwnd, LONG lPos)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCIWnd window.

lPos

Specifies the starting position for the sequence.

This macro starts play from the specified position. Playing continues until it is stopped or play reaches the end of the sequence.

This macro is defined with the MCIWNDM_PLAYFROM message. The wParam parameter for the message is set to zero, and the lParam parameter has the same definition as lPos.


MCIWndPlayFromTo

This MCIWnd macro specifies the starting and ending positions for playing a sequence and has the MCI device start playing.

LONG MCIWndPlayFromTo(HWND hwnd, LONG lStart, LONG lEnd)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

lStart

Specifies the starting position for the sequence.

lEnd

Specifies the ending position for the sequence.

This macro seeks to the starting position and then starts playing. Play stops when the sequence reaches the specified position (or the end of the sequence, if the specified position is beyond the end of the sequence).

This macro is defined with the MCIWndSeek and MCIWndPlayTo macros.


MCIWndPlayReverse

This MCIWnd macro has the MCI device start playing the sequence in reverse.

LONG MCIWndPlayReverse(HWND hwnd)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

This macro starts play from the current position. Play stops when the sequence reaches the beginning of the file or it is stopped.

This macro is defined with the MCIWNDM_PLAYREVERSE message. The wParam and lParam parameters for the message are set to zero.


MCIWndPlayTo

This MCIWnd macro specifies the ending position for playing and has the MCI device start playing.

LONG MCIWndPlayTo(HWND hwnd, LONG lPos)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

lPos

Specifies the ending position for the sequence.

This macro starts play from the current position. Play stops when the sequence reaches the specified position (or the end of the sequence, if the specified position is beyond the end of the sequence).

This macro is defined with the MCIWNDM_PLAYTO message. The wParam parameter is set to zero for the message, and the lParam parameter has the same definition as lPos.


MCIWndPutDest

This MCIWnd macro specifies the destination rectangle for an MCI device.

LONG MCIWndPutDest(HWND hwnd, RECT prc)

•	Returns zero if successful. Otherwise, it returns an error.

hwnd

Specifies the handle to the MCIWnd window.

prc

Specifies a rectangle indicating image destination.

This macro is defined with the MCIWNDM_PUT_DEST message. The wParam parameter is set to zero and the lParam has the same definition as prc.


MCIWndPutSource

This MCIWnd macro specifies the source rectangle for an MCI device.

LONG MCIWndPutSource(HWND hwnd, RECT prc)

•	Returns zero if successful. Otherwise, it returns an error.

hwnd

Specifies the handle to the MCIWnd window.

prc

Specifies a rectangle indicating image source.

This macro is defined with the MCIWNDM_PUT_SOURCE message. The wParam parameter is set to zero and the lParam has the same definition as prc.


MCIWndRealize

This MCIWnd macro has an MCI device realize its palette.

LONG MCIWndRealize(HWND hwnd, BOOL fBkgnd)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

fBkgnd

Set to TRUE if the window is a background application.

Call this macro from the WM_PALETTECHANGED and WM_QUERYNEWPALETTE message handlers instead of using RealizePalette. This MCIWnd macro uses the palette of the MCI device and calls RealizePalette. If realizing the palette is the only purpose of your WM_PALETTECHANGED and WM_QUERYNEWPALETTE message handlers, just pass the WM_PALETTECHANGED and WM_QUERYNEWPALETTE messages on to the MCI window and it will automatically realize the palette.

This macro is defined with the MCIWNDM_REALIZE message. The wParam parameter for the message has the same definition as fBkgnd, and the lParam parameter is set to zero.


MCIWndRecord

This MCIWnd macro has an MCI device start recording.

LONG MCIWndRecord(HWND hwnd)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

This macro starts recording from the current position.

This macro is defined with the MCI_RECORD message. The wParam and lParam parameters for the message are set to zero.


MCIWndRegisterClass

This function registers the MCI window class MCIWND_WINDOW_CLASS.

BOOL MCIWndRegisterClass()

•	Returns zero if the class is registered successfully.

Use CreateWindow to create the window used for playing the MCI device. Use MCIWndCreate to simultaneously register the window class and create a window.


MCIWndResume

This MCIWnd macro has an MCI device continue playing or recording.

LONG MCIWndResume(HWND hwnd)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

This macro is defined with the MCI_RESUME message. The wParam and lParam parameters for the message are set to zero.


MCIWndReturnString

This MCIWnd macro obtains the string information returned by an MCI device.

LONG MCIWndReturnString(HWND hwnd, LPARAM lp, int iLen)

•	Returns an integer corresponding to the MCI string.

hwnd

Specifies the handle to the MCI window.

lp

Specifies a pointer to the application-supplied buffer used to return the zero-terminated string.

iLen

Specifies the size of the data buffer.

If the zero-terminated string is longer than the buffer, it is truncated.

This macro is defined with the MCIWNDM_RETURNSTRING message. The wParam parameter for the message has the same definition as iLen, and the lParam parameter has the same definition as lp.


MCIWndSave

This MCIWnd macro has an MCI device save its data.

LONG MCIWndSave(HWND hwnd, LPSTR szFile)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

szFile

Specifies a zero-terminated string containing the name and path of the destination file. Specifying -1 for this parameter has the device display its dialog box for specifying the filename.

This macro is defined with the MCI_SAVE message. The wParam parameter for the message is set to zero, and the lParam parameter has the same definition as szFile.


MCIWndSaveDialog

This MCIWnd macro displays a dialog box for specifying the filename used to save data and has the MCI device save the data.

LONG MCIWndSaveDialog(HWND hwnd)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

This macro is defined with the MCI_SAVE message. The wParam parameter for the message is set to zero, and the lParam parameter is set to -1.


MCIWndSeek

This MCIWnd macro sends the MCI_SEEK message to an MCI device to seek to a specified position.

LONG MCIWndSeek(HWND hwnd, LONG lPos)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCIWnd window.

lPos

Specifies the seek position.

The units for the seek position depend on the current time format.

This macro is defined with the MCI_SEEK message. The wParam parameter for the message is set to zero, and the lParam parameter has the same definition as lPos.


MCIWndSendString

This MCIWnd macro sends a string command to an MCI device.

LONG MCIWndSendString(HWND hwnd, LPSTR sz)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

sz

Specifies a string to send to the MCI device.

When sending a string with this macro, omit the alias used when the string is sent with mciSendString.

This macro is defined with the MCIWNDM_SENDSTRING message. The wParam parameter for the message is set to zero, and the lParam parameter has the same definition as sz.


MCIWndSetActiveTimer

This MCIWnd macro sets the period used by MCIWnd to update the scroll bar, position information displayed in the window caption, and send notification messages to the parent window when the MCIWnd window is the active window.

VOID MCIWndSetActiveTimer(HWND hwnd, int iActive)

hwnd

Specifies the handle to the MCIWnd window.

iActive

Specifies an integer timer period in milliseconds.

This macro is defined with the MCIWNDM_SETACTIVETIMER message. The wParam parameter for the message has the same definition as iActive, and the lParam parameter is set to zero.


MCIWndSetInactiveTimer

This MCIWnd macro sets the period used by MCIWnd to update the scroll bar, position information displayed in the window caption, and send notification messages to the parent window when the MCIWnd window is the inactive window.

VOID MCIWndSetInactiveTimer(HWND hwnd, int iInactive)

hwnd

Specifies the handle to the MCI window.

iInactive

Specifies an integer timer period in milliseconds.

This macro is defined with the MCIWNDM_SETINACTIVETIMER message. The wParam parameter for the message has the same definition as iInactive, and the lParam parameter is set to zero.


MCIWndSetPalette

This MCIWnd macro sends a palette handle to an MCI device.

LONG MCIWndSetPalette(HWND hwnd, HPALETTE hpal)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCIWnd window.

hpal

Specifies the handle to the palette.

This macro is defined with the MCIWNDM_SETPALETTE message. The wParam parameter for the message has the same definition as hpal, and the lParam parameter is set to zero.


MCIWndSetRepeat

This MCIWnd macro has MCIWnd repeat a play sequence.

void MCIWndSetRepeat(HWND hwnd, BOOL f)

•	Returns TRUE if the flag is set.

hwnd

Specifies the handle to the MCI window.

f

Set to TRUE if MCIWnd is to continuously repeat a sequence.

This macro is defined with the MCIWNDM_SETREPEAT message. The wParam parameter is set to zero, and the lParam parameter has the same definition as f.


MCIWndSetSpeed

This MCIWnd macro sets the playback speed of an MCI device.

LONG MCIWndSetSpeed(HWND hwnd, int iSpeed)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCIWnd window.

iSpeed

Specifies the playback speed. Specify 1000 for the normal speed. Specify larger values for faster speeds and smaller values for slower speeds.

This macro is defined with the MCIWNDM_SETSPEED message. The wParam parameter for the message is set to zero, and the lParam parameter has the same definition as iSpeed.


MCIWndSetTimeFormat

This MCIWnd macro specifies the time format used by an MCI device.

LONG MCIWndSetTimeFormat(HWND hwnd, LPSTR lp)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

lp

Specifies a pointer to a data buffer containing the zero-terminated string indicating the time format.

Applications can specify formats other than frames and milliseconds if they are supported by the MCI device. Non-continuous formats, such as tracks and SMPTE, can cause the scroll bar to behave erratically. For these time formats, applications might change the window style by using MCIWNDF_NOPLAYBAR to turn off the play bar.

This macro is defined with the MCIWNDM_SETTIMEFORMAT message. The wParam parameter for the message is set to zero, and the lParam parameter has the same definition as lp.


MCIWndSetTimers

This MCIWnd macro sets the time periods used by MCIWnd to update the scroll bar, position information displayed in the window caption, and send notification messages to the parent window.

VOID MCIWndSetTimers(HWND hwnd, int iActive, int iInactive)

hwnd

Specifies the handle to the MCI window.

iActive

Specifies an integer timer period used by MCIWnd when it is the active window. This value is limited to 16 bits.

iInactive

Specifies an integer timer period used by MCIWnd when it is the inactive window. This value is limited to 16 bits.

This macro is defined with the MCIWNDM_SETTIMERS message. The wParam parameter for the message has the same definition as iActive, and the lParam parameter has the same definition as iInactive.


MCIWndSetVolume

This MCIWnd macro sets the volume level of an MCI device.

LONG MCIWndSetVolume(HWND hwnd, int iVol)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

iVol

Specifies the volume level. Specify 1000 for the normal volume level. Specify larger values to increase the volume level and smaller values to decrease the volume level.

This macro is defined with the MCIWNDM_SETVOLUME message. The wParam parameter for the message is set to zero, and the lParam parameter has the same definition as iVol.


MCIWndSetZoom

This MCIWnd macro has an MCI device stretch a video image.

VOID MCIWndSetZoom(HWND hwnd, int iZoom)

hwnd

Specifies the handle to the MCIWnd window.

iZoom

Specifies an integer indicating the zoom factor as a percentage of the original image. Specifying 100 displays the image at its authored size. Specifying 200 displays the image at twice normal size. Specifying 50 displays the image at half normal size.

This macro is defined with the MCIWNDM_SETZOOM message. The wParam parameter for the message is set to zero, and the lParam parameter has the same definition as iZoom.


MCIWndStep

This MCIWnd macro steps an MCI-device element.

LONG MCIWndStep(HWND hwnd, LPARAM n)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

n

Specifies the number of frames or milliseconds to step. Negative values step the device element in reverse.

The units for the step value depend on the current time format.

This macro is defined with the MCI_STEP message. The wParam parameter is set to zero and the lParam has the same definition as n.


MCIWndStop

This MCIWnd macro has an MCI device stop playing or recording.

LONG MCIWndStop(HWND hwnd)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCI window.

This macro is defined with the MCI_STOP message. The wParam and lParam parameters for the message are set to zero.


MCIWndUseFrames

This MCIWnd macro has an MCI device set its time format to frames.

LONG MCIWndUseFrames(HWND hwnd)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCIWnd window.

This macro is defined with the MCIWNDM_SETTIMEFORMAT message. The wParam parameter for the message is set to zero, and the lParam parameter is set to "frames".


MCIWndUseTime

This MCIWnd macro has an MCI device set its time format to milliseconds.

LONG MCIWndUseTime(HWND hwnd)

•	Returns zero if successful. Otherwise, it returns an MCI error code.

hwnd

Specifies the handle to the MCIWnd window.

This macro is defined with the MCIWNDM_SETTIMEFORMAT message. The wParam parameter for the message is set to zero, and the lParam parameter is set to "ms".


MCIWndValidateMedia

This macro has MCIWnd synchronize its position information to the new media when it has changed.

VOID MCIWndValidateMedia(HWND hwnd)

hwnd

Specifies the handle to the MCI window.

If your application changes the time format of a device without using MCIWnd, the starting and ending position of the media, as well as the track bar, continue to use the old format. Use the MCIWndValidateMedia macro to update these values. In general, you should not need to use this macro.

This macro is defined with the MCIWNDM_VALIDATEMEDIA message. The wParam and lParam parameters for the message are set to zero.


AVI File Capture: AVICap


About AVI File Capture

The AVICap window class lets you easily incorporate video-capture capabilities into your application. The AVICap window class provides client applications with a simple, message-based interface to access video and wave audio acquisition hardware, and control the process of streaming video capture to disk.

The AVICap window class supports four forms of video capture: streaming video capture, streaming video capture with MCI control, step video capture with MCI control, and single-frame capture.

A window created using the AVICap window class encompasses much of the functionality found in the VidCap application included in Video for Windows. Windows created using the AVICap window class can perform the following functions:

•	Capture audio and video streams to an AVI file

•	Dynamically connect and disconnect video and audio input devices

•	View live video using either overlay or preview methods

•	Specify a file to use when capturing and copy the contents of the capture file to another file

•	Set the capture rate

•	Display dialog boxes that control the video source and format

•	Create, save, and load palettes

•	Copy images and palettes to the Clipboard


AVICap Window Class Architecture

A window with the AVICap window class encapsulates all of the details of streaming audio and video capture to AVI files. Your application does not need to be involved with the details of the AVI file format, video and audio buffer management, or the low-level access of video and audio device drivers.

The AVICap window class provides a flexible interface for client applications. With a minimum of programming effort, you can add video capture to your application with only the following lines of code:

hwndC = capCreateCaptureWindow ( "My Own Capture Window",

            WS_CHILD | WS_VISIBLE , 0, 0, 160, 120, hwndParent, nID);

SendMessage (hwndC, WM_CAP_DRIVER_CONNECT, 0 /*wIndex*/, 0L);

SendMessage (hwndC, WM_CAP_SEQUENCE, 0, 0L);

By using other AVICap messages, your application can just as easily control most other aspects of the capture process.

A macro interface is also available. These macros isolate your application from the SendMessage interface:

hwndC = capCreateCaptureWindow (    "My Own Capture Window",

            WS_CHILD | WS_VISIBLE ,    0, 0, 160, 120, hwndParent, nID);

capDriverConnect (hwndC, 0);

capCaptureSequence (hwndC);

AVICap windows are conceptually similar to standard Windows controls, such as buttons, list boxes, or scroll bars. The client application creates the capture window, and then sends control messages to it with SendMessage.


Creating AVICap Windows

Applications use the capCreateCaptureWindow function to create an AVICap window.

Your application can create one or more AVICap windows. Typically, these windows use the style WS_CHILD | WS_VISIBLE. Each capture window can be connected to a different capture device.

The window handle returned from capCreateCaptureWindow identifies the AVICap window. Your application uses this handle to send subsequent messages to the window.


Connecting to a Video-Capture Device Driver

The process of connecting to a driver associates the AVICap window with a particular video-capture device driver. Before connecting to a driver, messages that are device specific (such as WM_CAP_GET_VIDEOFORMAT or WM_CAP_DRIVER_GET_CAPS) fail. Applications use the WM_CAP_DRIVER_CONNECT message to connect to a driver and use WM_CAP_DRIVER_DISCONNECT to disconnect from a driver.

Applications can dynamically connect and disconnect a video-capture device driver from an AVICap window. When an AVICap window is destroyed, any connected video-capture device driver is automatically disconnected.


Enumerating Installed Capture Devices

Your application can connect to a particular video-capture device driver by specifying an integer for the wParam parameter of the WM_CAP_DRIVER_CONNECT message. The integer corresponds to the indexes of the MSVideo drivers listed in the system registry.

Specifying zero for the index used with the WM_CAP_DRIVER_CONNECT message corresponds to the first MSVideo driver.

Applications can enumerate the installed video-capture device drivers and let the user select the capture device to connect to the AVICap window. Your application can use capGetDriverDescription to obtain the name and version of an installed video-capture device driver.

Your application can also use the WM_CAP_DRIVER_GET_NAME message to retrieve the name of the video-capture device driver connected to the capture window and use the WM_CAP_DRIVER_GET_VERSION message to obtain its version.


Controlling the Capture Window

Once an application creates the AVICap window and connects it to a video driver, the AVICap window is ready to capture data. At this point, applications can simply send the WM_CAP_SEQUENCE message to begin capturing.

By default, WM_CAP_SEQUENCE initiates capture of video and audio to a file named CAPTURE.AVI using default settings. Capture continues until one of the following events occurs:

•	The user presses the esc key.

•	A mouse button is pressed.

•	The disk is full.

Most applications can exert more control over the capture process as described in the following sections.


Parent-Child Window Interaction

Some system-level messages are sent only to top-level and overlapped windows. If the AVICap window is a child window, its parent must forward certain messages. In particular, the parent must forward WM_PALETTECHANGED and WM_QUERYNEWPALETTE.

Similarly, if the parent window changes size, it might need to send notification messages to the AVICap window. Conversely, if the dimensions of the captured video change, the AVICap window might need to send notification messages to the parent window. The simplest strategy is to always keep the capture window dimensions equal to the size of the captured video stream, and then notify the parent whenever these dimensions change.


Obtaining the Video-Device Capabilities

Once a driver is connected to the AVICap window, an application can use the WM_CAP_DRIVER_GET_CAPS message to obtain the hardware capabilities of the currently connected video-capture device driver. This message returns the capabilities of the driver and underlying hardware in the CAPDRIVERCAPS structure.


Obtaining the Status of an AVICap Window

The CAPSTATUS structure contains information regarding the dimensions of the image, scroll position, and whether overlay or preview of the image is enabled. Your application can use the WM_CAP_GET_STATUS message to obtain this structure containing the current status of an AVICap window.

Because the information represented in the CAPSTATUS structure is dynamic, your application should refresh the contents of the structure whenever your application displays the video format dialog box of the driver.

Changing the dimensions of the AVICap window has no effect on the dimensions of the actual video stream captured. The format dialog box displayed by the video-capture device driver controls the dimensions of the video stream captured.


Dialog Boxes for Setting the Video Format

Each video-capture device driver can provide up to three different dialog boxes to control aspects of the video digitization and capture process. (In the VidCap application, these three dialog boxes are invoked by three entries in the Options menu.) The video source dialog box controls selection of video input channels and controls parameters such as hue, brightness, and contrast. The video format dialog box controls selection of the dimensions of the captured video, compression and bit-depth of the captured video. The video display dialog box controls the appearance of the video on the monitor during capture, but it does not actually affect the video during digitization (that is, it controls post-capture effects only). The contents of these dialog boxes are defined by the video-capture driver.

One additional dialog box lets the user set the post-capture video compression attributes. The contents of this dialog box depend on the compression format selected.

If supported by a video-capture device driver, your application can use the following messages to display the dialog boxes. The WM_CAP_DLG_VIDEODISPLAY message displays a dialog box used to control the video output. The WM_CAP_DLG_VIDEOFORMAT message displays a dialog box used to select the video format. The WM_CAP_DLG_VIDEOSOURCE message displays a dialog box used to control the video source. The WM_CAP_DLG_VIDEOCOMPRESSION message displays a dialog box used to control the video compression.


Messages to Obtain and Set the Video Format

An application can use the WM_CAP_GET_VIDEOFORMAT message to obtain the video format data structure or its size, and it can use WM_CAP_SET_VIDEOFORMAT to set the format for capturing video.


Previewing Live Video

In preview mode, frames are transferred from the capture hardware to system memory and then displayed in the capture window using GDI functions. The WM_CAP_SET_PREVIEW and WM_CAP_SET_PREVIEWRATE messages control the preview operation. The WM_CAP_SET_PREVIEW message enables or disables preview mode. The WM_CAP_SET_PREVIEWRATE message sets the rate at which frames are displayed in preview mode.

Client applications might decrease the preview rate when the parent loses focus, and increase the preview rate when the parent gains focus. This improves general system responsiveness, because the preview operation is processor intensive.

Enabling video preview automatically disables video overlay.


Enabling Overlay of Live Video

Some capture devices support the display of live video using overlay. This hardware function displays the video on the VGA screen independent of the central processor. Applications can use the WM_CAP_SET_OVERLAY message to enable and disable video overlay. Enabling video overlay automatically disables video preview.


Setting the Capture File

By default, the AVICap window streams video to a file named CAPTURE.AVI in the root directory of the current drive. An application can specify an alternate filename with the WM_CAP_FILE_SET_CAPTURE_FILE message. It can use the WM_CAP_FILE_GET_CAPTURE_FILE message to retrieve the name of the current capture file.

The WM_CAP_FILE_SET_CAPTURE_FILE message only specifies the filename; it does not create, allocate, or open the file.


Preallocating Disk Space for the Capture File

Preallocation reduces the amount of processing required while capture is underway and results in fewer frames dropped. Your application only needs to preallocate a file the first time it is used. All subsequent operations on the capture file by the AVICap window preserve the file size and state of fragmentation. Typically, your application should preallocate enough disk space to hold the largest capture file anticipated. Preallocating disk space does not restrict the size of the captured file. The file size is automatically enlarged if the captured data exceeds the space allocated. An application can use the WM_CAP_FILE_ALLOCATE message to preallocate a new capture file.

Applications can obtain the best capture performance by both preallocating and defragmenting the capture file. If defragmented disk space is critical to your capture performance, avoid capturing files larger than the disk space preallocated and defragmented. Overwriting the disk space enlarges the preallocated space but the new space might not be adjacent to the original disk space. You might also improve performance by using an uncompressed disk for video capture. Compressing data during capture can limit capture throughput to the disk.

An application might reserve a permanent capture file to eliminate the time required to preallocate and defragment a file each time it is started. Because a capture file can require considerable disk space, and preallocating a capture file removes all data from an existing capture file, an application should let the user decide if the file is permanent or temporary.


Controlling Audio Capture

By default, audio is captured in a mono, 8-bit, 11-kHz PCM format. An application can use the WM_CAP_SET_AUDIOFORMAT message to change the audio format, and it can use the WM_CAP_GET_AUDIOFORMAT message to determine the current format or the size of the audio format structure.

To retrieve the current format, use the WM_CAP_GET_AUDIOFORMAT message. If NULL is specified for lParam, the function returns the size of the WAVEFORMATEX structure required to hold the audio format.

When setting the audio format, your application can pass a pointer to either a WAVEFORMAT or PCMWAVEFORMAT structure instead of the WAVEFORMATEX structure. When retrieving the format using the WM_CAP_GET_AUDIOFORMAT message, always use the WAVEFORMATEX structure.


Controlling Video Capture

The CAPTUREPARMS data structure contains the control parameters for streaming video capture. This structure controls aspects of the capture process such as:

•	specifying the frame rate

•	specifying the number of video buffers allocated

•	specifying use of memory below 1 megabyte

•	disabling and enabling audio capture

•	specifying the time interval for the capture

•	specifying if an MCI device (VCR or videodisc) is used during capture

•	specifying user mouse or keyboard control for ending streaming

•	specifying the type of video averaging applied during capture

The WM_CAP_SET_SEQUENCE_SETUP and WM_CAP_GET_SEQUENCE_SETUP messages let your application set and retrieve the CAPTUREPARMS structure. To determine the current settings used for capture, an application can use the WM_CAP_GET_SEQUENCE_SETUP message to obtain them. An application uses WM_CAP_SET_SEQUENCE_SETUP to send new settings to the AVICap window. If your application is changing only a few of the settings, it can get the current settings with WM_CAP_GET_SEQUENCE_SETUP, modify the members that need to be changed, and then return the structure with WM_CAP_SET_SEQUENCE_SETUP.

The fYield member in the CAPTUREPARMS structure controls whether message processing continues during capture and if a background task performs the capture. Continuing to process messages during capture is not required to detect the mouse or keyboard activities that terminate the capture, and message processing usually has a detrimental effect on capture rates. In addition, applications that enable message processing while capturing must ignore messages that could cause reentrancy problems.


Capturing Data

Once an application completes the setup, it uses the WM_CAP_SEQUENCE message to initiate background streaming video and audio capture to a file. An application uses the WM_CAP_STOP message to stop streaming captured data into a file. It uses WM_CAP_ABORT to abort streaming video and audio capture.

Capture continues until it is stopped or until the disk is full. Applications stop capture with the WM_CAP_STOP message. The user stops capture by clicking a mouse button or pressing a key. The AVICap window stops capture when the capture time limit or MCI stop time is reached.


Single-Frame Capture

If your application is capturing video one frame at a time, it can use the WM_CAP_SINGLE_FRAME_OPEN, WM_CAP_SINGLE_FRAME, and WM_CAP_SINGLE_FRAME_CLOSE messages to control the sequence. The WM_CAP_SINGLE_FRAME_OPEN message opens a file for single-frame capture. The WM_CAP_SINGLE_FRAME message captures a single frame and appends it to the capture file. The WM_CAP_SINGLE_FRAME_CLOSE message closes the file used for single-frame capture.

These messages are typically used to create animation by appending individual frames to the capture file. Frame capture can be initiated by application control or user control.


Copying the Capture File

Applications should copy the captured data into a new file when the user wants to retain it. Copying the data to a new file preserves the preallocated, and usually defragmented, disk space reserved for video capture. Only the AVI data is copied to the new file, so the new file is usually smaller than the preallocated file used for capturing data (that is, the unused portion of the preallocated file is not copied). The WM_CAP_FILE_SAVEAS message copies the contents of the capture file to another file. Because the video-capture file retains its filename, your application must use a new name for the new file.


Embedding Text Strings or Information in an AVI File

The WM_CAP_FILE_SET_INFOCHUNK message sets and clears information chunks. Applications can use this message to embed text strings or custom data in the file.


Yielding to Other Applications

By default, the AVICap window blocks other applications. Blocking other applications lets AVICap use the highest data rates possible and results in fewer dropped frames. If your application wants other applications to continue running, it can set the fYield member of the CAPTUREPARMS structure to TRUE. When this member is set to TRUE, messages continue to be dispatched during streaming capture. Applications using this flag must prevent reentrant calls. Applications can install their own custom yield processing function using the WM_CAP_SET_CALLBACK_YIELD message.


AVICap Callback Functions

Your application can register callbacks with the AVICap window to have it notify your application when the status changes, when errors occur, when video frame and audio buffers become available, and to yield during streaming capture. The following messages set the callback procedure.

Message	Description
WM_CAP_SET_CALLBACK_ERROR	Specifies the callback procedure in the client application called when an error occurs.
WM_CAP_SET_CALLBACK_FRAME	Specifies the callback procedure in the client application called when preview frames are captured.
WM_CAP_SET_CALLBACK_STATUS	Specifies the callback procedure in the client application called when the status changes.
WM_CAP_SET_CALLBACK_VIDEOSTREAM	Specifies the callback procedure in the client application called during streaming capture when a new video buffer becomes available.
WM_CAP_SET_CALLBACK_WAVESTREAM	Specifies the callback procedure in the client application called during streaming capture when a new audio buffer becomes available.
WM_CAP_SET_CALLBACK_YIELD	Specifies the callback procedure in the client application called when yielding during streaming capture.


Status Callbacks

The AVICap window can send messages to the status callback function during the process of capturing video to disk, and during other lengthy operations, so that the callback function notifies your application of the progress of an operation. In VidCap, this information is displayed in the status bar at the bottom of the application window. The AVICap window sends this same information through your application's status callback function for optional display. The callback information includes both a message ID and a formatted text string ready for display. Your application can use the message ID to filter the status callbacks and limit the messages it presents to the user. During all capture operations, the first message sent to the callback is always IDS_CAP_BEGIN and the last message is always IDS_CAP_END. A message ID of zero indicates a new operation is starting so the callback should clear the current status.


Error Callbacks

Similar in concept to status callbacks, the AVICap window uses error callbacks to notify your application of AVICap errors. Errors include faults such as a disk full error, attempting to write to a read-only file, problems with hardware access, or if too many frames have been dropped. The callback notification includes a message ID and a formatted text string ready for display. Your application can use the message ID to filter the error callbacks and limit the messages it presents to the user. A message ID of zero indicates a new operation is starting so the callback should clear a displayed error message.


Frame Callbacks

The AVICap window uses frame callbacks to notify your application whenever a new video frame is available. The AVICap window enables these callbacks only if the preview rate is non-zero and streaming capture is not in progress.


Yield Callback Functions

Applications use yield callbacks during streaming capture to continue message processing. A yield callback routine typically consists of a PeekMessage, TranslateMessage, DispatchMessage loop, with filtering of messages that could cause reentrancy problems (such as attempting to start a streaming capture when it is already started). While the exact rate at which the AVICap window calls the yield callback function depends on the frame rate and driver and disk overheads, the AVICap window calls the yield callback function at least once for every video frame captured.


Videostream Callback Functions

Applications use the videostream callback functions during streaming capture to process a captured video frame. The AVICap window calls a videostream callback just prior to writing each captured frame to the disk.


Wavestream Callback Functions

Applications use the wavestream callback functions during streaming capture to process audio buffers. The AVICap window calls a wavestream callback function just prior to writing each audio buffer to the disk.


Disabling Callback Functions

Any of the callback functions can be disabled, either temporarily or permanently, by using NULL in place of the callback function.


Capturing from MCI Devices

An application can capture data from an MCI device, such as a videodisc or video tape recorder by specifying the name of the device with the WM_CAP_SET_MCI_DEVICE message. An application can determine the device name set previously by retrieving it with the WM_CAP_GET_MCI_DEVICE message.

The MCI device itself is controlled through the CAPTUREPARMS data structure. If the fMCIControl member is set to TRUE, the AVICap window coordinates MCI operation. It uses the parameters specified in the dwMCIStartTime and dwMCIStopTime members of the CAPTUREPARMS structure for the starting and stopping positions of the sequence. The starting and stopping positions are specified in milliseconds.

The AVICap window synchronizes the capture operation and compensates for the delays associated with positioning the MCI video source and initializing the resources required for capturing data (such as capture buffers). The AVICap window expects a valid MCI video device to be installed in the system for capturing data this way.

If you need to verify that an MCI video device is properly connected to the system, you can use MPlayer for a quick test. Playing a device with MPlayer verifies that the MCI configuration for the device is correct. By observing if an image appears on the video display, you can determine if the video source is connected properly to the video-capture hardware.


Working with Palettes

Initially, if an application is capturing palettized video, the AVICap window uses the palette supplied by the video-capture device driver. This palette might consist of gray-scale values for black-and-white reproduction, or consist of a broad selection of color values. Your application can replace the default palette by creating a custom palette with the WM_CAP_PAL_AUTOCREATE or WM_CAP_PAL_MANUALCREATE message, or it can retrieve an existing palette with the WM_CAP_PAL_PASTE or WM_CAP_PAL_OPEN message. Once your application replaces the default palette, the AVICap window and driver use the replacement palette until your application creates or loads another one.

The WM_CAP_PAL_AUTOCREATE or WM_CAP_PAL_MANUALCREATE message creates an optimized palette based on the current video input. This custom palette gives a video sequence the best color fidelity because it is based upon colors that exist in the sequence. The AVICap window creates a 3-D histogram of the colors it samples. It reduces the number of colors by examining the absolute error between adjacent colors and consolidating those with the smallest error value.

When sending the WM_CAP_PAL_AUTOCREATE message, your application must specify the number of frames AVICap must sample and the size of the color palette. When specifying the number of frames, include enough frames to make sure that all colors in the sequence are sampled.

Your application can use the WM_CAP_PAL_MANUALCREATE message to sample the current frame. This lets your application create a palette from individual frames that contain the colors you want to appear.

Your application can specify up to 256 colors for the palette. If your application merges palettes or if the video sequence is to be displayed simultaneously with other video or images, your application should use a smaller palette so that other palette colors can coexist with it.

Your application can use WM_CAP_PAL_SAVE to save a new palette and later retrieve it with WM_CAP_PAL_OPEN. Your application can save a palette for post-processing of the palette or for use in another application.

Your application can use WM_CAP_PAL_PASTE to paste a palette from the Clipboard into the AVICap window. The AVICap window passes the palette on to the video-capture device driver. Palettes on the Clipboard can come from other applications or your application can use WM_CAP_EDIT_COPY to copy the video frame buffer onto the Clipboard. WM_CAP_PAL_PASTE only copies the palette information from the Clipboard, it does not copy the image.


Controlling the Video Display

The WM_CAP_SET_SCALE and WM_CAP_SET_SCROLL messages control the presentation of the video. The WM_CAP_SET_SCALE message enables or disables scaling of the preview video. If enabled, the captured video frame is stretched to the dimensions of the AVICap window. The WM_CAP_SET_SCROLL message sets the scroll position of the video frame within the client area of the AVICap window.


Directly Using Capture Data

The WM_CAP_SEQUENCE_NOFILE message lets your application use video-capture services without writing the data to a disk file. This message is only useful in conjunction with callbacks that let your application use the video and audio data directly. For example, videoconferencing applications might use this message to obtain streaming video frames. The callback functions would transfer the captured images to the remote computer.


Obtaining Single Frames

A set of messages has AVICap capture a single frame of data. The WM_CAP_GRAB_FRAME_NOSTOP and WM_CAP_GRAB_FRAME messages capture single frames to an internal buffer. The WM_CAP_EDIT_COPY message copies the frame buffer onto the Clipboard. The WM_CAP_FILE_SAVEDIB message copies the current frame buffer to a DIB file. Your application can use the two single-frame capture messages to edit a sequence frame by frame, or to create a time-lapse photography sequence. Your application can use the Clipboard and the WM_CAP_EDIT_COPY message or the WM_CAP_FILE_SAVEDIB to copy a frame to another application.


User Data Messages

The WM_CAP_GET_USER_DATA and WM_CAP_SET_USER_DATA messages let your application associate data with an AVICap window. The WM_CAP_GET_USER_DATA message retrieves a LONG data value, and the WM_CAP_SET_USER_DATA message sets a LONG data value.


Using AVI File Capture

This section contains information about using the AVICap window class. Example code fragments illustrate some of the concepts involved with the window class.


Creating an AVICap Window

The following example creates an AVICap window with capCreateCaptureWindow:

hwndC = capCreateCaptureWindow (

            (LPSTR) "My Capture Window", // Window name if popup

            WS_CHILD | WS_VISIBLE,       // window style

            0, 0, 160, 120,              // window position and

                                         // dimensions

            (HWND) hwndParent,

            (int) nID /* child ID */);


Connecting to a Video-Capture Device Driver: Examples

The following example connects the AVICap window with the handle hWndC to the MSVideo driver:

fOK = SendMessage (hwndC, WM_CAP_DRIVER_CONNECT, 0, 0L);

The following example demonstrates how to disconnect from a video-capture device driver:

SendMessage (hwndC, WM_CAP_DRIVER_DISCONNECT, 0, 0L);


Enumerating Installed Capture Devices: An Example

The following example uses capGetDriverDescription to obtain the names and versions of the installed drivers:

char szDeviceName [80];

char szDeviceVersion[80];

for (wIndex = 0; wIndex < 10; wIndex++) {

    if (capGetDriverDescription (wIndex,

                    szDeviceName,

                    sizeof (szDeviceName),

                    szDeviceVersion,

                    sizeof (szDeviceVersion)) {

            /* append the name to a list of installed drivers */

            /* wIndex is the index of the driver */

    }

}


Obtaining the Capabilities of a Video Device

The WM_CAP_DRIVER_GET_CAPS message returns the capabilities of the driver and underlying hardware in the CAPDRIVERCAPS structure. Because this information is generally useful, many of the following examples assume this structure is globally allocated and refer to its contents. Each time an application connects a new driver to the AVICap window, it should update the CAPDRIVERCAPS structure. The following example obtains the device capabilities:

CAPDRIVERCAPS CapDrvCaps;

SendMessage (hwndC, WM_CAP_DRIVER_GET_CAPS,

        sizeof (CAPDRIVERCAPS), (LONG)(LPVOID) &CapDrvCaps);


Obtaining the Status of an AVICap Window: An Example

The following example sets the size of the AVICap window to the overall dimensions of the incoming video stream based on information returned in the CAPSTATUS structure:

CAPSTATUS CapStatus;

SendMessage (hwndC, WM_CAP_GET_STATUS,

        sizeof (CAPSTATUS), (LONG) (LPVOID) &CapStatus);

SetWindowPos (hwndC, NULL, 0, 0,

        CapStatus.uiImageWidth, CapStatus.uiImageHeight,

        SWP_NOZORDER | SWP_NOMOVE);


Displaying Dialog Boxes for Setting the Video Format

Each video-capture device driver can provide up to three different dialog boxes used to control aspects of the video digitization and capture process. The examples in this section demonstrate how these dialog boxes are displayed. Before sending the message to display a dialog box, each example checks the CAPDRIVERCAPS structure to see if the driver can display it.

The following example displays the video source dialog box:

if (CapDriverCaps.fHasDlgVideoSource)

    SendMessage (hwndC, WM_CAP_DLG_VIDEOSOURCE, 0, 0L);

The following example displays the video format dialog box:

if (CapDriverCaps.fHasDlgVideoFormat) {

    SendMessage (hwndC, WM_CAP_DLG_VIDEOFORMAT, 0, 0L);

    // Find out the possibly new image dimensions

    SendMessage (hwndC, WM_CAP_GET_STATUS,

        sizeof (CAPSTATUS), (LONG) (LPVOID) &CapStatus);

    // Possibly notify the parent of a size change

}

The following example displays the video display dialog box:

if (CapDriverCaps.fHasDlgVideoDisplay)

    SendMessage (hwndC, WM_CAP_DLG_VIDEODISPLAY, 0, 0L);


Obtaining and Setting the Video Format

Video for Windows expanded the use of the BITMAPINFO data structure to include standard and compressed data formats. Because this structure is of variable length, applications must always query the size of the structure and allocate memory before retrieving the current video format. The following example uses WM_CAP_GET_VIDEOFORMAT twice to obtain the video format. The first time, the example sends WM_CAP_GET_VIDEOFORMAT without a return buffer to obtain the size of the buffer needed for the structure. The second time, the example sends a pointer to the return buffer used to return the structure.

LPBITMAPINFO lpbi;

DWORD dwSize;

dwSize = SendMessage (hwndC, WM_CAP_GET_VIDEOFORMAT, 0, 0L);

lpbi = GlobalAllocPtr (GHND, dwSize);

SendMessage (hwndC, WM_CAP_GET_VIDEOFORMAT,

            (WORD) dwSize, (LONG)(LPVOID)lpbi);

// Access the video format and then free the allocated memory

Applications use the WM_CAP_SET_VIDEOFORMAT message to send a BITMAPINFO header structure to the AVICap window. Because video formats are device specific, your application should check the return value to determine if the format was accepted.


Previewing Live Video: An Example

The following example sets the preview rate to 66 milliseconds, and then places the window in preview mode:

SendMessage (hwndC, WM_CAP_SET_PREVIEWRATE, 66 /*rate in MS*/, 0L);

SendMessage (hwndC, WM_CAP_SET_PREVIEW, 1 /*fEnable*/, 0L);


Enabling Overlay of Live Video: An Example

The following example determines if a device has overlay capabilities, and if possible, enables the overlay:

if (CapDrvCaps.fHasOverlay)

    SendMessage (hwndC, WM_CAP_SET_OVERLAY, 1 /*fEnable*/, 0L);


Setting the Capture File: An Example

The following example specifies an alternate filename of MYCAP.AVI for the capture file:

char szCaptureFile[] = "MYCAP.AVI";

SendMessage (hwndC, WM_CAP_FILE_SET_CAPTURE_FILE,

            0, (LONG)(LPVOID) szCaptureFile);


Preallocating Disk Space for the Capture File: An Example

The following example preallocates a 5-megabyte capture file:

SendMessage (hwndC, WM_CAP_FILE_ALLOCATE, 0, (1024L * 1024L * 5));


Controlling Audio Capture: An Example

The following example uses WM_CAP_SET_AUDIOFORMAT to set the audio format to the stereo, 8-bit, 11-kHz PCM format:

WAVEFORMATEX wfex;

wfex.wFormatTag = WAVE_FORMAT_PCM;

wfex.nChannels = 2;                // Use stereo

wfex.nSamplesPerSec = 11025;

wfex.nAvgBytesPerSec = 22050;

wfex.nBlockAlign = 2;

wfex.wBitsPerSample = 8;

wfex.cbSize = 0;

SendMessage (hwndC, WM_CAP_SET_AUDIOFORMAT, 0, (LONG)(LPVOID)&wfex);


Controlling Video Capture: An Example

The following example uses the WM_CAP_GET_SEQUENCE_SETUP and WM_CAP_SET_SEQUENCE_SETUP messages to change the capture rate (the default capture rate is 15 frames per second):

CAPTUREPARMS CaptureParms;

float FramesPerSec = 10.0;

SendMessage (hwndC, WM_CAP_GET_SEQUENCE_SETUP,

        sizeof (CAPTUREPARMS), (LONG)(DWORD) &CaptureParms);

CaptureParms.dwRequestMicroSecPerFrame = (DWORD) (1.0e6 / FramesPerSec);

CaptureParms.fYield = FALSE;

SendMessage (hwndC, WM_CAP_SET_SEQUENCE_SETUP,

        sizeof (CAPTUREPARMS), (LONG)(DWORD) &CaptureParms);


Capturing Data: An Example

The following example starts video capture:

SendMessage (hwndC, WM_CAP_SEQUENCE, 0, 0L);


Copying the Capture File: An Example

The following example copies the captured data in the capture file to the file NEWFILE.AVI:

char szNewName[] = "NewFile.avi";

SendMessage (hwndC, WM_CAP_FILE_SAVEAS, 0, (LPVOID) (LPSTR) szNewName);


AVICap Callbacks

Your application can register callbacks with the AVICap window to have it notify your application when the status changes, when errors occur, when video frame and audio buffers become available, and to yield during streaming capture.


Status Callback Functions

The following fragment creates the status callback function and registers it with the AVICap window:

FARPROC fpStatusCallback;

LRESULT FAR PASCAL MyStatusCallback (HWND hWnd, int nID, LPSTR

        lpStatusText)

{

    // Show the status text in some window

}

fpStatusCallback = MakeProcInstance ((FARPROC)MyStatusCallback, hInst);

SendMessage (hwndC, WM_CAP_SET_CALLBACK_STATUS,

        0, (DWORD) (LPVOID) fpStatusCallback);


Error Callback Functions

The following fragment creates the error callback function and registers it with the AVICap window:

FARPROC fpErrorCallback;

LRESULT FAR PASCAL MyErrorCallback (HWND hWnd, int nID, LPSTR lpStatusText)

{

// Warn the user that an error has occurred.

}

fpErrorCallback = MakeProcInstance ((FARPROC)MyErrorCallback, hInst);

SendMessage (hwndC, WM_CAP_SET_CALLBACK_ERROR,

        0, (DWORD) (LPVOID) fpErrorCallback);


Frame Callback Functions

The following fragment creates the frame callback function and registers it with the AVICap window:

FARPROC fpFrameCallback;

LRESULT FAR PASCAL MyFrameCallback (HWND hWnd, LPVIDEOHDR lpVHdr)

{

    // Process the frame.

}

fpFrameCallback = MakeProcInstance ((FARPROC)MyFrameCallback, hInst);

SendMessage (hwndC, WM_CAP_SET_CALLBACK_FRAME,

        0, (DWORD) (LPVOID) fpFrameCallback);


Disabling Callback Functions: An Example

The following fragment disables the frame callback function:

SendMessage (hwndC, WM_CAP_SET_CALLBACK_FRAME, 0, NULL);


Reference

This section is an alphabetic reference to the functions, macros, and messages of the AVICap window services.

To	See these functions or messages
Create an AVICap window	capCreateCaptureWindow
Connect to a video-capture device driver	WM_CAP_DRIVER_CONNECT WM_CAP_DRIVER_DISCONNECT
Enumerate installed capture devices	capGetDriverDescription WM_CAP_DRIVER_GET_NAME WM_CAP_DRIVER_GET_VERSION
Obtain video device capabilities	WM_CAP_DRIVER_GET_CAPS CAPDRIVERCAPS
Obtain the AVICap window status	WM_CAP_GET_STATUS CAPSTATUS
Display video dialog boxes	WM_CAP_DLG_VIDEOCOMPRESSION WM_CAP_DLG_VIDEODISPLAY WM_CAP_DLG_VIDEOFORMAT WM_CAP_DLG_VIDEOSOURCE
Obtain and set the video format	WM_CAP_GET_VIDEOFORMAT WM_CAP_SET_VIDEOFORMAT
Preview live video	WM_CAP_SET_PREVIEW WM_CAP_SET_PREVIEWRATE
Enable video overlay	WM_CAP_SET_OVERLAY
Set the capture file	WM_CAP_FILE_SET_CAPTURE_FILE WM_CAP_FILE_GET_CAPTURE_FILE
Preallocate disk space	WM_CAP_FILE_ALLOCATE
Control audio capture	WM_CAP_SET_AUDIOFORMAT WM_CAP_GET_AUDIOFORMAT
Control video capture	WM_CAP_GET_SEQUENCE_SETUP WM_CAP_SET_SEQUENCE_SETUP CAPTUREPARMS
Capture data	WM_CAP_SEQUENCE WM_CAP_STOP WM_CAP_ABORT
Capture a stream frame-by-frame	WM_CAP_SINGLE_FRAME_CLOSE WM_CAP_SINGLE_FRAME WM_CAP_SINGLE_FRAME_OPEN
Copy the capture file	WM_CAP_FILE_SAVEAS
Embed text strings in a file	WM_CAP_FILE_SET_INFOCHUNK CAPINFOCHUNK
Yield to other applications	WM_CAP_SET_CALLBACK_YIELD
Set AVICap callback functions	WM_CAP_SET_CALLBACK_ERROR WM_CAP_SET_CALLBACK_FRAME WM_CAP_SET_CALLBACK_STATUS WM_CAP_SET_CALLBACK_VIDEOSTREAM WM_CAP_SET_CALLBACK_WAVESTREAM
Capture from MCI devices	WM_CAP_GET_MCI_DEVICE WM_CAP_SET_MCI_DEVICE
Work with AVICap palettes	WM_CAP_PAL_AUTOCREATE WM_CAP_PAL_MANUALCREATE WM_CAP_PAL_OPEN WM_CAP_PAL_PASTE WM_CAP_PAL_SAVE
Control the video display	WM_CAP_SET_SCALE WM_CAP_SET_SCROLL
Directly use capture data	WM_CAP_SEQUENCE_NOFILE
Obtain a single frame	WM_CAP_FILE_SAVEDIB WM_CAP_GRAB_FRAME WM_CAP_GRAB_FRAME_NOSTOP WM_CAP_EDIT_COPY
Set user data	WM_CAP_GET_USER_DATA WM_CAP_SET_USER_DATA
Use AVICap Macros	AVICap Macros


AVICap Macros

The AVICap macros isolate your application from the SendMessage interface. The macros are identified with the prefix cap. The following table provides a cross-reference of macros to the corresponding messages.

For information about this macro	See
capCaptureAbort(hwnd)	WM_CAP_ABORT
capCaptureGetSetup      (hwnd, s, wSize)	WM_CAP_GET_SEQUENCE_SETUP
capCaptureSequence(hwnd)	WM_CAP_SEQUENCE
capCaptureSequenceNoFile      (hwnd)	WM_CAP_SEQUENCE_NOFILE
capCaptureSetSetup      (hwnd, s, wSize)	WM_CAP_SET_SEQUENCE_SETUP
capCaptureSingleFrame(hwnd)	WM_CAP_SINGLE_FRAME
capCaptureSingleFrameClose      (hwnd)	WM_CAP_SINGLE_FRAME_CLOSE
capCaptureSingleFrameOpen      (hwnd)	WM_CAP_SINGLE_FRAME_OPEN
capCaptureStop(hwnd)	WM_CAP_STOP
capDlgVideoCompression      (hwnd)	WM_CAP_DLG_VIDEOCOMPRESSION
capDlgVideoDisplay(hwnd)	WM_CAP_DLG_VIDEODISPLAY
capDlgVideoFormat(hwnd)	WM_CAP_DLG_VIDEOFORMAT
capDlgVideoSource(hwnd)	WM_CAP_DLG_VIDEOSOURCE
capDriverConnect(hwnd, i)	WM_CAP_DRIVER_CONNECT
capDriverDisconnect(hwnd)	WM_CAP_DRIVER_DISCONNECT
capDriverGetCaps      (hwnd, s, wSize)	WM_CAP_DRIVER_GET_CAPS
capDriverGetName       (hwnd, szName, wSize)	WM_CAP_DRIVER_GET_NAME
capDriverGetVersion      (hwnd, szVer, wSize)	WM_CAP_DRIVER_GET_VERSION
capEditCopy(hwnd)	WM_CAP_EDIT_COPY
capFileAlloc(hwnd, dwSize)	WM_CAP_FILE_ALLOCATE
capFileGetCaptureFile      (hwnd, szName, wSize)	WM_CAP_FILE_GET_CAPTURE_FILE
capFileSaveAs(hwnd, szName)	WM_CAP_FILE_SAVEAS
capFileSaveDIB      (hwnd, szName)	WM_CAP_FILE_SAVEDIB
capFileSetCaptureFile      (hwnd, szName)	WM_CAP_FILE_SET_CAPTURE_FILE
capFileSetInfoChunk      (hwnd, lpInfoChunk)	WM_CAP_FILE_SET_INFOCHUNK
capGetAudioFormat      (hwnd, s, wSize)	WM_CAP_GET_AUDIOFORMAT
capGetAudioFormatSize(hwnd)	WM_CAP_GET_AUDIOFORMAT
capGetMCIDeviceName      (hwnd, szName, wSize)	WM_CAP_GET_MCI_DEVICE
capGetStatus(hwnd, s, wSize)	WM_CAP_GET_STATUS
capGetUserData(hwnd)	WM_CAP_GET_USER_DATA
capGetVideoFormat      (hwnd, s, wSize)	WM_CAP_GET_VIDEOFORMAT
capGetVideoFormatSize(hwnd)	WM_CAP_GET_VIDEOFORMAT
capGrabFrame(hwnd)	WM_CAP_GRAB_FRAME
capGrabFrameNoStop(hwnd)	WM_CAP_GRAB_FRAME_NOSTOP
capOverlay(hwnd, f)	WM_CAP_SET_OVERLAY
capPaletteAuto     (hwnd, iFrames, iColors)	WM_CAP_PAL_AUTOCREATE
capPaletteManual     (hwnd, fGrab, iColors)	WM_CAP_PAL_MANUALCREATE
capPaletteOpen(hwnd, szName)	WM_CAP_PAL_OPEN
capPalettePaste(hwnd)	WM_CAP_PAL_PASTE
capPaletteSave(hwnd, szName)	WM_CAP_PAL_SAVE
capPreview(hwnd, f)	WM_CAP_SET_PREVIEW
capPreviewRate(hwnd, wMS)	WM_CAP_SET_PREVIEWRATE
capPreviewScale(hwnd, f)	WM_CAP_SET_SCALE
capSetAudioFormat      (hwnd, s, wSize)	WM_CAP_SET_AUDIOFORMAT
capSetCallbackOnError     (hwnd, fpProc)	WM_CAP_SET_CALLBACK_ERROR
capSetCallbackOnFrame      (hwnd, fpProc)	WM_CAP_SET_CALLBACK_FRAME
capSetCallbackOnStatus      (hwnd, fpProc)	WM_CAP_SET_CALLBACK_STATUS
capSetCallbackOnVideoStream      (hwnd, fpProc)	WM_CAP_SET_CALLBACK_VIDEOSTREAM
capSetCallbackOnWaveStream      (hwnd, fpProc)	WM_CAP_SET_CALLBACK_WAVESTREAM
capSetCallbackOnYield     (hwnd, fpProc)	WM_CAP_SET_CALLBACK_YIELD
capSetMCIDeviceName     (hwnd, szName)	WM_CAP_SET_MCI_DEVICE
capSetScrollPos(hwnd, lpP)	WM_CAP_SET_SCROLL
capSetUserData(hwnd, lUser)	WM_CAP_SET_USER_DATA
capSetVideoFormat      (hwnd, s, wSize)	WM_CAP_SET_VIDEOFORMAT


capCreateCaptureWindow

This function creates an AVICap capture window.

HWND FAR PASCAL _loadds capCreateCaptureWindow(LPCSTR lpszWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWnd, int nID)

•	Returns a handle to the window if the function was successful, otherwise it returns NULL.

lpszWindowName

Specifies a zero-terminated string containing the name used for the capture window.

dwStyle

Specifies the window styles used for the AVICap capture window. Window styles are described with the CreateWindow function.

x

Specifies the x-coordinate of the upper-left corner of the AVICap capture window.

y

Specifies the y-coordinate of the upper-left corner of the AVICap capture window.

nWidth

Specifies the width of the AVICap capture window.

nHeight

Specifies the height of the AVICap capture window.

hWnd

Specifies the handle to the parent window.

nID

Specifies the window ID.


CAPDRIVERCAPS

The CAPDRIVERCAPS structure defines the capabilities of the capture device.

typedef struct {

    WORD wDeviceIndex;

    BOOL fHasOverlay;

    BOOL fHasDlgVideoSource;

    BOOL fHasDlgVideoFormat;

    BOOL fHasDlgVideoDisplay;

    BOOL fCaptureInitialized;

    BOOL fDriverSuppliesPalettes;

} CAPDRIVERCAPS;

wDeviceIndex

Specifies the index of the connected video-capture driver corresponding to its system registry entry. These indexes can be non-contiguous.

fHasOverlay

Set TRUE if the device supports video overlay. Video overlay is a hardware function that displays the contents of the video-capture buffer on the VGA screen without using CPU resources.

fHasDlgVideoSource

Set TRUE if the device supports a dialog box for selecting and controlling the video source. This dialog box typically selects between SVHS and composite inputs, and provides controls to change hue, contrast, or saturation. It might also have other controls that affect the video image being digitized into the frame buffer.

fHasDlgVideoFormat

Set TRUE if the device supports a dialog box for selecting the video format. This dialog box typically controls bit depth, image dimensions, and compression options.

fHasDlgVideoDisplay

Set TRUE if the device supports a dialog box for controlling the redisplay of video from the capture frame buffer. Controls within this dialog box have no effect on the digitized video data, but might affect the presentation of the digitized signal. For example, capture devices that support overlay might allow altering hue and saturation, key color, or alignment of the overlay.

fCaptureInitialized

Set TRUE if a capture device has been successfully connected.

fDriverSuppliesPalettes

Set TRUE if the driver can create palettes.

Applications should use WM_CAP_DRIVER_GET_CAPS with the CAPDRIVERCAPS structure to initialize this structure whenever they connect an AVICap window to a driver.


capGetDriverDescription

This function retrieves the version description of the video-capture driver.

BOOL FAR PASCAL _loadds capGetDriverDescription(WORD wDriverIndex, LPSTR lpszName, INT cbName, LPSTR lpszVer, INT cbVer)

•	Returns TRUE if the function was successful.

wDriverIndex

Specifies an index to the video-capture driver.

lpszName

Specifies a pointer to a buffer this is filled with a zero-terminated string corresponding to the driver name.

cbName

Specifies the length of the buffer pointed to by lpszName.

lpszVer

Specifies a pointer to a buffer this is filled with a zero-terminated string corresponding to the description of the driver.

cbVer

Specifies the length of the buffer pointed to by lpszVer.

If the information description is longer than its buffer, the description is truncated. The returned string is always zero-terminated. If a buffer size is zero, its corresponding description is not copied.


CAPINFOCHUNK

The CAPINFOCHUNK structure contains parameters that can be used to define an info chunk within an AVI capture file. Typical uses include adding a copyright to a capture file.

typedef struct {

    FOURCC fccInfoID;

    LPVOID lpData;

    LONG cbData;

} CAPINFOCHUNK;

fccInfoID

Specifies the four-character code that identifies the representation of the chunk data. If this value is 0, all accumulated info chunks are deleted.

lpData

Specifies a pointer to the data. If this value is NULL, any existing fccInfoID info chunk will be deleted.

cbData

Specifies the size of the data pointed to by lpData. If lpData specifies a NULL zero-terminated string, use the string length plus one to save the NULL string.

The WM_CAP_FILE_SET_INFOCHUNK message is used to send a CAPINFOCHUNK to a capture window.


CAPSTATUS

The CAPSTATUS structure defines the current state of the AVICap window.

typedef struct {

    UINT uiImageWidth;

    UINT uiImageHeight;

    BOOL fLiveWindow;

    BOOL fOverlayWindow;

    BOOL fScale;

    POINT ptScroll;

    BOOL fUsingDefaultPalette;

    BOOL fAudioHardware;

    BOOL fCapFileExists;

    DWORD dwCurrentVideoFrame;

    DWORD dwCurrentVideoFramesDropped;

    DWORD dwCurrentWaveSamples;

    DWORD dwCurrentTimeElapsedMS;

    HPALETTE hPalCurrent;

    BOOL fCapturingNow;

    DWORD dwReturn;

    WORD wNumVideoAllocated;

    WORD wNumAudioAllocated;

} CAPSTATUS;

uiImageWidth

Specifies the image width in pixels.

uiImageHeight

Specifies the image height in pixels.

fLiveWindow

Set TRUE if the window is displaying video using the preview method.

fOverlayWindow

Set TRUE if the window is displaying video using hardware overlay.

fScale

Set TRUE if the window is scaling the input video to the client area when displaying video using preview. This parameter has no effect when displaying video using overlay.

ptScroll

Specifies the x and y offset of the pixel displayed in the upper-left corner of the client area of the window.

fUsingDefaultPalette

Set TRUE if the video-capture device driver is using its default palette.

fAudioHardware

Set TRUE if the system has wave audio hardware installed.

fCapFileExists

Set TRUE if a valid capture file has been generated.

dwCurrentVideoFrame

Specifies the number of frames processed during the current (or most recent) streaming capture. This count includes dropped frames.

dwCurrentVideoFramesDropped

Specifies the number of frames dropped during the current (or most recent) streaming capture. Dropped frames occur when the capture rate exceeds the rate at which frames can be saved to file. In this case, the video-capture device driver is starved for buffers. Dropping frames does not affect synchronization, because the previous frame is displayed in place of the dropped frame.

dwCurrentWaveSamples

Contains the number of wave samples processed during the current (or most recent) streaming capture.

dwCurrentTimeElapsedMS

Contains the number of milliseconds elapsed since the start of the current (or most recent) streaming capture.

hPalCurrent

Set to the handle of the current palette.

fCapturingNow

Set TRUE if capturing is in progress.

dwReturn

Set to error return values. Use this member if your application does not support an error callback function.

wNumVideoAllocated

Set to the actual number of video buffers allocated, which can be less than the number specified in wNumVideoRequested.

wNumAudioAllocated

Set to the actual number of audio buffers allocated, which can be less than the number specified in wNumAudioRequested.

This structure contains the current state of an AVICap window. Since this state is dynamic and changes in response to various messages, the client application should initialize this structure whenever it needs to enable menu items or determine the actual state of the capture window. If the client application yields during streaming capture, this structure returns the progress of the capture in the dwCurrentVideoFrame, dwCurrentVideoFramesDropped, dwCurrentWaveSamples, and dwCurrentElapsedTimeMS members. The WM_CAP_GET_STATUS message is used to initialize this structure.


CAPTUREPARMS

The CAPTUREPARMS structure contains parameters that control the process of streaming video capture. This structure is used both to get and set parameters that affect the rate of capture, the number of buffers to use while capturing, and how capture is terminated.

typedef struct {

    DWORD dwRequestMicroSecPerFrame;

    BOOL fMakeUserHitOKToCapture;

    WORD wPercentDropForError;

    BOOL fYield;

    DWORD dwIndexSize;

    WORD wChunkGranularity;

    BOOL fUsingDOSMemory;

    WORD wNumVideoRequested;

    BOOL fCaptureAudio;

    WORD wNumAudioRequested;

    WORD vKeyAbort;

    BOOL fAbortLeftMouse;

    BOOL fAbortRightMouse;

    BOOL fLimitEnabled;

    WORD wTimeLimit;

    BOOL fMCIControl;

    BOOL fStepMCIDevice;

    DWORD dwMCIStartTime;

    DWORD dwMCIStopTime;

    BOOL fStepCaptureAt2x;

    WORD wStepCaptureAverageFrames;

} CAPTUREPARMS;

dwRequestMicroSecPerFrame

Specifies the requested frame rate in microseconds. The default value is 66667, which corresponds to 15 frames per second.

fMakeUserHitOKToCapture

If TRUE, AVICap displays a dialog box prompting the user to initiate capture. Applications should request this dialog box when they specify a large number of video buffers. Allocating a large number of buffers can cause a noticeable delay in starting video capture. The dialog box is displayed after AVICap allocates all video and audio buffers. This lets the user eliminate capture delays that occur because of software initialization. If your application uses a small number of video buffers, this dialog box is probably unnecessary. The default value is FALSE.

wPercentDropForError

At the termination of streaming capture, this value is compared with the percentage of frames actually dropped. If the number of frames dropped is greater than wPercentDropForError, AVICap sends an error message to the error callback if it is installed. Values range from 0 to 100. The default value is 10.

fYield

If TRUE, the AVICap window spawns a separate background thread to perform step and streaming capture. Applications that use this flag must be written to avoid reentrant calls. Applications can optionally install their own custom yield processing function using the WM_CAP_SET_CALLBACK_YIELD message. If a custom yield callback is not installed, a default, internal PeekMessage, TranslateMessage, and DispatchMessage loop is used as a message loop. The default value is FALSE.

dwIndexSize

Specifies the maximum number of indexed entries. A single video frame or a single wave buffer corresponds to one index entry. The value used indirectly sets the upper limit on the number of frames captured. For example, if audio is not captured, the value corresponds to the number of video frames that the application might capture. Values can range from 1800 to 324000. If set to zero, a default value of 34952 is used. This is equal to 32K frames plus a proportional number of audio buffers.

wChunkGranularity

Specifies the size granularity of audio and video chunks as they are written to the AVI file. Audio and video chunks will have junk chunks appended to round the chunk up to the next multiple of wChunkGranularity. The default value is 2048, which generally gives the best disk write performance.

fUsingDOSMemory

If TRUE, AVICap attempts to allocate capture buffers in the memory area below one megabyte. Use of buffers in this memory area improves disk writing performance. Extended memory is automatically used if the buffers cannot be allocated. The default value is TRUE.

If a capture sequence can fit in memory, set fUsingDosMemory FALSE to use extended memory for capturing data. (The lower memory area does not have sufficient capacity to capture most sequences.) Capturing to memory yields the highest capture rate. Once memory is full, AVICap starts writing buffers to the disk file, which decreases the capture rate.

In general, setting fUsingDosMemory to TRUE yields the highest capture rate when capturing to disk. Writing from capture buffers in extended memory is usually slower than writing from capture buffers in the lower memory area.

wNumVideoRequested

Specifies the maximum number of video buffers to allocate. The memory area used for the buffers is determined by the fUsingDOSMemory flag. The actual number of buffers allocated might be lower if memory is unavailable. If you are using the lower memory area, you might be able to allocate more buffers by loading drivers and memory-resident applications into high memory. The default number of buffers allocated is 3 and the maximum is 1000.

fCaptureAudio

If TRUE, audio is captured during streaming capture. The default is TRUE if audio hardware is installed.

wNumAudioRequested

Specifies the maximum number of audio buffers to allocate. The size of each buffer is the maximum of .5 seconds of audio or 10K bytes. The default number of audio buffers is 4. The maximum number of buffers is 10.

vKeyAbort

Specifies the virtual key code used to terminate streaming capture. The default value is VK_ESCAPE. You can use the logical or operator to combine a virtual key code with 0x8000 or 0x4000 to obtain the key code corresponding to the key combined with the ctrl (0x8000) key or shift (0x4000) key.

fAbortLeftMouse

If TRUE, streaming capture terminates if the left mouse button is pressed. The default value is TRUE.

fAbortRightMouse

If TRUE, streaming capture terminates if the right mouse button is pressed. The default value is TRUE.

fLimitEnabled

If TRUE, streaming capture terminates after the number of seconds defined in wTimeLimit has elapsed. The default value is FALSE.

wTimeLimit

Specifies the time limit for capture in seconds. This parameter is used only if fLimitEnabled is TRUE.

fMCIControl

If TRUE, controls an MCI-compatible video source during streaming capture. MCI-compatible video sources include VCRs and laser discs.

fStepMCIDevice

If set TRUE, MCI step capture is enabled. If set FALSE, real-time capture from the MCI device is enabled. If fMCIControl is FALSE, this member is ignored.

dwMCIStartTime

Specifies, in milliseconds, the starting position of the MCI device used for the capture sequence. If fMCIControl is FALSE, this member is ignored.

dwMCIStopTime

Specifies the stopping position of the MCI device used for the capture sequence. When this position in the media is reached, capture ends and the MCI device stops. Units for this value are milliseconds. If fMCIControl is FALSE, this member is ignored.

fStepCaptureAt2x

If set TRUE, forces the capture hardware to capture at twice the specified resolution. (The resolution for both the height and width is doubled.) The software interpolates the pixels in the higher resolution image to produce the image at the specified resolution. This form of averaging can improve the edge definition of images in a frame. Enable this option if the hardware does not support hardware-based decimation and you are capturing in the RGB format. If fStepMCIDevice is FALSE, this member is ignored.

wStepCaptureAverageFrames

Specifies the number of times a frame is sampled when creating a frame based on the average sample. This averaging technique reduces the random digitization noise appearing in a frame. A typical value for the number of averages is 5. If fStepMCIDevice is FALSE, this member is ignored.

The WM_CAP_GET_SEQUENCE_SETUP message is used to retrieve the current capture parameters. The WM_CAP_SET_SEQUENCE_SETUP message is used to set the capture parameters.


WM_CAP_ABORT

This message stops the current capture operation. In the case of an MCI Step capture operation, the image data collected up to the point of the WM_CAP_ABORT message is retained in the capture file, but audio is not captured.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Not used.

The capture operation must yield to use this message. Use the WM_CAP_STOP message to halt an MCI step capture operation at the current position, and then capture audio.

The capCaptureAbort macro is defined using this message. The capCaptureAbort macro has the following syntax:

capCaptureAbort(hwnd)


WM_CAP_DLG_VIDEOCOMPRESSION

This message displays a dialog box for selecting a compressor used during the capture process.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Not used.

This message is most useful during MCI step capture for capturing and compressing frames in a single operation when the capture device can only provide BI_RGB formatted frames.

Compression does not affect the frames copied to the Clipboard.

The list of available compressors can vary with the video format selected in the video-capture device driver's video format dialog box.

The capDlgVideoCompression macro is defined using this message. The capDlgVideoCompression macro has the following syntax:

capDlgVideoCompression(hwnd)

The following example uses a macro to display the video compression dialog box:

capDlgVideoCompression (hwndCapture);


WM_CAP_DLG_VIDEODISPLAY

This message displays a dialog box used to control the video output. This dialog box might contain controls that affect the hue, contrast, and brightness of the displayed image, as well as key color alignment. These controls do not affect the digitized video data; they affect the output or redisplay of the video signal.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Not used.

The video display dialog box is unique for each video-capture device.

Not all devices support a video display dialog. Applications can check the fHasDlgVideoDisplay member to determine if a video display dialog is supported.

The capDlgVideoDisplay macro is defined using this message. The capDlgVideoDisplay macro has the following syntax:

capDlgVideoDisplay(hwnd)

The following example uses macros to display the video display dialog box:

CAPDRIVERCAPS CapDriverCaps;

capDriverGetCaps (hwndCapture, &CapDriverCaps, sizeof (CAPDRIVERCAPS));

if (CapDriverCaps.fHasDlgVideoDisplay)

     capDlgVideoDisplay (hwndCapture);


WM_CAP_DLG_VIDEOFORMAT

This message displays a dialog box used to select the video format. The video format dialog box might be used to select image dimensions, bit depth, and compression options.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Not used.

The video format dialog box is unique for each video-capture device. After this message returns, applications might need to update the CAPSTATUS structure if the user has changed the image dimensions.

Not all devices support a video format dialog box. Applications can check the fHasDlgVideoFormat member to determine if a video format dialog box is supported.

The capDlgVideoFormat macro is defined using this message. The capDlgVideoFormat macro has the following syntax:

capDlgVideoFormat(hwnd)

The following example uses macros to display the video format dialog box:

CAPDRIVERCAPS CapDriverCaps;

capDriverGetCaps (hwndCapture, &CapDriverCaps, sizeof (CAPDRIVERCAPS));

if (CapDriverCaps.fHasDlgVideoFormat)

     capDlgVideoFormat (hwndCapture);


WM_CAP_DLG_VIDEOSOURCE

This message displays a dialog box used to control the video source. The video source dialog box might contain controls that select input sources; alter the hue, contrast, and brightness of the image; and modify the video quality prior to digitization into the frame buffer.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Not used.

The video source dialog box is unique for each video-capture device.

Not all devices support a video source dialog box. Applications can check the fHasDlgVideoSource member to determine if a video source dialog box is supported.

The capDlgVideoSource macro is defined using this message. The capDlgVideoSource macro has the following syntax:

capDlgVideoSource(hwnd)

The following example uses macros to display the video source dialog box:

CAPDRIVERCAPS CapDriverCaps;

capDriverGetCaps (hwndCapture, &CapDriverCaps, sizeof (CAPDRIVERCAPS));

if (CapDriverCaps.fHasDlgVideoSource)

     capDlgVideoSource (hwndCapture);


WM_CAP_DRIVER_CONNECT

This message associates an AVICap window with a video-capture device driver.

•	Returns TRUE if the connection is successful, or FALSE if unable to connect to the specified video-capture device driver.

wParam

Specifies the index of the video-capture device driver corresponding to its system registry entry. These indexes can be noncontiguous and range between 0 and 9.

lParam

Not used.

Connecting an AVICap window to a video-capture device driver automatically disconnects any previously connected video-capture device driver.

The capDriverConnect macro is defined using this message. The capDriverConnect macro has the following syntax:

capDriverConnect(hwnd, i)

The following example uses a macro to connect to video-capture device driver 0:

capDriverConnect (hwndCapture, 0);


WM_CAP_DRIVER_DISCONNECT

This message disconnects the AVICap window from a video-capture device driver.

•	Returns TRUE on success, or FALSE if a driver was not previously connected.

wParam

Not used.

lParam

Not used.

The capDriverDisconnect macro is defined using this message. The capDriverDisconnect macro has the following syntax:

capDriverDisconnect(hwnd)

The following example uses a macro to disconnect the currently connected video-capture device driver:

capDriverDisconnect (hwndCapture);


WM_CAP_DRIVER_GET_CAPS

This message returns the hardware capabilities of the video-capture device driver currently connected.

•	Returns TRUE on success, or FALSE if no driver is connected.

wParam

Specifies the size of the CAPDRIVERCAPS structure in bytes.

lParam

Specifies the address of the CAPDRIVERCAPS structure to be filled.

The device capabilities returned in CAPDRIVERCAPS are static with respect to a given video-capture device driver. Applications need only retrieve this information once when the video-capture device driver is first connected.

The capDriverGetCaps macro is defined using this message. The capDriverGetCaps macro has the following syntax:

capDriverGetCaps(hwnd, s, wSize)

The following example uses a macro to get the capabilities of the capture device:

CAPDRIVERCAPS capDriverCaps;

capDriverGetCaps (hwndCapture, &capDriverCaps, sizeof (CAPDRIVERCAPS));


WM_CAP_DRIVER_GET_NAME

This message returns the name of the video-capture device driver connected to the AVICap window.

•	Returns TRUE if the name is returned, or FALSE if no driver is connected.

wParam

Specifies the size in bytes of the application-supplied buffer pointed to by lParam.

lParam

Specifies an LPSTR to an application-supplied buffer used to return a zero-terminated string containing the device name.

The name is a long text string retrieved from the drivers resource area. Applications should allocate approximately 80 bytes for this string. If the driver does not contain a name resource, the full path name of the driver as listed in the system registry is returned instead.

The capDriverGetName macro is defined using this message. The capDriverGetName macro has the following syntax:

capDriverGetName(hwnd, szName, wSize)

The following example uses a macro to get the name of the current video-capture device driver:

char szName[80];

capDriverGetName (hwndCapture, szName, sizeof(szName));


WM_CAP_DRIVER_GET_VERSION

This message returns the version of the video-capture device driver connected to the AVICap window.

•	Returns TRUE if the version string is returned, or FALSE if no driver is connected.

wParam

Specifies the size of the application-supplied buffer pointed to by lParam in bytes.

lParam

Specifies an LPSTR to an application-supplied buffer used to return a zero-terminated string containing the version information.

The version string is retrieved from the drivers resource area. Applications should allocate approximately 40 bytes for this string. If version information is not available, a NULL string is returned.

The capDriverGetVersion macro is defined using this message. The capDriverGetVersion macro has the following syntax:

capDriverGetVersion(hwnd, szVer, wSize)

The following example uses a macro to get the version of the current video-capture device driver:

char szVersion[40];

capDriverGetVersion (hwndCapture, szVersion, sizeof(szVersion));


WM_CAP_EDIT_COPY

This message copies the contents of the video frame buffer and associated palette onto the Clipboard.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Not used.

The capEditCopy macro is defined using this message. The capEditCopy macro has the following syntax:

capEditCopy(hwnd)

The following example uses a macro to copy the current image onto the Clipboard:

capEditCopy (hwndCapture);


WM_CAP_FILE_ALLOCATE

This message preallocates the capture file.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Specifies the number of bytes used for preallocating the capture file.

Preallocating the capture file improves streaming capture performance significantly. Defragmenting the capture file prior to capture also improves streaming capture performance.

If an error callback procedure is set using the WM_CAP_SET_CALLBACK_ERROR message, it is executed in the event of an error.

The capFileAlloc macro is defined using this message. The capFileAlloc macro has the following syntax:

capFileAlloc(hwnd, dwSize)

The following example uses a macro to allocate a 10-megabyte capture file:

capFileAlloc (hwndCapture, 1024L * 1024L * 10L);


WM_CAP_FILE_GET_CAPTURE_FILE

This message returns the name of the current capture file.

•	Returns TRUE on success.

wParam

Specifies the size of the application-supplied buffer pointed to by lParam in bytes.

lParam

Specifies an LPSTR to an application supplied buffer used to return the zero-terminated string containing the name of the capture file.

The default capture filename is \CAPTURE.AVI.

The capFileGetCaptureFile macro is defined using this message. The capFileGetCaptureFile macro has the following syntax:

capFileGetCaptureFile(hwnd, szName, wSize)

The following example uses a macro to get the name of the current capture file:

char szCapFile[144];

capFileGetCaptureFile (hwndCapture, szCapFile, sizeof (szCapFile));


WM_CAP_FILE_SAVEAS

This message copies the contents of the capture file to another file.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Specifies an LPSTR to the name of the destination file used to copy the file.

Typically, a capture file is preallocated for the largest capture segment anticipated and only a portion of it might be used to capture data. This message copies only the portion of the file containing the capture data to the destination file. If the copy operation is unsuccessful due to a disk-full error, the destination file is automatically deleted.

The name and contents of the current capture file are not changed by this message.

If an error callback procedure is set using the WM_CAP_SET_CALLBACK_ERROR message, it is executed in the event of an error.

The capFileSaveAs macro is defined using this message. The capFileSaveAs macro has the following syntax:

capFileSaveAs(hwnd, szName)

The following example uses a macro to copy the captured sequence to a new file:

capFileSaveAs (hwndCapture, "ANewFile.avi");


WM_CAP_FILE_SAVEDIB

This message copies the current frame to a DIB file.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Specifies an LPSTR to the name of the destination DIB file.

If the video-capture device driver is currently supplying frames in a compressed format, this call will attempt to decompress the frame to an uncompressed format prior to writing the file.

If an error callback procedure is set using the WM_CAP_SET_CALLBACK_ERROR message, it is executed in the event of an error.

The capFileSaveDIB macro is defined using this message. The capFileSaveDIB macro has the following syntax:

capFileSaveDIB(hwnd, szName)

The following example uses a macro to save the current frame to the file ONEFRAME.DIB:

capFileSaveDIB (hwndCapture, "OneFrame.DIB");


WM_CAP_FILE_SET_CAPTURE_FILE

This message specifies the name of the file used for video capture.

•	Returns TRUE on success, or FALSE if the filename is invalid or streaming capture is in progress.

wParam

Not used.

lParam

Specifies an LPSTR to the name of the capture file to use.

This message only stores the file name in an internal structure. It does not create, allocate, or open the specified file. The default capture file name is \CAPTURE.AVI.

The capFileSetCaptureFile macro is defined using this message. The capFileSetCaptureFile macro has the following syntax:

capFileSetCaptureFile(hwnd, szName)

The following example uses a macro to set the name of the capture file:

char szCapFile[] = "C:mycap.avi";

capFileSetCaptureFile (hwndCapture, szCapFile);


WM_CAP_FILE_SET_INFOCHUNK

This message sets and clears info chunks. Info chunks can be inserted in an AVI file during capture to embed text strings or custom data.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Specifies an LPCAPINFOCHUNK to the info chunk to be created or deleted.

Multiple registered info chunks can be added to an AVI file. Once set, an info chunk will continue to be added to subsequent capture files until either the entry is cleared, or all info chunk entries are cleared. To clear a single entry, set fccInfoID to the info chunk you want to clear, and set the lpData member to NULL. To clear all entries, set the fccInfoID member to NULL.

If an error callback procedure is set using the WM_CAP_SET_CALLBACK_ERROR message, it is executed in the event of an error.

The capFileSetInfoChunk macro is defined using this message. The capFileSetInfoChunk macro has the following syntax:

capFileSetInfoChunk(hwnd, lpInfoChunk)

The following example uses a macro to set a copyright string to be inserted in all subsequent capture files:

CAPINFOCHUNK InfoChunk;

char szCopyright[] = "Copyright 1993 Microsoft Corp.";

InfoChunk.fccInfoID = mmioFOURCC ('I','C','O','P');

InfoChunk.lpData = (LPSTR) szCopyright;

InfoChunk.cbData = lstrlen (szCopyright) + 1;   // plus NULL byte

capFileSetInfoChunk (hwndCapture, &InfoChunk);

...

// Now remove the copyright info chunk

InfoChunk.fccInfoID = mmioFOURCC ('I','C','O','P');

InfoChunk.lpData = NULL;

capFileSetInfoChunk (hwndCapture, &InfoChunk);

// Now remove ALL information chunks

InfoChunk.fccInfoID = NULL;

capFileSetInfoChunk (hwndCapture, &InfoChunk);


WM_CAP_GET_AUDIOFORMAT

This message obtains the audio format, or the size of the audio format.

•	Returns the size of the audio format in bytes.

wParam

Specifies the size of the structure pointed to by lParam in bytes.

lParam

Specifies a pointer to a WAVEFORMATEX structure, or NULL. If the value is NULL, the size required to hold the WAVEFORMATEX structure is returned.

Because compressed audio formats have a variable size format specification, applications must first inquire the size, and then allocate memory, and finally request the audio format data.

The capGetAudioFormat and capGetAudioFormatSize macros are defined using this message. The capGetAudioFormat macro has the following syntax:

capGetAudioFormat(hwnd, s, wSize)

The capGetAudioFormatSize macro has the following syntax:

capGetAudioFormatSize(hwnd)

The following example uses macros to get the audio format:

DWORD dwSize;

LPWAVEFORMATEX lpwfex;

dwSize = capGetAudioFormatSize (hwndCapture);

lpwfex = (LPWAVEFORMATEX) GlobalAlloc (GHND, dwSize);

capGetAudioFormat (hwndCapture, lpwfex, dwSize);


WM_CAP_GET_MCI_DEVICE

This message returns the name of an MCI device previously set with the WM_CAP_SET_MCI_DEVICE message.

•	Returns TRUE.

wParam

Specifies the length in bytes of the buffer pointed to by lParam.

lParam

Specifies an LPSTR to a buffer used to return the zero-terminated string containing the MCI device name.

The capGetMCIDeviceName macro is defined using this message. The capGetMCIDeviceName macro has the following syntax:

capGetMCIDeviceName(hwnd, szName, wSize)

The following example uses a macro to get the name of current MCI device:

char szName[80];

capGetMCIDeviceName(hwndCapture, szName, sizeof (szName));


WM_CAP_GET_SEQUENCE_SETUP

This message gets the current state of the parameters used for streaming capture.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Specifies the size in bytes of the structure pointed to by lParam.

lParam

Specifies a pointer to a CAPTUREPARMS structure.

Refer to the CAPTUREPARMS structure for a full description of the parameters used to control streaming capture.

The capCaptureGetSetup macro is defined using this message. The capCaptureGetSetup macro has the following syntax:

capCaptureGetSetup(hwnd, s, wSize)

The following example uses macros to first get the current capture parameters, and then change the frame rate to 10 frames per second, and finally send the altered capture parameters back to the capture window:

CAPTUREPARMS CapParms;

capCaptureGetSetup (hwndCapture, &CapParms, sizeof (CAPTUREPARMS));

CapParms.dwRequestMicroSecPerFrame = (DWORD) (1.0E6 / 10);

capCaptureSetSetup (hwndCapture, &CapParms, sizeof (CAPTUREPARMS));


WM_CAP_GET_STATUS

This message returns the status of the capture window.

•	Returns TRUE on success, or FALSE if no video-capture device driver is connected.

wParam

Specifies the size in bytes of the CAPSTATUS structure pointed to by lParam.

lParam

Specifies a pointer to a CAPSTATUS structure.

The CAPSTATUS structure contains the current state of the AVICap window. Since this state is dynamic and changes in response to various messages, the client application should initialize this structure whenever it needs to enable menu items or determine the actual state of the window.

The capGetStatus macro is defined using this message. The capGetStatus macro has the following syntax:

capGetStatus(hwnd, s, wSize)

The following example uses a macro to get the status of the AVICap window:

CAPSTATUS CapStatus;

capGetStatus (hwndCapture, &CapStatus, sizeof (CAPSTATUS));


WM_CAP_GET_USER_DATA

This message retrieves the LONG data type associated with an AVICap window.

•	Returns a value previously saved using WM_CAP_SET_USER_DATA.

wParam

Not used.

lParam

Not used.

Typically, this message is used to retrieve a pointer to an instance memory block.

The capGetUserData macro is defined using this message. The capGetUserData macro has the following syntax:

capGetUserData(hwnd)

The following example uses a macro to retrieve a value associated with an AVICap window:

lpMem = capGetUserData (hwndCapture);


WM_CAP_GET_VIDEOFORMAT

This message returns a copy of the video format in use, or the size required for the video format.

•	Returns the size in bytes of the video format, or zero if no video-capture device driver is connected.

wParam

Specifies the size of the structure pointed to by lParam.

lParam

Specifies NULL or a pointer to an extended BITMAPINFO structure. If NULL, the number of bytes used by the extended BITMAPINFO structure is returned.

Because compressed video formats have a variable size format specification, applications must first inquire the size, and then allocate memory, and finally request the video format data. For palettized formats, the current palette is also returned.

The capGetVideoFormat and capGetVideoFormatSize macros are defined using this message. The capGetVideoFormat macro has the following syntax:

capGetVideoFormat(hwnd, s, wSize)

The capGetVideoFormatSize macro has the following syntax:

capGetVideoFormatSize(hwnd)

The following example uses macros to get the video format:

DWORD dwSize;

LPBITMAPINFOHEADER lpFormatCap;

dwSize = capGetVideoFormatSize (hwndCapture);

lpFormatCap = (LPBITMAPINFOHEADER)GlobalAllocPtr (GHND, dwSize);

capGetVideoFormat (hwndCapture, lpFormatCap, dwSize);


WM_CAP_GRAB_FRAME

This message grabs and displays a single frame from the capture device. After capture, overlay and preview are both disabled.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Not used.

See the WM_CAP_SET_CALLBACK_ERROR and WM_CAP_SET_CALLBACK_FRAME messages for information about installing callbacks.

The capGrabFrame macro is defined using this message. The capGrabFrame macro has the following syntax:

capGrabFrame(hwnd)

The following example uses macros to capture a single frame to the capture file:

capGrabFrame (hwndCapture);


WM_CAP_GRAB_FRAME_NOSTOP

This message fills the frame buffer with a single frame from the capture device and displays it. Unlike the WM_CAP_GRAB_FRAME message, the state of overlay or preview is not altered by this message.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Not used.

This message does not use compression.

See the WM_CAP_SET_CALLBACK_ERROR and WM_CAP_SET_CALLBACK_FRAME messages for information about installing callbacks.

The capGrabFrameNoStop macro is defined using this message. The capGrabFrameNoStop macro has the following syntax:

capGrabFrameNoStop(hwnd)

The following example uses a macro to grab a single frame without affecting overlay or preview modes:

capGrabFrameNoStop (hwndCapture);


WM_CAP_PAL_AUTOCREATE

This message sends the video-capture device driver a request to automatically sample video frames and create a new palette.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Specifies the number of frames to sample.

lParam

Specifies the number of colors in the palette. The maximum value for this parameter is 256.

The video sequence sampled should include all the colors you want in the palette. To obtain the best palette, you might have to sample the whole sequence rather than a portion of it.

You can specify an error callback procedure (using the WM_CAP_SET_CALLBACK_ERROR message) that is executed in the event of an error.

The capPaletteAuto macro is defined using this message. The capPaletteAuto macro has the following syntax:

capPaletteAuto(hwnd, iFrames, iColors)

The following example uses a macro to create a new 256 color palette sampled from 5 video frames:

int nFrames = 5;

int nColors = 256;

capPaletteAuto (hwndCapture, nFrames, nColors);


WM_CAP_PAL_MANUALCREATE

This message sends the video-capture device driver a request to manually sample video frames and create a new palette.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Specifies whether the current frame is added to the pixel histogram. Set this parameter TRUE for each frame used when creating the optimal palette. After the last frame has been collected, set this parameter FALSE to calculate the optimal palette and send it to the driver.

lParam

Specifies the number of colors in the palette. The maximum value for this parameter is 256. This value is only used during collection of the first frame in a sequence.

You can specify an error callback procedure (using the WM_CAP_SET_CALLBACK_ERROR message) that is executed in the event of an error.

The capPaletteManual macro is defined using this message. The capPaletteManual macro has the following syntax:

capPaletteManual(hwnd, fGrab, iColors)

The following example uses a macro to create a new 256 color palette sampled from 3 video frames:

int nColors = 256;

// Arbitrary delays may exist between each frame

capPaletteManual (hwndCapture, TRUE, nColors);

capPaletteManual (hwndCapture, TRUE, nColors);

capPaletteManual (hwndCapture, TRUE, nColors);

// Now create the optimal palette for the 3 frames

capPaletteManual (hwndCapture, FALSE, nColors);


WM_CAP_PAL_OPEN

This message loads a new palette from a palette file. Palette files usually have the extension .PAL. The palette is passed to the video-capture device driver for use when capturing in palettized formats.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Specifies an LPSTR to the palette filename.

You can specify an error callback procedure (using the WM_CAP_SET_CALLBACK_ERROR message) that will be executed in the event of an error.

The capPaletteOpen macro is defined using this message. The capPaletteOpen macro has the following syntax:

capPaletteOpen(hwnd, szName)

The following example uses a macro to load a new palette from a file:

capPaletteOpen (hwndCapture, "optimal.pal");


WM_CAP_PAL_PASTE

This message pastes the palette from the Clipboard. The palette is passed to the video-capture device driver for use when capturing in palettized formats.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Not used.

You can specify an error callback procedure (using the WM_CAP_SET_CALLBACK_ERROR message) that is executed in the event of an error.

The capPalettePaste macro is defined using this message. The capPalettePaste macro has the following syntax:

capPalettePaste(hwnd)

The following example uses a macro to paste the current palette from the Clipboard to the AVICap window:

capPalettePaste (hwndCapture);


WM_CAP_PAL_SAVE

This message saves the current palette to a palette file. Palette files usually have the extension .PAL.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Specifies an LPSTR to a zero-terminated string containing the palette filename.

You can specify an error callback procedure (using the WM_CAP_SET_CALLBACK_ERROR message) that will be executed in the event of an error.

The capPaletteSave macro is defined using this message. The capPaletteSave macro has the following syntax:

capPaletteSave(hwnd, szName)

The following example uses a macro to save the current palette to a file:

capPaletteSave (hwndCapture, "optimal.pal");


WM_CAP_SEQUENCE

This message initiates streaming video and audio capture to a file.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Not used.

If you want to alter the parameters controlling streaming capture, use the WM_CAP_SET_SEQUENCE_SETUP message prior to starting the capture.

Streaming capture is non-yielding by default. To ensure that message processing continues during the capture, either set the fYield flag, or install a yield callback.

During streaming capture, the capture window might call back into your application. To install the procedures for the optional callbacks use the WM_CAP_SET_CALLBACK_ERROR, WM_CAP_SET_CALLBACK_STATUS, WM_CAP_SET_CALLBACK_YIELD, WM_CAP_SET_CALLBACK_VIDEOSTREAM, and WM_CAP_SET_CALLBACK_WAVESTREAM messages.

The capCaptureSequence macro is defined using this message. The capCaptureSequence macro has the following syntax:

capCaptureSequence(hwnd)

The following example uses macros to capture streaming video to the capture file:

capCaptureSequence (hwndCapture);


WM_CAP_SEQUENCE_NOFILE

This message initiates streaming video capture without writing the data to file. This message is only useful in conjunction with video stream or wave stream callbacks that let your application use the video and audio data directly. For example, videoconferencing applications might use this message to obtain streaming video frames.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Not used.

If you want to alter the parameters controlling streaming capture, use the WM_CAP_SET_SEQUENCE_SETUP message prior to starting the capture.

Streaming capture is non-yielding by default. To ensure that message processing continues during the capture, either set the fYield flag, or install a yield callback.

During streaming capture, the capture window can call back into your application. To install the procedures for these optional callbacks use the WM_CAP_SET_CALLBACK_ERROR, WM_CAP_SET_CALLBACK_STATUS, WM_CAP_SET_CALLBACK_YIELD, WM_CAP_SET_CALLBACK_VIDEOSTREAM, and WM_CAP_SET_CALLBACK_WAVESTREAM messages.

The capCaptureSequenceNoFile macro is defined using this message. The capCaptureSequenceNoFile macro has the following syntax:

capCaptureSequenceNoFile(hwnd)

The following example uses macros to capture streaming video. Video and audio buffers are returned to the application by means of callbacks:

capCaptureSequenceNoFile (hwndCapture);


WM_CAP_SET_AUDIOFORMAT

This message sets the audio format to use when performing streaming capture.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Specifies a pointer to a WAVEFORMATEX structure.

Although a WAVEFORMATEX structure is specified for use with this function, applications can use a PCMWAVEFORMAT or WAVEFORMAT structure.

The capSetAudioFormat macro is defined using this message. The capSetAudioFormat macro has the following syntax:

capSetAudioFormat(hwnd, s, wSize)

The following example uses a macro to set the current audio format to 16-bit stereo, 11 kHz:

WAVEFORMATEX wfex;

wfex.wFormatTag = WAVE_FORMAT_PCM;

wfex.nChannels = 2;

wfex.wBitsPerSample = 16;

wfex.nSamplesPerSec = 11025;

wfex.nAvgBytesPerSec = (LONG) wfex.nSamplesPerSec * wfex.nChannels *

         (wfex.wBitsPerSample / 8);

wfex.nBlockAlign = (wfex.wBitsPerSample / 8) * wfex.nChannels;

wfex.cbSize = 0;

capSetAudioFormat (hwndCapture, &wfex, sizeof (WAVEFORMATEX));


WM_CAP_SET_CALLBACK_ERROR

This message sets an error callback procedure in the client application. AVICap calls this procedure when errors occur.

•	Returns TRUE on success, or FALSE if streaming capture is in progress or if a single-frame capture session is in progress.

wParam

Not used.

lParam

Specifies NULL or the FARPROC address of the error callback procedure. NULL disables a previously installed error callback procedure.

Applications can optionally set an error callback. If set, AVICap calls the error procedure under situations such as the following:

•	Unable to connect to a video-capture device driver

•	Disk full

•	Unable to open wave device

•	Number of frames dropped during capture exceeded the specified percentage

•	No frames captured due to vertical synchronization interrupt problems

The capSetCallbackOnError macro is defined using this message. The capSetCallbackOnError macro has the following syntax:

capSetCallbackOnError(hwnd, fpProc)

The following example uses a macro to install an error callback procedure:

FARPROC fpErrorCallback;

LRESULT FAR PASCAL MyErrorCallback (HWND hwnd, int nID, LPCSTR lpszError)

{

     // Show the error somewhere

     // nID contains the error value defined in avicapid.h

     // lpszError is a formatted text string to display

     return (LRESULT) TRUE;

}

fpErrorCallback = MakeProcInstance ((FARPROC)MyErrorCallback, hInst);

capSetCallbackOnError (hwndCapture, fpErrorCallback);


WM_CAP_SET_CALLBACK_FRAME

This message sets a callback procedure in the client application called when the AVICap window captures preview frames.

•	Returns TRUE on success, or FALSE if streaming capture is in progress or if a single-frame capture session is in progress.

wParam

Not used.

lParam

Specifies NULL or a FARPROC address of the callback function. NULL disables a previously installed callback procedure.

The AVICap window calls the procedure prior to displaying preview frames. This lets an application modify the frame if desired. This callback is not used during streaming video capture.

The capSetCallbackOnFrame macro is defined using this message. The capSetCallbackOnFrame macro has the following syntax:

capSetCallbackOnFrame(hwnd, fpProc)

The following example uses a macro to install a frame callback procedure:

FARPROC fpFrameCallback;

LRESULT FAR PASCAL MyFrameCallback (HWND hwnd, LPVIDEOHDR lpVHdr)

{

     // Process the frame

     ...

     return (LRESULT) TRUE;

}

fpFrameCallback = MakeProcInstance ((FARPROC)MyFrameCallback, hInst);

capSetCallbackOnFrame (hwndCapture, fpFrameCallback);


WM_CAP_SET_CALLBACK_STATUS

This message sets a status callback procedure in the client application. The AVICap window calls this procedure whenever the status changes.

•	Returns TRUE on success, or FALSE if streaming capture is in progress or if a single-frame capture session is in progress.

wParam

Not used.

lParam

Specifies NULL or the FARPROC address of the status callback procedure. NULL disables a previously installed status callback procedure.

Applications can optionally set a status callback. If set, AVICap calls this procedure under situations such as:

•	Successful connection to a driver

•	To report the number of frames captured

•	Creation of optimal palette

•	Completion of capture

The capSetCallbackOnStatus macro is defined using this message. The capSetCallbackOnStatus macro has the following syntax:

capSetCallbackOnStatus(hwnd, fpProc)

The following example uses a macro to install a status callback procedure:

FARPROC fpStatusCallback;

LRESULT FAR PASCAL MyStatusCallback (HWND hwnd, int nID, LPCSTR lpszStatus)

{

     // Show the Status text in the status bar

     // nID contains the status value defined in avicapid.h

     // lpszStatus is a formatted text string to display

     ...

     return (LRESULT) TRUE;

}

fpStatusCallback = MakeProcInstance ((FARPROC)MyStatusCallback, hInst);

capSetCallbackOnStatus (hwndCapture, fpStatusCallback);


WM_CAP_SET_CALLBACK_VIDEOSTREAM

This message sets a callback procedure in the client application the AVICap window calls during streaming capture when a video buffer is filled.

•	Returns TRUE on success, or FALSE if streaming capture is in progress or if a single-frame capture session is in progress.

wParam

Not used.

lParam

Specifies NULL or a FARPROC address of the videostream callback procedure. NULL disables a previously installed videostream callback procedure.

The AVICap window calls the procedure prior to writing the captured frame to disk. This lets applications modify the frame if necessary.

If used, video stream callbacks must be installed prior to the start of streaming capture, and can only be disabled after streaming capture terminates.

The capSetCallbackOnVideoStream macro is defined using this message. The capSetCallbackOnVideoStream macro has the following syntax:

capSetCallbackOnVideoStream(hwnd, fpProc)

The following example uses a macro to install a video stream callback procedure:

FARPROC fpVideoStreamCallback;

LRESULT FAR PASCAL MyVideoStreamCallback (HWND hwnd, LPVIDEOHDR lpVHdr)

{

     // Process the video buffer

     ...

     return (LRESULT) TRUE;

}

fpVideoStreamCallback = MakeProcInstance ((FARPROC)MyVideoStreamCallback, hInst);

capSetCallbackOnVideoStream (hwndCapture, fpVideoStreamCallback);


WM_CAP_SET_CALLBACK_WAVESTREAM

This message sets a callback procedure in the client application to be called during streaming capture when a new audio buffer becomes available.

•	Returns TRUE on success, or FALSE if streaming capture is in progress or if a single-frame capture session is in progress.

wParam

Not used.

lParam

Specifies NULL or a FARPROC address of the wavestream callback procedure. NULL disables a previously installed wavestream callback procedure.

The AVICap window calls the procedure prior to writing the audio buffer to disk. This lets applications modify the audio buffer if necessary.

If used, wave stream callbacks must be installed prior to the start of streaming capture, and can only be disabled after streaming capture terminates.

The capSetCallbackOnWaveStream macro is defined using this message. The capSetCallbackOnWaveStream macro has the following syntax:

capSetCallbackOnWaveStream(hwnd, fpProc)

The following example uses a macro to install an audio stream callback:

FARPROC fpWaveStreamCallback;

LRESULT FAR PASCAL MyWaveStreamCallback (HWND hwnd, LPWAVEHDR lpWHdr)

{

     // Process the audio buffer

     ...

     return (LRESULT) TRUE;

}

fpWaveStreamCallback = MakeProcInstance ((FARPROC)MyWaveStreamCallback, hInst);

capSetCallbackOnWaveStream (hwndCapture, fpWaveStreamCallback);


WM_CAP_SET_CALLBACK_YIELD

This message sets a callback procedure in the client application called when the AVICap window yields during streaming capture.

•	Returns TRUE on success, or FALSE if streaming capture is in progress or if a single-frame capture session is in progress.

wParam

Not used.

lParam

Specifies NULL or the FARPROC address of the yield callback procedure. NULL disables a previously installed yield callback procedure.

If used, yield stream callbacks must be installed prior to the start of streaming capture, and can only be disabled after streaming capture terminates.

Applications can optionally set a yield callback procedure. The yield callback is called at least once for each video frame captured during streaming capture. If a yield callback is installed, it is called regardless of the state of fYield.

If used, yield callbacks must be installed prior to the start of streaming capture, and can only be disabled after streaming capture terminates.

Applications typically perform some type of message processing in the callback procedure consisting of a PeekMessage, TranslateMessage, and DispatchMessage loop. Messages that can cause reentrancy problems must be filtered by the callback procedure.

Applications usually return TRUE in the yield procedure to continue streaming capture. If they return FALSE, the AVICap window stops the capture process.

The capSetCallbackOnYield macro is defined using this message. The capSetCallbackOnYield macro has the following syntax:

capSetCallbackOnYield(hwnd, fpProc)

The following example uses a macro to install a yield callback procedure:

FARPROC fpYieldCallback;

LRESULT FAR PASCAL MyYieldCallback (HWND hwnd)

{

     BOOL fContinue = TRUE;

     // Implement your own Peek/Dispatch Message loop

     // Set fContinue = FALSE to abort streaming

     return (LRESULT) fContinue;

}

fpYieldCallback = MakeProcInstance ((FARPROC)MyYieldCallback, hInst);

capSetCallbackOnYield (hwndCapture, fpYieldCallback);


WM_CAP_SET_MCI_DEVICE

This message specifies the name of the MCI device to control while performing video capture.

•	Returns TRUE on success, or FALSE if an error occurred.

wParam

Not used.

lParam

Specifies an LPSTR to a the name of the MCI device.

This message only stores the MCI name in an internal structure. It does not open or access the MCI device. By default, the MCI device name is NULL.

The capSetMCIDeviceName macro is defined using this message. The capSetMCIDeviceName macro has the following syntax:

capSetMCIDeviceName(hwnd, szName)

The following example uses a macro to have the AVICap window use the videodisc device specified in the system registry:

capSetMCIDeviceName(hwndCapture, "videodisc" );


WM_CAP_SET_OVERLAY

This message enables or disables overlay mode. In overlay mode, live video is displayed using hardware overlay.

•	Returns TRUE if the operation is successful.

wParam

Specifies a Boolean value. If TRUE, overlay is enabled; if FALSE, overlay is disabled.

lParam

Not used.

Using overlay does not require CPU resources. The fHasOverlay member of the CAPDRIVERCAPS structure indicates if the device is capable of overlay.

Enabling overlay automatically disables preview mode.

The capOverlay macro is defined using this message. The capOverlay macro has the following syntax:

capOverlay(hwnd, f)

The following example uses macros to enable overlay mode:

CAPDRIVERCAPS capDriverCaps;

capDriverGetCaps (hwndCapture, &capDriverCaps, sizeof (CAPDRIVERCAPS));

if (capDriverCaps.fHasOverlay)

    capOverlay (hwndCapture, TRUE);


WM_CAP_SET_PREVIEW

This message enables or disables preview mode. In preview mode, frames are transferred from the capture hardware to system memory, and then displayed in the AVICap window using GDI functions.

•	Returns TRUE on success, or FALSE if an error occurred.

wParam

Specifies a Boolean value. If TRUE, preview is enabled; if FALSE, preview is disabled.

lParam

Not used.

Preview mode uses substantial CPU resources. Applications might want to disable preview, or lower the preview rate on loss of focus.

Enabling preview mode automatically disables overlay mode.

The capPreview macro is defined using this message. The capPreview macro has the following syntax:

capPreview(hwnd, f)

The following example uses macros to set the preview rate to 10 frames per second, and then enables preview mode:

capPreviewRate (hwndCapture, 1.0E3 / 10);

capPreview (hwndCapture, TRUE);


WM_CAP_SET_PREVIEWRATE

This message sets the frame display rate in preview mode.

•	Returns TRUE on success, or FALSE if a video-capture device driver is not connected.

wParam

Specifies the rate, in milliseconds, at which new frames are captured and displayed.

lParam

Not used.

Using preview uses substantial CPU resources. Applications might disable preview, or lower the preview rate on loss of focus. During streaming video capture, preview is lower priority than writing frames to disk. During streaming capture, preview frames are displayed only if no other buffers are available for writing.

The capPreviewRate macro is defined using this message. The capPreviewRate macro has the following syntax:

capPreviewRate(hwnd, wMS)

The following example uses macros to set the preview rate to 10 frames per second, and then enables preview mode:

capPreviewRate (hwndCapture, 1.0E3 / 10);

capPreview (hwndCapture, TRUE);


WM_CAP_SET_SCALE

This message enables or disables scaling of the preview video. If enabled, the captured video frame is stretched to the dimensions of the capture window.

•	Returns TRUE on success, or FALSE if an error occurred.

wParam

Specifies a Boolean value. If TRUE, preview is stretched to the size of the capture window. If FALSE, the image is displayed at its natural size.

lParam

Not used.

Scaling the captured video only affects the immediate presentation of the captured frames within the capture window. It has no effect on the size of the frames saved to file.

Scaling has no effect when using overlay to display video in the frame buffer.

The capPreviewScale macro is defined using this message. The capPreviewScale macro has the following syntax:

capPreviewScale(hwnd, f)

The following example uses macros to enable scaling of the preview:

capPreview (hwndCapture, TRUE);

capPreviewScale (hwndCapture, TRUE);


WM_CAP_SET_SCROLL

This message sets the scroll position of the video frame within the client area of the AVICap window. The scroll position specifies the coordinates of the pixel within the video frame to display in the upper-left corner of the capture window client area.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Specifies a pointer to a POINT data type containing the desired scroll position.

The scroll position affects the image in both preview and overlay modes.

The capSetScrollPos macro is defined using this message. The capSetScrollPos macro has the following syntax:

capSetScrollPos(hwnd, lpP)

The following example uses macros to set the scroll position to 100, 100:

POINT pt;

pt.x = pt.y = 100;

capSetScrollPos (hwndCapture, &pt);


WM_CAP_SET_SEQUENCE_SETUP

This message sets the parameters used when performing streaming capture. These set parameters such as frame rate, termination conditions, control of an MCI video source, and number of buffers to allocate.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Specifies the size in bytes of the structure pointed to by lParam.

lParam

Specifies a pointer to a CAPTUREPARMS structure.

Refer to the CAPTUREPARMS structure for a full description of the parameters used to control streaming capture.

The capCaptureSetSetup macro is defined using this message. The capCaptureSetSetup macro has the following syntax:

capCaptureSetSetup(hwnd, s, wSize)

The following example uses macros to first get the current capture parameters, and then change the frame rate to 10 frames per second, and finally send the altered capture parameters back to the capture window:

CAPTUREPARMS CapParms;

capCaptureGetSetup (hwndCapture, &CapParms, sizeof (CAPTUREPARMS));

CapParms.dwRequestMicroSecPerFrame = (DWORD) (1.0E6 / 10);

capCaptureSetSetup (hwndCapture, &CapParms, sizeof (CAPTUREPARMS));


WM_CAP_SET_USER_DATA

This message associates a LONG size data value with an AVICap window.

•	Returns TRUE on success, or FALSE if streaming capture is in progress.

wParam

Not used.

lParam

Specifies the LONG size data value to associate with a capture window.

Typically, this message is used to save a pointer to an instance memory block.

The capSetUserData macro is defined using this message. The capSetUserData macro has the following syntax:

capSetUserData(hwnd, lUser)

The following example uses a macro to set a data value:

capSetUserData (hwndCapture, lpMem);


WM_CAP_SET_VIDEOFORMAT

This message sets the format used when capturing video.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Specifies the size of the structure pointed to by lParam.

lParam

Specifies a pointer to an extended BITMAPINFO structure.

Since video formats are device specific, applications should always check the return value from this function to determine if the format is accepted by the driver.

The capSetVideoFormat macro is defined using this message. The capSetVideoFormat macro has the following syntax:

capSetVideoFormat(hwnd, s, wSize)

The following example uses macros to set the video format to palettized, 8-bit, and 160-by-120:

DWORD dwSize;

LPBITMAPINFOHEADER lpFormatCap;

BITMAPINFOHEADER bih;

bih.biSize            = sizeof(BITMAPINFOHEADER);

bih.biCompression     = BI_RGB;

bih.biWidth           = 160;

bih.biHeight          = 120;

bih.biPlanes          = 1;

bih.biBitCount        = 8;

bih.biSizeImage       = bih.biWidth * bih.biHeight *

     bih.biPlanes * bih.biBitCount / 8;

bih.biXPelsPerMeter   = 0;

bih.biYPelsPerMeter   = 0;

bih.biClrUsed         = 0;

bih.biClrImportant    = 0;

if (capSetVideoFormat (hwndCapture, &bih, sizeof (bih))) {

    // Now get the format with the palette attached

    // Note that the size of the format has increased

    dwSize = capGetVideoFormatSize (hwndCapture);

    lpFormatCap = (LPBITMAPINFOHEADER)GlobalAllocPtr (GHND, dwSize);

    capGetVideoFormat (hwndCapture, lpFormatCap, dwSize);

}


WM_CAP_SINGLE_FRAME

This message appends a single frame to a capture file previously opened using the WM_CAP_SINGLE_FRAME_OPEN message.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Not used.

See the WM_CAP_SET_CALLBACK_ERROR and WM_CAP_SET_CALLBACK_FRAME messages for information about installing callbacks.

The capCaptureSingleFrame macro is defined using this message. The capCaptureSingleFrame macro has the following syntax:

capCaptureSingleFrame(hwnd)

The following example uses macros to open the capture file, write two frames, and then close the capture file:

capCaptureSingleFrameOpen (hwndCapture);

capCaptureSingleFrame (hwndCapture);

capCaptureSingleFrame (hwndCapture);

capCaptureSingleFrameClose (hwndCapture);


WM_CAP_SINGLE_FRAME_CLOSE

This message closes the capture file previously opened by the WM_CAP_SINGLE_FRAME_OPEN message.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Not used.

See the WM_CAP_SET_CALLBACK_ERROR and WM_CAP_SET_CALLBACK_FRAME messages for information about installing callbacks.

The capCaptureSingleFrameClose macro is defined using this message. The capCaptureSingleFrameClose macro has the following syntax:

capCaptureSingleFrameClose(hwnd)

The following example uses macros to open the capture file, capture two frames, and then close the capture file:

capCaptureSingleFrameOpen (hwndCapture);

capCaptureSingleFrame (hwndCapture);

capCaptureSingleFrame (hwndCapture);

capCaptureSingleFrameClose (hwndCapture);


WM_CAP_SINGLE_FRAME_OPEN

This message opens the capture file for single frame capturing. Any previous information in the capture file is overwritten.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Not used.

See the WM_CAP_SET_CALLBACK_ERROR and WM_CAP_SET_CALLBACK_FRAME messages for information about installing callbacks.

The capCaptureSingleFrameOpen macro is defined using this message. The capCaptureSingleFrameOpen macro has the following syntax:

capCaptureSingleFrameOpen(hwnd)

The following example uses a macro to open the capture file, capture two frames, and then close the capture file:

capCaptureSingleFrameOpen (hwndCapture);

capCaptureSingleFrame (hwndCapture);

capCaptureSingleFrame (hwndCapture);

capCaptureSingleFrameClose (hwndCapture);


WM_CAP_STOP

This message stops the current capture operation. In the case of an MCI step capture operation, the image data collected up to the point of the WM_CAP_STOP message is retained in the capture file, and audio is captured if enabled.

•	Returns TRUE if the operation is successful, or FALSE in the case of an error.

wParam

Not used.

lParam

Not used.

The capture operation must yield to use this message. Use the WM_CAP_ABORT message to abandon the current capture operation.

The capCaptureStop macro is defined using this message. The capCaptureStop macro has the following syntax:

capCaptureStop(hwnd)

The following example uses a macro to stop capture:

capCaptureStop (hwndCapture);


Playing AVI Files: MCIAVI


About MCIAVI

The MCIAVI driver plays video sequences and other data streams under the control of MCI commands. Data streams can contain images, audio, and palettes. The image data can consist of images with either color palettes or true-color information.

The MCIAVI driver supports 11-, 22-, or 44-kHz audio. Audio is synchronized with the video within one-thirtieth of a second. However, if audio hardware is not available, the driver will silently play the video stream. The MCIAVI driver can drop video frames, if necessary, to play a stream without audio interruption.

Instead of using the MCI command interface to control the MCIAVI driver, your application can use the MCIWnd window class services. This window class handles many of the details of managing the window supporting the MCI device and simplifies the programming required to send the MCI commands. Your application can directly use the MCIWnd library services to control the MCI device, or it can have MCIWnd display a toolbar, scroll bar, and menus that let the user control the device. For more information about the MCIWnd window class, see <ch_mciwnd>.

This chapter describes the functions, structures and messages of the MCIAVI driver and explains how to use them to play AVI files.

The rest of this section and the following section describe how to play Video for Windows AVI files using the MCI interface for the MCIAVI driver. These sections contain the following topics:

•	MCI overview

•	Handling MCI notification

•	Playing AVI files using MCI

•	Using the MCI command interface

•	Using the MCI string interface


MCI Overview

MCI provides a high-level interface to control various media devices through generalized commands such as play, pause, and stop. Specific command sets defined for different device types provide MCI control over these devices. MCI uses the MCIAVI driver to play AVI files.

Your application uses MCI commands from the digital-video command set to control the MCIAVI driver. These commands contain the instructions for device operation, and MCI simply passes most of these commands to MCIAVI. MCI does not handle most commands, its interface is very simple. In fact, MCI has only five functions that applications use for MCI operation. Of these five functions, the following two functions are commonly used for sending commands.

Function	Description
mciSendCommand	Sends a command message to MCI.
mciSendString	Sends a command string to MCI.
For full information about the MCI commands, see the Microsoft Win32 Programmer's Reference.


Choosing the mciSendCommand or mciSendString Interface

Because there are two interfaces That can be used to send commands to MCIAVI, you must select the most appropriate one for your application's needs. With the mciSendCommand interface, your application must fill a data structure and make sure that the flags it sets match the data structure members it uses. With the mciSendString interface, however, your application must handle the conversion of string data for anything that might be variable within the application. You might choose to mix the two methods for the most efficient operation for your application. For straightforward commands, your application might use the string interface, and for commands that return information or commands to which your application passes information (such as window or palette handles), it might use the message interface.

You will probably find the string interface the easiest command set to understand and read. While the structure of the string commands is simple, it still retains the capabilities of the message commands to control MCI devices. This makes the command set extremely useful in planning your application and discussing the MCI capabilities of your application.

The examples in this chapter use a combination of the string and command interfaces.


Handling MCI Notification

Whichever interface your application uses, it can have MCI send notification messages to the application when an action completes. For both interfaces, your application must provide a callback window procedure if it is to handle the MM_MCINOTIFY message sent for notification. An MCI notification message indicates one of the following results:

•	The command completed successfully—MCI_NOTIFY_SUCCESSFUL

•	The current notification was superseded—MCI_NOTIFY_SUPERSEDED

•	The current notification was canceled—MCI_NOTIFY_ABORTED

•	The command fails—MCI_NOTIFY_FAILURE

The MOVPLAY sample applications use notification on the play command to determine when playing stops at the end of the sequence. Once started this way, the sequence plays independently of MOVPLAY and MCI notifies MOVPLAY when the sequence completes. MOVPLAY uses the notification message to rewind the sequence.


Playing AVI Files Using MCI

To play an AVI file, your application performs the following actions:

1.	Open the AVI file.

2.	Set up the playback window.

3.	Play the AVI sequence.

4.	Optionally, change the playback state.

5.	Optionally, get playback information.

6.	Close the AVI file.


Opening an AVI File

To open an AVI file, your application sends the open command to MCIAVI. This command lets your application specify the file. Your application can also specify information about the window used for playback.

If you plan on having your application open multiple AVI files, it might open the MCIAVI driver initially by specifying the driver identifier and then opening each file separately. This saves time because MCI will not load the MCIAVI driver for each file open command.

When your application uses a filename to open a device with a string command, MCI uses the file extension to locate the driver if the device type is not specified. For example, you can open MCIAVI by specifying YOSEMITE.AVI as a filename for the open command.

String commands can also specify an alias flag with the open command. This flag lets you specify a convenient name used to refer to the MCIAVI instance just opened. For example, you can open MCIAVI using the file YOSEMITE.AVI and the alias movie: open yosemite.avi alias movie. Subsequent commands for this file can use the alias movie to refer to it.

The open command has options to set some playback-window characteristics. These options are covered in the next section.


Setting Up the Playback Window

Your application can specify several options to define the playback window for playing the AVI sequence. The following options are available to your application:

•	Use the default pop-up window of MCIAVI for playing.

•	Specify a parent window and window style that MCIAVI can use to create the playback window.

•	Specify a playback window for MCIAVI to use for playback.

•	Play the AVI sequence on a full-screen display.

If your application does not specify any window options, MCIAVI creates a default window for playing the sequence. MCIAVI creates this playback window for the open command, but it does not display the window until your application either sends a command to display the window or sends a command to play the file. This default playback window is a sizable pop-up window with a caption, a thick frame, a system menu, and a minimize box.

The application can also specify a parent window handle and a window style when it opens MCIAVI. When opened this way, MCIAVI creates a window based on these specifications instead of the default pop-up window. Your application can specify any window style available for the CreateWindow function. Styles that require a parent window, like WS_CHILD, should include a parent window handle.

Your application can also create its own window and supply the handle to MCIAVI with the window command. MCIAVI uses this window instead of the one it might have created for playback.

When MCIAVI creates the playback window or obtains a window handle from your application, it does not display the window until your application either plays the sequence or sends a command to display the window. Your application can use the window command to display the window without playing the sequence. For example, the window movie state show command displays the window using the command-string interface.

Your application can also play an AVI sequence full-screen instead of in a window. To play full screen, modify the play command with the fullscreen flag. (Use the MCI_MCIAVI_PLAY_FULLSCREEN flag for the message interface.) When your application uses this flag, MCIAVI uses a 320-by-240 full-screen format for playing the sequence. For example, play movie fullscreen plays the opened file full-screen.

With the fullscreen flag, movies with 160-by-120 dimensions play back centered in the 320-by-240 screen. If you want your application to play these movies in a full 320-by-240 screen, it can use the play movie fullscreen by 2 command to stretch the 160-by-120 movie to full screen.


Playing the AVI Sequence

Use the MCI play command to play an AVI sequence. This command can play the entire sequence or portions of it.


Changing the Playback State

Your application can control many of the playback capabilities of MCIAVI. The pause, resume, stop, and seek commands let your application control the positioning of the AVI file. Using these, the application can pause a play in progress, seek to a location within the sequence, and resume play from that point.

Your application can use the seek command to move the play position to the beginning, the end, or an arbitrary position in the AVI file. There are two seek modes for the MCIAVI driver—exact or non-exact—which affect the seek position. When seek exactly is enabled (seek exactly on), MCIAVI seeks exactly to the frame your application specifies. This might cause a delay if the file is temporally encoded and your application does not specify a key frame. With seek exactly disabled (seek exactly off), MCIAVI seeks to the nearest key frame in a temporally encoded file. Your application can change the seek mode with the set command.

Other MCI commands let your application alter the play in ways other than altering the control flow of the play. For example, an AVI sequence, by default, plays at its normal rate of speed. Your application can change the play rate to speed up or slow down the playback. The speed flag for the set command lets your application control the play rate. For AVI sequences, a speed value of 1000 is considered normal. Thus, to play a movie at half-speed, your application can use the command string set movie speed 500. Alternatively, it can use set movie speed 2000 to play the sequence at twice the normal rate.

The setaudio command lets your application control the audio portion of an AVI sequence. You application can mute audio during playback, or in the case of multiple audio stream files, select the audio stream played. For example, the setaudio movie off command string turns audio off during playback. The setaudio movie stream to n command string specifies the audio stream number (specified by n) played for the sequence.

MCIAVI has a dialog box to control some of its playback options. Some of the important options available to the user include selection of window-oriented or full-screen playback, selection of the seek mode, and zooming the image. Your application can have MCIAVI display this dialog box with the configure command.


Obtaining Playback Information

Your application can get the status on the playback of an AVI sequence with the status command. This command obtains information about the state of the audio, state of the video, mode of play, position of play, and seek mode, as well as other parameters. Your application might monitor playback so that it can update the state and position of the play in a routine that gets called through a timer callback. The information returned by the status command can depend on the time format used. The device can specify the return values for position, length, and start in milliseconds or frames. Your application can use the set command to set alternate time formats and modes.


Closing the AVI File

When finished with a file, your application closes it with the close command. With the string interface, a close movie command is sent; with the command interface, an MCI_CLOSE command is used and all parameters can be NULL except for the device name or alias.


MCIAVI Selection of Stream Handlers

MCIAVI has the ability to use different stream handlers for the streams in an AVI file. The stream handler used and the method of selecting it depends on the type of stream.

Audio streams use the simplest selection method. MCIAVI will always use an internal handler for audio streams.

When a file containing text or custom data is opened, MCIAVI selects custom and text stream handlers based on the data format, the four-character code indicating the stream type, and the four-character code indicating the stream handler. (Internally, MCIAVI uses the ICM ICDrawOpen function to find the stream handler.) The system uses system registry entries to identify and find the ICM drivers. These entries are in the form of two four-character codes separated by a period. For text, the first four-character code is TXTS. Custom renderers can define their own four-character codes. The second four character code is defined by the driver. Typically, the second four-character code corresponds to the type of data the driver can handle; however, drivers might use other identifiers. For more information about ICM, see <ch_vcompsdk>.

MCIAVI's process for selecting video stream handlers is the most complex process. MCIAVI uses the following procedure:

•	If an application specifies the drawing handler, MCIAVI uses it. MCIAVI will not search for another drawing handler if it cannot find the specified handler.

•	If an application does not specify a drawing handler, MCIAVI uses the VIDS entries in the system registry to locate a stream handler that can handle the video stream. The VIDS four-character code identifies drivers that can handle video streams. (Internally, MCIAVI uses the ICM ICDrawOpen and ICDrawBegin functions to locate the stream handler and determine if the handler can completely handle the stream.)

•	If MCIAVI cannot find a VIDS handler that can handle the stream, MCIAVI tries the VIDS.DRAW driver.

•	If the VIDS.DRAW driver cannot draw the stream, MCIAVI uses an internal function (based on DrawDib) to draw the stream.

Note  When playing full-screen (the full screen flag is set), MCIAVI uses the VIDS.FULL driver rather than the VIDS.DRAW driver.


Specifying a Custom Drawing Function

The MCI_DGV_SETVIDEO_DRAW_PROCEDURE flag for the MCI_SETVIDEO command lets applications specify a custom drawing function. The internal structure of the function used for drawing should be the same as the DriverProc entry-point function used by installable drivers.


Using MCIAVI

This section contains information about using mciSendCommand and mciSendString to send MCI commands to MCIAVI.


Working with the MCI Command Interface

One method of sending MCI commands to MCIAVI uses mciSendCommand to send a command message. Command messages include a message corresponding to the command, a set of flags, and a data structure defining the parameters for that command. This function has the following syntax:

DWORD mciSendCommand(wDeviceID, wMessage, dwParam1, dwParam2)

The wDeviceID parameter defines the device ID of the MCI device that will receive the command. (This parameter is returned for the open command, which does not require the device ID.) The wMessage parameter specifies the message your application wants to send. The dwParam1 parameter defines the flags for the command, and dwParam2 points to a data structure for the command. This function returns zero on success or an MCI error code on failure.

The programming example for sending a command message has MCIAVI play an AVI file. The command message for playing an AVI file is MCI_PLAY. For this command, MCIAVI accepts the following flags in dwParam1.

Flag	Description
MCI_FROM	Indicates the dwFrom member of the structure identified by dwParam2 specifies a starting position for the file.
MCI_TO	Indicates the dwTo member of the structure identified by dwParam2 specifies an ending position for the file.
MCI_DGV_PLAY_WINDOW	Indicates playing should occur in the window associated with a device instance (the default).
MCI_MCIAVI_PLAY_FULLSCREEN	Indicates playing should use a full-screen display, typically with a 320-by-200 resolution.
The MCI_PLAY command uses the following data structure to pass information (dwParam2 points to this structure):

typedef struct {

    DWORD  dwCallback;

    DWORD  dwFrom;

    DWORD  dwTo;

} MCI_DGV_PLAY_PARMS;

Prior to using mciSendCommand to send the MCI_PLAY message, your application allocates the memory for the data structure, initializes the members it will use, and sets the flags corresponding to the members used in the data structure. (If your application does not set a flag for a data structure member, MCI drivers ignore the data structure member.) For example, the following function plays a movie from the starting position specified by dwFrom to the ending position specified by dwTo (if either position is zero, then the example assumes the position is not used):

DWORD PlayMovie(WORD wDevID, DWORD dwFrom, DWORD dwTo)

{

    MCI_DGV_PLAY_PARMS   mciPlay;    // play params

    DWORD                dwFlags = 0;

    // check dwFrom, if it is != 0 then set parameters and flags

    if (dwFrom){

        mciPlay.dwFrom = dwFrom; // set parameter

        dwFlags |= MCI_FROM;     // set flag to validate member

    }

    // check dwTo, if it is != 0 then set parameters and flags

    if (dwTo){

        mciPlay.dwTo = dwTo;    // set parameter

        dwFlags |= MCI_TO;      // set flag to validate member

    }

    // send the PLAY command and return the result

    return mciSendCommand(wDevID, MCI_PLAY, dwFlags,

            (DWORD)(LPVOID)&mciPlay);

}


Working with the MCI String Interface

Another method of sending MCI commands to MCIAVI uses mciSendString to send a command string. This function uses text strings to represent the command. It has the following syntax:

DWORD mciSendString(lpstrCommand, lpstrReturnString, wReturnLength, hCallback)

The lpstrCommand parameter specifies a pointer to the actual command string. Each command string includes a command, a device identifier, and command arguments. Arguments are optional on some commands and required on other commands. A command string has the following form:

command devicename arguments

The command parameter represents the command name (for example, open, close, or play). The devicename parameter identifies the MCI driver or a file. The arguments parameter indicates any flags and values associated with the command.

When your application opens MCIAVI, it uses a device name, a keyword from the the system registry, or filename as the devicename used to identify the MCI device. Your application can avoid using the formal devicename argument in subsequent commands by specifying the alias flag when it opens MCIAVI. (The alias for your application to use in subsequent commands is specified after the alias flag.) Most string examples in this section use the alias movie.

The lpstrReturnString parameter of mciSendString specifies a pointer to a buffer for return information. (Your application can set it NULL if a command does not return information.) The wReturnLength parameter specifies the size of the return buffer, or zero if no buffer is specified. The hCallback parameter specifies a window handle if your application is to receive MCI notify messages.

For example, the string play command used with MCIAVI starts playing the video sequence.

The syntax of the play command is play devicename parameters.

The following optional parameters modify play.

Parameter	Description
from position	Specifies the position to seek to before beginning the play.
to position	Specifies the position at which to stop playing.
fullscreen	Specifies playing should use a full-screen display.
window	Specifies that playing should use the window associated with a device instance. (Default)
The following example uses the string interface to send the play command with the from and to flags:

DWORD PlayMovie(LPSTR lpstrAlias, DWORD dwFrom, DWORD dwTo)

{

    char    achCmndBuff[128];

    wsprintf(achCmndBuff, "play %s from %u to %u",

             lpstrAlias, dwFrom, dwTo);

    return mciSendString(achCommandBuff, NULL, 0, NULL);

}

When using the string interface, all values passed with the command and all return values are text strings, so your application needs conversion routines to translate from variables to strings or back again. For example, the following fragment gets the source rectangle and converts the return string into rectangle coordinates:

void GetSourceRect(LPSTR lpstrAlias, LPRECT lpRect)

{

    char    achRetBuff[128];

    char     achCommandBuff[128];

    // build the command string "where name source"

    sprintf(achCommandBuff, "where %s source", lpstrAlias);

    SetRectEmpty(lpRect);    // clear the RECT

    // send the command

    if (mciSendString(achCommandBuff, achRetBuff,

               sizeof(achRetBuff), NULL)== 0){

        // The rectangle is returned in our buffer as "x y dx dy"

        // We know x and y are both 0 since this is the source

        // rectangle.

        // Translate the string into the RECT structure.

        char    *p;

        p = achRetBuff;           // point to the return string

        while (*p != ' ') p++;    // go past the x (0)

        while (*p == ' ') p++;    // go past spaces

        while (*p != ' ') p++;    // go past the y (0)

        while (*p == ' ') p++;    // go past spaces

        // now get the width

        for ( ; *p != ' '; p++)

            lpRect->right = (10 * lpRect->right) +

                            (*p - '0');

        while (*p == ' ') p++;    // go past spaces

        // now get the height

        for ( ; *p != ' '; p++)

            lpRect->bottom = (10 * lpRect->bottom) +

                            (*p - '0');

    }

}


Handling MCI Notification: Examples

With the string interface, your application requests notification by adding the notify flag to the string command it sends. It prepares to receive the notification messages by setting the hCallback parameter to its window handle.

With the message interface, your application requests notification by adding MCI_NOTIFY to the flags sent in dwParam1. It prepares to receive the notification messages by setting the dwCallback member associated with dwParam2 to the callback window handle.

For both interfaces, the callback window procedure must be able to handle the MM_MCINOTIFY message.

The following fragment shows how the notify flag is used with the play command. To use the previous fragment to process the notification message, the handle to the window procedure containing it is specified in hwnd.

MCI_DGV_PLAY_PARMS    mciPlay;

DWORD                dwFlags;

mciPlay.dwCallback = MAKELONG(hwnd, 0);

dwFlags = MCI_NOTIFY;

mciSendCommand(wMCIDeviceID, MCI_PLAY, dwFlags, (DWORD)(LPSTR)&mciPlay);

For the string interface, the following line uses mciSendString to send the play command and request notification. The hwnd parameter in it would also specify the handle to the window procedure containing the handler for notification.

mciSendString("play movie notify", NULL, 0, hwnd);


Opening an AVI File: Examples

If your application will open multiple files, it should include routines such as initAVI and termAVI. The application would use initAVI during its initialization and termAVI during its termination.

// Initialize the MCIAVI driver. This returns TRUE if OK, FALSE on error.

BOOL    initAVI(void)

{

    return mciSendString("open avivideo", NULL, 0, NULL) == 0;

}

// Close the MCIAVI driver

void termAVI(void)

{

    mciSendString("close avivideo", NULL, 0, NULL);

}

The following fragment opens MCIAVI using the file YOSEMITE.AVI and the alias movie. Subsequent commands for this file can use the alias movie to refer to it.

if (mciSendString("open yosemite.avi alias movie", NULL, 0, NULL) == 0){

    // open is OK

} else {

    // handle the error

}


Setting Up the Playback Window: Examples

The following fragment shows how to use the open command to set a parent window and create a child of that window:

MCI_DGV_OPEN_PARMS    mciOpen;

mciOpen.lpstrElementName = lpstrFile;  // set the file name

mciOpen.dwStyle = WS_CHILD;            // set the style

mciOpen.hWndParent = hWnd;             // give a window handle

if (mciSendCommand(0, MCI_OPEN,

   (DWORD)(MCI_OPEN_ELEMENT|MCI_DGV_OPEN_PARENT|MCI_DGV_OPEN),

   (DWORD)(LPSTR)&mciOpen) == 0){

    // open is OK, continue operation

}

The following fragment finds the dimensions needed to play an AVI file, creates a window corresponding to that size, and has MCIAVI to play the file in the window:

HWND        hwnd;

MCI_DGV_RECT_PARMS mciRect;

// Get the movie dimensions with MCI_WHERE.

mciSendCommand(wDeviceID, MCI_WHERE, MCI_DGV_WHERE_SOURCE,

    (DWORD)(LPSTR)&mciRect);

// Create the playback window. Make it bigger for the border.                               hwndMovie = CreateWindow("mywindow", "Playback",

                         WS_CHILD|WS_BORDER, 0,0,

                         mciRect.rc.right+(2*GetSystemMetric(SM_CXBORDER)),

                         mciRect.rc.bottom+(2*GetSystemMetric(SM_CYBORDER)),

                         hwndParent, hInstApp, NULL);

if (hwndMovie){

    // Window created OK, make it the playback window.

    MCI_DGV_WINDOW_PARMS    mciWindow;

    mciWindow.hWnd = hwndMovie;

    mciSendCommand(wDeviceID, MCI_WINDOW, MCI_DGV_WINDOW_HWND,

                   (DWORD)(LPSTR)&mciWindow);

}

The following fragment shows how to display the window using the command message interface:

MCI_DGV_WINDOW_PARMS    mciWindow;

mciWindow.nCmdShow = SW_SHOW;    // set command - see ShowWindow()

mciSendCommand(wDeviceID, MCI_WINDOW, MCI_DGV_WINDOW_STATE,

               (DWORD)(LPSTR)&mciWindow);


Changing the Playback State: Examples

The following string command examples show how to use the pause, resume, stop, and seek commands:

// assume the file was opened with the alias 'movie'

// pause playing

mciSendString("pause movie", NULL, 0, NULL);

// resume play

mciSendString("resume movie", NULL, 0, NULL);

// stop play

mciSendString("stop movie", NULL, 0, NULL);

// seek to the beginning

mciSendString("seek movie to start", NULL, 0, NULL);

The following example shows how to use the string interface to change the seek mode:

// Set seek mode with the string interface

// assume the file was opened with the alias 'movie'

void SetSeekMode(BOOL fExact)

{

    if (fExact)

        mciSendString("set movie seek exactly on", NULL, 0, NULL);

    else

        mciSendString("set movie seek exactly off", NULL, 0, NULL);

}


Obtaining Information About a Movie

The following fragment sets the time format to frames and obtains the current position if the device is playing:

MCI_DGV_SET_PARMS       mciSet;

MCI_DGV_STATUS_PARMS    mciStatus;

// put in frame mode

mciSet.dwTimeFormat=MCI_FORMAT_FRAMES;

mciSendCommand(wDeviceID, MCI_SET,

               MCI_SET_TIME_FORMAT,

               (DWORD)(LPSTR)&mciSet);

mciStatus.dwItem = MCI_STATUS_MODE;

mciSendCommand(wDeviceID, MCI_STATUS,

               MCI_STATUS_ITEM,

               (DWORD)(LPSTR)&mciStatus);

// If device is playing get the position

if (mciStatus.dwReturn == MCI_MODE_PLAY){

    mciStatus.dwItem = MCI_STATUS_POSITION;

    mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM,

               (DWORD)(LPSTR)&mciStatus);

    // update the position from mciStatus.dwReturn

}


Specifying a Custom Drawing Function: Examples

The following fragment creates an instance of a drawing procedure and sends the address to MCIAVI with the MCI_AVI_SETVIDEO_DRAW_PROCEDURE flag set for the MCI_SETVIDEO command.

if (!lpfnHook) {

    lpfnHook = MakeProcInstance((FARPROC) ICAVIDrawProc, hInstApp);

}

dgv.dwValue = (DWORD) lpfnHook;

dgv.dwItem = MCI_AVI_SETVIDEO_DRAW_PROCEDURE;

uDevice = MCIWndGetDeviceID(hwndMCI);

if (uDevice) {

    dw = mciSendCommand(uDevice, MCI_SETVIDEO,

            MCI_DGV_SETVIDEO_ITEM | MCI_DGV_SETVIDEO_VALUE,

            (DWORD) (MCI_DGV_SETVIDEO_PARMS FAR *)&dgv);

    if (dw != 0) {

    MessageBox(hwnd,

           "The currently installed MCIAVI does not "

           "support the MCI_AVI_SETVIDEO_DRAW_PROCEDURE "

           "command during play.","MCI Problem",

           MB_OK | MB_ICONHAND);

    }

}

The following fragment shows the structure of the drawing procedure used for the previous example. The internal structure of the function used for drawing should be the same as the DriverProc entry-point function used by installable drivers.

LONG FAR PASCAL _export ICAVIDrawProc(DWORD id, HDRVR hDriver, UINT uiMessage, LPARAM lParam1, LPARAM lParam2)

{

    PINSTINFO pi = (PINSTINFO)id;

    switch (uiMessage)

    {

        //System messages

        case DRV_LOAD:

        case DRV_FREE:

            return 1;

   .

   .

   .

        case DRV_CLOSE:

            return AVIDrawClose(pi);

        // ICM configuration messages

        case ICM_CONFIGURE:

        case ICM_ABOUT:

            return ICERR_UNSUPPORTED;

        // ICM state information messages

        case ICM_GETSTATE:

        case ICM_SETSTATE:

            return 0L;

        case ICM_GETINFO:

            return AVIDrawGetInfo((ICINFO FAR *)lParam1, lParam2);

        // ICM drawing messages

        case ICM_DRAW_QUERY:

            return AVIDrawQuery(pi, (LPBITMAPINFOHEADER)lParam1);

        case ICM_DRAW_SUGGESTFORMAT:

            return AVIDrawSuggestFormat(pi, (ICDRAWSUGGEST FAR *)

                   lParam1, lParam2);

        case ICM_DRAW_BEGIN:

            return AVIDrawBegin(pi, (ICDRAWBEGIN FAR *) lParam1,

                   lParam2);

   .

   .

   .

        case ICM_DRAW_END:

            return AVIDrawEnd(pi);

    }

    if (uiMessage < DRV_USER)

        return DefDriverProc(id,hDriver,uiMessage,lParam1,lParam2);

    else

        return ICERR_UNSUPPORTED;

}


Reference

The following section summarizes the MCI commands supported by MCIAVI. This command set is taken from the digital-video command set for MCI. Any device-specific behavior affecting the MCI commands is also noted.

MCIAVI uses a subset of the digital-video command set, except for the configure command and two custom flags used by the play command. The configure command displays a dialog box for setting the operating options of the MCIAVI. The custom flags used by the play command are fullscreen and window. These flags specify the display mode used for playing a video sequence. These flags are described with the play command.

The MCIAVI driver uses the AVIVideo keyword to identify the driver type.


MCIAVI Command Strings

This section describes the MCI command strings for the MCIAVI driver that you can use with applications that support the MCI command-string interface. (Applications with this interface send the command strings to MCI with the mciSendString function.)

All commands accept the optional flags wait and notify, although they are not explicitly listed in the command-string table. All commands, except open and close, also accept the optional flag test.

To	See this MCI command
Open and close an MCI device	open close
Obtain information about a device	capability info status
Configure a device or set operating parameters	configure set setaudio setvideo
Control playback	pause play resume stop
Control media position	cue seek step
Set signals	signal
Realize a palette	realize
Specify or obtain information about a window or display rectangle	put where window
Repaint the current frame into a display context	update
Use MCI command messages	MCIAVI command messages


capability

The capability command returns a string containing additional information about the capabilities of MCIAVI.

capability devicename parameters

One of the following parameters can modify capability:

can eject

Returns false.

can freeze

Returns false.

can lock

Returns false.

can play

Returns true.

can record

Returns false.

can reverse

Returns false.

can save

Returns false.

can stretch

Returns true.

can stretch input

Returns false.

can test

Returns true.

compound device

Returns true.

device type

Returns digital video.

has audio

Returns true.

has still

Returns false.

has video

Returns true.

uses files

Returns true.

uses palettes

Returns true.

windows

Returns the number of simultaneous display windows the device can support.


close

The close command closes this instance of the MCIAVI and releases all resources associated with it.

close devicename


configure

The configure command displays a dialog box used to configure MCIAVI.

configure devicename

The configure dialog box contains the following selections:

Option	Description
Window	Displays the video in a window.
Full Screen	Displays the video using the full screen with 320-by-240 resolution. This allows a 256-color display on 16-color devices.
Zoom By 2	Stretches the video to twice its normal size.
Skip Video Frames If Behind	Specifies dropping frames if the video falls behind. If this isn't selected, all the video frames will be shown and the audio will break up as necessary.
Don't Buffer Offscreen	Specifies that a copy of the display window should not be maintained.
Information list box	Contains information about the open file. Additional information might be listed after the file is played.


cue

The cue command prepares MCIAVI for playback and leaves it in a paused state.

cue devicename parameters

The following optional parameters modify cue:

output

Prepares MCIAVI for playing.

to position

Positions the workspace to the specified position.


info

The info command returns a string containing information about MCIAVI.

info devicename parameters

The following optional parameters modify info:

file

Returns the name of the file currently loaded.

product

Returns Video for Windows.

version

Returns the release level of MCIAVI.

window text

Returns the text string in the title bar of the window associated with MCIAVI.


open

The open command initializes MCIAVI.

open devicename parameters

The following parameters modify open:

alias alias

Specifies an alias used to reference this instance of MCIAVI.

elementname

Specifies the name of the device element (file) loaded when MCIAVI opens.

parent hwnd

Specifies the parent of the default window.

style stylevalue

Specifies the style used for the default window. The following constants are defined for stylevalue: overlapped, popup, and child.

type AVIVideo

Specifies the device type of the device element.


pause

The pause command pauses playing of motion video or audio.

pause devicename


play

The play command starts playing the video sequence.

play devicename parameters

The following optional parameters modify play:

from position

Specifies the position to seek to before beginning the play.

to position

Specifies the position at which to stop playing.

fullscreen

Specifies that playing should use a full-screen display. Use this flag only when playing compressed files. Uncompressed files won't play full-screen.

window

Specifies that playing should use the window associated with a device instance (the default).


put

The put command specifies a rectangular region that describes a cropping or scaling option. The rectangular region is defined by the upper-left corner, the width, and the height of the rectangle.

put devicename parameters

One of the following parameters must be present to indicate the specific type of rectangle:

destination

Restores the initial destination window associated with this instance of MCIAVI.

destination at rectangle

Specifies which portion of the destination window associated with this instance of MCIAVI is used.

source

Restores the initial source rectangle. The image from this rectangle is scaled to fit in the destination rectangle.

source at rectangle

Specifies which portion of the source is scaled to fit in the destination rectangle. The units for the source rectangle are based on the units for the AVI file.

window

Restores the initial window size on the display. This command also displays the window.

window at rectangle

Changes the size and location of the display window. The rectangle specified with the at flag is relative to the parent window of the display window (usually the desktop) if the style child flag has been used for the open command. To change the location of the window without changing its height or width, specify zero for the height and width.

window client

Restores the client area of the window.

window client at rectangle

Changes the size and location of the client area of the window. The rectangle specified with the at flag is relative to the parent window of the client window. To change the location of the window without changing its height or width, specify zero for the height and width.


realize

The realize command tells MCIAVI to select and realize its palette into a display context of the displayed window. Use this command only if your application uses a window handle and receives a WM_QUERYNEWPALETTE or WM_PALETTECHANGED message.

realize devicename parameters

One of the following parameters can modify realize:

background

Realizes the palette as a background palette.

normal

Realizes the palette used for a top-level window (the default).


resume

The resume command specifies that operation should continue from where it was interrupted by a pause command.

resume devicename


seek

The seek command positions and cues the workspace to the specified position showing the specified frame.

seek devicename parameters

One of the following parameters can modify seek:

to position

Specifies the desired new position, measured in units of the current-time format.

to end

Moves the position after the last frame of the workspace.

to start

Moves the position to the first frame of the workspace.


set

The set command sets the state of control items.

set devicename parameters

One of the following parameters can modify set:

seek exactly on

seek exactly off

Selects one of two seek modes. With seek exactly on, seek will always move to the frame specified. With seek exactly off, seek will move to the closest key frame prior to the frame specified.

speed factor

Sets the relative speed of video and audio playback from the workspace. Factor is the ratio between the nominal frame rate and the desired frame rate, where the nominal frame rate is designated as 1000. Setting the speed to 0 plays the video as fast as possible without dropping frames and without audio.

time format format

Sets the time format to format. The default time format is frames. Milliseconds can be abbreviated as ms. MCIAVI supports frames and milliseconds.

audio all off

Disables audio.

audio all on

Enables audio.

video off

Disables video.

video on

Enables video.


setaudio

The setaudio command sets various values associated with audio playback and capture.

setaudio devicename parameters

Only one of the following parameters can be present in a setaudio command unless otherwise noted:

off

Disables audio.

on

Enables audio.

volume to factor

Sets the average audio volume for both audio channels.


setvideo

The setvideo command sets various values associated with video playback.

setvideo devicename parameters

The following optional parameters modify setvideo:

off

Disables video display in the window.

on

Enables video display in the window.

palette handle to handle

Specifies the handle to a palette.


signal

The signal command identifies a specified position in the workspace. MCIAVI supports only one active signal at a time.

signal devicename parameters

The following parameters modify signal:

at position

Specifies the frame to invoke a signal.

cancel

Indicates the active signal should be removed from the workspace.

every interval

Specifies the period (in the current-time format) to send signals.

return position

An optional parameter which indicates that the MCIAVI should send the position value instead of the uservalue value in the window message.

uservalue id

Specifies a value associated with this signal request that is reported back with the window message.


status

The status command returns status information about this instance of MCIAVI.

status devicename parameters

One of the following parameters modifies status:

audio

Returns on if either or both speakers are enabled, and off otherwise.

forward

Returns true if playing forward.

length

Returns the length of the longest stream in the AVI file in the current-time format.

media present

Returns true.

mode

Returns one of the following: not ready, paused, playing, seeking, or stopped.

monitor

Returns file.

nominal frame rate

Returns the nominal frame rate associated with the file in units of frames per second times 1000.

number of tracks

Returns the number of tracks in a video sequence (usually 1).

palette handle

Returns the palette handle.

position

Returns the current position in the workspace in the current-time format.

ready

Returns true if this instance of MCIAVI is ready to accept another command.

reference frame

Returns the nearest key-frame number that precedes frame.

seek exactly

Returns on or off, indicating whether or not seek exactly is set.

speed

Returns the current playback speed.

start position

Returns the start of the media.

time format

Returns the current-time format (frames or milliseconds).

unsaved

Returns false.

video

Returns on or off, depending on the most recent setvideo.

volume

Returns the average volume to the left and right speaker. This returns an error if the device has not been played or volume has not been set.

window handle

Returns the ASCII decimal value for the window handle associated with this instance of MCIAVI.

window visible

Returns true if the window is not hidden.

window minimized

Returns true if the window is minimized.

window maximized

Return true if the window is maximized.


step

The step command advances the sequence to the specified image.

step devicename parameters

The following optional parameters modify step:

by frames

Specifies the number of frames to advance before showing another image. You can specify negative values for frames.

reverse

Requests that the step be taken in the reverse direction.


stop

The stop command stops playing.

stop devicename


update

The update command repaints the current frame into the specified display context.

update devicename parameters

The following optional parameters modify update:

hdc hdc at rect

Specifies the clipping rectangle relative to the client rectangle.

hdc hdc

Specifies the handle of the display context to paint.

paint hdc hdc

An application uses the paint flag with update when it receives a WM_PAINT message intended for a display context.


where

The where command returns the rectangular region that has been previously specified, or defaulted, using the put command. The rectangular region coordinates are defined by the upper-left corner, the width, and the height of the rectangle.

where devicename parameters

The following parameters modify where:

destination

Returns a description of the rectangular region used to display video and images in the client area of the current window.

destination max

Returns the current size of the client rectangle.

source

Returns a description of the rectangular region cropped from the frame buffer, which is stretched to fit the destination rectangle on the display.

source max

Returns the maximum size of the frame buffer.

window

Returns the current size and position of the display-window frame.

window max

Returns the size of the entire display.


window

The window command provides an instance of MCIAVI with a window handle used to display images or motion video.

window devicename parameters

The following parameters modify window:

handle hwnd

Specifies a window to be used with this instance.

handle default

Restores playback to the default window created during the open operation.

state showvalue

This command issues a ShowWindow call for the current window. The following constants are defined for showvalue:
hide
minimize
restore
show
show maximized
show minimized
show min noactive
show na
show noactivate
show normal

text caption

Specifies the text placed in the title bar of the window.


MCIAVI Command Messages

This section summarizes the MCI command messages for the Microsoft MCI video-device driver (MCIAVI) that you can use with the mciSendCommand function. These commands are used internally by applications.

All commands accept the optional flags MCI_NOTIFY and MCI_WAIT as described in the digital-video command set. All commands, except MCI_OPEN and MCI_CLOSE, also accept the optional flag MCI_TEST.

To	See this MCI command or data structure
Open and close an MCI device	MCI_OPEN MCI_DGV_OPEN_PARMS MCI_CLOSE MCI_GENERIC_PARMS
Obtain information about a device	MCI_INFO MCI_DGV_INFO_PARMS MCI_GETDEVCAPS MCI_GETDEVCAPS_PARMS MCI_STATUS MCI_DGV_STATUS_PARMS
Configure a device or set operating parameters	MCI_SET MCI_DGV_SET_PARMS MCI_SETAUDIO MCI_DGV_SETAUDIO_PARMS MCI_SETVIDEO MCI_DGV_SETVIDEO_PARMS
Control playback	MCI_PAUSE MCI_DGV_PAUSE_PARMS MCI_PLAY MCI_DGV_PLAY_PARMS MCI_RESUME MCI_STOP MCI_DGV_STOP_PARMS
Control media position	MCI_CUE MCI_DGV_CUE_PARMS MCI_SEEK MCI_SEEK_PARMS MCI_STEP MCI_DGV_STEP_PARMS
Set position marks	MCI_SIGNAL MCI_DGV_SIGNAL_PARMS MM_MCISIGNAL
Realize a palette	MCI_REALIZE
Specify or obtain information about a window or display rectangle	MCI_PUT MCI_DGV_PUT_PARMS MCI_WHERE MCI_DGV_RECT_PARMS MCI_WINDOW MCI_DGV_WINDOW_PARMS
Repaint the current frame into a display context	MCI_UPDATE MCI_DGV_UPDATE_PARMS
Use string commands	MCIAVI Command Strings


MCI_CLOSE

This message releases access to a device or device element.

DWORD lParam1

Specifies the MCI_NOTIFY or MCI_WAIT flag.

LPMCI_GENERIC_PARMS lParam2

Specifies a pointer to the MCI_GENERIC_PARMS data structure.


MCI_CUE

This message prepares a device instance so that it can begin playback with minimum delay.

DWORD lParam1

The following flags apply to MCIAVI:

MCI_DGV_CUE_OUTPUT

Specifies an instance should be cued for playing.

MCI_TO

Specifies that a workspace position is included in the dwTo member of the data structure identified by lParam2.

LPMCI_DGV_CUE_PARMS lParam2

Specifies a pointer to the MCI_DGV_CUE_PARMS data structure.


MCI_DGV_CUE_PARMS

The MCI_DGV_CUE_PARMS structure contains parameters used by the MCI_CUE message for digital-video devices. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD  dwCallback;

    DWORD  dwTo;

} MCI_DGV_CUE_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.

dwTo

Specifies the cue position.


MCI_DGV_INFO_PARMS

The MCI_DGV_INFO_PARMS structure contains parameters used by the MCI_INFO message for digital-video devices. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD  dwCallback;

    LPSTR  lpstrReturn;

    DWORD  dwRetSize;

    DWORD  dwItem;

} MCI_DGV_INFO_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.

lpstrReturn

Specifies a pointer to a user-supplied buffer for the return string.

dwRetSize

Specifies the size in bytes of the buffer for the return string.

dwItem

Specifies a constant describing the information to return.


MCI_DGV_OPEN_PARMS

The MCI_DGV_OPEN_PARMS structure contains information used by the MCI_OPEN message for digital-video devices. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD dwCallback;

    WORD  wDeviceID;

    WORD  wReserved0;

    LPSTR lpstrDeviceType;

    LPSTR lpstrElementName;

    LPSTR lpstrAlias;

    DWORD dwStyle;

    WORD  hWndParent;

    WORD  wReserved1;

} MCI_DGV_OPEN_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.

wDeviceID

Contains the device ID returned to user.

wReserved0

Reserved.

lpstrDeviceType

Specifies the name or constant ID of the device type.

lpstrElementName

Specifies the device-element name (usually a path).

lpstrAlias

Specifies an optional device alias.

dwStyle

Specifies the window style.

hWndParent

Specifies the handle to use as the window parent.

wReserved1

Reserved.


MCI_DGV_PAUSE_PARMS

The MCI_DGV_PAUSE_PARMS structure contains information used by the MCI_PAUSE command. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD  dwCallback;

} MCI_DGV_PAUSE_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.


MCI_DGV_PLAY_PARMS

The MCI_DGV_PLAY_PARMS structure contains parameters used by the MCI_PLAY message for digital-video devices. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD  dwCallback;

    DWORD  dwFrom;

    DWORD  dwTo;

} MCI_DGV_PLAY_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.

dwFrom

Specifies the position to play from.

dwTo

Specifies the position to play to.


MCI_DGV_PUT_PARMS

The MCI_DGV_PUT_PARMS structure contains parameters used by the MCI_PUT message for digital-video devices. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD  dwCallback;

    RECT   rc;

} MCI_DGV_PUT_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.

rc

Specifies a rectangle.


MCI_DGV_SIGNAL_PARMS

The MCI_DGV_SIGNAL_PARMS structure contains parameters for the MCI_SIGNAL message used by digital-video devices. When assigning data to the members in this data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member.

typedef struct {

    DWORD  dwCallback;

    DWORD  dwPosition;

    DWORD  dwPeriod;

    DWORD  dwUserParm;

} MCI_DGV_SIGNAL_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.

dwPosition

Specifies the position to be marked.

dwPeriod

Specifies the interval of the position marks.

dwUserParm

Specifies a value associated with the signals being set.


MCI_DGV_RECT_PARMS

The MCI_DGV_RECT_PARMS structure contains parameters used by the MCI_FREEZE, MCI_PUT, MCI_UNFREEZE, and MCI_WHERE messages for digital-video devices. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD  dwCallback;

    RECT  rc;

} MCI_DGV_RECT_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.

rc

Specifies a rectangle.


MCI_DGV_SET_PARMS

The MCI_DGV_SET_PARMS structure contains parameters used by the MCI_SET message for digital-video devices. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD  dwCallback;

    DWORD  dwTimeFormat;

    DWORD  dwAudio;

    DWORD  dwFileFormat;

    DWORD  dwSpeed;

} MCI_DGV_SET_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.

dwTimeFormat

Specifies the time format used by the device.

dwAudio

Specifies the channel used for audio output.

dwFileFormat

Specifies the file format.

dwSpeed

Specifies the playback speed.


MCI_DGV_SETAUDIO_PARMS

The MCI_DGV_SETAUDIO_PARMS structure contains parameters used by the MCI_SETAUDIO message for digital-video devices. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD  dwCallback;

    DWORD  dwItem;

    DWORD  dwValue;

    DWORD  dwOver;

    LPSTR  lpstrAlgorithm;

    LPSTR  lpstrQuality;

} MCI_DGV_SETAUDIO_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.

dwItem

Specifies the constant indicating the target adjustment.

dwValue

Specifies the adjustment level.

dwOver

Specifies the transition-length parameter.

lpstrAlgorithm

Specifies a pointer to a zero-terminated string containing the name of the audio-compression algorithm.

lpstrQuality

Specifies a pointer to a zero-terminated string containing a descriptor of the audio-compression algorithm.


MCI_DGV_SETVIDEO_PARMS

The MCI_DGV_SETVIDEO_PARMS structure contains parameters used by the MCI_SETVIDEO message for digital-video devices. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD  dwCallback;

    DWORD  dwItem;

    DWORD  dwValue;

    DWORD  dwOver;

    LPSTR  lpstrQuality;

    LPSTR  lpstrAlgorithm;

    DWORD  dwSourceNumber;

} MCI_DGV_SETVIDEO_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.

dwItem

Specifies the constant indicating the target adjustment.

dwValue

Specifies the adjustment level.

dwOver

Specifies the transition-length parameter.

lpstrQuality

Specifies a pointer to a zero-terminated string containing a descriptor of the video-compression algorithm.

lpstrAlgorithm

Specifies a pointer to a zero-terminated string containing the name of the video-compression algorithm.

dwSourceNumber

Specifies the index of input source.


MCI_DGV_STATUS_PARMS

The MCI_DGV_STATUS_PARMS structure contains parameters used by the MCI_STATUS message for digital-video devices. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD  dwCallback;

    DWORD  dwReturn;

    DWORD  dwItem;

    DWORD  dwTrack;

    LPSTR  lpstrDrive;

    DWORD  dwReference;

} MCI_DGV_STATUS_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.

dwReturn

Contains the return information on exit.

dwItem

Identifies the capability being queried.

dwTrack

Specifies the length or number of tracks.

lpstrDrive

Specifies the approximate amount of disk space that can be obtained by an MCI_RESERVE command.

dwReference

Specifies the approximate location of the nearest previous intraframe-encoded image.


MCI_DGV_STEP_PARMS

The MCI_DGV_STEP_PARMS structure contains parameters used by the MCI_STEP message for digital-video devices. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD  dwCallback;

    DWORD  dwFrames;

} MCI_DGV_STEP_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.

dwFrames

Specifies the number of frames to step.


MCI_DGV_STOP_PARMS

The MCI_DGV_STOP_PARMS structure contains information used by the MCI_STOP command message for digital-video devices. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD  dwCallback;

} MCI_DGV_STOP_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.


MCI_DGV_UPDATE_PARMS

The MCI_DGV_UPDATE_PARMS structure contains parameters used by the MCI_UPDATE message. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD dwCallback;

    RECT  rc;

    HDC   hDC;

    WORD  wReserved0;

} MCI_DGV_UPDATE_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.

rc

Specifies a rectangle.

hDC

Specifies a handle to a display context.

wReserved0

Reserved.


MCI_DGV_WINDOW_PARMS

The MCI_DGV_WINDOW_PARMS structure contains parameters used by the MCI_WINDOW message for digital-video devices. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD  dwCallback;

    WORD   hWnd;

    WORD   wReserved1;

    WORD   nCmdShow;

    WORD   wReserved2;

    LPSTR  lpstrText;

} MCI_DGV_WINDOW_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.

hWnd

Specifies a handle to the display window.

wReserved1

Reserved.

nCmdShow

Specifies how the window is displayed.

wReserved2

Reserved.

lpstrText

Specifies a pointer to a zero-terminated string containing the window caption.


MCI_GENERIC_PARMS

The MCI_GENERIC_PARMS structure contains the information used by MCI command messages that have empty parameter lists. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD  dwCallback;

} MCI_GENERIC_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.


MCI_GETDEVCAPS

This message obtains static information about a device.

DWORD lParam1

The following flags apply to the MCIAVI:

MCI_GETDEVCAPS_ITEM

Specifies that the dwItem member of the data structure identified by lParam2 contains a constant indicating which device capability to obtain. The following constants are recognized by MCIAVI:

•	MCI_GETDEVCAPS_CAN_EJECT

MCIAVI sets the dwReturn member to FALSE.

•	MCI_GETDEVCAPS_CAN_PLAY

MCIAVI sets the dwReturn member to TRUE.

•	MCI_GETDEVCAPS_CAN_RECORD

MCIAVI sets the dwReturn member to FALSE.

•	MCI_GETDEVCAPS_CAN_SAVE

MCIAVI sets the dwReturn member to FALSE.

•	MCI_GETDEVCAPS_COMPOUND_DEVICE

MCIAVI sets the dwReturn member to TRUE.

•	MCI_GETDEVCAPS_DEVICE_TYPE

MCIAVI sets the dwReturn member to MCI_DEVTYPE_DIGITAL_VIDEO.

•	MCI_GETDEVCAPS_HAS_AUDIO

MCIAVI sets the dwReturn member to TRUE.

•	MCI_GETDEVCAPS_HAS_VIDEO

MCIAVI sets the dwReturn member to TRUE.

•	MCI_GETDEVCAPS_USES_FILES

MCIAVI sets the dwReturn member to TRUE.

•	MCI_DGV_GETDEVCAPS_CAN_FREEZE

MCIAVI sets the dwReturn member to FALSE.

•	MCI_DGV_GETDEVCAPS_CAN_LOCK

MCIAVI sets the dwReturn member to FALSE.

•	MCI_DGV_GETDEVCAPS_CAN_REVERSE

MCIAVI sets the dwReturn member to FALSE.

•	MCI_DGV_GETDEVCAPS_CAN_STRETCH

MCIAVI sets the dwReturn member to TRUE.

•	MCI_DGV_GETDEVCAPS_CAN_STR_IN

MCIAVI sets the dwReturn member to FALSE.

•	MCI_DGV_GETDEVCAPS_CAN_TEST

MCIAVI sets the dwReturn member to TRUE.

•	MCI_DGV_GETDEVCAPS_HAS_STILL

MCIAVI sets the dwReturn member to FALSE.

•	MCI_DGV_GETDEVCAPS_MAX_WINDOWS

MCIAVI sets the dwReturn member to the number of simultaneous display windows the device can support.

•	MCI_DGV_GETDEVCAPS_PALETTES

MCIAVI sets the dwReturn member to TRUE.

LPMCI_GETDEVCAPS_PARMS lParam2

Specifies a pointer to the MCI_GETDEVCAPS_PARMS data structure.


MCI_GETDEVCAPS_PARMS

The MCI_GETDEVCAPS_PARMS structure contains parameters for the MCI_GETDEVCAPS message. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD  dwCallback;

    DWORD  dwReturn;

    DWORD  dwItem;

} MCI_GETDEVCAPS_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.

dwReturn

Contains the return information on exit.

dwItem

Identifies the capability being queried.


MCI_INFO

This message obtains string information from a device.

DWORD lParam1

The following flags apply to MCIAVI:

MCI_INFO_PRODUCT

MCIAVI returns Video for Windows.

MCI_DGV_INFO_TEXT

Returns the text string in the title bar of the window associated with the device instance.

MCI_INFO_FILE

Obtains the path and filename of the last file specified with the MCI_OPEN command.

MCI_INFO_VERSION

Returns the release level of the device driver and hardware.

LPMCI_DGV_INFO_PARMS lParam2

Specifies a pointer to the MCI_DGV_INFO_PARMS data structure.


MCI_OPEN

This message initializes an instance of the device or device element.

DWORD lParam1

The following flags apply to MCIAVI:

MCI_OPEN_ALIAS

Specifies that an alias is referenced in the lpstrAlias member of the data structure identified by lParam2.

MCI_OPEN_TYPE

Specifies that a device-type constant or a pointer to a device-type name is included in the lpstrDeviceType member of the data structure identified by lParam2.

MCI_OPEN_TYPE_ID

Specifies that the lpstrDeviceType member of the data structure identified by lParam2 contains a standard MCI device-type ID and the optional ordinal index for the device.

MCI_OPEN_ELEMENT

Specifies that an element name is included in the lpstrElementName member of the data structure identified by lParam2.

MCI_OPEN_ELEMENT_ID

Specifies that the lpstrElementName member of the data structure identified by lParam2 has meaning defined by the device.

MCI_DGV_OPEN_PARENT

Indicates the parent window handle is specified in the hWndParent member of the data structure identified by lParam2.

MCI_DGV_OPEN_WS

Indicates a window style is specified in the dwStyle member of the data structure identified by lParam2.

LPMCI_DGV_OPEN_PARMS lParam2

Specifies a pointer to the MCI_DGV_OPEN_PARMS data structure.


MCI_PAUSE

This message pauses the current action.

DWORD lParam1

Specifies the MCI_NOTIFY, MCI_TEST, and MCI_WAIT flags.

LPMCI_DGV_PAUSE_PARMS lParam2

Specifies a pointer to the MCI_DGV_PAUSE_PARMS data structure.


MCI_PLAY

This message begins play of the audio and video.

DWORD lParam1

The following flags apply to MCIAVI:

MCI_FROM

Specifies that a starting position is included in the dwFrom member of the data structure identified by lParam2.

MCI_TO

Specifies that an ending position is included in the dwTo member of the data structure identified by lParam2. MCIAVI returns an error if the "to" position is less than the "from" position.

MCI_DGV_PLAY_WINDOW

Specifies that playing should occur in the window associated with a device instance (the default). (This flag is specific to MCIAVI.)

MCI_MCIAVI_PLAY_FULLSCREEN

Specifies that playing should use a full-screen display, typically, with a 320-by-200 resolution. The full-screen display takes over the entire desktop. Use this flag only when playing compressed files. Uncompressed files won't play full-screen. (This flag is specific to MCIAVI.)

LPMCI_DGV_PLAY_PARMS lParam2

Specifies a pointer to an MCI_DGV_PLAY_PARMS data structure.


MCI_PUT

This message specifies a rectangular region that describes a cropping or scaling option.

DWORD lParam1

The following flags apply to MCIAVI:

MCI_DGV_RECT

Specifies that the rc member of the data structure identified by lParam2 contains a valid rectangle.

MCI_DGV_PUT_CLIENT

Indicates the rectangle defined for MCI_DGV_RECT applies to the position of the client window. The rectangle specified is relative to the parent window of the display window. MCI_DGV_PUT_WINDOW can be set concurrently with this flag.

MCI_DGV_PUT_DESTINATION

Indicates the rectangle defined for MCI_DGV_RECT specifies a destination rectangle. The destination rectangle specifies the portion of the client window associated with this device driver instance that shows the image or video.

MCI_DGV_PUT_SOURCE

Indicates the rectangle defined for MCI_DGV_RECT specifies a source rectangle. The source rectangle specifies which portion of the frame buffer is to be scaled to fit into the destination rectangle.

MCI_DGV_PUT_WINDOW

Indicates that the rectangle defined for MCI_DGV_RECT applies to the display window. This rectangle is relative to the parent window of the display window (usually the desktop). If the window is not specified, it defaults to the initial window size and position.

LPMCI_DGV_PUT_PARMS lParam2

Specifies a pointer to an MCI_DGV_PUT_PARMS data structure.


MCI_REALIZE

This message tells MCIAVI to select and realize its palette into a display context of the displayed window. You should use this message when your application receives the WM_QUERYNEWPALETTE message from the system.

DWORD lParam1

The following flags apply to MCIAVI:

MCI_DGV_REALIZE_BKGD

Realizes the palette as a background palette.

MCI_DGV_REALIZE_NORM

Realizes the palette normally (the default).

LPMCI_GENERIC_PARMS lParam2

Specifies a pointer to an MCI_GENERIC_PARMS data structure.


MCI_RESUME

This message resumes MCIAVI operation when it is paused.

DWORD lParam1

Specifies the MCI_NOTIFY, MCI_WAIT, and MCI_TEST flags.

LPMCI_GENERIC_PARMS lParam2

Specifies a pointer to the MCI_GENERIC_PARMS data structure.


MCI_SEEK

This message positions and cues the workspace to the specified position showing the specified frame.

DWORD lParam1

The following flags apply to MCIAVI:

MCI_SEEK_TO_END

Specifies the seek should move to the end of the workspace.

MCI_SEEK_TO_START

Specifies the seek should move to the beginning of the workspace.

MCI_TO

Specifies a position is included in the dwTo member of the MCI_SEEK_PARMS data structure.

LPMCI_SEEK_PARMS lParam2

Specifies a pointer to the MCI_SEEK_PARMS data structure.


MCI_SEEK_PARMS

The MCI_SEEK_PARMS structure contains parameters used by the MCI_SEEK message. When assigning data to the members in the following data structure, set the corresponding MCI flags in the lParam1 parameter of mciSendCommand to validate each member:

typedef struct {

    DWORD  dwCallback;

    DWORD  dwTo;

} MCI_SEEK_PARMS;

dwCallback

The low-order word specifies a window handle used for the MCI_NOTIFY flag.

dwTo

Specifies the seek position.


MCI_SET

This message sets device information.

DWORD lParam1

The following flags apply to MCIAVI:

MCI_SET_AUDIO

Specifies an audio-channel number is included in the dwAudio member of the data structure identified by lParam2. This flag must be used with MCI_SET_ON or MCI_SET_OFF. Specify the constant MCI_SET_AUDIO_ALL for the channel number.

MCI_SET_TIME_FORMAT

Specifies a time-format parameter is included in the dwTimeFormat member of the data structure identified by lParam2. Constants defined for time formats include:

•	MCI_FORMAT_FRAMES

Specifies frames.

•	MCI_FORMAT_MILLISECONDS

Specifies milliseconds.

MCI_SET_VIDEO

Sets the video signal on or off. This flag must be used with either MCI_SET_ON or MCI_SET_OFF.

MCI_SET_ON

Enables the video or audio channel, or enables the seek-exactly mode.

MCI_SET_OFF

Disables the video or audio channel, or disables the seek-exactly mode.

MCI_DGV_SET_SEEK_EXACTLY

Sets the format used for positioning. This flag must be used with MCI_SET_ON or MCI_SET_OFF.

MCI_DGV_SET_SPEED

Specifies that a speed parameter is included in the dwSpeed member of the data structure identified by lParam2. Setting the speed to 0 plays the video as fast as possible without dropping frames and without audio.

LPMCI_DGV_SET_PARMS lParam2

Specifies a pointer to the MCI_DGV_SET_PARMS data structure.


MCI_SETAUDIO

This message sets values associated with audio playback and capture.

DWORD lParam1

The following flags apply to MCIAVI:

MCI_DGV_SETAUDIO_ITEM

Indicates an audio constant is specified in the dwAdjustParm member of the data structure identified by lParam2. The following constant is supported by MCIAVI:

•	MCI_DGV_SETAUDIO_VOLUME

Indicates that the audio level is specified as a factor in the dwValue member of the data structure identified by lParam2. The volume level ranges between 0 and 1000.

•	MCI_DGV_SETAUDIO_VALUE

Indicates that an audio value is specified in the dwValue member of the data structure identified by lParam2.

MCI_SET_ON

Enables the audio channel.

MCI_SET_OFF

Disables the audio channel.

MCI_DGV_SETAUDIO_STREAM

Indicates the audio stream to play is specified in the dwValue member of the data structure identified by lParam2.

LPMCI_DGV_SETAUDIO_PARMS lParam2

Specifies a pointer to the MCI_DGV_SETAUDIO_PARMS data structure.


MCI_SETVIDEO

This message sets various values associated with video playback.

DWORD lParam1

The following flags apply to MCIAVI:

•	MCI_DGV_SETVIDEO_ITEM

Indicates a video constant is specified in the dwAdjustParm member of the data structure identified by lParam2. MCIAVI supports the following constant:

•	MCI_DGV_SETVIDEO_PALHANDLE

Indicates that a palette-handle value is specified in the dwValue member of the data structure identified by lParam2.

•	MCI_DGV_SETVIDEO_SRC_VALUE

Specifies a value is included in the dwValue member of the data structure identified by lParam2.

•	MCI_SET_ON

Enables video output.

•	MCI_SET_OFF

Disables video output.

•	MCI_DGV_SETVIDEO_DRAW_PROCEDURE

Indicates a drawing-procedure address is specified in the dwValue member of the data structure identified by lParam2.

LPMCI_DGV_SETVIDEO_PARMS lParam2

Specifies a pointer to the MCI_DGV_SETVIDEO_PARMS data structure.


MCI_SIGNAL

This message sets a specified position in the workspace. MCIAVI supports only one active signal at a time.

DWORD lParam1

The following flags apply to all devices supporting MCI_SIGNAL:

MCI_DGV_SIGNAL_AT

Specifies a signal position is included in the dwPosition member of the data structure identified by lParam2.

MCI_DGV_SIGNAL_EVERY

Specifies a signal-period value is included in the dwEvery member of the data structure identified by lParam2.

MCI_DGV_SIGNAL_USERVAL

Specifies a data value is included in the dwUserParm member of the data structure identified by lParam2. The data value associated with this request is reported back with the Windows message.

MCI_DGV_SIGNAL_CANCEL

Removes the signal position specified by the value associated with the MCI_DGV_SIGNAL_USERVAL flag.

MCI_DGV_SIGNAL_POSITION

Specifies that the device should send the position value with the Windows message instead of the user-specified value.

LPMCI_DGV_SIGNAL_PARMS lParam2

Specifies a pointer to the MCI_DGV_SIGNAL_PARMS structure.


MCI_STATUS

This message obtains information about an instance of an MCI device.

DWORD lParam1

The following flags apply to MCIAVI:

•	MCI_STATUS_ITEM

Specifies that the dwItem member of the data structure identified by lParam2 contains a constant specifying which status item to obtain. MCIAVI supports the following constants:

•	MCI_STATUS_LENGTH

MCIAVI sets the dwReturn member to the media length. (It returns an error for any track but 1.)

•	MCI_STATUS_MODE

MCIAVI sets the dwReturn member to the current mode of the device.

•	MCI_STATUS_NUMBER_OF_TRACKS

MCIAVI sets the dwReturn member to 1.

•	MCI_STATUS_POSITION

MCIAVI sets the dwReturn member to the position of the track. (It returns an error for any track but 1.)

•	MCI_STATUS_READY

MCIAVI sets the dwReturn member to TRUE if the device is ready to accept another command.

•	MCI_STATUS_TIME_FORMAT

MCIAVI sets the dwReturn to the current-time format.

•	MCI_DGV_STATUS_AUDIO

MCIAVI sets the dwReturn member to MCI_ON or MCI_OFF, depending on the most recent MCI_SET_AUDIO option for the MCI_SET command.

•	MCI_DGV_STATUS_FILEFORMAT

MCIAVI returns the constant for AVI RIFF in the dwReturn member.

•	MCI_DGV_STATUS_FORWARD

MCIAVI sets the dwReturn member to TRUE.

•	MCI_DGV_STATUS_MEDIA_PRESENT

MCIAVI sets the dwReturn member to TRUE.

•	MCI_DGV_STATUS_MONITOR

MCIAVI sets the dwReturn member to MCI_DGV_MONITOR_FILE.

•	MCI_DGV_STATUS_HPAL

MCIAVI sets the dwReturn member to the current palette handle.

•	MCI_DGV_STATUS_HWND

MCIAVI sets the dwReturn member to the window handle.

•	MCI_DGV_STATUS_NOMINAL_RATE

MCIAVI sets the dwReturn member to the nominal frame rate associated with the file.

•	MCI_DGV_STATUS_SIZE

MCIAVI sets the dwReturn member to zero.

•	MCI_DGV_STATUS_SEEK_EXACTLY

MCIAVI sets the dwReturn member to TRUE or FALSE indicating whether or not seek exactly is set.

•	MCI_DGV_STATUS_SPEED

MCIAVI sets the dwReturn member to the current playback speed.

•	MCI_DGV_STATUS_UNSAVED

MCIAVI sets the dwReturn member to FALSE.

•	MCI_DGV_STATUS_VIDEO

MCIAVI indicates whether the video is enabled or disabled in the dwReturn member.

•	MCI_DGV_STATUS_VOLUME

MCIAVI returns the average volume to the left and right speaker in the dwReturn member. This returns an error if the device has not been played or volume has not been set.

•	MCI_DGV_STATUS_WINDOW_VISIBLE

MCIAVI sets the dwReturn member to TRUE if the window is not hidden.

•	MCI_DGV_STATUS_WINDOW_MINIMIZED

MCIAVI sets the dwReturn member to TRUE if the window is minimized.

•	MCI_DGV_STATUS_WINDOW_MAXIMIZED

MCIAVI sets the dwReturn member to TRUE if the window is maximized.

MCI_STATUS_START

Obtains the starting position of the media. To get the starting position, combine this flag with MCI_STATUS_ITEM and set the dwItem member of the lParam2 data structure to MCI_STATUS_POSITION.

MCI_DGV_STATUS_REFERENCE

The dwReference member of the lParam2 data structure returns the nearest previous key frame.

LPMCI_DGV_STATUS_PARMS lParam2

Specifies a pointer to the MCI_DGV_STATUS_PARMS data structure.


MCI_STEP

This message steps the player one or more frames.

DWORD lParam1

The following flags apply to MCIAVI:

MCI_DGV_STEP_FRAMES

Indicates that the dwFrames member of the data structure identified by lParam2 specifies the number of frames to advance before displaying another image.

MCI_DGV_STEP_REVERSE

Steps in reverse.

LPMCI_DGV_STEP_PARMS lParam2

Specifies a pointer to the MCI_DGV_STEP_PARMS data structure.


MCI_STOP

This message stops all play sequences and ceases display of video images.

DWORD lParam1

Specifies the MCI_NOTIFY, MCI_WAIT, and MCI_TEST flags.

LPMCI_DGV_STOP_PARMS lParam2

Specifies a pointer to the MCI_DGV_STOP_PARMS data structure.


MCI_UPDATE

This message repaints the current frame into the specified display context.

DWORD lParam1

The following flags apply to MCIAVI:

MCI_UPDATE_HDC

Specifies that the hDC member of the data structure identified by lParam2 contains a valid window of the display context to paint.

MCI_DGV_UPDATE_PAINT

An application uses this flag when it receives a WM_PAINT message that is intended for a display DC. A frame-buffer device will usually paint the key color. If the display device does not have a frame buffer, it might ignore the MCI_UPDATE message when the MCI_DGV_UPDATE_PAINT flag is used, because the display will be repainted during the playback operation.

LPMCI_DGV_UPDATE_PARMS lParam2

Specifies a pointer to an MCI_DGV_UPDATE_PARMS data structure.


MCI_WHERE

This message returns the rectangular region that has been specified with the MCI_PUT command.

DWORD lParam1

The following flags apply to MCIAVI:

MCI_DGV_WHERE_DESTINATION

Obtains a description of the rectangular region used to display video and images in the client area of the current window.

MCI_DGV_WHERE_SOURCE

Obtains a description of the rectangular region (cropped from the frame

buffer) that is stretched to fit the destination rectangle on the display.

MCI_DGV_WHERE_MAX

When used with MCI_DGV_WHERE_DESTINATION or MCI_DGV_WHERE_SOURCE, the rectangle returned indicates the maximum width and height of the specified region. When used with MCI_DGV_WHERE_WINDOW, the rectangle returned indicates the size of the entire display.

MCI_DGV_WHERE_WINDOW

Obtains a description of the display-window frame.

LPMCI_DGV_RECT_PARMS lParam2

Specifies a pointer to an MCI_DGV_RECT_PARMS data structure.


MCI_WINDOW

This message specifies the window and the window characteristics for graphic devices.

DWORD lParam1

The following flags apply to MCIAVI:

MCI_DGV_WINDOW_HWND

Indicates that the handle of the window needed for use as the destination is included in the hWnd member of the data structure identified by lParam2.

MCI_DGV_WINDOW_STATE

Indicates the nCmdShow member of the MCI_DGV_WINDOW_PARMS data structure contains parameters for setting the window state.

MCI_DGV_WINDOW_TEXT

Indicates the lpstrText member of the MCI_DGV_WINDOW_PARMS data structure contains a pointer to a buffer containing the caption used in the window title bar.

LPMCI_DGV_WINDOW_PARMS lParam2

Specifies a pointer to an MCI_DGV_WINDOW_PARMS data structure.


MM_MCISIGNAL

This message is sent to a window to notify an application that an MCI device has reached a position defined in a previous MCI_SIGNAL to the device.

WORD wParam

Contains the ID of the device initiating the signal message.

LONG lParam

Usually, this contains the value passed in dwUserParm when the MCI_SIGNAL message has defined this callback. Alternatively, it might contain the position value.


AVI Files


About AVI Files

The AVI file functions are used to read and write time-based files, such as waveform or AVI files. They simplify your application by eliminating the need for your application to manage the RIFF file format. This chapter discusses the following topics:

•	Reading streams from AVI files

•	Writing streams to AVI files

•	Obtaining frame data from a stream

•	Combining streams from multiple AVI files

•	Positioning of AVI streams

•	Using custom stream handlers to read custom data as in an AVI file


Streams

You will come across the concept of streams many times when dealing with AVI file functions. Essentially, an AVI file can contain several different types of data — for instance, a video sequence, an English soundtrack, and a French soundtrack. Each of these components is considered a stream. When working with an AVI file, your application can use streams independent of other streams. Thus, when your application reads or writes an AVI file, it must specify which stream is the target stream.


Initializing the AVIFile Library

Prior to using any of the AVIFile functions, initialize the library with AVIFileInit. Conversely, when you are finished using the library release it with AVIFileExit. If you use AVIFileInit more than once, use AVIFileExit an equal number of times to completely release the library.


Opening and Closing AVI Files and Streams

As with any file, an application must open an AVI file for reading or writing. Opening an AVI file only partially prepares it for the AVI read and write operations because the data within the file is encapsulated in streams. Once a file is open, an application must also prepare each stream that it will use.


Opening AVI Files

The AVIFileOpen function opens an AVI file and initializes the file system. The function returns a file handle used to access the file.

The AVIFileOpen function has the following syntax:

LONG AVIFileOpen(PAVIFILE FAR * ppfile, LPCSTR szFile,

    UINT umode, LPCLSID pclsidHandler)

The ppfile parameter for this function specifies a pointer to a PAVIFILE data location the system uses to return the handle to the file. Your application supplies this handle to other AVIFile functions to identify the file.

The szFile parameter specifies the file to open. The umode parameter specifies any flags for opening the file. The flags valid for OpenFile are valid for this function.

The pclsidHandler parameter identifies the file handler used to read and write the AVI file and its components. Most applications will specify NULL for this parameter to use the default handlers. In this case, AVIFile searches the registration database to find default handlers that are associated with the filename extension or the RIFF type of the file.

If your application specifies an explicit class ID for pclsidHandler, it implies your application also specifies an external file handler to read and write custom file information. To find the file handler, AVIFile searches the registration database for the class ID and uses the file handler associated with it. Class IDs are unique identifiers associated with entries in the registration database. A file handler developer assigns a class ID when the file handler is created. These external file handlers must be registered in the registration database before your application can access them.


Accessing Streams

Once your application opens an AVI file, it can use AVIFileGetStream to prepare a stream and obtain a stream pointer to it. Use this function only to obtain a stream pointer to existing streams. The AVIFileGetStream function has the following syntax:

LONG AVIFileGetStream(PAVIFILE pfile, PAVISTREAM FAR * ppavi,

    DWORD fccType, LONG lParam)

Your application specifies the AVI file handle it received from AVIFileOpen in the pfile parameter. The ppavi parameter points to the location the system uses to return a pointer to the stream interface. Your application uses this pointer to refer to the stream in other functions that read or write the data stream.

Your application specifies the stream it must access in the fccType and lParam parameters. The fccType parameter indicates the type of stream to open. Your application can specify zero if it does not matter which stream type is opened. Your application can specify streamtypeAUDIO or streamtypeVIDEO to open an audio stream or video stream.

The lParam parameter indicates which stream of the type specified in fccType should be accessed. Zero indicates the first stream.


Opening a File and Obtaining a Stream-Interface Pointer Simultaneously

If your application will work with only one stream in a file, it can use AVIStreamOpenFromFile to open the file and obtain a stream-interface pointer to a stream. The AVIStreamOpenFromFile function has the following syntax:

LONG AVIStreamOpenFromFile(PAVISTREAM FAR * ppavi, LPSTR szFile,

    DWORD fccType, LONG lParam, UINT mode, CLSID pclsidHandler)

The szFile, mode, and pclsidHandler parameters specify the file, any flags used to open it, and the file handler used. These parameters have the same definitions used for AVIFileOpen. The fccType, and lParam parameters specify the file and a stream within the file. These parameters have the same definitions used for AVIFileGetStream.

If you are using more than one stream, it is more efficient to use AVIFileOpen to open the file and use AVIFileGetStream to obtain a stream-interface pointer to each stream.


Specifying a File or Stream Handler Using MCI String Commands

MCI can open files using a file-interface pointer or a stream-interface pointer. To open a file with an interface pointer, specify an at sign (@), followed by the interface pointer, in place of the file or device name.


Incrementing the Reference Count of a Stream or AVI File

Your application can use AVIFileAddRef and AVIStreamAddRef to keep an AVI stream or file open when it uses a function that normally closes the stream or file. The function AVIFileAddRef increases the reference count of an AVI file. The function AVIStreamAddRef increases the reference count of an AVI stream. When your application uses these functions, it must make sure that it, or a routine that uses the stream, decrements the reference count by closing the stream or file.


Closing a Stream

When your application is finished with a stream, it uses AVIStreamRelease to reduce the reference count of an AVI stream. The function closes the stream if the count reaches zero. Each stream opened or created with AVIFileGetStream, AVIFileCreateStream, AVIStreamAddRef, or AVIStreamOpenFromFile must be closed when your application is finished with it, or when it is ready to close the file.


Closing an AVI File

When your application is finished with an AVI file, it uses AVIFileRelease to reduce the reference count of an AVI file. AVIFileRelease closes the file if the count reaches zero. Closing an AVI file saves all changes to the file. Each call to AVIFileAddRef or AVIFileOpen should be balanced by a call to AVIFileRelease.

Note  Your application releases a file while it has streams open. The system will not close the streams until all of the streams are released. Files opened with AVIStreamOpenFromFile are closed when their streams are released.


Reading from a File

The following functions are used to retrieve information from an AVI file: AVIFileInfo, AVIStreamInfo, AVIStreamReadFormat, AVIStreamRead, AVIFileReadData, and AVIStreamReadData. These functions obtain the different types of information from an AVI file. Prior to reading any data, your application opens a file with AVIFileOpen and obtains a file handle used to refer to the file.

Once the file is open, your application can determine the characteristics of the file by reading the AVIFILEINFO structure from the file with AVIFileInfo. The AVIFILEINFO structure contains information such as the number of streams within the file, the width and height of the AVI sequence, and the data rate of the sequence. Your application can use the data from this structure to initialize the playback environment and determine the number of streams the application must handle.

Once your application has determined the number of streams to be handled, it opens each stream with AVIFileGetStream. This function creates an interface pointer to the stream. The interface pointer is used by other functions to identify the stream.

The AVIStreamInfo function lets your application read the AVISTREAMINFO structure for each stream. This structure provides general information about a stream. It specifies the type of data the stream contains, such as audio or video, by means of a four-character code. Other information describes the installable compressor or decompressor used with the data, any flags for the data stream, and the playback characteristics of the stream.

The AVIStreamReadFormat function lets your application read a stream-specific structure that describes the format of the stream content. For a video stream, the format is described by a BITMAPINFO structure. For an audio stream, the format is described by a WAVEFORMATEX or PCMWAVEFORMAT structure.

Your application can use the AVIStreamRead function to retrieve the multimedia content from a file. This function reads raw data from the stream into an application-supplied buffer. For a video stream, the raw data consists of the bits that make up the image. This image might be compressed and unusable until your application decompresses it. For an audio stream, the raw data consists of the actual wave samples. These wave samples might also be compressed.

If a file or stream contains any optional information, your application can use AVIFileReadData and AVIStreamReadData to obtain it. For a file, optional data can include 'INFO' data. For streams, optional data can include configuration (state) data used by a compressor or decompressor.

Once your application is finished with a stream, it closes it with AVIStreamRelease. Similarly, once your application is finished with a file, it closes it with AVIFileRelease.

The following sections expand the details on using these functions to read AVI files and streams.


Obtaining Information About a File

Applications use the AVIFileInfo function to obtain general information about the AVI file. An application must provide the buffer used to return this structure. Information about the file is returned in a AVIFILEINFO data structure.


Obtaining Information About a Stream

Applications use the AVIStreamInfo function to have a stream handler return an AVISTREAMINFO structure containing information about a stream. An application must provide the buffer used to return this structure.

The stream header specifies the type of data the stream contains, such as audio or video, by means of a four-character code. The fccType member is set to vids if the stream it specifies contains video data. It is set to auds if it contains audio data.

The fccHandler member contains a four-character code describing the installable compressor or decompressor used with the data.

The dwFlags member contains any flags for the data stream. The AVISF_DISABLED flag indicates that the stream data should be rendered only when explicitly enabled by the user. The AVISF_VIDEO_PALCHANGES flag indicates palette changes are embedded in the file.

Other important members describe the playback characteristics of the stream. These factors include the playback rate (this is equal to dwRate divided by dwScale), the starting time of the sequence, the length of the sequence, the size of the playback buffer, an indicator of the data quality, and sample size.

Some of the members in the stream header structure are also present in the main header structure. The data in the main header structure applies to the whole file while the data in the stream header structure applies only to a stream.


Reading the Format for Stream Data

Applications use the AVIStreamReadFormat function to have the stream handler return a stream-specific structure containing information about the format of the stream data. Your application must allocate the buffer used to return the format information. If you specify NULL for the buffer pointer, the function returns the size of the buffer it must have to return the format data. Your application can use this information to allocate a buffer of the proper size.

For a video stream, the stream handler returns a BITMAPINFO structure in the application-supplied buffer. Palette information follows this data structure. For an audio stream, the stream handler returns a WAVEFORMATEX or PCMWAVEFORMAT structure. For a different type of stream, the stream handler returns the stream-specific format data associated with that type of data stream.


Reading Optional Stream Header Information

Applications use the AVIStreamReadData function to have the stream handler return a stream-specific structure containing supplementary header information for a data stream. The supplementary information can include data used for driver configuration. Applications that read and write RIFF files do not need to decode this information. They transfer this data to and from a driver as a memory block. Not all streams have supplementary information.


Reading the Audio and Video Data from a Stream

Applications use the AVIStreamRead function to read audio or video data streams. The function reads raw data from the stream into an application-supplied buffer. Your application must specify the starting position (frame) and the number of samples (frames) to read.

If you do not supply a buffer, the function returns the number of bytes required to store the data you request. Your application can use this technique to determine the size of the buffer it must allocate.

For a video stream, the raw data consists of the bits that make up the image. This image might be compressed and unusable until your application decompresses it. Your application can determine the type of compression used by examining the BITMAPINFO structure obtained with AVIStreamReadFormat. AVIFile can also decompress video streams. For information about these functions, see <avr_compvid>. For information about drawing compressed data, see <ch_drawdib>.

For an audio stream, the stream handler returns the actual wave samples. These wave samples might also be compressed. The compression type is indicated in the PCMWAVEFORMAT structure returned by AVIStreamReadFormat. For information about decompressing waveform data, see <ch_acm_sdk>.


Reading Supplementary AVI File Information

The AVIFileReadData function reads other data chunks that might exist in the AVI file. For example, your application can use AVIFileReadData to read an information chunk. Your application must supply the return buffer for the returned information and handle the decoding of it.

Your application does not need to read or write the index chunk of an AVI file. The AVIFile read and write functions maintain this information automatically.


Working with Compressed Video Data in a Stream

If your application must decompress video data in a video stream, it can use the following functions: AVIStreamGetFrameOpen, AVIStreamGetFrame, and AVIStreamGetFrameClose. These functions can make it easier to work with video data from an AVI file. They handle decompressing and buffering the video.

The AVIStreamGetFrameOpen and AVIStreamGetFrameClose functions allocate and release the resources needed for AVIStreamGetFrame. One of these resources is the buffer used to return the decompressed video data. Use the stream-interface pointer returned by AVIStreamGetFrameOpen to identify the stream in the AVIStreamGetFrameClose and AVIStreamGetFrame functions.

The AVIStreamGetFrame function reads both the format of a video stream and its data bits. If necessary, it also handles decompression of the video stream. Your application specifies the pointer to a stream and the frame number AVIStreamGetFrame is to read. The function returns a pointer to a BITMAPINFOHEADER structure, which has a pointer to a valid, uncompressed device-independent bitmap (DIB). Your application can display this DIB with standard Win32 functions, or with the DrawDib functions. The DrawDib functions can handle images of different bit depths, and provide automatic dithering for displays that can't handle certain types of DIBs. For more information about the DrawDib functions, see <ch_drawdib>.

Your application can specify any frame within an AVI file even if the frame is compressed based upon data in previous frames. If necessary, AVIStreamGetFrame automatically starts reading the file at the segment's key frame to obtain the history needed to decompress the specified frame.


Writing to an AVI File

Applications typically create new AVI files when they capture data or combine existing data into a single file. There are two methods of writing to an AVI file. With the first method, your application selectively writes the information to the file. This lets your application control the organization of the file. With the second method, your application supplies the streams to the stream handler and AVIFile writes the AVI file.


Copying Existing Streams to a New File Using AVISave

Your application can use the AVISave, AVISaveV, and AVISaveOptions functions to write data to an AVI file. The AVISave and AVISaveV functions both save an AVI sequence to a disk file. The difference between the functions is the method of specifying streams saved in the file. The AVISave function uses a variable number of arguments to specify the stream handles, and the AVISaveV function uses an array to specify the stream handles.

Applications specify compression options for the AVISave and AVISaveV functions in an AVICOMPRESSOPTIONS structure. Your application can use AVISaveOptions to display a Compression Options dialog box that lets users specify the options for saving the file. When the user is done selecting the compression options, the options will be returned in the AVICOMPRESSOPTIONS structure.

Your application can also specify a callback function in the parameters of AVISave and AVISaveV. Your application can use this callback to display status information for the save operation and let the user cancel the save operation.


Application Control of Writing to an AVI File

Selectively writing the information to an AVI file lets your application control the layout of the file.

Opening and Creating an AVI File for Writing

If your application will write to an existing AVI file, it must open the file with the OF_WRITE flag to have write permission. If an AVI file is opened without write permission, functions that write to the AVI file will fail. If your application will write to a new AVI file, it uses AVIFileOpen with the OF_CREATE and OF_WRITE flags.

Creating a Stream

The AVIFileCreateStream function creates a new stream in an AVI file and obtains a stream pointer to it. Your application can use this function to add a new stream to an AVI file. The application uses the stream pointer to refer to the stream in other AVIFile functions.

Because this is a new stream, your application must supply information about the stream in an AVISTREAMINFO structure. This structure contains information such as the stream data type and the playback characteristics of the stream.

Your application must also specify the format of the stream with AVIStreamSetFormat. The data structure used to specify the format depends on the content of the stream. A BITMAPINFO structure is used for video streams and a WAVEFORMAT structure is used for audio streams.

Writing Data into an Existing Stream

The AVIStreamWrite function writes data into an existing stream in an AVI file. Your application can use this function to add new data to an AVI stream.

Writing Supplementary Information to AVI Files

If your application must write data in addition to the standard headers, formats, and audio or video data, it can use AVIFileWriteData and AVIStreamWriteData.

Use AVIFileWriteData to write data that applies to the entire file. This information can include information chunks.

Use AVIStreamWriteData to write data that applies to a specific stream. This information can include configuration data obtained from a compressor.

Closing Streams and AVI Files

When your application has finished writing a stream, it should close it with AVIStreamRelease. When your application has finished with an AVI file, it should close it with AVIFileRelease. Closing AVI streams and files flushes the buffers used and properly terminates the data chunks in the AVI file.


Positioning Within Streams

Positioning within streams is supported by the AVI read and write routines. The functions described in this section let your application find key frames, starting position, length, and time of a stream.


Finding Samples and Key Frames in a Stream

Your application can use AVIStreamFindSample to locate a sample, key frame, non-empty frame, or a format change in a stream. This function starts searching at the position specified and searches forward or backward (depending on the flags set) for the nearest sample of the type specified. When it finds the sample, it returns its position.

This function applies mostly to video streams for finding a non-empty frame, key frame, or format change.


Finding the Starting Position of a Stream

The AVIStreamStart function returns the sample (frame) number of the first sample in the stream. The frames of a movie might start at zero or one depending on the preference of the author. Get the number returned with AVIStreamStart and use the number with the read functions to access the first sample of data. Your application can also obtain the starting frame number from the AVISTREAMINFO structure returned by AVIStreamInfo.


Finding the Length of a Stream

Your application can use the AVIStreamLength, AVIStreamSampleToTime, and AVIStreamTimeToSample functions to obtain the length of a stream, convert between samples and time, and convert between time and samples.

The AVIStreamLength function returns the number of samples (or frames for video) in the stream. This value corresponds to the stream length value in the AVISTREAMINFO structure returned by AVIStreamInfo.

If you want to know the time length of a stream or a position within a stream, you can use AVIStreamSampleToTime to convert the number of samples to time in milliseconds. For a video frame, this corresponds to the time the frame appears when the AVI sequence is played at its normal speed. For an audio sample number, the value returned corresponds to the time the sample will be heard.

Conversely, if your application knows the video frame or audio sample that plays at a specific time in the sequence, it can use AVIStreamTimeToSample to obtain the sample number.

The AVIStreamSampleToTime and AVIStreamTimeToSample functions are not true inverses. For example, two consecutive samples of audio might both play in the same millisecond. Converting the time values of these consecutive samples to sample numbers can yield the same sample number. Because sample numbers provide a one-to-one correspondence to the samples, they more accurately determine the position in a file than time.


Preparing to Stream Data

Some AVI stream handlers might have delays associated with software and hardware initialization or coordination. The AVIStreamBeginStreaming and AVIStreamEndStreaming functions inform these handlers of the status of the streaming operation.

The AVIStreamBeginStreaming function informs a stream handler that it will be streaming data. This function lets the stream handler allocate the resources it needs and initialize them.

The AVIStreamEndStreaming function informs a stream handler that streaming operations have ended. This function lets the stream handler deallocate the resources it allocated for AVIStreamBeginStreaming.

Most stream handlers will ignore these functions.


Creating a Temporary Stream

The AVIStreamCreate function creates a stream that is not associated with any file. While most streams will be created with AVIMakeCompressedStream or CreateEditableStream, your application can create a temporary stream for use as a work stream. For example, it can use a temporary stream to convert one stream format into another. Alternatively, it can use the stream to extract portions of other streams and copy them into a common stream. When finished with this stream, your application should close it with AVIStreamClose.


Editing AVI Streams

The CreateEditableStream, EditStreamCut, EditStreamCopy, EditStreamPaste, EditStreamClone, and EditStreamSetName functions let an application manipulate streams during editing. The CreateEditableStream function initializes the environment for editing a stream. The function creates internal tables the other functions use during editing. The tables maintain all the changes for a stream  the source stream is never changed. The CreateEditableStream function returns a stream pointer to an editable stream. (The editable stream maintains the editing tables.) An editable stream pointer is required by other EditStream functions, and it can be used for other AVIFile functions that accept stream pointers.

The EditStreamCut, EditStreamCopy, and EditStreamPaste functions cut, copy, and paste stream data. They all require an editable stream as the source stream. The EditStreamClone function duplicates an editable stream. You can copy these streams to the Clipboard or use them to maintain a trail of edits made to a stream.

The EditStreamSetName function is used to edit the szName member of the AVISTREAMINFO structure.

Because the editing functions work on streams, you need to cut and paste each stream individually, and then use AVIMakeFileFromStreams to create a new stream pointer.


Putting AVI Files on the Clipboard

The AVIPutFileOnClipboard, AVIGetFromClipboard, and AVIClearClipboard functions let your application use the Clipboard with AVI files. They provide a convenient method of using the Clipboard to transfer AVI files to other applications. These functions work with the entire AVI file, however, and are not restricted to disk files.

If your application copies a file to the Clipboard and the stream data will continue to change, create a new file of cloned streams and place it on the Clipboard. Your application can create a memory file with AVIMakeFileFromStreams. After the file is placed on the Clipboard, it can release the file without invalidating it.

When your application ends, it should use AVIClearClipboard to clear the AVI file from the Clipboard. (Your application can use AVIClearClipboard even if it has not used AVIPutFileOnClipboard. It will not clear other information from the Clipboard.)


Previewing Files in the Open File Dialog Box

Your application can use GetOpenFileNamePreview and GetSaveFileNamePreview to let the user preview the first stream in an AVI file. These functions are similar to GetOpenFileName. In addition to displaying the Open File and Save As dialog boxes, the function displays a small preview window for displaying the movie.


AVIFile Macros

There are a number of macros available that use the AVIFile functions to make it easier for you to perform common tasks. The following list summarizes these macros:

AVIStreamSampleToSample(pavi1, pavi2, lSample)

Returns the sample in the stream specified by pavi1 that occurs at the same time as the sample specified in lSample occurs in the stream specified by pavi2.

AVIStreamNextSampleTime(pavi, time)

Returns the time that the sample occurring at the time specified by time will change to the next sample. Basically, this macro informs you of the next interesting time in the stream.

AVIStreamPrevSampleTime(pavi, time)

Returns the time corresponding to the sample just prior to the sample occurring at the time specified by time.

AVIStreamNextKeyFrameTime(pavi, t)

Returns the time of the next key frame in the stream, starting at a given time specified by t.

AVIStreamPrevKeyFrameTime(pavi, time)

Returns the time of the key frame that precedes the time specified by time.

AVIStreamStartTime(pavi)

Returns the starting time of the stream's first sample.

AVIStreamLengthTime(pavi)

Returns the length of the stream in time.

AVIStreamEnd(pavi)

Returns the sample number associated with the end of the stream. This sample number is not a valid sample number for reading data. It represents the end of the file. (The end position is equal to the start of the file plus its length.)

AVIStreamEndTime(pavi)

Returns the time representing the end of the stream.

AVIStreamSampleSize(pavi, lPos, plSize)

Returns the size of the buffer needed to store one sample of information from this stream in plsize. The size corresponds to the sample at the position specified by lPos.

AVIStreamFormatSize(pavi, lPos, plSize)

Uses plSize to return the size of the buffer needed to store the format information for the sample at the position specified by lPos.

AVIStreamNextSample(pavi, lPos)

Returns the non-empty sample following the position specified by lPos. The sample returned will not include lpos.

AVIStreamPrevSample(pavi, lPos)

Returns the non-empty sample preceding the position specified by lPos. The sample returned will not include lpos.

AVIStreamNearestSample(pavi, lPos)

Returns the non-empty sample at or prior to the position specified by lPos.

AVIStreamNextKeyFrame(pavi, lPos)

Returns the key frame following the position specified by lPos.

AVIStreamPrevKeyFrame(pavi, lPos)

Returns the key frame preceding the position specified by lPos.

AVIStreamNearestKeyFrame(pavi, lPos)

Returns the key frame at or prior to the position specified by lPos.

AVIStreamNearestSampleTime(pavi, time)

Returns the sample nearest to the position specified by time.

AVIStreamNearestKeyFrameTime(pavi, time)

Returns the key frame nearest to the position specified by time.

AVIStreamDataSize(pavi, fcc, plSize)

Returns the size of data contained in the stream with a four-character code specified by fcc. The size of data is returned in the location specified by the pointer plSize.


Using AVI Files

The following sections provide information about using AVIFile.


Opening an AVI File: An Example

The following fragment opens an AVI file and passes the file-interface pointer to an internal function:

//szFile specifies the file to open

hr = AVIFileOpen(&pfile, szFile, OF_SHARE_DENY_WRITE, 0L);

if (hr != 0)

{

    ErrMsg("Unable to open %s", szFile);

    return;

}

InsertAVIFile(pfile, hwnd, szFile);


Opening Streams in an AVI File and Closing the File

The following example opens all the streams in an AVI file. If an error is encountered, the file is closed.

// pfile is the file-interface pointer obtained from AVIFileOpen

void InsertAVIFile(PAVIFILE pfile, HWND hwnd, LPSTR lpszFile)

{

    int    i;

    // Open the streams until stream not available

    for (i = gcpavi; i < MAXNUMSTREAMS; i++) {

        gapavi[i] = NULL;

        if (AVIFileGetStream(pfile, &gapavi[i], 0L, i - gcpavi)

            != AVIERR_OK)

        break;

    if (gapavi[i] == NULL)

        break;

    }

    // Display error message-stream not found

    if (gcpavi == i)

    {

        ErrMsg("Unable to open %s", lpszFile);

    if (pfile) // If file is open, close it

        AVIFileClose(pfile);

        return;

    }

// Functions to process data deleted

}


Obtaining Stream Information from an AVI File

The following fragment obtains stream information from an AVI file and determines the stream type:

void FixScrollbars(HWND hwnd)

{

    AVISTREAMINFO     avis;

    LONG    r, lHeight = 0;

    WORD    w;

    int     i;

    RECT    rc;

    // Walk through all streams    for (i = 0; i < gcpavi; i++) {

        AVIStreamInfo(gapavi[i], &avis, sizeof(avis));

        if (avis.fccType == streamtypeVIDEO) {

        ,

        .

        .

        } else if (avis.fccType == streamtypeAUDIO) {

        .

        .

        .

        } else if (avis.fccType == streamtypeTEXT) {

        .

        .

        .

        }

    .

    .

    .

    }

}


Reading Data from One Stream into Another

The following fragment reads data from a stream, compresses it into a new stream, and writes the compressed data into a stream of a new file:

void SaveSmall(PAVISTREAM ps, LPSTR lpFilename)

{

    PAVIFILE         pf;

    PAVISTREAM       psSmall;

    HRESULT          hr;

    AVISTREAMINFO    strhdr;

    BITMAPINFOHEADER bi;

    BITMAPINFOHEADER biNew;

    LONG             l;

    LPVOID           lpOld;

    LPVOID           lpNew;

    // Determine the size of the format data

    AVIStreamFormatSize(ps, 0, &l);

    if (l > sizeof(bi)) // Format larger than space allocated?

return;

    l = sizeof(bi);

    hr = AVIStreamReadFormat(ps, 0, &bi, &l); // Read the format

    if (bi.biCompression != BI_RGB) // Wrong compression format?

return;

    hr = AVIStreamInfo(ps, &strhdr, sizeof(strhdr));

    // Create new AVI file

    hr = AVIFileOpen(&pf, lpFilename, OF_WRITE | OF_CREATE, NULL);

    if (hr != 0)

    return;

    // Set parameters for the new stream

    biNew = bi;

    biNew.biWidth /= 2;

    biNew.biHeight /= 2;

    biNew.biSizeImage = ((((UINT)biNew.biBitCount * biNew.biWidth

                        + 31)&~31) / 8) * biNew.biHeight;

    SetRect(&strhdr.rcFrame, 0, 0, (int) biNew.biWidth,

            (int) biNew.biHeight);

    // Create a stream

    hr = AVIFileCreateStream(pf, &psSmall, &strhdr);

    if (hr != 0) { //Stream created OK? If not close file.

    AVIFileClose(pf);

    return;

    }

    // Set format of new stream

    hr = AVIStreamSetFormat(psSmall, 0, &biNew, sizeof(biNew));

    if (hr != 0) {

    AVIStreamClose(psSmall);

    AVIFileClose(pf);

    return;

    }

    // Allocate memory for the bitmaps

    lpOld = GlobalAllocPtr(GMEM_MOVEABLE, bi.biSizeImage);

    lpNew = GlobalAllocPtr(GMEM_MOVEABLE, biNew.biSizeImage);

    // Read the stream data

    for (l = AVIStreamStart(ps); l < AVIStreamEnd(ps); l++) {

    hr = AVIStreamRead(ps, l, 1, lpOld, bi.biSizeImage, NULL, NULL);

    // error check

    // Compress the data

    CrunchDIB(&bi, lpOld, &biNew, lpNew);

    // Save the compressed data

    hr = AVIStreamWrite(psSmall, l, 1, lpNew, biNew.biSizeImage,

                        AVIIF_KEYFRAME, NULL, NULL);

    // error check

    }

     // Close the stream and file

    AVIStreamClose(psSmall);

    AVIFileClose(pf);

}


Specifying a File or Stream Handler Using MCI String Commands: An Example

The following example builds an MCI string command to open and play a file using a file handler:

// gpfile is a file-interface pointer

char ach[80];

HWND hwndMci = MCIWndCreate(NULL, ghInstApp,

        MCIWNDF_SHOWNAME | MCIWNDF_SHOWMODE |

        WS_OVERLAPPEDWINDOW | WS_VISIBLE,

        NULL);

if (hwndMci) {

        wsprintf(ach, "AVIVideo!@%ld", gpfile);

    MCIWndOpen(hwndMci, ach, 0);

    MCIWndPlay(hwndMci);

}


Using the Editing Functions and Putting a File on the Clipboard

The following fragment cuts, copies, or deletes segments from an array of streams. The cut and copied streams are merged into a new file and placed on the Clipboard.

// The source streams are specified in the gapavi array

// The destination streams are specified in the gapaviSel array

// The editable streams in gapaviSel have been previously initialized

// with CreateEditableStream

// The start and length positions used for editing each stream

// are specified in the galSelStart and galSelLen arrays

case MENU_CUT:

case MENU_COPY:

case MENU_DELETE:

{

    PAVIFILE pf;

    int      i;

    // Walk list of selections and make streams out of each section

    gcpaviSel = 0; //Index counter for destination streams

    for (i = 0; i < gcpavi; i++) {

    if (galSelStart[i] != -1) {

        if (wParam == MENU_COPY)

            EditStreamCopy(gapavi[i], &galSelStart[i],

            &galSelLen[i], &gapaviSel[gcpaviSel++]);

        else {

            EditStreamCut(gapavi[i], &galSelStart[i],

            &galSelLen[i], &gapaviSel[gcpaviSel++]);

        }

    }

    }

.

.

.

    // Put on the Clipboard if segment is not deleted

    if (gcpaviSel && wParam != MENU_DELETE) {

    PAVISTREAM   gapaviTemp[MAXNUMSTREAMS];

    int i;

    // Clone the edited streams, so that if the user does

    // more editing, the Clipboard won't change.

    for (i = 0; i < gcpaviSel; i++) {

        gapaviTemp[i] = NULL;

        EditStreamClone(gapaviSel[i], &gapaviTemp[i]);

        // Error check

    }

        // Create a file from the streams and put on Clipboard

        AVIMakeFileFromStreams(&pf, gcpaviSel, gapaviTemp);

        AVIPutFileOnClipboard(pf);

        // Release clone streams

        for (i = 0; i < gcpaviSel; i++) {

            AVIStreamRelease(gapaviTemp[i]);

        }

        // Release file put on Clipboard

        AVIFileRelease(pf);

    }

    // Release streams created

    for (i = 0; i < gcpaviSel; i++)

    AVIStreamRelease(gapaviSel[i]);

.

.

.

}


Initializing the AVICOMPRESSOPTIONS Structure

The following example shows the initialization of the AVICOMPRESSOPTIONS structure for audio and video streams:

void InitStreams(HWND hwnd)

{

    AVISTREAMINFO avis;

    LONG    lTemp;

    int     i;

    WORD    w;

    // Initialize times

    timeStart = 0x7FFFFFFF;

    timeEnd   = 0;

    // Walk through and initialize loaded streams

    for (i = 0; i < gcpavi; i++) {

        AVIStreamInfo(gapavi[i], &avis, sizeof(avis));

    // Save and SaveOptions code takes a pointer to our compression opts

    galpAVIOptions[i] = &gaAVIOptions[i];

    // clear options structure

    _fmemset(galpAVIOptions[i], 0, sizeof(AVICOMPRESSOPTIONS));

     // Initialize the compression options to default

    galpAVIOptions[i]->fccType = avis.fccType;

    switch(avis.fccType) {

        case streamtypeVIDEO:

            galpAVIOptions[i]->dwFlags = AVICOMPRESSF_VALID |

                AVICOMPRESSF_KEYFRAMES | AVICOMPRESSF_DATARATE;

            galpAVIOptions[i]->fccHandler = NULL;

            galpAVIOptions[i]->dwQuality = (DWORD)ICQUALITY_DEFAULT;

            galpAVIOptions[i]->dwKeyFrameEvery = 7;

            galpAVIOptions[i]->dwBytesPerSecond = 60000;

            break;

        case streamtypeAUDIO:

            galpAVIOptions[i]->dwFlags |= AVICOMPRESSF_VALID;

            galpAVIOptions[i]->dwInterleaveEvery = 5;

            AVIStreamReadFormat(gapavi[i], AVIStreamStart(gapavi[i]),

                        NULL, &lTemp);

            galpAVIOptions[i]->cbFormat = lTemp;

            if (lTemp)

                galpAVIOptions[i]->lpFormat

                    = GlobalAllocPtr(GHND, lTemp);

            // Use current format as default format

            if (galpAVIOptions[i]->lpFormat)

                AVIStreamReadFormat(gapavi[i],

                        AVIStreamStart(gapavi[i]),

                        galpAVIOptions[i]->lpFormat,

                        &lTemp);

            break;

        default:

        break;

    }

.

.

.

}


Reference

This section is an alphabetic reference to the functions provided by Windows for applications using the AVIFile services.

For information about	See these functions and structures
Initializing the AVIFile library	AVIFileInit AVIFileExit
Opening AVI files	AVIFileOpen
Opening streams	AVIFileGetStream
Opening an AVI file and stream simultaneously	AVIStreamOpenFromFile
Incrementing the reference count of a stream or AVI file	AVIFileAddRef AVIStreamAddRef
Closing a stream	AVIStreamRelease
Closing an AVI file	AVIFileRelease
Reading the AVI file header	AVIFileInfo AVIFILEINFO
Reading a stream header	AVIStreamInfo AVISTREAMINFO
Reading the format for stream data	AVIStreamReadFormat
Reading optional stream header information	AVIStreamReadData
Reading the audio and video data from a stream	AVIStreamRead
Reading supplementary AVI file information	AVIFileReadData
Decompressing data in a stream	AVIStreamGetFrame AVIStreamGetFrameClose AVIStreamGetFrameOpen
Creating a stream	AVIFileCreateStream AVIStreamSetFormat
Writing data into an existing stream	AVIStreamWrite
Writing supplementary information to AVI files	AVIFileWriteData AVIStreamWriteData
Using AVISave to copy existing streams to a new file	AVISave AVISaveV AVISaveOptions AVISaveOptionsFree AVICOMPRESSOPTIONS
Finding samples	AVIStreamFindSample
Finding the starting position of a stream	AVIStreamStart
Finding the length of a stream	AVIStreamLength AVIStreamSampleToTime AVIStreamTimeToSample
Preparing to stream data	AVIStreamBeginStreaming AVIStreamEndStreaming
Creating a temporary stream	AVIStreamCreate
Editing AVI Streams	CreateEditableStream EditStreamClone EditStreamCopy EditStreamCut EditStreamSetName EditStreamPaste EditStreamSetInfo AVIMakeFileFromStreams
Mark end of record	AVIFileEndRecord
Putting AVI files on the Clipboard	AVIClearClipboard AVIGetFromClipboard AVIPutFileOnClipboard AVIMakeStreamFromClipboard
Make a compressed stream	AVIMakeCompressedStream
Previewing streams	GetOpenFileNamePreview GetSaveFileNamePreview AVIBuildFilter


AVIBuildFilter

HRESULT AVIBuildFilter(LPSTR lpszFilter, LONG cbFilter, BOOL fSaving)

Builds a filter specification for passing to GetOpenFileName or GetSaveFileName.

•	Returns AVIERR_OK on success.

lpszFilter

Specifies a pointer to buffer where the filter string should be returned.

cbFilter

Size of buffer pointed to by lpszFilter.

fSaving

Indicates whether the filter should include only formats that can be written, or all formats that can be read.

This function does not check if the DLLs referred to in the registration database actually exist.


AVIClearClipboard

STDAPI AVIClearClipboard()

Clears an AVI file from the Clipboard. Use this function before ending your application to clear the contents of the Clipboard.

•	Returns zero if successful; otherwise, it returns an error code.


AVICOMPRESSOPTIONS

This structure contains information about a stream and how it is to be compressed and saved. This structure passes data to AVIMakeCompressedStream (or AVISave which uses AVIMakeCompressedStream).

typedef struct {

DWORD fccType;

DWORD fccHandler;

DWORD dwKeyFrameEvery;

DWORD dwQuality;

DWORD dwBytesPerSecond;

DWORD dwFlags;

LPVOID lpFormat;

DWORD cbFormat;

LPVOID lpParms;

DWORD cbParms;

DWORD dwInterleaveEvery;

} AVICOMPRESSOPTIONS;

fccType

Specifies a four-character code indicating the stream type. The following constants have been defined for the data commonly found in AVI streams:

streamtypeAUDIO

Indicates an audio stream.

streamtypeMIDI

Indicates a MIDI stream.

streamtypeTEXT

Indicates a text stream.

streamtypeVIDEO

Indicates a video stream.

fccHandler

For a video stream, specifies the four-character code for the compressor handler that will compress this stream when it is saved (for example, mmioFOURCC('M','S','V','C')). This member is not used for audio streams.

dwKeyFrameEvery

Specifies the maximum period between key frames. This member is used only if the AVICOMPRESSF_KEYFRAMES flag is set; otherwise, every frame is a key frame.

dwQuality

Specifies the quality value passed to a video compressor. This member is not used for an audio compressor.

dwBytesPerSecond

Specifies the data rate a video compressor should use. This member is used only if the AVICOMPRESSF_DATARATE flag is set.

dwFlags

Specifies the flags used for compression:

AVICOMPRESSF_INTERLEAVE

Indicates this stream is to be interleaved every dwInterleaveEvery frames with respect to the first stream.

AVICOMPRESSF_KEYFRAMES

Indicates this video stream is to be saved with key frames at least every dwKeyFrameEvery frames. By default, every frame will be a key frame.

AVICOMPRESSF_DATARATE

Indicates this video stream is to be compressed with the data rate specified in dwBytesPerSecond.

AVICOMPRESSF_VALID

Indicates this structure contains valid data. If this flag is set, AVIFile uses the structure data to set the default compression values for AVISaveOptions. If an empty structure is passed and this flag is not set, some defaults will be chosen.

lpFormat

Specifies a pointer to a structure defining the data format. For an audio stream, this is an LPWAVEFORMAT structure.

cbFormat

Specifies the size of the data referenced by lpFormat

lpParms

Used internally to store compressor-specific data.

cbParms

Specifies the size of the data referred to by lpParms

dwInterleaveEvery

Specifies how often to interleave stream data with the data from the first stream. Used only if the AVICOMPRESSF_INTERLEAVE flag is set.


AVIFileAddRef

LONG AVIFileAddRef(PAVIFILE pfile)

Increases the reference count of an AVI file.

•	Returns zero if successful; otherwise, it returns an error code.

pfile

Specifies the handle for an open AVI file.

Balance each call to AVIFileAddRef with a call to AVIFileRelease.


AVIFileCreateStream

LONG AVIFileCreateStream(PAVIFILE pfile, PAVISTREAM FAR * ppavi, AVISTREAMINFO FAR * psi)

Creates a new stream in an existing file, and returns a stream-interface pointer for it.

•	Returns zero if successful; otherwise, it returns an error code.

pfile

Specifies a handle to an open AVI file.

ppavi

Specifies a pointer used to return the new stream-interface pointer.

psi

Specifies a pointer to a structure containing information about the new stream. This structure contains the type of the new stream and its sample rate.

Balance each call to AVIFileCreateStream with a call to AVIStreamRelease using the returned stream handle.

This function fails with a return value of AVIERR_READONLY unless the file was opened with write permission.

After creating the stream, call AVIStreamSetFormat before using AVIStreamWrite to write to the stream.


AVIFileEndRecord

LONG AVIFileEndRecord(PAVIFILE pfile)

Marks the end of a record, if writing out a strictly interleaved file.

•	Returns zero if successful; otherwise, it returns an error code.

pfile

Specifies a handle to a currently open AVI file.

AVISave uses this function when writing files that are have audio interleaved every frame. In general, applications should not need to use this function.


AVIFileExit

void AVIFileExit()

This function exits the AVIFile library.

Call this function after using any other AVIFile functions.


AVIFileGetStream

LONG AVIFileGetStream(PAVIFILE pfile, PAVISTREAM FAR * ppavi, DWORD fccType, LONG lParam)

Returns a pointer to a stream interface that is a component of a file.

•	Returns zero if successful; otherwise, it returns an error code. Possible error codes include:

AVIERR_NODATA

There is no stream in the file corresponding to the values passed in for fccType and lParam.

AVIERR_MEMORY

Not enough memory.

pfile

Specifies a handle to an open AVI file.

ppavi

Specifies a pointer to the return location for the new stream-interface pointer.

fccType

Specifies a four-character code indicating the type of stream to be opened. Zero indicates that any stream can be opened. The following definitions apply to the data commonly found in AVI streams:

streamtypeAUDIO

Indicates an audio stream.

streamtypeMIDI

Indicates a MIDI stream.

streamtypeTEXT

Indicates a text stream.

streamtypeVIDEO

Indicates a video stream.

lParam

Specifies an integer indicating which stream of the type defined by fccType should actually be accessed.

Balance each call to AVIFileGetStream with a call to AVIStreamRelease using the stream handle returned.


AVIFILEINFO

This structure contains global information for an entire AVI file. It is similar to, but not identical to MainAVIHeader found in AVI files.

typedef struct {

DWORD dwMaxBytesPerSec;

DWORD dwFlags;

DWORD dwCaps;

DWORD dwStreams;

DWORD dwSuggestedBufferSize;

DWORD dwWidth;

DWORD dwHeight;

DWORD dwScale;

DWORD dwRate;

DWORD dwLength;

DWORD dwEditCount;

char szFileType[64];

} AVIFILEINFO;

dwMaxBytesPerSec

Specifies the approximate maximum data rate of the file.

dwFlags

Specifies any applicable flags. The following flags are defined:

AVIF_HASINDEX

Indicates the AVI file has an index at the end of the file. For good performance, all AVI files should contain an index.

AVIF_MUSTUSEINDEX

Indicates that the index, rather than the physical ordering of the chunks of data in the file, should be used to determine the order of presentation of the data. For example, this could be used for creating a list of frames for editing.

AVIF_ISINTERLEAVED

Indicates the AVI file is interleaved.

AVIF_WASCAPTUREFILE

Indicates the AVI file is a specially allocated file used for capturing real-time video. Applications should warn the user before writing over a file with this flag set because the user probably defragmented this file.

AVIF_COPYRIGHTED

Indicates the AVI file contains copyrighted data and software. When this flag is used, software should not permit the data to be duplicated.

dwCaps

Specifies capability flags. This is currently unused.

dwStreams

Specifies the number of streams in the file. For example, a file with audio and video has two streams.

dwSuggestedBufferSize

Specifies the suggested buffer size for reading the file. Generally, this size should be large enough to contain the largest chunk in the file. If set to zero, or if it is too small, the playback software will have to reallocate memory during playback, which will reduce performance.

For an interleaved file, this buffer size should be large enough to read an entire record and not just a chunk.

dwWidth

Specifies the width of the AVI file in pixels.

dwHeight

Specifies the height of the AVI file in pixels.

dwScale

This member is used with dwRate to specify the time scale that the file as a whole will use. In addition, each stream can have its own time scale. Dividing dwRate by dwScale gives the number of samples per second.

dwRate

See dwScale.

dwLength

Specifies the length of the AVI file. The units are defined by dwRate and dwScale.

dwEditCount

Specifies the number of streams that have been added or deleted.

szFileType[64]

Specifies a zero-terminated string containing descriptive information for the file type.


AVIFileInfo

LONG AVIFileInfo(PAVIFILE pfile, AVIFILEINFO FAR * pfi, LONG lSize)

Obtains information about an AVI file.

•	Returns zero if successful; otherwise, it returns an error code.

pfile

Specifies a handle to an open AVI file.

pfi

Specifies a pointer to the structure used to return file information.

lSize

Specifies the size of the structure. This value should be at least sizeof(AVIFILEINFO).


AVIFileInit

void AVIFileInit()

This function initializes the AVIFILE library.

Call this function before using any other AVIFile functions.


AVIFileOpen

LONG AVIFileOpen(PAVIFILE FAR * ppfile, LPCSTR szFile, UINT mode, CLSID FAR * pclsidHandler)

Opens an AVI file and returns a file-interface pointer used to access it.

•	Returns zero if successful; otherwise, it returns an error code. Possible error returns include:

AVIERR_BADFORMAT

The file was corrupted or not in the proper format, and could not be read.

AVIERR_MEMORY

The file could not be opened because there was not enough memory.

AVIERR_FILEREAD

A disk error occurred while reading the file.

AVIERR_FILEOPEN

A disk error occurred while opening the file.

REGDB_E_CLASSNOTREG

No handler could be found to open this type of file.

ppfile

Specifies a pointer to the location used to return the new PAVIFILE file pointer.

szFile

Specifies a zero-terminated string containing the name of the file to open.

mode

Specifies the mode to use when opening the file. The following flags are defined.

OF_READ

Opens the file for reading only. This is the default, if OF_WRITE and OF_READWRITE are not specified.

OF_WRITE

Opens the file for writing. You should not read from a file opened in this mode.

OF_READWRITE

Opens the file for both reading and writing.

OF_CREATE

Creates a new file. If the file already exists, it is truncated to zero length.

OF_DENYWRITE

Opens the file and denies other processes write access to the file. AVIFileOpen fails if the file has been opened in compatibility or for write access by any other process.

OF_DENYREAD

Opens the file and denies other processes read access to the file. AVIFileOpen fails if the file has been opened in compatibility mode or for read access by any other process.

OF_DENYNONE

Opens the file without denying other processes read or write access to the file. AVIFileOpen fails if the file has been opened in compatibility mode by any other process.

OF_EXCLUSIVE

Opens the file and denies other processes any access to the file. AVIFileOpen will fail if any other process has opened the file.

pclsidHandler

Specifies a pointer to a class ID identifying the handler you want to use. If NULL, the system chooses one from the registration database based on the file extension or the file's RIFF type.

Be sure to call AVIFileInit at least once in your application before calling this function, and to balance each call to AVIFileInit with a call to AVIFileExit.


AVIFileReadData

LONG AVIFileReadData(PAVIFILE pfile, DWORD ckid, LPVOID lpData, LONG FAR * lpcbData)

Reads optional header data from the file.

•	Returns zero if successful; otherwise, it returns an error code. The return value AVIERR_NODATA indicates that data with the requested chunk ID does not exist.

pfile

Specifies a handle to an open AVI file.

ckid

Specifies a four-character code identifying the data.

lpData

Specifies a pointer to a buffer used to return the data read.

lpcbData

Specifies a pointer to a location indicating the size of the memory block referred to by lpData. If the read is successful, the value is changed to indicate the amount of data read.

Do not use this function to read video and audio data. Use it only to read additional information such as author information or copyright information that applies to the file as a whole. Information that applies to a single stream should be read using AVIStreamReadData.


AVIFileRelease

LONG AVIFileRelease(PAVIFILE pfile)

Reduces the reference count of an AVI file interface handle by one, and closes the file if the count reaches zero.

•	Returns the reference count of the file. This return value should be used only for debugging purposes.

pfile

Specifies a handle to an open AVI file.

Balance each call to AVIFileAddRef or AVIFileOpen with a call to AVIFileRelease.


AVIFileWriteData

LONG AVIFileWriteData(PAVIFILE pfile, DWORD ckid, LPVOID lpData, LONG cbData)

Writes some additional data to the file.

•	Returns zero if successful; otherwise, it returns an error code.

pfile

Specifies a handle to an open AVI file.

ckid

Specifies a four-character code identifying the data.

lpData

Specifies a pointer to the data to write.

cbData

Specifies the size of the memory block referred to by lpData.

This function fails with a return value of AVIERR_READONLY unless the file was opened with write permission.

Use AVIStreamWriteData instead of this function to write data that applies to an individual stream.


AVIGetFromClipboard

STDAPI AVIGetFromClipboard(PAVIFILE * lppf)

Copies an AVI file from the Clipboard.

•	Returns zero if successful; otherwise, it returns an error code.

lppf

Specifies the location used to return the handle created for the AVI file.

This function will also copy data with the CF_DIB or CF_WAVE Clipboard flags.


AVIMakeCompressedStream

HRESULT AVIMakeCompressedStream(PAVISTREAM FAR * ppsCompressed, PAVISTREAM psSource, AVICOMPRESSOPTIONS FAR * lpOptions, CLSID FAR * pclsidHandler)

Returns a pointer to a compressed stream created from an uncompressed stream. The uncompressed stream is compressed using the compression options specified.

•	Returns AVIERR_OK on success, or an error code. Possible errors include:

AVIERR_NOCOMPRESSOR

No suitable compressor can be found.

AVIERR_MEMORY

There was not enough memory to complete the operation.

AVIERR_UNSUPPORTED

Compression is not supported for this type of data. This error may be returned if you try to compress data that is not audio or video.

ppsCompressed

Specifies a pointer to the location used to return the compressed stream pointer.

psSource

Specifies a pointer to the stream to be compressed.

lpOptions

Specifies a pointer to a structure indicating the type of compression to use and the options to apply.

pclsidHandler

Specifies a pointer to a class ID used to create the stream.

This function supports both audio and video compression. Applications can use the created stream for reading or writing.

For video compression, either specify a handler to use or specify the format for the compressed data.

For audio compression, you can only specify a format for the compressed data.


AVIMakeFileFromStreams

HRESULT AVIMakeFileFromStreams(PAVIFILE FAR * ppfile, int nStreams, PAVISTREAM FAR * papStreams)

Constructs an AVIFile-interface pointer out of separate streams. If AVIFileGetStream is called with the returned file-interface pointer, it returns the specified streams.

•	Returns zero if successful; otherwise, it returns an error code.

ppfile

Specifies a pointer to the location used to return the new file-interface pointer.

nStreams

Specifies the number of streams in the array of stream-interface pointers referred to by papStreams.

papStreams

Specifies a pointer to an array of stream-interface pointers.

Use AVIFileRelease to close the file. This function is useful for putting streams onto the Clipboard.


AVIMakeStreamFromClipboard

STDAPI AVIMakeStreamFromClipboard(UINT cfFormat, HANDLE hGlobal, PAVISTREAM FAR * ppstream)

Creates a stream from a stream on the Clipboard.

•	Returns zero if successful; otherwise, it returns an error code.

cfFormat

Specifies a Clipboard flag.

hGlobal

Specifies a handle to an open stream.

ppstream

Specifies a handle to an open stream.


AVIPutFileOnClipboard

STDAPI AVIPutFileOnClipboard(PAVIFILE pf)

Copies an AVI file onto the Clipboard.

•	Returns zero if successful; otherwise, it returns an error code.

pf

Specifies a handle to an open AVI file.

This function will also copy data with the CF_DIB and CF_WAVE Clipboard flags onto the Clipboard.


AVISave

LONG AVISave(LPCSTR szFile, CLSID FAR * pclsidHandler, AVISAVECALLBACK lpfnCallback, int nStreams, PAVISTREAM pavi, LPAVICOMPRESSOPTIONS lpOptions, . . .)

This function is used to save an AVI file.

•	Returns AVIERR_OK if successful; otherwise, it returns an error code.

zFile

Specifies a zero-terminated string containing the name of the file to save.

pclsidHandler

Specifies a pointer to the file handler used to write the file. The file will be created by calling AVIFileOpen using this handler. If a handler is not specified, a default handler is selected based upon the file extension.

lpfnCallback

Specifies a pointer to a callback function for the save operation.

nStreams

Specifies the number of streams saved in the file.

pavi

Specifies a pointer an AVI stream. This parameter is paired with lpOptions. The parameter pair can be repeated as a variable number of arguments.

lpOptions

Specifies a pointer to an AVICOMPRESSOPTIONS structure containing the compression options for the stream referred to by pavi. This parameter is paired with pavi. The parameter pair can be repeated as a variable number of arguments.

Additional streams can be opened by including more pavi and lpOptions parameter pairs.

This function saves an AVI sequence to the file specified by szFile. The pavi and lpOptions parameters define the streams saved. If saving more than one stream, repeat the pavi and lpOptions parameter pair for each additional stream.

A callback function can be supplied in lpfnCallback to display status information and let the user cancel the save operation. The callback uses the following format:

LONG FAR PASCAL SaveCallback(int nPercent)

The nPercent parameter specifies the percentage of the file saved.

The callback function should return AVIERR_OK if the operation should continue and AVIERR_USERABORT if the user wants to end the save operation.


AVISaveOptions

BOOL AVISaveOptions(HWND hwnd, UINT uiFlags, int nStreams, PAVISTREAM FAR * ppavi, LPAVICOMPRESSOPTIONS FAR * plpOptions)

This function gets the save options for a file and returns them in a buffer.

•	Returns TRUE if the user pressed OK, FALSE for CANCEL or an error.

hwnd

Specifies the parent window handle for the Compression Options dialog box.

uiFlags

Specifies the flags for displaying the Compression Options dialog box. The following flags are defined:

ICMF_CHOOSE_KEYFRAME

Displays a Key frame every dialog box for the video options. This is the same flag used in ICCompressorChoose.

ICMF_CHOOSE_DATARATE

Displays a Data rate dialog box for the video options. This is the same flag used in ICCompressorChoose.

ICMF_CHOOSE_PREVIEW

Displays a Preview button for the video options. This button is used to preview the compression using a frame from the stream. This is the same flag used in ICCompressorChoose.

nStreams

Specifies the number of streams that will have their options set by the dialog box.

ppavi

Specifies a pointer to an array of stream-interface pointers. The nStreams parameter indicates the number of pointers in the array.

plpOptions

Specifies a pointer to an array of LPAVICOMPRESSOPTIONS pointers to hold the compression options set by the dialog box. The nStreams parameter indicates the number of pointers in the array.

This function presents a standard Compression Options dialog box using hwnd as the parent window handle. When the user is finished selecting the compression options for each stream, the options are returned in the AVICOMPRESSOPTIONS structures in the array referred to by lpOptions. The caller must pass the interface pointers for the streams in the array referred to by ppavi.


AVISaveOptionsFree

LONG AVISaveOptionsFree(int nStreams, LPAVICOMPRESSOPTIONS FAR * plpOptions)

This function frees the resources allocated by AVISaveOptions.

•	This function always returns AVIERR_OK (zero)

nStreams

Specifies the number of AVICOMPRESSOPTIONS structures in the array passed in as the next parameter.

plpOptions

Specifies a pointer to an array of LPAVICOMPRESSOPTIONS pointers to hold the compression options set by the dialog box. The resources in each of these structures that were allocated by AVISaveOptions will be freed.

This function frees the resources allocated by AVISaveOptions.


AVISaveV

LONG AVISaveV(LPCSTR szFile, CLSID FAR * pclsidHandler, AVISAVECALLBACK lpfnCallback, int nStreams, PAVISTREAM FAR * ppavi, LPAVICOMPRESSOPTIONS FAR * plpOptions)

This function is used to save an AVI file.

•	Returns AVIERR_OK on success; otherwise it returns an error code.

szFile

Specifies a zero-terminated string containing the name of the file to save.

pclsidHandler

Specifies a pointer to the file handler used to write the file. The file will be created by calling AVIFileOpen using this handler. If a handler is not specified, a default handler is selected based upon the file extension.

lpfnCallback

Specifies a pointer to a callback function used to display status information and let the user cancel the save operation.

nStreams

Specifies the number of streams to save.

ppavi

Specifies a pointer to an array of PAVISTREAM pointers. The array uses one pointer for each stream.

plpOptions

Specifies a pointer to an array of LPAVICOMPRESSOPTIONS pointers. The array uses one pointer for each stream.

This function is equivalent to AVISave except the streams are passed in an array instead of as a variable number of arguments. (AVISaveV is to AVISave as wvsprintf is to wsprintf.)


AVIStreamAddRef

LONG AVIStreamAddRef(PAVISTREAM pavi)

Increases the reference count of an AVI stream.

•	Returns the current reference count of the stream. This value should only be used for debugging purposes.

pavi

Specifies a handle to an open AVI stream.

Balance each call to AVIStreamAddRef with a call to AVIStreamRelease.


AVIStreamBeginStreaming

LONG AVIStreamBeginStreaming(PAVISTREAM pavi, LONG lStart, LONG lEnd, LONG lRate)

Specifies the parameters for streaming and lets a stream handler prepare for streaming.

•	Returns zero if successful; otherwise, it returns an error code.

pavi

Specifies a pointer to a stream.

lStart

Specifies the starting point for streaming.

lEnd

Specifies the ending point for streaming.

lRate

Specifies the speed at which the file will be read relative to its natural speed. Specify 1000 for the normal speed.

Many stream implementations ignore this function.


AVIStreamCreate

LONG AVIStreamCreate(PAVISTREAM FAR * ppavi, LONG lParam1, LONG lParam2, CLSID FAR * pclsidHandler)

Creates a stream not associated with any file.

•	Returns zero if successful; otherwise, it returns an error code.

ppavi

Specifies a pointer to a location to return the new stream handle.

lParam1

Specifies stream-handler-specific information.

lParam2

Specifies stream-handler-specific information.

pclsidHandler

Specifies a pointer to the class ID used for the stream.

Balance each call to AVIStreamCreate with a call to AVIStreamRelease.

You should not need to call this function; functions like CreateEditableStream and AVIMakeCompressedStream use it internally.


AVIStreamEndStreaming

LONG AVIStreamEndStreaming(PAVISTREAM pavi)

Ends streaming.

•	Returns zero if successful; otherwise, it returns an error code.

pavi

Specifies a pointer to a stream.

Many stream implementations ignore this function.


AVIStreamFindSample

LONG AVIStreamFindSample(PAVISTREAM pavi, LONG lPos, LONG lFlags)

Returns the position of a key frame or non-empty frame relative to the specified position.

•	Returns the position found. In many boundary cases, this function will return 1; see the example above for details.

pavi

Specifies a handle to an open stream.

lPos

Specifies the starting position for the search.

lFlags

The following flags are defined:

FIND_KEY

Finds a key frame.

FIND_ANY

Finds a non-empty sample.

FIND_FORMAT

Finds a format change.

FIND_NEXT

Finds the nearest sample, frame, or format change searching forward. The current sample is included in the search. Use this flag with the FIND_ANY, FIND_KEY, or FIND_FORMAT flag.

FIND_PREV

Finds the nearest sample, frame, or format change searching backward. The current sample is included in the search. Use this flag with the FIND_ANY, FIND_KEY, or FIND_FORMAT flag.

The FIND_KEY, FIND_ANY, and FIND_FORMAT flags are mutually exclusive. The FIND_NEXT and FIND_PREV flags are also mutually exclusive. For example:

Flags	Description
FIND_PREV|FIND_KEY	Returns the first key sample prior to or at lPos.
FIND_PREV|FIND_ANY	Returns the first non-empty sample prior to or at lPos.
FIND_NEXT|FIND_KEY	Returns the first key sample after <p lPos>, or −1 if a key sample does not follow lPos.
FIND_NEXT|FIND_ANY	Returns the first non-empty sample after lPos, or −1 if a sample does not exist after lPos.
FIND_NEXT|FIND_FORMAT	Returns the first format change after or at lPos, or −1 if the stream does not have format changes.
FIND_PREV|FIND_FORMAT	Returns the first format change prior to or at lPos. If the stream does not have format changes, it returns the first sample.


AVIStreamGetFrame

LPVOID AVIStreamGetFrame(PGETFRAME pgf, LONG lPos)

This function returns a pointer to a decompressed frame of video.

•	Returns NULL on error; otherwise, it returns a pointer to the frame data. The returned data is a packed DIB.

pgf

Specifies a pointer to a GetFrame object.

lPos

Specifies the position of a desired frame in samples.

The returned frame is valid only until the next call to AVIStreamGetFrame or AVIStreamGetFrameClose.


AVIStreamGetFrameClose

LONG AVIStreamGetFrameClose(PGETFRAME pget)

This function releases resources used to decompress video frames.

•	Returns an error code.

pget

Specifies a handle returned from AVIStreamGetFrameOpen. After calling this function, the handle is invalid.


AVIStreamGetFrameOpen

PGETFRAME AVIStreamGetFrameOpen(PAVISTREAM pavi, LPBITMAPINFOHEADER lpbiWanted)

This function prepares to decompress video frames from the stream specified.

•	Returns a GetFrame object, which can be used with AVIStreamGetFrame.

If the system can't find a decompressor that can decompress the stream to the format given, or to any RGB format, the function returns NULL.

pavi

Specifies a pointer to the stream used as the video source.

lpbiWanted

Specifies a pointer to a structure defining the desired video format. If this is NULL, a default format is used.

The pavi parameter must specify a video stream.

This function is essentially just a helper function to handle a simple form of decompression.


AVIStreamInfo

LONG AVIStreamInfo(PAVISTREAM pavi, AVISTREAMINFO FAR * psi, LONG lSize)

Obtains stream header information.

•	Returns zero if successful; otherwise, it returns an error code.

pavi

Specifies a handle to an open stream.

psi

Specifies a pointer to a structure used to return stream information.

lSize

Specifies the size of the structure used for psi.


AVISTREAMINFO

This structure contains information for a single stream. It is similar, but not identical, to AVIStreamHeader found in AVI files.

typedef struct {

DWORD fccType;

DWORD fccHandler;

DWORD dwFlags;

DWORD dwCaps;

WORD wPriority;

WORD wLanguage;

DWORD dwScale;

DWORD dwRate;

DWORD dwStart;

DWORD dwLength;

DWORD dwInitialFrames;

DWORD dwSuggestedBufferSize;

DWORD dwQuality;

DWORD dwSampleSize;

RECT rcFrame;

DWORD dwEditCount;

DWORD dwFormatChangeCount;

char szName[64];

} AVISTREAMINFO;

fccType

Specifies a four-character code indicating the stream type. The following constants have been defined for the data commonly found in AVI streams:

streamtypeAUDIO

Indicates an audio stream.

streamtypeMIDI

Indicates a MIDI stream.

streamtypeTEXT

Indicates a text stream.

streamtypeVIDEO

Indicates a video stream.

fccHandler

For a video stream, specifies the four-character code of the compressor handler that will compress this stream when it is saved (for example, mmioFOURCC('M','S','V','C')). This member is not used for audio streams.

dwFlags

Specifies any applicable flags. The bits in the high-order word of these flags are specific to the type of data contained in the stream. The following flags are defined:

AVISF_DISABLED

Indicates this stream should not be enabled by default.

AVISF_VIDEO_PALCHANGES

Indicates this video stream contains palette changes. This flag warns the playback software that it will need to animate the palette.

dwCaps

Specifies capability flags. This is currently unused.

wPriority

Specifies the priority of the stream.

wLanguage

Specifies the language of the stream.

dwScale

This member is used with dwRate to specify the time scale this stream will use. Dividing dwRate by dwScale gives the number of samples per second. For video streams, this rate should be the frame rate. For audio streams, this rate should correspond to the time needed for nBlockAlign bytes of audio, which for PCM audio simply reduces to the sample rate.

dwRate

See dwScale.

dwStart

Specifies the starting time of the AVI file. The units are defined by the dwRate and dwScale members of this structure. Usually, this is zero, but it can specify a delay time for a stream that does not start concurrently with the file. Note that the version 1.0 release of the AVI tools does not support a non-zero starting time.

dwLength

Specifies the length of this stream. The units are defined by the dwRate and dwScale members of this structure.

dwInitialFrames

Specifies how far audio data is skewed ahead of the video frames in interleaved files. Typically, this is about 0.75 seconds.

dwSuggestedBufferSize

Suggests how large a buffer should be used to read this stream. Typically, this contains a value corresponding to the largest chunk present in the stream. Using the correct buffer size makes playback more efficient. Use zero if you do not know the correct buffer size.

dwQuality

Specifies an indicator of the quality of the data in the stream. Quality is represented as a number between 0 and 10000. For compressed data, this typically represents the value of the quality parameter passed to the compression software. If set to −1, drivers use the default quality value.

dwSampleSize

Specifies the size of a single sample of data. This is set to zero if the samples can vary in size. If this number is non-zero, then multiple samples of data can be grouped into a single chunk within the file. If it is zero, each sample of data (such as a video frame) must be in a separate chunk.

For video streams, this number is typically zero, although it can be non-zero if all video frames are the same size. For audio streams, this number should be the same as the nBlockAlign member of the WAVEFORMAT structure describing the audio.

rcFrame

Specifies the dimensions of the destination rectangle for the video. The coordinates represent the upper-left corner, the height, and the width.

dwEditCount

Specifies the number of times the stream has been edited. The stream handler maintains this count.

dwFormatChangeCount

Specifies the number of times the stream format has changed. The stream handler maintains this count.

szName[64]

Specifies a zero-terminated string containing a description of the stream.


AVIStreamLength

LONG AVIStreamLength(PAVISTREAM pavi)

Returns the length of the stream in samples.

•	Returns the stream's length in samples, or −1 on error.

pavi

Specifies a handle to an open stream.

Values in samples can be converted to milliseconds using the AVIStreamSampleToTime function.

For video streams, each sample generally corresponds to a frame of video. There may, however, be sample numbers for which no video data is present: If AVIStreamRead is called at those positions, it will return a data length of zero bytes. You can use AVIStreamFindSample with the FIND_ANY flag to find sample numbers which have data.

For audio streams, each sample corresponds to one data block of audio data. For example, if the audio data has a 22 kHz ADPCM format, each sample for AVIStreamLength corresponds to block of audio data of 256 bytes (uncompressed, this corresponds to about 500 audio samples that can be played at the 22 kHz audio rate). From the point of view of the AVIFile APIs, however, each 256-byte block is a single sample.

The starting position for a stream might not be zero. Use AVIStreamStart to obtain the starting position. Valid positions within a stream range from start of the stream to the start of the stream plus its length. There is no actual data present at the start position plus the length. It corresponds to a time after the last data has been rendered.


AVIStreamOpenFromFile

LONG AVIStreamOpenFromFile(PAVISTREAM FAR * ppavi, LPCSTR szFile, DWORD fccType, LONG lParam, UINT mode, CLSID FAR * pclsidHandler)

This function provides a convenient way to open a single stream from a file.

•	Returns zero if successful; otherwise, it returns an error code.

ppavi

Specifies a pointer to the location used to return the new stream handle.

szFile

Specifies a zero-terminated string containing the name of the file to open.

fccType

Specifies a four-character code indicating the type of stream to be opened. Zero indicates that any stream can be opened. The following definitions apply to the data commonly found in AVI streams:

streamtypeAUDIO

Indicates an audio stream.

streamtypeMIDI

Indicates a MIDI stream.

streamtypeTEXT

Indicates a text stream.

streamtypeVIDEO

Indicates a video stream.

lParam

Indicates which stream of the type specified in fccType should be accessed.

mode

Specifies the mode to use when opening the file. This function can only open existing streams so the OF_CREATE mode flag cannot be used. See OpenFile for more information about the available flags.

pclsidHandler

Specifies a pointer to a class ID identifying the handler you want to use. If NULL, the system chooses one from the registration database based on the file extension or the RIFF type of the file.

Balance each call to AVIStreamOpenFromFile with a call to AVIStreamRelease using the stream handle returned.

This function calls AVIFileOpen, AVIFileGetStream, and AVIFileRelease.


AVIStreamRead

LONG AVIStreamRead(PAVISTREAM pavi, LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer, LONG FAR * plBytes, LONG FAR * plSamples)

Reads audio or video data from a stream.

•	Returns zero if successful; otherwise, it returns an error code. Use plBytes and plSamples to find out how much was actually read.

Possible errors include:

AVIERR_BUFFERTOOSMALL

The buffer size cbBuffer was too small to read in even a single sample of data.

AVIERR_MEMORY

There was not enough memory for some reason to complete the read operation.

AVIERR_FILEREAD

A disk error occurred while reading the file.

pavi

Specifies a handle to an open stream.

lStart

Specifies the starting sample to read. For audio data, samples correspond to a block of audio data.

lSamples

Specifies the number of samples to read. For audio data, samples correspond to a block of audio data.

lpBuffer

Specifies a pointer to a buffer used to return the data.

cbBuffer

Specifies the size of buffer pointed to by lpBuffer.

plBytes

Specifies a pointer to the location used to return the number of bytes of data written into the buffer for lpBuffer. plBytes can be NULL.

plSamples

Specifies a pointer to the location used to return the number of samples written into the buffer for lpBuffer. plSamples can be NULL.

If lpBuffer is NULL, this function does not read any data; it returns information about the size of data that would be read.

See AVIStreamLength for a discussion of how sample numbers correspond to the data you want to read.


AVIStreamReadData

LONG AVIStreamReadData(PAVISTREAM pavi, DWORD ckid, LPVOID lpData, LONG FAR * lpcbData)

Reads optional header data from a stream.

•	Returns zero if successful; otherwise, it returns an error code. The return value AVIERR_NODATA indicates the system could not find any data with the specified chunk ID.

pavi

Specifies a handle to an open stream.

ckid

Specifies a four-character code identifying the data.

lpData

Specifies a pointer to be used to return the data read.

lpcbData

Points to a location which specifies the buffer size used for lpData. If the read is successful, AVIFile changes this value to indicate the amount of data written into the buffer for lpData.

This function only retrieves header information from the stream. To read the actual multimedia content of the stream, use AVIStreamRead.


AVIStreamReadFormat

LONG AVIStreamReadFormat(PAVISTREAM pavi, LONG lPos, LPVOID lpFormat, LONG FAR * lpcbFormat)

Reads the stream format data.

•	Returns zero if successful; otherwise, it returns an error code.

pavi

Specifies a handle to an open stream.

lPos

Specifies the position in the stream used to obtain the format data.

lpFormat

Specifies a pointer to a buffer used to return the format data.

lpcbFormat

Specifies a pointer to a location indicating the size of the memory block referred to by lpFormat. On return, the value is changed to indicate the amount of data read. If lpFormat is NULL, this parameter can be used to obtain the amount of memory needed to return the format.

This function will return part of the format even if the buffer provided is not large enough to hold the entire format. In this case the return value will be AVIERR_BUFFERTOOSMALL, and the location referred to by lpcbFormat will be filled in with the size of the entire format.

This function is useful because it allows you to use a buffer the size of a BITMAPINFOHEADER structure and retrieve just the common part of the video format if you are not interested in extended format information or palette information.


AVIStreamRelease

LONG AVIStreamRelease(PAVISTREAM pavi)

Reduces the reference count of an AVI stream interface handle by one, and closes the stream if the count reaches zero.

•	Returns the current reference count of the stream. This value should only be used for debugging purposes.

pavi

Specifies a handle to an open stream.

Balance each call to AVIStreamAddRef or AVIFileGetStream with a call to AVIStreamRelease.


AVIStreamSampleToTime

LONG AVIStreamSampleToTime(PAVISTREAM pavi, LONG lSample)

Converts from samples to milliseconds. Samples can correspond to blocks of audio samples, video frames, or other format depending on the stream type.

•	Returns the converted time, or −1 on error.

pavi

Specifies a handle to an open stream.

lSample

Specifies the position information.


AVIStreamSetFormat

LONG AVIStreamSetFormat(PAVISTREAM pavi, LONG lPos, LPVOID lpFormat, LONG cbFormat)

Sets the format of a stream at the specified position.

•	Returns zero if successful; otherwise, it returns an error code.

pavi

Specifies a handle to an open stream.

lPos

Specifies the position in the stream to receive the format.

lpFormat

Specifies a pointer to a structure containing the new format.

cbFormat

Specifies the size of the block of memory in bytes referred to by lpFormat.

After creating a new stream with AVIFileCreateStream, call this function to set the stream's format.

The handler for writing AVI files does not, in general, accept format changes. Aside from setting the initial format for a stream, only changes in the palette of a video stream are allowed in an AVI file. The palette change must be after any frames already written to the AVI file. Other handlers may impose different restrictions.


AVIStreamStart

LONG AVIStreamStart(PAVISTREAM pavi)

Returns the starting sample of the stream.

•	Returns the starting sample number for the stream, or −1 on error.

pavi

Specifies a handle to an open stream.

See AVIStreamLength for a discussion of how sample numbers correspond to the data you want to read.


AVIStreamTimeToSample

LONG AVIStreamTimeToSample(PAVISTREAM pavi, LONG lTime)

Converts from milliseconds to samples.

•	Returns the converted time, or −1 on error.

pavi

Specifies a handle to an open stream.

lTime

Specifies the time in milliseconds.

Samples typically correspond to audio samples or video frames. Other stream types might support different formats than these.


AVIStreamWrite

LONG AVIStreamWrite(PAVISTREAM pavi, LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer, DWORD dwFlags, LONG FAR * plSampWritten, LONG FAR * plBytesWritten)

Writes data to a stream.

•	Returns zero if successful; otherwise, it returns an error code.

pavi

Specifies a handle to an open stream.

lStart

Specifies the starting sample to write.

lSamples

Specifies the number of samples to write.

lpBuffer

Specifies a pointer to buffer containing the data to write.

cbBuffer

Specifies the size of buffer used by lpBuffer.

dwFlags

Specifies any flags associated with this data. The following flag is defined:

AVIIF_KEYFRAME

Indicates this data does not rely on preceding data in the file.

plSampWritten

Specifies a pointer to a location used to return the number of samples written. This can be set to NULL.

plBytesWritten

Specifies a pointer to a location used to return the number of bytes written. This can be set to NULL.

The default AVI file handler only supports writing to the end of a stream. The WAVE file handler supports writing anywhere.

This function overwrites existing data, rather than inserting new data.

See AVIStreamLength for a discussion of how sample numbers correspond to the data you want to read.


AVIStreamWriteData

LONG AVIStreamWriteData(PAVISTREAM pavi, DWORD ckid, LPVOID lpData, LONG cbData)

Writes optional data to the stream.

•	Returns zero if successful; otherwise, it returns an error code.

pavi

Specifies a handle to an open stream.

ckid

Specifies a four-character code identifying the data.

lpData

Specifies a pointer to a buffer containing the data to write.

cbData

Indicates the number of bytes of data to be copied from lpData into the stream.

This function only writes header information to the stream. To write the actual multimedia content of the stream, use AVIStreamWrite. Use AVIFileWriteData to write data that applies to an entire file.

This call fails with a return value of AVIERR_READONLY unless the file was opened with write permission.


CreateEditableStream

STDAPI CreateEditableStream(PAVISTREAM FAR * ppsEditable, PAVISTREAM psSource)

Creates an editable stream. Use this function before using other EditStream functions.

•	Returns zero if successful; otherwise, it returns an error code.

ppsEditable

Specifies a pointer to the location used to return the handle to the new stream.

psSource

Specifies a handle to the open stream used as the source of data. Specify NULL to create an empty editable string that you can copy and paste data into.

The stream pointer returned in ppsEditable must be used as the source stream in the other EditStream functions.

Internally, this function creates tables to keep track of changes to a stream. The original stream is never changed by the EditStream functions. The stream pointer created by this function can be used in any AVIFile function that accepts stream pointers. You can use this function on the same stream multiple times. A copy of a stream is not affected by changes in another copy.


EditStreamClone

STDAPI EditStreamClone(PAVISTREAM pavi, PAVISTREAM FAR * ppResult)

Creates a duplicate editable stream.

•	Returns zero if successful; otherwise, it returns an error code.

pavi

Specifies a handle to an editable stream.

ppResult

Specifies the location used to return the handle to the stream created. This stream is an editable stream.

The editable stream must be created by CreateEditableStream or one of the EditStream functions.

The stream created can be treated as any other AVI stream.

You can use this function as the basis of an "undo" feature. You can also use this function to create a stream copied onto the Clipboard.


EditStreamCopy

STDAPI EditStreamCopy(PAVISTREAM pavi, LONG FAR * plStart, LONG FAR * plLength, PAVISTREAM FAR * ppResult)

Copies an editable stream (or a portion of it) into a temporary stream.

•	Returns zero if successful; otherwise, it returns an error code.

pavi

Specifies a handle to an editable stream used as the source of the data.

plStart

Specifies the starting position of the data to be copied from the stream referred to by pavi. The actual starting position is returned.

plLength

Specifies the length of the data to be copied from the stream referred to by pavi. The actual length of the copied data is returned.

ppResult

Specifies a pointer to the location used to return the handle created for the new stream.

The editable stream must be created by CreateEditableStream or one of the EditStream functions.

The temporary stream can be treated as any other AVI stream.


EditStreamCut

STDAPI EditStreamCut(PAVISTREAM pavi, LONG FAR * plStart, LONG FAR * plLength, PAVISTREAM FAR * ppResult)

Deletes an editable stream (or a portion of it) and copies it into a temporary stream.

•	Returns zero if successful; otherwise, it returns an error code.

pavi

Specifies a handle to the editable stream used as the source of the data.

plStart

Specifies the starting position of the data to be cut from the stream referred to by pavi.

plLength

Specifies the length of the data to be cut from the stream referred to by pavi.

ppResult

Specifies a pointer to the location used to return the handle created for the new stream.

The editable stream must be created by CreateEditableStream or one of the EditStream functions.

The temporary stream is an editable stream and can be treated as any other AVI stream.


EditStreamPaste

STDAPI EditStreamPaste(PAVISTREAM pavi, LONG FAR * plPos, LONG FAR * plLength, PAVISTREAM pstream, LONG lStart, LONG lLength)

Copies a stream (or a portion of it) into another stream.

•	Returns zero if successful; otherwise, it returns an error code.

pavi

Specifies a handle to an editable stream used as the destination of data from the stream specified for pstream.

plPos

Specifies the starting position of the data to be copied from the stream referred to by pavi. On returning from the function, plPos

plLength

Specifies a pointer to where the length of the data pasted in will be returned.

pstream

Specifies a handle to a stream used as the source of the data. This stream does not need to be an editable stream.

lStart

Specifies the starting position within the stream referred to by pstream of the portion that will be pasted into stream pavi.

lLength

Specifies the length of the data to be copied to the stream specified by pavi. If lLength is −1, the entire stream pstream will be pasted in.

The stream pavi must be created by CreateEditableStream or one of the EditStream functions.


EditStreamSetInfo

STDAPI EditStreamSetInfo(PAVISTREAM pavi, AVISTREAMINFO FAR * lpInfo, LONG cbInfo)

Changes characteristics of an editable stream.

•	Returns zero if successful; otherwise, it returns an error code.

pavi

Specifies a handle to an open stream.

lpInfo

Points to an AVISTREAMINFO structure containing new information.

cbInfo

Specifies the size of the structure pointed to by lpInfo.

You must fill out the AVISTREAMINFO structure, including the members you will not use. You can use AVIStreamInfo to initialize the structure and then updated selected members with your data.

This function does not change the following members:

dwCaps
dwEditCount
dwFlags
dwInitialFrames
dwLength
dwSampleSize
dwSuggestedBufferSize
fccHandler
fccType

It does change the following members:

dwQuality
dwRate
dwScale
dwStart
rcFrame
szName
wLanguage
wPriority


EditStreamSetName

STDAPI EditStreamSetName(PAVISTREAM pavi, LPCSTR lpszName)

Assigns a descriptive string to a stream.

•	Returns zero if successful; otherwise, it returns an error code.

pavi

Specifies a handle to an open stream.

lpszName

Specifies a zero-terminated string containing the description of the stream.

This function updates the szName member of the AVISTREAMINFO structure.


GetOpenFileNamePreview

BOOL GetOpenFileNamePreview(LPOPENFILENAME lpofn)

This function is similar to GetOpenFileName defined in COMMDLG.DLL except that it has a preview window to display the movie about to be opened.

•	Returns true if a file was opened.

lpofn

Points to an OPENFILENAME structure used to initialize the dialog box. On return, the structure contains information about the user's file selection.

For more information about this function, see the description for GetOpenFileName.


GetSaveFileNamePreview

BOOL GetSaveFileNamePreview(LPOPENFILENAME lpofn)

This function is similar to GetSaveFileName defined in COMMDLG.DLL except that it has a preview window to display the movie about to be opened.

•	Returns true if a file was opened.

lpofn

Points to an OPENFILENAME structure used to initialize the dialog box. On return, the structure contains information about the user's file selection.

For more information about this function, see the description for GetSaveFileName.


Installable Compression Manager


About the Installable Compression Manager

The Installable Compression Manager (ICM) provides access to the interface used by installable compressors to handle real-time data. Applications can use installable compressors for the following activities:

•	Compressing and decompressing video data

•	Sending a renderer compressed video data and having it draw it to the display

•	Compressing, decompressing, or drawing data with application-supplied renderers

•	Using renderers to handle text and custom data

Typically, installable compressors operate with video-image data stored in AVI files. This chapter explains the programming techniques used to access these services. It covers the following topics:

•	The ICM and the Video for Windows architecture

•	How to compress and decompress image data from your application

•	How to use ICM renderers to draw data from your application

•	Alphabetic reference to the ICM functions and data structures

Before reading this chapter, you should be familiar with the graphic services available with the Microsoft Win32 application programming interface (API). For information about topics such as the BITMAPINFO and the BITMAPINFOHEADER structure, see the Microsoft Win32 Programmer's Reference.


ICM Architecture

ICM is the intermediary between the application and the actual compression and decompression drivers. The compression and decompression drivers do the real work of compressing and decompressing individual frames of data. For example, ICM services are used by the Video for Windows editing tool (VidEdit) and the playback engine (MCIAVI) to handle compression and decompression of image data.

This chapter covers the ICM and the functions an editing or playback application uses to communicate with it.

As the application makes calls to the ICM to compress or decompress data, the ICM translates these calls to a message to be sent to the appropriate compressor or decompressor that does the work of compressing or decompressing the data. The ICM gets the return from the driver and then returns back to the application.

The ICMApp sample application illustrates routines that compress data, decompress data, and display a dialog box.


System Entries for Compressors, Decompressors, and Renderers

The system uses entries in the system registry to find the ICM drivers. These entries are in the form of two four-character codes separated by a period. The first four-character code is VIDC, VIDS, TXTS or AUDS. (Custom renderers can also define their own four-character codes.) The second four-character code is defined by the driver. Typically, the second four-character code corresponds to the type of data the driver can handle; however, drivers might use other identifiers. The system defines the following four-character codes.

Four-character code	Description
VIDC	Identifies compressors and decompressors.
VIDS	Identifies video-stream renderers.
TXTS	Identifies text-stream renderers.
AUDS	Identifies audio-stream handlers.
When opening an ICM driver, an application specifies the type of driver and the type of data handler it needs. Typically, this comes from the stream header. The system tries to open the specified data handler directly. If the system cannot open the handler directly, it searches the registry entries for a driver that has the needed handler.

When searching for the driver, the system tries to match the four-character codes specified for the driver type and data handler with those specified in the driver entry. For example, if an application specifies the compressor MSSQ, the system tries to find the driver entry VIDC.MSSQ. If it cannot find a match, it will open each driver corresponding to the driver type and interrogate the driver to determine if it can handle the type of data your application specifies. In the previous example, if the system could not find VIDC.MSSQ, it would open all drivers with the VIDC four-character code and locate one that could handle the data.


Using ICM Services

In general, an application uses ICM services to perform the following tasks:

•	Locates, opens, or installs the appropriate compressor or decompressor

•	Configures or obtains configuration information about the compressor or decompressor

•	Uses a series of functions to compress, decompress, or (for decompressors with drawing capabilities) draw the data

The DrawDib functions perform these tasks implicitly and might provide the most convenient way to use ICM. The specific tasks for using ICM services are covered in the following sections. The sample application, ICMApp, shows how to use the ICM services to perform all of these tasks to compress and decompress images. For more information about the DrawDib functions, see <ch_drawdib>.


Errors Returned from the ICM Functions

For most ICM functions, return values of less than zero indicate an error. Your application should check these return values to see if the ICM function encounters an error. To keep the example fragments in this chapter simple, many of the examples do not check for errors.


Locating and Opening Compressors and Decompressors

To use ICM, an application must open a compressor or decompressor. If your application does not know about the compressors or decompressors installed on a system, it must find a suitable compressor to open. Once your application finishes with a compressor or decompressor, it closes it to free any resources used for compression or decompression. Your application can use the ICInfo, ICLocate, ICOpen, and ICClose functions for finding, opening, and closing compressors and decompressors.

If your application knows the compressor or decompressor it needs, it can open the compressor with the ICOpen function. Your application uses the handle returned by this function to identify the opened compressor or decompressor when it uses other ICM functions. The ICOpen function has the following syntax:

HIC ICOpen(fccType, fccHandler, wMode)

The fccType and fccHandler parameters are four-character codes used to describe the type and handler type for the compressor. The first four-character code describes the type of the compressor or decompressor. For video compressors and decompressors, this is always 'vidc'. The second four-character code identifies the specific compression handler type. For example, this value is 'msvc' for the Video 1 compressor.

Note  The stream header in an AVI file contains information about the stream type (the fccType) and the specific handler (the fccHandler) for that stream.

The wMode parameter specifies flags passed to the compressor or decompressor. These flags let the compressor or decompressor know why it is opened so it can prepare for subsequent operation. The flags indicate the following types of operations: compression, decompression, or directly decompress and draw. The following flags are defined:

Flag	Description
ICMODE_COMPRESS	Notifies a compressor that it is opened for compression.
ICMODE_FASTCOMPRESS	Notifies a compressor that it is opened for fast (real-time) compression.
ICMODE_DECOMPRESS	Notifies a decompressor that it is opened for decompression.
ICMODE_FASTDECOMPRESS	Notifies a decompressor that it is opened for fast (real-time) decompression.
ICMODE_DRAW	Notifies a decompressor that it is opened to decompress an image and draws it directly to hardware.
ICMODE_QUERY	Notifies a compressor or decompressor that it is opened to obtain information.
If your application does not know which compressors and decompressors are installed on a system, it can use ICInfo to enumerate them. This function has the following syntax:

BOOL ICInfo(fccType, fccHandler, lpicinfo)

The fccType parameter specifies a four-character code indicating the type of compressor or decompressor. Set this to zero if your application will accept any type of compressor or decompressor. To enumerate the compressors or decompressors, your application specifies an integer for fccHandler. Your application receives return information for integers between 0 and the number of installed compressors or decompressors of the type specified for fccType. The compressor or decompressor returns a description of itself in an ICINFO data structure pointed to by lpicinfo. For complete information about a compressor or decompressor, use ICGetInfo. The ICInfo function returns TRUE if it can locate the specified compressor or decompressor.

Applications can use ICLocate to find a compressor or decompressor of a specific type, and to obtain a handle to it for use in other ICM functions. The ICLocate function has the following syntax:

HIC ICLocate(fccType, fccHandler, lpbiIn, lpbiOut, wFlags)

The fccType and fccHandler parameters are four-character codes used to describe the type and handler type for the compressor. Your application can specify NULL for fccHandler if it does not know the handler type or if it can use any handler type.

The lpbiIn parameter contains a pointer to a format structure describing the input format the compressor or decompressor will handle. The lpbiOut parameter contains a pointer to a format structure describing the output format specified by the application. If it does not matter what output format is returned by a compressor or decompressor, you can set lpbiOut to NULL. The wFlags parameter indicates the type of operation you want the driver to do: compress, decompress, or directly decompress and draw. These flags are described for ICOpen.

Applications can use ICDecompressOpen and ICDrawOpen instead of ICLocate to locate and open decompressors. These macros predefine the wFlags parameter and use ICLocate for operation.


Letting the User Select Compressors

When compressing data, you can have the application let the user select the compressor with ICCompressorChoose. This function displays a dialog box listing available compressors. Flags specified for this function also let the user specify the key-frame frequency and the movie-data rate, and display a preview window.

The compressor selected by the user is automatically opened and its handle is returned in the hic member of the COMPVARS structure specified in ICCompressorChoose.

If you use ICCompressorChoose, use ICCompressorFree to close the compressor and free any resources associated with the COMPVARS structure.


Installing and Removing Compressors and Decompressors

There are three methods of installing compressors and decompressors. They might be installed during the set-up of Video for Windows or other software relating to Video for Windows. Users can also install compressors and decompressors with the Drivers option of the Control Panel. Applications can also install custom compressors and decompressors required for their operation. Most applications will not need to install or remove compressors or decompressors  compressors and decompressors are usually installed by a setup program or by the user with the Drivers option of the Control Panel. An application might, however, install a compressor directly or install a function as a compressor. In these cases, the application uses ICInstall and ICRemove.

The ICInstall function creates a new entry in the system registry for a compressor or decompressor. After installation, the compressor or decompressor must still be opened. The ICInstall function has the following syntax:

BOOL ICInstall (fccType, fccHandler, lParam, szDesc, wFlags)

The fccType and fccHandler parameters specify four-character codes describing the compressor type and handler type.

Flags set in wFlags specify the meaning of lParam. The ICINSTALL_DRIVER flag indicates lParam points to a zero-terminated string containing the name of a compressor or decompressor. The ICINSTALL_FUNCTION flag indicates lParam points to a compressor function.

If you are using a function as a compressor or decompressor, open it with ICOpenFunction before using it. Functions do not need to be installed with ICInstall. If your application does not install a function, it still must close the function, but it does not need to remove the function. The internal structure of the function used as a compressor or decompressor should be the same as the DriverProc entry-point function used by installable drivers.

Use the szDesc parameter for a descriptive name for the compressor or decompressor. This information is not used and your application does not have to supply a name.

Usually, the Drivers option of the Control Panel is used to remove a compressor or decompressor. Applications installing a function as a compressor or decompressor must remove the function before the application terminates so other applications do not try to use the function. Applications can use ICRemove to remove the function installed. When removing a function, the application must identify it with the four-character code used to install the function.


Configuring Compressors and Decompressors

Applications can configure the compressor or have the compressor display a dialog box to let the user to do the configuration. If it is practical, your application should let the user configure the compressor with the compressor's configuration dialog box. Typically, this makes your application independent of the compressor and you do not need to consider all the options available to the compressor.

Your application uses ICQueryConfigure to determine if a compressor can display a configuration dialog box. If the compressor can display a configuration dialog box, your application uses ICConfigure to display it. Both of these functions use the handle your application obtained when it located the compressor. The ICConfigure function also requires a handle to the parent window.

Your application can use ICGetStateSize, ICGetState, and ICSetState to directly get and set the state information for a compressor. If your application creates or modifies the state data, it must know the actual layout of the compressor data before restoring a compressor state. Alternatively, if your application obtains state data from a compressor and uses it to restore the state in a subsequent session, it must make sure that it only restores state information obtained from the compressor it is currently using.

Applications can send messages directly to compressors and decompressors with the ICSendMessage function. (If a macro is defined for an operation, your application should use it rather than sending messages.)


Getting Information About Compressors and Decompressors

The following functions can be used to get information about a compressor or decompressor.

Function	Description
ICGetInfo	Obtains general information about the compressor or decompressor.
ICGetDefaultKeyFrameRate	Determines the default key-frame rate of a compressor or decompressor.
ICGetDisplayFormat	Determines the best format a compressor or decompressor has for displaying on the screen.
ICGetDefaultQuality	Determines the default quality value of a compressor or decompressor.
To obtain information about a compressor or decompressor, your application can use ICGetInfo. This function fills an ICINFO structure with information about the compressor or decompressor. Your application must allocate the memory for the ICINFO structure and pass a pointer to it in ICGetInfo. The ICINFO structure has the following definition:

typedef struct {

    DWORD    dwSize;       // Contains the size of the ICINFO structure.

    DWORD    fccType;      // Contains 'vidc' for image compression.

    DWORD    fccHandler;   // Four-character code identifying

                           // compressor/decompressor.

    DWORD    dwFlags;      // Indicates compressor/decompressor

                           // capabilities.

    DWORD    dwVersion;    // Contains the version number of the driver.

    DWORD    dwVersionICM; // Contains the ICM version supported by the

                           // driver.

    char     szName[16];   // Points to the short name of the driver.

    char     szDescription[128]; // Points to the long name of the

                                 // compressor or decompressor.

    char     szDriver[128]; // Points to the module name containing the

                            // compressor or decompressor.

} ICINFO;

The dwFlags member of this structure contains flags indicating capabilities of the compressor or decompressor. Unless your application is looking for a particular compressor or decompressor, the flags give your application the most useful information about the capabilities of a compressor or decompressor.

The ICGetDefaultKeyFrameRate and ICGetDefaultQuality functions let your application determine the default key-frame rate and default quality value. Both of these functions require only the handle to the compressor or decompressor.

Your application can use the ICQueryAbout and ICAbout functions to display the about dialog box of a compressor or decompressor. The ICQueryAbout function lets your application determine if a compressor or decompressor can display the about dialog box. The ICAbout function displays the dialog box.


Compressing Single Images

The ICImageCompress function provides the most convenient method to compress a single image. This function returns a handle to the compressed DIB. The compressed DIB is a packed DIB with the CF_DIB format.


Compressing Sequences with the ICSeqCompress Functions

The ICSeqCompressFrame, ICSeqCompressFrameStart, and ICSeqCompressFrameEnd functions are the most convenient functions to use when compressing data. These functions use the data in the COMPVARS structure for operation. Typically, applications use ICCompressorChoose to let the user interactively select (and open) the compressor and set the compression parameters in the COMPVARS structure. Applications can also set the parameters in this structure manually.

When the application is ready to start compression, it uses ICSeqCompressFrameStart to initialize the system. Once the system is initialized, the application uses ICSeqCompressFrame to compress each frame individually. The data rate and key-frame frequency for the sequence is specified in the COMPVARS structure. The return value for ICSeqCompressFrame points to the compressed data.

When finished compressing a sequence, an application uses ICSeqCompressFrameEnd to free system resources allocated for ICSeqCompressFrameStart. An application uses ICCompressorFree to free the resources allocated for the COMPVARS structure.


Compressing Image Data with the ICCompress Functions

Your application uses the ICCompress functions when it needs more control over the compression process. For example, it can use these functions to specify which compression algorithm a compressor uses, or it can specify individual key frames rather than the key-frame frequency.

Your application uses a series of ICCompress functions to coordinate compressing data. The coordination involves the following activities:

•	Specifying the input format and determining the compression format

•	Preparing the compressor for compression

•	Compressing the data

•	Ending compression

Your application uses the following functions for these activities.

Function	Description
ICCompress	Compress data.
ICCompressBegin	Prepare compressor driver for compressing data.
ICCompressEnd	Tell the compressor driver to end compression.
ICCompressGetFormat	Determine the output format of a compressor.
ICCompressGetFormatSize	Get the size of the output data format.
ICCompressGetSize	Get the size of the compressed data.
ICCompressQuery	Determine if a compressor can compress a specific format.
Specifying the Input Format and Determining the Compression Format

To compress data when the output format is not important, your application must first locate a compressor that can handle the input format. When the output format is not important to your application, it can use ICCompressGetFormat to have the compressor suggest a default format. The ICCompressGetFormat function has the following syntax:

LRESULT ICCompressGetFormat(hic, lpbiInput, lpbiOutput)

The hic parameter specifies the compressor handle. The lpbiInput parameter specifies a pointer to a BITMAPINFO structure indicating the format of the input data. The lpbiOutput parameter specifies a pointer to a buffer used to return the output format suggested by the compressor. Your application can determine the size of the buffer needed for the default buffer with ICCompressGetFormatSize.

If your application requires a specific output format, it should use ICCompressQuery to interrogate a compressor to determine if it supports the output format your application suggests. This function has the following syntax:

LRESULT ICCompressQuery(hic, lpbiInput, lpbiOutput)

The hic parameter specifies the compressor handle. The lpbiInput and lpbiOutput parameters specify pointers to the data structures defining the input and output formats your application prefers. If the compressor can handle both formats it returns ICERR_OK. If it cannot handle the formats, it returns ICERR_BADFORMAT. If the compressor returns ICERR_BADFORMAT and the output format is critical to your application, your application will have to find an alternate compressor. If an alternate output format is satisfactory, your application might use ICCompressQuery with the alternate formats to determine if the compressor can handle them. Or your application can use ICCompressGetFormat to have the compressor suggest the output format.

If your application specifies NULL for the lpbiOutput parameter of ICCompressQuery, the compressor will select the output format. Typically, your application specifies NULL to find out if the compressor can handle the input format. The output format information is not returned to your application.

Your application will also need the size of the data returned from the compressor after compression is complete. Use ICCompressGetSize to obtain the worst-case (largest) buffer required by the compressor. The number of bytes returned should be used to allocate a buffer used for subsequent compression of images.

Initialization for the Compression Sequence

Once your application selects a compressor that handles the input and output formats it needs, it can prepare the compressor to start compressing data. The ICCompressBegin function initializes the compressor. This function requires the compressor handle and the input and output format. It returns ICERR_OK if it initializes properly for the specified formats. If the compressor cannot handle the formats, or if they are incorrect, it returns the error ICERR_BADFORMAT.

Compressing Data

The ICCompress function does the actual compression. Your application must use this function repeatedly until all the frames are compressed. This function has the following syntax:

LRESULT ICCompress(hic, dwFlags, lpbiOutput, lpData, lpbiInput, lpBits lpckid, lpdwFlags, lFrameNum, dwFrameSize, dwQuality, lpbiPrev, lpPrev)

The hic parameter specifies the handle to the compressor.

The dwFlags parameter specifies any applicable flags for the compression. Your application can use ICCOMPRESS_KEYFRAME to have the compressor make the frame a key frame. (A key frame is one that does not require data from a previous frame for decompression.) When this flag is set, compressors use this image as the initial one in a sequence.

The lpbiInput and lpBits parameters specify pointers to the data structure defining the input format and the location of the input buffer. Similarly, the lpbiOutput and lpData parameters specify pointers to the data structure defining the output format and the location of the buffer for the output data. Your application must allocate the memory for these buffers. When control returns to your application, it typically stores the compressed data in lpbiOutput and lpData in a subsequent operation. If your application needs to move the compressed data, it can find the size used for the data in the biSizeImage member in the BITMAPINFO structure specified for lpbiOutput.

The lpckid parameter is not used. The lpdwFlags parameter specifies a pointer to a DWORD holding the return flags used in the AVI index. The compressor will set this flag to AVIIF_KEYFRAME when it creates a key frame. The application sends the ICCOMPRESS_KEYFRAME flag to have the driver create a key frame. If your application creates AVI files, it should save the information returned for these parameters in the file.

The lFrameNum parameter specifies the frame number. Your application provides, and, if necessary, increments this information. A compressor uses this value to check if frames are being sent out of order when it is doing fast temporal compression. If your application has a frame recompressed, it should use the same frame number used when the frame was first compressed. If your application compresses a still-frame image, it can specify zero for lFrameNum.

The dwFrameSize parameter specifies the requested frame size in bytes. If set to zero, the compressor chooses the frame size. If set to a nonzero value, the compressor tries to compress the frame to within the specified size. To obtain the size goal, the compressor might have sacrificed image quality (or made some other trade-off). Compressors recognize the frame-size value only if they return the VIDCF_CRUNCH flag for ICGetInfo.

The dwQuality parameter specifies the requested quality value for the frame. Compressors support this only if they set the VIDCF_QUALITY flag for ICGetInfo. Set the parameter to −1 to use the default compression quality. Other values are compressor-specific, but will range between 0 and 10000. The lowest quality is represented by 0 and the highest quality is represented by 10000.

The lpbiPrev and lpPrev parameters specify pointers to the data structure defining the format and the location of the previous uncompressed image. Compressors use this data if they perform temporal compression (that is, they need the previous frame to compress the current frame). Compressors need this information only if they return the VIDCF_TEMPORALC flag. Compressors returning the VIDCF_FASTTEMPORALC flag can perform temporal compression without the previous frame. Set the lpbiPrev and lpPrev parameters to NULL when the ICCOMPRESS_KEYFRAME flag is set or if the driver does not need key frames.

The ICCompress function returns ICERR_OK if successful. Otherwise, it returns an error code.

After your application has compressed its data, it uses ICCompressEnd to notify the compressor that it has finished. To restart compression after using this function, your application must re-initialize the compressor with ICCompressBegin.


Monitoring the Progress of Compressors and Decompressors

Applications can monitor the progress of a lengthy operation performed by a compressor or decompressor by sending it the address of a callback function. When compressors and decompressors have this address, they will send status messages to the function. Status messages indicate the operation is starting, stopping, yielding, or proceeding. The ICSetStatusProc function sends the callback function address to the compressor or decompressor.


Decompressing Single Images

The ICImageDecompress function provides the most convenient method to decompress a single image. This function returns a handle to the decompressed DIB.


Decompressing Image Data

Your application uses a series of functions to control the decompressor used to decompress data, just as it controls a compressor used to compress data. Decompressing data involves the following activities:

•	Specifying the input format and determining the decompression format

•	Preparing to decompress data

•	Decompressing data

•	Ending decompression

For many applications, the DrawDib functions provide the most convenient method of decompressing data. <For more information about the DrawDib functions, see ch_drawdib.>

Your application uses the following functions for the decompression activities.

Function	Description
ICDecompressEx	Decompress data.
ICDecompressExBegin	Prepare decompressor for decompressing data.
ICDecompressExEnd	Tell decompressor to end decompression.
ICDecompressGetFormat	Determine the output format of a decompressor.
ICDecompressGetFormatSize	Get the size of the output data format.
ICDecompressGetPalette	Get the palette for the output format of a decompressor.
ICDecompressExQuery	Determine if a decompressor can decompress a specific format.
Decompression is handled very much like compression except that the input format is a compressed format and the output format is a displayable format. The input format for decompression is usually obtained from the stream header. After determining the input format, your application can use ICLocate or ICOpen to find a decompressor that can handle it.

Specifying the Input Format and Determining the Decompression Format

Because your application allocates the memory required for decompression, it needs to determine the maximum memory the decompressor can require for the output format. The ICDecompressGetFormatSize function obtains the number of bytes the decompressor uses for the default format. This function has the following syntax:

DWORD ICDecompressGetFormatSize(hic, lpbi)

The hic parameter specifies a handle to a decompressor. The lpbi parameter specifies a pointer to a BITMAPINFO structure indicating the format of the input data.

To have the decompressor suggest a format, your application can use ICDecompressGetFormat to obtain the format. This function has the following syntax:

DWORD ICDecompressGetFormat(hic, lpbiInput, lpbiOutput)

Like ICDecompressGetFormatSize, the hic and lpbiInput parameters specify a handle to the decompressor and a pointer to the structure indicating the format of the input data. The decompressor returns its suggested format in the BITMAPINFO structure pointed to by lpbiInput. The default format return typically preserves the most information during decompression. Your application should check that the decompressor returns ICERR_OK for the return value before accessing the lpbiOutput information. If the decompressor cannot handle the input format, it returns ICERR_BADFORMAT.

Use the ICDecompressExQuery function to determine if the decompressor can handle the specific formats or if stretching is supported.

If your application defines its own format by using ICDecompressExQuery, it must also obtain a palette for the bitmap. (Most applications use standard formats and do not need to obtain a palette.) Your application can obtain the palette with ICDecompressGetPalette. This function has the following syntax:

DWORD ICDecompressGetPalette(hic, lpbiInput, lpbiOutput)

Like the other functions, hic and lpbiInput specify a handle to a decompressor and point to a BITMAPINFO structure indicating the format of the input data. The lpbiOutput parameter points to a BITMAPINFO structure used to return the color table. The space reserved for the color table must have an entire 256-color palette table reserved at the end of the structure.

Initialization for the Decompression Sequence

Once your application selects a decompressor that handles the input and output formats it needs, it can prepare the decompressor to start decompressing data. The ICDecompressExBegin function initializes the decompressor. This function requires the decompressor handle and the input and output format. It returns ICERR_OK if it initializes properly for the specified formats. If the decompressor cannot handle the formats, or if they are incorrect, it returns the error ICERR_BADFORMAT.

Decompressing Data

The ICDecompressEx function does the actual decompression. Your application must use this function repeatedly until all the data is decompressed. This function has the following syntax:

DWORD ICDecompressEx(hic, dwFlags, lpbiSrc, lpSrc, xSrc, ySrc, dxSrc, dySrc, lpbiDst, lpDst, xDst, yDst, dxDst, dyDst)

The hic parameter specifies the handle to the decompressor.

The dwFlags parameter specifies any applicable flags for decompression. If your video presentation is starting to lag behind other components (such as audio), your application can use ICDECOMPRESS_HURRYUP to have the decompressor decompress at a faster rate. To speed up decompression, a decompressor might extract only the information it needs to decompress the next frame and not fully decompress the current frame. Thus, when your application uses this flag, it should not try to draw the decompressed data.

Applications use the ICDECOMPRESS_PREROLL flag to indicate that a frame will not be drawn because it is before the point in the movie where play will start. Typically, applications use this to seek to a compressed stream position. The flag is sent with the key frame and subsequent frames needed to decompress the desired frame.

Applications use the ICDECOMPRESS_UPDATE flag to have the decompressor redraw the current frame. Usually, applications use this flag to refresh the screen.

The ICDECOMPRESS_NULLFRAME flag is used to send empty frames to the decompressor. Decompressors do not update the frame when they receive this flag.

The lpbiSrc and lpSrc parameters specify pointers to the data structure defining the input format and the location of the input buffer. Similarly, the lpbiDst and lpDst parameters specify pointers to the data structure defining the output format and the location of the buffer for the output data. Your application must allocate the memory for these buffers. When control returns to your application, it will use the information in lpbiDst and lpDst for subsequent processing of the decompressed data.

The xSrc and ySrc parameters specify the coordinates of the source rectangle within the DIB specified by lpbiSrc. The dxSrc and dySrc parameters specify the width and height of the source rectangle. Similarly, the xDst, yDst, dxDst, and dyDst parameters define the destination rectangle. Applications can use these rectangles to decompress data into a region of a DIB and decompress portions of images.

The ICDecompressEx function returns ICERR_OK if successful. Otherwise, it returns an error code.

After your application has decompressed its data, it uses ICDecompressExEnd to notify the decompressor that it has finished. To restart decompression after using this function, your application must re-initialize the decompressor with ICDecompressExBegin.


The ICDecompressEx Functions

The ICDecompressEx, ICDecompressExBegin, ICDecompressExEnd, and ICDecompressExQuery functions replace the ICDecompress, ICDecompressBegin, ICDecompressEnd, and ICDecompressQuery functions. The ICDecompressEx functions are a superset of the ICDecompress function. The ICDecompressEx functions provide more capabilities and should be used in place of the ICCompress equivalents.


Using Hardware-Drawing Capabilities

Some renderers can draw directly to video hardware as they decompress video frames. These renderers return the VIDCF_DRAW flag in response to ICGetInfo. When using this type of renderer, your application does not have to handle the decompressed data. It lets the renderer retain the decompressed data for drawing. The following functions are used for decompressing and drawing with renderers that have drawing capabilities.

Function	Description
ICDrawBegin	Prepare a renderer for drawing.
ICDrawEnd	Stop any drawing operations.
ICDrawFlush	Flush the buffers in the renderer.
ICDrawQuery	Determine if the renderer can render data in a specific format.
ICDrawSuggestFormat	Have the renderer suggest the output format.
ICDrawStart	Start the internal clock a renderer uses for drawing.
ICDrawStop	Stop the internal clock a renderer uses for drawing.
ICGetBuffersWanted	Determine the pre-buffering requirements of a renderer.
ICDrawRealize	Tells a renderer to realize the palette it uses while drawing.
Applications can also use a function for rendering data. <For information about installing these functions, see icm_install.>

If your application uses a renderer with drawing capabilities, it must handle the following activities:

•	Find a renderer that can decompress and draw a bitmap with the input format specified.

•	Prepare for drawing.

•	Decompress data.

•	End the drawing process.

Finding the Renderer

The ICDrawOpen function opens a renderer that can draw images with the format specified. It returns a handle to a renderer if it is successful; otherwise, it returns zero. This function uses ICLocate to open the renderer.

HIC ICDrawOpen(fccType, fccHandler, lpbiIn)

Specifying Image Formats

Because your application no longer needs to draw the final data, it does not need to specify the output format. However, it must make sure the renderer can draw the input format. Your application can use ICDrawQuery to determine if a renderer can handle the input format. While this function can determine if a renderer can handle the format, it does not determine if a renderer has all the capabilities needed to draw a bitmap. If your application must determine if the renderer can render the bitmap as required, use this function with ICDrawBegin.

Your application can have a renderer suggest an output format with ICDrawSuggestFormat. This is used when a renderer separates the drawing capabilities from the decompressing capabilities. Most applications using the drawing functions will not need to determine the output format.

Preparing to Draw Images

The ICDrawBegin function initializes a renderer and informs it about the destination of drawing. The ICDrawBegin function has the following syntax:

DWORD ICDrawBegin(hic, dwFlags, hPal, hwnd, hdc, xDst, yDst, dxDst, dyDst, lpbi, xSrc, yScr, dxSrc, dySrc, dwRate, dwScale)

The hic parameter contains the handle to the renderer.

The dwFlags parameter specifies any applicable flags for drawing. The ICDRAW_QUERY flag determines if the renderer can handle the input format. The renderer does not draw when this flag is used. The ICDRAW_FULLSCREEN flag indicates that the renderer will draw to the full screen rather than to a window. The ICDRAW_HDC flag indicates that the renderer will use a window and display context for drawing.

The hPal parameter specifies a handle to the palette used for drawing. Renderers ignore this information. Your application can set it to NULL.

The hwnd and hdc parameters define the window and display context used for drawing. Your application must set both of these values if it uses the ICDRAW_HDC flag.

The xDst, yDst, dxDst and dyDst parameters define the destination rectangle used for drawing. Specify the destination rectangle values relative to the current window or display context. Your application should set these parameters to the size of the destination rectangle if it uses ICDRAW_HDC. It can set them to zero if it uses the ICDRAW_FULLSCREEN flag.

The xSrc, ySrc, dxSrc, and dySrc parameters specify the source rectangle used for clipping the frames of the image. The renderer will stretch the rectangle specified as the source into the rectangle specified by the destination when drawing.

The lpbi parameter should contain a pointer to the BITMAPINFO structure for the input format. Your application uses the dwRate and dwScale parameters to specify the decompression rate. The integer value specified for dwRate divided by the integer value specified for dwScale defines the play rate in frames per second. This is used by the renderer when it is responsible for timing of frames on playback.

Some renderers buffer the compressed data for more efficient operation. Your application can use ICGetBuffersWanted to determine how many data frames it should send to the renderer before it has the renderer draw them.

Drawing the Data

The ICDraw function has the renderer do the actual drawing. This function has the following syntax:

LRESULT ICDraw(hic, dwFlags, lpFormat, lpData, cbData, lTime)

The hic parameter is the handle to the renderer. The dwFlags parameter contains flags set by the application and used by the renderer.

Flag	Description
ICDRAW_HURRYUP	Indicates the renderer should just buffer the data if it needs it for decompression and not draw it to the screen.
ICDRAW_UPDATE	Tells the renderer to update the screen based on data previously received.
ICDRAW_PREROLL	Indicates this frame occurs before actual playback should start.
ICDRAW_NULLFRAME	Indicates this frame does not actually have any data, and the previous frame should be redrawn.
ICDRAW_NOTKEYFRAME	Indicates this frame is not a key frame.
The lpFormat parameter specifies a pointer to the format of the input data. The lpData parameter contains the actual data to be decompressed and later drawn. The cbData parameter specifies the number of bytes in lpData.

The lTime parameter specifies the time to draw this frame. The renderer divides this integer by the time scale specified with ICDrawBegin to obtain the actual time. Time for the ICDraw functions is relative to ICDrawStart; that is, ICDrawStart sets the clock to zero. For example, if your application specifies 1000 for the time scale and 75 for lTime, the renderer draws the frame 75 milliseconds into the sequence.

The renderer starts decompressing data in response to ICDraw; however, it does not start drawing data until your application calls ICDrawStart. (If a renderer buffers the data before drawing, your application should not use ICDrawStart until it has sent the number of frames the renderer returned for ICGetBuffersWanted.) When your application uses ICDrawStart, the renderer begins to draw the frames at the rate specified by dwRate specified with the ICDrawBegin function. Drawing continues until your application stops the renderer drawing clock with ICDrawStop.

Controlling Drawing Parameters

The ICDrawGetTime and ICDrawSetTime functions let your application monitor or change the clock of a renderer that can draw data.

To change the playback position while a renderer is drawing, your application can use ICDrawWindow for repositioning the window. Applications typically use this function whenever the window changes.

If the playback window gets a palette-realize message, your application must call ICDrawRealize to have the renderer realize the palette again for playback. Applications can change the palette with ICDrawChangePalette.

Some renderers must be specifically instructed to display frames passed to them. The ICDrawRenderBuffer function will have these renderers draw the frame.


Using the Installable Compression Manager

This section illustrates the use of the ICM functions.


Locating and Opening Compressors and Decompressors: Examples

The following fragment tries to find a compressor that can compress an 8-bits-per-pixel bitmap:

BITMAPINFOHEADER    bih;

HIC                 hIC

// initialize the Bitmap structure

bih.biSize = sizeof(BITMAPINFOHEADER);

bih.biWidth = bih.biHeight = 0;

bih.biPlanes = 1;

bih.biCompression = BI_RGB;      // standard RGB bitmap

bih.biBitcount = 8;              // 8bpp format

bih.biSizeImage = 0;

bih.biXPelsPerMeter = bih.biYPelsPerMeter = 0;

bih.biClrUsed = bih.biClrImportant = 256;

hIC = ICLocate (ICTYPE_VIDEO, 0L,

(LPBITMAPINFOHEADER)&bih, NULL, ICMODE_COMPRESS);

The following example enumerates the decompressors in the system to find one that can handle the format of its images. The following example uses ICTYPE_VIDEO and ICDecompressQuery to determine if a compressor or decompressor supports the image format:

for (i=0; ICInfo(fccType, i, &icinfo); i++)

{

    hic = ICOpen(icinfo.fccType, icinfo.fccHandler, ICMODE_QUERY);

    if (hic)

    {

        // skip this compressor if it can't handle the specified format

        if (fccType == ICTYPE_VIDEO &&

            pvIn != NULL &&

            ICDecompressQuery(hic, pvIn, NULL) != ICERR_OK)

        {

            ICClose(hic);

            continue;

        }

        // find out the compressor name.

        ICGetInfo(hic, &icinfo, sizeof(icinfo));

        // add it to the combo box

        n = ComboBox_AddString(hwndC,icinfo.szDescription);

        ComboBox_SetItemData(hwndC, n, hic);

    }

}

The following fragment tries to locate a specific compressor to compress the 8-bit RGB format to an 8-bit RLE format:

BITMAPINFOHEADER    bihIn, bihOut;

HIC                 hIC

// initialize the Bitmap structure

bihIn.biSize = bihOut.biSize = sizeof(BITMAPINFOHEADER);

bihIn.biWidth = bihIn.biHeight = bihOut.biWidth = bihOut.biHeight = 0;

bihIn.biPlanes = bihOut.biPlanes= 1;

bihIn.biCompression = BI_RGB;            //standard RGB bitmap for input

bihOut.biCompression = BI_RLE8;          // 8-bit RLE for output format

bihIn.biBitcount = bihOut.biBitCount = 8;  // 8bpp format

bihIn.biSizeImage = bihOut.biSizeImage = 0;

bihIn.biXPelsPerMeter = bih.biYPelsPerMeter =

    bihOut.biXPelsPerMeter = bihOut.biYPelsPerMeter = 0;

bihIn.biClrUsed = bih.biClrImportant =

    bihOut.biClrUsed = bihOut.biClrImportant = 256;

hIC = ICLocate (ICTYPE_VIDEO, 0L,

        (LPBITMAPINFOHEADER)&bihIn,

        (LPBITMAPINFOHEADER)&bihOut, ICMODE_COMPRESS);


Installing Compressors and Decompressors

The following fragment shows how an application would install a function as a compressor or decompressor.

// This function looks like a DriverProc entry point

LRESULT MyCodecFunction(DWORD dwID, HDRVR hDriver, // Not used

                        UINT uiMessage, LPARAM lParam1, LPARAM lParam2);

// This function installs the MyCodecFunction as a compressor

result = ICInstall ( ICTYPE_VIDEO, mmioFOURCC('s','a','m','p'),

(LPARAM)(FARPROC)&MyCodecFunction, NULL, ICINSTALL_FUNCTION);


Configuring Compressors and Decompressors: Examples

Your application can use the following fragment to test for support of the configuration dialog box and display it:

 if (ICQueryConfigure(hIC)){

    // If compressor handles a configuration dialog box, display it

    // using our app window as the parent window.

    ICConfigure(hIC, hwndApp);

}

The following fragment shows how to obtain the state data:

dwStateSize = ICGetStateSize(hIC);    // get size of buffer required

h = GlobalAlloc(GHND, dwStateSize);   // allocate data buffer

lpData = GlobalLock(h);               // lock data buffer

ICGetState(hIC, (LPVOID)lpData, dwStateSize); // get the state data

// Store the state data as required

The following fragment shows how to restore state data. State data restored by applications should not contain any changes to the state data obtained from a driver:

ICSetState(hIC, (LPVOID)lpData, dwStateSize); // set the new state data

GlobalUnlock(h);


Getting Information About Compressors and Decompressors: Examples

The following fragment shows how to obtain the ICINFO information from a compressor or decompressor:

ICINFO	ICInfo;

ICGetInfo(hIC, &ICInfo, sizeof(ICInfo));

The following fragment uses ICGetDefaultKeyFrameRate and ICGetDefaultQuality functions to obtain the default values:

DWORD    dwKeyFrameRate, dwQuality;

dwKeyFrameRate = ICGetDefaultKeyFrameRate(hIC);

dwQuality = ICGetDefaultQuality(hIC);

The following example uses the ICQueryAbout and ICAbout functions:

if ( ICQueryAbout(hIC)){

    // If the compressor has an about dialog box, show it

    ICAbout(hIC, hwndApp);

}


Specifying the Input Format and Determining the Compression Format: Examples

The following example fragment shows how an application can determine the output format for a compressor to use.

LPBITMAPINFOHEADER	lpbiIn, lpbiOut;

// *lpbiIn must be initialized to the input format

dwFormatSize = ICCompressGetFormatSize(hIC, lpbiIn); // get output

                                                     // buffer size

h = GlobalAlloc(GHND, dwFormatSize);          // allocate format buffer

lpbiOut = (LPBITMAPINFOHEADER)GlobalLock(h);  // lock format buffer

ICCompressGetFormat(hIC, lpbiIn, lpbiOut);           // fill the format

                                                     // information

The following fragment uses ICCompressQuery to determine if a compressor can handle both the input and output format:

LPBITMAPINFOHEADER	lpbiIn, lpbiOut;

// Both *lpbiIn & *lpbiOut must be initialized to the respective formats

if (ICCompressQuery(hIC, lpbiIn, lpbiOut) == ICERR_OK){

// format is supported - use the compressor

}

The following example determines the buffer size and allocates a buffer of that size:

// find the worst-case buffer size

dwCompressBufferSize = ICCompressGetSize(hIC, lpbiIn, lpbiOut);

// allocate a buffer and get lpOutput to point to it

h = GlobalAlloc(GHND, dwCompressBufferSize);

lpOutput = (LPVOID)GlobalLock(h);


Compressing a Sequence

The following fragment compresses image data for use in an AVI file. It assumes the compressor does not support VIDCF_CRUNCH or VIDCF_TEMPORAL flags, but it does support VIDCF_QUALITY.

DWORD    dwCkID;

DWORD    dwCompFlags;

DWORD    dwQuality;

LONG     lNumFrames, lFrameNum;

// assume dwNumFrames is initialized to the total number of frames

// assume dwQuality holds the proper quality value (0-10000)

// assume lpbiOut, lpOut, lpbiIn and lpIn are all initialized properly.

if (ICCompressBegin(hIC, lpbiIn, lpbiOut) == ICERR_OK){

    // If o.k. to start, compress each frame

    for ( lFrameNum = 0; lFrameNum < lNumFrames; lFrameNum++){

        if (ICCompress(hIC, 0, lpbiOut, lpOut, lpbiIn, lpIn,

            &dwCkID, &dwCompFlags, lFrameNum,

            0, dwQuality, NULL, NULL) == ICERR_OK){

            // Write compressed data to the AVI file.

            .

            .

            .

            // set lpIn to be the next frame in the sequence

        } else {

            // handle compressor error

        }

    }

    ICCompressEnd(hIC);    // terminate compression

} else {

    // handle error

}


Specifying the Input Format and Determining the Decompression Format: Examples

The following fragment shows how an application can use ICDecompressGetFormat:

LPBITMAPINFOHEADER	lpbiIn, lpbiOut;

// assume *lpbiIn points to the input (compressed) format

dwFormatSize = ICDecompressGetFormatSize(hIC, lpbiIn); // get output

                                                       // buffer size

h = GlobalAlloc(GHND, dwFormatSize);         // allocate format buffer

lpbiOut = (LPBITMAPINFOHEADER)GlobalLock(h); // lock format buffer

ICDecompressGetFormat(hIC, lpbiIn, lpbiOut); // fill the format

                                             // information

The following fragment shows how an application can use ICDecompressQuery:

LPBITMAPINFOHEADER	lpbiIn, lpbiOut;

// assume both *lpbiIn & *lpbiOut are initialized to the respective

// formats

if (ICDecompressQuery( hIC, lpbiIn, lpbiOut) == ICERR_OK){

    // format is supported - use the decompressor

}

The following fragment shows how to get the palette information:

ICDecompressGetPalette(hIC, lpbiIn, lpbiOut);

// move up to the palette

lpPalette = (LPBYTE)lpbiOut + lpbi->biSize;


Decompressing Data: An Example

The following fragment shows how an application can initialize a decompressor, decompress a frame sequence, and terminate decompression:

LPBITMAPINFOHEADER  lbpiIn, lpbiOut;

LPVOID              lpIn, lpOut;

LONG                lNumFrames, lFrameNum;

// assume lpbiIn and lpbiOut are initialized to the input and output

// format and lpIn and lpOut are pointing to the data buffers.

if (ICDecompressBegin(hIC, lpbiIn, lpbiOut) == ICERR_OK){

    for (lFrameNum = 0; lFrameNum < lNumFrames, lFrameNum++){

        if (ICDecompress(hIC, 0, lpbiIn, lpIn, lpbiOut, lpOut) == ICERR_OK){

            // frame decompressed OK so we can process it as required

        } else {

            // handle decompression error

        }

    }

    ICDecompressEnd(hIC);

} else {

    // handle error for decompression initialization

}


Determining If a Driver Can Handle the Input Format

The following fragment shows how to check the input format with ICDrawQuery:

// lpbiIn points to BITMAPINFOHEADER structure indicating the input

// format

if (ICDrawQuery(hIC, lpbiIn) == ICERR_OK){

    // driver recognizes the input format

} else {

    // we need a different decompressor

}


Preparing to Draw Data

The following fragment shows the initialization sequence to have the decompressor draw full screen:

// assume lpbiIn has the input format, dwRate has the data rate

if (ICDrawBegin(hIC, ICDRAW_QUERY|ICDRAW_FULLSCREEN, NULL, NULL,

        NULL, 0, 0, 0, 0, lpbiIn, 0, 0, 0, 0, dwRate, dwScale) == ICERR_OK){

    // decompressor supports this drawing so set up to draw.

    ICDrawBegin(hIC, ICDRAW_FULLSCREEN, hPal, NULL, NULL, 0, 0, 0, 0, lpbiIn,

        0, 0, lbpi->biWidth, lpbi->biHeight, dwRate, dwScale);

    // we're ready to start decompressing and drawing frames now

    // drawing done so terminate

    ICDrawEnd(hIC);

} else {

    // do drawing myself

}


Drawing the Data: An Example

The following fragment uses the ICDraw functions:

DWORD	dwNumBuffers;

// find out how many buffers need filling before drawing starts

ICGetBuffersWanted(hIC, &dwNumBuffers);

for (dw = 0; dw < dwNumBuffers; dw++){

ICDraw(hIC, 0, lpFormat, lpData, cbData, dw); // fill the pipeline

  // Point lpFormat and lpData to next format and data buffer

}

ICDrawStart(hIC); // start the clock

while (fPlaying){

ICDraw(hIC, 0, lpFormat, lpData, chData, dw); // fill more buffers

  // Point lpFormat and lpData to next format and data buffer, update dw

}

ICDrawStop(hIC);  // when done stop drawing and decompressing

ICDrawFlush(hIC); // flush any existing buffers

ICDrawEnd(hIC);   // end decompression


Monitoring the Progress of Compressors and Decompressors: Examples

The following fragment shows how the ICSetStatusProc function is used to inform the compressor or decompressor of the callback function address:

lpfnHook = MakeProcInstance((FARPROC) PreviewStatusProc, hInstApp);

ICSetStatusProc(compvars.hic, 0, (LPARAM) (UINT) hwndApp, lpfnHook);

The following fragment shows the callback function installed by the previous fragment:

LONG CALLBACK export PreviewStatusProc(LPARAM lParam,

                                       UINT message, LONG l)

{

    switch (message) {

MSG msg;

case ICSTATUS_START:

         .

         .

         .

     break;

case ICSTATUS_STATUS:

    ProSetBarPos((int) l); //Set status bar positions

    while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) //Watch for abort

    {

if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE)

   return 1;

if (msg.message == WM_SYSCOMMAND &&

           (msg.wParam & 0xFFF0) == SC_CLOSE)

   return 1;

TranslateMessage(&msg);

DispatchMessage(&msg);

    }

    break;

case ICSTATUS_END:

         .

         .

         .

    break;

case ICSTATUS_YIELD:

         .

         .

         .

    break;

    }

    return 0;

}


Reference

This section is an alphabetic reference to the functions and data structures provided by ICM for applications using video compression and decompression services. There are separate sections for functions and data structures.

To	See this function or data structure
Locate and open compressors and decompressors	ICInfo ICLocate ICOpen ICClose ICOpenFunction ICDecompressOpen ICDrawOpen
Let the user select the compressor	ICCompressorChoose ICCompressorFree COMPVARS
Install and remove compressors and decompressors	ICInstall ICRemove
Configure compressors and decompressors	ICQueryConfigure ICConfigure ICGetStateSize ICGetState ICSetState
Send messages to a compressor or decompressor	ICSendMessage
Get information about compressors and decompressors	ICAbout ICGetDefaultKeyFrameRate ICGetDefaultQuality ICGetDisplayFormat ICGetInfo ICQueryAbout ICINFO
Compress a single image	ICImageCompress
Compress video sequences with the ICSeqCompress functions	ICSeqCompressFrame ICSeqCompressFrameStart ICSeqCompressFrameEnd
Compress image data with the ICCompress functions	ICCompress ICCompressBegin ICCompressEnd ICCompressGetFormat ICCompressGetFormatSize ICCompressGetSize ICCompressQuery
Decompress a single image	ICImageDecompress
Decompress image data	ICDecompress ICDecompressBegin ICDecompressEnd ICDecompressGetFormat ICDecompressGetFormatSize ICDecompressGetPalette ICDecompressQuery ICDecompressEx ICDecompressExBegin ICDecompressExEnd ICDecompressExQuery
Use hardware-drawing capabilities	ICDraw ICDrawBegin ICDrawEnd ICDrawFlush ICDrawQuery ICDrawSuggestFormat ICDrawStart ICDrawStop ICGetBuffersWanted
Control drawing parameters	ICDrawGetTime ICDrawRealize ICDrawChangePalette ICDrawSetTime ICDrawWindow ICDrawRenderBuffer
Monitor the progress of a compressor or decompressor	ICSetStatusProc MyStatusProc


COMPVARS

This structure describes a compressor when using functions such as ICCompressorChoose, ICSeqCompressFrame, or ICCompressorFree.

typedef struct {

LONG cbSize;

DWORD dwFlags;

HIC hic;

DWORD fccType;

DWORD fccHandler;

LPBITMAPINFO lpbiIn;

LPBITMAPINFO lpbiOut;

LPVOID lpBitsOut;

LPVOID lpBitsPrev;

LONG lFrame;

LONG lKey;

LONG lDataRate;

LONG lQ;

LONG lKeyCount;

LPVOID lpState;

LONG cbState;

} COMPVARS;

cbSize

Set this to the size of this structure in bytes. This member must be set to validate the structure before calling any function using this structure.

dwFlags

Specifies the flag for this structure:

ICMF_COMPVARS_VALID

Indicates this structure has valid data. Set this flag if you fill out this structure manually before calling any functions. Do not set this flag if you let ICCompressorChoose initialize this structure.

hic

Specifies the handle of the compressor to use. The ICCompressorChoose function opens the chosen compressor and returns the handle to the compressor in this member. The compressor is closed by ICCompressorFree.

fccType

Specifies the type of compressor being used. Currently, only ICTYPE_VIDEO is supported. This can be set to zero.

fccHandler

Specifies the four-character code of the compressor. NULL indicates the data is not to be recompressed, and 'DIB ' indicates the data is full-framed (uncompressed). You can use this member to specify which compressor is selected by default when the dialog box is displayed.

lpbiIn

Specifies the input format. Used internally.

lpbiOut

Specifies the output format. This member is set by ICCompressorChoose. The ICSeqCompressFrameStart function uses this member to determine the compressed output format. If you do not want to use the default format, specify the preferred one.

lpBitsOut

Used internally for compression.

lpBitsPrev

Used internally for temporal compression.

lFrame

Used internally to count the number of frames compressed in a sequence.

lKey

Set by ICCompressorChoose to indicate the key-frame rate selected in the dialog box. This also specifies the rate that ICSeqCompressFrameStart uses for making key frames.

lDataRate

Set by ICCompressorChoose to indicate the data rate selected in the dialog box. The units are kilobytes per second.

lQ

Set by ICCompressorChoose to indicate the quality selected in the dialog box. This also specifies the quality ICSeqCompressFrameStart will use. ICQUALITY_DEFAULT specifies default quality.

lKeyCount

Used internally to count key frames.

lpState

Set by ICCompressorChoose to the state selected in the configuration dialog box for the compressor. The system uses this information to restore the state of the dialog box if it is redisplayed. Used internally.

cbState

Used internally for the size of the state information.


ICAbout

DWORD ICAbout(HIC hic, HWND hwnd)

This function instructs a compressor to display its About dialog box.

•	Returns ICERR_OK after the compressor displays the about dialog box. It returns ICERR_UNSUPPORTED if the compressor does not support an about dialog box.

hic

Specifies the handle to the compressor.

hwnd

Specifies a handle to the parent window.


ICClose

LRESULT ICClose(HIC hic)

This function closes a compressor or decompressor.

•	Returns ICERR_OK if successful; otherwise, it returns an error number.

hic

Specifies a handle to a compressor or decompressor.


ICCompress

DWORD ICCompress(HIC hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiOutput, LPVOID lpData, LPBITMAPINFOHEADER lpbiInput, LPVOID lpBits, LPDWORD lpckid, LPDWORD lpdwFlags, LONG lFrameNum, DWORD dwFrameSize, DWORD dwQuality, LPBITMAPINFOHEADER lpbiPrev, LPVOID lpPrev)

This function compresses a single video image.

•	This function returns ICERR_OK if successful; otherwise, it returns an error code.

hic

Specifies the handle of the compressor to use.

dwFlags

Specifies applicable flags for the compression. The following flag is defined:

ICCOMPRESS_KEYFRAME

Indicates that the compressor should make this frame a key frame.

lpbiOutput

Specifies a pointer to a BITMAPINFO structure holding the output format.

lpData

Specifies a pointer to an output data buffer.

lpbiInput

Specifies a pointer to a BITMAPINFO structure containing the input format.

lpBits

Specifies a pointer to the input data buffer.

lpckid

Not used.

lpdwFlags

Specifies a pointer to a DWORD holding the return flags used in the AVI index. The following flag is defined:

AVIIF_KEYFRAME

Indicates this frame should be used as a key frame.

lFrameNum

Specifies the frame number.

dwFrameSize

Specifies the requested frame size in bytes. If set to zero, the compressor chooses the frame size.

dwQuality

Specifies the requested quality value for the frame.

lpbiPrev

Specifies a pointer to a BITMAPINFO structure holding the previous frame's format. This parameter is not used for fast temporal compression.

lpPrev

Specifies a pointer to the previous frame's data buffer. This parameter is not used for fast temporal compression.

The lpData buffer should be large enough to hold a compressed frame. You can obtain the size of this buffer by calling ICCompressGetSize.

Set the dwFrameSize parameter to a requested frame size only if the compressor returns the VIDCF_CRUNCH flag in response to ICGetInfo. If this flag is not set, or if a data rate is not specified, set this parameter to zero.

Set the dwQuality parameter to a quality value only if the compressor returns the VIDCF_QUALITY flag in response to ICGetInfo. Without this flag, set this parameter to zero.


ICCompressBegin

DWORD ICCompressBegin(HIC hic, LPBITMAPINFOHEADER lpbiInput, LPBITMAPINFOHEADER lpbiOutput)

This function prepares a compressor for compressing data.

•	Returns ICERR_OK if the specified compression is supported; otherwise, it returns ICERR_BADFORMAT if either the input or output format is not supported.

hic

Specifies a handle to a compressor.

lpbiInput

Specifies a pointer to a BITMAPINFO structure holding the input format.

lpbiOutput

Specifies a pointer to a BITMAPINFO structure holding the output format.

Only one ICCompressBegin can be active at a time. Subsequent uses of ICCompressBegin end the currently active ICCompressBegin.


ICCompressEnd

DWORD ICCompressEnd(HIC hic)

This function ends compression by a compressor.

•	Returns ICERR_OK if successful; otherwise, it returns an error number.

hic

Specifies a handle to the compressor.


ICCompressGetFormat

DWORD ICCompressGetFormat(HIC hic, LPBITMAPINFOHEADER lpbiInput, LPBITMAPINFOHEADER lpbiOutput)

This function determines the default output format of a compressor.

•	Returns the size of the output format.

hic

Specifies a handle to a compressor.

lpbiInput

Specifies a pointer to a BITMAPINFO structure indicating the format of the input data.

lpbiOutput

Specifies a pointer to a BITMAPINFO structure used to return the output format.


ICCompressGetFormatSize

DWORD ICCompressGetFormatSize(HIC hic, LPBITMAPINFOHEADER lpbi)

This function obtains the size of the default output data format.

•	Returns the size of the output data format structure.

hic

Specifies a handle to a compressor.

lpbi

Specifies a pointer to a BITMAPINFO structure indicating the format of the input data.

Use this function to determine the size of the output format buffer you need to allocate when using ICCompressGetFormat.


ICCompressGetSize

DWORD ICCompressGetSize(HIC hic, LPBITMAPINFOHEADER lpbiInput, LPBITMAPINFOHEADER lpbiOutput)

This function obtains the size of the compressed data.

•	Returns the maximum number of bytes a single compressed frame can occupy.

hic

Specifies a handle to a compressor.

lpbiInput

Specifies a pointer to a BITMAPINFO structure indicating the format of the input data.

lpbiOutput

Specifies a pointer to a BITMAPINFO structure indicating the format of the output data.


ICCompressorChoose

BOOL ICCompressorChoose(HWND hwnd, UINT uiFlags, LPVOID pvIn, LPVOID lpData, PCOMPVARS pc, LPSTR lpszTitle)

Displays a dialog box for choosing a compressor. It optionally provides a data-rate box, key-frame box, preview window, and filtering to display only compressors that can handle a specific format.

•	Returns TRUE if the user chooses a compressor and chooses OK. Returns FALSE for an error, or if the user chooses CANCEL.

hwnd

Specifies the parent window for the dialog box.

uiFlags

Specifies flags for this function. The following flags are defined:

ICMF_CHOOSE_KEYFRAME

Displays a check box and edit box to enter the frequency of key frames.

ICMF_CHOOSE_DATARATE

Displays a check box and edit box to enter the data rate for the movie.

ICMF_CHOOSE_PREVIEW

Displays a button to expand the dialog box to include a preview window. The preview window shows how frames of your movie will appear when compressed with the current settings.

ICMF_CHOOSE_ALLCOMPRESSORS

Indicates all compressors should appear in the selection list. If this flag is not specified, only the compressors that can handle the input format appear in the selection list.

pvIn

Specifies the uncompressed data input format. This parameter is optional.

lpData

Specifies a PAVISTREAM of type stream type VIDEO to use in the preview window. This parameter is optional.

pc

Specifies a pointer to a COMPVARS structure. The information returned initializes the structure for use with other functions.

lpszTitle

Points to a optional zero-terminated string containing a title for the dialog box.

This function lets the user select a compressor from a list. Before using it, set the cbSize member of the COMPVARS structure to sizeof(COMPVARS). Initialize the rest of the structure to zeros, unless you want to specify some valid defaults for the dialog box. If specifying defaults, set the dwFlags member to ICMF_COMPVARS_VALID and initialize the other members of the structure. See ICSeqCompressFrameStart and COMPVARS for more information about initializing the structure.


ICCompressorFree

void ICCompressorFree(PCOMPVARS pc)

This function frees the resources in the COMPVARS structure used by other IC functions.

pc

Specifies a pointer to the COMPVARS structure containing the resources to be freed.

After using the ICCompressorChoose, ICSeqCompressFrameStart, ICSeqCompressFrame, and ICSeqCompressFrameEnd functions, call this function to release the resources in the COMPVARS structure.


ICCompressQuery

DWORD ICCompressQuery(HIC hic, LPBITMAPINFOHEADER lpbiInput, LPBITMAPINFOHEADER lpbiOutput)

This function determines if a compressor can compress a specific format.

•	Returns ICERR_OK if the compression is supported; otherwise, it returns ICERR_BADFORMAT.

hic

Specifies the compressor handle.

lpbiInput

Specifies a pointer to a BITMAPINFO structure indicating the format of the input data.

lpbiOutput

Specifies a pointer to a BITMAPINFO structure indicating the format of the output data. If NULL, any output format is acceptable.


ICConfigure

DWORD ICConfigure(HIC hic, HWND hwnd)

This function displays the configuration dialog box of a compressor.

•	Returns ICERR_OK after the configuration dialog box is displayed. It returns ICERR_UNSUPPORTED if the compressor does not support a a configuration dialog box.

hic

Specifies a handle to the compressor.

hwnd

Specifies a handle to the parent window.


ICDecompress

DWORD ICDecompress(HIC hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiFormat, LPVOID lpData, LPBITMAPINFOHEADER lpbi, LPVOID lpBits)

The function decompresses a single video frame.

•	Returns ICERR_OK on success; otherwise, it returns an error code.

hic

Specifies a handle to the decompressor.

dwFlags

Specifies applicable flags for decompression. The following flags are defined:

ICDECOMPRESS_HURRYUP

Indicates the decompressor should try to decompress at a faster rate. When an application uses this flag, it should not draw the decompressed data.

ICDECOMPRESS_UPDATE

Indicates that the screen is being updated.

ICDECOMPRESS_PREROLL

Indicates that this frame will not actually be drawn, because it is before the point in the movie where play will start.

ICDECOMPRESS_NULLFRAME

Indicates that this frame does not actually have any data, and the decompressed image should be left the same.

ICDECOMPRESS_NOTKEYFRAME

Indicates that this frame is not a key frame.

lpbiFormat

Specifies a pointer to a BITMAPINFO structure containing the format of the compressed data.

lpData

Specifies a pointer to the input data.

lpbi

Specifies a pointer to a BITMAPINFO structure containing the output format.

lpBits

Specifies a pointer to a data buffer for the decompressed data.

The lpBits parameter should point to a buffer large enough to hold the decompressed data.


ICDecompressBegin

DWORD ICDecompressBegin(HIC hic, LPBITMAPINFOHEADER lpbiInput, LPBITMAPINFOHEADER lpbiOutput)

This function prepares a decompressor for decompressing data.

•	Returns ICERR_OK if the specified decompression is supported; otherwise, it returns ICERR_BADFORMAT if either the input or output format is not supported.

hic

Specifies a handle to a decompressor.

lpbiInput

Specifies a pointer to a BITMAPINFO structure indicating the format of the input data.

lpbiOutput

Specifies a pointer to a BITMAPINFO structure indicating the format of the output data.


ICDecompressEnd

DWORD ICDecompressEnd(HIC hic)

This function tells a decompressor to end decompression.

•	Returns ICERR_OK if successful; otherwise, it returns an error number.

hic

Specifies a handle to a decompressor.


ICDecompressEx

DWORD ICDecompressEx(HIC hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiSrc, LPVOID lpSrc, int xSrc, int ySrc, int dxSrc, int dySrc, LPBITMAPINFOHEADER lpbiDst, LPVOID lpDst, int xDst, int yDst, int dxDst, int dyDst)

This function decompresses a single video frame.

•	Returns ICERR_OK on success; otherwise, it returns an error code.

hic

Specifies a handle to the decompressor to use.

dwFlags

Specifies applicable flags for decompression. The following flags are defined:

ICDECOMPRESS_HURRYUP

Indicates the decompressor should try to decompress at a faster rate. When an application uses this flag, it should not draw the decompressed data.

ICDECOMPRESS_UPDATE

Indicates that the screen is being updated.

ICDECOMPRESS_PREROLL

Indicates that this frame will not actually be drawn, because it is before the point in the movie where play will start.

ICDECOMPRESS_NULLFRAME

Indicates that this frame does not actually have any data, and the decompressed image should be left the same.

ICDECOMPRESS_NOTKEYFRAME

Indicates that this frame is not a key frame.

lpbiSrc

Specifies a pointer to a BITMAPINFOHEADER structure containing the format of the compressed data.

lpSrc

Specifies a pointer to the input data.

xSrc

Specifies the x-coordinate of the source rectangle, within the DIB specified by lpbiSrc.

ySrc

Specifies the y-coordinate of the source rectangle.

dxSrc

Specifies the width of the source rectangle.

dySrc

Specifies the height of the source rectangle.

lpbiDst

Specifies a pointer to a BITMAPINFOHEADER structure containing the output format.

lpDst

Specifies a pointer to a data buffer for the decompressed data.

xDst

Specifies the x-coordinate of the destination rectangle, within the DIB specified by lpbiDst.

yDst

Specifies the y-coordinate of the destination rectangle.

dxDst

Specifies the width of the destination rectangle.

dyDst

Specifies the height of the destination rectangle.

The lpDst parameter should point to a buffer large enough to hold the decompressed data.


ICDecompressExBegin

DWORD ICDecompressExBegin(HIC hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiSrc, LPVOID lpSrc, int xSrc, int ySrc, int dxSrc, int dySrc, LPBITMAPINFOHEADER lpbiDst, LPVOID lpDst, int xDst, int yDst, int dxDst, int dyDst)

This function prepares a decompressor for decompressing data.

•	Returns ICERR_OK on success; otherwise, it returns an error code.

hic

Specifies a handle to the decompressor to use.

dwFlags

Specifies applicable flags for decompression. The following flags are defined:

ICDECOMPRESS_HURRYUP

Indicates the decompressor should try to decompress at a faster rate. When an application uses this flag, it should not draw the decompressed data.

ICDECOMPRESS_UPDATE

Indicates that the screen is being updated.

ICDECOMPRESS_PREROLL

Indicates that this frame will not actually be drawn, because it is before the point in the movie where play will start.

ICDECOMPRESS_NULLFRAME

Indicates that this frame does not actually have any data, and the decompressed image should be left the same.

ICDECOMPRESS_NOTKEYFRAME

Indicates that this frame is not a key frame.

lpbiSrc

Specifies a pointer to a BITMAPINFOHEADER structure containing the format of the compressed data.

lpSrc

Specifies a pointer to the input data.

xSrc

Specifies the x-coordinate of the source rectangle, within the DIB specified by lpbiSrc.

ySrc

Specifies the y-coordinate of the source rectangle.

dxSrc

Specifies the width of the source rectangle.

dySrc

Specifies the height of the source rectangle.

lpbiDst

Specifies a pointer to a BITMAPINFOHEADER structure containing the output format.

lpDst

Specifies a pointer to a data buffer for the decompressed data.

xDst

Specifies the x-coordinate of the destination rectangle, within the DIB specified by lpbiDst.

yDst

Specifies the y-coordinate of the destination rectangle.

dxDst

Specifies the width of the destination rectangle.

dyDst

Specifies the height of the destination rectangle.

The lpDst parameter should point to a buffer large enough to hold the decompressed data.


ICDecompressExEnd

DWORD ICDecompressExEnd(HIC hic)

This function tells a decompressor to end decompression.

•	Returns ICERR_OK if successful; otherwise, it returns an error number.

hic

Specifies a handle to a decompressor.


ICDecompressExQuery

DWORD ICDecompressExQuery(HIC hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiSrc, LPVOID lpSrc, int xSrc, int ySrc, int dxSrc, int dySrc, LPBITMAPINFOHEADER lpbiDst, LPVOID lpDst, int xDst, int yDst, int dxDst, int dyDst)

This function determines if a decompressor can decompress data with a specific format.

•	Returns ICERR_OK on success; otherwise, it returns an error code.

hic

Specifies a handle to the decompressor to use.

dwFlags

Specifies applicable flags for decompression. This parameter is ignored.

lpbiSrc

Specifies a pointer to a BITMAPINFOHEADER structure containing the format of the compressed data.

lpSrc

Not used. Set to NULL.

xSrc

Specifies the x-coordinate of the source rectangle, within the DIB specified by lpbiSrc.

ySrc

Specifies the y-coordinate of the source rectangle.

dxSrc

Specifies the width of the source rectangle.

dySrc

Specifies the height of the source rectangle.

lpbiDst

Specifies a pointer to a BITMAPINFOHEADER structure containing the output format. If NULL, the function determines if the input format is supported and the other parameters are ignored.

lpDst

Specifies a pointer to a data buffer for the decompressed data.

xDst

Specifies the x-coordinate of the destination rectangle, within the DIB specified by lpbiDst.

yDst

Specifies the y-coordinate of the destination rectangle.

dxDst

Specifies the width of the destination rectangle.

dyDst

Specifies the height of the destination rectangle.

The lpDst parameter should point to a buffer large enough to hold the decompressed data.


ICDecompressGetFormat

DWORD ICDecompressGetFormat(HIC hic, LPBITMAPINFOHEADER lpbiInput, LPBITMAPINFOHEADER lpbiOutput)

This function determines the default output format of a decompressor. The default format provides the best quality output based on the input format.

•	Returns the size (in bytes) of the output format.

hic

Specifies a handle to a decompressor.

lpbiInput

Specifies a pointer to a BITMAPINFO structure indicating the format of the input data.

lpbiOutput

Specifies a pointer to a BITMAPINFO structure used to return the format of the output data.


ICDecompressGetFormatSize

DWORD ICDecompressGetFormatSize(HIC hic, LPBITMAPINFOHEADER lpbi)

This function obtains the size (in bytes) of the default output data format.

•	Returns the size of the output data format structure.

hic

Specifies a handle to a decompressor.

lpbi

Specifies a pointer to a BITMAPINFO structure indicating the format of the input data.

Use this function before ICDecompressGetFormat to find the size needed to allocate the output format buffer.


ICDecompressGetPalette

DWORD ICDecompressGetPalette(HIC hic, LPBITMAPINFOHEADER lpbiInput, LPBITMAPINFOHEADER lpbiOutput)

This function copies the color table into the output format of a decompressor.

•	Returns the size of the output format or an error code.

hic

Specifies a handle to a decompressor.

lpbiInput

Specifies a pointer to a BITMAPINFO structure indicating the format of the input data.

lpbiOutput

Specifies a pointer to a BITMAPINFO structure used to return the color table. The space reserved for the color table must be at least 256 bytes.


ICDecompressOpen

HIC ICDecompressOpen(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut)

This function opens a decompressor that can handle images with the formats specified.

•	Returns a handle to a decompressor if successful; otherwise, it returns zero.

fccType

Specifies the type of compressor the caller is trying to open. For video, this is ICTYPE_VIDEO.

fccHandler

Specifies a single, preferred handler of the given type that should be tried first. Typically, this comes from the stream header in an AVI file.

lpbiIn

Specifies a pointer to a structure defining the input format. A compressor handle will not be returned unless it can handle this format. For bitmaps, this is a BITMAPINFOHEADER structure.

lpbiOut

Specifies zero or a pointer to a structure defining an optional decompressed format. If lpbiOut is nonzero, a compressor handle will not be returned unless it can create this output format. For bitmaps, this is a BITMAPINFOHEADER structure.


ICDecompressQuery

DWORD ICDecompressQuery(HIC hic, LPBITMAPINFOHEADER lpbiInput, LPBITMAPINFOHEADER lpbiOutput)

This function determines if a decompressor can decompress data with a specific format.

•	Returns ICERR_OK if the decompression is supported; otherwise, it returns ICERR_BADFORMAT.

hic

Specifies a handle to a decompressor.

lpbiInput

Specifies a pointer to a BITMAPINFO structure indicating the format of the input data.

lpbiOutput

Specifies a pointer to a BITMAPINFO structure indicating the format of the output data. If NULL, any output format is acceptable.


ICDraw

DWORD ICDraw(HIC hic, DWORD dwFlags, LPVOID lpFormat, LPVOID lpData, DWORD cbData, LONG lTime)

This function decompresses an image for drawing.

•	Returns ICERR_OK on success; otherwise, it returns an appropriate error number.

hic

Specifies a handle to a decompressor.

dwFlags

Specifies any flags for the decompression. The following flags are defined:

ICDRAW_HURRYUP

Indicates the decompressor should just buffer the data if it needs it for decompression and not draw it to the screen.

ICDRAW_UPDATE

Tells the decompressor to update the screen based on data previously received. Set lpData to NULL when this flag is used.

ICDRAW_PREROLL

Indicates that this frame of video occurs before actual playback should start. For example, if playback is to begin on frame 10, and frame 0 is the nearest previous key frame, frames 0 through 9 are sent to the driver with the ICDRAW_PREROLL flag set. The renderer needs this data so it can display frame 10 properly, but frames 0 through 9 need not be individually displayed.

ICDRAW_NULLFRAME

Indicates that this frame does not actually have any data, and the previous frame should be redrawn.

ICDRAW_NOTKEYFRAME

Indicates that this frame is not a key frame.

lpFormat

Specifies a pointer to a BITMAPINFOHEADER structure containing the input format of the data.

lpData

Specifies a pointer to the actual input data.

cbData

Specifies the size of the input data (in bytes).

lTime

Specifies the time to draw this frame based on the time scale sent with ICDrawBegin.

This function is used to decompress the image data for drawing by the decompressor. Actual drawing of frames does not occur until ICDrawStart is called. The application should be sure to pre-buffer the required number of frames before drawing is started (you can obtain this value with ICGetBuffersWanted).


ICDrawBegin

DWORD ICDrawBegin(HIC hic, DWORD dwFlags, HPALETTE hpal, HWND hwnd, HDC hdc, int xDst, int yDst, int dxDst, int dyDst, LPBITMAPINFOHEADER lpbi, int xSrc, int ySrc, int dxSrc, int dySrc, DWORD dwRate, DWORD dwScale)

This function starts decompressing data directly to the screen.

•	Returns ICERR_OK if it can handle the decompression; otherwise, it returns ICERR_UNSUPPORTED.

hic

Specifies a handle to the decompressor to use.

dwFlags

Specifies flags for the decompression. The following flags are defined:

ICDRAW_QUERY

Determines if the decompressor can handle the decompression. The renderer does not actually decompress the data.

ICDRAW_FULLSCREEN

Tells the decompressor to draw the decompressed data on the full screen.

ICDRAW_HDC

Indicates the decompressor should use the window handle specified by hwnd and the display context handle specified by hdc for drawing the decompressed data.

ICDRAW_ANIMATE

Indicates the palette might be animated.

ICDRAW_CONTINUE

Indicates drawing is a continuation of the previous frame.

ICDRAW_MEMORYDC

Indicates the display context is offscreen.

ICDRAW_UPDATING

Indicates the frame is being updated rather than played.

hpal

Specifies a handle to the palette used for drawing.

hwnd

Specifies a handle for the window used for drawing.

hdc

Specifies the display context used for drawing.

xDst

Specifies the x-position of the upper-right corner of the destination rectangle.

yDst

Specifies the y-position of the upper-right corner of the destination rectangle.

dxDst

Specifies the width of the destination rectangle.

dyDst

Specifies the height of the destination rectangle.

lpbi

Specifies a pointer to a BITMAPINFO structure containing the format of the input data to be decompressed.

xSrc

Specifies the x-position of the upper-right corner of the source rectangle.

ySrc

Specifies the y-position of the upper-right corner of the source rectangle.

dxSrc

Specifies the width of the source rectangle.

dySrc

Specifies the height of the source rectangle.

dwRate

Specifies the data rate. The data rate in frames per second equals dwRate divided by dwScale.

dwScale

Specifies the data rate.

Decompressors use the hwnd and hdc parameters only if an application sets the ICDRAW_HDC flag in dwFlags. It will ignore these parameters if an application sets the ICDRAW_FULLSCREEN flag. When an application uses the ICDRAW_FULLSCREEN flag, it should set hwnd and hdc to NULL.

The destination rectangle is specified only if ICDRAW_HDC is used. If an application sets the ICDRAW_FULLSCREEN flag, the destination rectangle is ignored and its parameters can be set to zero.

The source rectangle is relative to the full video frame. The portion of the video frame specified by the source rectangle will be stretched to fit in the destination rectangle.


ICDrawChangePalette

DWORD ICDrawChangePalette(HIC hic, DWORD lpbiInput)

This function is sent to a renderer to inform it that the palette of the movie is changing.

•	Returns ICERR_OK if successful.

hic

Specifies a handle to a renderer.

lpbiInput

Points to a BITMAPINFO structure which contains the new format including the new color table.


ICDrawEnd

DWORD ICDrawEnd(HIC hic)

This function tells a renderer to end drawing.

•	Returns ICERR_OK if successful; otherwise, it returns an error number.

hic

Specifies a handle to a renderer.


ICDrawFlush

DWORD ICDrawFlush(HIC hic)

Flush the image buffers used for drawing.

•	Returns ICERR_OK on success.

hic

Specifies a handle to a renderer.


ICDrawGetTime

DWORD ICDrawGetTime(HIC hic, LPLONG lplTime)

This function obtains the current value of the internal clock if the renderer is handling the timing of drawing frames.

•	Returns ICERR_OK if successful.

hic

Specifies a handle to a renderer.

lplTime

Specifies a pointer to a LONG buffer used to return the current-time value. The value will be in samples (frames for video).


ICDrawOpen

HIC ICDrawOpen(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn)

This function opens a renderer that can draw images with the format specified.

•	Returns a handle to a renderer if successful; otherwise, it returns zero.

fccType

Specifies the type of renderer to open. For video, this is ICTYPE_VIDEO.

fccHandler

Specifies a single, preferred handler of the type that should be tried first. Typically, this comes from the stream header.

lpbiIn

Specifies a pointer to structure defining the input format. A renderer handle will not be returned unless it can handle this format. For images, this is a BITMAPINFOHEADER structure.


ICDrawQuery

DWORD ICDrawQuery(HIC hic, DWORD lpbiInput)

This function determines if a renderer can render data in a specific format.

•	Returns ICERR_OK if the compressor can render data in the specified format. Otherwise, it returns an error number. The following errors are defined:

ICERR_OK

No error.

ICERR_BADFORMAT

The format is not supported.

hic

Specifies a handle to a renderer.

lpbiInput

Specifies a pointer to a data structure describing the input format. For bitmaps, this is a BITMAPINFO structure.


ICDrawRealize

DWORD ICDrawRealize(HIC hic, HDC hdc, BOOL fBackground)

This function tells a renderer to realize the palette used while drawing.

•	Returns ICERR_OK if the palette is realized. The decompressor returns ICERR_UNSUPPORTED if the compressor doesn't support this function.

hic

Specifies a handle to a renderer.

hdc

Specifies the display context used to realize the palette.

fBackground

Specifies TRUE if the palette is to be realized in the background. It specifies FALSE if it is to be realized in the foreground.


ICDrawRenderBuffer

DWORD ICDrawRenderBuffer(HIC hic)

This function has a renderer draw the frames that have been passed to it.

•	None.

hic

Specifies a handle to a renderer.

This function is typically used to perform a seek operation when, instead of playing a sequence of video frames, the renderer must be specifically instructed to display a single video frame.

This function is used only by hardware that does its own asynchronous decompression, timing, and drawing.


ICDrawSetTime

DWORD ICDrawSetTime(HIC hic, LPLONG lpTime)

This function sets the value of the internal clock if the renderer is handling the timing of drawing frames.

•	Returns ICERR_OK if successful.

hic

Specifies a handle to a renderer.

lpTime

Specifies the current time that the renderer should render. This value should be in samples. For video, this corresponds to frames.


ICDrawStart

void ICDrawStart(HIC hic)

This function tells a renderer to start its internal clock for the timing of drawing frames.

hic

Specifies a handle to a renderer.

This function should only be used with renderers that do their own asynchronous decompression, timing, and drawing.


ICDrawStop

void ICDrawStop(HIC hic)

This function tells a renderer to stop its internal clock used for the timing of drawing frames.

hic

Specifies a handle to a renderer.

This function should only be used with renderers that do their own asynchronous decompression, timing, and drawing.


ICDrawSuggestFormat

DWORD ICDrawSuggestFormat(HIC hic, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, int dxSrc, int dySrc, int dxDst, int dyDst)

This function has a renderer suggest the input format for data.

•	Returns ICERR_OK on success; otherwise, it returns an error code.

hic

Specifies a handle to the renderer to use.

lpbiIn

Specifies a pointer to a structure containing the format of the compressed data. For bitmaps, this is a BITMAPINFOHEADER structure.

lpbiOut

Specifies a pointer to a structure used to return the suggested input format. (That is, a format the renderer can handle when drawing data. For bitmaps, this is a BITMAPINFOHEADER structure.

dxSrc

Specifies the width of the source rectangle.

dySrc

Specifies the height of the source rectangle.

dxDst

Specifies the width of the destination rectangle.

dyDst

Specifies the height of the destination rectangle.

Applications can use this function to determine alternate input formats to a renderer. When a renderer can handle the input format, it returns the same format for lpbiOut.

When the renderer cannot handle the format provided by an application, the application can use the ICDecompress functions to obtain alternate formats the renderer might be able to handle.

Applications can also use this function to determine if the renderer can stretch the data. If the renderer cannot stretch the data as requested, the application might have to do the stretching to use the renderer efficiently.

hicDecompressor

Specifies a decompressor which can use the format of data in lpbiIn.


ICDrawWindow

DWORD ICDrawWindow(HIC hic, LPRECT prc)

This function has a renderer redraw the window when it has moved.

•	Returns ICERR_OK if successful.

hic

Specifies a handle to a renderer.

prc

Specifies a pointer to the destination rectangle. The destination rectangle is specified in screen coordinates.

The rectangle is set to empty if the window is totally hidden by other windows.


ICGetBuffersWanted

DWORD ICGetBuffersWanted(HIC hic, LPDWORD lpdwBuffers)

This function obtains information about the pre-buffering needed by an asynchronous renderer.

•	Returns ICERR_OK if successful; otherwise, it returns ICERR_UNSUPPORTED.

hic

Specifies a handle to a renderer.

lpdwBuffers

Specifies a pointer to a DWORD used to return the number of samples the renderer needs before rendering.

This function is used only with a renderer that uses hardware to render data and must ensure that hardware pipelines remain full.


ICGetDefaultKeyFrameRate

DWORD ICGetDefaultKeyFrameRate(HIC hic)

This function obtains the default key-frame rate value.

•	Returns the default key-frame rate.

hic

Specifies a handle to a compressor.


ICGetDefaultQuality

DWORD ICGetDefaultQuality(HIC hic)

This function obtains the default quality value of a compressor.

•	Returns the default quality value.

hic

Specifies a handle to a compressor.


ICGetDisplayFormat

HIC ICGetDisplayFormat(HIC hic, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, int BitDepth, int dx, int dy)

This function returns the "best" format available to display a compressed image. The function will also open a compressor if a handle to an open compressor is not specified.

•	Returns a handle to a decompressor if successful, otherwise, it returns zero.

hic

Specifies the decompressor that should be used. If this is NULL, an appropriate compressor will be opened and returned.

lpbiIn

Specifies a pointer to a BITMAPINFOHEADER structure containing the compressed format.

lpbiOut

Specifies a pointer to a buffer used to return the decompressed format. The buffer should be large enough for a BITMAPINFOHEADER structure and 256 color entries.

BitDepth

If nonzero, specifies the preferred bit depth.

dx

If nonzero, specifies the width to which the image is to be stretched.

dy

If nonzero, specifies the height to which the image is to be stretched.


ICGetInfo

LRESULT ICGetInfo(HIC hic, ICINFO FAR * lpicinfo, DWORD cb)

This function obtains information about a compressor.

•	Return the number of bytes copied into the data structure, or zero if an error occurs.

hic

Specifies a handle to a compressor.

lpicinfo

Specifies a pointer to an ICINFO structure used to return information about the compressor.

cb

Specifies the size, in bytes, of the structure pointed to by lpicinfo.

Use ICInfo for full information about a compressor.


ICGetState

void ICGetState(HIC hic, LPVOID pv, DWORD cb)

This function gets the state of a compressor.

hic

Specifies a handle to the compressor.

pv

Specifies a pointer to a buffer used to return the state data.

cb

Specifies the byte count for the state buffer.

Use ICGetStateSize before calling ICGetState to determine the size of the buffer to allocate for the call.


ICGetStateSize

DWORD ICGetStateSize(HIC hic)

This function gets the size of the state data used by a compressor.

•	Returns the number of bytes used by the state data.

hic

Specifies a handle to the compressor.

Use this function to get the size of the state data for the ICGetState and ICSetState buffers.


ICImageCompress

HANDLE ICImageCompress(HIC hic, UINT uiFlags, LPBITMAPINFO lpbiIn, LPVOID lpBits, LPBITMAPINFO lpbiOut, LONG lQuality, LONG FAR * plSize)

This function provides a convenient method of compressing an image to a given size. This function does not require the use of initialization functions.

•	Returns a handle to a compressed DIB. The image data follows the format header.

hic

Specifies the handle to a compressor to be opened with ICOpen or NULL. Use NULL to choose a default compressor for your compression format. Applications can use the compressor handle returned by ICCompressorChoose in the hic member of the COMPVARS structure if they want the user to select the compressor. This compressor is already opened.

uiFlags

Specifies flags for this function. Set this to zero.

lpbiIn

Specifies the input data format.

lpBits

Specifies a pointer to input data bits to compress. (The data bits exclude header or format information.)

lpbiOut

Specifies the compressed output format or NULL. If NULL, the compressor uses a default format.

lQuality

Specifies the quality value of the compressor.

plSize

Specifies the maximum size desired for the compressed image. The compressor might not be able to compress the data to within this size. When the function returns, the parameter points to the size of the compressed image. Images sizes are specified in bytes.

This function returns a DIB with the format and image data. To obtain the format information from the LPBITMAPINFOHEADER structure, use GlobalLock to lock the data. Use GlobalFree to free the DIB when you have finished with it.


ICImageDecompress

HANDLE ICImageDecompress(HIC hic, UINT uiFlags, LPBITMAPINFO lpbiIn, LPVOID lpBits, LPBITMAPINFO lpbiOut)

This function provides a convenient method of decompressing an image without using initialization functions.

•	Returns a handle to an uncompressed DIB in the CF_DIB format, or NULL for an error. The image data follows the format header.

hic

Specifies the handle to a decompressor opened with ICOpen or NULL. Use NULL to choose a default decompressor for your format.

uiFlags

Specifies flags for this function. Set this to zero.

lpbiIn

Specifies the compressed input data format.

lpBits

Specifies a pointer to input data bits to compress. (The data bits exclude header or format information.)

lpbiOut

Specifies the decompressed output format or NULL. If NULL, the decompressor uses a default format.

This function returns a DIB with the format and image data. To obtain the format information from the LPBITMAPINFOHEADER structure, use GlobalLock to lock the data. Use GlobalFree to free the DIB when you have finished with it.


ICInfo

BOOL ICInfo(DWORD fccType, DWORD fccHandler, ICINFO FAR * lpicinfo)

This function returns information about specific installed compressors, or it enumerates the compressors installed.

•	Returns TRUE if successful.

fccType

Specifies a four-character code indicating the type of compressor. To match all compressor types, specify zero.

fccHandler

Specifies a four-character code identifying a specific compressor, or a number between 0 and the number of installed compressors of the type specified by fccType.

lpicinfo

Specifies a pointer to an ICINFO structure used to return information about the compressor.


ICINFO

The ICINFO structure is filled by a video compression driver when it receives the ICM_GETINFO message.

typedef struct {

DWORD dwSize;

DWORD fccType;

DWORD fccHandler;

DWORD dwFlags;

DWORD dwVersion;

DWORD dwVersionICM;

char szName[16];

char szDescription[128];

char szDriver[128];

} ICINFO;

dwSize

Should be set to the size of an ICINFO structure.

fccType

Specifies a four-character code representing the type of stream being compressed or decompressed. Set this to 'vidc' for video streams.

fccHandler

Specifies a four-character code identifying a specific compressor.

dwFlags

Specifies any flags. The following flags are defined for video compressors:

VIDCF_QUALITY

Indicates the driver supports quality values.

VIDCF_CRUNCH

Indicates the driver supports crunching to a frame size.

VIDCF_TEMPORAL

Indicates the driver supports inter-frame compression.

VIDCF_DRAW

Indicates the driver supports drawing.

VIDCF_FASTTEMPORALC

Indicates the driver can do temporal compression and doesn't need the previous frame.

VIDCF_FASTTEMPORALD

Indicates the driver can do temporal decompression and doesn't need the previous frame.

VIDCF_COMPRESSFRAMES

Indicates the driver wants the compress all frames message.

dwVersion

Specifies the version number of the driver.

dwVersionICM

Specifies the version of the ICM supported by this driver; it should be set to ICVERSION.

szName[16]

Specifies the short name for the compressor. The name in the zero-terminated string should be suitable for use in list boxes.

szDescription[128]

Specifies a zero-terminated string containing the long name for the compressor.

szDriver[128]

Specifies a zero-terminated string for the module that contains the driver. Usually, a driver will not need to fill this out.


ICInstall

BOOL ICInstall(DWORD fccType, DWORD fccHandler, LPARAM lParam, LPSTR szDesc, UINT wFlags)

This function installs a new compressor, decompressor, or renderer.

•	Returns TRUE if successful.

fccType

Specifies a four-character code indicating the type of data used by the compressor or decompressor. Use 'vidc' for a video compressor or decompressor.

fccHandler

Specifies a four-character code identifying a specific compressor or decompressor.

lParam

Specifies a pointer to a zero-terminated string containing the name of the compressor or decompressor, or a pointer to a function used for compression or decompression. The contents of this parameter are defined by the flags set for wFlags.

szDesc

Specifies a pointer to a zero-terminated string describing the installed compressor. Not use.

wFlags

Specifies flags defining the contents of lParam. The following flags are defined:

ICINSTALL_DRIVER

Indicates lParam is a pointer to a zero-terminated string containing the name of the compressor to install.

ICINSTALL_FUNCTION

Indicates lParam is a pointer to a compressor function. This function should be structured like the DriverProc entry-point function used by compressors.

An application must still open the installed compressor or decompressor before it can use the compressor or decompressor.

Usually, compressors and decompressors are installed by the user with the Drivers option of the Control Panel.

If your application installs a function as a compressor or decompressor, it should remove the compressor or decompressor with ICRemove before it terminates. This prevents other applications from trying to access the function when it is not available.


ICLocate

HIC ICLocate(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, WORD wFlags)

This function finds a compressor or decompressor that can handle images with the formats specified, or a driver that can decompress an image with a specified format directly to hardware. An application must close the compressor when it has finished using it.

•	Returns a handle to a compressor or decompressor if successful; otherwise, it returns zero.

fccType

Specifies the type of compressor the caller is trying to open. For video, this is ICTYPE_VIDEO. Other types include VIDS, TXTS, and AUDS.

fccHandler

Specifies a single, preferred handler of the given type that should be tried first. Typically, this comes from the stream header in an AVI file.

lpbiIn

Specifies a pointer to a BITMAPINFOHEADER structure defining the input format. A compressor handle will not be returned unless it can handle this format.

lpbiOut

Specifies zero or a pointer to a BITMAPINFOHEADER structure defining an optional decompressed format. If lpbiOut is nonzero, a compressor handle will not be returned unless it can create this output format.

wFlags

Specifies a flag defining the use of the compressor. This parameter must contain one of the following values:

ICMODE_COMPRESS

Indicates the compressor should be able to compress an image with a format defined by lpbiIn to the format defined by lpbiOut.

ICMODE_DECOMPRESS

Indicates the decompressor should be able to decompress an image with a format defined by lpbiIn to the format defined by lpbiOut.

ICMODE_FASTDECOMPRESS

Has the same definition as ICMODE_DECOMPRESS, except the decompressor is being used for a real-time operation and should trade off speed for quality, if possible.

ICMODE_FASTCOMPRESS

Has the same definition as ICMODE_COMPRESS, except the compressor is being used for a real-time operation and should trade off speed for quality, if possible.

ICMODE_DRAW

Indicates the decompressor should be able to decompress an image with a format defined by lpbiIn and draw it directly to hardware.


ICOpen

HIC ICOpen(DWORD fccType, DWORD fccHandler, UINT wMode)

This function opens a compressor or decompressor.

•	Returns a handle to a compressor or decompressor if successful; otherwise, it returns zero.

fccType

Specifies the type of compressor the caller is trying to open. For video, this is ICTYPE_VIDEO.

fccHandler

Specifies a single, preferred handler of the given type that should be tried first. Typically, this comes from the stream header in an AVI file.

wMode

Specifies a flag defining the use of the compressor or decompressor. This parameter can contain one of the following values:

ICMODE_COMPRESS

Advises a compressor that it is opened for compression. Some compressors can also decompress data when opened with this flag.

ICMODE_FASTCOMPRESS

Has the same definition as ICMODE_COMPRESS, except the compressor is being used for a real-time operation and should trade off speed for quality, if possible. Some compressors can also decompress data when opened with this flag.

ICMODE_DECOMPRESS

Advises a decompressor that it is opened for decompression.. Some decompressors can also compress data when opened with this flag.

ICMODE_FASTDECOMPRESS

Has the same definition as ICMODE_DECOMPRESS, except the decompressor is being used for real-time operation and should trade off speed for quality, if possible. Some decompressors can also compress data when opened with this flag.

ICMODE_DRAW

Advises a decompressor that it is opened to decompress an image and draw it directly to hardware.

ICMODE_QUERY

Advise a compressor or decompressor that it is opened to obtain information.


ICOpenFunction

HIC ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler)

This function opens a compressor or decompressor defined as a function.

•	Returns a handle to a compressor or decompressor if successful; otherwise, it returns zero.

fccType

Specifies the type of compressor the caller is trying to open. For video, this is ICTYPE_VIDEO.

fccHandler

Specifies a single, preferred handler of the given type that should be tried first. Typically, this comes from the stream header in an AVI file.

wMode

Specifies a flag to defining the use of the compressor or decompressor. This parameter can contain one of the following values:

ICMODE_COMPRESS

Advises a compressor it is opened for compression.

ICMODE_FASTCOMPRESS

Advise a compressor it is open for fast (real-time) compression.

ICMODE_DECOMPRESS

Advises a decompressor it is opened for decompression.

ICMODE_FASTDECOMPRESS

Advises a decompressor it is opened for fast (real-time) decompression.

ICMODE_DRAW

Advises a decompressor it is opened to decompress an image and draw it directly to hardware.

ICMODE_QUERY

Advise a compressor or decompressor it is opened to obtain information.

lpfnHandler

Specifies a pointer to the function used as the compressor or decompressor.


ICQueryAbout

BOOL ICQueryAbout(HIC hic)

This function determines if a compressor supports an about dialog box.

•	Returns TRUE if the compressor supports an about dialog box; otherwise, it returns FALSE.

hic

Specifies the handle to the compressor. This function should be structured like the DriverProc entry-point function used by compressors.


ICQueryConfigure

BOOL ICQueryConfigure(HIC hic)

This function determines if a compressor supports a configuration dialog box.

•	Returns TRUE if compressor supports a configuration dialog box; otherwise, it returns FALSE.

hic

Specifies a handle to the compressor.


ICRemove

BOOL ICRemove(DWORD fccType, DWORD fccHandler, UINT wFlags)

This function removes an installed compressor.

•	Returns TRUE if successful.

fccType

Specifies a four-character code indicating the type of data used by the compressor. Use 'vidc' for video compressors.

fccHandler

Specifies a four-character code identifying a specific compressor.

wFlags

Not used.


ICSendMessage

LRESULT ICSendMessage(HIC hic, UINT wMsg, DWORD dw1, DWORD dw2)

This function sends a message to a compressor.

•	Returns a message-specific result.

hic

Specifies the handle of the compressor to receive the message.

wMsg

Specifies the message to send.

dw1

Specifies additional message-specific information.

dw2

Specifies additional message-specific information.


ICSeqCompressFrame

LPVOID ICSeqCompressFrame(PCOMPVARS pc, UINT uiFlags, LPVOID lpBits, BOOL FAR * pfKey, LONG FAR * plSize)

This function compresses a frame in a sequence of frames. The data rate for the sequence, as well as the key-frame frequency, can be specified. Use this function once for each frame to be compressed.

•	Returns a pointer to the compressed bits.

pc

Specifies a pointer to a COMPVARS structure initialized with information about the compression.

uiFlags

Specifies flags for this function. Set this parameter to zero.

lpBits

Specifies a pointer the data bits to compress. (The data bits exclude header or format information.)

pfKey

Returns whether the frame was compressed into a key frame.

plSize

Specifies the maximum size for the compressed image. The compressor might not be able to compress the data to within this size. When the function returns, the parameter points to the size of the compressed image. Image sizes are specified in bytes.

Use ICCompressorChoose to let the user specify a compressor to use, or to initialize a COMPVARS structure manually. Use the ICSeqCompressFrameStart, ICSeqCompressFrame, and ICSeqCompressFrameEnd functions to compress a sequence of frames to a specified data rate and number of key frames. When finished with compression, use ICCompressorFree to release the resources specified by the COMPVARS structure.

Use this function repeatedly to compress a video sequence one frame at a time. Use this function instead of ICCompress to compress a video sequence. This function supports creating key frames in the compressed sequence at any frequency you like, and handles much of the initialization process.


ICSeqCompressFrameEnd

void ICSeqCompressFrameEnd(PCOMPVARS pc)

This function terminates sequence compression using ICSeqCompressFrame.

pc

Specifies a pointer to a COMPVARS structure used during sequence compression.

Use ICCompressorChoose to let the user specify a compressor to use, or initialize a COMPVARS structure manually. Use the ICSeqCompressFrameStart, ICSeqCompressFrame, and ICSeqCompressFrameEnd functions to compress a sequence of frames to a specified data rate and number of key frames. When finished with compression, use ICCompressorFree to release the resources specified by the COMPVARS structure.


ICSeqCompressFrameStart

BOOL ICSeqCompressFrameStart(PCOMPVARS pc, LPBITMAPINFO lpbiIn)

This function initializes the system prior to using ICSeqCompressFrame.

•	Returns TRUE if successful; otherwise it returns FALSE.

pc

Specifies a pointer to a COMPVARS structure initialized with information for compression.

lpbiIn

Specifies the format of the data to be compressed.

Prior to using this function, use ICCompressorChoose to let the user specify a compressor, or to initialize a COMPVARS structure manually. Use the ICSeqCompressFrameStart, ICSeqCompressFrame, and ICSeqCompressFrameEnd to compress a sequence of frames to a specified data rate and number of key frames. When finished compressing data, use ICCompressorFree to release the resources specified in the COMPVARS structure.

If you do not use ICCompressorChoose, you must initialize the following members of the COMPVARS structure:

cbSize

Set to the sizeof(COMPVARS) to validate the structure.

hic

Set to the handle of a compressor you have opened with ICOpen. You do not need to close it (ICCompressorFree will do this for you).

lpbiOut

Optionally set this to force the compressor to compress to a specific format instead of the default. This will be freed by ICCompressorFree.

lKey

Set this to the key-frame frequency you want or zero for none.

lQ

Set this to the quality level to use or ICQUALITY_DEFAULT.

dwFlags

Set ICMF_COMPVARS_VALID flag to indicate the structure is initialized.


ICSetState

void ICSetState(HIC hic, LPVOID pv, DWORD cb)

This function sets the state of a compressor.

hic

Specifies a handle to the compressor.

pv

Specifies a pointer to the state data to set.

cb

Specifies the size (in bytes) of the buffer containing the state data.


ICSetStatusProc

DWORD ICSetStatusProc(HIC hic, DWORD dwFlags, LONG lParam, LONG (CALLBACK * ()) fpfnStatus)

This function sends the address of a status callback function to a compressor. The compressor will call this function during length operations.

•	Returns ICERR_OK if successful.

hic

Specifies the compressor handle.

dwFlags

Specifies any flags. Set to zero.

lParam

Specifies a constant which will be passed back to the status function when it is called.

fpfnStatus

Specifies a pointer to your status function. Note that this can be NULL, indicating that no status callbacks should be sent.


MyStatusProc

LONG MyStatusProc(LPARAM lParam, UINT message)

This is the prototype for a status function used by the ICM_SET_STATUS_PROC message and the ICSetStatusProc function.

•	Return zero if processing should continue, or a nonzero value if it should end.

lParam

Contains the constant specified with the status callback address was set.

message

Specifies one of the following values:

ICSTATUS_START

Indicates a lengthy operation is starting.

ICSTATUS_STATUS

Indicates the operation is proceeding, and is l percent done.

ICSTATUS_END

Indicates a lengthy operation is finishing.

ICSTATUS_YIELD

Indicates a length operation is proceeding. Essentially, this is just the same as ICSTATUS_STATUS without a specific percentage value.


Audio Compression Manager


About the Audio Compression Manager

The multimedia services of the Microsoft Win32 application programming interface (API) provide extensible, device-independent audio support. Extensibility allows the architecture to support new technology without changing the architecture itself. Device independence makes it easier for you to develop multimedia applications that run on a wide range of hardware and provide varying levels of multimedia support.

The Audio Compression Manager (ACM) extends the basic audio architecture, adding system-level support for the following services:

•	Transparent run-time audio compression and decompression

•	Wave-data format selection

•	Wave-data filter selection

•	Wave-data format conversion

•	Wave-data filtering

This chapter describes the services available in the ACM and explains the programming techniques used to access these services. Before reading this chapter, you should be familiar with the audio capabilities available through the multimedia services of the Win32 API.  For information about these services, see the Microsoft Win32 Programmer's Reference.

This chapter includes the following topics:

•	Information about the ACM

•	Examples of how to use the ACM functions in applications

•	An alphabetic reference to the ACM functions and data structures


The ACM and System Support

The Win32 API provides a set of standard functions for audio devices. These functions issue calls to device drivers that manage hardware devices. The system uses a module called a mapper to manage installed devices. The mapper uses special hooks in the driver interface to intercept calls and to act between the system and the drivers installed in the system. The mapper is responsible for matching device-access requests from applications with available devices. It is the mapper's responsibility to find a device that meets the current application's audio requirements. There are mapper devices for standard driver types: WAVE, MIDI, and AUX.

The ACM is an extension of the basic multimedia system and is installed as a mapper. This means the ACM uses the driver-interface mapper hooks for wave devices. Using these hooks allows the ACM to decode or encode wave data before passing it to or from a wave device driver. The difference between the ACM and the standard system mapper is that the ACM can search for a wave device that supports a given format, or find a combination of awave device and an ACM compressor or decompressor that support a given format.

When an application asks the system to open a wave device for input or output, the request specifies the format and device. When the specified device is the mapper or the ACM, then the mapper (or the ACM) must find a device that supports the given format. The remainder of this discussion assumes the ACM is the specified device.

First, the ACM searches for an installed, available hardware device that supports the given format. If the ACM cannot find such a device, it searches for a wave device and compressor or decompressor that together support the format. Specifically, the ACM searches for a compressor or decompressor that converts the specified format into a format that is supported by an installed hardware device. After the ACM finds a device that supports the converted format, it can honor requests to play or record the format originally requested, even though no installed wave device directly supports that format.

The ACM also offers additional services to support compression, decompression, filtering, format selection, and filter selection. It provides a standard API set that it supports by calling its own drivers.

In addition to the functions and services the ACM adds, the ACM is accessible as the Sound Mapper in the Control Panel. So, if you use the Sound Mapper to choose or activate a device, you are using the ACM mapping services.


How the ACM Works

The ACM uses existing driver interface hooks to override the default mapping algorithm for wave devices. This allows the ACM to intercept device-open calls. After a call has been intercepted, the ACM can perform a variety of tasks to process the audio data, such as inserting an external compressor or decompressor into the sequence.

The ACM manages the following types of drivers:

•	Compressor and decompressor (codec) drivers

•	Format-converter drivers

•	Filter drivers

Compressor and decompressor modules change one format type to another. For example, a compressor or decompressor module can change a PCM file to an ADPCM file. Format converter modules change the format, but not the data type. For example, a converter module can change 44-kHz, 16-bit data to 44-kHz, 8-bit data. Filters do not change the data format at all, but change the wave data in some manner. For example, a filter could mix together a data stream and an echo of itself. A single ACM driver, or a filter tag or format tag within a driver, might also support combinations of the above types.

For wave output, the ACM passes each buffer to the converter as it arrives. The converter decompresses the data and returns the decompressed data to ACM in a "shadow" buffer. The ACM then passes the decompressed shadow buffer to the wave driver. The ACM allocates the shadow buffers whenever it receives a prepare message.

For wave input, the ACM passes empty shadow buffers to the driver. It uses a background task to receive non-interrupt time notification after the driver has filled the shadow buffer. The ACM then passes the buffers to the driver for compression. After compression is finished, the driver passes the data to the application.


Using the Audio Compression Manager

The ACM is active in any of the following circumstances:

•	Your application uses an ACM-specific function, message, or structure.

•	You use the Sound Mapper in Control Panel to select an audio device.

•	Your application performs a task that involves an ACM-specific service.

The following sections describe typical tasks that involve the ACM services. Many of these sections suggest specific functions to help you accomplish your goal.


Using Callback Functions

Callback functions are functions in your application that the system calls in response to a request made by an application. In the reference section of this chapter, the prototype of the callback is alphabetized with the other API descriptions.

All callback functions must be properly set up to operate correctly. Upon entering the callback function, the context of the application must be set up. The application can do this by properly declaring the function for export.

Most of the enumeration functions in the ACM use callback functions. For example, when you call an enumeration function, the ACM enumerates the items by repeatedly calling the application through the callback.

There are certain APIs which cannot be called from within callback functions, because they manipulate internal ACM structures which are used by the enumeration functions.  The following functions should not be called from within a callback function: acmDriverAdd, acmDriverRemove, acmDriverPriority.


Getting a String That Describes a Filter

Often, an application needs to display a string that describes the current format. This can be done very easily with the acmFilterTagDetails and acmFilterDetails functions. These functions must be called with the appropriate filter or filter tag. The following code segment provides an example of how to use these functions:

BOOL GetFilterDescription

(

    LPWAVEFILTER	pwfltr,

    LPTSTR	pszFilterTag,

    LPTSTR	pszFilter

)

{

    MMRESULT	mmr;

    //

    //  get the name for the filter tag of the specified filter

    //

    if (NULL != pszFilterTag)

    {

        ACMFILTERTAGDETAILS aftd;

        //

        //  initialize all unused members of the ACMFILTERTAGDETAILS

        //  structure to zero

        //

        memset(&aftd, 0, sizeof(aftd));

        //

        //  fill in the required members of the ACMFILTERTAGDETAILS

        //  structure for the ACM_FILTERTAGDETAILSF_FILTERTAG query

        //

        aftd.cbStruct    = sizeof(aftd);

        aftd.dwFilterTag = pwfltr->dwFilterTag;

        //

        //  ask the ACM to find the first available driver that

        //  supports the specified filter tag

        //

        mmr = acmFilterTagDetails(NULL,

                                  &aftd,

                                  ACM_FILTERTAGDETAILSF_FILTERTAG);

        if (MMSYSERR_NOERROR != mmr)

        {

            //

            //  no ACM driver is available that supports the

            //  specified filter tag

            //

            return (FALSE);

        }

        //

        //  copy the filter tag name into the caller's buffer

        //

        lstrcpy(pszFilterTag, aftd.szFilterTag);

    }

    //

    //  get the description of the attributes for the specified

    //  filter

    //

    if (NULL != pszFilter)

    {

        ACMFILTERDETAILS    afd;

        //

        //  initialize all unused members of the ACMFILTERDETAILS

        //  structure to zero

        //

        memset(&afd, 0, sizeof(afd));

        //

        //  fill in the required members of the ACMFILTERDETAILS

        //  structure for the ACM_FILTERDETAILSF_FILTER query

        //

        afd.cbStruct    = sizeof(afd);

        afd.dwFilterTag = pwfltr->dwFilterTag;

        afd.pwfltr      = pwfltr;

        afd.cbwfltr     = pwfltr->cbStruct;

        //

        //  ask the ACM to find the first available driver that

        //  supports the specified filter

        //

        mmr = acmFilterDetails(NULL, &afd, ACM_FILTERDETAILSF_FILTER);

        if (MMSYSERR_NOERROR != mmr)

        {

            //

            //  no ACM driver is available that supports the

            //  specified filter

            //

            return (FALSE);

        }

        //

        //  copy the filter attributes description into the caller's

        //  buffer

        //

        lstrcpy(pszFilter, afd.szFilter);

    }

    //

    //  succeed the call

    //

    return (TRUE);

}


Producing a Dialog to Select a Filter

Your application could allow users to select an arbitrary filter operation and apply it to wave data. These functions must be called with the appropriate filter or filter tag. In the following example, the application allocates a buffer to hold the filter, and then uses the acmFilterChoose API to select the filter.

   . . .

    MMRESULT            mmr;

    ACMFILTERCHOOSE     afc;

    PWAVEFILTER         pwfltr;

    DWORD               cbwfltr;

    //

    //  Determine the maximum size required for any valid filter

    //  for which the ACM has a driver installed and enabled.

    //

    mmr = acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FILTER, &cbwfltr);

    if (MMSYSERR_NOERROR != mmr)

    {

        //

        //  the ACM most likely has no drivers installed and

        //  enabled for filter operations.

        //

        return (mmr);

    }

    //

    //  Dynamically allocate a structure large enough to hold the

    //  maximum sized filter enabled in the system.

    //

    pwfltr = (PWAVEFILTER)LocalAlloc(LPTR, (UINT)cbwfltr);

    if (NULL == pwfltr)

    {

        return (MMSYSERR_NOMEM);

    }

    //

    //  Initialize the ACMFILTERCHOOSE members.

    //

    memset(&afc, 0, sizeof(afc));

    afc.cbStruct    = sizeof(afc);

    afc.fdwStyle    = 0L;               // no special style flags

    afc.hwndOwner   = hwnd;             // hwnd of parent window

    afc.pwfltr      = pwfltr;           // wfltr to receive selection

    afc.cbwfltr     = cbwfltr;          // size of wfltr buffer

    afc.pszTitle    = TEXT("Any Filter Selection");

    //

    //  Call the ACM to bring up the filter selection dialog.

    //

    mmr = acmFilterChoose(&afc);

    if (MMSYSERR_NOERROR == mmr)

    {

        //

        //  The user selected a valid filter. The pwfltr buffer,

        //  allocated above, contains the complete filter description.

        //

    }

    //

    //  Clean up and exit.

    //

    LocalFree((HLOCAL)pwfltr);

    return (mmr);

    . . .


Producing a Dialog to Select a Specific Type of Format

You might want your application to have the user select a format from a restricted list of formats. Restrictions might limit the number of channels, the sampling rate, the wave format tag, or bits per sample. In all of these cases, the list can be automatically generated by the acmFormatChoose function. The fdwEnum and pwfxEnum fields of the ACMFORMATCHOOSE structure are used for this.

The following sample illustrates this process:

    . . .

    MMRESULT            mmr;

    ACMFORMATCHOOSE     afc;

    WAVEFORMATEX        wfxSelection;

    WAVEFORMATEX        wfxEnum;

    //

    //  initialize the ACMFORMATCHOOSE members

    //

    memset(&afc, 0, sizeof(afc));

    afc.cbStruct    = sizeof(afc);

    afc.fdwStyle    = 0L;               // no special style flags

    afc.hwndOwner   = hwnd;             // hwnd of parent window

    afc.pwfx        = &wfxSelection;    // wfx to receive selection

    afc.cbwfx       = sizeof(wfxSelection);

    afc.pszTitle    = TEXT("16 Bit PCM Selection");

    //

    //  request all 16 bit PCM formats to be displayed for the user

    //  to select from.

    //

    memset(&wfxEnum, 0, sizeof(wfxEnum));

    wfxEnum.wFormatTag     = WAVE_FORMAT_PCM;

    wfxEnum.wBitsPerSample = 16;

    afc.fdwEnum     = ACM_FORMATENUMF_WFORMATTAG |

                      ACM_FORMATENUMF_WBITSPERSAMPLE;

    afc.pwfxEnum    = &wfxEnum;

    //

    //

    //

    mmr = acmFormatChoose(&afc);

    if ((MMSYSERR_NOERROR != mmr) && (ACMERR_CANCELED != mmr))

    {

        //

        //  there was a fatal error in bringing up the chooser

        //  dialog--probably invalid input parameters.

        //

    }

    . . .


Producing a Dialog with Restricted Formats

You might want to use the acmFormatChoose dialog, but limit or control the formats in the dialog. The application can filter the formats by responding to the MM_ACM_FORMATCHOOSE message in the message procedure for the dialog. Use the ACMFORMATCHOOSE_STYLEF_ENABLEHOOK flag to hook the dialog procedure. Respond to the message and give the appropriate return values.


Producing a Dialog to Select a Format for Saving

You might want your application to save existing wave data in another format. For example, a wave editor might save the current file as a compressed file. You can use the acmFormatChoose dialog box to list only the formats that are suggested destination formats for a given source format. To do so, specify the source format in the pwfxEnum member of the ACMFORMATCHOOSE structure and set the ACM_FORMATENUMF_SUGGEST flag in the fdwEnum member of the ACMFORMATCHOOSE structure.

Similarly, the dialog could list valid destination formats for a given format. In this case, use the ACM_FORMATENUMF_CONVERT flag instead of the ACM_FORMATENUMF_SUGGEST flag.


Producing a Dialog to Select a Format for Recording

An application can allow the user to select a format for which an installed wave device provides native support. For example, you might want a wave editor to record new wave data without using an ACM compressor or decompressor to provide a translation layer.

To do this, use the acmFormatChoose function. Specify the ACM_FORMATENUMF_HARDWARE and ACM_FORMATENUMF_INPUT flags in the fdwEnum member of the ACMFORMATCHOOSE structure.


Converting Data from One Format to Another

Data conversion is one of the services available through the ACM. The Stream functions support data format conversion. Converter modules in the ACM change the format, but not the data type. For example, a converter module can change 44-kHz, 16-bit data to 44-kHz, 8-bit data.

The following ACM functions support data format conversion. They are listed in the order you might typically use them.

•	The acmStreamOpen function opens a channel for conversion.

•	The acmStreamSize function calculates the appropriate size of the source or the destination buffer.

•	The acmStreamPrepareHeader function prepares buffers to be used in a conversion.

•	The acmStreamConvert function converts the source data into the destination format, writing the converted data into the destination buffer.

•	The acmStreamUnprepareHeader function cleans up the preparation performed by acmStreamPrepareHeader. This function must be called before freeing the source and destination buffers.

•	The acmStreamClose function closes a conversion channel.

As an example of using these functions, assume that your goal is to convert data in PCM format to some other format.

The first task, identifying the source format, is already complete — it's a PCM file. The next task is to choose the destination format. The easiest way to do this is through the acmFormatChoose function, which displays a format-selection dialog and returns the user's choice.

Once you know the source and destination formats, you can use the acmStreamOpen function to open a conversion stream. Then you can use the acmStreamSize function to determine the appropriate buffer sizes.

The next step is to prepare the buffers to be used in the conversion, using acmStreamPrepareHeader.

To perform the conversion, call the acmStreamConvert function until all the buffers have been processed. When the conversion is complete, use the acmStreamUnprepareHeader function to clean up the buffers, then use the acmStreamClose function to close the conversion stream.


Multi-Step Format Conversion

Sometimes the ACM cannot convert from one format to another in a single step. For example, an application might need to convert 16-bit, 44-kHz stereo data to 11-kHz mono ADPCM. If the compressor or decompressor cannot do this conversion directly, the application might attempt it in two steps. This usually means making one conversion between two PCM formats, and another to the final format type.

To do this, you can use the acmFormatSuggest API to find a PCM format that matches the ADPCM format. Then, use two conversion streams to perform the conversion. For example, perform one conversion from 16-bit, 44-kHz stereo PCM to 16-bit, 11-kHz mono, then convert from 16-bit, 11-kHz mono to 11-kHz mono ADPCM.

Another example of multi-step conversion is the case when either the source or the destination format is not PCM. If the source format is not PCM, it should be converted to a PCM format before conversion. If the destination format is not PCM, the source must be converted to an intermediate PCM format and then to the final destination format.

The most straightforward conversions occur when the source and destination formats are both PCM formats. When either the source or destination format is non-PCM, the conversion may require an additional step. If both source and destination formats are non-PCM, the conversion will usually require more than one step, and in some instances might not be possible.


Finding a Specific Format

An application might have only partial specification for a format when it needs the full specification. For example, an application might know that it wants an 11-kHz mono, 4-bit ADPCM format, but not know the details of the rest of the format, such as average bytes per second. The application can get the full format without user intervention by enumerating all the formats of that type and selecting the best one.

This is done with the acmFormatEnum function and the flags in the fdwEnum parameter.


Finding a Specific Driver

An application might want to send a message directly to a specific driver, or to identify certain drivers from the list.  For example, you might want to identify those drivers which support filters, and then query each driver to determine which filter tags it supports.  You can use the acmDriverEnum function to obtain a handle to the desired driver or drivers; this handle can then be used to communicate with that driver.

Note that when an application installs a local driver for its own use, the acmDriverAdd function returns a handle to that driver which can be used to communicate with it.  It is not necessary to use acmDriverEnum in this case.


Generating a Custom Format

Sometimes an application needs a nonstandard format. For example, an application might need a 16-kHz ADPCM-format file. Because 16 kHz is nonstandard, the enumeration functions will not generate such a format. In fact, short of custom coding the format knowledge into the application, there is no way to reliably generate an arbitrary format. However, it might be possible to generate an analogous format from a PCM format.

This is done by setting up a valid PCM format with all the required information, and then using the acmFormatSuggest API. Compressors and decompressors will try to suggest the format that is closest to the given format. This usually means the number of channels and frequency are preserved.


Reference

The ACM functions fall into several categories. Naming conventions for the functions make it easy to identify these categories. Function names (with two exceptions) are of the form acmGroupFunction, where Group will be one of Driver, Format, FormatTag, Filter, FilterTag or Stream.

Note the parallel nature of the functions in the filter and format groups. Almost every function that acts on filters has a parallel function that acts on formats.

In the format group, some functions refer to wave format tags (the wFormatTag field of a WAVEFORMATEX structure) while others refer to full wave formats (the full WAVEFORMATEX structure).

In the filter group, some functions concern wave filter tags (the dwFilterTag field of a WAVEFILTER structure) and others concern full wave filters (the full WAVEFILTER structure).

The functions in the stream group reflect the fact that a conversion involves several steps: opening a conversion instance, preparing for the conversion, performing conversions, cleaning up after the conversion is complete, and closing the conversion instance.

The following table identifies the messages, functions, and structures in each group.

This group	Includes these functions, messages, and structures
Driver: add, remove, enumerate, open, close, send messages to, and get information from drivers	acmDriverAdd acmDriverClose ACMDRIVERDETAILS acmDriverDetails acmDriverEnum acmDriverEnumCallback acmDriverID acmDriverMessage acmDriverOpen acmDriverPriority acmDriverProc acmDriverRemove
Format: enumerate, select, and get information about wave formats	acmFormatChoose ACMFORMATCHOOSE acmFormatChooseHookProc acmFormatDetails ACMFORMATDETAILS acmFormatEnum acmFormatEnumCallback acmFormatTagDetails acmFormatTagEnum acmFormatTagEnumCallback ACMFORMATTAGDETAILS MM_ACM_FORMATCHOOSE WAVEFORMATEX
Filter: enumerate, select, and get information about wave filters	acmFilterChoose ACMFILTERCHOOSE acmFilterChooseHookProc acmFilterDetails ACMFILTERDETAILS acmFilterEnum acmFilterEnumCallback acmFilterTagDetails ACMFILTERTAGDETAILS acmFilterTagEnum acmFilterTagEnumCallback MM_ACM_FILTERCHOOSE WAVEFILTER
Stream: manage wave format conversion and wave filtering	acmFormatSuggest ACMSTREAMHEADER acmStreamOpen acmStreamSize acmStreamPrepareHeader acmStreamConvert acmStreamConvertCallback acmStreamReset acmStreamUnprepareHeader acmStreamClose
General	acmGetVersion acmMetrics


acmDriverAdd

MMRESULT acmDriverAdd(LPHACMDRIVERID phadid, HINSTANCE hinstModule, LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)

This function adds a driver to the list of available Audio Compression Manager (ACM) drivers. The driver type and location are dependent on the fdwAdd flags. After a driver is successfully added, the driver entry function will receive ACM driver messages.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_INVALPARAM

One or more arguments passed is invalid.

MMSYSERR_NOMEM

Unable to allocate resources.

phadid

Specifies a pointer to an HACMDRIVERID handle. This location is filled with a handle identifying the installed driver. Use the handle to identify the driver when calling other ACM functions.

hinstModule

Identifies the instance of the module whose executable or dynamic link library (DLL) contains the driver entry function.

lParam

lParam is a handle to an installable driver or a driver function address, depending on the fdwAdd flags.

dwPriority

This parameter is currently only used with the ACM_DRIVERADDF_NOTIFYHWND flag to specify the window message to send for notification broadcasts. All other flags require that this member be set to zero.

fdwAdd

Specifies flags for adding ACM drivers.

ACM_DRIVERADDF_GLOBAL

This flag is provided for compatibility with 16-bit applications.  In Win32, ACM drivers added by the acmDriverAdd function can only be used by the application which added the driver.  This is true whether or not ACM_DRIVERADDF_GLOBAL is specified.

ACM_DRIVERADDF_FUNCTION

Specifies that lParam is a driver function address conforming to the acmDriverProc prototype. The function can reside in either an executable or a DLL. If the ACM_DRIVERADDF_GLOBAL flag is specified, then the function must reside in a .DLL.

ACM_DRIVERADDF_NOTIFYHWND

Specifies that lParam is a notification window handle to receive messages when changes to global driver priorities and states are made. The window message to receive is defined by the application and must be passed in the dwPriority argument. The wParam and lParam arguments passed with the window message are reserved for future use and should be ignored. The ACM_DRIVERADDF_GLOBAL flag cannot be specified in conjunction with the ACM_DRIVERADDF_NOTIFYHWND flag. For more information about driver priorities, see the description of acmDriverPriority later in this chapter.


acmDriverClose

MMRESULT acmDriverClose(HACMDRIVER had, DWORD fdwClose)

This function closes a previously opened Audio Compression Manager (ACM) driver instance. If the function is successful, the handle is invalidated.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

ACMERR_BUSY

The driver is in use and cannot be closed.

had

Identifies the open driver instance to be closed.

fdwClose

This argument is not used and must be set to zero.


ACMDRIVERDETAILS

The ACMDRIVERDETAILS structure describes various details of an Audio Compression Manager (ACM) driver.

typedef struct {

DWORD cbStruct;

FOURCC fccType;

FOURCC fccComp;

WORD wMid;

WORD wPid;

DWORD vdwACM;

DWORD vdwDriver;

DWORD fdwSupport;

DWORD cFormatTags;

DWORD cFilterTags;

HICON hicon;

TCHAR szShortName[ACMDRIVERDETAILS_SHORTNAME_CHARS];

TCHAR szLongName[ACMDRIVERDETAILS_LONGNAME_CHARS];

TCHAR szCopyright[ACMDRIVERDETAILS_COPYRIGHT_CHARS];

TCHAR szLicensing[ACMDRIVERDETAILS_LICENSING_CHARS];

TCHAR szFeatures[ACMDRIVERDETAILS_FEATURES_CHARS];

} ACMDRIVERDETAILS;

cbStruct

Specifies the size, in bytes, of the valid information contained in the ACMDRIVERDETAILS structure. An application should initialize this member to the size, in bytes, of the information. The size specified in this member must be large enough to contain the cbStruct member of the ACMDRIVERDETAILS structure. When the acmDriverDetails function returns, this member contains the actual size of the information returned. The returned information will never exceed the requested size.

fccType

Specifies the type of the driver. For ACM drivers, set this member to audc, which represents ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC.

fccComp

Specifies the sub-type of the driver. This member is currently set to ACMDRIVERDETAILS_FCCCOMP_UNDEFINED (zero).

wMid

Specifies a manufacturer ID for the ACM driver.

wPid

Specifies a product ID for the ACM driver.

vdwACM

Specifies the version of the ACM for which this driver was compiled. The version number is a hexadecimal number in the format 0xAABBCCCC, where AA is the major version number, BB is the minor version number, and CCCC is the build number. Note that the version parts (major, minor, and build) should be displayed as decimal numbers.

vdwDriver

Specifies the version of the driver. The version number is a hexadecimal number in the format 0xAABBCCCC, where AA is the major version number, BB is the minor version number, and CCCC is the build number. Note that the version parts (major, minor, and build) should be displayed as decimal numbers.


fdwSupport

Specifies support flags for the driver.

ACMDRIVERDETAILS_SUPPORTF_CODEC

Specifies that this driver supports conversion between two different format tags. For example, if a driver supports compression from WAVE_FORMAT_PCM to WAVE_FORMAT_ADPCM, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_CONVERTER

Specifies that this driver supports conversion between two different formats of the same format tag. For example, if a driver supports resampling of WAVE_FORMAT_PCM, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_FILTER

Specifies that this driver supports a filter (modification of the data without changing any of the format attributes). For example, if a driver supports volume or echo operations on WAVE_FORMAT_PCM, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_HARDWARE

Specifies that this driver supports hardware input and/or output through a waveform device. An application should use acmMetrics with the ACM_METRIC_HARDWARE_WAVE_INPUT and ACM_METRIC_HARDWARE_WAVE_OUTPUT metric indexes to get the waveform device identifiers associated with the supporting ACM driver.

ACMDRIVERDETAILS_SUPPORTF_DISABLED

Specifies that this driver has been disabled. This flag is set by the ACM for a driver when it has been disabled for any of a number of reasons. Disabled drivers cannot be opened and can only be used under very limited circumstances.

cFormatTags

Specifies the number of unique format tags supported by this driver.

cFilterTags

Specifies the number of unique filter tags supported by this driver.

hicon

Specifies an optional handle to a custom icon for this driver. An application can use this icon for referencing the driver visually. This member can be NULL.

szShortName[ACMDRIVERDETAILS_SHORTNAME_CHARS]

Specifies a null-terminated string that describes the name of the driver. This string is intended to be displayed in small spaces.

szLongName[ACMDRIVERDETAILS_LONGNAME_CHARS]

Specifies a null-terminated string that describes the full name of the driver. This string is intended to be displayed in large (descriptive) spaces.

szCopyright[ACMDRIVERDETAILS_COPYRIGHT_CHARS]

Specifies a null-terminated string that provides copyright information for the driver.

szLicensing[ACMDRIVERDETAILS_LICENSING_CHARS]

Specifies a null-terminated string that provides special licensing information for the driver.

szFeatures[ACMDRIVERDETAILS_FEATURES_CHARS]

Specifies a null-terminated string that provides special feature information for the driver.


acmDriverDetails

MMRESULT acmDriverDetails(HACMDRIVERID hadid, LPACMDRIVERDETAILS padd, DWORD fdwDetails)

This function queries a specified Audio Compression Manager (ACM) driver to determine its capabilities.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALPARAM

One or more arguments passed is invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

hadid

Handle to the driver identifier of an installed ACM driver. Disabled drivers can be queried for details.

padd

Pointer to an ACMDRIVERDETAILS structure that will receive the driver details. The cbStruct member must be initialized to the size, in bytes, of the structure.

fdwDetails

This argument is not used and must be set to zero.


acmDriverEnum

MMRESULT acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)

The acmDriverEnum function enumerates the available Audio Compression Manager (ACM) drivers, continuing until there are no more ACM drivers or the callback function returns FALSE.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

fnCallback

Specifies the procedure-instance address of the application-defined callback function.

dwInstance

Specifies a 32-bit application-defined value that is passed to the callback function along with ACM driver information.

fdwEnum

Specifies flags for enumerating ACM drivers.

ACM_DRIVERENUMF_DISABLED

Specifies that disabled ACM drivers should be included in the enumeration. Drivers can be disabled through the Sound Mapper Control Panel option. If a driver is disabled, the fdwSupport argument to the callback function will have the ACMDRIVERDETAILS_SUPPORTF_DISABLED flag set.

The acmDriverEnum function will return MMSYSERR_NOERROR (zero) if no ACM drivers are installed. Moreover, the callback function will not be called.


acmDriverEnumCallback

BOOL ACMDRIVERENUMCB acmDriverEnumCallback(HACMDRIVERID hadid, DWORD dwInstance, DWORD fdwSupport)

The acmDriverEnumCallback function is a placeholder for an application-defined function name, and refers to the callback function used with acmDriverEnum.

•	The callback function must return TRUE to continue enumeration; to stop enumeration, it must return FALSE.

hadid

Specifies an ACM driver identifier.

dwInstance

Specifies the application-defined value specified in the acmDriverEnum function.

fdwSupport

Specifies driver-support flags specific to the driver identifier hadid. These flags are identical to the fdwSupport flags of the ACMDRIVERDETAILS structure. This argument can be a combination of the following values:

ACMDRIVERDETAILS_SUPPORTF_CODEC

Specifies that this driver supports conversion between two different format tags. For example, if a driver supports compression from WAVE_FORMAT_PCM to WAVE_FORMAT_ADPCM, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_CONVERTER

Specifies that this driver supports conversion between two different formats of the same format tag. For example, if a driver supports resampling of WAVE_FORMAT_PCM, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_FILTER

Specifies that this driver supports a filter (modification of the data without changing any of the format attributes). For example, if a driver supports volume or echo operations on WAVE_FORMAT_PCM, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_DISABLED

Specifies that this driver has been disabled. An application must specify the ACM_DRIVERENUMF_DISABLED to the acmDriverEnum function to include disabled drivers in the enumeration.

The acmDriverEnum function will return MMSYSERR_NOERROR (zero) if no ACM drivers are installed. Moreover, the callback function will not be called.

Note the following functions should not be called from within the callback function: acmDriverAdd, acmDriverRemove, acmDriverPriority.


acmDriverID

MMRESULT acmDriverID(HACMOBJ hao, LPHACMDRIVERID phadid, DWORD fdwDriverID)

This function returns the handle to an Audio Compression Manager (ACM) driver identifier associated with an open ACM driver instance or stream handle. HACMOBJ is the handle to an ACM object, such as an open HACMDRIVER or HACMSTREAM.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

hao

Specifies the open driver instance or stream handle.

phadid

Specifies a pointer to an HACMDRIVERID handle. This location is filled with a handle identifying the installed driver that is associated with the hao.

fdwDriverID

This argument is not used and must be set to zero.


acmDriverMessage

LRESULT acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)

This function sends a user-defined message to a given Audio Compression Manager (ACM) driver instance.

•	The return value is specific to the user-defined ACM driver message uMsg sent. However, the following return values are possible:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALPARAM

uMsg is not in the ACMDM_USER range.

MMSYSERR_NOTSUPPORTED

The ACM driver did not process the message.

had

Specifies the ACM driver instance to which the message will be sent.

uMsg

Specifies the message that the ACM driver must process. This message must be in the ACMDM_USER message range (above or equal to ACMDM_USER and less than ACMDM_RESERVED_LOW). The exceptions to this restriction are the ACMDM_DRIVER_ABOUT, DRV_QUERYCONFIGURE, and DRV_CONFIGURE messages.

lParam1

Specifies the first message parameter.

lParam2

Specifies the second message parameter.

The acmDriverMessage function is provided to allow ACM driver- specific messages to be sent to an ACM driver. The messages that can be sent through this function must be above or equal to the ACMDM_USER message and less than ACMDM_RESERVED_LOW. The exceptions to this restriction are the ACMDM_DRIVER_ABOUT, DRV_QUERYCONFIGURE, and DRV_CONFIGURE messages.

To display a custom About dialog box from an ACM driver, an application must send the ACMDM_DRIVER_ABOUT message to the driver. The lParam1 argument should be the handle of the owner window for the custom about box; lParam2 must be set to zero. If the driver does not support a custom about box, then MMSYSERR_NOTSUPPORTED will be returned and it is up to the calling application to display its own dialog box. For example, the Control Panel Sound Mapper option will display a default about box based on the DRIVERDETAILS structure when an ACM driver returns MMSYSERR_NOTSUPPORTED. An application can query a driver for custom about box support without the dialog box being displayed by setting lParam1 to −1L. If the driver supports a custom about box, then MMSYSERR_NOERROR will be returned. Otherwise, the return value is MMSYSERR_NOTSUPPORTED.

User-defined messages must only be sent to an ACM driver that specifically supports the messages. The caller should verify that the ACM driver is in fact the correct driver by getting the driver details and checking the wMid, wPid, and vdwDriver members.

Never send user-defined messages to an unknown ACM driver.


acmDriverOpen

MMRESULT acmDriverOpen(LPHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)

This function opens the specified Audio Compression Manager (ACM) driver and returns a driver-instance handle that can be used to communicate with the driver.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_NOTENABLED

The driver is not enabled.

MMSYSERR_NOMEM

Unable to allocate resources.

phad

Specifies a pointer to a HACMDRIVER handle that will receive the new driver instance handle that can be used to communicate with the driver.

hadid

Handle to the driver identifier of an installed and enabled ACM driver.

fdwOpen

This argument is not used and must be set to zero.


acmDriverPriority

MMRESULT acmDriverPriority(HACMDRIVERID hadid, DWORD dwPriority, DWORD fdwPriority)

This function modifies the priority and state of an Audio Compression Manager (ACM) driver.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_ALLOCATED

Returned if the deferred broadcast lock is owned by a different task.

MMSYSERR_NOTSUPPORTED

The requested operation is not supported for the specified driver. For example, local and notify driver identifiers do not support priorities (but can be enabled and disabled). This error will therefore be returned if an application specifies a non-zero dwPriority for a local and notify driver identifiers.

hadid

Handle to the driver identifier of an installed ACM driver. This argument must be NULL when specifying the ACM_DRIVERPRIORITYF_BEGIN and ACM_DRIVERPRIORITYF_END flags.

dwPriority

Specifies the new priority for a global ACM driver identifier. A zero value specifies that the priority of the driver identifier should remain unchanged. A value of one (1) specifies that the driver should be placed as the highest search priority driver. A value of (DWORD)−1 specifies that the driver should be placed as the lowest search priority driver. Priorities are only used for global drivers.

fdwPriority

Specifies flags for setting priorities of ACM drivers.

ACM_DRIVERPRIORITYF_ENABLE

Specifies that the ACM driver should be enabled if it is currently disabled. Enabling an already enabled driver does nothing.

ACM_DRIVERPRIORITYF_DISABLE

Specifies that the ACM driver should be disabled if it is currently enabled. Disabling an already disabled driver does nothing.

ACM_DRIVERPRIORITYF_BEGIN

Specifies that the calling task wants to defer change notification broadcasts. An application must take care to re-enable notification broadcasts as soon as possible with the ACM_DRIVERPRIORITYF_END flag. Note that hadid must be NULL, dwPriority must be zero, and only the ACM_DRIVERPRIORITYF_BEGIN flag can be set.

ACM_DRIVERPRIORITYF_END

Specifies that the calling task wants to re-enable change notification broadcasts. An application must call acmDriverPriority with ACM_DRIVERPRIORITYF_END for each successful call with the ACM_DRIVERPRIORITYF_BEGIN flag. Note that hadid must be NULL, dwPriority must be zero, and only the ACM_DRIVERPRIORITYF_END flag can be set.

All driver identifiers can be enabled and disabled; this includes global, local and notification driver identifiers.

If more than one global driver identifier needs to be enabled, disabled or shifted in priority, then an application should defer change notification broadcasts using the ACM_DRIVERPRIORITYF_BEGIN flag. A single change notification will be broadcast when the ACM_DRIVERPRIORITYF_END flag is specified.

An application can use the acmMetrics function with the ACM_METRIC_DRIVER_PRIORITY metric index to retrieve the current priority of a global driver. Also note that drivers are always enumerated from highest to lowest priority by the acmDriverEnum function.

All enabled driver identifiers will receive change notifications. An application can register a notification message using the acmDriverAdd function in conjunction with the ACM_DRIVERADDF_NOTIFYHWND flag. Note that changes to non-global driver identifiers will not be broadcast.

Note that global priorities are simply used for the search order when an application does not specify a driver. Boosting the priority of a driver will have no effect on the performance of a driver.


acmDriverProc

LRESULT CALLBACK acmDriverProc(DWORD dwID, HDRIVER hdrvr, UINT uMsg, LPARAM lParam1, LPARAM lParam2)

The acmDriverProc function is a placeholder for an application-defined function name, and refers to the callback function used with the ACM. The actual name must be exported by including it in the module-definition file of the executable or DLL.

dwID

Specifies an identifier of the installable ACM driver.

hdrvr

Identifies the installable ACM driver. This argument is a unique handle the ACM assigns to the driver.

uMsg

Specifies an ACM driver message.

lParam1

Specifies the first message parameter.

lParam2

Specifies the second message parameter.


acmDriverRemove

MMRESULT acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)

This function removes an Audio Compression Manager (ACM) driver from the list of available ACM drivers.  The driver will be removed for the calling application only; if the driver is globally installed, the other applications will still be able to use it.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

ACMERR_BUSY

The driver is in use and cannot be removed.

hadid

Handle to the driver identifier to be removed.

fdwRemove

This argument is not used and must be set to zero.


ACMFILTERCHOOSE

The ACMFILTERCHOOSE structure contains information the Audio Compression Manager (ACM) uses to initialize the system-defined wave filter selection dialog box. After the user closes the dialog box, the system returns information about the user's selection in this structure.

typedef struct {

DWORD cbStruct;

DWORD fdwStyle;

HWND hwndOwner;

LPWAVEFILTER pwfltr;

DWORD cbwfltr;

LPCTSTR pszTitle;

TCHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS];

TCHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS];

LPTSTR pszName;

DWORD cchName;

DWORD fdwEnum;

LPWAVEFILTER pwfltrEnum;

HINSTANCE hInstance;

LPCTSTR pszTemplateName;

LPARAM lCustData;

ACMFILTERCHOOSEHOOKPROC pfnHook;

} ACMFILTERCHOOSE;

cbStruct

Specifies the size in bytes of the ACMFILTERCHOOSE structure. This member must be initialized before calling the acmFilterChoose function. The size specified in this member must be large enough to contain the base ACMFILTERCHOOSE structure.

fdwStyle

Specifies optional style flags for the acmFilterChoose function. This member must be initialized to a valid combination of the following flags before calling the acmFilterChoose function.

ACMFILTERCHOOSE_STYLEF_ENABLEHOOK

Enables the hook function specified in the pfnHook member. An application can use hook functions for a variety of customizations, including answering the MM_ACM_FILTERCHOOSE message.

ACMFILTERCHOOSE_STYLEF_ENABLETEMPLATE

Causes the ACM to create the dialog box template identified by the hInstance and pszTemplateName members.

ACMFILTERCHOOSE_STYLEF_ENABLETEMPLATEHANDLE

Indicates that the hInstance member identifies a data block that contains a pre-loaded dialog box template. The ACM ignores the pszTemplateName member if this flag is specified.

ACMFILTERCHOOSE_STYLEF_INITTOFILTERSTRUCT

Indicates that the buffer pointed to by pwfltr contains a valid WAVEFILTER structure that the dialog will use as the initial selection.

ACMFILTERCHOOSE_STYLEF_SHOWHELP

Indicates that a help button will appear in the dialog box. To use a custom Help file, an application must application register the ACMHELPMSGSTRING constant with RegisterWindowMessage. When the user presses the help button, the registered message is posted to the owner.

hwndOwner

Identifies the window that owns the dialog box. This member can be any valid window handle, or NULL if the dialog box has no owner. This member must be initialized before calling the acmFilterChoose function.

pwfltr

Specifies a pointer to a WAVEFILTER structure. If the ACMFILTERCHOOSE_STYLEF_INITTOFILTERSTRUCT flag is specified in the fdwStyle member, then this structure must be initialized to a valid filter. When the acmFilterChoose function returns, this buffer contains the selected filter. If the user cancels the dialog, no changes will be made to this buffer.

cbwfltr

Specifies the size in bytes of the buffer pointed to by the pwfltr member. The acmFilterChoose function returns ACMERR_NOTPOSSIBLE if the buffer is too small to contain the filter information; also, the ACM copies the required size into this member. An application can use the acmMetrics and acmFilterTagDetails functions to determine the largest size required for this buffer.

pszTitle

Points to a string to be placed in the title bar of the dialog box. If this member is NULL, the ACM uses the default title (that is, "Filter Selection").

szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS]

When the acmFilterChoose function returns, this buffer contains a null-terminated string describing the filter tag of the filter selection. This string is equivalent to the szFilterTag member of the ACMFILTERTAGDETAILS structure returned by acmFilterTagDetails. If the user cancels the dialog, this member will contain a NULL string.

szFilter[ACMFILTERDETAILS_FILTER_CHARS]

When the acmFilterChoose function returns, this buffer contains a null-terminated string describing the filter attributes of the filter selection. This string is equivalent to the szFilter member of the ACMFILTERDETAILS structure returned by acmFilterDetails. If the user cancels the dialog, this member will contain a NULL string.

pszName

Points to a string for a user-defined filter name. If this is a non-NULL string, then the ACM attempts to match the name with a previously saved user-defined filter name. If a match is found, then the dialog is initialized to that filter. If a match is not found or this member is a NULL string, then this member is ignored for input. When the acmFilterChoose function returns, this buffer contains a null-terminated string describing the user-defined filter. If the filter name is untitled (that is, the user has not given a name for the filter), then this member will be a NULL string on return. If the user cancels the dialog, no changes will be made to this buffer.

If the ACMFILTERCHOOSE_STYLEF_INITTOFILTERSTRUCT flag is specified in the fdwStyle member, then the pszName is ignored as an input parameter.

cchName

Specifies the size, in characters, of the buffer identified by the pszName member. This buffer should be at least 128 characters long. This parameter is ignored if the pszName member is NULL.

fdwEnum

Specifies optional flags for restricting the type of filters listed in the dialog. These flags are identical to the fdwEnum flags for the acmFilterEnum function. This member should be zero if pwfltrEnum is NULL.

ACM_FILTERENUMF_DWFILTERTAG

Specifies that the dwFilterTag member of the WAVEFILTER structure referred to by the pwfltrEnum member is valid. The enumerator will only enumerate a filter that conforms to this attribute.

pwfltrEnum

Points to a WAVEFILTER structure that will be used to restrict the filters listed in the dialog. The fdwEnum member defines which fields from the pwfltrEnum structure should be used for the enumeration restrictions. The cbStruct member of this WAVEFILTER structure must be initialized to the size of the WAVEFILTER structure. This member can be NULL if no special restrictions are specified.

hInstance

Identifies a data block that contains a dialog box template specified by the pszTemplateName member. This member is used only if the fdwStyle member specifies the ACMFILTERCHOOSE_STYLEF_ENABLETEMPLATE or the ACMFILTERCHOOSE_STYLEF_ENABLETEMPLATEHANDLE flag; otherwise, this member should be NULL on input.

pszTemplateName

Points to a null-terminated string that specifies the name of the resource file for the dialog box template that is to be substituted for the dialog box template in the ACM. An application can use the MAKEINTRESOURCE macro for numbered dialog box resources. This member is used only if the fdwStyle member specifies the ACMFILTERCHOOSE_STYLEF_ENABLETEMPLATE flag; otherwise, this member should be NULL on input.

lCustData

Specifies application-defined data that the ACM passes to the hook function identified by the pfnHook member. The system passes the data in the lParam argument of the WM_INITDIALOG message.

pfnHook

Points to a hook function that processes messages intended for the dialog box. An application must specify the ACMFILTERCHOOSE_STYLEF_ENABLEHOOK flag in the fdwStyle member to enable the hook; otherwise, this member should be NULL. The hook function should return FALSE to pass a message to the standard dialog box procedure, or TRUE to discard the message.


acmFilterChoose

MMRESULT acmFilterChoose(LPACMFILTERCHOOSE pafltrc)

The acmFilterChoose function creates an Audio Compression Manager (ACM) defined dialog box that enables the user to select a wave filter.

•	Returns MMSYSERR_NOERROR if the function was successful. Otherwise, it returns an error value. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_NODRIVER

A suitable driver is not available to provide valid filter selections.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

ACMERR_NOTPOSSIBLE

The buffer identified by the pwfltr member of the ACMFILTERCHOOSE structure is too small to contain the selected filter.

ACMERR_CANCELED

The user chose the Cancel button or the Close command on the System menu to close the dialog box.

pafltrc

Points to an ACMFILTERCHOOSE structure that contains information used to initialize the dialog box. When acmFilterChoose returns, this structure contains information about the user's filter selection.

The pwfltr member must be filled in with a valid pointer to a memory location that will contain the returned filter header structure. Moreover, the cbwfltr member must be filled in with the size in bytes of this memory buffer.


acmFilterChooseHookProc

UINT ACMFILTERCHOOSEHOOKPROC acmFilterChooseHookProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

The acmFilterChooseHookProc function is a placeholder for a user-defined function to hook the acmFilterChoose dialog box. Usage is equivalent to Common Dialog hook functions for customizing common dialogs. For more information about the uMsg, wParam, and lParam parameters, see the Microsoft Win32 Programmer's Reference.

hwnd

Specifies the window handle for the dialog box.

uMsg

Specifies the window message.

wParam

The first message parameter.

lParam

The second message parameter.

A hook function can optionally process the MM_ACM_FILTERCHOOSE message to customize the dialog selections.


ACMFILTERDETAILS

The ACMFILTERDETAILS structure details a wave filter for a specific filter tag for an Audio Compression Manager (ACM) driver.

typedef struct {

DWORD cbStruct;

DWORD dwFilterIndex;

DWORD dwFilterTag;

DWORD fdwSupport;

LPWAVEFILTER pwfltr;

DWORD cbwfltr;

TCHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS];

} ACMFILTERDETAILS;

cbStruct

Specifies the size in bytes of the ACMFILTERDETAILS structure. This member must be initialized before calling the acmFilterDetails or acmFilterEnum functions. The size specified in this member must be large enough to contain the base ACMFILTERDETAILS structure. When the acmFilterDetails function returns, this member contains the actual size of the information returned. The returned information will never exceed the requested size.

dwFilterIndex

Specifies the index of the filter about which details will be retrieved. The index ranges from zero to one less than the number of standard filters supported by an ACM driver for a filter tag. The number of standard filters supported by a driver for a filter tag is contained in the cStandardFilters member of the ACMFILTERTAGDETAILS structure. The dwFilterIndex member is only used when querying standard filter details on a driver by index; otherwise, this member should be zero. Also note that this member will be set to zero by the ACM when an application queries for details on a filter; in other words, this member is only used as an input argument and is never returned by the ACM or an ACM driver.

dwFilterTag

Specifies the wave filter tag that the ACMFILTERDETAILS structure describes. This member is used as an input for the ACM_FILTERDETAILSF_INDEX query flag. This member is always returned if the acmFilterDetails function is successful. This member should be set to WAVE_FILTER_UNKNOWN for all other query flags.

fdwSupport

Specifies driver-support flags specific to the specified filter. These flags are identical to the fdwSupport flags of the ACMDRIVERDETAILS structure, but are specific to the filter that is being queried. This argument can be a combination of the following values and identifies which operations the driver supports for the filter tag:

ACMDRIVERDETAILS_SUPPORTF_CODEC

Specifies that this driver supports conversion between two different format tags while using the specified filter. For example, if a driver supports compression from WAVE_FORMAT_PCM to WAVE_FORMAT_ADPCM with the specified filter, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_CONVERTER

Specifies that this driver supports conversion between two different formats of the same format tag while using the specified filter. For example, if a driver supports resampling of WAVE_FORMAT_PCM with the specified filter, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_FILTER

Specifies that this driver supports a filter (modification of the data without changing any of the format attributes). For example, if a driver supports volume or echo operations on WAVE_FORMAT_PCM, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_HARDWARE

Specifies that this driver supports hardware input and/or output with the specified filter through a waveform device. An application should use acmMetrics with the ACM_METRIC_HARDWARE_WAVE_INPUT and ACM_METRIC_HARDWARE_WAVE_OUTPUT metric indexes to get the waveform device identifiers associated with the supporting ACM driver.

pwfltr

Specifies a pointer to a WAVEFILTER data structure that will receive the filter details. This structure requires no initialization by the application unless the ACM_FILTERDETAILSF_FILTER flag is specified to acmFilterDetails. In this case, the dwFilterTag must be equal to the dwFilterTag of the ACMFILTERDETAILS structure.

cbwfltr

Specifies the size, in bytes, available for the pwfltr to receive the filter details. The acmMetrics and acmFilterTagDetails functions can be used to determine the maximum size required for any filter available for the specified driver (or for all installed ACM drivers).

szFilter[ACMFILTERDETAILS_FILTER_CHARS]

Specifies a string that describes the filter for the dwFilterTag type. This string is always returned if the acmFilterDetails function is successful.


acmFilterDetails

MMRESULT acmFilterDetails(HACMDRIVER had, LPACMFILTERDETAILS pafd, DWORD fdwDetails)

This function queries the Audio Compression Manager (ACM) for details about a filter with a specific wave filter tag.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALPARAM

One or more arguments passed is invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

ACMERR_NOTPOSSIBLE

The details requested are not available.

had

Optionally specifies an ACM driver to query for wave filter details for a filter tag. If this argument is NULL, then the ACM uses the details from the first suitable ACM driver.

pafd

Specifies a pointer to the ACMFILTERDETAILS structure that is to receive the filter details for the given filter tag.

fdwDetails

Specifies flags for getting the details.

ACM_FILTERDETAILSF_INDEX

Indicates that a filter index for the filter tag was given in the dwFilterIndex member of the ACMFILTERDETAILS structure. The filter details will be returned in the structure defined by pafd. The index ranges from zero to one less than the cStandardFilters member returned in the ACMFILTERTAGDETAILS structure for a filter tag. An application must specify a driver handle (had) when retrieving filter details with this flag. For information about the members that should be initialized before calling this function, see the description of the ACMFILTERDETAILS structure.

ACM_FILTERDETAILSF_FILTER

Indicates that a WAVEFILTER structure pointed to by pwfltr of the ACMFILTERDETAILS structure was given and the remaining details should be returned. The dwFilterTag member of the ACMFILTERDETAILS structure must be initialized to the same filter tag as the pwfltr member specifies. This query type can be used to get a string description of an arbitrary filter structure. If an application specifies an ACM driver handle (had), then details on the filter will be returned for that driver. If an application specifies NULL for had, then the ACM finds the first acceptable driver to return the details.


acmFilterEnum

MRESULT acmFilterEnum(HACMDRIVER had, LPACMFILTERDETAILS pafd, ACMFILTERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)

The acmFilterEnum function enumerates wave filters available for a given filter tag from an Audio Compression Manager (ACM) driver. The acmFilterEnum function continues enumerating until there are no more suitable filters for the filter tag or the callback function returns FALSE.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

ACMERR_NOTPOSSIBLE

The details for the filter cannot be returned.

had

Optionally specifies an ACM driver to query for wave filter details. If this argument is NULL, then the ACM uses the details from the first suitable ACM driver.

pafd

Specifies a pointer to the ACMFILTERDETAILS structure that is to receive the filter details passed to the fnCallback function. This structure must have the cbStruct, pwfltr, and cbwfltr members of the ACMFILTERDETAILS structure initialized. The dwFilterTag member must also be initialized to either WAVE_FILTER_UNKNOWN or a valid filter tag.

fnCallback

Specifies the procedure-instance address of the application-defined callback function.

dwInstance

Specifies a 32-bit, application-defined value that is passed to the callback function along with ACM filter details.

fdwEnum

Specifies flags for enumerating the filters for a given filter tag.

ACM_FILTERENUMF_DWFILTERTAG

Specifies that the dwFilterTag member of the WAVEFILTER structure referred to by the pwfltr member of the ACMFILTERDETAILS structure is valid. The enumerator will only enumerate a filter that conforms to this attribute. Note that the dwFilterTag member of the ACMFILTERDETAILS structure must be equal to the dwFilterTag member.

The acmFilterEnum function will return MMSYSERR_NOERROR (zero) if no suitable ACM drivers are installed. Moreover, the callback function will not be called.


acmFilterEnumCallback

BOOL ACMFILTERENUMCB acmFilterEnumCallback(HACMDRIVERID hadid, LPACMFILTERDETAILS pafd, DWORD dwInstance, DWORD fdwSupport)

The acmFilterEnumCallback function is a placeholder for an application-supplied function name and refers to the callback function used for Audio Compression Manager (ACM) wave filter detail enumeration.

•	The callback function must return TRUE to continue enumeration; to stop enumeration, it must return FALSE.

hadid

Specifies an ACM driver identifier.

pafd

Specifies a pointer to an ACMFILTERDETAILS structure that contains the enumerated filter details for a filter tag.

dwInstance

Specifies the application-defined value specified in the acmFilterEnum function.

fdwSupport

Specifies driver-support flags specific to the driver identifier hadid for the specified filter. These flags are identical to the fdwSupport flags of the ACMDRIVERDETAILS structure, but are specific to the filter that is being enumerated. This argument can be a combination of the following values and identifies which operations the driver supports for the filter tag.

ACMDRIVERDETAILS_SUPPORTF_CODEC

Specifies that this driver supports conversion between two different format tags while using the specified filter. For example, if a driver supports compression from WAVE_FORMAT_PCM to WAVE_FORMAT_ADPCM with the specified filter, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_CONVERTER

Specifies that this driver supports conversion between two different formats of the same format tag while using the specified filter. For example, if a driver supports resampling of WAVE_FORMAT_PCM with the specified filter, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_FILTER

Specifies that this driver supports a filter (modification of the data without changing any of the format attributes). For example, if a driver supports volume or echo operations on WAVE_FORMAT_PCM, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_HARDWARE

Specifies that this driver supports hardware input and/or output with the specified filter through a waveform device. An application should use acmMetrics with the ACM_METRIC_HARDWARE_WAVE_INPUT and ACM_METRIC_HARDWARE_WAVE_OUTPUT metric indexes to get the waveform device identifiers associated with the supporting ACM driver.

The acmFilterEnum function will return MMSYSERR_NOERROR (zero) if no filters are to be enumerated. Moreover, the callback function will not be called.

Note the following functions should not be called from within the callback function: acmDriverAdd, acmDriverRemove, acmDriverPriority.


acmFilterTagDetails

MMRESULT acmFilterTagDetails(HACMDRIVER had, LPACMFILTERTAGDETAILS paftd, DWORD fdwDetails)

This function queries the Audio Compression Manager (ACM) for details on a specific wave filter tag.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALPARAM

One or more arguments passed is invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

ACMERR_NOTPOSSIBLE

The details requested are not available.

had

Optionally specifies an ACM driver to query for wave filter tag details. If this argument is NULL, then the ACM uses the details from the first suitable ACM driver. Note that an application must specify a valid HACMDRIVER or HACMDRIVERID when using the ACM_FILTERTAGDETAILSF_INDEX query type. Driver identifiers for disabled drivers are not allowed.

paftd

Specifies a pointer to the ACMFILTERTAGDETAILS structure that is to receive the filter tag details.

fdwDetails

Specifies flags for getting the details.

ACM_FILTERTAGDETAILSF_INDEX

Indicates that a filter tag index was given in the dwFilterTagIndex member of the ACMFILTERTAGDETAILS structure. The filter tag and details will be returned in the structure defined by paftd. The index ranges from zero to one less than the cFilterTags member returned in the ACMDRIVERDETAILS structure for an ACM driver. An application must specify a driver handle (had) when retrieving filter tag details with this flag.

ACM_FILTERTAGDETAILSF_FILTERTAG

Indicates that a filter tag was given in the dwFilterTag member of the ACMFILTERTAGDETAILS structure. The filter tag details will be returned in the structure defined by paftd. If an application specifies an ACM driver handle (had), then details on the filter tag will be returned for that driver. If an application specifies NULL for had, then the ACM finds the first acceptable driver to return the details.

ACM_FILTERTAGDETAILSF_LARGESTSIZE

Indicates that the details on the filter tag with the largest filter size in bytes is to be returned. The dwFilterTag member must either be WAVE_FILTER_UNKNOWN or the filter tag to find the largest size for. If an application specifies an ACM driver handle (had), then details on the largest filter tag will be returned for that driver. If an application specifies NULL for had, then the ACM finds an acceptable driver with the largest filter tag requested to return the details.


ACMFILTERTAGDETAILS

The ACMFILTERTAGDETAILS structure details a wave filter tag for an Audio Compression Manager (ACM) filter driver.

typedef struct {

DWORD cbStruct;

DWORD dwFilterTagIndex;

DWORD dwFilterTag;

DWORD cbFilterSize;

DWORD fdwSupport;

DWORD cStandardFilters;

TCHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS];

} ACMFILTERTAGDETAILS;

cbStruct

Specifies the size in bytes of the ACMFILTERTAGDETAILS structure. This member must be initialized before calling the acmFilterTagDetails or acmFilterTagEnum functions. The size specified in this member must be large enough to contain the base ACMFILTERTAGDETAILS structure. When the acmFilterTagDetails function returns, this member contains the actual size of the information returned. The returned information will never exceed the requested size.

dwFilterTagIndex

Specifies the index of the filter tag to retrieve details for. The index ranges from zero to one less than the number of filter tags supported by an ACM driver. The number of filter tags supported by a driver is contained in the cFilterTags member of the ACMDRIVERDETAILS structure. The dwFilterTagIndex member is only used when querying filter tag details on a driver by index; otherwise, this member should be zero.

dwFilterTag

Specifies the wave filter tag that the ACMFILTERTAGDETAILS structure describes. This member is used as an input for the ACM_FILTERTAGDETAILSF_FILTERTAG and ACM_FILTERTAGDETAILSF_LARGESTSIZE query flags. This member is always returned if the acmFilterTagDetails is successful. This member should be set to WAVE_FILTER_UNKNOWN for all other query flags.

cbFilterSize

Specifies the largest total size in bytes of a wave filter of the dwFilterTag type. For example, this member will be 40 for WAVE_FILTER_ECHO and 36 for WAVE_FILTER_VOLUME.

fdwSupport

Specifies driver-support flags specific to the filter tag. These flags are identical to the fdwSupport flags of the ACMDRIVERDETAILS structure. This argument can be a combination of the following values and identifies which operations the driver supports with the filter tag:

ACMDRIVERDETAILS_SUPPORTF_CODEC

Specifies that this driver supports conversion between two different format tags while using the specified filter tag. For example, if a driver supports compression from WAVE_FORMAT_PCM to WAVE_FORMAT_ADPCM with the specified filter tag, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_CONVERTER

Specifies that this driver supports conversion between two different formats of the same format tag while using the specified filter tag. For example, if a driver supports resampling of WAVE_FORMAT_PCM with the specified filter tag, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_FILTER

Specifies that this driver supports a filter (modification of the data without changing any of the format attributes). For example, if a driver supports volume or echo operations on WAVE_FORMAT_PCM, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_HARDWARE

Specifies that this driver supports hardware input and/or output with the specified filter tag through a waveform device. An application should use acmMetrics with the ACM_METRIC_HARDWARE_WAVE_INPUT and ACM_METRIC_HARDWARE_WAVE_OUTPUT metric indexes to get the waveform device identifiers associated with the supporting ACM driver.

cStandardFilters

Specifies the number of standard filters of the dwFilterTag type. (that is, the combination of all filter characteristics). This value cannot specify all filters supported by the driver.

szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS]

Specifies a string that describes the dwFilterTag type. This string is always returned if the acmFilterTagDetails function is successful.


acmFilterTagEnum

MMRESULT acmFilterTagEnum(HACMDRIVER had, LPACMFILTERTAGDETAILS paftd, ACMFILTERTAGENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)

The acmFilterTagEnum function enumerates wave filter tags available from an Audio Compression Manager (ACM) driver. The acmFilterTagEnum function continues enumerating until there are no more suitable filter tags or the callback function returns FALSE.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

had

Optionally specifies an ACM driver to query for wave filter tag details. If this argument is NULL, then the ACM uses the details from the first suitable ACM driver.

paftd

Specifies a pointer to the ACMFILTERTAGDETAILS structure that is to receive the filter tag details passed to the fnCallback function. This structure must have the cbStruct member of the ACMFILTERTAGDETAILS structure initialized.

fnCallback

Specifies the procedure-instance address of the application-defined callback function.

dwInstance

Specifies a 32-bit, application-defined value that is passed to the callback function along with ACM filter tag details.

fdwEnum

This argument is not used and must be set to zero.

The acmFilterTagEnum function will return MMSYSERR_NOERROR (zero) if no suitable ACM drivers are installed. Moreover, the callback function will not be called.


acmFilterTagEnumCallback

BOOL ACMFILTERTAGENUMCB acmFilterTagEnumCallback(HACMDRIVERID hadid, LPACMFILTERTAGDETAILS paftd, DWORD dwInstance, DWORD fdwSupport)

The acmFilterTagEnumCallback function is a placeholder for an application-supplied function name and refers to the callback function used for Audio Compression Manager (ACM) wave filter tag enumeration.

•	The callback function must return TRUE to continue enumeration; to stop enumeration, it must return FALSE.

hadid

Specifies an ACM driver identifier.

paftd

Specifies a pointer to an ACMFILTERTAGDETAILS structure that contains the enumerated filter tag details.

dwInstance

Specifies the application-defined value specified in the acmFilterTagEnum function.

fdwSupport

Specifies driver-support flags specific to the driver identifier hadid. These flags are identical to the fdwSupport flags of the ACMDRIVERDETAILS structure. This argument can be a combination of the following values and identifies which operations the driver supports with the filter tag

ACMDRIVERDETAILS_SUPPORTF_CODEC

Specifies that this driver supports conversion between two different format tags while using the specified filter tag. For example, if a driver supports compression from WAVE_FORMAT_PCM to WAVE_FORMAT_ADPCM with the specified filter tag, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_CONVERTER

Specifies that this driver supports conversion between two different formats of the same format tag while using the specified filter tag. For example, if a driver supports resampling of WAVE_FORMAT_PCM with the specified filter tag, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_FILTER

Specifies that this driver supports a filter (modification of the data without changing any of the format attributes). For example, if a driver supports volume or echo operations on WAVE_FORMAT_PCM, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_HARDWARE

Specifies that this driver supports hardware input and/or output with the specified filter tag through a waveform device. An application should use acmMetrics with the ACM_METRIC_HARDWARE_WAVE_INPUT and ACM_METRIC_HARDWARE_WAVE_OUTPUT metric indexes to get the waveform device identifiers associated with the supporting ACM driver.

The acmFilterTagEnum function will return MMSYSERR_NOERROR (zero) if no filter tags are to be enumerated. Moreover, the callback function will not be called.

Note the following functions should not be called from within the callback function: acmDriverAdd, acmDriverRemove, acmDriverPriority.


ACMFORMATCHOOSE

The ACMFORMATCHOOSE structure contains information the Audio Compression Manager (ACM) uses to initialize the system-defined wave format selection dialog box. After the user closes the dialog box, the system returns information about the user's selection in this structure.

typedef struct {

DWORD cbStruct;

DWORD fdwStyle;

HWND hwndOwner;

LPWAVEFORMATEX pwfx;

DWORD cbwfx;

LPCTSTR pszTitle;

TCHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS];

TCHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS];

LPTSTR pszName;

DWORD cchName;

DWORD fdwEnum;

LPWAVEFORMATEX pwfxEnum;

HINSTANCE hInstance;

LPCTSTR pszTemplateName;

LPARAM lCustData;

ACMFORMATCHOOSEHOOKPROC pfnHook;

} ACMFORMATCHOOSE;

cbStruct

Specifies the size in bytes of the ACMFORMATCHOOSE structure. This member must be initialized before calling the acmFormatChoose function. The size specified in this member must be large enough to contain the base ACMFORMATCHOOSE structure.

fdwStyle

Specifies optional style flags for the acmFormatChoose function. This member must be initialized to a valid combination of the following flags before calling the acmFormatChoose function.

ACMFORMATCHOOSE_STYLEF_ENABLEHOOK

Enables the hook function specified in the pfnHook member. An application can use hook functions for a variety of customizations, including answering the MM_ACM_FORMATCHOOSE message.

ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATE

Causes the ACM to create the dialog box template identified by the hInstance and pszTemplateName members.

ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATEHANDLE

Indicates that the hInstance member identifies a data block that contains a pre-loaded dialog box template. The ACM ignores the pszTemplateName member if this flag is specified.

ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT

Indicates that the buffer pointed to by pwfx contains a valid WAVEFORMATEX structure that the dialog will use as the initial selection.

ACMFORMATCHOOSE_STYLEF_SHOWHELP

Indicates that a help button will appear in the dialog box. To use a custom Help file, an application must register the ACMHELPMSGSTRING constant with RegisterWindowMessage. When the user presses the help button, the registered message will be posted to the owner.

hwndOwner

Identifies the window that owns the dialog box. This member can be any valid window handle, or NULL if the dialog box has no owner. This member must be initialized before calling the acmFormatChoose function.

pwfx

Specifies a pointer to a WAVEFORMATEX structure. If the ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT flag is specified in the fdwStyle member, then this structure must be initialized to a valid format. When the acmFormatChoose function returns, this buffer contains the selected format. If the user cancels the dialog, no changes will be made to this buffer.

cbwfx

Specifies the size in bytes of the buffer pointed to by the pwfx member. The acmFormatChoose function returns ACMERR_NOTPOSSIBLE if the buffer is too small to contain the format information; also, the ACM copies the required size into this member. An application can use the acmMetrics and acmFormatTagDetails functions to determine the largest size required for this buffer.

pszTitle

Points to a string to be placed in the title bar of the dialog box. If this member is NULL, the ACM uses the default title (that is, "Sound Selection").

szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]

When the acmFormatChoose function returns, this buffer contains a null-terminated string describing the format tag of the format selection. This string is equivalent to the szFormatTag member of the ACMFORMATTAGDETAILS structure returned by acmFormatTagDetails. If the user cancels the dialog, this member will contain a NULL string.

szFormat[ACMFORMATDETAILS_FORMAT_CHARS]

When the acmFormatChoose function returns, this buffer contains a null-terminated string describing the format attributes of the format selection. This string is equivalent to the szFormat member of the ACMFORMATDETAILS structure returned by acmFormatDetails. If the user cancels the dialog, this member will contain a NULL string.

pszName

Points to a string for a user-defined format name. If this is a non-NULL string, then the ACM will attempt to match the name with a previously saved user-defined format name. If a match is found, then the dialog is initialized to that format. If a match is not found or this member is a NULL string, then this member is ignored for input. When the acmFormatChoose function returns, this buffer contains a null-terminated string describing the user-defined format. If the format name is untitled (that is, the user has not given a name for the format), then this member will be a NULL string on return. If the user cancels the dialog, no changes will be made to this buffer.

If the ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT flag is specified in the fdwStyle member, then the pszName is ignored as an input parameter.

cchName

Specifies the size, in characters, of the buffer identified by the pszName member. This buffer should be at least 128 characters long. This parameter is ignored if the pszName member is NULL.

fdwEnum

Specifies optional flags for restricting the type of formats listed in the dialog. These flags are identical to the fdwEnum flags for the acmFormatEnum function. This member should be zero if pwfxEnum is NULL.

ACM_FORMATENUMF_WFORMATTAG

Specifies that the wFormatTag member of the WAVEFORMATEX structure referred to by the pwfxEnum member is valid. The enumerator will only enumerate a format that conforms to this attribute.

ACM_FORMATENUMF_NCHANNELS

Specifies that the nChannels member of the WAVEFORMATEX structure referred to by the pwfxEnum member is valid. The enumerator will only enumerate a format that conforms to this attribute.

ACM_FORMATENUMF_NSAMPLESPERSEC

Specifies that the nSamplesPerSec member of the WAVEFORMATEX structure referred to by the pwfxEnum member is valid. The enumerator will only enumerate a format that conforms to this attribute.

ACM_FORMATENUMF_WBITSPERSAMPLE

Specifies that the wBitsPerSample member of the WAVEFORMATEX structure referred to by the pwfxEnum member is valid. The enumerator will only enumerate a format that conforms to this attribute.

ACM_FORMATENUMF_CONVERT

Specifies that the WAVEFORMATEX structure referred to by the pwfxEnum member is valid. The enumerator will only enumerate destination formats that can be converted from the given pwfxEnum format.

ACM_FORMATENUMF_SUGGEST

Specifies that the WAVEFORMATEX structure referred to by the pwfxEnum member is valid. The enumerator will enumerate all suggested destination formats for the given pwfxEnum format.

ACM_FORMATENUMF_HARDWARE

Specifies that the enumerator should only enumerate formats that are supported in hardware by one or more of the installed wave devices. This provides a way for an application to choose only formats native to an installed wave device.

ACM_FORMATENUMF_INPUT

Specifies that the enumerator should only enumerate formats that are supported for input (recording).

ACM_FORMATENUMF_OUTPUT

Specifies that the enumerator should only enumerate formats that are supported for output (playback).

pwfxEnum

Points to a WAVEFORMATEX structure that will be used to restrict the formats listed in the dialog. The fdwEnum member defines the fields of the pwfxEnum structure that should be used for the enumeration restrictions. This member can be NULL if no special restrictions are specified. For other requirements associated with the pwfxEnum member, see the description of acmFormatEnum.

hInstance

Identifies a data block that contains a dialog box template specified by the pszTemplateName member. This member is used only if the fdwStyle member specifies the ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATE or the ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATEHANDLE flag; otherwise, this member should be NULL on input.

pszTemplateName

Points to a null-terminated string that specifies the name of the resource file for the dialog box template that is to be substituted for the dialog box template in the ACM. An application can use the MAKEINTRESOURCE macro for numbered dialog box resources. This member is used only if the fdwStyle member specifies the ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATE flag; otherwise, this member should be NULL on input.

lCustData

Specifies application-defined data that the ACM passes to the hook function identified by the pfnHook member. The system passes the data in the lParam argument of the WM_INITDIALOG message.

pfnHook

Points to a hook function that processes messages intended for the dialog box. An application must specify the ACMFORMATCHOOSE_STYLEF_ENABLEHOOK flag in the fdwStyle member to enable the hook; otherwise, this member should be NULL. The hook function should return FALSE to pass a message to the standard dialog box procedure, or TRUE to discard the message.


acmFormatChoose

MMRESULT acmFormatChoose(LPACMFORMATCHOOSE pfmtc)

The acmFormatChoose function creates an Audio Compression Manager (ACM) defined dialog box that enables the user to select a wave format.

•	Returns MMSYSERR_NOERROR if the function was successful. Otherwise, it returns an error value. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_NODRIVER

A suitable driver is not available to provide valid format selections.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

ACMERR_NOTPOSSIBLE

The buffer identified by the pwfx member of the ACMFORMATCHOOSE structure is too small to contain the selected format.

ACMERR_CANCELED

The user chose the Cancel button or the Close command on the System menu to close the dialog box.

pfmtc

Points to an ACMFORMATCHOOSE structure that contains information used to initialize the dialog box. When acmFormatChoose returns, this structure contains information about the user's format selection.

The pwfx member must be filled in with a valid pointer to a memory location that will contain the returned format header structure. Moreover, the cbwfx member must be filled in with the size in bytes of this memory buffer.


acmFormatChooseHookProc

UINT ACMFORMATCHOOSEHOOKPROC acmFormatChooseHookProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

The acmFormatChooseHookProc function is a placeholder for a user-defined function to hook the acmFormatChoose dialog box. Usage is equivalent to the Common Dialog hook functions for customizing common dialogs. For more information about the uMsg, wParam, and lParam parameters, see the Microsoft Win32 Programmer's Reference.

hwnd

Specifies the window handle for the dialog box.

uMsg

Specifies the window message.

wParam

The first message parameter.

lParam

The second message parameter.

If the hook function processes the WM_CTLCOLOR message, this function must return a handle of the brush that should be used to paint the control background.

A hook function can optionally process the MM_ACM_FORMATCHOOSE message.


ACMFORMATDETAILS

The ACMFORMATDETAILS structure details a wave format for a specific format tag for an Audio Compression Manager (ACM) driver.

typedef struct {

DWORD cbStruct;

DWORD dwFormatIndex;

DWORD dwFormatTag;

DWORD fdwSupport;

LPWAVEFORMATEX pwfx;

DWORD cbwfx;

TCHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS];

} ACMFORMATDETAILS;

cbStruct

Specifies the size, in bytes, of the ACMFORMATDETAILS structure. This member must be initialized before calling the acmFormatDetails or acmFormatEnum functions. The size specified in this member must be large enough to contain the base ACMFORMATDETAILS structure. When the acmFormatDetails function returns, this member contains the actual size of the information returned. The returned information will never exceed the requested size.

dwFormatIndex

Specifies the index of the format to retrieve details for. The index ranges from zero to one less than the number of standard formats supported by an ACM driver for a format tag. The number of standard formats supported by a driver for a format tag is contained in the cStandardFormats member of the ACMFORMATTAGDETAILS structure. The dwFormatIndex member is only used when querying standard format details on a driver by index; otherwise, this member should be zero. Also note that this member will be set to zero by the ACM when an application queries for details on a format. In other words, this member is only used as an input argument and is never returned by the ACM or an ACM driver.

dwFormatTag

Specifies the wave format tag that the ACMFORMATDETAILS structure describes. This member is used as an input for the ACM_FORMATDETAILSF_INDEX query flag. This member is always returned if the acmFormatDetails is successful. This member should be set to WAVE_FORMAT_UNKNOWN for all other query flags.

fdwSupport

Specifies driver-support flags specific to the specified format. These flags are identical to the fdwSupport flags of the ACMDRIVERDETAILS structure. This argument can be a combination of the following values and indicates which operations the driver supports for the format tag:

ACMDRIVERDETAILS_SUPPORTF_CODEC

Specifies that this driver supports conversion between two different format tags for the specified format. For example, if a driver supports compression from WAVE_FORMAT_PCM to WAVE_FORMAT_ADPCM with the specified format, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_CONVERTER

Specifies that this driver supports conversion between two different formats of the same format tag while using the specified format. For example, if a driver supports resampling of WAVE_FORMAT_PCM to the specified format, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_FILTER

Specifies that this driver supports a filter (which modifies data without changing any format attributes) with the specified format. For example, if a driver supports volume or echo operations on WAVE_FORMAT_PCM, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_HARDWARE

Specifies that this driver supports hardware input and/or output of the specified format through a waveform device. An application should use acmMetrics with the ACM_METRIC_HARDWARE_WAVE_INPUT and ACM_METRIC_HARDWARE_WAVE_OUTPUT metric indexes to get the waveform device identifiers associated with the supporting ACM driver.

pwfx

Specifies a pointer to a WAVEFORMATEX data structure that will receive the format details. This structure requires no initialization by the application unless the ACM_FORMATDETAILSF_FORMAT flag is specified to acmFormatDetails. In this case, the wFormatTag must be equal to the dwFormatTag of the ACMFORMATDETAILS structure.

cbwfx

Specifies the size, in bytes, available for the pwfx to receive the format details. The acmMetrics and acmFormatTagDetails functions can be used to determine the maximum size required for any format available for the specified driver (or for all installed ACM drivers).

szFormat[ACMFORMATDETAILS_FORMAT_CHARS]

Specifies a string that describes the format for the dwFormatTag type. This string is always returned if the acmFormatDetails function is successful.


acmFormatDetails

MMRESULT acmFormatDetails(HACMDRIVER had, LPACMFORMATDETAILS pafd, DWORD fdwDetails)

This function queries the Audio Compression Manager (ACM) for details on format for a specific wave format tag.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

ACMERR_NOTPOSSIBLE

The details requested are not available.

had

Optionally specifies an ACM driver to query for wave format details for a format tag. If this argument is NULL, then the ACM uses the details from the first suitable ACM driver.

pafd

Specifies a pointer to the ACMFORMATDETAILS structure that is to receive the format details for the given format tag.

fdwDetails

Specifies flags for getting the wave format tag details.

ACM_FORMATDETAILSF_INDEX

Indicates that a format index for the format tag was given in the dwFormatIndex member of the ACMFORMATDETAILS structure. The format details will be returned in the structure defined by pafd. The index ranges from zero to one less than the cStandardFormats member returned in the ACMFORMATTAGDETAILS structure for a format tag. An application must specify a driver handle (had) when retrieving format details with this flag. For information about the members that should be initialized before calling this function, see the description of the ACMFORMATDETAILS structure.

ACM_FORMATDETAILSF_FORMAT

Indicates that a WAVEFORMATEX structure pointed to by the pwfx member of the ACMFORMATDETAILS structure was given and the remaining details should be returned. The dwFormatTag member of the ACMFORMATDETAILS structure must be initialized to the same format tag as the pwfx member specifies. This query type can be used to get a string description of an arbitrary format structure. If an application specifies an ACM driver handle (had), then details on the format will be returned for that driver. If an application specifies NULL for had, then the ACM finds the first acceptable driver to return the details.


acmFormatEnum

MMRESULT acmFormatEnum(HACMDRIVER had, LPACMFORMATDETAILS pafd, ACMFORMATENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)

The acmFormatEnum function enumerates wave formats available for a given format tag from an Audio Compression Manager (ACM) driver. The acmFormatEnum function continues enumerating until there are no more suitable formats for the format tag or the callback function returns FALSE.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

ACMERR_NOTPOSSIBLE

The details for the format cannot be returned.

had

Optionally specifies an ACM driver to query for wave format details. If this argument is NULL, then the ACM uses the details from the first suitable ACM driver.

pafd

Specifies a pointer to the ACMFORMATDETAILS structure that is to receive the format details passed to the fnCallback function. This structure must have the cbStruct, pwfx, and cbwfx members of the ACMFORMATDETAILS structure initialized. The dwFormatTag member must also be initialized to either WAVE_FORMAT_UNKNOWN or a valid format tag.

fnCallback

Specifies the procedure-instance address of the application-defined callback function.

dwInstance

Specifies a 32-bit, application-defined value that is passed to the callback function along with ACM format details.

fdwEnum

Specifies flags for enumerating the formats for a given format tag.

ACM_FORMATENUMF_WFORMATTAG

Specifies that the wFormatTag member of the WAVEFORMATEX structure referred to by the pwfx member of the ACMFORMATDETAILS structure is valid. The enumerator will only enumerate a format that conforms to this attribute. Note that the dwFormatTag member of the ACMFORMATDETAILS structure must be equal to the wFormatTag member.

ACM_FORMATENUMF_NCHANNELS

Specifies that the nChannels member of the WAVEFORMATEX structure referred to by the pwfx member of the ACMFORMATDETAILS structure is valid. The enumerator will only enumerate a format that conforms to this attribute.

ACM_FORMATENUMF_NSAMPLESPERSEC

Specifies that the nSamplesPerSec member of the WAVEFORMATEX structure referred to by the pwfx member of the ACMFORMATDETAILS structure is valid. The enumerator will only enumerate a format that conforms to this attribute.

ACM_FORMATENUMF_WBITSPERSAMPLE

Specifies that the wBitsPerSample member of the WAVEFORMATEX structure referred to by the pwfx member of the ACMFORMATDETAILS structure is valid. The enumerator will only enumerate a format that conforms to this attribute.

ACM_FORMATENUMF_CONVERT

Specifies that the WAVEFORMATEX structure referenced by the pwfx member of the ACMFORMATDETAILS structure is valid. The enumerator will only enumerate destination formats that can be converted from the given pwfx format.

ACM_FORMATENUMF_SUGGEST

Specifies that the WAVEFORMATEX structure referred to by the pwfx member of the ACMFORMATDETAILS structure is valid. The enumerator will enumerate all suggested destination formats for the given pwfx format. This can be used instead of acmFormatSuggest to allow an application to choose the best suggested format for conversion. Note that the dwFormatIndex member will always be set to zero on return.

ACM_FORMATENUMF_HARDWARE

Specifies that the enumerator should only enumerate formats that are supported as native input or output formats on one or more of the installed wave devices. This provides a way for an application to choose only formats native to an installed wave device. This flag must be used with one or both of the ACM_FORMATENUMF_INPUT and ACM_FORMATENUMF_OUTPUT flags. Note that specifying both ACM_FORMATENUMF_INPUT and ACM_FORMATENUMF_OUTPUT will enumerate only formats that can be opened for input or output. This is true regardless of whether the ACM_FORMATENUMF_HARDWARE flag is specified.

ACM_FORMATENUMF_INPUT

Specifies that the enumerator should only enumerate formats that are supported for input (recording).

ACM_FORMATENUMF_OUTPUT

Specifies that the enumerator should only enumerate formats that are supported for output (playback).

The acmFormatEnum function will return MMSYSERR_NOERROR (zero) if no suitable ACM drivers are installed. Moreover, the callback function will not be called.


acmFormatEnumCallback

BOOL ACMFORMATENUMCB acmFormatEnumCallback(HACMDRIVERID hadid, LPACMFORMATDETAILS pafd, DWORD dwInstance, DWORD fdwSupport)

The acmFormatEnumCallback function refers to the callback function used for Audio Compression Manager (ACM) wave format detail enumeration. The acmFormatEnumCallback is a placeholder for the application-supplied function name.

•	The callback function must return TRUE to continue enumeration; to stop enumeration, it must return FALSE.

hadid

Specifies an ACM driver identifier.

pafd

Specifies a pointer to an ACMFORMATDETAILS structure that contains the enumerated format details for a format tag.

dwInstance

Specifies the application-defined value specified in the acmFormatEnum function.

fdwSupport

Specifies driver-support flags specific to the driver identifier hadid for the specified format. These flags are identical to the fdwSupport flags of the ACMDRIVERDETAILS structure, but are specific to the format that is being enumerated. This argument can be a combination of the following values and indicates which operations the driver supports for the format tag.

ACMDRIVERDETAILS_SUPPORTF_CODEC

Specifies that this driver supports conversion between two different format tags for the specified format. For example, if a driver supports compression from WAVE_FORMAT_PCM to WAVE_FORMAT_ADPCM with the specified format, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_CONVERTER

Specifies that this driver supports conversion between two different formats of the same format tag while using the specified format. For example, if a driver supports resampling of WAVE_FORMAT_PCM to the specified format, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_FILTER

Specifies that this driver supports a filter (modification of the data without changing any of the format attributes) with the specified format. For example, if a driver supports volume or echo operations on WAVE_FORMAT_PCM, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_HARDWARE

Specifies that this driver supports hardware input and/or output of the specified format tag through a waveform device. An application should use acmMetrics with the ACM_METRIC_HARDWARE_WAVE_INPUT and ACM_METRIC_HARDWARE_WAVE_OUTPUT metric indexes to get the waveform device identifiers associated with the supporting ACM driver.

The acmFormatEnum function will return MMSYSERR_NOERROR (zero) if no formats are to be enumerated. Moreover, the callback function will not be called.

Note the following functions should not be called from within the callback function: acmDriverAdd, acmDriverRemove, acmDriverPriority.


acmFormatSuggest

MMRESULT acmFormatSuggest(HACMDRIVER had, LPWAVEFORMATEX pwfxSrc, LPWAVEFORMATEX pwfxDst, DWORD cbwfxDst, DWORD fdwSuggest)

This function asks the Audio Compression Manager (ACM) or a specified ACM driver to suggest a destination format for the supplied source format. For example, an application can use this function to determine one or more valid PCM formats to which a compressed format can be decompressed.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

had

Identifies an optional open instance of a driver to query for a suggested destination format. If this argument is NULL, the ACM attempts to find the best driver to suggest a destination format.

pwfxSrc

Specifies a pointer to a WAVEFORMATEX structure that identifies the source format to suggest a destination format to be used for a conversion.

pwfxDst

Specifies a pointer to a WAVEFORMATEX data structure that will receive the suggested destination format for the pwfxSrc format. Note that, based on the fdwSuggest argument, some members of the structure pointed to by pwfxDst might require initialization.

cbwfxDst

Specifies the size in bytes available for the destination format. The acmMetrics and acmFormatTagDetails functions can be used to determine the maximum size required for any format available for the specified driver (or for all installed ACM drivers).

fdwSuggest

Specifies flags for matching the destination format.

ACM_FORMATSUGGESTF_WFORMATTAG

Specifies that the wFormatTag member of the pwfxDst structure is valid. The ACM will query acceptable installed drivers that can suggest a destination format matching the wFormatTag member or fail.

ACM_FORMATSUGGESTF_NCHANNELS

Specifies that the nChannels member of the pwfxDst structure is valid. The ACM will query acceptable installed drivers that can suggest a destination format matching the nChannels member or fail.

ACM_FORMATSUGGESTF_NSAMPLESPERSEC

Specifies that the nSamplesPerSec member of the pwfxDst structure is valid. The ACM will query acceptable installed drivers that can suggest a destination format matching the nSamplesPerSec member or fail.

ACM_FORMATSUGGESTF_WBITSPERSAMPLE

Specifies that the wBitsPerSample member of the pwfxDst structure is valid. The ACM will query acceptable installed drivers that can suggest a destination format matching the wBitsPerSample member or fail.


acmFormatTagDetails

MMRESULT acmFormatTagDetails(HACMDRIVER had, LPACMFORMATTAGDETAILS paftd, DWORD fdwDetails)

This function queries the Audio Compression Manager (ACM) for details on a specific wave format tag.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

ACMERR_NOTPOSSIBLE

The details requested are not available.

had

Optionally specifies an ACM driver to query for wave format tag details. If this argument is NULL, then the ACM uses the details from the first suitable ACM driver. Note that an application must specify a valid HACMDRIVER or HACMDRIVERID when using the ACM_FORMATTAGDETAILSF_INDEX query type. Driver identifiers for disabled drivers are not allowed.

paftd

Specifies a pointer to the ACMFORMATTAGDETAILS structure that is to receive the format tag details.

fdwDetails

Specifies flags for getting the details.

ACM_FORMATTAGDETAILSF_INDEX

Indicates that a format tag index was given in the dwFormatTagIndex member of the ACMFORMATTAGDETAILS structure. The format tag and details will be returned in the structure defined by paftd. The index ranges from zero to one less than the cFormatTags member returned in the ACMDRIVERDETAILS structure for an ACM driver. An application must specify a driver handle (had) when retrieving format tag details with this flag.

ACM_FORMATTAGDETAILSF_FORMATTAG

Indicates that a format tag was given in the dwFormatTag member of the ACMFORMATTAGDETAILS structure. The format tag details will be returned in the structure defined by paftd. If an application specifies an ACM driver handle (had), then details on the format tag will be returned for that driver. If an application specifies NULL for had, then the ACM finds the first acceptable driver to return the details.

ACM_FORMATTAGDETAILSF_LARGESTSIZE

Indicates that the details on the format tag with the largest format size in bytes is to be returned. The dwFormatTag member must either be WAVE_FORMAT_UNKNOWN or the format tag to find the largest size for. If an application specifies an ACM driver handle (had), then details on the largest format tag will be returned for that driver. If an application specifies NULL for had, then the ACM finds an acceptable driver with the largest format tag requested to return the details.


ACMFORMATTAGDETAILS

The ACMFORMATTAGDETAILS structure details a wave format tag for an Audio Compression Manager (ACM) driver.

typedef struct {

DWORD cbStruct;

DWORD dwFormatTagIndex;

DWORD dwFormatTag;

DWORD cbFormatSize;

DWORD fdwSupport;

DWORD cStandardFormats;

TCHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS];

} ACMFORMATTAGDETAILS;

cbStruct

Specifies the size in bytes of the ACMFORMATTAGDETAILS structure. This member must be initialized before calling the acmFormatTagDetails or acmFormatTagEnum functions. The size specified in this member must be large enough to contain the base ACMFORMATTAGDETAILS structure. When the acmFormatTagDetails function returns, this member contains the actual size of the information returned. The returned information will never exceed the requested size.

dwFormatTagIndex

Specifies the index of the format tag for which details will be retrieved. The index ranges from zero to one less than the number of format tags supported by an ACM driver. The number of format tags supported by a driver is contained in the cFormatTags member of the ACMDRIVERDETAILS structure. The dwFormatTagIndex member is only used when querying format tag details on a driver by index; otherwise, this member should be zero.

dwFormatTag

Specifies the wave format tag that the ACMFORMATTAGDETAILS structure describes. This member is used as an input for the ACM_FORMATTAGDETAILSF_FORMATTAG and ACM_FORMATTAGDETAILSF_LARGESTSIZE query flags. This member is always returned if the acmFormatTagDetails function is successful. This member should be set to WAVE_FORMAT_UNKNOWN for all other query flags.

cbFormatSize

Specifies the largest total size in bytes of a wave format of the dwFormatTag type. For example, this member will be 16 for WAVE_FORMAT_PCM and 50 for WAVE_FORMAT_ADPCM.

fdwSupport

Specifies driver-support flags specific to the format tag. These flags are identical to the fdwSupport flags of the ACMDRIVERDETAILS structure. This argument can be a combination of the following values and refer to the operations the driver supports with the format tag:

ACMDRIVERDETAILS_SUPPORTF_CODEC

Specifies that this driver supports conversion between two different format tags where one of the tags is the specified format tag. For example, if a driver supports compression from WAVE_FORMAT_PCM to WAVE_FORMAT_ADPCM, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_CONVERTER

Specifies that this driver supports conversion between two different formats of the specified format tag. For example, if a driver supports resampling of WAVE_FORMAT_PCM, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_FILTER

Specifies that this driver supports a filter (modification of the data without changing any of the format attributes). For example, if a driver supports volume or echo operations on the specified format tag, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_HARDWARE

Specifies that this driver supports hardware input and/or output of the specified format tag through a waveform device. An application should use acmMetrics with the ACM_METRIC_HARDWARE_WAVE_INPUT and ACM_METRIC_HARDWARE_WAVE_OUTPUT metric indexes to get the waveform device identifiers associated with the supporting ACM driver.

cStandardFormats

Specifies the number of standard formats of the dwFormatTag type; that is, the combination of all sample rates, bits per sample, channels, and so on. This value can specify all formats supported by the driver, but not necessarily.

szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]

Specifies a string that describes the dwFormatTag type. This string is always returned if the acmFormatTagDetails function is successful.


acmFormatTagEnum

MMRESULT acmFormatTagEnum(HACMDRIVER had, LPACMFORMATTAGDETAILS paftd, ACMFORMATTAGENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)

The acmFormatTagEnum function enumerates wave format tags available from an Audio Compression Manager (ACM) driver. The acmFormatTagEnum function continues enumerating until there are no more suitable format tags or the callback function returns FALSE.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

had

Optionally specifies an ACM driver to query for wave format tag details. If this argument is NULL, then the ACM uses the details from the first suitable ACM driver.

paftd

Specifies a pointer to the ACMFORMATTAGDETAILS structure that is to receive the format tag details passed to the fnCallback function. This structure must have the cbStruct member of the ACMFORMATTAGDETAILS structure initialized.

fnCallback

Specifies the procedure-instance address of the application-defined callback function.

dwInstance

Specifies a 32-bit, application-defined value that is passed to the callback function along with ACM format tag details.

fdwEnum

This argument is not used and must be set to zero.

The acmFormatTagEnum function will return MMSYSERR_NOERROR (zero) if no suitable ACM drivers are installed. Moreover, the callback function will not be called.


acmFormatTagEnumCallback

BOOL ACMFORMATTAGENUMCB acmFormatTagEnumCallback(HACMDRIVERID hadid, LPACMFORMATTAGDETAILS paftd, DWORD dwInstance, DWORD fdwSupport)

The acmFormatTagEnumCallback function refers to the callback function used for Audio Compression Manager (ACM) wave format tag enumeration. The acmFormatTagEnumCallback function is a placeholder for the application-supplied function name.

•	The callback function must return TRUE to continue enumeration; to stop enumeration, it must return FALSE.

hadid

Specifies an ACM driver identifier.

paftd

Specifies a pointer to an ACMFORMATTAGDETAILS structure that contains the enumerated format tag details.

dwInstance

Specifies the application-defined value specified in the acmFormatTagEnum function.

fdwSupport

Specifies driver-support flags specific to the format tag. These flags are identical to the fdwSupport flags of the ACMDRIVERDETAILS structure. This argument can be a combination of the following values and indicates which operations the driver supports with the format tag:

ACMDRIVERDETAILS_SUPPORTF_CODEC

Specifies that this driver supports conversion between two different format tags where one of the tags is the specified format tag. For example, if a driver supports compression from WAVE_FORMAT_PCM to WAVE_FORMAT_ADPCM, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_CONVERTER

Specifies that this driver supports conversion between two different formats of the specified format tag. For example, if a driver supports resampling of WAVE_FORMAT_PCM, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_FILTER

Specifies that this driver supports a filter (modification of the data without changing any of the format attributes). For example, if a driver supports volume or echo operations on the specified format tag, then this flag is set.

ACMDRIVERDETAILS_SUPPORTF_HARDWARE

Specifies that this driver supports hardware input and/or output of the specified format tag through a waveform device. An application should use acmMetrics with the ACM_METRIC_HARDWARE_WAVE_INPUT and ACM_METRIC_HARDWARE_WAVE_OUTPUT metric indexes to get the waveform device identifiers associated with the supporting ACM driver.

The acmFormatTagEnum function will return MMSYSERR_NOERROR (zero) if no format tags are to be enumerated. Moreover, the callback function will not be called.

Note the following functions should not be called from within the callback function: acmDriverAdd, acmDriverRemove, acmDriverPriority.


acmGetVersion

DWORD acmGetVersion()

This function returns the version number of the Audio Compression Manager (ACM).

•	The version number is returned as a hexadecimal number of the form 0xAABBCCCC, where AA is the major version number, BB is the minor version number, and CCCC is the build number.

Win32 applications must verify that the ACM version is at least 0x03320000 (version 3.50) or greater before attempting to use any other ACM functions. Note that the build number (CCCC) is always zero for the retail (non-debug) version of the ACM.

To display the ACM version for a user, an application should use the following format (note that the values should be printed as unsigned decimals).

{

DWORD	dw;

TCHAR	ach[10];

dw = acmGetVersion();

wsprintf(ach, "%u.%.02u", HIWORD(dw) >> 8, HIWORD(dw) & 0x00FF);

}


acmMetrics

MMRESULT acmMetrics(HACMOBJ hao, UINT uMetric, LPVOID pMetric)

This function returns various metrics for the Audio Compression Manager (ACM) or related ACM objects.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

MMSYSERR_NOTSUPPORTED

The uMetric index is not supported.

ACMERR_NOTPOSSIBLE

The uMetric index cannot be returned for the specified hao.

hao

Specifies the ACM object to query for the metric specified in uMetric. This argument can be NULL for some queries.

uMetric

Specifies the metric index to be returned in pMetric.

ACM_METRIC_COUNT_DRIVERS

Specifies that the returned value is the total number of enabled global ACM drivers (of all support types) in the system. The hao argument must be NULL for this metric index. The pMetric argument must point to buffer of size equal to a DWORD.

ACM_METRIC_COUNT_CODECS

Specifies that the returned value is the number of global ACM compressor or decompressor drivers in the system. The hao argument must be NULL for this metric index. The pMetric argument must point to a buffer of a size equal to a DWORD.

ACM_METRIC_COUNT_CONVERTERS

Specifies that the returned value is the number of global ACM converter drivers in the system. The hao argument must be NULL for this metric index. The pMetric argument must point to a buffer of a size equal to a DWORD.

ACM_METRIC_COUNT_FILTERS

Specifies that the returned value is the number of global ACM filter drivers in the system. The hao argument must be NULL for this metric index. The pMetric argument must point to buffer of size equal to a DWORD.

ACM_METRIC_COUNT_DISABLED

Specifies that the returned value is the total number of global disabled ACM drivers (of all support types) in the system. The hao argument must be NULL for this metric index. The pMetric argument must point to a buffer of a size equal to a DWORD. The sum of the ACM_METRIC_COUNT_DRIVERS and ACM_METRIC_COUNT_DISABLED metrics is the total number of globally installed ACM drivers.

ACM_METRIC_COUNT_HARDWARE

Specifies that the returned value is the number of global ACM hardware drivers in the system. The hao argument must be NULL for this metric index. The pMetric argument must point to buffer of size equal to a DWORD.

ACM_METRIC_COUNT_LOCAL_DRIVERS

Specifies that the returned value is the total number of enabled local ACM drivers (of all support types) for the calling task. The hao argument must be NULL for this metric index. The pMetric argument must point to a buffer of a size equal to a DWORD.

ACM_METRIC_COUNT_LOCAL_CODECS

Specifies that the returned value is the number of local ACM compressor and/or decompressor drivers for the calling task. The hao argument must be NULL for this metric index. The pMetric argument must point to a buffer of a size equal to a DWORD.

ACM_METRIC_COUNT_LOCAL_CONVERTERS

Specifies that the returned value is the number of local ACM converter drivers for the calling task. The hao argument must be NULL for this metric index. The pMetric argument must point to a buffer of a size equal to a DWORD.

ACM_METRIC_COUNT_LOCAL_FILTERS

Specifies that the returned value is the number of local ACM filter drivers for the calling task. The hao argument must be NULL for this metric index. The pMetric argument must point to a buffer of a size equal to a DWORD.

ACM_METRIC_COUNT_LOCAL_DISABLED

Specifies that the returned value is the total number of local disabled ACM drivers, of all support types, for the calling task. The hao argument must be NULL for this metric index. The pMetric argument must point to a buffer of a size equal to a DWORD. The sum of the ACM_METRIC_COUNT_LOCAL_DRIVERS and ACM_METRIC_COUNT_LOCAL_DISABLED metrics is the total number of locally installed ACM drivers.

ACM_METRIC_HARDWARE_WAVE_INPUT

Specifies that the returned value is the waveform input device identifier associated with the specified driver. The hao argument must be a valid ACM driver identifier (HACMDRIVERID) that supports the ACMDRIVERDETAILS_SUPPORTF_HARDWARE flag. If no waveform input device is associated with the driver, then MMSYSERR_NOTSUPPORTED is returned. The pMetric argument must point to a buffer of a size equal to a DWORD.

ACM_METRIC_HARDWARE_WAVE_OUTPUT

Specifies that the returned value is the waveform output device identifier associated with the specified driver. The hao argument must be a valid ACM driver identifier (HACMDRIVERID) that supports the ACMDRIVERDETAILS_SUPPORTF_HARDWARE flag. If no waveform output device is associated with the driver, then MMSYSERR_NOTSUPPORTED is returned. The pMetric argument must point to a buffer of a size equal to a DWORD.

ACM_METRIC_MAX_SIZE_FORMAT

Specifies that the returned value is the size of the largest WAVEFORMATEX structure. If hao is NULL, then the return value is the largest WAVEFORMATEX structure in the system. If hao identifies an open instance of an ACM driver (HACMDRIVER) or an ACM driver identifier (HACMDRIVERID), then the largest WAVEFORMATEX structure for that driver is returned. The pMetric argument must point to a buffer of a size equal to a DWORD. This metric is not allowed for an ACM stream handle (HACMSTREAM).

ACM_METRIC_MAX_SIZE_FILTER

Specifies that the returned value is the size of the largest WAVEFILTER structure. If hao is NULL, then the return value is the largest WAVEFILTER structure in the system. If hao identifies an open instance of an ACM driver (HACMDRIVER) or an ACM driver identifier (HACMDRIVERID), then the largest WAVEFILTER structure for that driver is returned. The pMetric argument must point to a buffer of a size equal to a DWORD. This metric is not allowed for an ACM stream handle (HACMSTREAM).

ACM_METRIC_DRIVER_SUPPORT

Specifies that the returned value is the fdwSupport flags for the specified driver. The hao argument must be a valid ACM driver identifier (HACMDRIVERID). The pMetric argument must point to a buffer of a size equal to a DWORD.

ACM_METRIC_DRIVER_PRIORITY

Specifies that the returned value is the current priority for the specified driver. The hao argument must be a valid ACM driver identifier (HACMDRIVERID). The pMetric argument must point to a buffer of a size equal to a DWORD.

pMetric

Specifies a pointer to the buffer that will receive the metric details. The exact definition depends on the uMetric index.


acmStreamClose

MMRESULT acmStreamClose(HACMSTREAM has, DWORD fdwClose)

The acmStreamClose function closes a previously opened Audio Compression Manager (ACM) conversion stream. If the function is successful, the handle is invalidated.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

has

Identifies the open conversion stream to be closed.

fdwClose

This argument is not used and must be set to zero.


acmStreamConvert

MMRESULT acmStreamConvert(HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwConvert)

The acmStreamConvert function requests the Audio Compression Manager (ACM) to perform a conversion on the specified conversion stream.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

ACMERR_BUSY

The stream header pash is currently in use and cannot be reused.

ACMERR_UNPREPARED

The stream header pash is currently not prepared by the acmStreamPrepareHeader function.

has

Identifies the open conversion stream.

pash

Specifies a pointer to a stream header that describes source and destination buffers for a conversion. This header must have been prepared previously using the acmStreamPrepareHeader function.

fdwConvert

Specifies flags for doing the conversion.

ACM_STREAMCONVERTF_BLOCKALIGN

Specifies that only integral numbers of blocks will be converted. Converted data will end on block aligned boundaries. An application should use this flag for all conversions on a stream until there is not enough source data to convert to a block-aligned destination. In this case, the last conversion should be specified without this flag.

ACM_STREAMCONVERTF_START

Specifies that the ACM conversion stream should reinitialize its instance data. For example, if a conversion stream holds instance data, such as delta or predictor information, this flag will restore the stream to starting defaults. Note that this flag can be specified with the ACM_STREAMCONVERTF_END flag.

ACM_STREAMCONVERTF_END

Specifies that the ACM conversion stream should begin returning pending instance data. For example, if a conversion stream holds instance data, such as the tail end of an echo filter operation, this flag will cause the stream to start returning this remaining data with optional source data. Note that this flag can be specified with the ACM_STREAMCONVERTF_START flag.

The source and destination data buffers must be prepared with acmStreamPrepareHeader before they are passed to acmStreamConvert. The ACMSTREAMHEADER data structure and the source and destination data buffers pointed to by its pbSrc and pbDst members must be allocated with GlobalAlloc using the GMEM_MOVEABLE and GMEM_SHARE flags, and locked with GlobalLock.


acmStreamConvertCallback

void CALLBACK acmStreamConvertCallback(HACMSTREAM has, UINT uMsg, DWORD dwInstance, LPARAM lParam1, LPARAM lParam2)

The acmStreamConvertCallback function is a placeholder for an application-supplied function name and refers to a callback function.

This callback is reserved for future use and is not currently used.

has

Specifies a handle to the ACM conversion stream associated with the callback.

uMsg

Specifies an ACM conversion stream message.

dwInstance

Specifies the user-instance data.

lParam1

Specifies a parameter for the message.

lParam2

Specifies a parameter for the message.


ACMSTREAMHEADER

The ACMSTREAMHEADER structure defines the header used to identify an Audio Compression Manager (ACM) conversion source and destination buffer pair for a conversion stream.

typedef struct {

DWORD cbStruct;

DWORD fdwStatus;

DWORD dwUser;

LPBYTE pbSrc;

DWORD cbSrcLength;

DWORD cbSrcLengthUsed;

DWORD dwSrcUser;

LPBYTE pbDst;

DWORD cbDstLength;

DWORD cbDstLengthUsed;

DWORD dwDstUser;

DWORD dwReservedDriver[10];

} ACMSTREAMHEADER;

cbStruct

Specifies the size, in bytes, of the ACMSTREAMHEADER structure. This member must be initialized before calling any ACM stream functions using this structure. The size specified in this member must be large enough to contain the base ACMSTREAMHEADER structure.

fdwStatus

Specifies flags giving information about the conversion buffers. This member must be initialized to zero before calling acmStreamPrepareHeader and should not be modified by the application while the stream header remains prepared.

ACMSTREAMHEADER_STATUSF_DONE

Set by the ACM or driver to indicate that it is finished with the conversion and is returning it to the application.

ACMSTREAMHEADER_STATUSF_PREPARED

Set by the ACM to indicate that the data buffers have been prepared with acmStreamPrepareHeader.

ACMSTREAMHEADER_STATUSF_INQUEUE

Set by the ACM or driver to indicate that the data buffers are queued for conversion.

dwUser

Specifies 32 bits of user data. This can be any instance data specified by the application.

pbSrc

Specifies a pointer to the source data buffer. This pointer must always refer to the same location while the stream header remains prepared. If an application needs to change the source location, it must unprepare the header and re-prepare it with the alternate location.

cbSrcLength

Specifies the length, in bytes, of the source data buffer pointed to by pbSrc. When the header is prepared, this member must specify the maximum size that will be used in the source buffer. Conversions can be performed on source lengths less than or equal to the original prepared size. However, this member must be reset to the original size when unpreparing the header.

cbSrcLengthUsed

Specifies the amount of data, in bytes, used for the conversion. This member is not valid until the conversion is complete. Note that this value can be less than or equal to cbSrcLength. An application must use the cbSrcLengthUsed member when advancing to the next piece of source data for the conversion stream.

dwSrcUser

Specifies 32 bits of user data. This can be any instance data specified by the application.

pbDst

Specifies a pointer to the destination data buffer. This pointer must always refer to the same location while the stream header remains prepared. If an application needs to change the destination location, it must unprepare the header and re-prepare it with the alternate location.

cbDstLength

Specifies the length, in bytes, of the destination data buffer pointed to by pbDst. When the header is prepared, this member must specify the maximum size that will be used in the destination buffer. Conversions can be performed to destination lengths less than or equal to the original prepared size. However, this member must be reset to the original size when unpreparing the header.

cbDstLengthUsed

Specifies the amount of data, in bytes, returned by a conversion. This member is not valid until the conversion is complete. Note that this value can be less than or equal to cbDstLength. An application must use the cbDstLengthUsed member when advancing to the next destination location for the conversion stream.

dwDstUser

Specifies 32 bits of user data. This can be any instance data specified by the application.

dwReservedDriver[10]

This member is reserved and should not be used. This member requires no initialization by the application and should never be modified while the header remains prepared.

The source (pbSrc) and destination (pbDst) data buffers must be allocated with GlobalAlloc using the GMEM_MOVEABLE and GMEM_SHARE flags, and locked with GlobalLock.

Before an ACMSTREAMHEADER structure can be used for a conversion, it must be prepared with acmStreamPrepareHeader. When an application is finished with an ACMSTREAMHEADER structure, the acmStreamUnprepareHeader function must be called before freeing the source and destination buffers.


acmStreamOpen

MMRESULT acmStreamOpen(LPHACMSTREAM phas, HACMDRIVER had, LPWAVEFORMATEX pwfxSrc, LPWAVEFORMATEX pwfxDst, LPWAVEFILTER pwfltr, DWORD dwCallback, DWORD dwInstance, DWORD fdwOpen)

The acmStreamOpen function opens an Audio Compression Manager (ACM) conversion stream. Conversion streams are used to convert data from one specified audio format to another.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

MMSYSERR_NOMEM

Unable to allocate resources.

ACMERR_NOTPOSSIBLE

The requested operation cannot be performed.

phas

Specifies a pointer to a HACMSTREAM handle that will receive the new stream handle that can be used to perform conversions. Use this handle to identify the stream when calling other ACM stream conversion functions. This parameter should be NULL if the ACM_STREAMOPENF_QUERY flag is specified.

had

Specifies an optional handle to an ACM driver. If specified, this handle identifies a specific driver to be used for a conversion stream. If this argument is NULL, then all suitable installed ACM drivers are queried until a match is found.

pwfxSrc

Specifies a pointer to a WAVEFORMATEX structure that identifies the source format for the conversion.

pwfxDst

Specifies a pointer to a WAVEFORMATEX structure that identifies the destination format for the conversion.

pwfltr

Specifies a pointer to a WAVEFILTER structure that identifies the filtering operation to perform on the conversion stream. This argument can be NULL if no filtering operation is specified. If a filter is specified, the source (pwfxSrc) and destination (pwfxDst) formats must be the same.

dwCallback

This parameter is reserved and should be set to zero.

dwInstance

This parameter is reserved and should be set to zero.

fdwOpen

Specifies flags for opening the conversion stream.

ACM_STREAMOPENF_QUERY

Specifies that the ACM will be queried to determine whether it supports the given conversion. A conversion stream will not be opened and no HACMSTREAM handle will be returned.

ACM_STREAMOPENF_NONREALTIME

Specifies that the ACM will not consider time constraints when converting the data. By default, the driver will attempt to convert the data in real time. Note that for some formats, specifying this flag might improve the audio quality or other characteristics.

Note that if an ACM driver cannot perform real-time conversions, and the ACM_STREAMOPENF_NONREALTIME flag is not specified for the fdwOpen argument, the open will fail returning an ACMERR_NOTPOSSIBLE error code. An application can use the ACM_STREAMOPENF_QUERY flag to determine if real-time conversions are supported for the input arguments.


acmStreamPrepareHeader

MMRESULT acmStreamPrepareHeader(HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwPrepare)

The acmStreamPrepareHeader function prepares an ACMSTREAMHEADER for an Audio Compression Manager (ACM) stream conversion. This function must be called for every stream header before it can be used in a conversion stream. An application only needs to prepare a stream header once for the life of a given stream; the stream header can be reused as long as the size of the source and destination buffers do not exceed the sizes used when the stream header was originally prepared.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_NOMEM

Unable to allocate resources.

has

Specifies a handle to the conversion stream.

pash

Specifies a pointer to an ACMSTREAMHEADER structure that identifies the source and destination data buffers to be prepared.

fdwPrepare

This argument is not used and must be set to zero.

The ACMSTREAMHEADER data structure and the source (pbSrc) and destination (pbDst) data buffers must be allocated with GlobalAlloc using the GMEM_MOVEABLE and GMEM_SHARE flags, and locked with GlobalLock.

Preparing a stream header that has already been prepared has no effect, and the function returns zero. However, an application should take care to structure code so multiple prepares do not occur.


acmStreamReset

MMRESULT acmStreamReset(HACMSTREAM has, DWORD fdwReset)

The acmStreamReset function stops conversions for a given Audio Compression Manager (ACM) stream.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

has

Specifies the conversion stream.

fdwReset

This argument is not used and must be set to zero.

This function is intended for future use. With the current implementation it does not need to be called.


acmStreamSize

MMRESULT acmStreamSize(HACMSTREAM has, DWORD cbInput, LPDWORD pdwOutputBytes, DWORD fdwSize)

The acmStreamSize function returns a recommended size for a source or destination buffer on an Audio Compression Manager (ACM) stream.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

ACMERR_NOTPOSSIBLE

The requested operation cannot be performed.

has

Specifies the conversion stream.

cbInput

Specifies the size in bytes of either the source or destination buffer. The fdwSize flags specify what the input argument defines. This argument must be non-zero.

pdwOutputBytes

Specifies a pointer to a DWORD that contains the size in bytes of the source or destination buffer. The fdwSize flags specify what the output argument defines. If the acmStreamSize function succeeds, this location will always be filled with a non-zero value.

fdwSize

Specifies flags for the stream-size query.

ACM_STREAMSIZEF_SOURCE

Indicates that cbInput contains the size of the source buffer. The pdwOutputBytes argument will receive the recommended destination buffer size in bytes.

ACM_STREAMSIZEF_DESTINATION

Indicates that cbInput contains the size of the destination buffer. The pdwOutputBytes argument will receive the recommended source buffer size in bytes.

An application can use the acmStreamSize function to determine suggested buffer sizes for either source or destination buffers. The buffer sizes returned might be only an estimation of the actual sizes required for conversion. Because actual conversion sizes cannot always be determined without performing the conversion, the sizes returned will usually be overestimated.

In the event of an error, the location pointed to by pdwOutputBytes will receive zero. This assumes that the pointer specified by pdwOutputBytes is valid.


acmStreamUnprepareHeader

MMRESULT acmStreamUnprepareHeader(HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwUnprepare)

The acmStreamUnprepareHeader function cleans up the preparation performed by the acmStreamPrepareHeader function for an Audio Compression Manager (ACM) stream. This function must be called after the ACM is finished with the given buffers. An application must call this function before freeing the source and destination buffers.

•	Returns zero if the function was successful. Otherwise, it returns a non-zero error number. Possible error returns are the following:

MMSYSERR_INVALHANDLE

Specified handle is invalid.

MMSYSERR_INVALPARAM

One or more arguments passed are invalid.

MMSYSERR_INVALFLAG

One or more flags are invalid.

ACMERR_BUSY

The stream header pash is currently in use and cannot be unprepared.

ACMERR_UNPREPARED

The stream header pash is currently not prepared by the acmStreamPrepareHeader function.

has

Specifies a handle to the conversion stream.

pash

Specifies a pointer to an ACMSTREAMHEADER structure that identifies the source and destination data buffers to be unprepared.

fdwUnprepare

This argument is not used and must be set to zero.

Unpreparing a stream header that has already been unprepared is an error. An application must specify the source and destination buffer lengths (cbSrcLength and cbDstLength respectively) that were used during the corresponding acmStreamPrepareHeader call. Failing to reset these member values will cause acmStreamUnprepareHeader to fail with MMSYSERR_INVALPARAM.

Note that there are some errors that the ACM can recover from. The ACM will return a non-zero error, yet the stream header will be properly unprepared. To determine whether the stream header was actually unprepared an application can examine the ACMSTREAMHEADER_STATUSF_PREPARED flag. The header will always be unprepared if acmStreamUnprepareHeader returns success.


MM_ACM_FILTERCHOOSE

This message notifies an acmFilterChoose dialog hook function before adding an element to one of the three drop-down list boxes. This message allows an application to further customize the selections available through the user interface.

wParam

Specifies the drop-down list box being initialized and a verify or add operation.

FILTERCHOOSE_FILTERTAG_VERIFY

Specifies that lParam is a wave filter tag to be listed in the Filter Tag drop-down list box.

FILTERCHOOSE_FILTER_VERIFY

Specifies that lParam is a pointer to a WAVEFILTER structure to be added to the Filter drop-down list box.

FILTERCHOOSE_CUSTOM_VERIFY

The lParam value is a pointer to a WAVEFILTER structure to be added to the custom Name drop-down list box.

FILTERCHOOSE_FILTERTAG_ADD

Specifies that lParam is a pointer to a DWORD that will accept a wave filter tag to be added to the Filter Tag drop-down list box.

FILTERCHOOSE_FILTER_ADD

Specifies that lParam is a pointer to a buffer that will accept a WAVEFILTER structure to be added to the Filter drop-down list box. The application must copy the filter structure to be added into this buffer.

lParam

Defined by the list box specified in the wParam argument.

•	If an application handles this message, it must return TRUE; otherwise, it must return FALSE. If processing a verify operation, the application must precede the return with SetWindowLong(hwnd, DWL_MSGRESULT, (LONG)FALSE) to prevent the dialog from listing this selection, or SetWindowLong(hwnd, DWL_MSGRESULT, (LONG)TRUE) to allow the dialog box to list this selection. If processing an add operation, the application must precede the return with SetWindowLong(hwnd, DWL_MSGRESULT, (LONG)FALSE) to indicate that no more additions are required, or SetWindowLong(hwnd, DWL_MSGRESULT, (LONG)TRUE) if more additions are required.

If processing the FILTERCHOOSE_FILTER_ADD operation, the size of the memory buffer supplied in lParam will be determined from acmMetrics.


MM_ACM_FORMATCHOOSE

This message notifies an acmFormatChoose dialog hook function before adding an element to one of the three drop-down list boxes. This message allows an application to further customize the selections available through the user interface.

wParam

Specifies the drop-down list box being initialized and a verify or add operation.

FORMATCHOOSE_FORMATTAG_VERIFY

Specifies that lParam is a wave format tag to be listed in the Format Tag drop-down list box.

FORMATCHOOSE_FORMAT_VERIFY

Specifies that lParam is a pointer to a WAVEFORMATEX structure to be added to the Format drop-down list box.

FORMATCHOOSE_CUSTOM_VERIFY

The lParam value is a pointer to a WAVEFORMATEX structure to be added to the custom Name drop-down list box.

FORMATCHOOSE_FORMATTAG_ADD

Specifies that lParam is a pointer to a DWORD that will accept a wave format tag to be added to the Format Tag drop-down list box.

FORMATCHOOSE_FORMAT_ADD

Specifies that lParam is a pointer to a buffer that will accept a WAVEFORMATEX to be added to the Format drop-down list box. The application must copy the format structure to be added into this buffer.

lParam

Defined by the list box specified in the wParam parameter.

•	If an application handles this message, it must return TRUE; otherwise, it must return FALSE. If processing a verify operation, the application must precede the return with SetWindowLong(hwnd, DWL_MSGRESULT, (LONG)FALSE) to prevent the dialog from listing this selection, or SetWindowLong(hwnd, DWL_MSGRESULT, (LONG)TRUE) to allow the dialog box to list this selection. If processing an add operation, the application must precede the return with SetWindowLong(hwnd, DWL_MSGRESULT, (LONG)FALSE) to indicate that no more additions are required or SetWindowLong(hwnd, DWL_MSGRESULT, (LONG)TRUE) if more additions are required.

If processing the FILTERCHOOSE_FORMAT_ADD operation, the size of the memory buffer supplied in lParam will be determined from acmMetrics.


WAVEFILTER

The WAVEFILTER structure defines a filter for waveform data. Only filter information common to all waveform data filters is included in this structure. For filters that require additional information, this structure is included as the first member in another structure, along with the additional information.

typedef struct {

DWORD cbStruct;

DWORD dwFilterTag;

DWORD fdwFilter;

DWORD dwReserved[5];

} WAVEFILTER;

cbStruct

Specifies the size, in bytes, of the WAVEFILTER structure. The size specified in this member must be large enough to contain the base WAVEFILTER structure.

dwFilterTag

Specifies the waveform filter type. Filter tags are registered with Microsoft for various filter algorithms.

fdwFilter

Specifies flags for the dwFilterTag. The flags defined for this member are universal to all filters. Currently, no flags are defined.

dwReserved[5]

This member is reserved for system use and should not be examined or modified by an application.


WAVEFORMATEX

The WAVEFORMATEX structure defines the format of waveform data. Only format information common to all waveform data formats is included in this structure. For formats that require additional information, this structure is included as the first member in another structure, along with the additional information.

typedef struct {

WORD wFormatTag;

WORD nChannels;

DWORD nSamplesPerSec;

DWORD nAvgBytesPerSec;

WORD nBlockAlign;

WORD wBitsPerSample;

WORD cbSize;

} WAVEFORMATEX;

wFormatTag

Specifies the waveform format type. Format tags are registered with Microsoft for many compression algorithms.

nChannels

Specifies the number of channels in the waveform data. Monaural data uses one channel and stereo data uses two channels.

nSamplesPerSec

Specifies the sample rate, in samples per second (Hertz), that each channel should be played or recorded. If wFormatTag is WAVE_FORMAT_PCM, then common values for nSamplesPerSec are 8.0 kHz, 11.025 kHz, 22.05 kHz, and 44.1 kHz. For non-PCM formats, this member must be computed according to the manufacturer's specification of the format tag.

nAvgBytesPerSec

Specifies the required average data-transfer rate, in bytes per second, for the format tag. If wFormatTag is WAVE_FORMAT_PCM, then nAvgBytesPerSec should be equal to the product of nSamplesPerSec and nBlockAlign. For non-PCM formats, this member must be computed according to the manufacturer's specification of the format tag.

Playback and record software can estimate buffer sizes using the nAvgBytesPerSec member.

nBlockAlign

Specifies the block alignment, in bytes. The block alignment is the minimum atomic unit of data for the wFormatTag. If wFormatTag is WAVE_FORMAT_PCM, then nBlockAlign should be equal to the product of nChannels and wBitsPerSample divided by 8 (bits per byte). For non-PCM formats, this member must be computed according to the manufacturer's specification of the format tag.

Playback and record software must process a multiple of nBlockAlign bytes of data at a time. Data written and read from a device must always start at the beginning of a block. For example, it is illegal to start playback of PCM data in the middle of a sample (that is, on a non-block-aligned boundary).

wBitsPerSample

Specifies the bits per sample for the wFormatTag. If wFormatTag is WAVE_FORMAT_PCM, then wBitsPerSample should be equal to 8 or 16. For non-PCM formats, this member must be set according to the manufacturer's specification of the format tag. Note that some compression schemes cannot define a value for wBitsPerSample, so this member can be zero.

cbSize

Specifies the size, in bytes, of extra format information appended to the end of the WAVEFORMATEX structure. This information can be used by non-PCM formats to store extra attributes for the wFormatTag. If no extra information is required by the wFormatTag, then this member must be set to zero. Note that for WAVE_FORMAT_PCM formats (and only WAVE_FORMAT_PCM formats), this member is ignored.

An example of a format that uses extra information is the Microsoft Adaptive Delta Pulse Code Modulation (MS-ADPCM) format. The wFormatTag for MS-ADPCM is WAVE_FORMAT_ADPCM. The cbSize member will normally be set to 32. The extra information stored for WAVE_FORMAT_ADPCM is coefficient pairs required for encoding and decoding the waveform data.


Mixer Services


About Mixer Services

Low-level mixer services control the routing of audio lines to a destination device for playing or recording. Many of the concepts of using low-level services are like those for other audio devices. This section presents general information on using low-level mixer services. It covers the following topics:

•	Overview of the mixer architecture

•	Types of controls

•	Querying mixer devices

•	Opening and closing mixer devices

•	Retrieving control details

•	Setting control details


Mixer Architecture Overview

The mixer architecture provides audio line routing services to manage the different audio lines installed on a computer system. The mixer architecture lets several audio source lines map to a single destination, or master audio line. The mixer architecture can support routings , if adequate hardware devices and software drivers are installed.

The basic element of the mixer architecture is an audio line. Each audio line is made of one or more channels of audio waveform data coming from one origin or system resource. For example, a stereo audio line has two data channels, yet is considered a single line.

Each audio line also has zero or more mixer controls associated with it. A mixer control can take on a number of different characteristics, such as controlling volume, depending on the characteristics of the associated audio line.


Control Types

The mixer services include several types of standard controls to associate with audio source lines. The versatility of these controls range from meters to custom-controls. The following types (or classes) of controls are included with the mixer services:

•	Custom control

•	Meters

•	Switches

•	Numbers

•	Sliders

•	Faders

•	Time Controls

•	List Controls


Custom Control

The custom control class is the most generic control class. This type of control lets the mixer driver define the control's characteristics, and by implication, the visual representation of the control.


Meter Controls

Meter controls measure audio data passing through a line. These controls use the MIXERCONTROLDETAILS_SIGNED and MIXERCONTROLDETAILS_UNSIGNED data structures for getting or setting control details. Types of meters include the following:

Signed Meter

Measures integer values in the range of  2 (31)  to 2 (31)   1. The mixer driver defines the limits of this meter.

Peak Meter

Measures the deflection from zero in both the positive and negative directions. The range of integer values for the peak meter is  32,768 to 32,767.

Unsigned Meter

Measures integer values in the range of zero to 2 (32)   1. The mixer driver defines the limits of this meter.


Switch Controls

The switch controls are two-state switches that vary slightly from one another in their characteristics. This class of control uses the MIXERCONTROLDETAILS_BOOLEAN data structure to get and set control details.

Boolean Switch

The generic switch. Its states are TRUE and FALSE.

On/Off Switch

An alternative switch that uses a different graphic than the boolean switch. It can be set to ON or OFF.

Mute Switch

Mutes an audio line (suppressing the data flow of the line) or lets the audio data play. This switch type is important for controlling the lines feeding into the mixer.

Mono Switch

Switches between mono and stereo output for a stereo line. The OFF state lets stereo data play as separate channels. The ON state combines data from both channels as a mono audio line.

Loudness Switch

Boosts low-volume bass for a line when the switch is on. When the switch is off, volume levels are normal. The amount of boost is hardware specific. Check the documentation of your mixer device for additional information.

Stereo Enhanced Switch

Increases stereo separation when the switch is on. When the switch is off, no enhancement occurs.


Number Controls

The number controls let numerical data associated with a line be entered. The numerical data is expressed as signed integers, unsigned integers, or integer decibel values. These controls use the MIXERCONTROLDETAILS_SIGNED or the MIXERCONTROLDETAILS_UNSIGNED data structure to get and set control details.

Signed Control

Allows integer values entered in the range of  2^31 to 2^31  1.

Unsigned Control

Allows integer values entered in the range of zero to 2^32  1.

Decibel Control

Allows integer decibel values to be entered. The range of values for this control is − 32,768 to 32,767 in tenths of decibels.


Slider Controls

Slider controls are normally horizontal controls that can be adjusted to the left or right, as in adjusting the balance of a pair of stereo speakers. These controls use the MIXERCONTROLDETAILS_SIGNED data structure to get and set control details.

Slider Control

Has a range of  32768 to 32767. The mixer driver defines the limits of this control.

Pan Control

Has a range of  32768 to 32767. The mixer driver defines the limits of this control with zero as the midrange value.

QSound® Pan Control

Provides expanded sound control through QSound. This control has a range of  15 to 15. QSound is a registered trademark of QSound Labs, Inc.


Fader Controls

Fader controls are normally vertically-adjustable switches. These controls have a linear scale and use the MIXERCONTROLDETAILS_UNSIGNED data structure to get and set control details.

Fader

General fade control. The range of acceptable values is zero to 65,535.

Volume

General volume fade control. The range of acceptable values is zero to 65,535. Check the documentation of your mixer device to adjust the range of acceptable values.

Bass

Bass volume fade control The range of acceptable values is zero to 65,535. The limits of the bass frequency band are hardware specific. Check the documentation of your mixer device for the band limits.

Treble

Treble volume fade control The range of acceptable values is zero to 65,535. The limits of the treble frequency band are hardware specific. Check the documentation of your mixer device for the band limits.

Equalizer

Graphic equalizer control. The number of equalizer bands and their limits are hardware specific. The range of acceptable values for one band of the equalizer is zero to 65,535. Check the documentation of your mixer device for details about the equalizer.

You can use the MIXERCONTROLDETAILS_LISTTEXT structure to retrieve text labels for the equalizer.


Time Controls

The time controls let timing-related data, such as an echo delay or reverberation, be entered. The time data is expressed as positive integers.

Microsecond Time control

Supports timing data expressed in microseconds. The range of acceptable values is zero to 2^32  1.

Millisecond Control

Supports timing data expressed in milliseconds. The range of acceptable values is zero to 2^32  1.


List Controls

Provide single-select or multiple-select states for complex lines. This class of control uses the MIXERCONTROLDETAILS_BOOLEAN data structure to get and set control details. The MIXERCONTROLDETAILS_LISTTEXT data structure is also used to retrieve all text descriptions of a multiple item control.

Single-select Control

Restricts the control selection to one item at a time. Unlike the multiplexer control, the single-select control can be used to control things other than audio source lines. For example, you could use this control to select a low-pass filter from a list of filters supported by a mixer device.

Multiplexer (MUX)

Restricts the line selection to one source line at a time.

Multiple-select Control

Lets zero or more items from a list be selected at the same time. Unlike the mixer control, the multiple-select control can be used to control things other than audio source lines.

Mixer

Lets zero or more source lines from a list be selected at the same time.


Querying Mixer Devices

Before using a mixer, you must determine its capabilities in the system. Audio capability can vary from one multimedia computer to the next; applications should not make assumptions about the audio hardware present in a given system.

The mixerGetNumDevsfunction is available to determine how many mixer devices are present in the system.

Mixer devices are identified by a device identifier (device ID). The device ID is determined implicitly from the number of devices present in a given system. Device IDs range from zero to one less than the number of devices present.

Once you determine how many mixer devices are present in a system, you can inquire about the capabilities of each device. The mixerGetDevCaps function determines the capabilities of mixer devices. This function takes a pointer to a MIXERCAPS data structure, which it fills with information on the capabilities of a specified device.


Opening and Closing Mixer Devices

After getting the capabilities of a mixer device, you can either explicitly open the device or just begin using it. Explicitly opening a mixer device offers two main benefits:

•	It guarantees the continued existence of that mixer device.

•	It lets you set receive notification of line and control changes.

As long as a handle to a mixer device exists, the mixer device will continue to exist in a system. If a configuration change occurs to the mixer and it hasn't been explicitly opened, your application might suddenly not be able to access it. After opening a mixer device, you should close the device as soon as you finish using it.

The mixerOpen and mixerClose functions open and close mixer devices. These functions are discussed in detail in the reference section of chapter.

Each function that opens a mixer device takes as parameters a device ID, a pointer to a memory location, and some parameters unique to each type of device. The memory location is filled with a device handle. Use this device handle to identify the open mixer device when calling other audio mixer functions.

The distinction between device IDs and device handles is subtle, but very important. Don't confuse the two in your application. The differences between device IDs and device handles are as follows:

•	Device IDs are determined implicitly from the number of devices present in a system, which is obtained by using mixerGetNumDevs.

•	Device handles are returned when device drivers are opened by using the mixerOpen.


Using a Window to Process Driver Messages

The mixer services provide window callback services for your application to process mixer driver messages. To use a window callback, specify the CALLBACK_WINDOW flag in the fdwOpen parameter and a window handle in the dwCallback parameter of mixerOpen. Driver messages will be sent to the window-procedure function for the window identified by the handle in dwCallback.

Messages sent to the window function are specific to the audio device type used. For details on these messages, see the sections later in this chapter on using window messages for each specific audio device type.


Retrieving Line and Control Information

Three functions provide information about lines, line controls, and control details: mixerGetLineInfo, mixerGetLineControls, and mixerGetControlDetails.

The mixerGetLineInfo function provides information about a specified audio line. This function fills the MIXERLINE structure for a specified source audio line, destination audio line, or a specified line ID. The type of information stored in MIXERLINE includes the destination line number, the number of channels that make up the audio line, as well as a short and a long name for the audio line.

The mixerGetLineControls function retrieves one or more controls associated with an audio mixer line. This function fills the MIXERLINECONTROLS structure with information about the specified control or controls. You can specify for mixerGetLineControls to retrieve control details for one of the following:

•	All controls for a designated source line

•	Specified control for a designated source line

•	First control of a specific type for a designated source line.

The mixerGetControlDetails function retrieves details on a single control associated with an audio mixer device line. This function fills the MIXERCONTROLDETAILS data structure with the current values for a control. To set the control details, use the mixerSetControlDetails function.


Retrieving a Device ID

The mixerGetID function retrieves the audio mixer device ID associated with a specified device handle. For example, You can use mixerGetID to identify the audio mixer that is mixing audio for a specific audio device. Then, use the device ID to adjust the volume or to display another control.


Setting Control Details

The mixerSetControlDetails function uses the contents of the MIXERCONTROLDETAILS structure to set properties of the specified control. All members of the MIXERCONTROLDETAILS structure must be filled-in before calling mixerSetControlDetails.


Reference

This section provides detailed reference information for the low-level mixer functions, structures, and messages. The information is organized alphabetically. In addition, the following table summarizes the reference entries by functional group:

Group	Elements
Query Mixer Devices	MIXERCAPS mixerGetDevCaps mixerGetNumDevs
Open and Close Mixer Devices	mixerClose mixerOpen
Retrieve Mixer IDs	mixerGetID
Retrieve Line Controls	MIXERCONTROL MIXERLINECONTROLS mixerGetLineControls
Send User-defined Messages to the Mixer Driver	mixerMessage
Get and Set Control Attributes	MIXERCONTROLDETAILS MIXERCONTROLDETAILS_BOOLEAN MIXERCONTROLDETAILS_LISTTEXT MIXERCONTROLDETAILS_SIGNED MIXERCONTROLDETAILS_UNSIGNED mixerGetcontrolDetails mixerSetcontrolDetails
Retrieving Line Information	MIXERLINE mixerGetLineInfo MM_MIXM_LINE_CHANGE MM_MIXM_CONTROL_CHANGE


MIXERCAPS

The MIXERCAPS structure describes the capabilities of a mixer device.

typedef struct {

    WORD wMid;

    WORD wPid;

    VERSION vDriverVersion;

    char szPname[MAXPNAMELEN];

    DWORD fdwSupport;

    DWORD cDestinations;

} MIXERCAPS;

wMid

Specifies a manufacturer identifier for the mixer device driver.

wPid

Specifies a product identifier for the mixer device driver.

vDriverVersion

Specifies the version number of the mixer device driver. The high-order byte is the major version number, and the low-order byte is the minor version number.

szPname[MAXPNAMELEN]

Specifies the name of the product. If the mixer device driver supports multiple cards, this string must uniquely and easily identify (potentially to a user) the specific card. For example, szPname = "Sound Card Mixer, I/O address 200" would uniquely identify (to the user) this particular card as a Sound Card Mixer for the physical card based at I/O address 200. If only one device is installed, it is recommended that only the base name be returned. For example, szPname should be "Sound Card Mixer" if only one device is present.

fdwSupport

Specifies various support information for the mixer device driver. No extended support bits are currently defined.

cDestinations

The number of audio mixer line destinations available through the mixer. All mixer devices must support at least one destination line, so this member can not be zero. Destination indexes used in the dwDestination member of the MIXERLINE structure range from zero to the value specified in the cDestinations member minus one.


mixerClose

MMRESULT mixerClose(HMIXER hmx)

Closes the specified audio mixer device. An application must close all mixer handles before exiting (or when the application is finished using the device).

•	Returns zero if the function is successful. Otherwise, it returns a non-zero error number. Possible error returns are:

MMSYSERR_INVALHANDLE

Specified device handle is invalid.

hmx

Specifies a handle to the audio mixer device. This handle must have been returned successfully by mixerOpen. If mixerClose is successful, hmx is no longer valid.


MIXERCONTROL

The MIXERCONTROL structure describes the state and metrics of a single control for an audio mixer line.

typedef struct

{

    DWORD           cbStruct;

    DWORD           dwControlID;

    DWORD           dwControlType;

    DWORD           fdwControl;

    DWORD           cMultipleItems;

    char            szShortName[MIXER_SHORT_NAME_CHARS];

    char            szName[MIXER_LONG_NAME_CHARS];

    union

    {

        struct

        {

            LONG    lMinimum;

            LONG    lMaximum;

        };

        struct

        {

            DWORD   dwMinimum;

            DWORD   dwMaximum;

        };

        DWORD       dwReserved[6];

    } Bounds;

    union

    {

        DWORD       cSteps;

        DWORD       cbCustomData;

        DWORD       dwReserved[6];

    } Metrics;

} MIXERCONTROL;

cbStruct

Specifies the size, in bytes, of the MIXERCONTROL structure. The calling application does not need to initialize this member or other members of this structure because MIXERCONTROL is passed to mixerGetLineControls as a receiving buffer that is referenced and described by MIXERLINECONTROLS. When mixerGetLineControls returns, this member contains the actual size of the information returned by the mixer device. The returned information will not exceed the requested size, nor will it be smaller than the base MIXERCONTROL structure.

dwControlID

Specifies an audio-mixer-defined identifier that uniquely refers to the control described by the MIXERCONTROL structure. This identifier is unique to a single mixer device and can be any format supported by the mixer device. An application should only use this identifier as an abstract handle. No two controls for a single mixer device will have the same control identifier under any circumstances.

dwControlType

Specifies the type of the control whose ID is specified in dwControlID. An application must use this information to display the appropriate control for input from the user. An application may also wish to display tailored graphics based on the control type or search for a particular control type on a specific line. If an application does not know about a control type, then this control must be ignored. There are currently seven different control type classifications.

The custom control class (MIXERCONTROL_CT_CLASS_CUSTOM) includes the following standard control types:

MIXERCONTROL_CONTROLTYPE_CUSTOM

The meter control class (MIXERCONTROL_CT_CLASS_METER) includes the following standard control types:

MIXERCONTROL_CONTROLTYPE_SIGNEDMETER
MIXERCONTROL_CONTROLTYPE_PEAKMETER
MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER

The switch control type class (MIXERCONTROL_CT_CLASS_SWITCH) includes the following standard control types:

MIXERCONTROL_CONTROLTYPE_BOOLEAN
MIXERCONTROL_CONTROLTYPE_ONOFF
MIXERCONTROL_CONTROLTYPE_MUTE
MIXERCONTROL_CONTROLTYPE_MONO
MIXERCONTROL_CONTROLTYPE_LOUDNESS
MIXERCONTROL_CONTROLTYPE_STEREOENH

The number control type class (MIXERCONTROL_CT_CLASS_NUMBER) includes the following standard control types:

MIXERCONTROL_CONTROLTYPE_SIGNED
MIXERCONTROL_CONTROLTYPE_UNSIGNED

The slider control class (MIXERCONTROL_CT_CLASS_SLIDER) includes the following standard control types:

MIXERCONTROL_CONTROLTYPE_SLIDER
MIXERCONTROL_CONTROLTYPE_PAN
MIXERCONTROL_CONTROLTYPE_QSOUNDPAN

The fader control class (MIXERCONTROL_CT_CLASS_FADER) includes the following standard control types:

MIXERCONTROL_CONTROLTYPE_FADER
MIXERCONTROL_CONTROLTYPE_VOLUME
MIXERCONTROL_CONTROLTYPE_BASS
MIXERCONTROL_CONTROLTYPE_TREBLE
MIXERCONTROL_CONTROLTYPE_EQUALIZER

The time control class MIXERCONTROL_CT_CLASS_TIME includes the following standard control types:

MIXERCONTROL_CONTROLTYPE_MICROTIME
MIXERCONTROL_CONTROLTYPE_MILLITIME

The list control class MIXERCONTROL_CT_CLASS_LIST includes the following standard control types:

MIXERCONTROL_CONTROLTYPE_SINGLESELECT
MIXERCONTROL_CONTROLTYPE_MUX
MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT
MIXERCONTROL_CONTROLTYPE_MIXER

fdwControl

Specifies status and support flags for the audio mixer line control.

MIXERCONTROL_CONTROLF_UNIFORM

Specifies that the control acts on all channels of a multi-channel line in a uniform fashion. For example, a Mute control that mutes both channels of a stereo line would set this flag. Most MUX and Mixer controls will also specify the MIXERCONTROL_CONTROLF_UNIFORM flag.

MIXERCONTROL_CONTROLF_MULTIPLE

Specifies that the control has two or more settings per channel. An example of a control that requires the multiple flag is an equalizer--each frequency band can be set to different values. Note that an equalizer that affects both channels of a stereo line in a uniform fashion will also set the MIXERCONTROL_CONTROLF_UNIFORM flag.

MIXERCONTROL_CONTROLF_DISABLED

Specifies that the control is disabled (perhaps due to other settings for the mixer hardware) and cannot be used. An application can read current settings from a disabled control, but cannot apply settings.

cMultipleItems

Specifies the number of items per channel that make up a MIXERCONTROL_CONTROLF_MULTIPLE control. This number will always be two or greater for multiple item controls. If the control is not a multiple item control, do not use this member; it will be zero.

szShortName[MIXER_SHORT_NAME_CHARS]

Specifies a short string that describes the dwControlID audio mixer line control. This description is appropriate to use as a concise label for the control.

szName[MIXER_LONG_NAME_CHARS]

Specifies a string that describes the dwControlID audio mixer line control. This description is appropriate to use as a complete description for the control.

Bounds

Contains the union of boundary types.

dwMinimum

Specifies the minimum unsigned value for a control that has an unsigned boundary nature. Refer to the description for each control type to determine if this member is appropriate for the control. This member overlaps with the lMinimum member and cannot be used in conjunction with that member.

dwMaximum

Specifies the maximum unsigned value for a control that has an unsigned boundary nature. Refer to the description for each control type to determine if this member is appropriate for the control. This member overlaps with the lMaximum member and cannot be used in conjunction with that member.

lMinimum

Specifies the minimum signed value for a control that has a signed boundary nature. Refer to the description for each control type to determine if this member is appropriate for the control. This member overlaps with the dwMinimum member and cannot be used in conjunction with that member.

lMaximum

Specifies the maximum signed value for a control that has a signed boundary nature. Refer to the description for each control type to determine if this member is appropriate for the control. This member overlaps with the dwMaximum member and cannot be used in conjunction with that member.

Metrics

Contains the union of boundary metrics.

cSteps

Specifies the number of discrete ranges within the specified Bounds for a control. Refer to the description for each control type to determine if this member is appropriate for the control. This member overlaps with the other members of the Metrics structure member and cannot be used in conjunction with those members.

cbCustomData

Specifies the size, in bytes, required to hold the state of a custom control type. This member is only appropriate for the MIXERCONTROL_CONTROLTYPE_CUSTOM control type. See the description for custom control types for more information on the use of this member.


MIXERCONTROLDETAILS

The MIXERCONTROLDETAILS structure references control detail structures to retrieve or set state information of an audio mixer control. All members of this structure must be initialized before calling the mixerGetControlDetails and mixerSetControlDetails functions.

typedef struct {

    DWORD cbStruct;

    DWORD dwControlID;

    DWORD cChannels;

    DWORD cMultipleItems;

    DWORD cbDetails;

    LPVOID paDetails;

} MIXERCONTROLDETAILS;

cbStruct

Specifies the size, in bytes, of the MIXERCONTROLDETAILS structure. This member must be initialized before calling mixerGetControlDetails and mixerSetControlDetails. The size specified in this member must be large enough to contain the base MIXERCONTROLDETAILS structure. When mixerGetControlDetails returns, this member contains the actual size of the information returned. The returned information will not exceed the requested size, nor  will it be smaller than the base MIXERCONTROLDETAILS structure.

dwControlID

Specifies the control identifier on which to get or set details. This member must always be initialized before calling mixerGetControlDetails and mixerSetControlDetails.

cChannels

Specifies the number of channels on which to get or set control details. Acceptable values for this member follow:

zero

Use this value when the control is a MIXERCONTROL_CONTROLTYPE_CUSTOM control.

one

Use this value when the control is a MIXERCONTROL_CONTROLF_UNIFORM control or when an application wishes to get and set all channels as if they were uniform.

cChannels

Use this value when the details for the control are expected on all channels for a line

An application is not allowed to specify any value that comes between one and the number of channels for the line. For example, specifying two or three for a four channel line is not valid. This member can not be zero for non-custom control types.

cMultipleItems

Specifies the number of multiple items per channel on which to get or set details. Acceptable values for this member follow:

zero

Use this value for all controls other than a MIXERCONTROL_CONTROLF_MULTIPLE or a MIXERCONTROL_CONTROLTYPE_CUSTOM control.

cMultipleItems

Use this value when the control is MIXERCONTROL_CONTROLF_MULTIPLE control.

hwndOwner

Use this value when the control is a MIXERCONTROL_CONTROLTYPE_CUSTOM control and the MIXERCONTROL_CONTROLTYPE_CUSTOM flag is specified for mixerSetControlDetails. In this case, the hwndOwner member overlaps with cMultipleItems, providing the value of the window handle.

When using a MIXERCONTROL_CONTROLTYPE_CUSTOM control without the MIXERCONTROL_CONTROLTYPE_CUSTOM flag, use the value of zero.

An application is not allowed to specify any value other than the value specified in the cMultipleItems member of the MIXERCONTROL structure for a MIXERCONTROL_CONTROLF_MULTIPLE control.

cbDetails

Specifies the size, in bytes, of one of the following details structure being used:

MIXERCONTROLDETAILS_UNSIGNED

Defines an unsigned value for a mixer line control.

MIXERCONTROLDETAILS_SIGNED

Defines an signed value for a mixer line control.

MIXERCONTROLDETAILS_BOOLEAN

Defines a Boolean value for a mixer line control.

MIXERCONTROLDETAILS_LISTTEXT

Defines a list text buffer for a mixer line control.

Refer to the description of the control type for information on the appropriate details structure for a specific control.

If the control is a MIXERCONTROL_CONTROLTYPE_CUSTOM control, this member must be equal to the cbCustomData member of the MIXERCONTROL structure.

paDetails

Points to an array of one or more details structures to get or set details for the specified control in. The required size for this buffer is computed as follows:

For controls that are MIXERCONTROL_CONTROLF_MULTIPLE types, the size of this buffer is the product of the cChannels, cMultipleItems and cbDetails members of the MIXERCONTROLDETAILS structure.

For controls other than MIXERCONTROL_CONTROLF_MULTIPLE types, the size of this buffer is the product of the cChannels and cbDetails members of the MIXERCONTROLDETAILS structure.

The layout of the details elements in this array are as follows:

For controls that are MIXERCONTROL_CONTROLF_MULTIPLE types, the array can be thought of as a two dimensional array that is 'channel major'. That is, all multiple items for the left channel are given, then all multiple items for the right channel, etc.

For controls other than MIXERCONTROL_CONTROLF_MULTIPLE types, each element index is equivalent to the zero based channel that it affects. That is, paDetails[0] is for the left channel, paDetails[1] is for the right channel.

If the control is a MIXERCONTROL_CONTROLTYPE_CUSTOM control, then this member must point to a buffer that is at least large enough to hold the size, in bytes, specified by the cbCustomData member of the MIXERCONTROL structure.

The following example shows how to address a single item in a multiple item control for using the MIXERCONTROLDETAILS_SIGNED details structure.

{

    MIXERCONTROLDETAILS         mxcd;

    PMIXERCONTROLDETAILS_SIGNED pamxcd_s;

    PMIXERCONTROLDETAILS_SIGNED pmxcd_s;

    //  Assumptions:

    //

    //  'mxcd' is a valid MIXERCONTROLDETAILS structure.

    //

    //  'channel' is a valid channel ranging from zero to one less

    //  than the number of channels available for the signed control.

    //

    //  'item' is a valid item index ranging from zero to one less

    //  than the number of 'multiple items' stored in the variable

    //  called 'cMultipleItems'.

    //

    pamxcd_s = (PMIXERCONTROLDETAILS_SIGNED)mxcd.paDetails;

    pmxcd_s  = &pamxcd_s[(channel * cMultipleItems) + item];

}


MIXERCONTROLDETAILS_BOOLEAN

The MIXERCONTROLDETAILS_BOOLEAN structure is used to get and set Boolean type control details for an audio mixer control. Refer to the control type description of the desired control to determine an appropriate details structure to use.

typedef struct {

    LONG fValue;

} MIXERCONTROLDETAILS_BOOLEAN;

fValue

Specifies the Boolean value for a single item or channel. This value is assumed to zero for a 'FALSE' state (for example, off or disabled). This value is assumed to be non-zero for a 'TRUE' state (for example, on or enabled).

The following standard control types use the MIXERCONTROLDETAILS_BOOLEAN structure for getting and setting details:

MIXERCONTROL_CONTROLTYPE_BOOLEAN
MIXERCONTROL_CONTROLTYPE_ONOFF
MIXERCONTROL_CONTROLTYPE_MUTE
MIXERCONTROL_CONTROLTYPE_MONO
MIXERCONTROL_CONTROLTYPE_LOUDNESS
MIXERCONTROL_CONTROLTYPE_STEREOENH

MIXERCONTROL_CONTROLTYPE_SINGLESELECT
MIXERCONTROL_CONTROLTYPE_MUX
MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT
MIXERCONTROL_CONTROLTYPE_MIXER


MIXERCONTROLDETAILS_LISTTEXT

The MIXERCONTROLDETAILS_LISTTEXT structure is used to get list text, label text, and/or band range information for multiple item controls. This structure is used when the MIXER_GETCONTROLDETAILSF_LISTTEXT flag is specified in the mixerGetControlDetails function.

typedef struct {

    DWORD dwParam1;

    DWORD dwParam1;

    char szName[MIXER_LONG_NAME_CHARS];

} MIXERCONTROLDETAILS_LISTTEXT;

dwParam1

Specifies the first 32 bit control type specific value. Refer to the description of the multiple item control type for information on what this value represents for the given control.

dwParam1

Specifies the second 32 bit control type specific value. Refer to the description of the multiple item control type for information on what this value represents for the given control.

szName[MIXER_LONG_NAME_CHARS]

Specifies a name that describes a single item in a multiple item control. This text can be used as a label or item text depending on the specific control type.

The following standard control types use the MIXERCONTROLDETAILS_LISTTEXT structure for getting the item text descriptions on multiple item controls:

MIXERCONTROL_CONTROLTYPE_EQUALIZER

MIXERCONTROL_CONTROLTYPE_SINGLESELECT
MIXERCONTROL_CONTROLTYPE_MUX
MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT
MIXERCONTROL_CONTROLTYPE_MIXER


MIXERCONTROLDETAILS_SIGNED

The MIXERCONTROLDETAILS_SIGNED structure is used to get and set signed type control details for an audio mixer control. Refer to the control type description of the desired control to determine an appropriate details structure to use.

typedef struct {

    LONG lValue;

} MIXERCONTROLDETAILS_SIGNED;

lValue

Specifies a signed integer value for a single item or channel. This value must be inclusively within the bounds given in the Bounds structure member of the MIXERCONTROL structure for signed integer controls.

The following standard control types use the MIXERCONTROLDETAILS_SIGNED structure for getting and setting details:

MIXERCONTROL_CONTROLTYPE_SIGNEDMETER
MIXERCONTROL_CONTROLTYPE_PEAKMETER

MIXERCONTROL_CONTROLTYPE_SIGNED

MIXERCONTROL_CONTROLTYPE_SLIDER
MIXERCONTROL_CONTROLTYPE_PAN
MIXERCONTROL_CONTROLTYPE_QSOUNDPAN


MIXERCONTROLDETAILS_UNSIGNED

The MIXERCONTROLDETAILS_UNSIGNED structure is used to get and set unsigned type control details for an audio mixer control. Refer to the control type description of the desired control to determine an appropriate details structure to use.

typedef struct {

    DWORD dwValue;

} MIXERCONTROLDETAILS_UNSIGNED;

dwValue

Specifies an unsigned integer value for a single item or channel. This value must be inclusively within the bounds given in the Bounds structure member of the MIXERCONTROL structure for unsigned integer controls.

The following standard control types use the MIXERCONTROLDETAILS_UNSIGNED structure for getting and setting details:

MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER

MIXERCONTROL_CONTROLTYPE_UNSIGNED

MIXERCONTROL_CONTROLTYPE_FADER
MIXERCONTROL_CONTROLTYPE_VOLUME
MIXERCONTROL_CONTROLTYPE_BASS
MIXERCONTROL_CONTROLTYPE_TREBLE
MIXERCONTROL_CONTROLTYPE_EQUALIZER

MIXERCONTROL_CONTROLTYPE_MICROTIME
MIXERCONTROL_CONTROLTYPE_MILLITIME


mixerGetControlDetails

MMRESULT mixerGetControlDetails(HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails)

Retrieve details on a single control associated with an audio mixer device line.

•	The return value is zero if the function is successful. Otherwise, it returns a non-zero error number. Possible error returns include the following:

MMSYSERR_BADDEVICEID

The hmxobj argument specifies an invalid device identifier.

MMSYSERR_INVALHANDLE

The hmxobj argument specifies an invalid handle.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_INVALPARAM

One or more arguments passed is invalid.

MMSYSERR_NODRIVER

No audio mixer device is available for the object specified by hmxobj.

MIXERR_INVALCONTROL

The control reference is invalid.

hmxobj

Specifies a handle to the audio mixer device object being queried.

pmxcd

Points to a MIXERCONTROLDETAILS structure. This structure is used to reference control detail structures to be filled with state information about the control. See the comments for each query flag passed through fdwDetails for details on the members of the MIXERCONTROLDETAILS structure that must be initialized before calling the mixerGetControlDetails function. Note that in all cases, the cbStruct member of the MIXERCONTROLDETAILS structure must be initialized to be the size, in bytes, of the MIXERCONTROLDETAILS structure.

fdwDetails

Specifies flags for getting details on a control.

MIXER_GETCONTROLDETAILSF_VALUE

If this flag is specified, the current value(s) for a control are retrieved. The paDetails member of the MIXERCONTROLDETAILS points to one or more details structures appropriate for the control type. Refer to the description of the MIXERCONTROLDETAILS structure for information on the structure members that must be initialized before calling mixerGetControlDetails.

MIXER_GETCONTROLDETAILSF_LISTTEXT

If this flag is specified, the paDetails member of the MIXERCONTROLDETAILS structure points to one or more MIXERCONTROLDETAILS_LISTTEXT structures to receive text labels for multiple item controls. Note that an application must get all list text items for a multiple item control at once. Refer to the description of the MIXERCONTROLDETAILS structure for information on the structure members that must be initialized before calling mixerGetControlDetails. This flag cannot be used with MIXERCONTROL_CONTROLTYPE_CUSTOM controls.

MIXER_OBJECTF_MIXER

Specifies that hmxobj is an audio mixer device identifier in the range of zero to one less than the number of devices returned by mixerGetNumDevs. This flag is optional.

MIXER_OBJECTF_HMIXER

Specifies that hmxobj is a mixer device handle returned by mixerOpen. This flag is optional.

MIXER_OBJECTF_WAVEOUT

Specifies that hmxobj is a waveform output device identifier in the range of zero to one less than the number of devices returned by waveOutGetNumDevs.

MIXER_OBJECTF_HWAVEOUT

Specifies that hmxobj is a waveform output handle returned by waveOutOpen.

MIXER_OBJECTF_WAVEIN

Specifies that hmxobj is a waveform input device identifier in the range of zero to one less than the number of devices returned by waveInGetNumDevs.

MIXER_OBJECTF_HWAVEIN

Specifies that hmxobj is a waveform input handle returned by waveInOpen.

MIXER_OBJECTF_AUX

Specifies that hmxobj is an auxiliary device identifier in the range of zero to one less than the number of devices returned by auxGetNumDevs.


mixerGetDevCaps

MMRESULT mixerGetDevCaps(UINT uMxId, LPMIXERCAPS pmxcaps, UINT cbmxcaps)

Queries a specified audio mixer device to determine its capabilities.

•	The return value is zero if the function is successful. Otherwise, it returns a non-zero error number. Possible error returns include the following:

MMSYSERR_BADDEVICEID

The specified device identifier is out of range.

MMSYSERR_INVALHANDLE

The audio mixer device handle passed is invalid.

MMSYSERR_INVALPARAM

One or more arguments passed is invalid.

uMxId

Identifies the audio mixer device with either an audio mixer device identifier or a handle to an opened audio mixer device.

pmxcaps

Pointer to a MIXERCAPS structure that receives information about the capabilities of the device.

cbmxcaps

Specifies the size, in bytes, of the MIXERCAPS structure.

Use the mixerGetNumDevsfunction to determine the number of audio mixer devices present in the system. The device identifier specified by uMxId varies from zero to one less than the number of mixer devices present.

Only cbmxcaps bytes (or less) of information is copied to the location pointed to by pmxcaps. If cbmxcaps is zero, nothing is copied, and the function returns as successful.

This function also accepts an audio mixer device handle returned by the mixerOpen function as the uMxId argument. The calling application should cast the HMIXER handle to a UINT.


mixerGetID

MMRESULT mixerGetID(HMIXEROBJ hmxobj, UINT FAR * puMxId, DWORD fdwId)

Retrieves the device identifier for an audio mixer device associated with an audio mixer object handle hmxobj.

•	The return value is zero if the function is successful. Otherwise, it returns a non-zero error number. Possible error returns include the following:

MMSYSERR_BADDEVICEID

The hmxobj argument specifies an invalid device identifier.

MMSYSERR_INVALHANDLE

The hmxobj argument specifies an invalid handle.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_INVALPARAM

One or more passed arguments are invalid.

MMSYSERR_NODRIVER

No audio mixer device is available for the object specified by hmxobj. The location referenced by puMxId also contains the value "-1".

hmxobj

Identifies the audio mixer object handle to map to an audio mixer device identifier.

puMxId

Points to a UINT-sized variable that will receive the audio mixer device identifier. If no mixer device is available for the hmxobj object, the value "-1" is placed in this location and the MMSYSERR_NODRIVER error code is returned.

fdwId

Specifies flags for how to map the audio mixer object hmxobj.

MIXER_OBJECTF_MIXER

Specifies that hmxobj is an audio mixer device identifier in the range of zero to one less than the number of devices returned by mixerGetNumDevs. This flag is optional.

MIXER_OBJECTF_HMIXER

Specifies that hmxobj is a mixer device handle returned by mixerOpen. This flag is optional.

MIXER_OBJECTF_WAVEOUT

Specifies that hmxobj is a waveform output device identifier in the range of zero to one less than the number of devices returned by waveOutGetNumDevs.

MIXER_OBJECTF_HWAVEOUT

Specifies that hmxobj is a waveform output handle returned by waveOutOpen.

MIXER_OBJECTF_WAVEIN

Specifies that hmxobj is a waveform input device identifier in the range of zero to one less than the number of devices returned by waveInGetNumDevs.

MIXER_OBJECTF_HWAVEIN

Specifies that hmxobj is a waveform input handle returned by waveInOpen.

MIXER_OBJECTF_AUX

Specifies that hmxobj is an auxiliary device identifier in the range of zero to one less than the number of devices returned by auxGetNumDevs.

Use the mixerGetID function to determine which audio mixer device (if any) is responsible for performing mixing functions on a media device. For example, an application can use mixerGetID to get the mixer device identifier responsible for setting the volume on a waveform output handle. Or the application may want to display a peak meter for a waveform input device.


mixerGetLineControls

MMRESULT mixerGetLineControls(HMIXEROBJ hmxobj, LPMIXERLINECONTROLS pmxlc, DWORD fdwControls)

Retrieves one or more controls associated with an audio mixer device line.

•	The return value is zero if the function is successful. Otherwise, it returns a non-zero error number. Possible error returns include the following:

MMSYSERR_BADDEVICEID

The hmxobj argument specifies an invalid device identifier.

MMSYSERR_INVALHANDLE

The hmxobj argument specifies an invalid handle.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_INVALPARAM

One or more passed arguments are invalid.

MMSYSERR_NODRIVER

No audio mixer device is available for the object specified by hmxobj.

MIXERR_INVALLINE

The audio mixer device line reference is invalid.

MIXERR_INVALCONTROL

The control reference is invalid.

hmxobj

Specifies a handle to the audio mixer device object that is being queried.

pmxlc

Points to a MIXERLINECONTROLS structure. This structure is used to reference one or more MIXERCONTROL structures to be filled with information about the controls associated with a mixer line. See the comments for each query flag passed through fdwControls for details on the members of the MIXERLINECONTROLS structure that must be initialized. Note that in all cases, the cbStruct member of the MIXERLINECONTROLS structure must be initialized to be the size, in bytes, of the MIXERLINECONTROLS structure.

fdwControls

Specifies flags for getting information about one or more control associated with a mixer line.

MIXER_GETLINECONTROLSF_ALL

If this flag is specified, pmxlc references a list of MIXERCONTROL structures that will receive information on all controls associated with the line identified by the dwLineID member of the MIXERLINECONTROLS structure. cControls must be initialized to the number of controls associated with the line. This number is retrieved from the cControls member of the MIXERLINE structure returned by the mixerGetLineInfo function. cbmxctrl must be initialized to the size, in bytes, of a single MIXERCONTROL structure. pamxctrl must point to the first MIXERCONTROL structure to be filled in. Both the dwControlID and dwControlType members are ignored for this query.

MIXER_GETLINECONTROLSF_ONEBYID

If this flag is specified, pmxlc references a single MIXERCONTROL structure that will receive information on the control identified by the dwControlID member of the MIXERLINECONTROLS structure. cControls must be initialized to one. cbmxctrl must be initialized to the size, in bytes, of a single MIXERCONTROL structure. pamxctrl must point to a MIXERCONTROL structure to be filled in. Both the dwLineID and dwControlType members are ignored for this query. This query is usually used to refresh a control after receiving a MM_MIXM_CONTROL_CHANGE control change notification message by the user-specified callback (see mixerOpen).

MIXER_GETLINECONTROLSF_ONEBYTYPE

If this flag is specified, mixerGetLineControls retrieves information about the first control of a specific type for the line that is being queried. pmxlc references a single MIXERCONTROL structure that will receive information about the specific control. The audio line is identified by dwLineID The control type is specified in the dwControlType member of the MIXERLINECONTROLS structure.

The dwControlID member is ignored for this query. This query can be used by an application to get information on single control associated with a line. For example, an application may only want to use a peak meter from a waveform output line.

MIXER_OBJECTF_MIXER

Specifies that hmxobj is an audio mixer device identifier in the range of zero to one less than the number of devices returned by mixerGetNumDevs. This flag is optional.

MIXER_OBJECTF_HMIXER

Specifies that hmxobj is a mixer device handle returned by mixerOpen. This flag is optional.

MIXER_OBJECTF_WAVEOUT

Specifies that hmxobj is a waveform output device identifier in the range of zero to one less than the number of devices returned by waveOutGetNumDevs.

MIXER_OBJECTF_HWAVEOUT

Specifies that hmxobj is a waveform output handle returned by waveOutOpen.

MIXER_OBJECTF_WAVEIN

Specifies that hmxobj is a waveform input device identifier in the range of zero to one less than the number of devices returned by waveInGetNumDevs.

MIXER_OBJECTF_HWAVEIN

Specifies that hmxobj is a waveform input handle returned by waveInOpen.

MIXER_OBJECTF_AUX

Specifies that hmxobj is an auxiliary device identifier in the range of zero to one less than the number of devices returned by auxGetNumDevs.


mixerGetLineInfo

MMRESULT mixerGetLineInfo(HMIXEROBJ hmxobj, LPMIXERLINE pmxl, DWORD fdwInfo)

Retrieves information about a specific line of an audio mixer device.

•	The return value is zero if the function is successful. Otherwise, it returns a non-zero error number. Possible error returns include the following:

MMSYSERR_BADDEVICEID

The hmxobj argument specifies an invalid device identifier.

MMSYSERR_INVALHANDLE

The hmxobj argument specifies an invalid handle.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_INVALPARAM

One or more passed arguments are invalid.

MMSYSERR_NODRIVER

No audio mixer device is available for the object specified by hmxobj.

MIXERR_INVALLINE

The audio mixer device line reference is invalid.

hmxobj

Specifies a handle to the audio mixer device object that controls the specific audio line.

pmxl

Points to a MIXERLINE structure. This structure is filled with information about the mixer line for the audio mixer device. See the comments for each query flag passed through fdwInfo for details on the members of the MIXERLINE structure that must be initialized before calling mixerGetLineInfo. Note that in all cases, cbStruct must be initialized to be the size, in bytes, of the MIXERLINE structure.

fdwInfo

Specifies flags for getting information on a mixer line.

MIXER_GETLINEINFOF_DESTINATION

If this flag is specified, pmxl is to receive information on the destination line specified by the dwDestination member of the MIXERLINE structure. This index ranges from zero to one less than cDestinations of the MIXERCAPS structure. All remaining structure members except cbStruct require no further initialization.

MIXER_GETLINEINFOF_SOURCE

If this flag is specified, pmxl is to receive information on the source line specified by the dwDestination and dwSource members of the MIXERLINE structure. The index specified by dwDestination ranges from zero to one less than cDestinations of the MIXERCAPS structure. The index specified by for dwSource ranges from zero to one less than the cConnections member of the MIXERLINE structure returned for the dwDestination line. All remaining structure members except cbStruct require no further initialization.

MIXER_GETLINEINFOF_LINEID

If this flag is specified, pmxl is to receive information on the line specified by the dwLineID member of the MIXERLINE structure. This is usually used to retrieve updated information on a line's state. All remaining structure members except cbStruct require no further initialization.

MIXER_GETLINEINFOF_COMPONENTTYPE

If this flag is specified, pmxl is to receive information on the first line of the type specified in the dwComponentType member of the MIXERLINE structure. This flag is used to retrieve information on a line that is of a specific component type. Remaining structure members except cbStruct require no further initialization.

For example, an application could specify MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE to retrieve information on the first Microphone input associated with the specified hmxobj.

MIXER_GETLINEINFOF_TARGETTYPE

If this flag is specified, pmxl is to receive information on the line that is for the dwType of the MIXERLINE structure. This flag is used to retrieve information about a line that handles the target type (MIXERLINE_TARGETTYPE_WAVEOUT for example). An application must initialize dwType, wMid, wPid, vDriverVersion and szPname of the MIXERLINE structure before calling mixerGetLineInfo. All of these values can be retrieved from the device capabilities structures for all media devices. Remaining structure members except cbStruct require no further initialization.

MIXER_OBJECTF_MIXER

Specifies that hmxobj is an audio mixer device identifier in the range of zero to one less than the number of devices returned by mixerGetNumDevs. This flag is optional.

MIXER_OBJECTF_HMIXER

Specifies that hmxobj is a mixer device handle returned by mixerOpen. This flag is optional.

MIXER_OBJECTF_WAVEOUT

Specifies that hmxobj is a waveform output device identifier in the range of zero to one less than the number of devices returned by waveOutGetNumDevs.

MIXER_OBJECTF_HWAVEOUT

Specifies that hmxobj is a waveform output handle returned by waveOutOpen.

MIXER_OBJECTF_WAVEIN

Specifies that hmxobj is a waveform input device identifier in the range of zero to one less than the number of devices returned by waveInGetNumDevs.

MIXER_OBJECTF_HWAVEIN

Specifies that hmxobj is a waveform input handle returned by waveInOpen.

MIXER_OBJECTF_AUX

Specifies that hmxobj is an auxiliary device identifier in the range of zero to one less than the number of devices returned by auxGetNumDevs.


mixerGetNumDevs

UINT mixerGetNumDevs()

Retrieves the number of audio mixer devices present in the system.

•	Returns the number of audio mixer devices present in the system. If no audio mixer devices are available, zero is returned.


MIXERLINE

The MIXERLINE structure describes the state and metrics of an audio mixer device line.

typedef struct tMIXERLINE

{

    DWORD       cbStruct;

    DWORD       dwDestination;

    DWORD       dwSource;

    DWORD       dwLineID;

    DWORD       fdwLine;

    DWORD       dwUser;

    DWORD       dwComponentType;

    DWORD       cChannels;

    DWORD       cConnections;

    DWORD       cControls;

    char        szShortName[MIXER_SHORT_NAME_CHARS];

    char        szName[MIXER_LONG_NAME_CHARS];

    struct

    {

        DWORD   dwType;

        DWORD   dwDeviceID;

        WORD    wMid;

        WORD    wPid;

        VERSION vDriverVersion;

        char    szPname[MAXPNAMELEN];

    } Target;

} MIXERLINE;

cbStruct

Specifies the size, in bytes, of the MIXERLINE structure. This member must be initialized before calling mixerGetLineInfo. The size specified in this member must be large enough to contain the base MIXERLINE structure. When the mixerGetLineInfo function returns, this member contains the actual size of the information returned. The returned information will not exceed the requested size.

dwDestination

Specifies the destination line index. This member ranges from zero to one less than the value specified in cDestinations of the MIXERCAPS structure retrieved by mixerGetDevCaps. When mixerGetLineInfo is called with the MIXER_GETLINEINFOF_DESTINATION flag specified, details for the destination line are returned. Note that the dwSource member must be set to zero in this case. When called with the MIXER_GETLINEINFOF_SOURCE flag specified, the details for the source given by the dwSource member associated with the dwDestination member are returned.

dwSource

Specifies the index for the source line associated with the dwDestination member. That is, this member specifies the nth source line associated with the specified destination line. This member is not used for destination lines and must be set to zero when MIXER_GETLINEINFOF_DESTINATION is specified for mixerGetLineInfo. When the MIXER_GETLINEINFOF_SOURCE flag is specified, this member ranges from zero to one less than the value specified in cConnections of the MIXERLINE structure for the destination line given in the dwDestination member.

dwLineID

Specifies an audio mixer—defined identifier that uniquely refers to the line described by the MIXERLINE structure. This identifier is unique only to a single mixer device and may be of any format that the mixer device wishes. An application should only use this identifier as an abstract handle. No two lines for a single mixer device will have the same line identifier.

fdwLine

Specifies status and support flags for the audio mixer line. This member is always returned to the application and requires no initialization.

MIXERLINE_LINEF_SOURCE

Specifies that this audio mixer line is a source line associated with a single destination line. If this flag is not set, this line is a destination line associated with zero or more source lines.

MIXERLINE_LINEF_DISCONNECTED

Specifies that this audio mixer line is disconnected. A disconnected line's associated controls can still be modified but the changes will have no effect until the line becomes connected. An application might need to take a different course of action if a mixer line is disconnected.

MIXERLINE_LINEF_ACTIVE

Specifies that this audio mixer line is active. An active line specifies that a signal is (probably) passing through the line. For example, if a waveform output device is not in use by an application, then the line associated with that device would not be active (the MIXERLINE_LINEF_ACTIVE flag would not be set). If the waveform output device is opened, then the the line is considered active and the MIXERLINE_LINEF_ACTIVE flag will be set. Note that a 'paused' or 'starved' waveform output device is still considered active. In other words, if the waveform output device is opened by an application regardless of whether data is being played, the associated line is considered active. If a line cannot be strictly defined as 'active' verses 'inactive', then the audio mixer device will always set the MIXERLINE_LINEF_ACTIVE flag. An example of where this information can be used by an application is displaying a 'peak meter.' Peak meters are polled meters. An application may want to disable its polling timer while the line is inactive to improve system performance.

dwUser

Specifies 32-bits of audio mixer device defined instance data for the line. This member is intended for custom audio mixer applications designed specifically for the mixer device returning this information. An application that is not specifically tailored to understand this member should simply ignore this data.

dwComponentType

Specifies the component type for this line. An application may use this information to display tailored graphics or search for a particular component. If an application does not know about a component type, then this member should be ignored. Currently, this member may be one of the following values:

MIXERLINE_COMPONENTTYPE_DST_UNDEFINED

Specifies that the line is a destination that cannot be defined by one of the standard component types. An audio mixer device is required to use this component type for line component types that have not been defined by Microsoft.

MIXERLINE_COMPONENTTYPE_DST_DIGITAL

Specifies that the line is a digital destination (for example, digital input to a DAT or CD Audio Disc).

MIXERLINE_COMPONENTTYPE_DST_LINE

Specifies that the line is a line level destination (for example, line level input from a CD Audio Disc) that will be the final recording source for the ADC. Most audio cards for the PC provide some sort of gain for the recording source line, so the mixer device will use the MIXERLINE_COMPONENTTYPE_DST_WAVEIN type.

MIXERLINE_COMPONENTTYPE_DST_MONITOR

Specifies that the line is a destination used for a monitor.

MIXERLINE_COMPONENTTYPE_DST_SPEAKERS

Specifies that the line is an adjustable (gain and/or attenuation) destination intended to drive speakers. This is the normal component type for the audio output of most audio cards for the PC.

MIXERLINE_COMPONENTTYPE_DST_HEADPHONES

Specifies that the line is an adjustable (gain and/or attenuation) destination intended to drive headphones. Most audio cards use the same destination line for speakers and headphones in which case the mixer device will simply use the MIXERLINE_COMPONENTTYPE_DST_SPEAKERS type.

MIXERLINE_COMPONENTTYPE_DST_TELEPHONE

Specifies that the line is a destination that will be routed to the telephone line.

MIXERLINE_COMPONENTTYPE_DST_WAVEIN

Specifies that the line is a destination that will be the final recording source for the waveform input (ADC). This line will normally provide some sort of gain or attenuation. This is the normal component type for the recording line of most audio cards for the PC.

MIXERLINE_COMPONENTTYPE_DST_VOICEIN

Specifies that the line is a destination that will be the final recording source for voice input. This component type is exactly like MIXERLINE_COMPONENTTYPE_DST_WAVEIN but is intended specifically for settings used during voice recording/recognition. This line is entirely optional for a mixer device to support--many mixer devices might only provide MIXERLINE_COMPONENTTYPE_DST_WAVEIN.

MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED

Specifies that the line is a source that cannot be defined by one of the standard component types. An audio mixer device is required to use this component type for line component types that have not been defined by Microsoft.

MIXERLINE_COMPONENTTYPE_SRC_DIGITAL

Specifies that the line is a digital source (for example, digital output from a DAT or CD Audio Disc).

MIXERLINE_COMPONENTTYPE_SRC_LINE

Specifies that the line is a line—level source (for example, line—level input from an external stereo) that can be used as an optional recording source. Most audio cards for the PC provide some sort of gain for the recording source line, so the mixer device will use the MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY type.

MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE

Specifies that the line is a microphone recording source. Most audio cards for the PC provide at least two types of recording sources: an auxiliary line and microphone input. A microphone line normally provides some sort of gain. Audio cards that use a single input for use with a microphone or auxiliary line should use the MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE component type.

MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER

Specifies that the line is a source originating from the output of an internal synthesizer. Most audio cards for the PC provide some sort of MIDI synthesizer (for example, an Ad Lib compatible or OPL/3 FM synthesizer).

MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC

Specifies that the line is a source originating from the output of an internal audio compact disc. This component type is provided for those audio cards that provide a source line solely intended to be connected to an audio compact disc (or CD-ROM playing a Redbook Audio CD).

MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE

Specifies that the line is a source originating from an incoming telephone line.

MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER

Specifies that the line is a source originating from the PC speaker. Several audio cards for the PC provide the ability to mix what would normally be played on the internal speaker with the output of an audio card. The ability to use this output as a source for recording has also been exploited by some audio cards.

MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT

Specifies that the line is a source originating from the waveform output (DAC). Most cards for the PC provide this component type as a source to the MIXERLINE_COMPONENTTYPE_DST_SPEAKERS destination. Some cards will also allow this source to be routed to the MIXERLINE_COMPONENTTYPE_DST_WAVEIN destination.

MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY

Specifies that the line is a source originating from the auxiliary line. This line type is intended as a source with gain or attenuation that can be routed to the MIXERLINE_COMPONENTTYPE_DST_SPEAKERS destination and/or recorded from through the MIXERLINE_COMPONENTTYPE_DST_WAVEIN destination.

cChannels

Specifies the maximum number of separate channels that can be manipulated independently for the line. The minimum value for this field is one since a line must have at least one channel.Most modern audio cards for the PC are stereo devices; for them, the value of this member will be two.

Channel one is assumed to be the left channel; channel two is assumed to be the right channel. Note that a multi-channel line might have one or more uniform controls (controls that affect all channels of a line uniformly) associated with it. An example of a uniform control is a Mute that mutes all channels of a line simultaneously. A line must have at least one channel-- this member will not be zero.

cConnections

Specifies the number of connections that are associated with the line. Currently, this member is used only for destination lines and specifies the number of source lines that are associated with it. The value of this member is always zero for source lines. It is also zero for a destination line that does not have any source lines associated with it.

cControls

Specifies the number of controls associated with the line. This value may be zero. If no controls are associated with the line, then the line is probably (but not always) just a source that might be selected in a MUX or Mixer but allows no manipulation of the signal. For example, a digital source may have this attribute.

szShortName[MIXER_SHORT_NAME_CHARS]

Specifies a short string that describes the dwLineID audio mixer line. This description is appropriate as a concise label for the line.

szName[MIXER_LONG_NAME_CHARS]

Specifies a string that describes the dwLineID audio mixer line. This description is appropriate as a complete description for the line.

Target

Contains the target media information.

dwType

Specifies the target media device type associated with the audio mixer line described in the MIXERLINE structure. An application must ignore target information for media device types that it does not understand. Currently, this member can be describes with one of the following flags:

MIXERLINE_TARGETTYPE_UNDEFINED

Specifies that the line described by this MIXERLINE structure is not strictly bound to a defined media type. All remaining Target structure members of the MIXERLINE structure should be ignored. Note that an application may not use the MIXERLINE_TARGETTYPE_UNDEFINED target type when calling the mixerGetLineInfo function with the MIXER_GETLINEINFOF_TARGETTYPE flag.

MIXERLINE_TARGETTYPE_WAVEOUT

Specifies that the line described by this MIXERLINE structure is strictly bound to the waveform output device detailed in the remaining members of the Target structure member of the MIXERLINE structure.

MIXERLINE_TARGETTYPE_WAVEIN

Specifies that the line described by this MIXERLINE structure is strictly bound to the waveform input device detailed in the remaining members of the Target structure member of the MIXERLINE structure.

MIXERLINE_TARGETTYPE_AUX

Specifies that the line described by this MIXERLINE structure is strictly bound to the auxiliary device detailed in the remaining members of the Target structure member of the MIXERLINE structure.

dwDeviceID

In the case of the dwType member being a target type other than MIXERLINE_TARGETTYPE_UNDEFINED, this member is the current device identifier of the target media device. This identifier is identical to the current media device index of the associated media device. Note that when calling the mixerGetLineInfo function with the MIXER_GETLINEINFOF_TARGETTYPE flag, this member is ignored on input and will be returned to the caller by the audio mixer manager.

wMid

In the case of the dwType member being a target type other than MIXERLINE_TARGETTYPE_UNDEFINED, this member is the manufacturer identifier of the target media device. This identifier is identical to the wMid member of the associated media device capabilities structure.

wPid

In the case of the dwType member being a target type other than MIXERLINE_TARGETTYPE_UNDEFINED, this member is the product identifier of the target media device. This identifier is identical to the wPid member of the associated media device capabilities structure.

vDriverVersion

In the case of the dwType member being a target type other than MIXERLINE_TARGETTYPE_UNDEFINED, this member is the driver version of the target media device. This version is identical to the vDriverVersion member of the associated media device capabilities structure.

szPname[MAXPNAMELEN]

In the case of the dwType member being a target type other than MIXERLINE_TARGETTYPE_UNDEFINED, this member is the product name of the target media device. This name is identical to the szPname member of the associated media device capabilities structure.


MIXERLINECONTROLS

The MIXERLINECONTROLS structure references the controls of an audio mixer line that are being queried.

typedef struct {

    DWORD cbStruct;

    DWORD dwLineID;

    DWORD dwControlID;

    DWORD dwControlType;

    DWORD cControls;

    DWORD cbmxctrl;

    LPMIXERCONTROL pamxctrl;

} MIXERLINECONTROLS;

cbStruct

Specifies the size, in bytes, of the MIXERLINECONTROLS structure. This member must be initialized before calling the mixerGetLineControls function. The size specified in this member must be large enough to contain the base MIXERLINECONTROLS structure. When the mixerGetLineControls function returns, this member contains the actual size of the information returned. The returned information will not exceed the requested size, nor will it be smaller than the base MIXERLINECONTROLS structure.

dwLineID

Specifies the line identifier whose controls are being queried. This member is not used if the MIXER_GETLINECONTROLSF_ONEBYID flag is specified for the mixerGetLineControls function--but the mixer device will return this member in this case. The dwControlID and dwControlType members are not used when MIXER_GETLINECONTROLSF_ALL is specified.

dwControlID

Specifies the control identifier of the control desired. This member is used with the MIXER_GETLINECONTROLSF_ONEBYID flag for mixerGetLineControls to retrieve the control information of the specified control. Note that the dwLineID member of the MIXERLINECONTROLS structure will be returned by the mixer device and is not required as an input parameter. This member overlaps with the dwControlType member and cannot be used in conjunction with the MIXER_GETLINECONTROLSF_ONEBYTYPE query type.

dwControlType

Specifies the control type of the control desired. This member is used with the MIXER_GETLINECONTROLSF_ONEBYTYPE flag for mixerGetLineControls to retrieve the first control of the specified type on the line specified by the dwLineID member of the MIXERLINECONTROLS structure. This member overlaps with the dwControlID member and cannot be used in conjunction with the MIXER_GETLINECONTROLSF_ONEBYID query type.

cControls

Specifies the number of MIXERCONTROL structure elements to retrieve. This member must be initialized by the application before calling the mixerGetLineControls function. This member may only be one (if MIXER_GETLINECONTROLSF_ONEBYID or MIXER_GETLINECONTROLSF_ONEBYTYPE is specified) or the value returned in the cControls member of the MIXERLINE structure returned for a line. This member cannot be zero. If a line specifies that it has no controls, then mixerGetLineControls should not be called.

cbmxctrl

Specifies the size, in bytes, of a single MIXERCONTROL structure. This must be at least large enough to hold the base MIXERCONTROL structure. The total size, in bytes, required for the buffer pointed to by pamxctrl member is the product of the cbmxctrl and cControls members of the MIXERLINECONTROLS structure.

pamxctrl

Points to one or more MIXERCONTROL structures to receive the details on the requested audio mixer line controls. This member may not be NULL and must be initialized before calling the mixerGetLineControls function. Each element of the array of controls must be at least large enough to hold a base MIXERCONTROL structure. The cbmxctrl member must specify the size, in bytes, of each element in this array. No initialization of the buffer pointed to by this member needs to be initialized by the application. All members will be filled in by the mixer device (including the cbStruct member of each MIXERCONTROL structure) upon returning successfully to the application.


mixerMessage

DWORD mixerMessage(HMIXER hmx, UINT uMsg, DWORD dwParam1, DWORD dwParam2)

Sends a user—defined audio mixer driver message directly to a mixer driver.

•	The return value is specific to the user—defined mixer driver message uMsg sent. However, the following return values are possible:

MMSYSERR_INVALHANDLE

Specified device handle is invalid.

MMSYSERR_INVALPARAM

uMsg is not in the MXDM_USER range.

MMSYSERR_NOTSUPPORTED

The mixer device did not process the message.

hmx

Specifies a handle to an open instance of a mixer device. This handle is returned by mixerOpen.

uMsg

Specifies the user-defined mixer driver message to send to the mixer driver. This message must be above or equal to the MXDM_USER message.

dwParam1

Contains the first argument associated with the message being sent.

dwParam2

Contains the second argument associated with the message being sent.

The mixerMessage function is provided to allow audio mixer driver—specific messages to be sent to a mixer device. The messages that may be sent through this function must be above or equal to the MXDM_USER message.

User—defined messages must only be sent to a mixer driver that specifically supports the messages. The caller should verify that the mixer driver is in fact the correct driver by getting the mixer capabilities and checking the wMid, wPid, vDriverVersion and szPname members of the MIXERCAPS structure.

It is important for an application to verify all members specified above. Some drivers have been released drivers with improper or unregistered manufacturer and product identifiers.

Never send user—defined messages to an unknown audio mixer driver.


mixerOpen

MMRESULT mixerOpen(LPHMIXER phmx, UINT uMxId, DWORD dwCallback, DWORD dwInstance, DWORD fdwOpen)

Opens a specified audio mixer device for use. An application must open a mixer device if it wishes to receive notifications of mixer line and control changes. This function also ensures that the device will not be removed until the application closes the handle.

•	The return value is zero if the function is successful. Otherwise, it returns a non-zero error number. Possible error returns include the following:

MMSYSERR_BADDEVICEID

The uMxId argument specifies an invalid device identifier.

MMSYSERR_INVALHANDLE

The uMxId argument specifies an invalid handle.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_INVALPARAM

One or more arguments passed is invalid.

MMSYSERR_NODRIVER

No audio mixer device is available for the object specified by uMxId. Note that the location referenced by uMxId will also contain the value "-1".

MMSYSERR_ALLOCATED

The specified resource is already allocated by the maximum number of clients possible.

MMSYSERR_NOMEM

Unable to allocate resources.

phmx

Points to a variable that will receive a handle identifying the opened audio mixer device. Use this handle to identify the device when calling other audio mixer functions. This argument cannot be NULL. If an application wishes to query for audio mixer support on a media device, the mixerGetID function can be used.

uMxId

Identifies the audio mixer device to open. Use a valid device identifier or any HMIXEROBJ (see mixerGetID for a description of mixer object handles). Note that no 'mapper' for audio mixer devices currently exists, so a mixer device identifier of "-1" is not valid.

dwCallback

Specifies a handle to a window called when the state of an audio mixer line and/or control associated with the device being opened is changed. Specify zero for this argument if no callback mechanism is to be used.

dwInstance

Specifies user instance data passed to the callback function. This parameter is not used with window callbacks.

fdwOpen

Specifies flags for opening the device.

CALLBACK_WINDOW

If this flag is specified, dwCallback is assumed to be a window handle.

MIXER_OBJECTF_MIXER

Specifies that uMxId is an audio mixer device identifier in the range of zero to one less than the number of devices returned by mixerGetNumDevs. This flag is optional.

MIXER_OBJECTF_HMIXER

Specifies that uMxId is a mixer device handle returned by mixerOpen. This flag is optional.

MIXER_OBJECTF_WAVEOUT

Specifies that uMxId is a waveform output device identifier in the range of zero to one less than the number of devices returned by waveOutGetNumDevs.

MIXER_OBJECTF_HWAVEOUT

Specifies that uMxId is a waveform output handle returned by waveOutOpen.

MIXER_OBJECTF_WAVEIN

Specifies that uMxId is a waveform input device identifier in the range of zero to one less than the number of devices returned by waveInGetNumDevs.

MIXER_OBJECTF_HWAVEIN

Specifies that uMxId is a waveform input handle returned by waveInOpen.

MIXER_OBJECTF_AUX

Specifies that uMxId is an auxiliary device identifier in the range of zero to one less than the number of devices returned by auxGetNumDevs.

Use the mixerGetNumDevsfunction to determine the number of audio mixer devices present in the system. The device identifier specified by uMxId varies from zero to one less than the number of devices present.

If a window is chosen to receive callback information, the following messages are sent to the window procedure function to indicate when a line or control state changes: MM_MIXM_LINE_CHANGE, MM_MIXM_CONTROL_CHANGE. wParam is the handle to the mixer device. lParam is the line identifier for MM_MIXM_LINE_CHANGE or the control identifier for MM_MIXM_CONTROL_CHANGE that changed state.

If a function is chosen to receive callback information, the following messages are sent to the MixerCallback function to indicate when a line or control state changed: MM_MIXM_LINE_CHANGE, MM_MIXM_CONTROL_CHANGE.


mixerSetControlDetails

MMRESULT mixerSetControlDetails(HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails)

Sets details on a single control associated with an audio mixer device line.

•	The return value is zero if the function is successful. Otherwise, it returns a non-zero error number. Possible error returns include the following:

MMSYSERR_BADDEVICEID

The hmxobj argument specifies an invalid device identifier.

MMSYSERR_INVALHANDLE

The hmxobj argument specifies an invalid handle.

MMSYSERR_INVALFLAG

One or more flags are invalid.

MMSYSERR_INVALPARAM

One or more arguments passed is invalid.

MMSYSERR_NODRIVER

No audio mixer device is available for the object specified by hmxobj.

MIXERR_INVALCONTROL

The control reference is invalid.

hmxobj

Specifies a handle to the audio mixer device object whose control is being set.

pmxcd

Points to a MIXERCONTROLDETAILS structure. This structure is used to reference control detail structures that contain the desired state for the control. See the description for the MIXERCONTROLDETAILS structure to determine the structure members that must be initialized before calling mixerSetControlDetails. Note that in all cases, the cbStruct member of the MIXERCONTROLDETAILS structure must be initialized to be the size, in bytes, of the MIXERCONTROLDETAILS structure.

fdwDetails

Specifies flags for setting details for a control.

MIXER_SETCONTROLDETAILSF_VALUE

If this flag is specified, the current value(s) for a control are set. The paDetails member of the MIXERCONTROLDETAILS points to one or more details structures of appropriate for the control type. Refer to the description of the MIXERCONTROLDETAILS structure for information on those structure members that must be initialized before calling mixerSetControlDetails.

MIXER_SETCONTROLDETAILSF_CUSTOM

If this flag is specified, a custom dialog box for the specified custom mixer control will be displayed. The mixer device will gather the required information from the user and return the data in the specified buffer. The handle for the owning window is specified in the hwndOwner member. (This handle can be set to NULL). The data from the dialog can then be saved by the application and used later to reset the control to the same state using the MIXER_SETCONTROLDETAILSF_VALUE flag.

If an application only needs to get the current state of a custom mixer control without displaying a dialog, then mixerGetControlDetails can be used with the MIXER_GETCONTROLDETAILSF_VALUE flag.

MIXER_OBJECTF_MIXER

Specifies that hmxobj is an audio mixer device identifier in the range of zero to one less than the number of devices returned by mixerGetNumDevs. This flag is optional.

MIXER_OBJECTF_HMIXER

Specifies that hmxobj is a mixer device handle returned by mixerOpen. This flag is optional.

MIXER_OBJECTF_WAVEOUT

Specifies that hmxobj is a waveform output device identifier in the range of zero to one less than the number of devices returned by waveOutGetNumDevs.

MIXER_OBJECTF_HWAVEOUT

Specifies that hmxobj is a waveform output handle returned by waveOutOpen.

MIXER_OBJECTF_WAVEIN

Specifies that hmxobj is a waveform input device identifier in the range of zero to one less than the number of devices returned by waveInGetNumDevs.

MIXER_OBJECTF_HWAVEIN

Specifies that hmxobj is a waveform input handle returned by waveInOpen.

MIXER_OBJECTF_AUX

Specifies that hmxobj is an auxiliary device identifier in the range of zero to one less than the number of devices returned by auxGetNumDevs.


MM_MIXM_LINE_CHANGE

This message is sent to the callback window and indicates that the state of a line has changed.

wParam

Contains a handle to the mixer device.

lParam

Contains the line identifier.


MM_MIXM_CONTROL_CHANGE

This message is sent to the callback window and indicates that the state of a control has changed.

wParam

Contains a handle to the mixer device.

lParam

Contains the control ID.


Bitmap Drawing: DrawDib


About Bitmap Drawing

The DrawDib functions provide much of the functionality of StretchDIBits and add ICM support, improved stretching capabilities, and improved support of low-end display adapters. If a display driver cannot stretch an image, the DrawDib functions can stretch it more efficiently than StretchDIBits. The DrawDib functions also efficiently dither true-color images to 256 colors, and dither 8-bit images on 16-color VGA displays. These functions significantly improve the speed and quality of displaying such images on display adapters with limited capabilities.

This chapter discusses the following topics:

•	Drawing with the DrawDib functions

•	Optimizing DrawDibDraw

•	Profiling the display characteristics


Drawing Using the DrawDib Functions

Your application can use the DrawDibOpen, DrawDibClose, and DrawDibDraw functions with 8-, 16-, 24-, and 32-bit images to access the basic DrawDib services. While your application can use DrawDibDraw as an almost one-to-one replacement for StretchDIBits, DrawDibDraw has the following limitations:

•	The DIB must have the DIB_RGB_COLORS format.

•	Your application must use the simplest transfer mode, SRCCOPY.

For example, your application cannot use DrawDibDraw to XOR a picture with the screen.

Prior to using DrawDibDraw, your application must initialize the DrawDib library and let it allocate the memory it needs by calling DrawDibOpen. This function returns a DrawDib context handle your application uses for other DrawDib functions. If Windows cannot create a DrawDib context, DrawDibOpen returns NULL.

Your application can use DrawDibOpen to create multiple DrawDib contexts. This lets your application work with several DrawDib contexts that have different characteristics.

The DrawDibDraw function draws a device-independent bitmap to the screen. This function replaces StretchDIBits and provides transparent support of installable compressors for decompressing the bitmaps.

If your application must refresh the current image, or a portion of it, it can use DrawDibUpdate to update it.

When your application has finished using the DrawDib context, it uses DrawDibClose to close the context and clean up. This function uses the handle to the DrawDib context as its only argument. It returns TRUE if the context closed successfully; otherwise, it returns FALSE.

Your application can get a pointer to the decompress buffer with the DrawDibGetBuffer function.


Supporting Palettes for the DrawDib Functions

If your application uses DrawDib, it should be palette-aware. That is, it must respond to WM_QUERYNEWPALETTE and WM_PALETTECHANGED messages. If your application does not already use palettes, it will need two short message handlers for these messages. In response to WM_PALETTECHANGED, your application should invalidate the destination window to let DrawDib redraw. In response to WM_QUERYNEWPALETTE, your application uses DrawDibRealize to realize the palette.


Manipulating Palettes

Applications use DrawDibSetPalette, DrawDibChangePalette, and DrawDibGetPalette for handling palettes associated with a DrawDib context.

If your application is already palette-aware, it might already have realized a palette and must prevent DrawDib from realizing its own palette. Your application can use DrawDibSetPalette to notify DrawDib of the palette to use. If your substitute palette does not contain the colors required by images displayed by other applications, color shifts will appear in those images.

To modify the colors in the DrawDib palette, your application can use DrawDibChangePalette to specify the colors. If the DDF_ANIMATE flag was not set in the previous call to DrawDibBegin, this function will not animate the palette. In this case, use DrawDibRealize to realize the updated palette.

If your application must have the current palette, it can use DrawDibGetPalette to obtain a handle to the palette. To realize the correct palette in response to a window message, just use DrawDibRealize instead of using this function to obtain the palette and resending it. If your application uses this function, remember that it does not have exclusive use of the handle. Thus, your application should not free the palette when it is done and it should anticipate that some other application can invalidate the handle. Your application should rarely need to use DrawDibGetPalette.


Optimizing DrawDibDraw

If your application uses DrawDibDraw to display a series of bitmaps with the same dimensions and formats, it can use DrawDibBegin to improve the efficiency of DrawDibDraw. This function prepares DrawDibDraw for drawing.

If your application does not use DrawDibBegin, DrawDibDraw implicitly executes it prior to drawing. When your application uses DrawDibBegin prior to DrawDibDraw, DrawDibDraw does not have to take the time to process the function and wait for it to complete.

Your application should use the same DrawDib context and display context handle specified for these parameters in DrawDibDraw. When your application subsequently uses DrawDibDraw, it should set the DDF_SAME_HDC flag to indicate the handle to the display context has not changed.

Your application needs to use the same source height and width, destination height and width, and pointer to the BITMAPINFOHEADER structure it specified for DrawDibDraw. If your application changes these values, DrawDibDraw will sense any changes and implicitly use DrawDibBegin again. While your application must specify the width and height of the source and destination rectangles, it does not need to specify the origins. Thus, your application can redefine the origins in DrawDibDraw to use different portions of the image or update different portions of the display.

For debug operations, your application can use DrawDibTime to obtain timing information.


Streaming Data to a DrawDib Context

If your application will draw a series of images with DrawDibDraw, it should use DrawDibStart to prepare the DrawDib context for streaming playback. When the application has finished drawing the image series, it uses DrawDibStop to free the resources allocated by the DrawDib library for streaming playback.


Profiling the Display Characteristics

The very first time an application uses DrawDib capabilities, the Windows operating system executes a series of drawing tests to determine the display characteristics. Once the DrawDib libraries characterize the display, they will not run the tests again unless the information is removed (for example, by reinstalling Windows) or the user changes the display driver. Applications can use DrawDibProfileDisplay to retest the display.


Reference

This section contains an alphabetic listing of the functions applications can use for accessing the DrawDib services. The functions are identified with the prefix DrawDib.

To	See the following functions
Draw with the DrawDib functions	DrawDibClose DrawDibDraw DrawDibGetBuffer DrawDibOpen DrawDibUpdate
Use palettes with the DrawDib functions	DrawDibRealize
Manipulate palettes	DrawDibChangePalette DrawDibGetPalette DrawDibSetPalette
Optimize DrawDibDraw	DrawDibBegin DrawDibEnd DrawDibTime
Stream data to a DrawDib context	DrawDibStart DrawDibStop
Profile the display	DrawDibProfileDisplay


DrawDibBegin

BOOL DrawDibBegin(HDRAWDIB hdd, HDC hdc, int dxDest, int dyDest, LPBITMAPINFOHEADER lpbi, int dxSrc, int dySrc, UNIT wFlags)

This function changes parameters of a DrawDib context, or it initializes a new DrawDib context.

•	Returns TRUE if successful.

hdd

Specifies a handle to a DrawDib context.

hdc

Specifies a handle to a display context for drawing (optional).

dxDest

Specifies the width of the destination rectangle. Width is specified in MM_TEXT client units.

dyDest

Specifies the height of the destination rectangle. Height is specified in MM_TEXT client units.

lpbi

Specifies a pointer to a BITMAPINFOHEADER structure containing the image format. The color table for the DIB follows the image format.

dxSrc

Specifies the width of the source rectangle. Width is specified in pixels.

dySrc

Specifies the height of the source rectangle. Height is specified in pixels.

wFlags

Specifies the applicable flags for the function. The following flags are defined:

DDF_ANIMATE

Allows palette animation. If this flag is present, the palette DrawDib creates will have the PC_RESERVED flag set for as many entries as possible, and the palette can be animated by DrawDibChangePalette. If you are using DrawDibBegin with DrawDibDraw, set this flag with DrawDibBegin rather than DrawDibDraw.

DDF_JUSTDRAWIT

Uses GDI to draw the image. This prevents the DrawDib functions from calling ICM to decompress the image, or prevents them from using their own routines to stretch or dither the image. This essentially reduces DrawDibDraw to StretchDIBits.

DDF_HALFTONE

Always dithers the DIB to a standard palette, regardless of the palette of the DIB. If using DrawDibBegin with DrawDibDraw, set this flag with DrawDibBegin rather than DrawDibDraw.

This function prepares to draw a bitmap specified by lpbi to the display context hdc. The image is stretched to the size specified by dxDest and dyDest. If dxDest and dyDest are (−1,−1), the bitmap is drawn to a 1:1 scale without stretching.

Use this function only if you want to prepare DrawDib before using DrawDibDraw to draw the image. If you do not use this function, DrawDibDraw implicitly uses it when it draws the image.

To update the flags set with DrawDibBegin, call DrawDibBegin with new parameters.

When DrawDibBegin is used, the DDF_SAME_DRAW flag is normally set for DrawDibDraw.

If the parameters of DrawDibBegin have not changed, subsequent uses of it have not effect.

Use DrawDibEnd to free memory used by the DrawDib context.


DrawDibChangePalette

BOOL DrawDibChangePalette(HDRAWDIB hdd, int iStart, int iLen, LPPALETTEENTRY lppe)

This function sets the palette entries used for drawing device-independent bitmaps.

•	Returns TRUE if successful.

hdd

Specifies a handle to a DrawDib context.

iStart

Specifies the starting palette entry number.

iLen

Specifies the number of palette entries.

lppe

Specifies a pointer to an array of palette entries.

Use this function when the DIB color table changes and other parameters stay constant. This function changes the physical palette only if the current DrawDib palette is currently realized by calling DrawDibRealize.

The DIB color table must be changed by the user or the next use of DrawDibDraw without the DDF_SAME_DRAW flag implicitly calls DrawDibBegin.

If the DDF_ANIMATE flag is not set in the previous call to DrawDibBegin or DrawDibDraw, this function will animate the palette. In this case, update the DIB color table from the palette specified by lppe and use DrawDibRealize to realize the updated palette. Redraw the image to see the updated colors.


DrawDibClose

BOOL DrawDibClose(HDRAWDIB hdd)

This function closes a DrawDib context and frees the resources DrawDib allocated for it.

•	Returns TRUE if the context closed successfully.

hdd

Specifies a handle to a DrawDib context.

Use this function to free the hdd handle after the application has finished drawing.


DrawDibDraw

BOOL DrawDibDraw(HDRAWDIB hdd, HDC hdc, int xDst, int yDst, int dxDst, int dyDst, LPBITMAPINFOHEADER lpbi, LPVOID lpBits, int xSrc, int ySrc, int dxSrc, int dySrc, UINT wFlags)

This function draws a device-independent bitmap to the screen.

•	Returns TRUE if successful.

hdd

Specifies a handle to a DrawDib context.

hdc

Specifies a handle to the display context.

xDst

Specifies the x-coordinate of the upper-left corner of the destination rectangle. Coordinates are specified in MM_TEXT client coordinates.

yDst

Specifies the y-coordinate of the upper-left corner of the destination rectangle. Coordinates are specified in MM_TEXT client coordinates.

dxDst

Specifies the width of the destination rectangle. The width is specified in MM_TEXT client coordinates. If dxDst is −1, the width of the bitmap is used.

dyDst

Specifies the height of the destination rectangle. The height is specified in MM_TEXT client coordinates. If dyDst is −1, the height of the bitmap is used.

lpbi

Specifies a pointer to the BITMAPINFOHEADER structure for the bitmap. The color table for the DIB follows the format information. The height specified for the DIB in the structure must be positive (that is, this function will not draw inverted DIBs).

lpBits

Specifies a pointer to the buffer containing the bitmap bits.

xSrc

Specifies the x-coordinate of the upper-left corner source rectangle. Coordinates are specified in pixels. The coordinates (0,0) represent the upper-left corner of the bitmap.

ySrc

Specifies the y-coordinate of the upper-left corner source rectangle. Coordinates are specified in pixels. The coordinates (0,0) represent the upper-left corner of the bitmap.

dxSrc

Specifies the width of the source rectangle. The width is specified in pixels.

dySrc

Specifies the height of the source rectangle. The height is specified in pixels.

wFlags

Specifies any applicable flags for drawing. The following flags are defined:

DDF_SAME_HDC

Assumes the display context has been prepared with DrawDibRealize prior to this call and DrawDibDraw should not initialize it.

DDF_SAME_DRAW

Uses the drawing parameters previously specified for this function. Use this flag only if lpbi, dxDst, dyDst, dxSrc, and dySrc have not changed since using DrawDibDraw or DrawDibBegin. Normally DrawDibDraw checks the parameters, and if they have changed, DrawDibBegin prepares the DrawDib context for drawing.

DDF_DONTDRAW

Indicates the frame is not to be drawn and will later be recalled with the DDF_UPDATE flag. DrawDib does not buffer an image if an off-screen buffer does not exist. In this case, DDF_DONTDRAW draws the frame to the screen and the subsequent use of DDF_UPDATE fails. DrawDib does guarantee that the following will always draw "image" B to the screen:

        DrawDibDraw(hdd, ..., lpbiA, ..., DDF_DONTDRAW);

        DrawDibDraw(hdd, ..., lpbiB, ..., DDF_DONTDRAW);

        DrawDibDraw(hdd, ..., NULL,  ..., DDF_UPDATE);

The DDF_UPDATE and DDF_DONTDRAW flags are used together to create composite images off-screen, and then do a final update when finished.

DDF_HURRYUP

Indicates the data does not have to be drawn (that is, it can be dropped) and the DDF_UPDATE flags will not be used to recall this information. DrawDib looks at this data only if it is required to build the next frame, otherwise the data is ignored.

This flag is usually used to resynchronize video and audio. When resynchronizing data, applications should send the image with this flag in case the driver needs to buffer the frame to decompress subsequent frames.

DDF_UPDATE

Indicates the last buffered bitmap is to be redrawn. If drawing fails with this flag, a buffered image is not available and a new image needs to be specified before the display is updated. For more information, see the DDF_DONTDRAW flag.

DDF_BACKGROUNDPAL

Realizes the palette used for drawing in the background, leaving the actual palette used for display unchanged. (This flag is valid only if DDF_SAME_HDC is not set.)

DDF_HALFTONE

Always dithers the DIB to a standard palette regardless of the palette of the DIB. If using DrawDibBegin, set this flag for it rather than DrawDibDraw.

DDF_NOTKEYFRAME

Indicates the DIB data is not a key frame. Set the DDF_NOTKEYFRAME for the best performance.

This function replaces StretchDIBits and supports decompression of bitmaps by installable compressors. This function dithers true-color bitmaps properly on 8-bit display devices.


DrawDibEnd

BOOL DrawDibEnd(HDRAWDIB hdd)

This function frees a DrawDib context.

•	Returns TRUE if successful.

hdd

Specifies the handle to the DrawDib context to free.

Any flags set or palette changes made by DrawDibBegin or DrawDibDraw are discarded by DrawDibEnd.


DrawDibGetBuffer

LPVOID DrawDibGetBuffer(HDRAWDIB hdd, LPBITMAPINFOHEADER lpbi, DWORD dwSize, DWORD dwFlags)

This function returns the pointer to the DrawDib decompress buffer.

•	Returns a pointer to the buffer used by DrawDib for decompression, or NULL if no buffer is used. If lpbi is not NULL, it is filled in with a copy of the BITMAPINFOHEADER describing the buffer.

The structure for lpbi must have room for a BITMAPINFOHEADER and 256 colors.

hdd

Specifies a handle to a DrawDib context.

lpbi

Specifies a pointer to a BITMAPINFOHEADER structure.

dwSize

Specifies the size of the buffer pointed to by lpbi

dwFlags

Set to zero.


DrawDibGetPalette

HPALETTE DrawDibGetPalette(HDRAWDIB hdd)

This function obtains the palette used by a DrawDib context.

•	Returns a handle for the palette if successful; otherwise, it returns NULL.

hdd

Specifies a handle to a DrawDib context.

Use DrawDibRealize instead of this function to realize the correct palette in response to a window message. You should rarely need to call this function.

Applications do not have exclusive use of the palette obtained with this function. Applications should not free the palette or assign it to a display context with functions such as SelectPalette. Applications should also anticipate that some other application can invalidate the handle. The palette handle might also become invalid after the next use of a DrawDib function.

This function returns a valid handle only after DrawDibBegin has been used without pairing it with DrawDibEnd, or if DrawDibDraw has been used.


DrawDibOpen

HDRAWDIB DrawDibOpen()

This function opens a DrawDib context for drawing.

•	Returns a handle to a DrawDib context if successful; otherwise, it returns NULL.

Use this function to obtain a handle to a DrawDib context before drawing device-independent bitmaps.

If drawing multiple device-independent bitmaps simultaneously, obtain a handle to a DrawDib context for each bitmap.


DrawDibProfileDisplay

void DrawDibProfileDisplay(LPBITMAPINFOHEADER parms)

Profiles the display for DrawDib.

parms

Specifies bitmap information. Set to null if no information is available.


DrawDibRealize

UINT DrawDibRealize(HDRAWDIB hdd, HDC hdc, BOOL fBackground)

This function realizes the palette of the display context specified in the DrawDib context.

•	Returns the number of entries in the logical palette mapped to different values in the system palette. If an error occurs or no colors were updated, it returns zero.

hdd

Specifies a handle to a DrawDib context.

hdc

Specifies a handle to the display context containing the palette.

fBackground

If set to a non-zero value, the selected palette is selected as a background palette. If this is set to zero and the device context is attached to a window, the logical palette is a foreground palette when the window has the input focus. (The device context is attached to a window if it was obtained by using the GetDC function or if the window-class style is CS_OWNDC.)

This function should only be used to handle a WM_PALETTECHANGED or WM_QUERYNEWPALETTE message, or used in conjunction with the DDF_SAME_HDC flag to prepare a display context prior to calling DrawDibDraw multiple times.

To draw an image mapped to another palette use DrawDibSetPalette.

To make DrawDibDraw select its palette as a background palette use the DDF_BACKGROUNDPAL flag and not this function.

While the DrawDib palette is selected into the display context, do not call DrawDibEnd, DrawDibClose, DrawDibBegin, or DrawDibDraw (with a different draw/format) on the same DrawDib context hdd. These can free the selected palette while it is being used by your display context and cause a GDI error.

DrawDibRealize will return 0 if called before a DrawDibBegin or DrawDibDraw

The following example shows how the function is used to handle a WM_PALETTECHANGED or WM_QUERYNEWPALETTE message:

case WM_PALETTECHANGED:

    if ((HWND)wParam == hwnd)

        break;

case WM_QUERYNEWPALETTE:

    hdc = GetDC(hwnd);

    f = DrawDibRealize(hdd, hdc, FALSE) > 0;

    ReleaseDC(hwnd, hdc);

    if (f)

        InvalidateRect(hwnd, NULL, TRUE);

    break;

The following example shows using DrawDibRealize prior to calling DrawDibDraw multiple times:

hdc = GetDC(hwnd);

DrawDibRealize(hdd, hdc, fBackground);

DrawDibDraw(hdd, hdc, ..........., DDF_SAME_DRAW|DDF_SAME_HDC);

DrawDibDraw(hdd, hdc, ..........., DDF_SAME_DRAW|DDF_SAME_HDC);

DrawDibDraw(hdd, hdc, ..........., DDF_SAME_DRAW|DDF_SAME_HDC);

ReleaseDC(hwnd, hdc);

The following example shows DrawDibRealize used with DDF_ANIMATE and DrawDibChangePalette to do palette animation:

hdc = GetDC(hwnd);

DrawDibBegin(hdd, ....., DDF_ANIMATE);

DrawDibRealize(hdd, hdc, fBackground);

DrawDibDraw(hdd, hdc, ...., DDF_SAME_DRAW|DDF_SAME_HDC);

DrawDibChangePalette(hdd, ....);

ReleaseDC(hwnd, hdc);


DrawDibSetPalette

BOOL DrawDibSetPalette(HDRAWDIB hdd, HPALETTE hpal)

This function sets the palette used for drawing device-independent bitmaps.

•	Returns TRUE if successful.

hdd

Specifies a handle to a DrawDib context.

hpal

Specifies a handle to the palette. Specify NULL to use the default palette.

Use this function when the application needs to realize an alternate palette. The function forces the DrawDib context to use the specified palette, possibly at the expense of image quality.

Do not free a palette assigned to a DrawDib context until either a new palette replaces it (for example, if hpal1 is the current palette, replacing it with DrawDibSetPalette(hdd, hpal2)), or until the palette handle for the DrawDib context is set to the default palette (for example, DrawDibSetPalette(hdd, NULL)).


DrawDibStart

BOOL DrawDibStart(HDRAWDIB hdd, LONG rate)

This function prepares a DrawDib context for streaming playback.

•	Returns TRUE if successful.

hdd

Specifies a handle to a DrawDib context.

rate

Specifies the playback rate (in microseconds per frame).


DrawDibStop

BOOL DrawDibStop(HDRAWDIB hdd)

This function frees the resources used by a DrawDib context for streaming playback.

•	Returns TRUE if successful.

hdd

Specifies a handle to a DrawDib context.


DrawDibTime

BOOL DrawDibTime(HDRAWDIB hdd, LPDRAWDIBTIME lpddtime)

Returns timing information about the drawing during debug operation.

•	Returns TRUE if successful.

hdd

Specifies a handle to a DrawDib context.

lpddtime

Specifies a pointer to a DRAWDIBTIME structure.


DrawDibUpdate

BOOL DrawDibUpdate(HDRAWDIB hdd, HDC hdc, int xDst, int yDst)

This macro updates the last buffered frame drawn.

•	Returns TRUE if successful.

hdd

Specifies a handle to a DrawDib context.

hdc

Specifies a handle to the display context.

xDst

Specifies the x-coordinate of the upper-left corner of the destination rectangle. Coordinates are specified in MM_TEXT client coordinates.

yDst

Specifies the y-coordinate of the upper-left corner of the destination rectangle. Coordinates are specified in MM_TEXT client coordinates.

This macro uses DrawDibDraw to send the DDF_UPDATE flag to the DrawDib context.


Installable Drivers


About Installable Drivers

An installable driver is a Microsoft Windows dynamic-link library (DLL) that provides a standard interface through which Windows-based applications and dynamic-link libraries communicate with and manage the driver. The most common use for installable drivers is as multimedia device drivers, but installable drivers can also be used for other purposes and are particularly useful in situations that require a standard interface and control of multiple instances.

This chapter describes the general format of installable drivers and defines the installable driver functions that applications and dynamic-link libraries use to open and manage installable drivers.


Installable Driver Format

Every installable driver exports a DriverProc function. This common entry point receives driver messages from the system that direct the driver to carry out actions or provide information. The system sends driver messages to the DriverProc function when an application or dynamic-link library opens or closes the driver or requests that a message be sent to the driver. The DriverProc function either processes the message or passes the message to the default message handler, the DefDriverProc function. In either case, DriverProc must return a value indicating whether the requested action was successful.


Driver Messages

Each driver message consists of a message identifier and two 32-bit parameters. The message identifier is a unique value that the DriverProc function checks to determine which action to carry out. The meaning of the message parameters depends on the message. The parameters may represent values or addresses. In many cases, the parameters are not used and are set to zero.

Driver messages can be standard or custom. Window sends standard driver messages, such a DRV_OPEN and DRV_CONFIGURE, to an installable driver in response to a request to open, close, or configure the driver. The standard messages direct the installable driver to load or unload its resources, enable or disable its operation, open or close a driver instance, and display a configuration dialog box. Some standard messages, such as DRV_POWER and DRV_EXITSESSION, notify the driver of system-wide events that affect the operation of the driver or any related hardware.

Applications and dynamic-link libraries send custom driver messages to direct an installable driver to carry out driver-specific actions. Installable drivers that support custom messages must include appropriate processing in the DriverProc function. To prevent conflict between custom and standard driver messages, custom message identifiers must have values ranging from DRV_RESERVED to DRV_USER. Custom messages passed to the DefDriverProc function are ignored.


Driver Instances

Windows allows for multiples instances of an installable driver. The system creates an instance of the driver each time the driver is opened and destroys the instance when the driver is closed. Driver instances are especially useful for installable drivers that support multiple devices or that are opened by multiple applications or by the same application multiple times.

To help the driver keep track of the instances, the system sends a driver instance handle with each driver message after the instance has been created. This handle uniquely identifies the instance, so installable drivers often associate the handle with memory and other resources that they have specifically allocated for the instance.

When the first instance is opened, the system sends the DRV_LOAD, DRV_ENABLE, and DRV_OPEN messages to the driver in that order. The DRV_LOAD and DRV_ENABLE messages notify the driver is now in memory and enabled for operation. The DRV_OPEN message identifies the instance handle and may include configuration information for the instance. On each subsequent opening, the system sends only a DRV_OPEN message.

When processing a DRV_LOAD message, a driver typically reads configuration settings from the registry, configures the driver and any associated hardware, and allocates memory for use by all instances of the driver. If a driver can not complete the configuration or allocate memory, it returns zero to direct the system to immediately remove the driver from memory and prevent any subsequent messages from being sent. When processing the DRV_ENABLE message, the driver prepares the hardware to receive and process I/O requests; this may include installing interrupt handlers.

When processing the DRV_OPEN message, the driver allocates memory or resources required by the given instance of the driver, then returns a nonzero value. The system uses this nonzero value as the driver identifier in subsequent driver messages for the instance. The driver can use this identifier for any purpose. For example, some drivers use a memory handle for the identifier as a quick way to gain access to memory containing information about the given instance.

Many installable drivers process the second parameter of the DRV_OPEN message, giving the system and applications the means to send additional information to the driver when opening an instance. The parameter can be a single value or an address of a structure containing a set of values. When processing DRV_OPEN, the driver checks the parameter to determine whether it is value and uses the given values (if any) to complete the creation of the instance.

The system sends a DRV_CLOSE message each time an instance is closed. The instance handle sent with the message identifies which instance to close. When the last remaining instance is closed, the system sends the DRV_CLOSE, DRV_DISABLE, and DRV_FREE messages in that order. The DRV_CLOSE message directs the driver to close the instance and the DRV_DISABLE and DRV_FREE messages notify the driver that it is now disabled and will be immediately freed from memory.

When processing the DRV_CLOSE message, the driver typically frees any memory or resources allocated for the instance. When processing the DRV_DISABLE message, the driver places any hardware in an inactive state, which may include removing interrupt handlers. When processing the DRV_FREE message, the driver frees any memory or resources still allocated.

Installable drivers are not required to support multiple instances. A driver can prevent any instance from being created by returning zero for the DRV_OPEN message.


Configuration

An installable driver can let users choose configuration settings for the driver and associated hardware by displaying a configuration dialog box when processing the DRV_CONFIGURE message. The driver is responsible for creating and managing the dialog box, processing any user input from the dialog box, and changing the configuration of the driver or hardware as requested by the user. The driver must provide a separate dialog box procedure to process window messages for the dialog box and a dialog box template to define the appearance and content of the dialog box.

Before receiving the DRV_CONFIGURE message, a driver receives the DRV_QUERYCONFIGURE message. The driver must return a nonzero value to this query to ensure receipt of the subsequent DRV_CONFIGURE message.

When initializing the configuration dialog box, the driver typically retrieves configuration information from the registry. To help locate this information, the DRV_CONFIGURE message usually includes the address of a DRVCONFIGINFO structure that contains names of the registry key and value associated with the driver. If the user requests changes to the configuration, the driver should update the configuration information in the registry.


Installation

An installable driver can carry out driver-specific installation tasks when processing the DRV_INSTALL and DRV_REMOVE messages. An installation application, such as a Control Panel application, sends these messages to the driver when installing or removing the driver, respectively.

When processing the DRV_INSTALL message, the driver typically verifies that the any required hardware is present, then displays the configuration dialog box to let the user choose the initial configuration settings for the driver and associated hardware. The message includes the address of a DRVCONFIGINFO structure that contains the names of the registry key and value associated with the driver. The driver checks this registry value for default configuration information. Finally, the driver also creates any additional registry keys and values needed for successful operation.

When processing the DRV_REMOVE message, the driver removes any registry keys and values it may have created.


Callbacks

Installable drivers can call back to the application, window, or task that opened the given instance by using the DriverCallback function. This function gives the driver the means to return information to an application or dynamic-link library while continuing to process a request.

If a driver supports callbacks, the application or dynamic-link library that opens the instance must supply the address of a callback function, a window handle, or a task handle. This value and a flag identifying the type of the value are typically passed in a structure pointed to by the second parameter of the DRV_OPEN message.


Module Definition File

The module definition file of an installable driver names the driver, exports the DriverProc function, and defines a driver description. The following example shows a typical module definition file for an installable driver:

LIBRARY OSCI

DESCRIPTION 'FREQ,AMPL:Oscilloscope frequency and amplitude drivers.'

EXPORTS

    DriverProc

Some installation applications may open the driver and retrieve the description line to use when installing the driver. To remain compatible with these installation applications, the description line should have this form:

DESCRIPTION alias[,alias]...:text

The alias specifies a unique name for the driver that applications can use to open the driver. The alias also serves as the value name associated with the driver in the registry. Multiple aliases are separated by commas. The text describes the purpose of the driver.


Installable Driver Functions and Messages

You can open an installable driver by using the OpenDriver function. This function creates an instance of the driver, loading the driver into memory if not other instance exists, and returns the handle of the new instance. When opening an installable driver, you must supply either the full path of the driver or the names of the registry key and value associated with the driver.

Once a driver is open, you can direct it to carry out tasks by using the SendDriverMessage function to send driver messages to the driver. For example, you can direct the driver to display its configuration dialog box by sending the DRV_CONFIGURE message. Before sending this message, you must determine whether the driver has a configuration dialog box by sending the DRV_QUERYCONFIGURE message and checking for a nonzero return value. Many drivers provide a set of custom messages that you can send to direct the operations of the driver.

If you need special access to an installable driver, such as needing access to its resources, you can retrieve the module handle of the driver by using the GetDriverModuleHandle function.

When you no longer need the installable driver, you close it by using the CloseDriver function.

Although you can use the installable driver functions and messages to open and manage any installable driver, using them to open and manage multimedia device drivers is not recommended.


Using Installable Drivers

You use installable drivers to give applications or dynamic-link libraries a standard way to access a device or a set of useful routines. The following sections show how to create an installable driver by creating a DriverProc function and how to open an installable driver and direct it to carry out useful tasks.


Creating a DriverProc Function

You create a DriverProc function in much the same way as creating a window procedure. The function consists of a switch statement and each case processes a given driver message, returning a value indicating success or failure. The DriverProc function has the following structure:

LONG DriverProc(DWORD dwDriverId, HDRVR hdrvr, UINT msg,

    LONG lParam1, LONG lParam2)

{

    DWORD dwRes = 0L;

    switch (msg) {

    case DRV_LOAD:

    // Sent when the driver is loaded. This is always

    // the first message received by a driver.

        dwRes = 1L;  // Return 0L to fail.

        break;

    case DRV_FREE:

    // Sent when the driver is about to be discarded.

    // This is the last message a driver receives

    // before it is freed.

        dwRes = 1L;  // Return value is ignored.

        break;

    case DRV_OPEN:

    // Sent when the driver is opened.

        dwRes = 1L;  // Return 0L to fail.

        break;       // This value is subsequently used

                     // for dwDriverId.

    case DRV_CLOSE:

    // Sent when the driver is closed. Drivers are

    // unloaded when the open count reaches zero.

        dwRes = 1L;  // Return 0L to fail.

        break;

    case DRV_ENABLE:

    // Sent when the driver is loaded or reloaded and

    // when Windows is enabled. Install interrupt

    // handlers and initialize hardware. Expect the

    // driver to be in memory only between the enable

    // and disable messages.

        dwRes = 1L;  // Return value is ignored.

        break;

    case DRV_DISABLE:

    // Sent before the driver is freed or when Windows

    // is disabled. Remove interrupt handlers and place

    // hardware in an inactive state.

        dwRes = 1L;  // Return value is ignored.

        break;

    case DRV_INSTALL:

    // Sent when the driver is installed.

        dwRes = DRVCNF_OK;  // Can also return

        break;              // DRVCNF_CANCEL

                            // and DRV_RESTART.

    case DRV_REMOVE:

    // Sent when the driver is removed.

        dwRes = 1L;  // Return value is ignored.

        break;

    case DRV_QUERYCONFIGURE:

    // Sent to determine if the driver can be

    // configured.

        dwRes = 0L;  // Zero indicates configuration

        break;       // NOT supported.

    case DRV_CONFIGURE:

    // Sent to display the configuration

    // dialog box for the driver.

        dwRes = DRVCNF_OK;  // Can also return

        break;              // DRVCNF_CANCEL

                            // and DRVCNF_RESTART.

    default:

    // Process any other messages

        return DefDriverProc (dwDriverId, hdrvr,

            msg, lParam1, lParam2);

    }

    return dwRes;

}


Configuring an Installable Driver

To direct an installable driver to carry out useful tasks, you must open the driver using the OpenDriver function and send it messages using the SendDriverMessage function. The following sample shows how to direct the driver to display its configuration dialog box:

LONG MyConfigureDriver()

{

    HDRVR hdrvr;

    DRVCONFIGINFO dci;

    LONG lRes;

    // Open the driver. No additional parameters needed this time.

    if ((hdrvr = OpenDriver(L"\\samples\\sample.drv", 0, 0)) == 0) {

        // Can't open the driver

        return DRVCNF_CANCEL;

    }

    // Make sure driver has a configuration dialog box

    if (SendDriverMessage(hdrvr, DRV_QUERYCONFIGURE, 0, 0) != 0) {

        // Set the DRVCONFIGINFO structure and send the message

        dci.dwDCISize = sizeof (dci);

        dci.lpszDCISectionName = (LPWSTR)0;

        dci.lpszDCIAliasName = (LPWSTR)0;

        lRes = SendDriverMessage(hdrvr, DRV_CONFIGURE, 0, (LONG)&dci);

     }

    // Close the driver. No additional parameters needed this time.

    CloseDriver(hdrvr, 0, 0);

    return lRes;

}


Reference


Functions


CloseDriver

LRESULT CloseDriver(HDRVR hdrvr, LONG lParam1, LONG lParam2);

Closes an installable driver.

•	Returns nonzero if successful, zero otherwise.

hdrvr

Handle of an installable driver instance. The handle must have been previously created using the OpenDriver function.

lParam1

32-bit, driver-specific data.

lParam2

32-bit, driver-specific data.

The function passes the lParam1 and lParam2 parameters to the DriverProc function of the installable driver.


GetDriverModuleHandle

HMODULE GetDriverModuleHandle(HDRVR hdrvr);

Retrieves the instance handle of the module that contains the installable driver.

•	Returns an instance handle of the driver module if successful, NULL otherwise.

hdrvr

Handle of the installable driver instance. The handle must been previously created using the OpenDriver function.


OpenDriver

HDRVR OpenDriver(LPCWSTR lpDriverName, LPCWSTR lpSectionName,

    LONG lParam);

Opens an instance of an installable driver and initializes the instance using either the driver's default settings or settings specified by the lParam parameter.

•	Returns the handle of the installable driver instance if successful, NULL otherwise.

lpDriverName

Address of a null-terminated, wide-character string that specifies the filename of an installable driver or the name of a registry value associated with the installable driver. (This value must have been previously set when the driver was installed.)

lpSectionName

Address of a null-terminated, wide-character string that specifies the name of the registry key containing the registry value given by the lpDriverName parameter. If lpSectionName is NULL, the registry key is assumed to be Drivers32.

lParam

32-bit, driver-specific value. This value is passed as the lParam2 parameter to the DriverProc function of the installable driver.


SendDriverMessage

LRESULT SendDriverMessage(HDRVR hdrvr, UINT msg, LONG lParam1,

    LONG lParam2);

Sends the specified message to the installable driver.

•	Returns nonzero if successful, zero otherwise.

hdrvr

Handle of the installable driver instance. The handle must been previously created using the OpenDriver function.

msg

Driver message value. Can be a custom message value or one of these standard message values:

DRV_QUERYCONFIGURE	Queries an installable driver about whether it supports the DRV_CONFIGURE message and can display a configuration dialog box.
DRV_CONFIGURE	Notifies an installable driver that it should display a configuration dialog box. (This message should only be sent if the driver returns a nonzero value when the DRV_QUERYCONFIGURE message is processed.)
DRV_INSTALL	Notifies an installable driver that it has been successfully installed.
DRV_REMOVE	Notifies an installable driver that it is about to be removed from the system.
lParam1

32-bit, message-dependent information.

lParam2

32-bit, message-dependent information.


Driver Functions


DefDriverProc

LONG DefDriverProc(DWORD dwDriverId, HDRVR hdrvr, UINT msg,

    LONG lParam1, LONG lParam2);

Provides default processing for any messages not processed by an installable driver. This function is intended to be used only within the DriverProc function of an installable driver.

•	Returns nonzero if successful, zero otherwise.

dwDriverId

Identifier of the installable driver.

hdrvr

Handle of the installable driver instance.

msg

Driver message value.

lParam1

32-bit, message-dependent information.

lParam2

32-bit, message-dependent information.


DriverProc

LONG DriverProc(DWORD dwDriverId, HDRVR hdrvr, UINT msg,

    LONG lParam1, LONG lParam2);

An driver-supplied function that processes driver messages for the installable driver.

•	Returns nonzero if successful, zero otherwise.

dwDriverId

Identifier of the installable driver.

hdrvr

Handle of the installable driver instance. Each instance of the installable driver has a unique handle.

msg

Driver message value. Can be a custom value or one of these standard values:

DRV_CLOSE	Notifies the driver that it should decrement (decrease by one) its usage count and unload the driver if the count is zero.
DRV_CONFIGURE	Notifies the driver that it should display a configuration dialog box. This message is sent only if the driver returns a nonzero value when processing the DRV_QUERYCONFIGURE message.
DRV_DISABLE	Notifies the driver that its allocated memory is about to be freed.
DRV_ENABLE	Notifies the driver that it has been loaded or reloaded, or that Windows has been enabled.
DRV_FREE	Notifies the driver that it will be discarded.
DRV_INSTALL	Notifies the driver that it has been successfully installed.
DRV_LOAD	Notifies the driver that it has been successfully loaded.
DRV_OPEN	Notifies the driver that it is about to be opened.
DRV_POWER	Notifies the driver that the device's power source is about to be turned on or off.
DRV_QUERYCONFIGURE	Directs the driver to specify whether it supports the DRV_CONFIGURE message.
DRV_REMOVE	Notifies the driver that it is about to be removed from the system.
lParam1

32-bit, message-specific value.

lParam2

32-bit, message-specific value.

When the msg parameter is DRV_OPEN, lParam1 is the string following the driver filename from the SYSTEM.INI file and lParam2 is the value given as the lParam parameter in the call to the OpenDriver function.

When the msg parameter is DRV_CLOSE, lParam1 and lParam2 are the same values as the lParam1 and lParam2 parameters in the call to the CloseDriver function.


DriverCallback

BOOLEAN DriverCallback(DWORD dwCallBack, DWORD dwFlags, HDRVR hdrvr,

    DWORD msg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2);

Calls a callback function, sends a message to a window, or unblocks a thread. The action depends on the value of the dwCallBack and dwFlags parameters. This function is intended to be used only within the DriverProc function of an installable driver.

•	Returns TRUE if successful, FALSE if a parameter is invalid or the task's message queue is full.

dwCallBack

Address of the callback function, a window handle, or a task handle, depending on the flags specified in the dwFlags parameter.

dwFlags

Notification flags. Can be one of these values:

DCB_NOSWITCH	Prevents the system from switching stacks. Use only if enough stack space for the callback is known to exist.
DCB_FUNCTION	The dwCallback parameter is the address of an application-supplied callback function. The system sends the callback message to the callback function.
DCB_WINDOW	The dwCallback parameter is the handle of an application-defined window. The system sends the messages to the window.
DCB_TASK	The dwCallback parameter is the handle of an application or task. The system sends the message to the application or task.
hdrvr

Handle of the installable driver instance.

msg

Message value.

dwUser

32-bit, user-instance data supplied by the application when the device was opened.

dwParam1

32-bit, message-dependent parameter.

dwParam2

32-bit, message-dependent parameter.

The client specifies how to notify it when the device is opened. The DCB_FUNCTION and DCB_WINDOW flags are equivalent to the high-order word of the corresponding flags CALLBACK_FUNCTION and CALLBACK_WINDOW specified in the lParam2 parameter of the DRV_OPEN message when the device was opened.

If notification is accomplished with a callback function, hdrvr, msg, dwUser, dwParam1, and dwParam2 are passed to the callback. If notification is accomplished by means of a window, only msg, hdrvr, and dwParam1 are passed to the window.


Messages


DRV_CLOSE

Directs the driver to close to given instance. If no other instances are open, the driver should prepare for subsequent release from memory.

•	Returns nonzero if successful, zero otherwise.

dwDriverId

32-bit driver-supplied value. This is the same value previously returned by the driver from the DRV_OPEN message.

hdrvr

Handle of the installable driver instance.

lParam1

32-bit value specified as lParam1 in the call to the DriverClose function.

lParam2

32-bit value specified as lParam2 in the call to the DriverClose function.


DRV_CONFIGURE

Directs the installable driver to display its configuration dialog box and let the user specify new settings for the given installable driver instance.

•	Returns one of these values:

DRVCNF_OK	Configuration is successful; no further action is required.
DRVCNF_CANCEL	The user canceled the dialog box; no further action is required.
DRVCNF_RESTART	Configuration is successful, but changes do not take effect until the system is restarted.
dwDriverId

32-bit driver-supplied value. This is the same value previously returned by the driver from the DRV_OPEN message.

hdrvr

Handle of the installable driver instance.

lParam1

Handle of the parent window in low-order word. Use this window as the parent for the configuration dialog box.

lParam2

Address of a DRVCONFIGINFO structure or NULL. If the structure is given, it contains the names of the registry key and value associated with the the driver.

Some installable drivers append configuration information to the value assigned to the registry value associated with the driver.


DRV_DISABLE

Disables the driver. The driver should place the corresponding device (if any) in an inactive state and terminate any callbacks or threads.

•	No return value.

hdrvr

Handle of the installable driver instance.

The dwDriverId, lParam1, and lParam2 parameters are not used.

After disabling the driver, the system typically sends the driver a DRV_FREE message before removing the driver from memory.


DRV_ENABLE

Enables the driver. The driver should initialize any variables and locate devices with the I/O interface.

•	No return value.

hdrvr

Handle of the installable driver instance.

The dwDriverId, lParam1 and lParam2 parameters are not used.

Drivers are considered enabled from the time they receive this message until they are disabled with the DRV_DISABLE message.


DRV_FREE

Notifies the driver that it is being removed from memory. The driver should free any memory and other system resources it has allocated.

•	No return value.

hdrvr

Handle of the installable driver instance.

The dwDriverId, lParam1 and lParam2 parameters are not used.

The DRV_FREE message is always the last message a device driver receives.


DRV_INSTALL

Notifies the driver that is it being installed. The driver should create and initialize any needed registry keys and values and verify that the supporting drivers and hardware are installed and properly configured.

•	Returns one of these values:

DRVCNF_OK	Installation successful; no further action is required.
DRVCNF_CANCEL	Installation failed..
DRVCNF_RESTART	Installation successful, but does not take effect until the system is restarted.
dwDriverId

32-bit driver-supplied value. This is the same value previously returned by the driver from the DRV_OPEN message.

hdrvr

Handle of the installable driver instance.

lParam2

Address of a DRVCONFIGINFO structure or NULL. If a structure is given, it contains the names of the registry key and value associated with the driver.

The lParam1 parameter is not used.

Some installable drivers append configuration information to the value assigned to the registry value associated with the driver.


DRV_LOAD

Notifies the driver that it has been loaded. The driver should make sure that any hardware and supporting drivers it needs to function properly are present.

•	Returns nonzero if successful, zero otherwise.

The hdrvr parameter is always zero. The dwDriverId, lParam1 and lParam2 parameters are not used.

The DRV_LOAD message is always the first message a device driver receives.


DRV_OPEN

Directs the driver to open an new instance.

•	Returns a nonzero value if successful, zero otherwise.

dwDriverId

Handle of the installable driver instance.

hdrvr

Handle of the installable driver instance.

lParam1

Address of a null-terminated, wide-character string that specifies configuration information used to open the instance. If no configuration information is available, either this string is empty or the parameter is NULL.

lParam2

32-bit, driver-specific data.

If the driver returns a nonzero value, the system uses that value as the driver identifier (dwDriverId parameter) in messages it subsequently sends to the driver instance. The driver can return any type of value as the identifier. For example, some drivers return memory addresses that point to instance-specific information. This gives the driver ready access to the information while processing messages.


DRV_QUERYCONFIGURE

Directs the driver to specify whether it supports custom configuration.

•	Returns a nonzero value if the driver can display a configuration dialog box, zero otherwise.

dwDriverId

32-bit, driver-supplied value. This is the same value previously returned by the driver from the DRV_OPEN message.

hdrvr

Handle of the installable driver instance.

The lParam1 and lParam2 parameters are not used.


DRV_REMOVE

Notifies the driver it is about to be removed from the system. When a driver receives this message, it should remove any sections it created in the registry.

•	No return value.

dwDriverId

32-bit, driver-supplied value. This is the same value previously returned by the driver from the DRV_OPEN message.

hdrvr

Handle of the installable driver instance.

The lParam1 and lParam2 parameters are not used.


Structures


DRVCONFIGINFO

typedef struct tagDRVCONFIGINFO {

    DWORD dwDCISize;

    LPCWSTR lpszDCISectionName;

    LPCWSTR lpszDCIAliasName;

} DRVCONFIGINFO;

Contains the registry key and value names associated with the installable driver.

dwDCISize

Size of the structure in bytes.

lpszDCISectionName

Address of a null-terminated, wide-character string specifying the name of the registry key associated with the driver.

lpszDCIAliasName

Address of a null-terminated, wide-character string specifying the name of the registry value associated with the driver.


Bitmap Format Extensions


About the DIB Format Extensions

The device-independent bitmap (DIB) format extensions add the capabilities to handle new compression formats, custom compression formats, and inverted DIBs. The extensions also include an escape message to let applications interrogate display drivers to determine their capabilities. This chapter includes the following topics related to these extensions:

•	16- and 32-bit extensions to the BI_RGB compression format

•	16- and 32-bit BI_BITFIELDS compression format extensions

•	Extensions for custom compression formats

•	Determining display driver capabilities

•	Inverted DIBs

•	Defined DIB compression formats


Compression Formats

Compression flags for a bitmap are specified in the BITMAPINFOHEADER data structure. This structure has the following members:

Information about the compression format is specified in the biCompression and biBitCount members. The biCompression member specifies the type of compression used or requested. Both existing and new compression formats use this member.

The biBitCount member specifies the number of bits per pixel. Some compression formats need this information to properly decode the colors in the pixel.

When the value in the biBitCount member is set to less than or equal to eight, video drivers can assume the bitmap uses a palette or color table defined in the BITMAPINFO data structure. This structure has the following members:

When the value in the biBitCount member is set to greater than eight, video drivers can assume bitmaps are true color and they do not use a color table. For more information about these data structures, see the Microsoft Win32 Programmer's Reference.


Existing Formats

There are the following compression formats.

Compression format	Description
BI_RGB	Specifies that the bitmap is not compressed. (Valid for biBitCount set to 1, 4, 8, 16, 24, or 32.)
BI_RLE8	Specifies a run-length encoded format for bitmaps with 8 bits per pixel. (Valid for biBitCount set to 8.)
BI_RLE4	Specifies a run-length encoded format for bitmaps with 4 bits per pixel. (Valid for biBitCount set to 4.)
For more information about these formats, see the Microsoft Win32 Programmer's Reference.


New BI_RGB Formats

New BI_RGB formats include 16- and 32-bits-per-pixel bitmap formats. These formats do not use a color table. They embed the colors in the WORD or DWORD representing each pixel.

The 16-bit BI_RGB format is identified by setting biCompression to BI_RGB and biBitCount to 16. For this format, each pixel in the bitmap is represented by a 16-bit RGB color value. The high-bit of this value is zero. The remaining bits are divided into three groups of 5 bits to represent the red, green, and blue color values. The group containing the five most significant bits represents red. The group containing the five least significant bits represents blue. (This format is also referred to as the RGB555 format. This format supports 32K colors.)

The 32-bit BI_RGB format is identified by setting biCompression to BI_RGB and biBitCount to 32. For this format, each pixel is represented by a 32-bit (4-byte) RGB color value. The first byte is zero. The second byte represents red, the third byte represents green, and the last byte represents blue.

Display drivers must support the BI_RGB format for 1, 4, 8, and 24 bits per pixel bitmaps. If practical, they should also support this format for 16 and 32 bits per pixel bitmaps.


Formats Using BI_BITFIELDS and Color Masks

In addition to the 16 and 32 bits per pixel BI_RGB format, the BI_BITFIELDS format has been defined for 16- and 32-bit bitmaps. This flag is recognized only by enhanced display drivers and does not need to be supported by most display drivers. The BI_BITFIELDS flag has the following definition.

Compression format	Description
BI_BITFIELDS	Specifies the bitmap is not compressed and a color mask is defined in the bmiColors member of the BITMAPINFO data structure. (Valid for biBitCount set to 16 or 32.)
Setting the biCompression member of the BITMAPINFOHEADER structure to BI_BITFIELDS indicates the bmiColors member of the BITMAPINFO structure contains three DWORDs used to mask each pixel in the bitmap. The masks are used to obtain the RGB color values of the pixel. The first DWORD contains the red mask, the second DWORD contains the green mask, and the third DWORD contains the blue mask. The image bits follow the three DWORDs. The color masks have the following characteristics:

•	The bits in a mask must not overlap any bits in another mask.

•	The set of bits defined for each mask must be contiguous.

These characteristics do not restrict any one mask to a particular location in a DWORD. For example, the red mask can occupy the least significant, most significant, or central position of the ORed combination of all three masks. The position of each mask corresponds to the color position defined for the appropriate RGB component of each pixel. For a 16-bit image, this implies the color masks will reside in the low-ordered word of the DWORD. (For 16-bit images, set the biBitCount member of the BITMAPINFOHEADER structure to 16; for 32-bit images set it to 32.)

Additionally, you need to set the bits in a mask only for the bit positions in a pixel that represent color. Because unused bits in a pixel will always be masked, you can set the unused bits in a pixel to either zero or one.

For example, color masks can be used to decode the colors of a 16-bit pixel divided into three unequal groups of bits to represent the red, green, and blue color values. The group containing the five most significant bits represents red. The group containing the five least significant bits represents blue. The group containing the middle six bits represents green. (This format is also referred to as the RGB565 format.)

Drivers obtain the RGB values for a pixel by masking the pixel with the DWORD corresponding to each color mask, and then mapping the colors to the appropriate registers for display. (To retrieve the individual color values for a pixel, an application can use the color masks to separate the color components, and then right-shift each color component by the number of least significant zeros in the mask.)


Custom Formats

Compression and decompression drivers can define custom compression and bitmap formats by assigning a four-character code to the biCompression member in place of the standard constants. When defining a custom format, specify the number of bytes in the image in the biSizeImage member.

The compression type four-character code must be unique. If you want to create a new four-character code for a compression type, register it with Microsoft to set up a standard definition of it and avoid any conflicts with other compression codes that might be defined. The following is a list of the compression types used by the compressors included with Video for Windows.

Registered by	Four-character code	Compression method
Microsoft	MSVC	Video 1
Microsoft	MRLE	Run-length encoding
Texas Instruments®	JPEG	JPEG format for images
Supermac	CVID	Cinepak
Intel®	YUV9	411 YUV format
Intel	RT21	Indeo™ 2.1 format
Intel	IV31	Indeo 3.0 format


Determining Display Driver Capabilities

You can determine if a display driver can handle a DIB with the QUERYDIBSUPPORT escape. The following syntax statement illustrates the use of this escape:

short Escape(hdc, QUERYDIBSUPPORT, nSize, lpbi, lpFlags)

The following parameter descriptions apply to the QUERYDIBSUPPORT escape.

Parameter	Data type	Description
hdc	HDC	Identifies the device context.
nSize	int	Specifies the size of the BITMAPINFO structure passed.
lpbi	LPBITMAPINFO	Points to a BITMAPINFO structure containing the characteristics of the bitmap.
lpFlags	LPINT	Points to an integer containing the return flags. Drivers set these flags to indicate the capabilities they support. The following flags are defined.
		Flag	Description
		QDI_SETDIBITS	Device can convert DIB to bitmap
		QDI_GETDIBITS	Device can convert bitmap to DIB
		QDI_DIBTOSCREEN	Device can draw DIB
		QDI_STRETCHDIB	Device can stretch DIB
When a display driver gets this escape it should examine the BITMAPINFO structure indicated by lpbi and determine if it supports the DIB. The driver checks biBitCount for the proper bit depth, biCompression for the proper compression type, and biHeight for a positive or negative value (negative values indicate an inverted DIB). If biCompression is set to BI_BITFIELDS, the driver also checks the bit masks in the color table.

A display driver will set flags for lpFlags if it provides either partial or complete functionality corresponding to the flag. For example, a driver sets the QDI_STRETCHDIB flag if it can stretch a DIB by integer amounts (partial functionality) or if it can stretch a DIB by both integer and non-integer values (complete functionality).


Inverted DIBs

Video drivers incorporating the DIB format extensions will let you specify negative values for biHeight. If biHeight is negative, then the origin of the bitmap is the upper-left corner and the height is the absolute value of biHeight.

Element	Upright DIB	Inverted DIB
biHeight	Greater than zero	Less than zero
Pointer to DIB data (lpBits)	Points to bottom scan line	Points to top scan line
Location of DIB Origin	Lower-left corner of the DIB	Lower-left corner of the DIB
Address of DIB Origin	lpBits	lpBits +  (abs(biHeight) − 1) ×  WidthInBytes
Applications determine if a driver supports inverted DIBs by sending the QUERYDIBSUPPORT flag with biHeight set to a negative value. Drivers return the QDI_DIBTOSCREEN flag in response to this if they support inverted DIBs.

DIBs are usually rendered very slowly with most Windows video-display drivers compared to device-dependent bitmaps, which are usually rendered much faster. To improve rendering speed, Video for Windows can decompress to an upside-down DIB, which is equivalent to a device-dependent bitmap. New decompressors should support decompression to inverted DIBs. This lets them decompress directly into a bitmap-like format.


Using DIB Format Extensions

This section contains information about using the DIB format extensions. Example code fragments illustrate some of the concepts involved with using these extensions.


Handling Inverted DIBs

The following fragment computes a pointer to a DIB that might use an inverted DIB format:

LPVOID DibXY(

    BITMAPINFOHEADER *pbi,  // BITMAPINFO for DIB

    char *bits,             // bits pointer, NOTE this points to

                            // ...scan0 for a normal DIB (biHeight > 0)

                            // ...scanN-1 for an upside down DIB

                            // (biHeight < 0)

    long  x,                // x (DIB coordinates(0,0)is lower left)

    long  y,                // y (DIB coordinates(0,0)is lower left)

    int  *pNextScan)        // returns amount to add to get to next

                            // scan (y+1)

{

    int NextScan;

    if (x > 0)

        bits += (x * pbi->biBitCount) >> 3;

    NextScan = ((((pbi->biWidth * pbi->biBitCount) >> 3) + 3)&~3);

    if (pbi->biHeight < 0) {

        bits += (lpbi->biSizeImage - NextScan);

        NextScan = -NextScan;

    }

    if (y > 0)

        bits += (y * NextScan);

    if (pNextScan)

        *pNextScan = NextScan;

    return bits;

}


Custom AVI File Handlers


About Custom AVI File Handlers

If you have a custom file format for AVI data that you would like to use with the AVIFile functions, you need to write a custom handler. You can write a custom handler to read and write nonstandard files. If an application needs to read your file using the standard AVI functions, it simply uses the name of your handler when opening the file, and the system will use your handler's functions instead of the AVI default functions. This way, your custom format appears as a standard AVI data to any application that needs to read it.

Each audio and video component of an AVI sequence is considered a stream. An AVI file can contain several different types of data — for instance a video sequence, an English soundtrack, and a French soundtrack. In this example, there are three streams: one for the video sequence, and two for the audio tracks. Considering each multimedia component as a stream lets the software obtain a particular type of multimedia data and direct it to a handler designed to process it optimally.


Architecture of File Handlers

Stream and file handlers are types of drivers that provide a consistent interface to the application controlling the multimedia data. File handlers appear to the client application as a module to read and write AVI files. Similarly, stream handlers appear as a module to read and write streams. The internal function of a stream or file handler is defined by the handler. Custom stream and file handlers let applications access sources of multimedia data beyond that defined by the standard AVI format.

Typically, file handlers access disk files and their internal functions read and write the multimedia data. While file handlers typically access disk files, they are not limited to this type of operation. File handlers can work with any source of data, but the handler makes the data appear to come from an AVI file.

Stream handlers appear as data streams to the client application. The consistent stream interface makes the source and destination of the stream unimportant to the client application. Custom stream handlers can be used to convert nonstandard data into the multimedia data type expected by an application. For example, a stream handler might capture audio or video from an external source and supply it as a data stream to an application. In this case, the stream handler obtains the multimedia data from a nonstandard source and converts it to a standard format usable by the application, and the application remains unaware of the source.


The IAVIStream and IAVIFile Interfaces

The IAVIStream and IAVIFile interfaces contain the methods used by stream and file handlers. These interfaces use the PAVISTREAM and PAVIFILE data types as object pointers. From a C point of view, an object pointer like PAVISTREAM or PAVIFILE is a pointer to a structure whose first member is a pointer to a Vtbl table of functions. Other members of the structure retain data used by the interfaces.

For example, to create an object pointer, first allocate space for a structure large enough to contain the pointer to the Vtbl and any other members you want in the structure. Then, create a function table with the Read, Write, and other functions to operate on your type of stream, and then set the first member of the object pointer to point at the table.


IAVIFile Methods

In addition to the QueryInterface, AddRef, and Release methods of the IUnknown interface, the IAVIFile interface uses the following methods. (The IUnknown interface is defined by OLE version 2.0) . File handlers are written as DLLs external to any application. The methods used exclusively by file handlers have the following descriptions.

Method	Description
QueryInterface	Determines the interfaces a file handler supports.
AddRef	Increments the reference count of a handler.
Release	Decrements the reference count and frees any resources used.
Open	Initializes a file handler.
Info	Fills an AVIFILEINFO structure with information about a file.
GetStream	Prepares to read information from a stream.
CreateStream	Prepares a stream for writing.
Save	Flushes any changes that have been made to a file.
WriteData	Writes header data, format data, or non-audio and non-video data.
ReadData	Reads header data, format data, or non-audio and non-video data.
EndRecord	Used to write tightly interleaved AVI files.
When used in a Vtbl, the file-handler methods appear in the order presented in the previous table.


IAVIStream Methods

In addition to the QueryInterface, AddRef, and Release methods of the IUnknown interface, the IAVIStream interface uses the following methods. (The IUnknown interface is defined by OLE version 2.0) Stream handlers are written as part of the calling application. Stream handlers use the following methods to access streams.

Method	Description
QueryInterface	Determines the interfaces a stream handler supports.
AddRef	Increments the reference count of a handler.
Release	Decrements the reference count and frees any resources used.
Create	Prepares to read information from one of the streams.
Info	Fills an AVISTREAMINFO structure with information about a stream.
FindSample	Finds a sample in a stream.
ReadFormat	Obtains format information from a stream.
SetFormat	Sets format information in a stream.
Read	Reads multimedia data from a stream.
Write	Writes multimedia data into a stream.
Delete	Deletes multimedia data from a stream.
ReadData	Reads stream-header data, stream-format data, or non-audio and non-video data. (Use Read methods to read audio and video data.)
WriteData	Writes stream-header data, stream-format data, or non-audio and non-video data. (Use Write methods to write audio and video data.)
When used in a Vtbl, the stream-handler methods appear in the order presented in the previous table.


Using Custom AVI File Handlers

This section contains information about using stream and file handlers. Example code fragments illustrate some of the concepts involved with stream and file handlers.


Creating a Stream or File Handler in C

In C, your stream or file handler usually creates a function for each method. The client application accesses these functions through an array of function pointers your stream handler creates. An AVIStreamVtbl structure contains the array of function pointers. Your stream handler can assign any name it wants to functions it creates for the methods. The position of the function pointer in the structure implies the correspondence of the function to the method. For example, the first function pointer in the structure corresponds to the QueryInterface method. Your stream handler can use the default services of the system by specifying NULL in the data structure.


Creating a Stream Handler Vtbl in C

The following fragment shows how AVIBall creates the Vtbl used to reference its services.

HRESULT STDMETHODCALLTYPE AVIBallQueryInterface (PAVISTREAM ps,

                REFIID riid, LPVOID FAR* ppvObj);

HRESULT STDMETHODCALLTYPE AVIBallCreate (PAVISTREAM ps,

                LONG lParam1, LONG lParam2);

ULONG   STDMETHODCALLTYPE AVIBallAddRef (PAVISTREAM ps);

ULONG   STDMETHODCALLTYPE AVIBallRelease (PAVISTREAM ps);

HRESULT STDMETHODCALLTYPE AVIBallInfo (PAVISTREAM ps,

                AVIStreamHeader FAR * psi, LONG lSize);

LONG    STDMETHODCALLTYPE AVIBallSample (PAVISTREAM ps,

                LONG lPos, LONG lFlags);

HRESULT STDMETHODCALLTYPE AVIBallReadFormat (PAVISTREAM ps,

                LONG lPos, LPVOID lpFormat, LONG FAR *lpcbFormat);

HRESULT STDMETHODCALLTYPE AVIBallSetFormat (PAVISTREAM ps,

                LONG lPos, LPVOID lpFormat, LONG cbFormat);

HRESULT STDMETHODCALLTYPE AVIBallRead (PAVISTREAM ps,

                LONG lStart, LONG lSamples, LPVOID lpBuffer,

                LONG cbBuffer, LONG FAR * plBytes,LONG FAR * plSamples);

HRESULT STDMETHODCALLTYPE AVIBallWrite (PAVISTREAM ps, LONG lStart,

                LONG lSamples, LPVOID lpBuffer, LONG cbBuffer,

                DWORD dwFlags);

HRESULT STDMETHODCALLTYPE AVIBallDelete (PAVISTREAM ps,

                LONG lStart, LONG lSamples);

HRESULT STDMETHODCALLTYPE AVIBallReadData (PAVISTREAM ps,

                DWORD fcc, LPVOID lp,LONG FAR *lpcb);

HRESULT STDMETHODCALLTYPE AVIBallWriteData (PAVISTREAM ps,

                DWORD fcc, LPVOID lp,LONG cb);

IAVIStreamVtbl AVIBallHandler = {

    AVIBallQueryInterface,  //Function pointer for QueryInterface

    AVIBallAddRef,          //Function pointer for AddRef

    AVIBallRelease,         //Function pointer for Release

    AVIBallCreate,          //Function pointer for Create

    AVIBallInfo,            //Function pointer for Info

    AVIBallFindSample,   //Function pointer for FindSample

    AVIBallReadFormat,      //Function pointer for ReadFormat

    AVIBallSetFormat,       //Function pointer for SetFormat

    AVIBallRead,            //Function pointer for Read

    AVIBallWrite,           //Function pointer for Write

    AVIBallDelete,          //Function pointer for Delete

    AVIBallReadData,        //Function pointer for ReadData

    AVIBallWriteData        //Function pointer for WriteData

};

File handlers use a similar procedure, except they use a different definition for the Vtbl.


Creating an Object Pointer

AVIBall uses the following structure as its object pointer. The first member of this structure points to the Vtbl AVIBall uses to access its functions. Applications can cast this structure to the PAVISTREAM data type. Methods that use the PAVISTREAM data type use only the pointer to the Vtbl. The members following the pointer to the Vtbl are used internally by AVIBall.

typedef struct {

    IAVIStreamVtbl FAR * lpvtbl;

    //  ball instance data

    ULONG    ulRefCount;

    DWORD       fccType;        // is this audio/video

    int         width;          // size in pixels of each frame

    int         height;

    int         length;         // length in frames

    int         size;

    COLORREF    color;          // ball color

} AVIBALL, FAR * PAVIBALL;


C Example for Obtaining the Vtbl Address

Client applications using AVIBall can get the address of the IAVIStreamVtbl structure by calling NewBall. This function returns the address of a structure containing a pointer to IAVIStreamVtbl. Information following the IAVIStreamVtbl pointer specifies data used internally by AVIBall. Your stream handler can append its own information after the IAVIStreamVtbl pointer. This information is returned in subsequent calls to your stream handler.

PAVISTREAM FAR PASCAL NewBall(void)

{

    PAVIBALL pball;

    pball = (PAVIBALL) GlobalAllocPtr(GHND, sizeof(AVIBALL));

    if (!pball)

        return 0;

    pball->lpvtbl = &AVIBallHandler;

    pball->lpvtbl->Create((PAVISTREAM) pball, 0, 0);

    return (PAVISTREAM) pball;

}


Creating a File-Handler Instance in a DLL

When the client application specifies your file-handler DLL or stream handler, it is looked up in the registration database by its class ID and loaded. The system then calls the DLL's DllGetClassObject function to create an instance of the stream or file handler. The following C+ + example shows how a file handler creates an instance:

STDAPI DllGetClassObject(    //Main DLL entry point

    const CLSID FAR&    rclsid,

    const IID FAR&    riid,

    void FAR* FAR*    ppv)

{

    HRESULT    hresult;

    hresult = CAVIFileCF::Create(rclsid, riid, ppv);

    return hresult;

}

HRESULT CAVIFileCF::Create(

    const CLSID FAR&    rclsid,

    const IID FAR&    riid,

    void FAR* FAR*    ppv)

{ //The following is is the class factory creation and not an

  //actual PAVIFile

    CAVIFileCF FAR*    pAVIFileCF;

    IUnknown FAR*    pUnknown;

    HRESULT hresult;

    pAVIFileCF = new FAR CAVIFileCF(rclsid, &pUnknown); // Create the

                                                        // instance

    if (pAVIFileCF == NULL)

        return ResultFromScode(E_OUTOFMEMORY);

    hresult = pUnknown->QueryInterface(riid, ppv); // Set the

                                                   // interface pointer

    if (FAILED(GetScode(hresult)))

        delete pAVIFileCF;

    return hresult;

}


The QueryInterface Method in C++

The QueryInterface method lets a client application query an object to determine which interfaces it supports. The sample application sets the ppv pointer to the current interface.

STDMETHODIMP CAVIFileCF::QueryInterface(

    const IID FAR&    iid,

    void FAR* FAR*    ppv)

{

    if (iid == IID_IUnknown)

        *ppv = this;                     // Set the interface pointer

                                         // to this instance

    else if (iid == IID_IClassFactory)

        *ppv = this;                     // Second chance to set the

                                         // interface pointer to this

                                         // instance

    else

        return ResultFromScode(E_NOINTERFACE);

    AddRef();  //Increment the reference count

    return NULL;

}


The AddRef Method in C++

The AddRef method increments the stream- or file-handler reference counter.

STDMETHODIMP_(ULONG) CAVIFileCF::AddRef()

{

    return ++m_refs;

}


The Release Method in C++

The Release method deletes the object when its reference count is zero.

STDMETHODIMP_(ULONG) CAVIFileCF::Release()

{

    if (!--m_refs) {

        delete this;   // If O, delete this instance

        return 0;

    }

    return m_refs;

}


Reference

This section contains an alphabetical list of the functions, constants, and structures used by AVIFile. OLE version 2.0 must be installed correctly in the registration database for the Clipboard functions to work properly.

To	See these functions or methods
Add methods common to both stream and file and handlers	QueryInterface AddRef Release Info ReadData WriteData
Add methods that apply only to file handlers	Open GetStream CreateStream Save EndRecord
Add methods that apply only to stream handlers	Create ReadFormat Read FindSample Write Delete
Create an instance of a stream or file handler	DllGetClassObject


DllGetClassObject

This entry point is used by C+ + stream and file handlers to create an instance of the stream or file handler.

STDAPI DllGetClassObject(const CLSID FAR& rclsid, const IID FAR& riid, void FAR* FAR* ppv)

•	Returns a handle to an instance of the stream or file handlers.

rclsid

Specifies the class ID.

riid

Specifies the interface identifier.

ppv

On exit, points to the object whose interface is being queried. If the interface specified in riid is not supported by the object, S_FALSE is returned, and ppvObj must be set to NULL.

This is the only function that you need to export from your DLL. The OLE version 2.0 component object handler calls this function to obtain an instance of the stream- or file-handler interface.

Your stream or file handler should check that the system is asking for the correct class ID and then create the instance.


AddRef

The AddRef method corresponds to the AddRef member function available in OLE. The AVIStreamAddRef function uses this method to increment the use count of your stream or file handler. Typically, client applications use AVIStreamAddRef when they want a stream to remain open, and they call a function that uses AVIStreamRelease. A client application makes one call to AVIStreamRelease for every call it makes to AVIStreamAddRef or AVIStreamOpenFromFile.

For C+ + handlers, AddRef has the following example syntax:

STDMETHODIMP_(ULONG) myAVIFile::AddRef();

For C handlers, AddRef has the following example syntax:

ULONG STDMETHODCALLTYPE AVIBallAddRef (PAVISTREAM ps);

•	Returns the resulting reference count.

ps

Specifies a pointer to a stream or file structure. This parameter is implicitly defined for C+ +.


Create

The AVIStreamCreate function uses the Create method to initialize a stream handler.

For C+ + handlers, Create has the following example syntax:

STDMETHODIMP myAVIFile::Create(LONG lParam1, LONG lParam2)

For C handlers, Create has the following example syntax:

HRESULT STDMETHODCALLTYPE AVIBallCreate(PAVISTREAM ps, LONG lParam1, LONG lParam2);

•	Returns the HRESULT defined by OLE version 2.0..

ps

Specifies a pointer to a stream structure. This parameter is implicitly defined for C+ +.

lParam1

Specifies stream-handler-specific data.

lParam2

Specifies stream-handler-specific data.

This method is not used by streams that are part of file handlers. It is used only by streams that are independent (that is, they are not part of a file).


CreateStream

The CreateStream method creates a new stream for writing. This method applies only to file handlers.

For C+ + handlers, CreateStream has the following example syntax:

STDMETHODIMP myAVIFile::CreateStream (PAVISTREAM FAR * ppStream,

                                      AVISTREAMINFO FAR * psi);

For C handlers, CreateStream has the following example syntax:

HRESULT STDMETHODCALLTYPE myAVICreateStream(PAVIFILE pf,

                                            PAVISTREAM FAR * ppstream,

                                            AVISTREAMINFO FAR * psi);

•	Returns the HRESULT defined by OLE version 2.0.

pf

Specifies a pointer to a file structure. This parameter is implicitly defined for C+ +.

ppStream

Specifies a pointer to the stream created.

psi

Specifies a pointer to an AVISTREAMINFO structure defining the stream to create.


Delete

The Delete method in stream handlers deletes stream data.

For C+ + handlers, Delete has the following example syntax:

STDMETHODIMP myAVIFile::Delete (LONG lStart, LONG lSamples);

For C handlers, Delete has the following example syntax:

HRESULT STDMETHODCALLTYPE myAVIFileDelete (PAVISTREAM ps, LONG lStart,  LONG lSamples);

•	Returns the HRESULT defined by OLE version 2.0.

ps

Specifies a pointer to a stream structure. This parameter is implicitly defined for C+ +.

lStart

Specifies the starting sample or frame number to delete.

lSamples

Specifies the number of samples to delete.


EndRecord

The EndRecord method ends the 'rec ' chunk when writing tightly interleaved AVI files. This file handler method is typically not used.

For C+ + handlers, EndRecord has the following example syntax:

STDMETHODIMP myAVIFile::EndRecord ();

For C handlers, EndRecord has the following example syntax:

HRESULT STDMETHODCALLTYPE myAVIFileEndRecord (PAVISTREAM pf);

•	Returns the HRESULT defined by OLE version 2.0.

pf

Specifies a pointer to a file structure. This parameter is implicitly defined for C+ +.


FindSample

The AVIStreamFindSample function uses the FindSample method to obtain the position for a key frame or non-empty frame in a stream.

For C+ + handlers, FindSample has the following example syntax:

STDMETHODIMP_(LONG) myAVIFile::FindSample(LONG lPos, LONG lFlags)

For C handlers, FindSample has the following example syntax:

LONG STDMETHODCALLTYPE AVIBallFindSample(PAVISTREAM ps,

                       LONG lPos, LONG lFlags);

•	Returns the location of the key frame corresponding to the frame specified by the client application.

ps

Specifies a pointer to a stream structure. This parameter is implicitly defined for C+ +.

lPos

Specifies the position of the sample or frame.

lFlags

The following flags are defined:

FIND_KEY

Finds a key frame.

FIND_ANY

Finds a non-empty sample.

FIND_FORMAT

Finds a format change.

FIND_NEXT

Finds the nearest sample, frame, or format change, searching forward. The current sample is included in the search. Use this flag with the FIND_ANY, FIND_KEY, or FIND_FORMAT flag.

FIND_PREV

Finds the nearest sample, frame, or format change searching backward. The current sample is included in the search. Use this flag with the FIND_ANY, FIND_KEY, or FIND_FORMAT flag.

The FIND_ANY, FIND_KEY, and FIND_FORMAT flags are mutually exclusive. The FIND_NEXT and FIND_PREV flags are also mutually exclusive.

If key frames are not meaningful for your file format, return the position specified for lPos.


GetStream

The GetStream method obtains access to an individual stream in a file handler.

For C+ + handlers, GetStream has the following example syntax:

STDMETHODIMP myAVIFile::GetStream (PAVISTREAM FAR * ppStream,

                                   DWORD fccType, LONG lParam);

For C handlers, GetStream has the following example syntax:

STDMETHODIMP myAVIGetStream (PAVIFILE pf, PAVISTREAM FAR * ppStream,

                             DWORD fccType, LONG lParam);

•	Returns the HRESULT defined by OLE version 2.0.

pf

Specifies a pointer to a file structure. This parameter is implicitly defined for C+ +.

ppStream

Returns a pointer to the stream.

fcc

Specifies a four-character code indicating the type of stream.

lParam

Specifies the stream number.

It's usually easier to implement this method by creating all of the stream objects in advance with the Open method. Then, this method only has to decide which stream the client application wants and return it.

Remember to increment the reference count maintained by AddRef for the stream when this method is used.


Info

The AVIStreamInfo function uses the Info method to obtain information about a data stream or a file. This method uses the buffer supplied by the client application to return the data in a AVISTREAMINFO or AVIFILEINFO structure.

For C+ + handlers, Info has the following example syntax:

STDMETHODIMP myAVIFile::Info(AVIFILEINFO FAR * psi, LONG lSize)

For C handlers, Info has the following example syntax:

HRESULT STDMETHODCALLTYPE AVIBallInfo (PAVISTREAM ps,

                          AVISTREAMINFO FAR * psi, LONG lSize);

•	Returns the HRESULT defined by OLE version 2.0.

ps

Specifies a pointer to a stream structure. This parameter is implicitly defined for C+ +.

psi

Specifies a pointer to a buffer used to return stream information.

lSize

Indicates the size of the return buffer specified by lpFormat.

The example syntax for File handlers is similar to the examples, except the AVIFILEINFO data type is used in place of AVISTREAMINFO.

If the buffer allocated is too small for the structure, your Info method should fail the call by returning AVIERR_BUFFERTOOSMALL. Otherwise, it should fill the data structure and return its size.


Open

The Open method initializes a file handler. This will always be the first method called whether reading or writing.

For C+ + handlers, Open has the following example syntax:

STDMETHODIMP myAVIFile::Open (LPCSTR szFile, UINT mode);

For C handlers, Open has the following example syntax:

HRESULT STDMETHODIMP Open (PAVISTREAM pf,  LPCSTR szFile, UINT mode);

•	Returns the HRESULT defined by OLE version 2.0.

ps

Specifies a pointer to a file structure. This parameter is implicitly defined for C+ +.

szFile

Specifies a points to a zero-terminated string containing the filename.

mode

Specifies any flags for the open operation.


QueryInterface

The QueryInterface method corresponds to the QueryInterface member method available in OLE. This method lets a client application query an object to determine which interfaces it supports. Both stream and file handlers support this method.

For C+ + handlers, QueryInterface has the following example syntax:

STDMETHODIMP myAVIFile::QueryInterface(const IID FAR& riid, void FAR* FAR* ppvObj)

For C handlers, QueryInterface has the following example syntax:

HRESULT STDMETHODCALLTYPE AVIBallQueryInterface (PAVISTREAM ps, REFIID riid, LPVOID FAR* ppvObj);

•	Returns S_OK if the interface is supported, and E_NOINTERFACE if not.

ps

Specifies a pointer to a stream or file structure. This parameter is implicitly defined for C+ +.

riid

Specifies the interface identifier of the interface being queried.

ppvObj

On exit, points to the object whose interface is being queried. If the interface specified in riid is not supported by the object, E_NOINTERFACE is returned, and *ppvObj must be set to NULL.


Read

The AVIStreamRead function uses the Read method in your stream handler to read data from a stream. This method is responsible for getting the multimedia data out of the stream.

For C+ + handlers, Read has the following example syntax:

STDMETHODIMP myAVIFile::Read (LONG lStart, LONG lSamples,

             LPVOID lpBuffer, LONG cbBuffer,

             LONG FAR * plBytes, LONG FAR * plSamples);

For C handlers, Read has the following example syntax:

HRESULT STDMETHODCALLTYPE AVIBallRead(PAVISTREAM ps, LONG lStart,

        LONG lSamples, LPVOID lpBuffer, LONG cbBuffer,

        LONG FAR * plBytes, LONG FAR * plSamples);

•	If lpBuffer is NULL, return AVIERR_OK and set plBytes to the size (in bytes) of the buffer needed to return data. If lpBuffer is not NULL, return AVIERR_OK and set plSamples to the number of samples in the return buffer. If the data buffer is too small to hold the data, return the AVIERR_BUFFERTOOSMALL error so that the client application will know to call again with a larger buffer size. The following error code is defined:

AVIERR_BUFFERTOOSMALL

The return buffer is too small to hold to return the data.

ps

Specifies a pointer to a stream structure. This parameter is implicitly defined for C+ +.

lStart

Specifies the starting sample or frame number to read.

lSamples

Specifies the number of samples to read.

lpBuffer

Specifies a pointer to the return buffer for the data. If the client application specifies a NULL pointer to the buffer, it is requesting the number of bytes returned for the return data.

cbBuffer

Specifies the size of the return buffer specified by lpBuffer.

plBytes

Specifies a pointer to buffer used to return the number of bytes actually read.

plSamples

Specifies a pointer to buffer used to return the number of samples actually read.

If the client application specifies a NULL pointer to the return buffer, it wants to know how much memory it needs to allocate for the return buffer. Try to handle this efficiently. Many applications will precede every actual read with a call like this to see how large a buffer will be needed.


ReadData

The AVIStreamReadData function uses the ReadData method to read data headers from a file or stream. Use the Read method to obtain the multimedia data contained in a stream.

For C+ + handlers, ReadData has the following example syntax:

STDMETHODIMP myAVIFile::ReadData (DWORD fcc, LPVOID lp, LONG FAR *lpcb);

For C handlers, ReadData has the following example syntax:

HRESULT STDMETHODCALLTYPE AVIBallReadData (PAVISTREAM ps, DWORD fcc, LPVOID lpBuffer, LONG FAR * lpcbBuffer);

•	Returns the HRESULT defined by OLE version 2.0.

ps

Specifies a pointer to a stream or file structure. This parameter is implicitly defined for C+ +.

fcc

Specifies the four-character code of the header to read.

lpBuffer

Specifies a pointer to the buffer for the data.

lpcbBuffer

On input, indicates the size of the buffer specified by lpBuffer. On output, specifies the amount of data read.


ReadFormat

The AVIStreamReadFormat function uses the ReadFormat method in your stream handler to obtain the format data for the data stream. This method should return a format data structure in the buffer supplied by the client application. The data structure returned by your stream handler depends on the type of data in the stream.

For video streams, it returns a BITMAPINFOHEADER data structure. Your stream handler should return all applicable information in the structure, plus the palette information, if applicable. Your stream handler should not return any data bits with the structure. For audio streams, your stream handle returns a PCMWAVEFORMAT structure with its applicable data. Other data streams can use data structures that apply to the stream data.

For C+ + handlers, ReadFormat has the following example syntax:

STDMETHODIMP myAVIFile::ReadFormat(LONG lPos, LPVOID lpFormat, LONG FAR *lpcbFormat)

For C handlers, ReadFormat has the following example syntax:

HRESULT STDMETHODCALLTYPE AVIBallReadFormat (PAVISTREAM ps, LONG lPos, LPVOID lpFormat, LONG FAR * lpcbFormat);

•	Returns the HRESULT defined by OLE version 2.0.

ps

Specifies a pointer to a stream structure. This parameter is implicitly defined for C+ +.

lPos

Specified the position of the sample or frame.

lpFormat

Specifies a pointer to the return buffer for the format data.

lpcbFormat

Specifies a pointer to the memory containing the size of the return buffer specified by lpFormat.

If the client application specifies an invalid buffer, it is requesting the number of bytes returned for the return data. For an invalid buffer, return the number of bytes in lpcbFormat.


Release

The release services correspond to the Release member function available in OLE. The AVIStreamRelease function uses this method in your stream or file handler to close it. A client application makes one call to AVIStreamRelease for every call that increments the reference count. Your stream- or file-handler release function should free any resources established for the stream or file.

For C+ + handlers, Release has the following example syntax:

STDMETHODIMP_(ULONG) myAVIFile::Release()

For C handlers, Release has the following example syntax:

ULONG STDMETHODCALLTYPE AVIBallRelease (PAVISTREAM ps);

•	Returns the new reference count.

ps

Specifies a pointer to a stream or file structure. This parameter is implicitly defined for C+ +.


Save

The Save method flushes the buffers a file handler uses for writing to a file.

For C+ + handlers, Save has the following example syntax:

STDMETHODIMP myAVIFile::Save (LPCSTR szFile, AVICOMPRESSOPTIONS FAR *lpOptions, AVISAVECALLBACK lpfnCallback);

For C handlers, Save has the following example syntax:

HRESULT STDMETHODIMP Save (PAVISTREAM pf, LPCSTR szFile, AVICOMPRESSOPTIONS FAR *lpOptions, AVISAVECALLBACK lpfnCallback);

•	Returns the HRESULT defined by OLE version 2.0.

pf

Specifies a pointer to a file structure. This parameter is implicitly defined for C+ +.

szFile

Specifies a pointer to a zero-terminated string containing the file name.

lpOptions

Specifies a pointer to an AVICOMPRESSOPTIONS structure containing the compression options.

lpfnCallback

Specifies a pointer to a callback function. The callback function has the following example syntax:

    BOOL FAR PASCAL myCallBack(INT CallbackData);


SetFormat

The AVIStreamSetFormat function uses the SetFormat method to set the format data for the data stream. The format data structure sent to your stream handler depends on the type of data in the stream.

For video streams, the client application sends a BITMAPINFOHEADER data structure. For audio streams, the client application sends a PCMWAVEFORMAT structure. Other data streams can use data structures that apply to the stream data.

For C+ + handlers, SetFormat has the following example syntax:

STDMETHODIMP myAVIFile::SetFormat(LONG lPos, LPVOID lpFormat, LONG cbFormat)

For C handlers, SetFormat has the following example syntax:

HRESULT STDMETHODCALLTYPE AVIBallSetFormat (PAVISTREAM ps, LONG lPos, LPVOID lpFormat, LONG cbFormat);

•	Returns the HRESULT defined by OLE version 2.0.

ps

Specifies a pointer to a stream structure.

lPos

Specifies the position of the sample or frame.

lpFormat

Specifies a pointer to the return buffer for the format data.

cbFormat

Specifies a pointer to the memory containing the size of the return buffer specified by lpFormat.


Write

The AVIStreamWrite function uses the Write method in stream handlers to write multimedia data in a stream.

For C+ + handlers, Write has the following example syntax:

STDMETHODIMP myAVIFile::Write (LONG lStart, LONG lSamples,  LPVOID lpBuffer, LONG cbBuffer,  DWORD dwFlags,  LONG FAR *plSampWritten,  LONG FAR *plBytesWritten);

For C handlers, Write has the following example syntax:

HRESULT STDMETHODCALLTYPE AVIBallWrite     (PAVISTREAM ps,      LONG lStart,  LONG lSamples,      LPVOID lpBuffer,     LONG cbBuffer, DWORD dwFlags,  LONG FAR *plSampWritten,  LONG FAR *plBytesWritten);

•	Returns the HRESULT defined by OLE version 2.0.

ps

Specifies a pointer to a stream structure. This parameter is implicitly defined for C+ +.

lStart

Specifies the starting sample or frame number to write.

lSamples

Specifies the number of samples to write.

lpBuffer

Specifies a pointer to the buffer for the data.

cbBuffer

Specifies the size of the buffer specified by lpBuffer.

dwFlags

Specifies the AVIIF_KEYFRAME flag if the data does not rely on preceding data in the file.

plSampWritten

Specifies a pointer to a buffer used to return the number of samples written.

plBytesWritten

Specifies a pointer to a buffer used to return the number of bytes written.


WriteData

The AVIStreamWriteData function uses the WriteData method to write file and stream headers. Use the Write method to write the multimedia data in a stream.

For C+ + handlers, WriteData has the following example syntax:

STDMETHODIMP myAVIFile::WriteData(DWORD fcc, LPVOID lpBuffer, LONG cbBuffer);

For C handlers, WriteData has the following example syntax:

HRESULT STDMETHODCALLTYPE AVIBallWriteData (PAVISTREAM ps, DWORD fcc,  LPVOID lpBuffer, LONG cbBuffer);

•	Returns the HRESULT defined by OLE version 2.0.

ps

Specifies a pointer to a stream or file structure. This parameter is implicitly defined for C+ +.

fcc

Specifies the four-character code of the header to write.

lpBuffer

Specifies a pointer to the buffer for the data.

lpcbBuffer

Indicates the size of the buffer specified by lpBuffer.


AVI File Structure


About AVI File Structure

The Microsoft audio-video interleaved (AVI) file format is a RIFF file specification used with applications that capture, edit, and play back audio-video sequences. In general, AVI files contain multiple streams of different types of data. Most AVI sequences use both audio and video streams. A simple variation for an AVI sequence uses video data and does not require an audio stream. Specialized AVI sequences might include a control track or MIDI track as an additional data stream. The control track could control external devices, such as an MCI videodisc player. The MIDI track could play background music for the sequence. While a specialized sequence requires a specialized control program to take advantage of all its capabilities, applications that can read and play AVI sequences can still read and play an AVI sequence in a specialized file. (These applications ignore the non-AVI data in the specialized file.) This main topic primarily describes AVI files containing only audio and video data.

This main topic covers the following topics:

•	The required chunks of an AVI file

•	The optional chunks of an AVI file

•	Developing routines for writing AVI files

Applications that read or write AVI files should use the AVI file functions described in <ch_aviread> rather than developing the routines to perform these services. The AVI file functions simplify the programming requirements for accessing these files. The contents of this main topic should be used as background information to understand the format and type of data contained in an AVI file, or for programmers who are using AVI files on other platforms.


AVI RIFF Form

AVI files use the AVI RIFF form. The AVI RIFF form is identified by the four-character code 'AVI '. All AVI files include two mandatory LIST chunks. These chunks define the format of the streams and stream data. AVI files might also include an index chunk. This optional chunk specifies the location of data chunks within the file. An AVI file with these components has the following form:

RIFF ('AVI '

     LIST ('hdrl'

            .

            .

            .

          )

     LIST ('movi'

            .

            .

            .

          )

     ['idx1'<AVI Index>]

     )

The LIST chunks and the index chunk are subchunks of the RIFF 'AVI ' chunk. The 'AVI ' chunk identifies the file as an AVI RIFF file. The LIST 'hdrl' chunk defines the format of the data and is the first required LIST chunk. The LIST 'movi' chunk contains the data for the AVI sequence and is the second required LIST chunk. The 'idx1' chunk is the index chunk. AVI files must keep these three components in the proper sequence.

The LIST 'hdrl' and LIST 'movi' chunks use subchunks for their data. The following example shows the AVI RIFF form expanded with the chunks needed to complete the LIST 'hdrl' and LIST 'movi' chunks:

RIFF ('AVI '

       LIST ('hdrl'

             'avih'(<Main AVI Header>)

             LIST ('strl'

                   'strh'(<Stream header>)

                   'strf'(<Stream format>)

                   'strd'(additional header data)

                   'strn'(<Stream name>)

                   ...

             )

             .

             .

             .

   )

LIST ('movi'

             {SubChunk | LIST('rec '

                              SubChunk1

                              SubChunk2

                                 .

                                 .

                                 .

                         )

                 .

                 .

                 .

             }

        .

        .

        .

   )

   ['idx1'<AVIIndex>]

)

The following sections describe the chunks contained in the LIST 'hdrl' and LIST 'movi' chunks, as well as the 'idx1' chunk.


Data Structures for AVI Files

The reference section at the end of this main topic describes the data structures that can be used for the main AVI header, stream header, AVIIndex, and palette change chunks.


The Main AVI Header Chunk

The file begins with the main header. In the AVI file, this header is identified by the 'avih' four-character code. The header contains general information about the file, such as the number of streams within the file and the width and height of the AVI sequence. The main header has the following data structure defined for it:

typedef struct {

    DWORD  dwMicroSecPerFrame;

    DWORD  dwMaxBytesPerSec;

    DWORD  dwReserved1;

    DWORD  dwFlags;

    DWORD  dwTotalFrames;

    DWORD  dwInitialFrames;

    DWORD  dwStreams;

    DWORD  dwSuggestedBufferSize;

    DWORD  dwWidth;

    DWORD  dwHeight;

    DWORD  dwReserved[4];

} MainAVIHeader;

The dwMicroSecPerFrame member specifies the period between video frames. This value indicates the overall timing for the file.

The dwMaxBytesPerSec member specifies the approximate maximum data rate of the file. This value indicates the number of bytes per second the system must handle to present an AVI sequence as specified by the other parameters contained in the main header and stream header chunks.

The dwFlags member contains any flags for the file. The AVIF_HASINDEX, AVIF_MUSTUSEINDEX, AVIF_ISINTERLEAVED, AVIF_COPYRIGHTED, and AVIF_WASCAPTUREFILE flags are defined.

The AVIF_HASINDEX and AVIF_MUSTUSEINDEX flags apply to files with an index chunk. The AVIF_HASINDEX flag indicates an index is present. The AVIF_MUSTUSEINDEX flag indicates the index should be used to determine the order of the presentation of the data. When this flag is set, it implies the physical ordering of the chunks in the file does not correspond to the presentation order.

The AVIF_ISINTERLEAVED flag indicates the AVI file has been interleaved. The system can stream interleaved data from a CD-ROM more efficiently than non-interleaved data. For more information about interleaved files, see <arif_special>.

The AVIF_WASCAPTUREFILE flag indicates the AVI file is a specially allocated file used for capturing real-time video. Typically, capture files have been defragmented by the user so video capture data can be efficiently streamed into the file. If this flag is set, an application should warn the user before writing over the file.

The AVIF_COPYRIGHTED flag indicates the AVI file contains copyrighted data. When this flag is set, applications should not let users duplicate the file or the data in the file.

The dwTotalFrames member of the main header specifies the total number of frames of data in file.

The dwInitialFrames member is used for interleaved files. If you are creating interleaved files, specify the number of frames in the file prior to the initial frame of the AVI sequence in this member. For more information about the contents of this member, see <arif_special>.

The dwStreams member specifies the number of streams in the file. For example, a file with audio and video has two streams.

The dwSuggestedBufferSize member specifies the suggested buffer size for reading the file. Generally, this size should be large enough to contain the largest chunk in the file. If set to zero, or if it is too small, the playback software will have to reallocate memory during playback, which will reduce performance. For an interleaved file, the buffer size should be large enough to read an entire record, and not just a chunk.

The dwWidth and dwHeight members specify the width and height of the AVI file in pixels.


The Stream Header (strl) List Chunks
The Stream Header ('strl') List Chunks

The main header is followed by one or more 'strl' chunks. (A 'strl' chunk is required for each data stream.) These chunks contain information about the streams in the file. Each 'strl' chunk must contain a stream header and stream format chunk. Stream header chunks are identified by the four-character code 'strh' and stream format chunks are identified by the four-character code 'strf'. In addition to the stream header and stream format chunks, the 'strl' chunk might also contain a stream-header data chunk and a stream name chunk. Stream-header data chunks are identified by the four-character code 'strd'. Stream name chunks are identified by the four-character code 'strn'.

The stream header has the following data structure defined for it:

typedef struct {

    FOURCC  fccType;

    FOURCC  fccHandler;

    DWORD   dwFlags;

    WORD    wPriority;

    WORD    wLanguage;

    DWORD   dwInitialFrames;

    DWORD   dwScale;

    DWORD   dwRate;

    DWORD   dwStart;

    DWORD   dwLength;

    DWORD   dwSuggestedBufferSize;

    DWORD   dwQuality;

    DWORD   dwSampleSize;

} AVIStreamHeader;

The stream header specifies the type of data the stream contains, such as audio or video, by means of a four-character code. The fccType member is set to 'vids' if the stream it specifies contains video data. It is set to 'auds' if it contains audio data. It is set to 'txts' if it contains text data.

The fccHandler member contains a four-character code describing the stream handler for the data. For audio and video streams, this specifies the installable compressor or decompressor.

The dwFlags member contains any flags for the data stream. The AVISF_DISABLED flag indicates that the stream data should be rendered only when explicitly enabled by the user. The AVISF_VIDEO_PALCHANGES flag indicates palette changes are embedded in the file.

The dwInitialFrames member is used for interleaved files. If you are creating interleaved files, specify the number of frames in the file prior to the initial frame of the AVI sequence in this member. For more information about the contents of this member, see <arif_special>.

The remaining members describe the playback characteristics of the stream. These factors include the playback rate (dwScale and dwRate), the starting time of the sequence (dwStart), the length of the sequence (dwLength), the size of the playback buffer (dwSuggestedBuffer), an indicator of the data quality (dwQuality), and the sample size (dwSampleSize).

Some of the members in the stream header structure are also present in the main header structure. The data in the main header structure applies to the whole file, while the data in the stream header structure applies only to a stream.

A stream format ('strf') chunk must follow a stream header ('strh') chunk. The stream format chunk describes the format of the data in the stream. For video streams, the information in this chunk is a BITMAPINFO structure (including palette information if appropriate). For audio streams, the information in this chunk is a WAVEFORMATEX or PCMWAVEFORMAT structure. (The WAVEFORMATEX structure is an extended version of the WAVEFORMAT structure.) For more information about this structure and other stream types, see the New Multimedia Data Types and Data Techniques Standards Update.

The 'strl' chunk might also contain an additional stream-header data ('strd') chunk. If used, this chunk follows the stream format chunk. The format and content of this chunk is defined by installable compression or decompression drivers. Typically, drivers use this information for configuration. Applications that read and write RIFF files do not need to decode this information. They transfer this data to and from a driver as a memory block.

The optional 'strn' stream name chunk provides a zero-terminated text string describing the stream. (The AVIFile functions can use this chunk to let applications identify the steams they want to access by their names.)

An AVI player associates the stream headers in the LIST 'hdrl' chunk with the stream data in the LIST 'movi' chunk by using the order of the 'strl' chunks. The first 'strl' chunk applies to stream 0, the second applies to stream 1, and so forth. For example, if the first 'strl' chunk describes the wave audio data, the wave audio data is contained in stream 0. Similarly, if the second 'strl' chunk describes video data, then the video data is contained in stream 1.


Additional Header Data

After the 'strl' chunk, some AVI files might have additional header data. Additional information can include timecode chunks that apply to the whole file. The following timecode four-character codes are useful in AVI files:

Four-character code	Description
ISMP	Indicates the chunk contains the SMPTE timecode of the digitization starting point. The time is expressed as a zero-terminated text string of the form HH:MM:SS.FF. If performing MCI capture in AVICAP, this chunk is automatically set from the MCI start time.
IDIT	Indicates the chunk specifies the time and date digitizing commenced. This time is contained in an ASCII string of exactly 26 characters and has the format "Wed Jan 02 02:03:55 1990\n\0". The ctime and asctime functions can be used to create strings in this format.
The 'ISMP' timecode chunk usually corresponds to the starting timecode copied from the first sample of a captured sequence. Use this chunk to index the captured sample to the original sample. For example, if you need to recapture a video sequence, you can use the timecode to reposition the original sequence and restart capture from that point.

The 'IDIT' timecode chunk usually corresponds to the time the sample was captured. This timecode provides a reference to the age of a sample and creates a history if a series of samples is captured.


The LIST movi Chunk
The LIST 'movi' Chunk

Following the header information is a LIST 'movi' chunk that contains chunks of the actual data in the streams — that is, the pictures and sounds themselves. The data chunks can reside directly in the LIST 'movi' chunk or they might be grouped into 'rec ' chunks. The 'rec ' grouping implies that the grouped chunks should be read from disk all at once. This is used only for files specifically interleaved to play from CD-ROM.

Like any RIFF chunk, the data chunks contain a four-character code to identify the chunk type. The four-character code that identifies each chunk consists of the stream number and a two-character code that defines the type of information encapsulated in the chunk. For example, a waveform chunk is identified by a two-character code of 'wb'. If a waveform chunk corresponded to the second LIST 'hdrl' stream description, it would have a four-character code of '01wb'.

Note  While two-character codes are a convenient way to describe a stream, do not expect them to be recognized by other applications. Use four-character codes when creating a stream or transferring the information to other applications.

Because all the format information is in the header, the audio data contained in these data chunks does not contain any information about its format. An audio data chunk has the following format (the ## in the format represents the stream identifier):

WAVE  Bytes   '##wb'

      BYTE    abBytes[];

Video data can be compressed or uncompressed DIBs. An uncompressed DIB has BI_RGB specified for the biCompression member in its associated BITMAPINFO structure. A compressed DIB has a value other than BI_RGB specified in the biCompression member. For more information about compression formats, see the description of the BITMAPINFOHEADER data structure in <ch_dibfmt>.

A data chunk for an uncompressed DIB contains RGB video data. These chunks are identified by a two-character code of 'db' (db is an abbreviation for DIB bits). Data chunks for a compressed DIB are identified by a two-character code of 'dc' (dc is an abbreviation for DIB compressed). Neither data chunk will contain any header information about the DIBs. The data chunk for an uncompressed DIB has the following form:

DIB  Bits   '##db'

     BYTE   abBits[];

The data chunk for a compressed DIB has the following form:

Compressed DIB   '##dc'

     BYTE         abBits[];

Video data chunks can also define new palette entries used to update the palette during an AVI sequence. These chunks are identified by the two-character code 'pc' (pc is an abbreviation for palette change). The following data structure is defined for palette information:

typedef struct {

    BYTE          bFirstEntry;

    BYTE          bNumEntries;

    WORD          wFlags;

    PALETTEENTRY  peNew;

} AVIPALCHANGE;

The bFirstEntry member defines the first entry to change, and the bNumEntries member specifies the number of entries to change. The peNew member contains the new color entries.

If you include palette changes in a video stream, set the AVISF_VIDEO_PALCHANGES flag in the dwFlags member of the stream header. This flag indicates that this video stream contains palette changes and warns the playback software that it will need to animate the palette.

Text streams can use arbitrary two-character codes.


The idx1 Chunk
The 'idx1' Chunk

AVI files have an index chunk after the LIST 'movi' chunk. The index chunk contains a list of the data chunks and their locations in the file. This provides efficient random access to the data within the file, because an application can locate a particular sound sequence or video image in a large AVI file without having to scan it.

Index chunks use the four-character code 'idx1'. The following data structure is defined for index entries:

typedef struct {

    DWORD  ckid;

    DWORD  dwFlags;

    DWORD  dwChunkOffset;

    DWORD  dwChunkLength;

} AVIINDEXENTRY;

The ckid, dwFlags, dwChunkOffset, and dwChunkLength entries are repeated in the AVI file for each data chunk indexed. If the file is interleaved, the index will also have these entries for each 'rec ' chunk. The 'rec ' entries should have the AVIIF_LIST flag set and the list type in the ckid member.

The ckid member identifies the data chunk. This member uses four-character codes to identify the chunk.

The dwFlags member specifies any flags for the data. The AVIIF_KEYFRAME flag indicates key frames in the video sequence. Key frames do not need previous video information to be decompressed. The AVIIF_NOTIME flag indicates a chunk does not affect the timing of a video stream. For example, changing palette entries indicated by a palette chunk should occur between displaying video frames. Thus, if an application needs to determine the length of a video sequence, it should not use chunks with the AVIIF_NOTIME flag. In this case, it would ignore a palette chunk. The AVIIF_LIST flag indicates the current chunk is a LIST chunk. Use the ckid member to identify the type of LIST chunk.

The dwChunkOffset and dwChunkLength members specify the position of the chunk and the length of the chunk. The dwChunkOffset member specifies the position of the chunk in the file relative to the 'movi' list. The dwChunkLength member specifies the length of the chunk excluding the eight bytes for the RIFF header.

If you include an index in the RIFF file, set the AVIF_HASINDEX flag in the dwFlags member of the AVI header. (This header is identified by the 'avih' chunk code.)


Other Data Chunks

If you need to align data in your AVI file, you can add a 'JUNK' chunk. (This chunk is a standard RIFF type.) Applications reading these chunks ignore their contents. The 'JUNK' chunk has the following form:

AVI Padding   'JUNK'

    Byte      data[]

As with any other RIFF files, all applications that read AVI files should ignore the non-AVI chunks that they do not recognize. Applications that read and write AVI files should preserve the non-AVI chunks when they save files they have loaded.


Special Information for Interleaved Files

Files that are interleaved for playback from CD-ROM require some special handling. While they can be read similarly to any other AVI files, they require special care when produced.

The audio has to be separated into single-frame pieces, and audio and video for each frame needs to be grouped together into 'rec ' chunks. The record chunks should be padded so that their size is a multiple of 2 kilobytes, and so that the beginning of the actual data in the LIST chunk lies on a 2-kilobyte boundary in the file. (This implies that the LIST chunk itself begins 12 bytes before a 2-kilobyte boundary.)

Files played from CD-ROM might use 'JUNK' chunks to align data so they can be read more efficiently. You might want to use this chunk to align your data for the 2-kilobyte CD-ROM boundaries.

To give the audio driver enough audio to work with, the audio data has to be skewed from the video data. Typically, the audio data should be moved forward by enough frames to allow approximately 0.75 seconds of audio data to be preloaded. The dwInitialRecords member of the main header and the dwInitialFrames member of the audio stream header should be set to the number of frames the audio is skewed.

Additionally, you must ensure that the CD-ROM drive is capable of reading the data fast enough to support your AVI sequence. Non-MPC CD-ROM drives can have a data rate of less than 150 kilobytes per second.


Using VidEdit with AVI Files

VidEdit lets you create and edit audio-visual sequences consisting of a series of frames that contain digital audio and video data. You can use VidEdit to create and edit AVI files that contain one audio and one video stream. Each stream in the file must start at the beginning of the file (that is, the dwStart member in each stream header must be zero).


Using AVI File Structure

Like other RIFF files, AVI files are created with the mmioOpen, mmioCreateChunk, mmioWrite, mmioAscend, and mmioClose functions. These functions have the following descriptions:

Function	Description
mmioOpen	Opens a file for reading or writing, and returns a handle to the open file.
mmioCreateChunk	Creates a new chunk in a RIFF file.
mmioWrite	Writes a specified number of bytes to an open file.
mmioAscend	Ascends out of a RIFF file chunk to the next chunk in the file.
mmioClose	Closes an open file.
In addition to these functions, you can use mmioFOURCC to convert four individual characters into a four-character code. For more information about these functions and macros, see the Microsoft Win32 Programmer's Reference.

There are macro definitions for creating the two- and four-character codes described in this main topic. Also described are the aviTWOCC and TWOCCFromFOURCC macros. These macros create two-character codes from individual characters or from four-character codes.


An Outline for Writing AVI Files

Unlike many other RIFF files, AVI files use many nested chunks and subchunks. This makes them more complicated than most RIFF files. Use the tables in the following sections as a checklist to help you decide when to create a chunk, when to write data to a chunk, and when to ascend from a chunk. The tables do not include information about writing non-AVI data chunks to the file. The information in the Chunk column of the table mirrors the example in the "AVI RIFF Form" section, earlier in this main topic.


Creating the File and AVI  Chunk
Creating the File and 'AVI ' Chunk

The 'AVI ' chunk is the first chunk in the file. You will not ascend from this chunk until all other chunks have been created.

Chunk	How to handle
RIFF ('AVI '	Use mmioOpen to open the file. Seek to the beginning of the file with mmioSeek. Create the AVI chunk with mmioCreateChunk. (Use the 'AVI ' four-character code and the MMIO_CREATERIFF flag.) Do not ascend from this chunk in preparation for writing the remaining chunks.


Creating the LIST hdrl and avih Chunks
Creating the LIST 'hdrl' and 'avih' Chunks

The LIST 'hdrl' chunk contains the stream format header chunks. Because it contains other chunks, you will not ascend from it until the other header chunks are created.

The 'avih' chunk contains the main header list. This is written as a complete chunk.

Chunk	How to handle
LIST ('hdrl'	Create the LIST 'hdrl' chunk with mmioCreateChunk. (Use the 'hdrl' four-character code and the MMIO_CREATELIST flag.)
'avih'(<Main AVI Header>)	Create the main AVI header chunk with mmioCreateChunk. (Use the 'avih' four-character code.) Write the header information with mmioWrite. Ascend from the 'avih' chunk with mmioAscend. Do not ascend from the LIST 'hdrl' chunk.


Creating the strl, strh, strf, and strd Chunks
Creating the 'strl', 'strh', 'strf', and 'strd' Chunks

The 'strl', 'strh', 'strf', and 'strd' chunks are written as complete chunks. You write a set of the 'strh', 'strf', and 'strd' chunks for each stream in the file. After all the stream descriptions are written, you ascend from the LIST 'hdrl' chunk.

Chunk	How to handle
LIST ('strl'	Create the LIST 'strl' chunk with mmioCreateChunk. (Use the 'strl' four-character code and the MMIO_CREATELIST flag.)
'strh'(<Stream header>)	Create the stream header chunk with mmioCreateChunk. (Use the 'strh' four-character code.) Write the stream header information with mmioWrite. Ascend from the 'strh' chunk with mmioAscend.
'strf'(<Stream format>)	Create the stream format chunk with mmioCreateChunk. (Use the 'strf' four-character code.) Write the stream format information with mmioWrite. Ascend from the 'strf' chunk with mmioAscend.
'strd'(additional header data)	If needed, create chunks for any additional header data with mmioCreateChunk. (Use the 'strd' four-character code.) Write the additional header data with mmioWrite. Ascend from the 'strd' chunk.
'strn'(<stream name>)	If needed, create chunks for the stream name with mmioCreateChunk. (Use the 'strn' four-character code.) Write the stream name with mmioWrite. Ascend from the 'strd' chunk.
.           .           .	If needed, add stream header, stream format, and additional header data chunks for other streams in the file.
)	Ascend from the LIST 'strl' chunk with mmioAscend.
.     .     . )	Ascend from the LIST 'hdrl' chunk with mmioAscend. If needed, create and write padding chunks or other data chunks.


Creating the LIST movi and rec  Chunks
Creating the LIST 'movi' and 'rec ' Chunks

The LIST 'movi' chunk contains other chunks. After you create this chunk, you will not ascend from it until the other chunks are written.

You can write the data as an individual chunk or as part of a 'rec ' chunk. Like the LIST 'movi' chunk, you will not ascend from a 'rec ' chunk until you write all of its subchunks.

Chunk	How to handle
LIST ('movi'	Create the LIST 'movi' chunk with mmioCreateChunk. (Use the 'movi' four-character code and the MMIO_CREATELIST flag.)
{ SubChunk |   LIST('rec '   SubChunk1   SubChunk2      .      .      .    )    .     .    .    }    .    .    .	You can add your movie data directly at this point in a subchunk or include it in a 'rec ' chunk.  Create a data chunk with mmioCreateChunk. (Use the four-character code appropriate for the data chunk and stream.) If you are adding an index chunk to the end of the file, save the location of the subchunks for it.
)	Ascend from the LIST 'movi' chunk.


Creating the idx1 Chunk and Ascending from the AVI  Chunk
Creating the 'idx1' Chunk and Ascending from the 'AVI ' Chunk

The optional index chunk is written as a complete chunk. After you have completed this chunk, you can ascend from the 'AVI ' chunk and close the file.

Chunk	How to handle
['idx1'<AVIIndex>]	If used, create the AVI index chunk with mmioCreateChunk. (Use the 'idx1' four-character code.) Write the index information with mmioWrite. Ascend from the 'idx1' chunk with mmioAscend. Although 'idx1' is the last chunk used in an AVI sequence, you can add non-AVI chunks after it. These subchunks will still be part of the 'AVI ' chunk.
)	Ascend from the 'AVI ' chunk with mmioAscend. Close the file with mmioClose.


AVI RIFF File Macros


Macros to Create Two- and Four-Character Codes

The following macros create two- and four-character codes from individual characters.

Macro	Description
mmioFOURCC(ch0, ch1, ch2, ch3)	Creates a four-character code from the characters ch0, ch1, ch2, and ch3. For example: fcc = mmioFOURCC('h', 'd', 'r', 'l')
aviTWOCC(ch0, ch1)	Creates a two-character code from the characters ch0 and ch1. For example: tcc = aviTWOCC('w', 'b')


Macros to Create Four-Character Codes Used in AVI Files

The following macros create the four-character codes used in AVI files.

Macro	Description
formtypeAVI	Creates the four-character code 'AVI ' for an AVI file.
listtypeAVIHEADER	Creates the four-character code 'hdrl' for the AVI header list chunk.
ckidAVIMAINHDR	Creates the four-character code 'avih' for the AVI main header chunk.
listtypeSTREAMHEADER	Creates the four-character code 'strl' for the AVI stream header list chunk.
ckidSTREAMHEADER	Creates the four-character code 'strh' for an AVI stream header chunk.
ckidSTREAMFORMAT	Creates the four-character code 'strf' for an AVI stream format chunk.
ckidSTREAMHANDLERDATA	Creates the four-character code 'strd' for an AVI stream-header data chunk.
ckidSTREAMNAME	Creates the four-character code 'strn' for an AVI stream name.
listtypeAVIMOVIE	Creates the four-character code 'movi' for an AVI movie chunk.
listtypeAVIRECORD	Creates the four-character code 'rec ' for an AVI record chunk.
ckidAVINEWINDEX	Creates the four-character code 'idx1' for an AVI index chunk.
ckidAVIPADDING	Creates the four-character code 'JUNK' to identify a padding chunk.
The following macros create the four-character code identifying the stream type that is used in the fccType member of the stream header.

Macro	Description
streamtypeVIDEO	Creates the four-character code 'vids' to identify a video stream format.
streamtypeAUDIO	Creates the four-character code 'auds' to identify an audio stream format.
streamtypeTEXT	Creates the four-character code 'txts' to identify a text stream format.


Macros to Create Two-Character Codes Used in AVI Files

The following macros create two-character codes corresponding to the data contained in data chunks. The data chunks in a AVI file are identified by a four-character code containing the stream number in addition to the information contained in these two-character codes.

Macro	Description
cktypeDIBbits	Creates the two-character code 'db' to identify a DIB data chunk.
cktypeDIBcompressed	Creates the two-character code 'dc' to identify compressed DIB data chunk.
cktypePALchange	Creates the two-character code 'pc' to identify a palette data chunk.
cktypeWAVEbytes	Creates the two-character code 'wb' to identify a wave data chunk.


Macros to Convert Between Two- and Four-Character Codes

The following macros extract information from a four-character code and create a four-character code from a two-character code and stream number.

Macro	Description
TWOCCFromFOURCC(fcc)	Extracts the two-character code from the four-character code fcc.
StreamFromFOURCC(fcc)	Extracts the stream number from the four-character code fcc.
MAKEAVICKID(tcc, stream)	Creates a four-character code from the two-character code tcc and stream number stream. The stream number can range from 0 to 255.


Reference

This section contains an alphabetical list of the structures used to support AVI RIFF files.

For information about	See this data structure
The main AVI file header	MainAVIHeader
The stream header	AVIStreamHeader
The AVI indexes	AVIINDEXENTRY
Changing AVI palettes	AVIPALCHANGE


AVIINDEXENTRY

The AVI file index consists of an array of AVIINDEXENTRY structures contained within an 'idx1' chunk at the end of an AVI file. This chunk follows the main LIST 'movi' chunk, which contains the actual data.

typedef struct {

    DWORD  ckid;

    DWORD  dwFlags;

    DWORD  dwChunkOffset;

    DWORD  dwChunkLength;

} AVIINDEXENTRY;

ckid

Specifies a four-character code corresponding to the chunk ID of a data chunk in the file.

dwFlags

Specifies any applicable flags. The flags in the low-order word are reserved for AVI, while those in the high-order word can be used for stream-specific and compressor-decompressor-specific information.

The following values are currently defined:

AVIIF_LIST

Indicates the specified chunk is a 'LIST' chunk, and the ckid member contains the list type of the chunk.

AVIIF_KEYFRAME

Indicates this chunk is a key frame. Key frames do not require additional preceding chunks to be properly decoded.

AVIIF_NOTIME

Indicates this chunk should have no effect on timing or calculating time values based on the number of chunks. For example, palette change chunks in a video stream should have this flag set so they are not counted as taking up a frame's worth of time.

AVIIF_COMPUSE

Indicates the data is used by a compressor. The data is compressor-dependent.

dwChunkOffset

Specifies the position in the file of the specified chunk. The position value includes the 8-byte RIFF header.

dwChunkLength

Specifies the length of the specified chunk. The length value does not include the 8-byte RIFF header.


AVIPALCHANGE

The AVIPALCHANGE structure is used in video streams containing palettized data to indicate the palette should change for subsequent video data.

typedef struct {

    BYTE  bFirstEntry;

    BYTE  bNumEntries;

    WORD  wFlags;

    PALETTEENTRY  peNew[];

} AVIPALCHANGE;

bFirstEntry

Specifies the first palette entry to change.

bNumEntries

Specifies the number of entries to change.

wFlags

Reserved. (This should be set to 0.)

peNew[ ]

Specifies an array of new palette entries.


AVIStreamHeader

The AVIStreamHeader structure contains header information for a single stream of a file. It is contained within a 'strh' chunk within a LIST 'strl' chunk that is itself contained within the LIST 'hdrl' chunk at the beginning of an AVI RIFF file.

typedef struct {

    FOURCC  fccType;

    FOURCC  fccHandler;

    DWORD   dwFlags;

    WORD    wPriority;

    WORD    wLanguage;

    DWORD   dwInitialFrames;

    DWORD   dwScale;

    DWORD   dwRate;

    DWORD   dwStart;

    DWORD   dwLength;

    DWORD   dwSuggestedBufferSize;

    DWORD   dwQuality;

    DWORD   dwSampleSize;

    RECT    rcFrame

} AVIStreamHeader;

fccType

Contains a four-character code that specifies the type of data contained in the stream. The following values are currently defined for AVI data:

'vids'

Indicates the stream contains video data. The stream format chunk contains a BITMAPINFO structure that can include palette information.

'auds'

Indicates the stream contains video data. The stream format chunk contains a WAVEFORMAT or PCMWAVEFORMAT structure.

'txts'

Indicates the stream contains text data.

Other four-character codes can identify non-AVI data.

fccHandler

Optionally, contains a four-character code that identifies a specific data handler. The data handler is the preferred handler for the stream.

dwFlags

Specifies any applicable flags. The bits in the high-order word of these flags are specific to the type of data contained in the stream. The following flags are currently defined:

AVISF_DISABLED

Indicates this stream should not be enabled by default.

AVISF_VIDEO_PALCHANGES

Indicates this video stream contains palette changes. This flag warns the playback software that it will need to animate the palette.

wPriority

Specifies priority of a stream type. For example, in a file with multiple audio streams, the one with the highest priority might be the default stream.

wLanguage

Specifies the language of the stream.

dwInitialFrames

Specifies how far audio data is skewed ahead of the video frames in interleaved files. Typically, this is about 0.75 seconds.

dwScale

This member is used together with dwRate to specify the time scale that this stream will use.

Dividing dwRate by dwScale gives the number of samples per second.

For video streams, this rate should be the frame rate.

For audio streams, this rate should correspond to the time needed for nBlockAlign bytes of audio, which for PCM audio simply reduces to the sample rate.

dwRate

See dwScale.

dwStart

Specifies the starting time of the AVI file. The units are defined by the dwRate and dwScale members in the main file header. Usually, this is zero, but it can specify a delay time for a stream that does not start concurrently with the file.

dwLength

Specifies the length of this stream. The units are defined by the dwRate and dwScale members of the stream's header.

dwSuggestedBufferSize

Suggests how large a buffer should be used to read this stream. Typically, this contains a value corresponding to the largest chunk present in the stream. Using the correct buffer size makes playback more efficient. Use zero if you do not know the correct buffer size.

dwQuality

Specifies an indicator of the quality of the data in the stream. Quality is represented as a number between 0 and 10000. For compressed data, this typically represents the value of the quality parameter passed to the compression software. If set to −1, drivers use the default quality value.

dwSampleSize

Specifies the size of a single sample of data. This is set to zero if the samples can vary in size. If this number is non-zero, then multiple samples of data can be grouped into a single chunk within the file. If it is zero, each sample of data (such as a video frame) must be in a separate chunk.

For video streams, this number is typically zero, although it can be non-zero if all video frames are the same size.

For audio streams, this number should be the same as the nBlockAlign member of the WAVEFORMAT structure describing the audio.

rcFrame

Specifies the destination rectangle for a text or video stream within the movie rectangle specified by the dwWidth and dwHeight members of the MainAVIHeader structure. The rcFrame member is typically used in support of multiple video streams. Set this rectangle to the coordinates corresponding to the movie rectangle to update the whole movie rectangle. Units for this member are pixels. The upper-left corner of the destination rectangle is relative to the upper-left corner of the movie rectangle.


MainAVIHeader

The MainAVIHeader structure contains global information for the entire AVI file. It is contained within an 'avih' chunk within the LIST 'hdrl' chunk at the beginning of an AVI RIFF file.

typedef struct {

    DWORD  dwMicroSecPerFrame;

    DWORD  dwMaxBytesPerSec;

    DWORD  dwPaddingGranularity;

    DWORD  dwFlags;

    DWORD  dwTotalFrames;

    DWORD  dwInitialFrames;

    DWORD  dwStreams;

    DWORD  dwSuggestedBufferSize;

    DWORD  dwWidth;

    DWORD  dwHeight;

    DWORD  dwReserved[4];

} MainAVIHeader;

dwMicroSecPerFrame

Specifies the number of microseconds between frames.

dwMaxBytesPerSec

Specifies the approximate maximum data rate of a file.

dwPaddingGranularity

Specifies the chunk size created when a chunk is padded. Padding is used to maintain boundary alignment on CD-ROM. Usually, this is set to 2048.

dwFlags

Specifies any applicable flags. The following flags are defined:

AVIF_HASINDEX

Indicates the AVI file has an 'idx1' chunk containing an index at the end of the file. For good performance, all AVI files should contain an index.

AVIF_MUSTUSEINDEX

Indicates that the index, rather than the physical ordering of the chunks in the file, should be used to determine the order of presentation of the data. For example, this could be used for creating a list of frames for editing.

AVIF_ISINTERLEAVED

Indicates the AVI file is interleaved.

AVIF_WASCAPTUREFILE

Indicates the AVI file is a specially allocated file used for capturing real-time video. Applications should warn the user before writing over a file with this flag set because the user probably defragmented this file.

AVIF_COPYRIGHTED

Indicates the AVI file contains copyrighted data and software. When this flag is used, software should not permit the data to be duplicated.

dwTotalFrames

Specifies the number of frames of data in file.

dwInitialFrames

Specifies the initial frame for interleaved files. Non-interleaved files should specify zero.

dwStreams

Specifies the number of streams in the file. For example, a file with audio and video has two streams.

dwSuggestedBufferSize

Specifies the suggested buffer size for reading the file. Generally, this size should be large enough to contain the largest chunk in the file. If set to zero, or if it is too small, the playback software will have to reallocate memory during playback, which will reduce performance.

For an interleaved file, this buffer size should be large enough to read an entire record, and not just a chunk.

dwWidth

Specifies the width of the AVI file in pixels.

dwHeight

Specifies the height of the AVI file in pixels.

dwReserved[4]

Reserved. Set this array to zero.