windows-nt/Source/XPSP1/NT/multimedia/media/avi/mciavi32/aviffmt.h
2020-09-26 16:20:57 +08:00

530 lines
20 KiB
C

/****************************************************************************/
/* */
/* AVIFFMT.H - Include file for working with AVI files */
/* */
/* Note: You must include WINDOWS.H and MMSYSTEM.H before */
/* including this file. */
/* */
/* Copyright (c) 1991-1992, Microsoft Corp. All rights reserved. */
/* */
/****************************************************************************/
/*
*
* An AVI file is the following RIFF form:
*
* RIFF('AVI'
* LIST('hdrl'
* avih(<MainAVIHeader>)
* LIST ('strl'
* strh(<Stream header>)
* strf(<Stream format>)
* ... additional header data
* LIST('movi'
* { LIST('rec'
* SubChunk...
* )
* | SubChunk } ....
* )
* [ <AVIIndex> ]
* )
*
* The first two characters of each chunk are the track number.
* SubChunk = { xxdh(<AVI DIB header>)
* | xxdb(<AVI DIB bits>)
* | xxdc(<AVI compressed DIB bits>)
* | xxpc(<AVI Palette Change>)
* | xxwb(<AVI WAVE bytes>)
* | xxws(<AVI Silence record>)
* | xxmd(<MIDI data>)
* | additional custom chunks }
*
*/
/*
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* We need a better description of the AVI file header here.
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
* The grouping into LIST 'rec' chunks implies only that the contents of
* the chunk should be read into memory at the same time. This
* grouping is only necessary for interleaved files.
*
* For loading efficiency, the beginning of each LIST 'rec' chunk may
* be aligned on a 2K boundary. (Actually, the beginning of the LIST
* chunk should be 12 bytes before a 2K boundary, so that the data chunks
* inside the LIST chunk are aligned.)
*
* If the AVI file is being played from CD-ROM in, it is recommended that
* the file be padded.
*
* Limitations for the Alpha release:
* If the AVI file has audio, each record LIST must contain exactly
* one audio chunk, which must be the first chunk.
* Each record must contain exactly one video chunk (possibly preceded
* by one or more palette change chunks).
* No wave format or DIB header chunks may occur outside of the header.
*/
#ifndef _INC_AVIFFMT
#define _INC_AVIFFMT
#ifndef RC_INVOKED
#pragma pack(1) /* Assume byte packing throughout */
#endif /* RC_INVOKED */
#ifndef mmioFOURCC
#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \
( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) | \
( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) )
#endif
/* Macro to make a TWOCC out of two characters */
#ifndef aviTWOCC
#define aviTWOCC(ch0, ch1) ((WORD)(BYTE)(ch0) | ((WORD)(BYTE)(ch1) << 8))
#endif
typedef WORD TWOCC;
/* form types, list types, and chunk types */
#define formtypeAVI mmioFOURCC('A', 'V', 'I', ' ')
#define listtypeAVIHEADER mmioFOURCC('h', 'd', 'r', 'l')
#define ckidAVIMAINHDR mmioFOURCC('a', 'v', 'i', 'h')
#define listtypeSTREAMHEADER mmioFOURCC('s', 't', 'r', 'l')
#define ckidSTREAMHEADER mmioFOURCC('s', 't', 'r', 'h')
#define ckidSTREAMFORMAT mmioFOURCC('s', 't', 'r', 'f')
#define ckidSTREAMHANDLERDATA mmioFOURCC('s', 't', 'r', 'd')
#define listtypeAVIMOVIE mmioFOURCC('m', 'o', 'v', 'i')
#define listtypeAVIRECORD mmioFOURCC('r', 'e', 'c', ' ')
#define ckidAVINEWINDEX mmioFOURCC('i', 'd', 'x', '1')
/*
** Here are some stream types. Currently, only audio and video
** are supported.
*/
#define streamtypeVIDEO mmioFOURCC('v', 'i', 'd', 's')
#define streamtypeAUDIO mmioFOURCC('a', 'u', 'd', 's')
#define streamtypeMIDI mmioFOURCC('m', 'i', 'd', 's')
#define streamtypeTEXT mmioFOURCC('t', 'x', 't', 's')
/*
** Here are some compression types.
*/
#define comptypeRLE0 mmioFOURCC('R','L','E','0')
#define comptypeRLE mmioFOURCC('R','L','E',' ')
#define comptypeDIB mmioFOURCC('D','I','B',' ')
#define cktypeDIBbits aviTWOCC('d', 'b')
#define cktypeDIBcompressed aviTWOCC('d', 'c')
#define cktypeDIBhalf aviTWOCC('d', 'x')
#define cktypePALchange aviTWOCC('p', 'c')
#define cktypeWAVEbytes aviTWOCC('w', 'b')
#define cktypeWAVEsilence aviTWOCC('w', 's')
#define cktypeMIDIdata aviTWOCC('m', 'd')
#define cktypeDIBheader aviTWOCC('d', 'h')
#define cktypeWAVEformat aviTWOCC('w', 'f')
#define ckidAVIPADDING mmioFOURCC('J', 'U', 'N', 'K')
#define ckidOLDPADDING mmioFOURCC('p', 'a', 'd', 'd')
/*
** Useful macros
*/
#define ToHex(n) ((BYTE) (((n) > 9) ? ((n) - 10 + 'A') : ((n) + '0')))
#define FromHex(n) (((n) >= 'A') ? ((n) + 10 - 'A') : ((n) - '0'))
/* Macro to get stream number out of a FOURCC ckid */
#define StreamFromFOURCC(fcc) ((WORD) ((FromHex(LOBYTE(LOWORD(fcc))) << 4) + \
(FromHex(HIBYTE(LOWORD(fcc))))))
/* Macro to get TWOCC chunk type out of a FOURCC ckid */
#define TWOCCFromFOURCC(fcc) HIWORD(fcc)
/* Macro to make a ckid for a chunk out of a TWOCC and a stream number
** from 0-255.
**
** Warning: This is a nasty macro, and MS C 6.0 compiles it incorrectly
** if optimizations are on. Ack.
*/
#define MAKEAVICKID(tcc, stream) \
MAKELONG((ToHex((stream) & 0x0f) << 8) | ToHex(((stream) & 0xf0) >> 4), tcc)
/*
** Main AVI File Header
*/
/* flags for use in <dwFlags> in AVIFileHdr */
#define AVIF_HASINDEX 0x00000010 // Index at end of file?
#define AVIF_MUSTUSEINDEX 0x00000020
#define AVIF_ISINTERLEAVED 0x00000100
#define AVIF_VARIABLESIZEREC 0x00000200
#define AVIF_NOPADDING 0x00000400
#define AVIF_WASCAPTUREFILE 0x00010000
#define AVIF_COPYRIGHTED 0x00020000
/* The AVI File Header LIST chunk should be padded to this size */
#define AVI_HEADERSIZE 2048 // size of AVI header list
/*****************************************************************************
* @doc EXTERNAL AVI_FFMT
*
* @types MainAVIHeader | The <t 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.
*
* @field DWORD | dwMicroSecPerFrame | Specifies the number of
* microseconds between frames.
*
* @field DWORD | dwMaxBytesPerSec | Specifies the approximate
* maximum data rate of file.
*
* @field DWORD | dwReserved1 | Reserved. (This field should be set to 0.)
*
* @field DWORD | dwFlags | Specifies any applicable flags.
* The following flags are defined:
*
* @flag 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.
*
* @flag 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 frames for editing.
*
* @flag AVIF_ISINTERLEAVED | Indicates
* the AVI file is interleaved.
*
* @flag 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.
*
* @flag 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.
*
* @field DWORD | dwTotalFrames | Specifies the number of
* frames of data in file.
*
* @field DWORD | dwInitialFrames | Specifies the initial frame
* for interleaved files. Non-interleaved files should specify
* zero.
*
* @field DWORD | dwStreams | Specifies the number of streams in the file.
* For example, a file with audio and video has 2 streams.
*
* @field DWORD | 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.
*
* @field DWORD | dwWidth | Specifies the width of the AVI file in pixels.
*
* @field DWORD | dwHeight | Specifies the height of the AVI file in pixels.
*
* @field DWORD | dwScale | This field is used with
* <e MainAVIHeader.dwRate> to specify the time scale that
* applies to the AVI file. In addition, each stream
* can have its own time scale.
*
* Dividing <e MainAVIHeader.dwRate> by <e AVIStreamHeader.dwScale>
* gives the number of samples per second.
*
* @field DWORD | dwRate | See <e MainAVIHeader.dwScale>.
*
* @field DWORD | dwStart | Specifies the starting time of the AVI file.
* The units are defined by <e MainAVIHeader.dwRate> and
* <e MainAVIHeader.dwScale>. This field is usually set to zero.
*
* @field DWORD | dwLength | Specifies the length of the AVI file.
* The units are defined by <e AVIStreamHeader.dwRate> and
* <e AVIStreamHeader.dwScale>. This length is returned by MCIAVI when
* using the frames time format.
*
****************************************************************************/
typedef struct
{
DWORD dwMicroSecPerFrame; // frame display rate (or 0L)
DWORD dwMaxBytesPerSec; // max. transfer rate
DWORD dwPaddingGranularity; // pad to multiples of this
// size; normally 2K.
DWORD dwFlags; // the ever-present flags
DWORD dwTotalFrames; // # frames in file
DWORD dwInitialFrames;
DWORD dwStreams;
DWORD dwSuggestedBufferSize;
DWORD dwWidth;
DWORD dwHeight;
/* Do we want the stuff below for the whole movie, or just
** for the individual streams?
*/
DWORD dwScale;
DWORD dwRate; /* dwRate / dwScale == samples/second */
DWORD dwStart; /* Is this always zero? */
DWORD dwLength; /* In units above... */
} MainAVIHeader;
/*
** Stream header
*/
/* !!! Do we need to distinguish between discrete and continuous streams? */
#define AVISF_DISABLED 0x00000001
#define AVISF_VIDEO_PALCHANGES 0x00010000
/* Do we need identity palette support? */
/*****************************************************************************
* @doc EXTERNAL AVI_FFMT
*
* @types AVIStreamHeader | The <t AVIStreamHeader> structure contains
* header information for a single stream of an file. It is contained
* within an 'strh' chunk within a LIST 'strl' chunk that is itself
* contained within the LIST 'hdrl' chunk at the beginning of
* an AVI RIFF file.
*
* @field FOURCC | fccType | Contains a four-character code which specifies
* the type of data contained in the stream. The following values are
* currently defined:
*
* @flag 'vids' | Indicates the stream contains video data. The stream
* format chunk contains a <t BITMAPINFO> structure which can include
* palette information.
*
* @flag 'auds' | Indicates the stream contains video data. The stream
* format chunk contains a <t WAVEFORMATEX> or <t PCMWAVEFORMAT>
* structure.
*
* New data types should be registered with the <MI>Multimedia Developer
* Registration Kit<D>.
*
* @field FOURCC | fccHandler | Contains a four-character code that
* identifies a specific data handler.
*
* @field DWORD | 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:
*
* @flag AVISF_DISABLED | Indicates
* this stream should not be enabled by default.
*
* @flag AVISF_VIDEO_PALCHANGES | Indicates
* this video stream contains palette changes. This flag warns
* the playback software that it will need to animate the
* palette.
*
* @field DWORD | dwReserved1 | Reserved. (Should be set to 0.)
*
* @field DWORD | dwInitialFrames | Reserved for interleaved files.
* (Set this to 0 for non-interleaved files.)
*
* @field DWORD | dwScale | This field is used together with
* <e AVIStreamHeader.dwRate> to specify the time scale that
* this stream will use.
*
* Dividing <e AVIStreamHeader.dwRate> by <e AVIStreamHeader.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
* <e WAVEFORMATEX.nBlockAlign> bytes of audio, which for PCM audio simply
* reduces to the sample rate.
*
* @field DWORD | dwRate | See <e AVIStreamHeader.dwScale>.
*
* @field DWORD | dwStart | Specifies the starting time of the AVI file.
* The units are defined by the
* <e MainAVIHeader.dwRate> and <e MainAVIHeader.dwScale> fields
* in the main file header. Normally, this is zero, but it can
* specify a delay time for a stream which does not start concurrently
* with the file.
*
* Note: The 1.0 release of the AVI tools does not support a non-zero
* starting time.
*
* @field DWORD | dwLength | Specifies the length of this stream.
* The units are defined by the
* <e AVIStreamHeader.dwRate> and <e AVIStreamHeader.dwScale>
* fields of the stream's header.
*
* @field DWORD | 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.
*
* @field DWORD | 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 represent the value of the quality parameter
* passed to the compression software.
*
* @field DWORD | 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
* <e WAVEFORMATEX.nBlockAlign> field of the <t WAVEFORMATEX> structure
* describing the audio.
*
****************************************************************************/
typedef struct {
FOURCC fccType;
FOURCC fccHandler;
DWORD dwFlags; /* Contains AVITF_* flags */
WORD wPriority;
WORD wLanguage;
DWORD dwInitialFrames;
DWORD dwScale;
DWORD dwRate; /* dwRate / dwScale == samples/second */
DWORD dwStart;
DWORD dwLength; /* In units above... */
// new....
DWORD dwSuggestedBufferSize;
DWORD dwQuality;
DWORD dwSampleSize;
RECT rcFrame; /* does each frame need this? */
/* additional type-specific data goes in StreamInfo chunk */
/* For video: position within rectangle... */
/* For audio: volume? stereo channel? */
} AVIStreamHeader;
typedef struct {
RECT rcFrame;
} AVIVideoStreamInfo;
typedef struct {
WORD wLeftVolume; // !!! Range?
WORD wRightVolume;
DWORD dwLanguage; // !!! Is there a standard representation of this?
} AVIAudioStreamInfo;
#define AVIIF_LIST 0x00000001L // chunk is a 'LIST'
#define AVIIF_TWOCC 0x00000002L // ckid is a TWOCC?
#define AVIIF_KEYFRAME 0x00000010L // this frame is a key frame.
#define AVIIF_FIRSTPART 0x00000020L // this frame is the start of a partial frame.
#define AVIIF_LASTPART 0x00000040L // this frame is the end of a partial frame.
#define AVIIF_MIDPART (AVIIF_LASTPART|AVIIF_FIRSTPART)
#define AVIIF_NOTIME 0x00000100L // this frame doesn't take any time
#define AVIIF_COMPUSE 0x0FFF0000L // these bits are for compressor use
/*****************************************************************************
* @doc EXTERNAL AVI_FFMT
*
* @types AVIINDEXENTRY | The AVI file index consists of an array
* of <t 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.
*
* @field DWORD | ckid | Specifies a four-character code corresponding
* to the chunk ID of a data chunk in the file.
*
* @field DWORD | 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- and compressor/decompressor-specific information.
*
* The following values are currently defined:
*
* @flag AVIIF_LIST | Indicates the specified
* chunk is a 'LIST' chunk, and the <e AVIINDEXENTRY.ckid>
* field contains the list type of the chunk.
*
* @flag AVIIF_KEYFRAME | Indicates this chunk
* is a key frame. Key frames do not require
* additional preceding chunks to be properly decoded.
*
* @flag 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 that they are not counted
* as taking up a frame's worth of time.
*
* @field DWORD | dwChunkOffset | Specifies the position in the file of the
* specified chunk. The position value includes the eight byte RIFF header.
*
* @field DWORD | dwChunkLength | Specifies the length of the
* specified chunk. The length value does not include the eight
* byte RIFF header.
*
****************************************************************************/
typedef struct
{
DWORD ckid;
DWORD dwFlags;
DWORD dwChunkOffset; // Position of chunk
DWORD dwChunkLength; // Length of chunk
} AVIINDEXENTRY;
/*
** Palette change chunk
**
** Used in video streams.
*/
typedef struct
{
BYTE bFirstEntry; /* first entry to change */
BYTE bNumEntries; /* # entries to change (0 if 256) */
WORD wFlags; /* Mostly to preserve alignment... */
PALETTEENTRY peNew[]; /* New color specifications */
} AVIPALCHANGE;
/*****************************************************************************
* @doc EXTERNAL AVI_FFMT
*
* @types AVIPALCHANGE | The <t AVIPALCHANGE> structure is used in
* video streams containing palettized data to indicate the
* palette should change for subsequent video data.
*
* @field BYTE | bFirstEntry | Specifies the first palette entry to change.
*
* @field BYTE | bNumEntries | Specifies the number of entries to change.
*
* @field WORD | wFlags | Reserved. (This should be set to 0.)
*
* @field PALETTEENTRY | peNew | Specifies an array of new palette entries.
*
****************************************************************************/
#ifndef RC_INVOKED
#pragma pack() /* Revert to default packing */
#endif /* RC_INVOKED */
#endif /* INC_AVIFFMT */