You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1056 lines
38 KiB
1056 lines
38 KiB
/******************************************************************************
|
|
|
|
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 <windows.h>
|
|
#ifndef RC_INVOKED
|
|
#include <windowsx.h>
|
|
#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 <mmsystem.h>
|
|
#include <win32.h> // This must be included, for both versions
|
|
#include <mmddk.h>
|
|
#include "ntaviprt.h"
|
|
#include "common.h"
|
|
#include <vfw.h>
|
|
#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
|