OS/2 Multimedia Chapter – Multimedia Input/Output

by Maria Ingold

X.8 MULTIMEDIA INPUT/OUTPUT

Programmers of multimedia applications want to view images, hear audio, or watch movies without being concerned about how the data bytes are laid out in the file, or what storage media is holding these data bytes. The Multimedia Input/Output (MMIO) file services isolate applications, media control drivers, and stream handlers from these file format and storage system details. This means that as far as the application is concerned, access to files stored in memory, on CD-ROM, hard drive, diskette, or across a network, can all be accessed and manipulated transparently. The Multimedia I/O provides an application with a consistent set of interfaces for different file formats, storage systems and compression types. As shown in Figure X.8, the MMIO manager provides format independence by using installable I/O procedures (IOProcs) and CODEC procedures.

MMIO Subsystem Architecture

Figure X.8 MMIO Subsystem Architecture

IOProcs and CODEC procedures can be used to extend the capabilities of the Multimedia I/O subsystem. A simple example of this is when a new image format comes into use, a new IOProc for that format can be installed, and the Multimedia I/O will automatically take advantage of it. An IOProc is a Ring 3 DLL that performs operations on a specific data object or file type. Each IOProc is uniquely identified by a four-character code (FOURCC). IOProcs are divided into two types: storage system IOProcs and file format IOProcs.

X.8.1 Storage System IOProcs

A storage system IOProc operates on the storage mechanism used to contain the data rather than the data content itself. This type of IOProc “unwraps” data objects such as Resource Interchange File Format (RIFF) files, or RIFF compound files (CF). The storage system IOProc does not know what type of data is contained inside the wrapper. For example, the file may be contained in a DOS wrapper. The file format IOProc would call the storage system IOProc which would use DosOpen, DosRead, DosWrite and DosClose to unwrap the data. Inside it might contain wave or image file data which the file format IOProc would then process. Storage system IOProcs include the internal IOProcs provided for DOS files, memory (MEM) files, and RIFF compound files.

X.8.1.1 Resource Interchange File Format

RIFF is the standard format used for storing multimedia files. RIFF allows audio, image, animation, video, and other multimedia elements to be stored in a common format. This ensures portability of the file. RIFF files are composed of chunks. A RIFF chunk is a block of data identified by a FOURCC chunk id, or tag. The tag indicates the type of data that is contained in the chunk. For example, in a RIFF AVI file, the ‘movi’ tag says that the following data chunk contains audio and video tracks . The advantage of tagged file formats is that they allow an application to process only the blocks of data it is interested in. Additionally, by adding new tags, RIFF files can be easily extended without breaking existing applications.

A FOURCC tag can be created by using the mmioFOURCC function to convert four alphanumeric characters into the code. If less than four characters are specified, mmioFOURCC pads the end with blanks. A null terminated sting can also be converted into a FOURCC by using mmioStringToFOURCC.

RIFF chunks can be created, located, entered, and exited. A RIFF chunk is created by specifying mmioCreateChunk. This creates a new chunk at the current position in the open file. To process chunk data, the chunk is entered, or descended into, using the mmioDescend function. The mmioDescend function can also locate chunks. Before another chunk can be processed, the current chunk must be exited, or ascended out of, by using mmioAscend. RIFF files can be opened, read from, and written to the same way as other file types using the MMIO APIs.

X.8.1.1.1 Compound Files

A RIFF compound file, or a bundle file (BND), can hold one or many file elements. A file element can be an entire RIFF file, a non RIFF file, an arbitrary RIFF chunk, or arbitrary binary data. A RIFF compound file contains a resource group (CGRP) chunk, and a table of contents (CTOC) chunk. The CGRP chunk contains all of the compound file elements concatenated together into one contiguous block of data. The CTOC chunk provides the location, name, and other information about the individual compound file elements contained in the CGRP.

