www.pudn.com > mediator15src.zip > AVIOutput.h
/* * AVIOutput.h * Copyright (C) 1998-2001 Avery Lee * * This file is part of MPEG Mediator, a free MPEG stream converter. * * MPEG Mediator is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * MPEG Mediator is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef f_AVIOUTPUT_H #define f_AVIOUTPUT_H #include#include "Fixes.h" #define FMT_STR(x) {char tmp[1024]; class AVIIndex; class AudioSource; class VideoSource; class AVIIndexEntry2; typedef struct _avisuperindex_chunk AVISUPERINDEX; struct _avisuperindex_entry; ////////////////////////// class AVIOutputStream { private: LONG formatLen; void *format; protected: class AVIOutput *output; BOOL _write(FOURCC ckid, LONG dwIndexFlags, LPVOID lpBuffer, LONG cbBuffer); public: AVIStreamHeader_fixed streamInfo; AVIOutputStream(class AVIOutput *output); virtual ~AVIOutputStream(); void *allocFormat(LONG len) { if (format && formatLen == len) return format; delete format; return format = new char[formatLen = len]; } void *getFormat() { return format; } LONG getFormatLen() { return formatLen; } virtual BOOL write(LONG dwIndexFlags, LPVOID lpBuffer, LONG cbBuffer, LONG lSamples) = 0; virtual BOOL finalize(); LONG msToSamples(LONG lMs) { return (LONG)(((__int64)lMs * streamInfo.dwRate) / ((__int64)1000 * streamInfo.dwScale)); } LONG samplesToMs(LONG lSamples) { return (LONG)((((__int64)lSamples * streamInfo.dwScale) * 1000) / streamInfo.dwScale); } }; class AVIAudioOutputStream : public AVIOutputStream { public: __int64 lTotalBytesWritten; AVIAudioOutputStream(class AVIOutput *out); WAVEFORMATEX *getWaveFormat() { return (WAVEFORMATEX *)getFormat(); } BOOL write(LONG dwIndexFlags, LPVOID lpBuffer, LONG cbBuffer, LONG lSamples); virtual BOOL finalize(); virtual BOOL flush(); }; class AVIVideoOutputStream : public AVIOutputStream { public: LONG lTotalSamplesWritten; FOURCC id; AVIVideoOutputStream(class AVIOutput *out); BITMAPINFOHEADER *getImageFormat() { return (BITMAPINFOHEADER *)getFormat(); } void setCompressed(BOOL x) { id = x ? mmioFOURCC('0','0','d','c') : mmioFOURCC('0','0','d','b'); } BOOL isCompressed() { return id == mmioFOURCC('0','0','d','c'); } BOOL write(LONG dwIndexFlags, LPVOID lpBuffer, LONG cbBuffer, LONG lSamples); virtual BOOL finalize(); }; class AVIOutput { private: protected: static char szME[]; public: AVIAudioOutputStream *audioOut; AVIVideoOutputStream *videoOut; AVIOutput(); virtual ~AVIOutput(); virtual BOOL initOutputStreams()=0; virtual BOOL init(const char *szFile, LONG xSize, LONG ySize, BOOL videoIn, BOOL audioIn, LONG bufferSize, BOOL is_interleaved)=0; virtual BOOL finalize()=0; virtual BOOL isPreview()=0; virtual void writeIndexedChunk(FOURCC ckid, LONG dwIndexFlags, LPVOID lpBuffer, LONG cbBuffer)=0; }; class AVIOutputFile : public AVIOutput { private: enum { MAX_AVIBLOCKS = 64, MAX_SUPERINDEX_ENTRIES=256, MAX_INDEX_ENTRIES=3072 }; HANDLE hFile; __int64 i64FilePosition; __int64 i64XBufferLevel; __int64 avi_movi_pos[64]; __int64 avi_movi_len[64]; __int64 avi_riff_pos[64]; __int64 avi_riff_len[64]; int xblock; long strl_pos; long misc_pos; long main_hdr_pos; long audio_hdr_pos; long audio_format_pos; long video_hdr_pos; long audio_indx_pos; long video_indx_pos; long dmlh_pos; long seghint_pos; int chunkFlags; AVIIndex *index, *index_audio, *index_video; char * pHeaderBlock; long nHeaderLen; MainAVIHeader avihdr; long lChunkSize; long lAVILimit; int iPadOffset; bool fCaching; bool fExtendedAVI; bool fCaptureMode; bool fInitComplete; char * pSegmentHint; int cbSegmentHint; __int64 i64EndOfFile; __int64 i64FarthestWritePoint; long lLargestIndexDelta[2]; __int64 i64FirstIndexedChunk[2]; __int64 i64LastIndexedChunk[2]; bool fLimitTo4Gb; long lIndexedChunkCount[2]; long lIndexSize; bool fPreemptiveExtendFailed; BOOL _init(const char *szFile, LONG xSize, LONG ySize, BOOL videoIn, BOOL audioIn, LONG bufferSize, BOOL is_interleaved, bool fThreaded); __int64 _writeHdr(void *data, long len); __int64 _beginList(FOURCC ckid); __int64 _writeHdrChunk(FOURCC ckid, void *data, long len); void _closeList(__int64 pos); void _flushHdr(); __int64 _getPosition(); void _seekHdr(__int64 i64NewPos); bool _extendFile(__int64 i64NewPoint); void _seekDirect(__int64 i64NewPos); __int64 _writeDirect(void *data, long len); void _write(void *data, int len); void _closeXblock(); void _openXblock(); void _writeLegacyIndex(bool use_fastIO); void _createNewIndices(AVIIndex *index, AVISUPERINDEX *asi, _avisuperindex_entry *asie, bool is_audio); int _writeNewIndex(struct _avisuperindex_entry *asie, AVIIndexEntry2 *avie2, int size, FOURCC fcc, DWORD dwChunkId, DWORD dwSampleSize); char *SplitPathRoot(char *dst, const char *path) { if (!path) return NULL; // C: if (isalpha(path[0]) && path[1]==':') { dst[0] = path[0]; dst[1] = ':'; dst[2] = '\\'; dst[3] = 0; return dst; } // UNC path? if (path[0] == '\\' && path[1] == '\\') { const char *s = path+2; char *t = dst; *t++ = '\\'; *t++ = '\\'; while(*s && *s != '\\') *t++ = *s++; if (*s) *t++ = *s++; while(*s && *s != '\\') *t++ = *s++; *t++ = '\\'; *t = 0; return dst; } return NULL; } bool IsFilenameOnFATVolume(const char *pszFilename) { char szFileRoot[MAX_PATH]; DWORD dwMaxComponentLength; DWORD dwFSFlags; char szFilesystem[MAX_PATH]; if (!GetVolumeInformation(SplitPathRoot(szFileRoot, pszFilename), NULL, 0, // Volume name buffer NULL, // Serial number buffer &dwMaxComponentLength, &dwFSFlags, szFilesystem, sizeof szFilesystem)) return false; return !strnicmp(szFilesystem, "FAT", 3); } public: AVIOutputFile(); virtual ~AVIOutputFile(); void disable_os_caching(); void disable_extended_avi(); void set_1Gb_limit(); void set_chunk_size(long cs); void set_capture_mode(bool b); void setSegmentHintBlock(bool fIsFinal, const char *pszNextPath, int cbBlock); BOOL initOutputStreams(); BOOL init(const char *szFile, LONG xSize, LONG ySize, BOOL videoIn, BOOL audioIn, LONG bufferSize, BOOL is_interleaved); BOOL finalize(); BOOL isPreview(); void writeIndexedChunk(FOURCC ckid, LONG dwIndexFlags, LPVOID lpBuffer, LONG cbBuffer); LONG bufferStatus(LONG *lplBufferSize); }; #endif