Previous | Contents | Index |
This section presents the video compression and decompression return values or error codes. Table 5-2 lists the codes that can be returned by one or more of the video compression and decompression functions.
Error Code | Description |
---|---|
ICERR_OK | Success. |
ICERR_BADHANDLE | The handle is invalid. |
ICERR_BADIMAGESIZE | The specified image size is invalid. |
ICERR_BADPARAM | The value is invalid or out of range. |
ICERR_CANTUPDATE | The value cannot be updated. |
ICERR_ERROR | A palette has not been negotiated. |
ICERR_UNSUPPORTED | The function is unsupported. |
This chapter presents the multimedia file I/O services available to
applications. An application uses file I/O services in conjunction with
other multimedia functions to create, read, and write disk files that
store audio and video data.
6.1 Multimedia File I/O Services Overview
Multimedia file I/O services currently provide unbuffered file I/O and
support for standard IBM and Microsoft Resource Interchange File Format
(RIFF) files. Most multimedia applications need only basic file I/O
services and RIFF file I/O services.
6.2 Multimedia File I/O Data Structures
The function prototypes, constants, flags, and data structures that
applications can use to access the multimedia file I/O services are
defined in the
mme_api.h
header file provided with Multimedia Services for OpenVMS. Include this
header file in all application programs that use multimedia file I/O
functions.
6.2.1 MMCKINFO Data Structure
The mmioAscend , mmioCreateChunk , and mmioDescend functions use the MMCKINFO data structure to specify and retrieve information about RIFF chunks. A chunk is the basic building block of a RIFF file. (See Section 8.1 for more information.)
Example 6-1 shows the MMCKINFO data structure definition.
Example 6-1 MMCKINFO Data Structure Definition |
---|
typedef struct _MMCKINFO { FOURCC ckid; /* chunk ID */ DWORD cksize; /* chunk size */ FOURCC fccType; /* form type or list type */ DWORD dwDataOffset; /* offset of data part of chunk */ DWORD dwFlags; /* flags used by MMIO functions */ } MMCKINFO; |
The MMCKINFO data structure has the following fields:
ckid
Indicates the chunk ID of the chunk.
cksize
Indicates the size in bytes of the data portion of the chunk. The data
size includes the form type or list type (if any) but does not include
the 8-byte chunk header or the pad byte at the end of the data.
fccType
Indicates the form type if
MMCKINFO.ckid
is
RIFF
or the list type if
MMCKINFO.ckid
is
LIST
. Otherwise, it is NULL.
dwDataOffset
Indicates the file offset at the beginning of the data portion of the
chunk. If it is a
RIFF
or
LIST
chunk, then
MMCKINFO.dwDataOffset
is the offset of the form or list type.
dwFlags
Contains other information about the chunk. Currently, this information
is not used and is set to zero.
6.3 Multimedia File Format
The preferred format for multimedia files is RIFF, which is a tagged-file structure.
Multimedia Services for OpenVMS reads the following types of RIFF files:
See Chapter 8 for more detailed information about multimedia file formats.
The following functions provide support for file I/O to RIFF files:
mmioAscend
mmioCreateChunk
mmioDescend
mmioFOURCC
mmioStringToFOURCC
These functions work with the basic unbuffered file I/O services; you
can open, read, and write RIFF files in the same way as other files.
See Section 6.6 for specific information about these functions.
6.4 Performing Basic File I/O
Using the basic I/O services is similar to using the C run-time file I/O services. Files must be opened before they can be read or written. After a read or write operation, the file must be closed. An application can change the current read/write location by seeking in an open file. The basic file I/O functions are:
mmioClose
mmioFlush
mmioOpen
mmioRead
mmioRename
mmioSeek
mmioWrite
These file I/O functions provide the core of the multimedia file I/O
services. See Table 6-1 for more information about the basic I/O
functions. See Section 6.6 for specific information about each
function.
6.4.1 Opening a File
Before doing any I/O operations, open a file using the mmioOpen function. The mmioOpen function returns a file handle. Use the handle to identify the open file when calling other file I/O functions.
When opening a file, specify whether the file is being opened for reading, writing, or both reading and writing. Use the dwFlags argument of the mmioOpen function to specify options for opening a file.
See the description of the
mmioOpen
function in Section 6.6 for more information.
6.4.2 Creating and Deleting a File
To create a new file, specify the MMIO_CREATE flag with the mmioOpen function. To delete a file, specify the MMIO_DELETE flag with the mmioOpen function.
See the description of the
mmioOpen
function in Section 6.6 for more information.
6.4.3 Reading and Writing a File
To read and write to open files, use the mmioRead and mmioWrite functions. Each of these functions takes an HMMIO file handle, a pointer to a buffer, and a parameter specifying the number of bytes to read or write. If a buffer is to be used by other Multimedia Services for OpenVMS functions, allocate it using the mmeAllocMem or the mmeAllocBuffer function, as appropriate.
See the descriptions of the
mmioRead
and
mmioWrite
functions in Section 6.6 for more information.
6.4.4 Seeking a New Position in a File
The current position or file pointer in a file is the location where
the next read or write operation will occur. Change the current
position in an open file using the
mmioSeek
function. See the description of the
mmioSeek
function in Section 6.6 for more information.
6.4.5 Generating Four-Character Codes
A four-character code is a 32-bit quantity representing a sequence of one to four ASCII alphanumeric characters, and is padded on the right with blank characters. The data type for a four-character code is FOURCC.
Use the
mmioStringToFOURCC
function to convert a null-terminated string to a four-character code.
You can also use the
mmioFOURCC
macro to convert four characters to a four-character code. See the
descriptions of the
mmioStringToFOURCC
and
mmioFOURCC
functions in Section 6.6 for more information about generating
four-character codes.
6.4.6 Creating RIFF Chunks
To create a new chunk, use the mmioCreateChunk function to write a chunk header at the current position in an open file.
If creating a RIFF or LIST chunk, specify the form type in the fccType field of the MMCKINFO data structure. If the size of the data field in a new chunk is known, set the cksize field in the MMCKINFO data structure when the chunk is created. This value is written to the data size field in the new chunk. If this value is incorrect and the application calls the mmioAscend function, the value is rewritten automatically to reflect the correct size of the data field.
After you create a new chunk using the
mmioCreateChunk
function, the file position is set to the data field of the chunk (8
bytes from the beginning of the chunk). If the chunk is a
RIFF
or
LIST
chunk, the file position is set to the location following the form type
or list type (12 bytes from the beginning of the chunk).
6.4.7 Navigating RIFF Files
RIFF files consist of nested chunks of data. Multimedia file I/O services include two functions used to navigate between chunks in a RIFF file: the mmioAscend function and the mmioDescend function. Consider these functions as high-level seek functions. When an application descends into a chunk, the file position is set to the data field of the chunk (8 bytes from the beginning of the chunk). For RIFF and LIST chunks, the file position is set to the location following the form type or list type (12 bytes from the beginning of the chunk). When an application ascends from a chunk, the file position is set to the location following the end of the chunk.
See the descriptions of the
mmioAscend
and
mmioDescend
functions in Section 6.6 for more information about navigating RIFF
files.
6.4.8 RIFF File I/O
Example 6-2 shows how to open a RIFF file for buffered I/O and how to descend into, ascend from, and read RIFF chunks.
Example 6-2 RIFF File I/O: Playing a WAVE File Backwards |
---|
#include <mme/mme_api.h> /* ReversePlay--Plays a WAVE waveform audio file backwards */ void ReversePlay() { char szFileName[128]; /* filename of file to open */ HMMIO hmmio; /* file handle for open file */ MMCKINFO mmckinfoParent; /* parent chunk info structure */ MMCKINFO mmckinfoSubchunk; /* subchunk info structure */ DWORD dwFmtSize; /* size of (fmt) chunk */ DWORD dwDataSize; /* size of (data) chunk */ WAVEFORMAT * pFormat /* ptr to memory for (fmt) chunk */ HPSTR lpData; /* ptr to memory for (data) chunk */ /* Get the filename from the edit control */ ... /* Open the file */ if ( !(hmmio = mmioOpen(szFileName, NULL, MMIO_READ)) ) { printf("Could not open file %s\n", szFileName); return; } /* Locate a "RIFF" chunk with a "WAVE" form type */ /* to make sure the file is a WAVE file */ mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E'); if (mmioDescend(hmmio, (LPMMCKINFO) &mmckinfoParent, NULL, MMIO_FINDRIFF)){ printf("This is not a WAVE file."); mmioClose(hmmio, 0); return; } /* Find the "fmt" chunk (form type "fmt "); it must be * a subchunk of the "RIFF" parent chunk */ mmckinfoSubchunk.ckid = mmioFOURCC ('f', 'm', 't', ' '); if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK)){ printf("WAVE file has no \"fmt \" chunk."); mmioClose(hmmio, 0); return; } /* Get the size of the "fmt " chunk--allocate memory for it */ dwFmtSize = mmckinfoSubchunk.cksize; pFormat = (WAVEFORMAT *)malloc(mmckinfoSubchunk.cksize); /* Read the "fmt " chunk */ if (mmioRead(hmmio, (HPSTR) pFormat, dwFmtSize) != dwFmtSize){ printf("Failed to read format chunk."); mmioClose(hmmio, 0); return; } /* Ascend out of the "fmt " subchunk */ mmioAscend(hmmio, &mmckinfoSubchunk,0); /* Find the data subchunk. The current file position should be at the * beginning of the data chunk, however, you should not make this * assumption--use mmioDescend to locate the data chunk. */ mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, MMIO_FINDCHUNK)){ printf("Wave file has no data chunk."); mmioClose(hmmio, 0); return; } /* Get the size of the data subchunk */ dwDataSize = mmckinfoSubchunk.cksize; if (dwDataSize == 0L){ printf("the data chunk contains no data."); mmioClose(hmmio, 0); return; } /* Open a waveform output device */ ... /* Allocate memory for the waveform data */ lpData = (HPSTR)mmeAllocBuffer(dwDataSize); /* Read the waveform data subchunk */ if(mmioRead(hmmio, (HPSTR) lpData, dwDataSize) != dwDataSize){ printf("Failed to read data chunk."); mmioClose(hmmio, 0); return; } /* Close the file */ mmioClose(hmmio, 0); /* Reverse the sound and play it */ ... } |
Table 6-1 provides a summary of the multimedia file I/O functions.
Application Function | Description |
---|---|
Functions for performing basic file I/O: | |
mmioClose | Closes an open file |
mmioFlush | Flushes pending output to a file |
mmioOpen | Opens a file for reading, writing, or both and returns a handle to the open file |
mmioRead | Reads a specified number of bytes from a file opened with the mmioOpen function |
mmioRename | Renames a file |
mmioSeek | Changes the current position for reading, writing, or both to an open file |
mmioWrite | Writes a specified number of bytes to an open file |
Functions for supporting file I/O to RIFF files: | |
mmioAscend | Ascends from a RIFF file chunk to the next chunk in the file |
mmioCreateChunk | Creates a new chunk in a RIFF file |
mmioDescend | Descends into a RIFF file chunk beginning at the current file position or searches for a specified chunk |
mmioFOURCC | Converts four characters into a four-character code |
mmioStringToFOURCC | Converts a null-terminated string into a four-character code |
This section contains an alphabetical listing of the functions you can use to write applications that manage multimedia file I/O. These functions are prefixed with mmio.
#include <mme/mme_api.h> MMRESULT APIENTRY mmioAscend(HMMIO hmmio, LPMMCKINFO lpck, UINT uFlags); |
LPMMCKINFO lpck
Specifies a pointer to an MMCKINFO data structure
identifying a chunk. The function ascends to the location following the
end of this chunk.
The MMCKINFO data structure must be allocated with the mmeAllocMem function before being passed to the mmioAscend function. See Chapter 2 for more information about the memory allocation functions.
UINT uFlags
Not used, set to zero (0).
The mmioAscend function ascends from a RIFF chunk to the next chunk in the file. If the chunk was descended into using the mmioDescend function, then the mmioAscend function seeks to the location following the end of the chunk (past the extra pad byte, if any).Extensions None.The file position is assumed to be the end of the data portion of the chunk if the chunk was created and descended into using the mmioCreateChunk function, or if the MMIO_DIRTY flag is set in the dwFlags field of the MMCKINFO data structure referenced by the lpck argument.
If the chunk size is not the same as the value stored in the cksize field when the mmioCreateChunk function was called, then the mmioAscend function corrects the chunk size in the file before ascending from the chunk. If the chunk size is odd, the mmioAscend function writes a null pad byte at the end of the chunk. After ascending from the chunk, the current file position is the location following the end of the chunk (past the extra pad byte, if any).
Returns MMSYSERR_NOERROR if the function is successful; otherwise, it returns one of the following error codes:
Error Code | Description |
---|---|
MMIOERR_CANNOTWRITE | The contents of the buffer could not be written to disk. |
MMIOERR_CANNOTSEEK | An error occurred while seeking to the end of the file. |
#include <mme/mme_api.h> MMRESULT APIENTRY mmioClose(HMMIO hmmio, UINT uFlags); |
UINT uFlags
Specifies options for the close operation. The following flag is
defined:
MMIO_FHOPEN
Indicates that if a OpenVMS file handle of a previously opened file is passed to the mmioOpen function, the mmioClose function is to close the MMIO file handle but not the OpenVMS file handle.
The mmioClose function closes a file opened with the mmioOpen function. If the file is not opened with the mmioOpen function, the mmioClose function does not close it.Extensions None.
Returns MMSYSERR_NOERROR if the function is successful; otherwise, it returns the following error code:
Error Code | Description |
---|---|
MMIOERR_CANNOTWRITE | The contents of the buffer could not be written to disk. |
Previous | Next | Contents | Index |