DOSBox-X
|
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