There are two IOProcs that operate on compound files: the compound file IOProc and the bundle IOProc. The compound file IOProc is a storage system IOProc. It operates on the entire compound file rather than on the elements in the file. This IOProc is limited to operations required by the system to ensure storage system transparency at the application level. The bundle IOProc is a file format IOProc. It performs operations on the file elements themselves. There are a special set of MMIO functions that are used to manipulate compound files. See Table X.10 for a complete list of all the compound file functions.

MMIO Compound File Function Description
mmioCFOpen Opens a RIFF compound file by name
mmioCFClose Closes an open RIFF compound file
mmioCFGetInfo Retrieves CTOC header of an open RIFF compound file
mmioCFSetInfo Modifies information stored in CTOC
mmioCFAddEntry Adds entry to CTOC of open RIFF compound file
mmioCFChangeEntry Changes a CTOC entry in an open RIFF compound file
mmioCFFindEntry Finds a CTOC entry in an open RIFF compound file
mmioCFDeleteEntry Deletes a CTOC entry from an open RIFF compound file
mmioCFAddElement Adds element to CGRP of an open RIFF compound file
mmioCFCopy Copies CTOC and CGRP to another RIFF compound file
mmioCFCompact Removes elements marked as deleted
mmioFindElement Enumerates entries of a compound file
mmioRemoveElement Removes specified element from a compound file

Table X.10 MMIO Compound File Functions

X.8.2 File Format IOProcs

File format IOProcs manipulate different multimedia element types such as audio, image, or MIDI. Each file format IOProc handles the specific element type for which it was written. For example, there are separate IOProcs to handle AVI video, AutoDesk animation, OS/2 2.0 bitmaps, and RIFF Waveform digital audio. For a complete list of the file formats provided with OS/2 multimedia see Table X.11.

File Format IOProc FOURCC
AIFF Wave Digital Audio AIFF
Amiga IFF Format IFF
Creative Labs Inc. Voice Audio VOC
IBM Audio Visual Connection (AVC) ADPCM Digital Audio AVCA
RIFF Waveform Digital Audio WAVE
Unix (NeXT/SUN) SND Format SND
Musical Instrument Digital Interface (MIDI) MIDI, RMID
GIF (Graphics Interchange Format) Image Compressed GIFC
IBM Audio Visual Connection (AVC) Still Video Image AVCI
IBM M-Motion Still Video Image MMOT
IBM OS/2 1.3 Bitmap OS13
IBM OS/2 2.0 Bitmap OS20
Kodak PhotoCD PCD
MS Windows Device Independent Bitmap (DIB) W130
PCX (PC Paintbrush) Image Compressed PCXC
RIFF Device Independent Bitmap (RDIB) RDIB
Targa Image Compressed TGAC
Targa Image Uncompressed TGAU
TIFF (Tagged Interchange File Format) FAX Compressed TFFC
TIFF Intel Compressed TFIC
TIFF Intel Uncompressed TFIU
TIFF Motorola Compressed TFMC
TIFF Motorola Uncompressed TFMU
Autodesk Animation (FLI/FLC) FLIC
Audio Video Interleaved (AVI) Video AVI
Motion Pictures Expert Group (MPEG) MPEG

Table X.11 OS/2 Multimedia Provided File Format IOProcs

Additional IOProcs can be installed into the system and immediately taken advantage of by existing applications. An IOProc can be installed temporarily, semipermanently, or permanently. An IOProc DLL is temporarily installed by loading the DLL using the DosLoadModule and DosQueryProcAddr functions, and then calling mmioOpen to open a file and associate it with that IOProc. To install an IOProc semipermanently requires changing the IOProc table managed by the MMIO manager for the current application. The mmioInstallIOProc function maintains and modifies this table. This table exists separately for each application that uses MMIO. This means that IOProcs that are added or changed in one application can not be used by other applications. The IOProc is available until the application process terminates, or the IOProc is removed from the table. An IOProc can be permanently installed and used by all applications by storing information about the IOProc in the OS/2 multimedia MMIO initialization file (MMPMMMIO.INI). The mmioIniFileHandler function is used to do this installation.

