/****************************************************************************** Copyright (C) Microsoft Corporation 1985-1995. All rights reserved. Title: graphic.h - Multimedia Systems Media Control Interface driver for AVI. *****************************************************************************/ // This stuff is not going to work 64-bit #pragma warning(disable:4312) #define NOSHELLDEBUG #include #ifndef RC_INVOKED #include #else #define MMNODRV #define MMNOSOUND #define MMNOWAVE #define MMNOMIDI #define MMNOAUX #define MMNOMIXER #define MMNOTIMER #define MMNOJOY #define MMNOMMIO #define MMNOMMSYSTEM #define MMNOMIDIDEV #define MMNOWAVEDEV #define MMNOAUXDEV #define MMNOMIXERDEV #define MMNOTIMERDEV #define MMNOJOYDEV #define MMNOTASKDEV #endif #define MCI_USE_OFFEXT #include #include // This must be included, for both versions #include #include "ntaviprt.h" #include "common.h" #include #include "digitalv.h" /* ** Here are some compression types. */ #define comptypeRLE0 mmioFOURCC('R','L','E','0') #define comptypeRLE mmioFOURCC('R','L','E',' ') #ifndef RC_INVOKED // Don't overload RC! #include "avifilex.h" // include AVIFile stuff. #endif // !RC_INVOKED #include "mciavi.h" #include "profile.h" extern const TCHAR szIni[]; extern const TCHAR szReject[]; #ifdef _WIN32 //#define STATEEVENT /* * This define causes the code to be compiled with a event defined. This * event is signalled every time (almost) the task thread changes state. * Hence the routine waiting for a particular state need not poll. */ /* * On NT keep track of whether this process is WOW or not. Set during * DRV_LOAD processing. */ extern BOOL runningInWow; #define IsNTWOW() runningInWow #else // WIN 16 #define IsNTWOW() 0 #endif #if !defined NUMELMS #define NUMELMS(aa) (sizeof(aa)/sizeof((aa)[0])) #endif // Define this to make the code expire on a given date.... // #define EXPIRE (1994 * 65536 + 1 * 256 + 1) // expire 1/1/1994 #ifndef DRIVE_CDROM #define DRIVE_CDROM 5 #endif #define DRIVE_INTERFACE 42 #ifdef EXPIRE #define MCIERR_AVI_EXPIRED 9999 #endif #define MCIAVI_PRODUCTNAME 2 #define MCIAVI_VERSION 3 #define MCIAVI_BADMSVIDEOVERSION 4 #define MCIAVI_MENU_CONFIG 5 #define MCIAVI_MENU_STRETCH 6 #define MCIAVI_MENU_MUTE 7 #define MCIAVI_CANT_DRAW_VIDEO 8 #define MCIAVI_CANT_DRAW_STREAM 9 #define INFO_VIDEOFORMAT 10 #define INFO_MONOFORMAT 11 #define INFO_STEREOFORMAT 12 #define INFO_LENGTH 13 #define INFO_FILE 14 #define INFO_KEYFRAMES 15 #define INFO_AUDIO 16 #define INFO_SKIP 17 #define INFO_ADPCM 18 #define INFO_DATARATE 19 #define INFO_SKIPAUDIO 20 #define INFO_FILETYPE 21 #define INFO_FILETYPE_AVI 22 #define INFO_FILETYPE_INT 23 #define INFO_FILETYPE_ALPHA 24 #define INFO_FRAMERATE 25 #define INFO_STREAM 26 #define INFO_DISABLED 27 #define INFO_ALLKEYFRAMES 28 #define INFO_NOKEYFRAMES 29 #define INFO_COMPRESSED 30 #define INFO_NOTREAD 31 #define IDS_IRTL 32 #define IDS_VIDEO 33 #define IDS_VIDEOCAPTION 34 #ifndef RC_INVOKED #define MCIAVI_MAXSIGNALS 1 #define MCIAVI_MAXWINDOWS 8 /* Flags for dwFlags in MCIGRAPHIC */ #define MCIAVI_STOP 0x00000001L /* We need to stop */ #define MCIAVI_PAUSE 0x00000002L /* We need to be paused */ #define MCIAVI_CUEING 0x00000004L /* We are in a cue command */ #define MCIAVI_WAITING 0x00000008L /* We are waiting for a command to finish */ #define MCIAVI_PLAYAUDIO 0x00000010L /* Audio enabled */ #define MCIAVI_LOSTAUDIO 0x00000020L /* cant get audio device*/ #define MCIAVI_SHOWVIDEO 0x00000040L /* Video enabled */ #define MCIAVI_USING_AVIFILE 0x00000080L /* RTL to AVIFile */ #define MCIAVI_USINGDISPDIB 0x00000100L /* Now in MCGA mode */ #define MCIAVI_NEEDTOSHOW 0x00000200L /* window needs to be shown */ #define MCIAVI_WANTMOVE 0x00000400L /* call CheckWindowMove alot */ #define MCIAVI_ANIMATEPALETTE 0x00000800L /* Palette animated */ #define MCIAVI_NEEDUPDATE 0x00001000L /* Need to redraw full */ #define MCIAVI_PALCHANGED 0x00002000L /* Need to update palette */ #define MCIAVI_STUPIDMODE 0x00004000L /* dont buffer mode */ #define MCIAVI_CANDRAW 0x00008000L /* display driver can draw format */ #define MCIAVI_FULLSCREEN 0x00010000L /* draw fullscreen. */ #define MCIAVI_NEEDDRAWBEGIN 0x00020000L /* compressor is drawing */ #define MCIAVI_UPDATETOMEMORY 0x00040000L /* drawing to a bitmap */ #define MCIAVI_WAVEPAUSED 0x00080000L /* waveOut is temporarily paused */ #define MCIAVI_NOTINTERLEAVED 0x00100000L /* file is not interleaved. */ #define MCIAVI_USERDRAWPROC 0x00200000L /* user has set draw proc*/ #define MCIAVI_LOSEAUDIO 0x00400000L /* do not open wave device */ #define MCIAVI_VOLUMESET 0x00800000L /* Volume has been changed. */ #define MCIAVI_HASINDEX 0x01000000L /* File has index. */ #define MCIAVI_RELEASEDC 0x02000000L /* we got the DC via GetDC */ #define MCIAVI_SEEKING 0x04000000L /* audio disabled for seek. */ #define MCIAVI_UPDATING 0x08000000L /* handling WM_PAINT-don't yield. */ #define MCIAVI_REPEATING 0x10000000L /* repeat when play finishes. */ #define MCIAVI_REVERSE 0x20000000L /* playing backwards.... */ #define MCIAVI_NOBREAK 0x40000000L /* don't allow break out of DISPDIB */ #define MCIAVI_ZOOMBY2 0x80000000L /* fullscreen zoomed by 2 */ /* Flags for dwOptionFlags */ #define MCIAVIO_SEEKEXACT 0x00000001L /* If off, seek goes to ** previous key frame ** instead of real ** target frame. */ #define MCIAVIO_SKIPFRAMES 0x00000002L /* Skip frames to keep ** synchronized. */ #define MCIAVIO_STRETCHTOWINDOW 0x00000004L /* Resize destination ** rectangle if window ** resized. */ #define MCIAVIO_STUPIDMODE 0x00000020L /* Don't do nice updating. */ #define MCIAVIO_ZOOMBY2 0x00000100L #define MCIAVIO_USEVGABYDEFAULT 0x00000200L #define MCIAVIO_USEAVIFILE 0x00000400L #define MCIAVIO_NOSOUND 0x00000800L #define MCIAVIO_USEDCI 0x00001000L #define MCIAVIO_1QSCREENSIZE 0x00010000L #define MCIAVIO_2QSCREENSIZE 0x00020000L #define MCIAVIO_3QSCREENSIZE 0x00040000L #define MCIAVIO_MAXWINDOWSIZE 0x00080000L #define MCIAVIO_DEFWINDOWSIZE 0x00000000L #define MCIAVIO_WINDOWSIZEMASK 0x000F0000L #define MCIAVI_ALG_INTERLEAVED 0x0001 #define MCIAVI_ALG_CDROM 0x0002 #define MCIAVI_ALG_HARDDISK 0x0003 #define MCIAVI_ALG_AUDIOONLY 0x0004 #define MCIAVI_ALG_AVIFILE 0x0005 // // the frame index is indexed by frame number, it is used for // varible sizeed, fixed rate streams. // typedef struct { WORD iPrevKey; // prev "key" frame WORD iNextKey; // next "key" frame WORD iPalette; // palette frame (this points into index!) UINT wSmag; // DWORD dwOffset; // Position of chunk (file offset) DWORD dwLength; // Length of chunk (in bytes) } AVIFRAMEINDEX; #define NOBASED32 #if defined(_WIN32) || defined(NOBASED32) #define BASED32(p) _huge #define P32(t,p) ((t _huge *)(p)) #define B32(t,p) ((t _huge *)(p)) #else #define BASED32(p) _based32((_segment)SELECTOROF(p)) #define P32(t,p) ((t BASED32(p) *)OFFSETOF(p)) #define B32(t,p) ((t BASED32(p) *)0) #endif #define Frame(n) (P32(AVIFRAMEINDEX,npMCI->hpFrameIndex) + (DWORD)(n)) #define FrameNextKey(n) (LONG)((n) + (DWORD)Frame(n)->iNextKey) #define FramePrevKey(n) (LONG)((n) - (DWORD)Frame(n)->iPrevKey) #define FramePalette(n) (LONG)(Frame(n)->iPalette) #define FrameOffset(n) (DWORD)(Frame(n)->dwOffset) #define FrameLength(n) (DWORD)(Frame(n)->dwLength) #define UseIndex(p) SillyGlobal = (p) #define Index(n) (B32(AVIINDEXENTRY,npMCI->hpIndex) + (long)(n)) #define IndexOffset(n) Index(n)->dwChunkOffset #define IndexLength(n) Index(n)->dwChunkLength #define IndexFlags(n) Index(n)->dwFlags #define IndexID(n) Index(n)->ckid typedef struct { DWORD dwFlags; /* flags, STREAM_ENABLED... */ AVIStreamHeader sh; /* AVIStreamHeader...*/ DWORD cbFormat; /* Stream format...*/ LPVOID lpFormat; DWORD cbData; /* Extra stream data...*/ LPVOID lpData; HIC hicDraw; /* Draw codec...*/ RECT rcSource; /* rectangles...*/ RECT rcDest; LONG lStart; /* start */ LONG lEnd; /* end */ LONG lPlayStart; /* play start */ LONG lPlayFrom; /* play from */ LONG lPlayTo; /* play to */ LONG lFrameDrawn; /* we drew this */ LONG lPos; /* current pos */ LONG lNext; /* next pos */ LONG lLastKey; /* key frame */ LONG lNextKey; /* next key frame */ #ifdef USEAVIFILE PAVISTREAM ps; ////IAVIStreamVtbl vt; // so we can call direct. #endif } STREAMINFO; #define STREAM_ENABLED 0x0001 // stream is enabled for play #define STREAM_ACTIVE 0x0002 // stream is active for *current* play #define STREAM_NEEDUPDATE 0x0004 // stream needs update (paint) #define STREAM_ERROR 0x0008 // stream did not load #define STREAM_DIRTY 0x0010 // stream not showing current frame. #define STREAM_SKIP 0x0100 // can skip data #define STREAM_PALCHANGES 0x0200 // stream has palette changes #define STREAM_VIDEO 0x0400 // is a video stream #define STREAM_AUDIO 0x0800 // is a audio stream #define STREAM_PALCHANGED 0x1000 // palette has changed #define STREAM_WANTIDLE 0x2000 // should get idle time #define STREAM_WANTMOVE 0x4000 // should get ICM_DRAW_WINDOW message #define SI(stream) (npMCI->paStreamInfo + stream) #define SH(stream) (SI(stream)->sh) #define SOURCE(stream) (SI(stream)->rcSource) #define DEST(stream) (SI(stream)->rcDest) #define FRAME(stream) (SH(stream).rcFrame) #define FORMAT(stream) (SI(stream)->lpFormat) #define VIDFMT(stream) ((LPBITMAPINFOHEADER) FORMAT(stream)) #define AUDFMT(stream) ((LPPCMWAVEFORMAT) FORMAT(stream)) // // map from "movie" time into stream time. // #define TimeToMovie(t) muldiv32(t, npMCI->dwRate, npMCI->dwScale*1000) #define MovieToTime(l) muldiv32(l, npMCI->dwScale*1000, npMCI->dwRate) #define TimeToStream(psi, t) muldiv32(t, psi->sh.dwRate, psi->sh.dwScale*1000) #define StreamToTime(psi, l) muldiv32(l, psi->sh.dwScale*1000, psi->sh.dwRate) // // NOTE all dwScale's are equal so we can do this without as many // multiplies // #if 0 #define MovieToStream(psi, l) muldiv32(l, npMCI->dwScale * psi->sh.dwRate, npMCI->dwRate * psi->sh.dwScale) #define StreamToMovie(psi, l) muldiv32(l, npMCI->dwScale * psi->sh.dwRate, npMCI->dwRate * psi->sh.dwScale) #else #define MovieToStream(psi, l) muldiv32(l, psi->sh.dwRate, npMCI->dwRate) #define StreamToMovie(psi, l) muldiv32(l, psi->sh.dwRate, npMCI->dwRate) #endif /* * dwNTFlags definitions */ //#define NTF_AUDIO_ON 0x00000001 Messages are not used to regain wave device #define NTF_AUDIO_OFF 0x00000002 #define NTF_CLOSING 0x80000000 #define NTF_RETRYAUDIO 0x00000004 #define NTF_RESTARTFORAUDIO 0x00000008 #define NTF_DELETEWINCRITSEC 0x00000010 #define NTF_DELETECMDCRITSEC 0x00000020 #define NTF_DELETEHDCCRITSEC 0x00000040 #ifdef _WIN32 #define ResetNTFlags(npMCI, bits) (npMCI)->dwNTFlags &= ~(bits) #define SetNTFlags(npMCI, bits) (npMCI)->dwNTFlags |= (bits) #define TestNTFlags(npMCI, bits) ((npMCI)->dwNTFlags & (bits)) #ifdef REMOTESTEAL extern HKEY hkey; #endif #else #define ResetNTFlags(npMCI, bits) #define SetNTFlags(npMCI, bits) #define TestNTFlags(npMCI, bits) 0 #endif /* * RECT macros to get X,Y,Width,Height */ #define RCX(rc) ((rc).left) #define RCY(rc) ((rc).top) #define RCW(rc) ((rc).right - (rc).left) #define RCH(rc) ((rc).bottom - (rc).top) #ifdef _WIN32 // interaction between worker and winproc thread. // winproc thread sets these bits in npMCI->winproc_request #define WINPROC_STOP 0x0001 // stop play #define WINPROC_RESETDEST 0x0002 // reset dest rect (window sized) #define WINPROC_MUTE 0x0004 // mute flag changed #define WINPROC_ACTIVE 0x0008 // got activation #define WINPROC_INACTIVE 0x0010 // lost activation #define WINPROC_UPDATE 0x0020 // window needs painting #define WINPROC_REALIZE 0x0040 // palette needs realizing #define WINPROC_SILENT 0x0100 // go silent (release wave device) #define WINPROC_SOUND 0x0200 // restore sound (get wave device) #endif /* * The major control block for an AVI device * Define markers to more easily identify the control block when dumping */ #define MCIID (DWORD)(((WORD)('V' | ('F'<<8))) | ((WORD)('W' | ('>'<<8))<<16)) #define MCIIDX (DWORD)(((WORD)('v' | ('f'<<8))) | ((WORD)('w' | ('-'<<8))<<16)) typedef struct _MCIGRAPHIC { // --- these fields accessed by user thread ------------------------- #ifdef DEBUG DWORD mciid; /* visible identifier */ #endif struct _MCIGRAPHIC *npMCINext; /* ** Basic MCI information */ HWND hCallback; /* callback window handle */ UINT wDevID; /* device ID */ // -----new inter-task communication zone CRITICAL_SECTION CmdCritSec; // hold this to make request // next two events must be contiguous - WaitForMultipleObjects HANDLE hEventSend; // set to signal a request HANDLE heWinProcRequest; // set when something to process #define IDLEWAITFOR 2 // note - next two events are passed as an array to WaitForMultipleObjects HANDLE hEventResponse; // signalled by worker on req done. HANDLE hThreadTermination; /* Handle to wait on for thread to terminate so it's safe to unload DLL Must be closed by us */ HANDLE hEventAllDone; // signalled on end of play int EntryCount; // used to prevent re-entry on current thread UINT message; // request message (from mciDriverEntry) DWORD dwParamFlags; // request param LPARAM lParam; // request param DWORD dwReturn; // return value DWORD_PTR dwReqCallback; // callback for this request BOOL bDelayedComplete; // is async request with wait? HTASK hRequestor; // task id of requesting task DWORD dwTaskError; /* error return from task */ // --- read by user thread to optimise status/position queries------ UINT wTaskState; /* current task state */ DWORD dwFlags; /* flags */ LONG lCurrentFrame; /* current frame */ DWORD dwBufferedVideo; LONG lRealStart; /* frame playback starts */ // user thread uses this for volume setting only HWAVEOUT hWave; /* wave device handle */ DWORD dwVolume; /* Audio volume, 1000 is full on */ LONG lFrames; /* number of frames in movie */ // --- nothing below here touched by user thread (after init)-------------- #if 0 /////UNUSED // the original interface before we marshalled it PAVIFILE pf_AppThread; // marshalled into this block for passing to worker thread HANDLE hMarshalling; #endif/////UNUSED // set to TRUE during processing of an Update requested by the winproc // thread - don't do ShowStage during this as could cause deadlock BOOL bDoingWinUpdate; /* ** Internal task operation status and flags */ #ifndef _WIN32 UINT pspTask; /* background task's PSP */ UINT pspParent; /* PSP of the calling app */ #else DWORD dwNTFlags; /* NT specific flags */ HTASK hWaiter; // task waiting on hEventAllDone // communication between worker and winproc threads // note: next two events must be contiguous - passed to WaitForMultiple.. HANDLE hThreadWinproc; // signalled on thread exit HANDLE hEventWinProcOK; // signalled on init ok HANDLE hEventWinProcDie; // tell winproc thread to die CRITICAL_SECTION WinCritSec; // protect worker - winproc interaction CRITICAL_SECTION HDCCritSec; // protect worker - winproc drawing // ** VERY IMPORTANT ** IF both critical sections are needed then they // MUST be obtained in this order: WinCrit, then HDCCrit #ifdef DEBUG DWORD WinCritSecOwner; LONG WinCritSecDepth; DWORD HDCCritSecOwner; LONG HDCCritSecDepth; #endif // winproc sets bits in this (protected by WinCritSec) to // request stop/mute actions asynchronously DWORD dwWinProcRequests; // saved state over temporary stop UINT oldState; long oldTo; long oldFrom; DWORD oldFlags; DWORD_PTR oldCallback; #endif HTASK hTask; /* task id */ HTASK hCallingTask; /* task who opened us */ UINT uErrorMode; /* SetErrorMode value for calling task */ UINT wMessageCurrent;/* Command in progress, or zero */ DWORD dwOptionFlags; /* more flags */ /* ** Additional information controlled by MCI commands */ HPALETTE hpal; /* Palette forced with MCI commands */ HWND hwndPlayback; /* window handle for playback */ HWND hwndDefault; /* default window handle */ HWND hwndOldFocus; /* window which had keyboard focus */ BOOL fForceBackground;/* Select palette in foreground or back? */ DWORD dwTimeFormat; /* current time format */ RECT rcMovie; /* main movie rect */ RECT rcSource; /* drawing source rect */ RECT rcDest; /* drawing destination rect */ #ifdef DEBUG LONG PlaybackRate; /* 1000 is normal, more is fast.... */ #endif DWORD dwSpeedFactor; /* 1000 is normal, more is fast.... */ // What is this flag? We only listen to the zoom by 2 or fixed % window // size registry defaults if we're using the default window, not if // somebody is playing in their own window. But when we open an AVI, // (like we're doing now) we don't know yet what window they'll pick! // So let's make a note that so far there's no reason not to listen to // the defaults, and if anybody resizes, or changes the window handle, // or makes the default window not resizable, then we won't. BOOL fOKToUseDefaultSizing; /* * window creation parameters to open */ DWORD dwStyle; HWND hwndParent; /* ** Information about currently open file */ UINT uDriveType; /* drive type */ NPTSTR szFilename; /* AVI filename */ DWORD dwBytesPerSec; /* file attributes */ DWORD dwRate; /* master time base */ DWORD dwScale; DWORD dwMicroSecPerFrame; DWORD dwSuggestedBufferSize; DWORD dwKeyFrameInfo; /* how often key frames occur */ UINT wEarlyAudio; /* more file information */ UINT wEarlyVideo; UINT wEarlyRecords; STREAMINFO NEAR *paStreamInfo; int streams; // total streams int nAudioStreams; // total audio streams int nVideoStreams; // total video streams int nOtherStreams; // total other streams int nErrorStreams; // total error streams int nAudioStream; // current audio stream. int nVideoStream; // "master" video stream STREAMINFO *psiAudio; // points to video stream STREAMINFO *psiVideo; // points to audio stream #ifdef USEAVIFILE PAVIFILE pf; ////IAVIFileVtbl vt; // so we can call direct. #else LPVOID pf; // variable to be zero. #endif /* ** video stream junk */ BOOL fNoDrawing; LONG lFrameDrawn; /* number of last frame drawn */ /* Drawing information */ HDC hdc; /* DC we're playing into */ /* Video format */ BITMAPINFOHEADER FAR *pbiFormat; /* video format information */ /* BitmapInfo used for drawing */ BITMAPINFOHEADER bih; /* video format information */ RGBQUAD argb[256]; /* current drawing colors */ RGBQUAD argbOriginal[256]; /* original colors */ /* ** Installable compressor information */ //!!! move all this into the screen draw function!!! //!!! all this should be in DrawDIB !!! HIC hic; HIC hicDraw; LONG cbDecompress; HPSTR hpDecompress; /* pointer to full frame buffer */ /* ** Holding area for compressors we might use.... */ HIC hicDecompress; HIC hicDrawDefault; HIC hicDrawFull; HIC hicInternal; HIC hicInternalFull; LONG lLastPaletteChange; LONG lNextPaletteChange; /* ** wave stream junk */ /* Wave format stuff */ NPWAVEFORMAT pWF; /* current wave format */ UINT wABs; /* number of audio buffers */ UINT wABOptimal; /* number full if synchronized */ DWORD dwABSize; /* size of one audio buffer */ HMMIO hmmioAudio; BOOL fEmulatingVolume;/* Are we doing volume by table lookup? */ BYTE * pVolumeTable; DWORD dwAudioLength; DWORD dwAudioPos; /* Wave Output Device */ UINT wABFull; /* number now full */ UINT wNextAB; /* next buffer in line */ UINT nAudioBehind; /* how many audio below full */ HPSTR lpAudio; /* pointer to audio buffers */ DWORD dwUsedThisAB; /* ** File index information */ AVIINDEXENTRY _huge * hpIndex; /* pointer to index */ DWORD macIndex; /* # records in index */ AVIFRAMEINDEX _huge * hpFrameIndex; /* pointer to frame index */ HANDLE hgFrameIndex; // handle to non-offset memory /* ** play/seek params */ LONG lTo; /* frame we're playing to */ LONG lFrom; /* frame we're playing from */ LONG lRepeatFrom; /* Frame to repeat from */ /* ** Information regarding current play */ UINT wPlaybackAlg; /* playback algorithm in use */ LONG lAudioStart; /* first audio frame to play */ LONG lVideoStart; /* first video frame to play */ LONG lLastRead; /* Timing */ LONG lFramePlayStart;/* Frame playing started at */ DWORD dwTotalMSec; /* Total time spent playing */ DWORD dwMSecPlayStart;/* Start time */ DWORD dwTimingStart; DWORD dwPauseTime; DWORD dwPlayMicroSecPerFrame; DWORD dwAudioPlayed; /* ** Timing information */ #ifdef DEBUG #define INTERVAL_TIMES #endif #ifdef INTERVAL_TIMES #define NBUCKETS 25 #define BUCKETSIZE 10 //#define NTIMES 200 // frame interval timing DWORD dwStartTime; long msFrameMax; long msFrameMin; long msFrameTotal; long msSquares; long nFrames; int buckets[NBUCKETS+1]; long * paIntervals; long cIntervals; //long intervals[NTIMES]; long msReadTimeuS; long msReadMaxBytesPer; long msReadMax; long msReadTotal; long nReads; #endif DWORD dwLastDrawTime; /* How long did the last draw take? */ DWORD dwLastReadTime; DWORD msPeriodResolution; /* Clock resolution for this video */ /* Timing information kept after play completes */ DWORD dwSkippedFrames; /* Frames skipped during current play */ DWORD dwFramesSeekedPast; /* Frames not even read */ DWORD dwAudioBreaks; /* # times audio broke up, approx. */ DWORD dwSpeedPercentage; /* Ratio of ideal time to time taken */ /* Timing information for last play */ LONG lFramesPlayed; LONG lSkippedFrames; /* Frames skipped during last play */ LONG lFramesSeekedPast; /* Frames not even read */ LONG lAudioBreaks; /* # times audio broke up, approx. */ /* ** Information for pending 'signal' command */ DWORD dwSignals; DWORD dwSignalFlags; MCI_DGV_SIGNAL_PARMS signal; /* ** Information for watching to see if window has moved. */ UINT wRgnType; /* Region type, empty, simple, complex.... */ #ifdef _WIN32 POINT dwOrg; /* Physical DC origin */ #else DWORD dwOrg; /* Physical DC origin */ #endif RECT rcClip; /* clip box */ /* ** specific to RIFF files */ HMMIO hmmio; /* animation file handle */ BOOL fReadMany; /* read more than one record */ DWORD dwFirstRecordPosition; DWORD dwFirstRecordSize; DWORD dwFirstRecordType; DWORD dwNextRecordSize; // used for ReadNextChunk DWORD dwNextRecordType; DWORD dwMovieListOffset; DWORD dwBigListEnd; /* Read Buffer */ HPSTR lp; /* work pointer */ LPVOID lpMMIOBuffer; /* pointer to MMIO read buffer */ HPSTR lpBuffer; /* pointer to read buffer */ DWORD dwBufferSize; /* Read buffer size */ DWORD dwThisRecordSize; /* size of current record */ /* ** DEBUG stuff and more timing info. */ #ifdef DEBUG HANDLE hdd; //!!! LONG timePlay; /* total play time */ LONG timePrepare; /* time to prepare for play */ LONG timeCleanup; /* time to clean up play */ LONG timePaused; /* paused time */ LONG timeRead; /* time reading from disk */ LONG timeWait; /* time waiting */ LONG timeYield; /* time yielding to other apps */ LONG timeVideo; /* time "drawing" video stream */ LONG timeAudio; /* time "drawing" audio stream */ LONG timeOther; /* time "drawing" other streams */ LONG timeDraw; /* time drawing frame via DrawDib/DispDib/ICDraw */ LONG timeDecompress; /* time decompressing frame via ICDecompress */ #endif #ifdef AVIREAD /* * handle to current async read object */ HAVIRD hAviRd; HPSTR lpOldBuffer; #endif } MCIGRAPHIC, *NPMCIGRAPHIC, FAR *LPMCIGRAPHIC; extern HANDLE ghModule; // in DRVPROC.C extern TCHAR szClassName[]; // in WINDOW.C /* ** Flags to protect ourselves in case we're closed with a dialog up... */ extern BOOL gfEvil; // in GRAPHIC.C extern BOOL gfEvilSysMenu; // in GRAPHIC.C extern HDRVR ghdrvEvil; // in GRAPHIC.C /* ** Functions in GRAPHIC.C */ LPCTSTR FAR FileName(LPCTSTR szPath); BOOL FAR PASCAL GraphicInit (void); BOOL NEAR PASCAL GraphicWindowInit (void); #ifdef _WIN32 BOOL NEAR PASCAL GraphicWindowFree(void); void aviWinProcTask(DWORD_PTR dwInst); #endif void PASCAL GraphicFree (void); DWORD PASCAL GraphicDrvOpen (LPMCI_OPEN_DRIVER_PARMS lpParms); void FAR PASCAL GraphicDelayedNotify (NPMCIGRAPHIC npMCI, UINT wStatus); void FAR PASCAL GraphicImmediateNotify (UINT wDevID, LPMCI_GENERIC_PARMS lpParms, DWORD dwFlags, DWORD dwErr); DWORD PASCAL GraphicClose(NPMCIGRAPHIC npMCI); DWORD NEAR PASCAL ConvertFromFrames(NPMCIGRAPHIC npMCI, LONG lFrame); LONG NEAR PASCAL ConvertToFrames(NPMCIGRAPHIC npMCI, DWORD dwTime); DWORD PASCAL mciDriverEntry(UINT wDeviceID, UINT wMessage, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms); LRESULT FAR PASCAL _loadds GraphicWndProc(HWND, UINT, WPARAM, LPARAM); void CheckWindowMove(NPMCIGRAPHIC npMCI, BOOL fForce); DWORD InternalGetPosition(NPMCIGRAPHIC npMCI, LPLONG lpl); // now called only on worker thread void NEAR PASCAL GraphicSaveCallback (NPMCIGRAPHIC npMCI, HANDLE hCallback); /* * Functions in DEVICE.C * * All these DeviceXXX functions are called on USER THREAD ONLY (ok?) * EXCEPT for DeviceSetActive which is called on the winproc thread. * (From InternalRealize...CheckIfActive...DeviceSetActive) */ DWORD PASCAL DeviceOpen(NPMCIGRAPHIC npMCI, DWORD dwFlags); DWORD PASCAL DeviceClose(NPMCIGRAPHIC npMCI); DWORD PASCAL DevicePlay( NPMCIGRAPHIC npMCI, DWORD dwFlags, LPMCI_DGV_PLAY_PARMS lpPlay, LPARAM dwCallback ); DWORD PASCAL DeviceResume(NPMCIGRAPHIC npMCI, DWORD dwFlags, LPARAM dwCallback); DWORD PASCAL DeviceCue(NPMCIGRAPHIC npMCI, LONG lTo, DWORD dwFlags, LPARAM dwCallback); DWORD PASCAL DeviceStop(NPMCIGRAPHIC npMCI, DWORD dwFlags); DWORD PASCAL DevicePause(NPMCIGRAPHIC npMCI, DWORD dwFlags, LPARAM dwCallback); DWORD PASCAL DeviceSeek(NPMCIGRAPHIC npMCI, LONG lTo, DWORD dwFlags, LPARAM dwCallback); DWORD PASCAL DeviceRealize(NPMCIGRAPHIC npMCI); DWORD PASCAL DeviceUpdate(NPMCIGRAPHIC npMCI, DWORD dwFlags, LPMCI_DGV_UPDATE_PARMS lpParms); UINT PASCAL DeviceMode(NPMCIGRAPHIC npMCI); DWORD PASCAL DevicePosition(NPMCIGRAPHIC npMCI, LPLONG lpl); DWORD PASCAL DeviceSetWindow(NPMCIGRAPHIC npMCI, HWND hwnd); DWORD PASCAL DeviceSetSpeed(NPMCIGRAPHIC npMCI, DWORD dwNewSpeed); DWORD PASCAL DeviceMute(NPMCIGRAPHIC npMCI, BOOL fMute); DWORD PASCAL DeviceSetVolume(NPMCIGRAPHIC npMCI, DWORD dwVolume); DWORD PASCAL DeviceGetVolume(NPMCIGRAPHIC npMCI); DWORD PASCAL DeviceSetAudioStream(NPMCIGRAPHIC npMCI, UINT uStream); DWORD PASCAL DeviceSetVideoStream(NPMCIGRAPHIC npMCI, UINT uStream, BOOL fOn); DWORD PASCAL DeviceSetActive(NPMCIGRAPHIC npMCI, BOOL fActive); DWORD FAR PASCAL DevicePut(NPMCIGRAPHIC npMCI, LPRECT lprc, DWORD dwFlags); DWORD FAR PASCAL DeviceSetPalette(NPMCIGRAPHIC npMCI, HPALETTE hpal); DWORD FAR PASCAL DeviceSetPaletteColor(NPMCIGRAPHIC npMCI, DWORD index, DWORD color); void CheckIfActive(NPMCIGRAPHIC npMCI); // in window.c void FAR PASCAL AlterRectUsingDefaults(NPMCIGRAPHIC npMCI, LPRECT lprc); void FAR PASCAL SetWindowToDefaultSize(NPMCIGRAPHIC npMCI, BOOL fUseDefaultSizing); // user thread version void FAR PASCAL ResetDestRect(NPMCIGRAPHIC npMCI, BOOL fUseDefaultSizing); // same as ResetDestRect, but called on winproc thread void FAR PASCAL Winproc_DestRect(NPMCIGRAPHIC npMCI, BOOL fUseDefaultSizing); DWORD FAR PASCAL ReadConfigInfo(void); void FAR PASCAL WriteConfigInfo(DWORD dwOptions); BOOL FAR PASCAL ConfigDialog(HWND, NPMCIGRAPHIC); /* ** The Enumerate command isn't real: I'm just thinking about it. */ #define MCI_ENUMERATE 0x0901 #define MCI_ENUMERATE_STREAM 0x00000001L // constants for dwItem field of MCI_STATUS_PARMS parameter block #define MCI_AVI_STATUS_STREAMCOUNT 0x10000001L #define MCI_AVI_STATUS_STREAMTYPE 0x10000002L #define MCI_AVI_STATUS_STREAMENABLED 0x10000003L // flags for dwFlags field of MCI_STATUS_PARMS parameter block #define MCI_AVI_STATUS_STREAM 0x10000000L // flags for dwFlags field of MCI_SET_PARMS parameter block #define MCI_AVI_SET_STREAM 0x10000000L #define MCI_AVI_SET_USERPROC 0x20000000L /* ** Internal flag that can be used with SEEK */ #define MCI_AVI_SEEK_SHOWWINDOW 0x10000000L /* ** in AVIPLAY.C (and GRAPHIC.C) */ extern INT gwSkipTolerance; extern INT gwHurryTolerance; extern INT gwMaxSkipEver; extern BOOL gfUseGetPosition; extern LONG giGetPositionAdjust; #ifdef _WIN32 #define DEFAULTUSEGETPOSITION TRUE #else #define DEFAULTUSEGETPOSITION FALSE #endif /************************************************************************** **************************************************************************/ #ifdef DEBUG #define TIMEZERO(time) npMCI->time = 0; #define TIMESTART(time) npMCI->time -= (LONG)timeGetTime() #define TIMEEND(time) npMCI->time += (LONG)timeGetTime() #else #define TIMEZERO(time) #define TIMESTART(time) #define TIMEEND(time) #endif /************************************************************************** **************************************************************************/ #define FOURCC_AVIDraw mmioFOURCC('D','R','A','W') #define FOURCC_AVIFull mmioFOURCC('F','U','L','L') LRESULT FAR PASCAL _loadds ICAVIDrawProc(DWORD_PTR id, HDRVR hDriver, UINT uiMessage, LPARAM lParam1, LPARAM lParam2); LRESULT FAR PASCAL _loadds ICAVIFullProc(DWORD_PTR id, HDRVR hDriver, UINT uiMessage, LPARAM lParam1, LPARAM lParam2); /************************************************************************** **************************************************************************/ #include "avitask.h" /************************************************************************** Macros and constants for accessing the list of open MCI devices. In the debug build we track who has access to the list. **************************************************************************/ extern NPMCIGRAPHIC npMCIList; // in graphic.c #ifdef _WIN32 extern CRITICAL_SECTION MCIListCritSec; // in graphic.c #ifdef DEBUG // The debug versions of the macros track who owns the critical section extern DWORD ListOwner; #define EnterList() { EnterCriticalSection(&MCIListCritSec); \ ListOwner=GetCurrentThreadId();\ } #define LeaveList() { ListOwner=0;\ LeaveCriticalSection(&MCIListCritSec);\ } #else // !debug #define EnterList() EnterCriticalSection(&MCIListCritSec); #define LeaveList() LeaveCriticalSection(&MCIListCritSec); #endif //DEBUG // this critical section is used to protect drawing code from // interaction between the winproc and the worker thread. the user // thread should not need to hold this ever. #ifdef DEBUG // The debug versions of the EnterWinCrit/LeaveWinCrit macros track who // owns the window critical section. This makes it possible to Assert // in the code that we are validly in (or out) of the critical section. #define EnterWinCrit(p) { EnterCriticalSection(&(p)->WinCritSec); \ (p)->WinCritSecOwner=GetCurrentThreadId(); \ /* The first enter should mean that we do */\ /* NOT own the HDC critical section */\ if (!((p)->WinCritSecDepth++)) \ { HDCCritCheckOut(p) }; \ } #define LeaveWinCrit(p) { if(0 == (--(p)->WinCritSecDepth)) \ (p)->WinCritSecOwner=0; \ if ((p)->WinCritSecDepth<0) { \ DebugBreak(); \ } \ LeaveCriticalSection(&(p)->WinCritSec); \ } #define WinCritCheckIn(p) if ((p)->WinCritSecOwner != GetCurrentThreadId())\ Assert(!"Should own the window critical section"); #define WinCritCheckOut(p) if ((p)->WinCritSecOwner == GetCurrentThreadId()) \ Assert(!"Should not own the window critical section"); #define EnterHDCCrit(p) { EnterCriticalSection(&(p)->HDCCritSec); \ (p)->HDCCritSecOwner=GetCurrentThreadId(); \ (p)->HDCCritSecDepth++; \ } #define LeaveHDCCrit(p) { if(0 == (--(p)->HDCCritSecDepth)) \ (p)->HDCCritSecOwner=0; \ if ((p)->HDCCritSecDepth<0) { \ DebugBreak(); \ } \ LeaveCriticalSection(&(p)->HDCCritSec); \ } #define HDCCritCheckIn(p) if ((p)->HDCCritSecOwner != GetCurrentThreadId())\ Assert(!"Should own the hdc critical section"); #define HDCCritCheckOut(p) if ((p)->HDCCritSecOwner == GetCurrentThreadId()) \ Assert(!"Should not own the hdc critical section"); #else // Non debug versions #define EnterWinCrit(npMCI) EnterCriticalSection(&npMCI->WinCritSec) #define LeaveWinCrit(npMCI) LeaveCriticalSection(&npMCI->WinCritSec) #define WinCritCheckIn(p) #define WinCritCheckOut(p) #define EnterHDCCrit(npMCI) EnterCriticalSection(&npMCI->HDCCritSec) #define LeaveHDCCrit(npMCI) LeaveCriticalSection(&npMCI->HDCCritSec) #define HDCCritCheckIn(p) #define HDCCritCheckOut(p) #endif #else // !_WIN32 #define EnterList() #define LeaveList() #define EnterWinCrit(n) #define LeaveWinCrit(n) #endif #endif // RC_INVOKED