DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/aviwriter/avi.h
00001 /*
00002  *  Copyright (C) 2018-2020 Jon Campbell
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License along
00015  *  with this program; if not, write to the Free Software Foundation, Inc.,
00016  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00019 #ifndef __VIDEOMGR_UTIL_AVI_H
00020 #define __VIDEOMGR_UTIL_AVI_H
00021 
00022 #include <stdint.h>
00023 
00024 #include "informational.h"
00025 #include "wave_mmreg.h"
00026 #include "waveformatex.h"
00027 #include "bitmapinfoheader.h"
00028 #include "riff.h"
00029 
00030 #if defined(_MSC_VER)
00031 # pragma pack(push,1)
00032 #endif
00033 
00034 /* typedef for an AVI FOURCC */
00035 typedef uint32_t avi_fourcc_t;
00036 
00037 /* take chars and form them into an AVI FOURCC (little endian byte order) */
00038 #define avi_fourcc_const(a,b,c,d)       ( (((uint32_t)(a)) << 0U) | (((uint32_t)(b)) << 8U) | (((uint32_t)(c)) << 16U) | (((uint32_t)(d)) << 24U) )
00039 
00040 /* common AVI FOURCCs */
00041 #define avi_riff_AVI                    avi_fourcc_const('A','V','I',' ')
00042 #define avi_riff_movi                   avi_fourcc_const('m','o','v','i')
00043 #define avi_riff_hdrl                   avi_fourcc_const('h','d','r','l')
00044 #define avi_riff_idx1                   avi_fourcc_const('i','d','x','1')
00045 #define avi_riff_indx                   avi_fourcc_const('i','n','d','x')
00046 #define avi_riff_avih                   avi_fourcc_const('a','v','i','h')
00047 #define avi_riff_strl                   avi_fourcc_const('s','t','r','l')
00048 #define avi_riff_strh                   avi_fourcc_const('s','t','r','h')
00049 #define avi_riff_strf                   avi_fourcc_const('s','t','r','f')
00050 #define avi_riff_vprp                   avi_fourcc_const('v','p','r','p')
00051 #define avi_riff_dmlh                   avi_fourcc_const('d','m','l','h')
00052 #define avi_riff_odml                   avi_fourcc_const('o','d','m','l')
00053 
00054 #define avi_fccType_audio               avi_fourcc_const('a','u','d','s')
00055 #define avi_fccType_video               avi_fourcc_const('v','i','d','s')
00056 #define avi_fccType_iavs                avi_fourcc_const('i','a','v','s')
00057 
00058 /* AVI file struct: AVIMAINHEADER */
00059 /* AVI placement in file:
00060  * 
00061  * RIFF:AVI
00062  *   LIST:hdrl
00063  *     avih            <------- *HERE* usually first chunk in hdrl list
00064  *   LIST:strl
00065  *     strh
00066  *     strf
00067  * ...
00068  */
00069 typedef struct {                                                /* (sizeof) (offset hex) (offset dec) */
00070         /* NTS: The first two fields defined in Microsoft's SDK headers are not repeated here, because
00071          *      they are effectively the AVI RIFF chunk header, which most of our code does not include
00072          *      as part of the read (why did you do that, Microsoft?) */
00073         /* FOURCC       fcc */
00074         /* uint32_t     cb */
00075         uint32_t _Little_Endian_        dwMicroSecPerFrame;     /* (4)  +0x00 +0 */
00076         uint32_t _Little_Endian_        dwMaxBytesPerSec;       /* (4)  +0x04 +4 */
00077         uint32_t _Little_Endian_        dwPaddingGranularity;   /* (4)  +0x08 +8 */
00078         uint32_t _Little_Endian_        dwFlags;                /* (4)  +0x0C +12 */
00079         uint32_t _Little_Endian_        dwTotalFrames;          /* (4)  +0x10 +16 */
00080         uint32_t _Little_Endian_        dwInitialFrames;        /* (4)  +0x14 +20 */
00081         uint32_t _Little_Endian_        dwStreams;              /* (4)  +0x18 +24 */
00082         uint32_t _Little_Endian_        dwSuggestedBufferSize;  /* (4)  +0x1C +28 */
00083         uint32_t _Little_Endian_        dwWidth;                /* (4)  +0x20 +32 */
00084         uint32_t _Little_Endian_        dwHeight;               /* (4)  +0x24 +36 */
00085         uint32_t _Little_Endian_        dwReserved[4];          /* (16) +0x28 +40 */
00086 } GCC_ATTRIBUTE(packed) riff_avih_AVIMAINHEADER;                /* (56) =0x38 =56 */
00087 
00088 #define riff_avih_AVIMAINHEADER_flags_HASINDEX                          0x00000010UL
00089 #define riff_avih_AVIMAINHEADER_flags_MUSTUSEINDEX                      0x00000020UL
00090 #define riff_avih_AVIMAINHEADER_flags_ISINTERLEAVED                     0x00000100UL
00091 #define riff_avih_AVIMAINHEADER_flags_TRUSTCKTYPE                       0x00000800UL
00092 #define riff_avih_AVIMAINHEADER_flags_WASCAPTUREFILE                    0x00010000UL
00093 #define riff_avih_AVIMAINHEADER_flags_COPYRIGHTED                       0x00020000UL
00094 
00095 /* AVI file struct: AVISTREAMHEADER */
00096 /* AVI placement in file:
00097  * 
00098  * RIFF:AVI
00099  *   LIST:hdrl
00100  *     avih
00101  *   LIST:strl         <------- one LIST per AVI stream
00102  *     strh            <------- *HERE* usually first chunk in strl list
00103  *     strf
00104  * ...
00105  */
00106 typedef struct {                                                /* (sizeof) (offset hex) (offset dec) */
00107         /* NTS: The first two fields defined in Microsoft's SDK headers are not repeated here, because
00108          *      they are effectively the AVI RIFF chunk header, which most of our code does not include
00109          *      as part of the read (why did you do that, Microsoft?) */
00110         /* FOURCC       fcc */
00111         /* uint32_t     cb */
00112         avi_fourcc_t _Little_Endian_    fccType;                /* (4)  +0x00 +0 */
00113         avi_fourcc_t _Little_Endian_    fccHandler;             /* (4)  +0x04 +4 */
00114         uint32_t _Little_Endian_        dwFlags;                /* (4)  +0x08 +8 */
00115         uint16_t _Little_Endian_        wPriority;              /* (2)  +0x0C +12 */
00116         uint16_t _Little_Endian_        wLanguage;              /* (2)  +0x0E +14 */
00117         uint32_t _Little_Endian_        dwInitialFrames;        /* (4)  +0x10 +16 */
00118         uint32_t _Little_Endian_        dwScale;                /* (4)  +0x14 +20 */
00119         uint32_t _Little_Endian_        dwRate;                 /* (4)  +0x18 +24 */
00120         uint32_t _Little_Endian_        dwStart;                /* (4)  +0x1C +28 */
00121         uint32_t _Little_Endian_        dwLength;               /* (4)  +0x20 +32 */
00122         uint32_t _Little_Endian_        dwSuggestedBufferSize;  /* (4)  +0x24 +36 */
00123         uint32_t _Little_Endian_        dwQuality;              /* (4)  +0x28 +40 */
00124         uint32_t _Little_Endian_        dwSampleSize;           /* (4)  +0x2C +44 */
00125         struct {
00126                 int16_t _Little_Endian_ left;                   /* (2)  +0x30 +48 */
00127                 int16_t _Little_Endian_ top;                    /* (2)  +0x32 +50 */
00128                 int16_t _Little_Endian_ right;                  /* (2)  +0x34 +52 */
00129                 int16_t _Little_Endian_ bottom;                 /* (2)  +0x36 +54 */
00130         } GCC_ATTRIBUTE(packed) rcFrame;
00131 } GCC_ATTRIBUTE(packed) riff_strh_AVISTREAMHEADER;              /* (56) +0x38 +56 */
00132 
00133 static const riff_strh_AVISTREAMHEADER riff_strh_AVISTREAMHEADER_INIT = {
00134         0,
00135         0,
00136         0,
00137         0,
00138         0,
00139         0,//uint32_t        dwInitialFrames;
00140         0,//uint32_t        dwScale;
00141         0,//uint32_t        dwRate;
00142         0,//uint32_t        dwStart;
00143         0,//uint32_t        dwLength;
00144         0,//uint32_t        dwSuggestedBufferSize;
00145         0,//uint32_t        dwQuality;
00146         0,//uint32_t        dwSampleSize;
00147         { 0,0,0,0 }
00148 };
00149 
00150 #define riff_strh_AVISTREAMHEADER_flags_DISABLED                        0x00000001UL
00151 #define riff_strh_AVISTREAMHEADER_flags_VIDEO_PALCHANGES                0x00010000UL
00152 
00153 /* AVIPALCHANGE */
00154 typedef struct {
00155         uint8_t         bFirstEntry;
00156         uint8_t         bNumEntries;
00157         uint16_t        wFlags;
00158         /* PALETTEENTRY[] */
00159 } GCC_ATTRIBUTE(packed) riff_AVIPALCHANGE_header;
00160 
00161 /* AVI palette entry */
00162 typedef struct {
00163         uint8_t         peRed,peGreen,peBlue,peFlags;
00164 } GCC_ATTRIBUTE(packed) riff_AVIPALCHANGE_PALETTEENTRY;
00165 
00166 #define riff_AVIPALCHANGE_PALETTEENTRY_flags_PC_RESERVED                0x01U
00167 #define riff_AVIPALCHANGE_PALETTEENTRY_flags_PC_EXPLICIT                0x02U
00168 #define riff_AVIPALCHANGE_PALETTEENTRY_flags_PC_NOCOLLAPSE              0x04U
00169 
00170 /* AVIOLDINDEX (one element of the structure) */
00171 typedef struct {
00172         uint32_t        dwChunkId;
00173         uint32_t        dwFlags;
00174         uint32_t        dwOffset;
00175         uint32_t        dwSize;
00176 } GCC_ATTRIBUTE(packed) riff_idx1_AVIOLDINDEX;
00177 
00178 /* AVIOLDINDEX chunk IDs. NOTE that this chunk ID makes the last two bytes of dwChunkId (the upper 16 bits) */
00179 /* NOTICE due to little Endian byte order the string is typed in reverse here */
00180 #define riff_idx1_AVIOLDINDEX_chunkid_type_mask                         0xFFFF0000UL
00181 #define riff_idx1_AVIOLDINDEX_chunkid_stream_index_mask                 0x0000FFFFUL
00182 #define riff_idx1_AVIOLDINDEX_chunkid_uncompressed_videoframe           avi_fourcc_const(0,0,'d','b')
00183 #define riff_idx1_AVIOLDINDEX_chunkid_compressed_videoframe             avi_fourcc_const(0,0,'d','c')
00184 #define riff_idx1_AVIOLDINDEX_chunkid_palette_change                    avi_fourcc_const(0,0,'p','c')
00185 #define riff_idx1_AVIOLDINDEX_chunkid_audio_data                        avi_fourcc_const(0,0,'w','b')
00186 
00187 #define riff_idx1_AVIOLDINDEX_flags_LIST                                0x00000001UL
00188 #define riff_idx1_AVIOLDINDEX_flags_KEYFRAME                            0x00000010UL
00189 #define riff_idx1_AVIOLDINDEX_flags_FIRSTPART                           0x00000020UL
00190 #define riff_idx1_AVIOLDINDEX_flags_LASTPART                            0x00000040UL
00191 #define riff_idx1_AVIOLDINDEX_flags_NO_TIME                             0x00000100UL
00192 
00193 /* AVIMETAINDEX (a meta-structure for all the variations in indx and nnix chunks) */
00194 typedef struct {
00195 /*      FOURCC          fcc;
00196         UINT            cb; */
00197         uint16_t        wLongsPerEntry;
00198         uint8_t         bIndexSubType;
00199         uint8_t         bIndexType;
00200         uint32_t        nEntriesInUse;
00201         uint32_t        dwChunkId;
00202         uint32_t        dwReserved[3];
00203 /*      uint32_t           adwIndex[]; */
00204 } GCC_ATTRIBUTE(packed) riff_indx_AVIMETAINDEX;
00205 
00206 #define riff_indx_type_AVI_INDEX_OF_INDEXES                             0x00
00207 #define riff_indx_type_AVI_INDEX_OF_CHUNKS                              0x01
00208 #define riff_indx_type_AVI_INDEX_OF_TIMED_CHUNKS                        0x02
00209 #define riff_indx_type_AVI_INDEX_OF_SUB_2FIELD                          0x03
00210 #define riff_indx_type_AVI_INDEX_IS_DATA                                0x80
00211 
00212 #define riff_indx_subtype_AVI_INDEX_SUB_DEFAULT                         0x00
00213 #define riff_indx_subtype_AVI_INDEX_SUB_2FIELD                          0x01
00214 
00215 /* AVISUPERINDEX */
00216 typedef struct {
00217 /*      FOURCC          fcc;
00218         UINT            cb; */
00219         uint16_t        wLongsPerEntry;
00220         uint8_t         bIndexSubType;
00221         uint8_t         bIndexType;
00222         uint32_t        nEntriesInUse;
00223         uint32_t        dwChunkId;
00224         uint32_t        dwReserved[3];
00225 /*      AVISUPERINDEXentry[] */
00226 } GCC_ATTRIBUTE(packed) riff_indx_AVISUPERINDEX;
00227 
00228 typedef struct {
00229         uint64_t        qwOffset;
00230         uint32_t        dwSize;
00231         uint32_t        dwDuration;
00232 } GCC_ATTRIBUTE(packed) riff_indx_AVISUPERINDEX_entry;
00233 
00234 /* AVISTDINDEX */
00235 typedef struct {
00236 /*      FOURCC          fcc;
00237         UINT            cb; */
00238         uint16_t        wLongsPerEntry;
00239         uint8_t         bIndexSubType;
00240         uint8_t         bIndexType;
00241         uint32_t        nEntriesInUse;
00242         uint32_t        dwChunkId;
00243         uint64_t        qwBaseOffset;
00244         uint32_t        dwReserved_3;
00245 /*      AVISTDINDEXentry[] */
00246 } GCC_ATTRIBUTE(packed) riff_indx_AVISTDINDEX;
00247 
00248 typedef struct {
00249         uint32_t        dwOffset;               /* relative to qwBaseOffset */
00250         uint32_t        dwSize;                 /* bit 31 is set if delta frame */
00251 } GCC_ATTRIBUTE(packed) riff_indx_AVISTDINDEX_entry;
00252 
00253 typedef struct {
00254         uint32_t        CompressedBMHeight;
00255         uint32_t        CompressedBMWidth;
00256         uint32_t        ValidBMHeight;
00257         uint32_t        ValidBMWidth;
00258         uint32_t        ValidBMXOffset;
00259         uint32_t        ValidBMYOffset;
00260         uint32_t        VideoXOffsetInT;
00261         uint32_t        VideoYValidStartLine;
00262 } GCC_ATTRIBUTE(packed) riff_vprp_VIDEO_FIELD_DESC;
00263 
00264 /* vprp chunk */
00265 typedef struct {
00266         uint32_t        VideoFormatToken;
00267         uint32_t        VideoStandard;
00268         uint32_t        dwVerticalRefreshRate;
00269         uint32_t        dwHTotalInT;
00270         uint32_t        dwVTotalInLines;
00271         uint32_t        dwFrameAspectRatio;
00272         uint32_t        dwFrameWidthInPixels;
00273         uint32_t        dwFrameHeightInLines;
00274         uint32_t        nbFieldPerFrame;
00275 /*      riff_vprp_VIDEO_FIELD_DESC FieldInfo[nbFieldPerFrame]; */
00276 } GCC_ATTRIBUTE(packed) riff_vprp_VideoPropHeader;
00277 
00278 /* LIST:odml dmlh chunk */
00279 typedef struct {
00280         uint32_t        dwTotalFrames;
00281 } GCC_ATTRIBUTE(packed) riff_odml_dmlh_ODMLExtendedAVIHeader;
00282 
00283 /* AVI stream format contents if stream type is 'iavs' (Interleaved audio/video stream) */
00284 typedef struct windows_DVINFO {
00285         uint32_t        dwDVAAuxSrc;
00286         uint32_t        dwDVAAuxCtl;
00287         uint32_t        dwDVAAuxSrc1;
00288         uint32_t        dwDVAAuxCtl1;
00289         uint32_t        dwDVVAuxSrc;
00290         uint32_t        dwDVVAuxCtl;
00291         uint32_t        dwDVReserved[2];
00292 } GCC_ATTRIBUTE(packed) windows_DVINFO; /* =32 bytes */
00293 
00294 static const windows_DVINFO WINDOWS_DVINFO_INIT = {
00295         0,
00296         0,
00297         0,
00298         0,
00299         0,
00300         0,
00301         {0,0}
00302 };
00303 
00304 #if defined(_MSC_VER)
00305 # pragma pack(pop)
00306 #endif
00307 
00308 #endif
00309