Source code of Windows XP (NT5)
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
37 KiB

  1. /******************************************************************************
  2. Copyright (C) Microsoft Corporation 1985-1995. All rights reserved.
  3. Title: graphic.h - Multimedia Systems Media Control Interface
  4. driver for AVI.
  5. *****************************************************************************/
  6. // This stuff is not going to work 64-bit
  7. #pragma warning(disable:4312)
  8. #define NOSHELLDEBUG
  9. #include <windows.h>
  10. #ifndef RC_INVOKED
  11. #include <windowsx.h>
  12. #else
  13. #define MMNODRV
  14. #define MMNOSOUND
  15. #define MMNOWAVE
  16. #define MMNOMIDI
  17. #define MMNOAUX
  18. #define MMNOMIXER
  19. #define MMNOTIMER
  20. #define MMNOJOY
  21. #define MMNOMMIO
  22. #define MMNOMMSYSTEM
  23. #define MMNOMIDIDEV
  24. #define MMNOWAVEDEV
  25. #define MMNOAUXDEV
  26. #define MMNOMIXERDEV
  27. #define MMNOTIMERDEV
  28. #define MMNOJOYDEV
  29. #define MMNOTASKDEV
  30. #endif
  31. #define MCI_USE_OFFEXT
  32. #include <mmsystem.h>
  33. #include <win32.h> // This must be included, for both versions
  34. #include <mmddk.h>
  35. #include "ntaviprt.h"
  36. #include "common.h"
  37. #include <vfw.h>
  38. #include "digitalv.h"
  39. /*
  40. ** Here are some compression types.
  41. */
  42. #define comptypeRLE0 mmioFOURCC('R','L','E','0')
  43. #define comptypeRLE mmioFOURCC('R','L','E',' ')
  44. #ifndef RC_INVOKED // Don't overload RC!
  45. #include "avifilex.h" // include AVIFile stuff.
  46. #endif // !RC_INVOKED
  47. #include "mciavi.h"
  48. #include "profile.h"
  49. extern const TCHAR szIni[];
  50. extern const TCHAR szReject[];
  51. #ifdef _WIN32
  52. //#define STATEEVENT
  53. /*
  54. * This define causes the code to be compiled with a event defined. This
  55. * event is signalled every time (almost) the task thread changes state.
  56. * Hence the routine waiting for a particular state need not poll.
  57. */
  58. /*
  59. * On NT keep track of whether this process is WOW or not. Set during
  60. * DRV_LOAD processing.
  61. */
  62. extern BOOL runningInWow;
  63. #define IsNTWOW() runningInWow
  64. #else // WIN 16
  65. #define IsNTWOW() 0
  66. #endif
  67. #if !defined NUMELMS
  68. #define NUMELMS(aa) (sizeof(aa)/sizeof((aa)[0]))
  69. #endif
  70. // Define this to make the code expire on a given date....
  71. // #define EXPIRE (1994 * 65536 + 1 * 256 + 1) // expire 1/1/1994
  72. #ifndef DRIVE_CDROM
  73. #define DRIVE_CDROM 5
  74. #endif
  75. #define DRIVE_INTERFACE 42
  76. #ifdef EXPIRE
  77. #define MCIERR_AVI_EXPIRED 9999
  78. #endif
  79. #define MCIAVI_PRODUCTNAME 2
  80. #define MCIAVI_VERSION 3
  81. #define MCIAVI_BADMSVIDEOVERSION 4
  82. #define MCIAVI_MENU_CONFIG 5
  83. #define MCIAVI_MENU_STRETCH 6
  84. #define MCIAVI_MENU_MUTE 7
  85. #define MCIAVI_CANT_DRAW_VIDEO 8
  86. #define MCIAVI_CANT_DRAW_STREAM 9
  87. #define INFO_VIDEOFORMAT 10
  88. #define INFO_MONOFORMAT 11
  89. #define INFO_STEREOFORMAT 12
  90. #define INFO_LENGTH 13
  91. #define INFO_FILE 14
  92. #define INFO_KEYFRAMES 15
  93. #define INFO_AUDIO 16
  94. #define INFO_SKIP 17
  95. #define INFO_ADPCM 18
  96. #define INFO_DATARATE 19
  97. #define INFO_SKIPAUDIO 20
  98. #define INFO_FILETYPE 21
  99. #define INFO_FILETYPE_AVI 22
  100. #define INFO_FILETYPE_INT 23
  101. #define INFO_FILETYPE_ALPHA 24
  102. #define INFO_FRAMERATE 25
  103. #define INFO_STREAM 26
  104. #define INFO_DISABLED 27
  105. #define INFO_ALLKEYFRAMES 28
  106. #define INFO_NOKEYFRAMES 29
  107. #define INFO_COMPRESSED 30
  108. #define INFO_NOTREAD 31
  109. #define IDS_IRTL 32
  110. #define IDS_VIDEO 33
  111. #define IDS_VIDEOCAPTION 34
  112. #ifndef RC_INVOKED
  113. #define MCIAVI_MAXSIGNALS 1
  114. #define MCIAVI_MAXWINDOWS 8
  115. /* Flags for dwFlags in MCIGRAPHIC */
  116. #define MCIAVI_STOP 0x00000001L /* We need to stop */
  117. #define MCIAVI_PAUSE 0x00000002L /* We need to be paused */
  118. #define MCIAVI_CUEING 0x00000004L /* We are in a cue command */
  119. #define MCIAVI_WAITING 0x00000008L /* We are waiting for a command to finish */
  120. #define MCIAVI_PLAYAUDIO 0x00000010L /* Audio enabled */
  121. #define MCIAVI_LOSTAUDIO 0x00000020L /* cant get audio device*/
  122. #define MCIAVI_SHOWVIDEO 0x00000040L /* Video enabled */
  123. #define MCIAVI_USING_AVIFILE 0x00000080L /* RTL to AVIFile */
  124. #define MCIAVI_USINGDISPDIB 0x00000100L /* Now in MCGA mode */
  125. #define MCIAVI_NEEDTOSHOW 0x00000200L /* window needs to be shown */
  126. #define MCIAVI_WANTMOVE 0x00000400L /* call CheckWindowMove alot */
  127. #define MCIAVI_ANIMATEPALETTE 0x00000800L /* Palette animated */
  128. #define MCIAVI_NEEDUPDATE 0x00001000L /* Need to redraw full */
  129. #define MCIAVI_PALCHANGED 0x00002000L /* Need to update palette */
  130. #define MCIAVI_STUPIDMODE 0x00004000L /* dont buffer mode */
  131. #define MCIAVI_CANDRAW 0x00008000L /* display driver can draw format */
  132. #define MCIAVI_FULLSCREEN 0x00010000L /* draw fullscreen. */
  133. #define MCIAVI_NEEDDRAWBEGIN 0x00020000L /* compressor is drawing */
  134. #define MCIAVI_UPDATETOMEMORY 0x00040000L /* drawing to a bitmap */
  135. #define MCIAVI_WAVEPAUSED 0x00080000L /* waveOut is temporarily paused */
  136. #define MCIAVI_NOTINTERLEAVED 0x00100000L /* file is not interleaved. */
  137. #define MCIAVI_USERDRAWPROC 0x00200000L /* user has set draw proc*/
  138. #define MCIAVI_LOSEAUDIO 0x00400000L /* do not open wave device */
  139. #define MCIAVI_VOLUMESET 0x00800000L /* Volume has been changed. */
  140. #define MCIAVI_HASINDEX 0x01000000L /* File has index. */
  141. #define MCIAVI_RELEASEDC 0x02000000L /* we got the DC via GetDC */
  142. #define MCIAVI_SEEKING 0x04000000L /* audio disabled for seek. */
  143. #define MCIAVI_UPDATING 0x08000000L /* handling WM_PAINT-don't yield. */
  144. #define MCIAVI_REPEATING 0x10000000L /* repeat when play finishes. */
  145. #define MCIAVI_REVERSE 0x20000000L /* playing backwards.... */
  146. #define MCIAVI_NOBREAK 0x40000000L /* don't allow break out of DISPDIB */
  147. #define MCIAVI_ZOOMBY2 0x80000000L /* fullscreen zoomed by 2 */
  148. /* Flags for dwOptionFlags */
  149. #define MCIAVIO_SEEKEXACT 0x00000001L /* If off, seek goes to
  150. ** previous key frame
  151. ** instead of real
  152. ** target frame. */
  153. #define MCIAVIO_SKIPFRAMES 0x00000002L /* Skip frames to keep
  154. ** synchronized. */
  155. #define MCIAVIO_STRETCHTOWINDOW 0x00000004L /* Resize destination
  156. ** rectangle if window
  157. ** resized. */
  158. #define MCIAVIO_STUPIDMODE 0x00000020L /* Don't do nice updating. */
  159. #define MCIAVIO_ZOOMBY2 0x00000100L
  160. #define MCIAVIO_USEVGABYDEFAULT 0x00000200L
  161. #define MCIAVIO_USEAVIFILE 0x00000400L
  162. #define MCIAVIO_NOSOUND 0x00000800L
  163. #define MCIAVIO_USEDCI 0x00001000L
  164. #define MCIAVIO_1QSCREENSIZE 0x00010000L
  165. #define MCIAVIO_2QSCREENSIZE 0x00020000L
  166. #define MCIAVIO_3QSCREENSIZE 0x00040000L
  167. #define MCIAVIO_MAXWINDOWSIZE 0x00080000L
  168. #define MCIAVIO_DEFWINDOWSIZE 0x00000000L
  169. #define MCIAVIO_WINDOWSIZEMASK 0x000F0000L
  170. #define MCIAVI_ALG_INTERLEAVED 0x0001
  171. #define MCIAVI_ALG_CDROM 0x0002
  172. #define MCIAVI_ALG_HARDDISK 0x0003
  173. #define MCIAVI_ALG_AUDIOONLY 0x0004
  174. #define MCIAVI_ALG_AVIFILE 0x0005
  175. //
  176. // the frame index is indexed by frame number, it is used for
  177. // varible sizeed, fixed rate streams.
  178. //
  179. typedef struct
  180. {
  181. WORD iPrevKey; // prev "key" frame
  182. WORD iNextKey; // next "key" frame
  183. WORD iPalette; // palette frame (this points into index!)
  184. UINT wSmag; //
  185. DWORD dwOffset; // Position of chunk (file offset)
  186. DWORD dwLength; // Length of chunk (in bytes)
  187. } AVIFRAMEINDEX;
  188. #define NOBASED32
  189. #if defined(_WIN32) || defined(NOBASED32)
  190. #define BASED32(p) _huge
  191. #define P32(t,p) ((t _huge *)(p))
  192. #define B32(t,p) ((t _huge *)(p))
  193. #else
  194. #define BASED32(p) _based32((_segment)SELECTOROF(p))
  195. #define P32(t,p) ((t BASED32(p) *)OFFSETOF(p))
  196. #define B32(t,p) ((t BASED32(p) *)0)
  197. #endif
  198. #define Frame(n) (P32(AVIFRAMEINDEX,npMCI->hpFrameIndex) + (DWORD)(n))
  199. #define FrameNextKey(n) (LONG)((n) + (DWORD)Frame(n)->iNextKey)
  200. #define FramePrevKey(n) (LONG)((n) - (DWORD)Frame(n)->iPrevKey)
  201. #define FramePalette(n) (LONG)(Frame(n)->iPalette)
  202. #define FrameOffset(n) (DWORD)(Frame(n)->dwOffset)
  203. #define FrameLength(n) (DWORD)(Frame(n)->dwLength)
  204. #define UseIndex(p) SillyGlobal = (p)
  205. #define Index(n) (B32(AVIINDEXENTRY,npMCI->hpIndex) + (long)(n))
  206. #define IndexOffset(n) Index(n)->dwChunkOffset
  207. #define IndexLength(n) Index(n)->dwChunkLength
  208. #define IndexFlags(n) Index(n)->dwFlags
  209. #define IndexID(n) Index(n)->ckid
  210. typedef struct {
  211. DWORD dwFlags; /* flags, STREAM_ENABLED... */
  212. AVIStreamHeader sh; /* AVIStreamHeader...*/
  213. DWORD cbFormat; /* Stream format...*/
  214. LPVOID lpFormat;
  215. DWORD cbData; /* Extra stream data...*/
  216. LPVOID lpData;
  217. HIC hicDraw; /* Draw codec...*/
  218. RECT rcSource; /* rectangles...*/
  219. RECT rcDest;
  220. LONG lStart; /* start */
  221. LONG lEnd; /* end */
  222. LONG lPlayStart; /* play start */
  223. LONG lPlayFrom; /* play from */
  224. LONG lPlayTo; /* play to */
  225. LONG lFrameDrawn; /* we drew this */
  226. LONG lPos; /* current pos */
  227. LONG lNext; /* next pos */
  228. LONG lLastKey; /* key frame */
  229. LONG lNextKey; /* next key frame */
  230. #ifdef USEAVIFILE
  231. PAVISTREAM ps;
  232. ////IAVIStreamVtbl vt; // so we can call direct.
  233. #endif
  234. } STREAMINFO;
  235. #define STREAM_ENABLED 0x0001 // stream is enabled for play
  236. #define STREAM_ACTIVE 0x0002 // stream is active for *current* play
  237. #define STREAM_NEEDUPDATE 0x0004 // stream needs update (paint)
  238. #define STREAM_ERROR 0x0008 // stream did not load
  239. #define STREAM_DIRTY 0x0010 // stream not showing current frame.
  240. #define STREAM_SKIP 0x0100 // can skip data
  241. #define STREAM_PALCHANGES 0x0200 // stream has palette changes
  242. #define STREAM_VIDEO 0x0400 // is a video stream
  243. #define STREAM_AUDIO 0x0800 // is a audio stream
  244. #define STREAM_PALCHANGED 0x1000 // palette has changed
  245. #define STREAM_WANTIDLE 0x2000 // should get idle time
  246. #define STREAM_WANTMOVE 0x4000 // should get ICM_DRAW_WINDOW message
  247. #define SI(stream) (npMCI->paStreamInfo + stream)
  248. #define SH(stream) (SI(stream)->sh)
  249. #define SOURCE(stream) (SI(stream)->rcSource)
  250. #define DEST(stream) (SI(stream)->rcDest)
  251. #define FRAME(stream) (SH(stream).rcFrame)
  252. #define FORMAT(stream) (SI(stream)->lpFormat)
  253. #define VIDFMT(stream) ((LPBITMAPINFOHEADER) FORMAT(stream))
  254. #define AUDFMT(stream) ((LPPCMWAVEFORMAT) FORMAT(stream))
  255. //
  256. // map from "movie" time into stream time.
  257. //
  258. #define TimeToMovie(t) muldiv32(t, npMCI->dwRate, npMCI->dwScale*1000)
  259. #define MovieToTime(l) muldiv32(l, npMCI->dwScale*1000, npMCI->dwRate)
  260. #define TimeToStream(psi, t) muldiv32(t, psi->sh.dwRate, psi->sh.dwScale*1000)
  261. #define StreamToTime(psi, l) muldiv32(l, psi->sh.dwScale*1000, psi->sh.dwRate)
  262. //
  263. // NOTE all dwScale's are equal so we can do this without as many
  264. // multiplies
  265. //
  266. #if 0
  267. #define MovieToStream(psi, l) muldiv32(l, npMCI->dwScale * psi->sh.dwRate, npMCI->dwRate * psi->sh.dwScale)
  268. #define StreamToMovie(psi, l) muldiv32(l, npMCI->dwScale * psi->sh.dwRate, npMCI->dwRate * psi->sh.dwScale)
  269. #else
  270. #define MovieToStream(psi, l) muldiv32(l, psi->sh.dwRate, npMCI->dwRate)
  271. #define StreamToMovie(psi, l) muldiv32(l, psi->sh.dwRate, npMCI->dwRate)
  272. #endif
  273. /*
  274. * dwNTFlags definitions
  275. */
  276. //#define NTF_AUDIO_ON 0x00000001 Messages are not used to regain wave device
  277. #define NTF_AUDIO_OFF 0x00000002
  278. #define NTF_CLOSING 0x80000000
  279. #define NTF_RETRYAUDIO 0x00000004
  280. #define NTF_RESTARTFORAUDIO 0x00000008
  281. #define NTF_DELETEWINCRITSEC 0x00000010
  282. #define NTF_DELETECMDCRITSEC 0x00000020
  283. #define NTF_DELETEHDCCRITSEC 0x00000040
  284. #ifdef _WIN32
  285. #define ResetNTFlags(npMCI, bits) (npMCI)->dwNTFlags &= ~(bits)
  286. #define SetNTFlags(npMCI, bits) (npMCI)->dwNTFlags |= (bits)
  287. #define TestNTFlags(npMCI, bits) ((npMCI)->dwNTFlags & (bits))
  288. #ifdef REMOTESTEAL
  289. extern HKEY hkey;
  290. #endif
  291. #else
  292. #define ResetNTFlags(npMCI, bits)
  293. #define SetNTFlags(npMCI, bits)
  294. #define TestNTFlags(npMCI, bits) 0
  295. #endif
  296. /*
  297. * RECT macros to get X,Y,Width,Height
  298. */
  299. #define RCX(rc) ((rc).left)
  300. #define RCY(rc) ((rc).top)
  301. #define RCW(rc) ((rc).right - (rc).left)
  302. #define RCH(rc) ((rc).bottom - (rc).top)
  303. #ifdef _WIN32
  304. // interaction between worker and winproc thread.
  305. // winproc thread sets these bits in npMCI->winproc_request
  306. #define WINPROC_STOP 0x0001 // stop play
  307. #define WINPROC_RESETDEST 0x0002 // reset dest rect (window sized)
  308. #define WINPROC_MUTE 0x0004 // mute flag changed
  309. #define WINPROC_ACTIVE 0x0008 // got activation
  310. #define WINPROC_INACTIVE 0x0010 // lost activation
  311. #define WINPROC_UPDATE 0x0020 // window needs painting
  312. #define WINPROC_REALIZE 0x0040 // palette needs realizing
  313. #define WINPROC_SILENT 0x0100 // go silent (release wave device)
  314. #define WINPROC_SOUND 0x0200 // restore sound (get wave device)
  315. #endif
  316. /*
  317. * The major control block for an AVI device
  318. * Define markers to more easily identify the control block when dumping
  319. */
  320. #define MCIID (DWORD)(((WORD)('V' | ('F'<<8))) | ((WORD)('W' | ('>'<<8))<<16))
  321. #define MCIIDX (DWORD)(((WORD)('v' | ('f'<<8))) | ((WORD)('w' | ('-'<<8))<<16))
  322. typedef struct _MCIGRAPHIC {
  323. // --- these fields accessed by user thread -------------------------
  324. #ifdef DEBUG
  325. DWORD mciid; /* visible identifier */
  326. #endif
  327. struct _MCIGRAPHIC *npMCINext;
  328. /*
  329. ** Basic MCI information
  330. */
  331. HWND hCallback; /* callback window handle */
  332. UINT wDevID; /* device ID */
  333. // -----new inter-task communication zone
  334. CRITICAL_SECTION CmdCritSec; // hold this to make request
  335. // next two events must be contiguous - WaitForMultipleObjects
  336. HANDLE hEventSend; // set to signal a request
  337. HANDLE heWinProcRequest; // set when something to process
  338. #define IDLEWAITFOR 2
  339. // note - next two events are passed as an array to WaitForMultipleObjects
  340. HANDLE hEventResponse; // signalled by worker on req done.
  341. HANDLE hThreadTermination; /* Handle to wait on for thread to
  342. terminate so it's safe to unload DLL
  343. Must be closed by us */
  344. HANDLE hEventAllDone; // signalled on end of play
  345. int EntryCount; // used to prevent re-entry on current thread
  346. UINT message; // request message (from mciDriverEntry)
  347. DWORD dwParamFlags; // request param
  348. LPARAM lParam; // request param
  349. DWORD dwReturn; // return value
  350. DWORD_PTR dwReqCallback; // callback for this request
  351. BOOL bDelayedComplete; // is async request with wait?
  352. HTASK hRequestor; // task id of requesting task
  353. DWORD dwTaskError; /* error return from task */
  354. // --- read by user thread to optimise status/position queries------
  355. UINT wTaskState; /* current task state */
  356. DWORD dwFlags; /* flags */
  357. LONG lCurrentFrame; /* current frame */
  358. DWORD dwBufferedVideo;
  359. LONG lRealStart; /* frame playback starts */
  360. // user thread uses this for volume setting only
  361. HWAVEOUT hWave; /* wave device handle */
  362. DWORD dwVolume; /* Audio volume, 1000 is full on */
  363. LONG lFrames; /* number of frames in movie */
  364. // --- nothing below here touched by user thread (after init)--------------
  365. #if 0 /////UNUSED
  366. // the original interface before we marshalled it
  367. PAVIFILE pf_AppThread;
  368. // marshalled into this block for passing to worker thread
  369. HANDLE hMarshalling;
  370. #endif/////UNUSED
  371. // set to TRUE during processing of an Update requested by the winproc
  372. // thread - don't do ShowStage during this as could cause deadlock
  373. BOOL bDoingWinUpdate;
  374. /*
  375. ** Internal task operation status and flags
  376. */
  377. #ifndef _WIN32
  378. UINT pspTask; /* background task's PSP */
  379. UINT pspParent; /* PSP of the calling app */
  380. #else
  381. DWORD dwNTFlags; /* NT specific flags */
  382. HTASK hWaiter; // task waiting on hEventAllDone
  383. // communication between worker and winproc threads
  384. // note: next two events must be contiguous - passed to WaitForMultiple..
  385. HANDLE hThreadWinproc; // signalled on thread exit
  386. HANDLE hEventWinProcOK; // signalled on init ok
  387. HANDLE hEventWinProcDie; // tell winproc thread to die
  388. CRITICAL_SECTION WinCritSec; // protect worker - winproc interaction
  389. CRITICAL_SECTION HDCCritSec; // protect worker - winproc drawing
  390. // ** VERY IMPORTANT ** IF both critical sections are needed then they
  391. // MUST be obtained in this order: WinCrit, then HDCCrit
  392. #ifdef DEBUG
  393. DWORD WinCritSecOwner;
  394. LONG WinCritSecDepth;
  395. DWORD HDCCritSecOwner;
  396. LONG HDCCritSecDepth;
  397. #endif
  398. // winproc sets bits in this (protected by WinCritSec) to
  399. // request stop/mute actions asynchronously
  400. DWORD dwWinProcRequests;
  401. // saved state over temporary stop
  402. UINT oldState;
  403. long oldTo;
  404. long oldFrom;
  405. DWORD oldFlags;
  406. DWORD_PTR oldCallback;
  407. #endif
  408. HTASK hTask; /* task id */
  409. HTASK hCallingTask; /* task who opened us */
  410. UINT uErrorMode; /* SetErrorMode value for calling task */
  411. UINT wMessageCurrent;/* Command in progress, or zero */
  412. DWORD dwOptionFlags; /* more flags */
  413. /*
  414. ** Additional information controlled by MCI commands
  415. */
  416. HPALETTE hpal; /* Palette forced with MCI commands */
  417. HWND hwndPlayback; /* window handle for playback */
  418. HWND hwndDefault; /* default window handle */
  419. HWND hwndOldFocus; /* window which had keyboard focus */
  420. BOOL fForceBackground;/* Select palette in foreground or back? */
  421. DWORD dwTimeFormat; /* current time format */
  422. RECT rcMovie; /* main movie rect */
  423. RECT rcSource; /* drawing source rect */
  424. RECT rcDest; /* drawing destination rect */
  425. #ifdef DEBUG
  426. LONG PlaybackRate; /* 1000 is normal, more is fast.... */
  427. #endif
  428. DWORD dwSpeedFactor; /* 1000 is normal, more is fast.... */
  429. // What is this flag? We only listen to the zoom by 2 or fixed % window
  430. // size registry defaults if we're using the default window, not if
  431. // somebody is playing in their own window. But when we open an AVI,
  432. // (like we're doing now) we don't know yet what window they'll pick!
  433. // So let's make a note that so far there's no reason not to listen to
  434. // the defaults, and if anybody resizes, or changes the window handle,
  435. // or makes the default window not resizable, then we won't.
  436. BOOL fOKToUseDefaultSizing;
  437. /*
  438. * window creation parameters to open
  439. */
  440. DWORD dwStyle;
  441. HWND hwndParent;
  442. /*
  443. ** Information about currently open file
  444. */
  445. UINT uDriveType; /* drive type */
  446. NPTSTR szFilename; /* AVI filename */
  447. DWORD dwBytesPerSec; /* file attributes */
  448. DWORD dwRate; /* master time base */
  449. DWORD dwScale;
  450. DWORD dwMicroSecPerFrame;
  451. DWORD dwSuggestedBufferSize;
  452. DWORD dwKeyFrameInfo; /* how often key frames occur */
  453. UINT wEarlyAudio; /* more file information */
  454. UINT wEarlyVideo;
  455. UINT wEarlyRecords;
  456. STREAMINFO NEAR *paStreamInfo;
  457. int streams; // total streams
  458. int nAudioStreams; // total audio streams
  459. int nVideoStreams; // total video streams
  460. int nOtherStreams; // total other streams
  461. int nErrorStreams; // total error streams
  462. int nAudioStream; // current audio stream.
  463. int nVideoStream; // "master" video stream
  464. STREAMINFO *psiAudio; // points to video stream
  465. STREAMINFO *psiVideo; // points to audio stream
  466. #ifdef USEAVIFILE
  467. PAVIFILE pf;
  468. ////IAVIFileVtbl vt; // so we can call direct.
  469. #else
  470. LPVOID pf; // variable to be zero.
  471. #endif
  472. /*
  473. ** video stream junk
  474. */
  475. BOOL fNoDrawing;
  476. LONG lFrameDrawn; /* number of last frame drawn */
  477. /* Drawing information */
  478. HDC hdc; /* DC we're playing into */
  479. /* Video format */
  480. BITMAPINFOHEADER FAR *pbiFormat; /* video format information */
  481. /* BitmapInfo used for drawing */
  482. BITMAPINFOHEADER bih; /* video format information */
  483. RGBQUAD argb[256]; /* current drawing colors */
  484. RGBQUAD argbOriginal[256]; /* original colors */
  485. /*
  486. ** Installable compressor information
  487. */
  488. //!!! move all this into the screen draw function!!!
  489. //!!! all this should be in DrawDIB !!!
  490. HIC hic;
  491. HIC hicDraw;
  492. LONG cbDecompress;
  493. HPSTR hpDecompress; /* pointer to full frame buffer */
  494. /*
  495. ** Holding area for compressors we might use....
  496. */
  497. HIC hicDecompress;
  498. HIC hicDrawDefault;
  499. HIC hicDrawFull;
  500. HIC hicInternal;
  501. HIC hicInternalFull;
  502. LONG lLastPaletteChange;
  503. LONG lNextPaletteChange;
  504. /*
  505. ** wave stream junk
  506. */
  507. /* Wave format stuff */
  508. NPWAVEFORMAT pWF; /* current wave format */
  509. UINT wABs; /* number of audio buffers */
  510. UINT wABOptimal; /* number full if synchronized */
  511. DWORD dwABSize; /* size of one audio buffer */
  512. HMMIO hmmioAudio;
  513. BOOL fEmulatingVolume;/* Are we doing volume by table lookup? */
  514. BYTE * pVolumeTable;
  515. DWORD dwAudioLength;
  516. DWORD dwAudioPos;
  517. /* Wave Output Device */
  518. UINT wABFull; /* number now full */
  519. UINT wNextAB; /* next buffer in line */
  520. UINT nAudioBehind; /* how many audio below full */
  521. HPSTR lpAudio; /* pointer to audio buffers */
  522. DWORD dwUsedThisAB;
  523. /*
  524. ** File index information
  525. */
  526. AVIINDEXENTRY _huge * hpIndex; /* pointer to index */
  527. DWORD macIndex; /* # records in index */
  528. AVIFRAMEINDEX _huge * hpFrameIndex; /* pointer to frame index */
  529. HANDLE hgFrameIndex; // handle to non-offset memory
  530. /*
  531. ** play/seek params
  532. */
  533. LONG lTo; /* frame we're playing to */
  534. LONG lFrom; /* frame we're playing from */
  535. LONG lRepeatFrom; /* Frame to repeat from */
  536. /*
  537. ** Information regarding current play
  538. */
  539. UINT wPlaybackAlg; /* playback algorithm in use */
  540. LONG lAudioStart; /* first audio frame to play */
  541. LONG lVideoStart; /* first video frame to play */
  542. LONG lLastRead;
  543. /* Timing */
  544. LONG lFramePlayStart;/* Frame playing started at */
  545. DWORD dwTotalMSec; /* Total time spent playing */
  546. DWORD dwMSecPlayStart;/* Start time */
  547. DWORD dwTimingStart;
  548. DWORD dwPauseTime;
  549. DWORD dwPlayMicroSecPerFrame;
  550. DWORD dwAudioPlayed;
  551. /*
  552. ** Timing information
  553. */
  554. #ifdef DEBUG
  555. #define INTERVAL_TIMES
  556. #endif
  557. #ifdef INTERVAL_TIMES
  558. #define NBUCKETS 25
  559. #define BUCKETSIZE 10
  560. //#define NTIMES 200
  561. // frame interval timing
  562. DWORD dwStartTime;
  563. long msFrameMax;
  564. long msFrameMin;
  565. long msFrameTotal;
  566. long msSquares;
  567. long nFrames;
  568. int buckets[NBUCKETS+1];
  569. long * paIntervals;
  570. long cIntervals;
  571. //long intervals[NTIMES];
  572. long msReadTimeuS;
  573. long msReadMaxBytesPer;
  574. long msReadMax;
  575. long msReadTotal;
  576. long nReads;
  577. #endif
  578. DWORD dwLastDrawTime; /* How long did the last draw take? */
  579. DWORD dwLastReadTime;
  580. DWORD msPeriodResolution; /* Clock resolution for this video */
  581. /* Timing information kept after play completes */
  582. DWORD dwSkippedFrames; /* Frames skipped during current play */
  583. DWORD dwFramesSeekedPast; /* Frames not even read */
  584. DWORD dwAudioBreaks; /* # times audio broke up, approx. */
  585. DWORD dwSpeedPercentage; /* Ratio of ideal time to time taken */
  586. /* Timing information for last play */
  587. LONG lFramesPlayed;
  588. LONG lSkippedFrames; /* Frames skipped during last play */
  589. LONG lFramesSeekedPast; /* Frames not even read */
  590. LONG lAudioBreaks; /* # times audio broke up, approx. */
  591. /*
  592. ** Information for pending 'signal' command
  593. */
  594. DWORD dwSignals;
  595. DWORD dwSignalFlags;
  596. MCI_DGV_SIGNAL_PARMS signal;
  597. /*
  598. ** Information for watching to see if window has moved.
  599. */
  600. UINT wRgnType; /* Region type, empty, simple, complex.... */
  601. #ifdef _WIN32
  602. POINT dwOrg; /* Physical DC origin */
  603. #else
  604. DWORD dwOrg; /* Physical DC origin */
  605. #endif
  606. RECT rcClip; /* clip box */
  607. /*
  608. ** specific to RIFF files
  609. */
  610. HMMIO hmmio; /* animation file handle */
  611. BOOL fReadMany; /* read more than one record */
  612. DWORD dwFirstRecordPosition;
  613. DWORD dwFirstRecordSize;
  614. DWORD dwFirstRecordType;
  615. DWORD dwNextRecordSize; // used for ReadNextChunk
  616. DWORD dwNextRecordType;
  617. DWORD dwMovieListOffset;
  618. DWORD dwBigListEnd;
  619. /* Read Buffer */
  620. HPSTR lp; /* work pointer */
  621. LPVOID lpMMIOBuffer; /* pointer to MMIO read buffer */
  622. HPSTR lpBuffer; /* pointer to read buffer */
  623. DWORD dwBufferSize; /* Read buffer size */
  624. DWORD dwThisRecordSize; /* size of current record */
  625. /*
  626. ** DEBUG stuff and more timing info.
  627. */
  628. #ifdef DEBUG
  629. HANDLE hdd; //!!!
  630. LONG timePlay; /* total play time */
  631. LONG timePrepare; /* time to prepare for play */
  632. LONG timeCleanup; /* time to clean up play */
  633. LONG timePaused; /* paused time */
  634. LONG timeRead; /* time reading from disk */
  635. LONG timeWait; /* time waiting */
  636. LONG timeYield; /* time yielding to other apps */
  637. LONG timeVideo; /* time "drawing" video stream */
  638. LONG timeAudio; /* time "drawing" audio stream */
  639. LONG timeOther; /* time "drawing" other streams */
  640. LONG timeDraw; /* time drawing frame via DrawDib/DispDib/ICDraw */
  641. LONG timeDecompress; /* time decompressing frame via ICDecompress */
  642. #endif
  643. #ifdef AVIREAD
  644. /*
  645. * handle to current async read object
  646. */
  647. HAVIRD hAviRd;
  648. HPSTR lpOldBuffer;
  649. #endif
  650. } MCIGRAPHIC, *NPMCIGRAPHIC, FAR *LPMCIGRAPHIC;
  651. extern HANDLE ghModule; // in DRVPROC.C
  652. extern TCHAR szClassName[]; // in WINDOW.C
  653. /*
  654. ** Flags to protect ourselves in case we're closed with a dialog up...
  655. */
  656. extern BOOL gfEvil; // in GRAPHIC.C
  657. extern BOOL gfEvilSysMenu; // in GRAPHIC.C
  658. extern HDRVR ghdrvEvil; // in GRAPHIC.C
  659. /*
  660. ** Functions in GRAPHIC.C
  661. */
  662. LPCTSTR FAR FileName(LPCTSTR szPath);
  663. BOOL FAR PASCAL GraphicInit (void);
  664. BOOL NEAR PASCAL GraphicWindowInit (void);
  665. #ifdef _WIN32
  666. BOOL NEAR PASCAL GraphicWindowFree(void);
  667. void aviWinProcTask(DWORD_PTR dwInst);
  668. #endif
  669. void PASCAL GraphicFree (void);
  670. DWORD PASCAL GraphicDrvOpen (LPMCI_OPEN_DRIVER_PARMS lpParms);
  671. void FAR PASCAL GraphicDelayedNotify (NPMCIGRAPHIC npMCI, UINT wStatus);
  672. void FAR PASCAL GraphicImmediateNotify (UINT wDevID,
  673. LPMCI_GENERIC_PARMS lpParms,
  674. DWORD dwFlags, DWORD dwErr);
  675. DWORD PASCAL GraphicClose(NPMCIGRAPHIC npMCI);
  676. DWORD NEAR PASCAL ConvertFromFrames(NPMCIGRAPHIC npMCI, LONG lFrame);
  677. LONG NEAR PASCAL ConvertToFrames(NPMCIGRAPHIC npMCI, DWORD dwTime);
  678. DWORD PASCAL mciDriverEntry(UINT wDeviceID, UINT wMessage, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
  679. LRESULT FAR PASCAL _loadds GraphicWndProc(HWND, UINT, WPARAM, LPARAM);
  680. void CheckWindowMove(NPMCIGRAPHIC npMCI, BOOL fForce);
  681. DWORD InternalGetPosition(NPMCIGRAPHIC npMCI, LPLONG lpl);
  682. // now called only on worker thread
  683. void NEAR PASCAL GraphicSaveCallback (NPMCIGRAPHIC npMCI, HANDLE hCallback);
  684. /*
  685. * Functions in DEVICE.C
  686. *
  687. * All these DeviceXXX functions are called on USER THREAD ONLY (ok?)
  688. * EXCEPT for DeviceSetActive which is called on the winproc thread.
  689. * (From InternalRealize...CheckIfActive...DeviceSetActive)
  690. */
  691. DWORD PASCAL DeviceOpen(NPMCIGRAPHIC npMCI, DWORD dwFlags);
  692. DWORD PASCAL DeviceClose(NPMCIGRAPHIC npMCI);
  693. DWORD PASCAL DevicePlay(
  694. NPMCIGRAPHIC npMCI,
  695. DWORD dwFlags,
  696. LPMCI_DGV_PLAY_PARMS lpPlay,
  697. LPARAM dwCallback
  698. );
  699. DWORD PASCAL DeviceResume(NPMCIGRAPHIC npMCI, DWORD dwFlags, LPARAM dwCallback);
  700. DWORD PASCAL DeviceCue(NPMCIGRAPHIC npMCI, LONG lTo, DWORD dwFlags, LPARAM dwCallback);
  701. DWORD PASCAL DeviceStop(NPMCIGRAPHIC npMCI, DWORD dwFlags);
  702. DWORD PASCAL DevicePause(NPMCIGRAPHIC npMCI, DWORD dwFlags, LPARAM dwCallback);
  703. DWORD PASCAL DeviceSeek(NPMCIGRAPHIC npMCI, LONG lTo, DWORD dwFlags, LPARAM dwCallback);
  704. DWORD PASCAL DeviceRealize(NPMCIGRAPHIC npMCI);
  705. DWORD PASCAL DeviceUpdate(NPMCIGRAPHIC npMCI, DWORD dwFlags, LPMCI_DGV_UPDATE_PARMS lpParms);
  706. UINT PASCAL DeviceMode(NPMCIGRAPHIC npMCI);
  707. DWORD PASCAL DevicePosition(NPMCIGRAPHIC npMCI, LPLONG lpl);
  708. DWORD PASCAL DeviceSetWindow(NPMCIGRAPHIC npMCI, HWND hwnd);
  709. DWORD PASCAL DeviceSetSpeed(NPMCIGRAPHIC npMCI, DWORD dwNewSpeed);
  710. DWORD PASCAL DeviceMute(NPMCIGRAPHIC npMCI, BOOL fMute);
  711. DWORD PASCAL DeviceSetVolume(NPMCIGRAPHIC npMCI, DWORD dwVolume);
  712. DWORD PASCAL DeviceGetVolume(NPMCIGRAPHIC npMCI);
  713. DWORD PASCAL DeviceSetAudioStream(NPMCIGRAPHIC npMCI, UINT uStream);
  714. DWORD PASCAL DeviceSetVideoStream(NPMCIGRAPHIC npMCI, UINT uStream, BOOL fOn);
  715. DWORD PASCAL DeviceSetActive(NPMCIGRAPHIC npMCI, BOOL fActive);
  716. DWORD FAR PASCAL DevicePut(NPMCIGRAPHIC npMCI, LPRECT lprc, DWORD dwFlags);
  717. DWORD FAR PASCAL DeviceSetPalette(NPMCIGRAPHIC npMCI, HPALETTE hpal);
  718. DWORD FAR PASCAL DeviceSetPaletteColor(NPMCIGRAPHIC npMCI, DWORD index, DWORD color);
  719. void CheckIfActive(NPMCIGRAPHIC npMCI);
  720. // in window.c
  721. void FAR PASCAL AlterRectUsingDefaults(NPMCIGRAPHIC npMCI, LPRECT lprc);
  722. void FAR PASCAL SetWindowToDefaultSize(NPMCIGRAPHIC npMCI, BOOL fUseDefaultSizing);
  723. // user thread version
  724. void FAR PASCAL ResetDestRect(NPMCIGRAPHIC npMCI, BOOL fUseDefaultSizing);
  725. // same as ResetDestRect, but called on winproc thread
  726. void FAR PASCAL Winproc_DestRect(NPMCIGRAPHIC npMCI, BOOL fUseDefaultSizing);
  727. DWORD FAR PASCAL ReadConfigInfo(void);
  728. void FAR PASCAL WriteConfigInfo(DWORD dwOptions);
  729. BOOL FAR PASCAL ConfigDialog(HWND, NPMCIGRAPHIC);
  730. /*
  731. ** The Enumerate command isn't real: I'm just thinking about it.
  732. */
  733. #define MCI_ENUMERATE 0x0901
  734. #define MCI_ENUMERATE_STREAM 0x00000001L
  735. // constants for dwItem field of MCI_STATUS_PARMS parameter block
  736. #define MCI_AVI_STATUS_STREAMCOUNT 0x10000001L
  737. #define MCI_AVI_STATUS_STREAMTYPE 0x10000002L
  738. #define MCI_AVI_STATUS_STREAMENABLED 0x10000003L
  739. // flags for dwFlags field of MCI_STATUS_PARMS parameter block
  740. #define MCI_AVI_STATUS_STREAM 0x10000000L
  741. // flags for dwFlags field of MCI_SET_PARMS parameter block
  742. #define MCI_AVI_SET_STREAM 0x10000000L
  743. #define MCI_AVI_SET_USERPROC 0x20000000L
  744. /*
  745. ** Internal flag that can be used with SEEK
  746. */
  747. #define MCI_AVI_SEEK_SHOWWINDOW 0x10000000L
  748. /*
  749. ** in AVIPLAY.C (and GRAPHIC.C)
  750. */
  751. extern INT gwSkipTolerance;
  752. extern INT gwHurryTolerance;
  753. extern INT gwMaxSkipEver;
  754. extern BOOL gfUseGetPosition;
  755. extern LONG giGetPositionAdjust;
  756. #ifdef _WIN32
  757. #define DEFAULTUSEGETPOSITION TRUE
  758. #else
  759. #define DEFAULTUSEGETPOSITION FALSE
  760. #endif
  761. /**************************************************************************
  762. **************************************************************************/
  763. #ifdef DEBUG
  764. #define TIMEZERO(time) npMCI->time = 0;
  765. #define TIMESTART(time) npMCI->time -= (LONG)timeGetTime()
  766. #define TIMEEND(time) npMCI->time += (LONG)timeGetTime()
  767. #else
  768. #define TIMEZERO(time)
  769. #define TIMESTART(time)
  770. #define TIMEEND(time)
  771. #endif
  772. /**************************************************************************
  773. **************************************************************************/
  774. #define FOURCC_AVIDraw mmioFOURCC('D','R','A','W')
  775. #define FOURCC_AVIFull mmioFOURCC('F','U','L','L')
  776. LRESULT FAR PASCAL _loadds ICAVIDrawProc(DWORD_PTR id, HDRVR hDriver, UINT uiMessage, LPARAM lParam1, LPARAM lParam2);
  777. LRESULT FAR PASCAL _loadds ICAVIFullProc(DWORD_PTR id, HDRVR hDriver, UINT uiMessage, LPARAM lParam1, LPARAM lParam2);
  778. /**************************************************************************
  779. **************************************************************************/
  780. #include "avitask.h"
  781. /**************************************************************************
  782. Macros and constants for accessing the list of open MCI devices.
  783. In the debug build we track who has access to the list.
  784. **************************************************************************/
  785. extern NPMCIGRAPHIC npMCIList; // in graphic.c
  786. #ifdef _WIN32
  787. extern CRITICAL_SECTION MCIListCritSec; // in graphic.c
  788. #ifdef DEBUG
  789. // The debug versions of the macros track who owns the critical section
  790. extern DWORD ListOwner;
  791. #define EnterList() { EnterCriticalSection(&MCIListCritSec); \
  792. ListOwner=GetCurrentThreadId();\
  793. }
  794. #define LeaveList() { ListOwner=0;\
  795. LeaveCriticalSection(&MCIListCritSec);\
  796. }
  797. #else // !debug
  798. #define EnterList() EnterCriticalSection(&MCIListCritSec);
  799. #define LeaveList() LeaveCriticalSection(&MCIListCritSec);
  800. #endif //DEBUG
  801. // this critical section is used to protect drawing code from
  802. // interaction between the winproc and the worker thread. the user
  803. // thread should not need to hold this ever.
  804. #ifdef DEBUG
  805. // The debug versions of the EnterWinCrit/LeaveWinCrit macros track who
  806. // owns the window critical section. This makes it possible to Assert
  807. // in the code that we are validly in (or out) of the critical section.
  808. #define EnterWinCrit(p) { EnterCriticalSection(&(p)->WinCritSec); \
  809. (p)->WinCritSecOwner=GetCurrentThreadId(); \
  810. /* The first enter should mean that we do */\
  811. /* NOT own the HDC critical section */\
  812. if (!((p)->WinCritSecDepth++)) \
  813. { HDCCritCheckOut(p) }; \
  814. }
  815. #define LeaveWinCrit(p) { if(0 == (--(p)->WinCritSecDepth)) \
  816. (p)->WinCritSecOwner=0; \
  817. if ((p)->WinCritSecDepth<0) { \
  818. DebugBreak(); \
  819. } \
  820. LeaveCriticalSection(&(p)->WinCritSec); \
  821. }
  822. #define WinCritCheckIn(p) if ((p)->WinCritSecOwner != GetCurrentThreadId())\
  823. Assert(!"Should own the window critical section");
  824. #define WinCritCheckOut(p) if ((p)->WinCritSecOwner == GetCurrentThreadId()) \
  825. Assert(!"Should not own the window critical section");
  826. #define EnterHDCCrit(p) { EnterCriticalSection(&(p)->HDCCritSec); \
  827. (p)->HDCCritSecOwner=GetCurrentThreadId(); \
  828. (p)->HDCCritSecDepth++; \
  829. }
  830. #define LeaveHDCCrit(p) { if(0 == (--(p)->HDCCritSecDepth)) \
  831. (p)->HDCCritSecOwner=0; \
  832. if ((p)->HDCCritSecDepth<0) { \
  833. DebugBreak(); \
  834. } \
  835. LeaveCriticalSection(&(p)->HDCCritSec); \
  836. }
  837. #define HDCCritCheckIn(p) if ((p)->HDCCritSecOwner != GetCurrentThreadId())\
  838. Assert(!"Should own the hdc critical section");
  839. #define HDCCritCheckOut(p) if ((p)->HDCCritSecOwner == GetCurrentThreadId()) \
  840. Assert(!"Should not own the hdc critical section");
  841. #else // Non debug versions
  842. #define EnterWinCrit(npMCI) EnterCriticalSection(&npMCI->WinCritSec)
  843. #define LeaveWinCrit(npMCI) LeaveCriticalSection(&npMCI->WinCritSec)
  844. #define WinCritCheckIn(p)
  845. #define WinCritCheckOut(p)
  846. #define EnterHDCCrit(npMCI) EnterCriticalSection(&npMCI->HDCCritSec)
  847. #define LeaveHDCCrit(npMCI) LeaveCriticalSection(&npMCI->HDCCritSec)
  848. #define HDCCritCheckIn(p)
  849. #define HDCCritCheckOut(p)
  850. #endif
  851. #else // !_WIN32
  852. #define EnterList()
  853. #define LeaveList()
  854. #define EnterWinCrit(n)
  855. #define LeaveWinCrit(n)
  856. #endif
  857. #endif // RC_INVOKED