X.8.3 CODEC Procedures

MMIO also provides the ability to compress and decompress data through the use of compression/decompression (CODEC) procedures. Like I/O procedures, CODEC procedures are DLL routines that operate on data within a file or buffer. CODECs are typically loaded by a file format IOProc to compress or decompress the data. OS/2 multimedia provides a set of set of CODECs for the compression of audio and video data. See Table X.12 for details. Additional CODEC procedures can only be permanently installed into the initialization file using the mmioIniFileCODEC function. An existing CODEC can also be replaced provided that the name of the entry point and the FOURCC are the same as the original.

CODEC FOURCC
Ultimotion Video Decompressor ULTI
Indeo Video 2.1 Compressor/Decompressor rt21/RT21
Indeo 3.1/3.2 Decompressor iv31/IV31/iv32/IV32
Ultimotion Video Real-time Compressor ULTI
Ultimotion Video Frame-step Compressor ULTI
Intel Video 3.1 Real-time Compressor IV31
Intel Video 3.1 Frame-step Compressor IV31
MONDO Uncompressed Video Playback DIB
Autodesk Animation (FLI/FLC) Playback flic
Motion Picture Expert Group (MPEG) Hardware Interface MPEG
MS ADPCM Audio Compressor/Decompressor N/A
IMA ADPCM Audio Compressor/Decompressor N/A

Table X.12 OS/2 Multimedia Provided CODECs

X.8.4 The AVI File Format

The Ultimotion and Indeo CODECs store their data in the standard Audio Video Interleaved (AVI) Resource Interchange File Format (RIFF). See Figure X.9. The AVI RIFF format is identified by the FOURCC (four character code) ‘AVI ‘. Note that in the case of the ‘AVI ‘ FOURCC, the last character is padded with a blank. This format includes a header, ‘hdrl’, which lists details about the movie. The main AVI header, ‘avih’, contains the movie size and the number of audio and video tracks, or streams. The stream header, ‘strl’, specifies whether the track contains audio, ‘auds’, or video, ‘vids’. It also contains the FOURCC of the decompression algorithm. For example, ‘ULTI’ represents the decompressor for Ultimotion. The stream format, ‘strf’, contains the bitmap and audio structures for each track. The optional decompressor header data, ‘strd’, contains the configuration information specific to that decompressor. Following the AVI header, in ‘movi’, are the audio and video tracks. The optional index, ‘idx1’, lists the location of the track data within the file. This is useful for random access of the data.

RIFF ('AVI'
     LIST ('hdrl';
          'avih'(<Main AVI Header>)
          LIST ('strl'
                'strl'(<Stream header>)
                'strf'(<Stream format>)
                'strd'(additional header data)
                . . .
               )
          . . .
          )
          LIST ('movi'
               {SubChunk | LIST ('rec'
                                 SubChunk1
                                 SubChunk2
                                 . . .
                                 )
                      . . .
               }
                . . .
               )
      ['idx1'<AVIIndex>]
      )

Figure X.9 The AVI RIFF file format

X.8.5 Translating File Formats

Each media type has a specific standard format. The media types that are currently supported include PCM digital audio, MIDI, image, digital video, and multitrack audio and video movies. The standard format provides a superset of all of the information that can be expected for that particular media type. Each specific format then stores and uses its subset of that information.

MMIO allows an IOProc to access files in both their untranslated native format, or in a translated standard format. When a file is untranslated, all of the file manipulations are done in its native format. In a translated file, all of the descriptive and data information stored in the original file is presented in a standardized format. The file manipulations then use this standard format.

If two IOProcs of the same media type store their data in the standard format, file conversion between the two files is very easy. The file is simply loaded in one format and saved into the other. For example, to convert a PhotoCD image into a device independent bitmap, the PhotoCD image is loaded and translated into the standard image format by the PhotoCD IOProc, and then written to the device independent bitmap IOProc with translation enabled.

