winutil.h 16 KB

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