Leaked source code of windows server 2003
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.

418 lines
16 KiB

  1. //------------------------------------------------------------------------------
  2. // File: WinUtil.h
  3. //
  4. // Desc: DirectShow base classes - defines generic handler classes.
  5. //
  6. //@@BEGIN_MSINTERNAL
  7. //
  8. // December 1995
  9. //
  10. //@@END_MSINTERNAL
  11. // Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
  12. //------------------------------------------------------------------------------
  13. // Make sure that you call PrepareWindow to initialise the window after
  14. // the object has been constructed. It is a separate method so that
  15. // derived classes can override useful methods like MessageLoop. Also
  16. // any derived class must call DoneWithWindow in its destructor. If it
  17. // doesn't a message may be retrieved and call a derived class member
  18. // function while a thread is executing the base class destructor code
  19. #ifndef __WINUTIL__
  20. #define __WINUTIL__
  21. const int DEFWIDTH = 320; // Initial window width
  22. const int DEFHEIGHT = 240; // Initial window height
  23. const int CAPTION = 256; // Maximum length of caption
  24. const int TIMELENGTH = 50; // Maximum length of times
  25. const int PROFILESTR = 128; // Normal profile string
  26. const WORD PALVERSION = 0x300; // GDI palette version
  27. const LONG PALETTE_VERSION = (LONG) 1; // Initial palette version
  28. const COLORREF VIDEO_COLOUR = 0; // Defaults to black background
  29. const HANDLE hMEMORY = (HANDLE) (-1); // Says to open as memory file
  30. #define WIDTH(x) ((*(x)).right - (*(x)).left)
  31. #define HEIGHT(x) ((*(x)).bottom - (*(x)).top)
  32. #define SHOWSTAGE TEXT("WM_SHOWSTAGE")
  33. #define SHOWSTAGETOP TEXT("WM_SHOWSTAGETOP")
  34. #define REALIZEPALETTE TEXT("WM_REALIZEPALETTE")
  35. class AM_NOVTABLE CBaseWindow
  36. {
  37. protected:
  38. HINSTANCE m_hInstance; // Global module instance handle
  39. HWND m_hwnd; // Handle for our window
  40. HDC m_hdc; // Device context for the window
  41. LONG m_Width; // Client window width
  42. LONG m_Height; // Client window height
  43. BOOL m_bActivated; // Has the window been activated
  44. LPTSTR m_pClassName; // Static string holding class name
  45. DWORD m_ClassStyles; // Passed in to our constructor
  46. DWORD m_WindowStyles; // Likewise the initial window styles
  47. DWORD m_WindowStylesEx; // And the extended window styles
  48. UINT m_ShowStageMessage; // Have the window shown with focus
  49. UINT m_ShowStageTop; // Makes the window WS_EX_TOPMOST
  50. UINT m_RealizePalette; // Makes us realize our new palette
  51. HDC m_MemoryDC; // Used for fast BitBlt operations
  52. HPALETTE m_hPalette; // Handle to any palette we may have
  53. BYTE m_bNoRealize; // Don't realize palette now
  54. BYTE m_bBackground; // Should we realise in background
  55. BYTE m_bRealizing; // already realizing the palette
  56. CCritSec m_WindowLock; // Serialise window object access
  57. BOOL m_bDoGetDC; // Should this window get a DC
  58. bool m_bDoPostToDestroy; // Use PostMessage to destroy
  59. CCritSec m_PaletteLock; // This lock protects m_hPalette.
  60. // It should be held anytime the
  61. // program use the value of m_hPalette.
  62. // Maps windows message procedure into C++ methods
  63. friend LRESULT CALLBACK WndProc(HWND hwnd, // Window handle
  64. UINT uMsg, // Message ID
  65. WPARAM wParam, // First parameter
  66. LPARAM lParam); // Other parameter
  67. virtual LRESULT OnPaletteChange(HWND hwnd, UINT Message);
  68. public:
  69. CBaseWindow(BOOL bDoGetDC = TRUE, bool bPostToDestroy = false);
  70. #ifdef DEBUG
  71. virtual ~CBaseWindow();
  72. #endif
  73. virtual HRESULT DoneWithWindow();
  74. virtual HRESULT PrepareWindow();
  75. virtual HRESULT InactivateWindow();
  76. virtual HRESULT ActivateWindow();
  77. virtual BOOL OnSize(LONG Width, LONG Height);
  78. virtual BOOL OnClose();
  79. virtual RECT GetDefaultRect();
  80. virtual HRESULT UninitialiseWindow();
  81. virtual HRESULT InitialiseWindow(HWND hwnd);
  82. HRESULT CompleteConnect();
  83. HRESULT DoCreateWindow();
  84. HRESULT PerformanceAlignWindow();
  85. HRESULT DoShowWindow(LONG ShowCmd);
  86. void PaintWindow(BOOL bErase);
  87. void DoSetWindowForeground(BOOL bFocus);
  88. virtual HRESULT SetPalette(HPALETTE hPalette);
  89. void SetRealize(BOOL bRealize)
  90. {
  91. m_bNoRealize = !bRealize;
  92. }
  93. // Jump over to the window thread to set the current palette
  94. HRESULT SetPalette();
  95. void UnsetPalette(void);
  96. virtual HRESULT DoRealisePalette(BOOL bForceBackground = FALSE);
  97. void LockPaletteLock();
  98. void UnlockPaletteLock();
  99. virtual BOOL PossiblyEatMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
  100. { return FALSE; };
  101. // Access our window information
  102. bool WindowExists();
  103. LONG GetWindowWidth();
  104. LONG GetWindowHeight();
  105. HWND GetWindowHWND();
  106. HDC GetMemoryHDC();
  107. HDC GetWindowHDC();
  108. #ifdef DEBUG
  109. HPALETTE GetPalette();
  110. #endif // DEBUG
  111. // This is the window procedure the derived object should override
  112. virtual LRESULT OnReceiveMessage(HWND hwnd, // Window handle
  113. UINT uMsg, // Message ID
  114. WPARAM wParam, // First parameter
  115. LPARAM lParam); // Other parameter
  116. // Must be overriden to return class and window styles
  117. virtual LPTSTR GetClassWindowStyles(
  118. DWORD *pClassStyles, // Class styles
  119. DWORD *pWindowStyles, // Window styles
  120. DWORD *pWindowStylesEx) PURE; // Extended styles
  121. };
  122. // This helper class is entirely subservient to the owning CBaseWindow object
  123. // All this object does is to split out the actual drawing operation from the
  124. // main object (because it was becoming too large). We have a number of entry
  125. // points to set things like the draw device contexts, to implement the actual
  126. // drawing and to set the destination rectangle in the client window. We have
  127. // no critical section locking in this class because we are used exclusively
  128. // by the owning window object which looks after serialising calls into us
  129. // If you want to use this class make sure you call NotifyAllocator once the
  130. // allocate has been agreed, also call NotifyMediaType with a pointer to a
  131. // NON stack based CMediaType once that has been set (we keep a pointer to
  132. // the original rather than taking a copy). When the palette changes call
  133. // IncrementPaletteVersion (easiest thing to do is to also call this method
  134. // in the SetMediaType method most filters implement). Finally before you
  135. // start rendering anything call SetDrawContext so that we can get the HDCs
  136. // for drawing from the CBaseWindow object we are given during construction
  137. class CDrawImage
  138. {
  139. protected:
  140. CBaseWindow *m_pBaseWindow; // Owning video window object
  141. CRefTime m_StartSample; // Start time for the current sample
  142. CRefTime m_EndSample; // And likewise it's end sample time
  143. HDC m_hdc; // Main window device context
  144. HDC m_MemoryDC; // Offscreen draw device context
  145. RECT m_TargetRect; // Target destination rectangle
  146. RECT m_SourceRect; // Source image rectangle
  147. BOOL m_bStretch; // Do we have to stretch the images
  148. BOOL m_bUsingImageAllocator; // Are the samples shared DIBSECTIONs
  149. CMediaType *m_pMediaType; // Pointer to the current format
  150. int m_perfidRenderTime; // Time taken to render an image
  151. LONG m_PaletteVersion; // Current palette version cookie
  152. // Draw the video images in the window
  153. void SlowRender(IMediaSample *pMediaSample);
  154. void FastRender(IMediaSample *pMediaSample);
  155. void DisplaySampleTimes(IMediaSample *pSample);
  156. void UpdateColourTable(HDC hdc,BITMAPINFOHEADER *pbmi);
  157. void SetStretchMode();
  158. public:
  159. // Used to control the image drawing
  160. CDrawImage(CBaseWindow *pBaseWindow);
  161. BOOL DrawImage(IMediaSample *pMediaSample);
  162. BOOL DrawVideoImageHere(HDC hdc, IMediaSample *pMediaSample,
  163. LPRECT lprcSrc, LPRECT lprcDst);
  164. void SetDrawContext();
  165. void SetTargetRect(RECT *pTargetRect);
  166. void SetSourceRect(RECT *pSourceRect);
  167. void GetTargetRect(RECT *pTargetRect);
  168. void GetSourceRect(RECT *pSourceRect);
  169. virtual RECT ScaleSourceRect(const RECT *pSource);
  170. // Handle updating palettes as they change
  171. LONG GetPaletteVersion();
  172. void ResetPaletteVersion();
  173. void IncrementPaletteVersion();
  174. // Tell us media types and allocator assignments
  175. void NotifyAllocator(BOOL bUsingImageAllocator);
  176. void NotifyMediaType(CMediaType *pMediaType);
  177. BOOL UsingImageAllocator();
  178. // Called when we are about to draw an image
  179. void NotifyStartDraw() {
  180. MSR_START(m_perfidRenderTime);
  181. };
  182. // Called when we complete an image rendering
  183. void NotifyEndDraw() {
  184. MSR_STOP(m_perfidRenderTime);
  185. };
  186. };
  187. // This is the structure used to keep information about each GDI DIB. All the
  188. // samples we create from our allocator will have a DIBSECTION allocated to
  189. // them. When we receive the sample we know we can BitBlt straight to an HDC
  190. typedef struct tagDIBDATA {
  191. LONG PaletteVersion; // Current palette version in use
  192. DIBSECTION DibSection; // Details of DIB section allocated
  193. HBITMAP hBitmap; // Handle to bitmap for drawing
  194. HANDLE hMapping; // Handle to shared memory block
  195. BYTE *pBase; // Pointer to base memory address
  196. } DIBDATA;
  197. // This class inherits from CMediaSample and uses all of it's methods but it
  198. // overrides the constructor to initialise itself with the DIBDATA structure
  199. // When we come to render an IMediaSample we will know if we are using our own
  200. // allocator, and if we are, we can cast the IMediaSample to a pointer to one
  201. // of these are retrieve the DIB section information and hence the HBITMAP
  202. class CImageSample : public CMediaSample
  203. {
  204. protected:
  205. DIBDATA m_DibData; // Information about the DIBSECTION
  206. BOOL m_bInit; // Is the DIB information setup
  207. public:
  208. // Constructor
  209. CImageSample(CBaseAllocator *pAllocator,
  210. TCHAR *pName,
  211. HRESULT *phr,
  212. LPBYTE pBuffer,
  213. LONG length);
  214. // Maintain the DIB/DirectDraw state
  215. void SetDIBData(DIBDATA *pDibData);
  216. DIBDATA *GetDIBData();
  217. };
  218. // This is an allocator based on the abstract CBaseAllocator base class that
  219. // allocates sample buffers in shared memory. The number and size of these
  220. // are determined when the output pin calls Prepare on us. The shared memory
  221. // blocks are used in subsequent calls to GDI CreateDIBSection, once that
  222. // has been done the output pin can fill the buffers with data which will
  223. // then be handed to GDI through BitBlt calls and thereby remove one copy
  224. class CImageAllocator : public CBaseAllocator
  225. {
  226. protected:
  227. CBaseFilter *m_pFilter; // Delegate reference counts to
  228. CMediaType *m_pMediaType; // Pointer to the current format
  229. // Used to create and delete samples
  230. HRESULT Alloc();
  231. void Free();
  232. // Manage the shared DIBSECTION and DCI/DirectDraw buffers
  233. HRESULT CreateDIB(LONG InSize,DIBDATA &DibData);
  234. STDMETHODIMP CheckSizes(ALLOCATOR_PROPERTIES *pRequest);
  235. virtual CImageSample *CreateImageSample(LPBYTE pData,LONG Length);
  236. public:
  237. // Constructor and destructor
  238. CImageAllocator(CBaseFilter *pFilter,TCHAR *pName,HRESULT *phr);
  239. #ifdef DEBUG
  240. ~CImageAllocator();
  241. #endif
  242. STDMETHODIMP_(ULONG) NonDelegatingAddRef();
  243. STDMETHODIMP_(ULONG) NonDelegatingRelease();
  244. void NotifyMediaType(CMediaType *pMediaType);
  245. // Agree the number of buffers to be used and their size
  246. STDMETHODIMP SetProperties(
  247. ALLOCATOR_PROPERTIES *pRequest,
  248. ALLOCATOR_PROPERTIES *pActual);
  249. };
  250. // This class is a fairly specialised helper class for image renderers that
  251. // have to create and manage palettes. The CBaseWindow class looks after
  252. // realising palettes once they have been installed. This class can be used
  253. // to create the palette handles from a media format (which must contain a
  254. // VIDEOINFO structure in the format block). We try to make the palette an
  255. // identity palette to maximise performance and also only change palettes
  256. // if actually required to (we compare palette colours before updating).
  257. // All the methods are virtual so that they can be overriden if so required
  258. class CImagePalette
  259. {
  260. protected:
  261. CBaseWindow *m_pBaseWindow; // Window to realise palette in
  262. CBaseFilter *m_pFilter; // Media filter to send events
  263. CDrawImage *m_pDrawImage; // Object who will be drawing
  264. HPALETTE m_hPalette; // The palette handle we own
  265. public:
  266. CImagePalette(CBaseFilter *pBaseFilter,
  267. CBaseWindow *pBaseWindow,
  268. CDrawImage *pDrawImage);
  269. #ifdef DEBUG
  270. virtual ~CImagePalette();
  271. #endif
  272. static HPALETTE MakePalette(const VIDEOINFOHEADER *pVideoInfo, LPSTR szDevice);
  273. HRESULT RemovePalette();
  274. static HRESULT MakeIdentityPalette(PALETTEENTRY *pEntry,INT iColours, LPSTR szDevice);
  275. HRESULT CopyPalette(const CMediaType *pSrc,CMediaType *pDest);
  276. BOOL ShouldUpdate(const VIDEOINFOHEADER *pNewInfo,const VIDEOINFOHEADER *pOldInfo);
  277. HRESULT PreparePalette(const CMediaType *pmtNew,const CMediaType *pmtOld,LPSTR szDevice);
  278. BOOL DrawVideoImageHere(HDC hdc, IMediaSample *pMediaSample, LPRECT lprcSrc, LPRECT lprcDst)
  279. {
  280. return m_pDrawImage->DrawVideoImageHere(hdc, pMediaSample, lprcSrc,lprcDst);
  281. }
  282. };
  283. // Another helper class really for video based renderers. Most such renderers
  284. // need to know what the display format is to some degree or another. This
  285. // class initialises itself with the display format. The format can be asked
  286. // for through GetDisplayFormat and various other accessor functions. If a
  287. // filter detects a display format change (perhaps it gets a WM_DEVMODECHANGE
  288. // message then it can call RefreshDisplayType to reset that format). Also
  289. // many video renderers will want to check formats as they are proposed by
  290. // source filters. This class provides methods to check formats and only
  291. // accept those video formats that can be efficiently drawn using GDI calls
  292. class CImageDisplay : public CCritSec
  293. {
  294. protected:
  295. // This holds the display format; biSize should not be too big, so we can
  296. // safely use the VIDEOINFO structure
  297. VIDEOINFO m_Display;
  298. static DWORD CountSetBits(const DWORD Field);
  299. static DWORD CountPrefixBits(const DWORD Field);
  300. static BOOL CheckBitFields(const VIDEOINFO *pInput);
  301. public:
  302. // Constructor and destructor
  303. CImageDisplay();
  304. // Used to manage BITMAPINFOHEADERs and the display format
  305. const VIDEOINFO *GetDisplayFormat();
  306. HRESULT RefreshDisplayType(LPSTR szDeviceName);
  307. static BOOL CheckHeaderValidity(const VIDEOINFO *pInput);
  308. static BOOL CheckPaletteHeader(const VIDEOINFO *pInput);
  309. BOOL IsPalettised();
  310. WORD GetDisplayDepth();
  311. // Provide simple video format type checking
  312. HRESULT CheckMediaType(const CMediaType *pmtIn);
  313. HRESULT CheckVideoType(const VIDEOINFO *pInput);
  314. HRESULT UpdateFormat(VIDEOINFO *pVideoInfo);
  315. const DWORD *GetBitMasks(const VIDEOINFO *pVideoInfo);
  316. BOOL GetColourMask(DWORD *pMaskRed,
  317. DWORD *pMaskGreen,
  318. DWORD *pMaskBlue);
  319. };
  320. // Convert a FORMAT_VideoInfo to FORMAT_VideoInfo2
  321. STDAPI ConvertVideoInfoToVideoInfo2(AM_MEDIA_TYPE *pmt);
  322. #endif // __WINUTIL__