X.8.6 Unbuffered and Buffered I/O

Applications or Media Control Drivers can use unbuffered I/O or buffered I/O to handle I/O operations. The mmioOpen call is used to open a file for either buffered or unbuffered I/O. Unbuffered I/O is best in the case of data streaming since the Synchronization Streaming Manager provides its own internal buffers to process the data. When an application accesses a media device, it may need to perform numerous I/O operations. If the amount of data transferred in I/O operations is small (less than 4 KB in size) it is best to use buffered I/O. With buffered file I/O, the file system maintains a buffer cache that stores data as it is read from or written to a secondary storage device. Since the data is already in the buffer, the file system can transfer the buffer to the application without having to read the data sector again from the device. Lowering the number of secondary storage device accesses improves the performance of the application.

The buffer used for buffered I/O can be supplied by the MMIO manager or provided by the application. If the MMIO supplied buffer is used, then reading, writing, and seeking of the data is performed the same way as for unbuffered I/O. This is accomplished by respectively using the mmioRead, mmioWrite, and mmioSeek function calls. When writing is done using buffered I/O, the mmioFlush function should be called to make sure that the contents of the buffer are written to disk. The mmioClose call performs this flush automatically when it closes a file.

If an application is performance sensitive it may chose to supply and directly access its own buffer. The application can specify its buffer on an mmioOpen call or use mmioSetBuffer function. Applications use mmioGetInfo to access the buffer. All read and write operations are done through the mmioAdvance call. No other MMIO function calls can be made until the mmioSetInfo function is called indicating that direct access of the file buffer has ended.

X.8.7 MMIO Functions

See Table X.13 for a list of all the MMIO function calls. (This list excludes the RIFF compound file functions listed in Table X.10.)

MMIO Functions Description
mmioOpen Opens or creates file for reading, writing, or both
mmioRead Reads specified number of bytes from open file
mmioWrite Writes specified number of bytes to open file
mmioSeek Changes current position for reading, writing, or both
mmioClose Closes an open file
mmioFlush Writes or empties the I/O buffer out to disk
mmioSetBuffer Enables or disables buffered I/O
mmioGetInfo Retrieves information and allows direct access to I/O buffer
mmioAdvance Fills and empties the contents of a direct access I/O buffer
mmioSetInfo Changes information on the file I/O buffer
mmioInstallIOProc Installs, removes, or finds an IOProc in MMIO IOProc table
mmioIniFileHandler Adds, replaces, removes, or finds entry in ini file
mmioSendMessage Sends a message to IOProc associated with the open file
mmioIniFileCODEC Adds, replaces, removes, or finds CODEC entry in ini file
mmioQueryCODECName Returns associated CODEC proc name
mmioQueryCODECNameLength Returns associated CODEC proc name length
mmioLoadCODECProc Loads the installed CODEC proc
mmioSet Sets or queries extended file information and CODEC proc
mmioFOURCC Converts four characters to a four character code
mmioStringToFOURCC Converts a null terminated string to a four character code
mmioCreateChunk Creates a chunk in an open RIFF file
mmioAscend Moves the file position to the end of the chunk
mmioDescend Descends into a chunk of an open RIFF file
mmioGetHeader Returns header of the media structure of the open file
mmioSetHeader Sets attributes of the media in an open file
mmioQueryHeaderLength Determines the size of header for the open file
mmioGetFormats Lists the formats supported by the currently installed IOProc
mmioGetFormatName Returns the format name associated with the IOProc
mmioQueryFormatCount Provides the number of IOProcs that match the format data
mmioIdentifyFile Determines the file format and its associated loaded IOProc
mmioIdentifyStorageSystem Determines storage system and IOProc associated with file
mmioDetermineSSIOProc Determines storage system and FOURCC of media object
mmioQueryIOProcModuleHandle Provides module handle of an IOProc
mmioGetLastError Returns the last error condition

Table X.13 MMIO Functions