From 166b6c5d61711b218ca14a4aac54c7fd8ba94e07 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 8 May 2015 20:59:10 -0400 Subject: [PATCH] Time to remove these unused files. --- src/BaseClasses/AMVIDEO.H | 417 --- src/BaseClasses/Debug/strmbasd.lib | Bin 1851572 -> 0 bytes src/BaseClasses/Debug/vc60.pdb | Bin 831488 -> 0 bytes src/BaseClasses/Release/STRMBASE.lib | Bin 1065040 -> 0 bytes src/BaseClasses/activex.rcv | 140 - src/BaseClasses/activex.ver | 56 - src/BaseClasses/amextra.cpp | 111 - src/BaseClasses/amextra.h | 56 - src/BaseClasses/amfilter.cpp | 5207 -------------------------- src/BaseClasses/amfilter.h | 1589 -------- src/BaseClasses/amvideo.cpp | 275 -- src/BaseClasses/baseclasses.dsp | 322 -- src/BaseClasses/baseclasses.dsw | 29 - src/BaseClasses/baseclasses.mak | 456 --- src/BaseClasses/cache.h | 74 - src/BaseClasses/combase.cpp | 254 -- src/BaseClasses/combase.h | 319 -- src/BaseClasses/cprop.cpp | 380 -- src/BaseClasses/cprop.h | 95 - src/BaseClasses/ctlutil.cpp | 2378 ------------ src/BaseClasses/ctlutil.h | 919 ----- src/BaseClasses/ddmm.cpp | 126 - src/BaseClasses/ddmm.h | 28 - src/BaseClasses/dllentry.cpp | 332 -- src/BaseClasses/dllsetup.cpp | 651 ---- src/BaseClasses/dllsetup.h | 46 - src/BaseClasses/dsschedule.h | 132 - src/BaseClasses/fourcc.h | 100 - src/BaseClasses/measure.h | 222 -- src/BaseClasses/msgthrd.h | 120 - src/BaseClasses/mtype.cpp | 478 --- src/BaseClasses/mtype.h | 89 - src/BaseClasses/outputq.cpp | 790 ---- src/BaseClasses/outputq.h | 137 - src/BaseClasses/pstream.cpp | 196 - src/BaseClasses/pstream.h | 114 - src/BaseClasses/pullpin.cpp | 510 --- src/BaseClasses/pullpin.h | 152 - src/BaseClasses/readme.txt | 25 - src/BaseClasses/refclock.cpp | 308 -- src/BaseClasses/refclock.h | 169 - src/BaseClasses/reftime.h | 116 - src/BaseClasses/renbase.cpp | 2833 -------------- src/BaseClasses/renbase.h | 479 --- src/BaseClasses/schedule.cpp | 265 -- src/BaseClasses/seekpt.cpp | 83 - src/BaseClasses/seekpt.h | 30 - src/BaseClasses/source.cpp | 519 --- src/BaseClasses/source.h | 172 - src/BaseClasses/streams.h | 172 - src/BaseClasses/strmctl.cpp | 386 -- src/BaseClasses/strmctl.h | 158 - src/BaseClasses/sysclock.cpp | 75 - src/BaseClasses/sysclock.h | 39 - src/BaseClasses/transfrm.cpp | 974 ----- src/BaseClasses/transfrm.h | 304 -- src/BaseClasses/transip.cpp | 922 ----- src/BaseClasses/transip.h | 246 -- src/BaseClasses/videoctl.cpp | 653 ---- src/BaseClasses/videoctl.h | 178 - src/BaseClasses/vtrans.cpp | 468 --- src/BaseClasses/vtrans.h | 143 - src/BaseClasses/winctrl.cpp | 1977 ---------- src/BaseClasses/winctrl.h | 224 -- src/BaseClasses/winutil.cpp | 2696 ------------- src/BaseClasses/winutil.h | 414 -- src/BaseClasses/wxdebug.cpp | 1311 ------- src/BaseClasses/wxdebug.h | 379 -- src/BaseClasses/wxlist.cpp | 885 ----- src/BaseClasses/wxlist.h | 551 --- src/BaseClasses/wxutil.cpp | 1210 ------ src/BaseClasses/wxutil.h | 533 --- 72 files changed, 37197 deletions(-) delete mode 100644 src/BaseClasses/AMVIDEO.H delete mode 100644 src/BaseClasses/Debug/strmbasd.lib delete mode 100644 src/BaseClasses/Debug/vc60.pdb delete mode 100644 src/BaseClasses/Release/STRMBASE.lib delete mode 100644 src/BaseClasses/activex.rcv delete mode 100644 src/BaseClasses/activex.ver delete mode 100644 src/BaseClasses/amextra.cpp delete mode 100644 src/BaseClasses/amextra.h delete mode 100644 src/BaseClasses/amfilter.cpp delete mode 100644 src/BaseClasses/amfilter.h delete mode 100644 src/BaseClasses/amvideo.cpp delete mode 100644 src/BaseClasses/baseclasses.dsp delete mode 100644 src/BaseClasses/baseclasses.dsw delete mode 100644 src/BaseClasses/baseclasses.mak delete mode 100644 src/BaseClasses/cache.h delete mode 100644 src/BaseClasses/combase.cpp delete mode 100644 src/BaseClasses/combase.h delete mode 100644 src/BaseClasses/cprop.cpp delete mode 100644 src/BaseClasses/cprop.h delete mode 100644 src/BaseClasses/ctlutil.cpp delete mode 100644 src/BaseClasses/ctlutil.h delete mode 100644 src/BaseClasses/ddmm.cpp delete mode 100644 src/BaseClasses/ddmm.h delete mode 100644 src/BaseClasses/dllentry.cpp delete mode 100644 src/BaseClasses/dllsetup.cpp delete mode 100644 src/BaseClasses/dllsetup.h delete mode 100644 src/BaseClasses/dsschedule.h delete mode 100644 src/BaseClasses/fourcc.h delete mode 100644 src/BaseClasses/measure.h delete mode 100644 src/BaseClasses/msgthrd.h delete mode 100644 src/BaseClasses/mtype.cpp delete mode 100644 src/BaseClasses/mtype.h delete mode 100644 src/BaseClasses/outputq.cpp delete mode 100644 src/BaseClasses/outputq.h delete mode 100644 src/BaseClasses/pstream.cpp delete mode 100644 src/BaseClasses/pstream.h delete mode 100644 src/BaseClasses/pullpin.cpp delete mode 100644 src/BaseClasses/pullpin.h delete mode 100644 src/BaseClasses/readme.txt delete mode 100644 src/BaseClasses/refclock.cpp delete mode 100644 src/BaseClasses/refclock.h delete mode 100644 src/BaseClasses/reftime.h delete mode 100644 src/BaseClasses/renbase.cpp delete mode 100644 src/BaseClasses/renbase.h delete mode 100644 src/BaseClasses/schedule.cpp delete mode 100644 src/BaseClasses/seekpt.cpp delete mode 100644 src/BaseClasses/seekpt.h delete mode 100644 src/BaseClasses/source.cpp delete mode 100644 src/BaseClasses/source.h delete mode 100644 src/BaseClasses/streams.h delete mode 100644 src/BaseClasses/strmctl.cpp delete mode 100644 src/BaseClasses/strmctl.h delete mode 100644 src/BaseClasses/sysclock.cpp delete mode 100644 src/BaseClasses/sysclock.h delete mode 100644 src/BaseClasses/transfrm.cpp delete mode 100644 src/BaseClasses/transfrm.h delete mode 100644 src/BaseClasses/transip.cpp delete mode 100644 src/BaseClasses/transip.h delete mode 100644 src/BaseClasses/videoctl.cpp delete mode 100644 src/BaseClasses/videoctl.h delete mode 100644 src/BaseClasses/vtrans.cpp delete mode 100644 src/BaseClasses/vtrans.h delete mode 100644 src/BaseClasses/winctrl.cpp delete mode 100644 src/BaseClasses/winctrl.h delete mode 100644 src/BaseClasses/winutil.cpp delete mode 100644 src/BaseClasses/winutil.h delete mode 100644 src/BaseClasses/wxdebug.cpp delete mode 100644 src/BaseClasses/wxdebug.h delete mode 100644 src/BaseClasses/wxlist.cpp delete mode 100644 src/BaseClasses/wxlist.h delete mode 100644 src/BaseClasses/wxutil.cpp delete mode 100644 src/BaseClasses/wxutil.h diff --git a/src/BaseClasses/AMVIDEO.H b/src/BaseClasses/AMVIDEO.H deleted file mode 100644 index d39ed42b5f..0000000000 --- a/src/BaseClasses/AMVIDEO.H +++ /dev/null @@ -1,417 +0,0 @@ -//==========================================================================; -// -// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY -// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR -// PURPOSE. -// -// Copyright (c) 1992 - 1997 Microsoft Corporation. All Rights Reserved. -// -//--------------------------------------------------------------------------; - -// Video related definitions and interfaces for ActiveMovie - -#ifndef __AMVIDEO__ -#define __AMVIDEO__ - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#include - - -// This is an interface on the video renderer that provides information about -// DirectDraw with respect to its use by the renderer. For example it allows -// an application to get details of the surface and any hardware capabilities -// that are available. It also allows someone to adjust the surfaces that the -// renderer should use and furthermore even set the DirectDraw instance. We -// allow someone to set the DirectDraw instance because DirectDraw can only -// be opened once per process so it helps resolve conflicts. There is some -// duplication in this interface as the hardware/emulated/FOURCCs available -// can all be found through the IDirectDraw interface, this interface allows -// simple access to that information without calling the DirectDraw provider -// itself. The AMDDS prefix is ActiveMovie DirectDraw Switches abbreviated. - -#define AMDDS_NONE 0x00 // No use for DCI/DirectDraw -#define AMDDS_DCIPS 0x01 // Use DCI primary surface -#define AMDDS_PS 0x02 // Use DirectDraw primary -#define AMDDS_RGBOVR 0x04 // RGB overlay surfaces -#define AMDDS_YUVOVR 0x08 // YUV overlay surfaces -#define AMDDS_RGBOFF 0x10 // RGB offscreen surfaces -#define AMDDS_YUVOFF 0x20 // YUV offscreen surfaces -#define AMDDS_RGBFLP 0x40 // RGB flipping surfaces -#define AMDDS_YUVFLP 0x80 // YUV flipping surfaces -#define AMDDS_ALL 0xFF // ALL the previous flags -#define AMDDS_DEFAULT AMDDS_ALL // Use all available surfaces - -#define AMDDS_YUV (AMDDS_YUVOFF | AMDDS_YUVOVR | AMDDS_YUVFLP) -#define AMDDS_RGB (AMDDS_RGBOFF | AMDDS_RGBOVR | AMDDS_RGBFLP) -#define AMDDS_PRIMARY (AMDDS_DCIPS | AMDDS_PS) - -// be nice to our friends in C -#undef INTERFACE -#define INTERFACE IDirectDrawVideo - -DECLARE_INTERFACE_(IDirectDrawVideo, IUnknown) -{ - // IUnknown methods - - STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - // IDirectDrawVideo methods - - STDMETHOD(GetSwitches)(THIS_ DWORD *pSwitches) PURE; - STDMETHOD(SetSwitches)(THIS_ DWORD Switches) PURE; - STDMETHOD(GetCaps)(THIS_ DDCAPS *pCaps) PURE; - STDMETHOD(GetEmulatedCaps)(THIS_ DDCAPS *pCaps) PURE; - STDMETHOD(GetSurfaceDesc)(THIS_ DDSURFACEDESC *pSurfaceDesc) PURE; - STDMETHOD(GetFourCCCodes)(THIS_ DWORD *pCount,DWORD *pCodes) PURE; - STDMETHOD(SetDirectDraw)(THIS_ LPDIRECTDRAW pDirectDraw) PURE; - STDMETHOD(GetDirectDraw)(THIS_ LPDIRECTDRAW *ppDirectDraw) PURE; - STDMETHOD(GetSurfaceType)(THIS_ DWORD *pSurfaceType) PURE; - STDMETHOD(SetDefault)(THIS) PURE; - STDMETHOD(UseScanLine)(THIS_ long UseScanLine) PURE; - STDMETHOD(CanUseScanLine)(THIS_ long *UseScanLine) PURE; - STDMETHOD(UseOverlayStretch)(THIS_ long UseOverlayStretch) PURE; - STDMETHOD(CanUseOverlayStretch)(THIS_ long *UseOverlayStretch) PURE; - STDMETHOD(UseWhenFullScreen)(THIS_ long UseWhenFullScreen) PURE; - STDMETHOD(WillUseFullScreen)(THIS_ long *UseWhenFullScreen) PURE; -}; - - -// be nice to our friends in C -#undef INTERFACE -#define INTERFACE IQualProp - -DECLARE_INTERFACE_(IQualProp, IUnknown) -{ - // IUnknown methods - - STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - // Compare these with the functions in class CGargle in gargle.h - - STDMETHOD(get_FramesDroppedInRenderer)(THIS_ int *pcFrames) PURE; // Out - STDMETHOD(get_FramesDrawn)(THIS_ int *pcFramesDrawn) PURE; // Out - STDMETHOD(get_AvgFrameRate)(THIS_ int *piAvgFrameRate) PURE; // Out - STDMETHOD(get_Jitter)(THIS_ int *iJitter) PURE; // Out - STDMETHOD(get_AvgSyncOffset)(THIS_ int *piAvg) PURE; // Out - STDMETHOD(get_DevSyncOffset)(THIS_ int *piDev) PURE; // Out -}; - - -// This interface allows an application or plug in distributor to control a -// full screen renderer. The Modex renderer supports this interface. When -// connected a renderer should load the display modes it has available -// The number of modes available can be obtained through CountModes. Then -// information on each individual mode is available by calling GetModeInfo -// and IsModeAvailable. An application may enable and disable any modes -// by calling the SetEnabled flag with OATRUE or OAFALSE (not C/C++ TRUE -// and FALSE values) - the current value may be queried by IsModeEnabled - -// A more generic way of setting the modes enabled that is easier to use -// when writing applications is the clip loss factor. This defines the -// amount of video that can be lost when deciding which display mode to -// use. Assuming the decoder cannot compress the video then playing an -// MPEG file (say 352x288) into a 320x200 display will lose about 25% of -// the image. The clip loss factor specifies the upper range permissible. -// To allow typical MPEG video to be played in 320x200 it defaults to 25% - -// be nice to our friends in C -#undef INTERFACE -#define INTERFACE IFullScreenVideo - -DECLARE_INTERFACE_(IFullScreenVideo, IUnknown) -{ - // IUnknown methods - - STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - // IFullScreenVideo methods - - STDMETHOD(CountModes)(THIS_ long *pModes) PURE; - STDMETHOD(GetModeInfo)(THIS_ long Mode,long *pWidth,long *pHeight,long *pDepth) PURE; - STDMETHOD(GetCurrentMode)(THIS_ long *pMode) PURE; - STDMETHOD(IsModeAvailable)(THIS_ long Mode) PURE; - STDMETHOD(IsModeEnabled)(THIS_ long Mode) PURE; - STDMETHOD(SetEnabled)(THIS_ long Mode,long bEnabled) PURE; - STDMETHOD(GetClipFactor)(THIS_ long *pClipFactor) PURE; - STDMETHOD(SetClipFactor)(THIS_ long ClipFactor) PURE; - STDMETHOD(SetMessageDrain)(THIS_ HWND hwnd) PURE; - STDMETHOD(GetMessageDrain)(THIS_ HWND *hwnd) PURE; - STDMETHOD(SetMonitor)(THIS_ long Monitor) PURE; - STDMETHOD(GetMonitor)(THIS_ long *Monitor) PURE; - STDMETHOD(HideOnDeactivate)(THIS_ long Hide) PURE; - STDMETHOD(IsHideOnDeactivate)(THIS) PURE; - STDMETHOD(SetCaption)(THIS_ BSTR strCaption) PURE; - STDMETHOD(GetCaption)(THIS_ BSTR *pstrCaption) PURE; - STDMETHOD(SetDefault)(THIS) PURE; -}; - - -// This adds the accelerator table capabilities in fullscreen. This is being -// added between the original runtime release and the full SDK release. We -// cannot just add the method to IFullScreenVideo as we don't want to force -// applications to have to ship the ActiveMovie support DLLs - this is very -// important to applications that plan on being downloaded over the Internet - -// be nice to our friends in C -#undef INTERFACE -#define INTERFACE IFullScreenVideoEx - -DECLARE_INTERFACE_(IFullScreenVideoEx, IFullScreenVideo) -{ - // IUnknown methods - - STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - // IFullScreenVideo methods - - STDMETHOD(CountModes)(THIS_ long *pModes) PURE; - STDMETHOD(GetModeInfo)(THIS_ long Mode,long *pWidth,long *pHeight,long *pDepth) PURE; - STDMETHOD(GetCurrentMode)(THIS_ long *pMode) PURE; - STDMETHOD(IsModeAvailable)(THIS_ long Mode) PURE; - STDMETHOD(IsModeEnabled)(THIS_ long Mode) PURE; - STDMETHOD(SetEnabled)(THIS_ long Mode,long bEnabled) PURE; - STDMETHOD(GetClipFactor)(THIS_ long *pClipFactor) PURE; - STDMETHOD(SetClipFactor)(THIS_ long ClipFactor) PURE; - STDMETHOD(SetMessageDrain)(THIS_ HWND hwnd) PURE; - STDMETHOD(GetMessageDrain)(THIS_ HWND *hwnd) PURE; - STDMETHOD(SetMonitor)(THIS_ long Monitor) PURE; - STDMETHOD(GetMonitor)(THIS_ long *Monitor) PURE; - STDMETHOD(HideOnDeactivate)(THIS_ long Hide) PURE; - STDMETHOD(IsHideOnDeactivate)(THIS) PURE; - STDMETHOD(SetCaption)(THIS_ BSTR strCaption) PURE; - STDMETHOD(GetCaption)(THIS_ BSTR *pstrCaption) PURE; - STDMETHOD(SetDefault)(THIS) PURE; - - // IFullScreenVideoEx - - STDMETHOD(SetAcceleratorTable)(THIS_ HWND hwnd,HACCEL hAccel) PURE; - STDMETHOD(GetAcceleratorTable)(THIS_ HWND *phwnd,HACCEL *phAccel) PURE; - STDMETHOD(KeepPixelAspectRatio)(THIS_ long KeepAspect) PURE; - STDMETHOD(IsKeepPixelAspectRatio)(THIS_ long *pKeepAspect) PURE; -}; - - -// The SDK base classes contain a base video mixer class. Video mixing in a -// software environment is tricky because we typically have multiple streams -// each sending data at unpredictable times. To work with this we defined a -// pin that is the lead pin, when data arrives on this pin we do a mix. As -// an alternative we may not want to have a lead pin but output samples at -// predefined spaces, like one every 1/15 of a second, this interfaces also -// supports that mode of operations (there is a working video mixer sample) - -// be nice to our friends in C -#undef INTERFACE -#define INTERFACE IBaseVideoMixer - -DECLARE_INTERFACE_(IBaseVideoMixer, IUnknown) -{ - STDMETHOD(SetLeadPin)(THIS_ int iPin) PURE; - STDMETHOD(GetLeadPin)(THIS_ int *piPin) PURE; - STDMETHOD(GetInputPinCount)(THIS_ int *piPinCount) PURE; - STDMETHOD(IsUsingClock)(THIS_ int *pbValue) PURE; - STDMETHOD(SetUsingClock)(THIS_ int bValue) PURE; - STDMETHOD(GetClockPeriod)(THIS_ int *pbValue) PURE; - STDMETHOD(SetClockPeriod)(THIS_ int bValue) PURE; -}; - -#define iPALETTE_COLORS 256 // Maximum colours in palette -#define iEGA_COLORS 16 // Number colours in EGA palette -#define iMASK_COLORS 3 // Maximum three components -#define iTRUECOLOR 16 // Minimum true colour device -#define iRED 0 // Index position for RED mask -#define iGREEN 1 // Index position for GREEN mask -#define iBLUE 2 // Index position for BLUE mask -#define iPALETTE 8 // Maximum colour depth using a palette -#define iMAXBITS 8 // Maximum bits per colour component - - -// Used for true colour images that also have a palette - -typedef struct tag_TRUECOLORINFO { - DWORD dwBitMasks[iMASK_COLORS]; - RGBQUAD bmiColors[iPALETTE_COLORS]; -} TRUECOLORINFO; - - -// The BITMAPINFOHEADER contains all the details about the video stream such -// as the actual image dimensions and their pixel depth. A source filter may -// also request that the sink take only a section of the video by providing a -// clipping rectangle in rcSource. In the worst case where the sink filter -// forgets to check this on connection it will simply render the whole thing -// which isn't a disaster. Ideally a sink filter will check the rcSource and -// if it doesn't support image extraction and the rectangle is not empty then -// it will reject the connection. A filter should use SetRectEmpty to reset a -// rectangle to all zeroes (and IsRectEmpty to later check the rectangle). -// The rcTarget specifies the destination rectangle for the video, for most -// source filters they will set this to all zeroes, a downstream filter may -// request that the video be placed in a particular area of the buffers it -// supplies in which case it will call QueryAccept with a non empty target - -typedef struct tagVIDEOINFOHEADER { - - RECT rcSource; // The bit we really want to use - RECT rcTarget; // Where the video should go - DWORD dwBitRate; // Approximate bit data rate - DWORD dwBitErrorRate; // Bit error rate for this stream - REFERENCE_TIME AvgTimePerFrame; // Average time per frame (100ns units) - - BITMAPINFOHEADER bmiHeader; - -} VIDEOINFOHEADER; - -// make sure the pbmi is initialized before using these macros -#define TRUECOLOR(pbmi) ((TRUECOLORINFO *)(((LPBYTE)&((pbmi)->bmiHeader)) \ - + (pbmi)->bmiHeader.biSize)) -#define COLORS(pbmi) ((RGBQUAD *)(((LPBYTE)&((pbmi)->bmiHeader)) \ - + (pbmi)->bmiHeader.biSize)) -#define BITMASKS(pbmi) ((DWORD *)(((LPBYTE)&((pbmi)->bmiHeader)) \ - + (pbmi)->bmiHeader.biSize)) - -// All the image based filters use this to communicate their media types. It's -// centred principally around the BITMAPINFO. This structure always contains a -// BITMAPINFOHEADER followed by a number of other fields depending on what the -// BITMAPINFOHEADER contains. If it contains details of a palettised format it -// will be followed by one or more RGBQUADs defining the palette. If it holds -// details of a true colour format then it may be followed by a set of three -// DWORD bit masks that specify where the RGB data can be found in the image -// (For more information regarding BITMAPINFOs see the Win32 documentation) - -// The rcSource and rcTarget fields are not for use by filters supplying the -// data. The destination (target) rectangle should be set to all zeroes. The -// source may also be zero filled or set with the dimensions of the video. So -// if the video is 352x288 pixels then set it to (0,0,352,288). These fields -// are mainly used by downstream filters that want to ask the source filter -// to place the image in a different position in an output buffer. So when -// using for example the primary surface the video renderer may ask a filter -// to place the video images in a destination position of (100,100,452,388) -// on the display since that's where the window is positioned on the display - -// !!! WARNING !!! -// DO NOT use this structure unless you are sure that the BITMAPINFOHEADER -// has a normal biSize == sizeof(BITMAPINFOHEADER) ! -// !!! WARNING !!! - -typedef struct tagVIDEOINFO { - - RECT rcSource; // The bit we really want to use - RECT rcTarget; // Where the video should go - DWORD dwBitRate; // Approximate bit data rate - DWORD dwBitErrorRate; // Bit error rate for this stream - REFERENCE_TIME AvgTimePerFrame; // Average time per frame (100ns units) - - BITMAPINFOHEADER bmiHeader; - - union { - RGBQUAD bmiColors[iPALETTE_COLORS]; // Colour palette - DWORD dwBitMasks[iMASK_COLORS]; // True colour masks - TRUECOLORINFO TrueColorInfo; // Both of the above - }; - -} VIDEOINFO; - -// These macros define some standard bitmap format sizes - -#define SIZE_EGA_PALETTE (iEGA_COLORS * sizeof(RGBQUAD)) -#define SIZE_PALETTE (iPALETTE_COLORS * sizeof(RGBQUAD)) -#define SIZE_MASKS (iMASK_COLORS * sizeof(DWORD)) -#define SIZE_PREHEADER (FIELD_OFFSET(VIDEOINFOHEADER,bmiHeader)) -#define SIZE_VIDEOHEADER (sizeof(BITMAPINFOHEADER) + SIZE_PREHEADER) -// !!! for abnormal biSizes -// #define SIZE_VIDEOHEADER(pbmi) ((pbmi)->bmiHeader.biSize + SIZE_PREHEADER) - -// DIBSIZE calculates the number of bytes required by an image - -#define WIDTHBYTES(bits) ((DWORD)(((bits)+31) & (~31)) / 8) -#define DIBWIDTHBYTES(bi) (DWORD)WIDTHBYTES((DWORD)(bi).biWidth * (DWORD)(bi).biBitCount) -#define _DIBSIZE(bi) (DIBWIDTHBYTES(bi) * (DWORD)(bi).biHeight) -#define DIBSIZE(bi) ((bi).biHeight < 0 ? (-1)*(_DIBSIZE(bi)) : _DIBSIZE(bi)) - -// This compares the bit masks between two VIDEOINFOHEADERs - -#define BIT_MASKS_MATCH(pbmi1,pbmi2) \ - (((pbmi1)->dwBitMasks[iRED] == (pbmi2)->dwBitMasks[iRED]) && \ - ((pbmi1)->dwBitMasks[iGREEN] == (pbmi2)->dwBitMasks[iGREEN]) && \ - ((pbmi1)->dwBitMasks[iBLUE] == (pbmi2)->dwBitMasks[iBLUE])) - -// These zero fill different parts of the VIDEOINFOHEADER structure - -// Only use these macros for pbmi's with a normal BITMAPINFOHEADER biSize -#define RESET_MASKS(pbmi) (ZeroMemory((PVOID)(pbmi)->dwBitFields,SIZE_MASKS)) -#define RESET_HEADER(pbmi) (ZeroMemory((PVOID)(pbmi),SIZE_VIDEOHEADER)) -#define RESET_PALETTE(pbmi) (ZeroMemory((PVOID)(pbmi)->bmiColors,SIZE_PALETTE)); - -#if 0 -// !!! This is the right way to do it, but may break existing code -#define RESET_MASKS(pbmi) (ZeroMemory((PVOID)(((LPBYTE)(pbmi)->bmiHeader) + \ - (pbmi)->bmiHeader.biSize,SIZE_MASKS))) -#define RESET_HEADER(pbmi) (ZeroMemory((PVOID)(pbmi), SIZE_PREHEADER + \ - sizeof(BITMAPINFOHEADER))) -#define RESET_PALETTE(pbmi) (ZeroMemory((PVOID)(((LPBYTE)(pbmi)->bmiHeader) + \ - (pbmi)->bmiHeader.biSize,SIZE_PALETTE)) -#endif - -// Other (hopefully) useful bits and bobs - -#define PALETTISED(pbmi) ((pbmi)->bmiHeader.biBitCount <= iPALETTE) -#define PALETTE_ENTRIES(pbmi) ((DWORD) 1 << (pbmi)->bmiHeader.biBitCount) - -// Returns the address of the BITMAPINFOHEADER from the VIDEOINFOHEADER -#define HEADER(pVideoInfo) (&(((VIDEOINFOHEADER *) (pVideoInfo))->bmiHeader)) - - -// MPEG variant - includes a DWORD length followed by the -// video sequence header after the video header. -// -// The sequence header includes the sequence header start code and the -// quantization matrices associated with the first sequence header in the -// stream so is a maximum of 140 bytes long. - -typedef struct tagMPEG1VIDEOINFO { - - VIDEOINFOHEADER hdr; // Compatible with VIDEOINFO - DWORD dwStartTimeCode; // 25-bit Group of pictures time code - // at start of data - DWORD cbSequenceHeader; // Length in bytes of bSequenceHeader - BYTE bSequenceHeader[1]; // Sequence header including - // quantization matrices if any -} MPEG1VIDEOINFO; - -#define MAX_SIZE_MPEG1_SEQUENCE_INFO 140 -#define SIZE_MPEG1VIDEOINFO(pv) (FIELD_OFFSET(MPEG1VIDEOINFO, bSequenceHeader[0]) + (pv)->cbSequenceHeader) -#define MPEG1_SEQUENCE_INFO(pv) ((const BYTE *)(pv)->bSequenceHeader) - - -// Analog video variant - Use this when the format is FORMAT_AnalogVideo -// -// rcSource defines the portion of the active video signal to use -// rcTarget defines the destination rectangle -// both of the above are relative to the dwActiveWidth and dwActiveHeight fields -// dwActiveWidth is currently set to 720 for all formats (but could change for HDTV) -// dwActiveHeight is 483 for NTSC and 575 for PAL/SECAM (but could change for HDTV) - -typedef struct tagAnalogVideoInfo { - RECT rcSource; // Width max is 720, height varies w/ TransmissionStd - RECT rcTarget; // Where the video should go - DWORD dwActiveWidth; // Always 720 (CCIR-601 active samples per line) - DWORD dwActiveHeight; // 483 for NTSC, 575 for PAL/SECAM - REFERENCE_TIME AvgTimePerFrame; // Normal ActiveMovie units (100 nS) -} ANALOGVIDEOINFO; - - -#ifdef __cplusplus -} -#endif // __cplusplus -#endif // __AMVIDEO__ - diff --git a/src/BaseClasses/Debug/strmbasd.lib b/src/BaseClasses/Debug/strmbasd.lib deleted file mode 100644 index c0209fdcc41762381b5ca458a8e8815c6045b233..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1851572 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�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


3zPfI4 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

H2C0t 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 F@V|K8{zU)) diff --git a/src/BaseClasses/Release/STRMBASE.lib b/src/BaseClasses/Release/STRMBASE.lib deleted file mode 100644 index 943634bf2bcdee1ed2a09f40d7cb226fac73adae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1065040 zcmeFaO^>8Wk{6z^JKfVgJ+rgDvoFKU4*Qq(u;M~xbydHJ6%|iBPrN+w-WicuRSP1B z%8aUtt;mSnh|KJ+5#qv$3l{|9g2WBJ0cSvb0fhJlNQe^$&glO$Gk1U7&HahY>K(KT zRA)z4hP%1ByScf!xw*Od|M$m>-TCXk{qf)YgYduO2cJKF`1rxYFCK>J56suEzIgaR z{{H(PA02)4kB|Q9e|zx$^PUFpdEh+{yyt=UJn)_e-t)kF9(d0K?|I-o5By)j10VdY ze{q!j6n}K|!Ml8>fBWczzpS5s_Qyvb{O|t!+kbfU!TZm98ocL$_dM{P2mV5M;KTp; zM@R2Jf4OP!{oUy3{pT+i4L+LxwWD9z=O3LMef0hl)8M}pM<4wk{`vTC{QT(u`p>`q zqoa?1m7jn22S*=&m(PFwA4ebm1%7^z|J|c|fBw#YI{Lx8es2E#(GT8#{-2=1CvX1M z(VzSCPd_>OkN?ThU)bmP-yHq$T|WKM(GUMTpTGCd zkACQXmjCPMhwne{Y48`w13y~)_oMIhdHX+)e)N~&^DqCw(U0DL-qYYc5BzW8fgk^T zcJvOPc{ZG!j3?99tSsh})#eBZ^Kvw6owT#OCCSt4#pYtMyWqV3G|y(O&iLf{JUcDQ zu};jh$?Wu`6(ygHr_*M3qSK3PmgQr#p*5Y3qui6$sAxs0)5)Nmp@kaP>@3-$+1c!L z6hogi%Y0n4a*gGzELyf#6=|~kGXq$q<=d;blil_@$|%l?`N`sXnZI6aUM=J7+l&5U zx7fZ(W=(HiOjhSnq4sWZxtv}vucDmU)UPWaOfiyKK76`cTwN`9M{|=h9Nw(2SHtDS zYB9auEf<$n&TMtLT(350j)k=;`SubO>eSZDm&Tc>w++nWUV_{E>bu+ts-s1eL| zi}N?hy@ zc%Z|wC{LCfzmD_k)$MY)y4Hw&)Tt?vnJ{zulalEEj$sZZ3waZ@mWIpl%u-w0yta znSQ->bfD~Vb9HlFEN@rmw%>_-#%dbjlZ6n}B%h$=B*V<$5~Lz{m9*St7q^Se`SPL` z84cAk?!oP<@VW7JHN5$ja46PN>Bp{Fw<|@#+tu`Hy}I^Bxw+deF3uPG>((tsf4bZe zsVss#E0!-8nCZp(m7lg*E!K{E@@%-+fYaSfa0zJYw~pL-HpWEvfKHbCVo8{0yQNp- z`DMP%*NgpLW0g@HZa1qp9-6Wiez>|=jc=}#xQ18DR~d~^4*qi!DW_y+%rN=uU$$3k z&@71x@cH5@ne}vWyR2&g<*hc!Vi3){MZVo!@3w2hF@Y#Sb=Nn$Wd|bpb@OJm_NGW8 z>!BMsDHii!z5L6!>+Np3z1evzfux&i6s>S{mDmJdS_UGt;u{NErC=esUQz>_i&x{# z$?{cyS@F+qyWhW9>|`iXbSb8ku+5josuev9*Atp zN{BWj&tfD1)C&s%#*z^$efO!6iF+;1kU3i1u3q_T4$`1bUAx(X?@I`BUVR|Q{Pm|e zYi(+?AXXf?&Ww!F3s`ZcMMrTK&lQt~x*S3gzQWE?r&c?x{e`!B6)q)TuY8rG%BVW% z>R4UBu4F=Sdy$$O#kbel`s(#!y7c8AQkgyXD{n1FVh^Igq5t;UW5jmH%uSmOep`l< zgi@aFR-Twe$}5_$N~j5|a%(+oD91^o?d&zCgj;3=dKhS8ewv%=<>uwAlBomejW-a` z!8Ekh4VJGK=Wnx1!K24#06p&Ev0+J9#7}f}D!w1~CLNCphQmtFmNj!YJ_{G8;iT0$ z_S72wK7k6iyq>HVZ>#a;49$#`_|WyxHZ@H3WfJEU%S%#YuhvUXt>B!*oYm>=#W`5U z$*19zSJ39lSG$H&Op%Ng9wVA(+hTDI9^`e_Nxl@^_;$HNzXO%WgQFJiWKDFv<=TA3 zqdrGUh7D+9|5SrD&pOj;LU1$k^>)9cweNa`HF@J^i)3D}gSu-wo#;Uus{q!wpu9;7 z+Y6pu5^KBwlO*tTmY~q;+)nQhp{E!I6?y4lWrkr`VVyxkIna5m`OrE8w33t}IyA`; zRFA!TK5u#v7X>+~WCYNhr;(_fQO~vX_{C8SPU1HIdXl+a)c|hJOmF4r%64K>K5b8jGE$ z_|rD$TZ_ZOj&9a#otB!SljZK^c6Ukoe!Ng2bHCbO8zpv9Is)4Mg^LqXueTzZgEivo znb(Q0Zx&GL$#y`SPOlqZ->lBx(B6Bp*zK$Fl}@xaue?3_ba4qGh&o=pr~s$S#c7MIR#7wDn;gTf$)Y{xQPLXs^C316bR<;M&q1eh{ zl_B{iG_geU^&HHR?D~3#MY1ZwDMW~`y|lcUZ7MAV#qwrxb9w3HIj4|>3ChfNE60F< zXl-CSIA303>*RrXsZ~Fqmxgi;#T9z#m4`?Y@;n|}DGWt{^uPUqd=lu%>|u^gpH~-u z&ll@8NmHG!)E3mv;C}C*oMtO;oLXuxi86ZCqof-!?d=NNcdyF8a04JBy0^cqQu6Da zTV{}Yw%Dx}v>H{ocs&y`Cb?z#tzl(XWVhJtFIU%EbPytC9rD=KmOechgh~zUg43Jb zOPF;Wtlbg?tZl(=u?d0s(tKs@DJ;TCA#P5Z8=JXTQn&_#N>|?RMMU zV2c&l6m5NLjJtjcmXFQ;3KGpF$^tN4?a$lm#j6S*D^-rU49)=zDw}iY0rtDU-F2zK z(T9QLG}>f}Iu*ilx;ZMb@X;BH$rxWPH_@mVWwZUv;hnsGyI-9z);MVs);7f_H~ZJt zAYqbVY-KZ^9uer95m7_7^d+{d*(H*VQl(Cp#BVOqXl(lX2weUWjSm=;&kIPXn^u#~ zM)Rsz?XR%Ui_&?AC(6GnVV4juSuW*QoMxa`q^J;q3D$aWHDCvXLp@wVJl}ylBwI-D@=D zYTT~r>J^4BVl`@=WRdv99)ERiXDDUOwpTbfd1V=$lFqiU=+IK-*E-3k7=|@A^h@5l z*w!re%dm?`VBYrCi{=8$fl;!gbCkef6&{lStw%tD^FNd5>Bn(ONr%KBL7Zbd93C5T zHIziUvnwQD{SvHNN66i-#Go)@VYVCc-zK${~+|65h1Rl^;$O^A?lMupYw0}Wnv zl4(*&EqAC{M-RX0T2iNaf-26jqgN}U-2TSanGjbFhD4Yniv_F_Xs?#>8M8x1N!=J9LgX`aHJWG(ti4v66m%%m`c`}nd=`!~Dx-xU z^$+)KN_Dp9QewFr9N$?unug(k>%%(_5~N@s4m&=4>Sl;joSk%<50AfcU#lYw!656H zOzZNJeMd|N_60kb+P9aN@SU>d-9cHD;A(du?kr6ZR_S!W8_KxqoUKoy+_G?$EbGgH z42Dt7UY=)|Rh7mIRE2!9Skv)bggCK!RfUX&B`zeEmzW%;z-M(O9@S-hQI}CetAKH3 zn}aiI>5N0Qzuv80U>O$m%ZeG|e=Z)d!tF(V={Nvi`Y2R};`YK@8*yAp z-@GEUg1I43r>24+JT$dwa%O73@sTNiA!(2lHbI6JIFu-BouAUVfksKHPPFn8JexaY zH@AEx)>v0FvzssCr~pjwY$A40SnK`j;Cm3aLB_4T2upeb!pGo=7n=->OHy`%l{`$e zqrj=WW7EJ`d?EG8x02f~+2(XWr+C;<%o}qlWlxg5Vv-b=leEuVg&UGY))3jW$wdVzVw}G

j@L=D0P75Pkmbhr_xRhL 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

~l>Me;HH0V#Kh^r%~ z;3HEkL58??rq2FUP;s1sk4$ZrsOR_Pvl9hh$q(Tad}L~iL{;o@l`SrO)HqJTN2az) z)U5nZGX*u5Q}B_gw)clAy}4Q4T-&$P}AU4f&eiBgs%-k8uh zktsHi8A{{Y%#LglF3SFf-*`^JN2Weue-Sg$=vqBX3u+0c;3HG4u^On{w;u}>)H+VV zN2WfLs0;On{wk>VI0YY>DwL=na(=ojsNIxbNKn{uv; zxc=o7d}Qi`M1A|g-WGzY!FmmT@R6yL>@T9^mlqw)irH6R9XJIanK~s=4F=SnDX2(J z!AGXpBGM37`3*_U1eL@o_{h{364fN7{#8NcaSA>%^`%4|KlVw4pr&vNJ~G9cxFLnl zj;+KNxxUhPg;Vg6sjnq!PW!*R3F-|_!AGXPk*F-s^9h1F$|?BB)M<$twea&hf;z`3 z_{bC+Y7P0CR=4I!LH)}q_{h{5iE93Qh1r6t#^y5o;3HGtvA>8GH8$oqcG~1C!={{q zk4&AFs2@k)n<^+5r{E(~-%HfNM}{#MUtBSqf{#p{lc*-$`x-{<6i&fMrp`-L*KRY% zi@3&c3O+J*L887cteYyR#hikVOkI?yeq&k>5!7~0!AGVpNz~%8D{czvBTm6brr1Dc zsISW#t}GPP_nd-{O#L8H|33K|TMYV2{x43!N2Y$1sAs27XUXwV53|`8KlsShPwX$E zMSWJ|LU%zu!72F2)Xx(2>a5;uXz|4r%qjTD)D?+(^YSyj1@$ba;3HFPNHV1G)zIdK zQ8bHF@R6xsB&tNUX(dEl(>MhmnYt!XXAd~pWaZ1(%bbFbOtDGMkiyYl7r7^>O`L*{ zO#LQNO@8iZm{SgL3O+K$rYl2SQ*Yw^w!Rde

~l>V`x;GU{lKpe}I=J~H*YME$;F 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 z

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%0DMC4DG@^ns1ScPgUF7@8J13EmKI~ z6OV#XM@c9c6~i%)Jy$}gMSjz>=;`;xjQV0e;fwj2FNXD}oQ3)4Rs{Y|lJLuRj0KYe zt|`YDp&57OosB4`q#Ud`Fz(IE&F;36>#^ZiNS=K{t&adIm;B(H0*E{vzpfPhRfwz{YNUC}8na9wPIls=Akd%FK zmDDm}FrVU435zRb=IV}FfVXTbmLyzdm%`%eE?*4$d*v*culQnq;EQ?56GM6`E0#$A zu5x$RMFG%z>q3`{M+#I>tExG;I^d;peuWXXW89qQI-O(WdDEL8d`aPPw>WA9=T_TG zrhOc$#UgcF2c`nQk~-@!2S?^>)eB&e+Hrl5o#x5?M`y)O4!UWU=1bJ1U%F!EV@~eY zu?&R@v&*#XWWjtYeLS1@z3)_glPbCDI?hG4?)Q2qL;~ZBo*33eRfRgVWva1+(Nm;kvlKO9m4G9cIuMnaCp1Kd@;D@;X)g{Hp#xxCZ8s0lcTkuv=Wo)d< zwM0@AMrnX59G}9rrDEJIjr-oMSjV zq_j9UyH?>gV>-fU9xhoZJXA4m9+m*c%R}cL*QzC|2N4*>Lma~rMhX?NKN6lkFS>iWQ6zwGdEt;QTywd3O9xk9s&e05k;*zSoI zYK=`8rI7|S9z*a@Ru@9XD47bz&DA-A+1&;;W=Q5j^ulxkBV1hw2@l&bZm!Nnte2|_ zk6V691!f37C9C&mGeJ%cLUh(`*rmYl?ce9&t%Lc&|GwzQL3h1Y0FwAd=2t^hEzFm@72q z3#AmoRXrBH2(aGvrEY&^y)VL%Wpsp5?Q2oBx+hu1xFvyKwY}|2c}$oI~6EjoRX$=Nr~S(@~o6p?)JXGF6rV0s)r?vE~!2;NX58IO0DQEsm8;S>V8LHR7v%b zK`O>w(uIPj2tI3R_+$HzD?IL!QbKZb!te?6kD}*ZaY}l>E-7`g>THkb7(=@WH=1dA+DHSNkxtzxHCT_F=xvhC#si>;H5B8_PqNPqhVi znGbUfV!fCz6U-MO1-Id>li94Ck>PB@kyC17wW}H%S2eC$-QCQ+9Lv*=jHz8KSH7m- z0L%+Sx8Wk%-ihz0W%j%ta}BluS$WsX{ug!kFLsZt=^05h3=iWNmJ086vu*JmJww|D zhvONpoNa2V?{2~wE=>cNr=uuRP7k@ROtRffJMn=x*m~q+Aa<+hb5VkBL*|YpZ^4~3 zS#LvrN2lRrJfsEZ)AS|!dit%p;)yGslB~8aW3`eGwh#2FG}s7)>cEjH4(}S{{X^b! zXWDAz7@R=-P4=lSI|g^g8@Uxp-Sn!Y0k3fclEW5=l@d2zYrLgDksOKl8q3?_1HH8a zH(b|)ol73-u>njDQ)!N0*B0NpBaW?9egK^5q9l8MT^%-xwZ%8v!o0j;U0a3}poewm zKh8z2QjYc~N48~7rJ2|oA92dD9Jg3!NwVB?ZjGmOV9o~LX)|o2xO8@XPhY>ElkMHz zv2|@t>zmd!^FSls-i)noo8vg?#!s+51F5&KN1t;ed$~0D+GKyCZ>T?WG9OVu#a(>J z3kCP*By|)Wj_c!jM$#ZyPO`jtFwwW=27RuNw;nZ!&0n01GZMFzLuCE}oWwNJ)SHQ3 zIr|856&oB~ydk|kA36eRbaEtkD#y_iGYCn_2fm)>C< zHMBFXf65KKFLU1Fb{Y1bv6Fij`s!x(*Kkz+LAKi)0JF^nm&vxA_=W*>~_Hg(f2;U z+~tDHgfEQDJ`0#fTyR17egK$XxZr~D{T49!TnB*5R^B4Ogk5l%@C^aSg&IZ>!V9AB zVgZx_n(0Iy$dcAeU!h~0aL)WC%A0oJryu>TyUB2QU1ySvr)rw zI2T0U5McI9fG>>nw*%(OF1R3k4+7><7hER#i0_DoK~P)}zTX4xtrNgkz!f-`3&K|h zxM~ecK4+qj^|9gv@wEc(>Iv|Lfv+Dhcevn!==&&OzTkojqVE9>1JvSz@Eri$QzwA$ z=O>8oCBXe{0(=orls5x<2oGI0d2R+wmkTaadBec5O~Vi$T~K-72e`XV0N-Z;^N0&B z2;UC?^9vVTCi*skp5Fo{O2L84*50lF%ytbIB!7E=BLSE{p8&oBERq)Ep$ozn#=AKh zhH!L2-G#n?4LG(QYn8!6-w(>p= zm_KT`Z1m;N#N-qYT@bzq-h~0PNyBBMZ#Q7>oB-bt@ZANNf)E05%r~gKrvhe<3oeuV zMUcK6FxCy)+3@WI+VY$>BI83!-lo#&cKTp|kk+&)*xTj;nHv5Llz1 z#G?wr&u4B&dgY`0QN~&q7jwWvgHGgD@{Fa2RULErA{$pd8w8>Gggqo z-9wSWRBa*f*&o!sI4>k3I3N_96a)1U9#+%(#IUggH%*19RN>eYiAkv(;wtd$B2xx$ zcOj*sa}E*0p~QldpAP=nIJw;J;Ix=#7gC!;ldD`rQFLh$x64X8PYeekGvnaWE^w?b z&4Xdg!On-tUGs0|@yZwebYF6%{M>tE(cYmViCCl~%J&YHOT;|0F=7r!YK|mlgS&<1 zP`!C$edU2aeIYpwcR7-KSE5YaT|8#Yb+skp<(6Ik1rQszETXE?s9jrseSY?Vh&z$+ zgiHD5cvNY$vQgE9*!g(eI8<_`akyv=f~0Ekh6{9%!cG{u6`HTsyp@=(%p^N4Yss6Y zc0a@&lN7;j+|DLQ*&VCazy|Bc&L#Lo2ka0Zm9NOSV(oVs2majG-8JJQ&M{$}jMU;$ zA1Wws+6j&beyCDqZXK$WOhKulv&t4lSfw02SQMC;DZ=#Ntdy$}M#|bSjAio7+Ok7( zs2L&jK!ibYG59JE*gO`9B!i&CwPB)4)s`vhD9KmgQT3KiXS?7)8vJ#R9ORDzdM-yC zDz{W^sX`68Ab_6G*(K-}NZP#?;^s7~GLw_Bu?z>^-CPe{gIDIkgD+0{)91~{MOa6F zll!N81wc1IF@;S4lcKwt8Ns1iq-J^%w)k8Aw)op8DY>(wa(v0|NMfoPt=DEwsomTe z+)Yy?cH)D0lw8oLL_5iS06$=u4D;6lB3jZF!BKfpq-0yO?qkOGw8+?a^0b=guXA2n z4HA{>$++G;oa%}w1QrL*L@r4@`C?S&P_sdkf@+rbOD>U`pQ*D4&ALd<_driwJ&)_l zGc04Qqj)j)3g|fwdaRe~9Kt+W;9XF2d}NaOJ#(bqe7w{Ahpru|7;|-fi?)@+*6i-o zNF;Sly(z~5+PZ}wHWjs3BjiwfgF~%U<&8qE`Qy%qsY76&`nNybFCx<2Yo-5mx;k z6V0ZloHP#hXKc}0SxSqBzI^&m_a$aQEsBP;n|UG^_1Gc=)r;IQeP>A$#qz<UvyT!A3|8S*ml@h z7j-D{Gyh_~2_4ix1I0?M1+aO#u0DxlF;jJstEB&t129)d%w#=k+frMqVO+U%>;>$z zp4K+rlBc#tx`#ODB3IQWNXu4wa1bxyEa}#qRVI?KRJT--wzxbTt!D~lI%!`8zm#zn z@4ft%S9oicn{@&ymaZ3fT2f_|n1@)KC7r1P^E3)|<#;NVXP!)jk0W-?(>Pj8#R|8W z`CFE~HJ&_sZ?t&t>VQt{SVjBZYl`F)(k(cdA+!Z1y|appRD+ys`tTmCqof-0zF}0~ zb8TvEL8`s*D)Tg;H}yLMxiQro7K z=I?L)lY`mPEO|y4*xi_k#fv%5_gR%XUzq`t(!4+RKki_zKn$HWz;t~I=G@DR*>7M- zNp>*5`n8X5b}+|?7OucYGe>D&%mqH0*>eS9X0J-8Oc&kUpl0@B4l+v&1Crc0?ec4X z>(ERsMW@XYUEH8j@nZHH^l{9Zn-hlb$9xE}bklv@n1NU?=IK6euqVsS86pC>#`|6e z;j_bUb{ib=;Dh|zS9~#Ecz{30wjrmj`X3i14m{0Z5%;xLBEc@U6 z=Q)^*br#y_&&6jdOeYly@Eh52Q9{WETjO6_=3U@mUZ^q8^3m)y-@AL@uP+6iFd7C{ zqIvv-4ZmALGL3m6lRBmhGO3H;T@Ie_d}_%)2XmjstW4_M+K;O&UYfHR&;i)kQ~1%% z4rWthp2&c%>7zf%FY|HZLdiW0pERGc=f!V1nEyj#Rt9u^c^IekrH<5xyMQh_Q zxLJ=;xnqO``?wQ|jjd?!UfJGMuMS=Ir>e#K+O;lJ+A1d#WJd+;gT!WMc~x5OwY7NZ z!$tF+AW*=|>uL|C6%CEGE38*b0$;&2C*pa@8@pC?%omiIU#1n4c{h!8^z`@PfNodu zTR;I#%gD3t=JqvfXi1h3-h04k0pwvVpxTmGbL!;9=L6)y*K*?+kG1x~uF&UQ2SWgx zT=Rw8I(mltdamw|`_TZ1rctCjzGG-`xTn8vaL3Rv?iA}A9Ps7{P#QcEHaa-GqsPZq zoF?92<)|P|fEQxYrJz?Nw``&HpPR*sKHGS3eb2}>Fv+B?SELGtYW=wUEn8wuQF?kw zM+7*#`~*>mrK3Yx1|lINFA-H@c4fec^kX52C3G*EZBQ)vmuh*3c~}jH#C{taw|Naf=pKEOad6 zW{G9o6io4~b?i)*akuF{h&onW2Fp11xX%La3tIbfP9OB;_P+r0M-4~Kp6Sc-0lfG- zV7^5}aGZrIe9pZVR(va$0$fhrR_29cc0DHm$9a7`Bb;+9HM3$LHVC+zHEd8hVt`8l z=4Tp?bOiAw2eal=xMTqrgl`Yt&DJo4qYJ`!58&>f0N;M3|2kmW+1bL8%uIYHU+&Q` zgrm#EXU@PrpApW_ze9lgiG~d-?+{-65-@AIbOOg&dr*0~SUQi3mT*D%B6x8rU6AeHe#_D4!Q{= zS$QkYyKBMXaz!3cjXw+IORzLtC&dWvz& z%Ns%a-rGtG`R9((P56UvOP$-#k6B;Wq||#qjN^)7n1o`NY-94+__OMC40U~35lUIy z(#ltRa5~0;=rl;iHVR{Y77$8DwWV;=5;>f*HmJJ5t;WE+k~+OCddvIyohz%Y*k zcTwy3bD$s;8-H%>wcUlc{FVnb-g1P6QHLJeC33CsGe|viE*@-hf*+O;E9@KzaSp*% zrhNI%!!@aVIgYJZLZ61O;tnIEWaec%?k@-_c{>-SQ*UDksT9{D#Fe^y<9dXsjq;7% zHk>k$?;F^~KQiwX@ ziD$im`IYMEHBXd-fLBLpxryUPF zCc5+ROfm3zir=M*@kOxkA>cJ|Ord;*nNACla0?r>oB&fK_rjIpligx7T4**GnH>c< zq_qe%7vM;!klCCUGxL=OzzI_&=IJf5PNCCS%i4hoQjW8tMYKCrMXHzMz!)|l)%VEh}1sD z%F*wIYTnrO5&5>8ZbKy(L{|70$@Y3kaY}sM4GwOyZ%~?o&$-%?=y57>jX3t-;rnB z@e5GVxn18vVoHk#z9OX(ZH+)lAo=(k=3i(7q`ql3aw`<^Hf&J!YS-1DA)Fj1w5;u$ zMF^X@kUlEJP&+=qpVXpypkvcSb*Udjy6a>~xpMSS2q%a=$@4vnkg!0V%YAGreiy2f ziBth~PxxB*t`ICWiuT?njA^$J;yd_NHs8?ZD59(IN-lOGq-yy+2q~@dL4=f6c@QC`RVX1bJUAx{tWsF; z)3^-3C`WKox9bqVIfiYD(d`|TubGEdcY^)5-HA79(6YDip1n)=syZMSYyDh&Mz~gN za|&FvIaqM4NOPr7aV3!lJ}xk)Q0M+2v%%O=5-2#Qn%`eN`iBtC|GZT(`f^w$krq{^ zGZ9jpDMd(ehQ2C0Iiqwd0>)SHp!jrBcJ_Pk?BjiJfB#54ksNY=zmIIj^3NrGz4>#e z863v&bPi{m8S~A}!J4tSzr6bU&#I7nQFRic)Z%qMLjSs8Uc#o=?w{4id!{{|o;WUN z(_JDyJu8NKLpdwvN-M&K8S%up7fjJ`T??ic&bjJ-|LIAr33X}~r|6&FcqHl2Jf<<{ z*?E0V$0!Of>2)UQlLZfP(DnCkzg~Cy`1LJ`Qzt{HlK!WT@#7)qa;>8ljGIs`9n9A0Qqz2xIoWbB zH=T3VeL)wY?gu3Ka#Q4$Hyz9mXqv5yP@Q_G&U5(uZ-4pxKP;ZY{7t7KjJI|uC%HLi z!>614`1%D-s^dBpVN~s`vntMxNqS=3wNnHbr=&+O*`MdXn3Ypfm^&aJs*%^v{>8aY zN#Cb2pJIe{?)TbxSux-8#k}B)dBcveN^vrqqju_L*cW4c@FSRlX|iFg+L15RE9nd!^xG=X^lKDEpG*W)}9et>xr)G9~_AjmK*5%b_{jn`p>Nm1IZnTYq-8P zf}^mU_;o|^0UeJ+M|6DuNMg7@K2S>xwQC1=_F>mw)pT)d<5{|0RXEGcSPUx1j~xKkhDT`@pcbwDT8v-dntg z_Vt4!D!CPhPZx?sBd8aBYwMDR*h;yxbp?wvNH0Ne8$CX}-B#{*U9m2*ZsqFL0^Gzm z1N4UI4bzjfn;B}O7q?&R^!}{mPq4y9zqOm+kNP1?BaujDthS>r+Os(^IDCT@9f{N$ z%eQuKwtf?=5e!ozP~YEg6;PFKfg@mb=|@KB+N~Sp*NOH4p5d^j@9JTE<3i?;vkX$D zI4SiY)!3~f*7gkHya}UQj{5LM`N2?!J~&(2>jstNG!2X-dImPfDQ-5M&H)!rspJ5J z6*ur+;m*F^c-^+1Vam2nlljaN#9~b**&hd~@#dZ#JhcQuy0v>7vlYI#H#Rl5t*>pa zYv}GK%Y*n!K1pd@%yI$yB(#EGX%;M2UtN@MonNqUi90qNo?lV1Xwjl@xT<Q zl)2!7=vx4o6)w0;{5ycW)&QoEBQQAT8-#BbV9s;FWx~huRsd#`hGV}Rgl{)s?wkPM z14w@tU>Z3FhGTJp@ZAQO4{Nv}{zZ`fQ-JwT4VR6+zXPU_<7&7dd||ws1(-z|E?fPs z0?ZW?;2Q$IUcmfR!*PHfRNiX5Y$O1jMc+UF>kzj{;akk^JbiT>Ch3KTqr$$_l*1xk zoMmGzP%T<;;I9@GxM;zFofbia(p@nk@@2w8*nHWwRw^N4p)BP~%UviTcyeVL|DwEP zwS48pLKA4}7(39J#FoQcET(kP{2!|}ZLXa>*ynSYDU2(zp{KDswh};7okv>XEqkpa<9Tc@QJQS zd{u7@5~IDFq@XbsElAG7hMgko3a_IC8htd++DEB)&0*?=ctWytJWoRKO+N7=W65K+=*M3cMGVssFZSGUzfExm)-$JJM-q8^3tvC-}R((qF)nEqJ%aXLPQGR+ z=7@g*vQ;%j0=`BM4t2neNF+?^r(o>BXBd%~7Wo|iRvy6j&PFHb!l>Ye?!=LWi9#%dY8FD0SB=#c*U( z6dP}~wn0(kIf+)hn}d*&^2-q7;%>eyp)HlrF#H-kA>$VKoJ0$AW$_F@*c2p!X{Q*% zXYAg@>Hg<)LsMbLcPNNvKB$~xHoxA|HvW{r$XAoscm1~O%5G;j{l0xU09F)G%P0yc z`6>T>j` zk!WvBZj{}1ddu53f*$_=?7a(k71h}`JRuzzw$%D6T57)g ze%6}Po|&Bu`d#09{nx)>CTp*`*S((gtY;l(&5U&RBviiZ;4_!IyGPu@nkJ^TA|*=8 zP~U+=If*oEyY#2w%pinNfpc-Fn+22*UtPudAn~1yvkEJOuSUYC85LFvpTbqcM`foA zW(IuO(q<_ie&WWFa!?%Qmz#YDyx@sfxOH80pbMVY{-AZKlEpbDWsOQrxmjI^JF{iI z5eG3mxC>rA32leWKnQVm$b9^wQz6cAEse*1Dr4V^b6T`g5Kfz?OEp4>Io>hKC3|WL z%S)_)AT5nOnl>dcj0fd9Pr~CEwKBH7OmX5}hwn@kMyG_dQ1uiIrO(~G;ybp4zeNaL zx-g3`MFQkRJnFP7#5o4%u*^=K*q~>n%zoq1=$bd|)W4#c2YXg3Wo{Op9%Npf`J&z0 zn!o6iEfJf!LNlvpr6^gem5X>C((3J8{Q8c*XM&!dVlGH?)uuCw?D8@fPSw*>xNKY% zm=+hM?6imtdY-Bu*GMz%SO3**=j#^D{6(Ip$_Fd0_8%|ozSm~{qh`)B;`O7JCC$7~ z8^0Z|@rf@Bj^I*LKnDvz>%RT6XKm(mWkwj~k(n-6hbVhyi2V|NQ?KsDRj1XlMR)5k z=qao)kvLZTb^hhHJd1Ve*`A!T3$>Y7%)9oIpr^1xK$7OfC;toMMXfqxy=GQVVd1jT zXXTW5XD)b~#ZGJ6DOdCdJ(sl_NZR@*lfH=t#Z2oi&75Ot)w}%rqLn%|?@XQjw4FMB zU=+$S{TMN(uWDK{yK~7(Zj~)-Z&|ZOuN#HK`B)yp+D7M^>W-zISlpQ3G`GH?qOKk< zpRBH_oLj0_lv-9ru*=E;8)g4&1TiUV&JGR|v%`csat>@+@`$(yJFQi(BaU%87 z%>0g(9i8j&-dVhlv#xEa58GMXyIt2NZ>tQt9RI>yXF`r=1k|f!omnDx+@h9Ge)z6V zEhq}aley_ETfL_16I8YteOY=f2%k+2Ra37Ay1Y0Y++2MVaxP7tT`HT{ zn-E^s(lNiIy|bmYrgL2wi^DKPl|0@b%Gc_ey2zh}Wi;R`ICO|~F2_q?xt?piT)3gF zi<{-SIBl)pl`mhz{q|~YS}jgqRECY=YXF%rX;Qu{i|LcOj#fO;8EUViO)M#NtfLK= z-OhFBu8(F#g7aHP+hA5)1ySp0j?V-!m^J-*;Lg_V5&6E(gQvW<=M^YqV<8@NN?L?&ksUtFeaADOZZEmO9+e&H_@ zdIyn-SGkcd1fAqz&Q5tT4evRen=;d|gLhzFUJ=#UyB+^SPhbw8h6#9@+IEEq5<`RX zdbd-rCpDOD2O#X00x(c->GFXsTiOi>b4ts3 z^a0MJT34-d&Y?iGUvGUl_vPam1^T@q>pR}17 zN@vf1I5$)-KCR?uJDWhjw7&7`p;y>x{Y=rK#N(M+&+S|gre-@Yz&E{ec}Ht`+uG$z z+Spw!ZdtMtedbI&*=3Jf$|ve^i|PS+KX=Kh)ysLG*e80$h5iI!teS(7+`PGUyi>)e zh{~69r%`!V%Q`je;Qdo2i`m=aZmzt>pF5M;*#^hJb4C*;6;E;YsDt&h#YIJh1rmYx ztIkQO#r>+~-@wd;1_kHW&*pLOn$z)qm1E}3OKd&X#^J&S?k~ml$63JL6^9Gz?;Zl~ z8I7d{`}KDrguj#|-$%fuO-2N`AigYI7zxZVB??D73X<}E!oWlvI6pqhcMdRjX&lWUi0>(2UK@ljg!u0QGlYwd zaEav01SZ#k^OKMHJqefwjbj@SB;N{P)+fPtIWYGn!S@s}uMNVt3G%!P%wjIY!X?UY zJ1`p@xS;%A0n7sqTu^@dfqB7!^W$rVOuq+a>gkkDt-%HHEe57beq-=fDN! zHyt~)55qy1NWKs-5eF`a?;K!OIB-Gw>jvgl2QG;39$+4I;QaX59y|q1&UDF!tn~!( z6$4YLaY6YFfhGdXY6mWeZ#^(qIdFdRv3#!sX1m5ED&Nk1~FVBzTz$&m{t8TP1%F{oh(mA}a(|5e_8P)CC7BA$VvVC6gtNk7 z=a?HoYCj7wS7=<2d@PSGz})P>1=+z}z&zx@`RT72eA|J^tAq#6%7^351;d%{3}EUs zE=WG=Zy_+xI&eYqy#ma84xFESjD*#*~`3iuU;lKs)%?9Rb2QEmyZv%6?0~f@1FED!?xFEjIfEiJ3=Oc(O z8<=?xToB(PU^*PQAifKM+3LUr@ofWUrvn$n_XaSzv+R5X@tp)ru> z!Sg#Fm@_plD8FIQQ~`6P0~b^t*8=kc2QH{Q?gnPJ0~f^iF)-=ed;k|DUo);{0kc}; ztn!T;A7lV`xyHaNE~p>88n_!ZHYnXN7;XpVJqIo*AA5+ID@g|CgM1@^ndQI*@y!FK z)qxAra|bZ@IB-FHTY-7XfeYf>3Cw6VNO06k5MM4Z;~cmkzG7h3I&eXJn}FdRd%8sB zaRV^Fci@8f{shcN4qT9Yp96Ddt(|TVUllM59JnC9#lZZ)feYfh8<>Y3I6uB-i1j2e zC)FwWEW7s^H%$d*mc}L0-#lQhbKrvHy9tuqzyNLGm@@ zS}rgfG;Sz<3twD4&qDY;z&xsPY546o58!a*Jz&OjLI5`!haZlY-^HnTK2eG13mFZV zU*ez(%11t~9S=;M#w9AZrNFEmgl`l0HWAZ^18x`&(TmS~p%R!2HO?Am`^*=<4a}n& zNBM%<$(_Kwt8qd34I%z+je%EOkR4<$KpEqp3*x&M*G>ZF6^&!N?w4Pd=SgSd5nUW~ ziSpY3%tnn%l;3NC`GLj-$w&LU8<>Y3xS;$#3Ct@FoL@a6-#Z$^e9#5)?IG?QfduN0 zd?PeQA%ppj1n!h1_==L`D+g}gAbep6wFsD-G%iv7_!%(U2I1=m-?PA6eJ(t3BX9)S z%N}5cEEHHmdkFzkrE!VuWg#%_8W&_Q`ABXpFt9^(q)2eYn@=<>sz})1( z1<7|OFk2lsKl#Go+Xl>#CM6&Hk08ENfSIasLGqEW9GJ@;xFEi3fVs(m^OKMHy%U(% z9JnC9cY*oPf%D^|eEWboy%`?3MEPxP#)ftrbcyo2u^Igb4!T74x3d}j2M)SKe7l=5 zo@^0VLcTCC5seGt%L2_g8lxD4%XbBE>j&Wrf#mWe`ECX7zCrj{zK^wR55gA)-}AtX zT&|=`RNsyVraB=-;65=9 zx}f~BJvauK8V4>&z6HQ6bKv~yFWZAIV76&oB71%Zm_38=g~0b2Fh{P02afp&k}nUK zA_vY-KIZpKU^+A|k-dBsm}`^ZyAhaYli+&?m_38=ZGwEC0kggx9=JsLy&Rb99JrwT z-UQ6^4qTA_UIS*A1Lw!b^8FB)8LLD*d*0*IzBB`~TH}K3F9e$Pz}(=#1<7|SF!wod ze)6$=9|h*`8keYihjd^a2M1k{eB{doX12y9;%f$G^&otkz_%Wl&m6d*{HArH{^FoZ zB;PT>)HrZKd<%eC=D_*suNi4|0kc!%tbWj^d_Mzb#A-?xEMExMvVkdb;DY2k6POwY z&QHF4@GSu5N{vfY9ybDWx5g#X-vhwBmjvHuz>K&60>B0FZNjx|V6JoEg7SM4F!wlc ze)-Kp2Dbw9)EcI$o@@`|yP_LkZoxqpBpi(5||i}2mRWUo`Wp(ZYFe3gsvN?;ai+%Ww1TW8He_?^IP)i~Oz;NsRNOA!7J zFgX{(1E+BQ`x(N(L^Liazaem(qcP;83o4KGz+E*6AMtH4*Cqnf zqH!E=1kD331?KA-7bIUZ;(r&IPc_a;*QfnE?qZ~kgD!}V@=eni0pb*7FDrq&co06? z%jP8cz6IQEgYZ$lpCrlmHgNwKgzsMPeG1GEH^2jz$X*@+<~fZE(qBI~UIpemmyk{A zIY@uE0P|A^&aXY)1dd+M9De#M zM)-`&u#SX-E**#9;`A3r_^Ld7ON#ANK?EXN^n6?;!b7FGv53gD#PLM+5U8jSJEr???4)HjJ;~pkumz z`eVO(8!*pl9P3+}Ug?a3E|GjqzP z63O>HV1A@=LGo=uTK5A}ait_1c>j{}#en&~#wC*Pm%#i{;}XgD2{6N=D%~LYsJ}yi z`Gdx#;kW3|r~ep!72be=gD!|~HLjfi%r`Y|7=8zp$M1moK;shScX$l_77n^Z`K?)BMDh*28m|DxL6=CrNx+<^af#%+0GP`(E=axzF2sO&y-%e(0)K+^ zH~kvJsKr5-NWM;BzN2x82jK{kuNRnaXwv{|9Rlqco?0ZOv3}?2K{&?ruh>ePUyr(6uRXj3hj7FcDK=PEJhAuDR@dWUA_OG zZw*3_yo{EAO*axA^?o2cI-9XIHEe9cyQFp))Qr4VO5PC{a_)Fph&qIa4xYV%KVc^4sk4|>mN_0A!@6Y5|P zE94oxx{Rj=d_bk&7sGG%%+AZJt;0t+QUp8j0^Y_oK5;aOVxc$inc6(OXey_^R$eTX zBQN^OQ{PL#2OEZ~SFFNo01#@uajO)v=HkefcM(x%=|&UIM~bf% zXWCY}aRJWiDvRX^3Hu(-tkLPloj9wjkHW`V#SszI!eW6N$^_tYaG><~9TGgI%hpAKX{pQsB?;p! zCIklwB=zIqR~CbJ?M0AwW^G?h+AczNRA%uHsp7vIatOk|f+{B@f6 za584_1c&xf%z7OBqEDul(ffFonVKs*tTVKJm6t=|qZ0!BEy5vr$)avpE~-rGdi%4) z;Iy>XqxT{!b*^OPSd-jomArkC_Q)ESSsSSnYeWWMk1TFv-ZoMR zwr!I6ir`4c_qWaWqjBb=>~Ri!%0}Ta8hC;;EwcvxFKU_d6$i{kMBNX|R8l9l%yUfk z{kBZSp4c+khW>B2Ot$V{wq-6)iZj0D^KWfoOVZkQ*qk0~|6;9eH<*)eZMjJOMQxf3 zgQD~OwrM46Vw>J*vhTM|EB3@T-7D<>yIb2UO$}u5&AMziB6zuOt^Ic09Q9INyr8o( zX9wqV7zJeTPtORnkl8ziq+&!UuiSNXc+1b((a@?anB6hv_@^Su__;B*LM-Zak z!h5awnAkVO$M*H>;=}1nbNpC?O78>lF}=TwkLl6=)LVaPE9ug&vRu=p52yChWjuH) zY98P1f%koikNrA#JE_{jj~1mH;}AAoeAGa>_=@1G79ZCR>&16Ed^O?=!?!?u>@Uv~ zA3Xn8TvXW8!2JX9Q4e>Bk9v3xhtk7N@v($o6(7ekZ-|ehkoUwF!ubR7Q4fC*-&mYS z3Lo__Tzu3+n)s-PJvh=0>fwLHM?HKdzA(-?f}62LI9|9s6eDlGAXzS>a%L=QjUG&V@AfS9o>&;F@nanLOcu^R7aw~E z<)bb~;>eZ_{&$OSiFGwrv8Q)e8b6iASxIcpp6Hx?@3V^UsMv=yLiWASzgu|{A4`+J zvgMP2KZQ?y67U`g3l06I^A(;5b30~?AsIM+hC_Y(@<-ys$ykYl+J+O2QtSTjiB>rw zP_##nc9c%~i%fgID^rP#de^Itt@m&L>yD;H=SF(6FtW?&?cZxnHK^@6Yc66MgZ|52 zg+u3bdE@VR__F2WdF=66Gf?Dmmhl~n$Y866&y;cG%@3$%s-`qniVw+gkeq`V?TD=@ zXiA&T#yhzo3{h#A(q)J}MFtL$A+`F%8$RQ<$OQ+qus?dZ#C3`~38{ADP$TVD_^4PM zQXigx|No6lN_R-!h?nUpkqOFAlec_{;bZ1;EHsja{w9MO!30Bn)DAN*b873Fz-{3i zoJ^`L*tXCi(_&X_%hb3eVH)Zaa0i$MTgfES$d*z)z%o~wP*s>>)M&1|6 z#~+eQBlnA>!G0-;e1yJ88tn0W(kO)8=E&kqF6%X?&ADpEoGX4V)fC02YfbIrY`F?) z(4j_)Ewj(`Npn2MW~?*rMIlPUP&hQm`NVl?1g{mkDUre?JPXL}Z;ui{JTe#0&l-5wtkN)~ ztC1c#Rjb3)=#ZMUwjAd`Yv^X!x^cIy?)F`j)XKZUHVQtQ?J&aOgbIH-eoBt*jU?DO zE=!K>?IhSZ7E9JX!Ut#{91Z%U5#LW##nZcs&uxS8{RBss!;Ckv7>g0^!n};P-}!iZ zxI1HOqcLogS`Tt}Qoa?SJYE8;0_cvKC3+%KN|*06*w)Ha>FU%Ut7dTY>&Q7)qjnKt zb&?pj;IsGqdVz*^z%fxKOVe z5-xjY#j9T9=p;@0q;`A|!v zj)aoQ2WO4`X~gFv-!!-V&IjkC{%QE;!|Jijgp$bzXS)7r#OK56H%$7Z%Y!rLWNNLW z;`nCJ>LX1FTou=@wI{*e?3y%R?9aA9&ghfNvDFfq=_Q?Gt`H=bhSeDDcN$!KKpI?I z<|sV&Pu5J{n#ioh4CZ-hg8FK5^{b2v`*&1UA%+pHEQwZzqm`#eE6deFlJ&CU3~GwE zk{s(syo=U{BU`=^)Cq=k`P6rZ_$qN_rTFH+w@iHScwFKYq}ITA9-<@z{{IyurKta} ztROvLSxBR{0IW(N414i#KCl&}ix6|L6{ID??!SVB8rN5u9Z~nt`)c;`>sfu3vYZsO zn$%#gChbgeHHkwK^qs~gNaDYubS$o3Dp$+lQ)^30;8QCyo$#rZr!Ts;)GKLlWo7@@ zmM)jLd5F7FeDE0SaG(_F5QcSKoTWYEs)EePGGk%hZq67u#JtTt@HPnA;e|ghG`T8p(Vt=H%4L{Z!0~u*fGv&4JqN*lU|#zvSpfy)`2C#G-T2 zu4Y?{d?B?K#5Py%P@p*lTW+)=+!(EqHnp;fGUR!=hTl3N z@7#Y=u5tzSTJbf*r^<4R6?U@~);H&!xV1rQ_xp&MEh~}V5f0kN{+HkN5|`!o4e`Na z+=YWZ1_GoYu7L;Tm!fNg{v;QN>PmWeWG4pynvT-xG7o3Uv@s3(r88F%0T9O(a5pj| z0Lc~dVaC>>Sh;h|<47X?8~&OzHm*xc+acy*nFc4c+3ZYJ+2#b4t;|NzQ*y?lN{S|A z=XE-M(IG#Q;7=tr|F(oS+P5gTK8nwsX*nvZV3aZ!=-r#rb8Ni|UL^UVNv2sQm4$4^ zYEF+el*H22+?a#(vDlqci%;Pd$xHR~u-Kiud0<0MtfoA6*fPph8>GbtopWWcD`kc2U^h=o&ex!IUZ#TEY_!JK*@!wgc`0 z(N64OyRi4}#`1UUpS>HaQt;(ORjR$)GoFa0W1mz83vL`+q74(`ZBy(L+y#_p&bhkHiTcU0zc`sx@-9)h22(bU}bT=?jqbEK}m zdm?o^!*xSIc7EXQ_;DQ5I`18Dkc&G5`;hZUY)^56dD!2N->`Oz$Gr;N#*(wUY=59&4Av&~Q2 zJ6%zE(_)9j!ug-PaKg4vUOTG)lh+&)s6Df6LFr7Up^AyElJR`@7!1r1t(X72WRfOl0%Uo`agq@8e=myx;u|w(RHAD z|DDpE)%))uF06bGC{|e%!8dBgDr*C-=b%^xruI3pIcXo{AWF|+vH3=-F;7Kna(f3-dJaJegkl-dnoul~7H!D;;LP5E)Sjaxv?eE(6m14DX_kn0_Yh*+ubN8zi?8?!B1nTHE`deDb&&<@}ut%vcOyz@4{4sW`w-Y;r$ z@7bk(xyw-13-$tby*L5C=*%6rqfG6}Dm@f>P^>m5niZ?fWxFX|1A{^cs?Lj6;kGNA ze=?XouT(Gm&bFAqa_|m9j2&V2{01v|76d*e*}9#HJ(~Q8?v^d5AiBy2YqXt@8uG#+ zbrIkQNuB)okd)PSG$IEy8+5N@qc!7Hfhq+qh}+C4M#LaoUO4$ay%-KAkyf2QgeEBsG`t}__nSv0YUjs-dlER)<@?d9jH-U}@C_fny8cY28{hI5Ncv(KvC0x%mEMG9 ztHgFO4)fcP7pp1J>v_sVs<;bQDRav~Kq<>O6uvVgeU29RMY(MGTDNU2FN|JNic7M$ znSWt5QtPIQB*|!E>;Y?n>BVcHEGZ3)jW&#n*TC!p)Ij{*O@32PjX~KZ<$XRh6@x!l zzeF`tc8jdeeT|J&CvBnemQYVYPP@Qa))Z(lP_QgI5 zbtx-alOMr=-r3?r9Ln@q)d|RfZ9xSp^Oof-l+@6e;iGQO7JzlruKJ90l#YoA;#v+k z=29!B)mD7r=OR|xoQ`3?+J*kbcIsXL=Hz$ku2ynzl*P%;0X-M7*38R(@6=VYa!*wb z4%KSrsp4X*DehvEeZP0=D)!^S!ahu~oAV}&sl;s(_W#{GbvK(D@XnnN__>^`Y|by) z{_XSrgme4JP}3+n-`T9(ERNfBz-y|GVw)R#O9CqW%5Q z=JeR#m-}4Ky+}ztm-7?xCHq{?JxanaWSRGyx!iBdR8l9l%!f?&{kBZSetbg9d`#H? zcU$Imk+GIt7X-Iy8Om=>+f7)oD)i|IW_BSKDe zBaovmzXX6CxScgj9%VQiB}tcyKo3TFnn=FtjBo#{UQIlE%r?B zA5#ByE2r|^SeGYdeZ~i67{PIKbWXH11Ajt@pRP6K1|F$0s_v_NkZJzHP6G}quqKcZ z?)_EPw8ycMkTdG5{htpEoOdpt8=`Lo7IaZxf8#@FWzdkrdyeR{bj1R`Zi=`htXZyL@+K##a zrn250S<_zYy1xnEqL%p|f)|~u@2PSAdJB$hquKJoW31pwIhk_2F4Fnlal-8fm_Tm* zd{$39PKx@OE9tTs)y0ftXKH5XJJQ1bl-z=rSOWZr*`#^j@hEL7O--S<&uetM1@!^?|_YurzKYAZ8 zvb|N}-O5Yi<0zcJvgPa2Ea_}{;+=QJvW;VL{!mimsQn%Z!zrQLD|qt$M|>IZ4MFD9 z)jNd5$90qw#Ygj>AU@{c6!F31aYxD(vR;cLT~?RBAwCxPyOI*0QUNT`aSrLc$nvD4 zg#WT~xl4RBy}yXB2)_5k2ahook$5i}`jMLZ4zB3?$@Xr8y~*r0pq_Nh@ZN;?tf@yg zGU%Q)^&Gd0rF(dT7&hAjY{^Q4HByV2KxP}XKiZaL#aeeq7DY9GkaT_PeJz?Q^`H}P zFJ}=hsi5AXQf8?in?L3?YCVa^oy^8vcBvd9r9B+1@%7|ngelwPI8WJY4SaXw$d->> z1loUMqo)e8C0X90Ql?IWf(`;*yg|{B4iyeomn`wokVc7*G>dUi{cxgU7K2(Y^1Wqw zGMb_^^vj2!Wy$RA$5ZQ~We#ExP}uMIP3x0gdltmf=oVIyqbzC0<5#xh@us=>eVT;f z58seJZDC$$-6*_LWNRUm!#n6Kqnfn7jUP3#lc0*mAVb;Fj!fR^ zu1RZ@E}SnRQDD2Ywrru{tA?M8gsPEeu5QJ_oFP+EW7%*rcjHhS8*%p#1IB}zRPpp~ zANNG8lJ8gHJ4IF)eGOImjR%lqBRWOga__?vYq6|G?7^I;gO+w)r>_SnuGiEe3)WB{Gr&f^CNw@d!)9A)HV*(kBe5$1_53TAzM(PZ)wzEHCYYJ zYvy@+G2>iCZDsgWn=} zo1>COv`0B9@@qv(UrmHRhp6&L6^d@07u~oZx^ZE2V{>$4YjoqX=*D(-;Z_H(p2ma_ zMk!9g+f~$-)K2d(7qco$DJ|>ryJXYDP>VdMoTy1;5fgR>5vy44Qzv?o3 zpUluViP%`6b+GI(+fpiY#Vj@9IBECMWA@-CQBFuOM63gUr#|J~OmxLQk zv_!BcHf;8eyzFiH<~=`E{V3fk(ZO)|REgU&6wXf6eZeaD)Li=}_&5U2Hhux0x~oH5 zQgO}wcd-h+K6CaHcC*GpRhvo=hVK>}Y7_Np5#WoB!7dOE7I?e(Sl}zg2aoY04i+v( zMF_*=1~?}u+}Q8tH}tK{Xq+EK7pQf)A#bc%wz0XHeKXmPq{U|D_pL$0(UaP@CKOAT z79^{?(tL&@7Rimx&F$^anfBXDPu_rcGsfoTOnZFYG3cW45-9bY1)3su;?Lq)MJdk@ zxSN6@Bdn0&jTYgr1vB3&-yF0T&OO4}GTPToE3|l8GNc4 z;Y90V3Hxu$$LhIW!np167V$j{pE82y;By;+U&&LFO^BH;LwdWyn;jA^dz@L}GjQcH ziOX`nNPGmpii4#K4(UPG;!0rYVv`LPEFraB+p zgJAoSU68qPiwHT+f|T+^rtm7epbo$;&H2Eo(rklIl_ooYs}MKaxDh^8a(BR|N{;1} zT*+M{>5l|{|4Z)c5|yS2>XhI_mJ&C+E6p^WQAX1{uLBCe`>v=Tn0TXwxl zw_k-XIo*CwQaCW(-Y9XY+wX`E9^+~pX*i(UG5mcUuJ9F*YT^J5jk^4&2#!@o^gudR zIks@1@b%688%J|2RTI+YePK>)L2j(F72}=BvC1&6=VLEGUrmWQs>+FVEQ^J6V-4-8 z&yCp@d-b3fyGKlW;?fZt(x&}pO1&a z+>bB@e1U>3rX)738}g#**o!xERedQg1u$V1-L z6`bhmK3oaV6(2G(8#W9jv&^=LRZ*rg9LE?NN4hHHUR4>VsLEInUl|uIqQON&TZ@)96Kfzj8>U>!O+kDeM)tH9)}G4s0@Mxe zsT(k}Gdr&YRU4}gGGoW!Chz^xxEyO#11Y(wRD{ZvRU0i)n8N-KhRTu;Li1SVt-2J_ zbqPu}o)n$?*@oR8Rsg5kg%->A34E$XrK9ftN?1;TPle5Z&$OJx4@NyLF%Qggo{_k; zobBR+$C!H?BW=s$xH72aEXv@+Kjti?GK@z2Z@4GAA#WV*#?eskLJN=9yVGq< zFoyGDGjm`DQqt0QRuw+Y=i4|K!jYri{voA(>1iAIG(TIyYz$?Ob&Q4Q<(-ZzS&`^e zs|YXQ-dI3OU?4^4p-+uf{^Hmb1X}(Jqvg z{N3{9S(Y=w@|7iRL$8P=2WCUBN?h8|PVvEG%+WT40I{Lpz@u*^7z52?p|P|WJY2XF z4+pH`$?t8?OG|s792}GJ(a3DW9mYrL;=}mRT(&WO>GF1tH|ajdEtm6C%cd^uZd z`UwXaymgamjBo8~ThhH&$dQzhno_6HOJ+>uL=tYi<5NRya#K^-Bhc+TVmu>h$5uHP zhhQY^Y@9JGbcAqFM5i$0`LQDvAXCTG6q(i|VT3BWW} zEK`tFnXNdPhYBWyGu;nYZT*wYe5{T()WghDvY8)zvgN^{9_C>R0}k5yNk=~Yn9V#( zGY=DHT$VEDUpnR=A05>g!@}?pH|3a9I^J|wE5lNOqx?V{@G+RpR7d3y0e)JZn0G^J}ugZ zoz~muHl2QuCoLMH$_1*Madlwfl+wmdnSd6dZGv{l-+n|YLnnae{;s}%X|RRfrCG7Y*i&3uT5c{HxN znGf+Wj}Z*Zi_9y_KStFtnJ?7LV?4}kJF&<_PJ5p0N;Y_}F=iG^;Oy-|z z=0k-UmyJVMWwmo_o-b~)(<03q&x!?Fw<0J2(5=sS|sICv|SVPE85noPxt`QFmzOqdfUy zYwKn{%EQcC8$lNJf@VJ2!+eZ~`DhRGu`Xt}MWwRQg*(>6973pD=3_m~#|dT=&M7$D z7By8fALn5{UShG9F&5o%9_AAe8e~7$YvvO?%y|;a$$Wx``9v4^S^DvM1FrVgO z<{kH-mhD~5Ji)`vJlZn9x_Rc)6Fkfl1;a9B6)fB^W|wU(WgJ$(O%!JO*69$#3i+lZ zWO>Rpz_3+!yPr5P>gp@55a+m#H;9zXx=FxqlX0JpMGP#;F&ZqCSXDT)2U5{uO9xw3x63hd5XMLg|T!<2`$IO(Dz+eE*Pr>Px+5^VeWNd#ydXM z#s_FqQ;4SQ-`VnJhL&d@d8kip(ZZ2xe!2^D z)uuC0?4}NXtC>$%I&_Tr&v3=cO1tW_(>NRJf7Z-r3NtPnCvljp zo!jcBBh;OXGd*dA1w%_n!O`%IG&D%`(M{3JVNWhfan;Qn_At*7j6ZX`W}e|;F7q(Y z@GzGPCX6#B{rgilKqvIk-KLq#JXy0O!(1ttFwW#FxVii;oB4UoTLv#+l4z6CZ#<(MR`)W{!B6YjM@h9Pu#M35NXSOZofdSSmD`|Dl=d zJk0eT<~k2EdlP$}`=9szgj;bY^H@$*;pTamF}aG9d7g*4K`>#Q$+v#g);^oLPBS-n zm>VUQvjiJF%v|@ft*-j5E-1#7dA(*{;9=&Pid)YMJj~}<%xq16J);l z?|g}+J5KoN7@zJb9g7$h_MQ$gJQ6Mg#+Hz=mwF^zE|@UR%<-g8N3_@y?$ON4JXvz>hk2D?!Z?%p;MaZ*Iq9P-)6A

3nrm@v-d+d1%ku$jz%(9As^ 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 - -#ifndef _ACTIVEX_VER_ -#include -#endif - -// -// Version flags. -// -// OFFICIAL and FINAL should be defined when appropriate. -// - -#ifndef OFFICIAL -#define VER_PRIVATEBUILD VS_FF_PRIVATEBUILD -#else -#define VER_PRIVATEBUILD 0 -#endif - -#ifndef FINAL -#define VER_PRERELEASE VS_FF_PRERELEASE -#else -#define VER_PRERELEASE 0 -#endif - -#ifdef DEBUG -#define VER_DEBUG VS_FF_DEBUG -#else -#define VER_DEBUG 0 -#endif - -// -// Version definitions -// - -#define VERSION_RES_FLAGSMASK 0x0030003FL -#define VERSION_RES_FLAGS (VER_PRIVATEBUILD|VER_PRERELEASE|VER_DEBUG) - -#ifndef VERSION_RES_OS -#define VERSION_RES_OS VOS__WINDOWS32 -#endif - -#ifndef VERSION_RES_TYPE -#define VERSION_RES_TYPE VFT_DLL -#endif - -#ifndef VERSION_RES_SUBTYPE -#define VERSION_RES_SUBTYPE VFT2_UNKNOWN -#endif - -#define VERSION_RES_LANGUAGE 0x409 - -#ifdef UNICODE -#define VERSION_RES_CHARSET 1200 -#else -#define VERSION_RES_CHARSET 1252 -#endif - -#ifndef VERSION_RES_ACTIVEX -#define VERSION_RES_ACTIVEX "Filter dll\0" -#endif - -#ifdef AMOVIE_SELF_REGISTER -#ifndef OLE_SELF_REGISTER -#define OLE_SELF_REGISTER -#endif -#endif - -#ifdef OLE_SELF_REGISTER -#ifdef AMOVIE_SELF_REGISTER -#define VERSION_RES_SELFREGISTER "AM20\0" -#else -#define VERSION_RES_SELFREGISTER "\0" -#endif -#endif - -// -// Version resource -// - -VS_VERSION_INFO VERSIONINFO -FILEVERSION VERSION_RES_MAJOR_VER, VERSION_RES_MINOR_VER, 0, VERSION_RES_BUILD -PRODUCTVERSION VERSION_RES_MAJOR_VER, VERSION_RES_MINOR_VER, 0, VERSION_RES_BUILD -FILEFLAGSMASK VERSION_RES_FLAGSMASK -FILEFLAGS VERSION_RES_FLAGS -FILEOS VERSION_RES_OS -FILETYPE VERSION_RES_TYPE -FILESUBTYPE VERSION_RES_SUBTYPE -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904E4" - BEGIN - VALUE "CompanyName", VERSION_RES_COMPANY_NAME - VALUE "Comment", VERSION_RES_COMMENT - VALUE "FileDescription", VERSION_RES_BIN_DESCRIPTION - VALUE "FileVersion", VERSION_RES_STRING - VALUE "InternalName", VERSION_RES_BIN_NAME - VALUE "LegalCopyright", VERSION_RES_COPYRIGHT - VALUE "OriginalFilename", VERSION_RES_BIN_NAME - VALUE "ProductName", VERSION_RES_PRODUCT_NAME -#ifdef DEBUG - VALUE "ProductVersion", VERSION_RES_STRING_D -#else - VALUE "ProductVersion", VERSION_RES_STRING -#endif - VALUE "ActiveMovie", VERSION_RES_ACTIVEX -#ifdef OLE_SELF_REGISTER - VALUE "OLESelfRegister", VERSION_RES_SELFREGISTER -#endif - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", VERSION_RES_LANGUAGE, VERSION_RES_CHARSET - END -END - -#endif -// _ACTIVEX_RCV_ diff --git a/src/BaseClasses/activex.ver b/src/BaseClasses/activex.ver deleted file mode 100644 index 59943f3cdb..0000000000 --- a/src/BaseClasses/activex.ver +++ /dev/null @@ -1,56 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Activex.ver -// -// Desc: DirectShow base classes - common versioning information for -// ACTIVEX binaries. -// -// Copyright (c) 1996 - 2001, Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef _ACTIVEX_VER_ -#define _ACTIVEX_VER_ - -// NOTE: all string resources that will be used in ACTIVEX.RCV for the -// version resource information *MUST* have an explicit \0 terminator! - -#define VERSION_RES_MAJOR_VER 8 -#define VERSION_RES_MINOR_VER 1 -#define VERSION_RES_BUILD 0 - -#define VERSION_RES_STRING_D "8.10 (Debug)\0" -#define VERSION_RES_STRING "8.10\0" - -#define VERSION_RES_PRODUCT_NAME "DirectX 8.1 Sample\0" -#define VERSION_RES_COMMENT "DirectShow Sample\0" -#define VERSION_RES_COMPANY_NAME "Microsoft Corporation\0" -#define VERSION_RES_COPYRIGHT "Copyright (C) 1992-2001 Microsoft Corporation\0" - -// The following defines are required on a file-by-file basis -// -// #define VERSION_RES_BIN_NAME "sample.ax\0" -// #define VERSION_RES_BIN_DESCRIPTION "Sample Filter\0" -// -// Also required, if you don't want the defaults, are -// -// #define VERSION_RES_ACTIVEX "Filter dll\0" (the default value) -// -// A string defining the type of component. -// -// #define VERSION_RES_TYPE VFT_DLL (default) -// VFT_APP -// VFT_VXD -// VFT_DRV -// VFT_FONT -// VFT_STATIC_LIB -// VFT_UNKNOWN -// -// #define VERSION_RES_SUBTYPE VFT2_UNKNOWN (default) -// VFT2_DRV_INSTALLABLE -// VFT2_DRV_SOUND -// -// -// See winver.h for further details - -#endif - diff --git a/src/BaseClasses/amextra.cpp b/src/BaseClasses/amextra.cpp deleted file mode 100644 index 156bbd3772..0000000000 --- a/src/BaseClasses/amextra.cpp +++ /dev/null @@ -1,111 +0,0 @@ -//------------------------------------------------------------------------------ -// File: AMExtra.cpp -// -// Desc: DirectShow base classes - implements CRenderedInputPin class. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include // DirectShow base class definitions -#include // Needed for definition of timeGetTime -#include // Standard data type limit definitions -#include // Used for time critical log functions - -#include "amextra.h" - -#pragma warning(disable:4355) - -// Implements CRenderedInputPin class - -CRenderedInputPin::CRenderedInputPin(TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName) : - CBaseInputPin(pObjectName, pFilter, pLock, phr, pName), - m_bAtEndOfStream(FALSE), - m_bCompleteNotified(FALSE) -{ -} -#ifdef UNICODE -CRenderedInputPin::CRenderedInputPin(CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName) : - CBaseInputPin(pObjectName, pFilter, pLock, phr, pName), - m_bAtEndOfStream(FALSE), - m_bCompleteNotified(FALSE) -{ -} -#endif - -// Flush end of stream condition - caller should do any -// necessary stream level locking before calling this - -STDMETHODIMP CRenderedInputPin::EndOfStream() -{ - HRESULT hr = CheckStreaming(); - - // Do EC_COMPLETE handling for rendered pins - if (S_OK == hr && !m_bAtEndOfStream) { - m_bAtEndOfStream = TRUE; - FILTER_STATE fs; - EXECUTE_ASSERT(SUCCEEDED(m_pFilter->GetState(0, &fs))); - if (fs == State_Running) { - DoCompleteHandling(); - } - } - return hr; -} - - -// Called to complete the flush - -STDMETHODIMP CRenderedInputPin::EndFlush() -{ - CAutoLock lck(m_pLock); - - // Clean up renderer state - m_bAtEndOfStream = FALSE; - m_bCompleteNotified = FALSE; - - return CBaseInputPin::EndFlush(); -} - - -// Notify of Run() from filter - -HRESULT CRenderedInputPin::Run(REFERENCE_TIME tStart) -{ - UNREFERENCED_PARAMETER(tStart); - m_bCompleteNotified = FALSE; - if (m_bAtEndOfStream) { - DoCompleteHandling(); - } - return S_OK; -} - - -// Clear status on going into paused state - -HRESULT CRenderedInputPin::Active() -{ - m_bAtEndOfStream = FALSE; - m_bCompleteNotified = FALSE; - return CBaseInputPin::Active(); -} - - -// Do stuff to deliver end of stream - -void CRenderedInputPin::DoCompleteHandling() -{ - ASSERT(m_bAtEndOfStream); - if (!m_bCompleteNotified) { - m_bCompleteNotified = TRUE; - m_pFilter->NotifyEvent(EC_COMPLETE, S_OK, (LONG_PTR)(IBaseFilter *)m_pFilter); - } -} - diff --git a/src/BaseClasses/amextra.h b/src/BaseClasses/amextra.h deleted file mode 100644 index b10e22ac41..0000000000 --- a/src/BaseClasses/amextra.h +++ /dev/null @@ -1,56 +0,0 @@ -//------------------------------------------------------------------------------ -// File: AMExtra.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __AMEXTRA__ -#define __AMEXTRA__ - -// Simple rendered input pin -// -// NOTE if your filter queues stuff before rendering then it may not be -// appropriate to use this class -// -// In that case queue the end of stream condition until the last sample -// is actually rendered and flush the condition appropriately - -class CRenderedInputPin : public CBaseInputPin -{ -public: - - CRenderedInputPin(TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName); -#ifdef UNICODE - CRenderedInputPin(CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName); -#endif - - // Override methods to track end of stream state - STDMETHODIMP EndOfStream(); - STDMETHODIMP EndFlush(); - - HRESULT Active(); - HRESULT Run(REFERENCE_TIME tStart); - -protected: - - // Member variables to track state - BOOL m_bAtEndOfStream; // Set by EndOfStream - BOOL m_bCompleteNotified; // Set when we notify for EC_COMPLETE - -private: - void DoCompleteHandling(); -}; - -#endif // __AMEXTRA__ - diff --git a/src/BaseClasses/amfilter.cpp b/src/BaseClasses/amfilter.cpp deleted file mode 100644 index 2865bc75d1..0000000000 --- a/src/BaseClasses/amfilter.cpp +++ /dev/null @@ -1,5207 +0,0 @@ -//------------------------------------------------------------------------------ -// File: AMFilter.cpp -// -// Desc: DirectShow base classes - implements class hierarchy for streams -// architecture. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -//===================================================================== -//===================================================================== -// The following classes are declared in this header: -// -// -// CBaseMediaFilter Basic IMediaFilter support (abstract class) -// CBaseFilter Support for IBaseFilter (incl. IMediaFilter) -// CEnumPins Enumerate input and output pins -// CEnumMediaTypes Enumerate the preferred pin formats -// CBasePin Abstract base class for IPin interface -// CBaseOutputPin Adds data provider member functions -// CBaseInputPin Implements IMemInputPin interface -// CMediaSample Basic transport unit for IMemInputPin -// CBaseAllocator General list guff for most allocators -// CMemAllocator Implements memory buffer allocation -// -//===================================================================== -//===================================================================== - -#include - - - -//===================================================================== -// Helpers -//===================================================================== -STDAPI CreateMemoryAllocator(IMemAllocator **ppAllocator) -{ - return CoCreateInstance(CLSID_MemoryAllocator, - 0, - CLSCTX_INPROC_SERVER, - IID_IMemAllocator, - (void **)ppAllocator); -} - -// Put this one here rather than in ctlutil.cpp to avoid linking -// anything brought in by ctlutil.cpp -STDAPI CreatePosPassThru( - LPUNKNOWN pAgg, - BOOL bRenderer, - IPin *pPin, - IUnknown **ppPassThru -) -{ - *ppPassThru = NULL; - IUnknown *pUnkSeek; - HRESULT hr = CoCreateInstance(CLSID_SeekingPassThru, - pAgg, - CLSCTX_INPROC_SERVER, - IID_IUnknown, - (void **)&pUnkSeek - ); - if (FAILED(hr)) { - return hr; - } - - ISeekingPassThru *pPassThru; - hr = pUnkSeek->QueryInterface(IID_ISeekingPassThru, (void**)&pPassThru); - if (FAILED(hr)) { - pUnkSeek->Release(); - return hr; - } - hr = pPassThru->Init(bRenderer, pPin); - pPassThru->Release(); - if (FAILED(hr)) { - pUnkSeek->Release(); - return hr; - } - *ppPassThru = pUnkSeek; - return S_OK; -} - - - -#define CONNECT_TRACE_LEVEL 3 - -//===================================================================== -//===================================================================== -// Implements CBaseMediaFilter -//===================================================================== -//===================================================================== - - -/* Constructor */ - -CBaseMediaFilter::CBaseMediaFilter(const TCHAR *pName, - LPUNKNOWN pUnk, - CCritSec *pLock, - REFCLSID clsid) : - CUnknown(pName, pUnk), - m_pLock(pLock), - m_clsid(clsid), - m_State(State_Stopped), - m_pClock(NULL) -{ -} - - -/* Destructor */ - -CBaseMediaFilter::~CBaseMediaFilter() -{ - // must be stopped, but can't call Stop here since - // our critsec has been destroyed. - - /* Release any clock we were using */ - - if (m_pClock) { - m_pClock->Release(); - m_pClock = NULL; - } -} - - -/* Override this to say what interfaces we support and where */ - -STDMETHODIMP -CBaseMediaFilter::NonDelegatingQueryInterface( - REFIID riid, - void ** ppv) -{ - if (riid == IID_IMediaFilter) { - return GetInterface((IMediaFilter *) this, ppv); - } else if (riid == IID_IPersist) { - return GetInterface((IPersist *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - -/* Return the filter's clsid */ -STDMETHODIMP -CBaseMediaFilter::GetClassID(CLSID *pClsID) -{ - CheckPointer(pClsID,E_POINTER); - ValidateReadWritePtr(pClsID,sizeof(CLSID)); - *pClsID = m_clsid; - return NOERROR; -} - -/* Override this if your state changes are not done synchronously */ - -STDMETHODIMP -CBaseMediaFilter::GetState(DWORD dwMSecs, FILTER_STATE *State) -{ - UNREFERENCED_PARAMETER(dwMSecs); - CheckPointer(State,E_POINTER); - ValidateReadWritePtr(State,sizeof(FILTER_STATE)); - - *State = m_State; - return S_OK; -} - - -/* Set the clock we will use for synchronisation */ - -STDMETHODIMP -CBaseMediaFilter::SetSyncSource(IReferenceClock *pClock) -{ - CAutoLock cObjectLock(m_pLock); - - // Ensure the new one does not go away - even if the same as the old - if (pClock) { - pClock->AddRef(); - } - - // if we have a clock, release it - if (m_pClock) { - m_pClock->Release(); - } - - // Set the new reference clock (might be NULL) - // Should we query it to ensure it is a clock? Consider for a debug build. - m_pClock = pClock; - - return NOERROR; -} - -/* Return the clock we are using for synchronisation */ -STDMETHODIMP -CBaseMediaFilter::GetSyncSource(IReferenceClock **pClock) -{ - CheckPointer(pClock,E_POINTER); - ValidateReadWritePtr(pClock,sizeof(IReferenceClock *)); - CAutoLock cObjectLock(m_pLock); - - if (m_pClock) { - // returning an interface... addref it... - m_pClock->AddRef(); - } - *pClock = (IReferenceClock*)m_pClock; - return NOERROR; -} - - -/* Put the filter into a stopped state */ - -STDMETHODIMP -CBaseMediaFilter::Stop() -{ - CAutoLock cObjectLock(m_pLock); - - m_State = State_Stopped; - return S_OK; -} - - -/* Put the filter into a paused state */ - -STDMETHODIMP -CBaseMediaFilter::Pause() -{ - CAutoLock cObjectLock(m_pLock); - - m_State = State_Paused; - return S_OK; -} - - -// Put the filter into a running state. - -// The time parameter is the offset to be added to the samples' -// stream time to get the reference time at which they should be presented. -// -// you can either add these two and compare it against the reference clock, -// or you can call CBaseMediaFilter::StreamTime and compare that against -// the sample timestamp. - -STDMETHODIMP -CBaseMediaFilter::Run(REFERENCE_TIME tStart) -{ - CAutoLock cObjectLock(m_pLock); - - // remember the stream time offset - m_tStart = tStart; - - if (m_State == State_Stopped){ - HRESULT hr = Pause(); - - if (FAILED(hr)) { - return hr; - } - } - m_State = State_Running; - return S_OK; -} - - -// -// return the current stream time - samples with start timestamps of this -// time or before should be rendered by now -HRESULT -CBaseMediaFilter::StreamTime(CRefTime& rtStream) -{ - // Caller must lock for synchronization - // We can't grab the filter lock because we want to be able to call - // this from worker threads without deadlocking - - if (m_pClock == NULL) { - return VFW_E_NO_CLOCK; - } - - // get the current reference time - HRESULT hr = m_pClock->GetTime((REFERENCE_TIME*)&rtStream); - if (FAILED(hr)) { - return hr; - } - - // subtract the stream offset to get stream time - rtStream -= m_tStart; - - return S_OK; -} - - -//===================================================================== -//===================================================================== -// Implements CBaseFilter -//===================================================================== -//===================================================================== - - -/* Override this to say what interfaces we support and where */ - -STDMETHODIMP CBaseFilter::NonDelegatingQueryInterface(REFIID riid, - void **ppv) -{ - /* Do we have this interface */ - - if (riid == IID_IBaseFilter) { - return GetInterface((IBaseFilter *) this, ppv); - } else if (riid == IID_IMediaFilter) { - return GetInterface((IMediaFilter *) this, ppv); - } else if (riid == IID_IPersist) { - return GetInterface((IPersist *) this, ppv); - } else if (riid == IID_IAMovieSetup) { - return GetInterface((IAMovieSetup *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - -#ifdef DEBUG -STDMETHODIMP_(ULONG) CBaseFilter::NonDelegatingRelease() -{ - if (m_cRef == 1) { - KASSERT(m_pGraph == NULL); - } - return CUnknown::NonDelegatingRelease(); -} -#endif - - -/* Constructor */ - -CBaseFilter::CBaseFilter(const TCHAR *pName, - LPUNKNOWN pUnk, - CCritSec *pLock, - REFCLSID clsid) : - CUnknown( pName, pUnk ), - m_pLock(pLock), - m_clsid(clsid), - m_State(State_Stopped), - m_pClock(NULL), - m_pGraph(NULL), - m_pSink(NULL), - m_pName(NULL), - m_PinVersion(1) -{ - - ASSERT(pLock != NULL); -} - -/* Passes in a redundant HRESULT argument */ - -CBaseFilter::CBaseFilter(TCHAR *pName, - LPUNKNOWN pUnk, - CCritSec *pLock, - REFCLSID clsid, - HRESULT *phr) : - CUnknown( pName, pUnk ), - m_pLock(pLock), - m_clsid(clsid), - m_State(State_Stopped), - m_pClock(NULL), - m_pGraph(NULL), - m_pSink(NULL), - m_pName(NULL), - m_PinVersion(1) -{ - - ASSERT(pLock != NULL); - UNREFERENCED_PARAMETER(phr); -} - -#ifdef UNICODE -CBaseFilter::CBaseFilter(const CHAR *pName, - LPUNKNOWN pUnk, - CCritSec *pLock, - REFCLSID clsid) : - CUnknown( pName, pUnk ), - m_pLock(pLock), - m_clsid(clsid), - m_State(State_Stopped), - m_pClock(NULL), - m_pGraph(NULL), - m_pSink(NULL), - m_pName(NULL), - m_PinVersion(1) -{ - - ASSERT(pLock != NULL); -} -CBaseFilter::CBaseFilter(CHAR *pName, - LPUNKNOWN pUnk, - CCritSec *pLock, - REFCLSID clsid, - HRESULT *phr) : - CUnknown( pName, pUnk ), - m_pLock(pLock), - m_clsid(clsid), - m_State(State_Stopped), - m_pClock(NULL), - m_pGraph(NULL), - m_pSink(NULL), - m_pName(NULL), - m_PinVersion(1) -{ - - ASSERT(pLock != NULL); - UNREFERENCED_PARAMETER(phr); -} -#endif - -/* Destructor */ - -CBaseFilter::~CBaseFilter() -{ - - // NOTE we do NOT hold references on the filtergraph for m_pGraph or m_pSink - // When we did we had the circular reference problem. Nothing would go away. - - delete[] m_pName; - - // must be stopped, but can't call Stop here since - // our critsec has been destroyed. - - /* Release any clock we were using */ - if (m_pClock) { - m_pClock->Release(); - m_pClock = NULL; - } -} - -/* Return the filter's clsid */ -STDMETHODIMP -CBaseFilter::GetClassID(CLSID *pClsID) -{ - CheckPointer(pClsID,E_POINTER); - ValidateReadWritePtr(pClsID,sizeof(CLSID)); - *pClsID = m_clsid; - return NOERROR; -} - -/* Override this if your state changes are not done synchronously */ -STDMETHODIMP -CBaseFilter::GetState(DWORD dwMSecs, FILTER_STATE *State) -{ - UNREFERENCED_PARAMETER(dwMSecs); - CheckPointer(State,E_POINTER); - ValidateReadWritePtr(State,sizeof(FILTER_STATE)); - - *State = m_State; - return S_OK; -} - - -/* Set the clock we will use for synchronisation */ - -STDMETHODIMP -CBaseFilter::SetSyncSource(IReferenceClock *pClock) -{ - CAutoLock cObjectLock(m_pLock); - - // Ensure the new one does not go away - even if the same as the old - if (pClock) { - pClock->AddRef(); - } - - // if we have a clock, release it - if (m_pClock) { - m_pClock->Release(); - } - - // Set the new reference clock (might be NULL) - // Should we query it to ensure it is a clock? Consider for a debug build. - m_pClock = pClock; - - return NOERROR; -} - -/* Return the clock we are using for synchronisation */ -STDMETHODIMP -CBaseFilter::GetSyncSource(IReferenceClock **pClock) -{ - CheckPointer(pClock,E_POINTER); - ValidateReadWritePtr(pClock,sizeof(IReferenceClock *)); - CAutoLock cObjectLock(m_pLock); - - if (m_pClock) { - // returning an interface... addref it... - m_pClock->AddRef(); - } - *pClock = (IReferenceClock*)m_pClock; - return NOERROR; -} - - - -// override CBaseMediaFilter Stop method, to deactivate any pins this -// filter has. -STDMETHODIMP -CBaseFilter::Stop() -{ - CAutoLock cObjectLock(m_pLock); - HRESULT hr = NOERROR; - - // notify all pins of the state change - if (m_State != State_Stopped) { - int cPins = GetPinCount(); - for (int c = 0; c < cPins; c++) { - - CBasePin *pPin = GetPin(c); - - // Disconnected pins are not activated - this saves pins worrying - // about this state themselves. We ignore the return code to make - // sure everyone is inactivated regardless. The base input pin - // class can return an error if it has no allocator but Stop can - // be used to resync the graph state after something has gone bad - - if (pPin->IsConnected()) { - HRESULT hrTmp = pPin->Inactive(); - if (FAILED(hrTmp) && SUCCEEDED(hr)) { - hr = hrTmp; - } - } - } - } - - - m_State = State_Stopped; - return hr; -} - - -// override CBaseMediaFilter Pause method to activate any pins -// this filter has (also called from Run) - -STDMETHODIMP -CBaseFilter::Pause() -{ - CAutoLock cObjectLock(m_pLock); - - // notify all pins of the change to active state - if (m_State == State_Stopped) { - int cPins = GetPinCount(); - for (int c = 0; c < cPins; c++) { - - CBasePin *pPin = GetPin(c); - - // Disconnected pins are not activated - this saves pins - // worrying about this state themselves - - if (pPin->IsConnected()) { - HRESULT hr = pPin->Active(); - if (FAILED(hr)) { - return hr; - } - } - } - } - - - - m_State = State_Paused; - return S_OK; -} - -// Put the filter into a running state. - -// The time parameter is the offset to be added to the samples' -// stream time to get the reference time at which they should be presented. -// -// you can either add these two and compare it against the reference clock, -// or you can call CBaseFilter::StreamTime and compare that against -// the sample timestamp. - -STDMETHODIMP -CBaseFilter::Run(REFERENCE_TIME tStart) -{ - CAutoLock cObjectLock(m_pLock); - - // remember the stream time offset - m_tStart = tStart; - - if (m_State == State_Stopped){ - HRESULT hr = Pause(); - - if (FAILED(hr)) { - return hr; - } - } - // notify all pins of the change to active state - if (m_State != State_Running) { - int cPins = GetPinCount(); - for (int c = 0; c < cPins; c++) { - - CBasePin *pPin = GetPin(c); - - // Disconnected pins are not activated - this saves pins - // worrying about this state themselves - - if (pPin->IsConnected()) { - HRESULT hr = pPin->Run(tStart); - if (FAILED(hr)) { - return hr; - } - } - } - } - - - m_State = State_Running; - return S_OK; -} - -// -// return the current stream time - samples with start timestamps of this -// time or before should be rendered by now -HRESULT -CBaseFilter::StreamTime(CRefTime& rtStream) -{ - // Caller must lock for synchronization - // We can't grab the filter lock because we want to be able to call - // this from worker threads without deadlocking - - if (m_pClock == NULL) { - return VFW_E_NO_CLOCK; - } - - // get the current reference time - HRESULT hr = m_pClock->GetTime((REFERENCE_TIME*)&rtStream); - if (FAILED(hr)) { - return hr; - } - - // subtract the stream offset to get stream time - rtStream -= m_tStart; - - return S_OK; -} - - -/* Create an enumerator for the pins attached to this filter */ - -STDMETHODIMP -CBaseFilter::EnumPins(IEnumPins **ppEnum) -{ - CheckPointer(ppEnum,E_POINTER); - ValidateReadWritePtr(ppEnum,sizeof(IEnumPins *)); - - /* Create a new ref counted enumerator */ - - *ppEnum = new CEnumPins(this, - NULL); - - return *ppEnum == NULL ? E_OUTOFMEMORY : NOERROR; -} - - -// default behaviour of FindPin is to assume pins are named -// by their pin names -STDMETHODIMP -CBaseFilter::FindPin( - LPCWSTR Id, - IPin ** ppPin -) -{ - CheckPointer(ppPin,E_POINTER); - ValidateReadWritePtr(ppPin,sizeof(IPin *)); - - // We're going to search the pin list so maintain integrity - CAutoLock lck(m_pLock); - int iCount = GetPinCount(); - for (int i = 0; i < iCount; i++) { - CBasePin *pPin = GetPin(i); - ASSERT(pPin != NULL); - - if (0 == lstrcmpW(pPin->Name(), Id)) { - // Found one that matches - // - // AddRef() and return it - *ppPin = pPin; - pPin->AddRef(); - return S_OK; - } - } - *ppPin = NULL; - return VFW_E_NOT_FOUND; -} - -/* Return information about this filter */ - -STDMETHODIMP -CBaseFilter::QueryFilterInfo(FILTER_INFO * pInfo) -{ - CheckPointer(pInfo,E_POINTER); - ValidateReadWritePtr(pInfo,sizeof(FILTER_INFO)); - - if (m_pName) { - lstrcpynW(pInfo->achName, m_pName, sizeof(pInfo->achName)/sizeof(WCHAR)); - } else { - pInfo->achName[0] = L'\0'; - } - pInfo->pGraph = m_pGraph; - if (m_pGraph) - m_pGraph->AddRef(); - return NOERROR; -} - - -/* Provide the filter with a filter graph */ - -STDMETHODIMP -CBaseFilter::JoinFilterGraph( - IFilterGraph * pGraph, - LPCWSTR pName) -{ - CAutoLock cObjectLock(m_pLock); - - // NOTE: we no longer hold references on the graph (m_pGraph, m_pSink) - - m_pGraph = pGraph; - if (m_pGraph) { - HRESULT hr = m_pGraph->QueryInterface(IID_IMediaEventSink, - (void**) &m_pSink); - if (FAILED(hr)) { - ASSERT(m_pSink == NULL); - } - else m_pSink->Release(); // we do NOT keep a reference on it. - } else { - // if graph pointer is null, then we should - // also release the IMediaEventSink on the same object - we don't - // refcount it, so just set it to null - m_pSink = NULL; - } - - - if (m_pName) { - delete[] m_pName; - m_pName = NULL; - } - - if (pName) { - DWORD nameLen = lstrlenW(pName)+1; - m_pName = new WCHAR[nameLen]; - if (m_pName) { - CopyMemory(m_pName, pName, nameLen*sizeof(WCHAR)); - } else { - // !!! error here? - ASSERT(FALSE); - } - } - - - return NOERROR; -} - - -// return a Vendor information string. Optional - may return E_NOTIMPL. -// memory returned should be freed using CoTaskMemFree -// default implementation returns E_NOTIMPL -STDMETHODIMP -CBaseFilter::QueryVendorInfo( - LPWSTR* pVendorInfo) -{ - UNREFERENCED_PARAMETER(pVendorInfo); - return E_NOTIMPL; -} - - -// send an event notification to the filter graph if we know about it. -// returns S_OK if delivered, S_FALSE if the filter graph does not sink -// events, or an error otherwise. -HRESULT -CBaseFilter::NotifyEvent( - long EventCode, - LONG_PTR EventParam1, - LONG_PTR EventParam2) -{ - // Snapshot so we don't have to lock up - IMediaEventSink *pSink = m_pSink; - if (pSink) { - if (EC_COMPLETE == EventCode) { - EventParam2 = (LONG_PTR)(IBaseFilter*)this; - } - - return pSink->Notify(EventCode, EventParam1, EventParam2); - } else { - return E_NOTIMPL; - } -} - -// Request reconnect -// pPin is the pin to reconnect -// pmt is the type to reconnect with - can be NULL -// Calls ReconnectEx on the filter graph -HRESULT -CBaseFilter::ReconnectPin( - IPin *pPin, - AM_MEDIA_TYPE const *pmt -) -{ - IFilterGraph2 *pGraph2; - if (m_pGraph != NULL) { - HRESULT hr = m_pGraph->QueryInterface(IID_IFilterGraph2, (void **)&pGraph2); - if (SUCCEEDED(hr)) { - hr = pGraph2->ReconnectEx(pPin, pmt); - pGraph2->Release(); - return hr; - } else { - return m_pGraph->Reconnect(pPin); - } - } else { - return E_NOINTERFACE; - } -} - - - -/* This is the same idea as the media type version does for type enumeration - on pins but for the list of pins available. So if the list of pins you - provide changes dynamically then either override this virtual function - to provide the version number, or more simply call IncrementPinVersion */ - -LONG CBaseFilter::GetPinVersion() -{ - return m_PinVersion; -} - - -/* Increment the current pin version cookie */ - -void CBaseFilter::IncrementPinVersion() -{ - InterlockedIncrement(&m_PinVersion); -} - -/* register filter */ - -STDMETHODIMP CBaseFilter::Register() -{ - // get setup data, if it exists - // - LPAMOVIESETUP_FILTER psetupdata = GetSetupData(); - - // check we've got data - // - if( NULL == psetupdata ) return S_FALSE; - - // init is ref counted so call just in case - // we're being called cold. - // - HRESULT hr = CoInitialize( (LPVOID)NULL ); - ASSERT( SUCCEEDED(hr) ); - - // get hold of IFilterMapper - // - IFilterMapper *pIFM; - hr = CoCreateInstance( CLSID_FilterMapper - , NULL - , CLSCTX_INPROC_SERVER - , IID_IFilterMapper - , (void **)&pIFM ); - if( SUCCEEDED(hr) ) - { - hr = AMovieSetupRegisterFilter( psetupdata, pIFM, TRUE ); - pIFM->Release(); - } - - // and clear up - // - CoFreeUnusedLibraries(); - CoUninitialize(); - - return NOERROR; -} - - -/* unregister filter */ - -STDMETHODIMP CBaseFilter::Unregister() -{ - // get setup data, if it exists - // - LPAMOVIESETUP_FILTER psetupdata = GetSetupData(); - - // check we've got data - // - if( NULL == psetupdata ) return S_FALSE; - - // OLE init is ref counted so call - // just in case we're being called cold. - // - HRESULT hr = CoInitialize( (LPVOID)NULL ); - ASSERT( SUCCEEDED(hr) ); - - // get hold of IFilterMapper - // - IFilterMapper *pIFM; - hr = CoCreateInstance( CLSID_FilterMapper - , NULL - , CLSCTX_INPROC_SERVER - , IID_IFilterMapper - , (void **)&pIFM ); - if( SUCCEEDED(hr) ) - { - hr = AMovieSetupRegisterFilter( psetupdata, pIFM, FALSE ); - - // release interface - // - pIFM->Release(); - } - - // clear up - // - CoFreeUnusedLibraries(); - CoUninitialize(); - - // handle one acceptable "error" - that - // of filter not being registered! - // (couldn't find a suitable #define'd - // name for the error!) - // - if( 0x80070002 == hr) - return NOERROR; - else - return hr; -} - - -//===================================================================== -//===================================================================== -// Implements CEnumPins -//===================================================================== -//===================================================================== - - -CEnumPins::CEnumPins(CBaseFilter *pFilter, - CEnumPins *pEnumPins) : - m_Position(0), - m_PinCount(0), - m_pFilter(pFilter), - m_cRef(1), // Already ref counted - m_PinCache(NAME("Pin Cache")) -{ - -#ifdef DEBUG - m_dwCookie = DbgRegisterObjectCreation("CEnumPins", 0); -#endif - - /* We must be owned by a filter derived from CBaseFilter */ - - ASSERT(pFilter != NULL); - - /* Hold a reference count on our filter */ - m_pFilter->AddRef(); - - /* Are we creating a new enumerator */ - - if (pEnumPins == NULL) { - m_Version = m_pFilter->GetPinVersion(); - m_PinCount = m_pFilter->GetPinCount(); - } else { - ASSERT(m_Position <= m_PinCount); - m_Position = pEnumPins->m_Position; - m_PinCount = pEnumPins->m_PinCount; - m_Version = pEnumPins->m_Version; - m_PinCache.AddTail(&(pEnumPins->m_PinCache)); - } -} - - -/* Destructor releases the reference count on our filter NOTE since we hold - a reference count on the filter who created us we know it is safe to - release it, no access can be made to it afterwards though as we have just - caused the last reference count to go and the object to be deleted */ - -CEnumPins::~CEnumPins() -{ - m_pFilter->Release(); - -#ifdef DEBUG - DbgRegisterObjectDestruction(m_dwCookie); -#endif -} - - -/* Override this to say what interfaces we support where */ - -STDMETHODIMP -CEnumPins::QueryInterface(REFIID riid,void **ppv) -{ - CheckPointer(ppv, E_POINTER); - - /* Do we have this interface */ - - if (riid == IID_IEnumPins || riid == IID_IUnknown) { - return GetInterface((IEnumPins *) this, ppv); - } else { - *ppv = NULL; - return E_NOINTERFACE; - } -} - -STDMETHODIMP_(ULONG) -CEnumPins::AddRef() -{ - return InterlockedIncrement(&m_cRef); -} - -STDMETHODIMP_(ULONG) -CEnumPins::Release() -{ - ULONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) { - delete this; - } - return cRef; -} - -/* One of an enumerator's basic member functions allows us to create a cloned - interface that initially has the same state. Since we are taking a snapshot - of an object (current position and all) we must lock access at the start */ - -STDMETHODIMP -CEnumPins::Clone(IEnumPins **ppEnum) -{ - CheckPointer(ppEnum,E_POINTER); - ValidateReadWritePtr(ppEnum,sizeof(IEnumPins *)); - HRESULT hr = NOERROR; - - /* Check we are still in sync with the filter */ - if (AreWeOutOfSync() == TRUE) { - *ppEnum = NULL; - hr = VFW_E_ENUM_OUT_OF_SYNC; - } else { - - *ppEnum = new CEnumPins(m_pFilter, - this); - if (*ppEnum == NULL) { - hr = E_OUTOFMEMORY; - } - } - return hr; -} - - -/* Return the next pin after the current position */ - -STDMETHODIMP -CEnumPins::Next(ULONG cPins, // place this many pins... - IPin **ppPins, // ...in this array - ULONG *pcFetched) // actual count passed returned here -{ - CheckPointer(ppPins,E_POINTER); - ValidateReadWritePtr(ppPins,cPins * sizeof(IPin *)); - - ASSERT(ppPins); - - if (pcFetched!=NULL) { - ValidateWritePtr(pcFetched, sizeof(ULONG)); - *pcFetched = 0; // default unless we succeed - } - // now check that the parameter is valid - else if (cPins>1) { // pcFetched == NULL - return E_INVALIDARG; - } - ULONG cFetched = 0; // increment as we get each one. - - /* Check we are still in sync with the filter */ - if (AreWeOutOfSync() == TRUE) { - // If we are out of sync, we should refresh the enumerator. - // This will reset the position and update the other members, but - // will not clear cache of pins we have already returned. - Refresh(); - } - - /* Calculate the number of available pins */ - - int cRealPins = min(m_PinCount - m_Position, (int) cPins); - if (cRealPins == 0) { - return S_FALSE; - } - - /* Return each pin interface NOTE GetPin returns CBasePin * not addrefed - so we must QI for the IPin (which increments its reference count) - If while we are retrieving a pin from the filter an error occurs we - assume that our internal state is stale with respect to the filter - (for example someone has deleted a pin) so we - return VFW_E_ENUM_OUT_OF_SYNC */ - - while (cRealPins && (m_PinCount - m_Position)) { - - /* Get the next pin object from the filter */ - - CBasePin *pPin = m_pFilter->GetPin(m_Position++); - if (pPin == NULL) { - // If this happend, and it's not the first time through, then we've got a problem, - // since we should really go back and release the iPins, which we have previously - // AddRef'ed. - ASSERT( cFetched==0 ); - return VFW_E_ENUM_OUT_OF_SYNC; - } - - /* We only want to return this pin, if it is not in our cache */ - if (0 == m_PinCache.Find(pPin)) - { - /* From the object get an IPin interface */ - - *ppPins = pPin; - pPin->AddRef(); - - cFetched++; - ppPins++; - - m_PinCache.AddTail(pPin); - - cRealPins--; - - } - } - - if (pcFetched!=NULL) { - *pcFetched = cFetched; - } - - return (cPins==cFetched ? NOERROR : S_FALSE); -} - - -/* Skip over one or more entries in the enumerator */ - -STDMETHODIMP -CEnumPins::Skip(ULONG cPins) -{ - /* Check we are still in sync with the filter */ - if (AreWeOutOfSync() == TRUE) { - return VFW_E_ENUM_OUT_OF_SYNC; - } - - /* Work out how many pins are left to skip over */ - /* We could position at the end if we are asked to skip too many... */ - /* ..which would match the base implementation for CEnumMediaTypes::Skip */ - - ULONG PinsLeft = m_PinCount - m_Position; - if (cPins > PinsLeft) { - return S_FALSE; - } - m_Position += cPins; - return NOERROR; -} - - -/* Set the current position back to the start */ -/* Reset has 4 simple steps: - * - * Set position to head of list - * Sync enumerator with object being enumerated - * Clear the cache of pins already returned - * return S_OK - */ - -STDMETHODIMP -CEnumPins::Reset() -{ - m_Version = m_pFilter->GetPinVersion(); - m_PinCount = m_pFilter->GetPinCount(); - - m_Position = 0; - - // Clear the cache - m_PinCache.RemoveAll(); - - return S_OK; -} - - -/* Set the current position back to the start */ -/* Refresh has 3 simple steps: - * - * Set position to head of list - * Sync enumerator with object being enumerated - * return S_OK - */ - -STDMETHODIMP -CEnumPins::Refresh() -{ - m_Version = m_pFilter->GetPinVersion(); - m_PinCount = m_pFilter->GetPinCount(); - - m_Position = 0; - return S_OK; -} - - -//===================================================================== -//===================================================================== -// Implements CEnumMediaTypes -//===================================================================== -//===================================================================== - - -CEnumMediaTypes::CEnumMediaTypes(CBasePin *pPin, - CEnumMediaTypes *pEnumMediaTypes) : - m_Position(0), - m_pPin(pPin), - m_cRef(1) -{ - -#ifdef DEBUG - m_dwCookie = DbgRegisterObjectCreation("CEnumMediaTypes", 0); -#endif - - /* We must be owned by a pin derived from CBasePin */ - - ASSERT(pPin != NULL); - - /* Hold a reference count on our pin */ - m_pPin->AddRef(); - - /* Are we creating a new enumerator */ - - if (pEnumMediaTypes == NULL) { - m_Version = m_pPin->GetMediaTypeVersion(); - return; - } - - m_Position = pEnumMediaTypes->m_Position; - m_Version = pEnumMediaTypes->m_Version; -} - - -/* Destructor releases the reference count on our base pin. NOTE since we hold - a reference count on the pin who created us we know it is safe to release - it, no access can be made to it afterwards though as we might have just - caused the last reference count to go and the object to be deleted */ - -CEnumMediaTypes::~CEnumMediaTypes() -{ -#ifdef DEBUG - DbgRegisterObjectDestruction(m_dwCookie); -#endif - m_pPin->Release(); -} - - -/* Override this to say what interfaces we support where */ - -STDMETHODIMP -CEnumMediaTypes::QueryInterface(REFIID riid,void **ppv) -{ - CheckPointer(ppv, E_POINTER); - - /* Do we have this interface */ - - if (riid == IID_IEnumMediaTypes || riid == IID_IUnknown) { - return GetInterface((IEnumMediaTypes *) this, ppv); - } else { - *ppv = NULL; - return E_NOINTERFACE; - } -} - -STDMETHODIMP_(ULONG) -CEnumMediaTypes::AddRef() -{ - return InterlockedIncrement(&m_cRef); -} - -STDMETHODIMP_(ULONG) -CEnumMediaTypes::Release() -{ - ULONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) { - delete this; - } - return cRef; -} - -/* One of an enumerator's basic member functions allows us to create a cloned - interface that initially has the same state. Since we are taking a snapshot - of an object (current position and all) we must lock access at the start */ - -STDMETHODIMP -CEnumMediaTypes::Clone(IEnumMediaTypes **ppEnum) -{ - CheckPointer(ppEnum,E_POINTER); - ValidateReadWritePtr(ppEnum,sizeof(IEnumMediaTypes *)); - HRESULT hr = NOERROR; - - /* Check we are still in sync with the pin */ - if (AreWeOutOfSync() == TRUE) { - *ppEnum = NULL; - hr = VFW_E_ENUM_OUT_OF_SYNC; - } else { - - *ppEnum = new CEnumMediaTypes(m_pPin, - this); - - if (*ppEnum == NULL) { - hr = E_OUTOFMEMORY; - } - } - return hr; -} - - -/* Enumerate the next pin(s) after the current position. The client using this - interface passes in a pointer to an array of pointers each of which will - be filled in with a pointer to a fully initialised media type format - Return NOERROR if it all works, - S_FALSE if fewer than cMediaTypes were enumerated. - VFW_E_ENUM_OUT_OF_SYNC if the enumerator has been broken by - state changes in the filter - The actual count always correctly reflects the number of types in the array. -*/ - -STDMETHODIMP -CEnumMediaTypes::Next(ULONG cMediaTypes, // place this many types... - AM_MEDIA_TYPE **ppMediaTypes, // ...in this array - ULONG *pcFetched) // actual count passed -{ - CheckPointer(ppMediaTypes,E_POINTER); - ValidateReadWritePtr(ppMediaTypes,cMediaTypes * sizeof(AM_MEDIA_TYPE *)); - /* Check we are still in sync with the pin */ - if (AreWeOutOfSync() == TRUE) { - return VFW_E_ENUM_OUT_OF_SYNC; - } - - if (pcFetched!=NULL) { - ValidateWritePtr(pcFetched, sizeof(ULONG)); - *pcFetched = 0; // default unless we succeed - } - // now check that the parameter is valid - else if (cMediaTypes>1) { // pcFetched == NULL - return E_INVALIDARG; - } - ULONG cFetched = 0; // increment as we get each one. - - /* Return each media type by asking the filter for them in turn - If we - have an error code retured to us while we are retrieving a media type - we assume that our internal state is stale with respect to the filter - (for example the window size changing) so we return - VFW_E_ENUM_OUT_OF_SYNC */ - - while (cMediaTypes) { - - CMediaType cmt; - - HRESULT hr = m_pPin->GetMediaType(m_Position++, &cmt); - if (S_OK != hr) { - break; - } - - /* We now have a CMediaType object that contains the next media type - but when we assign it to the array position we CANNOT just assign - the AM_MEDIA_TYPE structure because as soon as the object goes out of - scope it will delete the memory we have just copied. The function - we use is CreateMediaType which allocates a task memory block */ - - /* Transfer across the format block manually to save an allocate - and free on the format block and generally go faster */ - - *ppMediaTypes = (AM_MEDIA_TYPE *)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); - if (*ppMediaTypes == NULL) { - break; - } - - /* Do a regular copy */ - **ppMediaTypes = (AM_MEDIA_TYPE)cmt; - - /* Make sure the destructor doesn't free these */ - cmt.pbFormat = NULL; - cmt.cbFormat = NULL; - cmt.pUnk = NULL; - - - ppMediaTypes++; - cFetched++; - cMediaTypes--; - } - - if (pcFetched!=NULL) { - *pcFetched = cFetched; - } - - return ( cMediaTypes==0 ? NOERROR : S_FALSE ); -} - - -/* Skip over one or more entries in the enumerator */ - -STDMETHODIMP -CEnumMediaTypes::Skip(ULONG cMediaTypes) -{ - // If we're skipping 0 elements we're guaranteed to skip the - // correct number of elements - if (cMediaTypes == 0) { - return S_OK; - } - - /* Check we are still in sync with the pin */ - if (AreWeOutOfSync() == TRUE) { - return VFW_E_ENUM_OUT_OF_SYNC; - } - - m_Position += cMediaTypes; - - /* See if we're over the end */ - CMediaType cmt; - return S_OK == m_pPin->GetMediaType(m_Position - 1, &cmt) ? S_OK : S_FALSE; -} - - -/* Set the current position back to the start */ -/* Reset has 3 simple steps: - * - * set position to head of list - * sync enumerator with object being enumerated - * return S_OK - */ - -STDMETHODIMP -CEnumMediaTypes::Reset() - -{ - m_Position = 0; - - // Bring the enumerator back into step with the current state. This - // may be a noop but ensures that the enumerator will be valid on the - // next call. - m_Version = m_pPin->GetMediaTypeVersion(); - return NOERROR; -} - - -//===================================================================== -//===================================================================== -// Implements CBasePin -//===================================================================== -//===================================================================== - - -/* NOTE The implementation of this class calls the CUnknown constructor with - a NULL outer unknown pointer. This has the effect of making us a self - contained class, ie any QueryInterface, AddRef or Release calls will be - routed to the class's NonDelegatingUnknown methods. You will typically - find that the classes that do this then override one or more of these - virtual functions to provide more specialised behaviour. A good example - of this is where a class wants to keep the QueryInterface internal but - still wants its lifetime controlled by the external object */ - -/* Constructor */ - -CBasePin::CBasePin(TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName, - PIN_DIRECTION dir) : - CUnknown( pObjectName, NULL ), - m_pFilter(pFilter), - m_pLock(pLock), - m_pName(NULL), - m_Connected(NULL), - m_dir(dir), - m_bRunTimeError(FALSE), - m_pQSink(NULL), - m_TypeVersion(1), - m_tStart(), - m_tStop(MAX_TIME), - m_bCanReconnectWhenActive(false), - m_bTryMyTypesFirst(false), - m_dRate(1.0) -{ - /* WARNING - pFilter is often not a properly constituted object at - this state (in particular QueryInterface may not work) - this - is because its owner is often its containing object and we - have been called from the containing object's constructor so - the filter's owner has not yet had its CUnknown constructor - called - */ - - ASSERT(pFilter != NULL); - ASSERT(pLock != NULL); - - if (pName) { - DWORD nameLen = lstrlenW(pName)+1; - m_pName = new WCHAR[nameLen]; - if (m_pName) { - CopyMemory(m_pName, pName, nameLen*sizeof(WCHAR)); - } - } - -#ifdef DEBUG - m_cRef = 0; -#endif -} - -#ifdef UNICODE -CBasePin::CBasePin(CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName, - PIN_DIRECTION dir) : - CUnknown( pObjectName, NULL ), - m_pFilter(pFilter), - m_pLock(pLock), - m_pName(NULL), - m_Connected(NULL), - m_dir(dir), - m_bRunTimeError(FALSE), - m_pQSink(NULL), - m_TypeVersion(1), - m_tStart(), - m_tStop(MAX_TIME), - m_bCanReconnectWhenActive(false), - m_bTryMyTypesFirst(false), - m_dRate(1.0) -{ - /* WARNING - pFilter is often not a properly constituted object at - this state (in particular QueryInterface may not work) - this - is because its owner is often its containing object and we - have been called from the containing object's constructor so - the filter's owner has not yet had its CUnknown constructor - called - */ - - ASSERT(pFilter != NULL); - ASSERT(pLock != NULL); - - if (pName) { - DWORD nameLen = lstrlenW(pName)+1; - m_pName = new WCHAR[nameLen]; - if (m_pName) { - CopyMemory(m_pName, pName, nameLen*sizeof(WCHAR)); - } - } - -#ifdef DEBUG - m_cRef = 0; -#endif -} -#endif - -/* Destructor since a connected pin holds a reference count on us there is - no way that we can be deleted unless we are not currently connected */ - -CBasePin::~CBasePin() -{ - - // We don't call disconnect because if the filter is going away - // all the pins must have a reference count of zero so they must - // have been disconnected anyway - (but check the assumption) - ASSERT(m_Connected == FALSE); - - delete[] m_pName; - - // check the internal reference count is consistent - ASSERT(m_cRef == 0); -} - - -/* Override this to say what interfaces we support and where */ - -STDMETHODIMP -CBasePin::NonDelegatingQueryInterface(REFIID riid, void ** ppv) -{ - /* Do we have this interface */ - - if (riid == IID_IPin) { - return GetInterface((IPin *) this, ppv); - } else if (riid == IID_IQualityControl) { - return GetInterface((IQualityControl *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -/* Override to increment the owning filter's reference count */ - -STDMETHODIMP_(ULONG) -CBasePin::NonDelegatingAddRef() -{ - ASSERT(InterlockedIncrement(&m_cRef) > 0); - return m_pFilter->AddRef(); -} - - -/* Override to decrement the owning filter's reference count */ - -STDMETHODIMP_(ULONG) -CBasePin::NonDelegatingRelease() -{ - ASSERT(InterlockedDecrement(&m_cRef) >= 0); - return m_pFilter->Release(); -} - - -/* Displays pin connection information */ - -#ifdef DEBUG -void -CBasePin::DisplayPinInfo(IPin *pReceivePin) -{ - - if (DbgCheckModuleLevel(LOG_TRACE, CONNECT_TRACE_LEVEL)) { - PIN_INFO ConnectPinInfo; - PIN_INFO ReceivePinInfo; - - if (FAILED(QueryPinInfo(&ConnectPinInfo))) { - lstrcpyW(ConnectPinInfo.achName, L"Bad Pin"); - } else { - QueryPinInfoReleaseFilter(ConnectPinInfo); - } - - if (FAILED(pReceivePin->QueryPinInfo(&ReceivePinInfo))) { - lstrcpyW(ReceivePinInfo.achName, L"Bad Pin"); - } else { - QueryPinInfoReleaseFilter(ReceivePinInfo); - } - - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Trying to connect Pins :"))); - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT(" <%ls>"), ConnectPinInfo.achName)); - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT(" <%ls>"), ReceivePinInfo.achName)); - } -} -#endif - - -/* Displays general information on the pin media type */ - -#ifdef DEBUG -void CBasePin::DisplayTypeInfo(IPin *pPin, const CMediaType *pmt) -{ - UNREFERENCED_PARAMETER(pPin); - if (DbgCheckModuleLevel(LOG_TRACE, CONNECT_TRACE_LEVEL)) { - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Trying media type:"))); - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT(" major type: %hs"), - GuidNames[*pmt->Type()])); - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT(" sub type : %hs"), - GuidNames[*pmt->Subtype()])); - } -} -#endif - -/* Asked to connect to a pin. A pin is always attached to an owning filter - object so we always delegate our locking to that object. We first of all - retrieve a media type enumerator for the input pin and see if we accept - any of the formats that it would ideally like, failing that we retrieve - our enumerator and see if it will accept any of our preferred types */ - -STDMETHODIMP -CBasePin::Connect( - IPin * pReceivePin, - const AM_MEDIA_TYPE *pmt // optional media type -) -{ - CheckPointer(pReceivePin,E_POINTER); - ValidateReadPtr(pReceivePin,sizeof(IPin)); - CAutoLock cObjectLock(m_pLock); - DisplayPinInfo(pReceivePin); - - /* See if we are already connected */ - - if (m_Connected) { - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Already connected"))); - return VFW_E_ALREADY_CONNECTED; - } - - /* See if the filter is active */ - if (!IsStopped() && !m_bCanReconnectWhenActive) { - return VFW_E_NOT_STOPPED; - } - - - // Find a mutually agreeable media type - - // Pass in the template media type. If this is partially specified, - // each of the enumerated media types will need to be checked against - // it. If it is non-null and fully specified, we will just try to connect - // with this. - - const CMediaType * ptype = (CMediaType*)pmt; - HRESULT hr = AgreeMediaType(pReceivePin, ptype); - if (FAILED(hr)) { - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Failed to agree type"))); - - // Since the procedure is already returning an error code, there - // is nothing else this function can do to report the error. - EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) ); - - - return hr; - } - - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Connection succeeded"))); - - - return NOERROR; -} - -// given a specific media type, attempt a connection (includes -// checking that the type is acceptable to this pin) -HRESULT -CBasePin::AttemptConnection( - IPin* pReceivePin, // connect to this pin - const CMediaType* pmt // using this type -) -{ - // The caller should hold the filter lock becasue this function - // uses m_Connected. The caller should also hold the filter lock - // because this function calls SetMediaType(), IsStopped() and - // CompleteConnect(). - ASSERT(CritCheckIn(m_pLock)); - - // Check that the connection is valid -- need to do this for every - // connect attempt since BreakConnect will undo it. - HRESULT hr = CheckConnect(pReceivePin); - if (FAILED(hr)) { - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("CheckConnect failed"))); - - // Since the procedure is already returning an error code, there - // is nothing else this function can do to report the error. - EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) ); - - return hr; - } - - DisplayTypeInfo(pReceivePin, pmt); - - /* Check we will accept this media type */ - - hr = CheckMediaType(pmt); - if (hr == NOERROR) { - - /* Make ourselves look connected otherwise ReceiveConnection - may not be able to complete the connection - */ - m_Connected = pReceivePin; - m_Connected->AddRef(); - hr = SetMediaType(pmt); - if (SUCCEEDED(hr)) { - /* See if the other pin will accept this type */ - - hr = pReceivePin->ReceiveConnection((IPin *)this, pmt); - if (SUCCEEDED(hr)) { - /* Complete the connection */ - - hr = CompleteConnect(pReceivePin); - if (SUCCEEDED(hr)) { - return hr; - } else { - DbgLog((LOG_TRACE, - CONNECT_TRACE_LEVEL, - TEXT("Failed to complete connection"))); - pReceivePin->Disconnect(); - } - } - } - } else { - // we cannot use this media type - - // return a specific media type error if there is one - // or map a general failure code to something more helpful - // (in particular S_FALSE gets changed to an error code) - if (SUCCEEDED(hr) || - (hr == E_FAIL) || - (hr == E_INVALIDARG)) { - hr = VFW_E_TYPE_NOT_ACCEPTED; - } - } - - // BreakConnect and release any connection here in case CheckMediaType - // failed, or if we set anything up during a call back during - // ReceiveConnection. - - // Since the procedure is already returning an error code, there - // is nothing else this function can do to report the error. - EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) ); - - /* If failed then undo our state */ - if (m_Connected) { - m_Connected->Release(); - m_Connected = NULL; - } - - return hr; -} - -/* Given an enumerator we cycle through all the media types it proposes and - firstly suggest them to our derived pin class and if that succeeds try - them with the pin in a ReceiveConnection call. This means that if our pin - proposes a media type we still check in here that we can support it. This - is deliberate so that in simple cases the enumerator can hold all of the - media types even if some of them are not really currently available */ - -HRESULT CBasePin::TryMediaTypes( - IPin *pReceivePin, - const CMediaType *pmt, - IEnumMediaTypes *pEnum) -{ - /* Reset the current enumerator position */ - - HRESULT hr = pEnum->Reset(); - if (FAILED(hr)) { - return hr; - } - - CMediaType *pMediaType = NULL; - ULONG ulMediaCount = 0; - - // attempt to remember a specific error code if there is one - HRESULT hrFailure = S_OK; - - for (;;) { - - /* Retrieve the next media type NOTE each time round the loop the - enumerator interface will allocate another AM_MEDIA_TYPE structure - If we are successful then we copy it into our output object, if - not then we must delete the memory allocated before returning */ - - hr = pEnum->Next(1, (AM_MEDIA_TYPE**)&pMediaType,&ulMediaCount); - if (hr != S_OK) { - if (S_OK == hrFailure) { - hrFailure = VFW_E_NO_ACCEPTABLE_TYPES; - } - return hrFailure; - } - - - ASSERT(ulMediaCount == 1); - ASSERT(pMediaType); - - // check that this matches the partial type (if any) - - if ((pmt == NULL) || - pMediaType->MatchesPartial(pmt)) { - - hr = AttemptConnection(pReceivePin, pMediaType); - - // attempt to remember a specific error code - if (FAILED(hr) && - SUCCEEDED(hrFailure) && - (hr != E_FAIL) && - (hr != E_INVALIDARG) && - (hr != VFW_E_TYPE_NOT_ACCEPTED)) { - hrFailure = hr; - } - } else { - hr = VFW_E_NO_ACCEPTABLE_TYPES; - } - - DeleteMediaType(pMediaType); - - if (S_OK == hr) { - return hr; - } - } -} - - -/* This is called to make the connection, including the taask of finding - a media type for the pin connection. pmt is the proposed media type - from the Connect call: if this is fully specified, we will try that. - Otherwise we enumerate and try all the input pin's types first and - if that fails we then enumerate and try all our preferred media types. - For each media type we check it against pmt (if non-null and partially - specified) as well as checking that both pins will accept it. - */ - -HRESULT CBasePin::AgreeMediaType( - IPin *pReceivePin, - const CMediaType *pmt) -{ - ASSERT(pReceivePin); - IEnumMediaTypes *pEnumMediaTypes = NULL; - - // if the media type is fully specified then use that - if ( (pmt != NULL) && (!pmt->IsPartiallySpecified())) { - - // if this media type fails, then we must fail the connection - // since if pmt is nonnull we are only allowed to connect - // using a type that matches it. - - return AttemptConnection(pReceivePin, pmt); - } - - - /* Try the other pin's enumerator */ - - HRESULT hrFailure = VFW_E_NO_ACCEPTABLE_TYPES; - - for (int i = 0; i < 2; i++) { - HRESULT hr; - if (i == (int)m_bTryMyTypesFirst) { - hr = pReceivePin->EnumMediaTypes(&pEnumMediaTypes); - } else { - hr = EnumMediaTypes(&pEnumMediaTypes); - } - if (SUCCEEDED(hr)) { - ASSERT(pEnumMediaTypes); - hr = TryMediaTypes(pReceivePin,pmt,pEnumMediaTypes); - pEnumMediaTypes->Release(); - if (SUCCEEDED(hr)) { - return NOERROR; - } else { - // try to remember specific error codes if there are any - if ((hr != E_FAIL) && - (hr != E_INVALIDARG) && - (hr != VFW_E_TYPE_NOT_ACCEPTED)) { - hrFailure = hr; - } - } - } - } - - return hrFailure; -} - - -/* Called when we want to complete a connection to another filter. Failing - this will also fail the connection and disconnect the other pin as well */ - -HRESULT -CBasePin::CompleteConnect(IPin *pReceivePin) -{ - UNREFERENCED_PARAMETER(pReceivePin); - return NOERROR; -} - - -/* This is called to set the format for a pin connection - CheckMediaType - will have been called to check the connection format and if it didn't - return an error code then this (virtual) function will be invoked */ - -HRESULT -CBasePin::SetMediaType(const CMediaType *pmt) -{ - HRESULT hr = m_mt.Set(*pmt); - if (FAILED(hr)) { - return hr; - } - - return NOERROR; -} - - -/* This is called during Connect() to provide a virtual method that can do - any specific check needed for connection such as QueryInterface. This - base class method just checks that the pin directions don't match */ - -HRESULT -CBasePin::CheckConnect(IPin * pPin) -{ - /* Check that pin directions DONT match */ - - PIN_DIRECTION pd; - pPin->QueryDirection(&pd); - - ASSERT((pd == PINDIR_OUTPUT) || (pd == PINDIR_INPUT)); - ASSERT((m_dir == PINDIR_OUTPUT) || (m_dir == PINDIR_INPUT)); - - // we should allow for non-input and non-output connections? - if (pd == m_dir) { - return VFW_E_INVALID_DIRECTION; - } - return NOERROR; -} - - -/* This is called when we realise we can't make a connection to the pin and - must undo anything we did in CheckConnect - override to release QIs done */ - -HRESULT -CBasePin::BreakConnect() -{ - return NOERROR; -} - - -/* Called normally by an output pin on an input pin to try and establish a - connection. -*/ - -STDMETHODIMP -CBasePin::ReceiveConnection( - IPin * pConnector, // this is the pin who we will connect to - const AM_MEDIA_TYPE *pmt // this is the media type we will exchange -) -{ - CheckPointer(pConnector,E_POINTER); - CheckPointer(pmt,E_POINTER); - ValidateReadPtr(pConnector,sizeof(IPin)); - ValidateReadPtr(pmt,sizeof(AM_MEDIA_TYPE)); - CAutoLock cObjectLock(m_pLock); - - /* Are we already connected */ - if (m_Connected) { - return VFW_E_ALREADY_CONNECTED; - } - - /* See if the filter is active */ - if (!IsStopped() && !m_bCanReconnectWhenActive) { - return VFW_E_NOT_STOPPED; - } - - HRESULT hr = CheckConnect(pConnector); - if (FAILED(hr)) { - // Since the procedure is already returning an error code, there - // is nothing else this function can do to report the error. - EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) ); - - - return hr; - } - - /* Ask derived class if this media type is ok */ - - CMediaType * pcmt = (CMediaType*) pmt; - hr = CheckMediaType(pcmt); - if (hr != NOERROR) { - // no -we don't support this media type - - // Since the procedure is already returning an error code, there - // is nothing else this function can do to report the error. - EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) ); - - // return a specific media type error if there is one - // or map a general failure code to something more helpful - // (in particular S_FALSE gets changed to an error code) - if (SUCCEEDED(hr) || - (hr == E_FAIL) || - (hr == E_INVALIDARG)) { - hr = VFW_E_TYPE_NOT_ACCEPTED; - } - - - return hr; - } - - /* Complete the connection */ - - m_Connected = pConnector; - m_Connected->AddRef(); - hr = SetMediaType(pcmt); - if (SUCCEEDED(hr)) { - hr = CompleteConnect(pConnector); - if (SUCCEEDED(hr)) { - - - return NOERROR; - } - } - - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Failed to set the media type or failed to complete the connection."))); - m_Connected->Release(); - m_Connected = NULL; - - // Since the procedure is already returning an error code, there - // is nothing else this function can do to report the error. - EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) ); - - - return hr; -} - - -/* Called when we want to terminate a pin connection */ - -STDMETHODIMP -CBasePin::Disconnect() -{ - CAutoLock cObjectLock(m_pLock); - - /* See if the filter is active */ - if (!IsStopped()) { - return VFW_E_NOT_STOPPED; - } - - return DisconnectInternal(); -} - -STDMETHODIMP -CBasePin::DisconnectInternal() -{ - ASSERT(CritCheckIn(m_pLock)); - - if (m_Connected) { - HRESULT hr = BreakConnect(); - if( FAILED( hr ) ) { - - - // There is usually a bug in the program if BreakConnect() fails. - DbgBreak( "WARNING: BreakConnect() failed in CBasePin::Disconnect()." ); - return hr; - } - - m_Connected->Release(); - m_Connected = NULL; - - - return S_OK; - } else { - // no connection - not an error - - - return S_FALSE; - } -} - - -/* Return an AddRef()'d pointer to the connected pin if there is one */ -STDMETHODIMP -CBasePin::ConnectedTo( - IPin **ppPin -) -{ - CheckPointer(ppPin,E_POINTER); - ValidateReadWritePtr(ppPin,sizeof(IPin *)); - // - // It's pointless to lock here. - // The caller should ensure integrity. - // - - IPin *pPin = m_Connected; - *ppPin = pPin; - if (pPin != NULL) { - pPin->AddRef(); - return S_OK; - } else { - ASSERT(*ppPin == NULL); - return VFW_E_NOT_CONNECTED; - } -} - -#pragma warning(disable:4702) // Unreachable code at return - -/* Return the media type of the connection */ -STDMETHODIMP -CBasePin::ConnectionMediaType( - AM_MEDIA_TYPE *pmt -) -{ - CheckPointer(pmt,E_POINTER); - ValidateReadWritePtr(pmt,sizeof(AM_MEDIA_TYPE)); - CAutoLock cObjectLock(m_pLock); - - /* Copy constructor of m_mt allocates the memory */ - if (IsConnected()) { - CopyMediaType( pmt, &m_mt ); - return S_OK; - } else { - ((CMediaType *)pmt)->InitMediaType(); - return VFW_E_NOT_CONNECTED; - } -} - -#pragma warning(default:4702) // Unreachable code at return - -/* Return information about the filter we are connect to */ - -STDMETHODIMP -CBasePin::QueryPinInfo( - PIN_INFO * pInfo -) -{ - CheckPointer(pInfo,E_POINTER); - ValidateReadWritePtr(pInfo,sizeof(PIN_INFO)); - - pInfo->pFilter = m_pFilter; - if (m_pFilter) { - m_pFilter->AddRef(); - } - - if (m_pName) { - lstrcpynW(pInfo->achName, m_pName, sizeof(pInfo->achName)/sizeof(WCHAR)); - } else { - pInfo->achName[0] = L'\0'; - } - - pInfo->dir = m_dir; - - return NOERROR; -} - -STDMETHODIMP -CBasePin::QueryDirection( - PIN_DIRECTION * pPinDir -) -{ - CheckPointer(pPinDir,E_POINTER); - ValidateReadWritePtr(pPinDir,sizeof(PIN_DIRECTION)); - - *pPinDir = m_dir; - return NOERROR; -} - -// Default QueryId to return the pin's name -STDMETHODIMP -CBasePin::QueryId( - LPWSTR * Id -) -{ - // We're not going away because someone's got a pointer to us - // so there's no need to lock - - return AMGetWideString(Name(), Id); -} - -/* Does this pin support this media type WARNING this interface function does - not lock the main object as it is meant to be asynchronous by nature - if - the media types you support depend on some internal state that is updated - dynamically then you will need to implement locking in a derived class */ - -STDMETHODIMP -CBasePin::QueryAccept( - const AM_MEDIA_TYPE *pmt -) -{ - CheckPointer(pmt,E_POINTER); - ValidateReadPtr(pmt,sizeof(AM_MEDIA_TYPE)); - - /* The CheckMediaType method is valid to return error codes if the media - type is horrible, an example might be E_INVALIDARG. What we do here - is map all the error codes into either S_OK or S_FALSE regardless */ - - HRESULT hr = CheckMediaType((CMediaType*)pmt); - if (FAILED(hr)) { - return S_FALSE; - } - // note that the only defined success codes should be S_OK and S_FALSE... - return hr; -} - - -/* This can be called to return an enumerator for the pin's list of preferred - media types. An input pin is not obliged to have any preferred formats - although it can do. For example, the window renderer has a preferred type - which describes a video image that matches the current window size. All - output pins should expose at least one preferred format otherwise it is - possible that neither pin has any types and so no connection is possible */ - -STDMETHODIMP -CBasePin::EnumMediaTypes( - IEnumMediaTypes **ppEnum -) -{ - CheckPointer(ppEnum,E_POINTER); - ValidateReadWritePtr(ppEnum,sizeof(IEnumMediaTypes *)); - - /* Create a new ref counted enumerator */ - - *ppEnum = new CEnumMediaTypes(this, - NULL); - - if (*ppEnum == NULL) { - return E_OUTOFMEMORY; - } - - return NOERROR; -} - - - -/* This is a virtual function that returns a media type corresponding with - place iPosition in the list. This base class simply returns an error as - we support no media types by default but derived classes should override */ - -HRESULT CBasePin::GetMediaType(int iPosition, CMediaType *pMediaType) -{ - UNREFERENCED_PARAMETER(iPosition); - UNREFERENCED_PARAMETER(pMediaType); - return E_UNEXPECTED; -} - - -/* This is a virtual function that returns the current media type version. - The base class initialises the media type enumerators with the value 1 - By default we always returns that same value. A Derived class may change - the list of media types available and after doing so it should increment - the version either in a method derived from this, or more simply by just - incrementing the m_TypeVersion base pin variable. The type enumerators - call this when they want to see if their enumerations are out of date */ - -LONG CBasePin::GetMediaTypeVersion() -{ - return m_TypeVersion; -} - - -/* Increment the cookie representing the current media type version */ - -void CBasePin::IncrementTypeVersion() -{ - InterlockedIncrement(&m_TypeVersion); -} - - -/* Called by IMediaFilter implementation when the state changes from Stopped - to either paused or running and in derived classes could do things like - commit memory and grab hardware resource (the default is to do nothing) */ - -HRESULT -CBasePin::Active(void) -{ - return NOERROR; -} - -/* Called by IMediaFilter implementation when the state changes from - to either paused to running and in derived classes could do things like - commit memory and grab hardware resource (the default is to do nothing) */ - -HRESULT -CBasePin::Run(REFERENCE_TIME tStart) -{ - UNREFERENCED_PARAMETER(tStart); - return NOERROR; -} - - -/* Also called by the IMediaFilter implementation when the state changes to - Stopped at which point you should decommit allocators and free hardware - resources you grabbed in the Active call (default is also to do nothing) */ - -HRESULT -CBasePin::Inactive(void) -{ - m_bRunTimeError = FALSE; - return NOERROR; -} - - -// Called when no more data will arrive -STDMETHODIMP -CBasePin::EndOfStream(void) -{ - return S_OK; -} - - -STDMETHODIMP -CBasePin::SetSink(IQualityControl * piqc) -{ - CAutoLock cObjectLock(m_pLock); - if (piqc) ValidateReadPtr(piqc,sizeof(IQualityControl)); - m_pQSink = piqc; - return NOERROR; -} // SetSink - - -STDMETHODIMP -CBasePin::Notify(IBaseFilter * pSender, Quality q) -{ - UNREFERENCED_PARAMETER(q); - UNREFERENCED_PARAMETER(pSender); - DbgBreak("IQualityControl::Notify not over-ridden from CBasePin. (IGNORE is OK)"); - return E_NOTIMPL; -} //Notify - - -// NewSegment notifies of the start/stop/rate applying to the data -// about to be received. Default implementation records data and -// returns S_OK. -// Override this to pass downstream. -STDMETHODIMP -CBasePin::NewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate) -{ - m_tStart = tStart; - m_tStop = tStop; - m_dRate = dRate; - - return S_OK; -} - - -//===================================================================== -//===================================================================== -// Implements CBaseOutputPin -//===================================================================== -//===================================================================== - - -CBaseOutputPin::CBaseOutputPin(TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName) : - CBasePin(pObjectName, pFilter, pLock, phr, pName, PINDIR_OUTPUT), - m_pAllocator(NULL), - m_pInputPin(NULL) -{ - ASSERT(pFilter); -} - -#ifdef UNICODE -CBaseOutputPin::CBaseOutputPin(CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName) : - CBasePin(pObjectName, pFilter, pLock, phr, pName, PINDIR_OUTPUT), - m_pAllocator(NULL), - m_pInputPin(NULL) -{ - ASSERT(pFilter); -} -#endif - -/* This is called after a media type has been proposed - - Try to complete the connection by agreeing the allocator -*/ -HRESULT -CBaseOutputPin::CompleteConnect(IPin *pReceivePin) -{ - UNREFERENCED_PARAMETER(pReceivePin); - return DecideAllocator(m_pInputPin, &m_pAllocator); -} - - -/* This method is called when the output pin is about to try and connect to - an input pin. It is at this point that you should try and grab any extra - interfaces that you need, in this case IMemInputPin. Because this is - only called if we are not currently connected we do NOT need to call - BreakConnect. This also makes it easier to derive classes from us as - BreakConnect is only called when we actually have to break a connection - (or a partly made connection) and not when we are checking a connection */ - -/* Overriden from CBasePin */ - -HRESULT -CBaseOutputPin::CheckConnect(IPin * pPin) -{ - HRESULT hr = CBasePin::CheckConnect(pPin); - if (FAILED(hr)) { - return hr; - } - - // get an input pin and an allocator interface - hr = pPin->QueryInterface(IID_IMemInputPin, (void **) &m_pInputPin); - if (FAILED(hr)) { - return hr; - } - return NOERROR; -} - - -/* Overriden from CBasePin */ - -HRESULT -CBaseOutputPin::BreakConnect() -{ - /* Release any allocator we hold */ - - if (m_pAllocator) { - // Always decommit the allocator because a downstream filter may or - // may not decommit the connection's allocator. A memory leak could - // occur if the allocator is not decommited when a connection is broken. - HRESULT hr = m_pAllocator->Decommit(); - if( FAILED( hr ) ) { - return hr; - } - - m_pAllocator->Release(); - m_pAllocator = NULL; - } - - /* Release any input pin interface we hold */ - - if (m_pInputPin) { - m_pInputPin->Release(); - m_pInputPin = NULL; - } - return NOERROR; -} - - -/* This is called when the input pin didn't give us a valid allocator */ - -HRESULT -CBaseOutputPin::InitAllocator(IMemAllocator **ppAlloc) -{ - return CreateMemoryAllocator(ppAlloc); -} - - -/* Decide on an allocator, override this if you want to use your own allocator - Override DecideBufferSize to call SetProperties. If the input pin fails - the GetAllocator call then this will construct a CMemAllocator and call - DecideBufferSize on that, and if that fails then we are completely hosed. - If the you succeed the DecideBufferSize call, we will notify the input - pin of the selected allocator. NOTE this is called during Connect() which - therefore looks after grabbing and locking the object's critical section */ - -// We query the input pin for its requested properties and pass this to -// DecideBufferSize to allow it to fulfill requests that it is happy -// with (eg most people don't care about alignment and are thus happy to -// use the downstream pin's alignment request). - -HRESULT -CBaseOutputPin::DecideAllocator(IMemInputPin *pPin, IMemAllocator **ppAlloc) -{ - HRESULT hr = NOERROR; - *ppAlloc = NULL; - - // get downstream prop request - // the derived class may modify this in DecideBufferSize, but - // we assume that he will consistently modify it the same way, - // so we only get it once - ALLOCATOR_PROPERTIES prop; - ZeroMemory(&prop, sizeof(prop)); - - // whatever he returns, we assume prop is either all zeros - // or he has filled it out. - pPin->GetAllocatorRequirements(&prop); - - // if he doesn't care about alignment, then set it to 1 - if (prop.cbAlign == 0) { - prop.cbAlign = 1; - } - - /* Try the allocator provided by the input pin */ - - hr = pPin->GetAllocator(ppAlloc); - if (SUCCEEDED(hr)) { - - hr = DecideBufferSize(*ppAlloc, &prop); - if (SUCCEEDED(hr)) { - hr = pPin->NotifyAllocator(*ppAlloc, FALSE); - if (SUCCEEDED(hr)) { - return NOERROR; - } - } - } - - /* If the GetAllocator failed we may not have an interface */ - - if (*ppAlloc) { - (*ppAlloc)->Release(); - *ppAlloc = NULL; - } - - /* Try the output pin's allocator by the same method */ - - hr = InitAllocator(ppAlloc); - if (SUCCEEDED(hr)) { - - // note - the properties passed here are in the same - // structure as above and may have been modified by - // the previous call to DecideBufferSize - hr = DecideBufferSize(*ppAlloc, &prop); - if (SUCCEEDED(hr)) { - hr = pPin->NotifyAllocator(*ppAlloc, FALSE); - if (SUCCEEDED(hr)) { - return NOERROR; - } - } - } - - /* Likewise we may not have an interface to release */ - - if (*ppAlloc) { - (*ppAlloc)->Release(); - *ppAlloc = NULL; - } - return hr; -} - - -/* This returns an empty sample buffer from the allocator WARNING the same - dangers and restrictions apply here as described below for Deliver() */ - -HRESULT -CBaseOutputPin::GetDeliveryBuffer(IMediaSample ** ppSample, - REFERENCE_TIME * pStartTime, - REFERENCE_TIME * pEndTime, - DWORD dwFlags) -{ - if (m_pAllocator != NULL) { - return m_pAllocator->GetBuffer(ppSample,pStartTime,pEndTime,dwFlags); - } else { - return E_NOINTERFACE; - } -} - - -/* Deliver a filled-in sample to the connected input pin. NOTE the object must - have locked itself before calling us otherwise we may get halfway through - executing this method only to find the filter graph has got in and - disconnected us from the input pin. If the filter has no worker threads - then the lock is best applied on Receive(), otherwise it should be done - when the worker thread is ready to deliver. There is a wee snag to worker - threads that this shows up. The worker thread must lock the object when - it is ready to deliver a sample, but it may have to wait until a state - change has completed, but that may never complete because the state change - is waiting for the worker thread to complete. The way to handle this is for - the state change code to grab the critical section, then set an abort event - for the worker thread, then release the critical section and wait for the - worker thread to see the event we set and then signal that it has finished - (with another event). At which point the state change code can complete */ - -// note (if you've still got any breath left after reading that) that you -// need to release the sample yourself after this call. if the connected -// input pin needs to hold onto the sample beyond the call, it will addref -// the sample itself. - -// of course you must release this one and call GetDeliveryBuffer for the -// next. You cannot reuse it directly. - -HRESULT -CBaseOutputPin::Deliver(IMediaSample * pSample) -{ - if (m_pInputPin == NULL) { - return VFW_E_NOT_CONNECTED; - } - - - return m_pInputPin->Receive(pSample); -} - - -// called from elsewhere in our filter to pass EOS downstream to -// our connected input pin -HRESULT -CBaseOutputPin::DeliverEndOfStream(void) -{ - // remember this is on IPin not IMemInputPin - if (m_Connected == NULL) { - return VFW_E_NOT_CONNECTED; - } - return m_Connected->EndOfStream(); -} - - -/* Commit the allocator's memory, this is called through IMediaFilter - which is responsible for locking the object before calling us */ - -HRESULT -CBaseOutputPin::Active(void) -{ - if (m_pAllocator == NULL) { - return VFW_E_NO_ALLOCATOR; - } - return m_pAllocator->Commit(); -} - - -/* Free up or unprepare allocator's memory, this is called through - IMediaFilter which is responsible for locking the object first */ - -HRESULT -CBaseOutputPin::Inactive(void) -{ - m_bRunTimeError = FALSE; - if (m_pAllocator == NULL) { - return VFW_E_NO_ALLOCATOR; - } - return m_pAllocator->Decommit(); -} - -// we have a default handling of EndOfStream which is to return -// an error, since this should be called on input pins only -STDMETHODIMP -CBaseOutputPin::EndOfStream(void) -{ - return E_UNEXPECTED; -} - - -// BeginFlush should be called on input pins only -STDMETHODIMP -CBaseOutputPin::BeginFlush(void) -{ - return E_UNEXPECTED; -} - -// EndFlush should be called on input pins only -STDMETHODIMP -CBaseOutputPin::EndFlush(void) -{ - return E_UNEXPECTED; -} - -// call BeginFlush on the connected input pin -HRESULT -CBaseOutputPin::DeliverBeginFlush(void) -{ - // remember this is on IPin not IMemInputPin - if (m_Connected == NULL) { - return VFW_E_NOT_CONNECTED; - } - return m_Connected->BeginFlush(); -} - -// call EndFlush on the connected input pin -HRESULT -CBaseOutputPin::DeliverEndFlush(void) -{ - // remember this is on IPin not IMemInputPin - if (m_Connected == NULL) { - return VFW_E_NOT_CONNECTED; - } - return m_Connected->EndFlush(); -} -// deliver NewSegment to connected pin -HRESULT -CBaseOutputPin::DeliverNewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate) -{ - if (m_Connected == NULL) { - return VFW_E_NOT_CONNECTED; - } - return m_Connected->NewSegment(tStart, tStop, dRate); -} - - -//===================================================================== -//===================================================================== -// Implements CBaseInputPin -//===================================================================== -//===================================================================== - - -/* Constructor creates a default allocator object */ - -CBaseInputPin::CBaseInputPin(TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pPinName) : - CBasePin(pObjectName, pFilter, pLock, phr, pPinName, PINDIR_INPUT), - m_pAllocator(NULL), - m_bReadOnly(FALSE), - m_bFlushing(FALSE) -{ - ZeroMemory(&m_SampleProps, sizeof(m_SampleProps)); -} - -#ifdef UNICODE -CBaseInputPin::CBaseInputPin(CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pPinName) : - CBasePin(pObjectName, pFilter, pLock, phr, pPinName, PINDIR_INPUT), - m_pAllocator(NULL), - m_bReadOnly(FALSE), - m_bFlushing(FALSE) -{ - ZeroMemory(&m_SampleProps, sizeof(m_SampleProps)); -} -#endif - -/* Destructor releases it's reference count on the default allocator */ - -CBaseInputPin::~CBaseInputPin() -{ - if (m_pAllocator != NULL) { - m_pAllocator->Release(); - m_pAllocator = NULL; - } -} - - -// override this to publicise our interfaces -STDMETHODIMP -CBaseInputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - /* Do we know about this interface */ - - if (riid == IID_IMemInputPin) { - return GetInterface((IMemInputPin *) this, ppv); - } else { - return CBasePin::NonDelegatingQueryInterface(riid, ppv); - } -} - - -/* Return the allocator interface that this input pin would like the output - pin to use. NOTE subsequent calls to GetAllocator should all return an - interface onto the SAME object so we create one object at the start - - Note: - The allocator is Release()'d on disconnect and replaced on - NotifyAllocator(). - - Override this to provide your own allocator. -*/ - -STDMETHODIMP -CBaseInputPin::GetAllocator( - IMemAllocator **ppAllocator) -{ - CheckPointer(ppAllocator,E_POINTER); - ValidateReadWritePtr(ppAllocator,sizeof(IMemAllocator *)); - CAutoLock cObjectLock(m_pLock); - - if (m_pAllocator == NULL) { - HRESULT hr = CreateMemoryAllocator(&m_pAllocator); - if (FAILED(hr)) { - return hr; - } - } - ASSERT(m_pAllocator != NULL); - *ppAllocator = m_pAllocator; - m_pAllocator->AddRef(); - return NOERROR; -} - - -/* Tell the input pin which allocator the output pin is actually going to use - Override this if you care - NOTE the locking we do both here and also in - GetAllocator is unnecessary but derived classes that do something useful - will undoubtedly have to lock the object so this might help remind people */ - -STDMETHODIMP -CBaseInputPin::NotifyAllocator( - IMemAllocator * pAllocator, - BOOL bReadOnly) -{ - CheckPointer(pAllocator,E_POINTER); - ValidateReadPtr(pAllocator,sizeof(IMemAllocator)); - CAutoLock cObjectLock(m_pLock); - - IMemAllocator *pOldAllocator = m_pAllocator; - pAllocator->AddRef(); - m_pAllocator = pAllocator; - - if (pOldAllocator != NULL) { - pOldAllocator->Release(); - } - - // the readonly flag indicates whether samples from this allocator should - // be regarded as readonly - if true, then inplace transforms will not be - // allowed. - m_bReadOnly = (BYTE)bReadOnly; - return NOERROR; -} - - -HRESULT -CBaseInputPin::BreakConnect() -{ - /* We don't need our allocator any more */ - if (m_pAllocator) { - // Always decommit the allocator because a downstream filter may or - // may not decommit the connection's allocator. A memory leak could - // occur if the allocator is not decommited when a pin is disconnected. - HRESULT hr = m_pAllocator->Decommit(); - if( FAILED( hr ) ) { - return hr; - } - - m_pAllocator->Release(); - m_pAllocator = NULL; - } - - return S_OK; -} - - -/* Do something with this media sample - this base class checks to see if the - format has changed with this media sample and if so checks that the filter - will accept it, generating a run time error if not. Once we have raised a - run time error we set a flag so that no more samples will be accepted - - It is important that any filter should override this method and implement - synchronization so that samples are not processed when the pin is - disconnected etc -*/ - -STDMETHODIMP -CBaseInputPin::Receive(IMediaSample *pSample) -{ - CheckPointer(pSample,E_POINTER); - ValidateReadPtr(pSample,sizeof(IMediaSample)); - ASSERT(pSample); - - HRESULT hr = CheckStreaming(); - if (S_OK != hr) { - return hr; - } - - - - /* Check for IMediaSample2 */ - IMediaSample2 *pSample2; - if (SUCCEEDED(pSample->QueryInterface(IID_IMediaSample2, (void **)&pSample2))) { - hr = pSample2->GetProperties(sizeof(m_SampleProps), (PBYTE)&m_SampleProps); - pSample2->Release(); - if (FAILED(hr)) { - return hr; - } - } else { - /* Get the properties the hard way */ - m_SampleProps.cbData = sizeof(m_SampleProps); - m_SampleProps.dwTypeSpecificFlags = 0; - m_SampleProps.dwStreamId = AM_STREAM_MEDIA; - m_SampleProps.dwSampleFlags = 0; - if (S_OK == pSample->IsDiscontinuity()) { - m_SampleProps.dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY; - } - if (S_OK == pSample->IsPreroll()) { - m_SampleProps.dwSampleFlags |= AM_SAMPLE_PREROLL; - } - if (S_OK == pSample->IsSyncPoint()) { - m_SampleProps.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT; - } - if (SUCCEEDED(pSample->GetTime(&m_SampleProps.tStart, - &m_SampleProps.tStop))) { - m_SampleProps.dwSampleFlags |= AM_SAMPLE_TIMEVALID | - AM_SAMPLE_STOPVALID; - } - if (S_OK == pSample->GetMediaType(&m_SampleProps.pMediaType)) { - m_SampleProps.dwSampleFlags |= AM_SAMPLE_TYPECHANGED; - } - pSample->GetPointer(&m_SampleProps.pbBuffer); - m_SampleProps.lActual = pSample->GetActualDataLength(); - m_SampleProps.cbBuffer = pSample->GetSize(); - } - - /* Has the format changed in this sample */ - - if (!(m_SampleProps.dwSampleFlags & AM_SAMPLE_TYPECHANGED)) { - return NOERROR; - } - - /* Check the derived class accepts this format */ - /* This shouldn't fail as the source must call QueryAccept first */ - - hr = CheckMediaType((CMediaType *)m_SampleProps.pMediaType); - - if (hr == NOERROR) { - return NOERROR; - } - - /* Raise a runtime error if we fail the media type */ - - m_bRunTimeError = TRUE; - EndOfStream(); - m_pFilter->NotifyEvent(EC_ERRORABORT,VFW_E_TYPE_NOT_ACCEPTED,0); - return VFW_E_INVALIDMEDIATYPE; -} - - -/* Receive multiple samples */ -STDMETHODIMP -CBaseInputPin::ReceiveMultiple ( - IMediaSample **pSamples, - long nSamples, - long *nSamplesProcessed) -{ - CheckPointer(pSamples,E_POINTER); - ValidateReadPtr(pSamples,nSamples * sizeof(IMediaSample *)); - - HRESULT hr = S_OK; - *nSamplesProcessed = 0; - while (nSamples-- > 0) { - hr = Receive(pSamples[*nSamplesProcessed]); - - /* S_FALSE means don't send any more */ - if (hr != S_OK) { - break; - } - (*nSamplesProcessed)++; - } - return hr; -} - -/* See if Receive() might block */ -STDMETHODIMP -CBaseInputPin::ReceiveCanBlock() -{ - /* Ask all the output pins if they block - If there are no output pin assume we do block - */ - int cPins = m_pFilter->GetPinCount(); - int cOutputPins = 0; - for (int c = 0; c < cPins; c++) { - CBasePin *pPin = m_pFilter->GetPin(c); - PIN_DIRECTION pd; - HRESULT hr = pPin->QueryDirection(&pd); - if (FAILED(hr)) { - return hr; - } - - if (pd == PINDIR_OUTPUT) { - - IPin *pConnected; - hr = pPin->ConnectedTo(&pConnected); - if (SUCCEEDED(hr)) { - ASSERT(pConnected != NULL); - cOutputPins++; - IMemInputPin *pInputPin; - hr = pConnected->QueryInterface( - IID_IMemInputPin, - (void **)&pInputPin); - pConnected->Release(); - if (SUCCEEDED(hr)) { - hr = pInputPin->ReceiveCanBlock(); - pInputPin->Release(); - if (hr != S_FALSE) { - return S_OK; - } - } else { - /* There's a transport we don't understand here */ - return S_OK; - } - } - } - } - return cOutputPins == 0 ? S_OK : S_FALSE; -} - -// Default handling for BeginFlush - call at the beginning -// of your implementation (makes sure that all Receive calls -// fail). After calling this, you need to free any queued data -// and then call downstream. -STDMETHODIMP -CBaseInputPin::BeginFlush(void) -{ - // BeginFlush is NOT synchronized with streaming but is part of - // a control action - hence we synchronize with the filter - CAutoLock lck(m_pLock); - - // if we are already in mid-flush, this is probably a mistake - // though not harmful - try to pick it up for now so I can think about it - ASSERT(!m_bFlushing); - - // first thing to do is ensure that no further Receive calls succeed - m_bFlushing = TRUE; - - // now discard any data and call downstream - must do that - // in derived classes - return S_OK; -} - -// default handling for EndFlush - call at end of your implementation -// - before calling this, ensure that there is no queued data and no thread -// pushing any more without a further receive, then call downstream, -// then call this method to clear the m_bFlushing flag and re-enable -// receives -STDMETHODIMP -CBaseInputPin::EndFlush(void) -{ - // Endlush is NOT synchronized with streaming but is part of - // a control action - hence we synchronize with the filter - CAutoLock lck(m_pLock); - - // almost certainly a mistake if we are not in mid-flush - ASSERT(m_bFlushing); - - // before calling, sync with pushing thread and ensure - // no more data is going downstream, then call EndFlush on - // downstream pins. - - // now re-enable Receives - m_bFlushing = FALSE; - - // No more errors - m_bRunTimeError = FALSE; - - return S_OK; -} - - -STDMETHODIMP -CBaseInputPin::Notify(IBaseFilter * pSender, Quality q) -{ - UNREFERENCED_PARAMETER(q); - CheckPointer(pSender,E_POINTER); - ValidateReadPtr(pSender,sizeof(IBaseFilter)); - DbgBreak("IQuality::Notify called on an input pin"); - return NOERROR; -} // Notify - -/* Free up or unprepare allocator's memory, this is called through - IMediaFilter which is responsible for locking the object first */ - -HRESULT -CBaseInputPin::Inactive(void) -{ - m_bRunTimeError = FALSE; - if (m_pAllocator == NULL) { - return VFW_E_NO_ALLOCATOR; - } - - m_bFlushing = FALSE; - - return m_pAllocator->Decommit(); -} - -// what requirements do we have of the allocator - override if you want -// to support other people's allocators but need a specific alignment -// or prefix. -STDMETHODIMP -CBaseInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES*pProps) -{ - UNREFERENCED_PARAMETER(pProps); - return E_NOTIMPL; -} - -// Check if it's OK to process data -// -HRESULT -CBaseInputPin::CheckStreaming() -{ - // Shouldn't be able to get any data if we're not connected! - ASSERT(IsConnected()); - - // Don't process stuff in Stopped state - if (IsStopped()) { - return VFW_E_WRONG_STATE; - } - if (m_bFlushing) { - return S_FALSE; - } - if (m_bRunTimeError) { - return VFW_E_RUNTIME_ERROR; - } - return S_OK; -} - -// Pass on the Quality notification q to -// a. Our QualityControl sink (if we have one) or else -// b. to our upstream filter -// and if that doesn't work, throw it away with a bad return code -HRESULT -CBaseInputPin::PassNotify(Quality& q) -{ - // We pass the message on, which means that we find the quality sink - // for our input pin and send it there - - DbgLog((LOG_TRACE,3,TEXT("Passing Quality notification through transform"))); - if (m_pQSink!=NULL) { - return m_pQSink->Notify(m_pFilter, q); - } else { - // no sink set, so pass it upstream - HRESULT hr; - IQualityControl * pIQC; - - hr = VFW_E_NOT_FOUND; // default - if (m_Connected) { - m_Connected->QueryInterface(IID_IQualityControl, (void**)&pIQC); - - if (pIQC!=NULL) { - hr = pIQC->Notify(m_pFilter, q); - pIQC->Release(); - } - } - return hr; - } - -} // PassNotify - -//===================================================================== -//===================================================================== -// Memory allocation class, implements CMediaSample -//===================================================================== -//===================================================================== - - -/* NOTE The implementation of this class calls the CUnknown constructor with - a NULL outer unknown pointer. This has the effect of making us a self - contained class, ie any QueryInterface, AddRef or Release calls will be - routed to the class's NonDelegatingUnknown methods. You will typically - find that the classes that do this then override one or more of these - virtual functions to provide more specialised behaviour. A good example - of this is where a class wants to keep the QueryInterface internal but - still wants it's lifetime controlled by the external object */ - -/* The last two parameters have default values of NULL and zero */ - -CMediaSample::CMediaSample(TCHAR *pName, - CBaseAllocator *pAllocator, - HRESULT *phr, - LPBYTE pBuffer, - LONG length) : - m_pBuffer(pBuffer), // Initialise the buffer - m_cbBuffer(length), // And it's length - m_lActual(length), // By default, actual = length - m_pMediaType(NULL), // No media type change - m_dwFlags(0), // Nothing set - m_cRef(0), // 0 ref count - m_dwTypeSpecificFlags(0), // Type specific flags - m_dwStreamId(AM_STREAM_MEDIA), // Stream id - m_pAllocator(pAllocator) // Allocator -{ - - /* We must have an owner and it must also be derived from class - CBaseAllocator BUT we do not hold a reference count on it */ - - ASSERT(pAllocator); -} - -#ifdef UNICODE -CMediaSample::CMediaSample(CHAR *pName, - CBaseAllocator *pAllocator, - HRESULT *phr, - LPBYTE pBuffer, - LONG length) : - m_pBuffer(pBuffer), // Initialise the buffer - m_cbBuffer(length), // And it's length - m_lActual(length), // By default, actual = length - m_pMediaType(NULL), // No media type change - m_dwFlags(0), // Nothing set - m_cRef(0), // 0 ref count - m_dwTypeSpecificFlags(0), // Type specific flags - m_dwStreamId(AM_STREAM_MEDIA), // Stream id - m_pAllocator(pAllocator) // Allocator -{ - - /* We must have an owner and it must also be derived from class - CBaseAllocator BUT we do not hold a reference count on it */ - - ASSERT(pAllocator); -} -#endif - -/* Destructor deletes the media type memory */ - -CMediaSample::~CMediaSample() -{ - - if (m_pMediaType) { - DeleteMediaType(m_pMediaType); - } -} - -/* Override this to publicise our interfaces */ - -STDMETHODIMP -CMediaSample::QueryInterface(REFIID riid, void **ppv) -{ - if (riid == IID_IMediaSample || - riid == IID_IMediaSample2 || - riid == IID_IUnknown) { - return GetInterface((IMediaSample *) this, ppv); - } else { - return E_NOINTERFACE; - } -} - -STDMETHODIMP_(ULONG) -CMediaSample::AddRef() -{ - return InterlockedIncrement(&m_cRef); -} - - -// -- CMediaSample lifetimes -- -// -// On final release of this sample buffer it is not deleted but -// returned to the freelist of the owning memory allocator -// -// The allocator may be waiting for the last buffer to be placed on the free -// list in order to decommit all the memory, so the ReleaseBuffer() call may -// result in this sample being deleted. We also need to hold a refcount on -// the allocator to stop that going away until we have finished with this. -// However, we cannot release the allocator before the ReleaseBuffer, as the -// release may cause us to be deleted. Similarly we can't do it afterwards. -// -// Thus we must leave it to the allocator to hold an addref on our behalf. -// When he issues us in GetBuffer, he addref's himself. When ReleaseBuffer -// is called, he releases himself, possibly causing us and him to be deleted. - - -STDMETHODIMP_(ULONG) -CMediaSample::Release() -{ - /* Decrement our own private reference count */ - LONG lRef; - if (m_cRef == 1) { - lRef = 0; - m_cRef = 0; - } else { - lRef = InterlockedDecrement(&m_cRef); - } - ASSERT(lRef >= 0); - - DbgLog((LOG_MEMORY,3,TEXT(" Unknown %X ref-- = %d"), - this, m_cRef)); - - /* Did we release our final reference count */ - if (lRef == 0) { - /* Free all resources */ - if (m_dwFlags & Sample_TypeChanged) { - SetMediaType(NULL); - } - ASSERT(m_pMediaType == NULL); - m_dwFlags = 0; - m_dwTypeSpecificFlags = 0; - m_dwStreamId = AM_STREAM_MEDIA; - - /* This may cause us to be deleted */ - // Our refcount is reliably 0 thus no-one will mess with us - m_pAllocator->ReleaseBuffer(this); - } - return (ULONG)lRef; -} - - -// set the buffer pointer and length. Used by allocators that -// want variable sized pointers or pointers into already-read data. -// This is only available through a CMediaSample* not an IMediaSample* -// and so cannot be changed by clients. -HRESULT -CMediaSample::SetPointer(BYTE * ptr, LONG cBytes) -{ - m_pBuffer = ptr; // new buffer area (could be null) - m_cbBuffer = cBytes; // length of buffer - m_lActual = cBytes; // length of data in buffer (assume full) - - return S_OK; -} - - -// get me a read/write pointer to this buffer's memory. I will actually -// want to use sizeUsed bytes. -STDMETHODIMP -CMediaSample::GetPointer(BYTE ** ppBuffer) -{ - ValidateReadWritePtr(ppBuffer,sizeof(BYTE *)); - - // creator must have set pointer either during - // constructor or by SetPointer - ASSERT(m_pBuffer); - - *ppBuffer = m_pBuffer; - return NOERROR; -} - - -// return the size in bytes of this buffer -STDMETHODIMP_(LONG) -CMediaSample::GetSize(void) -{ - return m_cbBuffer; -} - - -// get the stream time at which this sample should start and finish. -STDMETHODIMP -CMediaSample::GetTime( - REFERENCE_TIME * pTimeStart, // put time here - REFERENCE_TIME * pTimeEnd -) -{ - ValidateReadWritePtr(pTimeStart,sizeof(REFERENCE_TIME)); - ValidateReadWritePtr(pTimeEnd,sizeof(REFERENCE_TIME)); - - if (!(m_dwFlags & Sample_StopValid)) { - if (!(m_dwFlags & Sample_TimeValid)) { - return VFW_E_SAMPLE_TIME_NOT_SET; - } else { - *pTimeStart = m_Start; - - // Make sure old stuff works - *pTimeEnd = m_Start + 1; - return VFW_S_NO_STOP_TIME; - } - } - - *pTimeStart = m_Start; - *pTimeEnd = m_End; - return NOERROR; -} - - -// Set the stream time at which this sample should start and finish. -// NULL pointers means the time is reset -STDMETHODIMP -CMediaSample::SetTime( - REFERENCE_TIME * pTimeStart, - REFERENCE_TIME * pTimeEnd -) -{ - if (pTimeStart == NULL) { - ASSERT(pTimeEnd == NULL); - m_dwFlags &= ~(Sample_TimeValid | Sample_StopValid); - } else { - if (pTimeEnd == NULL) { - m_Start = *pTimeStart; - m_dwFlags |= Sample_TimeValid; - m_dwFlags &= ~Sample_StopValid; - } else { - ValidateReadPtr(pTimeStart,sizeof(REFERENCE_TIME)); - ValidateReadPtr(pTimeEnd,sizeof(REFERENCE_TIME)); - ASSERT(*pTimeEnd >= *pTimeStart); - - m_Start = *pTimeStart; - m_End = *pTimeEnd; - m_dwFlags |= Sample_TimeValid | Sample_StopValid; - } - } - return NOERROR; -} - - -// get the media times (eg bytes) for this sample -STDMETHODIMP -CMediaSample::GetMediaTime( - LONGLONG * pTimeStart, - LONGLONG * pTimeEnd -) -{ - ValidateReadWritePtr(pTimeStart,sizeof(LONGLONG)); - ValidateReadWritePtr(pTimeEnd,sizeof(LONGLONG)); - - if (!(m_dwFlags & Sample_MediaTimeValid)) { - return VFW_E_MEDIA_TIME_NOT_SET; - } - - *pTimeStart = m_MediaStart; - *pTimeEnd = (m_MediaStart + m_MediaEnd); - return NOERROR; -} - - -// Set the media times for this sample -STDMETHODIMP -CMediaSample::SetMediaTime( - LONGLONG * pTimeStart, - LONGLONG * pTimeEnd -) -{ - if (pTimeStart == NULL) { - ASSERT(pTimeEnd == NULL); - m_dwFlags &= ~Sample_MediaTimeValid; - } else { - ValidateReadPtr(pTimeStart,sizeof(LONGLONG)); - ValidateReadPtr(pTimeEnd,sizeof(LONGLONG)); - ASSERT(*pTimeEnd >= *pTimeStart); - - m_MediaStart = *pTimeStart; - m_MediaEnd = (LONG)(*pTimeEnd - *pTimeStart); - m_dwFlags |= Sample_MediaTimeValid; - } - return NOERROR; -} - - -STDMETHODIMP -CMediaSample::IsSyncPoint(void) -{ - if (m_dwFlags & Sample_SyncPoint) { - return S_OK; - } else { - return S_FALSE; - } -} - - -STDMETHODIMP -CMediaSample::SetSyncPoint(BOOL bIsSyncPoint) -{ - if (bIsSyncPoint) { - m_dwFlags |= Sample_SyncPoint; - } else { - m_dwFlags &= ~Sample_SyncPoint; - } - return NOERROR; -} - -// returns S_OK if there is a discontinuity in the data (this same is -// not a continuation of the previous stream of data -// - there has been a seek). -STDMETHODIMP -CMediaSample::IsDiscontinuity(void) -{ - if (m_dwFlags & Sample_Discontinuity) { - return S_OK; - } else { - return S_FALSE; - } -} - -// set the discontinuity property - TRUE if this sample is not a -// continuation, but a new sample after a seek. -STDMETHODIMP -CMediaSample::SetDiscontinuity(BOOL bDiscont) -{ - // should be TRUE or FALSE - if (bDiscont) { - m_dwFlags |= Sample_Discontinuity; - } else { - m_dwFlags &= ~Sample_Discontinuity; - } - return S_OK; -} - -STDMETHODIMP -CMediaSample::IsPreroll(void) -{ - if (m_dwFlags & Sample_Preroll) { - return S_OK; - } else { - return S_FALSE; - } -} - - -STDMETHODIMP -CMediaSample::SetPreroll(BOOL bIsPreroll) -{ - if (bIsPreroll) { - m_dwFlags |= Sample_Preroll; - } else { - m_dwFlags &= ~Sample_Preroll; - } - return NOERROR; -} - -STDMETHODIMP_(LONG) -CMediaSample::GetActualDataLength(void) -{ - return m_lActual; -} - - -STDMETHODIMP -CMediaSample::SetActualDataLength(LONG lActual) -{ - if (lActual > m_cbBuffer) { - ASSERT(lActual <= GetSize()); - return VFW_E_BUFFER_OVERFLOW; - } - m_lActual = lActual; - return NOERROR; -} - - -/* These allow for limited format changes in band */ - -STDMETHODIMP -CMediaSample::GetMediaType(AM_MEDIA_TYPE **ppMediaType) -{ - ValidateReadWritePtr(ppMediaType,sizeof(AM_MEDIA_TYPE *)); - ASSERT(ppMediaType); - - /* Do we have a new media type for them */ - - if (!(m_dwFlags & Sample_TypeChanged)) { - ASSERT(m_pMediaType == NULL); - *ppMediaType = NULL; - return S_FALSE; - } - - ASSERT(m_pMediaType); - - /* Create a copy of our media type */ - - *ppMediaType = CreateMediaType(m_pMediaType); - if (*ppMediaType == NULL) { - return E_OUTOFMEMORY; - } - return NOERROR; -} - - -/* Mark this sample as having a different format type */ - -STDMETHODIMP -CMediaSample::SetMediaType(AM_MEDIA_TYPE *pMediaType) -{ - /* Delete the current media type */ - - if (m_pMediaType) { - DeleteMediaType(m_pMediaType); - m_pMediaType = NULL; - } - - /* Mechanism for resetting the format type */ - - if (pMediaType == NULL) { - m_dwFlags &= ~Sample_TypeChanged; - return NOERROR; - } - - ASSERT(pMediaType); - ValidateReadPtr(pMediaType,sizeof(AM_MEDIA_TYPE)); - - /* Take a copy of the media type */ - - m_pMediaType = CreateMediaType(pMediaType); - if (m_pMediaType == NULL) { - m_dwFlags &= ~Sample_TypeChanged; - return E_OUTOFMEMORY; - } - - m_dwFlags |= Sample_TypeChanged; - return NOERROR; -} - -// Set and get properties (IMediaSample2) -STDMETHODIMP CMediaSample::GetProperties( - DWORD cbProperties, - BYTE * pbProperties -) -{ - if (0 != cbProperties) { - CheckPointer(pbProperties, E_POINTER); - // Return generic stuff up to the length - AM_SAMPLE2_PROPERTIES Props; - Props.cbData = min(cbProperties, sizeof(Props)); - Props.dwSampleFlags = m_dwFlags & ~Sample_MediaTimeValid; - Props.dwTypeSpecificFlags = m_dwTypeSpecificFlags; - Props.pbBuffer = m_pBuffer; - Props.cbBuffer = m_cbBuffer; - Props.lActual = m_lActual; - Props.tStart = m_Start; - Props.tStop = m_End; - Props.dwStreamId = m_dwStreamId; - if (m_dwFlags & AM_SAMPLE_TYPECHANGED) { - Props.pMediaType = m_pMediaType; - } else { - Props.pMediaType = NULL; - } - CopyMemory(pbProperties, &Props, Props.cbData); - } - return S_OK; -} - -#define CONTAINS_FIELD(type, field, offset) \ - ((FIELD_OFFSET(type, field) + sizeof(((type *)0)->field)) <= offset) - -HRESULT CMediaSample::SetProperties( - DWORD cbProperties, - const BYTE * pbProperties -) -{ - - /* Generic properties */ - AM_MEDIA_TYPE *pMediaType = NULL; - - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, cbData, cbProperties)) { - CheckPointer(pbProperties, E_POINTER); - AM_SAMPLE2_PROPERTIES *pProps = - (AM_SAMPLE2_PROPERTIES *)pbProperties; - - /* Don't use more data than is actually there */ - if (pProps->cbData < cbProperties) { - cbProperties = pProps->cbData; - } - /* We only handle IMediaSample2 */ - if (cbProperties > sizeof(*pProps) || - pProps->cbData > sizeof(*pProps)) { - return E_INVALIDARG; - } - /* Do checks first, the assignments (for backout) */ - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, dwSampleFlags, cbProperties)) { - /* Check the flags */ - if (pProps->dwSampleFlags & - (~Sample_ValidFlags | Sample_MediaTimeValid)) { - return E_INVALIDARG; - } - /* Check a flag isn't being set for a property - not being provided - */ - if ((pProps->dwSampleFlags & AM_SAMPLE_TIMEVALID) && - !(m_dwFlags & AM_SAMPLE_TIMEVALID) && - !CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, tStop, cbProperties)) { - return E_INVALIDARG; - } - } - /* NB - can't SET the pointer or size */ - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, pbBuffer, cbProperties)) { - - /* Check pbBuffer */ - if (pProps->pbBuffer != 0 && pProps->pbBuffer != m_pBuffer) { - return E_INVALIDARG; - } - } - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, cbBuffer, cbProperties)) { - - /* Check cbBuffer */ - if (pProps->cbBuffer != 0 && pProps->cbBuffer != m_cbBuffer) { - return E_INVALIDARG; - } - } - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, cbBuffer, cbProperties) && - CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, lActual, cbProperties)) { - - /* Check lActual */ - if (pProps->cbBuffer < pProps->lActual) { - return E_INVALIDARG; - } - } - - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, pMediaType, cbProperties)) { - - /* Check pMediaType */ - if (pProps->dwSampleFlags & AM_SAMPLE_TYPECHANGED) { - CheckPointer(pProps->pMediaType, E_POINTER); - pMediaType = CreateMediaType(pProps->pMediaType); - if (pMediaType == NULL) { - return E_OUTOFMEMORY; - } - } - } - - /* Now do the assignments */ - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, dwStreamId, cbProperties)) { - m_dwStreamId = pProps->dwStreamId; - } - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, dwSampleFlags, cbProperties)) { - /* Set the flags */ - m_dwFlags = pProps->dwSampleFlags | - (m_dwFlags & Sample_MediaTimeValid); - m_dwTypeSpecificFlags = pProps->dwTypeSpecificFlags; - } else { - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, dwTypeSpecificFlags, cbProperties)) { - m_dwTypeSpecificFlags = pProps->dwTypeSpecificFlags; - } - } - - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, lActual, cbProperties)) { - /* Set lActual */ - m_lActual = pProps->lActual; - } - - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, tStop, cbProperties)) { - - /* Set the times */ - m_End = pProps->tStop; - } - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, tStart, cbProperties)) { - - /* Set the times */ - m_Start = pProps->tStart; - } - - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, pMediaType, cbProperties)) { - /* Set pMediaType */ - if (pProps->dwSampleFlags & AM_SAMPLE_TYPECHANGED) { - if (m_pMediaType != NULL) { - DeleteMediaType(m_pMediaType); - } - m_pMediaType = pMediaType; - } - } - - /* Fix up the type changed flag to correctly reflect the current state - If, for instance the input contained no type change but the - output does then if we don't do this we'd lose the - output media type. - */ - if (m_pMediaType) { - m_dwFlags |= Sample_TypeChanged; - } else { - m_dwFlags &= ~Sample_TypeChanged; - } - } - - return S_OK; -} - - -// -// The streaming thread calls IPin::NewSegment(), IPin::EndOfStream(), -// IMemInputPin::Receive() and IMemInputPin::ReceiveMultiple() on the -// connected input pin. The application thread calls Block(). The -// following class members can only be called by the streaming thread. -// -// Deliver() -// DeliverNewSegment() -// StartUsingOutputPin() -// StopUsingOutputPin() -// ChangeOutputFormat() -// ChangeMediaType() -// DynamicReconnect() -// -// The following class members can only be called by the application thread. -// -// Block() -// SynchronousBlockOutputPin() -// AsynchronousBlockOutputPin() -// - -CDynamicOutputPin::CDynamicOutputPin( - TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName) : - CBaseOutputPin(pObjectName, pFilter, pLock, phr, pName), - m_hStopEvent(NULL), - m_pGraphConfig(NULL), - m_bPinUsesReadOnlyAllocator(FALSE), - m_BlockState(NOT_BLOCKED), - m_hUnblockOutputPinEvent(NULL), - m_hNotifyCallerPinBlockedEvent(NULL), - m_dwBlockCallerThreadID(0), - m_dwNumOutstandingOutputPinUsers(0) -{ - HRESULT hr = Initialize(); - if( FAILED( hr ) ) { - *phr = hr; - return; - } -} - -#ifdef UNICODE -CDynamicOutputPin::CDynamicOutputPin( - CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName) : - CBaseOutputPin(pObjectName, pFilter, pLock, phr, pName), - m_hStopEvent(NULL), - m_pGraphConfig(NULL), - m_bPinUsesReadOnlyAllocator(FALSE), - m_BlockState(NOT_BLOCKED), - m_hUnblockOutputPinEvent(NULL), - m_hNotifyCallerPinBlockedEvent(NULL), - m_dwBlockCallerThreadID(0), - m_dwNumOutstandingOutputPinUsers(0) -{ - HRESULT hr = Initialize(); - if( FAILED( hr ) ) { - *phr = hr; - return; - } -} -#endif - -CDynamicOutputPin::~CDynamicOutputPin() -{ - if(NULL != m_hUnblockOutputPinEvent) { - // This call should not fail because we have access to m_hUnblockOutputPinEvent - // and m_hUnblockOutputPinEvent is a valid event. - EXECUTE_ASSERT(::CloseHandle(m_hUnblockOutputPinEvent)); - } - - if(NULL != m_hNotifyCallerPinBlockedEvent) { - // This call should not fail because we have access to m_hNotifyCallerPinBlockedEvent - // and m_hNotifyCallerPinBlockedEvent is a valid event. - EXECUTE_ASSERT(::CloseHandle(m_hNotifyCallerPinBlockedEvent)); - } -} - -HRESULT CDynamicOutputPin::Initialize(void) -{ - m_hUnblockOutputPinEvent = ::CreateEvent( NULL, // The event will have the default security descriptor. - TRUE, // This is a manual reset event. - TRUE, // The event is initially signaled. - NULL ); // The event is not named. - - // CreateEvent() returns NULL if an error occurs. - if(NULL == m_hUnblockOutputPinEvent) { - return AmGetLastErrorToHResult(); - } - - // Set flag to say we can reconnect while streaming. - SetReconnectWhenActive(true); - - return S_OK; -} - -STDMETHODIMP CDynamicOutputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - if(riid == IID_IPinFlowControl) { - return GetInterface(static_cast(this), ppv); - } else { - return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv); - } -} - -STDMETHODIMP CDynamicOutputPin::Disconnect(void) -{ - CAutoLock cObjectLock(m_pLock); - return DisconnectInternal(); -} - -STDMETHODIMP CDynamicOutputPin::Block(DWORD dwBlockFlags, HANDLE hEvent) -{ - const DWORD VALID_FLAGS = AM_PIN_FLOW_CONTROL_BLOCK; - - // Check for illegal flags. - if(dwBlockFlags & ~VALID_FLAGS) { - return E_INVALIDARG; - } - - // Make sure the event is unsignaled. - if((dwBlockFlags & AM_PIN_FLOW_CONTROL_BLOCK) && (NULL != hEvent)) { - if( !::ResetEvent( hEvent ) ) { - return AmGetLastErrorToHResult(); - } - } - - // No flags are set if we are unblocking the output pin. - if(0 == dwBlockFlags) { - - // This parameter should be NULL because unblock operations are always synchronous. - // There is no need to notify the caller when the event is done. - if(NULL != hEvent) { - return E_INVALIDARG; - } - } - - #ifdef DEBUG - AssertValid(); - #endif // DEBUG - - HRESULT hr; - - if(dwBlockFlags & AM_PIN_FLOW_CONTROL_BLOCK) { - // IPinFlowControl::Block()'s hEvent parameter is NULL if the block is synchronous. - // If hEvent is not NULL, the block is asynchronous. - if(NULL == hEvent) { - hr = SynchronousBlockOutputPin(); - } else { - hr = AsynchronousBlockOutputPin(hEvent); - } - } else { - hr = UnblockOutputPin(); - } - - #ifdef DEBUG - AssertValid(); - #endif // DEBUG - - if(FAILED(hr)) { - return hr; - } - - return S_OK; -} - -HRESULT CDynamicOutputPin::SynchronousBlockOutputPin(void) -{ - HANDLE hNotifyCallerPinBlockedEvent = :: CreateEvent( NULL, // The event will have the default security attributes. - FALSE, // This is an automatic reset event. - FALSE, // The event is initially unsignaled. - NULL ); // The event is not named. - - // CreateEvent() returns NULL if an error occurs. - if(NULL == hNotifyCallerPinBlockedEvent) { - return AmGetLastErrorToHResult(); - } - - HRESULT hr = AsynchronousBlockOutputPin(hNotifyCallerPinBlockedEvent); - if(FAILED(hr)) { - // This call should not fail because we have access to hNotifyCallerPinBlockedEvent - // and hNotifyCallerPinBlockedEvent is a valid event. - EXECUTE_ASSERT(::CloseHandle(hNotifyCallerPinBlockedEvent)); - - return hr; - } - - hr = WaitEvent(hNotifyCallerPinBlockedEvent); - - // This call should not fail because we have access to hNotifyCallerPinBlockedEvent - // and hNotifyCallerPinBlockedEvent is a valid event. - EXECUTE_ASSERT(::CloseHandle(hNotifyCallerPinBlockedEvent)); - - if(FAILED(hr)) { - return hr; - } - - return S_OK; -} - -HRESULT CDynamicOutputPin::AsynchronousBlockOutputPin(HANDLE hNotifyCallerPinBlockedEvent) -{ - // This function holds the m_BlockStateLock because it uses - // m_dwBlockCallerThreadID, m_BlockState and - // m_hNotifyCallerPinBlockedEvent. - CAutoLock alBlockStateLock(&m_BlockStateLock); - - if(NOT_BLOCKED != m_BlockState) { - if(m_dwBlockCallerThreadID == ::GetCurrentThreadId()) { - return VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREAD; - } else { - return VFW_E_PIN_ALREADY_BLOCKED; - } - } - - BOOL fSuccess = ::DuplicateHandle( ::GetCurrentProcess(), - hNotifyCallerPinBlockedEvent, - ::GetCurrentProcess(), - &m_hNotifyCallerPinBlockedEvent, - EVENT_MODIFY_STATE, - FALSE, - 0 ); - if( !fSuccess ) { - return AmGetLastErrorToHResult(); - } - - m_BlockState = PENDING; - m_dwBlockCallerThreadID = ::GetCurrentThreadId(); - - // The output pin cannot be blocked if the streaming thread is - // calling IPin::NewSegment(), IPin::EndOfStream(), IMemInputPin::Receive() - // or IMemInputPin::ReceiveMultiple() on the connected input pin. Also, it - // cannot be blocked if the streaming thread is calling DynamicReconnect(), - // ChangeMediaType() or ChangeOutputFormat(). - if(!StreamingThreadUsingOutputPin()) { - - // The output pin can be immediately blocked. - BlockOutputPin(); - } - - return S_OK; -} - -void CDynamicOutputPin::BlockOutputPin(void) -{ - // The caller should always hold the m_BlockStateLock because this function - // uses m_BlockState and m_hNotifyCallerPinBlockedEvent. - ASSERT(CritCheckIn(&m_BlockStateLock)); - - // This function should not be called if the streaming thread is modifying - // the connection state or it's passing data downstream. - ASSERT(!StreamingThreadUsingOutputPin()); - - // This should not fail because we successfully created the event - // and we have the security permissions to change it's state. - EXECUTE_ASSERT(::ResetEvent(m_hUnblockOutputPinEvent)); - - // This event should not fail because AsynchronousBlockOutputPin() successfully - // duplicated this handle and we have the appropriate security permissions. - EXECUTE_ASSERT(::SetEvent(m_hNotifyCallerPinBlockedEvent)); - EXECUTE_ASSERT(::CloseHandle(m_hNotifyCallerPinBlockedEvent)); - - m_BlockState = BLOCKED; - m_hNotifyCallerPinBlockedEvent = NULL; -} - -HRESULT CDynamicOutputPin::UnblockOutputPin(void) -{ - // UnblockOutputPin() holds the m_BlockStateLock because it - // uses m_BlockState, m_dwBlockCallerThreadID and - // m_hNotifyCallerPinBlockedEvent. - CAutoLock alBlockStateLock(&m_BlockStateLock); - - if(NOT_BLOCKED == m_BlockState) { - return S_FALSE; - } - - // This should not fail because we successfully created the event - // and we have the security permissions to change it's state. - EXECUTE_ASSERT(::SetEvent(m_hUnblockOutputPinEvent)); - - // Cancel the block operation if it's still pending. - if(NULL != m_hNotifyCallerPinBlockedEvent) { - // This event should not fail because AsynchronousBlockOutputPin() successfully - // duplicated this handle and we have the appropriate security permissions. - EXECUTE_ASSERT(::SetEvent(m_hNotifyCallerPinBlockedEvent)); - EXECUTE_ASSERT(::CloseHandle(m_hNotifyCallerPinBlockedEvent)); - } - - m_BlockState = NOT_BLOCKED; - m_dwBlockCallerThreadID = 0; - m_hNotifyCallerPinBlockedEvent = NULL; - - return S_OK; -} - -HRESULT CDynamicOutputPin::StartUsingOutputPin(void) -{ - // The caller should not hold m_BlockStateLock. If the caller does, - // a deadlock could occur. - ASSERT(CritCheckOut(&m_BlockStateLock)); - - CAutoLock alBlockStateLock(&m_BlockStateLock); - - #ifdef DEBUG - AssertValid(); - #endif // DEBUG - - // Are we in the middle of a block operation? - while(BLOCKED == m_BlockState) { - m_BlockStateLock.Unlock(); - - // If this ASSERT fires, a deadlock could occur. The caller should make sure - // that this thread never acquires the Block State lock more than once. - ASSERT(CritCheckOut( &m_BlockStateLock )); - - // WaitForMultipleObjects() returns WAIT_OBJECT_0 if the unblock event - // is fired. It returns WAIT_OBJECT_0 + 1 if the stop event if fired. - // See the Windows SDK documentation for more information on - // WaitForMultipleObjects(). - const DWORD UNBLOCK = WAIT_OBJECT_0; - const DWORD STOP = WAIT_OBJECT_0 + 1; - - HANDLE ahWaitEvents[] = { m_hUnblockOutputPinEvent, m_hStopEvent }; - DWORD dwNumWaitEvents = sizeof(ahWaitEvents)/sizeof(HANDLE); - - DWORD dwReturnValue = ::WaitForMultipleObjects( dwNumWaitEvents, ahWaitEvents, FALSE, INFINITE ); - - m_BlockStateLock.Lock(); - - #ifdef DEBUG - AssertValid(); - #endif // DEBUG - - switch( dwReturnValue ) { - case UNBLOCK: - break; - - case STOP: - return VFW_E_STATE_CHANGED; - - case WAIT_FAILED: - return AmGetLastErrorToHResult(); - - default: - DbgBreak( "An Unexpected case occured in CDynamicOutputPin::StartUsingOutputPin()." ); - return E_UNEXPECTED; - } - } - - m_dwNumOutstandingOutputPinUsers++; - - #ifdef DEBUG - AssertValid(); - #endif // DEBUG - - return S_OK; -} - -void CDynamicOutputPin::StopUsingOutputPin(void) -{ - CAutoLock alBlockStateLock(&m_BlockStateLock); - - #ifdef DEBUG - AssertValid(); - #endif // DEBUG - - m_dwNumOutstandingOutputPinUsers--; - - if((m_dwNumOutstandingOutputPinUsers == 0) && (NOT_BLOCKED != m_BlockState)) { - BlockOutputPin(); - } - - #ifdef DEBUG - AssertValid(); - #endif // DEBUG -} - -bool CDynamicOutputPin::StreamingThreadUsingOutputPin(void) -{ - CAutoLock alBlockStateLock(&m_BlockStateLock); - - return (m_dwNumOutstandingOutputPinUsers > 0); -} - -void CDynamicOutputPin::SetConfigInfo(IGraphConfig *pGraphConfig, HANDLE hStopEvent) -{ - // This pointer is not addrefed because filters are not allowed to - // hold references to the filter graph manager. See the documentation for - // IBaseFilter::JoinFilterGraph() in the Direct Show SDK for more information. - m_pGraphConfig = pGraphConfig; - - m_hStopEvent = hStopEvent; -} - -HRESULT CDynamicOutputPin::Active(void) -{ - // Make sure the user initialized the object by calling SetConfigInfo(). - if((NULL == m_hStopEvent) || (NULL == m_pGraphConfig)) { - DbgBreak( ERROR: CDynamicOutputPin::Active() failed because m_pGraphConfig and m_hStopEvent were not initialized. Call SetConfigInfo() to initialize them. ); - return E_FAIL; - } - - // If this ASSERT fires, the user may have passed an invalid event handle to SetConfigInfo(). - // The ASSERT can also fire if the event if destroyed and then Active() is called. An event - // handle is invalid if 1) the event does not exist or the user does not have the security - // permissions to use the event. - EXECUTE_ASSERT(ResetEvent(m_hStopEvent)); - - return CBaseOutputPin::Active(); -} - -HRESULT CDynamicOutputPin::Inactive(void) -{ - // If this ASSERT fires, the user may have passed an invalid event handle to SetConfigInfo(). - // The ASSERT can also fire if the event if destroyed and then Active() is called. An event - // handle is invalid if 1) the event does not exist or the user does not have the security - // permissions to use the event. - EXECUTE_ASSERT(SetEvent(m_hStopEvent)); - - return CBaseOutputPin::Inactive(); -} - -HRESULT CDynamicOutputPin::DeliverBeginFlush(void) -{ - // If this ASSERT fires, the user may have passed an invalid event handle to SetConfigInfo(). - // The ASSERT can also fire if the event if destroyed and then DeliverBeginFlush() is called. - // An event handle is invalid if 1) the event does not exist or the user does not have the security - // permissions to use the event. - EXECUTE_ASSERT(SetEvent(m_hStopEvent)); - - return CBaseOutputPin::DeliverBeginFlush(); -} - -HRESULT CDynamicOutputPin::DeliverEndFlush(void) -{ - // If this ASSERT fires, the user may have passed an invalid event handle to SetConfigInfo(). - // The ASSERT can also fire if the event if destroyed and then DeliverBeginFlush() is called. - // An event handle is invalid if 1) the event does not exist or the user does not have the security - // permissions to use the event. - EXECUTE_ASSERT(ResetEvent(m_hStopEvent)); - - return CBaseOutputPin::DeliverEndFlush(); -} - - -// ChangeOutputFormat() either dynamicly changes the connection's format type or it dynamicly -// reconnects the output pin. -HRESULT CDynamicOutputPin::ChangeOutputFormat - ( - const AM_MEDIA_TYPE *pmt, - REFERENCE_TIME tSegmentStart, - REFERENCE_TIME tSegmentStop, - double dSegmentRate - ) -{ - // The caller should call StartUsingOutputPin() before calling this - // method. - ASSERT(StreamingThreadUsingOutputPin()); - - // Callers should always pass a valid media type to ChangeOutputFormat() . - ASSERT(NULL != pmt); - - CMediaType cmt(*pmt); - HRESULT hr = ChangeMediaType(&cmt); - if (FAILED(hr)) { - return hr; - } - - hr = DeliverNewSegment(tSegmentStart, tSegmentStop, dSegmentRate); - if( FAILED( hr ) ) { - return hr; - } - - return S_OK; -} - -HRESULT CDynamicOutputPin::ChangeMediaType(const CMediaType *pmt) -{ - // The caller should call StartUsingOutputPin() before calling this - // method. - ASSERT(StreamingThreadUsingOutputPin()); - - // This function assumes the filter graph is running. - ASSERT(!IsStopped()); - - if(!IsConnected()) { - return VFW_E_NOT_CONNECTED; - } - - /* First check if the downstream pin will accept a dynamic - format change - */ - QzCComPtr pConnection; - - m_Connected->QueryInterface(IID_IPinConnection, (void **)&pConnection); - if(pConnection != NULL) { - - if(S_OK == pConnection->DynamicQueryAccept(pmt)) { - - HRESULT hr = ChangeMediaTypeHelper(pmt); - if(FAILED(hr)) { - return hr; - } - - return S_OK; - } - } - - /* Can't do the dynamic connection */ - return DynamicReconnect(pmt); -} - -HRESULT CDynamicOutputPin::ChangeMediaTypeHelper(const CMediaType *pmt) -{ - // The caller should call StartUsingOutputPin() before calling this - // method. - ASSERT(StreamingThreadUsingOutputPin()); - - HRESULT hr = m_Connected->ReceiveConnection(this, pmt); - if(FAILED(hr)) { - return hr; - } - - hr = SetMediaType(pmt); - if(FAILED(hr)) { - return hr; - } - - // Does this pin use the local memory transport? - if(NULL != m_pInputPin) { - // This function assumes that m_pInputPin and m_Connected are - // two different interfaces to the same object. - ASSERT(::IsEqualObject(m_Connected, m_pInputPin)); - - ALLOCATOR_PROPERTIES apInputPinRequirements; - apInputPinRequirements.cbAlign = 0; - apInputPinRequirements.cbBuffer = 0; - apInputPinRequirements.cbPrefix = 0; - apInputPinRequirements.cBuffers = 0; - - m_pInputPin->GetAllocatorRequirements(&apInputPinRequirements); - - // A zero allignment does not make any sense. - if(0 == apInputPinRequirements.cbAlign) { - apInputPinRequirements.cbAlign = 1; - } - - hr = m_pAllocator->Decommit(); - if(FAILED(hr)) { - return hr; - } - - hr = DecideBufferSize(m_pAllocator, &apInputPinRequirements); - if(FAILED(hr)) { - return hr; - } - - hr = m_pAllocator->Commit(); - if(FAILED(hr)) { - return hr; - } - - hr = m_pInputPin->NotifyAllocator(m_pAllocator, m_bPinUsesReadOnlyAllocator); - if(FAILED(hr)) { - return hr; - } - } - - return S_OK; -} - -// this method has to be called from the thread that is pushing data, -// and it's the caller's responsibility to make sure that the thread -// has no outstand samples because they cannot be delivered after a -// reconnect -// -HRESULT CDynamicOutputPin::DynamicReconnect( const CMediaType* pmt ) -{ - // The caller should call StartUsingOutputPin() before calling this - // method. - ASSERT(StreamingThreadUsingOutputPin()); - - if((m_pGraphConfig == NULL) || (NULL == m_hStopEvent)) { - return E_FAIL; - } - - HRESULT hr = m_pGraphConfig->Reconnect( - this, - NULL, - pmt, - NULL, - m_hStopEvent, - AM_GRAPH_CONFIG_RECONNECT_CACHE_REMOVED_FILTERS ); - - return hr; -} - -HRESULT CDynamicOutputPin::CompleteConnect(IPin *pReceivePin) -{ - HRESULT hr = CBaseOutputPin::CompleteConnect(pReceivePin); - if(SUCCEEDED(hr)) { - if(!IsStopped() && m_pAllocator) { - hr = m_pAllocator->Commit(); - ASSERT(hr != VFW_E_ALREADY_COMMITTED); - } - } - - return hr; -} - -#ifdef DEBUG -void CDynamicOutputPin::AssertValid(void) -{ - // Make sure the object was correctly initialized. - - // This ASSERT only fires if the object failed to initialize - // and the user ignored the constructor's return code (phr). - ASSERT(NULL != m_hUnblockOutputPinEvent); - - // If either of these ASSERTs fire, the user did not correctly call - // SetConfigInfo(). - ASSERT(NULL != m_hStopEvent); - ASSERT(NULL != m_pGraphConfig); - - // Make sure the block state is consistent. - - CAutoLock alBlockStateLock(&m_BlockStateLock); - - // BLOCK_STATE variables only have three legal values: PENDING, BLOCKED and NOT_BLOCKED. - ASSERT((NOT_BLOCKED == m_BlockState) || (PENDING == m_BlockState) || (BLOCKED == m_BlockState)); - - // m_hNotifyCallerPinBlockedEvent is only needed when a block operation cannot complete - // immediately. - ASSERT(((NULL == m_hNotifyCallerPinBlockedEvent) && (PENDING != m_BlockState)) || - ((NULL != m_hNotifyCallerPinBlockedEvent) && (PENDING == m_BlockState)) ); - - // m_dwBlockCallerThreadID should always be 0 if the pin is not blocked and - // the user is not trying to block the pin. - ASSERT((0 == m_dwBlockCallerThreadID) || (NOT_BLOCKED != m_BlockState)); - - // If this ASSERT fires, the streaming thread is using the output pin and the - // output pin is blocked. - ASSERT(((0 != m_dwNumOutstandingOutputPinUsers) && (BLOCKED != m_BlockState)) || - ((0 == m_dwNumOutstandingOutputPinUsers) && (NOT_BLOCKED != m_BlockState)) || - ((0 == m_dwNumOutstandingOutputPinUsers) && (NOT_BLOCKED == m_BlockState)) ); -} -#endif // DEBUG - -HRESULT CDynamicOutputPin::WaitEvent(HANDLE hEvent) -{ - const DWORD EVENT_SIGNALED = WAIT_OBJECT_0; - - DWORD dwReturnValue = ::WaitForSingleObject(hEvent, INFINITE); - - switch( dwReturnValue ) { - case EVENT_SIGNALED: - return S_OK; - - case WAIT_FAILED: - return AmGetLastErrorToHResult(); - - default: - DbgBreak( "An Unexpected case occured in CDynamicOutputPin::WaitEvent()." ); - return E_UNEXPECTED; - } -} - -//===================================================================== -//===================================================================== -// Implements CBaseAllocator -//===================================================================== -//===================================================================== - - -/* Constructor overrides the default settings for the free list to request - that it be alertable (ie the list can be cast to a handle which can be - passed to WaitForSingleObject). Both of the allocator lists also ask for - object locking, the all list matches the object default settings but I - have included them here just so it is obvious what kind of list it is */ - -CBaseAllocator::CBaseAllocator(TCHAR *pName, - LPUNKNOWN pUnk, - HRESULT *phr, - BOOL bEvent, - BOOL fEnableReleaseCallback - ) : - CUnknown(pName, pUnk), - m_lAllocated(0), - m_bChanged(FALSE), - m_bCommitted(FALSE), - m_bDecommitInProgress(FALSE), - m_lSize(0), - m_lCount(0), - m_lAlignment(0), - m_lPrefix(0), - m_hSem(NULL), - m_lWaiting(0), - m_fEnableReleaseCallback(fEnableReleaseCallback), - m_pNotify(NULL) -{ - - if (bEvent) { - m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL); - if (m_hSem == NULL) { - *phr = E_OUTOFMEMORY; - return; - } - } -} - -#ifdef UNICODE -CBaseAllocator::CBaseAllocator(CHAR *pName, - LPUNKNOWN pUnk, - HRESULT *phr, - BOOL bEvent, - BOOL fEnableReleaseCallback) : - CUnknown(pName, pUnk), - m_lAllocated(0), - m_bChanged(FALSE), - m_bCommitted(FALSE), - m_bDecommitInProgress(FALSE), - m_lSize(0), - m_lCount(0), - m_lAlignment(0), - m_lPrefix(0), - m_hSem(NULL), - m_lWaiting(0), - m_fEnableReleaseCallback(fEnableReleaseCallback), - m_pNotify(NULL) -{ - - if (bEvent) { - m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL); - if (m_hSem == NULL) { - *phr = E_OUTOFMEMORY; - return; - } - } -} -#endif - -/* Destructor */ - -CBaseAllocator::~CBaseAllocator() -{ - // we can't call Decommit here since that would mean a call to a - // pure virtual in destructor. - // We must assume that the derived class has gone into decommit state in - // its destructor. - - ASSERT(!m_bCommitted); - if (m_hSem != NULL) { - EXECUTE_ASSERT(CloseHandle(m_hSem)); - } - if (m_pNotify) { - m_pNotify->Release(); - } -} - - -/* Override this to publicise our interfaces */ - -STDMETHODIMP -CBaseAllocator::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - /* Do we know about this interface */ - - if (riid == IID_IMemAllocator || - riid == IID_IMemAllocatorCallbackTemp && m_fEnableReleaseCallback) { - return GetInterface((IMemAllocatorCallbackTemp *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -/* This sets the size and count of the required samples. The memory isn't - actually allocated until Commit() is called, if memory has already been - allocated then assuming no samples are outstanding the user may call us - to change the buffering, the memory will be released in Commit() */ - -STDMETHODIMP -CBaseAllocator::SetProperties( - ALLOCATOR_PROPERTIES* pRequest, - ALLOCATOR_PROPERTIES* pActual) -{ - CheckPointer(pRequest, E_POINTER); - CheckPointer(pActual, E_POINTER); - ValidateReadWritePtr(pActual, sizeof(ALLOCATOR_PROPERTIES)); - CAutoLock cObjectLock(this); - - ZeroMemory(pActual, sizeof(ALLOCATOR_PROPERTIES)); - - ASSERT(pRequest->cbBuffer > 0); - - /* Check the alignment requested */ - if (pRequest->cbAlign != 1) { - DbgLog((LOG_ERROR, 2, TEXT("Alignment requested was 0x%x, not 1"), - pRequest->cbAlign)); - return VFW_E_BADALIGN; - } - - /* Can't do this if already committed, there is an argument that says we - should not reject the SetProperties call if there are buffers still - active. However this is called by the source filter, which is the same - person who is holding the samples. Therefore it is not unreasonable - for them to free all their samples before changing the requirements */ - - if (m_bCommitted) { - return VFW_E_ALREADY_COMMITTED; - } - - /* Must be no outstanding buffers */ - - if (m_lAllocated != m_lFree.GetCount()) { - return VFW_E_BUFFERS_OUTSTANDING; - } - - /* There isn't any real need to check the parameters as they - will just be rejected when the user finally calls Commit */ - - pActual->cbBuffer = m_lSize = pRequest->cbBuffer; - pActual->cBuffers = m_lCount = pRequest->cBuffers; - pActual->cbAlign = m_lAlignment = pRequest->cbAlign; - pActual->cbPrefix = m_lPrefix = pRequest->cbPrefix; - - m_bChanged = TRUE; - return NOERROR; -} - -STDMETHODIMP -CBaseAllocator::GetProperties( - ALLOCATOR_PROPERTIES * pActual) -{ - CheckPointer(pActual,E_POINTER); - ValidateReadWritePtr(pActual,sizeof(ALLOCATOR_PROPERTIES)); - - CAutoLock cObjectLock(this); - pActual->cbBuffer = m_lSize; - pActual->cBuffers = m_lCount; - pActual->cbAlign = m_lAlignment; - pActual->cbPrefix = m_lPrefix; - return NOERROR; -} - -// get container for a sample. Blocking, synchronous call to get the -// next free buffer (as represented by an IMediaSample interface). -// on return, the time etc properties will be invalid, but the buffer -// pointer and size will be correct. - -HRESULT CBaseAllocator::GetBuffer(IMediaSample **ppBuffer, - REFERENCE_TIME *pStartTime, - REFERENCE_TIME *pEndTime, - DWORD dwFlags - ) -{ - UNREFERENCED_PARAMETER(pStartTime); - UNREFERENCED_PARAMETER(pEndTime); - UNREFERENCED_PARAMETER(dwFlags); - CMediaSample *pSample; - - *ppBuffer = NULL; - for (;;) - { - { // scope for lock - CAutoLock cObjectLock(this); - - /* Check we are committed */ - if (!m_bCommitted) { - return VFW_E_NOT_COMMITTED; - } - pSample = (CMediaSample *) m_lFree.RemoveHead(); - if (pSample == NULL) { - SetWaiting(); - } - } - - /* If we didn't get a sample then wait for the list to signal */ - - if (pSample) { - break; - } - if (dwFlags & AM_GBF_NOWAIT) { - return VFW_E_TIMEOUT; - } - ASSERT(m_hSem != NULL); - WaitForSingleObject(m_hSem, INFINITE); - } - - /* Addref the buffer up to one. On release - back to zero instead of being deleted, it will requeue itself by - calling the ReleaseBuffer member function. NOTE the owner of a - media sample must always be derived from CBaseAllocator */ - - - ASSERT(pSample->m_cRef == 0); - pSample->m_cRef = 1; - *ppBuffer = pSample; - - - return NOERROR; -} - - -/* Final release of a CMediaSample will call this */ - -STDMETHODIMP -CBaseAllocator::ReleaseBuffer(IMediaSample * pSample) -{ - CheckPointer(pSample,E_POINTER); - ValidateReadPtr(pSample,sizeof(IMediaSample)); - - - - BOOL bRelease = FALSE; - { - CAutoLock cal(this); - - /* Put back on the free list */ - - m_lFree.Add((CMediaSample *)pSample); - if (m_lWaiting != 0) { - NotifySample(); - } - - // if there is a pending Decommit, then we need to complete it by - // calling Free() when the last buffer is placed on the free list - - LONG l1 = m_lFree.GetCount(); - if (m_bDecommitInProgress && (l1 == m_lAllocated)) { - Free(); - m_bDecommitInProgress = FALSE; - bRelease = TRUE; - } - } - - if (m_pNotify) { - - ASSERT(m_fEnableReleaseCallback); - - // - // Note that this is not synchronized with setting up a notification - // method. - // - m_pNotify->NotifyRelease(); - } - - /* For each buffer there is one AddRef, made in GetBuffer and released - here. This may cause the allocator and all samples to be deleted */ - - if (bRelease) { - Release(); - } - return NOERROR; -} - -STDMETHODIMP -CBaseAllocator::SetNotify( - IMemAllocatorNotifyCallbackTemp* pNotify - ) -{ - ASSERT(m_fEnableReleaseCallback); - CAutoLock lck(this); - if (pNotify) { - pNotify->AddRef(); - } - if (m_pNotify) { - m_pNotify->Release(); - } - m_pNotify = pNotify; - return S_OK; -} - -STDMETHODIMP -CBaseAllocator::GetFreeCount( - LONG* plBuffersFree - ) -{ - ASSERT(m_fEnableReleaseCallback); - CAutoLock cObjectLock(this); - *plBuffersFree = m_lCount - m_lAllocated + m_lFree.GetCount(); - return NOERROR; -} - -void -CBaseAllocator::NotifySample() -{ - if (m_lWaiting != 0) { - ASSERT(m_hSem != NULL); - ReleaseSemaphore(m_hSem, m_lWaiting, 0); - m_lWaiting = 0; - } -} - -STDMETHODIMP -CBaseAllocator::Commit() -{ - /* Check we are not decommitted */ - CAutoLock cObjectLock(this); - - // cannot need to alloc or re-alloc if we are committed - if (m_bCommitted) { - return NOERROR; - } - - /* Allow GetBuffer calls */ - - m_bCommitted = TRUE; - - // is there a pending decommit ? if so, just cancel it - if (m_bDecommitInProgress) { - m_bDecommitInProgress = FALSE; - - // don't call Alloc at this point. He cannot allow SetProperties - // between Decommit and the last free, so the buffer size cannot have - // changed. And because some of the buffers are not free yet, he - // cannot re-alloc anyway. - return NOERROR; - } - - DbgLog((LOG_MEMORY, 1, TEXT("Allocating: %ldx%ld"), m_lCount, m_lSize)); - - // actually need to allocate the samples - HRESULT hr = Alloc(); - if (FAILED(hr)) { - m_bCommitted = FALSE; - return hr; - } - AddRef(); - return NOERROR; -} - - -STDMETHODIMP -CBaseAllocator::Decommit() -{ - BOOL bRelease = FALSE; - { - /* Check we are not already decommitted */ - CAutoLock cObjectLock(this); - if (m_bCommitted == FALSE) { - if (m_bDecommitInProgress == FALSE) { - return NOERROR; - } - } - - /* No more GetBuffer calls will succeed */ - m_bCommitted = FALSE; - - // are any buffers outstanding? - if (m_lFree.GetCount() < m_lAllocated) { - // please complete the decommit when last buffer is freed - m_bDecommitInProgress = TRUE; - } else { - m_bDecommitInProgress = FALSE; - - // need to complete the decommit here as there are no - // outstanding buffers - - Free(); - bRelease = TRUE; - } - - // Tell anyone waiting that they can go now so we can - // reject their call - NotifySample(); - } - - if (bRelease) { - Release(); - } - return NOERROR; -} - - -/* Base definition of allocation which checks we are ok to go ahead and do - the full allocation. We return S_FALSE if the requirements are the same */ - -HRESULT -CBaseAllocator::Alloc(void) -{ - /* Error if he hasn't set the size yet */ - if (m_lCount <= 0 || m_lSize <= 0 || m_lAlignment <= 0) { - return VFW_E_SIZENOTSET; - } - - /* should never get here while buffers outstanding */ - ASSERT(m_lFree.GetCount() == m_lAllocated); - - /* If the requirements haven't changed then don't reallocate */ - if (m_bChanged == FALSE) { - return S_FALSE; - } - - return NOERROR; -} - -/* Implement CBaseAllocator::CSampleList::Remove(pSample) - Removes pSample from the list -*/ -void -CBaseAllocator::CSampleList::Remove(CMediaSample * pSample) -{ - CMediaSample **pSearch; - for (pSearch = &m_List; - *pSearch != NULL; - pSearch = &(CBaseAllocator::NextSample(*pSearch))) { - if (*pSearch == pSample) { - *pSearch = CBaseAllocator::NextSample(pSample); - CBaseAllocator::NextSample(pSample) = NULL; - m_nOnList--; - return; - } - } - DbgBreak("Couldn't find sample in list"); -} - -//===================================================================== -//===================================================================== -// Implements CMemAllocator -//===================================================================== -//===================================================================== - - -/* This goes in the factory template table to create new instances */ -CUnknown *CMemAllocator::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr) -{ - CUnknown *pUnkRet = new CMemAllocator(NAME("CMemAllocator"), pUnk, phr); - return pUnkRet; -} - -CMemAllocator::CMemAllocator( - TCHAR *pName, - LPUNKNOWN pUnk, - HRESULT *phr) - : CBaseAllocator(pName, pUnk, phr, TRUE, TRUE), - m_pBuffer(NULL) -{ -} - -#ifdef UNICODE -CMemAllocator::CMemAllocator( - CHAR *pName, - LPUNKNOWN pUnk, - HRESULT *phr) - : CBaseAllocator(pName, pUnk, phr, TRUE, TRUE), - m_pBuffer(NULL) -{ -} -#endif - -/* This sets the size and count of the required samples. The memory isn't - actually allocated until Commit() is called, if memory has already been - allocated then assuming no samples are outstanding the user may call us - to change the buffering, the memory will be released in Commit() */ -STDMETHODIMP -CMemAllocator::SetProperties( - ALLOCATOR_PROPERTIES* pRequest, - ALLOCATOR_PROPERTIES* pActual) -{ - CheckPointer(pActual,E_POINTER); - ValidateReadWritePtr(pActual,sizeof(ALLOCATOR_PROPERTIES)); - CAutoLock cObjectLock(this); - - ZeroMemory(pActual, sizeof(ALLOCATOR_PROPERTIES)); - - ASSERT(pRequest->cbBuffer > 0); - - SYSTEM_INFO SysInfo; - GetSystemInfo(&SysInfo); - - /* Check the alignment request is a power of 2 */ - if ((-pRequest->cbAlign & pRequest->cbAlign) != pRequest->cbAlign) { - DbgLog((LOG_ERROR, 1, TEXT("Alignment requested 0x%x not a power of 2!"), - pRequest->cbAlign)); - } - /* Check the alignment requested */ - if (pRequest->cbAlign == 0 || - (SysInfo.dwAllocationGranularity & (pRequest->cbAlign - 1)) != 0) { - DbgLog((LOG_ERROR, 1, TEXT("Invalid alignment 0x%x requested - granularity = 0x%x"), - pRequest->cbAlign, SysInfo.dwAllocationGranularity)); - return VFW_E_BADALIGN; - } - - /* Can't do this if already committed, there is an argument that says we - should not reject the SetProperties call if there are buffers still - active. However this is called by the source filter, which is the same - person who is holding the samples. Therefore it is not unreasonable - for them to free all their samples before changing the requirements */ - - if (m_bCommitted == TRUE) { - return VFW_E_ALREADY_COMMITTED; - } - - /* Must be no outstanding buffers */ - - if (m_lFree.GetCount() < m_lAllocated) { - return VFW_E_BUFFERS_OUTSTANDING; - } - - /* There isn't any real need to check the parameters as they - will just be rejected when the user finally calls Commit */ - - // round length up to alignment - remember that prefix is included in - // the alignment - LONG lSize = pRequest->cbBuffer + pRequest->cbPrefix; - LONG lRemainder = lSize % pRequest->cbAlign; - if (lRemainder != 0) { - lSize = lSize - lRemainder + pRequest->cbAlign; - } - pActual->cbBuffer = m_lSize = (lSize - pRequest->cbPrefix); - - pActual->cBuffers = m_lCount = pRequest->cBuffers; - pActual->cbAlign = m_lAlignment = pRequest->cbAlign; - pActual->cbPrefix = m_lPrefix = pRequest->cbPrefix; - - m_bChanged = TRUE; - return NOERROR; -} - -// override this to allocate our resources when Commit is called. -// -// note that our resources may be already allocated when this is called, -// since we don't free them on Decommit. We will only be called when in -// decommit state with all buffers free. -// -// object locked by caller -HRESULT -CMemAllocator::Alloc(void) -{ - CAutoLock lck(this); - - /* Check he has called SetProperties */ - HRESULT hr = CBaseAllocator::Alloc(); - if (FAILED(hr)) { - return hr; - } - - /* If the requirements haven't changed then don't reallocate */ - if (hr == S_FALSE) { - ASSERT(m_pBuffer); - return NOERROR; - } - ASSERT(hr == S_OK); // we use this fact in the loop below - - /* Free the old resources */ - if (m_pBuffer) { - ReallyFree(); - } - - /* Compute the aligned size */ - LONG lAlignedSize = m_lSize + m_lPrefix; - if (m_lAlignment > 1) { - LONG lRemainder = lAlignedSize % m_lAlignment; - if (lRemainder != 0) { - lAlignedSize += (m_lAlignment - lRemainder); - } - } - - /* Create the contiguous memory block for the samples - making sure it's properly aligned (64K should be enough!) - */ - ASSERT(lAlignedSize % m_lAlignment == 0); - - m_pBuffer = (PBYTE)VirtualAlloc(NULL, - m_lCount * lAlignedSize, - MEM_COMMIT, - PAGE_READWRITE); - - if (m_pBuffer == NULL) { - return E_OUTOFMEMORY; - } - - LPBYTE pNext = m_pBuffer; - CMediaSample *pSample; - - ASSERT(m_lAllocated == 0); - - // Create the new samples - we have allocated m_lSize bytes for each sample - // plus m_lPrefix bytes per sample as a prefix. We set the pointer to - // the memory after the prefix - so that GetPointer() will return a pointer - // to m_lSize bytes. - for (; m_lAllocated < m_lCount; m_lAllocated++, pNext += lAlignedSize) { - - - pSample = new CMediaSample( - NAME("Default memory media sample"), - this, - &hr, - pNext + m_lPrefix, // GetPointer() value - m_lSize); // not including prefix - - ASSERT(SUCCEEDED(hr)); - if (pSample == NULL) { - return E_OUTOFMEMORY; - } - - // This CANNOT fail - m_lFree.Add(pSample); - } - - m_bChanged = FALSE; - return NOERROR; -} - - -// override this to free up any resources we have allocated. -// called from the base class on Decommit when all buffers have been -// returned to the free list. -// -// caller has already locked the object. - -// in our case, we keep the memory until we are deleted, so -// we do nothing here. The memory is deleted in the destructor by -// calling ReallyFree() -void -CMemAllocator::Free(void) -{ - return; -} - - -// called from the destructor (and from Alloc if changing size/count) to -// actually free up the memory -void -CMemAllocator::ReallyFree(void) -{ - /* Should never be deleting this unless all buffers are freed */ - - ASSERT(m_lAllocated == m_lFree.GetCount()); - - /* Free up all the CMediaSamples */ - - CMediaSample *pSample; - for (;;) { - pSample = m_lFree.RemoveHead(); - if (pSample != NULL) { - delete pSample; - } else { - break; - } - } - - m_lAllocated = 0; - - // free the block of buffer memory - if (m_pBuffer) { - EXECUTE_ASSERT(VirtualFree(m_pBuffer, 0, MEM_RELEASE)); - m_pBuffer = NULL; - } -} - - -/* Destructor frees our memory resources */ - -CMemAllocator::~CMemAllocator() -{ - Decommit(); - ReallyFree(); -} - -// ------------------------------------------------------------------------ -// filter registration through IFilterMapper. used if IFilterMapper is -// not found (Quartz 1.0 install) - -STDAPI -AMovieSetupRegisterFilter( const AMOVIESETUP_FILTER * const psetupdata - , IFilterMapper * pIFM - , BOOL bRegister ) -{ - DbgLog((LOG_TRACE, 3, TEXT("= AMovieSetupRegisterFilter"))); - - // check we've got data - // - if( NULL == psetupdata ) return S_FALSE; - - - // unregister filter - // (as pins are subkeys of filter's CLSID key - // they do not need to be removed separately). - // - DbgLog((LOG_TRACE, 3, TEXT("= = unregister filter"))); - HRESULT hr = pIFM->UnregisterFilter( *(psetupdata->clsID) ); - - - if( bRegister ) - { - // register filter - // - DbgLog((LOG_TRACE, 3, TEXT("= = register filter"))); - hr = pIFM->RegisterFilter( *(psetupdata->clsID) - , psetupdata->strName - , psetupdata->dwMerit ); - if( SUCCEEDED(hr) ) - { - // all its pins - // - DbgLog((LOG_TRACE, 3, TEXT("= = register filter pins"))); - for( UINT m1=0; m1 < psetupdata->nPins; m1++ ) - { - hr = pIFM->RegisterPin( *(psetupdata->clsID) - , psetupdata->lpPin[m1].strName - , psetupdata->lpPin[m1].bRendered - , psetupdata->lpPin[m1].bOutput - , psetupdata->lpPin[m1].bZero - , psetupdata->lpPin[m1].bMany - , *(psetupdata->lpPin[m1].clsConnectsToFilter) - , psetupdata->lpPin[m1].strConnectsToPin ); - - if( SUCCEEDED(hr) ) - { - // and each pin's media types - // - DbgLog((LOG_TRACE, 3, TEXT("= = register filter pin types"))); - for( UINT m2=0; m2 < psetupdata->lpPin[m1].nMediaTypes; m2++ ) - { - hr = pIFM->RegisterPinType( *(psetupdata->clsID) - , psetupdata->lpPin[m1].strName - , *(psetupdata->lpPin[m1].lpMediaType[m2].clsMajorType) - , *(psetupdata->lpPin[m1].lpMediaType[m2].clsMinorType) ); - if( FAILED(hr) ) break; - } - if( FAILED(hr) ) break; - } - if( FAILED(hr) ) break; - } - } - } - - // handle one acceptable "error" - that - // of filter not being registered! - // (couldn't find a suitable #define'd - // name for the error!) - // - if( 0x80070002 == hr) - return NOERROR; - else - return hr; -} - -// Remove warnings about unreferenced inline functions -#pragma warning(disable:4514) - diff --git a/src/BaseClasses/amfilter.h b/src/BaseClasses/amfilter.h deleted file mode 100644 index 5d0f224d90..0000000000 --- a/src/BaseClasses/amfilter.h +++ /dev/null @@ -1,1589 +0,0 @@ -//------------------------------------------------------------------------------ -// File: AMFilter.h -// -// Desc: DirectShow base classes - efines class hierarchy for streams -// architecture. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __FILTER__ -#define __FILTER__ - -/* The following classes are declared in this header: */ - -class CBaseMediaFilter; // IMediaFilter support -class CBaseFilter; // IBaseFilter,IMediaFilter support -class CBasePin; // Abstract base class for IPin interface -class CEnumPins; // Enumerate input and output pins -class CEnumMediaTypes; // Enumerate the pin's preferred formats -class CBaseOutputPin; // Adds data provider member functions -class CBaseInputPin; // Implements IMemInputPin interface -class CMediaSample; // Basic transport unit for IMemInputPin -class CBaseAllocator; // General list guff for most allocators -class CMemAllocator; // Implements memory buffer allocation - - -//===================================================================== -//===================================================================== -// -// QueryFilterInfo and QueryPinInfo AddRef the interface pointers -// they return. You can use the macro below to release the interface. -// -//===================================================================== -//===================================================================== - -#define QueryFilterInfoReleaseGraph(fi) if ((fi).pGraph) (fi).pGraph->Release(); - -#define QueryPinInfoReleaseFilter(pi) if ((pi).pFilter) (pi).pFilter->Release(); - -//===================================================================== -//===================================================================== -// Defines CBaseMediaFilter -// -// Abstract base class implementing IMediaFilter. -// -// Typically you will derive your filter from CBaseFilter rather than -// this, unless you are implementing an object such as a plug-in -// distributor that needs to support IMediaFilter but not IBaseFilter. -// -// Note that IMediaFilter is derived from IPersist to allow query of -// class id. -//===================================================================== -//===================================================================== - -class AM_NOVTABLE CBaseMediaFilter : public CUnknown, - public IMediaFilter -{ - -protected: - - FILTER_STATE m_State; // current state: running, paused - IReferenceClock *m_pClock; // this filter's reference clock - // note: all filters in a filter graph use the same clock - - // offset from stream time to reference time - CRefTime m_tStart; - - CLSID m_clsid; // This filters clsid - // used for serialization - CCritSec *m_pLock; // Object we use for locking - -public: - - CBaseMediaFilter( - const TCHAR *pName, - LPUNKNOWN pUnk, - CCritSec *pLock, - REFCLSID clsid); - - virtual ~CBaseMediaFilter(); - - DECLARE_IUNKNOWN - - // override this to say what interfaces we support where - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv); - - // - // --- IPersist method --- - // - - STDMETHODIMP GetClassID(CLSID *pClsID); - - // --- IMediaFilter methods --- - - STDMETHODIMP GetState(DWORD dwMSecs, FILTER_STATE *State); - - STDMETHODIMP SetSyncSource(IReferenceClock *pClock); - - STDMETHODIMP GetSyncSource(IReferenceClock **pClock); - - // default implementation of Stop and Pause just record the - // state. Override to activate or de-activate your filter. - // Note that Run when called from Stopped state will call Pause - // to ensure activation, so if you are a source or transform - // you will probably not need to override Run. - STDMETHODIMP Stop(); - STDMETHODIMP Pause(); - - - // the start parameter is the difference to be added to the - // sample's stream time to get the reference time for - // its presentation - STDMETHODIMP Run(REFERENCE_TIME tStart); - - // --- helper methods --- - - // return the current stream time - ie find out what - // stream time should be appearing now - virtual HRESULT StreamTime(CRefTime& rtStream); - - // Is the filter currently active? (running or paused) - BOOL IsActive() { - CAutoLock cObjectLock(m_pLock); - return ((m_State == State_Paused) || (m_State == State_Running)); - }; -}; - -//===================================================================== -//===================================================================== -// Defines CBaseFilter -// -// An abstract class providing basic IBaseFilter support for pin -// enumeration and filter information reading. -// -// We cannot derive from CBaseMediaFilter since methods in IMediaFilter -// are also in IBaseFilter and would be ambiguous. Since much of the code -// assumes that they derive from a class that has m_State and other state -// directly available, we duplicate code from CBaseMediaFilter rather than -// having a member variable. -// -// Derive your filter from this, or from a derived object such as -// CTransformFilter. -//===================================================================== -//===================================================================== - - -class AM_NOVTABLE CBaseFilter : public CUnknown, // Handles an IUnknown - public IBaseFilter, // The Filter Interface - public IAMovieSetup // For un/registration -{ - -friend class CBasePin; - -protected: - FILTER_STATE m_State; // current state: running, paused - IReferenceClock *m_pClock; // this graph's ref clock - CRefTime m_tStart; // offset from stream time to reference time - CLSID m_clsid; // This filters clsid - // used for serialization - CCritSec *m_pLock; // Object we use for locking - - WCHAR *m_pName; // Full filter name - IFilterGraph *m_pGraph; // Graph we belong to - IMediaEventSink *m_pSink; // Called with notify events - LONG m_PinVersion; // Current pin version - -public: - - CBaseFilter( - const TCHAR *pName, // Object description - LPUNKNOWN pUnk, // IUnknown of delegating object - CCritSec *pLock, // Object who maintains lock - REFCLSID clsid); // The clsid to be used to serialize this filter - - CBaseFilter( - TCHAR *pName, // Object description - LPUNKNOWN pUnk, // IUnknown of delegating object - CCritSec *pLock, // Object who maintains lock - REFCLSID clsid, // The clsid to be used to serialize this filter - HRESULT *phr); // General OLE return code -#ifdef UNICODE - CBaseFilter( - const CHAR *pName, // Object description - LPUNKNOWN pUnk, // IUnknown of delegating object - CCritSec *pLock, // Object who maintains lock - REFCLSID clsid); // The clsid to be used to serialize this filter - - CBaseFilter( - CHAR *pName, // Object description - LPUNKNOWN pUnk, // IUnknown of delegating object - CCritSec *pLock, // Object who maintains lock - REFCLSID clsid, // The clsid to be used to serialize this filter - HRESULT *phr); // General OLE return code -#endif - ~CBaseFilter(); - - DECLARE_IUNKNOWN - - // override this to say what interfaces we support where - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv); -#ifdef DEBUG - STDMETHODIMP_(ULONG) NonDelegatingRelease(); -#endif - - // - // --- IPersist method --- - // - - STDMETHODIMP GetClassID(CLSID *pClsID); - - // --- IMediaFilter methods --- - - STDMETHODIMP GetState(DWORD dwMSecs, FILTER_STATE *State); - - STDMETHODIMP SetSyncSource(IReferenceClock *pClock); - - STDMETHODIMP GetSyncSource(IReferenceClock **pClock); - - - // override Stop and Pause so we can activate the pins. - // Note that Run will call Pause first if activation needed. - // Override these if you want to activate your filter rather than - // your pins. - STDMETHODIMP Stop(); - STDMETHODIMP Pause(); - - // the start parameter is the difference to be added to the - // sample's stream time to get the reference time for - // its presentation - STDMETHODIMP Run(REFERENCE_TIME tStart); - - // --- helper methods --- - - // return the current stream time - ie find out what - // stream time should be appearing now - virtual HRESULT StreamTime(CRefTime& rtStream); - - // Is the filter currently active? - BOOL IsActive() { - CAutoLock cObjectLock(m_pLock); - return ((m_State == State_Paused) || (m_State == State_Running)); - }; - - // Is this filter stopped (without locking) - BOOL IsStopped() { - return (m_State == State_Stopped); - }; - - // - // --- IBaseFilter methods --- - // - - // pin enumerator - STDMETHODIMP EnumPins( - IEnumPins ** ppEnum); - - - // default behaviour of FindPin assumes pin ids are their names - STDMETHODIMP FindPin( - LPCWSTR Id, - IPin ** ppPin - ); - - STDMETHODIMP QueryFilterInfo( - FILTER_INFO * pInfo); - - STDMETHODIMP JoinFilterGraph( - IFilterGraph * pGraph, - LPCWSTR pName); - - // return a Vendor information string. Optional - may return E_NOTIMPL. - // memory returned should be freed using CoTaskMemFree - // default implementation returns E_NOTIMPL - STDMETHODIMP QueryVendorInfo( - LPWSTR* pVendorInfo - ); - - // --- helper methods --- - - // send an event notification to the filter graph if we know about it. - // returns S_OK if delivered, S_FALSE if the filter graph does not sink - // events, or an error otherwise. - HRESULT NotifyEvent( - long EventCode, - LONG_PTR EventParam1, - LONG_PTR EventParam2); - - // return the filter graph we belong to - IFilterGraph *GetFilterGraph() { - return m_pGraph; - } - - // Request reconnect - // pPin is the pin to reconnect - // pmt is the type to reconnect with - can be NULL - // Calls ReconnectEx on the filter graph - HRESULT ReconnectPin(IPin *pPin, AM_MEDIA_TYPE const *pmt); - - // find out the current pin version (used by enumerators) - virtual LONG GetPinVersion(); - void IncrementPinVersion(); - - // you need to supply these to access the pins from the enumerator - // and for default Stop and Pause/Run activation. - virtual int GetPinCount() PURE; - virtual CBasePin *GetPin(int n) PURE; - - // --- IAMovieSetup methods --- - - STDMETHODIMP Register(); // ask filter to register itself - STDMETHODIMP Unregister(); // and unregister itself - - // --- setup helper methods --- - // (override to return filters setup data) - - virtual LPAMOVIESETUP_FILTER GetSetupData(){ return NULL; } - -}; - - -//===================================================================== -//===================================================================== -// Defines CBasePin -// -// Abstract class that supports the basics of IPin -//===================================================================== -//===================================================================== - -class AM_NOVTABLE CBasePin : public CUnknown, public IPin, public IQualityControl -{ - -protected: - - WCHAR * m_pName; // This pin's name - IPin *m_Connected; // Pin we have connected to - PIN_DIRECTION m_dir; // Direction of this pin - CCritSec *m_pLock; // Object we use for locking - bool m_bRunTimeError; // Run time error generated - bool m_bCanReconnectWhenActive; // OK to reconnect when active - bool m_bTryMyTypesFirst; // When connecting enumerate - // this pin's types first - CBaseFilter *m_pFilter; // Filter we were created by - IQualityControl *m_pQSink; // Target for Quality messages - LONG m_TypeVersion; // Holds current type version - CMediaType m_mt; // Media type of connection - - CRefTime m_tStart; // time from NewSegment call - CRefTime m_tStop; // time from NewSegment - double m_dRate; // rate from NewSegment - -#ifdef DEBUG - LONG m_cRef; // Ref count tracing -#endif - - // displays pin connection information - -#ifdef DEBUG - void DisplayPinInfo(IPin *pReceivePin); - void DisplayTypeInfo(IPin *pPin, const CMediaType *pmt); -#else - void DisplayPinInfo(IPin *pReceivePin) {}; - void DisplayTypeInfo(IPin *pPin, const CMediaType *pmt) {}; -#endif - - // used to agree a media type for a pin connection - - // given a specific media type, attempt a connection (includes - // checking that the type is acceptable to this pin) - HRESULT - AttemptConnection( - IPin* pReceivePin, // connect to this pin - const CMediaType* pmt // using this type - ); - - // try all the media types in this enumerator - for each that - // we accept, try to connect using ReceiveConnection. - HRESULT TryMediaTypes( - IPin *pReceivePin, // connect to this pin - const CMediaType *pmt, // proposed type from Connect - IEnumMediaTypes *pEnum); // try this enumerator - - // establish a connection with a suitable mediatype. Needs to - // propose a media type if the pmt pointer is null or partially - // specified - use TryMediaTypes on both our and then the other pin's - // enumerator until we find one that works. - HRESULT AgreeMediaType( - IPin *pReceivePin, // connect to this pin - const CMediaType *pmt); // proposed type from Connect - -public: - - CBasePin( - TCHAR *pObjectName, // Object description - CBaseFilter *pFilter, // Owning filter who knows about pins - CCritSec *pLock, // Object who implements the lock - HRESULT *phr, // General OLE return code - LPCWSTR pName, // Pin name for us - PIN_DIRECTION dir); // Either PINDIR_INPUT or PINDIR_OUTPUT -#ifdef UNICODE - CBasePin( - CHAR *pObjectName, // Object description - CBaseFilter *pFilter, // Owning filter who knows about pins - CCritSec *pLock, // Object who implements the lock - HRESULT *phr, // General OLE return code - LPCWSTR pName, // Pin name for us - PIN_DIRECTION dir); // Either PINDIR_INPUT or PINDIR_OUTPUT -#endif - virtual ~CBasePin(); - - DECLARE_IUNKNOWN - - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv); - STDMETHODIMP_(ULONG) NonDelegatingRelease(); - STDMETHODIMP_(ULONG) NonDelegatingAddRef(); - - // --- IPin methods --- - - // take lead role in establishing a connection. Media type pointer - // may be null, or may point to partially-specified mediatype - // (subtype or format type may be GUID_NULL). - STDMETHODIMP Connect( - IPin * pReceivePin, - const AM_MEDIA_TYPE *pmt // optional media type - ); - - // (passive) accept a connection from another pin - STDMETHODIMP ReceiveConnection( - IPin * pConnector, // this is the initiating connecting pin - const AM_MEDIA_TYPE *pmt // this is the media type we will exchange - ); - - STDMETHODIMP Disconnect(); - - STDMETHODIMP ConnectedTo(IPin **pPin); - - STDMETHODIMP ConnectionMediaType(AM_MEDIA_TYPE *pmt); - - STDMETHODIMP QueryPinInfo( - PIN_INFO * pInfo - ); - - STDMETHODIMP QueryDirection( - PIN_DIRECTION * pPinDir - ); - - STDMETHODIMP QueryId( - LPWSTR * Id - ); - - // does the pin support this media type - STDMETHODIMP QueryAccept( - const AM_MEDIA_TYPE *pmt - ); - - // return an enumerator for this pins preferred media types - STDMETHODIMP EnumMediaTypes( - IEnumMediaTypes **ppEnum - ); - - // return an array of IPin* - the pins that this pin internally connects to - // All pins put in the array must be AddReffed (but no others) - // Errors: "Can't say" - FAIL, not enough slots - return S_FALSE - // Default: return E_NOTIMPL - // The filter graph will interpret NOT_IMPL as any input pin connects to - // all visible output pins and vice versa. - // apPin can be NULL if nPin==0 (not otherwise). - STDMETHODIMP QueryInternalConnections( - IPin* *apPin, // array of IPin* - ULONG *nPin // on input, the number of slots - // on output the number of pins - ) { return E_NOTIMPL; } - - // Called when no more data will be sent - STDMETHODIMP EndOfStream(void); - - // Begin/EndFlush still PURE - - // NewSegment notifies of the start/stop/rate applying to the data - // about to be received. Default implementation records data and - // returns S_OK. - // Override this to pass downstream. - STDMETHODIMP NewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate); - - //================================================================================ - // IQualityControl methods - //================================================================================ - - STDMETHODIMP Notify(IBaseFilter * pSender, Quality q); - - STDMETHODIMP SetSink(IQualityControl * piqc); - - // --- helper methods --- - - // Returns true if the pin is connected. false otherwise. - BOOL IsConnected(void) {return (m_Connected != NULL); }; - // Return the pin this is connected to (if any) - IPin * GetConnected() { return m_Connected; }; - - // Check if our filter is currently stopped - BOOL IsStopped() { - return (m_pFilter->m_State == State_Stopped); - }; - - // find out the current type version (used by enumerators) - virtual LONG GetMediaTypeVersion(); - void IncrementTypeVersion(); - - // switch the pin to active (paused or running) mode - // not an error to call this if already active - virtual HRESULT Active(void); - - // switch the pin to inactive state - may already be inactive - virtual HRESULT Inactive(void); - - // Notify of Run() from filter - virtual HRESULT Run(REFERENCE_TIME tStart); - - // check if the pin can support this specific proposed type and format - virtual HRESULT CheckMediaType(const CMediaType *) PURE; - - // set the connection to use this format (previously agreed) - virtual HRESULT SetMediaType(const CMediaType *); - - // check that the connection is ok before verifying it - // can be overridden eg to check what interfaces will be supported. - virtual HRESULT CheckConnect(IPin *); - - // Set and release resources required for a connection - virtual HRESULT BreakConnect(); - virtual HRESULT CompleteConnect(IPin *pReceivePin); - - // returns the preferred formats for a pin - virtual HRESULT GetMediaType(int iPosition,CMediaType *pMediaType); - - // access to NewSegment values - REFERENCE_TIME CurrentStopTime() { - return m_tStop; - } - REFERENCE_TIME CurrentStartTime() { - return m_tStart; - } - double CurrentRate() { - return m_dRate; - } - - // Access name - LPWSTR Name() { return m_pName; }; - - // Can reconnectwhen active? - void SetReconnectWhenActive(bool bCanReconnect) - { - m_bCanReconnectWhenActive = bCanReconnect; - } - - bool CanReconnectWhenActive() - { - return m_bCanReconnectWhenActive; - } - -protected: - STDMETHODIMP DisconnectInternal(); -}; - - -//===================================================================== -//===================================================================== -// Defines CEnumPins -// -// Pin enumerator class that works by calling CBaseFilter. This interface -// is provided by CBaseFilter::EnumPins and calls GetPinCount() and -// GetPin() to enumerate existing pins. Needs to be a separate object so -// that it can be cloned (creating an existing object at the same -// position in the enumeration) -// -//===================================================================== -//===================================================================== - -class CEnumPins : public IEnumPins // The interface we support -{ - int m_Position; // Current ordinal position - int m_PinCount; // Number of pins available - CBaseFilter *m_pFilter; // The filter who owns us - LONG m_Version; // Pin version information - LONG m_cRef; - - typedef CGenericList CPinList; - - CPinList m_PinCache; // These pointers have not been AddRef'ed and - // so they should not be dereferenced. They are - // merely kept to ID which pins have been enumerated. - -#ifdef DEBUG - DWORD m_dwCookie; -#endif - - /* If while we are retrieving a pin for example from the filter an error - occurs we assume that our internal state is stale with respect to the - filter (someone may have deleted all the pins). We can check before - starting whether or not the operation is likely to fail by asking the - filter what it's current version number is. If the filter has not - overriden the GetPinVersion method then this will always match */ - - BOOL AreWeOutOfSync() { - return (m_pFilter->GetPinVersion() == m_Version ? FALSE : TRUE); - }; - - /* This method performs the same operations as Reset, except is does not clear - the cache of pins already enumerated. */ - - STDMETHODIMP Refresh(); - -public: - - CEnumPins( - CBaseFilter *pFilter, - CEnumPins *pEnumPins); - - virtual ~CEnumPins(); - - // IUnknown - STDMETHODIMP QueryInterface(REFIID riid, void **ppv); - STDMETHODIMP_(ULONG) AddRef(); - STDMETHODIMP_(ULONG) Release(); - - // IEnumPins - STDMETHODIMP Next( - ULONG cPins, // place this many pins... - IPin ** ppPins, // ...in this array of IPin* - ULONG * pcFetched // actual count passed returned here - ); - - STDMETHODIMP Skip(ULONG cPins); - STDMETHODIMP Reset(); - STDMETHODIMP Clone(IEnumPins **ppEnum); - - -}; - - -//===================================================================== -//===================================================================== -// Defines CEnumMediaTypes -// -// Enumerates the preferred formats for input and output pins -//===================================================================== -//===================================================================== - -class CEnumMediaTypes : public IEnumMediaTypes // The interface we support -{ - int m_Position; // Current ordinal position - CBasePin *m_pPin; // The pin who owns us - LONG m_Version; // Media type version value - LONG m_cRef; -#ifdef DEBUG - DWORD m_dwCookie; -#endif - - /* The media types a filter supports can be quite dynamic so we add to - the general IEnumXXXX interface the ability to be signaled when they - change via an event handle the connected filter supplies. Until the - Reset method is called after the state changes all further calls to - the enumerator (except Reset) will return E_UNEXPECTED error code */ - - BOOL AreWeOutOfSync() { - return (m_pPin->GetMediaTypeVersion() == m_Version ? FALSE : TRUE); - }; - -public: - - CEnumMediaTypes( - CBasePin *pPin, - CEnumMediaTypes *pEnumMediaTypes); - - virtual ~CEnumMediaTypes(); - - // IUnknown - STDMETHODIMP QueryInterface(REFIID riid, void **ppv); - STDMETHODIMP_(ULONG) AddRef(); - STDMETHODIMP_(ULONG) Release(); - - // IEnumMediaTypes - STDMETHODIMP Next( - ULONG cMediaTypes, // place this many pins... - AM_MEDIA_TYPE ** ppMediaTypes, // ...in this array - ULONG * pcFetched // actual count passed - ); - - STDMETHODIMP Skip(ULONG cMediaTypes); - STDMETHODIMP Reset(); - STDMETHODIMP Clone(IEnumMediaTypes **ppEnum); -}; - - - - -//===================================================================== -//===================================================================== -// Defines CBaseOutputPin -// -// class derived from CBasePin that can pass buffers to a connected pin -// that supports IMemInputPin. Supports IPin. -// -// Derive your output pin from this. -// -//===================================================================== -//===================================================================== - -class AM_NOVTABLE CBaseOutputPin : public CBasePin -{ - -protected: - - IMemAllocator *m_pAllocator; - IMemInputPin *m_pInputPin; // interface on the downstreaminput pin - // set up in CheckConnect when we connect. - -public: - - CBaseOutputPin( - TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName); -#ifdef UNICODE - CBaseOutputPin( - CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName); -#endif - // override CompleteConnect() so we can negotiate an allocator - virtual HRESULT CompleteConnect(IPin *pReceivePin); - - // negotiate the allocator and its buffer size/count and other properties - // Calls DecideBufferSize to set properties - virtual HRESULT DecideAllocator(IMemInputPin * pPin, IMemAllocator ** pAlloc); - - // override this to set the buffer size and count. Return an error - // if the size/count is not to your liking. - // The allocator properties passed in are those requested by the - // input pin - use eg the alignment and prefix members if you have - // no preference on these. - virtual HRESULT DecideBufferSize( - IMemAllocator * pAlloc, - ALLOCATOR_PROPERTIES * ppropInputRequest - ) PURE; - - // returns an empty sample buffer from the allocator - virtual HRESULT GetDeliveryBuffer(IMediaSample ** ppSample, - REFERENCE_TIME * pStartTime, - REFERENCE_TIME * pEndTime, - DWORD dwFlags); - - // deliver a filled-in sample to the connected input pin - // note - you need to release it after calling this. The receiving - // pin will addref the sample if it needs to hold it beyond the - // call. - virtual HRESULT Deliver(IMediaSample *); - - // override this to control the connection - virtual HRESULT InitAllocator(IMemAllocator **ppAlloc); - HRESULT CheckConnect(IPin *pPin); - HRESULT BreakConnect(); - - // override to call Commit and Decommit - HRESULT Active(void); - HRESULT Inactive(void); - - // we have a default handling of EndOfStream which is to return - // an error, since this should be called on input pins only - STDMETHODIMP EndOfStream(void); - - // called from elsewhere in our filter to pass EOS downstream to - // our connected input pin - virtual HRESULT DeliverEndOfStream(void); - - // same for Begin/EndFlush - we handle Begin/EndFlush since it - // is an error on an output pin, and we have Deliver methods to - // call the methods on the connected pin - STDMETHODIMP BeginFlush(void); - STDMETHODIMP EndFlush(void); - virtual HRESULT DeliverBeginFlush(void); - virtual HRESULT DeliverEndFlush(void); - - // deliver NewSegment to connected pin - you will need to - // override this if you queue any data in your output pin. - virtual HRESULT DeliverNewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate); - - //================================================================================ - // IQualityControl methods - //================================================================================ - - // All inherited from CBasePin and not overridden here. - // STDMETHODIMP Notify(IBaseFilter * pSender, Quality q); - // STDMETHODIMP SetSink(IQualityControl * piqc); -}; - - -//===================================================================== -//===================================================================== -// Defines CBaseInputPin -// -// derive your standard input pin from this. -// you need to supply GetMediaType and CheckConnect etc (see CBasePin), -// and you need to supply Receive to do something more useful. -// -//===================================================================== -//===================================================================== - -class AM_NOVTABLE CBaseInputPin : public CBasePin, - public IMemInputPin -{ - -protected: - - IMemAllocator *m_pAllocator; // Default memory allocator - - // allocator is read-only, so received samples - // cannot be modified (probably only relevant to in-place - // transforms - BYTE m_bReadOnly; - -//private: this should really be private... only the MPEG code -// currently looks at it directly and it should use IsFlushing(). - // in flushing state (between BeginFlush and EndFlush) - // if TRUE, all Receives are returned with S_FALSE - BYTE m_bFlushing; - - // Sample properties - initalized in Receive - AM_SAMPLE2_PROPERTIES m_SampleProps; - -public: - - CBaseInputPin( - TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName); -#ifdef UNICODE - CBaseInputPin( - CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName); -#endif - virtual ~CBaseInputPin(); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - // return the allocator interface that this input pin - // would like the output pin to use - STDMETHODIMP GetAllocator(IMemAllocator ** ppAllocator); - - // tell the input pin which allocator the output pin is actually - // going to use. - STDMETHODIMP NotifyAllocator( - IMemAllocator * pAllocator, - BOOL bReadOnly); - - // do something with this media sample - STDMETHODIMP Receive(IMediaSample *pSample); - - // do something with these media samples - STDMETHODIMP ReceiveMultiple ( - IMediaSample **pSamples, - long nSamples, - long *nSamplesProcessed); - - // See if Receive() blocks - STDMETHODIMP ReceiveCanBlock(); - - // Default handling for BeginFlush - call at the beginning - // of your implementation (makes sure that all Receive calls - // fail). After calling this, you need to free any queued data - // and then call downstream. - STDMETHODIMP BeginFlush(void); - - // default handling for EndFlush - call at end of your implementation - // - before calling this, ensure that there is no queued data and no thread - // pushing any more without a further receive, then call downstream, - // then call this method to clear the m_bFlushing flag and re-enable - // receives - STDMETHODIMP EndFlush(void); - - // this method is optional (can return E_NOTIMPL). - // default implementation returns E_NOTIMPL. Override if you have - // specific alignment or prefix needs, but could use an upstream - // allocator - STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES*pProps); - - // Release the pin's allocator. - HRESULT BreakConnect(); - - // helper method to check the read-only flag - BOOL IsReadOnly() { - return m_bReadOnly; - }; - - // helper method to see if we are flushing - BOOL IsFlushing() { - return m_bFlushing; - }; - - // Override this for checking whether it's OK to process samples - // Also call this from EndOfStream. - virtual HRESULT CheckStreaming(); - - // Pass a Quality notification on to the appropriate sink - HRESULT PassNotify(Quality& q); - - - //================================================================================ - // IQualityControl methods (from CBasePin) - //================================================================================ - - STDMETHODIMP Notify(IBaseFilter * pSender, Quality q); - - // no need to override: - // STDMETHODIMP SetSink(IQualityControl * piqc); - - - // switch the pin to inactive state - may already be inactive - virtual HRESULT Inactive(void); - - // Return sample properties pointer - AM_SAMPLE2_PROPERTIES * SampleProps() { - ASSERT(m_SampleProps.cbData != 0); - return &m_SampleProps; - } - -}; - -/////////////////////////////////////////////////////////////////////////// -// CDynamicOutputPin -// - -class CDynamicOutputPin : public CBaseOutputPin, - public IPinFlowControl -{ -public: -#ifdef UNICODE - CDynamicOutputPin( - CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName); -#endif - - CDynamicOutputPin( - TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName); - - ~CDynamicOutputPin(); - - // IUnknown Methods - DECLARE_IUNKNOWN - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - // IPin Methods - STDMETHODIMP Disconnect(void); - - // IPinFlowControl Methods - STDMETHODIMP Block(DWORD dwBlockFlags, HANDLE hEvent); - - // Set graph config info - void SetConfigInfo(IGraphConfig *pGraphConfig, HANDLE hStopEvent); - - #ifdef DEBUG - virtual HRESULT Deliver(IMediaSample *pSample); - virtual HRESULT DeliverEndOfStream(void); - virtual HRESULT DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); - #endif // DEBUG - - HRESULT DeliverBeginFlush(void); - HRESULT DeliverEndFlush(void); - - HRESULT Inactive(void); - HRESULT Active(void); - virtual HRESULT CompleteConnect(IPin *pReceivePin); - - virtual HRESULT StartUsingOutputPin(void); - virtual void StopUsingOutputPin(void); - virtual bool StreamingThreadUsingOutputPin(void); - - HRESULT ChangeOutputFormat - ( - const AM_MEDIA_TYPE *pmt, - REFERENCE_TIME tSegmentStart, - REFERENCE_TIME tSegmentStop, - double dSegmentRate - ); - HRESULT ChangeMediaType(const CMediaType *pmt); - HRESULT DynamicReconnect(const CMediaType *pmt); - -protected: - HRESULT SynchronousBlockOutputPin(void); - HRESULT AsynchronousBlockOutputPin(HANDLE hNotifyCallerPinBlockedEvent); - HRESULT UnblockOutputPin(void); - - void BlockOutputPin(void); - void ResetBlockState(void); - - static HRESULT WaitEvent(HANDLE hEvent); - - enum BLOCK_STATE - { - NOT_BLOCKED, - PENDING, - BLOCKED - }; - - // This lock should be held when the following class members are - // being used: m_hNotifyCallerPinBlockedEvent, m_BlockState, - // m_dwBlockCallerThreadID and m_dwNumOutstandingOutputPinUsers. - CCritSec m_BlockStateLock; - - // This event should be signaled when the output pin is - // not blocked. This is a manual reset event. For more - // information on events, see the documentation for - // CreateEvent() in the Windows SDK. - HANDLE m_hUnblockOutputPinEvent; - - // This event will be signaled when block operation succeedes or - // when the user cancels the block operation. The block operation - // can be canceled by calling IPinFlowControl2::Block( 0, NULL ) - // while the block operation is pending. - HANDLE m_hNotifyCallerPinBlockedEvent; - - // The state of the current block operation. - BLOCK_STATE m_BlockState; - - // The ID of the thread which last called IPinFlowControl::Block(). - // For more information on thread IDs, see the documentation for - // GetCurrentThreadID() in the Windows SDK. - DWORD m_dwBlockCallerThreadID; - - // The number of times StartUsingOutputPin() has been sucessfully - // called and a corresponding call to StopUsingOutputPin() has not - // been made. When this variable is greater than 0, the streaming - // thread is calling IPin::NewSegment(), IPin::EndOfStream(), - // IMemInputPin::Receive() or IMemInputPin::ReceiveMultiple(). The - // streaming thread could also be calling: DynamicReconnect(), - // ChangeMediaType() or ChangeOutputFormat(). The output pin cannot - // be blocked while the output pin is being used. - DWORD m_dwNumOutstandingOutputPinUsers; - - // This event should be set when the IMediaFilter::Stop() is called. - // This is a manual reset event. It is also set when the output pin - // delivers a flush to the connected input pin. - HANDLE m_hStopEvent; - IGraphConfig* m_pGraphConfig; - - // TRUE if the output pin's allocator's samples are read only. - // Otherwise FALSE. For more information, see the documentation - // for IMemInputPin::NotifyAllocator(). - BOOL m_bPinUsesReadOnlyAllocator; - -private: - HRESULT Initialize(void); - HRESULT ChangeMediaTypeHelper(const CMediaType *pmt); - - #ifdef DEBUG - void AssertValid(void); - #endif // DEBUG -}; - -class CAutoUsingOutputPin -{ -public: - CAutoUsingOutputPin( CDynamicOutputPin* pOutputPin, HRESULT* phr ); - ~CAutoUsingOutputPin(); - -private: - CDynamicOutputPin* m_pOutputPin; -}; - -inline CAutoUsingOutputPin::CAutoUsingOutputPin( CDynamicOutputPin* pOutputPin, HRESULT* phr ) : - m_pOutputPin(NULL) -{ - // The caller should always pass in valid pointers. - ASSERT( NULL != pOutputPin ); - ASSERT( NULL != phr ); - - // Make sure the user initialized phr. - ASSERT( S_OK == *phr ); - - HRESULT hr = pOutputPin->StartUsingOutputPin(); - if( FAILED( hr ) ) - { - *phr = hr; - return; - } - - m_pOutputPin = pOutputPin; -} - -inline CAutoUsingOutputPin::~CAutoUsingOutputPin() -{ - if( NULL != m_pOutputPin ) - { - m_pOutputPin->StopUsingOutputPin(); - } -} - -#ifdef DEBUG - -inline HRESULT CDynamicOutputPin::Deliver(IMediaSample *pSample) -{ - // The caller should call StartUsingOutputPin() before calling this - // method. - ASSERT(StreamingThreadUsingOutputPin()); - - return CBaseOutputPin::Deliver(pSample); -} - -inline HRESULT CDynamicOutputPin::DeliverEndOfStream(void) -{ - // The caller should call StartUsingOutputPin() before calling this - // method. - ASSERT( StreamingThreadUsingOutputPin() ); - - return CBaseOutputPin::DeliverEndOfStream(); -} - -inline HRESULT CDynamicOutputPin::DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) -{ - // The caller should call StartUsingOutputPin() before calling this - // method. - ASSERT(StreamingThreadUsingOutputPin()); - - return CBaseOutputPin::DeliverNewSegment(tStart, tStop, dRate); -} - -#endif // DEBUG - -//===================================================================== -//===================================================================== -// Memory allocators -// -// the shared memory transport between pins requires the input pin -// to provide a memory allocator that can provide sample objects. A -// sample object supports the IMediaSample interface. -// -// CBaseAllocator handles the management of free and busy samples. It -// allocates CMediaSample objects. CBaseAllocator is an abstract class: -// in particular it has no method of initializing the list of free -// samples. CMemAllocator is derived from CBaseAllocator and initializes -// the list of samples using memory from the standard IMalloc interface. -// -// If you want your buffers to live in some special area of memory, -// derive your allocator object from CBaseAllocator. If you derive your -// IMemInputPin interface object from CBaseMemInputPin, you will get -// CMemAllocator-based allocation etc for free and will just need to -// supply the Receive handling, and media type / format negotiation. -//===================================================================== -//===================================================================== - - -//===================================================================== -//===================================================================== -// Defines CMediaSample -// -// an object of this class supports IMediaSample and represents a buffer -// for media data with some associated properties. Releasing it returns -// it to a freelist managed by a CBaseAllocator derived object. -//===================================================================== -//===================================================================== - -class CMediaSample : public IMediaSample2 // The interface we support -{ - -protected: - - friend class CBaseAllocator; - - /* Values for dwFlags - these are used for backward compatiblity - only now - use AM_SAMPLE_xxx - */ - enum { Sample_SyncPoint = 0x01, /* Is this a sync point */ - Sample_Preroll = 0x02, /* Is this a preroll sample */ - Sample_Discontinuity = 0x04, /* Set if start of new segment */ - Sample_TypeChanged = 0x08, /* Has the type changed */ - Sample_TimeValid = 0x10, /* Set if time is valid */ - Sample_MediaTimeValid = 0x20, /* Is the media time valid */ - Sample_TimeDiscontinuity = 0x40, /* Time discontinuity */ - Sample_StopValid = 0x100, /* Stop time valid */ - Sample_ValidFlags = 0x1FF - }; - - /* Properties, the media sample class can be a container for a format - change in which case we take a copy of a type through the SetMediaType - interface function and then return it when GetMediaType is called. As - we do no internal processing on it we leave it as a pointer */ - - DWORD m_dwFlags; /* Flags for this sample */ - /* Type specific flags are packed - into the top word - */ - DWORD m_dwTypeSpecificFlags; /* Media type specific flags */ - LPBYTE m_pBuffer; /* Pointer to the complete buffer */ - LONG m_lActual; /* Length of data in this sample */ - LONG m_cbBuffer; /* Size of the buffer */ - CBaseAllocator *m_pAllocator; /* The allocator who owns us */ - CMediaSample *m_pNext; /* Chaining in free list */ - REFERENCE_TIME m_Start; /* Start sample time */ - REFERENCE_TIME m_End; /* End sample time */ - LONGLONG m_MediaStart; /* Real media start position */ - LONG m_MediaEnd; /* A difference to get the end */ - AM_MEDIA_TYPE *m_pMediaType; /* Media type change data */ - DWORD m_dwStreamId; /* Stream id */ -public: - LONG m_cRef; /* Reference count */ - - -public: - - CMediaSample( - TCHAR *pName, - CBaseAllocator *pAllocator, - HRESULT *phr, - LPBYTE pBuffer = NULL, - LONG length = 0); -#ifdef UNICODE - CMediaSample( - CHAR *pName, - CBaseAllocator *pAllocator, - HRESULT *phr, - LPBYTE pBuffer = NULL, - LONG length = 0); -#endif - - virtual ~CMediaSample(); - - /* Note the media sample does not delegate to its owner */ - - STDMETHODIMP QueryInterface(REFIID riid, void **ppv); - STDMETHODIMP_(ULONG) AddRef(); - STDMETHODIMP_(ULONG) Release(); - - // set the buffer pointer and length. Used by allocators that - // want variable sized pointers or pointers into already-read data. - // This is only available through a CMediaSample* not an IMediaSample* - // and so cannot be changed by clients. - HRESULT SetPointer(BYTE * ptr, LONG cBytes); - - // Get me a read/write pointer to this buffer's memory. - STDMETHODIMP GetPointer(BYTE ** ppBuffer); - - STDMETHODIMP_(LONG) GetSize(void); - - // get the stream time at which this sample should start and finish. - STDMETHODIMP GetTime( - REFERENCE_TIME * pTimeStart, // put time here - REFERENCE_TIME * pTimeEnd - ); - - // Set the stream time at which this sample should start and finish. - STDMETHODIMP SetTime( - REFERENCE_TIME * pTimeStart, // put time here - REFERENCE_TIME * pTimeEnd - ); - STDMETHODIMP IsSyncPoint(void); - STDMETHODIMP SetSyncPoint(BOOL bIsSyncPoint); - STDMETHODIMP IsPreroll(void); - STDMETHODIMP SetPreroll(BOOL bIsPreroll); - - STDMETHODIMP_(LONG) GetActualDataLength(void); - STDMETHODIMP SetActualDataLength(LONG lActual); - - // these allow for limited format changes in band - - STDMETHODIMP GetMediaType(AM_MEDIA_TYPE **ppMediaType); - STDMETHODIMP SetMediaType(AM_MEDIA_TYPE *pMediaType); - - // returns S_OK if there is a discontinuity in the data (this same is - // not a continuation of the previous stream of data - // - there has been a seek). - STDMETHODIMP IsDiscontinuity(void); - // set the discontinuity property - TRUE if this sample is not a - // continuation, but a new sample after a seek. - STDMETHODIMP SetDiscontinuity(BOOL bDiscontinuity); - - // get the media times for this sample - STDMETHODIMP GetMediaTime( - LONGLONG * pTimeStart, - LONGLONG * pTimeEnd - ); - - // Set the media times for this sample - STDMETHODIMP SetMediaTime( - LONGLONG * pTimeStart, - LONGLONG * pTimeEnd - ); - - // Set and get properties (IMediaSample2) - STDMETHODIMP GetProperties( - DWORD cbProperties, - BYTE * pbProperties - ); - - STDMETHODIMP SetProperties( - DWORD cbProperties, - const BYTE * pbProperties - ); -}; - - -//===================================================================== -//===================================================================== -// Defines CBaseAllocator -// -// Abstract base class that manages a list of media samples -// -// This class provides support for getting buffers from the free list, -// including handling of commit and (asynchronous) decommit. -// -// Derive from this class and override the Alloc and Free functions to -// allocate your CMediaSample (or derived) objects and add them to the -// free list, preparing them as necessary. -//===================================================================== -//===================================================================== - -class AM_NOVTABLE CBaseAllocator : public CUnknown,// A non delegating IUnknown - public IMemAllocatorCallbackTemp, // The interface we support - public CCritSec // Provides object locking -{ - class CSampleList; - friend class CSampleList; - - /* Trick to get at protected member in CMediaSample */ - static CMediaSample * &NextSample(CMediaSample *pSample) - { - return pSample->m_pNext; - }; - - /* Mini list class for the free list */ - class CSampleList - { - public: - CSampleList() : m_List(NULL), m_nOnList(0) {}; -#ifdef DEBUG - ~CSampleList() - { - ASSERT(m_nOnList == 0); - }; -#endif - CMediaSample *Head() const { return m_List; }; - CMediaSample *Next(CMediaSample *pSample) const { return CBaseAllocator::NextSample(pSample); }; - int GetCount() const { return m_nOnList; }; - void Add(CMediaSample *pSample) - { - ASSERT(pSample != NULL); - CBaseAllocator::NextSample(pSample) = m_List; - m_List = pSample; - m_nOnList++; - }; - CMediaSample *RemoveHead() - { - CMediaSample *pSample = m_List; - if (pSample != NULL) { - m_List = CBaseAllocator::NextSample(m_List); - m_nOnList--; - } - return pSample; - }; - void Remove(CMediaSample *pSample); - - public: - CMediaSample *m_List; - int m_nOnList; - }; -protected: - - CSampleList m_lFree; // Free list - - /* Note to overriders of CBaseAllocator. - - We use a lazy signalling mechanism for waiting for samples. - This means we don't call the OS if no waits occur. - - In order to implement this: - - 1. When a new sample is added to m_lFree call NotifySample() which - calls ReleaseSemaphore on m_hSem with a count of m_lWaiting and - sets m_lWaiting to 0. - This must all be done holding the allocator's critical section. - - 2. When waiting for a sample call SetWaiting() which increments - m_lWaiting BEFORE leaving the allocator's critical section. - - 3. Actually wait by calling WaitForSingleObject(m_hSem, INFINITE) - having left the allocator's critical section. The effect of - this is to remove 1 from the semaphore's count. You MUST call - this once having incremented m_lWaiting. - - The following are then true when the critical section is not held : - (let nWaiting = number about to wait or waiting) - - (1) if (m_lFree.GetCount() != 0) then (m_lWaiting == 0) - (2) m_lWaiting + Semaphore count == nWaiting - - We would deadlock if - nWaiting != 0 && - m_lFree.GetCount() != 0 && - Semaphore count == 0 - - But from (1) if m_lFree.GetCount() != 0 then m_lWaiting == 0 so - from (2) Semaphore count == nWaiting (which is non-0) so the - deadlock can't happen. - */ - - HANDLE m_hSem; // For signalling - long m_lWaiting; // Waiting for a free element - long m_lCount; // how many buffers we have agreed to provide - long m_lAllocated; // how many buffers are currently allocated - long m_lSize; // agreed size of each buffer - long m_lAlignment; // agreed alignment - long m_lPrefix; // agreed prefix (preceeds GetPointer() value) - BOOL m_bChanged; // Have the buffer requirements changed - - // if true, we are decommitted and can't allocate memory - BOOL m_bCommitted; - // if true, the decommit has happened, but we haven't called Free yet - // as there are still outstanding buffers - BOOL m_bDecommitInProgress; - - // Notification interface - IMemAllocatorNotifyCallbackTemp *m_pNotify; - - BOOL m_fEnableReleaseCallback; - - // called to decommit the memory when the last buffer is freed - // pure virtual - need to override this - virtual void Free(void) PURE; - - // override to allocate the memory when commit called - virtual HRESULT Alloc(void); - -public: - - CBaseAllocator( - TCHAR *, LPUNKNOWN, HRESULT *, - BOOL bEvent = TRUE, BOOL fEnableReleaseCallback = FALSE); -#ifdef UNICODE - CBaseAllocator( - CHAR *, LPUNKNOWN, HRESULT *, - BOOL bEvent = TRUE, BOOL fEnableReleaseCallback = FALSE); -#endif - virtual ~CBaseAllocator(); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - STDMETHODIMP SetProperties( - ALLOCATOR_PROPERTIES* pRequest, - ALLOCATOR_PROPERTIES* pActual); - - // return the properties actually being used on this allocator - STDMETHODIMP GetProperties( - ALLOCATOR_PROPERTIES* pProps); - - // override Commit to allocate memory. We handle the GetBuffer - //state changes - STDMETHODIMP Commit(); - - // override this to handle the memory freeing. We handle any outstanding - // GetBuffer calls - STDMETHODIMP Decommit(); - - // get container for a sample. Blocking, synchronous call to get the - // next free buffer (as represented by an IMediaSample interface). - // on return, the time etc properties will be invalid, but the buffer - // pointer and size will be correct. The two time parameters are - // optional and either may be NULL, they may alternatively be set to - // the start and end times the sample will have attached to it - // bPrevFramesSkipped is not used (used only by the video renderer's - // allocator where it affects quality management in direct draw). - - STDMETHODIMP GetBuffer(IMediaSample **ppBuffer, - REFERENCE_TIME * pStartTime, - REFERENCE_TIME * pEndTime, - DWORD dwFlags); - - // final release of a CMediaSample will call this - STDMETHODIMP ReleaseBuffer(IMediaSample *pBuffer); - // obsolete:: virtual void PutOnFreeList(CMediaSample * pSample); - - STDMETHODIMP SetNotify(IMemAllocatorNotifyCallbackTemp *pNotify); - - STDMETHODIMP GetFreeCount(LONG *plBuffersFree); - - // Notify that a sample is available - void NotifySample(); - - // Notify that we're waiting for a sample - void SetWaiting() { m_lWaiting++; }; -}; - - -//===================================================================== -//===================================================================== -// Defines CMemAllocator -// -// this is an allocator based on CBaseAllocator that allocates sample -// buffers in main memory (from 'new'). You must call SetProperties -// before calling Commit. -// -// we don't free the memory when going into Decommit state. The simplest -// way to implement this without complicating CBaseAllocator is to -// have a Free() function, called to go into decommit state, that does -// nothing and a ReallyFree function called from our destructor that -// actually frees the memory. -//===================================================================== -//===================================================================== - -// Make me one from quartz.dll -STDAPI CreateMemoryAllocator(IMemAllocator **ppAllocator); - -class CMemAllocator : public CBaseAllocator -{ - -protected: - - LPBYTE m_pBuffer; // combined memory for all buffers - - // override to free the memory when decommit completes - // - we actually do nothing, and save the memory until deletion. - void Free(void); - - // called from the destructor (and from Alloc if changing size/count) to - // actually free up the memory - void ReallyFree(void); - - // overriden to allocate the memory when commit called - HRESULT Alloc(void); - -public: - /* This goes in the factory template table to create new instances */ - static CUnknown *CreateInstance(LPUNKNOWN, HRESULT *); - - STDMETHODIMP SetProperties( - ALLOCATOR_PROPERTIES* pRequest, - ALLOCATOR_PROPERTIES* pActual); - - CMemAllocator(TCHAR *, LPUNKNOWN, HRESULT *); -#ifdef UNICODE - CMemAllocator(CHAR *, LPUNKNOWN, HRESULT *); -#endif - ~CMemAllocator(); -}; - -// helper used by IAMovieSetup implementation -STDAPI -AMovieSetupRegisterFilter( const AMOVIESETUP_FILTER * const psetupdata - , IFilterMapper * pIFM - , BOOL bRegister ); - - -/////////////////////////////////////////////////////////////////////////// -// ------------------------------------------------------------------------ -// ------------------------------------------------------------------------ -// ------------------------------------------------------------------------ -// ------------------------------------------------------------------------ -/////////////////////////////////////////////////////////////////////////// - -#endif /* __FILTER__ */ - - - diff --git a/src/BaseClasses/amvideo.cpp b/src/BaseClasses/amvideo.cpp deleted file mode 100644 index 5c2755d61d..0000000000 --- a/src/BaseClasses/amvideo.cpp +++ /dev/null @@ -1,275 +0,0 @@ -//------------------------------------------------------------------------------ -// File: AMVideo.cpp -// -// Desc: DirectShow base classes - implements helper functions for -// bitmap formats. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include - -// These are bit field masks for true colour devices - -const DWORD bits555[] = {0x007C00,0x0003E0,0x00001F}; -const DWORD bits565[] = {0x00F800,0x0007E0,0x00001F}; -const DWORD bits888[] = {0xFF0000,0x00FF00,0x0000FF}; - -// This maps bitmap subtypes into a bits per pixel value and also a -// name. unicode and ansi versions are stored because we have to -// return a pointer to a static string. -const struct { - const GUID *pSubtype; - WORD BitCount; - CHAR *pName; - WCHAR *wszName; -} BitCountMap[] = { &MEDIASUBTYPE_RGB1, 1, "RGB Monochrome", L"RGB Monochrome", - &MEDIASUBTYPE_RGB4, 4, "RGB VGA", L"RGB VGA", - &MEDIASUBTYPE_RGB8, 8, "RGB 8", L"RGB 8", - &MEDIASUBTYPE_RGB565, 16, "RGB 565 (16 bit)", L"RGB 565 (16 bit)", - &MEDIASUBTYPE_RGB555, 16, "RGB 555 (16 bit)", L"RGB 555 (16 bit)", - &MEDIASUBTYPE_RGB24, 24, "RGB 24", L"RGB 24", - &MEDIASUBTYPE_RGB32, 32, "RGB 32", L"RGB 32", - &MEDIASUBTYPE_ARGB32, 32, "ARGB 32", L"ARGB 32", - &MEDIASUBTYPE_Overlay, 0, "Overlay", L"Overlay", - &GUID_NULL, 0, "UNKNOWN", L"UNKNOWN" -}; - -// Return the size of the bitmap as defined by this header - -STDAPI_(DWORD) GetBitmapSize(const BITMAPINFOHEADER *pHeader) -{ - return DIBSIZE(*pHeader); -} - - -// This is called if the header has a 16 bit colour depth and needs to work -// out the detailed type from the bit fields (either RGB 565 or RGB 555) - -STDAPI_(const GUID) GetTrueColorType(const BITMAPINFOHEADER *pbmiHeader) -{ - BITMAPINFO *pbmInfo = (BITMAPINFO *) pbmiHeader; - ASSERT(pbmiHeader->biBitCount == 16); - - // If its BI_RGB then it's RGB 555 by default - - if (pbmiHeader->biCompression == BI_RGB) { - return MEDIASUBTYPE_RGB555; - } - - // Compare the bit fields with RGB 555 - - DWORD *pMask = (DWORD *) pbmInfo->bmiColors; - if (pMask[0] == bits555[0]) { - if (pMask[1] == bits555[1]) { - if (pMask[2] == bits555[2]) { - return MEDIASUBTYPE_RGB555; - } - } - } - - // Compare the bit fields with RGB 565 - - pMask = (DWORD *) pbmInfo->bmiColors; - if (pMask[0] == bits565[0]) { - if (pMask[1] == bits565[1]) { - if (pMask[2] == bits565[2]) { - return MEDIASUBTYPE_RGB565; - } - } - } - return GUID_NULL; -} - - -// Given a BITMAPINFOHEADER structure this returns the GUID sub type that is -// used to describe it in format negotiations. For example a video codec fills -// in the format block with a VIDEOINFO structure, it also fills in the major -// type with MEDIATYPE_VIDEO and the subtype with a GUID that matches the bit -// count, for example if it is an eight bit image then MEDIASUBTYPE_RGB8 - -STDAPI_(const GUID) GetBitmapSubtype(const BITMAPINFOHEADER *pbmiHeader) -{ - ASSERT(pbmiHeader); - - // If it's not RGB then create a GUID from the compression type - - if (pbmiHeader->biCompression != BI_RGB) { - if (pbmiHeader->biCompression != BI_BITFIELDS) { - FOURCCMap FourCCMap(pbmiHeader->biCompression); - return (const GUID) FourCCMap; - } - } - - // Map the RGB DIB bit depth to a image GUID - - switch(pbmiHeader->biBitCount) { - case 1 : return MEDIASUBTYPE_RGB1; - case 4 : return MEDIASUBTYPE_RGB4; - case 8 : return MEDIASUBTYPE_RGB8; - case 16 : return GetTrueColorType(pbmiHeader); - case 24 : return MEDIASUBTYPE_RGB24; - case 32 : return MEDIASUBTYPE_RGB32; - } - return GUID_NULL; -} - - -// Given a video bitmap subtype we return the number of bits per pixel it uses -// We return a WORD bit count as thats what the BITMAPINFOHEADER uses. If the -// GUID subtype is not found in the table we return an invalid USHRT_MAX - -STDAPI_(WORD) GetBitCount(const GUID *pSubtype) -{ - ASSERT(pSubtype); - const GUID *pMediaSubtype; - INT iPosition = 0; - - // Scan the mapping list seeing if the source GUID matches any known - // bitmap subtypes, the list is terminated by a GUID_NULL entry - - while (TRUE) { - pMediaSubtype = BitCountMap[iPosition].pSubtype; - if (IsEqualGUID(*pMediaSubtype,GUID_NULL)) { - return USHRT_MAX; - } - if (IsEqualGUID(*pMediaSubtype,*pSubtype)) { - return BitCountMap[iPosition].BitCount; - } - iPosition++; - } -} - - -// Given a bitmap subtype we return a description name that can be used for -// debug purposes. In a retail build this function still returns the names -// If the subtype isn't found in the lookup table we return string UNKNOWN - -int LocateSubtype(const GUID *pSubtype) -{ - ASSERT(pSubtype); - const GUID *pMediaSubtype; - INT iPosition = 0; - - // Scan the mapping list seeing if the source GUID matches any known - // bitmap subtypes, the list is terminated by a GUID_NULL entry - - while (TRUE) { - pMediaSubtype = BitCountMap[iPosition].pSubtype; - if (IsEqualGUID(*pMediaSubtype,*pSubtype) || - IsEqualGUID(*pMediaSubtype,GUID_NULL) - ) - { - break; - } - - iPosition++; - } - - return iPosition; -} - - - -STDAPI_(WCHAR *) GetSubtypeNameW(const GUID *pSubtype) -{ - return BitCountMap[LocateSubtype(pSubtype)].wszName; -} - -STDAPI_(CHAR *) GetSubtypeNameA(const GUID *pSubtype) -{ - return BitCountMap[LocateSubtype(pSubtype)].pName; -} - -#ifndef GetSubtypeName -#error wxutil.h should have defined GetSubtypeName -#endif -#undef GetSubtypeName - -// this is here for people that linked to it directly; most people -// would use the header file that picks the A or W version. -STDAPI_(CHAR *) GetSubtypeName(const GUID *pSubtype) -{ - return GetSubtypeNameA(pSubtype); -} - - -// The mechanism for describing a bitmap format is with the BITMAPINFOHEADER -// This is really messy to deal with because it invariably has fields that -// follow it holding bit fields, palettes and the rest. This function gives -// the number of bytes required to hold a VIDEOINFO that represents it. This -// count includes the prefix information (like the rcSource rectangle) the -// BITMAPINFOHEADER field, and any other colour information on the end. -// -// WARNING If you want to copy a BITMAPINFOHEADER into a VIDEOINFO always make -// sure that you use the HEADER macro because the BITMAPINFOHEADER field isn't -// right at the start of the VIDEOINFO (there are a number of other fields), -// -// CopyMemory(HEADER(pVideoInfo),pbmi,sizeof(BITMAPINFOHEADER)); -// - -STDAPI_(LONG) GetBitmapFormatSize(const BITMAPINFOHEADER *pHeader) -{ - // Everyone has this to start with this - LONG Size = SIZE_PREHEADER + pHeader->biSize; - - ASSERT(pHeader->biSize >= sizeof(BITMAPINFOHEADER)); - - // Does this format use a palette, if the number of colours actually used - // is zero then it is set to the maximum that are allowed for that colour - // depth (an example is 256 for eight bits). Truecolour formats may also - // pass a palette with them in which case the used count is non zero - - // This would scare me. - ASSERT(pHeader->biBitCount <= iPALETTE || pHeader->biClrUsed == 0); - - if (pHeader->biBitCount <= iPALETTE || pHeader->biClrUsed) { - LONG Entries = (DWORD) 1 << pHeader->biBitCount; - if (pHeader->biClrUsed) { - Entries = pHeader->biClrUsed; - } - Size += Entries * sizeof(RGBQUAD); - } - - // Truecolour formats may have a BI_BITFIELDS specifier for compression - // type which means that room for three DWORDs should be allocated that - // specify where in each pixel the RGB colour components may be found - - if (pHeader->biCompression == BI_BITFIELDS) { - Size += SIZE_MASKS; - } - - // A BITMAPINFO for a palettised image may also contain a palette map that - // provides the information to map from a source palette to a destination - // palette during a BitBlt for example, because this information is only - // ever processed during drawing you don't normally store the palette map - // nor have any way of knowing if it is present in the data structure - - return Size; -} - - -// Returns TRUE if the VIDEOINFO contains a palette - -STDAPI_(BOOL) ContainsPalette(const VIDEOINFOHEADER *pVideoInfo) -{ - if (PALETTISED(pVideoInfo) == FALSE) { - if (pVideoInfo->bmiHeader.biClrUsed == 0) { - return FALSE; - } - } - return TRUE; -} - - -// Return a pointer to the first entry in a palette - -STDAPI_(const RGBQUAD *) GetBitmapPalette(const VIDEOINFOHEADER *pVideoInfo) -{ - if (pVideoInfo->bmiHeader.biCompression == BI_BITFIELDS) { - return TRUECOLOR(pVideoInfo)->bmiColors; - } - return COLORS(pVideoInfo); -} diff --git a/src/BaseClasses/baseclasses.dsp b/src/BaseClasses/baseclasses.dsp deleted file mode 100644 index d6d68faf00..0000000000 --- a/src/BaseClasses/baseclasses.dsp +++ /dev/null @@ -1,322 +0,0 @@ -# Microsoft Developer Studio Project File - Name="BaseClasses" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=BaseClasses - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "baseclasses.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "baseclasses.mak" CFG="BaseClasses - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "BaseClasses - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "BaseClasses - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "BaseClasses - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MD /W3 /Gi /GX /O2 /I "." /I ".." /I "..\..\..\..\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_WIN32_DCOM" /D WINVER=0x400 /Yu"streams.h" /FD /c -# SUBTRACT CPP /Fr -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" /d "WIN32" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 strmiids.lib /nologo /out:"Release\STRMBASE.lib" /nodefaultlib - -!ELSEIF "$(CFG)" == "BaseClasses - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /Gz /MD /W3 /Gi /GX /Zi /Od /I "." /I ".." /I "..\..\..\..\include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_WIN32_DCOM" /D "DEBUG" /D WINVER=0x400 /Yu"streams.h" /FD /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" /d "WIN32" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 strmiids.lib /nologo /out:"debug\strmbasd.lib" /nodefaultlib - -!ENDIF - -# Begin Target - -# Name "BaseClasses - Win32 Release" -# Name "BaseClasses - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\amextra.cpp -# End Source File -# Begin Source File - -SOURCE=.\amfilter.cpp -# End Source File -# Begin Source File - -SOURCE=.\amvideo.cpp -# End Source File -# Begin Source File - -SOURCE=.\combase.cpp -# End Source File -# Begin Source File - -SOURCE=.\cprop.cpp -# End Source File -# Begin Source File - -SOURCE=.\ctlutil.cpp -# End Source File -# Begin Source File - -SOURCE=.\ddmm.cpp -# End Source File -# Begin Source File - -SOURCE=.\dllentry.cpp -# ADD CPP /Yc"streams.h" -# End Source File -# Begin Source File - -SOURCE=.\dllsetup.cpp -# End Source File -# Begin Source File - -SOURCE=.\mtype.cpp -# End Source File -# Begin Source File - -SOURCE=.\outputq.cpp -# End Source File -# Begin Source File - -SOURCE=.\pstream.cpp -# End Source File -# Begin Source File - -SOURCE=.\pullpin.cpp -# End Source File -# Begin Source File - -SOURCE=.\refclock.cpp -# End Source File -# Begin Source File - -SOURCE=.\renbase.cpp -# End Source File -# Begin Source File - -SOURCE=.\schedule.cpp -# End Source File -# Begin Source File - -SOURCE=.\seekpt.cpp -# End Source File -# Begin Source File - -SOURCE=.\source.cpp -# End Source File -# Begin Source File - -SOURCE=.\strmctl.cpp -# End Source File -# Begin Source File - -SOURCE=.\sysclock.cpp -# End Source File -# Begin Source File - -SOURCE=.\transfrm.cpp -# End Source File -# Begin Source File - -SOURCE=.\transip.cpp -# End Source File -# Begin Source File - -SOURCE=.\videoctl.cpp -# End Source File -# Begin Source File - -SOURCE=.\vtrans.cpp -# End Source File -# Begin Source File - -SOURCE=.\winctrl.cpp -# End Source File -# Begin Source File - -SOURCE=.\winutil.cpp -# End Source File -# Begin Source File - -SOURCE=.\wxdebug.cpp -# End Source File -# Begin Source File - -SOURCE=.\wxlist.cpp -# End Source File -# Begin Source File - -SOURCE=.\wxutil.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\activex.rcv -# End Source File -# Begin Source File - -SOURCE=.\activex.ver -# End Source File -# Begin Source File - -SOURCE=.\dllsetup.h -# End Source File -# Begin Source File - -SOURCE=.\dsschedule.h -# End Source File -# Begin Source File - -SOURCE=.\fourcc.h -# End Source File -# Begin Source File - -SOURCE=.\measure.h -# End Source File -# Begin Source File - -SOURCE=.\msgthrd.h -# End Source File -# Begin Source File - -SOURCE=.\mtype.h -# End Source File -# Begin Source File - -SOURCE=.\outputq.h -# End Source File -# Begin Source File - -SOURCE=.\pstream.h -# End Source File -# Begin Source File - -SOURCE=.\pullpin.h -# End Source File -# Begin Source File - -SOURCE=.\refclock.h -# End Source File -# Begin Source File - -SOURCE=.\reftime.h -# End Source File -# Begin Source File - -SOURCE=.\renbase.h -# End Source File -# Begin Source File - -SOURCE=.\seekpt.h -# End Source File -# Begin Source File - -SOURCE=.\source.h -# End Source File -# Begin Source File - -SOURCE=.\streams.h -# End Source File -# Begin Source File - -SOURCE=.\strmctl.h -# End Source File -# Begin Source File - -SOURCE=.\sysclock.h -# End Source File -# Begin Source File - -SOURCE=.\transfrm.h -# End Source File -# Begin Source File - -SOURCE=.\transip.h -# End Source File -# Begin Source File - -SOURCE=.\videoctl.h -# End Source File -# Begin Source File - -SOURCE=.\vtrans.h -# End Source File -# Begin Source File - -SOURCE=.\winctrl.h -# End Source File -# Begin Source File - -SOURCE=.\winutil.h -# End Source File -# Begin Source File - -SOURCE=.\wxdebug.h -# End Source File -# Begin Source File - -SOURCE=.\wxlist.h -# End Source File -# Begin Source File - -SOURCE=.\wxutil.h -# End Source File -# End Group -# End Target -# End Project diff --git a/src/BaseClasses/baseclasses.dsw b/src/BaseClasses/baseclasses.dsw deleted file mode 100644 index 64700b68ab..0000000000 --- a/src/BaseClasses/baseclasses.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "BaseClasses"=.\baseclasses.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/src/BaseClasses/baseclasses.mak b/src/BaseClasses/baseclasses.mak deleted file mode 100644 index f05ee8f24a..0000000000 --- a/src/BaseClasses/baseclasses.mak +++ /dev/null @@ -1,456 +0,0 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on baseclasses.dsp -!IF "$(CFG)" == "" -CFG=BaseClasses - Win32 Debug -!MESSAGE No configuration specified. Defaulting to BaseClasses - Win32 Debug. -!ENDIF - -!IF "$(CFG)" != "BaseClasses - Win32 Release" && "$(CFG)" != "BaseClasses - Win32 Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "baseclasses.mak" CFG="BaseClasses - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "BaseClasses - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "BaseClasses - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -!IF "$(CFG)" == "BaseClasses - Win32 Release" - -OUTDIR=.\Release -INTDIR=.\Release -# Begin Custom Macros -OutDir=.\Release -# End Custom Macros - -ALL : "$(OUTDIR)\STRMBASE.lib" - - -CLEAN : - -@erase "$(INTDIR)\amextra.obj" - -@erase "$(INTDIR)\amfilter.obj" - -@erase "$(INTDIR)\amvideo.obj" - -@erase "$(INTDIR)\baseclasses.pch" - -@erase "$(INTDIR)\combase.obj" - -@erase "$(INTDIR)\cprop.obj" - -@erase "$(INTDIR)\ctlutil.obj" - -@erase "$(INTDIR)\ddmm.obj" - -@erase "$(INTDIR)\dllentry.obj" - -@erase "$(INTDIR)\dllsetup.obj" - -@erase "$(INTDIR)\mtype.obj" - -@erase "$(INTDIR)\outputq.obj" - -@erase "$(INTDIR)\pstream.obj" - -@erase "$(INTDIR)\pullpin.obj" - -@erase "$(INTDIR)\refclock.obj" - -@erase "$(INTDIR)\renbase.obj" - -@erase "$(INTDIR)\schedule.obj" - -@erase "$(INTDIR)\seekpt.obj" - -@erase "$(INTDIR)\source.obj" - -@erase "$(INTDIR)\strmctl.obj" - -@erase "$(INTDIR)\sysclock.obj" - -@erase "$(INTDIR)\transfrm.obj" - -@erase "$(INTDIR)\transip.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\videoctl.obj" - -@erase "$(INTDIR)\vtrans.obj" - -@erase "$(INTDIR)\winctrl.obj" - -@erase "$(INTDIR)\winutil.obj" - -@erase "$(INTDIR)\wxdebug.obj" - -@erase "$(INTDIR)\wxlist.obj" - -@erase "$(INTDIR)\wxutil.obj" - -@erase "$(OUTDIR)\STRMBASE.lib" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MT /W3 /Gi /GX /O2 /I "." /I "..\..\..\..\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_WIN32_DCOM" /Fp"$(INTDIR)\baseclasses.pch" /Yu"streams.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\baseclasses.bsc" -BSC32_SBRS= \ - -LIB32=link.exe -lib -LIB32_FLAGS=..\..\..\..\lib\strmiids.lib /nologo /out:"$(OUTDIR)\STRMBASE.lib" /nodefaultlib -LIB32_OBJS= \ - "$(INTDIR)\amextra.obj" \ - "$(INTDIR)\amfilter.obj" \ - "$(INTDIR)\amvideo.obj" \ - "$(INTDIR)\combase.obj" \ - "$(INTDIR)\cprop.obj" \ - "$(INTDIR)\ctlutil.obj" \ - "$(INTDIR)\ddmm.obj" \ - "$(INTDIR)\dllentry.obj" \ - "$(INTDIR)\dllsetup.obj" \ - "$(INTDIR)\mtype.obj" \ - "$(INTDIR)\outputq.obj" \ - "$(INTDIR)\pstream.obj" \ - "$(INTDIR)\pullpin.obj" \ - "$(INTDIR)\refclock.obj" \ - "$(INTDIR)\renbase.obj" \ - "$(INTDIR)\schedule.obj" \ - "$(INTDIR)\seekpt.obj" \ - "$(INTDIR)\source.obj" \ - "$(INTDIR)\strmctl.obj" \ - "$(INTDIR)\sysclock.obj" \ - "$(INTDIR)\transfrm.obj" \ - "$(INTDIR)\transip.obj" \ - "$(INTDIR)\videoctl.obj" \ - "$(INTDIR)\vtrans.obj" \ - "$(INTDIR)\winctrl.obj" \ - "$(INTDIR)\winutil.obj" \ - "$(INTDIR)\wxdebug.obj" \ - "$(INTDIR)\wxlist.obj" \ - "$(INTDIR)\wxutil.obj" - -"$(OUTDIR)\STRMBASE.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) - $(LIB32) @<< - $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) -<< - -!ELSEIF "$(CFG)" == "BaseClasses - Win32 Debug" - -OUTDIR=.\Debug -INTDIR=.\Debug -# Begin Custom Macros -OutDir=.\Debug -# End Custom Macros - -ALL : "$(OUTDIR)\strmbasd.lib" - - -CLEAN : - -@erase "$(INTDIR)\amextra.obj" - -@erase "$(INTDIR)\amfilter.obj" - -@erase "$(INTDIR)\amvideo.obj" - -@erase "$(INTDIR)\baseclasses.pch" - -@erase "$(INTDIR)\combase.obj" - -@erase "$(INTDIR)\cprop.obj" - -@erase "$(INTDIR)\ctlutil.obj" - -@erase "$(INTDIR)\ddmm.obj" - -@erase "$(INTDIR)\dllentry.obj" - -@erase "$(INTDIR)\dllsetup.obj" - -@erase "$(INTDIR)\mtype.obj" - -@erase "$(INTDIR)\outputq.obj" - -@erase "$(INTDIR)\pstream.obj" - -@erase "$(INTDIR)\pullpin.obj" - -@erase "$(INTDIR)\refclock.obj" - -@erase "$(INTDIR)\renbase.obj" - -@erase "$(INTDIR)\schedule.obj" - -@erase "$(INTDIR)\seekpt.obj" - -@erase "$(INTDIR)\source.obj" - -@erase "$(INTDIR)\strmctl.obj" - -@erase "$(INTDIR)\sysclock.obj" - -@erase "$(INTDIR)\transfrm.obj" - -@erase "$(INTDIR)\transip.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(INTDIR)\vc60.pdb" - -@erase "$(INTDIR)\videoctl.obj" - -@erase "$(INTDIR)\vtrans.obj" - -@erase "$(INTDIR)\winctrl.obj" - -@erase "$(INTDIR)\winutil.obj" - -@erase "$(INTDIR)\wxdebug.obj" - -@erase "$(INTDIR)\wxlist.obj" - -@erase "$(INTDIR)\wxutil.obj" - -@erase "$(OUTDIR)\strmbasd.lib" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /Gz /MTd /W3 /Gm /Gi /GX /Zi /Od /I "." /I "..\..\..\..\include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_WIN32_DCOM" /D "DEBUG" /Fp"$(INTDIR)\baseclasses.pch" /Yu"streams.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\baseclasses.bsc" -BSC32_SBRS= \ - -LIB32=link.exe -lib -LIB32_FLAGS=..\..\..\..\lib\strmiids.lib /nologo /out:"$(OUTDIR)\strmbasd.lib" /nodefaultlib -LIB32_OBJS= \ - "$(INTDIR)\amextra.obj" \ - "$(INTDIR)\amfilter.obj" \ - "$(INTDIR)\amvideo.obj" \ - "$(INTDIR)\combase.obj" \ - "$(INTDIR)\cprop.obj" \ - "$(INTDIR)\ctlutil.obj" \ - "$(INTDIR)\ddmm.obj" \ - "$(INTDIR)\dllentry.obj" \ - "$(INTDIR)\dllsetup.obj" \ - "$(INTDIR)\mtype.obj" \ - "$(INTDIR)\outputq.obj" \ - "$(INTDIR)\pstream.obj" \ - "$(INTDIR)\pullpin.obj" \ - "$(INTDIR)\refclock.obj" \ - "$(INTDIR)\renbase.obj" \ - "$(INTDIR)\schedule.obj" \ - "$(INTDIR)\seekpt.obj" \ - "$(INTDIR)\source.obj" \ - "$(INTDIR)\strmctl.obj" \ - "$(INTDIR)\sysclock.obj" \ - "$(INTDIR)\transfrm.obj" \ - "$(INTDIR)\transip.obj" \ - "$(INTDIR)\videoctl.obj" \ - "$(INTDIR)\vtrans.obj" \ - "$(INTDIR)\winctrl.obj" \ - "$(INTDIR)\winutil.obj" \ - "$(INTDIR)\wxdebug.obj" \ - "$(INTDIR)\wxlist.obj" \ - "$(INTDIR)\wxutil.obj" - -"$(OUTDIR)\strmbasd.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) - $(LIB32) @<< - $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) -<< - -!ENDIF - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("baseclasses.dep") -!INCLUDE "baseclasses.dep" -!ELSE -!MESSAGE Warning: cannot find "baseclasses.dep" -!ENDIF -!ENDIF - - -!IF "$(CFG)" == "BaseClasses - Win32 Release" || "$(CFG)" == "BaseClasses - Win32 Debug" -SOURCE=.\amextra.cpp - -"$(INTDIR)\amextra.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\amfilter.cpp - -"$(INTDIR)\amfilter.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\amvideo.cpp - -"$(INTDIR)\amvideo.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\combase.cpp - -"$(INTDIR)\combase.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\cprop.cpp - -"$(INTDIR)\cprop.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\ctlutil.cpp - -"$(INTDIR)\ctlutil.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\ddmm.cpp - -"$(INTDIR)\ddmm.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\dllentry.cpp - -!IF "$(CFG)" == "BaseClasses - Win32 Release" - -CPP_SWITCHES=/nologo /MT /W3 /Gi /GX /O2 /I "." /I "..\..\..\..\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_WIN32_DCOM" /Fp"$(INTDIR)\baseclasses.pch" /Yc"streams.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -"$(INTDIR)\dllentry.obj" "$(INTDIR)\baseclasses.pch" : $(SOURCE) "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ELSEIF "$(CFG)" == "BaseClasses - Win32 Debug" - -CPP_SWITCHES=/nologo /Gz /MTd /W3 /Gm /Gi /GX /Zi /Od /I "." /I "..\..\..\..\include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_WIN32_DCOM" /D "DEBUG" /Fp"$(INTDIR)\baseclasses.pch" /Yc"streams.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c - -"$(INTDIR)\dllentry.obj" "$(INTDIR)\baseclasses.pch" : $(SOURCE) "$(INTDIR)" - $(CPP) @<< - $(CPP_SWITCHES) $(SOURCE) -<< - - -!ENDIF - -SOURCE=.\dllsetup.cpp - -"$(INTDIR)\dllsetup.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\mtype.cpp - -"$(INTDIR)\mtype.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\outputq.cpp - -"$(INTDIR)\outputq.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\pstream.cpp - -"$(INTDIR)\pstream.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\pullpin.cpp - -"$(INTDIR)\pullpin.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\refclock.cpp - -"$(INTDIR)\refclock.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\renbase.cpp - -"$(INTDIR)\renbase.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\schedule.cpp - -"$(INTDIR)\schedule.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\seekpt.cpp - -"$(INTDIR)\seekpt.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\source.cpp - -"$(INTDIR)\source.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\strmctl.cpp - -"$(INTDIR)\strmctl.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\sysclock.cpp - -"$(INTDIR)\sysclock.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\transfrm.cpp - -"$(INTDIR)\transfrm.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\transip.cpp - -"$(INTDIR)\transip.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\videoctl.cpp - -"$(INTDIR)\videoctl.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\vtrans.cpp - -"$(INTDIR)\vtrans.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\winctrl.cpp - -"$(INTDIR)\winctrl.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\winutil.cpp - -"$(INTDIR)\winutil.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\wxdebug.cpp - -"$(INTDIR)\wxdebug.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\wxlist.cpp - -"$(INTDIR)\wxlist.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - -SOURCE=.\wxutil.cpp - -"$(INTDIR)\wxutil.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\baseclasses.pch" - - - -!ENDIF - diff --git a/src/BaseClasses/cache.h b/src/BaseClasses/cache.h deleted file mode 100644 index 404207b06d..0000000000 --- a/src/BaseClasses/cache.h +++ /dev/null @@ -1,74 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Cache.h -// -// Desc: DirectShow base classes - efines a non-MFC generic cache class. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -/* This class implements a simple cache. A cache object is instantiated - with the number of items it is to hold. An item is a pointer to an - object derived from CBaseObject (helps reduce memory leaks). The cache - can then have objects added to it and removed from it. The cache size - is fixed at construction time and may therefore run out or be flooded. - If it runs out it returns a NULL pointer, if it fills up it also returns - a NULL pointer instead of a pointer to the object just inserted */ - -/* Making these classes inherit from CBaseObject does nothing for their - functionality but it allows us to check there are no memory leaks */ - -/* WARNING Be very careful when using this class, what it lets you do is - store and retrieve objects so that you can minimise object creation - which in turns improves efficiency. However the object you store is - exactly the same as the object you get back which means that it short - circuits the constructor initialisation phase. This means any class - variables the object has (eg pointers) are highly likely to be invalid. - Therefore ensure you reinitialise the object before using it again */ - - -#ifndef __CACHE__ -#define __CACHE__ - - -class CCache : CBaseObject { - - /* Make copy constructor and assignment operator inaccessible */ - - CCache(const CCache &refCache); - CCache &operator=(const CCache &refCache); - -private: - - /* These are initialised in the constructor. The first variable points to - an array of pointers, each of which points to a CBaseObject derived - object. The m_iCacheSize is the static fixed size for the cache and the - m_iUsed defines the number of places filled with objects at any time. - We fill the array of pointers from the start (ie m_ppObjects[0] first) - and then only add and remove objects from the end position, so in this - respect the array of object pointers should be treated as a stack */ - - CBaseObject **m_ppObjects; - const INT m_iCacheSize; - INT m_iUsed; - -public: - - CCache(TCHAR *pName,INT iItems); - virtual ~CCache(); - - /* Add an item to the cache */ - CBaseObject *AddToCache(CBaseObject *pObject); - - /* Remove an item from the cache */ - CBaseObject *RemoveFromCache(); - - /* Delete all the objects held in the cache */ - void RemoveAll(void); - - /* Return the cache size which is set during construction */ - INT GetCacheSize(void) const {return m_iCacheSize;}; -}; - -#endif /* __CACHE__ */ - diff --git a/src/BaseClasses/combase.cpp b/src/BaseClasses/combase.cpp deleted file mode 100644 index 536faf28f7..0000000000 --- a/src/BaseClasses/combase.cpp +++ /dev/null @@ -1,254 +0,0 @@ -//------------------------------------------------------------------------------ -// File: ComBase.cpp -// -// Desc: DirectShow base classes - implements class hierarchy for creating -// COM objects. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#pragma warning( disable : 4514 ) // Disable warnings re unused inline functions - - -/* Define the static member variable */ - -LONG CBaseObject::m_cObjects = 0; - - -/* Constructor */ - -CBaseObject::CBaseObject(const TCHAR *pName) -{ - /* Increment the number of active objects */ - InterlockedIncrement(&m_cObjects); - -#ifdef DEBUG - -#ifdef UNICODE - m_dwCookie = DbgRegisterObjectCreation(0, pName); -#else - m_dwCookie = DbgRegisterObjectCreation(pName, 0); -#endif - -#endif -} - -#ifdef UNICODE -CBaseObject::CBaseObject(const char *pName) -{ - /* Increment the number of active objects */ - InterlockedIncrement(&m_cObjects); - -#ifdef DEBUG - m_dwCookie = DbgRegisterObjectCreation(pName, 0); -#endif -} -#endif - -HINSTANCE hlibOLEAut32; - -/* Destructor */ - -CBaseObject::~CBaseObject() -{ - /* Decrement the number of objects active */ - if (InterlockedDecrement(&m_cObjects) == 0) { - if (hlibOLEAut32) { - FreeLibrary(hlibOLEAut32); - hlibOLEAut32 = 0; - } - }; - - -#ifdef DEBUG - DbgRegisterObjectDestruction(m_dwCookie); -#endif -} - -static const TCHAR szOle32Aut[] = TEXT("OleAut32.dll"); - -HINSTANCE LoadOLEAut32() -{ - if (hlibOLEAut32 == 0) { - hlibOLEAut32 = LoadLibrary(szOle32Aut); - } - - return hlibOLEAut32; -} - - -/* Constructor */ - -// We know we use "this" in the initialization list, we also know we don't modify *phr. -#pragma warning( disable : 4355 4100 ) -CUnknown::CUnknown(const TCHAR *pName, LPUNKNOWN pUnk) -: CBaseObject(pName) -/* Start the object with a reference count of zero - when the */ -/* object is queried for it's first interface this may be */ -/* incremented depending on whether or not this object is */ -/* currently being aggregated upon */ -, m_cRef(0) -/* Set our pointer to our IUnknown interface. */ -/* If we have an outer, use its, otherwise use ours. */ -/* This pointer effectivly points to the owner of */ -/* this object and can be accessed by the GetOwner() method. */ -, m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast( static_cast(this) ) ) - /* Why the double cast? Well, the inner cast is a type-safe cast */ - /* to pointer to a type from which we inherit. The second is */ - /* type-unsafe but works because INonDelegatingUnknown "behaves */ - /* like" IUnknown. (Only the names on the methods change.) */ -{ - // Everything we need to do has been done in the initializer list -} - -// This does the same as above except it has a useless HRESULT argument -// use the previous constructor, this is just left for compatibility... -CUnknown::CUnknown(TCHAR *pName, LPUNKNOWN pUnk,HRESULT *phr) : - CBaseObject(pName), - m_cRef(0), - m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast( static_cast(this) ) ) -{ -} - -#ifdef UNICODE -CUnknown::CUnknown(const CHAR *pName, LPUNKNOWN pUnk) -: CBaseObject(pName), m_cRef(0), - m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast( static_cast(this) ) ) -{ } - -CUnknown::CUnknown(CHAR *pName, LPUNKNOWN pUnk,HRESULT *phr) : - CBaseObject(pName), m_cRef(0), - m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast( static_cast(this) ) ) -{ } - -#endif - -#pragma warning( default : 4355 4100 ) - - -/* QueryInterface */ - -STDMETHODIMP CUnknown::NonDelegatingQueryInterface(REFIID riid, void ** ppv) -{ - CheckPointer(ppv,E_POINTER); - ValidateReadWritePtr(ppv,sizeof(PVOID)); - - /* We know only about IUnknown */ - - if (riid == IID_IUnknown) { - GetInterface((LPUNKNOWN) (PNDUNKNOWN) this, ppv); - return NOERROR; - } else { - *ppv = NULL; - return E_NOINTERFACE; - } -} - -/* We have to ensure that we DON'T use a max macro, since these will typically */ -/* lead to one of the parameters being evaluated twice. Since we are worried */ -/* about concurrency, we can't afford to access the m_cRef twice since we can't */ -/* afford to run the risk that its value having changed between accesses. */ - -template inline static T ourmax( const T & a, const T & b ) -{ - return a > b ? a : b; -} - -/* AddRef */ - -STDMETHODIMP_(ULONG) CUnknown::NonDelegatingAddRef() -{ - LONG lRef = InterlockedIncrement( &m_cRef ); - ASSERT(lRef > 0); - DbgLog((LOG_MEMORY,3,TEXT(" Obj %d ref++ = %d"), - m_dwCookie, m_cRef)); - return ourmax(ULONG(m_cRef), 1ul); -} - - -/* Release */ - -STDMETHODIMP_(ULONG) CUnknown::NonDelegatingRelease() -{ - /* If the reference count drops to zero delete ourselves */ - - LONG lRef = InterlockedDecrement( &m_cRef ); - ASSERT(lRef >= 0); - - DbgLog((LOG_MEMORY,3,TEXT(" Object %d ref-- = %d"), - m_dwCookie, m_cRef)); - if (lRef == 0) { - - // COM rules say we must protect against re-entrancy. - // If we are an aggregator and we hold our own interfaces - // on the aggregatee, the QI for these interfaces will - // addref ourselves. So after doing the QI we must release - // a ref count on ourselves. Then, before releasing the - // private interface, we must addref ourselves. When we do - // this from the destructor here it will result in the ref - // count going to 1 and then back to 0 causing us to - // re-enter the destructor. Hence we add an extra refcount here - // once we know we will delete the object. - // for an example aggregator see filgraph\distrib.cpp. - - m_cRef++; - - delete this; - return ULONG(0); - } else { - return ourmax(ULONG(m_cRef), 1ul); - } -} - - -/* Return an interface pointer to a requesting client - performing a thread safe AddRef as necessary */ - -STDAPI GetInterface(LPUNKNOWN pUnk, void **ppv) -{ - CheckPointer(ppv, E_POINTER); - *ppv = pUnk; - pUnk->AddRef(); - return NOERROR; -} - - -/* Compares two interfaces and returns TRUE if they are on the same object */ - -BOOL WINAPI IsEqualObject(IUnknown *pFirst, IUnknown *pSecond) -{ - /* Different objects can't have the same interface pointer for - any interface - */ - if (pFirst == pSecond) { - return TRUE; - } - /* OK - do it the hard way - check if they have the same - IUnknown pointers - a single object can only have one of these - */ - LPUNKNOWN pUnknown1; // Retrieve the IUnknown interface - LPUNKNOWN pUnknown2; // Retrieve the other IUnknown interface - HRESULT hr; // General OLE return code - - ASSERT(pFirst); - ASSERT(pSecond); - - /* See if the IUnknown pointers match */ - - hr = pFirst->QueryInterface(IID_IUnknown,(void **) &pUnknown1); - ASSERT(SUCCEEDED(hr)); - ASSERT(pUnknown1); - - hr = pSecond->QueryInterface(IID_IUnknown,(void **) &pUnknown2); - ASSERT(SUCCEEDED(hr)); - ASSERT(pUnknown2); - - /* Release the extra interfaces we hold */ - - pUnknown1->Release(); - pUnknown2->Release(); - return (pUnknown1 == pUnknown2); -} - diff --git a/src/BaseClasses/combase.h b/src/BaseClasses/combase.h deleted file mode 100644 index d6197e53f3..0000000000 --- a/src/BaseClasses/combase.h +++ /dev/null @@ -1,319 +0,0 @@ -//------------------------------------------------------------------------------ -// File: ComBase.h -// -// Desc: DirectShow base classes - defines a class hierarchy for creating -// COM objects. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -/* - -a. Derive your COM object from CUnknown - -b. Make a static CreateInstance function that takes an LPUNKNOWN, an HRESULT * - and a TCHAR *. The LPUNKNOWN defines the object to delegate IUnknown calls - to. The HRESULT * allows error codes to be passed around constructors and - the TCHAR * is a descriptive name that can be printed on the debugger. - - It is important that constructors only change the HRESULT * if they have - to set an ERROR code, if it was successful then leave it alone or you may - overwrite an error code from an object previously created. - - When you call a constructor the descriptive name should be in static store - as we do not copy the string. To stop large amounts of memory being used - in retail builds by all these static strings use the NAME macro, - - CMyFilter = new CImplFilter(NAME("My filter"),pUnknown,phr); - if (FAILED(hr)) { - return hr; - } - - In retail builds NAME(_x_) compiles to NULL, the base CBaseObject class - knows not to do anything with objects that don't have a name. - -c. Have a constructor for your object that passes the LPUNKNOWN, HRESULT * and - TCHAR * to the CUnknown constructor. You can set the HRESULT if you have an - error, or just simply pass it through to the constructor. - - The object creation will fail in the class factory if the HRESULT indicates - an error (ie FAILED(HRESULT) == TRUE) - -d. Create a FactoryTemplate with your object's class id and CreateInstance - function. - -Then (for each interface) either - -Multiple inheritance - -1. Also derive it from ISomeInterface -2. Include DECLARE_IUNKNOWN in your class definition to declare - implementations of QueryInterface, AddRef and Release that - call the outer unknown -3. Override NonDelegatingQueryInterface to expose ISomeInterface by - code something like - - if (riid == IID_ISomeInterface) { - return GetInterface((ISomeInterface *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } - -4. Declare and implement the member functions of ISomeInterface. - -or: Nested interfaces - -1. Declare a class derived from CUnknown -2. Include DECLARE_IUNKNOWN in your class definition -3. Override NonDelegatingQueryInterface to expose ISomeInterface by - code something like - - if (riid == IID_ISomeInterface) { - return GetInterface((ISomeInterface *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } - -4. Implement the member functions of ISomeInterface. Use GetOwner() to - access the COM object class. - -And in your COM object class: - -5. Make the nested class a friend of the COM object class, and declare - an instance of the nested class as a member of the COM object class. - - NOTE that because you must always pass the outer unknown and an hResult - to the CUnknown constructor you cannot use a default constructor, in - other words you will have to make the member variable a pointer to the - class and make a NEW call in your constructor to actually create it. - -6. override the NonDelegatingQueryInterface with code like this: - - if (riid == IID_ISomeInterface) { - return m_pImplFilter-> - NonDelegatingQueryInterface(IID_ISomeInterface, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } - -You can have mixed classes which support some interfaces via multiple -inheritance and some via nested classes - -*/ - -#ifndef __COMBASE__ -#define __COMBASE__ - -// Filter Setup data structures no defined in axextend.idl - -typedef REGPINTYPES -AMOVIESETUP_MEDIATYPE, * PAMOVIESETUP_MEDIATYPE, * FAR LPAMOVIESETUP_MEDIATYPE; - -typedef REGFILTERPINS -AMOVIESETUP_PIN, * PAMOVIESETUP_PIN, * FAR LPAMOVIESETUP_PIN; - -typedef struct _AMOVIESETUP_FILTER -{ - const CLSID * clsID; - const WCHAR * strName; - DWORD dwMerit; - UINT nPins; - const AMOVIESETUP_PIN * lpPin; -} -AMOVIESETUP_FILTER, * PAMOVIESETUP_FILTER, * FAR LPAMOVIESETUP_FILTER; - -/* The DLLENTRY module initialises the module handle on loading */ - -extern HINSTANCE g_hInst; - -/* On DLL load remember which platform we are running on */ - -extern DWORD g_amPlatform; -extern OSVERSIONINFO g_osInfo; // Filled in by GetVersionEx - -/* Version of IUnknown that is renamed to allow a class to support both - non delegating and delegating IUnknowns in the same COM object */ - -#ifndef INONDELEGATINGUNKNOWN_DEFINED -DECLARE_INTERFACE(INonDelegatingUnknown) -{ - STDMETHOD(NonDelegatingQueryInterface) (THIS_ REFIID, LPVOID *) PURE; - STDMETHOD_(ULONG, NonDelegatingAddRef)(THIS) PURE; - STDMETHOD_(ULONG, NonDelegatingRelease)(THIS) PURE; -}; -#define INONDELEGATINGUNKNOWN_DEFINED -#endif - -typedef INonDelegatingUnknown *PNDUNKNOWN; - - -/* This is the base object class that supports active object counting. As - part of the debug facilities we trace every time a C++ object is created - or destroyed. The name of the object has to be passed up through the class - derivation list during construction as you cannot call virtual functions - in the constructor. The downside of all this is that every single object - constructor has to take an object name parameter that describes it */ - -class CBaseObject -{ - -private: - - // Disable the copy constructor and assignment by default so you will get - // compiler errors instead of unexpected behaviour if you pass objects - // by value or assign objects. - CBaseObject(const CBaseObject& objectSrc); // no implementation - void operator=(const CBaseObject& objectSrc); // no implementation - -private: - static LONG m_cObjects; /* Total number of objects active */ - -protected: -#ifdef DEBUG - DWORD m_dwCookie; /* Cookie identifying this object */ -#endif - - -public: - - /* These increment and decrement the number of active objects */ - - CBaseObject(const TCHAR *pName); -#ifdef UNICODE - CBaseObject(const char *pName); -#endif - ~CBaseObject(); - - /* Call this to find if there are any CUnknown derived objects active */ - - static LONG ObjectsActive() { - return m_cObjects; - }; -}; - - -/* An object that supports one or more COM interfaces will be based on - this class. It supports counting of total objects for DLLCanUnloadNow - support, and an implementation of the core non delegating IUnknown */ - -class AM_NOVTABLE CUnknown : public INonDelegatingUnknown, - public CBaseObject -{ -private: - const LPUNKNOWN m_pUnknown; /* Owner of this object */ - -protected: /* So we can override NonDelegatingRelease() */ - volatile LONG m_cRef; /* Number of reference counts */ - -public: - - CUnknown(const TCHAR *pName, LPUNKNOWN pUnk); - virtual ~CUnknown() {}; - - // This is redundant, just use the other constructor - // as we never touch the HRESULT in this anyway - CUnknown(TCHAR *pName, LPUNKNOWN pUnk,HRESULT *phr); -#ifdef UNICODE - CUnknown(const char *pName, LPUNKNOWN pUnk); - CUnknown(char *pName, LPUNKNOWN pUnk,HRESULT *phr); -#endif - - /* Return the owner of this object */ - - LPUNKNOWN GetOwner() const { - return m_pUnknown; - }; - - /* Called from the class factory to create a new instance, it is - pure virtual so it must be overriden in your derived class */ - - /* static CUnknown *CreateInstance(LPUNKNOWN, HRESULT *) */ - - /* Non delegating unknown implementation */ - - STDMETHODIMP NonDelegatingQueryInterface(REFIID, void **); - STDMETHODIMP_(ULONG) NonDelegatingAddRef(); - STDMETHODIMP_(ULONG) NonDelegatingRelease(); -}; - -#if (_MSC_VER <= 1200) -#pragma warning(disable:4211) - -/* The standard InterlockedXXX functions won't take volatiles */ -static inline LONG WINAPI InterlockedIncrement( volatile LONG * plong ) -{ return InterlockedIncrement( const_cast( plong ) ); } - -static inline LONG WINAPI InterlockedDecrement( volatile LONG * plong ) -{ return InterlockedDecrement( const_cast( plong ) ); } - -#pragma warning(default:4211) -#endif - - -/* Return an interface pointer to a requesting client - performing a thread safe AddRef as necessary */ - -STDAPI GetInterface(LPUNKNOWN pUnk, void **ppv); - -/* A function that can create a new COM object */ - -typedef CUnknown *(CALLBACK *LPFNNewCOMObject)(LPUNKNOWN pUnkOuter, HRESULT *phr); - -/* A function (can be NULL) which is called from the DLL entrypoint - routine for each factory template: - - bLoading - TRUE on DLL load, FALSE on DLL unload - rclsid - the m_ClsID of the entry -*/ -typedef void (CALLBACK *LPFNInitRoutine)(BOOL bLoading, const CLSID *rclsid); - -/* Create one of these per object class in an array so that - the default class factory code can create new instances */ - -class CFactoryTemplate { - -public: - - const WCHAR * m_Name; - const CLSID * m_ClsID; - LPFNNewCOMObject m_lpfnNew; - LPFNInitRoutine m_lpfnInit; - const AMOVIESETUP_FILTER * m_pAMovieSetup_Filter; - - BOOL IsClassID(REFCLSID rclsid) const { - return (IsEqualCLSID(*m_ClsID,rclsid)); - }; - - CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr) const { - CheckPointer(phr,NULL); - return m_lpfnNew(pUnk, phr); - }; -}; - - -/* You must override the (pure virtual) NonDelegatingQueryInterface to return - interface pointers (using GetInterface) to the interfaces your derived - class supports (the default implementation only supports IUnknown) */ - -#define DECLARE_IUNKNOWN \ - STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { \ - return GetOwner()->QueryInterface(riid,ppv); \ - }; \ - STDMETHODIMP_(ULONG) AddRef() { \ - return GetOwner()->AddRef(); \ - }; \ - STDMETHODIMP_(ULONG) Release() { \ - return GetOwner()->Release(); \ - }; - - - -HINSTANCE LoadOLEAut32(); - - -#endif /* __COMBASE__ */ - - - - diff --git a/src/BaseClasses/cprop.cpp b/src/BaseClasses/cprop.cpp deleted file mode 100644 index f737890afb..0000000000 --- a/src/BaseClasses/cprop.cpp +++ /dev/null @@ -1,380 +0,0 @@ -//------------------------------------------------------------------------------ -// File: CProp.cpp -// -// Desc: DirectShow base classes - implements CBasePropertyPage class. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include - -// Constructor for the base property page class. As described in the header -// file we must be initialised with dialog and title resource identifiers. -// The class supports IPropertyPage and overrides AddRef and Release calls -// to keep track of the reference counts. When the last count is released -// we call SetPageSite(NULL) and SetObjects(0,NULL) to release interfaces -// previously obtained by the property page when it had SetObjects called - -CBasePropertyPage::CBasePropertyPage(TCHAR *pName, // Debug only name - LPUNKNOWN pUnk, // COM Delegator - int DialogId, // Resource ID - int TitleId) : // To get tital - CUnknown(pName,pUnk), - m_DialogId(DialogId), - m_TitleId(TitleId), - m_hwnd(NULL), - m_Dlg(NULL), - m_pPageSite(NULL), - m_bObjectSet(FALSE), - m_bDirty(FALSE) -{ -} - -#ifdef UNICODE -CBasePropertyPage::CBasePropertyPage(CHAR *pName, // Debug only name - LPUNKNOWN pUnk, // COM Delegator - int DialogId, // Resource ID - int TitleId) : // To get tital - CUnknown(pName,pUnk), - m_DialogId(DialogId), - m_TitleId(TitleId), - m_hwnd(NULL), - m_Dlg(NULL), - m_pPageSite(NULL), - m_bObjectSet(FALSE), - m_bDirty(FALSE) -{ -} -#endif - -// Increment our reference count - -STDMETHODIMP_(ULONG) CBasePropertyPage::NonDelegatingAddRef() -{ - LONG lRef = InterlockedIncrement(&m_cRef); - ASSERT(lRef > 0); - return max(ULONG(m_cRef),1ul); -} - - -// Release a reference count and protect against reentrancy - -STDMETHODIMP_(ULONG) CBasePropertyPage::NonDelegatingRelease() -{ - // If the reference count drops to zero delete ourselves - - if (InterlockedDecrement(&m_cRef) == 0) { - m_cRef++; - SetPageSite(NULL); - SetObjects(0,NULL); - delete this; - return ULONG(0); - } else { - return max(ULONG(m_cRef),1ul); - } -} - - -// Expose our IPropertyPage interface - -STDMETHODIMP -CBasePropertyPage::NonDelegatingQueryInterface(REFIID riid,void **ppv) -{ - if (riid == IID_IPropertyPage) { - return GetInterface((IPropertyPage *)this,ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid,ppv); - } -} - - -// Get the page info so that the page site can size itself - -STDMETHODIMP CBasePropertyPage::GetPageInfo(LPPROPPAGEINFO pPageInfo) -{ - CheckPointer(pPageInfo,E_POINTER); - WCHAR wszTitle[STR_MAX_LENGTH]; - WideStringFromResource(wszTitle,m_TitleId); - - // Allocate dynamic memory for the property page title - - LPOLESTR pszTitle; - HRESULT hr = AMGetWideString(wszTitle, &pszTitle); - if (FAILED(hr)) { - NOTE("No caption memory"); - return hr; - } - - pPageInfo->cb = sizeof(PROPPAGEINFO); - pPageInfo->pszTitle = pszTitle; - pPageInfo->pszDocString = NULL; - pPageInfo->pszHelpFile = NULL; - pPageInfo->dwHelpContext = 0; - - // Set defaults in case GetDialogSize fails - pPageInfo->size.cx = 340; - pPageInfo->size.cy = 150; - - GetDialogSize(m_DialogId, DialogProc,0L,&pPageInfo->size); - return NOERROR; -} - - -// Handles the messages for our property window - -INT_PTR CALLBACK CBasePropertyPage::DialogProc(HWND hwnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) -{ - CBasePropertyPage *pPropertyPage; - - switch (uMsg) { - - case WM_INITDIALOG: - - SetWindowLongPtr(hwnd, DWLP_USER, lParam); - - // This pointer may be NULL when calculating size - - pPropertyPage = (CBasePropertyPage *) lParam; - if (pPropertyPage == NULL) { - return (LRESULT) 1; - } - pPropertyPage->m_Dlg = hwnd; - } - - // This pointer may be NULL when calculating size - - pPropertyPage = (CBasePropertyPage *) GetWindowLongPtr(hwnd, DWLP_USER); - if (pPropertyPage == NULL) { - return (LRESULT) 1; - } - return pPropertyPage->OnReceiveMessage(hwnd,uMsg,wParam,lParam); -} - - -// Tells us the object that should be informed of the property changes - -STDMETHODIMP CBasePropertyPage::SetObjects(ULONG cObjects,LPUNKNOWN *ppUnk) -{ - if (cObjects == 1) { - - if ((ppUnk == NULL) || (*ppUnk == NULL)) { - return E_POINTER; - } - - // Set a flag to say that we have set the Object - m_bObjectSet = TRUE ; - return OnConnect(*ppUnk); - - } else if (cObjects == 0) { - - // Set a flag to say that we have not set the Object for the page - m_bObjectSet = FALSE ; - return OnDisconnect(); - } - - DbgBreak("No support for more than one object"); - return E_UNEXPECTED; -} - - -// Create the window we will use to edit properties - -STDMETHODIMP CBasePropertyPage::Activate(HWND hwndParent, - LPCRECT pRect, - BOOL fModal) -{ - CheckPointer(pRect,E_POINTER); - - // Return failure if SetObject has not been called. - if (m_bObjectSet == FALSE) { - return E_UNEXPECTED; - } - - if (m_hwnd) { - return E_UNEXPECTED; - } - - m_hwnd = CreateDialogParam(g_hInst, - MAKEINTRESOURCE(m_DialogId), - hwndParent, - DialogProc, - (LPARAM) this); - if (m_hwnd == NULL) { - return E_OUTOFMEMORY; - } - - OnActivate(); - Move(pRect); - return Show(SW_SHOWNORMAL); -} - - -// Set the position of the property page - -STDMETHODIMP CBasePropertyPage::Move(LPCRECT pRect) -{ - CheckPointer(pRect,E_POINTER); - - if (m_hwnd == NULL) { - return E_UNEXPECTED; - } - - MoveWindow(m_hwnd, // Property page handle - pRect->left, // x coordinate - pRect->top, // y coordinate - WIDTH(pRect), // Overall window width - HEIGHT(pRect), // And likewise height - TRUE); // Should we repaint it - - return NOERROR; -} - - -// Display the property dialog - -STDMETHODIMP CBasePropertyPage::Show(UINT nCmdShow) -{ - // Have we been activated yet - - if (m_hwnd == NULL) { - return E_UNEXPECTED; - } - - // Ignore wrong show flags - - if ((nCmdShow != SW_SHOW) && (nCmdShow != SW_SHOWNORMAL) && (nCmdShow != SW_HIDE)) { - return E_INVALIDARG; - } - - ShowWindow(m_hwnd,nCmdShow); - InvalidateRect(m_hwnd,NULL,TRUE); - return NOERROR; -} - - -// Destroy the property page dialog - -STDMETHODIMP CBasePropertyPage::Deactivate(void) -{ - if (m_hwnd == NULL) { - return E_UNEXPECTED; - } - - // Remove WS_EX_CONTROLPARENT before DestroyWindow call - - DWORD dwStyle = GetWindowLong(m_hwnd, GWL_EXSTYLE); - dwStyle = dwStyle & (~WS_EX_CONTROLPARENT); - - // Set m_hwnd to be NULL temporarily so the message handler - // for WM_STYLECHANGING doesn't add the WS_EX_CONTROLPARENT - // style back in - HWND hwnd = m_hwnd; - m_hwnd = NULL; - SetWindowLong(hwnd, GWL_EXSTYLE, dwStyle); - m_hwnd = hwnd; - - OnDeactivate(); - - // Destroy the dialog window - - DestroyWindow(m_hwnd); - m_hwnd = NULL; - return NOERROR; -} - - -// Tells the application property page site - -STDMETHODIMP CBasePropertyPage::SetPageSite(LPPROPERTYPAGESITE pPageSite) -{ - if (pPageSite) { - - if (m_pPageSite) { - return E_UNEXPECTED; - } - - m_pPageSite = pPageSite; - m_pPageSite->AddRef(); - - } else { - - if (m_pPageSite == NULL) { - return E_UNEXPECTED; - } - - m_pPageSite->Release(); - m_pPageSite = NULL; - } - return NOERROR; -} - - -// Apply any changes so far made - -STDMETHODIMP CBasePropertyPage::Apply() -{ - // In ActiveMovie 1.0 we used to check whether we had been activated or - // not. This is too constrictive. Apply should be allowed as long as - // SetObject was called to set an object. So we will no longer check to - // see if we have been activated (ie., m_hWnd != NULL), but instead - // make sure that m_bObjectSet is TRUE (ie., SetObject has been called). - - if (m_bObjectSet == FALSE) { - return E_UNEXPECTED; - } - - // Must have had a site set - - if (m_pPageSite == NULL) { - return E_UNEXPECTED; - } - - // Has anything changed - - if (m_bDirty == FALSE) { - return NOERROR; - } - - // Commit derived class changes - - HRESULT hr = OnApplyChanges(); - if (SUCCEEDED(hr)) { - m_bDirty = FALSE; - } - return hr; -} - - -// Base class definition for message handling - -INT_PTR CBasePropertyPage::OnReceiveMessage(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) -{ - // we would like the TAB key to move around the tab stops in our property - // page, but for some reason OleCreatePropertyFrame clears the CONTROLPARENT - // style behind our back, so we need to switch it back on now behind its - // back. Otherwise the tab key will be useless in every page. - // - - CBasePropertyPage *pPropertyPage; - { - pPropertyPage = (CBasePropertyPage *) GetWindowLongPtr(hwnd, DWLP_USER); - if (pPropertyPage->m_hwnd == NULL) { - return 0; - } - switch (uMsg) { - case WM_STYLECHANGING: - if (wParam == GWL_EXSTYLE) { - LPSTYLESTRUCT lpss = (LPSTYLESTRUCT)lParam; - lpss->styleNew |= WS_EX_CONTROLPARENT; - return 0; - } - } - } - - return DefWindowProc(hwnd,uMsg,wParam,lParam); -} - diff --git a/src/BaseClasses/cprop.h b/src/BaseClasses/cprop.h deleted file mode 100644 index 034ebc3bdf..0000000000 --- a/src/BaseClasses/cprop.h +++ /dev/null @@ -1,95 +0,0 @@ -//------------------------------------------------------------------------------ -// File: CProp.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __CPROP__ -#define __CPROP__ - -// Base property page class. Filters typically expose custom properties by -// implementing special control interfaces, examples are IDirectDrawVideo -// and IQualProp on renderers. This allows property pages to be built that -// use the given interface. Applications such as the ActiveMovie OCX query -// filters for the property pages they support and expose them to the user -// -// This class provides all the framework for a property page. A property -// page is a COM object that supports IPropertyPage. We should be created -// with a resource ID for the dialog which we will load when required. We -// should also be given in the constructor a resource ID for a title string -// we will load from the DLLs STRINGTABLE. The property page titles must be -// stored in resource files so that they can be easily internationalised -// -// We have a number of virtual methods (not PURE) that may be overriden in -// derived classes to query for interfaces and so on. These functions have -// simple implementations here that just return NOERROR. Derived classes -// will almost definately have to override the message handler method called -// OnReceiveMessage. We have a static dialog procedure that calls the method -// so that derived classes don't have to fiddle around with the this pointer - -class AM_NOVTABLE CBasePropertyPage : public IPropertyPage, public CUnknown -{ -protected: - - LPPROPERTYPAGESITE m_pPageSite; // Details for our property site - HWND m_hwnd; // Window handle for the page - HWND m_Dlg; // Actual dialog window handle - BOOL m_bDirty; // Has anything been changed - int m_TitleId; // Resource identifier for title - int m_DialogId; // Dialog resource identifier - - static INT_PTR CALLBACK DialogProc(HWND hwnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam); - -private: - BOOL m_bObjectSet ; // SetObject has been called or not. -public: - - CBasePropertyPage(TCHAR *pName, // Debug only name - LPUNKNOWN pUnk, // COM Delegator - int DialogId, // Resource ID - int TitleId); // To get tital - -#ifdef UNICODE - CBasePropertyPage(CHAR *pName, - LPUNKNOWN pUnk, - int DialogId, - int TitleId); -#endif - virtual ~CBasePropertyPage() { }; - DECLARE_IUNKNOWN - - // Override these virtual methods - - virtual HRESULT OnConnect(IUnknown *pUnknown) { return NOERROR; }; - virtual HRESULT OnDisconnect() { return NOERROR; }; - virtual HRESULT OnActivate() { return NOERROR; }; - virtual HRESULT OnDeactivate() { return NOERROR; }; - virtual HRESULT OnApplyChanges() { return NOERROR; }; - virtual INT_PTR OnReceiveMessage(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam); - - // These implement an IPropertyPage interface - - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void **ppv); - STDMETHODIMP_(ULONG) NonDelegatingRelease(); - STDMETHODIMP_(ULONG) NonDelegatingAddRef(); - STDMETHODIMP SetPageSite(LPPROPERTYPAGESITE pPageSite); - STDMETHODIMP Activate(HWND hwndParent,LPCRECT prect,BOOL fModal); - STDMETHODIMP Deactivate(void); - STDMETHODIMP GetPageInfo(LPPROPPAGEINFO pPageInfo); - STDMETHODIMP SetObjects(ULONG cObjects, LPUNKNOWN *ppUnk); - STDMETHODIMP Show(UINT nCmdShow); - STDMETHODIMP Move(LPCRECT prect); - STDMETHODIMP IsPageDirty(void) { return m_bDirty ? S_OK : S_FALSE; } - STDMETHODIMP Apply(void); - STDMETHODIMP Help(LPCWSTR lpszHelpDir) { return E_NOTIMPL; } - STDMETHODIMP TranslateAccelerator(LPMSG lpMsg) { return E_NOTIMPL; } -}; - -#endif // __CPROP__ - diff --git a/src/BaseClasses/ctlutil.cpp b/src/BaseClasses/ctlutil.cpp deleted file mode 100644 index 8a98c83a08..0000000000 --- a/src/BaseClasses/ctlutil.cpp +++ /dev/null @@ -1,2378 +0,0 @@ -//------------------------------------------------------------------------------ -// File: CtlUtil.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// Base classes implementing IDispatch parsing for the basic control dual -// interfaces. Derive from these and implement just the custom method and -// property methods. We also implement CPosPassThru that can be used by -// renderers and transforms to pass by IMediaPosition and IMediaSeeking - - -#include -#include -#include "seekpt.h" - -// 'bool' non standard reserved word -#pragma warning(disable:4237) - - -// --- CBaseDispatch implementation ---------- -CBaseDispatch::~CBaseDispatch() { - if(m_pti) { - m_pti->Release(); - } -} - - -// return 1 if we support GetTypeInfo - -STDMETHODIMP -CBaseDispatch::GetTypeInfoCount(UINT * pctinfo) { - CheckPointer(pctinfo,E_POINTER); - ValidateReadWritePtr(pctinfo,sizeof(UINT *)); - *pctinfo = 1; - return S_OK; -} - - -typedef HRESULT(STDAPICALLTYPE *LPLOADTYPELIB)( - const OLECHAR FAR *szFile, - ITypeLib FAR* FAR* pptlib); - -typedef HRESULT(STDAPICALLTYPE *LPLOADREGTYPELIB)(REFGUID rguid, - WORD wVerMajor, - WORD wVerMinor, - LCID lcid, - ITypeLib FAR* FAR* pptlib); - -// attempt to find our type library - -STDMETHODIMP -CBaseDispatch::GetTypeInfo( - REFIID riid, - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo) { - CheckPointer(pptinfo,E_POINTER); - ValidateReadWritePtr(pptinfo,sizeof(ITypeInfo *)); - HRESULT hr; - - *pptinfo = NULL; - - // we only support one type element - if(0 != itinfo) { - return TYPE_E_ELEMENTNOTFOUND; - } - - // always look for neutral - if(NULL == m_pti) { - - LPLOADTYPELIB lpfnLoadTypeLib; - LPLOADREGTYPELIB lpfnLoadRegTypeLib; - ITypeLib *ptlib; - HINSTANCE hInst; - - static const char szTypeLib[] = "LoadTypeLib"; - static const char szRegTypeLib[] = "LoadRegTypeLib"; - static const WCHAR szControl[] = L"control.tlb"; - - // - // Try to get the Ole32Aut.dll module handle. - // - - hInst = LoadOLEAut32(); - if(hInst == NULL) { - DWORD dwError = GetLastError(); - return AmHresultFromWin32(dwError); - } - lpfnLoadRegTypeLib = (LPLOADREGTYPELIB)GetProcAddress(hInst, - szRegTypeLib); - if(lpfnLoadRegTypeLib == NULL) { - DWORD dwError = GetLastError(); - return AmHresultFromWin32(dwError); - } - - hr = (*lpfnLoadRegTypeLib)(LIBID_QuartzTypeLib, 1, 0, // version 1.0 - lcid, &ptlib); - - if(FAILED(hr)) { - - // attempt to load directly - this will fill the - // registry in if it finds it - - lpfnLoadTypeLib = (LPLOADTYPELIB)GetProcAddress(hInst, szTypeLib); - if(lpfnLoadTypeLib == NULL) { - DWORD dwError = GetLastError(); - return AmHresultFromWin32(dwError); - } - - hr = (*lpfnLoadTypeLib)(szControl, &ptlib); - if(FAILED(hr)) { - return hr; - } - } - - hr = ptlib->GetTypeInfoOfGuid(riid, &m_pti); - - ptlib->Release(); - - if(FAILED(hr)) { - return hr; - } - } - - *pptinfo = m_pti; - m_pti->AddRef(); - return S_OK; -} - - -STDMETHODIMP -CBaseDispatch::GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid) { - // although the IDispatch riid is dead, we use this to pass from - // the interface implementation class to us the iid we are talking about. - - ITypeInfo * pti; - HRESULT hr = GetTypeInfo(riid, 0, lcid, &pti); - - if(SUCCEEDED(hr)) { - hr = pti->GetIDsOfNames(rgszNames, cNames, rgdispid); - - pti->Release(); - } - return hr; -} - - -// --- CMediaControl implementation --------- - -CMediaControl::CMediaControl(const TCHAR * name,LPUNKNOWN pUnk) : - CUnknown(name, pUnk) { -} - -// expose our interfaces IMediaControl and IUnknown - -STDMETHODIMP -CMediaControl::NonDelegatingQueryInterface(REFIID riid, void **ppv) { - ValidateReadWritePtr(ppv,sizeof(PVOID)); - if(riid == IID_IMediaControl) { - return GetInterface((IMediaControl *) this, ppv); - } - else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -// return 1 if we support GetTypeInfo - -STDMETHODIMP -CMediaControl::GetTypeInfoCount(UINT * pctinfo) { - return m_basedisp.GetTypeInfoCount(pctinfo); -} - - -// attempt to find our type library - -STDMETHODIMP -CMediaControl::GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo) { - return m_basedisp.GetTypeInfo(IID_IMediaControl, - itinfo, - lcid, - pptinfo); -} - - -STDMETHODIMP -CMediaControl::GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid) { - return m_basedisp.GetIDsOfNames(IID_IMediaControl, - rgszNames, - cNames, - lcid, - rgdispid); -} - - -STDMETHODIMP -CMediaControl::Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr) { - // this parameter is a dead leftover from an earlier interface - if(IID_NULL != riid) { - return DISP_E_UNKNOWNINTERFACE; - } - - ITypeInfo * pti; - HRESULT hr = GetTypeInfo(0, lcid, &pti); - - if(FAILED(hr)) { - return hr; - } - - hr = pti->Invoke((IMediaControl *)this, - dispidMember, - wFlags, - pdispparams, - pvarResult, - pexcepinfo, - puArgErr); - - pti->Release(); - return hr; -} - - -// --- CMediaEvent implementation ---------- - - -CMediaEvent::CMediaEvent(const TCHAR * name,LPUNKNOWN pUnk) : - CUnknown(name, pUnk) { -} - - -// expose our interfaces IMediaEvent and IUnknown - -STDMETHODIMP -CMediaEvent::NonDelegatingQueryInterface(REFIID riid, void **ppv) { - ValidateReadWritePtr(ppv,sizeof(PVOID)); - if(riid == IID_IMediaEvent || riid == IID_IMediaEventEx) { - return GetInterface((IMediaEventEx *) this, ppv); - } - else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -// return 1 if we support GetTypeInfo - -STDMETHODIMP -CMediaEvent::GetTypeInfoCount(UINT * pctinfo) { - return m_basedisp.GetTypeInfoCount(pctinfo); -} - - -// attempt to find our type library - -STDMETHODIMP -CMediaEvent::GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo) { - return m_basedisp.GetTypeInfo(IID_IMediaEvent, - itinfo, - lcid, - pptinfo); -} - - -STDMETHODIMP -CMediaEvent::GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid) { - return m_basedisp.GetIDsOfNames(IID_IMediaEvent, - rgszNames, - cNames, - lcid, - rgdispid); -} - - -STDMETHODIMP -CMediaEvent::Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr) { - // this parameter is a dead leftover from an earlier interface - if(IID_NULL != riid) { - return DISP_E_UNKNOWNINTERFACE; - } - - ITypeInfo * pti; - HRESULT hr = GetTypeInfo(0, lcid, &pti); - - if(FAILED(hr)) { - return hr; - } - - hr = pti->Invoke((IMediaEvent *)this, - dispidMember, - wFlags, - pdispparams, - pvarResult, - pexcepinfo, - puArgErr); - - pti->Release(); - return hr; -} - - -// --- CMediaPosition implementation ---------- - - -CMediaPosition::CMediaPosition(const TCHAR * name,LPUNKNOWN pUnk) : - CUnknown(name, pUnk) { -} - -CMediaPosition::CMediaPosition(const TCHAR * name, - LPUNKNOWN pUnk, - HRESULT * phr) : - CUnknown(name, pUnk) { - UNREFERENCED_PARAMETER(phr); -} - - -// expose our interfaces IMediaPosition and IUnknown - -STDMETHODIMP -CMediaPosition::NonDelegatingQueryInterface(REFIID riid, void **ppv) { - ValidateReadWritePtr(ppv,sizeof(PVOID)); - if(riid == IID_IMediaPosition) { - return GetInterface((IMediaPosition *) this, ppv); - } - else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -// return 1 if we support GetTypeInfo - -STDMETHODIMP -CMediaPosition::GetTypeInfoCount(UINT * pctinfo) { - return m_basedisp.GetTypeInfoCount(pctinfo); -} - - -// attempt to find our type library - -STDMETHODIMP -CMediaPosition::GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo) { - return m_basedisp.GetTypeInfo(IID_IMediaPosition, - itinfo, - lcid, - pptinfo); -} - - -STDMETHODIMP -CMediaPosition::GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid) { - return m_basedisp.GetIDsOfNames(IID_IMediaPosition, - rgszNames, - cNames, - lcid, - rgdispid); -} - - -STDMETHODIMP -CMediaPosition::Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr) { - // this parameter is a dead leftover from an earlier interface - if(IID_NULL != riid) { - return DISP_E_UNKNOWNINTERFACE; - } - - ITypeInfo * pti; - HRESULT hr = GetTypeInfo(0, lcid, &pti); - - if(FAILED(hr)) { - return hr; - } - - hr = pti->Invoke((IMediaPosition *)this, - dispidMember, - wFlags, - pdispparams, - pvarResult, - pexcepinfo, - puArgErr); - - pti->Release(); - return hr; -} - - -// --- IMediaPosition and IMediaSeeking pass through class ---------- - - -CPosPassThru::CPosPassThru(const TCHAR *pName, - LPUNKNOWN pUnk, - HRESULT *phr, - IPin *pPin) : - CMediaPosition(pName,pUnk), - m_pPin(pPin) { - if(pPin == NULL) { - *phr = E_POINTER; - return; - } -} - - -// Expose our IMediaSeeking and IMediaPosition interfaces - -STDMETHODIMP -CPosPassThru::NonDelegatingQueryInterface(REFIID riid,void **ppv) { - CheckPointer(ppv,E_POINTER); - *ppv = NULL; - - if(riid == IID_IMediaSeeking) { - return GetInterface(static_cast(this), ppv); - } - return CMediaPosition::NonDelegatingQueryInterface(riid,ppv); -} - - -// Return the IMediaPosition interface from our peer - -HRESULT -CPosPassThru::GetPeer(IMediaPosition ** ppMP) { - *ppMP = NULL; - - IPin *pConnected; - HRESULT hr = m_pPin->ConnectedTo(&pConnected); - if(FAILED(hr)) { - return E_NOTIMPL; - } - - IMediaPosition * pMP; - hr = pConnected->QueryInterface(IID_IMediaPosition, (void **) &pMP); - pConnected->Release(); - if(FAILED(hr)) { - return E_NOTIMPL; - } - - *ppMP = pMP; - return S_OK; -} - - -// Return the IMediaSeeking interface from our peer - -HRESULT -CPosPassThru::GetPeerSeeking(IMediaSeeking ** ppMS) { - *ppMS = NULL; - - IPin *pConnected; - HRESULT hr = m_pPin->ConnectedTo(&pConnected); - if(FAILED(hr)) { - return E_NOTIMPL; - } - - IMediaSeeking * pMS; - hr = pConnected->QueryInterface(IID_IMediaSeeking, (void **) &pMS); - pConnected->Release(); - if(FAILED(hr)) { - return E_NOTIMPL; - } - - *ppMS = pMS; - return S_OK; -} - - -// --- IMediaSeeking methods ---------- - - -STDMETHODIMP -CPosPassThru::GetCapabilities(DWORD * pCaps) { - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if(FAILED(hr)) { - return hr; - } - - hr = pMS->GetCapabilities(pCaps); - pMS->Release(); - return hr; -} - -STDMETHODIMP -CPosPassThru::CheckCapabilities(DWORD * pCaps) { - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if(FAILED(hr)) { - return hr; - } - - hr = pMS->CheckCapabilities(pCaps); - pMS->Release(); - return hr; -} - -STDMETHODIMP -CPosPassThru::IsFormatSupported(const GUID * pFormat) { - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if(FAILED(hr)) { - return hr; - } - - hr = pMS->IsFormatSupported(pFormat); - pMS->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::QueryPreferredFormat(GUID *pFormat) { - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if(FAILED(hr)) { - return hr; - } - - hr = pMS->QueryPreferredFormat(pFormat); - pMS->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::SetTimeFormat(const GUID * pFormat) { - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if(FAILED(hr)) { - return hr; - } - - hr = pMS->SetTimeFormat(pFormat); - pMS->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::GetTimeFormat(GUID *pFormat) { - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if(FAILED(hr)) { - return hr; - } - - hr = pMS->GetTimeFormat(pFormat); - pMS->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::IsUsingTimeFormat(const GUID * pFormat) { - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if(FAILED(hr)) { - return hr; - } - - hr = pMS->IsUsingTimeFormat(pFormat); - pMS->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::ConvertTimeFormat(LONGLONG * pTarget, const GUID * pTargetFormat, - LONGLONG Source, const GUID * pSourceFormat ) { - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if(FAILED(hr)) { - return hr; - } - - hr = pMS->ConvertTimeFormat(pTarget, pTargetFormat, Source, pSourceFormat); - pMS->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::SetPositions( LONGLONG * pCurrent, DWORD CurrentFlags - , LONGLONG * pStop, DWORD StopFlags ) { - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if(FAILED(hr)) { - return hr; - } - - hr = pMS->SetPositions(pCurrent, CurrentFlags, pStop, StopFlags); - pMS->Release(); - return hr; -} - -STDMETHODIMP -CPosPassThru::GetPositions(LONGLONG *pCurrent, LONGLONG * pStop) { - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if(FAILED(hr)) { - return hr; - } - - hr = pMS->GetPositions(pCurrent,pStop); - pMS->Release(); - return hr; -} - -HRESULT -CPosPassThru::GetSeekingLongLong -( HRESULT(__stdcall IMediaSeeking::*pMethod)( LONGLONG * ) -, LONGLONG * pll -) { - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if(SUCCEEDED(hr)) { - hr = (pMS->*pMethod)(pll); - pMS->Release(); - } - return hr; -} - -// If we don't have a current position then ask upstream - -STDMETHODIMP -CPosPassThru::GetCurrentPosition(LONGLONG *pCurrent) { - // Can we report the current position - HRESULT hr = GetMediaTime(pCurrent,NULL); - if(SUCCEEDED(hr)) - hr = NOERROR; - else - hr = GetSeekingLongLong(&IMediaSeeking::GetCurrentPosition, pCurrent); - return hr; -} - - -STDMETHODIMP -CPosPassThru::GetStopPosition(LONGLONG *pStop) { - return GetSeekingLongLong(&IMediaSeeking::GetStopPosition, pStop);; -} - -STDMETHODIMP -CPosPassThru::GetDuration(LONGLONG *pDuration) { - return GetSeekingLongLong(&IMediaSeeking::GetDuration, pDuration);; -} - - -STDMETHODIMP -CPosPassThru::GetPreroll(LONGLONG *pllPreroll) { - return GetSeekingLongLong(&IMediaSeeking::GetPreroll, pllPreroll);; -} - - -STDMETHODIMP -CPosPassThru::GetAvailable( LONGLONG *pEarliest, LONGLONG *pLatest ) { - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if(FAILED(hr)) { - return hr; - } - - hr = pMS->GetAvailable(pEarliest, pLatest); - pMS->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::GetRate(double * pdRate) { - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if(FAILED(hr)) { - return hr; - } - hr = pMS->GetRate(pdRate); - pMS->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::SetRate(double dRate) { - if(0.0 == dRate) { - return E_INVALIDARG; - } - - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if(FAILED(hr)) { - return hr; - } - hr = pMS->SetRate(dRate); - pMS->Release(); - return hr; -} - - - - -// --- IMediaPosition methods ---------- - - -STDMETHODIMP -CPosPassThru::get_Duration(REFTIME * plength) { - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if(FAILED(hr)) { - return hr; - } - - hr = pMP->get_Duration(plength); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::get_CurrentPosition(REFTIME * pllTime) { - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if(FAILED(hr)) { - return hr; - } - hr = pMP->get_CurrentPosition(pllTime); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::put_CurrentPosition(REFTIME llTime) { - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if(FAILED(hr)) { - return hr; - } - hr = pMP->put_CurrentPosition(llTime); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::get_StopTime(REFTIME * pllTime) { - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if(FAILED(hr)) { - return hr; - } - hr = pMP->get_StopTime(pllTime); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::put_StopTime(REFTIME llTime) { - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if(FAILED(hr)) { - return hr; - } - hr = pMP->put_StopTime(llTime); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::get_PrerollTime(REFTIME * pllTime) { - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if(FAILED(hr)) { - return hr; - } - hr = pMP->get_PrerollTime(pllTime); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::put_PrerollTime(REFTIME llTime) { - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if(FAILED(hr)) { - return hr; - } - hr = pMP->put_PrerollTime(llTime); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::get_Rate(double * pdRate) { - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if(FAILED(hr)) { - return hr; - } - hr = pMP->get_Rate(pdRate); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::put_Rate(double dRate) { - if(0.0 == dRate) { - return E_INVALIDARG; - } - - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if(FAILED(hr)) { - return hr; - } - hr = pMP->put_Rate(dRate); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::CanSeekForward(LONG *pCanSeekForward) { - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if(FAILED(hr)) { - return hr; - } - hr = pMP->CanSeekForward(pCanSeekForward); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::CanSeekBackward(LONG *pCanSeekBackward) { - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if(FAILED(hr)) { - return hr; - } - hr = pMP->CanSeekBackward(pCanSeekBackward); - pMP->Release(); - return hr; -} - - -// --- Implements the CRendererPosPassThru class ---------- - - -// Media times (eg current frame, field, sample etc) are passed through the -// filtergraph in media samples. When a renderer gets a sample with media -// times in it, it will call one of the RegisterMediaTime methods we expose -// (one takes an IMediaSample, the other takes the media times direct). We -// store the media times internally and return them in GetCurrentPosition. - -CRendererPosPassThru::CRendererPosPassThru(const TCHAR *pName, - LPUNKNOWN pUnk, - HRESULT *phr, - IPin *pPin) : - CPosPassThru(pName,pUnk,phr,pPin), - m_StartMedia(0), - m_EndMedia(0), - m_bReset(TRUE) { -} - - -// Sets the media times the object should report - -HRESULT -CRendererPosPassThru::RegisterMediaTime(IMediaSample *pMediaSample) { - ASSERT(pMediaSample); - LONGLONG StartMedia; - LONGLONG EndMedia; - - CAutoLock cAutoLock(&m_PositionLock); - - // Get the media times from the sample - - HRESULT hr = pMediaSample->GetTime(&StartMedia,&EndMedia); - if(FAILED(hr)) { - ASSERT(hr == VFW_E_SAMPLE_TIME_NOT_SET); - return hr; - } - - m_StartMedia = StartMedia; - m_EndMedia = EndMedia; - m_bReset = FALSE; - return NOERROR; -} - - -// Sets the media times the object should report - -HRESULT -CRendererPosPassThru::RegisterMediaTime(LONGLONG StartTime,LONGLONG EndTime) { - CAutoLock cAutoLock(&m_PositionLock); - m_StartMedia = StartTime; - m_EndMedia = EndTime; - m_bReset = FALSE; - return NOERROR; -} - - -// Return the current media times registered in the object - -HRESULT -CRendererPosPassThru::GetMediaTime(LONGLONG *pStartTime,LONGLONG *pEndTime) { - ASSERT(pStartTime); - - CAutoLock cAutoLock(&m_PositionLock); - if(m_bReset == TRUE) { - return E_FAIL; - } - - // We don't have to return the end time - - HRESULT hr = ConvertTimeFormat(pStartTime, 0, m_StartMedia, &TIME_FORMAT_MEDIA_TIME); - if(pEndTime && SUCCEEDED(hr)) { - hr = ConvertTimeFormat(pEndTime, 0, m_EndMedia, &TIME_FORMAT_MEDIA_TIME); - } - return hr; -} - - -// Resets the media times we hold - -HRESULT -CRendererPosPassThru::ResetMediaTime() { - CAutoLock cAutoLock(&m_PositionLock); - m_StartMedia = 0; - m_EndMedia = 0; - m_bReset = TRUE; - return NOERROR; -} - -// Intended to be called by the owing filter during EOS processing so -// that the media times can be adjusted to the stop time. This ensures -// that the GetCurrentPosition will actully get to the stop position. -HRESULT -CRendererPosPassThru::EOS() { - HRESULT hr; - - if(m_bReset == TRUE) hr = E_FAIL; - else { - LONGLONG llStop; - if (SUCCEEDED(hr=GetStopPosition(&llStop))) { - CAutoLock cAutoLock(&m_PositionLock); - m_StartMedia = m_EndMedia = llStop; - } - } - return hr; -} - -// -- CSourceSeeking implementation ------------ - -CSourceSeeking::CSourceSeeking( - const TCHAR * pName, - LPUNKNOWN pUnk, - HRESULT* phr, - CCritSec * pLock) : - CUnknown(pName, pUnk), - m_pLock(pLock), - m_rtStart((long)0) { - m_rtStop = _I64_MAX / 2; - m_rtDuration = m_rtStop; - m_dRateSeeking = 1.0; - - m_dwSeekingCaps = AM_SEEKING_CanSeekForwards - | AM_SEEKING_CanSeekBackwards - | AM_SEEKING_CanSeekAbsolute - | AM_SEEKING_CanGetStopPos - | AM_SEEKING_CanGetDuration; -} - -HRESULT CSourceSeeking::NonDelegatingQueryInterface(REFIID riid, void **ppv) { - if(riid == IID_IMediaSeeking) { - CheckPointer(ppv, E_POINTER); - return GetInterface(static_cast(this), ppv); - } - else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -HRESULT CSourceSeeking::IsFormatSupported(const GUID * pFormat) { - CheckPointer(pFormat, E_POINTER); - // only seeking in time (REFERENCE_TIME units) is supported - return *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE; -} - -HRESULT CSourceSeeking::QueryPreferredFormat(GUID *pFormat) { - CheckPointer(pFormat, E_POINTER); - *pFormat = TIME_FORMAT_MEDIA_TIME; - return S_OK; -} - -HRESULT CSourceSeeking::SetTimeFormat(const GUID * pFormat) { - CheckPointer(pFormat, E_POINTER); - - // nothing to set; just check that it's TIME_FORMAT_TIME - return *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : E_INVALIDARG; -} - -HRESULT CSourceSeeking::IsUsingTimeFormat(const GUID * pFormat) { - CheckPointer(pFormat, E_POINTER); - return *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE; -} - -HRESULT CSourceSeeking::GetTimeFormat(GUID *pFormat) { - CheckPointer(pFormat, E_POINTER); - *pFormat = TIME_FORMAT_MEDIA_TIME; - return S_OK; -} - -HRESULT CSourceSeeking::GetDuration(LONGLONG *pDuration) { - CheckPointer(pDuration, E_POINTER); - CAutoLock lock(m_pLock); - *pDuration = m_rtDuration; - return S_OK; -} - -HRESULT CSourceSeeking::GetStopPosition(LONGLONG *pStop) { - CheckPointer(pStop, E_POINTER); - CAutoLock lock(m_pLock); - *pStop = m_rtStop; - return S_OK; -} - -HRESULT CSourceSeeking::GetCurrentPosition(LONGLONG *pCurrent) { - // GetCurrentPosition is typically supported only in renderers and - // not in source filters. - return E_NOTIMPL; -} - -HRESULT CSourceSeeking::GetCapabilities( DWORD * pCapabilities ) { - CheckPointer(pCapabilities, E_POINTER); - *pCapabilities = m_dwSeekingCaps; - return S_OK; -} - -HRESULT CSourceSeeking::CheckCapabilities( DWORD * pCapabilities ) { - CheckPointer(pCapabilities, E_POINTER); - - // make sure all requested capabilities are in our mask - return (~m_dwSeekingCaps & *pCapabilities) ? S_FALSE : S_OK; -} - -HRESULT CSourceSeeking::ConvertTimeFormat( LONGLONG * pTarget, const GUID * pTargetFormat, - LONGLONG Source, const GUID * pSourceFormat ) { - CheckPointer(pTarget, E_POINTER); - // format guids can be null to indicate current format - - // since we only support TIME_FORMAT_MEDIA_TIME, we don't really - // offer any conversions. - if(pTargetFormat == 0 || *pTargetFormat == TIME_FORMAT_MEDIA_TIME) { - if(pSourceFormat == 0 || *pSourceFormat == TIME_FORMAT_MEDIA_TIME) { - *pTarget = Source; - return S_OK; - } - } - - return E_INVALIDARG; -} - - -HRESULT CSourceSeeking::SetPositions( LONGLONG * pCurrent, DWORD CurrentFlags - , LONGLONG * pStop, DWORD StopFlags ) { - DWORD StopPosBits = StopFlags & AM_SEEKING_PositioningBitsMask; - DWORD StartPosBits = CurrentFlags & AM_SEEKING_PositioningBitsMask; - - if(StopFlags) { - CheckPointer(pStop, E_POINTER); - - // accept only relative, incremental, or absolute positioning - if(StopPosBits != StopFlags) { - return E_INVALIDARG; - } - } - - if(CurrentFlags) { - CheckPointer(pCurrent, E_POINTER); - if(StartPosBits != AM_SEEKING_AbsolutePositioning && - StartPosBits != AM_SEEKING_RelativePositioning) { - return E_INVALIDARG; - } - } - - - // scope for autolock - { - CAutoLock lock(m_pLock); - - // set start position - if(StartPosBits == AM_SEEKING_AbsolutePositioning) { - m_rtStart = *pCurrent; - } - else if(StartPosBits == AM_SEEKING_RelativePositioning) { - m_rtStart += *pCurrent; - } - - // set stop position - if(StopPosBits == AM_SEEKING_AbsolutePositioning) { - m_rtStop = *pStop; - } - else if(StopPosBits == AM_SEEKING_IncrementalPositioning) { - m_rtStop = m_rtStart + *pStop; - } - else if(StopPosBits == AM_SEEKING_RelativePositioning) { - m_rtStop = m_rtStop + *pStop; - } - } - - - HRESULT hr = S_OK; - if(SUCCEEDED(hr) && StopPosBits) { - hr = ChangeStop(); - } - if(StartPosBits) { - hr = ChangeStart(); - } - - return hr; -} - - -HRESULT CSourceSeeking::GetPositions( LONGLONG * pCurrent, LONGLONG * pStop ) { - if(pCurrent) { - *pCurrent = m_rtStart; - } - if(pStop) { - *pStop = m_rtStop; - } - - return S_OK;; -} - - -HRESULT CSourceSeeking::GetAvailable( LONGLONG * pEarliest, LONGLONG * pLatest ) { - if(pEarliest) { - *pEarliest = 0; - } - if(pLatest) { - CAutoLock lock(m_pLock); - *pLatest = m_rtDuration; - } - return S_OK; -} - -HRESULT CSourceSeeking::SetRate( double dRate) { { - CAutoLock lock(m_pLock); - m_dRateSeeking = dRate; - } - return ChangeRate(); -} - -HRESULT CSourceSeeking::GetRate( double * pdRate) { - CheckPointer(pdRate, E_POINTER); - CAutoLock lock(m_pLock); - *pdRate = m_dRateSeeking; - return S_OK; -} - -HRESULT CSourceSeeking::GetPreroll(LONGLONG *pPreroll) { - CheckPointer(pPreroll, E_POINTER); - *pPreroll = 0; - return S_OK; -} - - - - - -// --- CSourcePosition implementation ---------- - - -CSourcePosition::CSourcePosition(const TCHAR * pName, - LPUNKNOWN pUnk, - HRESULT* phr, - CCritSec * pLock) : - CMediaPosition(pName, pUnk), - m_pLock(pLock), - m_Start(CRefTime((LONGLONG)0)) { - m_Stop = _I64_MAX; - m_Rate = 1.0; -} - - -STDMETHODIMP -CSourcePosition::get_Duration(REFTIME * plength) { - CheckPointer(plength,E_POINTER); - ValidateReadWritePtr(plength,sizeof(REFTIME)); - CAutoLock lock(m_pLock); - - *plength = m_Duration; - return S_OK; -} - - -STDMETHODIMP -CSourcePosition::put_CurrentPosition(REFTIME llTime) { - m_pLock->Lock(); - m_Start = llTime; - m_pLock->Unlock(); - - return ChangeStart(); -} - - -STDMETHODIMP -CSourcePosition::get_StopTime(REFTIME * pllTime) { - CheckPointer(pllTime,E_POINTER); - ValidateReadWritePtr(pllTime,sizeof(REFTIME)); - CAutoLock lock(m_pLock); - - *pllTime = m_Stop; - return S_OK; -} - - -STDMETHODIMP -CSourcePosition::put_StopTime(REFTIME llTime) { - m_pLock->Lock(); - m_Stop = llTime; - m_pLock->Unlock(); - - return ChangeStop(); -} - - -STDMETHODIMP -CSourcePosition::get_PrerollTime(REFTIME * pllTime) { - CheckPointer(pllTime,E_POINTER); - ValidateReadWritePtr(pllTime,sizeof(REFTIME)); - return E_NOTIMPL; -} - - -STDMETHODIMP -CSourcePosition::put_PrerollTime(REFTIME llTime) { - return E_NOTIMPL; -} - - -STDMETHODIMP -CSourcePosition::get_Rate(double * pdRate) { - CheckPointer(pdRate,E_POINTER); - ValidateReadWritePtr(pdRate,sizeof(double)); - CAutoLock lock(m_pLock); - - *pdRate = m_Rate; - return S_OK; -} - - -STDMETHODIMP -CSourcePosition::put_Rate(double dRate) { - m_pLock->Lock(); - m_Rate = dRate; - m_pLock->Unlock(); - - return ChangeRate(); -} - - -// By default we can seek forwards - -STDMETHODIMP -CSourcePosition::CanSeekForward(LONG *pCanSeekForward) { - CheckPointer(pCanSeekForward,E_POINTER); - *pCanSeekForward = OATRUE; - return S_OK; -} - - -// By default we can seek backwards - -STDMETHODIMP -CSourcePosition::CanSeekBackward(LONG *pCanSeekBackward) { - CheckPointer(pCanSeekBackward,E_POINTER); - *pCanSeekBackward = OATRUE; - return S_OK; -} - - -// --- Implementation of CBasicAudio class ---------- - - -CBasicAudio::CBasicAudio(const TCHAR * pName,LPUNKNOWN punk) : - CUnknown(pName, punk) { -} - -// overriden to publicise our interfaces - -STDMETHODIMP -CBasicAudio::NonDelegatingQueryInterface(REFIID riid, void **ppv) { - ValidateReadWritePtr(ppv,sizeof(PVOID)); - if(riid == IID_IBasicAudio) { - return GetInterface((IBasicAudio *) this, ppv); - } - else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -STDMETHODIMP -CBasicAudio::GetTypeInfoCount(UINT * pctinfo) { - return m_basedisp.GetTypeInfoCount(pctinfo); -} - - -STDMETHODIMP -CBasicAudio::GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo) { - return m_basedisp.GetTypeInfo(IID_IBasicAudio, - itinfo, - lcid, - pptinfo); -} - - -STDMETHODIMP -CBasicAudio::GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid) { - return m_basedisp.GetIDsOfNames(IID_IBasicAudio, - rgszNames, - cNames, - lcid, - rgdispid); -} - - -STDMETHODIMP -CBasicAudio::Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr) { - // this parameter is a dead leftover from an earlier interface - if(IID_NULL != riid) { - return DISP_E_UNKNOWNINTERFACE; - } - - ITypeInfo * pti; - HRESULT hr = GetTypeInfo(0, lcid, &pti); - - if(FAILED(hr)) { - return hr; - } - - hr = pti->Invoke((IBasicAudio *)this, - dispidMember, - wFlags, - pdispparams, - pvarResult, - pexcepinfo, - puArgErr); - - pti->Release(); - return hr; -} - - -// --- IVideoWindow implementation ---------- - -CBaseVideoWindow::CBaseVideoWindow(const TCHAR * pName,LPUNKNOWN punk) : - CUnknown(pName, punk) { -} - - -// overriden to publicise our interfaces - -STDMETHODIMP -CBaseVideoWindow::NonDelegatingQueryInterface(REFIID riid, void **ppv) { - ValidateReadWritePtr(ppv,sizeof(PVOID)); - if(riid == IID_IVideoWindow) { - return GetInterface((IVideoWindow *) this, ppv); - } - else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -STDMETHODIMP -CBaseVideoWindow::GetTypeInfoCount(UINT * pctinfo) { - return m_basedisp.GetTypeInfoCount(pctinfo); -} - - -STDMETHODIMP -CBaseVideoWindow::GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo) { - return m_basedisp.GetTypeInfo(IID_IVideoWindow, - itinfo, - lcid, - pptinfo); -} - - -STDMETHODIMP -CBaseVideoWindow::GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid) { - return m_basedisp.GetIDsOfNames(IID_IVideoWindow, - rgszNames, - cNames, - lcid, - rgdispid); -} - - -STDMETHODIMP -CBaseVideoWindow::Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr) { - // this parameter is a dead leftover from an earlier interface - if(IID_NULL != riid) { - return DISP_E_UNKNOWNINTERFACE; - } - - ITypeInfo * pti; - HRESULT hr = GetTypeInfo(0, lcid, &pti); - - if(FAILED(hr)) { - return hr; - } - - hr = pti->Invoke((IVideoWindow *)this, - dispidMember, - wFlags, - pdispparams, - pvarResult, - pexcepinfo, - puArgErr); - - pti->Release(); - return hr; -} - - -// --- IBasicVideo implementation ---------- - - -CBaseBasicVideo::CBaseBasicVideo(const TCHAR * pName,LPUNKNOWN punk) : - CUnknown(pName, punk) { -} - - -// overriden to publicise our interfaces - -STDMETHODIMP -CBaseBasicVideo::NonDelegatingQueryInterface(REFIID riid, void **ppv) { - ValidateReadWritePtr(ppv,sizeof(PVOID)); - if(riid == IID_IBasicVideo || riid == IID_IBasicVideo2) { - return GetInterface(static_cast(this), ppv); - } - else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -STDMETHODIMP -CBaseBasicVideo::GetTypeInfoCount(UINT * pctinfo) { - return m_basedisp.GetTypeInfoCount(pctinfo); -} - - -STDMETHODIMP -CBaseBasicVideo::GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo) { - return m_basedisp.GetTypeInfo(IID_IBasicVideo, - itinfo, - lcid, - pptinfo); -} - - -STDMETHODIMP -CBaseBasicVideo::GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid) { - return m_basedisp.GetIDsOfNames(IID_IBasicVideo, - rgszNames, - cNames, - lcid, - rgdispid); -} - - -STDMETHODIMP -CBaseBasicVideo::Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr) { - // this parameter is a dead leftover from an earlier interface - if(IID_NULL != riid) { - return DISP_E_UNKNOWNINTERFACE; - } - - ITypeInfo * pti; - HRESULT hr = GetTypeInfo(0, lcid, &pti); - - if(FAILED(hr)) { - return hr; - } - - hr = pti->Invoke((IBasicVideo *)this, - dispidMember, - wFlags, - pdispparams, - pvarResult, - pexcepinfo, - puArgErr); - - pti->Release(); - return hr; -} - - -// --- Implementation of Deferred Commands ---------- - - -CDispParams::CDispParams(UINT nArgs, VARIANT* pArgs, HRESULT *phr) { - cNamedArgs = 0; - rgdispidNamedArgs = NULL; - cArgs = nArgs; - - if(cArgs) { - rgvarg = new VARIANT[cArgs]; - if(NULL == rgvarg) { - cArgs = 0; - if(phr) { - *phr = E_OUTOFMEMORY; - } - return; - } - - for(UINT i = 0; i < cArgs; i++) { - - VARIANT * pDest = &rgvarg[i]; - VARIANT * pSrc = &pArgs[i]; - - pDest->vt = pSrc->vt; - switch(pDest->vt) { - - case VT_I4: - pDest->lVal = pSrc->lVal; - break; - - case VT_UI1: - pDest->bVal = pSrc->bVal; - break; - - case VT_I2: - pDest->iVal = pSrc->iVal; - break; - - case VT_R4: - pDest->fltVal = pSrc->fltVal; - break; - - case VT_R8: - pDest->dblVal = pSrc->dblVal; - break; - - case VT_BOOL: - pDest->boolVal = pSrc->boolVal; - break; - - case VT_ERROR: - pDest->scode = pSrc->scode; - break; - - case VT_CY: - pDest->cyVal = pSrc->cyVal; - break; - - case VT_DATE: - pDest->date = pSrc->date; - break; - - case VT_BSTR: - if(pSrc->bstrVal == NULL) { - pDest->bstrVal = NULL; - } - else { - - // a BSTR is a WORD followed by a UNICODE string. - // the pointer points just after the WORD - - WORD len = * (WORD*) (pSrc->bstrVal - (sizeof(WORD) / sizeof(OLECHAR))); - OLECHAR* pch = new OLECHAR[len + (sizeof(WORD)/sizeof(OLECHAR))]; - if(pch) { - WORD *pui = (WORD*)pch; - *pui = len; - pDest->bstrVal = pch + (sizeof(WORD)/sizeof(OLECHAR)); - CopyMemory(pDest->bstrVal, pSrc->bstrVal, len*sizeof(OLECHAR)); - } - else { - cArgs = i; - if(phr) { - *phr = E_OUTOFMEMORY; - } - } - } - pDest->bstrVal = pSrc->bstrVal; - break; - - case VT_UNKNOWN: - pDest->punkVal = pSrc->punkVal; - pDest->punkVal->AddRef(); - break; - - case VT_DISPATCH: - pDest->pdispVal = pSrc->pdispVal; - pDest->pdispVal->AddRef(); - break; - - default: - // a type we haven't got round to adding yet! - ASSERT(0); - break; - } - } - - } - else { - rgvarg = NULL; - } - -} - - -CDispParams::~CDispParams() { - for(UINT i = 0; i < cArgs; i++) { - switch(rgvarg[i].vt) { - case VT_BSTR: - if(rgvarg[i].bstrVal != NULL) { - OLECHAR * pch = rgvarg[i].bstrVal - (sizeof(WORD)/sizeof(OLECHAR)); - delete pch; - } - break; - - case VT_UNKNOWN: - rgvarg[i].punkVal->Release(); - break; - - case VT_DISPATCH: - rgvarg[i].pdispVal->Release(); - break; - } - } - delete[] rgvarg; -} - - -// lifetime is controlled by refcounts (see defer.h) - -CDeferredCommand::CDeferredCommand( - CCmdQueue * pQ, - LPUNKNOWN pUnk, - HRESULT * phr, - LPUNKNOWN pUnkExecutor, - REFTIME time, - GUID* iid, - long dispidMethod, - short wFlags, - long nArgs, - VARIANT* pDispParams, - VARIANT* pvarResult, - short* puArgErr, - BOOL bStream - ) : - CUnknown(NAME("DeferredCommand"), pUnk), - m_pQueue(pQ), - m_pUnk(pUnkExecutor), - m_iid(iid), - m_dispidMethod(dispidMethod), - m_wFlags(wFlags), - m_DispParams(nArgs, pDispParams, phr), - m_pvarResult(pvarResult), - m_bStream(bStream), - m_hrResult(E_ABORT) { - - // convert REFTIME to REFERENCE_TIME - COARefTime convertor(time); - m_time = convertor; - - // no check of time validity - it's ok to queue a command that's - // already late - - // check iid is supportable on pUnk by QueryInterface for it - IUnknown * pInterface; - HRESULT hr = m_pUnk->QueryInterface(GetIID(), (void**) &pInterface); - if(FAILED(hr)) { - *phr = hr; - return; - } - pInterface->Release(); - - - // !!! check dispidMethod and param/return types using typelib - ITypeInfo *pti; - hr = m_Dispatch.GetTypeInfo(*iid, 0, 0, &pti); - if(FAILED(hr)) { - *phr = hr; - return; - } - // !!! some sort of ITypeInfo validity check here - pti->Release(); - - - // Fix up the dispid for put and get - if(wFlags == DISPATCH_PROPERTYPUT) { - m_DispParams.cNamedArgs = 1; - m_DispId = DISPID_PROPERTYPUT; - m_DispParams.rgdispidNamedArgs = &m_DispId; - } - - // all checks ok - add to queue - hr = pQ->Insert(this); - if(FAILED(hr)) { - *phr = hr; - } -} - - -// refcounts are held by caller of InvokeAt... and by list. So if -// we get here, we can't be on the list - -#if 0 -CDeferredCommand::~CDeferredCommand() { - // this assert is invalid since if the queue is deleted while we are - // still on the queue, we will have been removed by the queue and this - // m_pQueue will not have been modified. - // ASSERT(m_pQueue == NULL); - - // we don't hold a ref count on pUnk, which is the object that should - // execute the command. - // This is because there would otherwise be a circular refcount problem - // since pUnk probably owns the CmdQueue object that has a refcount - // on us. - // The lifetime of pUnk is guaranteed by it being part of, or lifetime - // controlled by, our parent object. As long as we are on the list, pUnk - // must be valid. Once we are off the list, we do not use pUnk. - -} -#endif - - -// overriden to publicise our interfaces - -STDMETHODIMP -CDeferredCommand::NonDelegatingQueryInterface(REFIID riid, void **ppv) { - ValidateReadWritePtr(ppv,sizeof(PVOID)); - if(riid == IID_IDeferredCommand) { - return GetInterface((IDeferredCommand *) this, ppv); - } - else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -// remove from q. this will reduce the refcount by one (since the q -// holds a count) but can't make us go away since he must have a -// refcount in order to call this method. - -STDMETHODIMP -CDeferredCommand::Cancel() { - if(m_pQueue == NULL) { - return VFW_E_ALREADY_CANCELLED; - } - - HRESULT hr = m_pQueue->Remove(this); - if(FAILED(hr)) { - return hr; - } - - m_pQueue = NULL; - return S_OK; -} - - -STDMETHODIMP -CDeferredCommand::Confidence(LONG* pConfidence) { - return E_NOTIMPL; -} - - -STDMETHODIMP -CDeferredCommand::GetHResult(HRESULT * phrResult) { - CheckPointer(phrResult,E_POINTER); - ValidateReadWritePtr(phrResult,sizeof(HRESULT)); - - if(m_pQueue != NULL) { - return E_ABORT; - } - *phrResult = m_hrResult; - return S_OK; -} - - -// set the time to be a new time (checking that it is valid) and -// then requeue - -STDMETHODIMP -CDeferredCommand::Postpone(REFTIME newtime) { - - // check that this time is not past - // convert REFTIME to REFERENCE_TIME - COARefTime convertor(newtime); - - // check that the time has not passed - if(m_pQueue->CheckTime(convertor, IsStreamTime())) { - return VFW_E_TIME_ALREADY_PASSED; - } - - // extract from list - HRESULT hr = m_pQueue->Remove(this); - if(FAILED(hr)) { - return hr; - } - - // change time - m_time = convertor; - - // requeue - hr = m_pQueue->Insert(this); - - return hr; -} - - -HRESULT -CDeferredCommand::Invoke() { - // check that we are still outstanding - if(m_pQueue == NULL) { - return VFW_E_ALREADY_CANCELLED; - } - - // get the type info - ITypeInfo* pti; - HRESULT hr = m_Dispatch.GetTypeInfo(GetIID(), 0, 0, &pti); - if(FAILED(hr)) { - return hr; - } - - // qi for the expected interface and then invoke it. Note that we have to - // treat the returned interface as IUnknown since we don't know its type. - IUnknown* pInterface; - - hr = m_pUnk->QueryInterface(GetIID(), (void**) &pInterface); - if(FAILED(hr)) { - pti->Release(); - return hr; - } - - EXCEPINFO expinfo; - UINT uArgErr; - m_hrResult = pti->Invoke(pInterface, - GetMethod(), - GetFlags(), - GetParams(), - GetResult(), - &expinfo, - &uArgErr); - - // release the interface we QI'd for - pInterface->Release(); - pti->Release(); - - - // remove from list whether or not successful - // or we loop indefinitely - hr = m_pQueue->Remove(this); - m_pQueue = NULL; - return hr; -} - - - -// --- CCmdQueue methods ---------- - - -CCmdQueue::CCmdQueue() : - m_listPresentation(NAME("Presentation time command list")), - m_listStream(NAME("Stream time command list")), - m_evDue(TRUE), // manual reset - m_dwAdvise(0), - m_pClock(NULL), - m_bRunning(FALSE) { -} - - -CCmdQueue::~CCmdQueue() { - // empty all our lists - - // we hold a refcount on each, so traverse and Release each - // entry then RemoveAll to empty the list - POSITION pos = m_listPresentation.GetHeadPosition(); - - while(pos) { - CDeferredCommand* pCmd = m_listPresentation.GetNext(pos); - pCmd->Release(); - } - m_listPresentation.RemoveAll(); - - pos = m_listStream.GetHeadPosition(); - - while(pos) { - CDeferredCommand* pCmd = m_listStream.GetNext(pos); - pCmd->Release(); - } - m_listStream.RemoveAll(); - - if(m_pClock) { - if(m_dwAdvise) { - m_pClock->Unadvise(m_dwAdvise); - m_dwAdvise = 0; - } - m_pClock->Release(); - } -} - - -// returns a new CDeferredCommand object that will be initialised with -// the parameters and will be added to the queue during construction. -// returns S_OK if successfully created otherwise an error and -// no object has been queued. - -HRESULT -CCmdQueue::New( - CDeferredCommand **ppCmd, - LPUNKNOWN pUnk, // this object will execute command - REFTIME time, - GUID* iid, - long dispidMethod, - short wFlags, - long cArgs, - VARIANT* pDispParams, - VARIANT* pvarResult, - short* puArgErr, - BOOL bStream -) { - CAutoLock lock(&m_Lock); - - HRESULT hr = S_OK; - *ppCmd = NULL; - - CDeferredCommand* pCmd; - pCmd = new CDeferredCommand(this, - NULL, // not aggregated - &hr, - pUnk, // this guy will execute - time, - iid, - dispidMethod, - wFlags, - cArgs, - pDispParams, - pvarResult, - puArgErr, - bStream); - - if(pCmd == NULL) { - hr = E_OUTOFMEMORY; - } - else { - *ppCmd = pCmd; - } - return hr; -} - - -HRESULT -CCmdQueue::Insert(CDeferredCommand* pCmd) { - CAutoLock lock(&m_Lock); - - // addref the item - pCmd->AddRef(); - - CGenericList * pList; - if(pCmd->IsStreamTime()) { - pList = &m_listStream; - } - else { - pList = &m_listPresentation; - } - POSITION pos = pList->GetHeadPosition(); - - // seek past all items that are before us - while(pos && - (pList->Get(pos)->GetTime() <= pCmd->GetTime())) { - - pList->GetNext(pos); - } - - // now at end of list or in front of items that come later - if(!pos) { - pList->AddTail(pCmd); - } - else { - pList->AddBefore(pos, pCmd); - } - - SetTimeAdvise(); - return S_OK; -} - - -HRESULT -CCmdQueue::Remove(CDeferredCommand* pCmd) { - CAutoLock lock(&m_Lock); - HRESULT hr = S_OK; - - CGenericList * pList; - if(pCmd->IsStreamTime()) { - pList = &m_listStream; - } - else { - pList = &m_listPresentation; - } - POSITION pos = pList->GetHeadPosition(); - - // traverse the list - while(pos && (pList->Get(pos) != pCmd)) { - pList->GetNext(pos); - } - - // did we drop off the end? - if(!pos) { - hr = VFW_E_NOT_FOUND; - } - else { - - // found it - now take off list - pList->Remove(pos); - - // Insert did an AddRef, so release it - pCmd->Release(); - - // check that timer request is still for earliest time - SetTimeAdvise(); - } - return hr; -} - - -// set the clock used for timing - -HRESULT -CCmdQueue::SetSyncSource(IReferenceClock* pClock) { - CAutoLock lock(&m_Lock); - - // addref the new clock first in case they are the same - if(pClock) { - pClock->AddRef(); - } - - // kill any advise on the old clock - if(m_pClock) { - if(m_dwAdvise) { - m_pClock->Unadvise(m_dwAdvise); - m_dwAdvise = 0; - } - m_pClock->Release(); - } - m_pClock = pClock; - - // set up a new advise - SetTimeAdvise(); - return S_OK; -} - - -// set up a timer event with the reference clock - -void -CCmdQueue::SetTimeAdvise(void) { - // make sure we have a clock to use - if(!m_pClock) { - return; - } - - // reset the event whenever we are requesting a new signal - m_evDue.Reset(); - - // time 0 is earliest - CRefTime current; - - // find the earliest presentation time - if(m_listPresentation.GetCount() > 0) { - - POSITION pos = m_listPresentation.GetHeadPosition(); - current = m_listPresentation.Get(pos)->GetTime(); - } - - // if we're running, check the stream times too - if(m_bRunning) { - - CRefTime t; - - if(m_listStream.GetCount() > 0) { - - POSITION pos = m_listStream.GetHeadPosition(); - t = m_listStream.Get(pos)->GetTime(); - - // add on stream time offset to get presentation time - t += m_StreamTimeOffset; - - // is this earlier? - if((current == TimeZero) || (t < current)) { - current = t; - } - } - } - - // need to change? - if((current > TimeZero) && (current != m_tCurrentAdvise)) { - if(m_dwAdvise) { - m_pClock->Unadvise(m_dwAdvise); - // reset the event whenever we are requesting a new signal - m_evDue.Reset(); - } - - // ask for time advice - the first two params are either - // stream time offset and stream time or - // presentation time and 0. we always use the latter - HRESULT hr = m_pClock->AdviseTime((REFERENCE_TIME)current, - TimeZero, - (HEVENT) HANDLE(m_evDue), - &m_dwAdvise); - - ASSERT(SUCCEEDED(hr)); - m_tCurrentAdvise = current; - } -} - - -// switch to run mode. Streamtime to Presentation time mapping known. - -HRESULT -CCmdQueue::Run(REFERENCE_TIME tStreamTimeOffset) { - CAutoLock lock(&m_Lock); - - m_StreamTimeOffset = tStreamTimeOffset; - m_bRunning = TRUE; - - // ensure advise is accurate - SetTimeAdvise(); - return S_OK; -} - - -// switch to Stopped or Paused mode. Time mapping not known. - -HRESULT -CCmdQueue::EndRun() { - CAutoLock lock(&m_Lock); - - m_bRunning = FALSE; - - // check timer setting - stream times - SetTimeAdvise(); - return S_OK; -} - - -// return a pointer to the next due command. Blocks for msTimeout -// milliseconds until there is a due command. -// Stream-time commands will only become due between Run and Endrun calls. -// The command remains queued until invoked or cancelled. -// Returns E_ABORT if timeout occurs, otherwise S_OK (or other error). -// -// returns an AddRef'd object - -HRESULT -CCmdQueue::GetDueCommand(CDeferredCommand ** ppCmd, long msTimeout) { - // loop until we timeout or find a due command - for(;;) { { - CAutoLock lock(&m_Lock); - - - // find the earliest command - CDeferredCommand * pCmd = NULL; - - // check the presentation time and the - // stream time list to find the earliest - - if(m_listPresentation.GetCount() > 0) { - POSITION pos = m_listPresentation.GetHeadPosition(); - pCmd = m_listPresentation.Get(pos); - } - - if(m_bRunning && (m_listStream.GetCount() > 0)) { - POSITION pos = m_listStream.GetHeadPosition(); - CDeferredCommand* pStrm = m_listStream.Get(pos); - - CRefTime t = pStrm->GetTime() + m_StreamTimeOffset; - if(!pCmd || (t < pCmd->GetTime())) { - pCmd = pStrm; - } - } - - // if we have found one, is it due? - if(pCmd) { - if(CheckTime(pCmd->GetTime(), pCmd->IsStreamTime())) { - - // yes it's due - addref it - pCmd->AddRef(); - *ppCmd = pCmd; - return S_OK; - } - } - } - - // block until the advise is signalled - if(WaitForSingleObject(m_evDue, msTimeout) != WAIT_OBJECT_0) { - return E_ABORT; - } - } -} - - -// return a pointer to a command that will be due for a given time. -// Pass in a stream time here. The stream time offset will be passed -// in via the Run method. -// Commands remain queued until invoked or cancelled. -// This method will not block. It will report E_ABORT if there are no -// commands due yet. -// -// returns an AddRef'd object - -HRESULT -CCmdQueue::GetCommandDueFor(REFERENCE_TIME rtStream, CDeferredCommand**ppCmd) { - CAutoLock lock(&m_Lock); - - CRefTime tStream(rtStream); - - // find the earliest stream and presentation time commands - CDeferredCommand* pStream = NULL; - if(m_listStream.GetCount() > 0) { - POSITION pos = m_listStream.GetHeadPosition(); - pStream = m_listStream.Get(pos); - } - CDeferredCommand* pPresent = NULL; - if(m_listPresentation.GetCount() > 0) { - POSITION pos = m_listPresentation.GetHeadPosition(); - pPresent = m_listPresentation.Get(pos); - } - - // is there a presentation time that has passed already - if(pPresent && CheckTime(pPresent->GetTime(), FALSE)) { - pPresent->AddRef(); - *ppCmd = pPresent; - return S_OK; - } - - // is there a stream time command due before this stream time - if(pStream && (pStream->GetTime() <= tStream)) { - pPresent->AddRef(); - *ppCmd = pStream; - return S_OK; - } - - // if we are running, we can map presentation times to - // stream time. In this case, is there a presentation time command - // that will be due before this stream time is presented? - if(m_bRunning && pPresent) { - - // this stream time will appear at... - tStream += m_StreamTimeOffset; - - // due before that? - if(pPresent->GetTime() <= tStream) { - *ppCmd = pPresent; - return S_OK; - } - } - - // no commands due yet - return VFW_E_NOT_FOUND; -} - - diff --git a/src/BaseClasses/ctlutil.h b/src/BaseClasses/ctlutil.h deleted file mode 100644 index 0a244edc27..0000000000 --- a/src/BaseClasses/ctlutil.h +++ /dev/null @@ -1,919 +0,0 @@ -//------------------------------------------------------------------------------ -// File: CtlUtil.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// Base classes implementing IDispatch parsing for the basic control dual -// interfaces. Derive from these and implement just the custom method and -// property methods. We also implement CPosPassThru that can be used by -// renderers and transforms to pass by IMediaPosition and IMediaSeeking - -#ifndef __CTLUTIL__ -#define __CTLUTIL__ - -// OLE Automation has different ideas of TRUE and FALSE - -#define OATRUE (-1) -#define OAFALSE (0) - - -// It's possible that we could replace this class with CreateStdDispatch - -class CBaseDispatch -{ - ITypeInfo * m_pti; - -public: - - CBaseDispatch() : m_pti(NULL) {} - ~CBaseDispatch(); - - /* IDispatch methods */ - STDMETHODIMP GetTypeInfoCount(UINT * pctinfo); - - STDMETHODIMP GetTypeInfo( - REFIID riid, - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo); - - STDMETHODIMP GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid); -}; - - -class AM_NOVTABLE CMediaControl : - public IMediaControl, - public CUnknown -{ - CBaseDispatch m_basedisp; - -public: - - CMediaControl(const TCHAR *, LPUNKNOWN); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - /* IDispatch methods */ - STDMETHODIMP GetTypeInfoCount(UINT * pctinfo); - - STDMETHODIMP GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo); - - STDMETHODIMP GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid); - - STDMETHODIMP Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr); -}; - - -class AM_NOVTABLE CMediaEvent : - public IMediaEventEx, - public CUnknown -{ - CBaseDispatch m_basedisp; - -public: - - CMediaEvent(const TCHAR *, LPUNKNOWN); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - /* IDispatch methods */ - STDMETHODIMP GetTypeInfoCount(UINT * pctinfo); - - STDMETHODIMP GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo); - - STDMETHODIMP GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid); - - STDMETHODIMP Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr); -}; - - -class AM_NOVTABLE CMediaPosition : - public IMediaPosition, - public CUnknown -{ - CBaseDispatch m_basedisp; - - -public: - - CMediaPosition(const TCHAR *, LPUNKNOWN); - CMediaPosition(const TCHAR *, LPUNKNOWN, HRESULT *phr); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - /* IDispatch methods */ - STDMETHODIMP GetTypeInfoCount(UINT * pctinfo); - - STDMETHODIMP GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo); - - STDMETHODIMP GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid); - - STDMETHODIMP Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr); - -}; - - -// OA-compatibility means that we must use double as the RefTime value, -// and REFERENCE_TIME (essentially a LONGLONG) within filters. -// this class converts between the two - -class COARefTime : public CRefTime { -public: - - COARefTime() { - }; - - COARefTime(CRefTime t) - : CRefTime(t) - { - }; - - COARefTime(REFERENCE_TIME t) - : CRefTime(t) - { - }; - - COARefTime(double d) { - m_time = (LONGLONG) (d * 10000000); - }; - - operator double() { - return double(m_time) / 10000000; - }; - - operator REFERENCE_TIME() { - return m_time; - }; - - COARefTime& operator=(const double& rd) { - m_time = (LONGLONG) (rd * 10000000); - return *this; - } - - COARefTime& operator=(const REFERENCE_TIME& rt) { - m_time = rt; - return *this; - } - - inline BOOL operator==(const COARefTime& rt) - { - return m_time == rt.m_time; - }; - - inline BOOL operator!=(const COARefTime& rt) - { - return m_time != rt.m_time; - }; - - inline BOOL operator < (const COARefTime& rt) - { - return m_time < rt.m_time; - }; - - inline BOOL operator > (const COARefTime& rt) - { - return m_time > rt.m_time; - }; - - inline BOOL operator >= (const COARefTime& rt) - { - return m_time >= rt.m_time; - }; - - inline BOOL operator <= (const COARefTime& rt) - { - return m_time <= rt.m_time; - }; - - inline COARefTime operator+(const COARefTime& rt) - { - return COARefTime(m_time + rt.m_time); - }; - - inline COARefTime operator-(const COARefTime& rt) - { - return COARefTime(m_time - rt.m_time); - }; - - inline COARefTime operator*(LONG l) - { - return COARefTime(m_time * l); - }; - - inline COARefTime operator/(LONG l) - { - return COARefTime(m_time / l); - }; - -private: - // Prevent bugs from constructing from LONG (which gets - // converted to double and then multiplied by 10000000 - COARefTime(LONG); - COARefTime& operator=(LONG l); -}; - - -// A utility class that handles IMediaPosition and IMediaSeeking on behalf -// of single-input pin renderers, or transform filters. -// -// Renderers will expose this from the filter; transform filters will -// expose it from the output pin and not the renderer. -// -// Create one of these, giving it your IPin* for your input pin, and delegate -// all IMediaPosition methods to it. It will query the input pin for -// IMediaPosition and respond appropriately. -// -// Call ForceRefresh if the pin connection changes. -// -// This class no longer caches the upstream IMediaPosition or IMediaSeeking -// it acquires it on each method call. This means ForceRefresh is not needed. -// The method is kept for source compatibility and to minimise the changes -// if we need to put it back later for performance reasons. - -class CPosPassThru : public IMediaSeeking, public CMediaPosition -{ - IPin *m_pPin; - - HRESULT GetPeer(IMediaPosition **ppMP); - HRESULT GetPeerSeeking(IMediaSeeking **ppMS); - -public: - - CPosPassThru(const TCHAR *, LPUNKNOWN, HRESULT*, IPin *); - DECLARE_IUNKNOWN - - HRESULT ForceRefresh() { - return S_OK; - }; - - // override to return an accurate current position - virtual HRESULT GetMediaTime(LONGLONG *pStartTime,LONGLONG *pEndTime) { - return E_FAIL; - } - - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void **ppv); - - // IMediaSeeking methods - STDMETHODIMP GetCapabilities( DWORD * pCapabilities ); - STDMETHODIMP CheckCapabilities( DWORD * pCapabilities ); - STDMETHODIMP SetTimeFormat(const GUID * pFormat); - STDMETHODIMP GetTimeFormat(GUID *pFormat); - STDMETHODIMP IsUsingTimeFormat(const GUID * pFormat); - STDMETHODIMP IsFormatSupported( const GUID * pFormat); - STDMETHODIMP QueryPreferredFormat( GUID *pFormat); - STDMETHODIMP ConvertTimeFormat(LONGLONG * pTarget, const GUID * pTargetFormat, - LONGLONG Source, const GUID * pSourceFormat ); - STDMETHODIMP SetPositions( LONGLONG * pCurrent, DWORD CurrentFlags - , LONGLONG * pStop, DWORD StopFlags ); - - STDMETHODIMP GetPositions( LONGLONG * pCurrent, LONGLONG * pStop ); - STDMETHODIMP GetCurrentPosition( LONGLONG * pCurrent ); - STDMETHODIMP GetStopPosition( LONGLONG * pStop ); - STDMETHODIMP SetRate( double dRate); - STDMETHODIMP GetRate( double * pdRate); - STDMETHODIMP GetDuration( LONGLONG *pDuration); - STDMETHODIMP GetAvailable( LONGLONG *pEarliest, LONGLONG *pLatest ); - STDMETHODIMP GetPreroll( LONGLONG *pllPreroll ); - - // IMediaPosition properties - STDMETHODIMP get_Duration(REFTIME * plength); - STDMETHODIMP put_CurrentPosition(REFTIME llTime); - STDMETHODIMP get_StopTime(REFTIME * pllTime); - STDMETHODIMP put_StopTime(REFTIME llTime); - STDMETHODIMP get_PrerollTime(REFTIME * pllTime); - STDMETHODIMP put_PrerollTime(REFTIME llTime); - STDMETHODIMP get_Rate(double * pdRate); - STDMETHODIMP put_Rate(double dRate); - STDMETHODIMP get_CurrentPosition(REFTIME * pllTime); - STDMETHODIMP CanSeekForward(LONG *pCanSeekForward); - STDMETHODIMP CanSeekBackward(LONG *pCanSeekBackward); - -private: - HRESULT GetSeekingLongLong( HRESULT (__stdcall IMediaSeeking::*pMethod)( LONGLONG * ), - LONGLONG * pll ); -}; - - -// Adds the ability to return a current position - -class CRendererPosPassThru : public CPosPassThru -{ - CCritSec m_PositionLock; // Locks access to our position - LONGLONG m_StartMedia; // Start media time last seen - LONGLONG m_EndMedia; // And likewise the end media - BOOL m_bReset; // Have media times been set - -public: - - // Used to help with passing media times through graph - - CRendererPosPassThru(const TCHAR *, LPUNKNOWN, HRESULT*, IPin *); - HRESULT RegisterMediaTime(IMediaSample *pMediaSample); - HRESULT RegisterMediaTime(LONGLONG StartTime,LONGLONG EndTime); - HRESULT GetMediaTime(LONGLONG *pStartTime,LONGLONG *pEndTime); - HRESULT ResetMediaTime(); - HRESULT EOS(); -}; - -STDAPI CreatePosPassThru( - LPUNKNOWN pAgg, - BOOL bRenderer, - IPin *pPin, - IUnknown **ppPassThru -); - -// A class that handles the IDispatch part of IBasicAudio and leaves the -// properties and methods themselves pure virtual. - -class AM_NOVTABLE CBasicAudio : public IBasicAudio, public CUnknown -{ - CBaseDispatch m_basedisp; - -public: - - CBasicAudio(const TCHAR *, LPUNKNOWN); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - /* IDispatch methods */ - STDMETHODIMP GetTypeInfoCount(UINT * pctinfo); - - STDMETHODIMP GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo); - - STDMETHODIMP GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid); - - STDMETHODIMP Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr); -}; - - -// A class that handles the IDispatch part of IBasicVideo and leaves the -// properties and methods themselves pure virtual. - -class AM_NOVTABLE CBaseBasicVideo : public IBasicVideo2, public CUnknown -{ - CBaseDispatch m_basedisp; - -public: - - CBaseBasicVideo(const TCHAR *, LPUNKNOWN); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - /* IDispatch methods */ - STDMETHODIMP GetTypeInfoCount(UINT * pctinfo); - - STDMETHODIMP GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo); - - STDMETHODIMP GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid); - - STDMETHODIMP Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr); - - STDMETHODIMP GetPreferredAspectRatio( - long *plAspectX, - long *plAspectY) - { - return E_NOTIMPL; - } -}; - - -// A class that handles the IDispatch part of IVideoWindow and leaves the -// properties and methods themselves pure virtual. - -class AM_NOVTABLE CBaseVideoWindow : public IVideoWindow, public CUnknown -{ - CBaseDispatch m_basedisp; - -public: - - CBaseVideoWindow(const TCHAR *, LPUNKNOWN); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - /* IDispatch methods */ - STDMETHODIMP GetTypeInfoCount(UINT * pctinfo); - - STDMETHODIMP GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo); - - STDMETHODIMP GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid); - - STDMETHODIMP Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr); -}; - - -// abstract class to help source filters with their implementation -// of IMediaPosition. Derive from this and set the duration (and stop -// position). Also override NotifyChange to do something when the properties -// change. - -class AM_NOVTABLE CSourcePosition : public CMediaPosition -{ - -public: - CSourcePosition(const TCHAR *, LPUNKNOWN, HRESULT*, CCritSec *); - - // IMediaPosition methods - STDMETHODIMP get_Duration(REFTIME * plength); - STDMETHODIMP put_CurrentPosition(REFTIME llTime); - STDMETHODIMP get_StopTime(REFTIME * pllTime); - STDMETHODIMP put_StopTime(REFTIME llTime); - STDMETHODIMP get_PrerollTime(REFTIME * pllTime); - STDMETHODIMP put_PrerollTime(REFTIME llTime); - STDMETHODIMP get_Rate(double * pdRate); - STDMETHODIMP put_Rate(double dRate); - STDMETHODIMP CanSeekForward(LONG *pCanSeekForward); - STDMETHODIMP CanSeekBackward(LONG *pCanSeekBackward); - - // override if you can return the data you are actually working on - STDMETHODIMP get_CurrentPosition(REFTIME * pllTime) { - return E_NOTIMPL; - }; - -protected: - - // we call this to notify changes. Override to handle them - virtual HRESULT ChangeStart() PURE; - virtual HRESULT ChangeStop() PURE; - virtual HRESULT ChangeRate() PURE; - - COARefTime m_Duration; - COARefTime m_Start; - COARefTime m_Stop; - double m_Rate; - - CCritSec * m_pLock; -}; - -class AM_NOVTABLE CSourceSeeking : - public IMediaSeeking, - public CUnknown -{ - -public: - - DECLARE_IUNKNOWN; - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - // IMediaSeeking methods - - STDMETHODIMP IsFormatSupported(const GUID * pFormat); - STDMETHODIMP QueryPreferredFormat(GUID *pFormat); - STDMETHODIMP SetTimeFormat(const GUID * pFormat); - STDMETHODIMP IsUsingTimeFormat(const GUID * pFormat); - STDMETHODIMP GetTimeFormat(GUID *pFormat); - STDMETHODIMP GetDuration(LONGLONG *pDuration); - STDMETHODIMP GetStopPosition(LONGLONG *pStop); - STDMETHODIMP GetCurrentPosition(LONGLONG *pCurrent); - STDMETHODIMP GetCapabilities( DWORD * pCapabilities ); - STDMETHODIMP CheckCapabilities( DWORD * pCapabilities ); - STDMETHODIMP ConvertTimeFormat( LONGLONG * pTarget, const GUID * pTargetFormat, - LONGLONG Source, const GUID * pSourceFormat ); - - STDMETHODIMP SetPositions( LONGLONG * pCurrent, DWORD CurrentFlags - , LONGLONG * pStop, DWORD StopFlags ); - - STDMETHODIMP GetPositions( LONGLONG * pCurrent, LONGLONG * pStop ); - - STDMETHODIMP GetAvailable( LONGLONG * pEarliest, LONGLONG * pLatest ); - STDMETHODIMP SetRate( double dRate); - STDMETHODIMP GetRate( double * pdRate); - STDMETHODIMP GetPreroll(LONGLONG *pPreroll); - - -protected: - - // ctor - CSourceSeeking(const TCHAR *, LPUNKNOWN, HRESULT*, CCritSec *); - - // we call this to notify changes. Override to handle them - virtual HRESULT ChangeStart() PURE; - virtual HRESULT ChangeStop() PURE; - virtual HRESULT ChangeRate() PURE; - - CRefTime m_rtDuration; // length of stream - CRefTime m_rtStart; // source will start here - CRefTime m_rtStop; // source will stop here - double m_dRateSeeking; - - // seeking capabilities - DWORD m_dwSeekingCaps; - - CCritSec * m_pLock; -}; - - -// Base classes supporting Deferred commands. - -// Deferred commands are queued by calls to methods on the IQueueCommand -// interface, exposed by the filtergraph and by some filters. A successful -// call to one of these methods will return an IDeferredCommand interface -// representing the queued command. -// -// A CDeferredCommand object represents a single deferred command, and exposes -// the IDeferredCommand interface as well as other methods permitting time -// checks and actual execution. It contains a reference to the CCommandQueue -// object on which it is queued. -// -// CCommandQueue is a base class providing a queue of CDeferredCommand -// objects, and methods to add, remove, check status and invoke the queued -// commands. A CCommandQueue object would be part of an object that -// implemented IQueueCommand. - -class CCmdQueue; - -// take a copy of the params and store them. Release any allocated -// memory in destructor - -class CDispParams : public DISPPARAMS -{ -public: - CDispParams(UINT nArgs, VARIANT* pArgs, HRESULT *phr = NULL); - ~CDispParams(); -}; - - -// CDeferredCommand lifetime is controlled by refcounts. Caller of -// InvokeAt.. gets a refcounted interface pointer, and the CCmdQueue -// object also holds a refcount on us. Calling Cancel or Invoke takes -// us off the CCmdQueue and thus reduces the refcount by 1. Once taken -// off the queue we cannot be put back on the queue. - -class CDeferredCommand - : public CUnknown, - public IDeferredCommand -{ -public: - - CDeferredCommand( - CCmdQueue * pQ, - LPUNKNOWN pUnk, // aggregation outer unk - HRESULT * phr, - LPUNKNOWN pUnkExecutor, // object that will execute this cmd - REFTIME time, - GUID* iid, - long dispidMethod, - short wFlags, - long cArgs, - VARIANT* pDispParams, - VARIANT* pvarResult, - short* puArgErr, - BOOL bStream - ); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - // IDeferredCommand methods - STDMETHODIMP Cancel(); - STDMETHODIMP Confidence( - LONG* pConfidence); - STDMETHODIMP Postpone( - REFTIME newtime); - STDMETHODIMP GetHResult( - HRESULT* phrResult); - - // other public methods - - HRESULT Invoke(); - - // access methods - - // returns TRUE if streamtime, FALSE if presentation time - BOOL IsStreamTime() { - return m_bStream; - }; - - CRefTime GetTime() { - return m_time; - }; - - REFIID GetIID() { - return *m_iid; - }; - - long GetMethod() { - return m_dispidMethod; - }; - - short GetFlags() { - return m_wFlags; - }; - - DISPPARAMS* GetParams() { - return &m_DispParams; - }; - - VARIANT* GetResult() { - return m_pvarResult; - }; - -protected: - - CCmdQueue* m_pQueue; - - // pUnk for the interface that we will execute the command on - LPUNKNOWN m_pUnk; - - // stored command data - REFERENCE_TIME m_time; - GUID* m_iid; - long m_dispidMethod; - short m_wFlags; - VARIANT* m_pvarResult; - BOOL m_bStream; - CDispParams m_DispParams; - DISPID m_DispId; // For get and put - - // we use this for ITypeInfo access - CBaseDispatch m_Dispatch; - - // save retval here - HRESULT m_hrResult; -}; - - -// a list of CDeferredCommand objects. this is a base class providing -// the basics of access to the list. If you want to use CDeferredCommand -// objects then your queue needs to be derived from this class. - -class AM_NOVTABLE CCmdQueue -{ -public: - CCmdQueue(); - virtual ~CCmdQueue(); - - // returns a new CDeferredCommand object that will be initialised with - // the parameters and will be added to the queue during construction. - // returns S_OK if successfully created otherwise an error and - // no object has been queued. - virtual HRESULT New( - CDeferredCommand **ppCmd, - LPUNKNOWN pUnk, - REFTIME time, - GUID* iid, - long dispidMethod, - short wFlags, - long cArgs, - VARIANT* pDispParams, - VARIANT* pvarResult, - short* puArgErr, - BOOL bStream - ); - - // called by the CDeferredCommand object to add and remove itself - // from the queue - virtual HRESULT Insert(CDeferredCommand* pCmd); - virtual HRESULT Remove(CDeferredCommand* pCmd); - - // Command-Due Checking - // - // There are two schemes of synchronisation: coarse and accurate. In - // coarse mode, you wait till the time arrives and then execute the cmd. - // In accurate mode, you wait until you are processing the sample that - // will appear at the time, and then execute the command. It's up to the - // filter which one it will implement. The filtergraph will always - // implement coarse mode for commands queued at the filtergraph. - // - // If you want coarse sync, you probably want to wait until there is a - // command due, and then execute it. You can do this by calling - // GetDueCommand. If you have several things to wait for, get the - // event handle from GetDueHandle() and when this is signalled then call - // GetDueCommand. Stream time will only advance between calls to Run and - // EndRun. Note that to avoid an extra thread there is no guarantee that - // if the handle is set there will be a command ready. Each time the - // event is signalled, call GetDueCommand (probably with a 0 timeout); - // This may return E_ABORT. - // - // If you want accurate sync, you must call GetCommandDueFor, passing - // as a parameter the stream time of the samples you are about to process. - // This will return: - // -- a stream-time command due at or before that stream time - // -- a presentation-time command due at or before the - // time that stream time will be presented (only between Run - // and EndRun calls, since outside of this, the mapping from - // stream time to presentation time is not known. - // -- any presentation-time command due now. - // This means that if you want accurate synchronisation on samples that - // might be processed during Paused mode, you need to use - // stream-time commands. - // - // In all cases, commands remain queued until Invoked or Cancelled. The - // setting and resetting of the event handle is managed entirely by this - // queue object. - - // set the clock used for timing - virtual HRESULT SetSyncSource(IReferenceClock*); - - // switch to run mode. Streamtime to Presentation time mapping known. - virtual HRESULT Run(REFERENCE_TIME tStreamTimeOffset); - - // switch to Stopped or Paused mode. Time mapping not known. - virtual HRESULT EndRun(); - - // return a pointer to the next due command. Blocks for msTimeout - // milliseconds until there is a due command. - // Stream-time commands will only become due between Run and Endrun calls. - // The command remains queued until invoked or cancelled. - // Returns E_ABORT if timeout occurs, otherwise S_OK (or other error). - // Returns an AddRef-ed object - virtual HRESULT GetDueCommand(CDeferredCommand ** ppCmd, long msTimeout); - - // return the event handle that will be signalled whenever - // there are deferred commands due for execution (when GetDueCommand - // will not block). - HANDLE GetDueHandle() { - return HANDLE(m_evDue); - }; - - // return a pointer to a command that will be due for a given time. - // Pass in a stream time here. The stream time offset will be passed - // in via the Run method. - // Commands remain queued until invoked or cancelled. - // This method will not block. It will report VFW_E_NOT_FOUND if there - // are no commands due yet. - // Returns an AddRef-ed object - virtual HRESULT GetCommandDueFor(REFERENCE_TIME tStream, CDeferredCommand**ppCmd); - - // check if a given time is due (TRUE if it is due yet) - BOOL CheckTime(CRefTime time, BOOL bStream) { - - // if no clock, nothing is due! - if (!m_pClock) { - return FALSE; - } - - // stream time - if (bStream) { - - // not valid if not running - if (!m_bRunning) { - return FALSE; - } - // add on known stream time offset to get presentation time - time += m_StreamTimeOffset; - } - - CRefTime Now; - m_pClock->GetTime((REFERENCE_TIME*)&Now); - return (time <= Now); - }; - -protected: - - // protect access to lists etc - CCritSec m_Lock; - - // commands queued in presentation time are stored here - CGenericList m_listPresentation; - - // commands queued in stream time are stored here - CGenericList m_listStream; - - // set when any commands are due - CAMEvent m_evDue; - - // creates an advise for the earliest time required, if any - void SetTimeAdvise(void); - - // advise id from reference clock (0 if no outstanding advise) - DWORD_PTR m_dwAdvise; - - // advise time is for this presentation time - CRefTime m_tCurrentAdvise; - - // the reference clock we are using (addrefed) - IReferenceClock* m_pClock; - - // true when running - BOOL m_bRunning; - - // contains stream time offset when m_bRunning is true - CRefTime m_StreamTimeOffset; -}; - -#endif // __CTLUTIL__ diff --git a/src/BaseClasses/ddmm.cpp b/src/BaseClasses/ddmm.cpp deleted file mode 100644 index 72afc264a4..0000000000 --- a/src/BaseClasses/ddmm.cpp +++ /dev/null @@ -1,126 +0,0 @@ -//------------------------------------------------------------------------------ -// File: DDMM.cpp -// -// Desc: DirectShow base classes - implements routines for using DirectDraw -// on a multimonitor system. -// -// Copyright (c) 1995-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include -#include "ddmm.h" - -/* - * FindDeviceCallback - */ -typedef struct { - LPSTR szDevice; - GUID* lpGUID; - GUID GUID; - BOOL fFound; -} FindDeviceData; - -BOOL CALLBACK FindDeviceCallback(GUID* lpGUID, LPSTR szName, LPSTR szDevice, LPVOID lParam) { - FindDeviceData *p = (FindDeviceData*)lParam; - - if(lstrcmpiA(p->szDevice, szDevice) == 0) { - if(lpGUID) { - p->GUID = *lpGUID; - p->lpGUID = &p->GUID; - } - else { - p->lpGUID = NULL; - } - p->fFound = TRUE; - return FALSE; - } - return TRUE; -} - - -BOOL CALLBACK FindDeviceCallbackEx(GUID* lpGUID, LPSTR szName, LPSTR szDevice, LPVOID lParam, HMONITOR hMonitor) { - FindDeviceData *p = (FindDeviceData*)lParam; - - if(lstrcmpiA(p->szDevice, szDevice) == 0) { - if(lpGUID) { - p->GUID = *lpGUID; - p->lpGUID = &p->GUID; - } - else { - p->lpGUID = NULL; - } - p->fFound = TRUE; - return FALSE; - } - return TRUE; -} - - -/* - * DirectDrawCreateFromDevice - * - * create a DirectDraw object for a particular device - */ -IDirectDraw * DirectDrawCreateFromDevice(LPSTR szDevice, PDRAWCREATE DirectDrawCreateP, PDRAWENUM DirectDrawEnumerateP) { - IDirectDraw* pdd = NULL; - FindDeviceData find; - - if(szDevice == NULL) { - DirectDrawCreateP(NULL, &pdd, NULL); - return pdd; - } - - find.szDevice = szDevice; - find.fFound = FALSE; - DirectDrawEnumerateP(FindDeviceCallback, (LPVOID)&find); - - if(find.fFound) { - // - // In 4bpp mode the following DDraw call causes a message box to be popped - // up by DDraw (!?!). It's DDraw's fault, but we don't like it. So we - // make sure it doesn't happen. - // - UINT ErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); - DirectDrawCreateP(find.lpGUID, &pdd, NULL); - SetErrorMode(ErrorMode); - } - - return pdd; -} - - -/* - * DirectDrawCreateFromDeviceEx - * - * create a DirectDraw object for a particular device - */ -IDirectDraw * DirectDrawCreateFromDeviceEx(LPSTR szDevice, PDRAWCREATE DirectDrawCreateP, LPDIRECTDRAWENUMERATEEXA DirectDrawEnumerateExP) { - IDirectDraw* pdd = NULL; - FindDeviceData find; - - if(szDevice == NULL) { - DirectDrawCreateP(NULL, &pdd, NULL); - return pdd; - } - - find.szDevice = szDevice; - find.fFound = FALSE; - DirectDrawEnumerateExP(FindDeviceCallbackEx, (LPVOID)&find, - DDENUM_ATTACHEDSECONDARYDEVICES); - - if(find.fFound) { - // - // In 4bpp mode the following DDraw call causes a message box to be popped - // up by DDraw (!?!). It's DDraw's fault, but we don't like it. So we - // make sure it doesn't happen. - // - UINT ErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); - DirectDrawCreateP(find.lpGUID, &pdd, NULL); - SetErrorMode(ErrorMode); - } - - return pdd; -} - diff --git a/src/BaseClasses/ddmm.h b/src/BaseClasses/ddmm.h deleted file mode 100644 index 2bb95deb9b..0000000000 --- a/src/BaseClasses/ddmm.h +++ /dev/null @@ -1,28 +0,0 @@ -//------------------------------------------------------------------------------ -// File: DDMM.h -// -// Desc: DirectShow base classes - efines routines for using DirectDraw -// on a multimonitor system. -// -// Copyright (c) 1995-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifdef __cplusplus -extern "C" { /* Assume C declarations for C++ */ -#endif /* __cplusplus */ - -// DDRAW.H might not include these -#ifndef DDENUM_ATTACHEDSECONDARYDEVICES -#define DDENUM_ATTACHEDSECONDARYDEVICES 0x00000001L -#endif - -typedef HRESULT (*PDRAWCREATE)(IID *,LPDIRECTDRAW *,LPUNKNOWN); -typedef HRESULT (*PDRAWENUM)(LPDDENUMCALLBACKA, LPVOID); - -IDirectDraw * DirectDrawCreateFromDevice(LPSTR, PDRAWCREATE, PDRAWENUM); -IDirectDraw * DirectDrawCreateFromDeviceEx(LPSTR, PDRAWCREATE, LPDIRECTDRAWENUMERATEEXA); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ diff --git a/src/BaseClasses/dllentry.cpp b/src/BaseClasses/dllentry.cpp deleted file mode 100644 index 6b74d2e524..0000000000 --- a/src/BaseClasses/dllentry.cpp +++ /dev/null @@ -1,332 +0,0 @@ -//------------------------------------------------------------------------------ -// File: DllEntry.cpp -// -// Desc: DirectShow base classes - implements classes used to support dll -// entry points for COM objects. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include - -#ifdef DEBUG -#ifdef UNICODE -#ifndef _UNICODE -#define _UNICODE -#endif // _UNICODE -#endif // UNICODE - -#include -#endif // DEBUG - -extern CFactoryTemplate g_Templates[]; -extern int g_cTemplates; - -HINSTANCE g_hInst; -DWORD g_amPlatform; // VER_PLATFORM_WIN32_WINDOWS etc... (from GetVersionEx) -OSVERSIONINFO g_osInfo; - -// -// an instance of this is created by the DLLGetClassObject entrypoint -// it uses the CFactoryTemplate object it is given to support the -// IClassFactory interface - -class CClassFactory : public IClassFactory, public CBaseObject { - - private: - const CFactoryTemplate *const m_pTemplate; - - ULONG m_cRef; - - static int m_cLocked; - public: - CClassFactory(const CFactoryTemplate *); - - // IUnknown - STDMETHODIMP QueryInterface(REFIID riid, void ** ppv); - STDMETHODIMP_(ULONG)AddRef(); - STDMETHODIMP_(ULONG)Release(); - - // IClassFactory - STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void **pv); - STDMETHODIMP LockServer(BOOL fLock); - - // allow DLLGetClassObject to know about global server lock status - static BOOL IsLocked() { - return (m_cLocked > 0); - }; -}; - -// process-wide dll locked state -int CClassFactory::m_cLocked = 0; - -CClassFactory::CClassFactory(const CFactoryTemplate *pTemplate) -: CBaseObject(NAME("Class Factory")) -, m_cRef(0) -, m_pTemplate(pTemplate) { -} - - -STDMETHODIMP -CClassFactory::QueryInterface(REFIID riid,void **ppv) { - CheckPointer(ppv,E_POINTER) - ValidateReadWritePtr(ppv,sizeof(PVOID)); - *ppv = NULL; - - // any interface on this object is the object pointer. - if((riid == IID_IUnknown) || (riid == IID_IClassFactory)) { - *ppv = (LPVOID) this; - // AddRef returned interface pointer - ((LPUNKNOWN) *ppv)->AddRef(); - return NOERROR; - } - - return ResultFromScode(E_NOINTERFACE); -} - - -STDMETHODIMP_(ULONG) -CClassFactory::AddRef() { - return ++m_cRef; -} - -STDMETHODIMP_(ULONG) -CClassFactory::Release() { - if(--m_cRef == 0) { - delete this; - return 0; - } - else { - return m_cRef; - } -} - -STDMETHODIMP -CClassFactory::CreateInstance( - LPUNKNOWN pUnkOuter, - REFIID riid, - void **pv) { - CheckPointer(pv,E_POINTER) - ValidateReadWritePtr(pv,sizeof(void *)); - - /* Enforce the normal OLE rules regarding interfaces and delegation */ - - if(pUnkOuter != NULL) { - if(IsEqualIID(riid,IID_IUnknown) == FALSE) { - return ResultFromScode(E_NOINTERFACE); - } - } - - /* Create the new object through the derived class's create function */ - - HRESULT hr = NOERROR; - CUnknown *pObj = m_pTemplate->CreateInstance(pUnkOuter, &hr); - - if(pObj == NULL) { - if(SUCCEEDED(hr)) { - hr = E_OUTOFMEMORY; - } - return hr; - } - - /* Delete the object if we got a construction error */ - - if(FAILED(hr)) { - delete pObj; - return hr; - } - - /* Get a reference counted interface on the object */ - - /* We wrap the non-delegating QI with NDAddRef & NDRelease. */ - /* This protects any outer object from being prematurely */ - /* released by an inner object that may have to be created */ - /* in order to supply the requested interface. */ - pObj->NonDelegatingAddRef(); - hr = pObj->NonDelegatingQueryInterface(riid, pv); - pObj->NonDelegatingRelease(); - - /* Note that if NonDelegatingQueryInterface fails, it will */ - /* not increment the ref count, so the NonDelegatingRelease */ - /* will drop the ref back to zero and the object will "self-*/ - /* destruct". Hence we don't need additional tidy-up code */ - /* to cope with NonDelegatingQueryInterface failing. */ - - if(SUCCEEDED(hr)) { - ASSERT(*pv); - } - - return hr; -} - -STDMETHODIMP -CClassFactory::LockServer(BOOL fLock) { - if(fLock) { - m_cLocked++; - } - else { - m_cLocked--; - } - return NOERROR; -} - - -// --- COM entrypoints ----------------------------------------- - -//called by COM to get the class factory object for a given class -STDAPI -DllGetClassObject( - REFCLSID rClsID, - REFIID riid, - void **pv) { - if(!(riid == IID_IUnknown) && !(riid == IID_IClassFactory)) { - return E_NOINTERFACE; - } - - // traverse the array of templates looking for one with this - // class id - for(int i = 0; i < g_cTemplates; i++) { - const CFactoryTemplate * pT = &g_Templates[i]; - if(pT->IsClassID(rClsID)) { - - // found a template - make a class factory based on this - // template - - *pv = (LPVOID) (LPUNKNOWN) new CClassFactory(pT); - if(*pv == NULL) { - return E_OUTOFMEMORY; - } - ((LPUNKNOWN)*pv)->AddRef(); - return NOERROR; - } - } - return CLASS_E_CLASSNOTAVAILABLE; -} - -// -// Call any initialization routines -// -void -DllInitClasses(BOOL bLoading) { - int i; - - // traverse the array of templates calling the init routine - // if they have one - for(i = 0; i < g_cTemplates; i++) { - const CFactoryTemplate * pT = &g_Templates[i]; - if(pT->m_lpfnInit != NULL) { - (*pT->m_lpfnInit)(bLoading, pT->m_ClsID); - } - } - -} - -// called by COM to determine if this dll can be unloaded -// return ok unless there are outstanding objects or a lock requested -// by IClassFactory::LockServer -// -// CClassFactory has a static function that can tell us about the locks, -// and CCOMObject has a static function that can tell us about the active -// object count -STDAPI -DllCanUnloadNow() { - DbgLog((LOG_MEMORY,2,TEXT("DLLCanUnloadNow called - IsLocked = %d, Active objects = %d"), - CClassFactory::IsLocked(), - CBaseObject::ObjectsActive())); - - if(CClassFactory::IsLocked() || CBaseObject::ObjectsActive()) { - return S_FALSE; - } - else { - return S_OK; - } -} - - -// --- standard WIN32 entrypoints -------------------------------------- - - -extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID); - -BOOL WINAPI -DllEntryPoint(HINSTANCE hInstance, ULONG ulReason, LPVOID pv) { -#ifdef DEBUG - extern bool g_fDbgInDllEntryPoint; - g_fDbgInDllEntryPoint = true; -#endif - - switch(ulReason) { - - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hInstance); -#ifdef DEBUG - DbgInitialise(hInstance); -#endif - - { - // The platform identifier is used to work out whether - // full unicode support is available or not. Hence the - // default will be the lowest common denominator - i.e. N/A - g_amPlatform = VER_PLATFORM_WIN32_WINDOWS; // win95 assumed in case GetVersionEx fails - - g_osInfo.dwOSVersionInfoSize = sizeof(g_osInfo); - if(GetVersionEx(&g_osInfo)) { - g_amPlatform = g_osInfo.dwPlatformId; - } - else { - DbgLog((LOG_ERROR, 1, TEXT("Failed to get the OS platform, assuming Win95"))); - } - } - - g_hInst = hInstance; - DllInitClasses(TRUE); - break; - - case DLL_PROCESS_DETACH: - DllInitClasses(FALSE); - -#ifdef DEBUG - if(CBaseObject::ObjectsActive()) { - DbgSetModuleLevel(LOG_MEMORY, 2); - TCHAR szInfo[512]; - extern TCHAR m_ModuleName[]; // Cut down module name - - TCHAR FullName[_MAX_PATH]; // Load the full path and module name - TCHAR *pName; // Searches from the end for a backslash - - GetModuleFileName(NULL,FullName,_MAX_PATH); - pName = _tcsrchr(FullName,'\\'); - if(pName == NULL) { - pName = FullName; - } - else { - pName++; - } - - DWORD cch = wsprintf(szInfo, TEXT("Executable: %s Pid %x Tid %x. "), - pName, GetCurrentProcessId(), GetCurrentThreadId()); - - wsprintf(szInfo+cch, TEXT("Module %s, %d objects left active!"), - m_ModuleName, CBaseObject::ObjectsActive()); - DbgAssert(szInfo, TEXT(__FILE__),__LINE__); - - // If running remotely wait for the Assert to be acknowledged - // before dumping out the object register - DbgDumpObjectRegister(); - } - - DbgTerminate(); -#endif - break; - } - -#ifdef DEBUG - g_fDbgInDllEntryPoint = false; -#endif - return TRUE; -} - - - diff --git a/src/BaseClasses/dllsetup.cpp b/src/BaseClasses/dllsetup.cpp deleted file mode 100644 index 3a0be6f1ab..0000000000 --- a/src/BaseClasses/dllsetup.cpp +++ /dev/null @@ -1,651 +0,0 @@ -//------------------------------------------------------------------------------ -// File: DllSetup.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include - -//--------------------------------------------------------------------------- -// defines - -#define MAX_KEY_LEN 260 - - -//--------------------------------------------------------------------------- -// externally defined functions/variable - -extern int g_cTemplates; -extern CFactoryTemplate g_Templates[]; - -//--------------------------------------------------------------------------- -// -// EliminateSubKey -// -// Try to enumerate all keys under this one. -// if we find anything, delete it completely. -// Otherwise just delete it. -// -// note - this was pinched/duplicated from -// Filgraph\Mapper.cpp - so should it be in -// a lib somewhere? -// -//--------------------------------------------------------------------------- - -STDAPI -EliminateSubKey( HKEY hkey, LPTSTR strSubKey ) { - HKEY hk; - if(0 == lstrlen(strSubKey)) { - // defensive approach - return E_FAIL; - } - - LONG lreturn = RegOpenKeyEx(hkey - , strSubKey - , 0 - , MAXIMUM_ALLOWED - , &hk); - - ASSERT(lreturn == ERROR_SUCCESS - || lreturn == ERROR_FILE_NOT_FOUND - || lreturn == ERROR_INVALID_HANDLE); - - if(ERROR_SUCCESS == lreturn) { - // Keep on enumerating the first (zero-th) - // key and deleting that - - for(; ;) { - TCHAR Buffer[MAX_KEY_LEN]; - DWORD dw = MAX_KEY_LEN; - FILETIME ft; - - lreturn = RegEnumKeyEx(hk - , 0 - , Buffer - , &dw - , NULL - , NULL - , NULL - , &ft); - - ASSERT(lreturn == ERROR_SUCCESS - || lreturn == ERROR_NO_MORE_ITEMS); - - if(ERROR_SUCCESS == lreturn) { - EliminateSubKey(hk, Buffer); - } - else { - break; - } - } - - RegCloseKey(hk); - RegDeleteKey(hkey, strSubKey); - } - - return NOERROR; -} - - -//--------------------------------------------------------------------------- -// -// AMovieSetupRegisterServer() -// -// registers specfied file "szFileName" as server for -// CLSID "clsServer". A description is also required. -// The ThreadingModel and ServerType are optional, as -// they default to InprocServer32 (i.e. dll) and Both. -// -//--------------------------------------------------------------------------- - -STDAPI -AMovieSetupRegisterServer( CLSID clsServer - , LPCWSTR szDescription - , LPCWSTR szFileName - , LPCWSTR szThreadingModel = L"Both" - , LPCWSTR szServerType = L"InprocServer32" ) { - // temp buffer - // - TCHAR achTemp[MAX_PATH]; - - // convert CLSID uuid to string and write - // out subkey as string - CLSID\{} - // - OLECHAR szCLSID[CHARS_IN_GUID]; - HRESULT hr = StringFromGUID2(clsServer - , szCLSID - , CHARS_IN_GUID); - ASSERT(SUCCEEDED(hr)); - - // create key - // - HKEY hkey; - wsprintf(achTemp, TEXT("CLSID\\%ls"), szCLSID); - LONG lreturn = RegCreateKey(HKEY_CLASSES_ROOT - , (LPCTSTR)achTemp - , &hkey); - if(ERROR_SUCCESS != lreturn) { - return AmHresultFromWin32(lreturn); - } - - // set description string - // - - wsprintf(achTemp, TEXT("%ls"), szDescription); - lreturn = RegSetValue(hkey - , (LPCTSTR)NULL - , REG_SZ - , achTemp - , sizeof(achTemp)/sizeof(achTemp[0])); - if(ERROR_SUCCESS != lreturn) { - RegCloseKey(hkey); - return AmHresultFromWin32(lreturn); - } - - // create CLSID\\{"CLSID"}\\"ServerType" key, - // using key to CLSID\\{"CLSID"} passed back by - // last call to RegCreateKey(). - // - HKEY hsubkey; - - wsprintf(achTemp, TEXT("%ls"), szServerType); - lreturn = RegCreateKey(hkey - , achTemp - , &hsubkey); - if(ERROR_SUCCESS != lreturn) { - RegCloseKey(hkey); - return AmHresultFromWin32(lreturn); - } - - // set Server string - // - wsprintf(achTemp, TEXT("%ls"), szFileName); - lreturn = RegSetValue(hsubkey - , (LPCTSTR)NULL - , REG_SZ - , (LPCTSTR)achTemp - , sizeof(TCHAR) * (lstrlen(achTemp)+1)); - if(ERROR_SUCCESS != lreturn) { - RegCloseKey(hkey); - RegCloseKey(hsubkey); - return AmHresultFromWin32(lreturn); - } - - wsprintf(achTemp, TEXT("%ls"), szThreadingModel); - lreturn = RegSetValueEx(hsubkey - , TEXT("ThreadingModel") - , 0L - , REG_SZ - , (CONST BYTE *)achTemp - , sizeof(TCHAR) * (lstrlen(achTemp)+1)); - - // close hkeys - // - RegCloseKey(hkey); - RegCloseKey(hsubkey); - - // and return - // - return HRESULT_FROM_WIN32(lreturn); - -} - - -//--------------------------------------------------------------------------- -// -// AMovieSetupUnregisterServer() -// -// default ActiveMovie dll setup function -// - to use must be called from an exported -// function named DllRegisterServer() -// -//--------------------------------------------------------------------------- - -STDAPI -AMovieSetupUnregisterServer( CLSID clsServer ) { - // convert CLSID uuid to string and write - // out subkey CLSID\{} - // - OLECHAR szCLSID[CHARS_IN_GUID]; - HRESULT hr = StringFromGUID2(clsServer - , szCLSID - , CHARS_IN_GUID); - ASSERT(SUCCEEDED(hr)); - - TCHAR achBuffer[MAX_KEY_LEN]; - wsprintf(achBuffer, TEXT("CLSID\\%ls"), szCLSID); - - // delete subkey - // - - hr = EliminateSubKey(HKEY_CLASSES_ROOT, achBuffer); - ASSERT(SUCCEEDED(hr)); - - // return - // - return NOERROR; -} - - -//--------------------------------------------------------------------------- -// -// AMovieSetupRegisterFilter through IFilterMapper2 -// -//--------------------------------------------------------------------------- - -STDAPI -AMovieSetupRegisterFilter2( const AMOVIESETUP_FILTER * const psetupdata - , IFilterMapper2 * pIFM2 - , BOOL bRegister ) { - DbgLog((LOG_TRACE, 3, TEXT("= AMovieSetupRegisterFilter"))); - - // check we've got data - // - if(NULL == psetupdata) return S_FALSE; - - - // unregister filter - // (as pins are subkeys of filter's CLSID key - // they do not need to be removed separately). - // - DbgLog((LOG_TRACE, 3, TEXT("= = unregister filter"))); - HRESULT hr = pIFM2->UnregisterFilter(0, // default category - 0, // default instance name - *psetupdata->clsID); - - - if(bRegister) { - REGFILTER2 rf2; - rf2.dwVersion = 1; - rf2.dwMerit = psetupdata->dwMerit; - rf2.cPins = psetupdata->nPins; - rf2.rgPins = psetupdata->lpPin; - - // register filter - // - DbgLog((LOG_TRACE, 3, TEXT("= = register filter"))); - hr = pIFM2->RegisterFilter(*psetupdata->clsID - , psetupdata->strName - , 0 // moniker - , 0 // category - , NULL // instance - , &rf2); - } - - // handle one acceptable "error" - that - // of filter not being registered! - // (couldn't find a suitable #define'd - // name for the error!) - // - if(0x80070002 == hr) - return NOERROR; - else - return hr; -} - - -//--------------------------------------------------------------------------- -// -// RegisterAllServers() -// -//--------------------------------------------------------------------------- - -STDAPI -RegisterAllServers( LPCWSTR szFileName, BOOL bRegister ) { - HRESULT hr = NOERROR; - - for(int i = 0; i < g_cTemplates; i++) { - // get i'th template - // - const CFactoryTemplate *pT = &g_Templates[i]; - - DbgLog((LOG_TRACE, 2, TEXT("- - register %ls"), - (LPCWSTR)pT->m_Name )); - - // register CLSID and InprocServer32 - // - if(bRegister) { - hr = AMovieSetupRegisterServer(*(pT->m_ClsID) - , (LPCWSTR)pT->m_Name - , szFileName); - } - else { - hr = AMovieSetupUnregisterServer(*(pT->m_ClsID)); - } - - // check final error for this pass - // and break loop if we failed - // - if(FAILED(hr)) - break; - } - - return hr; -} - - -//--------------------------------------------------------------------------- -// -// AMovieDllRegisterServer2() -// -// default ActiveMovie dll setup function -// - to use must be called from an exported -// function named DllRegisterServer() -// -// this function is table driven using the -// static members of the CFactoryTemplate -// class defined in the dll. -// -// it registers the Dll as the InprocServer32 -// and then calls the IAMovieSetup.Register -// method. -// -//--------------------------------------------------------------------------- - -STDAPI -AMovieDllRegisterServer2( BOOL bRegister ) { - HRESULT hr = NOERROR; - - DbgLog((LOG_TRACE, 2, TEXT("AMovieDllRegisterServer2()"))); - - // get file name (where g_hInst is the - // instance handle of the filter dll) - // - WCHAR achFileName[MAX_PATH]; - - // WIN95 doesn't support GetModuleFileNameW - // - { - char achTemp[MAX_PATH]; - - DbgLog((LOG_TRACE, 2, TEXT("- get module file name"))); - - // g_hInst handle is set in our dll entry point. Make sure - // DllEntryPoint in dllentry.cpp is called - ASSERT(g_hInst != 0); - - if(0 == GetModuleFileNameA(g_hInst - , achTemp - , sizeof(achTemp))) { - // we've failed! - DWORD dwerr = GetLastError(); - return AmHresultFromWin32(dwerr); - } - - MultiByteToWideChar(CP_ACP - , 0L - , achTemp - , lstrlenA(achTemp) + 1 - , achFileName - , sizeof(achFileName)/sizeof(TCHAR)); - } - - // - // first registering, register all OLE servers - // - if(bRegister) { - DbgLog((LOG_TRACE, 2, TEXT("- register OLE Servers"))); - hr = RegisterAllServers(achFileName, TRUE); - } - - // - // next, register/unregister all filters - // - - if(SUCCEEDED(hr)) { - // init is ref counted so call just in case - // we're being called cold. - // - DbgLog((LOG_TRACE, 2, TEXT("- CoInitialize"))); - hr = CoInitialize((LPVOID)NULL); - ASSERT(SUCCEEDED(hr)); - - // get hold of IFilterMapper2 - // - DbgLog((LOG_TRACE, 2, TEXT("- obtain IFilterMapper2"))); - IFilterMapper2 *pIFM2 = 0; - IFilterMapper *pIFM = 0; - hr = CoCreateInstance(CLSID_FilterMapper2 - , NULL - , CLSCTX_INPROC_SERVER - , IID_IFilterMapper2 - , (void **)&pIFM2); - if(FAILED(hr)) { - DbgLog((LOG_TRACE, 2, TEXT("- trying IFilterMapper instead"))); - - hr = CoCreateInstance(CLSID_FilterMapper, - NULL, - CLSCTX_INPROC_SERVER, - IID_IFilterMapper, - (void **)&pIFM); - } - if(SUCCEEDED(hr)) { - // scan through array of CFactoryTemplates - // registering servers and filters. - // - DbgLog((LOG_TRACE, 2, TEXT("- register Filters"))); - for(int i = 0; i < g_cTemplates; i++) { - // get i'th template - // - const CFactoryTemplate *pT = &g_Templates[i]; - - if(NULL != pT->m_pAMovieSetup_Filter) { - DbgLog((LOG_TRACE, 2, TEXT("- - register %ls"), (LPCWSTR)pT->m_Name )); - - if(pIFM2) { - hr = AMovieSetupRegisterFilter2(pT->m_pAMovieSetup_Filter, pIFM2, bRegister); - } - else { - hr = AMovieSetupRegisterFilter(pT->m_pAMovieSetup_Filter, pIFM, bRegister); - } - } - - // check final error for this pass - // and break loop if we failed - // - if(FAILED(hr)) - break; - } - - // release interface - // - if(pIFM2) - pIFM2->Release(); - else - pIFM->Release(); - - } - - // and clear up - // - CoFreeUnusedLibraries(); - CoUninitialize(); - } - - // - // if unregistering, unregister all OLE servers - // - if(SUCCEEDED(hr) && !bRegister) { - DbgLog((LOG_TRACE, 2, TEXT("- register OLE Servers"))); - hr = RegisterAllServers(achFileName, FALSE); - } - - DbgLog((LOG_TRACE, 2, TEXT("- return %0x"), hr)); - return hr; -} - - -//--------------------------------------------------------------------------- -// -// AMovieDllRegisterServer() -// -// default ActiveMovie dll setup function -// - to use must be called from an exported -// function named DllRegisterServer() -// -// this function is table driven using the -// static members of the CFactoryTemplate -// class defined in the dll. -// -// it registers the Dll as the InprocServer32 -// and then calls the IAMovieSetup.Register -// method. -// -//--------------------------------------------------------------------------- - - -STDAPI -AMovieDllRegisterServer( void ) { - HRESULT hr = NOERROR; - - // get file name (where g_hInst is the - // instance handle of the filter dll) - // - WCHAR achFileName[MAX_PATH]; - - { - // WIN95 doesn't support GetModuleFileNameW - // - char achTemp[MAX_PATH]; - - if(0 == GetModuleFileNameA(g_hInst - , achTemp - , sizeof(achTemp))) { - // we've failed! - DWORD dwerr = GetLastError(); - return AmHresultFromWin32(dwerr); - } - - MultiByteToWideChar(CP_ACP - , 0L - , achTemp - , lstrlenA(achTemp) + 1 - , achFileName - , sizeof(achFileName)/sizeof(TCHAR)); - } - - // scan through array of CFactoryTemplates - // registering servers and filters. - // - for(int i = 0; i < g_cTemplates; i++) { - // get i'th template - // - const CFactoryTemplate *pT = &g_Templates[i]; - - // register CLSID and InprocServer32 - // - hr = AMovieSetupRegisterServer(*(pT->m_ClsID) - , (LPCWSTR)pT->m_Name - , achFileName); - - // instantiate all servers and get hold of - // IAMovieSetup, if implemented, and call - // IAMovieSetup.Register() method - // - if(SUCCEEDED(hr) && (NULL != pT->m_lpfnNew)) { - // instantiate object - // - PAMOVIESETUP psetup; - hr = CoCreateInstance(*(pT->m_ClsID) - , 0 - , CLSCTX_INPROC_SERVER - , IID_IAMovieSetup - , reinterpret_cast(&psetup)); - if(SUCCEEDED(hr)) { - hr = psetup->Unregister(); - if(SUCCEEDED(hr)) - hr = psetup->Register(); - psetup->Release(); - } - else { - if((E_NOINTERFACE == hr ) - || (VFW_E_NEED_OWNER == hr )) - hr = NOERROR; - } - } - - // check final error for this pass - // and break loop if we failed - // - if(FAILED(hr)) - break; - - } // end-for - - return hr; -} - - -//--------------------------------------------------------------------------- -// -// AMovieDllUnregisterServer() -// -// default ActiveMovie dll uninstall function -// - to use must be called from an exported -// function named DllRegisterServer() -// -// this function is table driven using the -// static members of the CFactoryTemplate -// class defined in the dll. -// -// it calls the IAMovieSetup.Unregister -// method and then unregisters the Dll -// as the InprocServer32 -// -//--------------------------------------------------------------------------- - -STDAPI -AMovieDllUnregisterServer() { - // initialize return code - // - HRESULT hr = NOERROR; - - // scan through CFactory template and unregister - // all OLE servers and filters. - // - for(int i = g_cTemplates; i--;) { - // get i'th template - // - const CFactoryTemplate *pT = &g_Templates[i]; - - // check method exists - // - if(NULL != pT->m_lpfnNew) { - // instantiate object - // - PAMOVIESETUP psetup; - hr = CoCreateInstance(*(pT->m_ClsID) - , 0 - , CLSCTX_INPROC_SERVER - , IID_IAMovieSetup - , reinterpret_cast(&psetup)); - if(SUCCEEDED(hr)) { - hr = psetup->Unregister(); - psetup->Release(); - } - else { - if((E_NOINTERFACE == hr ) - || (VFW_E_NEED_OWNER == hr )) - hr = NOERROR; - } - } - - // unregister CLSID and InprocServer32 - // - if(SUCCEEDED(hr)) { - hr = AMovieSetupUnregisterServer(*(pT->m_ClsID)); - } - - // check final error for this pass - // and break loop if we failed - // - if(FAILED(hr)) - break; - } - - return hr; -} - diff --git a/src/BaseClasses/dllsetup.h b/src/BaseClasses/dllsetup.h deleted file mode 100644 index 310d6717be..0000000000 --- a/src/BaseClasses/dllsetup.h +++ /dev/null @@ -1,46 +0,0 @@ -//------------------------------------------------------------------------------ -// File: DllSetup.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// To be self registering, OLE servers must -// export functions named DllRegisterServer -// and DllUnregisterServer. To allow use of -// custom and default implementations the -// defaults are named AMovieDllRegisterServer -// and AMovieDllUnregisterServer. -// -// To the use the default implementation you -// must provide stub functions. -// -// i.e. STDAPI DllRegisterServer() -// { -// return AMovieDllRegisterServer(); -// } -// -// STDAPI DllUnregisterServer() -// { -// return AMovieDllUnregisterServer(); -// } -// -// -// AMovieDllRegisterServer calls IAMovieSetup.Register(), and -// AMovieDllUnregisterServer calls IAMovieSetup.Unregister(). - -STDAPI AMovieDllRegisterServer2( BOOL ); -STDAPI AMovieDllRegisterServer(); -STDAPI AMovieDllUnregisterServer(); - -// helper functions -STDAPI EliminateSubKey( HKEY, LPTSTR ); - - -STDAPI -AMovieSetupRegisterFilter2( const AMOVIESETUP_FILTER * const psetupdata - , IFilterMapper2 * pIFM2 - , BOOL bRegister ); - diff --git a/src/BaseClasses/dsschedule.h b/src/BaseClasses/dsschedule.h deleted file mode 100644 index eddb8cd498..0000000000 --- a/src/BaseClasses/dsschedule.h +++ /dev/null @@ -1,132 +0,0 @@ -//------------------------------------------------------------------------------ -// File: DSSchedule.h (replaces DX8's schedule.h) -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1996-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __CAMSchedule__ -#define __CAMSchedule__ - -class CAMSchedule : private CBaseObject -{ -public: - virtual ~CAMSchedule(); - // ev is the event we should fire if the advise time needs re-evaluating - CAMSchedule( HANDLE ev ); - - DWORD GetAdviseCount(); - REFERENCE_TIME GetNextAdviseTime(); - - // We need a method for derived classes to add advise packets, we return the cookie - DWORD_PTR AddAdvisePacket( const REFERENCE_TIME & time1, const REFERENCE_TIME & time2, HANDLE h, BOOL periodic ); - // And a way to cancel - HRESULT Unadvise(DWORD_PTR dwAdviseCookie); - - // Tell us the time please, and we'll dispatch the expired events. We return the time of the next event. - // NB: The time returned will be "useless" if you start adding extra Advises. But that's the problem of - // whoever is using this helper class (typically a clock). - REFERENCE_TIME Advise( const REFERENCE_TIME & rtTime ); - - // Get the event handle which will be set if advise time requires re-evaluation. - HANDLE GetEvent() const { return m_ev; } - -private: - // We define the nodes that will be used in our singly linked list - // of advise packets. The list is ordered by time, with the - // elements that will expire first at the front. - class CAdvisePacket - { - public: - CAdvisePacket() - {} - - CAdvisePacket * m_next; - DWORD_PTR m_dwAdviseCookie; - REFERENCE_TIME m_rtEventTime; // Time at which event should be set - REFERENCE_TIME m_rtPeriod; // Periodic time - HANDLE m_hNotify; // Handle to event or semephore - BOOL m_bPeriodic; // TRUE => Periodic event - - CAdvisePacket( CAdvisePacket * next, LONGLONG time ) : m_next(next), m_rtEventTime(time) - {} - - void InsertAfter( CAdvisePacket * p ) - { - p->m_next = m_next; - m_next = p; - } - - int IsZ() const // That is, is it the node that represents the end of the list - { - return m_next == 0; - } - - CAdvisePacket * RemoveNext() - { - CAdvisePacket *const next = m_next; - CAdvisePacket *const new_next = next->m_next; - m_next = new_next; - return next; - } - - void DeleteNext() - { - delete RemoveNext(); - } - - CAdvisePacket * Next() const - { - CAdvisePacket * result = m_next; - if (result->IsZ()) result = 0; - return result; - } - - DWORD_PTR Cookie() const - { - return m_dwAdviseCookie; - } - }; - - // Structure is: - // head -> elmt1 -> elmt2 -> z -> null - // So an empty list is: head -> z -> null - // Having head & z as links makes insertaion, - // deletion and shunting much easier. - CAdvisePacket head, z; // z is both a tail and a sentry - - volatile DWORD_PTR m_dwNextCookie; // Strictly increasing - volatile DWORD m_dwAdviseCount; // Number of elements on list - - CCritSec m_Serialize; - - // AddAdvisePacket: adds the packet, returns the cookie (0 if failed) - DWORD_PTR AddAdvisePacket( CAdvisePacket * pPacket ); - // Event that we should set if the packed added above will be the next to fire. - const HANDLE m_ev; - - // A Shunt is where we have changed the first element in the - // list and want it re-evaluating (i.e. repositioned) in - // the list. - void ShuntHead(); - - // Rather than delete advise packets, we cache them for future use - CAdvisePacket * m_pAdviseCache; - DWORD m_dwCacheCount; - enum { dwCacheMax = 5 }; // Don't bother caching more than five - - void Delete( CAdvisePacket * pLink );// This "Delete" will cache the Link - -// Attributes and methods for debugging -public: -#ifdef DEBUG - void DumpLinkedList(); -#else - void DumpLinkedList() {} -#endif - -}; - -#endif // __CAMSchedule__ diff --git a/src/BaseClasses/fourcc.h b/src/BaseClasses/fourcc.h deleted file mode 100644 index 5f9d66e120..0000000000 --- a/src/BaseClasses/fourcc.h +++ /dev/null @@ -1,100 +0,0 @@ -//------------------------------------------------------------------------------ -// File: FourCC.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// FOURCCMap -// -// provides a mapping between old-style multimedia format DWORDs -// and new-style GUIDs. -// -// A range of 4 billion GUIDs has been allocated to ensure that this -// mapping can be done straightforwardly one-to-one in both directions. -// -// January 95 - - -#ifndef __FOURCC__ -#define __FOURCC__ - - -// Multimedia format types are marked with DWORDs built from four 8-bit -// chars and known as FOURCCs. New multimedia AM_MEDIA_TYPE definitions include -// a subtype GUID. In order to simplify the mapping, GUIDs in the range: -// XXXXXXXX-0000-0010-8000-00AA00389B71 -// are reserved for FOURCCs. - -class FOURCCMap : public GUID -{ - -public: - FOURCCMap(); - FOURCCMap(DWORD Fourcc); - FOURCCMap(const GUID *); - - DWORD GetFOURCC(void); - void SetFOURCC(DWORD fourcc); - void SetFOURCC(const GUID *); - -private: - void InitGUID(); -}; - -#define GUID_Data2 0 -#define GUID_Data3 0x10 -#define GUID_Data4_1 0xaa000080 -#define GUID_Data4_2 0x719b3800 - -inline void -FOURCCMap::InitGUID() { - Data2 = GUID_Data2; - Data3 = GUID_Data3; - ((DWORD *)Data4)[0] = GUID_Data4_1; - ((DWORD *)Data4)[1] = GUID_Data4_2; -} - -inline -FOURCCMap::FOURCCMap() { - InitGUID(); - SetFOURCC( DWORD(0)); -} - -inline -FOURCCMap::FOURCCMap(DWORD fourcc) -{ - InitGUID(); - SetFOURCC(fourcc); -} - -inline -FOURCCMap::FOURCCMap(const GUID * pGuid) -{ - InitGUID(); - SetFOURCC(pGuid); -} - -inline void -FOURCCMap::SetFOURCC(const GUID * pGuid) -{ - FOURCCMap * p = (FOURCCMap*) pGuid; - SetFOURCC(p->GetFOURCC()); -} - -inline void -FOURCCMap::SetFOURCC(DWORD fourcc) -{ - Data1 = fourcc; -} - -inline DWORD -FOURCCMap::GetFOURCC(void) -{ - return Data1; -} - -#endif /* __FOURCC__ */ - diff --git a/src/BaseClasses/measure.h b/src/BaseClasses/measure.h deleted file mode 100644 index a34fb62a0e..0000000000 --- a/src/BaseClasses/measure.h +++ /dev/null @@ -1,222 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Measure.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -/* - The idea is to pepper the source code with interesting measurements and - have the last few thousand of these recorded in a circular buffer that - can be post-processed to give interesting numbers. - - WHAT THE LOG LOOKS LIKE: - - Time (sec) Type Delta Incident_Name - 0.055,41 NOTE -. Incident Nine - Another note - 0.055,42 NOTE 0.000,01 Incident Nine - Another note - 0.055,44 NOTE 0.000,02 Incident Nine - Another note - 0.055,45 STOP -. Incident Eight - Also random - 0.055,47 START -. Incident Seven - Random - 0.055,49 NOTE 0.000,05 Incident Nine - Another note - ------- ---------------- - 0.125,60 STOP 0.000,03 Msr_Stop - 0.125,62 START -. Msr_Start - 0.125,63 START -. Incident Two - Start/Stop - 0.125,65 STOP 0.000,03 Msr_Start - 0.125,66 START -. Msr_Stop - 0.125,68 STOP 0.000,05 Incident Two - Start/Stop - 0.125,70 STOP 0.000,04 Msr_Stop - 0.125,72 START -. Msr_Start - 0.125,73 START -. Incident Two - Start/Stop - 0.125,75 STOP 0.000,03 Msr_Start - 0.125,77 START -. Msr_Stop - 0.125,78 STOP 0.000,05 Incident Two - Start/Stop - 0.125,80 STOP 0.000,03 Msr_Stop - 0.125,81 NOTE -. Incident Three - single Note - 0.125,83 START -. Incident Four - Start, no stop - 0.125,85 START -. Incident Five - Single Start/Stop - 0.125,87 STOP 0.000,02 Incident Five - Single Start/Stop - -Number Average StdDev Smallest Largest Incident_Name - 10 0.000,58 0.000,10 0.000,55 0.000,85 Incident One - Note - 50 0.000,05 0.000,00 0.000,05 0.000,05 Incident Two - Start/Stop - 1 -. -. -. -. Incident Three - single Note - 0 -. -. -. -. Incident Four - Start, no stop - 1 0.000,02 -. 0.000,02 0.000,02 Incident Five - Single Start/Stop - 0 -. -. -. -. Incident Six - zero occurrences - 100 0.000,25 0.000,12 0.000,02 0.000,62 Incident Seven - Random - 100 0.000,79 0.000,48 0.000,02 0.001,92 Incident Eight - Also random - 5895 0.000,01 0.000,01 0.000,01 0.000,56 Incident Nine - Another note - 10 0.000,03 0.000,00 0.000,03 0.000,04 Msr_Note - 50 0.000,03 0.000,00 0.000,03 0.000,04 Msr_Start - 50 0.000,04 0.000,03 0.000,03 0.000,31 Msr_Stop - - WHAT IT MEANS: - The log shows what happened and when. Each line shows the time at which - something happened (see WHAT YOU CODE below) what it was that happened - and (if approporate) the time since the corresponding previous event - (that's the delta column). - - The statistics show how many times each event occurred, what the average - delta time was, also the standard deviation, largest and smalles delta. - - WHAT YOU CODE: - - Before anything else executes: - register your ids - - int id1 = Msr_Register("Incident One - Note"); - int id2 = Msr_Register("Incident Two - Start/Stop"); - int id3 = Msr_Register("Incident Three - single Note"); - etc. - - At interesting moments: - - // To measure a repetitive event - e.g. end of bitblt to screen - Msr_Note(Id9); // e.g. "video frame hiting the screen NOW!" - - or - - // To measure an elapsed time e.g. time taken to decode an MPEG B-frame - Msr_Start(Id2); // e.g. "Starting to decode MPEG B-frame" - . . . - MsrStop(Id2); // "Finished MPEG decode" - - At the end: - - HANDLE hFile; - hFile = CreateFile("Perf.log", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); - Msr_Dump(hFile); // This writes the log out to the file - CloseHandle(hFile); - - or - - Msr_Dump(NULL); // This writes it to DbgLog((LOG_TRACE,0, ... )); - // but if you are writing it out to the debugger - // then the times are probably all garbage because - // the debugger can make things run awfully slow. - - A given id should be used either for start / stop or Note calls. If Notes - are mixed in with Starts and Stops their statistics will be gibberish. - - If you code the calls in upper case i.e. MSR_START(idMunge); then you get - macros which will turn into nothing unless PERF is defined. - - You can reset the statistical counts for a given id by calling Reset(Id). - They are reset by default at the start. - It logs Reset as a special incident, so you can see it in the log. - - The log is a circular buffer in storage (to try to minimise disk I/O). - It overwrites the oldest entries once full. The statistics include ALL - incidents since the last Reset, whether still visible in the log or not. -*/ - -#ifndef __MEASURE__ -#define __MEASURE__ - -#ifdef PERF -#define MSR_INIT() Msr_Init() -#define MSR_TERMINATE() Msr_Terminate() -#define MSR_REGISTER(a) Msr_Register(a) -#define MSR_RESET(a) Msr_Reset(a) -#define MSR_CONTROL(a) Msr_Control(a) -#define MSR_START(a) Msr_Start(a) -#define MSR_STOP(a) Msr_Stop(a) -#define MSR_NOTE(a) Msr_Note(a) -#define MSR_INTEGER(a,b) Msr_Integer(a,b) -#define MSR_DUMP(a) Msr_Dump(a) -#define MSR_DUMPSTATS(a) Msr_DumpStats(a) -#else -#define MSR_INIT() ((void)0) -#define MSR_TERMINATE() ((void)0) -#define MSR_REGISTER(a) 0 -#define MSR_RESET(a) ((void)0) -#define MSR_CONTROL(a) ((void)0) -#define MSR_START(a) ((void)0) -#define MSR_STOP(a) ((void)0) -#define MSR_NOTE(a) ((void)0) -#define MSR_INTEGER(a,b) ((void)0) -#define MSR_DUMP(a) ((void)0) -#define MSR_DUMPSTATS(a) ((void)0) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -// This must be called first - (called by the DllEntry) - -void WINAPI Msr_Init(void); - - -// Call this last to clean up (or just let it fall off the end - who cares?) - -void WINAPI Msr_Terminate(void); - - -// Call this to get an Id for an "incident" that you can pass to Start, Stop or Note -// everything that's logged is called an "incident". - -int WINAPI Msr_Register(LPTSTR Incident); - - -// Reset the statistical counts for an incident - -void WINAPI Msr_Reset(int Id); - - -// Reset all the counts for all incidents -#define MSR_RESET_ALL 0 -#define MSR_PAUSE 1 -#define MSR_RUN 2 - -void WINAPI Msr_Control(int iAction); - - -// log the start of an operation - -void WINAPI Msr_Start(int Id); - - -// log the end of an operation - -void WINAPI Msr_Stop(int Id); - - -// log a one-off or repetitive operation - -void WINAPI Msr_Note(int Id); - - -// log an integer (on which we can see statistics later) -void WINAPI Msr_Integer(int Id, int n); - - -// print out all the vaialable log (it may have wrapped) and then the statistics. -// When the log wraps you lose log but the statistics are still complete. -// hFIle==NULL => use DbgLog -// otherwise hFile must have come from CreateFile or OpenFile. - -void WINAPI Msr_Dump(HANDLE hFile); - - -// just dump the statistics - never mind the log - -void WINAPI Msr_DumpStats(HANDLE hFile); - -// Type definitions in case you want to declare a pointer to the dump functions -// (makes it a trifle easier to do dynamic linking -// i.e. LoadModule, GetProcAddress and call that) - -// Typedefs so can declare MSR_DUMPPROC *MsrDumpStats; or whatever -typedef void WINAPI MSR_DUMPPROC(HANDLE hFile); -typedef void WINAPI MSR_CONTROLPROC(int iAction); - - -#ifdef __cplusplus -} -#endif - -#endif // __MEASURE__ diff --git a/src/BaseClasses/msgthrd.h b/src/BaseClasses/msgthrd.h deleted file mode 100644 index 75ce5cd61d..0000000000 --- a/src/BaseClasses/msgthrd.h +++ /dev/null @@ -1,120 +0,0 @@ -//------------------------------------------------------------------------------ -// File: MsgThrd.h -// -// Desc: DirectShow base classes - provides support for a worker thread -// class to which one can asynchronously post messages. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// Message class - really just a structure. -// -class CMsg { -public: - UINT uMsg; - DWORD dwFlags; - LPVOID lpParam; - CAMEvent *pEvent; - - CMsg(UINT u, DWORD dw, LPVOID lp, CAMEvent *pEvnt) - : uMsg(u), dwFlags(dw), lpParam(lp), pEvent(pEvnt) {} - - CMsg() - : uMsg(0), dwFlags(0L), lpParam(NULL), pEvent(NULL) {} -}; - -// This is the actual thread class. It exports all the usual thread control -// functions. The created thread is different from a normal WIN32 thread in -// that it is prompted to perform particaular tasks by responding to messages -// posted to its message queue. -// -class AM_NOVTABLE CMsgThread { -private: - static DWORD WINAPI DefaultThreadProc(LPVOID lpParam); - DWORD m_ThreadId; - HANDLE m_hThread; - -protected: - - // if you want to override GetThreadMsg to block on other things - // as well as this queue, you need access to this - CGenericList m_ThreadQueue; - CCritSec m_Lock; - HANDLE m_hSem; - LONG m_lWaiting; - -public: - CMsgThread() - : m_ThreadId(0), - m_hThread(NULL), - m_lWaiting(0), - m_hSem(NULL), - // make a list with a cache of 5 items - m_ThreadQueue(NAME("MsgThread list"), 5) - { - } - - ~CMsgThread(); - // override this if you want to block on other things as well - // as the message loop - void virtual GetThreadMsg(CMsg *msg); - - // override this if you want to do something on thread startup - virtual void OnThreadInit() { }; - - BOOL CreateThread(); - - BOOL WaitForThreadExit(LPDWORD lpdwExitCode) { - if (m_hThread != NULL) { - WaitForSingleObject(m_hThread, INFINITE); - return GetExitCodeThread(m_hThread, lpdwExitCode); - } - return FALSE; - } - - DWORD ResumeThread() { - return ::ResumeThread(m_hThread); - } - - DWORD SuspendThread() { - return ::SuspendThread(m_hThread); - } - - int GetThreadPriority() { - return ::GetThreadPriority(m_hThread); - } - - BOOL SetThreadPriority(int nPriority) { - return ::SetThreadPriority(m_hThread, nPriority); - } - - HANDLE GetThreadHandle() { - return m_hThread; - } - - DWORD GetThreadId() { - return m_ThreadId; - } - - - void PutThreadMsg(UINT uMsg, DWORD dwMsgFlags, - LPVOID lpMsgParam, CAMEvent *pEvent = NULL) { - CAutoLock lck(&m_Lock); - CMsg* pMsg = new CMsg(uMsg, dwMsgFlags, lpMsgParam, pEvent); - m_ThreadQueue.AddTail(pMsg); - - if (m_lWaiting != 0) { - ReleaseSemaphore(m_hSem, m_lWaiting, 0); - m_lWaiting = 0; - } - } - - // This is the function prototype of the function that the client - // supplies. It is always called on the created thread, never on - // the creator thread. - // - virtual LRESULT ThreadMessageProc( - UINT uMsg, DWORD dwFlags, LPVOID lpParam, CAMEvent *pEvent) = 0; -}; - diff --git a/src/BaseClasses/mtype.cpp b/src/BaseClasses/mtype.cpp deleted file mode 100644 index a69cac44a5..0000000000 --- a/src/BaseClasses/mtype.cpp +++ /dev/null @@ -1,478 +0,0 @@ -//------------------------------------------------------------------------------ -// File: MType.cpp -// -// Desc: DirectShow base classes - implements a class that holds and -// manages media type information. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// helper class that derived pin objects can use to compare media -// types etc. Has same data members as the struct AM_MEDIA_TYPE defined -// in the streams IDL file, but also has (non-virtual) functions - -#include -#include - -CMediaType::~CMediaType(){ - FreeMediaType(*this); -} - - -CMediaType::CMediaType() -{ - InitMediaType(); -} - - -CMediaType::CMediaType(const GUID * type) -{ - InitMediaType(); - majortype = *type; -} - - -// copy constructor does a deep copy of the format block - -CMediaType::CMediaType(const AM_MEDIA_TYPE& rt, HRESULT* phr) -{ - HRESULT hr = CopyMediaType(this, &rt); - if (FAILED(hr) && (NULL != phr)) { - *phr = hr; - } -} - - -CMediaType::CMediaType(const CMediaType& rt, HRESULT* phr) -{ - HRESULT hr = CopyMediaType(this, &rt); - if (FAILED(hr) && (NULL != phr)) { - *phr = hr; - } -} - - -// this class inherits publicly from AM_MEDIA_TYPE so the compiler could generate -// the following assignment operator itself, however it could introduce some -// memory conflicts and leaks in the process because the structure contains -// a dynamically allocated block (pbFormat) which it will not copy correctly - -CMediaType& -CMediaType::operator=(const AM_MEDIA_TYPE& rt) -{ - Set(rt); - return *this; -} - -CMediaType& -CMediaType::operator=(const CMediaType& rt) -{ - *this = (AM_MEDIA_TYPE &) rt; - return *this; -} - -BOOL -CMediaType::operator == (const CMediaType& rt) const -{ - // I don't believe we need to check sample size or - // temporal compression flags, since I think these must - // be represented in the type, subtype and format somehow. They - // are pulled out as separate flags so that people who don't understand - // the particular format representation can still see them, but - // they should duplicate information in the format block. - - return ((IsEqualGUID(majortype,rt.majortype) == TRUE) && - (IsEqualGUID(subtype,rt.subtype) == TRUE) && - (IsEqualGUID(formattype,rt.formattype) == TRUE) && - (cbFormat == rt.cbFormat) && - ( (cbFormat == 0) || - (memcmp(pbFormat, rt.pbFormat, cbFormat) == 0))); -} - - -BOOL -CMediaType::operator != (const CMediaType& rt) const -{ - /* Check to see if they are equal */ - - if (*this == rt) { - return FALSE; - } - return TRUE; -} - - -HRESULT -CMediaType::Set(const CMediaType& rt) -{ - return Set((AM_MEDIA_TYPE &) rt); -} - - -HRESULT -CMediaType::Set(const AM_MEDIA_TYPE& rt) -{ - if (&rt != this) { - FreeMediaType(*this); - HRESULT hr = CopyMediaType(this, &rt); - if (FAILED(hr)) { - return E_OUTOFMEMORY; - } - } - - return S_OK; -} - - -BOOL -CMediaType::IsValid() const -{ - return (!IsEqualGUID(majortype,GUID_NULL)); -} - - -void -CMediaType::SetType(const GUID* ptype) -{ - majortype = *ptype; -} - - -void -CMediaType::SetSubtype(const GUID* ptype) -{ - subtype = *ptype; -} - - -ULONG -CMediaType::GetSampleSize() const { - if (IsFixedSize()) { - return lSampleSize; - } else { - return 0; - } -} - - -void -CMediaType::SetSampleSize(ULONG sz) { - if (sz == 0) { - SetVariableSize(); - } else { - bFixedSizeSamples = TRUE; - lSampleSize = sz; - } -} - - -void -CMediaType::SetVariableSize() { - bFixedSizeSamples = FALSE; -} - - -void -CMediaType::SetTemporalCompression(BOOL bCompressed) { - bTemporalCompression = bCompressed; -} - -BOOL -CMediaType::SetFormat(BYTE * pformat, ULONG cb) -{ - if (NULL == AllocFormatBuffer(cb)) - return(FALSE); - - ASSERT(pbFormat); - memcpy(pbFormat, pformat, cb); - return(TRUE); -} - - -// set the type of the media type format block, this type defines what you -// will actually find in the format pointer. For example FORMAT_VideoInfo or -// FORMAT_WaveFormatEx. In the future this may be an interface pointer to a -// property set. Before sending out media types this should be filled in. - -void -CMediaType::SetFormatType(const GUID *pformattype) -{ - formattype = *pformattype; -} - - -// reset the format buffer - -void CMediaType::ResetFormatBuffer() -{ - if (cbFormat) { - CoTaskMemFree((PVOID)pbFormat); - } - cbFormat = 0; - pbFormat = NULL; -} - - -// allocate length bytes for the format and return a read/write pointer -// If we cannot allocate the new block of memory we return NULL leaving -// the original block of memory untouched (as does ReallocFormatBuffer) - -BYTE* -CMediaType::AllocFormatBuffer(ULONG length) -{ - ASSERT(length); - - // do the types have the same buffer size - - if (cbFormat == length) { - return pbFormat; - } - - // allocate the new format buffer - - BYTE *pNewFormat = (PBYTE)CoTaskMemAlloc(length); - if (pNewFormat == NULL) { - if (length <= cbFormat) return pbFormat; //reuse the old block anyway. - return NULL; - } - - // delete the old format - - if (cbFormat != 0) { - ASSERT(pbFormat); - CoTaskMemFree((PVOID)pbFormat); - } - - cbFormat = length; - pbFormat = pNewFormat; - return pbFormat; -} - - -// reallocate length bytes for the format and return a read/write pointer -// to it. We keep as much information as we can given the new buffer size -// if this fails the original format buffer is left untouched. The caller -// is responsible for ensuring the size of memory required is non zero - -BYTE* -CMediaType::ReallocFormatBuffer(ULONG length) -{ - ASSERT(length); - - // do the types have the same buffer size - - if (cbFormat == length) { - return pbFormat; - } - - // allocate the new format buffer - - BYTE *pNewFormat = (PBYTE)CoTaskMemAlloc(length); - if (pNewFormat == NULL) { - if (length <= cbFormat) return pbFormat; //reuse the old block anyway. - return NULL; - } - - // copy any previous format (or part of if new is smaller) - // delete the old format and replace with the new one - - if (cbFormat != 0) { - ASSERT(pbFormat); - memcpy(pNewFormat,pbFormat,min(length,cbFormat)); - CoTaskMemFree((PVOID)pbFormat); - } - - cbFormat = length; - pbFormat = pNewFormat; - return pNewFormat; -} - -// initialise a media type structure - -void CMediaType::InitMediaType() -{ - ZeroMemory((PVOID)this, sizeof(*this)); - lSampleSize = 1; - bFixedSizeSamples = TRUE; -} - - -// a partially specified media type can be passed to IPin::Connect -// as a constraint on the media type used in the connection. -// the type, subtype or format type can be null. -BOOL -CMediaType::IsPartiallySpecified(void) const -{ - if ((majortype == GUID_NULL) || - (formattype == GUID_NULL)) { - return TRUE; - } else { - return FALSE; - } -} - -BOOL -CMediaType::MatchesPartial(const CMediaType* ppartial) const -{ - if ((ppartial->majortype != GUID_NULL) && - (majortype != ppartial->majortype)) { - return FALSE; - } - if ((ppartial->subtype != GUID_NULL) && - (subtype != ppartial->subtype)) { - return FALSE; - } - - if (ppartial->formattype != GUID_NULL) { - // if the format block is specified then it must match exactly - if (formattype != ppartial->formattype) { - return FALSE; - } - if (cbFormat != ppartial->cbFormat) { - return FALSE; - } - if ((cbFormat != 0) && - (memcmp(pbFormat, ppartial->pbFormat, cbFormat) != 0)) { - return FALSE; - } - } - - return TRUE; - -} - - - -// general purpose function to delete a heap allocated AM_MEDIA_TYPE structure -// which is useful when calling IEnumMediaTypes::Next as the interface -// implementation allocates the structures which you must later delete -// the format block may also be a pointer to an interface to release - -void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pmt) -{ - // allow NULL pointers for coding simplicity - - if (pmt == NULL) { - return; - } - - FreeMediaType(*pmt); - CoTaskMemFree((PVOID)pmt); -} - - -// this also comes in useful when using the IEnumMediaTypes interface so -// that you can copy a media type, you can do nearly the same by creating -// a CMediaType object but as soon as it goes out of scope the destructor -// will delete the memory it allocated (this takes a copy of the memory) - -AM_MEDIA_TYPE * WINAPI CreateMediaType(AM_MEDIA_TYPE const *pSrc) -{ - ASSERT(pSrc); - - // Allocate a block of memory for the media type - - AM_MEDIA_TYPE *pMediaType = - (AM_MEDIA_TYPE *)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); - - if (pMediaType == NULL) { - return NULL; - } - // Copy the variable length format block - - HRESULT hr = CopyMediaType(pMediaType,pSrc); - if (FAILED(hr)) { - CoTaskMemFree((PVOID)pMediaType); - return NULL; - } - - return pMediaType; -} - - -// Copy 1 media type to another - -HRESULT WINAPI CopyMediaType(AM_MEDIA_TYPE *pmtTarget, const AM_MEDIA_TYPE *pmtSource) -{ - // We'll leak if we copy onto one that already exists - there's one - // case we can check like that - copying to itself. - ASSERT(pmtSource != pmtTarget); - *pmtTarget = *pmtSource; - if (pmtSource->cbFormat != 0) { - ASSERT(pmtSource->pbFormat != NULL); - pmtTarget->pbFormat = (PBYTE)CoTaskMemAlloc(pmtSource->cbFormat); - if (pmtTarget->pbFormat == NULL) { - pmtTarget->cbFormat = 0; - return E_OUTOFMEMORY; - } else { - CopyMemory((PVOID)pmtTarget->pbFormat, (PVOID)pmtSource->pbFormat, - pmtTarget->cbFormat); - } - } - if (pmtTarget->pUnk != NULL) { - pmtTarget->pUnk->AddRef(); - } - - return S_OK; -} - -// Free an existing media type (ie free resources it holds) - -void WINAPI FreeMediaType(AM_MEDIA_TYPE& mt) -{ - if (mt.cbFormat != 0) { - CoTaskMemFree((PVOID)mt.pbFormat); - - // Strictly unnecessary but tidier - mt.cbFormat = 0; - mt.pbFormat = NULL; - } - if (mt.pUnk != NULL) { - mt.pUnk->Release(); - mt.pUnk = NULL; - } -} - -// Initialize a media type from a WAVEFORMATEX - -STDAPI CreateAudioMediaType( - const WAVEFORMATEX *pwfx, - AM_MEDIA_TYPE *pmt, - BOOL bSetFormat -) -{ - pmt->majortype = MEDIATYPE_Audio; - if (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { - pmt->subtype = ((PWAVEFORMATEXTENSIBLE)pwfx)->SubFormat; - } else { - pmt->subtype = FOURCCMap(pwfx->wFormatTag); - } - - pmt->formattype = FORMAT_WaveFormatEx; - pmt->bFixedSizeSamples = TRUE; - pmt->bTemporalCompression = FALSE; - pmt->lSampleSize = pwfx->nBlockAlign; - pmt->pUnk = NULL; - if (bSetFormat) { - if (pwfx->wFormatTag == WAVE_FORMAT_PCM) { - pmt->cbFormat = sizeof(WAVEFORMATEX); - } else { - pmt->cbFormat = sizeof(WAVEFORMATEX) + pwfx->cbSize; - } - pmt->pbFormat = (PBYTE)CoTaskMemAlloc(pmt->cbFormat); - if (pmt->pbFormat == NULL) { - return E_OUTOFMEMORY; - } - if (pwfx->wFormatTag == WAVE_FORMAT_PCM) { - CopyMemory(pmt->pbFormat, pwfx, sizeof(PCMWAVEFORMAT)); - ((WAVEFORMATEX *)pmt->pbFormat)->cbSize = 0; - } else { - CopyMemory(pmt->pbFormat, pwfx, pmt->cbFormat); - } - } - return S_OK; -} - -// eliminate very many spurious warnings from MS compiler -#pragma warning(disable:4514) diff --git a/src/BaseClasses/mtype.h b/src/BaseClasses/mtype.h deleted file mode 100644 index 9bd770a4ea..0000000000 --- a/src/BaseClasses/mtype.h +++ /dev/null @@ -1,89 +0,0 @@ -//------------------------------------------------------------------------------ -// File: MtType.h -// -// Desc: DirectShow base classes - defines a class that holds and manages -// media type information. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __MTYPE__ -#define __MTYPE__ - -/* Helper class that derived pin objects can use to compare media - types etc. Has same data members as the struct AM_MEDIA_TYPE defined - in the streams IDL file, but also has (non-virtual) functions */ - -class CMediaType : public _AMMediaType { - -public: - - ~CMediaType(); - CMediaType(); - CMediaType(const GUID * majortype); - CMediaType(const AM_MEDIA_TYPE&, HRESULT* phr = NULL); - CMediaType(const CMediaType&, HRESULT* phr = NULL); - - CMediaType& operator=(const CMediaType&); - CMediaType& operator=(const AM_MEDIA_TYPE&); - - BOOL operator == (const CMediaType&) const; - BOOL operator != (const CMediaType&) const; - - HRESULT Set(const CMediaType& rt); - HRESULT Set(const AM_MEDIA_TYPE& rt); - - BOOL IsValid() const; - - const GUID *Type() const { return &majortype;} ; - void SetType(const GUID *); - const GUID *Subtype() const { return &subtype;} ; - void SetSubtype(const GUID *); - - BOOL IsFixedSize() const {return bFixedSizeSamples; }; - BOOL IsTemporalCompressed() const {return bTemporalCompression; }; - ULONG GetSampleSize() const; - - void SetSampleSize(ULONG sz); - void SetVariableSize(); - void SetTemporalCompression(BOOL bCompressed); - - // read/write pointer to format - can't change length without - // calling SetFormat, AllocFormatBuffer or ReallocFormatBuffer - - BYTE* Format() const {return pbFormat; }; - ULONG FormatLength() const { return cbFormat; }; - - void SetFormatType(const GUID *); - const GUID *FormatType() const {return &formattype; }; - BOOL SetFormat(BYTE *pFormat, ULONG length); - void ResetFormatBuffer(); - BYTE* AllocFormatBuffer(ULONG length); - BYTE* ReallocFormatBuffer(ULONG length); - - void InitMediaType(); - - BOOL MatchesPartial(const CMediaType* ppartial) const; - BOOL IsPartiallySpecified(void) const; -}; - - -/* General purpose functions to copy and delete a task allocated AM_MEDIA_TYPE - structure which is useful when using the IEnumMediaFormats interface as - the implementation allocates the structures which you must later delete */ - -void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pmt); -AM_MEDIA_TYPE * WINAPI CreateMediaType(AM_MEDIA_TYPE const *pSrc); -HRESULT WINAPI CopyMediaType(AM_MEDIA_TYPE *pmtTarget, const AM_MEDIA_TYPE *pmtSource); -void WINAPI FreeMediaType(AM_MEDIA_TYPE& mt); - -// Initialize a media type from a WAVEFORMATEX - -STDAPI CreateAudioMediaType( - const WAVEFORMATEX *pwfx, - AM_MEDIA_TYPE *pmt, - BOOL bSetFormat); - -#endif /* __MTYPE__ */ - diff --git a/src/BaseClasses/outputq.cpp b/src/BaseClasses/outputq.cpp deleted file mode 100644 index d80d84f45e..0000000000 --- a/src/BaseClasses/outputq.cpp +++ /dev/null @@ -1,790 +0,0 @@ -//------------------------------------------------------------------------------ -// File: OutputQ.cpp -// -// Desc: DirectShow base classes - implements COutputQueue class used by an -// output pin which may sometimes want to queue output samples on a -// separate thread and sometimes call Receive() directly on the input -// pin. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include - - -// -// COutputQueue Constructor : -// -// Determines if a thread is to be created and creates resources -// -// pInputPin - the downstream input pin we're queueing samples to -// -// phr - changed to a failure code if this function fails -// (otherwise unchanges) -// -// bAuto - Ask pInputPin if it can block in Receive by calling -// its ReceiveCanBlock method and create a thread if -// it can block, otherwise not. -// -// bQueue - if bAuto == FALSE then we create a thread if and only -// if bQueue == TRUE -// -// lBatchSize - work in batches of lBatchSize -// -// bBatchEact - Use exact batch sizes so don't send until the -// batch is full or SendAnyway() is called -// -// lListSize - If we create a thread make the list of samples queued -// to the thread have this size cache -// -// dwPriority - If we create a thread set its priority to this -// -COutputQueue::COutputQueue( - IPin *pInputPin, // Pin to send stuff to - HRESULT *phr, // 'Return code' - BOOL bAuto, // Ask pin if queue or not - BOOL bQueue, // Send through queue - LONG lBatchSize, // Batch - BOOL bBatchExact, // Batch exactly to BatchSize - LONG lListSize, - DWORD dwPriority, - bool bFlushingOpt // flushing optimization - ) : m_lBatchSize(lBatchSize), - m_bBatchExact(bBatchExact && (lBatchSize > 1)), - m_hThread(NULL), - m_hSem(NULL), - m_List(NULL), - m_pPin(pInputPin), - m_ppSamples(NULL), - m_lWaiting(0), - m_pInputPin(NULL), - m_bSendAnyway(FALSE), - m_nBatched(0), - m_bFlushing(FALSE), - m_bFlushed(TRUE), - m_bFlushingOpt(bFlushingOpt), - m_bTerminate(FALSE), - m_hEventPop(NULL), - m_hr(S_OK) { - ASSERT(m_lBatchSize > 0); - - - if(FAILED(*phr)) { - return; - } - - // Check the input pin is OK and cache its IMemInputPin interface - - *phr = pInputPin->QueryInterface(IID_IMemInputPin, (void **)&m_pInputPin); - if(FAILED(*phr)) { - return; - } - - // See if we should ask the downstream pin - - if(bAuto) { - HRESULT hr = m_pInputPin->ReceiveCanBlock(); - if(SUCCEEDED(hr)) { - bQueue = hr == S_OK; - } - } - - // Create our sample batch - - m_ppSamples = new PMEDIASAMPLE[m_lBatchSize]; - if(m_ppSamples == NULL) { - *phr = E_OUTOFMEMORY; - return; - } - - // If we're queueing allocate resources - - if(bQueue) { - DbgLog((LOG_TRACE, 2, TEXT("Creating thread for output pin"))); - m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL); - if(m_hSem == NULL) { - DWORD dwError = GetLastError(); - *phr = AmHresultFromWin32(dwError); - return; - } - m_List = new CSampleList(NAME("Sample Queue List"), - lListSize, - FALSE // No lock - ); - if(m_List == NULL) { - *phr = E_OUTOFMEMORY; - return; - } - - - DWORD dwThreadId; - m_hThread = CreateThread(NULL, - 0, - InitialThreadProc, - (LPVOID)this, - 0, - &dwThreadId); - if(m_hThread == NULL) { - DWORD dwError = GetLastError(); - *phr = AmHresultFromWin32(dwError); - return; - } - SetThreadPriority(m_hThread, dwPriority); - } - else { - DbgLog((LOG_TRACE, 2, TEXT("Calling input pin directly - no thread"))); - } -} - -// -// COutputQueuee Destructor : -// -// Free all resources - -// -// Thread, -// Batched samples -// -COutputQueue::~COutputQueue() { - DbgLog((LOG_TRACE, 3, TEXT("COutputQueue::~COutputQueue"))); - /* Free our pointer */ - if(m_pInputPin != NULL) { - m_pInputPin->Release(); - } - if(m_hThread != NULL) { { - CAutoLock lck(this); - m_bTerminate = TRUE; - m_hr = S_FALSE; - NotifyThread(); - } - DbgWaitForSingleObject(m_hThread); - EXECUTE_ASSERT(CloseHandle(m_hThread)); - - // The thread frees the samples when asked to terminate - - ASSERT(m_List->GetCount() == 0); - delete m_List; - } - else { - FreeSamples(); - } - if(m_hSem != NULL) { - EXECUTE_ASSERT(CloseHandle(m_hSem)); - } - delete [] m_ppSamples; -} - -// -// Call the real thread proc as a member function -// -DWORD WINAPI COutputQueue::InitialThreadProc(LPVOID pv) { - HRESULT hrCoInit = CAMThread::CoInitializeHelper(); - - COutputQueue *pSampleQueue = (COutputQueue *)pv; - DWORD dwReturn = pSampleQueue->ThreadProc(); - - if(hrCoInit == S_OK) { - CoUninitialize(); - } - - return dwReturn; -} - -// -// Thread sending the samples downstream : -// -// When there is nothing to do the thread sets m_lWaiting (while -// holding the critical section) and then waits for m_hSem to be -// set (not holding the critical section) -// -DWORD COutputQueue::ThreadProc() { - while(TRUE) { - BOOL bWait = FALSE; - IMediaSample *pSample=0; - LONG lNumberToSend=0; // Local copy - NewSegmentPacket* ppacket=0; - - // - // Get a batch of samples and send it if possible - // In any case exit the loop if there is a control action - // requested - // - { - CAutoLock lck(this); - while(TRUE) { - - if(m_bTerminate) { - FreeSamples(); - return 0; - } - if(m_bFlushing) { - FreeSamples(); - SetEvent(m_evFlushComplete); - } - - // Get a sample off the list - - pSample = m_List->RemoveHead(); - // inform derived class we took something off the queue - if(m_hEventPop) { - //DbgLog((LOG_TRACE,3,TEXT("Queue: Delivered SET EVENT"))); - SetEvent(m_hEventPop); - } - - if(pSample != NULL && - !IsSpecialSample(pSample)) { - - // If its just a regular sample just add it to the batch - // and exit the loop if the batch is full - - m_ppSamples[m_nBatched++] = pSample; - if(m_nBatched == m_lBatchSize) { - break; - } - } - else { - - // If there was nothing in the queue and there's nothing - // to send (either because there's nothing or the batch - // isn't full) then prepare to wait - - if(pSample == NULL && - (m_bBatchExact || m_nBatched == 0)) { - - // Tell other thread to set the event when there's - // something do to - - ASSERT(m_lWaiting == 0); - m_lWaiting++; - bWait = TRUE; - } - else { - - // We break out of the loop on SEND_PACKET unless - // there's nothing to send - - if(pSample == SEND_PACKET && m_nBatched == 0) { - continue; - } - - if(pSample == NEW_SEGMENT) { - // now we need the parameters - we are - // guaranteed that the next packet contains them - ppacket = (NewSegmentPacket *) m_List->RemoveHead(); - // we took something off the queue - if(m_hEventPop) { - //DbgLog((LOG_TRACE,3,TEXT("Queue: Delivered SET EVENT"))); - SetEvent(m_hEventPop); - } - - ASSERT(ppacket); - } - // EOS_PACKET falls through here and we exit the loop - // In this way it acts like SEND_PACKET - } - break; - } - } - if(!bWait) { - // We look at m_nBatched from the client side so keep - // it up to date inside the critical section - lNumberToSend = m_nBatched; // Local copy - m_nBatched = 0; - } - } - - // Wait for some more data - - if(bWait) { - DbgWaitForSingleObject(m_hSem); - continue; - } - - - - // OK - send it if there's anything to send - // We DON'T check m_bBatchExact here because either we've got - // a full batch or we dropped through because we got - // SEND_PACKET or EOS_PACKET - both of which imply we should - // flush our batch - - if(lNumberToSend != 0) { - long nProcessed; - if(m_hr == S_OK) { - ASSERT(!m_bFlushed); - HRESULT hr = m_pInputPin->ReceiveMultiple(m_ppSamples, - lNumberToSend, - &nProcessed); - /* Don't overwrite a flushing state HRESULT */ - CAutoLock lck(this); - if(m_hr == S_OK) { - m_hr = hr; - } - ASSERT(!m_bFlushed); - } - while(lNumberToSend != 0) { - m_ppSamples[--lNumberToSend]->Release(); - } - if(m_hr != S_OK) { - - // In any case wait for more data - S_OK just - // means there wasn't an error - - DbgLog((LOG_ERROR, 2, TEXT("ReceiveMultiple returned %8.8X"), - m_hr)); - } - } - - // Check for end of stream - - if(pSample == EOS_PACKET) { - - // We don't send even end of stream on if we've previously - // returned something other than S_OK - // This is because in that case the pin which returned - // something other than S_OK should have either sent - // EndOfStream() or notified the filter graph - - if(m_hr == S_OK) { - DbgLog((LOG_TRACE, 2, TEXT("COutputQueue sending EndOfStream()"))); - HRESULT hr = m_pPin->EndOfStream(); - if(FAILED(hr)) { - DbgLog((LOG_ERROR, 2, TEXT("COutputQueue got code 0x%8.8X from EndOfStream()"))); - } - } - } - - // Data from a new source - - if(pSample == RESET_PACKET) { - m_hr = S_OK; - SetEvent(m_evFlushComplete); - } - - if(pSample == NEW_SEGMENT) { - m_pPin->NewSegment(ppacket->tStart, ppacket->tStop, ppacket->dRate); - delete ppacket; - } - } -} - -// Send batched stuff anyway -void COutputQueue::SendAnyway() { - if(!IsQueued()) { - - // m_bSendAnyway is a private parameter checked in ReceiveMultiple - - m_bSendAnyway = TRUE; - LONG nProcessed; - ReceiveMultiple(NULL, 0, &nProcessed); - m_bSendAnyway = FALSE; - - } - else { - CAutoLock lck(this); - QueueSample(SEND_PACKET); - NotifyThread(); - } -} - -void -COutputQueue::NewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate) { - if(!IsQueued()) { - if(S_OK == m_hr) { - if(m_bBatchExact) { - SendAnyway(); - } - m_pPin->NewSegment(tStart, tStop, dRate); - } - } - else { - if(m_hr == S_OK) { - // - // we need to queue the new segment to appear in order in the - // data, but we need to pass parameters to it. Rather than - // take the hit of wrapping every single sample so we can tell - // special ones apart, we queue special pointers to indicate - // special packets, and we guarantee (by holding the - // critical section) that the packet immediately following a - // NEW_SEGMENT value is a NewSegmentPacket containing the - // parameters. - NewSegmentPacket * ppack = new NewSegmentPacket; - if(ppack == NULL) { - return; - } - ppack->tStart = tStart; - ppack->tStop = tStop; - ppack->dRate = dRate; - - CAutoLock lck(this); - QueueSample(NEW_SEGMENT); - QueueSample((IMediaSample*) ppack); - NotifyThread(); - } - } -} - - -// -// End of Stream is queued to output device -// -void COutputQueue::EOS() { - CAutoLock lck(this); - if(!IsQueued()) { - if(m_bBatchExact) { - SendAnyway(); - } - if(m_hr == S_OK) { - DbgLog((LOG_TRACE, 2, TEXT("COutputQueue sending EndOfStream()"))); - m_bFlushed = FALSE; - HRESULT hr = m_pPin->EndOfStream(); - if(FAILED(hr)) { - DbgLog((LOG_ERROR, 2, TEXT("COutputQueue got code 0x%8.8X from EndOfStream()"))); - } - } - } - else { - if(m_hr == S_OK) { - m_bFlushed = FALSE; - QueueSample(EOS_PACKET); - NotifyThread(); - } - } -} - -// -// Flush all the samples in the queue -// -void COutputQueue::BeginFlush() { - if(IsQueued()) { { - CAutoLock lck(this); - - // block receives -- we assume this is done by the - // filter in which we are a component - - // discard all queued data - - m_bFlushing = TRUE; - - // Make sure we discard all samples from now on - - if(m_hr == S_OK) { - m_hr = S_FALSE; - } - - // Optimize so we don't keep calling downstream all the time - - if(m_bFlushed && m_bFlushingOpt) { - return; - } - - // Make sure we really wait for the flush to complete - m_evFlushComplete.Reset(); - - NotifyThread(); - } - - // pass this downstream - - m_pPin->BeginFlush(); - } - else { - // pass downstream first to avoid deadlocks - m_pPin->BeginFlush(); - CAutoLock lck(this); - // discard all queued data - - m_bFlushing = TRUE; - - // Make sure we discard all samples from now on - - if(m_hr == S_OK) { - m_hr = S_FALSE; - } - } - -} - -// -// leave flush mode - pass this downstream -void COutputQueue::EndFlush() { { - CAutoLock lck(this); - ASSERT(m_bFlushing); - if(m_bFlushingOpt && m_bFlushed && IsQueued()) { - m_bFlushing = FALSE; - m_hr = S_OK; - return; - } - } - - // sync with pushing thread -- done in BeginFlush - // ensure no more data to go downstream -- done in BeginFlush - // - // Because we are synching here there is no need to hold the critical - // section (in fact we'd deadlock if we did!) - - if(IsQueued()) { - m_evFlushComplete.Wait(); - } - else { - FreeSamples(); - } - - // Be daring - the caller has guaranteed no samples will arrive - // before EndFlush() returns - - m_bFlushing = FALSE; - m_bFlushed = TRUE; - - // call EndFlush on downstream pins - - m_pPin->EndFlush(); - - m_hr = S_OK; -} - -// COutputQueue::QueueSample -// -// private method to Send a sample to the output queue -// The critical section MUST be held when this is called - -void COutputQueue::QueueSample(IMediaSample *pSample) { - if(NULL == m_List->AddTail(pSample)) { - if(!IsSpecialSample(pSample)) { - pSample->Release(); - } - } -} - -// -// COutputQueue::Receive() -// -// Send a single sample by the multiple sample route -// (NOTE - this could be optimized if necessary) -// -// On return the sample will have been Release()'d -// - -HRESULT COutputQueue::Receive(IMediaSample *pSample) { - LONG nProcessed; - return ReceiveMultiple(&pSample, 1, &nProcessed); -} - -// -// COutputQueue::ReceiveMultiple() -// -// Send a set of samples to the downstream pin -// -// ppSamples - array of samples -// nSamples - how many -// nSamplesProcessed - How many were processed -// -// On return all samples will have been Release()'d -// - -HRESULT COutputQueue::ReceiveMultiple( - IMediaSample **ppSamples, - long nSamples, - long *nSamplesProcessed) { - CAutoLock lck(this); - // Either call directly or queue up the samples - - if(!IsQueued()) { - - // If we already had a bad return code then just return - - if(S_OK != m_hr) { - - // If we've never received anything since the last Flush() - // and the sticky return code is not S_OK we must be - // flushing - // ((!A || B) is equivalent to A implies B) - ASSERT(!m_bFlushed || m_bFlushing); - - // We're supposed to Release() them anyway! - *nSamplesProcessed = 0; - for(int i = 0; i < nSamples; i++) { - DbgLog((LOG_TRACE, 3, TEXT("COutputQueue (direct) : Discarding %d samples code 0x%8.8X"), - nSamples, m_hr)); - ppSamples[i]->Release(); - } - - return m_hr; - } - // - // If we're flushing the sticky return code should be S_FALSE - // - ASSERT(!m_bFlushing); - m_bFlushed = FALSE; - - ASSERT(m_nBatched < m_lBatchSize); - ASSERT(m_nBatched == 0 || m_bBatchExact); - - // Loop processing the samples in batches - - LONG iLost = 0; -/*NABIL: I moved this long declaration out of the for loop, incorrect scope*/ - long iDone; - for(iDone = 0; - iDone < nSamples || (m_nBatched != 0 && m_bSendAnyway);) { - - //pragma message (REMIND("Implement threshold scheme")) - ASSERT(m_nBatched < m_lBatchSize); - if(iDone < nSamples) { - m_ppSamples[m_nBatched++] = ppSamples[iDone++]; - } - if(m_nBatched == m_lBatchSize || - nSamples == 0 && (m_bSendAnyway || !m_bBatchExact)) { - LONG nDone; - DbgLog((LOG_TRACE, 4, TEXT("Batching %d samples"), - m_nBatched)); - - if(m_hr == S_OK) { - m_hr = m_pInputPin->ReceiveMultiple(m_ppSamples, - m_nBatched, - &nDone); - } - else { - nDone = 0; - } - iLost += m_nBatched - nDone; - for(LONG i = 0; i < m_nBatched; i++) { - m_ppSamples[i]->Release(); - } - m_nBatched = 0; - } - } - *nSamplesProcessed = iDone - iLost; - if(*nSamplesProcessed < 0) { - *nSamplesProcessed = 0; - } - return m_hr; - } - else { - /* We're sending to our thread */ - - if(m_hr != S_OK) { - *nSamplesProcessed = 0; - DbgLog((LOG_TRACE, 3, TEXT("COutputQueue (queued) : Discarding %d samples code 0x%8.8X"), - nSamples, m_hr)); - for(int i = 0; i < nSamples; i++) { - ppSamples[i]->Release(); - } - return m_hr; - } - m_bFlushed = FALSE; - for(long i = 0; i < nSamples; i++) { - QueueSample(ppSamples[i]); - } - *nSamplesProcessed = nSamples; - if(!m_bBatchExact || - m_nBatched + m_List->GetCount() >= m_lBatchSize) { - NotifyThread(); - } - } - - return S_OK; -} - -// Get ready for new data - cancels sticky m_hr -void COutputQueue::Reset() { - if(!IsQueued()) { - m_hr = S_OK; - } - else { - CAutoLock lck(this); - QueueSample(RESET_PACKET); - NotifyThread(); - m_evFlushComplete.Wait(); - } -} - -// Remove and Release() all queued and Batched samples -void COutputQueue::FreeSamples() { - CAutoLock lck(this); - if(IsQueued()) { - while(TRUE) { - IMediaSample *pSample = m_List->RemoveHead(); - // inform derived class we took something off the queue - if(m_hEventPop) { - //DbgLog((LOG_TRACE,3,TEXT("Queue: Delivered SET EVENT"))); - SetEvent(m_hEventPop); - } - - if(pSample == NULL) { - break; - } - if(!IsSpecialSample(pSample)) { - pSample->Release(); - } - else { - if(pSample == NEW_SEGMENT) { - // Free NEW_SEGMENT packet - NewSegmentPacket *ppacket = - (NewSegmentPacket *) m_List->RemoveHead(); - // inform derived class we took something off the queue - if(m_hEventPop) { - //DbgLog((LOG_TRACE,3,TEXT("Queue: Delivered SET EVENT"))); - SetEvent(m_hEventPop); - } - - ASSERT(ppacket != NULL); - delete ppacket; - } - } - } - } - for(int i = 0; i < m_nBatched; i++) { - m_ppSamples[i]->Release(); - } - m_nBatched = 0; -} - -// Notify the thread if there is something to do -// -// The critical section MUST be held when this is called -void COutputQueue::NotifyThread() { - // Optimize - no need to signal if it's not waiting - ASSERT(IsQueued()); - if(m_lWaiting) { - ReleaseSemaphore(m_hSem, m_lWaiting, NULL); - m_lWaiting = 0; - } -} - -// See if there's any work to do -// Returns -// TRUE if there is nothing on the queue and nothing in the batch -// and all data has been sent -// FALSE otherwise -// -BOOL COutputQueue::IsIdle() { - CAutoLock lck(this); - - // We're idle if - // there is no thread (!IsQueued()) OR - // the thread is waiting for more work (m_lWaiting != 0) - // AND - // there's nothing in the current batch (m_nBatched == 0) - - if(IsQueued() && m_lWaiting == 0 || m_nBatched != 0) { - return FALSE; - } - else { - - // If we're idle it shouldn't be possible for there - // to be anything on the work queue - ASSERT(!IsQueued() || m_List->GetCount() == 0); - } - - return TRUE; -} - - -void COutputQueue::SetPopEvent(HANDLE hEvent) { - m_hEventPop = hEvent; -} - diff --git a/src/BaseClasses/outputq.h b/src/BaseClasses/outputq.h deleted file mode 100644 index 257700147f..0000000000 --- a/src/BaseClasses/outputq.h +++ /dev/null @@ -1,137 +0,0 @@ -//------------------------------------------------------------------------------ -// File: OutputQ.h -// -// Desc: DirectShow base classes - defines the COutputQueue class, which -// makes a queue of samples and sends them to an output pin. The -// class will optionally send the samples to the pin directly. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -typedef CGenericList CSampleList; - -class COutputQueue : public CCritSec -{ -public: - // Constructor - COutputQueue(IPin *pInputPin, // Pin to send stuff to - HRESULT *phr, // 'Return code' - BOOL bAuto = TRUE, // Ask pin if blocks - BOOL bQueue = TRUE, // Send through queue (ignored if - // bAuto set) - LONG lBatchSize = 1, // Batch - BOOL bBatchExact = FALSE,// Batch exactly to BatchSize - LONG lListSize = // Likely number in the list - DEFAULTCACHE, - DWORD dwPriority = // Priority of thread to create - THREAD_PRIORITY_NORMAL, - bool bFlushingOpt = false // flushing optimization - ); - ~COutputQueue(); - - // enter flush state - discard all data - void BeginFlush(); // Begin flushing samples - - // re-enable receives (pass this downstream) - void EndFlush(); // Complete flush of samples - downstream - // pin guaranteed not to block at this stage - - void EOS(); // Call this on End of stream - - void SendAnyway(); // Send batched samples anyway (if bBatchExact set) - - void NewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate); - - HRESULT Receive(IMediaSample *pSample); - - // do something with these media samples - HRESULT ReceiveMultiple ( - IMediaSample **pSamples, - long nSamples, - long *nSamplesProcessed); - - void Reset(); // Reset m_hr ready for more data - - // See if its idle or not - BOOL IsIdle(); - - // give the class an event to fire after everything removed from the queue - void SetPopEvent(HANDLE hEvent); - -protected: - static DWORD WINAPI InitialThreadProc(LPVOID pv); - DWORD ThreadProc(); - BOOL IsQueued() - { - return m_List != NULL; - } - - // The critical section MUST be held when this is called - void QueueSample(IMediaSample *pSample); - - BOOL IsSpecialSample(IMediaSample *pSample) - { - return (DWORD_PTR)pSample > (DWORD_PTR)(LONG_PTR)(-16); - } - - // Remove and Release() batched and queued samples - void FreeSamples(); - - // Notify the thread there is something to do - void NotifyThread(); - - -protected: - // Queue 'messages' - #define SEND_PACKET ((IMediaSample *)(LONG_PTR)(-2)) // Send batch - #define EOS_PACKET ((IMediaSample *)(LONG_PTR)(-3)) // End of stream - #define RESET_PACKET ((IMediaSample *)(LONG_PTR)(-4)) // Reset m_hr - #define NEW_SEGMENT ((IMediaSample *)(LONG_PTR)(-5)) // send NewSegment - - // new segment packet is always followed by one of these - struct NewSegmentPacket { - REFERENCE_TIME tStart; - REFERENCE_TIME tStop; - double dRate; - }; - - // Remember input stuff - IPin * const m_pPin; - IMemInputPin * m_pInputPin; - BOOL const m_bBatchExact; - LONG const m_lBatchSize; - - CSampleList * m_List; - HANDLE m_hSem; - CAMEvent m_evFlushComplete; - HANDLE m_hThread; - IMediaSample ** m_ppSamples; - LONG m_nBatched; - - // Wait optimization - LONG m_lWaiting; - // Flush synchronization - BOOL m_bFlushing; - - // flushing optimization. some downstream filters have trouble - // with the queue's flushing optimization. other rely on it - BOOL m_bFlushed; - bool m_bFlushingOpt; - - // Terminate now - BOOL m_bTerminate; - - // Send anyway flag for batching - BOOL m_bSendAnyway; - - // Deferred 'return code' - BOOL volatile m_hr; - - // an event that can be fired after every deliver - HANDLE m_hEventPop; -}; - diff --git a/src/BaseClasses/pstream.cpp b/src/BaseClasses/pstream.cpp deleted file mode 100644 index f7642bf586..0000000000 --- a/src/BaseClasses/pstream.cpp +++ /dev/null @@ -1,196 +0,0 @@ -//------------------------------------------------------------------------------ -// File: PStream.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include - -#ifdef PERF -#include -#endif -// #include "pstream.h" in streams.h - -// -// Constructor -// -CPersistStream::CPersistStream(IUnknown *punk, HRESULT *phr) - : mPS_fDirty(FALSE) -{ - mPS_dwFileVersion = GetSoftwareVersion(); -} - - -// -// Destructor -// -CPersistStream::~CPersistStream() { - // Nothing to do -} - -#if 0 -SAMPLE CODE TO COPY - not active at the moment - -// -// NonDelegatingQueryInterface -// -// This object supports IPersist & IPersistStream -STDMETHODIMP CPersistStream::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - if (riid == IID_IPersist) { - return GetInterface((IPersist *) this, ppv); // ??? - } - else if (riid == IID_IPersistStream) { - return GetInterface((IPersistStream *) this, ppv); - } - else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} -#endif - - -// -// WriteToStream -// -// Writes to the stream (default action is to write nothing) -HRESULT CPersistStream::WriteToStream(IStream *pStream) -{ - // You can override this to do things like - // hr = pStream->Write(MyStructure, sizeof(MyStructure), NULL); - - return NOERROR; -} - - - -HRESULT CPersistStream::ReadFromStream(IStream * pStream) -{ - // You can override this to do things like - // hr = pStream->Read(MyStructure, sizeof(MyStructure), NULL); - - return NOERROR; -} - - -// -// Load -// -// Load all the data from the given stream -STDMETHODIMP CPersistStream::Load(LPSTREAM pStm) -{ - HRESULT hr; - // Load the version number then the data - mPS_dwFileVersion = ReadInt(pStm, hr); - if (FAILED(hr)) { - return hr; - } - - return ReadFromStream(pStm); -} // Load - - - -// -// Save -// -// Save the contents of this Stream. -STDMETHODIMP CPersistStream::Save(LPSTREAM pStm, BOOL fClearDirty) -{ - - HRESULT hr = WriteInt(pStm, GetSoftwareVersion()); - if (FAILED(hr)) { - return hr; - } - - hr = WriteToStream(pStm); - if (FAILED(hr)) { - return hr; - } - - mPS_fDirty = !fClearDirty; - - return hr; -} // Save - - -// WriteInt -// -// Writes an integer to an IStream as 11 UNICODE characters followed by one space. -// You could use this for shorts or unsigneds or anything (up to 32 bits) -// where the value isn't actually truncated by squeezing it into 32 bits. -// Values such as (unsigned) 0x80000000 would come out as -2147483648 -// but would then load as 0x80000000 through ReadInt. Cast as you please. - -STDAPI WriteInt(IStream *pIStream, int n) -{ - WCHAR Buff[13]; // Allows for trailing null that we don't write - wsprintfW(Buff, L"%011d ",n); - return pIStream->Write(&(Buff[0]), 12*sizeof(WCHAR), NULL); -} // WriteInt - - -// ReadInt -// -// Reads an integer from an IStream. -// Read as 4 bytes. You could use this for shorts or unsigneds or anything -// where the value isn't actually truncated by squeezing it into 32 bits -// Striped down subset of what sscanf can do (without dragging in the C runtime) - -STDAPI_(int) ReadInt(IStream *pIStream, HRESULT &hr) -{ - - int Sign = 1; - unsigned int n = 0; // result wil be n*Sign - WCHAR wch; - - hr = pIStream->Read( &wch, sizeof(wch), NULL); - if (FAILED(hr)) { - return 0; - } - - if (wch==L'-'){ - Sign = -1; - hr = pIStream->Read( &wch, sizeof(wch), NULL); - if (FAILED(hr)) { - return 0; - } - } - - for( ; ; ) { - if (wch>=L'0' && wch<=L'9') { - n = 10*n+(int)(wch-L'0'); - } else if ( wch == L' ' - || wch == L'\t' - || wch == L'\r' - || wch == L'\n' - || wch == L'\0' - ) { - break; - } else { - hr = VFW_E_INVALID_FILE_FORMAT; - return 0; - } - - hr = pIStream->Read( &wch, sizeof(wch), NULL); - if (FAILED(hr)) { - return 0; - } - } - - if (n==0x80000000 && Sign==-1) { - // This is the negative number that has no positive version! - return (int)n; - } - else return (int)n * Sign; -} // ReadInt - - -// The microsoft C/C++ compile generates level 4 warnings to the effect that -// a particular inline function (from some base class) was not needed. -// This line gets rid of hundreds of such unwanted messages and makes -// -W4 compilation feasible: -#pragma warning(disable: 4514) diff --git a/src/BaseClasses/pstream.h b/src/BaseClasses/pstream.h deleted file mode 100644 index 088dddb1e1..0000000000 --- a/src/BaseClasses/pstream.h +++ /dev/null @@ -1,114 +0,0 @@ -//------------------------------------------------------------------------------ -// File: PStream.h -// -// Desc: DirectShow base classes - defines a class for persistent properties -// of filters. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __PSTREAM__ -#define __PSTREAM__ - -// Base class for persistent properties of filters -// (i.e. filter properties in saved graphs) - -// The simplest way to use this is: -// 1. Arrange for your filter to inherit this class -// 2. Implement in your class WriteToStream and ReadFromStream -// These will override the "do nothing" functions here. -// 3. Change your NonDelegatingQueryInterface to handle IPersistStream -// 4. Implement SizeMax to return the number of bytes of data you save. -// If you save UNICODE data, don't forget a char is 2 bytes. -// 5. Whenever your data changes, call SetDirty() -// -// At some point you may decide to alter, or extend the format of your data. -// At that point you will wish that you had a version number in all the old -// saved graphs, so that you can tell, when you read them, whether they -// represent the old or new form. To assist you in this, this class -// writes and reads a version number. -// When it writes, it calls GetSoftwareVersion() to enquire what version -// of the software we have at the moment. (In effect this is a version number -// of the data layout in the file). It writes this as the first thing in the data. -// If you want to change the version, implement (override) GetSoftwareVersion(). -// It reads this from the file into mPS_dwFileVersion before calling ReadFromStream, -// so in ReadFromStream you can check mPS_dwFileVersion to see if you are reading -// an old version file. -// Normally you should accept files whose version is no newer than the software -// version that's reading them. - - -// CPersistStream -// -// Implements IPersistStream. -// See 'OLE Programmers Reference (Vol 1):Structured Storage Overview' for -// more implementation information. -class CPersistStream : public IPersistStream { - private: - - // Internal state: - - protected: - DWORD mPS_dwFileVersion; // version number of file (being read) - BOOL mPS_fDirty; - - public: - - // IPersistStream methods - - STDMETHODIMP IsDirty() - {return (mPS_fDirty ? S_OK : S_FALSE);} // note FALSE means clean - STDMETHODIMP Load(LPSTREAM pStm); - STDMETHODIMP Save(LPSTREAM pStm, BOOL fClearDirty); - STDMETHODIMP GetSizeMax(ULARGE_INTEGER * pcbSize) - // Allow 24 bytes for version. - { pcbSize->QuadPart = 12*sizeof(WCHAR)+SizeMax(); return NOERROR; } - - // implementation - - CPersistStream(IUnknown *punk, HRESULT *phr); - ~CPersistStream(); - - HRESULT SetDirty(BOOL fDirty) - { mPS_fDirty = fDirty; return NOERROR;} - - - // override to reveal IPersist & IPersistStream - // STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - // --- IPersist --- - - // You must override this to provide your own class id - STDMETHODIMP GetClassID(CLSID *pClsid) PURE; - - // overrideable if you want - // file version number. Override it if you ever change format - virtual DWORD GetSoftwareVersion(void) { return 0; } - - - //========================================================================= - // OVERRIDE THESE to read and write your data - // OVERRIDE THESE to read and write your data - // OVERRIDE THESE to read and write your data - - virtual int SizeMax() {return 0;} - virtual HRESULT WriteToStream(IStream *pStream); - virtual HRESULT ReadFromStream(IStream *pStream); - //========================================================================= - - private: - -}; - - -// --- Useful helpers --- - - -// Writes an int to an IStream as UNICODE. -STDAPI WriteInt(IStream *pIStream, int n); - -// inverse of WriteInt -STDAPI_(int) ReadInt(IStream *pIStream, HRESULT &hr); - -#endif // __PSTREAM__ diff --git a/src/BaseClasses/pullpin.cpp b/src/BaseClasses/pullpin.cpp deleted file mode 100644 index 548086f4ec..0000000000 --- a/src/BaseClasses/pullpin.cpp +++ /dev/null @@ -1,510 +0,0 @@ -//------------------------------------------------------------------------------ -// File: PullPin.cpp -// -// Desc: DirectShow base classes - implements CPullPin class that pulls data -// from IAsyncReader. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include "pullpin.h" - - - -CPullPin::CPullPin() - : m_pReader(NULL), - m_pAlloc(NULL), - m_State(TM_Exit) { - -} - -CPullPin::~CPullPin() { - Disconnect(); -} - -// returns S_OK if successfully connected to an IAsyncReader interface -// from this object -// Optional allocator should be proposed as a preferred allocator if -// necessary -HRESULT -CPullPin::Connect(IUnknown* pUnk, IMemAllocator* pAlloc, BOOL bSync) { - CAutoLock lock(&m_AccessLock); - - if(m_pReader) { - return VFW_E_ALREADY_CONNECTED; - } - - HRESULT hr = pUnk->QueryInterface(IID_IAsyncReader, (void**)&m_pReader); - if(FAILED(hr)) { - return(hr); - } - - hr = DecideAllocator(pAlloc, NULL); - if(FAILED(hr)) { - Disconnect(); - return hr; - } - - LONGLONG llTotal, llAvail; - hr = m_pReader->Length(&llTotal, &llAvail); - if(FAILED(hr)) { - Disconnect(); - return hr; - } - - // convert from file position to reference time - m_tDuration = llTotal * UNITS; - m_tStop = m_tDuration; - m_tStart = 0; - m_bSync = bSync; - - return S_OK; -} - -// disconnect any connection made in Connect -HRESULT -CPullPin::Disconnect() { - CAutoLock lock(&m_AccessLock); - - StopThread(); - - if(m_pReader) { - m_pReader->Release(); - m_pReader = NULL; - } - - if(m_pAlloc) { - m_pAlloc->Release(); - m_pAlloc = NULL; - } - - return S_OK; -} - -// agree an allocator using RequestAllocator - optional -// props param specifies your requirements (non-zero fields). -// returns an error code if fail to match requirements. -// optional IMemAllocator interface is offered as a preferred allocator -// but no error occurs if it can't be met. -HRESULT -CPullPin::DecideAllocator( - IMemAllocator * pAlloc, - ALLOCATOR_PROPERTIES * pProps) { - ALLOCATOR_PROPERTIES *pRequest; - ALLOCATOR_PROPERTIES Request; - if(pProps == NULL) { - Request.cBuffers = 3; - Request.cbBuffer = 64*1024; - Request.cbAlign = 0; - Request.cbPrefix = 0; - pRequest = &Request; - } - else { - pRequest = pProps; - } - HRESULT hr = m_pReader->RequestAllocator(pAlloc, - pRequest, - &m_pAlloc); - return hr; -} - -// start pulling data -HRESULT -CPullPin::Active(void) { - ASSERT(!ThreadExists()); - return StartThread(); -} - -// stop pulling data -HRESULT -CPullPin::Inactive(void) { - StopThread(); - - return S_OK; -} - -HRESULT -CPullPin::Seek(REFERENCE_TIME tStart, REFERENCE_TIME tStop) { - CAutoLock lock(&m_AccessLock); - - ThreadMsg AtStart = m_State; - - if(AtStart == TM_Start) { - BeginFlush(); - PauseThread(); - EndFlush(); - } - - m_tStart = tStart; - m_tStop = tStop; - - HRESULT hr = S_OK; - if(AtStart == TM_Start) { - hr = StartThread(); - } - - return hr; -} - -HRESULT -CPullPin::Duration(REFERENCE_TIME* ptDuration) { - *ptDuration = m_tDuration; - return S_OK; -} - - -HRESULT -CPullPin::StartThread() { - CAutoLock lock(&m_AccessLock); - - if(!m_pAlloc || !m_pReader) { - return E_UNEXPECTED; - } - - HRESULT hr; - if(!ThreadExists()) { - - // commit allocator - hr = m_pAlloc->Commit(); - if(FAILED(hr)) { - return hr; - } - - // start thread - if(!Create()) { - return E_FAIL; - } - } - - m_State = TM_Start; - hr = (HRESULT) CallWorker(m_State); - return hr; -} - -HRESULT -CPullPin::PauseThread() { - CAutoLock lock(&m_AccessLock); - - if(!ThreadExists()) { - return E_UNEXPECTED; - } - - // need to flush to ensure the thread is not blocked - // in WaitForNext - HRESULT hr = m_pReader->BeginFlush(); - if(FAILED(hr)) { - return hr; - } - - m_State = TM_Pause; - hr = CallWorker(TM_Pause); - - m_pReader->EndFlush(); - return hr; -} - -HRESULT -CPullPin::StopThread() { - CAutoLock lock(&m_AccessLock); - - if(!ThreadExists()) { - return S_FALSE; - } - - // need to flush to ensure the thread is not blocked - // in WaitForNext - HRESULT hr = m_pReader->BeginFlush(); - if(FAILED(hr)) { - return hr; - } - - m_State = TM_Exit; - hr = CallWorker(TM_Exit); - - m_pReader->EndFlush(); - - // wait for thread to completely exit - Close(); - - // decommit allocator - if(m_pAlloc) { - m_pAlloc->Decommit(); - } - - return S_OK; -} - - -DWORD -CPullPin::ThreadProc(void) { - while(1) { - DWORD cmd = GetRequest(); - switch(cmd) { - case TM_Exit: - Reply(S_OK); - return 0; - - case TM_Pause: - // we are paused already - Reply(S_OK); - break; - - case TM_Start: - Reply(S_OK); - Process(); - break; - } - - // at this point, there should be no outstanding requests on the - // upstream filter. - // We should force begin/endflush to ensure that this is true. - // !!!Note that we may currently be inside a BeginFlush/EndFlush pair - // on another thread, but the premature EndFlush will do no harm now - // that we are idle. - m_pReader->BeginFlush(); - CleanupCancelled(); - m_pReader->EndFlush(); - } -} - -HRESULT -CPullPin::QueueSample( - REFERENCE_TIME& tCurrent, - REFERENCE_TIME tAlignStop, - BOOL bDiscontinuity - ) { - IMediaSample* pSample; - - HRESULT hr = m_pAlloc->GetBuffer(&pSample, NULL, NULL, 0); - if(FAILED(hr)) { - return hr; - } - - LONGLONG tStopThis = tCurrent + (pSample->GetSize() * UNITS); - if(tStopThis > tAlignStop) { - tStopThis = tAlignStop; - } - pSample->SetTime(&tCurrent, &tStopThis); - tCurrent = tStopThis; - - pSample->SetDiscontinuity(bDiscontinuity); - - hr = m_pReader->Request(pSample, - 0); - if(FAILED(hr)) { - pSample->Release(); - - CleanupCancelled(); - OnError(hr); - } - return hr; -} - -HRESULT -CPullPin::CollectAndDeliver( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop) { - IMediaSample* pSample = NULL; // better be sure pSample is set - DWORD_PTR dwUnused; - HRESULT hr = m_pReader->WaitForNext(INFINITE, - &pSample, - &dwUnused); - if(FAILED(hr)) { - if(pSample) { - pSample->Release(); - } - } - else { - hr = DeliverSample(pSample, tStart, tStop); - } - if(FAILED(hr)) { - CleanupCancelled(); - OnError(hr); - } - return hr; - -} - -HRESULT -CPullPin::DeliverSample( - IMediaSample* pSample, - REFERENCE_TIME tStart, - REFERENCE_TIME tStop - ) { - // fix up sample if past actual stop (for sector alignment) - REFERENCE_TIME t1, t2; - pSample->GetTime(&t1, &t2); - if(t2 > tStop) { - t2 = tStop; - } - - // adjust times to be relative to (aligned) start time - t1 -= tStart; - t2 -= tStart; - pSample->SetTime(&t1, &t2); - - - HRESULT hr = Receive(pSample); - pSample->Release(); - return hr; -} - -void -CPullPin::Process(void) { - // is there anything to do? - if(m_tStop <= m_tStart) { - EndOfStream(); - return; - } - - BOOL bDiscontinuity = TRUE; - - // if there is more than one sample at the allocator, - // then try to queue 2 at once in order to overlap. - // -- get buffer count and required alignment - ALLOCATOR_PROPERTIES Actual; - HRESULT hr = m_pAlloc->GetProperties(&Actual); - - // align the start position downwards - REFERENCE_TIME tStart = AlignDown(m_tStart / UNITS, Actual.cbAlign) * UNITS; - REFERENCE_TIME tCurrent = tStart; - - REFERENCE_TIME tStop = m_tStop; - if(tStop > m_tDuration) { - tStop = m_tDuration; - } - - // align the stop position - may be past stop, but that - // doesn't matter - REFERENCE_TIME tAlignStop = AlignUp(tStop / UNITS, Actual.cbAlign) * UNITS; - - - DWORD dwRequest; - - if(!m_bSync) { - - // Break out of the loop either if we get to the end or we're asked - // to do something else - while(tCurrent < tAlignStop) { - - // Break out without calling EndOfStream if we're asked to - // do something different - if(CheckRequest(&dwRequest)) { - return; - } - - // queue a first sample - if(Actual.cBuffers > 1) { - - hr = QueueSample(tCurrent, tAlignStop, TRUE); - bDiscontinuity = FALSE; - - if(FAILED(hr)) { - return; - } - } - - - - // loop queueing second and waiting for first.. - while(tCurrent < tAlignStop) { - - hr = QueueSample(tCurrent, tAlignStop, bDiscontinuity); - bDiscontinuity = FALSE; - - if(FAILED(hr)) { - return; - } - - hr = CollectAndDeliver(tStart, tStop); - if(S_OK != hr) { - - // stop if error, or if downstream filter said - // to stop. - return; - } - } - - if(Actual.cBuffers > 1) { - hr = CollectAndDeliver(tStart, tStop); - if(FAILED(hr)) { - return; - } - } - } - } - else { - - // sync version of above loop - while(tCurrent < tAlignStop) { - - // Break out without calling EndOfStream if we're asked to - // do something different - if(CheckRequest(&dwRequest)) { - return; - } - - IMediaSample* pSample; - - hr = m_pAlloc->GetBuffer(&pSample, NULL, NULL, 0); - if(FAILED(hr)) { - OnError(hr); - return; - } - - LONGLONG tStopThis = tCurrent + (pSample->GetSize() * UNITS); - if(tStopThis > tAlignStop) { - tStopThis = tAlignStop; - } - pSample->SetTime(&tCurrent, &tStopThis); - tCurrent = tStopThis; - - if(bDiscontinuity) { - pSample->SetDiscontinuity(TRUE); - bDiscontinuity = FALSE; - } - - hr = m_pReader->SyncReadAligned(pSample); - - if(FAILED(hr)) { - pSample->Release(); - OnError(hr); - return; - } - - hr = DeliverSample(pSample, tStart, tStop); - if(hr != S_OK) { - if(FAILED(hr)) { - OnError(hr); - } - return; - } - } - } - - EndOfStream(); -} - -// after a flush, cancelled i/o will be waiting for collection -// and release -void -CPullPin::CleanupCancelled(void) { - while(1) { - IMediaSample * pSample; - DWORD_PTR dwUnused; - - HRESULT hr = m_pReader->WaitForNext(0, // no wait - &pSample, - &dwUnused); - if(pSample) { - pSample->Release(); - } - else { - // no more samples - return; - } - } -} - diff --git a/src/BaseClasses/pullpin.h b/src/BaseClasses/pullpin.h deleted file mode 100644 index 3601feb5c1..0000000000 --- a/src/BaseClasses/pullpin.h +++ /dev/null @@ -1,152 +0,0 @@ -//------------------------------------------------------------------------------ -// File: PullPin.h -// -// Desc: DirectShow base classes - defines CPullPin class. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __PULLPIN_H__ -#define __PULLPIN_H__ - -// -// CPullPin -// -// object supporting pulling data from an IAsyncReader interface. -// Given a start/stop position, calls a pure Receive method with each -// IMediaSample received. -// -// This is essentially for use in a MemInputPin when it finds itself -// connected to an IAsyncReader pin instead of a pushing pin. -// - -class CPullPin : public CAMThread -{ - IAsyncReader* m_pReader; - REFERENCE_TIME m_tStart; - REFERENCE_TIME m_tStop; - REFERENCE_TIME m_tDuration; - BOOL m_bSync; - - enum ThreadMsg { - TM_Pause, // stop pulling and wait for next message - TM_Start, // start pulling - TM_Exit, // stop and exit - }; - - ThreadMsg m_State; - - // override pure thread proc from CAMThread - DWORD ThreadProc(void); - - // running pull method (check m_bSync) - void Process(void); - - // clean up any cancelled i/o after a flush - void CleanupCancelled(void); - - // suspend thread from pulling, eg during seek - HRESULT PauseThread(); - - // start thread pulling - create thread if necy - HRESULT StartThread(); - - // stop and close thread - HRESULT StopThread(); - - // called from ProcessAsync to queue and collect requests - HRESULT QueueSample( - REFERENCE_TIME& tCurrent, - REFERENCE_TIME tAlignStop, - BOOL bDiscontinuity); - - HRESULT CollectAndDeliver( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop); - - HRESULT DeliverSample( - IMediaSample* pSample, - REFERENCE_TIME tStart, - REFERENCE_TIME tStop); - -protected: - IMemAllocator * m_pAlloc; - -public: - CPullPin(); - virtual ~CPullPin(); - - // returns S_OK if successfully connected to an IAsyncReader interface - // from this object - // Optional allocator should be proposed as a preferred allocator if - // necessary - // bSync is TRUE if we are to use sync reads instead of the - // async methods. - HRESULT Connect(IUnknown* pUnk, IMemAllocator* pAlloc, BOOL bSync); - - // disconnect any connection made in Connect - HRESULT Disconnect(); - - // agree an allocator using RequestAllocator - optional - // props param specifies your requirements (non-zero fields). - // returns an error code if fail to match requirements. - // optional IMemAllocator interface is offered as a preferred allocator - // but no error occurs if it can't be met. - virtual HRESULT DecideAllocator( - IMemAllocator* pAlloc, - ALLOCATOR_PROPERTIES * pProps); - - // set start and stop position. if active, will start immediately at - // the new position. Default is 0 to duration - HRESULT Seek(REFERENCE_TIME tStart, REFERENCE_TIME tStop); - - // return the total duration - HRESULT Duration(REFERENCE_TIME* ptDuration); - - // start pulling data - HRESULT Active(void); - - // stop pulling data - HRESULT Inactive(void); - - // helper functions - LONGLONG AlignDown(LONGLONG ll, LONG lAlign) { - // aligning downwards is just truncation - return ll & ~(lAlign-1); - }; - - LONGLONG AlignUp(LONGLONG ll, LONG lAlign) { - // align up: round up to next boundary - return (ll + (lAlign -1)) & ~(lAlign -1); - }; - - // GetReader returns the (addrefed) IAsyncReader interface - // for SyncRead etc - IAsyncReader* GetReader() { - m_pReader->AddRef(); - return m_pReader; - }; - - // -- pure -- - - // override this to handle data arrival - // return value other than S_OK will stop data - virtual HRESULT Receive(IMediaSample*) PURE; - - // override this to handle end-of-stream - virtual HRESULT EndOfStream(void) PURE; - - // called on runtime errors that will have caused pulling - // to stop - // these errors are all returned from the upstream filter, who - // will have already reported any errors to the filtergraph. - virtual void OnError(HRESULT hr) PURE; - - // flush this pin and all downstream - virtual HRESULT BeginFlush() PURE; - virtual HRESULT EndFlush() PURE; - -}; - -#endif //__PULLPIN_H__ diff --git a/src/BaseClasses/readme.txt b/src/BaseClasses/readme.txt deleted file mode 100644 index b7460677eb..0000000000 --- a/src/BaseClasses/readme.txt +++ /dev/null @@ -1,25 +0,0 @@ -DirectShow Sample -- Base Classes ---------------------------------- - -The Microsoft DirectShow base classes are a set of C++ classes -and utility functions that you can use to implement DirectShow filters. -For complete documentation of the base classes, see "DirectShow Base Classes" -in the DirectShow Reference section of the DirectX SDK documentation. - -NOTE: The BaseClasses header file schedule.h has been renamed to dsschedule.h -to prevent conflicts with the Platform SDK . Only the refclock.h -header in the BaseClasses directory uses this header, so the impact should -be minimal. - -Building for Windows XP ------------------------ -If you want to target Windows XP specifically to use its new features, -you must set WINVER=0x501 in the BaseClasses project file. You must also -install the Windows XP Platform SDK, however, to ensure that you have the -latest header files. For example, wxutil.cpp uses the new TIME_KILL_SYNCHRONOUS flag -only if (WINVER >= 0x501). This flag is conditionally defined in the Windows XP -Platform SDK in mmsystem.h, but only if WINVER is also set to 0x501 when compiling. - - #if (WINVER >= 0x501) - #define TIME_KILL_SYNCHRONOUS 0x0100 - #endif diff --git a/src/BaseClasses/refclock.cpp b/src/BaseClasses/refclock.cpp deleted file mode 100644 index 2af26dfaee..0000000000 --- a/src/BaseClasses/refclock.cpp +++ /dev/null @@ -1,308 +0,0 @@ -//------------------------------------------------------------------------------ -// File: RefClock.cpp -// -// Desc: DirectShow base classes - implements the IReferenceClock interface. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include - - - -// 'this' used in constructor list -#pragma warning(disable:4355) - - -STDMETHODIMP CBaseReferenceClock::NonDelegatingQueryInterface( - REFIID riid, - void ** ppv) { - HRESULT hr; - - if(riid == IID_IReferenceClock) { - hr = GetInterface((IReferenceClock *) this, ppv); - } - else { - hr = CUnknown::NonDelegatingQueryInterface(riid, ppv); - } - return hr; -} - -CBaseReferenceClock::~CBaseReferenceClock() { - - if(m_TimerResolution) timeEndPeriod(m_TimerResolution); - - m_pSchedule->DumpLinkedList(); - - if(m_hThread) { - m_bAbort = TRUE; - TriggerThread(); - WaitForSingleObject(m_hThread, INFINITE); - EXECUTE_ASSERT(CloseHandle(m_hThread)); - m_hThread = 0; - EXECUTE_ASSERT(CloseHandle(m_pSchedule->GetEvent())); - delete m_pSchedule; - } -} - -// A derived class may supply a hThreadEvent if it has its own thread that will take care -// of calling the schedulers Advise method. (Refere to CBaseReferenceClock::AdviseThread() -// to see what such a thread has to do.) -CBaseReferenceClock::CBaseReferenceClock( TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr, CAMSchedule * pShed ) -: CUnknown( pName, pUnk ) -, m_rtLastGotTime(0) -, m_TimerResolution(0) -, m_bAbort( FALSE ) -, m_pSchedule( pShed ? pShed : new CAMSchedule(CreateEvent(NULL, FALSE, FALSE, NULL)) ) -, m_hThread(0) { - - - ASSERT(m_pSchedule); - if(!m_pSchedule) { - *phr = E_OUTOFMEMORY; - } - else { - // Set up the highest resolution timer we can manage - TIMECAPS tc; - m_TimerResolution = (TIMERR_NOERROR == timeGetDevCaps(&tc, sizeof(tc))) - ? tc.wPeriodMin : 1; - - timeBeginPeriod(m_TimerResolution); - - /* Initialise our system times - the derived clock should set the right values */ - m_dwPrevSystemTime = timeGetTime(); - m_rtPrivateTime = (UNITS / MILLISECONDS) * m_dwPrevSystemTime; - -#ifdef PERF - m_idGetSystemTime = MSR_REGISTER(TEXT("CBaseReferenceClock::GetTime")); -#endif - - if(!pShed) { - DWORD ThreadID; - m_hThread = ::CreateThread(NULL, // Security attributes - (DWORD) 0, // Initial stack size - AdviseThreadFunction, // Thread start address - (LPVOID) this, // Thread parameter - (DWORD) 0, // Creation flags - &ThreadID); // Thread identifier - - if(m_hThread) { - SetThreadPriority(m_hThread, THREAD_PRIORITY_TIME_CRITICAL); - } - else { - *phr = E_FAIL; - EXECUTE_ASSERT(CloseHandle(m_pSchedule->GetEvent())); - delete m_pSchedule; - } - } - } -} - -STDMETHODIMP CBaseReferenceClock::GetTime(REFERENCE_TIME *pTime) { - HRESULT hr; - if(pTime) { - REFERENCE_TIME rtNow; - Lock(); - rtNow = GetPrivateTime(); - if(rtNow > m_rtLastGotTime) { - m_rtLastGotTime = rtNow; - hr = S_OK; - } - else { - hr = S_FALSE; - } - - *pTime = m_rtLastGotTime; - Unlock(); - MSR_INTEGER(m_idGetSystemTime, LONG((*pTime) / (UNITS/MILLISECONDS))); - } - else hr = E_POINTER; - - return hr; -} - -/* Ask for an async notification that a time has elapsed */ - -STDMETHODIMP CBaseReferenceClock::AdviseTime( - REFERENCE_TIME baseTime, // base reference time - REFERENCE_TIME streamTime, // stream offset time - HEVENT hEvent, // advise via this event - DWORD_PTR *pdwAdviseCookie) // where your cookie goes -{ - CheckPointer(pdwAdviseCookie, E_POINTER); - *pdwAdviseCookie = 0; - - // Check that the event is not already set - ASSERT(WAIT_TIMEOUT == WaitForSingleObject(HANDLE(hEvent),0)); - - HRESULT hr; - - const REFERENCE_TIME lRefTime = baseTime + streamTime; - if(lRefTime <= 0 || lRefTime == MAX_TIME) { - hr = E_INVALIDARG; - } - else { - *pdwAdviseCookie = m_pSchedule->AddAdvisePacket(lRefTime, 0, HANDLE(hEvent), FALSE); - hr = *pdwAdviseCookie ? NOERROR : E_OUTOFMEMORY; - } - return hr; -} - - -/* Ask for an asynchronous periodic notification that a time has elapsed */ - -STDMETHODIMP CBaseReferenceClock::AdvisePeriodic( - REFERENCE_TIME StartTime, // starting at this time - REFERENCE_TIME PeriodTime, // time between notifications - HSEMAPHORE hSemaphore, // advise via a semaphore - DWORD_PTR *pdwAdviseCookie) // where your cookie goes -{ - CheckPointer(pdwAdviseCookie, E_POINTER); - *pdwAdviseCookie = 0; - - HRESULT hr; - if(StartTime > 0 && PeriodTime > 0 && StartTime != MAX_TIME) { - *pdwAdviseCookie = m_pSchedule->AddAdvisePacket(StartTime, PeriodTime, HANDLE(hSemaphore), TRUE); - hr = *pdwAdviseCookie ? NOERROR : E_OUTOFMEMORY; - } - else hr = E_INVALIDARG; - - return hr; -} - - -STDMETHODIMP CBaseReferenceClock::Unadvise(DWORD_PTR dwAdviseCookie) { - return m_pSchedule->Unadvise(dwAdviseCookie); -} - - -REFERENCE_TIME CBaseReferenceClock::GetPrivateTime() { - CAutoLock cObjectLock(this); - - - /* If the clock has wrapped then the current time will be less than - * the last time we were notified so add on the extra milliseconds - * - * The time period is long enough so that the likelihood of - * successive calls spanning the clock cycle is not considered. - */ - - DWORD dwTime = timeGetTime(); { - m_rtPrivateTime += Int32x32To64(UNITS / MILLISECONDS, (DWORD)(dwTime - m_dwPrevSystemTime)); - m_dwPrevSystemTime = dwTime; - } - - return m_rtPrivateTime; -} - - -/* Adjust the current time by the input value. This allows an - external time source to work out some of the latency of the clock - system and adjust the "current" time accordingly. The intent is - that the time returned to the user is synchronised to a clock - source and allows drift to be catered for. - - For example: if the clock source detects a drift it can pass a delta - to the current time rather than having to set an explicit time. -*/ - -STDMETHODIMP CBaseReferenceClock::SetTimeDelta(const REFERENCE_TIME & TimeDelta) { -#ifdef DEBUG - - // Just break if passed an improper time delta value - LONGLONG llDelta = TimeDelta > 0 ? TimeDelta : -TimeDelta; - if(llDelta > UNITS * 1000) { - DbgLog((LOG_TRACE, 0, TEXT("Bad Time Delta"))); - DebugBreak(); - } - - // We're going to calculate a "severity" for the time change. Max -1 - // min 8. We'll then use this as the debug logging level for a - // debug log message. - const LONG usDelta = LONG(TimeDelta/10); // Delta in micro-secs - - DWORD delta = abs(usDelta); // varying delta - // Severity == 8 - ceil(log(abs( micro-secs delta))) - int Severity = 8; - while(delta > 0) { - delta >>= 3; // div 8 - Severity--; - } - - // Sev == 0 => > 2 second delta! - DbgLog((LOG_TIMING, Severity < 0 ? 0 : Severity, - TEXT("Sev %2i: CSystemClock::SetTimeDelta(%8ld us) %lu -> %lu ms."), - Severity, usDelta, DWORD(ConvertToMilliseconds(m_rtPrivateTime)), - DWORD(ConvertToMilliseconds(TimeDelta+m_rtPrivateTime)) )); - - // Don't want the DbgBreak to fire when running stress on debug-builds. -#ifdef BREAK_ON_SEVERE_TIME_DELTA - if(Severity < 0) - DbgBreakPoint(TEXT("SetTimeDelta > 16 seconds!"), - TEXT(__FILE__),__LINE__); -#endif - -#endif - - CAutoLock cObjectLock(this); - m_rtPrivateTime += TimeDelta; - // If time goes forwards, and we have advises, then we need to - // trigger the thread so that it can re-evaluate its wait time. - // Since we don't want the cost of the thread switches if the change - // is really small, only do it if clock goes forward by more than - // 0.5 millisecond. If the time goes backwards, the thread will - // wake up "early" (relativly speaking) and will re-evaluate at - // that time. - if(TimeDelta > 5000 && m_pSchedule->GetAdviseCount() > 0) TriggerThread(); - return NOERROR; -} - -// Thread stuff - -DWORD __stdcall CBaseReferenceClock::AdviseThreadFunction(LPVOID p) { - return DWORD(reinterpret_cast(p)->AdviseThread()); -} - -HRESULT CBaseReferenceClock::AdviseThread() { - DWORD dwWait = INFINITE; - - // The first thing we do is wait until something interesting happens - // (meaning a first advise or shutdown). This prevents us calling - // GetPrivateTime immediately which is goodness as that is a virtual - // routine and the derived class may not yet be constructed. (This - // thread is created in the base class constructor.) - - while(!m_bAbort) { - // Wait for an interesting event to happen - DbgLog((LOG_TIMING, 3, TEXT("CBaseRefClock::AdviseThread() Delay: %lu ms"), dwWait )); - WaitForSingleObject(m_pSchedule->GetEvent(), dwWait); - if(m_bAbort) break; - - // There are several reasons why we need to work from the internal - // time, mainly to do with what happens when time goes backwards. - // Mainly, it stop us looping madly if an event is just about to - // expire when the clock goes backward (i.e. GetTime stop for a - // while). - const REFERENCE_TIME rtNow = GetPrivateTime(); - - DbgLog((LOG_TIMING, 3, - TEXT("CBaseRefClock::AdviseThread() Woke at = %lu ms"), - ConvertToMilliseconds(rtNow) )); - - // We must add in a millisecond, since this is the resolution of our - // WaitForSingleObject timer. Failure to do so will cause us to loop - // franticly for (approx) 1 a millisecond. - m_rtNextAdvise = m_pSchedule->Advise(10000 + rtNow); - LONGLONG llWait = m_rtNextAdvise - rtNow; - - ASSERT(llWait > 0); - - llWait = ConvertToMilliseconds(llWait); - // DON'T replace this with a max!! (The type's of these things is VERY important) - dwWait = (llWait > REFERENCE_TIME(UINT_MAX)) ? UINT_MAX : DWORD(llWait); - }; - return NOERROR; -} - diff --git a/src/BaseClasses/refclock.h b/src/BaseClasses/refclock.h deleted file mode 100644 index f1ec57592d..0000000000 --- a/src/BaseClasses/refclock.h +++ /dev/null @@ -1,169 +0,0 @@ -//------------------------------------------------------------------------------ -// File: RefClock.h -// -// Desc: DirectShow base classes - defines the IReferenceClock interface. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __BASEREFCLOCK__ -#define __BASEREFCLOCK__ - -#include "dsschedule.h" - -const UINT RESOLUTION = 1; /* High resolution timer */ -const INT ADVISE_CACHE = 4; /* Default cache size */ -const LONGLONG MAX_TIME = 0x7FFFFFFFFFFFFFFF; /* Maximum LONGLONG value */ - -inline LONGLONG WINAPI ConvertToMilliseconds(const REFERENCE_TIME& RT) -{ - /* This converts an arbitrary value representing a reference time - into a MILLISECONDS value for use in subsequent system calls */ - - return (RT / (UNITS / MILLISECONDS)); -} - -/* This class hierarchy will support an IReferenceClock interface so - that an audio card (or other externally driven clock) can update the - system wide clock that everyone uses. - - The interface will be pretty thin with probably just one update method - This interface has not yet been defined. - */ - -/* This abstract base class implements the IReferenceClock - * interface. Classes that actually provide clock signals (from - * whatever source) have to be derived from this class. - * - * The abstract class provides implementations for: - * CUnknown support - * locking support (CCritSec) - * client advise code (creates a thread) - * - * Question: what can we do about quality? Change the timer - * resolution to lower the system load? Up the priority of the - * timer thread to force more responsive signals? - * - * During class construction we create a worker thread that is destroyed during - * destuction. This thread executes a series of WaitForSingleObject calls, - * waking up when a command is given to the thread or the next wake up point - * is reached. The wakeup points are determined by clients making Advise - * calls. - * - * Each advise call defines a point in time when they wish to be notified. A - * periodic advise is a series of these such events. We maintain a list of - * advise links and calculate when the nearest event notification is due for. - * We then call WaitForSingleObject with a timeout equal to this time. The - * handle we wait on is used by the class to signal that something has changed - * and that we must reschedule the next event. This typically happens when - * someone comes in and asks for an advise link while we are waiting for an - * event to timeout. - * - * While we are modifying the list of advise requests we - * are protected from interference through a critical section. Clients are NOT - * advised through callbacks. One shot clients have an event set, while - * periodic clients have a semaphore released for each event notification. A - * semaphore allows a client to be kept up to date with the number of events - * actually triggered and be assured that they can't miss multiple events being - * set. - * - * Keeping track of advises is taken care of by the CAMSchedule class. - */ - -class CBaseReferenceClock -: public CUnknown, public IReferenceClock, public CCritSec -{ -protected: - virtual ~CBaseReferenceClock(); // Don't let me be created on the stack! -public: - CBaseReferenceClock(TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr, CAMSchedule * pSched = 0 ); - - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void ** ppv); - - DECLARE_IUNKNOWN - - /* IReferenceClock methods */ - // Derived classes must implement GetPrivateTime(). All our GetTime - // does is call GetPrivateTime and then check so that time does not - // go backwards. A return code of S_FALSE implies that the internal - // clock has gone backwards and GetTime time has halted until internal - // time has caught up. (Don't know if this will be much use to folk, - // but it seems odd not to use the return code for something useful.) - STDMETHODIMP GetTime(REFERENCE_TIME *pTime); - // When this is called, it sets m_rtLastGotTime to the time it returns. - - /* Provide standard mechanisms for scheduling events */ - - /* Ask for an async notification that a time has elapsed */ - STDMETHODIMP AdviseTime( - REFERENCE_TIME baseTime, // base reference time - REFERENCE_TIME streamTime, // stream offset time - HEVENT hEvent, // advise via this event - DWORD_PTR *pdwAdviseCookie // where your cookie goes - ); - - /* Ask for an asynchronous periodic notification that a time has elapsed */ - STDMETHODIMP AdvisePeriodic( - REFERENCE_TIME StartTime, // starting at this time - REFERENCE_TIME PeriodTime, // time between notifications - HSEMAPHORE hSemaphore, // advise via a semaphore - DWORD_PTR *pdwAdviseCookie // where your cookie goes - ); - - /* Cancel a request for notification(s) - if the notification was - * a one shot timer then this function doesn't need to be called - * as the advise is automatically cancelled, however it does no - * harm to explicitly cancel a one-shot advise. It is REQUIRED that - * clients call Unadvise to clear a Periodic advise setting. - */ - - STDMETHODIMP Unadvise(DWORD_PTR dwAdviseCookie); - - /* Methods for the benefit of derived classes or outer objects */ - - // GetPrivateTime() is the REAL clock. GetTime is just a cover for - // it. Derived classes will probably override this method but not - // GetTime() itself. - // The important point about GetPrivateTime() is it's allowed to go - // backwards. Our GetTime() will keep returning the LastGotTime - // until GetPrivateTime() catches up. - virtual REFERENCE_TIME GetPrivateTime(); - - /* Provide a method for correcting drift */ - STDMETHODIMP SetTimeDelta( const REFERENCE_TIME& TimeDelta ); - - CAMSchedule * GetSchedule() const { return m_pSchedule; } - -private: - REFERENCE_TIME m_rtPrivateTime; // Current best estimate of time - DWORD m_dwPrevSystemTime; // Last vaule we got from timeGetTime - REFERENCE_TIME m_rtLastGotTime; // Last time returned by GetTime - REFERENCE_TIME m_rtNextAdvise; // Time of next advise - UINT m_TimerResolution; - -#ifdef PERF - int m_idGetSystemTime; -#endif - -// Thread stuff -public: - void TriggerThread() // Wakes thread up. Need to do this if - { // time to next advise needs reevaluating. - EXECUTE_ASSERT(SetEvent(m_pSchedule->GetEvent())); - } - - -private: - BOOL m_bAbort; // Flag used for thread shutdown - HANDLE m_hThread; // Thread handle - - HRESULT AdviseThread(); // Method in which the advise thread runs - static DWORD __stdcall AdviseThreadFunction(LPVOID); // Function used to get there - -protected: - CAMSchedule * const m_pSchedule; -}; - -#endif - diff --git a/src/BaseClasses/reftime.h b/src/BaseClasses/reftime.h deleted file mode 100644 index 0ed32f6e17..0000000000 --- a/src/BaseClasses/reftime.h +++ /dev/null @@ -1,116 +0,0 @@ -//------------------------------------------------------------------------------ -// File: RefTime.h -// -// Desc: DirectShow base classes - defines CRefTime, a class that manages -// reference times. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// -// CRefTime -// -// Manage reference times. -// Shares same data layout as REFERENCE_TIME, but adds some (nonvirtual) -// functions providing simple comparison, conversion and arithmetic. -// -// A reference time (at the moment) is a unit of seconds represented in -// 100ns units as is used in the Win32 FILETIME structure. BUT the time -// a REFERENCE_TIME represents is NOT the time elapsed since 1/1/1601 it -// will either be stream time or reference time depending upon context -// -// This class provides simple arithmetic operations on reference times -// -// keep non-virtual otherwise the data layout will not be the same as -// REFERENCE_TIME - - -// ----- -// note that you are safe to cast a CRefTime* to a REFERENCE_TIME*, but -// you will need to do so explicitly -// ----- - - -#ifndef __REFTIME__ -#define __REFTIME__ - - -const LONGLONG MILLISECONDS = (1000); // 10 ^ 3 -const LONGLONG NANOSECONDS = (1000000000); // 10 ^ 9 -const LONGLONG UNITS = (NANOSECONDS / 100); // 10 ^ 7 - -/* Unfortunately an inline function here generates a call to __allmul - - even for constants! -*/ -#define MILLISECONDS_TO_100NS_UNITS(lMs) \ - Int32x32To64((lMs), (UNITS / MILLISECONDS)) - -class CRefTime -{ -public: - - // *MUST* be the only data member so that this class is exactly - // equivalent to a REFERENCE_TIME. - // Also, must be *no virtual functions* - - REFERENCE_TIME m_time; - - inline CRefTime() - { - // default to 0 time - m_time = 0; - }; - - inline CRefTime(LONG msecs) - { - m_time = MILLISECONDS_TO_100NS_UNITS(msecs); - }; - - inline CRefTime(REFERENCE_TIME rt) - { - m_time = rt; - }; - - inline operator REFERENCE_TIME() const - { - return m_time; - }; - - inline CRefTime& operator=(const CRefTime& rt) - { - m_time = rt.m_time; - return *this; - }; - - inline CRefTime& operator=(const LONGLONG ll) - { - m_time = ll; - return *this; - }; - - inline CRefTime& operator+=(const CRefTime& rt) - { - return (*this = *this + rt); - }; - - inline CRefTime& operator-=(const CRefTime& rt) - { - return (*this = *this - rt); - }; - - inline LONG Millisecs(void) - { - return (LONG)(m_time / (UNITS / MILLISECONDS)); - }; - - inline LONGLONG GetUnits(void) - { - return m_time; - }; -}; - -const LONGLONG TimeZero = 0; - -#endif /* __REFTIME__ */ - diff --git a/src/BaseClasses/renbase.cpp b/src/BaseClasses/renbase.cpp deleted file mode 100644 index 81cdb60b24..0000000000 --- a/src/BaseClasses/renbase.cpp +++ /dev/null @@ -1,2833 +0,0 @@ -//------------------------------------------------------------------------------ -// File: RenBase.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include // DirectShow base class definitions -#include // Needed for definition of timeGetTime -#include // Standard data type limit definitions -#include // Used for time critical log functions - -#pragma warning(disable:4355) - -// Helper function for clamping time differences -int inline TimeDiff(REFERENCE_TIME rt) -{ - if (rt < - (50 * UNITS)) { - return -(50 * UNITS); - } else - if (rt > 50 * UNITS) { - return 50 * UNITS; - } else return (int)rt; -} - -// Implements the CBaseRenderer class - -CBaseRenderer::CBaseRenderer(REFCLSID RenderClass, // CLSID for this renderer - TCHAR *pName, // Debug ONLY description - LPUNKNOWN pUnk, // Aggregated owner object - HRESULT *phr) : // General OLE return code - - CBaseFilter(pName,pUnk,&m_InterfaceLock,RenderClass), - m_evComplete(TRUE), - m_bAbort(FALSE), - m_pPosition(NULL), - m_ThreadSignal(TRUE), - m_bStreaming(FALSE), - m_bEOS(FALSE), - m_bEOSDelivered(FALSE), - m_pMediaSample(NULL), - m_dwAdvise(0), - m_pQSink(NULL), - m_pInputPin(NULL), - m_bRepaintStatus(TRUE), - m_SignalTime(0), - m_bInReceive(FALSE), - m_EndOfStreamTimer(0) -{ - Ready(); -#ifdef PERF - m_idBaseStamp = MSR_REGISTER(TEXT("BaseRenderer: sample time stamp")); - m_idBaseRenderTime = MSR_REGISTER(TEXT("BaseRenderer: draw time (msec)")); - m_idBaseAccuracy = MSR_REGISTER(TEXT("BaseRenderer: Accuracy (msec)")); -#endif -} - - -// Delete the dynamically allocated IMediaPosition and IMediaSeeking helper -// object. The object is created when somebody queries us. These are standard -// control interfaces for seeking and setting start/stop positions and rates. -// We will probably also have made an input pin based on CRendererInputPin -// that has to be deleted, it's created when an enumerator calls our GetPin - -CBaseRenderer::~CBaseRenderer() -{ - ASSERT(m_bStreaming == FALSE); - ASSERT(m_EndOfStreamTimer == 0); - StopStreaming(); - ClearPendingSample(); - - // Delete any IMediaPosition implementation - - if (m_pPosition) { - delete m_pPosition; - m_pPosition = NULL; - } - - // Delete any input pin created - - if (m_pInputPin) { - delete m_pInputPin; - m_pInputPin = NULL; - } - - // Release any Quality sink - - ASSERT(m_pQSink == NULL); -} - - -// This returns the IMediaPosition and IMediaSeeking interfaces - -HRESULT CBaseRenderer::GetMediaPositionInterface(REFIID riid,void **ppv) -{ - CAutoLock cObjectCreationLock(&m_ObjectCreationLock); - if (m_pPosition) { - return m_pPosition->NonDelegatingQueryInterface(riid,ppv); - } - - HRESULT hr = NOERROR; - - // Create implementation of this dynamically since sometimes we may - // never try and do a seek. The helper object implements a position - // control interface (IMediaPosition) which in fact simply takes the - // calls normally from the filter graph and passes them upstream - - m_pPosition = new CRendererPosPassThru(NAME("Renderer CPosPassThru"), - CBaseFilter::GetOwner(), - (HRESULT *) &hr, - GetPin(0)); - if (m_pPosition == NULL) { - return E_OUTOFMEMORY; - } - - if (FAILED(hr)) { - delete m_pPosition; - m_pPosition = NULL; - return E_NOINTERFACE; - } - return GetMediaPositionInterface(riid,ppv); -} - - -// Overriden to say what interfaces we support and where - -STDMETHODIMP CBaseRenderer::NonDelegatingQueryInterface(REFIID riid,void **ppv) -{ - // Do we have this interface - - if (riid == IID_IMediaPosition || riid == IID_IMediaSeeking) { - return GetMediaPositionInterface(riid,ppv); - } else { - return CBaseFilter::NonDelegatingQueryInterface(riid,ppv); - } -} - - -// This is called whenever we change states, we have a manual reset event that -// is signalled whenever we don't won't the source filter thread to wait in us -// (such as in a stopped state) and likewise is not signalled whenever it can -// wait (during paused and running) this function sets or resets the thread -// event. The event is used to stop source filter threads waiting in Receive - -HRESULT CBaseRenderer::SourceThreadCanWait(BOOL bCanWait) -{ - if (bCanWait == TRUE) { - m_ThreadSignal.Reset(); - } else { - m_ThreadSignal.Set(); - } - return NOERROR; -} - - -#ifdef DEBUG -// Dump the current renderer state to the debug terminal. The hardest part of -// the renderer is the window where we unlock everything to wait for a clock -// to signal it is time to draw or for the application to cancel everything -// by stopping the filter. If we get things wrong we can leave the thread in -// WaitForRenderTime with no way for it to ever get out and we will deadlock - -void CBaseRenderer::DisplayRendererState() -{ - DbgLog((LOG_TIMING, 1, TEXT("\nTimed out in WaitForRenderTime"))); - - // No way should this be signalled at this point - - BOOL bSignalled = m_ThreadSignal.Check(); - DbgLog((LOG_TIMING, 1, TEXT("Signal sanity check %d"),bSignalled)); - - // Now output the current renderer state variables - - DbgLog((LOG_TIMING, 1, TEXT("Filter state %d"),m_State)); - DbgLog((LOG_TIMING, 1, TEXT("Abort flag %d"),m_bAbort)); - DbgLog((LOG_TIMING, 1, TEXT("Streaming flag %d"),m_bStreaming)); - DbgLog((LOG_TIMING, 1, TEXT("Clock advise link %d"),m_dwAdvise)); - DbgLog((LOG_TIMING, 1, TEXT("Current media sample %x"),m_pMediaSample)); - DbgLog((LOG_TIMING, 1, TEXT("EOS signalled %d"),m_bEOS)); - DbgLog((LOG_TIMING, 1, TEXT("EOS delivered %d"),m_bEOSDelivered)); - DbgLog((LOG_TIMING, 1, TEXT("Repaint status %d"),m_bRepaintStatus)); - - - // Output the delayed end of stream timer information - - DbgLog((LOG_TIMING, 1, TEXT("End of stream timer %x"),m_EndOfStreamTimer)); - DbgLog((LOG_TIMING, 1, TEXT("Deliver time %s"),CDisp((LONGLONG)m_SignalTime))); - - - // Should never timeout during a flushing state - - BOOL bFlushing = m_pInputPin->IsFlushing(); - DbgLog((LOG_TIMING, 1, TEXT("Flushing sanity check %d"),bFlushing)); - - // Display the time we were told to start at - DbgLog((LOG_TIMING, 1, TEXT("Last run time %s"),CDisp((LONGLONG)m_tStart.m_time))); - - // Do we have a reference clock? - if (m_pClock == NULL) return; - - // Get the current time from the wall clock - - CRefTime CurrentTime,StartTime,EndTime; - m_pClock->GetTime((REFERENCE_TIME*) &CurrentTime); - CRefTime Offset = CurrentTime - m_tStart; - - // Display the current time from the clock - - DbgLog((LOG_TIMING, 1, TEXT("Clock time %s"),CDisp((LONGLONG)CurrentTime.m_time))); - DbgLog((LOG_TIMING, 1, TEXT("Time difference %dms"),Offset.Millisecs())); - - // Do we have a sample ready to render - if (m_pMediaSample == NULL) return; - - m_pMediaSample->GetTime((REFERENCE_TIME*)&StartTime, (REFERENCE_TIME*)&EndTime); - DbgLog((LOG_TIMING, 1, TEXT("Next sample stream times (Start %d End %d ms)"), - StartTime.Millisecs(),EndTime.Millisecs())); - - // Calculate how long it is until it is due for rendering - CRefTime Wait = (m_tStart + StartTime) - CurrentTime; - DbgLog((LOG_TIMING, 1, TEXT("Wait required %d ms"),Wait.Millisecs())); -} -#endif - - -// Wait until the clock sets the timer event or we're otherwise signalled. We -// set an arbitrary timeout for this wait and if it fires then we display the -// current renderer state on the debugger. It will often fire if the filter's -// left paused in an application however it may also fire during stress tests -// if the synchronisation with application seeks and state changes is faulty - -#define RENDER_TIMEOUT 10000 - -HRESULT CBaseRenderer::WaitForRenderTime() -{ - HANDLE WaitObjects[] = { m_ThreadSignal, m_RenderEvent }; - DWORD Result = WAIT_TIMEOUT; - - // Wait for either the time to arrive or for us to be stopped - - OnWaitStart(); - while (Result == WAIT_TIMEOUT) { - Result = WaitForMultipleObjects(2,WaitObjects,FALSE,RENDER_TIMEOUT); - -#ifdef DEBUG - if (Result == WAIT_TIMEOUT) DisplayRendererState(); -#endif - - } - OnWaitEnd(); - - // We may have been awoken without the timer firing - - if (Result == WAIT_OBJECT_0) { - return VFW_E_STATE_CHANGED; - } - - SignalTimerFired(); - return NOERROR; -} - - -// Poll waiting for Receive to complete. This really matters when -// Receive may set the palette and cause window messages -// The problem is that if we don't really wait for a renderer to -// stop processing we can deadlock waiting for a transform which -// is calling the renderer's Receive() method because the transform's -// Stop method doesn't know to process window messages to unblock -// the renderer's Receive processing -void CBaseRenderer::WaitForReceiveToComplete() -{ - for (;;) { - if (!m_bInReceive) { - break; - } - - MSG msg; - // Receive all interthread sendmessages - PeekMessage(&msg, NULL, WM_NULL, WM_NULL, PM_NOREMOVE); - - Sleep(1); - } - - // If the wakebit for QS_POSTMESSAGE is set, the PeekMessage call - // above just cleared the changebit which will cause some messaging - // calls to block (waitMessage, MsgWaitFor...) now. - // Post a dummy message to set the QS_POSTMESSAGE bit again - if (HIWORD(GetQueueStatus(QS_POSTMESSAGE)) & QS_POSTMESSAGE) { - // Send dummy message - PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0); - } -} - -// A filter can have four discrete states, namely Stopped, Running, Paused, -// Intermediate. We are in an intermediate state if we are currently trying -// to pause but haven't yet got the first sample (or if we have been flushed -// in paused state and therefore still have to wait for a sample to arrive) - -// This class contains an event called m_evComplete which is signalled when -// the current state is completed and is not signalled when we are waiting to -// complete the last state transition. As mentioned above the only time we -// use this at the moment is when we wait for a media sample in paused state -// If while we are waiting we receive an end of stream notification from the -// source filter then we know no data is imminent so we can reset the event -// This means that when we transition to paused the source filter must call -// end of stream on us or send us an image otherwise we'll hang indefinately - - -// Simple internal way of getting the real state - -FILTER_STATE CBaseRenderer::GetRealState() { - return m_State; -} - - -// The renderer doesn't complete the full transition to paused states until -// it has got one media sample to render. If you ask it for its state while -// it's waiting it will return the state along with VFW_S_STATE_INTERMEDIATE - -STDMETHODIMP CBaseRenderer::GetState(DWORD dwMSecs,FILTER_STATE *State) -{ - CheckPointer(State,E_POINTER); - - if (WaitDispatchingMessages(m_evComplete, dwMSecs) == WAIT_TIMEOUT) { - *State = m_State; - return VFW_S_STATE_INTERMEDIATE; - } - *State = m_State; - return NOERROR; -} - - -// If we're pausing and we have no samples we don't complete the transition -// to State_Paused and we return S_FALSE. However if the m_bAbort flag has -// been set then all samples are rejected so there is no point waiting for -// one. If we do have a sample then return NOERROR. We will only ever return -// VFW_S_STATE_INTERMEDIATE from GetState after being paused with no sample -// (calling GetState after either being stopped or Run will NOT return this) - -HRESULT CBaseRenderer::CompleteStateChange(FILTER_STATE OldState) -{ - // Allow us to be paused when disconnected - - if (m_pInputPin->IsConnected() == FALSE) { - Ready(); - return S_OK; - } - - // Have we run off the end of stream - - if (IsEndOfStream() == TRUE) { - Ready(); - return S_OK; - } - - // Make sure we get fresh data after being stopped - - if (HaveCurrentSample() == TRUE) { - if (OldState != State_Stopped) { - Ready(); - return S_OK; - } - } - NotReady(); - return S_FALSE; -} - - -// When we stop the filter the things we do are:- - -// Decommit the allocator being used in the connection -// Release the source filter if it's waiting in Receive -// Cancel any advise link we set up with the clock -// Any end of stream signalled is now obsolete so reset -// Allow us to be stopped when we are not connected - -STDMETHODIMP CBaseRenderer::Stop() -{ - CAutoLock cRendererLock(&m_InterfaceLock); - - // Make sure there really is a state change - - if (m_State == State_Stopped) { - return NOERROR; - } - - // Is our input pin connected - - if (m_pInputPin->IsConnected() == FALSE) { - NOTE("Input pin is not connected"); - m_State = State_Stopped; - return NOERROR; - } - - CBaseFilter::Stop(); - - // If we are going into a stopped state then we must decommit whatever - // allocator we are using it so that any source filter waiting in the - // GetBuffer can be released and unlock themselves for a state change - - if (m_pInputPin->Allocator()) { - m_pInputPin->Allocator()->Decommit(); - } - - // Cancel any scheduled rendering - - SetRepaintStatus(TRUE); - StopStreaming(); - SourceThreadCanWait(FALSE); - ResetEndOfStream(); - CancelNotification(); - - // There should be no outstanding clock advise - ASSERT(CancelNotification() == S_FALSE); - ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0)); - ASSERT(m_EndOfStreamTimer == 0); - - Ready(); - WaitForReceiveToComplete(); - m_bAbort = FALSE; - - return NOERROR; -} - - -// When we pause the filter the things we do are:- - -// Commit the allocator being used in the connection -// Allow a source filter thread to wait in Receive -// Cancel any clock advise link (we may be running) -// Possibly complete the state change if we have data -// Allow us to be paused when we are not connected - -STDMETHODIMP CBaseRenderer::Pause() -{ - CAutoLock cRendererLock(&m_InterfaceLock); - FILTER_STATE OldState = m_State; - ASSERT(m_pInputPin->IsFlushing() == FALSE); - - // Make sure there really is a state change - - if (m_State == State_Paused) { - return CompleteStateChange(State_Paused); - } - - // Has our input pin been connected - - if (m_pInputPin->IsConnected() == FALSE) { - NOTE("Input pin is not connected"); - m_State = State_Paused; - return CompleteStateChange(State_Paused); - } - - // Pause the base filter class - - HRESULT hr = CBaseFilter::Pause(); - if (FAILED(hr)) { - NOTE("Pause failed"); - return hr; - } - - // Enable EC_REPAINT events again - - SetRepaintStatus(TRUE); - StopStreaming(); - SourceThreadCanWait(TRUE); - CancelNotification(); - ResetEndOfStreamTimer(); - - // If we are going into a paused state then we must commit whatever - // allocator we are using it so that any source filter can call the - // GetBuffer and expect to get a buffer without returning an error - - if (m_pInputPin->Allocator()) { - m_pInputPin->Allocator()->Commit(); - } - - // There should be no outstanding advise - ASSERT(CancelNotification() == S_FALSE); - ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0)); - ASSERT(m_EndOfStreamTimer == 0); - ASSERT(m_pInputPin->IsFlushing() == FALSE); - - // When we come out of a stopped state we must clear any image we were - // holding onto for frame refreshing. Since renderers see state changes - // first we can reset ourselves ready to accept the source thread data - // Paused or running after being stopped causes the current position to - // be reset so we're not interested in passing end of stream signals - - if (OldState == State_Stopped) { - m_bAbort = FALSE; - ClearPendingSample(); - } - return CompleteStateChange(OldState); -} - - -// When we run the filter the things we do are:- - -// Commit the allocator being used in the connection -// Allow a source filter thread to wait in Receive -// Signal the render event just to get us going -// Start the base class by calling StartStreaming -// Allow us to be run when we are not connected -// Signal EC_COMPLETE if we are not connected - -STDMETHODIMP CBaseRenderer::Run(REFERENCE_TIME StartTime) -{ - CAutoLock cRendererLock(&m_InterfaceLock); - FILTER_STATE OldState = m_State; - - // Make sure there really is a state change - - if (m_State == State_Running) { - return NOERROR; - } - - // Send EC_COMPLETE if we're not connected - - if (m_pInputPin->IsConnected() == FALSE) { - NotifyEvent(EC_COMPLETE,S_OK,(LONG_PTR)(IBaseFilter *)this); - m_State = State_Running; - return NOERROR; - } - - Ready(); - - // Pause the base filter class - - HRESULT hr = CBaseFilter::Run(StartTime); - if (FAILED(hr)) { - NOTE("Run failed"); - return hr; - } - - // Allow the source thread to wait - ASSERT(m_pInputPin->IsFlushing() == FALSE); - SourceThreadCanWait(TRUE); - SetRepaintStatus(FALSE); - - // There should be no outstanding advise - ASSERT(CancelNotification() == S_FALSE); - ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0)); - ASSERT(m_EndOfStreamTimer == 0); - ASSERT(m_pInputPin->IsFlushing() == FALSE); - - // If we are going into a running state then we must commit whatever - // allocator we are using it so that any source filter can call the - // GetBuffer and expect to get a buffer without returning an error - - if (m_pInputPin->Allocator()) { - m_pInputPin->Allocator()->Commit(); - } - - // When we come out of a stopped state we must clear any image we were - // holding onto for frame refreshing. Since renderers see state changes - // first we can reset ourselves ready to accept the source thread data - // Paused or running after being stopped causes the current position to - // be reset so we're not interested in passing end of stream signals - - if (OldState == State_Stopped) { - m_bAbort = FALSE; - ClearPendingSample(); - } - return StartStreaming(); -} - - -// Return the number of input pins we support - -int CBaseRenderer::GetPinCount() -{ - return 1; -} - - -// We only support one input pin and it is numbered zero - -CBasePin *CBaseRenderer::GetPin(int n) -{ - CAutoLock cObjectCreationLock(&m_ObjectCreationLock); - - // Should only ever be called with zero - ASSERT(n == 0); - - if (n != 0) { - return NULL; - } - - // Create the input pin if not already done so - - if (m_pInputPin == NULL) { - - // hr must be initialized to NOERROR because - // CRendererInputPin's constructor only changes - // hr's value if an error occurs. - HRESULT hr = NOERROR; - - m_pInputPin = new CRendererInputPin(this,&hr,L"In"); - if (NULL == m_pInputPin) { - return NULL; - } - - if (FAILED(hr)) { - delete m_pInputPin; - m_pInputPin = NULL; - return NULL; - } - } - return m_pInputPin; -} - - -// If "In" then return the IPin for our input pin, otherwise NULL and error - -STDMETHODIMP CBaseRenderer::FindPin(LPCWSTR Id, IPin **ppPin) -{ - CheckPointer(ppPin,E_POINTER); - - if (0==lstrcmpW(Id,L"In")) { - *ppPin = GetPin(0); - ASSERT(*ppPin); - (*ppPin)->AddRef(); - } else { - *ppPin = NULL; - return VFW_E_NOT_FOUND; - } - return NOERROR; -} - - -// Called when the input pin receives an EndOfStream notification. If we have -// not got a sample, then notify EC_COMPLETE now. If we have samples, then set -// m_bEOS and check for this on completing samples. If we're waiting to pause -// then complete the transition to paused state by setting the state event - -HRESULT CBaseRenderer::EndOfStream() -{ - // Ignore these calls if we are stopped - - if (m_State == State_Stopped) { - return NOERROR; - } - - // If we have a sample then wait for it to be rendered - - m_bEOS = TRUE; - if (m_pMediaSample) { - return NOERROR; - } - - // If we are waiting for pause then we are now ready since we cannot now - // carry on waiting for a sample to arrive since we are being told there - // won't be any. This sets an event that the GetState function picks up - - Ready(); - - // Only signal completion now if we are running otherwise queue it until - // we do run in StartStreaming. This is used when we seek because a seek - // causes a pause where early notification of completion is misleading - - if (m_bStreaming) { - SendEndOfStream(); - } - return NOERROR; -} - - -// When we are told to flush we should release the source thread - -HRESULT CBaseRenderer::BeginFlush() -{ - // If paused then report state intermediate until we get some data - - if (m_State == State_Paused) { - NotReady(); - } - - SourceThreadCanWait(FALSE); - CancelNotification(); - ClearPendingSample(); - // Wait for Receive to complete - WaitForReceiveToComplete(); - - return NOERROR; -} - - -// After flushing the source thread can wait in Receive again - -HRESULT CBaseRenderer::EndFlush() -{ - // Reset the current sample media time - if (m_pPosition) m_pPosition->ResetMediaTime(); - - // There should be no outstanding advise - - ASSERT(CancelNotification() == S_FALSE); - SourceThreadCanWait(TRUE); - return NOERROR; -} - - -// We can now send EC_REPAINTs if so required - -HRESULT CBaseRenderer::CompleteConnect(IPin *pReceivePin) -{ - // The caller should always hold the interface lock because - // the function uses CBaseFilter::m_State. - ASSERT(CritCheckIn(&m_InterfaceLock)); - - m_bAbort = FALSE; - - if (State_Running == GetRealState()) { - HRESULT hr = StartStreaming(); - if (FAILED(hr)) { - return hr; - } - - SetRepaintStatus(FALSE); - } else { - SetRepaintStatus(TRUE); - } - - return NOERROR; -} - - -// Called when we go paused or running - -HRESULT CBaseRenderer::Active() -{ - return NOERROR; -} - - -// Called when we go into a stopped state - -HRESULT CBaseRenderer::Inactive() -{ - if (m_pPosition) { - m_pPosition->ResetMediaTime(); - } - // People who derive from this may want to override this behaviour - // to keep hold of the sample in some circumstances - ClearPendingSample(); - - return NOERROR; -} - - -// Tell derived classes about the media type agreed - -HRESULT CBaseRenderer::SetMediaType(const CMediaType *pmt) -{ - return NOERROR; -} - - -// When we break the input pin connection we should reset the EOS flags. When -// we are asked for either IMediaPosition or IMediaSeeking we will create a -// CPosPassThru object to handles media time pass through. When we're handed -// samples we store (by calling CPosPassThru::RegisterMediaTime) their media -// times so we can then return a real current position of data being rendered - -HRESULT CBaseRenderer::BreakConnect() -{ - // Do we have a quality management sink - - if (m_pQSink) { - m_pQSink->Release(); - m_pQSink = NULL; - } - - // Check we have a valid connection - - if (m_pInputPin->IsConnected() == FALSE) { - return S_FALSE; - } - - // Check we are stopped before disconnecting - if (m_State != State_Stopped && !m_pInputPin->CanReconnectWhenActive()) { - return VFW_E_NOT_STOPPED; - } - - SetRepaintStatus(FALSE); - ResetEndOfStream(); - ClearPendingSample(); - m_bAbort = FALSE; - - if (State_Running == m_State) { - StopStreaming(); - } - - return NOERROR; -} - - -// Retrieves the sample times for this samples (note the sample times are -// passed in by reference not value). We return S_FALSE to say schedule this -// sample according to the times on the sample. We also return S_OK in -// which case the object should simply render the sample data immediately - -HRESULT CBaseRenderer::GetSampleTimes(IMediaSample *pMediaSample, - REFERENCE_TIME *pStartTime, - REFERENCE_TIME *pEndTime) -{ - ASSERT(m_dwAdvise == 0); - ASSERT(pMediaSample); - - // If the stop time for this sample is before or the same as start time, - // then just ignore it (release it) and schedule the next one in line - // Source filters should always fill in the start and end times properly! - - if (SUCCEEDED(pMediaSample->GetTime(pStartTime, pEndTime))) { - if (*pEndTime < *pStartTime) { - return VFW_E_START_TIME_AFTER_END; - } - } else { - // no time set in the sample... draw it now? - return S_OK; - } - - // Can't synchronise without a clock so we return S_OK which tells the - // caller that the sample should be rendered immediately without going - // through the overhead of setting a timer advise link with the clock - - if (m_pClock == NULL) { - return S_OK; - } - return ShouldDrawSampleNow(pMediaSample,pStartTime,pEndTime); -} - - -// By default all samples are drawn according to their time stamps so we -// return S_FALSE. Returning S_OK means draw immediately, this is used -// by the derived video renderer class in its quality management. - -HRESULT CBaseRenderer::ShouldDrawSampleNow(IMediaSample *pMediaSample, - REFERENCE_TIME *ptrStart, - REFERENCE_TIME *ptrEnd) -{ - return S_FALSE; -} - - -// We must always reset the current advise time to zero after a timer fires -// because there are several possible ways which lead us not to do any more -// scheduling such as the pending image being cleared after state changes - -void CBaseRenderer::SignalTimerFired() -{ - m_dwAdvise = 0; -} - - -// Cancel any notification currently scheduled. This is called by the owning -// window object when it is told to stop streaming. If there is no timer link -// outstanding then calling this is benign otherwise we go ahead and cancel -// We must always reset the render event as the quality management code can -// signal immediate rendering by setting the event without setting an advise -// link. If we're subsequently stopped and run the first attempt to setup an -// advise link with the reference clock will find the event still signalled - -HRESULT CBaseRenderer::CancelNotification() -{ - ASSERT(m_dwAdvise == 0 || m_pClock); - DWORD_PTR dwAdvise = m_dwAdvise; - - // Have we a live advise link - - if (m_dwAdvise) { - m_pClock->Unadvise(m_dwAdvise); - SignalTimerFired(); - ASSERT(m_dwAdvise == 0); - } - - // Clear the event and return our status - - m_RenderEvent.Reset(); - return (dwAdvise ? S_OK : S_FALSE); -} - - -// Responsible for setting up one shot advise links with the clock -// Return FALSE if the sample is to be dropped (not drawn at all) -// Return TRUE if the sample is to be drawn and in this case also -// arrange for m_RenderEvent to be set at the appropriate time - -BOOL CBaseRenderer::ScheduleSample(IMediaSample *pMediaSample) -{ - REFERENCE_TIME StartSample, EndSample; - - // Is someone pulling our leg - - if (pMediaSample == NULL) { - return FALSE; - } - - // Get the next sample due up for rendering. If there aren't any ready - // then GetNextSampleTimes returns an error. If there is one to be done - // then it succeeds and yields the sample times. If it is due now then - // it returns S_OK other if it's to be done when due it returns S_FALSE - - HRESULT hr = GetSampleTimes(pMediaSample, &StartSample, &EndSample); - if (FAILED(hr)) { - return FALSE; - } - - // If we don't have a reference clock then we cannot set up the advise - // time so we simply set the event indicating an image to render. This - // will cause us to run flat out without any timing or synchronisation - - if (hr == S_OK) { - EXECUTE_ASSERT(SetEvent((HANDLE) m_RenderEvent)); - return TRUE; - } - - ASSERT(m_dwAdvise == 0); - ASSERT(m_pClock); - ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0)); - - // We do have a valid reference clock interface so we can ask it to - // set an event when the image comes due for rendering. We pass in - // the reference time we were told to start at and also the current - // stream time which is the offset from the start reference time - - hr = m_pClock->AdviseTime( - (REFERENCE_TIME) m_tStart, // Start run time - StartSample, // Stream time - (HEVENT)(HANDLE) m_RenderEvent, // Render notification - &m_dwAdvise); // Advise cookie - - if (SUCCEEDED(hr)) { - return TRUE; - } - - // We could not schedule the next sample for rendering despite the fact - // we have a valid sample here. This is a fair indication that either - // the system clock is wrong or the time stamp for the sample is duff - - ASSERT(m_dwAdvise == 0); - return FALSE; -} - - -// This is called when a sample comes due for rendering. We pass the sample -// on to the derived class. After rendering we will initialise the timer for -// the next sample, NOTE signal that the last one fired first, if we don't -// do this it thinks there is still one outstanding that hasn't completed - -HRESULT CBaseRenderer::Render(IMediaSample *pMediaSample) -{ - // If the media sample is NULL then we will have been notified by the - // clock that another sample is ready but in the mean time someone has - // stopped us streaming which causes the next sample to be released - - if (pMediaSample == NULL) { - return S_FALSE; - } - - // If we have stopped streaming then don't render any more samples, the - // thread that got in and locked us and then reset this flag does not - // clear the pending sample as we can use it to refresh any output device - - if (m_bStreaming == FALSE) { - return S_FALSE; - } - - // Time how long the rendering takes - - OnRenderStart(pMediaSample); - DoRenderSample(pMediaSample); - OnRenderEnd(pMediaSample); - - return NOERROR; -} - - -// Checks if there is a sample waiting at the renderer - -BOOL CBaseRenderer::HaveCurrentSample() -{ - CAutoLock cRendererLock(&m_RendererLock); - return (m_pMediaSample == NULL ? FALSE : TRUE); -} - - -// Returns the current sample waiting at the video renderer. We AddRef the -// sample before returning so that should it come due for rendering the -// person who called this method will hold the remaining reference count -// that will stop the sample being added back onto the allocator free list - -IMediaSample *CBaseRenderer::GetCurrentSample() -{ - CAutoLock cRendererLock(&m_RendererLock); - if (m_pMediaSample) { - m_pMediaSample->AddRef(); - } - return m_pMediaSample; -} - - -// Called when the source delivers us a sample. We go through a few checks to -// make sure the sample can be rendered. If we are running (streaming) then we -// have the sample scheduled with the reference clock, if we are not streaming -// then we have received an sample in paused mode so we can complete any state -// transition. On leaving this function everything will be unlocked so an app -// thread may get in and change our state to stopped (for example) in which -// case it will also signal the thread event so that our wait call is stopped - -HRESULT CBaseRenderer::PrepareReceive(IMediaSample *pMediaSample) -{ - CAutoLock cInterfaceLock(&m_InterfaceLock); - m_bInReceive = TRUE; - - // Check our flushing and filter state - - // This function must hold the interface lock because it calls - // CBaseInputPin::Receive() and CBaseInputPin::Receive() uses - // CBasePin::m_bRunTimeError. - HRESULT hr = m_pInputPin->CBaseInputPin::Receive(pMediaSample); - - if (hr != NOERROR) { - m_bInReceive = FALSE; - return E_FAIL; - } - - // Has the type changed on a media sample. We do all rendering - // synchronously on the source thread, which has a side effect - // that only one buffer is ever outstanding. Therefore when we - // have Receive called we can go ahead and change the format - // Since the format change can cause a SendMessage we just don't - // lock - if (m_pInputPin->SampleProps()->pMediaType) { - hr = m_pInputPin->SetMediaType( - (CMediaType *)m_pInputPin->SampleProps()->pMediaType); - if (FAILED(hr)) { - m_bInReceive = FALSE; - return hr; - } - } - - - CAutoLock cSampleLock(&m_RendererLock); - - ASSERT(IsActive() == TRUE); - ASSERT(m_pInputPin->IsFlushing() == FALSE); - ASSERT(m_pInputPin->IsConnected() == TRUE); - ASSERT(m_pMediaSample == NULL); - - // Return an error if we already have a sample waiting for rendering - // source pins must serialise the Receive calls - we also check that - // no data is being sent after the source signalled an end of stream - - if (m_pMediaSample || m_bEOS || m_bAbort) { - Ready(); - m_bInReceive = FALSE; - return E_UNEXPECTED; - } - - // Store the media times from this sample - if (m_pPosition) m_pPosition->RegisterMediaTime(pMediaSample); - - // Schedule the next sample if we are streaming - - if ((m_bStreaming == TRUE) && (ScheduleSample(pMediaSample) == FALSE)) { - ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0)); - ASSERT(CancelNotification() == S_FALSE); - m_bInReceive = FALSE; - return VFW_E_SAMPLE_REJECTED; - } - - // Store the sample end time for EC_COMPLETE handling - m_SignalTime = m_pInputPin->SampleProps()->tStop; - - // BEWARE we sometimes keep the sample even after returning the thread to - // the source filter such as when we go into a stopped state (we keep it - // to refresh the device with) so we must AddRef it to keep it safely. If - // we start flushing the source thread is released and any sample waiting - // will be released otherwise GetBuffer may never return (see BeginFlush) - - m_pMediaSample = pMediaSample; - m_pMediaSample->AddRef(); - - if (m_bStreaming == FALSE) { - SetRepaintStatus(TRUE); - } - return NOERROR; -} - - -// Called by the source filter when we have a sample to render. Under normal -// circumstances we set an advise link with the clock, wait for the time to -// arrive and then render the data using the PURE virtual DoRenderSample that -// the derived class will have overriden. After rendering the sample we may -// also signal EOS if it was the last one sent before EndOfStream was called - -HRESULT CBaseRenderer::Receive(IMediaSample *pSample) -{ - ASSERT(pSample); - - // It may return VFW_E_SAMPLE_REJECTED code to say don't bother - - HRESULT hr = PrepareReceive(pSample); - ASSERT(m_bInReceive == SUCCEEDED(hr)); - if (FAILED(hr)) { - if (hr == VFW_E_SAMPLE_REJECTED) { - return NOERROR; - } - return hr; - } - - // We realize the palette in "PrepareRender()" so we have to give away the - // filter lock here. - if (m_State == State_Paused) { - PrepareRender(); - // no need to use InterlockedExchange - m_bInReceive = FALSE; - { - // We must hold both these locks - CAutoLock cRendererLock(&m_InterfaceLock); - if (m_State == State_Stopped) - return NOERROR; - - m_bInReceive = TRUE; - CAutoLock cSampleLock(&m_RendererLock); - OnReceiveFirstSample(pSample); - } - Ready(); - } - // Having set an advise link with the clock we sit and wait. We may be - // awoken by the clock firing or by a state change. The rendering call - // will lock the critical section and check we can still render the data - - hr = WaitForRenderTime(); - if (FAILED(hr)) { - m_bInReceive = FALSE; - return NOERROR; - } - - PrepareRender(); - - // Set this here and poll it until we work out the locking correctly - // It can't be right that the streaming stuff grabs the interface - // lock - after all we want to be able to wait for this stuff - // to complete - m_bInReceive = FALSE; - - // We must hold both these locks - CAutoLock cRendererLock(&m_InterfaceLock); - - // since we gave away the filter wide lock, the sate of the filter could - // have chnaged to Stopped - if (m_State == State_Stopped) - return NOERROR; - - CAutoLock cSampleLock(&m_RendererLock); - - // Deal with this sample - - Render(m_pMediaSample); - ClearPendingSample(); - SendEndOfStream(); - CancelNotification(); - return NOERROR; -} - - -// This is called when we stop or are inactivated to clear the pending sample -// We release the media sample interface so that they can be allocated to the -// source filter again, unless of course we are changing state to inactive in -// which case GetBuffer will return an error. We must also reset the current -// media sample to NULL so that we know we do not currently have an image - -HRESULT CBaseRenderer::ClearPendingSample() -{ - CAutoLock cRendererLock(&m_RendererLock); - if (m_pMediaSample) { - m_pMediaSample->Release(); - m_pMediaSample = NULL; - } - return NOERROR; -} - - -// Used to signal end of stream according to the sample end time - -void CALLBACK EndOfStreamTimer(UINT uID, // Timer identifier - UINT uMsg, // Not currently used - DWORD_PTR dwUser,// User information - DWORD_PTR dw1, // Windows reserved - DWORD_PTR dw2) // is also reserved -{ - CBaseRenderer *pRenderer = (CBaseRenderer *) dwUser; - NOTE1("EndOfStreamTimer called (%d)",uID); - pRenderer->TimerCallback(); -} - -// Do the timer callback work -void CBaseRenderer::TimerCallback() -{ - // Lock for synchronization (but don't hold this lock when calling - // timeKillEvent) - CAutoLock cRendererLock(&m_RendererLock); - - // See if we should signal end of stream now - - if (m_EndOfStreamTimer) { - m_EndOfStreamTimer = 0; - SendEndOfStream(); - } -} - - -// If we are at the end of the stream signal the filter graph but do not set -// the state flag back to FALSE. Once we drop off the end of the stream we -// leave the flag set (until a subsequent ResetEndOfStream). Each sample we -// get delivered will update m_SignalTime to be the last sample's end time. -// We must wait this long before signalling end of stream to the filtergraph - -#define TIMEOUT_DELIVERYWAIT 50 -#define TIMEOUT_RESOLUTION 10 - -HRESULT CBaseRenderer::SendEndOfStream() -{ - ASSERT(CritCheckIn(&m_RendererLock)); - if (m_bEOS == FALSE || m_bEOSDelivered || m_EndOfStreamTimer) { - return NOERROR; - } - - // If there is no clock then signal immediately - if (m_pClock == NULL) { - return NotifyEndOfStream(); - } - - // How long into the future is the delivery time - - REFERENCE_TIME Signal = m_tStart + m_SignalTime; - REFERENCE_TIME CurrentTime; - m_pClock->GetTime(&CurrentTime); - LONG Delay = LONG((Signal - CurrentTime) / 10000); - - // Dump the timing information to the debugger - - NOTE1("Delay until end of stream delivery %d",Delay); - NOTE1("Current %s",(LPCTSTR)CDisp((LONGLONG)CurrentTime)); - NOTE1("Signal %s",(LPCTSTR)CDisp((LONGLONG)Signal)); - - // Wait for the delivery time to arrive - - if (Delay < TIMEOUT_DELIVERYWAIT) { - return NotifyEndOfStream(); - } - - // Signal a timer callback on another worker thread - - m_EndOfStreamTimer = CompatibleTimeSetEvent((UINT) Delay, // Period of timer - TIMEOUT_RESOLUTION, // Timer resolution - EndOfStreamTimer, // Callback function - DWORD_PTR(this), // Used information - TIME_ONESHOT); // Type of callback - if (m_EndOfStreamTimer == 0) { - return NotifyEndOfStream(); - } - return NOERROR; -} - - -// Signals EC_COMPLETE to the filtergraph manager - -HRESULT CBaseRenderer::NotifyEndOfStream() -{ - CAutoLock cRendererLock(&m_RendererLock); - ASSERT(m_bEOSDelivered == FALSE); - ASSERT(m_EndOfStreamTimer == 0); - - // Has the filter changed state - - if (m_bStreaming == FALSE) { - ASSERT(m_EndOfStreamTimer == 0); - return NOERROR; - } - - // Reset the end of stream timer - m_EndOfStreamTimer = 0; - - // If we've been using the IMediaPosition interface, set it's start - // and end media "times" to the stop position by hand. This ensures - // that we actually get to the end, even if the MPEG guestimate has - // been bad or if the quality management dropped the last few frames - - if (m_pPosition) m_pPosition->EOS(); - m_bEOSDelivered = TRUE; - NOTE("Sending EC_COMPLETE..."); - return NotifyEvent(EC_COMPLETE,S_OK,(LONG_PTR)(IBaseFilter *)this); -} - - -// Reset the end of stream flag, this is typically called when we transfer to -// stopped states since that resets the current position back to the start so -// we will receive more samples or another EndOfStream if there aren't any. We -// keep two separate flags one to say we have run off the end of the stream -// (this is the m_bEOS flag) and another to say we have delivered EC_COMPLETE -// to the filter graph. We need the latter otherwise we can end up sending an -// EC_COMPLETE every time the source changes state and calls our EndOfStream - -HRESULT CBaseRenderer::ResetEndOfStream() -{ - ResetEndOfStreamTimer(); - CAutoLock cRendererLock(&m_RendererLock); - - m_bEOS = FALSE; - m_bEOSDelivered = FALSE; - m_SignalTime = 0; - - return NOERROR; -} - - -// Kills any outstanding end of stream timer - -void CBaseRenderer::ResetEndOfStreamTimer() -{ - ASSERT(CritCheckOut(&m_RendererLock)); - if (m_EndOfStreamTimer) { - timeKillEvent(m_EndOfStreamTimer); - m_EndOfStreamTimer = 0; - } -} - - -// This is called when we start running so that we can schedule any pending -// image we have with the clock and display any timing information. If we -// don't have any sample but we have queued an EOS flag then we send it. If -// we do have a sample then we wait until that has been rendered before we -// signal the filter graph otherwise we may change state before it's done - -HRESULT CBaseRenderer::StartStreaming() -{ - CAutoLock cRendererLock(&m_RendererLock); - if (m_bStreaming == TRUE) { - return NOERROR; - } - - // Reset the streaming times ready for running - - m_bStreaming = TRUE; - - timeBeginPeriod(1); - OnStartStreaming(); - - // There should be no outstanding advise - ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0)); - ASSERT(CancelNotification() == S_FALSE); - - // If we have an EOS and no data then deliver it now - - if (m_pMediaSample == NULL) { - return SendEndOfStream(); - } - - // Have the data rendered - - ASSERT(m_pMediaSample); - if (!ScheduleSample(m_pMediaSample)) - m_RenderEvent.Set(); - - return NOERROR; -} - - -// This is called when we stop streaming so that we can set our internal flag -// indicating we are not now to schedule any more samples arriving. The state -// change methods in the filter implementation take care of cancelling any -// clock advise link we have set up and clearing any pending sample we have - -HRESULT CBaseRenderer::StopStreaming() -{ - CAutoLock cRendererLock(&m_RendererLock); - m_bEOSDelivered = FALSE; - - if (m_bStreaming == TRUE) { - m_bStreaming = FALSE; - OnStopStreaming(); - timeEndPeriod(1); - } - return NOERROR; -} - - -// We have a boolean flag that is reset when we have signalled EC_REPAINT to -// the filter graph. We set this when we receive an image so that should any -// conditions arise again we can send another one. By having a flag we ensure -// we don't flood the filter graph with redundant calls. We do not set the -// event when we receive an EndOfStream call since there is no point in us -// sending further EC_REPAINTs. In particular the AutoShowWindow method and -// the DirectDraw object use this method to control the window repainting - -void CBaseRenderer::SetRepaintStatus(BOOL bRepaint) -{ - CAutoLock cSampleLock(&m_RendererLock); - m_bRepaintStatus = bRepaint; -} - - -// Pass the window handle to the upstream filter - -void CBaseRenderer::SendNotifyWindow(IPin *pPin,HWND hwnd) -{ - IMediaEventSink *pSink; - - // Does the pin support IMediaEventSink - HRESULT hr = pPin->QueryInterface(IID_IMediaEventSink,(void **)&pSink); - if (SUCCEEDED(hr)) { - pSink->Notify(EC_NOTIFY_WINDOW,LONG_PTR(hwnd),0); - pSink->Release(); - } - NotifyEvent(EC_NOTIFY_WINDOW,LONG_PTR(hwnd),0); -} - - -// Signal an EC_REPAINT to the filter graph. This can be used to have data -// sent to us. For example when a video window is first displayed it may -// not have an image to display, at which point it signals EC_REPAINT. The -// filtergraph will either pause the graph if stopped or if already paused -// it will call put_CurrentPosition of the current position. Setting the -// current position to itself has the stream flushed and the image resent - -#define RLOG(_x_) DbgLog((LOG_TRACE,1,TEXT(_x_))); - -void CBaseRenderer::SendRepaint() -{ - CAutoLock cSampleLock(&m_RendererLock); - ASSERT(m_pInputPin); - - // We should not send repaint notifications when... - // - An end of stream has been notified - // - Our input pin is being flushed - // - The input pin is not connected - // - We have aborted a video playback - // - There is a repaint already sent - - if (m_bAbort == FALSE) { - if (m_pInputPin->IsConnected() == TRUE) { - if (m_pInputPin->IsFlushing() == FALSE) { - if (IsEndOfStream() == FALSE) { - if (m_bRepaintStatus == TRUE) { - IPin *pPin = (IPin *) m_pInputPin; - NotifyEvent(EC_REPAINT,(LONG_PTR) pPin,0); - SetRepaintStatus(FALSE); - RLOG("Sending repaint"); - } - } - } - } - } -} - - -// When a video window detects a display change (WM_DISPLAYCHANGE message) it -// can send an EC_DISPLAY_CHANGED event code along with the renderer pin. The -// filtergraph will stop everyone and reconnect our input pin. As we're then -// reconnected we can accept the media type that matches the new display mode -// since we may no longer be able to draw the current image type efficiently - -BOOL CBaseRenderer::OnDisplayChange() -{ - // Ignore if we are not connected yet - - CAutoLock cSampleLock(&m_RendererLock); - if (m_pInputPin->IsConnected() == FALSE) { - return FALSE; - } - - RLOG("Notification of EC_DISPLAY_CHANGE"); - - // Pass our input pin as parameter on the event - - IPin *pPin = (IPin *) m_pInputPin; - m_pInputPin->AddRef(); - NotifyEvent(EC_DISPLAY_CHANGED,(LONG_PTR) pPin,0); - SetAbortSignal(TRUE); - ClearPendingSample(); - m_pInputPin->Release(); - - return TRUE; -} - - -// Called just before we start drawing. -// Store the current time in m_trRenderStart to allow the rendering time to be -// logged. Log the time stamp of the sample and how late it is (neg is early) - -void CBaseRenderer::OnRenderStart(IMediaSample *pMediaSample) -{ -#ifdef PERF - REFERENCE_TIME trStart, trEnd; - pMediaSample->GetTime(&trStart, &trEnd); - - MSR_INTEGER(m_idBaseStamp, (int)trStart); // dump low order 32 bits - - m_pClock->GetTime(&m_trRenderStart); - MSR_INTEGER(0, (int)m_trRenderStart); - REFERENCE_TIME trStream; - trStream = m_trRenderStart-m_tStart; // convert reftime to stream time - MSR_INTEGER(0,(int)trStream); - - const int trLate = (int)(trStream - trStart); - MSR_INTEGER(m_idBaseAccuracy, trLate/10000); // dump in mSec -#endif - -} // OnRenderStart - - -// Called directly after drawing an image. -// calculate the time spent drawing and log it. - -void CBaseRenderer::OnRenderEnd(IMediaSample *pMediaSample) -{ -#ifdef PERF - REFERENCE_TIME trNow; - m_pClock->GetTime(&trNow); - MSR_INTEGER(0,(int)trNow); - int t = (int)((trNow - m_trRenderStart)/10000); // convert UNITS->msec - MSR_INTEGER(m_idBaseRenderTime, t); -#endif -} // OnRenderEnd - - - - -// Constructor must be passed the base renderer object - -CRendererInputPin::CRendererInputPin(CBaseRenderer *pRenderer, - HRESULT *phr, - LPCWSTR pPinName) : - CBaseInputPin(NAME("Renderer pin"), - pRenderer, - &pRenderer->m_InterfaceLock, - (HRESULT *) phr, - pPinName) -{ - m_pRenderer = pRenderer; - ASSERT(m_pRenderer); -} - - -// Signals end of data stream on the input pin - -STDMETHODIMP CRendererInputPin::EndOfStream() -{ - CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock); - CAutoLock cSampleLock(&m_pRenderer->m_RendererLock); - - // Make sure we're streaming ok - - HRESULT hr = CheckStreaming(); - if (hr != NOERROR) { - return hr; - } - - // Pass it onto the renderer - - hr = m_pRenderer->EndOfStream(); - if (SUCCEEDED(hr)) { - hr = CBaseInputPin::EndOfStream(); - } - return hr; -} - - -// Signals start of flushing on the input pin - we do the final reset end of -// stream with the renderer lock unlocked but with the interface lock locked -// We must do this because we call timeKillEvent, our timer callback method -// has to take the renderer lock to serialise our state. Therefore holding a -// renderer lock when calling timeKillEvent could cause a deadlock condition - -STDMETHODIMP CRendererInputPin::BeginFlush() -{ - CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock); - { - CAutoLock cSampleLock(&m_pRenderer->m_RendererLock); - CBaseInputPin::BeginFlush(); - m_pRenderer->BeginFlush(); - } - return m_pRenderer->ResetEndOfStream(); -} - - -// Signals end of flushing on the input pin - -STDMETHODIMP CRendererInputPin::EndFlush() -{ - CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock); - CAutoLock cSampleLock(&m_pRenderer->m_RendererLock); - - HRESULT hr = m_pRenderer->EndFlush(); - if (SUCCEEDED(hr)) { - hr = CBaseInputPin::EndFlush(); - } - return hr; -} - - -// Pass the sample straight through to the renderer object - -STDMETHODIMP CRendererInputPin::Receive(IMediaSample *pSample) -{ - HRESULT hr = m_pRenderer->Receive(pSample); - if (FAILED(hr)) { - - // A deadlock could occur if the caller holds the renderer lock and - // attempts to acquire the interface lock. - ASSERT(CritCheckOut(&m_pRenderer->m_RendererLock)); - - { - // The interface lock must be held when the filter is calling - // IsStopped() or IsFlushing(). The interface lock must also - // be held because the function uses m_bRunTimeError. - CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock); - - // We do not report errors which occur while the filter is stopping, - // flushing or if the m_bAbort flag is set . Errors are expected to - // occur during these operations and the streaming thread correctly - // handles the errors. - if (!IsStopped() && !IsFlushing() && !m_pRenderer->m_bAbort && !m_bRunTimeError) { - - // EC_ERRORABORT's first parameter is the error which caused - // the event and its' last parameter is 0. See the Direct - // Show SDK documentation for more information. - m_pRenderer->NotifyEvent(EC_ERRORABORT,hr,0); - - { - CAutoLock alRendererLock(&m_pRenderer->m_RendererLock); - if (m_pRenderer->IsStreaming() && !m_pRenderer->IsEndOfStreamDelivered()) { - m_pRenderer->NotifyEndOfStream(); - } - } - - m_bRunTimeError = TRUE; - } - } - } - - return hr; -} - - -// Called when the input pin is disconnected - -HRESULT CRendererInputPin::BreakConnect() -{ - HRESULT hr = m_pRenderer->BreakConnect(); - if (FAILED(hr)) { - return hr; - } - return CBaseInputPin::BreakConnect(); -} - - -// Called when the input pin is connected - -HRESULT CRendererInputPin::CompleteConnect(IPin *pReceivePin) -{ - HRESULT hr = m_pRenderer->CompleteConnect(pReceivePin); - if (FAILED(hr)) { - return hr; - } - return CBaseInputPin::CompleteConnect(pReceivePin); -} - - -// Give the pin id of our one and only pin - -STDMETHODIMP CRendererInputPin::QueryId(LPWSTR *Id) -{ - CheckPointer(Id,E_POINTER); - - *Id = (LPWSTR)CoTaskMemAlloc(8); - if (*Id == NULL) { - return E_OUTOFMEMORY; - } - lstrcpyW(*Id, L"In"); - return NOERROR; -} - - -// Will the filter accept this media type - -HRESULT CRendererInputPin::CheckMediaType(const CMediaType *pmt) -{ - return m_pRenderer->CheckMediaType(pmt); -} - - -// Called when we go paused or running - -HRESULT CRendererInputPin::Active() -{ - return m_pRenderer->Active(); -} - - -// Called when we go into a stopped state - -HRESULT CRendererInputPin::Inactive() -{ - // The caller must hold the interface lock because - // this function uses m_bRunTimeError. - ASSERT(CritCheckIn(&m_pRenderer->m_InterfaceLock)); - - m_bRunTimeError = FALSE; - - return m_pRenderer->Inactive(); -} - - -// Tell derived classes about the media type agreed - -HRESULT CRendererInputPin::SetMediaType(const CMediaType *pmt) -{ - HRESULT hr = CBaseInputPin::SetMediaType(pmt); - if (FAILED(hr)) { - return hr; - } - return m_pRenderer->SetMediaType(pmt); -} - - -// We do not keep an event object to use when setting up a timer link with -// the clock but are given a pointer to one by the owning object through the -// SetNotificationObject method - this must be initialised before starting -// We can override the default quality management process to have it always -// draw late frames, this is currently done by having the following registry -// key (actually an INI key) called DrawLateFrames set to 1 (default is 0) - -const TCHAR AMQUALITY[] = TEXT("ActiveMovie"); -const TCHAR DRAWLATEFRAMES[] = TEXT("DrawLateFrames"); - -CBaseVideoRenderer::CBaseVideoRenderer( - REFCLSID RenderClass, // CLSID for this renderer - TCHAR *pName, // Debug ONLY description - LPUNKNOWN pUnk, // Aggregated owner object - HRESULT *phr) : // General OLE return code - - CBaseRenderer(RenderClass,pName,pUnk,phr), - m_cFramesDropped(0), - m_cFramesDrawn(0), - m_bSupplierHandlingQuality(FALSE) -{ - ResetStreamingTimes(); - -#ifdef PERF - m_idTimeStamp = MSR_REGISTER(TEXT("Frame time stamp")); - m_idEarliness = MSR_REGISTER(TEXT("Earliness fudge")); - m_idTarget = MSR_REGISTER(TEXT("Target (mSec)")); - m_idSchLateTime = MSR_REGISTER(TEXT("mSec late when scheduled")); - m_idDecision = MSR_REGISTER(TEXT("Scheduler decision code")); - m_idQualityRate = MSR_REGISTER(TEXT("Quality rate sent")); - m_idQualityTime = MSR_REGISTER(TEXT("Quality time sent")); - m_idWaitReal = MSR_REGISTER(TEXT("Render wait")); - // m_idWait = MSR_REGISTER(TEXT("wait time recorded (msec)")); - m_idFrameAccuracy = MSR_REGISTER(TEXT("Frame accuracy (msecs)")); - m_bDrawLateFrames = GetProfileInt(AMQUALITY, DRAWLATEFRAMES, FALSE); - //m_idSendQuality = MSR_REGISTER(TEXT("Processing Quality message")); - - m_idRenderAvg = MSR_REGISTER(TEXT("Render draw time Avg")); - m_idFrameAvg = MSR_REGISTER(TEXT("FrameAvg")); - m_idWaitAvg = MSR_REGISTER(TEXT("WaitAvg")); - m_idDuration = MSR_REGISTER(TEXT("Duration")); - m_idThrottle = MSR_REGISTER(TEXT("Audio-video throttle wait")); - // m_idDebug = MSR_REGISTER(TEXT("Debug stuff")); -#endif // PERF -} // Constructor - - -// Destructor is just a placeholder - -CBaseVideoRenderer::~CBaseVideoRenderer() -{ - ASSERT(m_dwAdvise == 0); -} - - -// The timing functions in this class are called by the window object and by -// the renderer's allocator. -// The windows object calls timing functions as it receives media sample -// images for drawing using GDI. -// The allocator calls timing functions when it starts passing DCI/DirectDraw -// surfaces which are not rendered in the same way; The decompressor writes -// directly to the surface with no separate rendering, so those code paths -// call direct into us. Since we only ever hand out DCI/DirectDraw surfaces -// when we have allocated one and only one image we know there cannot be any -// conflict between the two. -// -// We use timeGetTime to return the timing counts we use (since it's relative -// performance we are interested in rather than absolute compared to a clock) -// The window object sets the accuracy of the system clock (normally 1ms) by -// calling timeBeginPeriod/timeEndPeriod when it changes streaming states - - -// Reset all times controlling streaming. -// Set them so that -// 1. Frames will not initially be dropped -// 2. The first frame will definitely be drawn (achieved by saying that there -// has not ben a frame drawn for a long time). - -HRESULT CBaseVideoRenderer::ResetStreamingTimes() -{ - m_trLastDraw = -1000; // set up as first frame since ages (1 sec) ago - m_tStreamingStart = timeGetTime(); - m_trRenderAvg = 0; - m_trFrameAvg = -1; // -1000 fps == "unset" - m_trDuration = 0; // 0 - strange value - m_trRenderLast = 0; - m_trWaitAvg = 0; - m_tRenderStart = 0; - m_cFramesDrawn = 0; - m_cFramesDropped = 0; - m_iTotAcc = 0; - m_iSumSqAcc = 0; - m_iSumSqFrameTime = 0; - m_trFrame = 0; // hygeine - not really needed - m_trLate = 0; // hygeine - not really needed - m_iSumFrameTime = 0; - m_nNormal = 0; - m_trEarliness = 0; - m_trTarget = -300000; // 30mSec early - m_trThrottle = 0; - m_trRememberStampForPerf = 0; - -#ifdef PERF - m_trRememberFrameForPerf = 0; -#endif - - return NOERROR; -} // ResetStreamingTimes - - -// Reset all times controlling streaming. Note that we're now streaming. We -// don't need to set the rendering event to have the source filter released -// as it is done during the Run processing. When we are run we immediately -// release the source filter thread and draw any image waiting (that image -// may already have been drawn once as a poster frame while we were paused) - -HRESULT CBaseVideoRenderer::OnStartStreaming() -{ - ResetStreamingTimes(); - return NOERROR; -} // OnStartStreaming - - -// Called at end of streaming. Fixes times for property page report - -HRESULT CBaseVideoRenderer::OnStopStreaming() -{ - m_tStreamingStart = timeGetTime()-m_tStreamingStart; - return NOERROR; -} // OnStopStreaming - - -// Called when we start waiting for a rendering event. -// Used to update times spent waiting and not waiting. - -void CBaseVideoRenderer::OnWaitStart() -{ - MSR_START(m_idWaitReal); -} // OnWaitStart - - -// Called when we are awoken from the wait in the window OR by our allocator -// when it is hanging around until the next sample is due for rendering on a -// DCI/DirectDraw surface. We add the wait time into our rolling average. -// We grab the interface lock so that we're serialised with the application -// thread going through the run code - which in due course ends up calling -// ResetStreaming times - possibly as we run through this section of code - -void CBaseVideoRenderer::OnWaitEnd() -{ -#ifdef PERF - MSR_STOP(m_idWaitReal); - // for a perf build we want to know just exactly how late we REALLY are. - // even if this means that we have to look at the clock again. - - REFERENCE_TIME trRealStream; // the real time now expressed as stream time. -#if 0 - m_pClock->GetTime(&trRealStream); // Calling clock here causes W95 deadlock! -#else - // We will be discarding overflows like mad here! - // This is wrong really because timeGetTime() can wrap but it's - // only for PERF - REFERENCE_TIME tr = timeGetTime()*10000; - trRealStream = tr + m_llTimeOffset; -#endif - trRealStream -= m_tStart; // convert to stream time (this is a reftime) - - if (m_trRememberStampForPerf==0) { - // This is probably the poster frame at the start, and it is not scheduled - // in the usual way at all. Just count it. The rememberstamp gets set - // in ShouldDrawSampleNow, so this does invalid frame recording until we - // actually start playing. - PreparePerformanceData(0, 0); - } else { - int trLate = (int)(trRealStream - m_trRememberStampForPerf); - int trFrame = (int)(tr - m_trRememberFrameForPerf); - PreparePerformanceData(trLate, trFrame); - } - m_trRememberFrameForPerf = tr; -#endif //PERF -} // OnWaitEnd - - -// Put data on one side that describes the lateness of the current frame. -// We don't yet know whether it will actually be drawn. In direct draw mode, -// this decision is up to the filter upstream, and it could change its mind. -// The rules say that if it did draw it must call Receive(). One way or -// another we eventually get into either OnRenderStart or OnDirectRender and -// these both call RecordFrameLateness to update the statistics. - -void CBaseVideoRenderer::PreparePerformanceData(int trLate, int trFrame) -{ - m_trLate = trLate; - m_trFrame = trFrame; -} // PreparePerformanceData - - -// update the statistics: -// m_iTotAcc, m_iSumSqAcc, m_iSumSqFrameTime, m_iSumFrameTime, m_cFramesDrawn -// Note that because the properties page reports using these variables, -// 1. We need to be inside a critical section -// 2. They must all be updated together. Updating the sums here and the count -// elsewhere can result in imaginary jitter (i.e. attempts to find square roots -// of negative numbers) in the property page code. - -void CBaseVideoRenderer::RecordFrameLateness(int trLate, int trFrame) -{ - // Record how timely we are. - int tLate = trLate/10000; - - // Best estimate of moment of appearing on the screen is average of - // start and end draw times. Here we have only the end time. This may - // tend to show us as spuriously late by up to 1/2 frame rate achieved. - // Decoder probably monitors draw time. We don't bother. - MSR_INTEGER( m_idFrameAccuracy, tLate ); - - // This is a kludge - we can get frames that are very late - // especially (at start-up) and they invalidate the statistics. - // So ignore things that are more than 1 sec off. - if (tLate>1000 || tLate<-1000) { - if (m_cFramesDrawn<=1) { - tLate = 0; - } else if (tLate>0) { - tLate = 1000; - } else { - tLate = -1000; - } - } - // The very first frame often has a invalid time, so don't - // count it into the statistics. (???) - if (m_cFramesDrawn>1) { - m_iTotAcc += tLate; - m_iSumSqAcc += (tLate*tLate); - } - - // calculate inter-frame time. Doesn't make sense for first frame - // second frame suffers from invalid first frame stamp. - if (m_cFramesDrawn>2) { - int tFrame = trFrame/10000; // convert to mSec else it overflows - - // This is a kludge. It can overflow anyway (a pause can cause - // a very long inter-frame time) and it overflows at 2**31/10**7 - // or about 215 seconds i.e. 3min 35sec - if (tFrame>1000||tFrame<0) tFrame = 1000; - m_iSumSqFrameTime += tFrame*tFrame; - ASSERT(m_iSumSqFrameTime>=0); - m_iSumFrameTime += tFrame; - } - ++m_cFramesDrawn; - -} // RecordFrameLateness - - -void CBaseVideoRenderer::ThrottleWait() -{ - if (m_trThrottle>0) { - int iThrottle = m_trThrottle/10000; // convert to mSec - MSR_INTEGER( m_idThrottle, iThrottle); - DbgLog((LOG_TRACE, 0, TEXT("Throttle %d ms"), iThrottle)); - Sleep(iThrottle); - } else { - Sleep(0); - } -} // ThrottleWait - - -// Whenever a frame is rendered it goes though either OnRenderStart -// or OnDirectRender. Data that are generated during ShouldDrawSample -// are added to the statistics by calling RecordFrameLateness from both -// these two places. - -// Called in place of OnRenderStart..OnRenderEnd -// When a DirectDraw image is drawn -void CBaseVideoRenderer::OnDirectRender(IMediaSample *pMediaSample) -{ - m_trRenderAvg = 0; - m_trRenderLast = 5000000; // If we mode switch, we do NOT want this - // to inhibit the new average getting going! - // so we set it to half a second - // MSR_INTEGER(m_idRenderAvg, m_trRenderAvg/10000); - RecordFrameLateness(m_trLate, m_trFrame); - ThrottleWait(); -} // OnDirectRender - - -// Called just before we start drawing. All we do is to get the current clock -// time (from the system) and return. We have to store the start render time -// in a member variable because it isn't used until we complete the drawing -// The rest is just performance logging. - -void CBaseVideoRenderer::OnRenderStart(IMediaSample *pMediaSample) -{ - RecordFrameLateness(m_trLate, m_trFrame); - m_tRenderStart = timeGetTime(); -} // OnRenderStart - - -// Called directly after drawing an image. We calculate the time spent in the -// drawing code and if this doesn't appear to have any odd looking spikes in -// it then we add it to the current average draw time. Measurement spikes may -// occur if the drawing thread is interrupted and switched to somewhere else. - -void CBaseVideoRenderer::OnRenderEnd(IMediaSample *pMediaSample) -{ - // The renderer time can vary erratically if we are interrupted so we do - // some smoothing to help get more sensible figures out but even that is - // not enough as figures can go 9,10,9,9,83,9 and we must disregard 83 - - int tr = (timeGetTime() - m_tRenderStart)*10000; // convert mSec->UNITS - if (tr < m_trRenderAvg*2 || tr < 2 * m_trRenderLast) { - // DO_MOVING_AVG(m_trRenderAvg, tr); - m_trRenderAvg = (tr + (AVGPERIOD-1)*m_trRenderAvg)/AVGPERIOD; - } - m_trRenderLast = tr; - ThrottleWait(); -} // OnRenderEnd - - -STDMETHODIMP CBaseVideoRenderer::SetSink( IQualityControl * piqc) -{ - - m_pQSink = piqc; - - return NOERROR; -} // SetSink - - -STDMETHODIMP CBaseVideoRenderer::Notify( IBaseFilter * pSelf, Quality q) -{ - // NOTE: We are NOT getting any locks here. We could be called - // asynchronously and possibly even on a time critical thread of - // someone else's - so we do the minumum. We only set one state - // variable (an integer) and if that happens to be in the middle - // of another thread reading it they will just get either the new - // or the old value. Locking would achieve no more than this. - - // It might be nice to check that we are being called from m_pGraph, but - // it turns out to be a millisecond or so per throw! - - // This is heuristics, these numbers are aimed at being "what works" - // rather than anything based on some theory. - // We use a hyperbola because it's easy to calculate and it includes - // a panic button asymptote (which we push off just to the left) - // The throttling fits the following table (roughly) - // Proportion Throttle (msec) - // >=1000 0 - // 900 3 - // 800 7 - // 700 11 - // 600 17 - // 500 25 - // 400 35 - // 300 50 - // 200 72 - // 125 100 - // 100 112 - // 50 146 - // 0 200 - - // (some evidence that we could go for a sharper kink - e.g. no throttling - // until below the 750 mark - might give fractionally more frames on a - // P60-ish machine). The easy way to get these coefficients is to use - // Renbase.xls follow the instructions therein using excel solver. - - if (q.Proportion>=1000) { m_trThrottle = 0; } - else { - // The DWORD is to make quite sure I get unsigned arithmetic - // as the constant is between 2**31 and 2**32 - m_trThrottle = -330000 + (388880000/(q.Proportion+167)); - } - return NOERROR; -} // Notify - - -// Send a message to indicate what our supplier should do about quality. -// Theory: -// What a supplier wants to know is "is the frame I'm working on NOW -// going to be late?". -// F1 is the frame at the supplier (as above) -// Tf1 is the due time for F1 -// T1 is the time at that point (NOW!) -// Tr1 is the time that f1 WILL actually be rendered -// L1 is the latency of the graph for frame F1 = Tr1-T1 -// D1 (for delay) is how late F1 will be beyond its due time i.e. -// D1 = (Tr1-Tf1) which is what the supplier really wants to know. -// Unfortunately Tr1 is in the future and is unknown, so is L1 -// -// We could estimate L1 by its value for a previous frame, -// L0 = Tr0-T0 and work off -// D1' = ((T1+L0)-Tf1) = (T1 + (Tr0-T0) -Tf1) -// Rearranging terms: -// D1' = (T1-T0) + (Tr0-Tf1) -// adding (Tf0-Tf0) and rearranging again: -// = (T1-T0) + (Tr0-Tf0) + (Tf0-Tf1) -// = (T1-T0) - (Tf1-Tf0) + (Tr0-Tf0) -// But (Tr0-Tf0) is just D0 - how late frame zero was, and this is the -// Late field in the quality message that we send. -// The other two terms just state what correction should be applied before -// using the lateness of F0 to predict the lateness of F1. -// (T1-T0) says how much time has actually passed (we have lost this much) -// (Tf1-Tf0) says how much time should have passed if we were keeping pace -// (we have gained this much). -// -// Suppliers should therefore work off: -// Quality.Late + (T1-T0) - (Tf1-Tf0) -// and see if this is "acceptably late" or even early (i.e. negative). -// They get T1 and T0 by polling the clock, they get Tf1 and Tf0 from -// the time stamps in the frames. They get Quality.Late from us. -// - -HRESULT CBaseVideoRenderer::SendQuality(REFERENCE_TIME trLate, - REFERENCE_TIME trRealStream) -{ - Quality q; - HRESULT hr; - - // If we are the main user of time, then report this as Flood/Dry. - // If our suppliers are, then report it as Famine/Glut. - // - // We need to take action, but avoid hunting. Hunting is caused by - // 1. Taking too much action too soon and overshooting - // 2. Taking too long to react (so averaging can CAUSE hunting). - // - // The reason why we use trLate as well as Wait is to reduce hunting; - // if the wait time is coming down and about to go into the red, we do - // NOT want to rely on some average which is only telling is that it used - // to be OK once. - - q.TimeStamp = (REFERENCE_TIME)trRealStream; - - if (m_trFrameAvg<0) { - q.Type = Famine; // guess - } - // Is the greater part of the time taken bltting or something else - else if (m_trFrameAvg > 2*m_trRenderAvg) { - q.Type = Famine; // mainly other - } else { - q.Type = Flood; // mainly bltting - } - - q.Proportion = 1000; // default - - if (m_trFrameAvg<0) { - // leave it alone - we don't know enough - } - else if ( trLate> 0 ) { - // try to catch up over the next second - // We could be Really, REALLY late, but rendering all the frames - // anyway, just because it's so cheap. - - q.Proportion = 1000 - (int)((trLate)/(UNITS/1000)); - if (q.Proportion<500) { - q.Proportion = 500; // don't go daft. (could've been negative!) - } else { - } - - } else if ( m_trWaitAvg>20000 - && trLate<-20000 - ){ - // Go cautiously faster - aim at 2mSec wait. - if (m_trWaitAvg>=m_trFrameAvg) { - // This can happen because of some fudges. - // The waitAvg is how long we originally planned to wait - // The frameAvg is more honest. - // It means that we are spending a LOT of time waiting - q.Proportion = 2000; // double. - } else { - if (m_trFrameAvg+20000 > m_trWaitAvg) { - q.Proportion - = 1000 * (m_trFrameAvg / (m_trFrameAvg + 20000 - m_trWaitAvg)); - } else { - // We're apparently spending more than the whole frame time waiting. - // Assume that the averages are slightly out of kilter, but that we - // are indeed doing a lot of waiting. (This leg probably never - // happens, but the code avoids any potential divide by zero). - q.Proportion = 2000; - } - } - - if (q.Proportion>2000) { - q.Proportion = 2000; // don't go crazy. - } - } - - // Tell the supplier how late frames are when they get rendered - // That's how late we are now. - // If we are in directdraw mode then the guy upstream can see the drawing - // times and we'll just report on the start time. He can figure out any - // offset to apply. If we are in DIB Section mode then we will apply an - // extra offset which is half of our drawing time. This is usually small - // but can sometimes be the dominant effect. For this we will use the - // average drawing time rather than the last frame. If the last frame took - // a long time to draw and made us late, that's already in the lateness - // figure. We should not add it in again unless we expect the next frame - // to be the same. We don't, we expect the average to be a better shot. - // In direct draw mode the RenderAvg will be zero. - - q.Late = trLate + m_trRenderAvg/2; - - // log what we're doing - MSR_INTEGER(m_idQualityRate, q.Proportion); - MSR_INTEGER( m_idQualityTime, (int)q.Late / 10000 ); - - // A specific sink interface may be set through IPin - - if (m_pQSink==NULL) { - // Get our input pin's peer. We send quality management messages - // to any nominated receiver of these things (set in the IPin - // interface), or else to our source filter. - - IQualityControl *pQC = NULL; - IPin *pOutputPin = m_pInputPin->GetConnected(); - ASSERT(pOutputPin != NULL); - - // And get an AddRef'd quality control interface - - hr = pOutputPin->QueryInterface(IID_IQualityControl,(void**) &pQC); - if (SUCCEEDED(hr)) { - m_pQSink = pQC; - } - } - if (m_pQSink) { - return m_pQSink->Notify(this,q); - } - - return S_FALSE; - -} // SendQuality - - -// We are called with a valid IMediaSample image to decide whether this is to -// be drawn or not. There must be a reference clock in operation. -// Return S_OK if it is to be drawn Now (as soon as possible) -// Return S_FALSE if it is to be drawn when it's due -// Return an error if we want to drop it -// m_nNormal=-1 indicates that we dropped the previous frame and so this -// one should be drawn early. Respect it and update it. -// Use current stream time plus a number of heuristics (detailed below) -// to make the decision - -HRESULT CBaseVideoRenderer::ShouldDrawSampleNow(IMediaSample *pMediaSample, - REFERENCE_TIME *ptrStart, - REFERENCE_TIME *ptrEnd) -{ - - // Don't call us unless there's a clock interface to synchronise with - ASSERT(m_pClock); - - MSR_INTEGER(m_idTimeStamp, (int)((*ptrStart)>>32)); // high order 32 bits - MSR_INTEGER(m_idTimeStamp, (int)(*ptrStart)); // low order 32 bits - - // We lose a bit of time depending on the monitor type waiting for the next - // screen refresh. On average this might be about 8mSec - so it will be - // later than we think when the picture appears. To compensate a bit - // we bias the media samples by -8mSec i.e. 80000 UNITs. - // We don't ever make a stream time negative (call it paranoia) - if (*ptrStart>=80000) { - *ptrStart -= 80000; - *ptrEnd -= 80000; // bias stop to to retain valid frame duration - } - - // Cache the time stamp now. We will want to compare what we did with what - // we started with (after making the monitor allowance). - m_trRememberStampForPerf = *ptrStart; - - // Get reference times (current and late) - REFERENCE_TIME trRealStream; // the real time now expressed as stream time. - m_pClock->GetTime(&trRealStream); -#ifdef PERF - // While the reference clock is expensive: - // Remember the offset from timeGetTime and use that. - // This overflows all over the place, but when we subtract to get - // differences the overflows all cancel out. - m_llTimeOffset = trRealStream-timeGetTime()*10000; -#endif - trRealStream -= m_tStart; // convert to stream time (this is a reftime) - - // We have to wory about two versions of "lateness". The truth, which we - // try to work out here and the one measured against m_trTarget which - // includes long term feedback. We report statistics against the truth - // but for operational decisions we work to the target. - // We use TimeDiff to make sure we get an integer because we - // may actually be late (or more likely early if there is a big time - // gap) by a very long time. - const int trTrueLate = TimeDiff(trRealStream - *ptrStart); - const int trLate = trTrueLate; - - MSR_INTEGER(m_idSchLateTime, trTrueLate/10000); - - // Send quality control messages upstream, measured against target - HRESULT hr = SendQuality(trLate, trRealStream); - // Note: the filter upstream is allowed to this FAIL meaning "you do it". - m_bSupplierHandlingQuality = (hr==S_OK); - - // Decision time! Do we drop, draw when ready or draw immediately? - - const int trDuration = (int)(*ptrEnd - *ptrStart); - { - // We need to see if the frame rate of the file has just changed. - // This would make comparing our previous frame rate with the current - // frame rate inefficent. Hang on a moment though. I've seen files - // where the frames vary between 33 and 34 mSec so as to average - // 30fps. A minor variation like that won't hurt us. - int t = m_trDuration/32; - if ( trDuration > m_trDuration+t - || trDuration < m_trDuration-t - ) { - // There's a major variation. Reset the average frame rate to - // exactly the current rate to disable decision 9002 for this frame, - // and remember the new rate. - m_trFrameAvg = trDuration; - m_trDuration = trDuration; - } - } - - MSR_INTEGER(m_idEarliness, m_trEarliness/10000); - MSR_INTEGER(m_idRenderAvg, m_trRenderAvg/10000); - MSR_INTEGER(m_idFrameAvg, m_trFrameAvg/10000); - MSR_INTEGER(m_idWaitAvg, m_trWaitAvg/10000); - MSR_INTEGER(m_idDuration, trDuration/10000); - -#ifdef PERF - if (S_OK==pMediaSample->IsDiscontinuity()) { - MSR_INTEGER(m_idDecision, 9000); - } -#endif - - // Control the graceful slide back from slow to fast machine mode. - // After a frame drop accept an early frame and set the earliness to here - // If this frame is already later than the earliness then slide it to here - // otherwise do the standard slide (reduce by about 12% per frame). - // Note: earliness is normally NEGATIVE - BOOL bJustDroppedFrame - = ( m_bSupplierHandlingQuality - // Can't use the pin sample properties because we might - // not be in Receive when we call this - && (S_OK == pMediaSample->IsDiscontinuity()) // he just dropped one - ) - || (m_nNormal==-1); // we just dropped one - - - // Set m_trEarliness (slide back from slow to fast machine mode) - if (trLate>0) { - m_trEarliness = 0; // we are no longer in fast machine mode at all! - } else if ( (trLate>=m_trEarliness) || bJustDroppedFrame) { - m_trEarliness = trLate; // Things have slipped of their own accord - } else { - m_trEarliness = m_trEarliness - m_trEarliness/8; // graceful slide - } - - // prepare the new wait average - but don't pollute the old one until - // we have finished with it. - int trWaitAvg; - { - // We never mix in a negative wait. This causes us to believe in fast machines - // slightly more. - int trL = trLate<0 ? -trLate : 0; - trWaitAvg = (trL + m_trWaitAvg*(AVGPERIOD-1))/AVGPERIOD; - } - - - int trFrame; - { - REFERENCE_TIME tr = trRealStream - m_trLastDraw; // Cd be large - 4 min pause! - if (tr>10000000) { - tr = 10000000; // 1 second - arbitrarily. - } - trFrame = int(tr); - } - - // We will DRAW this frame IF... - if ( - // ...the time we are spending drawing is a small fraction of the total - // observed inter-frame time so that dropping it won't help much. - (3*m_trRenderAvg <= m_trFrameAvg) - - // ...or our supplier is NOT handling things and the next frame would - // be less timely than this one or our supplier CLAIMS to be handling - // things, and is now less than a full FOUR frames late. - || ( m_bSupplierHandlingQuality - ? (trLate <= trDuration*4) - : (trLate+trLate < trDuration) - ) - - // ...or we are on average waiting for over eight milliseconds then - // this may be just a glitch. Draw it and we'll hope to catch up. - || (m_trWaitAvg > 80000) - - // ...or we haven't drawn an image for over a second. We will update - // the display, which stops the video looking hung. - // Do this regardless of how late this media sample is. - || ((trRealStream - m_trLastDraw) > UNITS) - - ) { - HRESULT Result; - - // We are going to play this frame. We may want to play it early. - // We will play it early if we think we are in slow machine mode. - // If we think we are NOT in slow machine mode, we will still play - // it early by m_trEarliness as this controls the graceful slide back. - // and in addition we aim at being m_trTarget late rather than "on time". - - BOOL bPlayASAP = FALSE; - - // we will play it AT ONCE (slow machine mode) if... - - // ...we are playing catch-up - if ( bJustDroppedFrame) { - bPlayASAP = TRUE; - MSR_INTEGER(m_idDecision, 9001); - } - - // ...or if we are running below the true frame rate - // exact comparisons are glitchy, for these measurements, - // so add an extra 5% or so - else if ( (m_trFrameAvg > trDuration + trDuration/16) - - // It's possible to get into a state where we are losing ground, but - // are a very long way ahead. To avoid this or recover from it - // we refuse to play early by more than 10 frames. - && (trLate > - trDuration*10) - ){ - bPlayASAP = TRUE; - MSR_INTEGER(m_idDecision, 9002); - } -#if 0 - // ...or if we have been late and are less than one frame early - else if ( (trLate + trDuration > 0) - && (m_trWaitAvg<=20000) - ) { - bPlayASAP = TRUE; - MSR_INTEGER(m_idDecision, 9003); - } -#endif - // We will NOT play it at once if we are grossly early. On very slow frame - // rate movies - e.g. clock.avi - it is not a good idea to leap ahead just - // because we got starved (for instance by the net) and dropped one frame - // some time or other. If we are more than 900mSec early, then wait. - if (trLate<-9000000) { - bPlayASAP = FALSE; - } - - if (bPlayASAP) { - - m_nNormal = 0; - MSR_INTEGER(m_idDecision, 0); - // When we are here, we are in slow-machine mode. trLate may well - // oscillate between negative and positive when the supplier is - // dropping frames to keep sync. We should not let that mislead - // us into thinking that we have as much as zero spare time! - // We just update with a zero wait. - m_trWaitAvg = (m_trWaitAvg*(AVGPERIOD-1))/AVGPERIOD; - - // Assume that we draw it immediately. Update inter-frame stats - m_trFrameAvg = (trFrame + m_trFrameAvg*(AVGPERIOD-1))/AVGPERIOD; -#ifndef PERF - // If this is NOT a perf build, then report what we know so far - // without looking at the clock any more. This assumes that we - // actually wait for exactly the time we hope to. It also reports - // how close we get to the manipulated time stamps that we now have - // rather than the ones we originally started with. It will - // therefore be a little optimistic. However it's fast. - PreparePerformanceData(trTrueLate, trFrame); -#endif - m_trLastDraw = trRealStream; - if (m_trEarliness > trLate) { - m_trEarliness = trLate; // if we are actually early, this is neg - } - Result = S_OK; // Draw it now - - } else { - ++m_nNormal; - // Set the average frame rate to EXACTLY the ideal rate. - // If we are exiting slow-machine mode then we will have caught up - // and be running ahead, so as we slide back to exact timing we will - // have a longer than usual gap at this point. If we record this - // real gap then we'll think that we're running slow and go back - // into slow-machine mode and vever get it straight. - m_trFrameAvg = trDuration; - MSR_INTEGER(m_idDecision, 1); - - // Play it early by m_trEarliness and by m_trTarget - - { - int trE = m_trEarliness; - if (trE < -m_trFrameAvg) { - trE = -m_trFrameAvg; - } - *ptrStart += trE; // N.B. earliness is negative - } - - int Delay = -trTrueLate; - Result = Delay<=0 ? S_OK : S_FALSE; // OK = draw now, FALSE = wait - - m_trWaitAvg = trWaitAvg; - - // Predict when it will actually be drawn and update frame stats - - if (Result==S_FALSE) { // We are going to wait - trFrame = TimeDiff(*ptrStart-m_trLastDraw); - m_trLastDraw = *ptrStart; - } else { - // trFrame is already = trRealStream-m_trLastDraw; - m_trLastDraw = trRealStream; - } -#ifndef PERF - int iAccuracy; - if (Delay>0) { - // Report lateness based on when we intend to play it - iAccuracy = TimeDiff(*ptrStart-m_trRememberStampForPerf); - } else { - // Report lateness based on playing it *now*. - iAccuracy = trTrueLate; // trRealStream-RememberStampForPerf; - } - PreparePerformanceData(iAccuracy, trFrame); -#endif - } - return Result; - } - - // We are going to drop this frame! - // Of course in DirectDraw mode the guy upstream may draw it anyway. - - // This will probably give a large negative wack to the wait avg. - m_trWaitAvg = trWaitAvg; - -#ifdef PERF - // Respect registry setting - debug only! - if (m_bDrawLateFrames) { - return S_OK; // draw it when it's ready - } // even though it's late. -#endif - - // We are going to drop this frame so draw the next one early - // n.b. if the supplier is doing direct draw then he may draw it anyway - // but he's doing something funny to arrive here in that case. - - MSR_INTEGER(m_idDecision, 2); - m_nNormal = -1; - return E_FAIL; // drop it - -} // ShouldDrawSampleNow - - -// NOTE we're called by both the window thread and the source filter thread -// so we have to be protected by a critical section (locked before called) -// Also, when the window thread gets signalled to render an image, it always -// does so regardless of how late it is. All the degradation is done when we -// are scheduling the next sample to be drawn. Hence when we start an advise -// link to draw a sample, that sample's time will always become the last one -// drawn - unless of course we stop streaming in which case we cancel links - -BOOL CBaseVideoRenderer::ScheduleSample(IMediaSample *pMediaSample) -{ - // We override ShouldDrawSampleNow to add quality management - - BOOL bDrawImage = CBaseRenderer::ScheduleSample(pMediaSample); - if (bDrawImage == FALSE) { - ++m_cFramesDropped; - return FALSE; - } - - // m_cFramesDrawn must NOT be updated here. It has to be updated - // in RecordFrameLateness at the same time as the other statistics. - return TRUE; -} - - -// Implementation of IQualProp interface needed to support the property page -// This is how the property page gets the data out of the scheduler. We are -// passed into the constructor the owning object in the COM sense, this will -// either be the video renderer or an external IUnknown if we're aggregated. -// We initialise our CUnknown base class with this interface pointer. Then -// all we have to do is to override NonDelegatingQueryInterface to expose -// our IQualProp interface. The AddRef and Release are handled automatically -// by the base class and will be passed on to the appropriate outer object - -STDMETHODIMP CBaseVideoRenderer::get_FramesDroppedInRenderer(int *pcFramesDropped) -{ - CheckPointer(pcFramesDropped,E_POINTER); - CAutoLock cVideoLock(&m_InterfaceLock); - *pcFramesDropped = m_cFramesDropped; - return NOERROR; -} // get_FramesDroppedInRenderer - - -// Set *pcFramesDrawn to the number of frames drawn since -// streaming started. - -STDMETHODIMP CBaseVideoRenderer::get_FramesDrawn( int *pcFramesDrawn) -{ - CheckPointer(pcFramesDrawn,E_POINTER); - CAutoLock cVideoLock(&m_InterfaceLock); - *pcFramesDrawn = m_cFramesDrawn; - return NOERROR; -} // get_FramesDrawn - - -// Set iAvgFrameRate to the frames per hundred secs since -// streaming started. 0 otherwise. - -STDMETHODIMP CBaseVideoRenderer::get_AvgFrameRate( int *piAvgFrameRate) -{ - CheckPointer(piAvgFrameRate,E_POINTER); - CAutoLock cVideoLock(&m_InterfaceLock); - - int t; - if (m_bStreaming) { - t = timeGetTime()-m_tStreamingStart; - } else { - t = m_tStreamingStart; - } - - if (t<=0) { - *piAvgFrameRate = 0; - ASSERT(m_cFramesDrawn == 0); - } else { - // i is frames per hundred seconds - *piAvgFrameRate = MulDiv(100000, m_cFramesDrawn, t); - } - return NOERROR; -} // get_AvgFrameRate - - -// Set *piAvg to the average sync offset since streaming started -// in mSec. The sync offset is the time in mSec between when the frame -// should have been drawn and when the frame was actually drawn. - -STDMETHODIMP CBaseVideoRenderer::get_AvgSyncOffset( int *piAvg) -{ - CheckPointer(piAvg,E_POINTER); - CAutoLock cVideoLock(&m_InterfaceLock); - - if (NULL==m_pClock) { - *piAvg = 0; - return NOERROR; - } - - // Note that we didn't gather the stats on the first frame - // so we use m_cFramesDrawn-1 here - if (m_cFramesDrawn<=1) { - *piAvg = 0; - } else { - *piAvg = (int)(m_iTotAcc / (m_cFramesDrawn-1)); - } - return NOERROR; -} // get_AvgSyncOffset - - -// To avoid dragging in the maths library - a cheap -// approximate integer square root. -// We do this by getting a starting guess which is between 1 -// and 2 times too large, followed by THREE iterations of -// Newton Raphson. (That will give accuracy to the nearest mSec -// for the range in question - roughly 0..1000) -// -// It would be faster to use a linear interpolation and ONE NR, but -// who cares. If anyone does - the best linear interpolation is -// to approximates sqrt(x) by -// y = x * (sqrt(2)-1) + 1 - 1/sqrt(2) + 1/(8*(sqrt(2)-1)) -// 0r y = x*0.41421 + 0.59467 -// This minimises the maximal error in the range in question. -// (error is about +0.008883 and then one NR will give error .0000something -// (Of course these are integers, so you can't just multiply by 0.41421 -// you'd have to do some sort of MulDiv). -// Anyone wanna check my maths? (This is only for a property display!) - -int isqrt(int x) -{ - int s = 1; - // Make s an initial guess for sqrt(x) - if (x > 0x40000000) { - s = 0x8000; // prevent any conceivable closed loop - } else { - while (s*s=0) s = (s*s+x)/(2*s); - if (s>=0) s = (s*s+x)/(2*s); - } - } - return s; -} - -// -// Do estimates for standard deviations for per-frame -// statistics -// -HRESULT CBaseVideoRenderer::GetStdDev( - int nSamples, - int *piResult, - LONGLONG llSumSq, - LONGLONG iTot -) -{ - CheckPointer(piResult,E_POINTER); - CAutoLock cVideoLock(&m_InterfaceLock); - - if (NULL==m_pClock) { - *piResult = 0; - return NOERROR; - } - - // If S is the Sum of the Squares of observations and - // T the Total (i.e. sum) of the observations and there were - // N observations, then an estimate of the standard deviation is - // sqrt( (S - T**2/N) / (N-1) ) - - if (nSamples<=1) { - *piResult = 0; - } else { - LONGLONG x; - // First frames have invalid stamps, so we get no stats for them - // So we need 2 frames to get 1 datum, so N is cFramesDrawn-1 - - // so we use m_cFramesDrawn-1 here - x = llSumSq - llMulDiv(iTot, iTot, nSamples, 0); - x = x / (nSamples-1); - ASSERT(x>=0); - *piResult = isqrt((LONG)x); - } - return NOERROR; -} - -// Set *piDev to the standard deviation in mSec of the sync offset -// of each frame since streaming started. - -STDMETHODIMP CBaseVideoRenderer::get_DevSyncOffset( int *piDev) -{ - // First frames have invalid stamps, so we get no stats for them - // So we need 2 frames to get 1 datum, so N is cFramesDrawn-1 - return GetStdDev(m_cFramesDrawn - 1, - piDev, - m_iSumSqAcc, - m_iTotAcc); -} // get_DevSyncOffset - - -// Set *piJitter to the standard deviation in mSec of the inter-frame time -// of frames since streaming started. - -STDMETHODIMP CBaseVideoRenderer::get_Jitter( int *piJitter) -{ - // First frames have invalid stamps, so we get no stats for them - // So second frame gives invalid inter-frame time - // So we need 3 frames to get 1 datum, so N is cFramesDrawn-2 - return GetStdDev(m_cFramesDrawn - 2, - piJitter, - m_iSumSqFrameTime, - m_iSumFrameTime); -} // get_Jitter - - -// Overidden to return our IQualProp interface - -STDMETHODIMP -CBaseVideoRenderer::NonDelegatingQueryInterface(REFIID riid,VOID **ppv) -{ - // We return IQualProp and delegate everything else - - if (riid == IID_IQualProp) { - return GetInterface( (IQualProp *)this, ppv); - } else if (riid == IID_IQualityControl) { - return GetInterface( (IQualityControl *)this, ppv); - } - return CBaseRenderer::NonDelegatingQueryInterface(riid,ppv); -} - - -// Override JoinFilterGraph so that, just before leaving -// the graph we can send an EC_WINDOW_DESTROYED event - -STDMETHODIMP -CBaseVideoRenderer::JoinFilterGraph(IFilterGraph *pGraph,LPCWSTR pName) -{ - // Since we send EC_ACTIVATE, we also need to ensure - // we send EC_WINDOW_DESTROYED or the resource manager may be - // holding us as a focus object - if (!pGraph && m_pGraph) { - - // We were in a graph and now we're not - // Do this properly in case we are aggregated - IBaseFilter* pFilter; - QueryInterface(IID_IBaseFilter,(void **) &pFilter); - NotifyEvent(EC_WINDOW_DESTROYED, (LPARAM) pFilter, 0); - pFilter->Release(); - } - return CBaseFilter::JoinFilterGraph(pGraph, pName); -} - - -// This removes a large number of level 4 warnings from the -// Microsoft compiler which in this case are not very useful -#pragma warning(disable: 4514) - diff --git a/src/BaseClasses/renbase.h b/src/BaseClasses/renbase.h deleted file mode 100644 index 5a6eb3e2da..0000000000 --- a/src/BaseClasses/renbase.h +++ /dev/null @@ -1,479 +0,0 @@ -//------------------------------------------------------------------------------ -// File: RenBase.h -// -// Desc: DirectShow base classes - defines a generic ActiveX base renderer -// class. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __RENBASE__ -#define __RENBASE__ - -// Forward class declarations - -class CBaseRenderer; -class CBaseVideoRenderer; -class CRendererInputPin; - -// This is our input pin class that channels calls to the renderer - -class CRendererInputPin : public CBaseInputPin -{ -protected: - - CBaseRenderer *m_pRenderer; - -public: - - CRendererInputPin(CBaseRenderer *pRenderer, - HRESULT *phr, - LPCWSTR Name); - - // Overriden from the base pin classes - - HRESULT BreakConnect(); - HRESULT CompleteConnect(IPin *pReceivePin); - HRESULT SetMediaType(const CMediaType *pmt); - HRESULT CheckMediaType(const CMediaType *pmt); - HRESULT Active(); - HRESULT Inactive(); - - // Add rendering behaviour to interface functions - - STDMETHODIMP QueryId(LPWSTR *Id); - STDMETHODIMP EndOfStream(); - STDMETHODIMP BeginFlush(); - STDMETHODIMP EndFlush(); - STDMETHODIMP Receive(IMediaSample *pMediaSample); - - // Helper - IMemAllocator inline *Allocator() const - { - return m_pAllocator; - } -}; - -// Main renderer class that handles synchronisation and state changes - -class CBaseRenderer : public CBaseFilter -{ -protected: - - friend class CRendererInputPin; - - friend void CALLBACK EndOfStreamTimer(UINT uID, // Timer identifier - UINT uMsg, // Not currently used - DWORD_PTR dwUser, // User information - DWORD_PTR dw1, // Windows reserved - DWORD_PTR dw2); // Is also reserved - - CRendererPosPassThru *m_pPosition; // Media seeking pass by object - CAMEvent m_RenderEvent; // Used to signal timer events - CAMEvent m_ThreadSignal; // Signalled to release worker thread - CAMEvent m_evComplete; // Signalled when state complete - BOOL m_bAbort; // Stop us from rendering more data - BOOL m_bStreaming; // Are we currently streaming - DWORD_PTR m_dwAdvise; // Timer advise cookie - IMediaSample *m_pMediaSample; // Current image media sample - BOOL m_bEOS; // Any more samples in the stream - BOOL m_bEOSDelivered; // Have we delivered an EC_COMPLETE - CRendererInputPin *m_pInputPin; // Our renderer input pin object - CCritSec m_InterfaceLock; // Critical section for interfaces - CCritSec m_RendererLock; // Controls access to internals - IQualityControl * m_pQSink; // QualityControl sink - BOOL m_bRepaintStatus; // Can we signal an EC_REPAINT - - // Avoid some deadlocks by tracking filter during stop - volatile BOOL m_bInReceive; // Inside Receive between PrepareReceive - // And actually processing the sample - REFERENCE_TIME m_SignalTime; // Time when we signal EC_COMPLETE - UINT m_EndOfStreamTimer; // Used to signal end of stream - CCritSec m_ObjectCreationLock; // This lock protects the creation and - // of m_pPosition and m_pInputPin. It - // ensures that two threads cannot create - // either object simultaneously. - -public: - - CBaseRenderer(REFCLSID RenderClass, // CLSID for this renderer - TCHAR *pName, // Debug ONLY description - LPUNKNOWN pUnk, // Aggregated owner object - HRESULT *phr); // General OLE return code - - ~CBaseRenderer(); - - // Overriden to say what interfaces we support and where - - virtual HRESULT GetMediaPositionInterface(REFIID riid,void **ppv); - STDMETHODIMP NonDelegatingQueryInterface(REFIID, void **); - - virtual HRESULT SourceThreadCanWait(BOOL bCanWait); - -#ifdef DEBUG - // Debug only dump of the renderer state - void DisplayRendererState(); -#endif - virtual HRESULT WaitForRenderTime(); - virtual HRESULT CompleteStateChange(FILTER_STATE OldState); - - // Return internal information about this filter - - BOOL IsEndOfStream() { return m_bEOS; }; - BOOL IsEndOfStreamDelivered() { return m_bEOSDelivered; }; - BOOL IsStreaming() { return m_bStreaming; }; - void SetAbortSignal(BOOL bAbort) { m_bAbort = bAbort; }; - virtual void OnReceiveFirstSample(IMediaSample *pMediaSample) { }; - CAMEvent *GetRenderEvent() { return &m_RenderEvent; }; - - // Permit access to the transition state - - void Ready() { m_evComplete.Set(); }; - void NotReady() { m_evComplete.Reset(); }; - BOOL CheckReady() { return m_evComplete.Check(); }; - - virtual int GetPinCount(); - virtual CBasePin *GetPin(int n); - FILTER_STATE GetRealState(); - void SendRepaint(); - void SendNotifyWindow(IPin *pPin,HWND hwnd); - BOOL OnDisplayChange(); - void SetRepaintStatus(BOOL bRepaint); - - // Override the filter and pin interface functions - - STDMETHODIMP Stop(); - STDMETHODIMP Pause(); - STDMETHODIMP Run(REFERENCE_TIME StartTime); - STDMETHODIMP GetState(DWORD dwMSecs,FILTER_STATE *State); - STDMETHODIMP FindPin(LPCWSTR Id, IPin **ppPin); - - // These are available for a quality management implementation - - virtual void OnRenderStart(IMediaSample *pMediaSample); - virtual void OnRenderEnd(IMediaSample *pMediaSample); - virtual HRESULT OnStartStreaming() { return NOERROR; }; - virtual HRESULT OnStopStreaming() { return NOERROR; }; - virtual void OnWaitStart() { }; - virtual void OnWaitEnd() { }; - virtual void PrepareRender() { }; - -#ifdef PERF - REFERENCE_TIME m_trRenderStart; // Just before we started drawing - // Set in OnRenderStart, Used in OnRenderEnd - int m_idBaseStamp; // MSR_id for frame time stamp - int m_idBaseRenderTime; // MSR_id for true wait time - int m_idBaseAccuracy; // MSR_id for time frame is late (int) -#endif - - // Quality management implementation for scheduling rendering - - virtual BOOL ScheduleSample(IMediaSample *pMediaSample); - virtual HRESULT GetSampleTimes(IMediaSample *pMediaSample, - REFERENCE_TIME *pStartTime, - REFERENCE_TIME *pEndTime); - - virtual HRESULT ShouldDrawSampleNow(IMediaSample *pMediaSample, - REFERENCE_TIME *ptrStart, - REFERENCE_TIME *ptrEnd); - - // Lots of end of stream complexities - - void TimerCallback(); - void ResetEndOfStreamTimer(); - HRESULT NotifyEndOfStream(); - virtual HRESULT SendEndOfStream(); - virtual HRESULT ResetEndOfStream(); - virtual HRESULT EndOfStream(); - - // Rendering is based around the clock - - void SignalTimerFired(); - virtual HRESULT CancelNotification(); - virtual HRESULT ClearPendingSample(); - - // Called when the filter changes state - - virtual HRESULT Active(); - virtual HRESULT Inactive(); - virtual HRESULT StartStreaming(); - virtual HRESULT StopStreaming(); - virtual HRESULT BeginFlush(); - virtual HRESULT EndFlush(); - - // Deal with connections and type changes - - virtual HRESULT BreakConnect(); - virtual HRESULT SetMediaType(const CMediaType *pmt); - virtual HRESULT CompleteConnect(IPin *pReceivePin); - - // These look after the handling of data samples - - virtual HRESULT PrepareReceive(IMediaSample *pMediaSample); - virtual HRESULT Receive(IMediaSample *pMediaSample); - virtual BOOL HaveCurrentSample(); - virtual IMediaSample *GetCurrentSample(); - virtual HRESULT Render(IMediaSample *pMediaSample); - - // Derived classes MUST override these - virtual HRESULT DoRenderSample(IMediaSample *pMediaSample) PURE; - virtual HRESULT CheckMediaType(const CMediaType *) PURE; - - // Helper - void WaitForReceiveToComplete(); -}; - - -// CBaseVideoRenderer is a renderer class (see its ancestor class) and -// it handles scheduling of media samples so that they are drawn at the -// correct time by the reference clock. It implements a degradation -// strategy. Possible degradation modes are: -// Drop frames here (only useful if the drawing takes significant time) -// Signal supplier (upstream) to drop some frame(s) - i.e. one-off skip. -// Signal supplier to change the frame rate - i.e. ongoing skipping. -// Or any combination of the above. -// In order to determine what's useful to try we need to know what's going -// on. This is done by timing various operations (including the supplier). -// This timing is done by using timeGetTime as it is accurate enough and -// usually cheaper than calling the reference clock. It also tells the -// truth if there is an audio break and the reference clock stops. -// We provide a number of public entry points (named OnXxxStart, OnXxxEnd) -// which the rest of the renderer calls at significant moments. These do -// the timing. - -// the number of frames that the sliding averages are averaged over. -// the rule is (1024*NewObservation + (AVGPERIOD-1) * PreviousAverage)/AVGPERIOD -#define AVGPERIOD 4 -#define DO_MOVING_AVG(avg,obs) (avg = (1024*obs + (AVGPERIOD-1)*avg)/AVGPERIOD) -// Spot the bug in this macro - I can't. but it doesn't work! - -class CBaseVideoRenderer : public CBaseRenderer, // Base renderer class - public IQualProp, // Property page guff - public IQualityControl // Allow throttling -{ -protected: - - // Hungarian: - // tFoo is the time Foo in mSec (beware m_tStart from filter.h) - // trBar is the time Bar by the reference clock - - //****************************************************************** - // State variables to control synchronisation - //****************************************************************** - - // Control of sending Quality messages. We need to know whether - // we are in trouble (e.g. frames being dropped) and where the time - // is being spent. - - // When we drop a frame we play the next one early. - // The frame after that is likely to wait before drawing and counting this - // wait as spare time is unfair, so we count it as a zero wait. - // We therefore need to know whether we are playing frames early or not. - - int m_nNormal; // The number of consecutive frames - // drawn at their normal time (not early) - // -1 means we just dropped a frame. - -#ifdef PERF - BOOL m_bDrawLateFrames; // Don't drop any frames (debug and I'm - // not keen on people using it!) -#endif - - BOOL m_bSupplierHandlingQuality;// The response to Quality messages says - // our supplier is handling things. - // We will allow things to go extra late - // before dropping frames. We will play - // very early after he has dropped one. - - // Control of scheduling, frame dropping etc. - // We need to know where the time is being spent so as to tell whether - // we should be taking action here, signalling supplier or what. - // The variables are initialised to a mode of NOT dropping frames. - // They will tell the truth after a few frames. - // We typically record a start time for an event, later we get the time - // again and subtract to get the elapsed time, and we average this over - // a few frames. The average is used to tell what mode we are in. - - // Although these are reference times (64 bit) they are all DIFFERENCES - // between times which are small. An int will go up to 214 secs before - // overflow. Avoiding 64 bit multiplications and divisions seems - // worth while. - - - - // Audio-video throttling. If the user has turned up audio quality - // very high (in principle it could be any other stream, not just audio) - // then we can receive cries for help via the graph manager. In this case - // we put in a wait for some time after rendering each frame. - int m_trThrottle; - - // The time taken to render (i.e. BitBlt) frames controls which component - // needs to degrade. If the blt is expensive, the renderer degrades. - // If the blt is cheap it's done anyway and the supplier degrades. - int m_trRenderAvg; // Time frames are taking to blt - int m_trRenderLast; // Time for last frame blt - int m_tRenderStart; // Just before we started drawing (mSec) - // derived from timeGetTime. - - // When frames are dropped we will play the next frame as early as we can. - // If it was a false alarm and the machine is fast we slide gently back to - // normal timing. To do this, we record the offset showing just how early - // we really are. This will normally be negative meaning early or zero. - int m_trEarliness; - - // Target provides slow long-term feedback to try to reduce the - // average sync offset to zero. Whenever a frame is actually rendered - // early we add a msec or two, whenever late we take off a few. - // We add or take off 1/32 of the error time. - // Eventually we should be hovering around zero. For a really bad case - // where we were (say) 300mSec off, it might take 100 odd frames to - // settle down. The rate of change of this is intended to be slower - // than any other mechanism in Quartz, thereby avoiding hunting. - int m_trTarget; - - // The proportion of time spent waiting for the right moment to blt - // controls whether we bother to drop a frame or whether we reckon that - // we're doing well enough that we can stand a one-frame glitch. - int m_trWaitAvg; // Average of last few wait times - // (actually we just average how early - // we were). Negative here means LATE. - - // The average inter-frame time. - // This is used to calculate the proportion of the time used by the - // three operations (supplying us, waiting, rendering) - int m_trFrameAvg; // Average inter-frame time - int m_trDuration; // duration of last frame. - -#ifdef PERF - // Performance logging identifiers - int m_idTimeStamp; // MSR_id for frame time stamp - int m_idEarliness; // MSR_id for earliness fudge - int m_idTarget; // MSR_id for Target fudge - int m_idWaitReal; // MSR_id for true wait time - int m_idWait; // MSR_id for wait time recorded - int m_idFrameAccuracy; // MSR_id for time frame is late (int) - int m_idRenderAvg; // MSR_id for Render time recorded (int) - int m_idSchLateTime; // MSR_id for lateness at scheduler - int m_idQualityRate; // MSR_id for Quality rate requested - int m_idQualityTime; // MSR_id for Quality time requested - int m_idDecision; // MSR_id for decision code - int m_idDuration; // MSR_id for duration of a frame - int m_idThrottle; // MSR_id for audio-video throttling - //int m_idDebug; // MSR_id for trace style debugging - //int m_idSendQuality; // MSR_id for timing the notifications per se -#endif // PERF - REFERENCE_TIME m_trRememberStampForPerf; // original time stamp of frame - // with no earliness fudges etc. -#ifdef PERF - REFERENCE_TIME m_trRememberFrameForPerf; // time when previous frame rendered - - // debug... - int m_idFrameAvg; - int m_idWaitAvg; -#endif - - // PROPERTY PAGE - // This has edit fields that show the user what's happening - // These member variables hold these counts. - - int m_cFramesDropped; // cumulative frames dropped IN THE RENDERER - int m_cFramesDrawn; // Frames since streaming started seen BY THE - // RENDERER (some may be dropped upstream) - - // Next two support average sync offset and standard deviation of sync offset. - LONGLONG m_iTotAcc; // Sum of accuracies in mSec - LONGLONG m_iSumSqAcc; // Sum of squares of (accuracies in mSec) - - // Next two allow jitter calculation. Jitter is std deviation of frame time. - REFERENCE_TIME m_trLastDraw; // Time of prev frame (for inter-frame times) - LONGLONG m_iSumSqFrameTime; // Sum of squares of (inter-frame time in mSec) - LONGLONG m_iSumFrameTime; // Sum of inter-frame times in mSec - - // To get performance statistics on frame rate, jitter etc, we need - // to record the lateness and inter-frame time. What we actually need are the - // data above (sum, sum of squares and number of entries for each) but the data - // is generated just ahead of time and only later do we discover whether the - // frame was actually drawn or not. So we have to hang on to the data - int m_trLate; // hold onto frame lateness - int m_trFrame; // hold onto inter-frame time - - int m_tStreamingStart; // if streaming then time streaming started - // else time of last streaming session - // used for property page statistics -#ifdef PERF - LONGLONG m_llTimeOffset; // timeGetTime()*10000+m_llTimeOffset==ref time -#endif - -public: - - - CBaseVideoRenderer(REFCLSID RenderClass, // CLSID for this renderer - TCHAR *pName, // Debug ONLY description - LPUNKNOWN pUnk, // Aggregated owner object - HRESULT *phr); // General OLE return code - - ~CBaseVideoRenderer(); - - // IQualityControl methods - Notify allows audio-video throttling - - STDMETHODIMP SetSink( IQualityControl * piqc); - STDMETHODIMP Notify( IBaseFilter * pSelf, Quality q); - - // These provide a full video quality management implementation - - void OnRenderStart(IMediaSample *pMediaSample); - void OnRenderEnd(IMediaSample *pMediaSample); - void OnWaitStart(); - void OnWaitEnd(); - HRESULT OnStartStreaming(); - HRESULT OnStopStreaming(); - void ThrottleWait(); - - // Handle the statistics gathering for our quality management - - void PreparePerformanceData(int trLate, int trFrame); - virtual void RecordFrameLateness(int trLate, int trFrame); - virtual void OnDirectRender(IMediaSample *pMediaSample); - virtual HRESULT ResetStreamingTimes(); - BOOL ScheduleSample(IMediaSample *pMediaSample); - HRESULT ShouldDrawSampleNow(IMediaSample *pMediaSample, - REFERENCE_TIME *ptrStart, - REFERENCE_TIME *ptrEnd); - - virtual HRESULT SendQuality(REFERENCE_TIME trLate, REFERENCE_TIME trRealStream); - STDMETHODIMP JoinFilterGraph(IFilterGraph * pGraph, LPCWSTR pName); - - // - // Do estimates for standard deviations for per-frame - // statistics - // - // *piResult = (llSumSq - iTot * iTot / m_cFramesDrawn - 1) / - // (m_cFramesDrawn - 2) - // or 0 if m_cFramesDrawn <= 3 - // - HRESULT GetStdDev( - int nSamples, - int *piResult, - LONGLONG llSumSq, - LONGLONG iTot - ); -public: - - // IQualProp property page support - - STDMETHODIMP get_FramesDroppedInRenderer(int *cFramesDropped); - STDMETHODIMP get_FramesDrawn(int *pcFramesDrawn); - STDMETHODIMP get_AvgFrameRate(int *piAvgFrameRate); - STDMETHODIMP get_Jitter(int *piJitter); - STDMETHODIMP get_AvgSyncOffset(int *piAvg); - STDMETHODIMP get_DevSyncOffset(int *piDev); - - // Implement an IUnknown interface and expose IQualProp - - DECLARE_IUNKNOWN - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,VOID **ppv); -}; - -#endif // __RENBASE__ - diff --git a/src/BaseClasses/schedule.cpp b/src/BaseClasses/schedule.cpp deleted file mode 100644 index 975fa20321..0000000000 --- a/src/BaseClasses/schedule.cpp +++ /dev/null @@ -1,265 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Schedule.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1996-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include - -#pragma warning(disable:4706) // C4706: assignment within conditional expression - -// DbgLog values (all on LOG_TIMING): -// -// 2 for schedulting, firing and shunting of events -// 3 for wait delays and wake-up times of event thread -// 4 for details of whats on the list when the thread awakes - -/* Construct & destructors */ - -CAMSchedule::CAMSchedule( HANDLE ev ) -: CBaseObject(TEXT("CAMSchedule")) -, head(&z, 0), z(0, MAX_TIME) -, m_dwNextCookie(0), m_dwAdviseCount(0) -, m_pAdviseCache(0), m_dwCacheCount(0) -, m_ev( ev ) { - head.m_dwAdviseCookie = z.m_dwAdviseCookie = 0; -} - -CAMSchedule::~CAMSchedule() { - m_Serialize.Lock(); - - // Delete cache - CAdvisePacket * p = m_pAdviseCache; - while(p) { - CAdvisePacket *const p_next = p->m_next; - delete p; - p = p_next; - } - - ASSERT(m_dwAdviseCount == 0); - // Better to be safe than sorry - if(m_dwAdviseCount > 0) { - DumpLinkedList(); - while(!head.m_next->IsZ()) { - head.DeleteNext(); - --m_dwAdviseCount; - } - } - - // If, in the debug version, we assert twice, it means, not only - // did we have left over advises, but we have also let m_dwAdviseCount - // get out of sync. with the number of advises actually on the list. - ASSERT(m_dwAdviseCount == 0); - - m_Serialize.Unlock(); -} - -/* Public methods */ - -DWORD CAMSchedule::GetAdviseCount() { - // No need to lock, m_dwAdviseCount is 32bits & declared volatile - return m_dwAdviseCount; -} - -REFERENCE_TIME CAMSchedule::GetNextAdviseTime() { - CAutoLock lck(&m_Serialize); // Need to stop the linked list from changing - return head.m_next->m_rtEventTime; -} - -DWORD_PTR CAMSchedule::AddAdvisePacket -( const REFERENCE_TIME & time1 -, const REFERENCE_TIME & time2 -, HANDLE h, BOOL periodic -) { - // Since we use MAX_TIME as a sentry, we can't afford to - // schedule a notification at MAX_TIME - ASSERT(time1 < MAX_TIME); - DWORD_PTR Result; - CAdvisePacket * p; - - m_Serialize.Lock(); - - if(m_pAdviseCache) { - p = m_pAdviseCache; - m_pAdviseCache = p->m_next; - --m_dwCacheCount; - } - else { - p = new CAdvisePacket(); - } - if(p) { - p->m_rtEventTime = time1; p->m_rtPeriod = time2; - p->m_hNotify = h; p->m_bPeriodic = periodic; - Result = AddAdvisePacket(p); - } - else Result = 0; - - m_Serialize.Unlock(); - - return Result; -} - -HRESULT CAMSchedule::Unadvise(DWORD_PTR dwAdviseCookie) { - HRESULT hr = S_FALSE; - CAdvisePacket * p_prev = &head; - CAdvisePacket * p_n; - m_Serialize.Lock(); - while(p_n = p_prev->Next()) // The Next() method returns NULL when it hits z - { - if(p_n->m_dwAdviseCookie == dwAdviseCookie) { - Delete(p_prev->RemoveNext()); - --m_dwAdviseCount; - hr = S_OK; - // Having found one cookie that matches, there should be no more -#ifdef DEBUG - while(p_n = p_prev->Next()) { - ASSERT(p_n->m_dwAdviseCookie != dwAdviseCookie); - p_prev = p_n; - } -#endif - break; - } - p_prev = p_n; - }; - m_Serialize.Unlock(); - return hr; -} - -REFERENCE_TIME CAMSchedule::Advise( const REFERENCE_TIME & rtTime ) { - REFERENCE_TIME rtNextTime; - CAdvisePacket * pAdvise; - - DbgLog((LOG_TIMING, 2, - TEXT("CAMSchedule::Advise( %lu ms )"), ULONG(rtTime / (UNITS / MILLISECONDS)))); - - CAutoLock lck(&m_Serialize); - -#ifdef DEBUG - if(DbgCheckModuleLevel(LOG_TIMING, 4)) DumpLinkedList(); -#endif - - // Note - DON'T cache the difference, it might overflow - while(rtTime >= (rtNextTime = (pAdvise=head.m_next)->m_rtEventTime) && - !pAdvise->IsZ()) { - ASSERT(pAdvise->m_dwAdviseCookie); // If this is zero, its the head or the tail!! - - ASSERT(pAdvise->m_hNotify != INVALID_HANDLE_VALUE); - - if(pAdvise->m_bPeriodic == TRUE) { - ReleaseSemaphore(pAdvise->m_hNotify,1,NULL); - pAdvise->m_rtEventTime += pAdvise->m_rtPeriod; - ShuntHead(); - } - else { - ASSERT(pAdvise->m_bPeriodic == FALSE); - EXECUTE_ASSERT(SetEvent(pAdvise->m_hNotify)); - --m_dwAdviseCount; - Delete(head.RemoveNext()); - } - - } - - DbgLog((LOG_TIMING, 3, - TEXT("CAMSchedule::Advise() Next time stamp: %lu ms, for advise %lu."), - DWORD(rtNextTime / (UNITS / MILLISECONDS)), pAdvise->m_dwAdviseCookie )); - - return rtNextTime; -} - -/* Private methods */ - -DWORD_PTR CAMSchedule::AddAdvisePacket( CAdvisePacket * pPacket ) { - ASSERT(pPacket->m_rtEventTime >= 0 && pPacket->m_rtEventTime < MAX_TIME); - ASSERT(CritCheckIn(&m_Serialize)); - - CAdvisePacket * p_prev = &head; - CAdvisePacket * p_n; - - const DWORD_PTR Result = pPacket->m_dwAdviseCookie = ++m_dwNextCookie; - // This relies on the fact that z is a sentry with a maximal m_rtEventTime - for(;;p_prev = p_n) - { - p_n = p_prev->m_next; - if(p_n->m_rtEventTime >= pPacket->m_rtEventTime) - break; - } - p_prev->InsertAfter( pPacket ); - ++m_dwAdviseCount; - - DbgLog((LOG_TIMING, 2, TEXT("Added advise %lu, for thread 0x%02X, scheduled at %lu"), - pPacket->m_dwAdviseCookie, GetCurrentThreadId(), (pPacket->m_rtEventTime / (UNITS / MILLISECONDS)) )); - - // If packet added at the head, then clock needs to re-evaluate wait time. - if(p_prev == &head) SetEvent(m_ev); - - return Result; -} - -void CAMSchedule::Delete( CAdvisePacket * pPacket ) { - if(m_dwCacheCount >= dwCacheMax) delete pPacket; - else { - m_Serialize.Lock(); - pPacket->m_next = m_pAdviseCache; - m_pAdviseCache = pPacket; - ++m_dwCacheCount; - m_Serialize.Unlock(); - } -} - - -// Takes the head of the list & repositions it -void CAMSchedule::ShuntHead() { - CAdvisePacket * p_prev = &head; - CAdvisePacket * p_n; - - m_Serialize.Lock(); - CAdvisePacket *const pPacket = head.m_next; - - // This will catch both an empty list, - // and if somehow a MAX_TIME time gets into the list - // (which would also break this method). - ASSERT(pPacket->m_rtEventTime < MAX_TIME); - - // This relies on the fact that z is a sentry with a maximal m_rtEventTime - for(;;p_prev = p_n) - { - p_n = p_prev->m_next; - if(p_n->m_rtEventTime > pPacket->m_rtEventTime) - break; - } - - // If p_prev == pPacket then we're already in the right place - if(p_prev != pPacket) - { - head.m_next = pPacket->m_next; - (p_prev->m_next = pPacket)->m_next = p_n; - } - #ifdef DEBUG - DbgLog((LOG_TIMING, 2, TEXT("Periodic advise %lu, shunted to %lu"), - pPacket->m_dwAdviseCookie, (pPacket->m_rtEventTime / (UNITS / MILLISECONDS)) )); -#endif - m_Serialize.Unlock(); -} - - -#ifdef DEBUG -void CAMSchedule::DumpLinkedList() { - m_Serialize.Lock(); - int i=0; - DbgLog((LOG_TIMING, 1, TEXT("CAMSchedule::DumpLinkedList() this = 0x%p"), this)); - for(CAdvisePacket * p = &head - ; p - ; p = p->m_next , i++) { - DbgLog((LOG_TIMING, 1, TEXT("Advise List # %lu, Cookie %d, RefTime %lu"), - i, - p->m_dwAdviseCookie, - p->m_rtEventTime / (UNITS / MILLISECONDS) - )); - } - m_Serialize.Unlock(); -} -#endif - diff --git a/src/BaseClasses/seekpt.cpp b/src/BaseClasses/seekpt.cpp deleted file mode 100644 index 2f49f6660b..0000000000 --- a/src/BaseClasses/seekpt.cpp +++ /dev/null @@ -1,83 +0,0 @@ -//------------------------------------------------------------------------------ -// File: SeekPT.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include "seekpt.h" - -//================================================================== -// CreateInstance -// This goes in the factory template table to create new instances -// If there is already a mapper instance - return that, else make one -// and save it in a static variable so that forever after we can return that. -//================================================================== - -CUnknown * CSeekingPassThru::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr) -{ - return new CSeekingPassThru(NAME("Seeking PassThru"),pUnk, phr); -} - - -STDMETHODIMP CSeekingPassThru::NonDelegatingQueryInterface(REFIID riid, void ** ppv) -{ - if (riid == IID_ISeekingPassThru) { - return GetInterface((ISeekingPassThru *) this, ppv); - } else { - if (m_pPosPassThru && - (riid == IID_IMediaSeeking || - riid == IID_IMediaPosition)) { - return m_pPosPassThru->NonDelegatingQueryInterface(riid,ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } - } -} - - -CSeekingPassThru::CSeekingPassThru( TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr ) - : CUnknown(pName, pUnk, phr), - m_pPosPassThru(NULL) -{ -} - - -CSeekingPassThru::~CSeekingPassThru() -{ - delete m_pPosPassThru; -} - -STDMETHODIMP CSeekingPassThru::Init(BOOL bRendererSeeking, IPin *pPin) -{ - HRESULT hr = NOERROR; - if (m_pPosPassThru) { - hr = E_FAIL; - } else { - m_pPosPassThru = - bRendererSeeking ? - new CRendererPosPassThru( - NAME("Render Seeking COM object"), - (IUnknown *)this, - &hr, - pPin) : - new CPosPassThru( - NAME("Render Seeking COM object"), - (IUnknown *)this, - &hr, - pPin); - if (!m_pPosPassThru) { - hr = E_OUTOFMEMORY; - } else { - if (FAILED(hr)) { - delete m_pPosPassThru; - m_pPosPassThru = NULL; - } - } - } - return hr; -} - diff --git a/src/BaseClasses/seekpt.h b/src/BaseClasses/seekpt.h deleted file mode 100644 index 49ba33db3d..0000000000 --- a/src/BaseClasses/seekpt.h +++ /dev/null @@ -1,30 +0,0 @@ -//------------------------------------------------------------------------------ -// File: SeekPT.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __seekpt_h__ -#define __seekpt_h__ - - -class CSeekingPassThru : public ISeekingPassThru, public CUnknown -{ -public: - static CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr); - CSeekingPassThru(TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr); - ~CSeekingPassThru(); - - DECLARE_IUNKNOWN; - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv); - - STDMETHODIMP Init(BOOL bSupportRendering, IPin *pPin); - -private: - CPosPassThru *m_pPosPassThru; -}; - -#endif diff --git a/src/BaseClasses/source.cpp b/src/BaseClasses/source.cpp deleted file mode 100644 index f8cb36360a..0000000000 --- a/src/BaseClasses/source.cpp +++ /dev/null @@ -1,519 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Source.cpp -// -// Desc: DirectShow base classes - implements CSource, which is a Quartz -// source filter 'template.' -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// Locking Strategy. -// -// Hold the filter critical section (m_pFilter->pStateLock()) to serialise -// access to functions. Note that, in general, this lock may be held -// by a function when the worker thread may want to hold it. Therefore -// if you wish to access shared state from the worker thread you will -// need to add another critical section object. The execption is during -// the threads processing loop, when it is safe to get the filter critical -// section from within FillBuffer(). - -#include - - -// -// CSource::Constructor -// -// Initialise the pin count for the filter. The user will create the pins in -// the derived class. -CSource::CSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid) - : CBaseFilter(pName, lpunk, &m_cStateLock, clsid), - m_iPins(0), - m_paStreams(NULL) { -} - -CSource::CSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr) - : CBaseFilter(pName, lpunk, &m_cStateLock, clsid), - m_iPins(0), - m_paStreams(NULL) { - UNREFERENCED_PARAMETER(phr); -} - -#ifdef UNICODE -CSource::CSource(CHAR *pName, LPUNKNOWN lpunk, CLSID clsid) - : CBaseFilter(pName, lpunk, &m_cStateLock, clsid), - m_iPins(0), - m_paStreams(NULL) { -} - -CSource::CSource(CHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr) - : CBaseFilter(pName, lpunk, &m_cStateLock, clsid), - m_iPins(0), - m_paStreams(NULL) { - UNREFERENCED_PARAMETER(phr); -} -#endif - -// -// CSource::Destructor -// -CSource::~CSource() { - /* Free our pins and pin array */ - while(m_iPins != 0) { - // deleting the pins causes them to be removed from the array... - delete m_paStreams[m_iPins - 1]; - } - - ASSERT(m_paStreams == NULL); -} - - -// -// Add a new pin -// -HRESULT CSource::AddPin(CSourceStream *pStream) { - CAutoLock lock(&m_cStateLock); - - /* Allocate space for this pin and the old ones */ - CSourceStream **paStreams = new CSourceStream *[m_iPins + 1]; - if(paStreams == NULL) { - return E_OUTOFMEMORY; - } - if(m_paStreams != NULL) { - CopyMemory((PVOID)paStreams, (PVOID)m_paStreams, - m_iPins * sizeof(m_paStreams[0])); - paStreams[m_iPins] = pStream; - delete [] m_paStreams; - } - m_paStreams = paStreams; - m_paStreams[m_iPins] = pStream; - m_iPins++; - return S_OK; -} - -// -// Remove a pin - pStream is NOT deleted -// -HRESULT CSource::RemovePin(CSourceStream *pStream) { - int i; - for(i = 0; i < m_iPins; i++) { - if(m_paStreams[i] == pStream) { - if(m_iPins == 1) { - delete [] m_paStreams; - m_paStreams = NULL; - } - else { - /* no need to reallocate */ - while(++i < m_iPins) - m_paStreams[i - 1] = m_paStreams[i]; - } - m_iPins--; - return S_OK; - } - } - return S_FALSE; -} - -// -// FindPin -// -// Set *ppPin to the IPin* that has the id Id. -// or to NULL if the Id cannot be matched. -STDMETHODIMP CSource::FindPin(LPCWSTR Id, IPin **ppPin) { - CheckPointer(ppPin,E_POINTER); - ValidateReadWritePtr(ppPin,sizeof(IPin *)); - // The -1 undoes the +1 in QueryId and ensures that totally invalid - // strings (for which WstrToInt delivers 0) give a deliver a NULL pin. - int i = WstrToInt(Id) -1; - *ppPin = GetPin(i); - if(*ppPin!=NULL) { - (*ppPin)->AddRef(); - return NOERROR; - } - else { - return VFW_E_NOT_FOUND; - } -} - -// -// FindPinNumber -// -// return the number of the pin with this IPin* or -1 if none -int CSource::FindPinNumber(IPin *iPin) { - int i; - for(i=0; in && n>=0 it follows that m_iPins>0 - // which is what used to be checked (i.e. checking that we have a pin) - if((n >= 0) && (n < m_iPins)) { - - ASSERT(m_paStreams[n]); - return m_paStreams[n]; - } - return NULL; -} - - -// - - -// * -// * --- CSourceStream ---- -// * - -// -// Set Id to point to a CoTaskMemAlloc'd -STDMETHODIMP CSourceStream::QueryId(LPWSTR *Id) { - CheckPointer(Id,E_POINTER); - ValidateReadWritePtr(Id,sizeof(LPWSTR)); - - // We give the pins id's which are 1,2,... - // FindPinNumber returns -1 for an invalid pin - int i = 1+ m_pFilter->FindPinNumber(this); - if(i<1) return VFW_E_NOT_FOUND; - *Id = (LPWSTR)CoTaskMemAlloc(8); - if(*Id==NULL) { - return E_OUTOFMEMORY; - } - IntToWstr(i, *Id); - return NOERROR; -} - - - -// -// CSourceStream::Constructor -// -// increments the number of pins present on the filter -CSourceStream::CSourceStream( - TCHAR *pObjectName, - HRESULT *phr, - CSource *ps, - LPCWSTR pPinName) - : CBaseOutputPin(pObjectName, ps, ps->pStateLock(), phr, pPinName), - m_pFilter(ps) { - - *phr = m_pFilter->AddPin(this); -} - -#ifdef UNICODE -CSourceStream::CSourceStream( - char *pObjectName, - HRESULT *phr, - CSource *ps, - LPCWSTR pPinName) - : CBaseOutputPin(pObjectName, ps, ps->pStateLock(), phr, pPinName), - m_pFilter(ps) { - - *phr = m_pFilter->AddPin(this); -} -#endif -// -// CSourceStream::Destructor -// -// Decrements the number of pins on this filter -CSourceStream::~CSourceStream(void) { - - m_pFilter->RemovePin(this); -} - - -// -// CheckMediaType -// -// Do we support this type? Provides the default support for 1 type. -HRESULT CSourceStream::CheckMediaType(const CMediaType *pMediaType) { - - CAutoLock lock(m_pFilter->pStateLock()); - - CMediaType mt; - GetMediaType(&mt); - - if(mt == *pMediaType) { - return NOERROR; - } - - return E_FAIL; -} - - -// -// GetMediaType/3 -// -// By default we support only one type -// iPosition indexes are 0-n -HRESULT CSourceStream::GetMediaType(int iPosition, CMediaType *pMediaType) { - - CAutoLock lock(m_pFilter->pStateLock()); - - if(iPosition<0) { - return E_INVALIDARG; - } - if(iPosition>0) { - return VFW_S_NO_MORE_ITEMS; - } - return GetMediaType(pMediaType); -} - - -// -// Active -// -// The pin is active - start up the worker thread -HRESULT CSourceStream::Active(void) { - - CAutoLock lock(m_pFilter->pStateLock()); - - HRESULT hr; - - if(m_pFilter->IsActive()) { - return S_FALSE; // succeeded, but did not allocate resources (they already exist...) - } - - // do nothing if not connected - its ok not to connect to - // all pins of a source filter - if(!IsConnected()) { - return NOERROR; - } - - hr = CBaseOutputPin::Active(); - if(FAILED(hr)) { - return hr; - } - - ASSERT(!ThreadExists()); - - // start the thread - if(!Create()) { - return E_FAIL; - } - - // Tell thread to initialize. If OnThreadCreate Fails, so does this. - hr = Init(); - if(FAILED(hr)) - return hr; - - return Pause(); -} - - -// -// Inactive -// -// Pin is inactive - shut down the worker thread -// Waits for the worker to exit before returning. -HRESULT CSourceStream::Inactive(void) { - - CAutoLock lock(m_pFilter->pStateLock()); - - HRESULT hr; - - // do nothing if not connected - its ok not to connect to - // all pins of a source filter - if(!IsConnected()) { - return NOERROR; - } - - // !!! need to do this before trying to stop the thread, because - // we may be stuck waiting for our own allocator!!! - - hr = CBaseOutputPin::Inactive(); // call this first to Decommit the allocator - if(FAILED(hr)) { - return hr; - } - - if(ThreadExists()) { - hr = Stop(); - - if(FAILED(hr)) { - return hr; - } - - hr = Exit(); - if(FAILED(hr)) { - return hr; - } - - Close(); // Wait for the thread to exit, then tidy up. - } - - // hr = CBaseOutputPin::Inactive(); // call this first to Decommit the allocator - //if (FAILED(hr)) { - // return hr; - //} - - return NOERROR; -} - - -// -// ThreadProc -// -// When this returns the thread exits -// Return codes > 0 indicate an error occured -DWORD CSourceStream::ThreadProc(void) { - - HRESULT hr; // the return code from calls - Command com; - - do { - com = GetRequest(); - if(com != CMD_INIT) { - DbgLog((LOG_ERROR, 1, TEXT("Thread expected init command"))); - Reply((DWORD) E_UNEXPECTED); - } - } while(com != CMD_INIT); - - DbgLog((LOG_TRACE, 1, TEXT("CSourceStream worker thread initializing"))); - - hr = OnThreadCreate(); // perform set up tasks - if(FAILED(hr)) { - DbgLog((LOG_ERROR, 1, TEXT("CSourceStream::OnThreadCreate failed. Aborting thread."))); - OnThreadDestroy(); - Reply(hr); // send failed return code from OnThreadCreate - return 1; - } - - // Initialisation suceeded - Reply(NOERROR); - - Command cmd; - do { - cmd = GetRequest(); - - switch(cmd) { - - case CMD_EXIT: - Reply(NOERROR); - break; - - case CMD_RUN: - DbgLog((LOG_ERROR, 1, TEXT("CMD_RUN received before a CMD_PAUSE???"))); - // !!! fall through??? - - case CMD_PAUSE: - Reply(NOERROR); - DoBufferProcessingLoop(); - break; - - case CMD_STOP: - Reply(NOERROR); - break; - - default: - DbgLog((LOG_ERROR, 1, TEXT("Unknown command %d received!"), cmd)); - Reply((DWORD) E_NOTIMPL); - break; - } - } while(cmd != CMD_EXIT); - - hr = OnThreadDestroy(); // tidy up. - if(FAILED(hr)) { - DbgLog((LOG_ERROR, 1, TEXT("CSourceStream::OnThreadDestroy failed. Exiting thread."))); - return 1; - } - - DbgLog((LOG_TRACE, 1, TEXT("CSourceStream worker thread exiting"))); - return 0; -} - - -// -// DoBufferProcessingLoop -// -// Grabs a buffer and calls the users processing function. -// Overridable, so that different delivery styles can be catered for. -HRESULT CSourceStream::DoBufferProcessingLoop(void) { - - Command com; - - OnThreadStartPlay(); - - do { - while(!CheckRequest(&com)) { - - IMediaSample *pSample; - - HRESULT hr = GetDeliveryBuffer(&pSample,NULL,NULL,0); - if(FAILED(hr)) { - Sleep(1); - continue; // go round again. Perhaps the error will go away - // or the allocator is decommited & we will be asked to - // exit soon. - } - - // Virtual function user will override. - hr = FillBuffer(pSample); - - if(hr == S_OK) { - hr = Deliver(pSample); - pSample->Release(); - - // downstream filter returns S_FALSE if it wants us to - // stop or an error if it's reporting an error. - if(hr != S_OK) { - DbgLog((LOG_TRACE, 2, TEXT("Deliver() returned %08x; stopping"), hr)); - return S_OK; - } - - } - else if(hr == S_FALSE) { - // derived class wants us to stop pushing data - pSample->Release(); - DeliverEndOfStream(); - return S_OK; - } - else { - // derived class encountered an error - pSample->Release(); - DbgLog((LOG_ERROR, 1, TEXT("Error %08lX from FillBuffer!!!"), hr)); - DeliverEndOfStream(); - m_pFilter->NotifyEvent(EC_ERRORABORT, hr, 0); - return hr; - } - - // all paths release the sample - } - - // For all commands sent to us there must be a Reply call! - - if(com == CMD_RUN || com == CMD_PAUSE) { - Reply(NOERROR); - } - else if(com != CMD_STOP) { - Reply((DWORD) E_UNEXPECTED); - DbgLog((LOG_ERROR, 1, TEXT("Unexpected command!!!"))); - } - } while(com != CMD_STOP); - - return S_FALSE; -} - - diff --git a/src/BaseClasses/source.h b/src/BaseClasses/source.h deleted file mode 100644 index 2f4634e894..0000000000 --- a/src/BaseClasses/source.h +++ /dev/null @@ -1,172 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Source.h -// -// Desc: DirectShow base classes - defines classes to simplify creation of -// ActiveX source filters that support continuous generation of data. -// No support is provided for IMediaControl or IMediaPosition. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// -// Derive your source filter from CSource. -// During construction either: -// Create some CSourceStream objects to manage your pins -// Provide the user with a means of doing so eg, an IPersistFile interface. -// -// CSource provides: -// IBaseFilter interface management -// IMediaFilter interface management, via CBaseFilter -// Pin counting for CBaseFilter -// -// Derive a class from CSourceStream to manage your output pin types -// Implement GetMediaType/1 to return the type you support. If you support multiple -// types then overide GetMediaType/3, CheckMediaType and GetMediaTypeCount. -// Implement Fillbuffer() to put data into one buffer. -// -// CSourceStream provides: -// IPin management via CBaseOutputPin -// Worker thread management - -#ifndef __CSOURCE__ -#define __CSOURCE__ - -class CSourceStream; // The class that will handle each pin - - -// -// CSource -// -// Override construction to provide a means of creating -// CSourceStream derived objects - ie a way of creating pins. -class CSource : public CBaseFilter { -public: - - CSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr); - CSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid); -#ifdef UNICODE - CSource(CHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr); - CSource(CHAR *pName, LPUNKNOWN lpunk, CLSID clsid); -#endif - ~CSource(); - - int GetPinCount(void); - CBasePin *GetPin(int n); - - // -- Utilities -- - - CCritSec* pStateLock(void) { return &m_cStateLock; } // provide our critical section - - HRESULT AddPin(CSourceStream *); - HRESULT RemovePin(CSourceStream *); - - STDMETHODIMP FindPin( - LPCWSTR Id, - IPin ** ppPin - ); - - int FindPinNumber(IPin *iPin); - -protected: - - int m_iPins; // The number of pins on this filter. Updated by CSourceStream - // constructors & destructors. - CSourceStream **m_paStreams; // the pins on this filter. - - CCritSec m_cStateLock; // Lock this to serialize function accesses to the filter state - -}; - - -// -// CSourceStream -// -// Use this class to manage a stream of data that comes from a -// pin. -// Uses a worker thread to put data on the pin. -class CSourceStream : public CAMThread, public CBaseOutputPin { -public: - - CSourceStream(TCHAR *pObjectName, - HRESULT *phr, - CSource *pms, - LPCWSTR pName); -#ifdef UNICODE - CSourceStream(CHAR *pObjectName, - HRESULT *phr, - CSource *pms, - LPCWSTR pName); -#endif - virtual ~CSourceStream(void); // virtual destructor ensures derived class destructors are called too. - -protected: - - CSource *m_pFilter; // The parent of this stream - - // * - // * Data Source - // * - // * The following three functions: FillBuffer, OnThreadCreate/Destroy, are - // * called from within the ThreadProc. They are used in the creation of - // * the media samples this pin will provide - // * - - // Override this to provide the worker thread a means - // of processing a buffer - virtual HRESULT FillBuffer(IMediaSample *pSamp) PURE; - - // Called as the thread is created/destroyed - use to perform - // jobs such as start/stop streaming mode - // If OnThreadCreate returns an error the thread will exit. - virtual HRESULT OnThreadCreate(void) {return NOERROR;}; - virtual HRESULT OnThreadDestroy(void) {return NOERROR;}; - virtual HRESULT OnThreadStartPlay(void) {return NOERROR;}; - - // * - // * Worker Thread - // * - - HRESULT Active(void); // Starts up the worker thread - HRESULT Inactive(void); // Exits the worker thread. - -public: - // thread commands - enum Command {CMD_INIT, CMD_PAUSE, CMD_RUN, CMD_STOP, CMD_EXIT}; - HRESULT Init(void) { return CallWorker(CMD_INIT); } - HRESULT Exit(void) { return CallWorker(CMD_EXIT); } - HRESULT Run(void) { return CallWorker(CMD_RUN); } - HRESULT Pause(void) { return CallWorker(CMD_PAUSE); } - HRESULT Stop(void) { return CallWorker(CMD_STOP); } - -protected: - Command GetRequest(void) { return (Command) CAMThread::GetRequest(); } - BOOL CheckRequest(Command *pCom) { return CAMThread::CheckRequest( (DWORD *) pCom); } - - // override these if you want to add thread commands - virtual DWORD ThreadProc(void); // the thread function - - virtual HRESULT DoBufferProcessingLoop(void); // the loop executed whilst running - - - // * - // * AM_MEDIA_TYPE support - // * - - // If you support more than one media type then override these 2 functions - virtual HRESULT CheckMediaType(const CMediaType *pMediaType); - virtual HRESULT GetMediaType(int iPosition, CMediaType *pMediaType); // List pos. 0-n - - // If you support only one type then override this fn. - // This will only be called by the default implementations - // of CheckMediaType and GetMediaType(int, CMediaType*) - // You must override this fn. or the above 2! - virtual HRESULT GetMediaType(CMediaType *pMediaType) {return E_UNEXPECTED;} - - STDMETHODIMP QueryId( - LPWSTR * Id - ); -}; - -#endif // __CSOURCE__ - diff --git a/src/BaseClasses/streams.h b/src/BaseClasses/streams.h deleted file mode 100644 index 8baa6fedf6..0000000000 --- a/src/BaseClasses/streams.h +++ /dev/null @@ -1,172 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Streams.h -// -// Desc: DirectShow base classes - defines overall streams architecture. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __STREAMS__ -#define __STREAMS__ - -// disable some level-4 warnings, use #pragma warning(enable:###) to re-enable -#pragma warning(disable:4100) // warning C4100: unreferenced formal parameter -#pragma warning(disable:4127) // warning C4127: conditional expression is constant -#pragma warning(disable:4189) // warning C4189: local variable is initialized but not referenced -#pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union -#pragma warning(disable:4511) // warning C4511: copy constructor could not be generated -#pragma warning(disable:4512) // warning C4512: assignment operator could not be generated -#pragma warning(disable:4514) // warning C4514: unreferenced inline function has been removed -#pragma warning(disable:4710) // warning C4710: 'function' not inlined - -#ifdef _MSC_VER -#if _MSC_VER>=1100 -#define AM_NOVTABLE __declspec(novtable) -#else -#define AM_NOVTABLE -#endif -#endif // MSC_VER - - -#include -#include -#include -#include -#include - -#ifndef NUMELMS - #define NUMELMS(aa) (sizeof(aa)/sizeof((aa)[0])) -#endif - -/////////////////////////////////////////////////////////////////////////// -// The following definitions come from the Platform SDK and are required if -// the applicaiton is being compiled with the headers from Visual C++ 6.0. -/////////////////////////////////////////////////////////////////////////// -#ifndef InterlockedExchangePointer - #define InterlockedExchangePointer(Target, Value) \ - (PVOID)InterlockedExchange((PLONG)(Target), (LONG)(Value)) -#endif - -#ifndef _WAVEFORMATEXTENSIBLE_ -#define _WAVEFORMATEXTENSIBLE_ -typedef struct { - WAVEFORMATEX Format; - union { - WORD wValidBitsPerSample; /* bits of precision */ - WORD wSamplesPerBlock; /* valid if wBitsPerSample==0 */ - WORD wReserved; /* If neither applies, set to zero. */ - } Samples; - DWORD dwChannelMask; /* which channels are */ - /* present in stream */ - GUID SubFormat; -} WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE; -#endif // !_WAVEFORMATEXTENSIBLE_ - -#if !defined(WAVE_FORMAT_EXTENSIBLE) -#define WAVE_FORMAT_EXTENSIBLE 0xFFFE -#endif // !defined(WAVE_FORMAT_EXTENSIBLE) - -#ifndef GetWindowLongPtr - #define GetWindowLongPtrA GetWindowLongA - #define GetWindowLongPtrW GetWindowLongW - #ifdef UNICODE - #define GetWindowLongPtr GetWindowLongPtrW - #else - #define GetWindowLongPtr GetWindowLongPtrA - #endif // !UNICODE -#endif // !GetWindowLongPtr - -#ifndef SetWindowLongPtr - #define SetWindowLongPtrA SetWindowLongA - #define SetWindowLongPtrW SetWindowLongW - #ifdef UNICODE - #define SetWindowLongPtr SetWindowLongPtrW - #else - #define SetWindowLongPtr SetWindowLongPtrA - #endif // !UNICODE -#endif // !SetWindowLongPtr - -#ifndef GWLP_WNDPROC - #define GWLP_WNDPROC (-4) -#endif -#ifndef GWLP_HINSTANCE - #define GWLP_HINSTANCE (-6) -#endif -#ifndef GWLP_HWNDPARENT - #define GWLP_HWNDPARENT (-8) -#endif -#ifndef GWLP_USERDATA - #define GWLP_USERDATA (-21) -#endif -#ifndef GWLP_ID - #define GWLP_ID (-12) -#endif -#ifndef DWLP_MSGRESULT - #define DWLP_MSGRESULT 0 -#endif -#ifndef DWLP_DLGPROC - #define DWLP_DLGPROC DWLP_MSGRESULT + sizeof(LRESULT) -#endif -#ifndef DWLP_USER - #define DWLP_USER DWLP_DLGPROC + sizeof(DLGPROC) -#endif -/////////////////////////////////////////////////////////////////////////// -// End Platform SDK definitions -/////////////////////////////////////////////////////////////////////////// - - -#pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union -#include // Generated IDL header file for streams interfaces - -// -// Modified by Chris to look in local baseclasses directory instead of include path -// -#include "baseclasses/reftime.h" // Helper class for REFERENCE_TIME management -#include "baseclasses/wxdebug.h" // Debug support for logging and ASSERTs -#include "baseclasses/amvideo.h" // ActiveMovie video interfaces and definitions - -//include amaudio.h explicitly if you need it. it requires the DX SDK. -//#include // ActiveMovie audio interfaces and definitions - -#include "baseclasses/wxutil.h" // General helper classes for threads etc -#include "baseclasses/combase.h" // Base COM classes to support IUnknown -#include "baseclasses/dllsetup.h" // Filter registration support functions -#include "baseclasses/measure.h" // Performance measurement -#include // Light weight com function prototypes - -#include "baseclasses/cache.h" // Simple cache container class -#include "baseclasses/wxlist.h" // Non MFC generic list class -#include "baseclasses/msgthrd.h" // CMsgThread -#include "baseclasses/mtype.h" // Helper class for managing media types -#include "baseclasses/fourcc.h" // conversions between FOURCCs and GUIDs -#include // generated from control.odl -#include "baseclasses/ctlutil.h" // control interface utility classes -#include // event code definitions -#include "baseclasses/amfilter.h" // Main streams architecture class hierachy -#include "baseclasses/transfrm.h" // Generic transform filter -#include "baseclasses/transip.h" // Generic transform-in-place filter -#include // declaration of type GUIDs and well-known clsids -#include "baseclasses/source.h" // Generic source filter -#include "baseclasses/outputq.h" // Output pin queueing -#include // HRESULT status and error definitions -#include "baseclasses/renbase.h" // Base class for writing ActiveX renderers -#include "baseclasses/winutil.h" // Helps with filters that manage windows -#include "baseclasses/winctrl.h" // Implements the IVideoWindow interface -#include "baseclasses/videoctl.h" // Specifically video related classes -#include "baseclasses/refclock.h" // Base clock class -#include "baseclasses/sysclock.h" // System clock -#include "baseclasses/pstream.h" // IPersistStream helper class -#include "baseclasses/vtrans.h" // Video Transform Filter base class -#include "baseclasses/amextra.h" -#include "baseclasses/cprop.h" // Base property page class -#include "baseclasses/strmctl.h" // IAMStreamControl support -#include // External device control interface defines -#include // audio filter device error event codes - -#else - #ifdef DEBUG - #pragma message("STREAMS.H included TWICE") - #endif -#endif // __STREAMS__ - diff --git a/src/BaseClasses/strmctl.cpp b/src/BaseClasses/strmctl.cpp deleted file mode 100644 index f176c14166..0000000000 --- a/src/BaseClasses/strmctl.cpp +++ /dev/null @@ -1,386 +0,0 @@ -//------------------------------------------------------------------------------ -// File: StrmCtl.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1996-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include - -CBaseStreamControl::CBaseStreamControl() -: m_StreamState(STREAM_FLOWING) -, m_StreamStateOnStop(STREAM_FLOWING) // means no pending stop -, m_tStartTime(MAX_TIME) -, m_tStopTime(MAX_TIME) -, m_dwStartCookie(0) -, m_dwStopCookie(0) -, m_pRefClock(NULL) -, m_FilterState(State_Stopped) -, m_bIsFlushing(FALSE) -, m_bStopSendExtra(FALSE) { -} - -CBaseStreamControl::~CBaseStreamControl() { - // Make sure we release the clock. - SetSyncSource(NULL); - return; -} - - -STDMETHODIMP CBaseStreamControl::StopAt(const REFERENCE_TIME * ptStop, BOOL bSendExtra, DWORD dwCookie) { - CAutoLock lck(&m_CritSec); - m_bStopSendExtra = FALSE; // reset - m_bStopExtraSent = FALSE; - if(ptStop) { - if(*ptStop == MAX_TIME) { - DbgLog((LOG_TRACE,2,TEXT("StopAt: Cancel stop"))); - CancelStop(); - // If there's now a command to start in the future, we assume - // they want to be stopped when the graph is first run - if(m_FilterState == State_Stopped && m_tStartTime < MAX_TIME) { - m_StreamState = STREAM_DISCARDING; - DbgLog((LOG_TRACE,2,TEXT("graph will begin by DISCARDING"))); - } - return NOERROR; - } - DbgLog((LOG_TRACE,2,TEXT("StopAt: %dms extra=%d"), - (int)(*ptStop/10000), bSendExtra)); - // if the first command is to stop in the future, then we assume they - // want to be started when the graph is first run - if(m_FilterState == State_Stopped && m_tStartTime > *ptStop) { - m_StreamState = STREAM_FLOWING; - DbgLog((LOG_TRACE,2,TEXT("graph will begin by FLOWING"))); - } - m_bStopSendExtra = bSendExtra; - m_tStopTime = *ptStop; - m_dwStopCookie = dwCookie; - m_StreamStateOnStop = STREAM_DISCARDING; - } - else { - DbgLog((LOG_TRACE,2,TEXT("StopAt: now"))); - // sending an extra frame when told to stop now would mess people up - m_bStopSendExtra = FALSE; - m_tStopTime = MAX_TIME; - m_dwStopCookie = 0; - m_StreamState = STREAM_DISCARDING; - m_StreamStateOnStop = STREAM_FLOWING; // no pending stop - } - // we might change our mind what to do with a sample we're blocking - m_StreamEvent.Set(); - return NOERROR; -} - - -STDMETHODIMP CBaseStreamControl::StartAt -( const REFERENCE_TIME *ptStart, DWORD dwCookie ) { - CAutoLock lck(&m_CritSec); - if(ptStart) { - if(*ptStart == MAX_TIME) { - DbgLog((LOG_TRACE,2,TEXT("StartAt: Cancel start"))); - CancelStart(); - // If there's now a command to stop in the future, we assume - // they want to be started when the graph is first run - if(m_FilterState == State_Stopped && m_tStopTime < MAX_TIME) { - DbgLog((LOG_TRACE,2,TEXT("graph will begin by FLOWING"))); - m_StreamState = STREAM_FLOWING; - } - return NOERROR; - } - DbgLog((LOG_TRACE,2,TEXT("StartAt: %dms"), (int)(*ptStart/10000))); - // if the first command is to start in the future, then we assume they - // want to be stopped when the graph is first run - if(m_FilterState == State_Stopped && m_tStopTime >= *ptStart) { - DbgLog((LOG_TRACE,2,TEXT("graph will begin by DISCARDING"))); - m_StreamState = STREAM_DISCARDING; - } - m_tStartTime = *ptStart; - m_dwStartCookie = dwCookie; - // if (m_tStopTime == m_tStartTime) CancelStop(); - } - else { - DbgLog((LOG_TRACE,2,TEXT("StartAt: now"))); - m_tStartTime = MAX_TIME; - m_dwStartCookie = 0; - m_StreamState = STREAM_FLOWING; - } - // we might change our mind what to do with a sample we're blocking - m_StreamEvent.Set(); - return NOERROR; -} - - -// Retrieve information about current settings -STDMETHODIMP CBaseStreamControl::GetInfo(AM_STREAM_INFO *pInfo) { - if(pInfo == NULL) - return E_POINTER; - - pInfo->tStart = m_tStartTime; - pInfo->tStop = m_tStopTime; - pInfo->dwStartCookie = m_dwStartCookie; - pInfo->dwStopCookie = m_dwStopCookie; - pInfo->dwFlags = m_bStopSendExtra ? AM_STREAM_INFO_STOP_SEND_EXTRA : 0; - pInfo->dwFlags |= m_tStartTime == MAX_TIME ? 0 : AM_STREAM_INFO_START_DEFINED; - pInfo->dwFlags |= m_tStopTime == MAX_TIME ? 0 : AM_STREAM_INFO_STOP_DEFINED; - switch(m_StreamState) { - default: - DbgBreak("Invalid stream state"); - case STREAM_FLOWING: - break; - case STREAM_DISCARDING: - pInfo->dwFlags |= AM_STREAM_INFO_DISCARDING; - break; - } - return S_OK; -} - - -void CBaseStreamControl::ExecuteStop() { - ASSERT(CritCheckIn(&m_CritSec)); - m_StreamState = m_StreamStateOnStop; - if(m_dwStopCookie && m_pSink) { - DbgLog((LOG_TRACE,2,TEXT("*sending EC_STREAM_CONTROL_STOPPED (%d)"), - m_dwStopCookie)); - m_pSink->Notify(EC_STREAM_CONTROL_STOPPED, (LONG_PTR)this, m_dwStopCookie); - } - CancelStop(); // This will do the tidy up -} - -void CBaseStreamControl::ExecuteStart() { - ASSERT(CritCheckIn(&m_CritSec)); - m_StreamState = STREAM_FLOWING; - if(m_dwStartCookie) { - DbgLog((LOG_TRACE,2,TEXT("*sending EC_STREAM_CONTROL_STARTED (%d)"), - m_dwStartCookie)); - m_pSink->Notify(EC_STREAM_CONTROL_STARTED, (LONG_PTR)this, m_dwStartCookie); - } - CancelStart(); // This will do the tidy up -} - -void CBaseStreamControl::CancelStop() { - ASSERT(CritCheckIn(&m_CritSec)); - m_tStopTime = MAX_TIME; - m_dwStopCookie = 0; - m_StreamStateOnStop = STREAM_FLOWING; -} - -void CBaseStreamControl::CancelStart() { - ASSERT(CritCheckIn(&m_CritSec)); - m_tStartTime = MAX_TIME; - m_dwStartCookie = 0; -} - - -// This guy will return one of the three StreamControlState's. Here's what the caller -// should do for each one: -// -// STREAM_FLOWING: Proceed as usual (render or pass the sample on) -// STREAM_DISCARDING: Calculate the time 'til *pSampleStart and wait that long -// for the event handle (GetStreamEventHandle()). If the -// wait expires, throw the sample away. If the event -// fires, call me back, I've changed my mind. -// I use pSampleStart (not Stop) so that live sources don't -// block for the duration of their samples, since the clock -// will always read approximately pSampleStart when called - - -// All through this code, you'll notice the following rules: -// - When start and stop time are the same, it's as if start was first -// - An event is considered inside the sample when it's >= sample start time -// but < sample stop time -// - if any part of the sample is supposed to be sent, we'll send the whole -// thing since we don't break it into smaller pieces -// - If we skip over a start or stop without doing it, we still signal the event -// and reset ourselves in case somebody's waiting for the event, and to make -// sure we notice that the event is past and should be forgotten -// Here are the 19 cases that have to be handled (x=start o=stop <-->=sample): -// -// 1. xo<--> start then stop -// 2. ox<--> stop then start -// 3. x start -// 4. o stop then start -// 5. x<-->o start -// 6. o<-->x stop -// 7. o start -// 8. x no change -// 9. start -// 10. stop then start -// 11. <-->xo no change -// 12. <-->ox no change -// 13. x<--> start -// 14. start -// 15. <-->x no change -// 16. o<--> stop -// 17. no change -// 18. <-->o no change -// 19. <--> no change - - -enum CBaseStreamControl::StreamControlState CBaseStreamControl::CheckSampleTimes -( const REFERENCE_TIME * pSampleStart, const REFERENCE_TIME * pSampleStop ) { - CAutoLock lck(&m_CritSec); - - ASSERT(!m_bIsFlushing); - ASSERT(pSampleStart && pSampleStop); - - // Don't ask how I came up with the code below to handle all 19 cases... - if(m_tStopTime >= *pSampleStart) { - if(m_tStartTime >= *pSampleStop) - return m_StreamState; // cases 8 11 12 15 17 18 19 - - if(m_tStopTime < m_tStartTime) - ExecuteStop(); // case 10 - - ExecuteStart(); // cases 3 5 7 9 13 14 - return m_StreamState; - } - - if(m_tStartTime >= *pSampleStop) { - ExecuteStop(); // cases 6 16 - return m_StreamState; - } - - if(m_tStartTime <= m_tStopTime) { - ExecuteStart(); - ExecuteStop(); - } - else { - ExecuteStop(); - ExecuteStart(); - } - - return m_StreamState; // case 1, 2, or 4 -} - - -enum CBaseStreamControl::StreamControlState CBaseStreamControl::CheckStreamState( IMediaSample * pSample ) { - - REFERENCE_TIME rtBufferStart, rtBufferStop; - const BOOL bNoBufferTimes = - pSample == NULL || - FAILED(pSample->GetTime(&rtBufferStart, &rtBufferStop)); - - StreamControlState state; - LONG lWait; - - do { - // something has to break out of the blocking - if(m_bIsFlushing || m_FilterState == State_Stopped) - return STREAM_DISCARDING; - - if(bNoBufferTimes) { - // Can't do anything until we get a time stamp - state = m_StreamState; - break; - } - else { - state = CheckSampleTimes(&rtBufferStart, &rtBufferStop); - if(state == STREAM_FLOWING) - break; - - // we aren't supposed to send this, but we've been - // told to send one more than we were supposed to - // (and the stop isn't still pending and we're streaming) - if(m_bStopSendExtra && !m_bStopExtraSent && - m_tStopTime == MAX_TIME && - m_FilterState != State_Stopped) { - m_bStopExtraSent = TRUE; - DbgLog((LOG_TRACE,2,TEXT("%d sending an EXTRA frame"), - m_dwStopCookie)); - state = STREAM_FLOWING; - break; - } - } - - // We're in discarding mode - - // If we've no clock, discard as fast as we can - if(!m_pRefClock) { - break; - - // If we're paused, we can't discard in a timely manner because - // there's no such thing as stream times. We must block until - // we run or stop, or we'll end up throwing the whole stream away - // as quickly as possible - } - else if(m_FilterState == State_Paused) { - lWait = INFINITE; - - } - else { - // wait until it's time for the sample until we say "discard" - // ("discard in a timely fashion") - REFERENCE_TIME rtNow; - EXECUTE_ASSERT(SUCCEEDED(m_pRefClock->GetTime(&rtNow))); - rtNow -= m_tRunStart; // Into relative ref-time - lWait = LONG((rtBufferStart - rtNow)/10000); // 100ns -> ms - if(lWait < 10) break; // Not worth waiting - discard early - } - - } while(WaitForSingleObject(GetStreamEventHandle(), lWait) != WAIT_TIMEOUT); - - return state; -} - - -void CBaseStreamControl::NotifyFilterState( FILTER_STATE new_state, REFERENCE_TIME tStart ) { - CAutoLock lck(&m_CritSec); - - // or we will get confused - if(m_FilterState == new_state) - return; - - switch(new_state) { - case State_Stopped: - - DbgLog((LOG_TRACE,2,TEXT("Filter is STOPPED"))); - - // execute any pending starts and stops in the right order, - // to make sure all notifications get sent, and we end up - // in the right state to begin next time (??? why not?) - - if(m_tStartTime != MAX_TIME && m_tStopTime == MAX_TIME) { - ExecuteStart(); - } - else if(m_tStopTime != MAX_TIME && m_tStartTime == MAX_TIME) { - ExecuteStop(); - } - else if(m_tStopTime != MAX_TIME && m_tStartTime != MAX_TIME) { - if(m_tStartTime <= m_tStopTime) { - ExecuteStart(); - ExecuteStop(); - } - else { - ExecuteStop(); - ExecuteStart(); - } - } - // always start off flowing when the graph starts streaming - // unless told otherwise - m_StreamState = STREAM_FLOWING; - m_FilterState = new_state; - break; - - case State_Running: - - DbgLog((LOG_TRACE,2,TEXT("Filter is RUNNING"))); - - m_tRunStart = tStart; - // fall-through - - default: // case State_Paused: - m_FilterState = new_state; - } - // unblock! - m_StreamEvent.Set(); -} - - -void CBaseStreamControl::Flushing(BOOL bInProgress) { - CAutoLock lck(&m_CritSec); - m_bIsFlushing = bInProgress; - m_StreamEvent.Set(); -} - diff --git a/src/BaseClasses/strmctl.h b/src/BaseClasses/strmctl.h deleted file mode 100644 index edb4d78380..0000000000 --- a/src/BaseClasses/strmctl.h +++ /dev/null @@ -1,158 +0,0 @@ -//------------------------------------------------------------------------------ -// File: StrmCtl.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1996-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __strmctl_h__ -#define __strmctl_h__ - -class CBaseStreamControl : public IAMStreamControl -{ -public: - // Used by the implementation - enum StreamControlState - { STREAM_FLOWING = 0x1000, - STREAM_DISCARDING - }; - -private: - enum StreamControlState m_StreamState; // Current stream state - enum StreamControlState m_StreamStateOnStop; // State after next stop - // (i.e.Blocking or Discarding) - - REFERENCE_TIME m_tStartTime; // MAX_TIME implies none - REFERENCE_TIME m_tStopTime; // MAX_TIME implies none - DWORD m_dwStartCookie; // Cookie for notification to app - DWORD m_dwStopCookie; // Cookie for notification to app - volatile BOOL m_bIsFlushing; // No optimization pls! - volatile BOOL m_bStopSendExtra; // bSendExtra was set - volatile BOOL m_bStopExtraSent; // the extra one was sent - - CCritSec m_CritSec; // CritSec to guard above attributes - - // Event to fire when we can come - // out of blocking, or to come out of waiting - // to discard if we change our minds. - // - CAMEvent m_StreamEvent; - - // All of these methods execute immediately. Helpers for others. - // - void ExecuteStop(); - void ExecuteStart(); - void CancelStop(); - void CancelStart(); - - // Some things we need to be told by our owning filter - // Your pin must also expose IAMStreamControl when QI'd for it! - // - IReferenceClock * m_pRefClock; // Need it to set advises - // Filter must tell us via - // SetSyncSource - IMediaEventSink * m_pSink; // Event sink - // Filter must tell us after it - // creates it in JoinFilterGraph() - FILTER_STATE m_FilterState; // Just need it! - // Filter must tell us via - // NotifyFilterState - REFERENCE_TIME m_tRunStart; // Per the Run call to the filter - - // This guy will return one of the three StreamControlState's. Here's what - // the caller should do for each one: - // - // STREAM_FLOWING: Proceed as usual (render or pass the sample on) - // STREAM_DISCARDING: Calculate the time 'til *pSampleStop and wait - // that long for the event handle - // (GetStreamEventHandle()). If the wait - // expires, throw the sample away. If the event - // fires, call me back - I've changed my mind. - // - enum StreamControlState CheckSampleTimes( const REFERENCE_TIME * pSampleStart, - const REFERENCE_TIME * pSampleStop ); - -public: - // You don't have to tell us much when we're created, but there are other - // obligations that must be met. See SetSyncSource & NotifyFilterState - // below. - // - CBaseStreamControl(); - ~CBaseStreamControl(); - - // If you want this class to work properly, there are thing you need to - // (keep) telling it. Filters with pins that use this class - // should ensure that they pass through to this method any calls they - // receive on their SetSyncSource. - - // We need a clock to see what time it is. This is for the - // "discard in a timely fashion" logic. If we discard everything as - // quick as possible, a whole 60 minute file could get discarded in the - // first 10 seconds, and if somebody wants to turn streaming on at 30 - // minutes into the file, and they make the call more than a few seconds - // after the graph is run, it may be too late! - // So we hold every sample until it's time has gone, then we discard it. - // The filter should call this when it gets a SetSyncSource - // - void SetSyncSource( IReferenceClock * pRefClock ) - { - CAutoLock lck(&m_CritSec); - if (m_pRefClock) m_pRefClock->Release(); - m_pRefClock = pRefClock; - if (m_pRefClock) - m_pRefClock->AddRef(); - } - - // Set event sink for notifications - // The filter should call this in its JoinFilterGraph after it creates the - // IMediaEventSink - // - void SetFilterGraph( IMediaEventSink *pSink ) { - m_pSink = pSink; - } - - // Since we schedule in stream time, we need the tStart and must track the - // state of our owning filter. - // The app should call this ever state change - // - void NotifyFilterState( FILTER_STATE new_state, REFERENCE_TIME tStart = 0 ); - - // Filter should call Flushing(TRUE) in BeginFlush, - // and Flushing(FALSE) in EndFlush. - // - void Flushing( BOOL bInProgress ); - - - // The two main methods of IAMStreamControl - - // Class adds default values suitable for immediate - // muting and unmuting of the stream. - - STDMETHODIMP StopAt( const REFERENCE_TIME * ptStop = NULL, - BOOL bSendExtra = FALSE, - DWORD dwCookie = 0 ); - STDMETHODIMP StartAt( const REFERENCE_TIME * ptStart = NULL, - DWORD dwCookie = 0 ); - STDMETHODIMP GetInfo( AM_STREAM_INFO *pInfo); - - // Helper function for pin's receive method. Call this with - // the sample and we'll tell you what to do with it. We'll do a - // WaitForSingleObject within this call if one is required. This is - // a "What should I do with this sample?" kind of call. We'll tell the - // caller to either flow it or discard it. - // If pSample is NULL we evaluate based on the current state - // settings - enum StreamControlState CheckStreamState( IMediaSample * pSample ); - -private: - // These don't require locking, but we are relying on the fact that - // m_StreamState can be retrieved with integrity, and is a snap shot that - // may have just been, or may be just about to be, changed. - HANDLE GetStreamEventHandle() const { return m_StreamEvent; } - enum StreamControlState GetStreamState() const { return m_StreamState; } - BOOL IsStreaming() const { return m_StreamState == STREAM_FLOWING; } -}; - -#endif diff --git a/src/BaseClasses/sysclock.cpp b/src/BaseClasses/sysclock.cpp deleted file mode 100644 index b07a2e5cbb..0000000000 --- a/src/BaseClasses/sysclock.cpp +++ /dev/null @@ -1,75 +0,0 @@ -//------------------------------------------------------------------------------ -// File: SysClock.cpp -// -// Desc: DirectShow base classes - implements a system clock based on -// IReferenceClock. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include - -/*NABIL: I changed this*/ -//#ifdef FILTER_DLL - -/* List of class IDs and creator functions for the class factory. This - provides the link between the OLE entry point in the DLL and an object - being created. The class factory will call the static CreateInstance - function when it is asked to create a CLSID_SystemClock object */ - -/*NABIL: This was screwed up....(It didn't have the "blah")*/ -CFactoryTemplate g_Templates[1] = { - { (const WCHAR *) "blah", &CLSID_SystemClock, CSystemClock::CreateInstance } -}; - -int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); -//#endif - -/* This goes in the factory template table to create new instances */ -CUnknown * WINAPI CSystemClock::CreateInstance(LPUNKNOWN pUnk,HRESULT *phr) -{ - return new CSystemClock(NAME("System reference clock"),pUnk, phr); -} - - -CSystemClock::CSystemClock(TCHAR *pName,LPUNKNOWN pUnk,HRESULT *phr) : - CBaseReferenceClock(pName, pUnk, phr) -{ -} - -STDMETHODIMP CSystemClock::NonDelegatingQueryInterface( - REFIID riid, - void ** ppv) -{ - if (riid == IID_IPersist) - { - return GetInterface(static_cast(this), ppv); - } - else if (riid == IID_IAMClockAdjust) - { - return GetInterface(static_cast(this), ppv); - } - else - { - return CBaseReferenceClock::NonDelegatingQueryInterface(riid, ppv); - } -} - -/* Return the clock's clsid */ -STDMETHODIMP -CSystemClock::GetClassID(CLSID *pClsID) -{ - CheckPointer(pClsID,E_POINTER); - ValidateReadWritePtr(pClsID,sizeof(CLSID)); - *pClsID = CLSID_SystemClock; - return NOERROR; -} - - -STDMETHODIMP -CSystemClock::SetClockDelta(REFERENCE_TIME rtDelta) -{ - return SetTimeDelta(rtDelta); -} diff --git a/src/BaseClasses/sysclock.h b/src/BaseClasses/sysclock.h deleted file mode 100644 index 3fe707b740..0000000000 --- a/src/BaseClasses/sysclock.h +++ /dev/null @@ -1,39 +0,0 @@ -//------------------------------------------------------------------------------ -// File: SysClock.h -// -// Desc: DirectShow base classes - defines a system clock implementation of -// IReferenceClock. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __SYSTEMCLOCK__ -#define __SYSTEMCLOCK__ - -// -// Base clock. Uses timeGetTime ONLY -// Uses most of the code in the base reference clock. -// Provides GetTime -// - -class CSystemClock : public CBaseReferenceClock, public IAMClockAdjust, public IPersist -{ -public: - // We must be able to create an instance of ourselves - static CUnknown * WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *phr); - CSystemClock(TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr); - - DECLARE_IUNKNOWN - - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void ** ppv); - - // Yield up our class id so that we can be persisted - // Implement required Ipersist method - STDMETHODIMP GetClassID(CLSID *pClsID); - - // IAMClockAdjust methods - STDMETHODIMP SetClockDelta(REFERENCE_TIME rtDelta); -}; //CSystemClock - -#endif /* __SYSTEMCLOCK__ */ diff --git a/src/BaseClasses/transfrm.cpp b/src/BaseClasses/transfrm.cpp deleted file mode 100644 index 9e328c9e6e..0000000000 --- a/src/BaseClasses/transfrm.cpp +++ /dev/null @@ -1,974 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Transfrm.cpp -// -// Desc: DirectShow base classes - implements class for simple transform -// filters such as video decompressors. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include - - -// ================================================================= -// Implements the CTransformFilter class -// ================================================================= - -CTransformFilter::CTransformFilter(TCHAR *pName, - LPUNKNOWN pUnk, - REFCLSID clsid) : - CBaseFilter(pName,pUnk,&m_csFilter, clsid), - m_pInput(NULL), - m_pOutput(NULL), - m_bEOSDelivered(FALSE), - m_bQualityChanged(FALSE), - m_bSampleSkipped(FALSE) { -#ifdef PERF - RegisterPerfId(); -#endif // PERF -} - -#ifdef UNICODE -CTransformFilter::CTransformFilter(char *pName, - LPUNKNOWN pUnk, - REFCLSID clsid) : - CBaseFilter(pName,pUnk,&m_csFilter, clsid), - m_pInput(NULL), - m_pOutput(NULL), - m_bEOSDelivered(FALSE), - m_bQualityChanged(FALSE), - m_bSampleSkipped(FALSE) { -#ifdef PERF - RegisterPerfId(); -#endif // PERF -} -#endif - -// destructor - -CTransformFilter::~CTransformFilter() { - // Delete the pins - - delete m_pInput; - delete m_pOutput; -} - - -// Transform place holder - should never be called -HRESULT CTransformFilter::Transform(IMediaSample * pIn, IMediaSample *pOut) { - UNREFERENCED_PARAMETER(pIn); - UNREFERENCED_PARAMETER(pOut); - DbgBreak("CTransformFilter::Transform() should never be called"); - return E_UNEXPECTED; -} - - -// return the number of pins we provide - -int CTransformFilter::GetPinCount() { - return 2; -} - - -// return a non-addrefed CBasePin * for the user to addref if he holds onto it -// for longer than his pointer to us. We create the pins dynamically when they -// are asked for rather than in the constructor. This is because we want to -// give the derived class an oppportunity to return different pin objects - -// We return the objects as and when they are needed. If either of these fails -// then we return NULL, the assumption being that the caller will realise the -// whole deal is off and destroy us - which in turn will delete everything. - -CBasePin * -CTransformFilter::GetPin(int n) { - HRESULT hr = S_OK; - - // Create an input pin if necessary - - if(m_pInput == NULL) { - - m_pInput = new CTransformInputPin(NAME("Transform input pin"), - this, // Owner filter - &hr, // Result code - L"XForm In"); // Pin name - - - // Can't fail - ASSERT(SUCCEEDED(hr)); - if(m_pInput == NULL) { - return NULL; - } - m_pOutput = (CTransformOutputPin *) - new CTransformOutputPin(NAME("Transform output pin"), - this, // Owner filter - &hr, // Result code - L"XForm Out"); // Pin name - - - // Can't fail - ASSERT(SUCCEEDED(hr)); - if(m_pOutput == NULL) { - delete m_pInput; - m_pInput = NULL; - } - } - - // Return the appropriate pin - - if(n == 0) { - return m_pInput; - } - else - if(n == 1) { - return m_pOutput; - } - else { - return NULL; - } -} - - -// -// FindPin -// -// If Id is In or Out then return the IPin* for that pin -// creating the pin if need be. Otherwise return NULL with an error. - -STDMETHODIMP CTransformFilter::FindPin(LPCWSTR Id, IPin **ppPin) { - CheckPointer(ppPin,E_POINTER); - ValidateReadWritePtr(ppPin,sizeof(IPin *)); - - if(0==lstrcmpW(Id,L"In")) { - *ppPin = GetPin(0); - } - else if(0==lstrcmpW(Id,L"Out")) { - *ppPin = GetPin(1); - } - else { - *ppPin = NULL; - return VFW_E_NOT_FOUND; - } - - HRESULT hr = NOERROR; - // AddRef() returned pointer - but GetPin could fail if memory is low. - if(*ppPin) { - (*ppPin)->AddRef(); - } - else { - hr = E_OUTOFMEMORY; // probably. There's no pin anyway. - } - return hr; -} - - -// override these two functions if you want to inform something -// about entry to or exit from streaming state. - -HRESULT -CTransformFilter::StartStreaming() { - return NOERROR; -} - - -HRESULT -CTransformFilter::StopStreaming() { - return NOERROR; -} - - -// override this to grab extra interfaces on connection - -HRESULT -CTransformFilter::CheckConnect(PIN_DIRECTION dir,IPin *pPin) { - UNREFERENCED_PARAMETER(dir); - UNREFERENCED_PARAMETER(pPin); - return NOERROR; -} - - -// place holder to allow derived classes to release any extra interfaces - -HRESULT -CTransformFilter::BreakConnect(PIN_DIRECTION dir) { - UNREFERENCED_PARAMETER(dir); - return NOERROR; -} - - -// Let derived classes know about connection completion - -HRESULT -CTransformFilter::CompleteConnect(PIN_DIRECTION direction,IPin *pReceivePin) { - UNREFERENCED_PARAMETER(direction); - UNREFERENCED_PARAMETER(pReceivePin); - return NOERROR; -} - - -// override this to know when the media type is really set - -HRESULT -CTransformFilter::SetMediaType(PIN_DIRECTION direction,const CMediaType *pmt) { - UNREFERENCED_PARAMETER(direction); - UNREFERENCED_PARAMETER(pmt); - return NOERROR; -} - - -// Set up our output sample -HRESULT -CTransformFilter::InitializeOutputSample(IMediaSample *pSample, IMediaSample **ppOutSample) { - IMediaSample *pOutSample; - - // default - times are the same - - AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps(); - DWORD dwFlags = m_bSampleSkipped ? AM_GBF_PREVFRAMESKIPPED : 0; - - // This will prevent the image renderer from switching us to DirectDraw - // when we can't do it without skipping frames because we're not on a - // keyframe. If it really has to switch us, it still will, but then we - // will have to wait for the next keyframe - if(!(pProps->dwSampleFlags & AM_SAMPLE_SPLICEPOINT)) { - dwFlags |= AM_GBF_NOTASYNCPOINT; - } - - ASSERT(m_pOutput->m_pAllocator != NULL); - HRESULT hr = m_pOutput->m_pAllocator->GetBuffer(&pOutSample - , pProps->dwSampleFlags & AM_SAMPLE_TIMEVALID ? - &pProps->tStart : NULL - , pProps->dwSampleFlags & AM_SAMPLE_STOPVALID ? - &pProps->tStop : NULL - , dwFlags); - *ppOutSample = pOutSample; - if(FAILED(hr)) { - return hr; - } - - ASSERT(pOutSample); - IMediaSample2 *pOutSample2; - if(SUCCEEDED(pOutSample->QueryInterface(IID_IMediaSample2, - (void **)&pOutSample2))) { - /* Modify it */ - AM_SAMPLE2_PROPERTIES OutProps; - EXECUTE_ASSERT(SUCCEEDED(pOutSample2->GetProperties(FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, tStart), (PBYTE)&OutProps))); - OutProps.dwTypeSpecificFlags = pProps->dwTypeSpecificFlags; - OutProps.dwSampleFlags = - (OutProps.dwSampleFlags & AM_SAMPLE_TYPECHANGED) | - (pProps->dwSampleFlags & ~AM_SAMPLE_TYPECHANGED); - - OutProps.tStart = pProps->tStart; - OutProps.tStop = pProps->tStop; - OutProps.cbData = FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, dwStreamId); - - hr = pOutSample2->SetProperties(FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, dwStreamId), - (PBYTE)&OutProps); - if(pProps->dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) { - m_bSampleSkipped = FALSE; - } - pOutSample2->Release(); - } - else { - if(pProps->dwSampleFlags & AM_SAMPLE_TIMEVALID) { - pOutSample->SetTime(&pProps->tStart, - &pProps->tStop); - } - if(pProps->dwSampleFlags & AM_SAMPLE_SPLICEPOINT) { - pOutSample->SetSyncPoint(TRUE); - } - if(pProps->dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) { - pOutSample->SetDiscontinuity(TRUE); - m_bSampleSkipped = FALSE; - } - // Copy the media times - - LONGLONG MediaStart, MediaEnd; - if(pSample->GetMediaTime(&MediaStart,&MediaEnd) == NOERROR) { - pOutSample->SetMediaTime(&MediaStart,&MediaEnd); - } - } - return S_OK; -} - -// override this to customize the transform process - -HRESULT -CTransformFilter::Receive(IMediaSample *pSample) { - /* Check for other streams and pass them on */ - AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps(); - if(pProps->dwStreamId != AM_STREAM_MEDIA) { - return m_pOutput->m_pInputPin->Receive(pSample); - } - HRESULT hr; - ASSERT(pSample); - IMediaSample * pOutSample; - - // If no output to deliver to then no point sending us data - - ASSERT(m_pOutput != NULL) ; - - // Set up the output sample - hr = InitializeOutputSample(pSample, &pOutSample); - - if(FAILED(hr)) { - return hr; - } - - // Start timing the transform (if PERF is defined) - MSR_START(m_idTransform); - - // have the derived class transform the data - - hr = Transform(pSample, pOutSample); - - // Stop the clock and log it (if PERF is defined) - MSR_STOP(m_idTransform); - - if(FAILED(hr)) { - DbgLog((LOG_TRACE,1,TEXT("Error from transform"))); - } - else { - // the Transform() function can return S_FALSE to indicate that the - // sample should not be delivered; we only deliver the sample if it's - // really S_OK (same as NOERROR, of course.) - if(hr == NOERROR) { - hr = m_pOutput->m_pInputPin->Receive(pOutSample); - m_bSampleSkipped = FALSE; // last thing no longer dropped - } - else { - // S_FALSE returned from Transform is a PRIVATE agreement - // We should return NOERROR from Receive() in this cause because returning S_FALSE - // from Receive() means that this is the end of the stream and no more data should - // be sent. - if(S_FALSE == hr) { - - // Release the sample before calling notify to avoid - // deadlocks if the sample holds a lock on the system - // such as DirectDraw buffers do - pOutSample->Release(); - m_bSampleSkipped = TRUE; - if(!m_bQualityChanged) { - NotifyEvent(EC_QUALITY_CHANGE,0,0); - m_bQualityChanged = TRUE; - } - return NOERROR; - } - } - } - - // release the output buffer. If the connected pin still needs it, - // it will have addrefed it itself. - pOutSample->Release(); - - return hr; -} - - -// Return S_FALSE to mean "pass the note on upstream" -// Return NOERROR (Same as S_OK) -// to mean "I've done something about it, don't pass it on" -HRESULT CTransformFilter::AlterQuality(Quality q) { - UNREFERENCED_PARAMETER(q); - return S_FALSE; -} - - -// EndOfStream received. Default behaviour is to deliver straight -// downstream, since we have no queued data. If you overrode Receive -// and have queue data, then you need to handle this and deliver EOS after -// all queued data is sent -HRESULT -CTransformFilter::EndOfStream(void) { - HRESULT hr = NOERROR; - if(m_pOutput != NULL) { - hr = m_pOutput->DeliverEndOfStream(); - } - - return hr; -} - - -// enter flush state. Receives already blocked -// must override this if you have queued data or a worker thread -HRESULT -CTransformFilter::BeginFlush(void) { - HRESULT hr = NOERROR; - if(m_pOutput != NULL) { - // block receives -- done by caller (CBaseInputPin::BeginFlush) - - // discard queued data -- we have no queued data - - // free anyone blocked on receive - not possible in this filter - - // call downstream - hr = m_pOutput->DeliverBeginFlush(); - } - return hr; -} - - -// leave flush state. must override this if you have queued data -// or a worker thread -HRESULT -CTransformFilter::EndFlush(void) { - // sync with pushing thread -- we have no worker thread - - // ensure no more data to go downstream -- we have no queued data - - // call EndFlush on downstream pins - ASSERT(m_pOutput != NULL); - return m_pOutput->DeliverEndFlush(); - - // caller (the input pin's method) will unblock Receives -} - - -// override these so that the derived filter can catch them - -STDMETHODIMP -CTransformFilter::Stop() { - CAutoLock lck1(&m_csFilter); - if(m_State == State_Stopped) { - return NOERROR; - } - - // Succeed the Stop if we are not completely connected - - ASSERT(m_pInput == NULL || m_pOutput != NULL); - if(m_pInput == NULL || m_pInput->IsConnected() == FALSE || - m_pOutput->IsConnected() == FALSE) { - m_State = State_Stopped; - m_bEOSDelivered = FALSE; - return NOERROR; - } - - ASSERT(m_pInput); - ASSERT(m_pOutput); - - // decommit the input pin before locking or we can deadlock - m_pInput->Inactive(); - - // synchronize with Receive calls - - CAutoLock lck2(&m_csReceive); - m_pOutput->Inactive(); - - // allow a class derived from CTransformFilter - // to know about starting and stopping streaming - - HRESULT hr = StopStreaming(); - if(SUCCEEDED(hr)) { - // complete the state transition - m_State = State_Stopped; - m_bEOSDelivered = FALSE; - } - return hr; -} - - -STDMETHODIMP -CTransformFilter::Pause() { - CAutoLock lck(&m_csFilter); - HRESULT hr = NOERROR; - - if(m_State == State_Paused) { - // (This space left deliberately blank) - } - - // If we have no input pin or it isn't yet connected then when we are - // asked to pause we deliver an end of stream to the downstream filter. - // This makes sure that it doesn't sit there forever waiting for - // samples which we cannot ever deliver without an input connection. - - else if(m_pInput == NULL || m_pInput->IsConnected() == FALSE) { - if(m_pOutput && m_bEOSDelivered == FALSE) { - m_pOutput->DeliverEndOfStream(); - m_bEOSDelivered = TRUE; - } - m_State = State_Paused; - } - - // We may have an input connection but no output connection - // However, if we have an input pin we do have an output pin - - else if(m_pOutput->IsConnected() == FALSE) { - m_State = State_Paused; - } - else { - if(m_State == State_Stopped) { - // allow a class derived from CTransformFilter - // to know about starting and stopping streaming - CAutoLock lck2(&m_csReceive); - hr = StartStreaming(); - } - if(SUCCEEDED(hr)) { - hr = CBaseFilter::Pause(); - } - } - - m_bSampleSkipped = FALSE; - m_bQualityChanged = FALSE; - return hr; -} - -HRESULT -CTransformFilter::NewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate) { - if(m_pOutput != NULL) { - return m_pOutput->DeliverNewSegment(tStart, tStop, dRate); - } - return S_OK; -} - -// Check streaming status -HRESULT -CTransformInputPin::CheckStreaming() { - ASSERT(m_pTransformFilter->m_pOutput != NULL); - if(!m_pTransformFilter->m_pOutput->IsConnected()) { - return VFW_E_NOT_CONNECTED; - } - else { - // Shouldn't be able to get any data if we're not connected! - ASSERT(IsConnected()); - - // we're flushing - if(m_bFlushing) { - return S_FALSE; - } - // Don't process stuff in Stopped state - if(IsStopped()) { - return VFW_E_WRONG_STATE; - } - if(m_bRunTimeError) { - return VFW_E_RUNTIME_ERROR; - } - return S_OK; - } -} - - -// ================================================================= -// Implements the CTransformInputPin class -// ================================================================= - - -// constructor - -CTransformInputPin::CTransformInputPin( - TCHAR *pObjectName, - CTransformFilter *pTransformFilter, - HRESULT * phr, - LPCWSTR pName) - : CBaseInputPin(pObjectName, pTransformFilter, &pTransformFilter->m_csFilter, phr, pName) { - DbgLog((LOG_TRACE,2,TEXT("CTransformInputPin::CTransformInputPin"))); - m_pTransformFilter = pTransformFilter; -} - -#ifdef UNICODE -CTransformInputPin::CTransformInputPin( - CHAR *pObjectName, - CTransformFilter *pTransformFilter, - HRESULT * phr, - LPCWSTR pName) - : CBaseInputPin(pObjectName, pTransformFilter, &pTransformFilter->m_csFilter, phr, pName) { - DbgLog((LOG_TRACE,2,TEXT("CTransformInputPin::CTransformInputPin"))); - m_pTransformFilter = pTransformFilter; -} -#endif - -// provides derived filter a chance to grab extra interfaces - -HRESULT -CTransformInputPin::CheckConnect(IPin *pPin) { - HRESULT hr = m_pTransformFilter->CheckConnect(PINDIR_INPUT,pPin); - if(FAILED(hr)) { - return hr; - } - return CBaseInputPin::CheckConnect(pPin); -} - - -// provides derived filter a chance to release it's extra interfaces - -HRESULT -CTransformInputPin::BreakConnect() { - // Can't disconnect unless stopped - ASSERT(IsStopped()); - m_pTransformFilter->BreakConnect(PINDIR_INPUT); - return CBaseInputPin::BreakConnect(); -} - - -// Let derived class know when the input pin is connected - -HRESULT -CTransformInputPin::CompleteConnect(IPin *pReceivePin) { - HRESULT hr = m_pTransformFilter->CompleteConnect(PINDIR_INPUT,pReceivePin); - if(FAILED(hr)) { - return hr; - } - return CBaseInputPin::CompleteConnect(pReceivePin); -} - - -// check that we can support a given media type - -HRESULT -CTransformInputPin::CheckMediaType(const CMediaType* pmt) { - // Check the input type - - HRESULT hr = m_pTransformFilter->CheckInputType(pmt); - if(S_OK != hr) { - return hr; - } - - // if the output pin is still connected, then we have - // to check the transform not just the input format - - if((m_pTransformFilter->m_pOutput != NULL) && - (m_pTransformFilter->m_pOutput->IsConnected())) { - return m_pTransformFilter->CheckTransform(pmt, - &m_pTransformFilter->m_pOutput->CurrentMediaType()); - } - else { - return hr; - } -} - - -// set the media type for this connection - -HRESULT -CTransformInputPin::SetMediaType(const CMediaType* mtIn) { - // Set the base class media type (should always succeed) - HRESULT hr = CBasePin::SetMediaType(mtIn); - if(FAILED(hr)) { - return hr; - } - - // check the transform can be done (should always succeed) - ASSERT(SUCCEEDED(m_pTransformFilter->CheckInputType(mtIn))); - - return m_pTransformFilter->SetMediaType(PINDIR_INPUT,mtIn); -} - - -// ================================================================= -// Implements IMemInputPin interface -// ================================================================= - - -// provide EndOfStream that passes straight downstream -// (there is no queued data) -STDMETHODIMP -CTransformInputPin::EndOfStream(void) { - CAutoLock lck(&m_pTransformFilter->m_csReceive); - HRESULT hr = CheckStreaming(); - if(S_OK == hr) { - hr = m_pTransformFilter->EndOfStream(); - } - return hr; -} - - -// enter flushing state. Call default handler to block Receives, then -// pass to overridable method in filter -STDMETHODIMP -CTransformInputPin::BeginFlush(void) { - CAutoLock lck(&m_pTransformFilter->m_csFilter); - // Are we actually doing anything? - ASSERT(m_pTransformFilter->m_pOutput != NULL); - if(!IsConnected() || - !m_pTransformFilter->m_pOutput->IsConnected()) { - return VFW_E_NOT_CONNECTED; - } - HRESULT hr = CBaseInputPin::BeginFlush(); - if(FAILED(hr)) { - return hr; - } - - return m_pTransformFilter->BeginFlush(); -} - - -// leave flushing state. -// Pass to overridable method in filter, then call base class -// to unblock receives (finally) -STDMETHODIMP -CTransformInputPin::EndFlush(void) { - CAutoLock lck(&m_pTransformFilter->m_csFilter); - // Are we actually doing anything? - ASSERT(m_pTransformFilter->m_pOutput != NULL); - if(!IsConnected() || - !m_pTransformFilter->m_pOutput->IsConnected()) { - return VFW_E_NOT_CONNECTED; - } - - HRESULT hr = m_pTransformFilter->EndFlush(); - if(FAILED(hr)) { - return hr; - } - - return CBaseInputPin::EndFlush(); -} - - -// here's the next block of data from the stream. -// AddRef it yourself if you need to hold it beyond the end -// of this call. - -HRESULT -CTransformInputPin::Receive(IMediaSample * pSample) { - HRESULT hr; - CAutoLock lck(&m_pTransformFilter->m_csReceive); - ASSERT(pSample); - - // check all is well with the base class - hr = CBaseInputPin::Receive(pSample); - if(S_OK == hr) { - hr = m_pTransformFilter->Receive(pSample); - } - return hr; -} - - - - -// override to pass downstream -STDMETHODIMP -CTransformInputPin::NewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate) { - // Save the values in the pin - CBasePin::NewSegment(tStart, tStop, dRate); - return m_pTransformFilter->NewSegment(tStart, tStop, dRate); -} - - - - -// ================================================================= -// Implements the CTransformOutputPin class -// ================================================================= - - -// constructor - -CTransformOutputPin::CTransformOutputPin( - TCHAR *pObjectName, - CTransformFilter *pTransformFilter, - HRESULT * phr, - LPCWSTR pPinName) - : CBaseOutputPin(pObjectName, pTransformFilter, &pTransformFilter->m_csFilter, phr, pPinName), - m_pPosition(NULL) { - DbgLog((LOG_TRACE,2,TEXT("CTransformOutputPin::CTransformOutputPin"))); - m_pTransformFilter = pTransformFilter; - -} - -#ifdef UNICODE -CTransformOutputPin::CTransformOutputPin( - CHAR *pObjectName, - CTransformFilter *pTransformFilter, - HRESULT * phr, - LPCWSTR pPinName) - : CBaseOutputPin(pObjectName, pTransformFilter, &pTransformFilter->m_csFilter, phr, pPinName), - m_pPosition(NULL) { - DbgLog((LOG_TRACE,2,TEXT("CTransformOutputPin::CTransformOutputPin"))); - m_pTransformFilter = pTransformFilter; - -} -#endif - -// destructor - -CTransformOutputPin::~CTransformOutputPin() { - DbgLog((LOG_TRACE,2,TEXT("CTransformOutputPin::~CTransformOutputPin"))); - - if(m_pPosition) m_pPosition->Release(); -} - - -// overriden to expose IMediaPosition and IMediaSeeking control interfaces - -STDMETHODIMP -CTransformOutputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv) { - CheckPointer(ppv,E_POINTER); - ValidateReadWritePtr(ppv,sizeof(PVOID)); - *ppv = NULL; - - if(riid == IID_IMediaPosition || riid == IID_IMediaSeeking) { - - // we should have an input pin by now - - ASSERT(m_pTransformFilter->m_pInput != NULL); - - if(m_pPosition == NULL) { - - HRESULT hr = CreatePosPassThru(GetOwner(), - FALSE, - (IPin *)m_pTransformFilter->m_pInput, - &m_pPosition); - if(FAILED(hr)) { - return hr; - } - } - return m_pPosition->QueryInterface(riid, ppv); - } - else { - return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv); - } -} - - -// provides derived filter a chance to grab extra interfaces - -HRESULT -CTransformOutputPin::CheckConnect(IPin *pPin) { - // we should have an input connection first - - ASSERT(m_pTransformFilter->m_pInput != NULL); - if((m_pTransformFilter->m_pInput->IsConnected() == FALSE)) { - return E_UNEXPECTED; - } - - HRESULT hr = m_pTransformFilter->CheckConnect(PINDIR_OUTPUT,pPin); - if(FAILED(hr)) { - return hr; - } - return CBaseOutputPin::CheckConnect(pPin); -} - - -// provides derived filter a chance to release it's extra interfaces - -HRESULT -CTransformOutputPin::BreakConnect() { - // Can't disconnect unless stopped - ASSERT(IsStopped()); - m_pTransformFilter->BreakConnect(PINDIR_OUTPUT); - return CBaseOutputPin::BreakConnect(); -} - - -// Let derived class know when the output pin is connected - -HRESULT -CTransformOutputPin::CompleteConnect(IPin *pReceivePin) { - HRESULT hr = m_pTransformFilter->CompleteConnect(PINDIR_OUTPUT,pReceivePin); - if(FAILED(hr)) { - return hr; - } - return CBaseOutputPin::CompleteConnect(pReceivePin); -} - - -// check a given transform - must have selected input type first - -HRESULT -CTransformOutputPin::CheckMediaType(const CMediaType* pmtOut) { - // must have selected input first - ASSERT(m_pTransformFilter->m_pInput != NULL); - if((m_pTransformFilter->m_pInput->IsConnected() == FALSE)) { - return E_INVALIDARG; - } - - return m_pTransformFilter->CheckTransform(&m_pTransformFilter->m_pInput->CurrentMediaType(), - pmtOut); -} - - -// called after we have agreed a media type to actually set it in which case -// we run the CheckTransform function to get the output format type again - -HRESULT -CTransformOutputPin::SetMediaType(const CMediaType* pmtOut) { - HRESULT hr = NOERROR; - ASSERT(m_pTransformFilter->m_pInput != NULL); - - ASSERT(m_pTransformFilter->m_pInput->CurrentMediaType().IsValid()); - - // Set the base class media type (should always succeed) - hr = CBasePin::SetMediaType(pmtOut); - if(FAILED(hr)) { - return hr; - } - -#ifdef DEBUG - if(FAILED(m_pTransformFilter->CheckTransform(&m_pTransformFilter-> - m_pInput->CurrentMediaType(),pmtOut))) { - DbgLog((LOG_ERROR,0,TEXT("*** This filter is accepting an output media type"))); - DbgLog((LOG_ERROR,0,TEXT(" that it can't currently transform to. I hope"))); - DbgLog((LOG_ERROR,0,TEXT(" it's smart enough to reconnect its input."))); - } -#endif - - return m_pTransformFilter->SetMediaType(PINDIR_OUTPUT,pmtOut); -} - - -// pass the buffer size decision through to the main transform class - -HRESULT -CTransformOutputPin::DecideBufferSize( - IMemAllocator * pAllocator, - ALLOCATOR_PROPERTIES* pProp) { - return m_pTransformFilter->DecideBufferSize(pAllocator, pProp); -} - - - -// return a specific media type indexed by iPosition - -HRESULT -CTransformOutputPin::GetMediaType( - int iPosition, - CMediaType *pMediaType) { - ASSERT(m_pTransformFilter->m_pInput != NULL); - - // We don't have any media types if our input is not connected - - if(m_pTransformFilter->m_pInput->IsConnected()) { - return m_pTransformFilter->GetMediaType(iPosition,pMediaType); - } - else { - return VFW_S_NO_MORE_ITEMS; - } -} - - -// Override this if you can do something constructive to act on the -// quality message. Consider passing it upstream as well - -// Pass the quality mesage on upstream. - -STDMETHODIMP -CTransformOutputPin::Notify(IBaseFilter * pSender, Quality q) { - UNREFERENCED_PARAMETER(pSender); - ValidateReadPtr(pSender,sizeof(IBaseFilter)); - - // First see if we want to handle this ourselves - HRESULT hr = m_pTransformFilter->AlterQuality(q); - if(hr!=S_FALSE) { - return hr; // either S_OK or a failure - } - - // S_FALSE means we pass the message on. - // Find the quality sink for our input pin and send it there - - ASSERT(m_pTransformFilter->m_pInput != NULL); - - return m_pTransformFilter->m_pInput->PassNotify(q); - -} // Notify - - -// the following removes a very large number of level 4 warnings from the microsoft -// compiler output, which are not useful at all in this case. -#pragma warning(disable:4514) - diff --git a/src/BaseClasses/transfrm.h b/src/BaseClasses/transfrm.h deleted file mode 100644 index 15cec3765d..0000000000 --- a/src/BaseClasses/transfrm.h +++ /dev/null @@ -1,304 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Transfrm.h -// -// Desc: DirectShow base classes - defines classes from which simple -// transform codecs may be derived. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// It assumes the codec has one input and one output stream, and has no -// interest in memory management, interface negotiation or anything else. -// -// derive your class from this, and supply Transform and the media type/format -// negotiation functions. Implement that class, compile and link and -// you're done. - - -#ifndef __TRANSFRM__ -#define __TRANSFRM__ - -// ====================================================================== -// This is the com object that represents a simple transform filter. It -// supports IBaseFilter, IMediaFilter and two pins through nested interfaces -// ====================================================================== - -class CTransformFilter; - -// ================================================== -// Implements the input pin -// ================================================== - -class CTransformInputPin : public CBaseInputPin -{ - friend class CTransformFilter; - -protected: - CTransformFilter *m_pTransformFilter; - - -public: - - CTransformInputPin( - TCHAR *pObjectName, - CTransformFilter *pTransformFilter, - HRESULT * phr, - LPCWSTR pName); -#ifdef UNICODE - CTransformInputPin( - char *pObjectName, - CTransformFilter *pTransformFilter, - HRESULT * phr, - LPCWSTR pName); -#endif - - STDMETHODIMP QueryId(LPWSTR * Id) - { - return AMGetWideString(L"In", Id); - } - - // Grab and release extra interfaces if required - - HRESULT CheckConnect(IPin *pPin); - HRESULT BreakConnect(); - HRESULT CompleteConnect(IPin *pReceivePin); - - // check that we can support this output type - HRESULT CheckMediaType(const CMediaType* mtIn); - - // set the connection media type - HRESULT SetMediaType(const CMediaType* mt); - - // --- IMemInputPin ----- - - // here's the next block of data from the stream. - // AddRef it yourself if you need to hold it beyond the end - // of this call. - STDMETHODIMP Receive(IMediaSample * pSample); - - // provide EndOfStream that passes straight downstream - // (there is no queued data) - STDMETHODIMP EndOfStream(void); - - // passes it to CTransformFilter::BeginFlush - STDMETHODIMP BeginFlush(void); - - // passes it to CTransformFilter::EndFlush - STDMETHODIMP EndFlush(void); - - STDMETHODIMP NewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate); - - // Check if it's OK to process samples - virtual HRESULT CheckStreaming(); - - // Media type -public: - CMediaType& CurrentMediaType() { return m_mt; }; - -}; - -// ================================================== -// Implements the output pin -// ================================================== - -class CTransformOutputPin : public CBaseOutputPin -{ - friend class CTransformFilter; - -protected: - CTransformFilter *m_pTransformFilter; - -public: - - // implement IMediaPosition by passing upstream - IUnknown * m_pPosition; - - CTransformOutputPin( - TCHAR *pObjectName, - CTransformFilter *pTransformFilter, - HRESULT * phr, - LPCWSTR pName); -#ifdef UNICODE - CTransformOutputPin( - CHAR *pObjectName, - CTransformFilter *pTransformFilter, - HRESULT * phr, - LPCWSTR pName); -#endif - ~CTransformOutputPin(); - - // override to expose IMediaPosition - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - // --- CBaseOutputPin ------------ - - STDMETHODIMP QueryId(LPWSTR * Id) - { - return AMGetWideString(L"Out", Id); - } - - // Grab and release extra interfaces if required - - HRESULT CheckConnect(IPin *pPin); - HRESULT BreakConnect(); - HRESULT CompleteConnect(IPin *pReceivePin); - - // check that we can support this output type - HRESULT CheckMediaType(const CMediaType* mtOut); - - // set the connection media type - HRESULT SetMediaType(const CMediaType *pmt); - - // called from CBaseOutputPin during connection to ask for - // the count and size of buffers we need. - HRESULT DecideBufferSize( - IMemAllocator * pAlloc, - ALLOCATOR_PROPERTIES *pProp); - - // returns the preferred formats for a pin - HRESULT GetMediaType(int iPosition,CMediaType *pMediaType); - - // inherited from IQualityControl via CBasePin - STDMETHODIMP Notify(IBaseFilter * pSender, Quality q); - - // Media type -public: - CMediaType& CurrentMediaType() { return m_mt; }; -}; - - -class AM_NOVTABLE CTransformFilter : public CBaseFilter -{ - -public: - - // map getpin/getpincount for base enum of pins to owner - // override this to return more specialised pin objects - - virtual int GetPinCount(); - virtual CBasePin * GetPin(int n); - STDMETHODIMP FindPin(LPCWSTR Id, IPin **ppPin); - - // override state changes to allow derived transform filter - // to control streaming start/stop - STDMETHODIMP Stop(); - STDMETHODIMP Pause(); - -public: - - CTransformFilter(TCHAR *, LPUNKNOWN, REFCLSID clsid); -#ifdef UNICODE - CTransformFilter(CHAR *, LPUNKNOWN, REFCLSID clsid); -#endif - ~CTransformFilter(); - - // ================================================================= - // ----- override these bits --------------------------------------- - // ================================================================= - - // These must be supplied in a derived class - - virtual HRESULT Transform(IMediaSample * pIn, IMediaSample *pOut); - - // check if you can support mtIn - virtual HRESULT CheckInputType(const CMediaType* mtIn) PURE; - - // check if you can support the transform from this input to this output - virtual HRESULT CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut) PURE; - - // this goes in the factory template table to create new instances - // static CCOMObject * CreateInstance(LPUNKNOWN, HRESULT *); - - // call the SetProperties function with appropriate arguments - virtual HRESULT DecideBufferSize( - IMemAllocator * pAllocator, - ALLOCATOR_PROPERTIES *pprop) PURE; - - // override to suggest OUTPUT pin media types - virtual HRESULT GetMediaType(int iPosition, CMediaType *pMediaType) PURE; - - - - // ================================================================= - // ----- Optional Override Methods ----------------------- - // ================================================================= - - // you can also override these if you want to know about streaming - virtual HRESULT StartStreaming(); - virtual HRESULT StopStreaming(); - - // override if you can do anything constructive with quality notifications - virtual HRESULT AlterQuality(Quality q); - - // override this to know when the media type is actually set - virtual HRESULT SetMediaType(PIN_DIRECTION direction,const CMediaType *pmt); - - // chance to grab extra interfaces on connection - virtual HRESULT CheckConnect(PIN_DIRECTION dir,IPin *pPin); - virtual HRESULT BreakConnect(PIN_DIRECTION dir); - virtual HRESULT CompleteConnect(PIN_DIRECTION direction,IPin *pReceivePin); - - // chance to customize the transform process - virtual HRESULT Receive(IMediaSample *pSample); - - // Standard setup for output sample - HRESULT InitializeOutputSample(IMediaSample *pSample, IMediaSample **ppOutSample); - - // if you override Receive, you may need to override these three too - virtual HRESULT EndOfStream(void); - virtual HRESULT BeginFlush(void); - virtual HRESULT EndFlush(void); - virtual HRESULT NewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate); - -#ifdef PERF - // Override to register performance measurement with a less generic string - // You should do this to avoid confusion with other filters - virtual void RegisterPerfId() - {m_idTransform = MSR_REGISTER(TEXT("Transform"));} -#endif // PERF - - -// implementation details - -protected: - -#ifdef PERF - int m_idTransform; // performance measuring id -#endif - BOOL m_bEOSDelivered; // have we sent EndOfStream - BOOL m_bSampleSkipped; // Did we just skip a frame - BOOL m_bQualityChanged; // Have we degraded? - - // critical section protecting filter state. - - CCritSec m_csFilter; - - // critical section stopping state changes (ie Stop) while we're - // processing a sample. - // - // This critical section is held when processing - // events that occur on the receive thread - Receive() and EndOfStream(). - // - // If you want to hold both m_csReceive and m_csFilter then grab - // m_csFilter FIRST - like CTransformFilter::Stop() does. - - CCritSec m_csReceive; - - // these hold our input and output pins - - friend class CTransformInputPin; - friend class CTransformOutputPin; - CTransformInputPin *m_pInput; - CTransformOutputPin *m_pOutput; -}; - -#endif /* __TRANSFRM__ */ - - diff --git a/src/BaseClasses/transip.cpp b/src/BaseClasses/transip.cpp deleted file mode 100644 index 3e87572891..0000000000 --- a/src/BaseClasses/transip.cpp +++ /dev/null @@ -1,922 +0,0 @@ -//------------------------------------------------------------------------------ -// File: TransIP.cpp -// -// Desc: DirectShow base classes - implements class for simple Transform- -// In-Place filters such as audio. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// How allocators are decided. -// -// An in-place transform tries to do its work in someone else's buffers. -// It tries to persuade the filters on either side to use the same allocator -// (and for that matter the same media type). In desperation, if the downstream -// filter refuses to supply an allocator and the upstream filter offers only -// a read-only one then it will provide an allocator. -// if the upstream filter insists on a read-only allocator then the transform -// filter will (reluctantly) copy the data before transforming it. -// -// In order to pass an allocator through it needs to remember the one it got -// from the first connection to pass it on to the second one. -// -// It is good if we can avoid insisting on a particular order of connection -// (There is a precedent for insisting on the input -// being connected first. Insisting on the output being connected first is -// not allowed. That would break RenderFile.) -// -// The base pin classes (CBaseOutputPin and CBaseInputPin) both have a -// m_pAllocator member which is used in places like -// CBaseOutputPin::GetDeliveryBuffer and CBaseInputPin::Inactive. -// To avoid lots of extra overriding, we should keep these happy -// by using these pointers. -// -// When each pin is connected, it will set the corresponding m_pAllocator -// and will have a single ref-count on that allocator. -// -// Refcounts are acquired by GetAllocator calls which return AddReffed -// allocators and are released in one of: -// CBaseInputPin::Disconnect -// CBaseOutputPin::BreakConect -// In each case m_pAllocator is set to NULL after the release, so this -// is the last chance to ever release it. If there should ever be -// multiple refcounts associated with the same pointer, this had better -// be cleared up before that happens. To avoid such problems, we'll -// stick with one per pointer. - - - -// RECONNECTING and STATE CHANGES -// -// Each pin could be disconnected, connected with a read-only allocator, -// connected with an upstream read/write allocator, connected with an -// allocator from downstream or connected with its own allocator. -// Five states for each pin gives a data space of 25 states. -// -// Notation: -// -// R/W == read/write -// R-O == read-only -// -// -// -// 00 means an unconnected pin. -// <- means using a R/W allocator from the upstream filter -// <= means using a R-O allocator from an upstream filter -// || means using our own (R/W) allocator. -// -> means using a R/W allocator from a downstream filter -// (a R-O allocator from downstream is nonsense, it can't ever work). -// -// -// That makes 25 possible states. Some states are nonsense (two different -// allocators from the same place). These are just an artifact of the notation. -// <= <- Nonsense. -// <- <= Nonsense -// Some states are illegal (the output pin never accepts a R-O allocator): -// 00 <= !! Error !! -// <= <= !! Error !! -// || <= !! Error !! -// -> <= !! Error !! -// Three states appears to be inaccessible: -// -> || Inaccessible -// || -> Inaccessible -// || <- Inaccessible -// Some states only ever occur as intermediates with a pending reconnect which -// is guaranteed to finish in another state. -// -> 00 ?? unstable goes to || 00 -// 00 <- ?? unstable goes to 00 || -// -> <- ?? unstable goes to -> -> -// <- || ?? unstable goes to <- <- -// <- -> ?? unstable goes to <- <- -// And that leaves 11 possible resting states: -// 1 00 00 Nothing connected. -// 2 <- 00 Input pin connected. -// 3 <= 00 Input pin connected using R-O allocator. -// 4 || 00 Needs several state changes to get here. -// 5 00 || Output pin connected using our allocator -// 6 00 -> Downstream only connected -// 7 || || Undesirable but can be forced upon us. -// 8 <= || Copy forced. <= -> is preferable -// 9 <= -> OK - forced to copy. -// 10 <- <- Transform in place (ideal) -// 11 -> -> Transform in place (ideal) -// -// The object of the exercise is to ensure that we finish up in states -// 10 or 11 whenever possible. State 10 is only possible if the upstream -// filter has a R/W allocator (the AVI splitter notoriously -// doesn't) and state 11 is only possible if the downstream filter does -// offer an allocator. -// -// The transition table (entries marked * go via a reconnect) -// -// There are 8 possible transitions: -// A: Connect upstream to filter with R-O allocator that insists on using it. -// B: Connect upstream to filter with R-O allocator but chooses not to use it. -// C: Connect upstream to filter with R/W allocator and insists on using it. -// D: Connect upstream to filter with R/W allocator but chooses not to use it. -// E: Connect downstream to a filter that offers an allocator -// F: Connect downstream to a filter that does not offer an allocator -// G: disconnect upstream -// H: Disconnect downstream -// -// A B C D E F G H -// --------------------------------------------------------- -// 00 00 1 | 3 3 2 2 6 5 . . |1 00 00 -// <- 00 2 | . . . . *10/11 10 1 . |2 <- 00 -// <= 00 3 | . . . . *9/11 *7/8 1 . |3 <= 00 -// || 00 4 | . . . . *8 *7 1 . |4 || 00 -// 00 || 5 | 8 7 *10 7 . . . 1 |5 00 || -// 00 -> 6 | 9 11 *10 11 . . . 1 |6 00 -> -// || || 7 | . . . . . . 5 4 |7 || || -// <= || 8 | . . . . . . 5 3 |8 <= || -// <= -> 9 | . . . . . . 6 3 |9 <= -> -// <- <- 10| . . . . . . *5/6 2 |10 <- <- -// -> -> 11| . . . . . . 6 *2/3 |11 -> -> -// --------------------------------------------------------- -// A B C D E F G H -// -// All these states are accessible without requiring any filter to -// change its behaviour but not all transitions are accessible, for -// instance a transition from state 4 to anywhere other than -// state 8 requires that the upstream filter first offer a R-O allocator -// and then changes its mind and offer R/W. This is NOT allowable - it -// leads to things like the output pin getting a R/W allocator from -// upstream and then the input pin being told it can only have a R-O one. -// Note that you CAN change (say) the upstream filter for a different one, but -// only as a disconnect / connect, not as a Reconnect. (Exercise for -// the reader is to see how you get into state 4). -// -// The reconnection stuff goes as follows (some of the cases shown here as -// "no reconnect" may get one to finalise media type - an old story). -// If there is a reconnect where it says "no reconnect" here then the -// reconnection must not change the allocator choice. -// -// state 2: <- 00 transition E <- <- case C <- <- (no change) -// case D -> <- and then to -> -> -// -// state 2: <- 00 transition F <- <- (no reconnect) -// -// state 3: <= 00 transition E <= -> case A <= -> (no change) -// case B -> -> -// transition F <= || case A <= || (no change) -// case B || || -// -// state 4: || 00 transition E || || case B -> || and then all cases to -> -> -// F || || case B || || (no change) -// -// state 5: 00 || transition A <= || (no reconnect) -// B || || (no reconnect) -// C <- || all cases <- <- -// D || || (unfortunate, but upstream's choice) -// -// state 6: 00 -> transition A <= -> (no reconnect) -// B -> -> (no reconnect) -// C <- -> all cases <- <- -// D -> -> (no reconnect) -// -// state 10:<- <- transition G 00 <- case E 00 -> -// case F 00 || -// -// state 11:-> -> transition H -> 00 case A <= 00 (schizo) -// case B <= 00 -// case C <- 00 (schizo) -// case D <- 00 -// -// The Rules: -// To sort out media types: -// The input is reconnected -// if the input pin is connected and the output pin connects -// The output is reconnected -// If the output pin is connected -// and the input pin connects to a different media type -// -// To sort out allocators: -// The input is reconnected -// if the output disconnects and the input was using a downstream allocator -// The output pin calls SetAllocator to pass on a new allocator -// if the output is connected and -// if the input disconnects and the output was using an upstream allocator -// if the input acquires an allocator different from the output one -// and that new allocator is not R-O -// -// Data is copied (i.e. call getbuffer and copy the data before transforming it) -// if the two allocators are different. - - - -// CHAINS of filters: -// -// We sit between two filters (call them A and Z). We should finish up -// with the same allocator on both of our pins and that should be the -// same one that A and Z would have agreed on if we hadn't been in the -// way. Furthermore, it should not matter how many in-place transforms -// are in the way. Let B, C, D... be in-place transforms ("us"). -// Here's how it goes: -// -// 1. -// A connects to B. They agree on A's allocator. -// A-a->B -// -// 2. -// B connects to C. Same story. There is no point in a reconnect, but -// B will request an input reconnect anyway. -// A-a->B-a->C -// -// 3. -// C connects to Z. -// C insists on using A's allocator, but compromises by requesting a reconnect. -// of C's input. -// A-a->B-?->C-a->Z -// -// We now have pending reconnects on both A--->B and B--->C -// -// 4. -// The A--->B link is reconnected. -// A asks B for an allocator. B sees that it has a downstream connection so -// asks its downstream input pin i.e. C's input pin for an allocator. C sees -// that it too has a downstream connection so asks Z for an allocator. -// -// Even though Z's input pin is connected, it is being asked for an allocator. -// It could refuse, in which case the chain is done and will use A's allocator -// Alternatively, Z may supply one. A chooses either Z's or A's own one. -// B's input pin gets NotifyAllocator called to tell it the decision and it -// propagates this downstream by calling ReceiveAllocator on its output pin -// which calls NotifyAllocator on the next input pin downstream etc. -// If the choice is Z then it goes: -// A-z->B-a->C-a->Z -// A-z->B-z->C-a->Z -// A-z->B-z->C-z->Z -// -// And that's IT!! Any further (essentially spurious) reconnects peter out -// with no change in the chain. - -#include -#include -#include - - -// ================================================================= -// Implements the CTransInPlaceFilter class -// ================================================================= - -CTransInPlaceFilter::CTransInPlaceFilter - ( TCHAR *pName, - LPUNKNOWN pUnk, - REFCLSID clsid, - HRESULT *phr, - bool bModifiesData - ) - : CTransformFilter(pName, pUnk, clsid), - m_bModifiesData(bModifiesData) { -#ifdef PERF - RegisterPerfId(); -#endif // PERF - -} // constructor - -#ifdef UNICODE -CTransInPlaceFilter::CTransInPlaceFilter - ( CHAR *pName, - LPUNKNOWN pUnk, - REFCLSID clsid, - HRESULT *phr, - bool bModifiesData - ) - : CTransformFilter(pName, pUnk, clsid), - m_bModifiesData(bModifiesData) { -#ifdef PERF - RegisterPerfId(); -#endif // PERF - -} // constructor -#endif - -// return a non-addrefed CBasePin * for the user to addref if he holds onto it -// for longer than his pointer to us. We create the pins dynamically when they -// are asked for rather than in the constructor. This is because we want to -// give the derived class an oppportunity to return different pin objects - -// As soon as any pin is needed we create both (this is different from the -// usual transform filter) because enumerators, allocators etc are passed -// through from one pin to another and it becomes very painful if the other -// pin isn't there. If we fail to create either pin we ensure we fail both. - -CBasePin * -CTransInPlaceFilter::GetPin(int n) { - HRESULT hr = S_OK; - - // Create an input pin if not already done - - if(m_pInput == NULL) { - - m_pInput = new CTransInPlaceInputPin(NAME("TransInPlace input pin") - , this // Owner filter - , &hr // Result code - , L"Input" // Pin name - ); - - // Constructor for CTransInPlaceInputPin can't fail - ASSERT(SUCCEEDED(hr)); - } - - // Create an output pin if not already done - - if(m_pInput!=NULL && m_pOutput == NULL) { - - m_pOutput = new CTransInPlaceOutputPin(NAME("TransInPlace output pin") - , this // Owner filter - , &hr // Result code - , L"Output" // Pin name - ); - - // a failed return code should delete the object - - ASSERT(SUCCEEDED(hr)); - if(m_pOutput == NULL) { - delete m_pInput; - m_pInput = NULL; - } - } - - // Return the appropriate pin - - ASSERT(n>=0 && n<=1); - if(n == 0) { - return m_pInput; - } - else if(n==1) { - return m_pOutput; - } - else { - return NULL; - } - -} // GetPin - - - -// dir is the direction of our pin. -// pReceivePin is the pin we are connecting to. -HRESULT CTransInPlaceFilter::CompleteConnect(PIN_DIRECTION dir,IPin *pReceivePin) { - UNREFERENCED_PARAMETER(pReceivePin); - ASSERT(m_pInput); - ASSERT(m_pOutput); - - // if we are not part of a graph, then don't indirect the pointer - // this probably prevents use of the filter without a filtergraph - if(!m_pGraph) { - return VFW_E_NOT_IN_GRAPH; - } - - // Always reconnect the input to account for buffering changes - // - // Because we don't get to suggest a type on ReceiveConnection - // we need another way of making sure the right type gets used. - // - // One way would be to have our EnumMediaTypes return our output - // connection type first but more deterministic and simple is to - // call ReconnectEx passing the type we want to reconnect with - // via the base class ReconeectPin method. - - if(dir == PINDIR_OUTPUT) { - if(m_pInput->IsConnected()) { - return ReconnectPin(m_pInput, &m_pOutput->CurrentMediaType()); - } - return NOERROR; - } - - ASSERT(dir == PINDIR_INPUT); - - // Reconnect output if necessary - - if(m_pOutput->IsConnected()) { - - if(m_pInput->CurrentMediaType() - != m_pOutput->CurrentMediaType()) { - return ReconnectPin(m_pOutput, &m_pInput->CurrentMediaType()); - } - } - return NOERROR; - -} // ComnpleteConnect - - -// -// DecideBufferSize -// -// Tell the output pin's allocator what size buffers we require. -// *pAlloc will be the allocator our output pin is using. -// - -HRESULT CTransInPlaceFilter::DecideBufferSize - ( IMemAllocator *pAlloc - , ALLOCATOR_PROPERTIES *pProperties - ) { - ALLOCATOR_PROPERTIES Request, Actual; - HRESULT hr; - - // If we are connected upstream, get his views - if(m_pInput->IsConnected()) { - // Get the input pin allocator, and get its size and count. - // we don't care about his alignment and prefix. - - hr = InputPin()->PeekAllocator()->GetProperties(&Request); - if(FAILED(hr)) { - // Input connected but with a secretive allocator - enough! - return hr; - } - } - else { - // We're reduced to blind guessing. Let's guess one byte and if - // this isn't enough then when the other pin does get connected - // we can revise it. - ZeroMemory(&Request, sizeof(Request)); - Request.cBuffers = 1; - Request.cbBuffer = 1; - } - - - DbgLog((LOG_MEMORY,1,TEXT("Setting Allocator Requirements"))); - DbgLog((LOG_MEMORY,1,TEXT("Count %d, Size %d"), - Request.cBuffers, Request.cbBuffer)); - - // Pass the allocator requirements to our output side - // but do a little sanity checking first or we'll just hit - // asserts in the allocator. - - pProperties->cBuffers = Request.cBuffers; - pProperties->cbBuffer = Request.cbBuffer; - if(pProperties->cBuffers<=0) {pProperties->cBuffers = 1; - } - if(pProperties->cbBuffer<=0) {pProperties->cbBuffer = 1; - } - hr = pAlloc->SetProperties(pProperties, &Actual); - - if(FAILED(hr)) { - return hr; - } - - DbgLog((LOG_MEMORY,1,TEXT("Obtained Allocator Requirements"))); - DbgLog((LOG_MEMORY,1,TEXT("Count %d, Size %d, Alignment %d"), - Actual.cBuffers, Actual.cbBuffer, Actual.cbAlign)); - - // Make sure we got the right alignment and at least the minimum required - - if((Request.cBuffers > Actual.cBuffers) - || (Request.cbBuffer > Actual.cbBuffer) - || (Request.cbAlign > Actual.cbAlign)) { - return E_FAIL; - } - return NOERROR; - -} // DecideBufferSize - -// -// Copy -// -// return a pointer to an identical copy of pSample -IMediaSample * CTransInPlaceFilter::Copy(IMediaSample *pSource) { - IMediaSample * pDest; - - HRESULT hr; - REFERENCE_TIME tStart, tStop; - const BOOL bTime = S_OK == pSource->GetTime(&tStart, &tStop); - - // this may block for an indeterminate amount of time - hr = OutputPin()->PeekAllocator()->GetBuffer(&pDest - , bTime ? &tStart : NULL - , bTime ? &tStop : NULL - , m_bSampleSkipped ? AM_GBF_PREVFRAMESKIPPED : 0); - - if(FAILED(hr)) { - return NULL; - } - - ASSERT(pDest); - IMediaSample2 *pSample2; - if(SUCCEEDED(pDest->QueryInterface(IID_IMediaSample2, (void **)&pSample2))) { - HRESULT hr = pSample2->SetProperties(FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, pbBuffer), - (PBYTE)m_pInput->SampleProps()); - pSample2->Release(); - if(FAILED(hr)) { - pDest->Release(); - return NULL; - } - } - else { - if(bTime) { - pDest->SetTime(&tStart, &tStop); - } - - if(S_OK == pSource->IsSyncPoint()) { - pDest->SetSyncPoint(TRUE); - } - if(S_OK == pSource->IsDiscontinuity() || m_bSampleSkipped) { - pDest->SetDiscontinuity(TRUE); - } - if(S_OK == pSource->IsPreroll()) { - pDest->SetPreroll(TRUE); - } - - // Copy the media type - AM_MEDIA_TYPE *pMediaType; - if(S_OK == pSource->GetMediaType(&pMediaType)) { - pDest->SetMediaType(pMediaType); - DeleteMediaType(pMediaType); - } - - } - - m_bSampleSkipped = FALSE; - - // Copy the sample media times - REFERENCE_TIME TimeStart, TimeEnd; - if(pSource->GetMediaTime(&TimeStart,&TimeEnd) == NOERROR) { - pDest->SetMediaTime(&TimeStart,&TimeEnd); - } - - // Copy the actual data length and the actual data. - { - const long lDataLength = pSource->GetActualDataLength(); - pDest->SetActualDataLength(lDataLength); - - // Copy the sample data - { - BYTE *pSourceBuffer, *pDestBuffer; - long lSourceSize = pSource->GetSize(); - long lDestSize = pDest->GetSize(); - - ASSERT(lDestSize >= lSourceSize && lDestSize >= lDataLength); - - pSource->GetPointer(&pSourceBuffer); - pDest->GetPointer(&pDestBuffer); - ASSERT(lDestSize == 0 || pSourceBuffer != NULL && pDestBuffer != NULL); - - CopyMemory((PVOID) pDestBuffer, (PVOID) pSourceBuffer, lDataLength); - } - } - - return pDest; - -} // Copy - - -// override this to customize the transform process - -HRESULT -CTransInPlaceFilter::Receive(IMediaSample *pSample) { - /* Check for other streams and pass them on */ - AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps(); - if(pProps->dwStreamId != AM_STREAM_MEDIA) { - return m_pOutput->Deliver(pSample); - } - HRESULT hr; - - // Start timing the TransInPlace (if PERF is defined) - MSR_START(m_idTransInPlace); - - if(UsingDifferentAllocators()) { - - // We have to copy the data. - - pSample = Copy(pSample); - - if(pSample==NULL) { - MSR_STOP(m_idTransInPlace); - return E_UNEXPECTED; - } - } - - // have the derived class transform the data - hr = Transform(pSample); - - // Stop the clock and log it (if PERF is defined) - MSR_STOP(m_idTransInPlace); - - if(FAILED(hr)) { - DbgLog((LOG_TRACE, 1, TEXT("Error from TransInPlace"))); - if(UsingDifferentAllocators()) { - pSample->Release(); - } - return hr; - } - - // the Transform() function can return S_FALSE to indicate that the - // sample should not be delivered; we only deliver the sample if it's - // really S_OK (same as NOERROR, of course.) - if(hr == NOERROR) { - hr = m_pOutput->Deliver(pSample); - } - else { - // But it would be an error to return this private workaround - // to the caller ... - if(S_FALSE == hr) { - // S_FALSE returned from Transform is a PRIVATE agreement - // We should return NOERROR from Receive() in this cause because - // returning S_FALSE from Receive() means that this is the end - // of the stream and no more data should be sent. - m_bSampleSkipped = TRUE; - if(!m_bQualityChanged) { - NotifyEvent(EC_QUALITY_CHANGE,0,0); - m_bQualityChanged = TRUE; - } - hr = NOERROR; - } - } - - // release the output buffer. If the connected pin still needs it, - // it will have addrefed it itself. - if(UsingDifferentAllocators()) { - pSample->Release(); - } - - return hr; - -} // Receive - - - -// ================================================================= -// Implements the CTransInPlaceInputPin class -// ================================================================= - - -// constructor - -CTransInPlaceInputPin::CTransInPlaceInputPin - ( TCHAR *pObjectName - , CTransInPlaceFilter *pFilter - , HRESULT *phr - , LPCWSTR pName - ) - : CTransformInputPin(pObjectName, - pFilter, - phr, - pName) - , m_bReadOnly(FALSE) - , m_pTIPFilter(pFilter) { - - DbgLog((LOG_TRACE, 2 - , TEXT("CTransInPlaceInputPin::CTransInPlaceInputPin"))); - -} // constructor - - -// ================================================================= -// Implements IMemInputPin interface -// ================================================================= - - -// If the downstream filter has one then offer that (even if our own output -// pin is not using it yet. If the upstream filter chooses it then we will -// tell our output pin to ReceiveAllocator). -// Else if our output pin is using an allocator then offer that. -// ( This could mean offering the upstream filter his own allocator, -// it could mean offerring our own -// ) or it could mean offering the one from downstream -// Else fail to offer any allocator at all. - -STDMETHODIMP CTransInPlaceInputPin::GetAllocator(IMemAllocator ** ppAllocator) { - CheckPointer(ppAllocator,E_POINTER); - ValidateReadWritePtr(ppAllocator,sizeof(IMemAllocator *)); - CAutoLock cObjectLock(m_pLock); - - HRESULT hr; - - if(m_pTIPFilter->m_pOutput->IsConnected()) { - // Store the allocator we got - hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin() - ->GetAllocator(ppAllocator); - if(SUCCEEDED(hr)) { - m_pTIPFilter->OutputPin()->SetAllocator(*ppAllocator); - } - } - else { - // Help upstream filter (eg TIP filter which is having to do a copy) - // by providing a temp allocator here - we'll never use - // this allocator because when our output is connected we'll - // reconnect this pin - hr = CTransformInputPin::GetAllocator(ppAllocator); - } - return hr; - -} // GetAllocator - - - -/* Get told which allocator the upstream output pin is actually going to use */ - - -STDMETHODIMP -CTransInPlaceInputPin::NotifyAllocator( - IMemAllocator * pAllocator, - BOOL bReadOnly) { - HRESULT hr = S_OK; - CheckPointer(pAllocator,E_POINTER); - ValidateReadPtr(pAllocator,sizeof(IMemAllocator)); - - CAutoLock cObjectLock(m_pLock); - - m_bReadOnly = bReadOnly; - // If we modify data then don't accept the allocator if it's - // the same as the output pin's allocator - - // If our output is not connected just accept the allocator - // We're never going to use this allocator because when our - // output pin is connected we'll reconnect this pin - if(!m_pTIPFilter->OutputPin()->IsConnected()) { - return CTransformInputPin::NotifyAllocator(pAllocator, bReadOnly); - } - - // If the allocator is read-only and we're modifying data - // and the allocator is the same as the output pin's - // then reject - if(bReadOnly && m_pTIPFilter->m_bModifiesData) { - IMemAllocator *pOutputAllocator = - m_pTIPFilter->OutputPin()->PeekAllocator(); - - // Make sure we have an output allocator - if(pOutputAllocator == NULL) { - hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin()-> - GetAllocator(&pOutputAllocator); - if(FAILED(hr)) { - hr = CreateMemoryAllocator(&pOutputAllocator); - } - if(SUCCEEDED(hr)) { - m_pTIPFilter->OutputPin()->SetAllocator(pOutputAllocator); - pOutputAllocator->Release(); - } - } - if(pAllocator == pOutputAllocator) { - hr = E_FAIL; - } - else if(SUCCEEDED(hr)) { - // Must copy so set the allocator properties on the output - ALLOCATOR_PROPERTIES Props, Actual={0}; - hr = pAllocator->GetProperties(&Props); - if(SUCCEEDED(hr)) { - hr = pOutputAllocator->SetProperties(&Props, &Actual); - } - if(SUCCEEDED(hr)) { - if((Props.cBuffers > Actual.cBuffers) - || (Props.cbBuffer > Actual.cbBuffer) - || (Props.cbAlign > Actual.cbAlign)) { - hr = E_FAIL; - } - } - - // Set the allocator on the output pin - if(SUCCEEDED(hr)) { - hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin() - ->NotifyAllocator(pOutputAllocator, FALSE); - } - } - } - else { - hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin() - ->NotifyAllocator(pAllocator, bReadOnly); - if(SUCCEEDED(hr)) { - m_pTIPFilter->OutputPin()->SetAllocator(pAllocator); - } - } - - if(SUCCEEDED(hr)) { - - // It's possible that the old and the new are the same thing. - // AddRef before release ensures that we don't unload it. - pAllocator->AddRef(); - - if(m_pAllocator != NULL) - m_pAllocator->Release(); - - m_pAllocator = pAllocator; // We have an allocator for the input pin - } - - return hr; - -} // NotifyAllocator - - -// EnumMediaTypes -// - pass through to our downstream filter -STDMETHODIMP CTransInPlaceInputPin::EnumMediaTypes( IEnumMediaTypes **ppEnum ) { - // Can only pass through if connected - if(!m_pTIPFilter->m_pOutput->IsConnected()) - return VFW_E_NOT_CONNECTED; - - return m_pTIPFilter->m_pOutput->GetConnected()->EnumMediaTypes(ppEnum); - -} // EnumMediaTypes - - -// CheckMediaType -// - agree to anything if not connected, -// otherwise pass through to the downstream filter. -// This assumes that the filter does not change the media type. - -HRESULT CTransInPlaceInputPin::CheckMediaType(const CMediaType *pmt ) { - HRESULT hr = m_pTIPFilter->CheckInputType(pmt); - if(hr!=S_OK) return hr; - - if(m_pTIPFilter->m_pOutput->IsConnected()) - return m_pTIPFilter->m_pOutput->GetConnected()->QueryAccept(pmt); - else - return S_OK; - -} // CheckMediaType - - -// If upstream asks us what our requirements are, we will try to ask downstream -// if that doesn't work, we'll just take the defaults. -STDMETHODIMP -CTransInPlaceInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps) { - - if(m_pTIPFilter->m_pOutput->IsConnected()) - return m_pTIPFilter->OutputPin() - ->ConnectedIMemInputPin()->GetAllocatorRequirements(pProps); - else - return E_NOTIMPL; - -} // GetAllocatorRequirements - - - -// ================================================================= -// Implements the CTransInPlaceOutputPin class -// ================================================================= - - -// constructor - -CTransInPlaceOutputPin::CTransInPlaceOutputPin( - TCHAR *pObjectName, - CTransInPlaceFilter *pFilter, - HRESULT * phr, - LPCWSTR pPinName) - : CTransformOutputPin( pObjectName - , pFilter - , phr - , pPinName), - m_pTIPFilter(pFilter) { - - DbgLog(( LOG_TRACE, 2 - , TEXT("CTransInPlaceOutputPin::CTransInPlaceOutputPin"))); - -} // constructor - - -// EnumMediaTypes -// - pass through to our upstream filter -STDMETHODIMP CTransInPlaceOutputPin::EnumMediaTypes( IEnumMediaTypes **ppEnum ) { - // Can only pass through if connected. - if(! m_pTIPFilter->m_pInput->IsConnected()) - return VFW_E_NOT_CONNECTED; - - return m_pTIPFilter->m_pInput->GetConnected()->EnumMediaTypes(ppEnum); - -} // EnumMediaTypes - - - -// CheckMediaType -// - agree to anything if not connected, -// otherwise pass through to the upstream filter. - -HRESULT CTransInPlaceOutputPin::CheckMediaType(const CMediaType *pmt ) { - // Don't accept any output pin type changes if we're copying - // between allocators - it's too late to change the input - // allocator size. - if(m_pTIPFilter->UsingDifferentAllocators() && !m_pFilter->IsStopped()) { - if(*pmt == m_mt) { - return S_OK; - } - else { - return VFW_E_TYPE_NOT_ACCEPTED; - } - } - - // Assumes the type does not change. That's why we're calling - // CheckINPUTType here on the OUTPUT pin. - HRESULT hr = m_pTIPFilter->CheckInputType(pmt); - if(hr!=S_OK) - return hr; - - if(m_pTIPFilter->m_pInput->IsConnected()) - return m_pTIPFilter->m_pInput->GetConnected()->QueryAccept(pmt); - else - return S_OK; - -} //CheckMediaType - - -/* Save the allocator pointer in the output pin -*/ -void -CTransInPlaceOutputPin::SetAllocator(IMemAllocator * pAllocator) { - pAllocator->AddRef(); - if(m_pAllocator) { - m_pAllocator->Release(); - } - m_pAllocator = pAllocator; -} // receiveAllocator diff --git a/src/BaseClasses/transip.h b/src/BaseClasses/transip.h deleted file mode 100644 index f36a1c4295..0000000000 --- a/src/BaseClasses/transip.h +++ /dev/null @@ -1,246 +0,0 @@ -//------------------------------------------------------------------------------ -// File: TransIP.h -// -// Desc: DirectShow base classes - defines classes from which simple -// Transform-In-Place filters may be derived. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// -// The difference between this and Transfrm.h is that Transfrm copies the data. -// -// It assumes the filter has one input and one output stream, and has no -// interest in memory management, interface negotiation or anything else. -// -// Derive your class from this, and supply Transform and the media type/format -// negotiation functions. Implement that class, compile and link and -// you're done. - - -#ifndef __TRANSIP__ -#define __TRANSIP__ - -// ====================================================================== -// This is the com object that represents a simple transform filter. It -// supports IBaseFilter, IMediaFilter and two pins through nested interfaces -// ====================================================================== - -class CTransInPlaceFilter; - -// Several of the pin functions call filter functions to do the work, -// so you can often use the pin classes unaltered, just overriding the -// functions in CTransInPlaceFilter. If that's not enough and you want -// to derive your own pin class, override GetPin in the filter to supply -// your own pin classes to the filter. - -// ================================================== -// Implements the input pin -// ================================================== - -class CTransInPlaceInputPin : public CTransformInputPin -{ - -protected: - CTransInPlaceFilter * const m_pTIPFilter; // our filter - BOOL m_bReadOnly; // incoming stream is read only - -public: - - CTransInPlaceInputPin( - TCHAR *pObjectName, - CTransInPlaceFilter *pFilter, - HRESULT *phr, - LPCWSTR pName); - - // --- IMemInputPin ----- - - // Provide an enumerator for media types by getting one from downstream - STDMETHODIMP EnumMediaTypes( IEnumMediaTypes **ppEnum ); - - // Say whether media type is acceptable. - HRESULT CheckMediaType(const CMediaType* pmt); - - // Return our upstream allocator - STDMETHODIMP GetAllocator(IMemAllocator ** ppAllocator); - - // get told which allocator the upstream output pin is actually - // going to use. - STDMETHODIMP NotifyAllocator(IMemAllocator * pAllocator, - BOOL bReadOnly); - - // Allow the filter to see what allocator we have - // N.B. This does NOT AddRef - IMemAllocator * PeekAllocator() const - { return m_pAllocator; } - - // Pass this on downstream if it ever gets called. - STDMETHODIMP - CTransInPlaceInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps); - - inline const BOOL ReadOnly() { return m_bReadOnly ; } - -}; // CTransInPlaceInputPin - -// ================================================== -// Implements the output pin -// ================================================== - -class CTransInPlaceOutputPin : public CTransformOutputPin -{ - -protected: - // m_pFilter points to our CBaseFilter - CTransInPlaceFilter * const m_pTIPFilter; - -public: - - CTransInPlaceOutputPin( - TCHAR *pObjectName, - CTransInPlaceFilter *pFilter, - HRESULT *phr, - LPCWSTR pName); - - - // --- CBaseOutputPin ------------ - - // negotiate the allocator and its buffer size/count - // Insists on using our own allocator. (Actually the one upstream of us). - // We don't override this - instead we just agree the default - // then let the upstream filter decide for itself on reconnect - // virtual HRESULT DecideAllocator(IMemInputPin * pPin, IMemAllocator ** pAlloc); - - // Provide a media type enumerator. Get it from upstream. - STDMETHODIMP EnumMediaTypes( IEnumMediaTypes **ppEnum ); - - // Say whether media type is acceptable. - HRESULT CheckMediaType(const CMediaType* pmt); - - // This just saves the allocator being used on the output pin - // Also called by input pin's GetAllocator() - void SetAllocator(IMemAllocator * pAllocator); - - IMemInputPin * ConnectedIMemInputPin() - { return m_pInputPin; } - - // Allow the filter to see what allocator we have - // N.B. This does NOT AddRef - IMemAllocator * PeekAllocator() const - { return m_pAllocator; } -}; // CTransInPlaceOutputPin - - -class AM_NOVTABLE CTransInPlaceFilter : public CTransformFilter -{ - -public: - - // map getpin/getpincount for base enum of pins to owner - // override this to return more specialised pin objects - - virtual CBasePin *GetPin(int n); - -public: - - // Set bModifiesData == false if your derived filter does - // not modify the data samples (for instance it's just copying - // them somewhere else or looking at the timestamps). - - CTransInPlaceFilter(TCHAR *, LPUNKNOWN, REFCLSID clsid, HRESULT *, - bool bModifiesData = true); -#ifdef UNICODE - CTransInPlaceFilter(CHAR *, LPUNKNOWN, REFCLSID clsid, HRESULT *, - bool bModifiesData = true); -#endif - // The following are defined to avoid undefined pure virtuals. - // Even if they are never called, they will give linkage warnings/errors - - // We override EnumMediaTypes to bypass the transform class enumerator - // which would otherwise call this. - HRESULT GetMediaType(int iPosition, CMediaType *pMediaType) - { DbgBreak("CTransInPlaceFilter::GetMediaType should never be called"); - return E_UNEXPECTED; - } - - // This is called when we actually have to provide out own allocator. - HRESULT DecideBufferSize(IMemAllocator*, ALLOCATOR_PROPERTIES *); - - // The functions which call this in CTransform are overridden in this - // class to call CheckInputType with the assumption that the type - // does not change. In Debug builds some calls will be made and - // we just ensure that they do not assert. - HRESULT CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut) - { - return S_OK; - }; - - - // ================================================================= - // ----- You may want to override this ----------------------------- - // ================================================================= - - HRESULT CompleteConnect(PIN_DIRECTION dir,IPin *pReceivePin); - - // chance to customize the transform process - virtual HRESULT Receive(IMediaSample *pSample); - - // ================================================================= - // ----- You MUST override these ----------------------------------- - // ================================================================= - - virtual HRESULT Transform(IMediaSample *pSample) PURE; - - // this goes in the factory template table to create new instances - // static CCOMObject * CreateInstance(LPUNKNOWN, HRESULT *); - - -#ifdef PERF - // Override to register performance measurement with a less generic string - // You should do this to avoid confusion with other filters - virtual void RegisterPerfId() - {m_idTransInPlace = MSR_REGISTER(TEXT("TransInPlace"));} -#endif // PERF - - -// implementation details - -protected: - - IMediaSample * CTransInPlaceFilter::Copy(IMediaSample *pSource); - -#ifdef PERF - int m_idTransInPlace; // performance measuring id -#endif // PERF - bool m_bModifiesData; // Does this filter change the data? - - // these hold our input and output pins - - friend class CTransInPlaceInputPin; - friend class CTransInPlaceOutputPin; - - CTransInPlaceInputPin *InputPin() const - { - return (CTransInPlaceInputPin *)m_pInput; - }; - CTransInPlaceOutputPin *OutputPin() const - { - return (CTransInPlaceOutputPin *)m_pOutput; - }; - - // Helper to see if the input and output types match - BOOL TypesMatch() - { - return InputPin()->CurrentMediaType() == - OutputPin()->CurrentMediaType(); - } - - // Are the input and output allocators different? - BOOL UsingDifferentAllocators() const - { - return InputPin()->PeekAllocator() != OutputPin()->PeekAllocator(); - } -}; // CTransInPlaceFilter - -#endif /* __TRANSIP__ */ - diff --git a/src/BaseClasses/videoctl.cpp b/src/BaseClasses/videoctl.cpp deleted file mode 100644 index ca00ce1752..0000000000 --- a/src/BaseClasses/videoctl.cpp +++ /dev/null @@ -1,653 +0,0 @@ -//------------------------------------------------------------------------------ -// File: VideoCtl.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include "ddmm.h" - -// Load a string from the resource file string table. The buffer must be at -// least STR_MAX_LENGTH bytes. The easiest way to use this is to declare a -// buffer in the property page class and use it for all string loading. It -// cannot be static as multiple property pages may be active simultaneously - -TCHAR *WINAPI StringFromResource(TCHAR *pBuffer, int iResourceID) { - if(LoadString(g_hInst,iResourceID,pBuffer,STR_MAX_LENGTH) == 0) { - return TEXT(""); - } - return pBuffer; -} - -#ifdef UNICODE -char *WINAPI StringFromResource(char *pBuffer, int iResourceID) { - if(LoadStringA(g_hInst,iResourceID,pBuffer,STR_MAX_LENGTH) == 0) { - return ""; - } - return pBuffer; -} -#endif - - - -// Property pages typically are called through their OLE interfaces. These -// use UNICODE strings regardless of how the binary is built. So when we -// load strings from the resource file we sometimes want to convert them -// to UNICODE. This method is passed the target UNICODE buffer and does a -// convert after loading the string (if built UNICODE this is not needed) -// On WinNT we can explicitly call LoadStringW which saves two conversions - -#ifndef UNICODE - -WCHAR * WINAPI WideStringFromResource(WCHAR *pBuffer, int iResourceID) { - *pBuffer = 0; - - if(g_amPlatform == VER_PLATFORM_WIN32_NT) { - LoadStringW(g_hInst,iResourceID,pBuffer,STR_MAX_LENGTH); - } - else { - - CHAR szBuffer[STR_MAX_LENGTH]; - DWORD dwStringLength = LoadString(g_hInst,iResourceID,szBuffer,STR_MAX_LENGTH); - // if we loaded a string convert it to wide characters, ensuring - // that we also null terminate the result. - if(dwStringLength++) { - MultiByteToWideChar(CP_ACP,0,szBuffer,dwStringLength,pBuffer,STR_MAX_LENGTH); - } - } - return pBuffer; -} - -#endif - - -// Helper function to calculate the size of the dialog - -BOOL WINAPI GetDialogSize(int iResourceID, - DLGPROC pDlgProc, - LPARAM lParam, - SIZE *pResult) { - RECT rc; - HWND hwnd; - - // Create a temporary property page - - hwnd = CreateDialogParam(g_hInst, - MAKEINTRESOURCE(iResourceID), - GetDesktopWindow(), - pDlgProc, - lParam); - if(hwnd == NULL) { - return FALSE; - } - - GetWindowRect(hwnd, &rc); - pResult->cx = rc.right - rc.left; - pResult->cy = rc.bottom - rc.top; - - DestroyWindow(hwnd); - return TRUE; -} - - -// Class that aggregates on the IDirectDraw interface. Although DirectDraw -// has the ability in its interfaces to be aggregated they're not currently -// implemented. This makes it difficult for various parts of Quartz that want -// to aggregate these interfaces. In particular the video renderer passes out -// media samples that expose IDirectDraw and IDirectDrawSurface. The filter -// graph manager also exposes IDirectDraw as a plug in distributor. For these -// objects we provide these aggregation classes that republish the interfaces - -STDMETHODIMP CAggDirectDraw::NonDelegatingQueryInterface(REFIID riid, void **ppv) { - ASSERT(m_pDirectDraw); - - // Do we have this interface - - if(riid == IID_IDirectDraw) { - return GetInterface((IDirectDraw *)this,ppv); - } - else { - return CUnknown::NonDelegatingQueryInterface(riid,ppv); - } -} - - -STDMETHODIMP CAggDirectDraw::Compact() { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->Compact(); -} - - -STDMETHODIMP CAggDirectDraw::CreateClipper(DWORD dwFlags,LPDIRECTDRAWCLIPPER *lplpDDClipper,IUnknown *pUnkOuter) { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->CreateClipper(dwFlags,lplpDDClipper,pUnkOuter); -} - - -STDMETHODIMP CAggDirectDraw::CreatePalette(DWORD dwFlags,LPPALETTEENTRY lpColorTable,LPDIRECTDRAWPALETTE *lplpDDPalette,IUnknown *pUnkOuter) { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->CreatePalette(dwFlags,lpColorTable,lplpDDPalette,pUnkOuter); -} - - -STDMETHODIMP CAggDirectDraw::CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc,LPDIRECTDRAWSURFACE *lplpDDSurface,IUnknown *pUnkOuter) { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->CreateSurface(lpDDSurfaceDesc,lplpDDSurface,pUnkOuter); -} - - -STDMETHODIMP CAggDirectDraw::DuplicateSurface(LPDIRECTDRAWSURFACE lpDDSurface,LPDIRECTDRAWSURFACE *lplpDupDDSurface) { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->DuplicateSurface(lpDDSurface,lplpDupDDSurface); -} - - -STDMETHODIMP CAggDirectDraw::EnumDisplayModes(DWORD dwSurfaceDescCount,LPDDSURFACEDESC lplpDDSurfaceDescList,LPVOID lpContext,LPDDENUMMODESCALLBACK lpEnumCallback) { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->EnumDisplayModes(dwSurfaceDescCount,lplpDDSurfaceDescList,lpContext,lpEnumCallback); -} - - -STDMETHODIMP CAggDirectDraw::EnumSurfaces(DWORD dwFlags,LPDDSURFACEDESC lpDDSD,LPVOID lpContext,LPDDENUMSURFACESCALLBACK lpEnumCallback) { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->EnumSurfaces(dwFlags,lpDDSD,lpContext,lpEnumCallback); -} - - -STDMETHODIMP CAggDirectDraw::FlipToGDISurface() { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->FlipToGDISurface(); -} - - -STDMETHODIMP CAggDirectDraw::GetCaps(LPDDCAPS lpDDDriverCaps,LPDDCAPS lpDDHELCaps) { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->GetCaps(lpDDDriverCaps,lpDDHELCaps); -} - - -STDMETHODIMP CAggDirectDraw::GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->GetDisplayMode(lpDDSurfaceDesc); -} - - -STDMETHODIMP CAggDirectDraw::GetFourCCCodes(LPDWORD lpNumCodes,LPDWORD lpCodes) { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->GetFourCCCodes(lpNumCodes,lpCodes); -} - - -STDMETHODIMP CAggDirectDraw::GetGDISurface(LPDIRECTDRAWSURFACE *lplpGDIDDSurface) { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->GetGDISurface(lplpGDIDDSurface); -} - - -STDMETHODIMP CAggDirectDraw::GetMonitorFrequency(LPDWORD lpdwFrequency) { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->GetMonitorFrequency(lpdwFrequency); -} - - -STDMETHODIMP CAggDirectDraw::GetScanLine(LPDWORD lpdwScanLine) { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->GetScanLine(lpdwScanLine); -} - - -STDMETHODIMP CAggDirectDraw::GetVerticalBlankStatus(LPBOOL lpblsInVB) { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->GetVerticalBlankStatus(lpblsInVB); -} - - -STDMETHODIMP CAggDirectDraw::Initialize(GUID *lpGUID) { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->Initialize(lpGUID); -} - - -STDMETHODIMP CAggDirectDraw::RestoreDisplayMode() { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->RestoreDisplayMode(); -} - - -STDMETHODIMP CAggDirectDraw::SetCooperativeLevel(HWND hWnd,DWORD dwFlags) { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->SetCooperativeLevel(hWnd,dwFlags); -} - - -STDMETHODIMP CAggDirectDraw::SetDisplayMode(DWORD dwWidth,DWORD dwHeight,DWORD dwBpp) { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->SetDisplayMode(dwWidth,dwHeight,dwBpp); -} - - -STDMETHODIMP CAggDirectDraw::WaitForVerticalBlank(DWORD dwFlags,HANDLE hEvent) { - ASSERT(m_pDirectDraw); - return m_pDirectDraw->WaitForVerticalBlank(dwFlags,hEvent); -} - - -// Class that aggregates an IDirectDrawSurface interface. Although DirectDraw -// has the ability in its interfaces to be aggregated they're not currently -// implemented. This makes it difficult for various parts of Quartz that want -// to aggregate these interfaces. In particular the video renderer passes out -// media samples that expose IDirectDraw and IDirectDrawSurface. The filter -// graph manager also exposes IDirectDraw as a plug in distributor. For these -// objects we provide these aggregation classes that republish the interfaces - -STDMETHODIMP CAggDrawSurface::NonDelegatingQueryInterface(REFIID riid, void **ppv) { - ASSERT(m_pDirectDrawSurface); - - // Do we have this interface - - if(riid == IID_IDirectDrawSurface) { - return GetInterface((IDirectDrawSurface *)this,ppv); - } - else { - return CUnknown::NonDelegatingQueryInterface(riid,ppv); - } -} - - -STDMETHODIMP CAggDrawSurface::AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttachedSurface) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->AddAttachedSurface(lpDDSAttachedSurface); -} - - -STDMETHODIMP CAggDrawSurface::AddOverlayDirtyRect(LPRECT lpRect) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->AddOverlayDirtyRect(lpRect); -} - - -STDMETHODIMP CAggDrawSurface::Blt(LPRECT lpDestRect,LPDIRECTDRAWSURFACE lpDDSrcSurface,LPRECT lpSrcRect,DWORD dwFlags,LPDDBLTFX lpDDBltFx) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->Blt(lpDestRect,lpDDSrcSurface,lpSrcRect,dwFlags,lpDDBltFx); -} - - -STDMETHODIMP CAggDrawSurface::BltBatch(LPDDBLTBATCH lpDDBltBatch,DWORD dwCount,DWORD dwFlags) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->BltBatch(lpDDBltBatch,dwCount,dwFlags); -} - - -STDMETHODIMP CAggDrawSurface::BltFast(DWORD dwX,DWORD dwY,LPDIRECTDRAWSURFACE lpDDSrcSurface,LPRECT lpSrcRect,DWORD dwTrans) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->BltFast(dwX,dwY,lpDDSrcSurface,lpSrcRect,dwTrans); -} - - -STDMETHODIMP CAggDrawSurface::DeleteAttachedSurface(DWORD dwFlags,LPDIRECTDRAWSURFACE lpDDSAttachedSurface) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->DeleteAttachedSurface(dwFlags,lpDDSAttachedSurface); -} - - -STDMETHODIMP CAggDrawSurface::EnumAttachedSurfaces(LPVOID lpContext,LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->EnumAttachedSurfaces(lpContext,lpEnumSurfacesCallback); -} - - -STDMETHODIMP CAggDrawSurface::EnumOverlayZOrders(DWORD dwFlags,LPVOID lpContext,LPDDENUMSURFACESCALLBACK lpfnCallback) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->EnumOverlayZOrders(dwFlags,lpContext,lpfnCallback); -} - - -STDMETHODIMP CAggDrawSurface::Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride,DWORD dwFlags) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->Flip(lpDDSurfaceTargetOverride,dwFlags); -} - - -STDMETHODIMP CAggDrawSurface::GetAttachedSurface(LPDDSCAPS lpDDSCaps,LPDIRECTDRAWSURFACE *lplpDDAttachedSurface) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetAttachedSurface(lpDDSCaps,lplpDDAttachedSurface); -} - - -STDMETHODIMP CAggDrawSurface::GetBltStatus(DWORD dwFlags) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetBltStatus(dwFlags); -} - - -STDMETHODIMP CAggDrawSurface::GetCaps(LPDDSCAPS lpDDSCaps) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetCaps(lpDDSCaps); -} - - -STDMETHODIMP CAggDrawSurface::GetClipper(LPDIRECTDRAWCLIPPER *lplpDDClipper) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetClipper(lplpDDClipper); -} - - -STDMETHODIMP CAggDrawSurface::GetColorKey(DWORD dwFlags,LPDDCOLORKEY lpDDColorKey) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetColorKey(dwFlags,lpDDColorKey); -} - - -STDMETHODIMP CAggDrawSurface::GetDC(HDC *lphDC) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetDC(lphDC); -} - - -STDMETHODIMP CAggDrawSurface::GetFlipStatus(DWORD dwFlags) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetFlipStatus(dwFlags); -} - - -STDMETHODIMP CAggDrawSurface::GetOverlayPosition(LPLONG lpdwX,LPLONG lpdwY) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetOverlayPosition(lpdwX,lpdwY); -} - - -STDMETHODIMP CAggDrawSurface::GetPalette(LPDIRECTDRAWPALETTE *lplpDDPalette) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetPalette(lplpDDPalette); -} - - -STDMETHODIMP CAggDrawSurface::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetPixelFormat(lpDDPixelFormat); -} - - -// A bit of a warning here: Our media samples in DirectShow aggregate on -// IDirectDraw and IDirectDrawSurface (ie are available through IMediaSample -// by QueryInterface). Unfortunately the underlying DirectDraw code cannot -// be aggregated so we have to use these classes. The snag is that when we -// call a different surface and pass in this interface as perhaps the source -// surface the call will fail because DirectDraw dereferences the pointer to -// get at its private data structures. Therefore we supply this workaround to give -// access to the real IDirectDraw surface. A filter can call GetSurfaceDesc -// and we will fill in the lpSurface pointer with the real underlying surface - -STDMETHODIMP CAggDrawSurface::GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) { - ASSERT(m_pDirectDrawSurface); - - // First call down to the underlying DirectDraw - - HRESULT hr = m_pDirectDrawSurface->GetSurfaceDesc(lpDDSurfaceDesc); - if(FAILED(hr)) { - return hr; - } - - // Store the real DirectDrawSurface interface - lpDDSurfaceDesc->lpSurface = m_pDirectDrawSurface; - return hr; -} - - -STDMETHODIMP CAggDrawSurface::Initialize(LPDIRECTDRAW lpDD,LPDDSURFACEDESC lpDDSurfaceDesc) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->Initialize(lpDD,lpDDSurfaceDesc); -} - - -STDMETHODIMP CAggDrawSurface::IsLost() { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->IsLost(); -} - - -STDMETHODIMP CAggDrawSurface::Lock(LPRECT lpDestRect,LPDDSURFACEDESC lpDDSurfaceDesc,DWORD dwFlags,HANDLE hEvent) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->Lock(lpDestRect,lpDDSurfaceDesc,dwFlags,hEvent); -} - - -STDMETHODIMP CAggDrawSurface::ReleaseDC(HDC hDC) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->ReleaseDC(hDC); -} - - -STDMETHODIMP CAggDrawSurface::Restore() { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->Restore(); -} - - -STDMETHODIMP CAggDrawSurface::SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->SetClipper(lpDDClipper); -} - - -STDMETHODIMP CAggDrawSurface::SetColorKey(DWORD dwFlags,LPDDCOLORKEY lpDDColorKey) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->SetColorKey(dwFlags,lpDDColorKey); -} - - -STDMETHODIMP CAggDrawSurface::SetOverlayPosition(LONG dwX,LONG dwY) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->SetOverlayPosition(dwX,dwY); -} - - -STDMETHODIMP CAggDrawSurface::SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->SetPalette(lpDDPalette); -} - - -STDMETHODIMP CAggDrawSurface::Unlock(LPVOID lpSurfaceData) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->Unlock(lpSurfaceData); -} - - -STDMETHODIMP CAggDrawSurface::UpdateOverlay(LPRECT lpSrcRect,LPDIRECTDRAWSURFACE lpDDDestSurface,LPRECT lpDestRect,DWORD dwFlags,LPDDOVERLAYFX lpDDOverlayFX) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->UpdateOverlay(lpSrcRect,lpDDDestSurface,lpDestRect,dwFlags,lpDDOverlayFX); -} - - -STDMETHODIMP CAggDrawSurface::UpdateOverlayDisplay(DWORD dwFlags) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->UpdateOverlayDisplay(dwFlags); -} - - -STDMETHODIMP CAggDrawSurface::UpdateOverlayZOrder(DWORD dwFlags,LPDIRECTDRAWSURFACE lpDDSReference) { - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->UpdateOverlayZOrder(dwFlags,lpDDSReference); -} - - -// DirectShow must work on multiple platforms. In particular, it also runs on -// Windows NT 3.51 which does not have DirectDraw capabilities. The filters -// cannot therefore link statically to the DirectDraw library. To make their -// lives that little bit easier we provide this class that manages loading -// and unloading the library and creating the initial IDirectDraw interface - -CLoadDirectDraw::CLoadDirectDraw() : - m_pDirectDraw(NULL), - m_hDirectDraw(NULL) { -} - - -// Destructor forces unload - -CLoadDirectDraw::~CLoadDirectDraw() { - ReleaseDirectDraw(); - - if(m_hDirectDraw) { - NOTE("Unloading library"); - FreeLibrary(m_hDirectDraw); - } -} - - -// We can't be sure that DirectDraw is always available so we can't statically -// link to the library. Therefore we load the library, get the function entry -// point addresses and call them to create the driver objects. We return S_OK -// if we manage to load DirectDraw correctly otherwise we return E_NOINTERFACE -// We initialise a DirectDraw instance by explicitely loading the library and -// calling GetProcAddress on the DirectDrawCreate entry point that it exports - -// On a multi monitor system, we can get the DirectDraw object for any -// monitor (device) with the optional szDevice parameter - -HRESULT CLoadDirectDraw::LoadDirectDraw(LPSTR szDevice) { - PDRAWCREATE pDrawCreate; - PDRAWENUM pDrawEnum; - LPDIRECTDRAWENUMERATEEXA pDrawEnumEx; - HRESULT hr = NOERROR; - - NOTE("Entering DoLoadDirectDraw"); - - // Is DirectDraw already loaded - - if(m_pDirectDraw) { - NOTE("Already loaded"); - ASSERT(m_hDirectDraw); - return NOERROR; - } - - // Make sure the library is available - - if(!m_hDirectDraw) { - UINT ErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX); - m_hDirectDraw = LoadLibrary(TEXT("DDRAW.DLL")); - SetErrorMode(ErrorMode); - - if(m_hDirectDraw == NULL) { - DbgLog((LOG_ERROR,1,TEXT("Can't load DDRAW.DLL"))); - NOTE("No library"); - return E_NOINTERFACE; - } - } - - // Get the DLL address for the creator function - - pDrawCreate = (PDRAWCREATE)GetProcAddress(m_hDirectDraw,"DirectDrawCreate"); - // force ANSI, we assume it - pDrawEnum = (PDRAWENUM)GetProcAddress(m_hDirectDraw,"DirectDrawEnumerateA"); - pDrawEnumEx = (LPDIRECTDRAWENUMERATEEXA)GetProcAddress(m_hDirectDraw, - "DirectDrawEnumerateExA"); - - // We don't NEED DirectDrawEnumerateEx, that's just for multimon stuff - if(pDrawCreate == NULL || pDrawEnum == NULL) { - DbgLog((LOG_ERROR,1,TEXT("Can't get functions: Create=%x Enum=%x"), - pDrawCreate, pDrawEnum)); - NOTE("No entry point"); - ReleaseDirectDraw(); - return E_NOINTERFACE; - } - - DbgLog((LOG_TRACE,3,TEXT("Creating DDraw for device %s"), - szDevice ? szDevice : "")); - - // Create a DirectDraw display provider for this device, using the fancy - // multimon-aware version, if it exists - if(pDrawEnumEx) - m_pDirectDraw = DirectDrawCreateFromDeviceEx(szDevice, pDrawCreate, - pDrawEnumEx); - else - m_pDirectDraw = DirectDrawCreateFromDevice(szDevice, pDrawCreate, - pDrawEnum); - - if(m_pDirectDraw == NULL) { - DbgLog((LOG_ERROR,1,TEXT("Can't create DDraw"))); - NOTE("No instance"); - ReleaseDirectDraw(); - return E_NOINTERFACE; - } - return NOERROR; -} - - -// Called to release any DirectDraw provider we previously loaded. We may be -// called at any time especially when something goes horribly wrong and when -// we need to clean up before returning so we can't guarantee that all state -// variables are consistent so free only those really allocated allocated -// This should only be called once all reference counts have been released - -void CLoadDirectDraw::ReleaseDirectDraw() { - NOTE("Releasing DirectDraw driver"); - - // Release any DirectDraw provider interface - - if(m_pDirectDraw) { - NOTE("Releasing instance"); - m_pDirectDraw->Release(); - m_pDirectDraw = NULL; - } - -} - - -// Return NOERROR (S_OK) if DirectDraw has been loaded by this object - -HRESULT CLoadDirectDraw::IsDirectDrawLoaded() { - NOTE("Entering IsDirectDrawLoaded"); - - if(m_pDirectDraw == NULL) { - NOTE("DirectDraw not loaded"); - return S_FALSE; - } - return NOERROR; -} - - -// Return the IDirectDraw interface we look after - -LPDIRECTDRAW CLoadDirectDraw::GetDirectDraw() { - NOTE("Entering GetDirectDraw"); - - if(m_pDirectDraw == NULL) { - NOTE("No DirectDraw"); - return NULL; - } - - NOTE("Returning DirectDraw"); - m_pDirectDraw->AddRef(); - return m_pDirectDraw; -} - - -// Are we running on Direct Draw version 1? We need to find out as -// we rely on specific bug fixes in DirectDraw 2 for fullscreen playback. To -// find out, we simply see if it supports IDirectDraw2. Only version 2 and -// higher support this. - -BOOL CLoadDirectDraw::IsDirectDrawVersion1() { - - if(m_pDirectDraw == NULL) - return FALSE; - - IDirectDraw2 *p = NULL; - HRESULT hr = m_pDirectDraw->QueryInterface(IID_IDirectDraw2, (void **)&p); - if(p) - p->Release(); - if(hr == NOERROR) { - DbgLog((LOG_TRACE,3,TEXT("Direct Draw Version 2 or greater"))); - return FALSE; - } - else { - DbgLog((LOG_TRACE,3,TEXT("Direct Draw Version 1"))); - return TRUE; - } -} - diff --git a/src/BaseClasses/videoctl.h b/src/BaseClasses/videoctl.h deleted file mode 100644 index cf2a5e4b2b..0000000000 --- a/src/BaseClasses/videoctl.h +++ /dev/null @@ -1,178 +0,0 @@ -//------------------------------------------------------------------------------ -// File: VideoCtl.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __VIDEOCTL__ -#define __VIDEOCTL__ - -// These help with property page implementations. The first can be used to -// load any string from a resource file. The buffer to load into is passed -// as an input parameter. The same buffer is the return value if the string -// was found otherwise it returns TEXT(""). The GetDialogSize is passed the -// resource ID of a dialog box and returns the size of it in screen pixels - -#define STR_MAX_LENGTH 256 -TCHAR * WINAPI StringFromResource(TCHAR *pBuffer, int iResourceID); - -#ifdef UNICODE -#define WideStringFromResource StringFromResource -char* WINAPI StringFromResource(char*pBuffer, int iResourceID); -#else -WCHAR * WINAPI WideStringFromResource(WCHAR *pBuffer, int iResourceID); -#endif - - -BOOL WINAPI GetDialogSize(int iResourceID, // Dialog box resource identifier - DLGPROC pDlgProc, // Pointer to dialog procedure - LPARAM lParam, // Any user data wanted in pDlgProc - SIZE *pResult); // Returns the size of dialog box - -// Class that aggregates an IDirectDraw interface - -class CAggDirectDraw : public IDirectDraw, public CUnknown -{ -protected: - - LPDIRECTDRAW m_pDirectDraw; - -public: - - DECLARE_IUNKNOWN - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void **ppv); - - // Constructor and destructor - - CAggDirectDraw(TCHAR *pName,LPUNKNOWN pUnk) : - CUnknown(pName,pUnk), - m_pDirectDraw(NULL) { }; - - virtual CAggDirectDraw::~CAggDirectDraw() { }; - - // Set the object we should be aggregating - void SetDirectDraw(LPDIRECTDRAW pDirectDraw) { - m_pDirectDraw = pDirectDraw; - } - - // IDirectDraw methods - - STDMETHODIMP Compact(); - STDMETHODIMP CreateClipper(DWORD dwFlags,LPDIRECTDRAWCLIPPER *lplpDDClipper,IUnknown *pUnkOuter); - STDMETHODIMP CreatePalette(DWORD dwFlags,LPPALETTEENTRY lpColorTable,LPDIRECTDRAWPALETTE *lplpDDPalette,IUnknown *pUnkOuter); - STDMETHODIMP CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc,LPDIRECTDRAWSURFACE *lplpDDSurface,IUnknown *pUnkOuter); - STDMETHODIMP DuplicateSurface(LPDIRECTDRAWSURFACE lpDDSurface,LPDIRECTDRAWSURFACE *lplpDupDDSurface); - STDMETHODIMP EnumDisplayModes(DWORD dwSurfaceDescCount,LPDDSURFACEDESC lplpDDSurfaceDescList,LPVOID lpContext,LPDDENUMMODESCALLBACK lpEnumCallback); - STDMETHODIMP EnumSurfaces(DWORD dwFlags,LPDDSURFACEDESC lpDDSD,LPVOID lpContext,LPDDENUMSURFACESCALLBACK lpEnumCallback); - STDMETHODIMP FlipToGDISurface(); - STDMETHODIMP GetCaps(LPDDCAPS lpDDDriverCaps,LPDDCAPS lpDDHELCaps); - STDMETHODIMP GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc); - STDMETHODIMP GetFourCCCodes(LPDWORD lpNumCodes,LPDWORD lpCodes); - STDMETHODIMP GetGDISurface(LPDIRECTDRAWSURFACE *lplpGDIDDSurface); - STDMETHODIMP GetMonitorFrequency(LPDWORD lpdwFrequency); - STDMETHODIMP GetScanLine(LPDWORD lpdwScanLine); - STDMETHODIMP GetVerticalBlankStatus(LPBOOL lpblsInVB); - STDMETHODIMP Initialize(GUID *lpGUID); - STDMETHODIMP RestoreDisplayMode(); - STDMETHODIMP SetCooperativeLevel(HWND hWnd,DWORD dwFlags); - STDMETHODIMP SetDisplayMode(DWORD dwWidth,DWORD dwHeight,DWORD dwBpp); - STDMETHODIMP WaitForVerticalBlank(DWORD dwFlags,HANDLE hEvent); -}; - - -// Class that aggregates an IDirectDrawSurface interface - -class CAggDrawSurface : public IDirectDrawSurface, public CUnknown -{ -protected: - - LPDIRECTDRAWSURFACE m_pDirectDrawSurface; - -public: - - DECLARE_IUNKNOWN - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void **ppv); - - // Constructor and destructor - - CAggDrawSurface(TCHAR *pName,LPUNKNOWN pUnk) : - CUnknown(pName,pUnk), - m_pDirectDrawSurface(NULL) { }; - - virtual ~CAggDrawSurface() { }; - - // Set the object we should be aggregating - void SetDirectDrawSurface(LPDIRECTDRAWSURFACE pDirectDrawSurface) { - m_pDirectDrawSurface = pDirectDrawSurface; - } - - // IDirectDrawSurface methods - - STDMETHODIMP AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttachedSurface); - STDMETHODIMP AddOverlayDirtyRect(LPRECT lpRect); - STDMETHODIMP Blt(LPRECT lpDestRect,LPDIRECTDRAWSURFACE lpDDSrcSurface,LPRECT lpSrcRect,DWORD dwFlags,LPDDBLTFX lpDDBltFx); - STDMETHODIMP BltBatch(LPDDBLTBATCH lpDDBltBatch,DWORD dwCount,DWORD dwFlags); - STDMETHODIMP BltFast(DWORD dwX,DWORD dwY,LPDIRECTDRAWSURFACE lpDDSrcSurface,LPRECT lpSrcRect,DWORD dwTrans); - STDMETHODIMP DeleteAttachedSurface(DWORD dwFlags,LPDIRECTDRAWSURFACE lpDDSAttachedSurface); - STDMETHODIMP EnumAttachedSurfaces(LPVOID lpContext,LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback); - STDMETHODIMP EnumOverlayZOrders(DWORD dwFlags,LPVOID lpContext,LPDDENUMSURFACESCALLBACK lpfnCallback); - STDMETHODIMP Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride,DWORD dwFlags); - STDMETHODIMP GetAttachedSurface(LPDDSCAPS lpDDSCaps,LPDIRECTDRAWSURFACE *lplpDDAttachedSurface); - STDMETHODIMP GetBltStatus(DWORD dwFlags); - STDMETHODIMP GetCaps(LPDDSCAPS lpDDSCaps); - STDMETHODIMP GetClipper(LPDIRECTDRAWCLIPPER *lplpDDClipper); - STDMETHODIMP GetColorKey(DWORD dwFlags,LPDDCOLORKEY lpDDColorKey); - STDMETHODIMP GetDC(HDC *lphDC); - STDMETHODIMP GetFlipStatus(DWORD dwFlags); - STDMETHODIMP GetOverlayPosition(LPLONG lpdwX,LPLONG lpdwY); - STDMETHODIMP GetPalette(LPDIRECTDRAWPALETTE *lplpDDPalette); - STDMETHODIMP GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat); - STDMETHODIMP GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc); - STDMETHODIMP Initialize(LPDIRECTDRAW lpDD,LPDDSURFACEDESC lpDDSurfaceDesc); - STDMETHODIMP IsLost(); - STDMETHODIMP Lock(LPRECT lpDestRect,LPDDSURFACEDESC lpDDSurfaceDesc,DWORD dwFlags,HANDLE hEvent); - STDMETHODIMP ReleaseDC(HDC hDC); - STDMETHODIMP Restore(); - STDMETHODIMP SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper); - STDMETHODIMP SetColorKey(DWORD dwFlags,LPDDCOLORKEY lpDDColorKey); - STDMETHODIMP SetOverlayPosition(LONG dwX,LONG dwY); - STDMETHODIMP SetPalette(LPDIRECTDRAWPALETTE lpDDPalette); - STDMETHODIMP Unlock(LPVOID lpSurfaceData); - STDMETHODIMP UpdateOverlay(LPRECT lpSrcRect,LPDIRECTDRAWSURFACE lpDDDestSurface,LPRECT lpDestRect,DWORD dwFlags,LPDDOVERLAYFX lpDDOverlayFX); - STDMETHODIMP UpdateOverlayDisplay(DWORD dwFlags); - STDMETHODIMP UpdateOverlayZOrder(DWORD dwFlags,LPDIRECTDRAWSURFACE lpDDSReference); -}; - - -// DirectShow must work on multiple platforms. In particular, it also runs on -// Windows NT 3.51 which does not have DirectDraw capabilities. The filters -// cannot therefore link statically to the DirectDraw library. To make their -// lives that little bit easier we provide this class that manages loading -// and unloading the library and creating the initial IDirectDraw interface - -typedef DWORD (WINAPI *PGETFILEVERSIONINFOSIZE)(LPTSTR,LPDWORD); -typedef BOOL (WINAPI *PGETFILEVERSIONINFO)(LPTSTR,DWORD,DWORD,LPVOID); -typedef BOOL (WINAPI *PVERQUERYVALUE)(LPVOID,LPTSTR,LPVOID,PUINT); - -class CLoadDirectDraw -{ - LPDIRECTDRAW m_pDirectDraw; // The DirectDraw driver instance - HINSTANCE m_hDirectDraw; // Handle to the loaded library - -public: - - CLoadDirectDraw(); - ~CLoadDirectDraw(); - - HRESULT LoadDirectDraw(LPSTR szDevice); - void ReleaseDirectDraw(); - HRESULT IsDirectDrawLoaded(); - LPDIRECTDRAW GetDirectDraw(); - BOOL IsDirectDrawVersion1(); -}; - -#endif // __VIDEOCTL__ - diff --git a/src/BaseClasses/vtrans.cpp b/src/BaseClasses/vtrans.cpp deleted file mode 100644 index 3e2766de9d..0000000000 --- a/src/BaseClasses/vtrans.cpp +++ /dev/null @@ -1,468 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Vtrans.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include -// #include // now in precomp file streams.h - -CVideoTransformFilter::CVideoTransformFilter - ( TCHAR *pName, LPUNKNOWN pUnk, REFCLSID clsid) - : CTransformFilter(pName, pUnk, clsid) - , m_itrLate(0) - , m_nKeyFramePeriod(0) // No QM until we see at least 2 key frames - , m_nFramesSinceKeyFrame(0) - , m_bSkipping(FALSE) - , m_tDecodeStart(0) - , m_itrAvgDecode(300000) // 30mSec - probably allows skipping - , m_bQualityChanged(FALSE) { -#ifdef PERF - RegisterPerfId(); -#endif // PERF -} - - -CVideoTransformFilter::~CVideoTransformFilter() { - // nothing to do -} - - -// Reset our quality management state - -HRESULT CVideoTransformFilter::StartStreaming() { - m_itrLate = 0; - m_nKeyFramePeriod = 0; // No QM until we see at least 2 key frames - m_nFramesSinceKeyFrame = 0; - m_bSkipping = FALSE; - m_tDecodeStart = 0; - m_itrAvgDecode = 300000; // 30mSec - probably allows skipping - m_bQualityChanged = FALSE; - m_bSampleSkipped = FALSE; - return NOERROR; -} - - -// Overriden to reset quality management information - -HRESULT CVideoTransformFilter::EndFlush() { { - // Synchronize - CAutoLock lck(&m_csReceive); - - // Reset our stats - // - // Note - we don't want to call derived classes here, - // we only want to reset our internal variables and this - // is a convenient way to do it - CVideoTransformFilter::StartStreaming(); - } - return CTransformFilter::EndFlush(); -} - - -HRESULT CVideoTransformFilter::AbortPlayback(HRESULT hr) { - NotifyEvent(EC_ERRORABORT, hr, 0); - m_pOutput->DeliverEndOfStream(); - return hr; -} - - -// Receive() -// -// Accept a sample from upstream, decide whether to process it -// or drop it. If we process it then get a buffer from the -// allocator of the downstream connection, transform it into the -// new buffer and deliver it to the downstream filter. -// If we decide not to process it then we do not get a buffer. - -// Remember that although this code will notice format changes coming into -// the input pin, it will NOT change its output format if that results -// in the filter needing to make a corresponding output format change. Your -// derived filter will have to take care of that. (eg. a palette change if -// the input and output is an 8 bit format). If the input sample is discarded -// and nothing is sent out for this Receive, please remember to put the format -// change on the first output sample that you actually do send. -// If your filter will produce the same output type even when the input type -// changes, then this base class code will do everything you need. - -HRESULT CVideoTransformFilter::Receive(IMediaSample *pSample) { - // If the next filter downstream is the video renderer, then it may - // be able to operate in DirectDraw mode which saves copying the data - // and gives higher performance. In that case the buffer which we - // get from GetDeliveryBuffer will be a DirectDraw buffer, and - // drawing into this buffer draws directly onto the display surface. - // This means that any waiting for the correct time to draw occurs - // during GetDeliveryBuffer, and that once the buffer is given to us - // the video renderer will count it in its statistics as a frame drawn. - // This means that any decision to drop the frame must be taken before - // calling GetDeliveryBuffer. - - ASSERT(CritCheckIn(&m_csReceive)); - AM_MEDIA_TYPE *pmtOut, *pmt; -#ifdef DEBUG - FOURCCMap fccOut; -#endif - HRESULT hr; - ASSERT(pSample); - IMediaSample * pOutSample; - - // If no output pin to deliver to then no point sending us data - ASSERT(m_pOutput != NULL) ; - - // The source filter may dynamically ask us to start transforming from a - // different media type than the one we're using now. If we don't, we'll - // draw garbage. (typically, this is a palette change in the movie, - // but could be something more sinister like the compression type changing, - // or even the video size changing) - -#define rcS1 ((VIDEOINFOHEADER *)(pmt->pbFormat))->rcSource -#define rcT1 ((VIDEOINFOHEADER *)(pmt->pbFormat))->rcTarget - - pSample->GetMediaType(&pmt); - if(pmt != NULL && pmt->pbFormat != NULL) { - - // spew some debug output - ASSERT(!IsEqualGUID(pmt->majortype, GUID_NULL)); -#ifdef DEBUG - fccOut.SetFOURCC(&pmt->subtype); - LONG lCompression = HEADER(pmt->pbFormat)->biCompression; - LONG lBitCount = HEADER(pmt->pbFormat)->biBitCount; - LONG lStride = (HEADER(pmt->pbFormat)->biWidth * lBitCount + 7) / 8; - lStride = (lStride + 3) & ~3; - DbgLog((LOG_TRACE,3,TEXT("*Changing input type on the fly to"))); - DbgLog((LOG_TRACE,3,TEXT("FourCC: %lx Compression: %lx BitCount: %ld"), - fccOut.GetFOURCC(), lCompression, lBitCount)); - DbgLog((LOG_TRACE,3,TEXT("biHeight: %ld rcDst: (%ld, %ld, %ld, %ld)"), - HEADER(pmt->pbFormat)->biHeight, - rcT1.left, rcT1.top, rcT1.right, rcT1.bottom)); - DbgLog((LOG_TRACE,3,TEXT("rcSrc: (%ld, %ld, %ld, %ld) Stride: %ld"), - rcS1.left, rcS1.top, rcS1.right, rcS1.bottom, - lStride)); -#endif - - // now switch to using the new format. I am assuming that the - // derived filter will do the right thing when its media type is - // switched and streaming is restarted. - - StopStreaming(); - m_pInput->CurrentMediaType() = *pmt; - DeleteMediaType(pmt); - // if this fails, playback will stop, so signal an error - hr = StartStreaming(); - if(FAILED(hr)) { - return AbortPlayback(hr); - } - } - - // Now that we have noticed any format changes on the input sample, it's - // OK to discard it. - - if(ShouldSkipFrame(pSample)) { - MSR_NOTE(m_idSkip); - m_bSampleSkipped = TRUE; - return NOERROR; - } - - // Set up the output sample - hr = InitializeOutputSample(pSample, &pOutSample); - - if(FAILED(hr)) { - return hr; - } - - m_bSampleSkipped = FALSE; - - // The renderer may ask us to on-the-fly to start transforming to a - // different format. If we don't obey it, we'll draw garbage - -#define rcS ((VIDEOINFOHEADER *)(pmtOut->pbFormat))->rcSource -#define rcT ((VIDEOINFOHEADER *)(pmtOut->pbFormat))->rcTarget - - pOutSample->GetMediaType(&pmtOut); - if(pmtOut != NULL && pmtOut->pbFormat != NULL) { - - // spew some debug output - ASSERT(!IsEqualGUID(pmtOut->majortype, GUID_NULL)); -#ifdef DEBUG - fccOut.SetFOURCC(&pmtOut->subtype); - LONG lCompression = HEADER(pmtOut->pbFormat)->biCompression; - LONG lBitCount = HEADER(pmtOut->pbFormat)->biBitCount; - LONG lStride = (HEADER(pmtOut->pbFormat)->biWidth * lBitCount + 7) / 8; - lStride = (lStride + 3) & ~3; - DbgLog((LOG_TRACE,3,TEXT("*Changing output type on the fly to"))); - DbgLog((LOG_TRACE,3,TEXT("FourCC: %lx Compression: %lx BitCount: %ld"), - fccOut.GetFOURCC(), lCompression, lBitCount)); - DbgLog((LOG_TRACE,3,TEXT("biHeight: %ld rcDst: (%ld, %ld, %ld, %ld)"), - HEADER(pmtOut->pbFormat)->biHeight, - rcT.left, rcT.top, rcT.right, rcT.bottom)); - DbgLog((LOG_TRACE,3,TEXT("rcSrc: (%ld, %ld, %ld, %ld) Stride: %ld"), - rcS.left, rcS.top, rcS.right, rcS.bottom, - lStride)); -#endif - - // now switch to using the new format. I am assuming that the - // derived filter will do the right thing when its media type is - // switched and streaming is restarted. - - StopStreaming(); - m_pOutput->CurrentMediaType() = *pmtOut; - DeleteMediaType(pmtOut); - hr = StartStreaming(); - - if(SUCCEEDED(hr)) { - // a new format, means a new empty buffer, so wait for a keyframe - // before passing anything on to the renderer. - // !!! a keyframe may never come, so give up after 30 frames - DbgLog((LOG_TRACE,3,TEXT("Output format change means we must wait for a keyframe"))); - m_nWaitForKey = 30; - - // if this fails, playback will stop, so signal an error - } - else { - - // Must release the sample before calling AbortPlayback - // because we might be holding the win16 lock or - // ddraw lock - pOutSample->Release(); - AbortPlayback(hr); - return hr; - } - } - - // After a discontinuity, we need to wait for the next key frame - if(pSample->IsDiscontinuity() == S_OK) { - DbgLog((LOG_TRACE,3,TEXT("Non-key discontinuity - wait for keyframe"))); - m_nWaitForKey = 30; - } - - // Start timing the transform (and log it if PERF is defined) - - if(SUCCEEDED(hr)) { - m_tDecodeStart = timeGetTime(); - MSR_START(m_idTransform); - - // have the derived class transform the data - hr = Transform(pSample, pOutSample); - - // Stop the clock (and log it if PERF is defined) - MSR_STOP(m_idTransform); - m_tDecodeStart = timeGetTime()-m_tDecodeStart; - m_itrAvgDecode = m_tDecodeStart*(10000/16) + 15*(m_itrAvgDecode/16); - - // Maybe we're waiting for a keyframe still? - if(m_nWaitForKey) - m_nWaitForKey--; - if(m_nWaitForKey && pSample->IsSyncPoint() == S_OK) - m_nWaitForKey = FALSE; - - // if so, then we don't want to pass this on to the renderer - if(m_nWaitForKey && hr == NOERROR) { - DbgLog((LOG_TRACE,3,TEXT("still waiting for a keyframe"))); - hr = S_FALSE; - } - } - - if(FAILED(hr)) { - DbgLog((LOG_TRACE,1,TEXT("Error from video transform"))); - } - else { - // the Transform() function can return S_FALSE to indicate that the - // sample should not be delivered; we only deliver the sample if it's - // really S_OK (same as NOERROR, of course.) - // Try not to return S_FALSE to a direct draw buffer (it's wasteful) - // Try to take the decision earlier - before you get it. - - if(hr == NOERROR) { - hr = m_pOutput->Deliver(pOutSample); - } - else { - // S_FALSE returned from Transform is a PRIVATE agreement - // We should return NOERROR from Receive() in this case because returning S_FALSE - // from Receive() means that this is the end of the stream and no more data should - // be sent. - if(S_FALSE == hr) { - - // We must Release() the sample before doing anything - // like calling the filter graph because having the - // sample means we may have the DirectDraw lock - // (== win16 lock on some versions) - pOutSample->Release(); - m_bSampleSkipped = TRUE; - if(!m_bQualityChanged) { - m_bQualityChanged = TRUE; - NotifyEvent(EC_QUALITY_CHANGE,0,0); - } - return NOERROR; - } - } - } - - // release the output buffer. If the connected pin still needs it, - // it will have addrefed it itself. - pOutSample->Release(); - ASSERT(CritCheckIn(&m_csReceive)); - - return hr; -} - - - -BOOL CVideoTransformFilter::ShouldSkipFrame( IMediaSample * pIn) { - REFERENCE_TIME trStart, trStopAt; - HRESULT hr = pIn->GetTime(&trStart, &trStopAt); - - // Don't skip frames with no timestamps - if(hr != S_OK) - return FALSE; - - int itrFrame = (int)(trStopAt - trStart); // frame duration - - if(S_OK==pIn->IsSyncPoint()) { - MSR_INTEGER(m_idFrameType, 1); - if(m_nKeyFramePeriod < m_nFramesSinceKeyFrame) { - // record the max - m_nKeyFramePeriod = m_nFramesSinceKeyFrame; - } - m_nFramesSinceKeyFrame = 0; - m_bSkipping = FALSE; - } - else { - MSR_INTEGER(m_idFrameType, 2); - if(m_nFramesSinceKeyFrame>m_nKeyFramePeriod - && m_nKeyFramePeriod>0) { - // We haven't seen the key frame yet, but we were clearly being - // overoptimistic about how frequent they are. - m_nKeyFramePeriod = m_nFramesSinceKeyFrame; - } - } - - - // Whatever we might otherwise decide, - // if we are taking only a small fraction of the required frame time to decode - // then any quality problems are actually coming from somewhere else. - // Could be a net problem at the source for instance. In this case there's - // no point in us skipping frames here. - if(m_itrAvgDecode*4>itrFrame) { - - // Don't skip unless we are at least a whole frame late. - // (We would skip B frames if more than 1/2 frame late, but they're safe). - if(m_itrLate > itrFrame) { - - // Don't skip unless the anticipated key frame would be no more than - // 1 frame early. If the renderer has not been waiting (we *guess* - // it hasn't because we're late) then it will allow frames to be - // played early by up to a frame. - - // Let T = Stream time from now to anticipated next key frame - // = (frame duration) * (KeyFramePeriod - FramesSinceKeyFrame) - // So we skip if T - Late < one frame i.e. - // (duration) * (freq - FramesSince) - Late < duration - // or (duration) * (freq - FramesSince - 1) < Late - - // We don't dare skip until we have seen some key frames and have - // some idea how often they occur and they are reasonably frequent. - if(m_nKeyFramePeriod>0) { - // It would be crazy - but we could have a stream with key frames - // a very long way apart - and if they are further than about - // 3.5 minutes apart then we could get arithmetic overflow in - // reference time units. Therefore we switch to mSec at this point - int it = (itrFrame/10000) - * (m_nKeyFramePeriod-m_nFramesSinceKeyFrame - 1); - MSR_INTEGER(m_idTimeTillKey, it); - - // For debug - might want to see the details - dump them as scratch pad -#ifdef VTRANSPERF - MSR_INTEGER(0, itrFrame); - MSR_INTEGER(0, m_nFramesSinceKeyFrame); - MSR_INTEGER(0, m_nKeyFramePeriod); -#endif - if(m_itrLate/10000 > it) { - m_bSkipping = TRUE; - // Now we are committed. Once we start skipping, we - // cannot stop until we hit a key frame. - } - else { -#ifdef VTRANSPERF - MSR_INTEGER(0, 777770); // not near enough to next key -#endif - } - } - else { -#ifdef VTRANSPERF - MSR_INTEGER(0, 777771); // Next key not predictable -#endif - } - } - else { -#ifdef VTRANSPERF - MSR_INTEGER(0, 777772); // Less than one frame late - MSR_INTEGER(0, m_itrLate); - MSR_INTEGER(0, itrFrame); -#endif - } - } - else { -#ifdef VTRANSPERF - MSR_INTEGER(0, 777773); // Decode time short - not not worth skipping - MSR_INTEGER(0, m_itrAvgDecode); - MSR_INTEGER(0, itrFrame); -#endif - } - - ++m_nFramesSinceKeyFrame; - - if(m_bSkipping) { - // We will count down the lateness as we skip each frame. - // We re-assess each frame. The key frame might not arrive when expected. - // We reset m_itrLate if we get a new Quality message, but actually that's - // not likely because we're not sending frames on to the Renderer. In - // fact if we DID get another one it would mean that there's a long - // pipe between us and the renderer and we might need an altogether - // better strategy to avoid hunting! - m_itrLate = m_itrLate - itrFrame; - } - - MSR_INTEGER(m_idLate, (int)m_itrLate/10000); // Note how late we think we are - if(m_bSkipping) { - if(!m_bQualityChanged) { - m_bQualityChanged = TRUE; - NotifyEvent(EC_QUALITY_CHANGE,0,0); - } - } - return m_bSkipping; -} - - -HRESULT CVideoTransformFilter::AlterQuality(Quality q) { - // to reduce the amount of 64 bit arithmetic, m_itrLate is an int. - // +, -, >, == etc are not too bad, but * and / are painful. - if(m_itrLate>300000000) { - // Avoid overflow and silliness - more than 30 secs late is already silly - m_itrLate = 300000000; - } - else { - m_itrLate = (int)q.Late; - } - // We ignore the other fields - - // We're actually not very good at handling this. In non-direct draw mode - // most of the time can be spent in the renderer which can skip any frame. - // In that case we'd rather the renderer handled things. - // Nevertheless we will keep an eye on it and if we really start getting - // a very long way behind then we will actually skip - but we'll still tell - // the renderer (or whoever is downstream) that they should handle quality. - - return E_FAIL; // Tell the renderer to do his thing. - -} - - - -// This will avoid several hundred useless warnings if compiled -W4 by MS VC++ v4 -#pragma warning(disable:4514) - - diff --git a/src/BaseClasses/vtrans.h b/src/BaseClasses/vtrans.h deleted file mode 100644 index 5135266941..0000000000 --- a/src/BaseClasses/vtrans.h +++ /dev/null @@ -1,143 +0,0 @@ -//------------------------------------------------------------------------------ -// File: VTrans.h -// -// Desc: DirectShow base classes - defines a video transform class. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// This class is derived from CTransformFilter, but is specialised to handle -// the requirements of video quality control by frame dropping. -// This is a non-in-place transform, (i.e. it copies the data) such as a decoder. - -class CVideoTransformFilter : public CTransformFilter -{ - public: - - CVideoTransformFilter(TCHAR *, LPUNKNOWN, REFCLSID clsid); - ~CVideoTransformFilter(); - HRESULT EndFlush(); - - // ================================================================= - // ----- override these bits --------------------------------------- - // ================================================================= - // The following methods are in CTransformFilter which is inherited. - // They are mentioned here for completeness - // - // These MUST be supplied in a derived class - // - // NOTE: - // virtual HRESULT Transform(IMediaSample * pIn, IMediaSample *pOut); - // virtual HRESULT CheckInputType(const CMediaType* mtIn) PURE; - // virtual HRESULT CheckTransform - // (const CMediaType* mtIn, const CMediaType* mtOut) PURE; - // static CCOMObject * CreateInstance(LPUNKNOWN, HRESULT *); - // virtual HRESULT DecideBufferSize - // (IMemAllocator * pAllocator, ALLOCATOR_PROPERTIES *pprop) PURE; - // virtual HRESULT GetMediaType(int iPosition, CMediaType *pMediaType) PURE; - // - // These MAY also be overridden - // - // virtual HRESULT StopStreaming(); - // virtual HRESULT SetMediaType(PIN_DIRECTION direction,const CMediaType *pmt); - // virtual HRESULT CheckConnect(PIN_DIRECTION dir,IPin *pPin); - // virtual HRESULT BreakConnect(PIN_DIRECTION dir); - // virtual HRESULT CompleteConnect(PIN_DIRECTION direction,IPin *pReceivePin); - // virtual HRESULT EndOfStream(void); - // virtual HRESULT BeginFlush(void); - // virtual HRESULT EndFlush(void); - // virtual HRESULT NewSegment - // (REFERENCE_TIME tStart,REFERENCE_TIME tStop,double dRate); -#ifdef PERF - - // If you override this - ensure that you register all these ids - // as well as any of your own, - virtual void RegisterPerfId() { - m_idSkip = MSR_REGISTER(TEXT("Video Transform Skip frame")); - m_idFrameType = MSR_REGISTER(TEXT("Video transform frame type")); - m_idLate = MSR_REGISTER(TEXT("Video Transform Lateness")); - m_idTimeTillKey = MSR_REGISTER(TEXT("Video Transform Estd. time to next key")); - CTransformFilter::RegisterPerfId(); - } -#endif - - protected: - - // =========== QUALITY MANAGEMENT IMPLEMENTATION ======================== - // Frames are assumed to come in three types: - // Type 1: an AVI key frame or an MPEG I frame. - // This frame can be decoded with no history. - // Dropping this frame means that no further frame can be decoded - // until the next type 1 frame. - // Type 1 frames are sync points. - // Type 2: an AVI non-key frame or an MPEG P frame. - // This frame cannot be decoded unless the previous type 1 frame was - // decoded and all type 2 frames since have been decoded. - // Dropping this frame means that no further frame can be decoded - // until the next type 1 frame. - // Type 3: An MPEG B frame. - // This frame cannot be decoded unless the previous type 1 or 2 frame - // has been decoded AND the subsequent type 1 or 2 frame has also - // been decoded. (This requires decoding the frames out of sequence). - // Dropping this frame affects no other frames. This implementation - // does not allow for these. All non-sync-point frames are treated - // as being type 2. - // - // The spacing of frames of type 1 in a file is not guaranteed. There MUST - // be a type 1 frame at (well, near) the start of the file in order to start - // decoding at all. After that there could be one every half second or so, - // there could be one at the start of each scene (aka "cut", "shot") or - // there could be no more at all. - // If there is only a single type 1 frame then NO FRAMES CAN BE DROPPED - // without losing all the rest of the movie. There is no way to tell whether - // this is the case, so we find that we are in the gambling business. - // To try to improve the odds, we record the greatest interval between type 1s - // that we have seen and we bet on things being no worse than this in the - // future. - - // You can tell if it's a type 1 frame by calling IsSyncPoint(). - // there is no architected way to test for a type 3, so you should override - // the quality management here if you have B-frames. - - int m_nKeyFramePeriod; // the largest observed interval between type 1 frames - // 1 means every frame is type 1, 2 means every other. - - int m_nFramesSinceKeyFrame; // Used to count frames since the last type 1. - // becomes the new m_nKeyFramePeriod if greater. - - BOOL m_bSkipping; // we are skipping to the next type 1 frame - -#ifdef PERF - int m_idFrameType; // MSR id Frame type. 1=Key, 2="non-key" - int m_idSkip; // MSR id skipping - int m_idLate; // MSR id lateness - int m_idTimeTillKey; // MSR id for guessed time till next key frame. -#endif - - virtual HRESULT StartStreaming(); - - HRESULT AbortPlayback(HRESULT hr); // if something bad happens - - HRESULT Receive(IMediaSample *pSample); - - HRESULT AlterQuality(Quality q); - - BOOL ShouldSkipFrame(IMediaSample * pIn); - - int m_itrLate; // lateness from last Quality message - // (this overflows at 214 secs late). - int m_tDecodeStart; // timeGetTime when decode started. - int m_itrAvgDecode; // Average decode time in reference units. - - BOOL m_bNoSkip; // debug - no skipping. - - // We send an EC_QUALITY_CHANGE notification to the app if we have to degrade. - // We send one when we start degrading, not one for every frame, this means - // we track whether we've sent one yet. - BOOL m_bQualityChanged; - - // When non-zero, don't pass anything to renderer until next keyframe - // If there are few keys, give up and eventually draw something - int m_nWaitForKey; -}; diff --git a/src/BaseClasses/winctrl.cpp b/src/BaseClasses/winctrl.cpp deleted file mode 100644 index 9998e26a05..0000000000 --- a/src/BaseClasses/winctrl.cpp +++ /dev/null @@ -1,1977 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WinCtrl.cpp -// -// Desc: DirectShow base classes - implements video control interface class. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include - -// The control interface methods require us to be connected - -#define CheckConnected(pin,code) \ -{ \ - if(pin == NULL) { \ - ASSERT(!TEXT("Pin not set")); \ - } \ - else if(pin->IsConnected() == FALSE) { \ - return (code); \ - } \ -} - -// This checks to see whether the window has a drain. An application can in -// most environments set the owner/parent of windows so that they appear in -// a compound document context (for example). In this case, the application -// would probably like to be told of any keyboard/mouse messages. Therefore -// we pass these messages on untranslated, returning TRUE if we're successful - -BOOL WINAPI PossiblyEatMessage(HWND hwndDrain, UINT uMsg, WPARAM wParam, LPARAM lParam) { - if(hwndDrain != NULL && !InSendMessage()) { - switch(uMsg) { - case WM_CHAR: - case WM_DEADCHAR: - case WM_KEYDOWN: - case WM_KEYUP: - case WM_LBUTTONDBLCLK: - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_MBUTTONDBLCLK: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_MOUSEACTIVATE: - case WM_MOUSEMOVE: - // If we pass this on we don't get any mouse clicks - //case WM_NCHITTEST: - case WM_NCLBUTTONDBLCLK: - case WM_NCLBUTTONDOWN: - case WM_NCLBUTTONUP: - case WM_NCMBUTTONDBLCLK: - case WM_NCMBUTTONDOWN: - case WM_NCMBUTTONUP: - case WM_NCMOUSEMOVE: - case WM_NCRBUTTONDBLCLK: - case WM_NCRBUTTONDOWN: - case WM_NCRBUTTONUP: - case WM_RBUTTONDBLCLK: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_SYSCHAR: - case WM_SYSDEADCHAR: - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - - DbgLog((LOG_TRACE, 2, TEXT("Forwarding %x to drain"))); - PostMessage(hwndDrain, uMsg, wParam, lParam); - - return TRUE; - } - } - return FALSE; -} - - -// This class implements the IVideoWindow control functions (dual interface) -// we support a large number of properties and methods designed to allow the -// client (whether it be an automation controller or a C/C++ application) to -// set and get a number of window related properties such as it's position. -// We also support some methods that duplicate the properties but provide a -// more direct and efficient mechanism as many values may be changed in one - -CBaseControlWindow::CBaseControlWindow( - CBaseFilter *pFilter, // Owning filter - CCritSec *pInterfaceLock, // Locking object - TCHAR *pName, // Object description - LPUNKNOWN pUnk, // Normal COM ownership - HRESULT *phr) : // OLE return code - - CBaseVideoWindow(pName,pUnk), - m_pInterfaceLock(pInterfaceLock), - m_hwndOwner(NULL), - m_hwndDrain(NULL), - m_bAutoShow(TRUE), - m_pFilter(pFilter), - m_bCursorHidden(FALSE), - m_pPin(NULL) { - ASSERT(m_pFilter); - ASSERT(m_pInterfaceLock); - ASSERT(phr); - m_BorderColour = VIDEO_COLOUR; -} - - -// Set the title caption on the base window, we don't do any field checking -// as we really don't care what title they intend to have. We can always get -// it back again later with GetWindowText. The only other complication is to -// do the necessary string conversions between ANSI and OLE Unicode strings - -STDMETHODIMP CBaseControlWindow::put_Caption(BSTR strCaption) { - CheckPointer(strCaption,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); -#ifdef UNICODE - SetWindowText(m_hwnd, strCaption); -#else - CHAR Caption[CAPTION]; - - WideCharToMultiByte(CP_ACP,0,strCaption,-1,Caption,CAPTION,NULL,NULL); - SetWindowText(m_hwnd, Caption); -#endif - return NOERROR; -} - - -// Get the current base window title caption, once again we do no real field -// checking. We allocate a string for the window title to be filled in with -// which ensures the interface doesn't fiddle around with getting memory. A -// BSTR is a normal C string with the length at position (-1), we use the -// WriteBSTR helper function to create the caption to try and avoid OLE32 - -/* NABIL: I un-commented this entire function...*/ - -STDMETHODIMP CBaseControlWindow::get_Caption(BSTR *pstrCaption) { - CheckPointer(pstrCaption,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - WCHAR WideCaption[CAPTION]; - -#ifdef UNICODE - GetWindowText(m_hwnd,WideCaption,CAPTION); -#else - // Convert the ASCII caption to a UNICODE string - - TCHAR Caption[CAPTION]; - GetWindowText(m_hwnd,Caption,CAPTION); - MultiByteToWideChar(CP_ACP,0,Caption,-1,WideCaption,CAPTION); -#endif - return WriteBSTR(pstrCaption,WideCaption); -} - -/*NABIL: END Un-comment*/ - -// Set the window style using GWL_EXSTYLE - -STDMETHODIMP CBaseControlWindow::put_WindowStyleEx(long WindowStyleEx) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - - // Should we be taking off WS_EX_TOPMOST - - if(GetWindowLong(m_hwnd,GWL_EXSTYLE) & WS_EX_TOPMOST) { - if((WindowStyleEx & WS_EX_TOPMOST) == 0) { - SendMessage(m_hwnd,m_ShowStageTop,(WPARAM) FALSE,(LPARAM) 0); - } - } - - // Likewise should we be adding WS_EX_TOPMOST - - if(WindowStyleEx & WS_EX_TOPMOST) { - SendMessage(m_hwnd,m_ShowStageTop,(WPARAM) TRUE,(LPARAM) 0); - WindowStyleEx &= (~WS_EX_TOPMOST); - if(WindowStyleEx == 0) return NOERROR; - } - return DoSetWindowStyle(WindowStyleEx,GWL_EXSTYLE); -} - - -// Gets the current GWL_EXSTYLE base window style - -STDMETHODIMP CBaseControlWindow::get_WindowStyleEx(long *pWindowStyleEx) { - CheckPointer(pWindowStyleEx,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - return DoGetWindowStyle(pWindowStyleEx,GWL_EXSTYLE); -} - - -// Set the window style using GWL_STYLE - -STDMETHODIMP CBaseControlWindow::put_WindowStyle(long WindowStyle) { - // These styles cannot be changed dynamically - - if((WindowStyle & WS_DISABLED) || - (WindowStyle & WS_ICONIC) || - (WindowStyle & WS_MAXIMIZE) || - (WindowStyle & WS_MINIMIZE) || - (WindowStyle & WS_HSCROLL) || - (WindowStyle & WS_VSCROLL)) { - - return E_INVALIDARG; - } - - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - return DoSetWindowStyle(WindowStyle,GWL_STYLE); -} - - -// Get the current GWL_STYLE base window style - -STDMETHODIMP CBaseControlWindow::get_WindowStyle(long *pWindowStyle) { - CheckPointer(pWindowStyle,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - return DoGetWindowStyle(pWindowStyle,GWL_STYLE); -} - - -// Change the base window style or the extended styles depending on whether -// WindowLong is GWL_STYLE or GWL_EXSTYLE. We must call SetWindowPos to have -// the window displayed in it's new style after the change which is a little -// tricky if the window is not currently visible as we realise it offscreen. -// In most cases the client will call get_WindowStyle before they call this -// and then AND and OR in extra bit settings according to the requirements - -HRESULT CBaseControlWindow::DoSetWindowStyle(long Style,long WindowLong) { - RECT WindowRect; - - // Get the window's visibility before setting the style - BOOL bVisible = IsWindowVisible(m_hwnd); - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - - // Set the new style flags for the window - SetWindowLong(m_hwnd,WindowLong,Style); - UINT WindowFlags = SWP_SHOWWINDOW | SWP_FRAMECHANGED | SWP_NOACTIVATE; - WindowFlags |= SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE; - - // Show the window again in the current position - - if(bVisible == TRUE) { - - SetWindowPos(m_hwnd, // Base window handle - HWND_TOP, // Just a place holder - 0,0,0,0, // Leave size and position - WindowFlags); // Just draw it again - - return NOERROR; - } - - // Move the window offscreen so the user doesn't see the changes - - MoveWindow((HWND) m_hwnd, // Base window handle - GetSystemMetrics(SM_CXSCREEN), // Current desktop width - GetSystemMetrics(SM_CYSCREEN), // Likewise it's height - WIDTH(&WindowRect), // Use the same width - HEIGHT(&WindowRect), // Keep height same to - TRUE); // May as well repaint - - // Now show the previously hidden window - - SetWindowPos(m_hwnd, // Base window handle - HWND_TOP, // Just a place holder - 0,0,0,0, // Leave size and position - WindowFlags); // Just draw it again - - ShowWindow(m_hwnd,SW_HIDE); - - if(GetParent(m_hwnd)) { - - MapWindowPoints(HWND_DESKTOP, GetParent(m_hwnd), (LPPOINT)&WindowRect, 2); - } - - MoveWindow((HWND) m_hwnd, // Base window handle - WindowRect.left, // Existing x coordinate - WindowRect.top, // Existing y coordinate - WIDTH(&WindowRect), // Use the same width - HEIGHT(&WindowRect), // Keep height same to - TRUE); // May as well repaint - - return NOERROR; -} - - -// Get the current base window style (either GWL_STYLE or GWL_EXSTYLE) - -HRESULT CBaseControlWindow::DoGetWindowStyle(long *pStyle,long WindowLong) { - *pStyle = GetWindowLong(m_hwnd,WindowLong); - return NOERROR; -} - - -// Change the visibility of the base window, this takes the same parameters -// as the ShowWindow Win32 API does, so the client can have the window hidden -// or shown, minimised to an icon, or maximised to play in full screen mode -// We pass the request on to the base window to actually make the change - -STDMETHODIMP CBaseControlWindow::put_WindowState(long WindowState) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - DoShowWindow(WindowState); - return NOERROR; -} - - -// Get the current window state, this function returns a subset of the SW bit -// settings available in ShowWindow, if the window is visible then SW_SHOW is -// set, if it is hidden then the SW_HIDDEN is set, if it is either minimised -// or maximised then the SW_MINIMIZE or SW_MAXIMIZE is set respectively. The -// other SW bit settings are really set commands not readable output values - -STDMETHODIMP CBaseControlWindow::get_WindowState(long *pWindowState) { - CheckPointer(pWindowState,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - ASSERT(pWindowState); - *pWindowState = FALSE; - - // Is the window visible, a window is termed visible if it is somewhere on - // the current desktop even if it is completely obscured by other windows - // so the flag is a style for each window set with the WS_VISIBLE bit - - if(IsWindowVisible(m_hwnd) == TRUE) { - - // Is the base window iconic - if(IsIconic(m_hwnd) == TRUE) { - *pWindowState |= SW_MINIMIZE; - } - - // Has the window been maximised - else if(IsZoomed(m_hwnd) == TRUE) { - *pWindowState |= SW_MAXIMIZE; - } - - // Window is normal - else { - *pWindowState |= SW_SHOW; - } - - } - else { - *pWindowState |= SW_HIDE; - } - return NOERROR; -} - - -// This makes sure that any palette we realise in the base window (through a -// media type or through the overlay interface) is done in the background and -// is therefore mapped to existing device entries rather than taking it over -// as it will do when we this window gets the keyboard focus. An application -// uses this to make sure it doesn't have it's palette removed by the window - -STDMETHODIMP CBaseControlWindow::put_BackgroundPalette(long BackgroundPalette) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cWindowLock(&m_WindowLock); - - // Check this is a valid automation boolean type - - if(BackgroundPalette != OATRUE) { - if(BackgroundPalette != OAFALSE) { - return E_INVALIDARG; - } - } - - // Make sure the window realises any palette it has again - - m_bBackground = (BYTE) (BackgroundPalette == OATRUE ? TRUE : FALSE); - PostMessage(m_hwnd,m_RealizePalette,0,0); - PaintWindow(FALSE); - - return NOERROR; -} - - -// This returns the current background realisation setting - -STDMETHODIMP -CBaseControlWindow::get_BackgroundPalette(long *pBackgroundPalette) { - CheckPointer(pBackgroundPalette,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cWindowLock(&m_WindowLock); - - // Get the current background palette setting - - *pBackgroundPalette = (m_bBackground == TRUE ? OATRUE : OAFALSE); - return NOERROR; -} - - -// Change the visibility of the base window - -STDMETHODIMP CBaseControlWindow::put_Visible(long Visible) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - - // Check this is a valid automation boolean type - - if(Visible != OATRUE) { - if(Visible != OAFALSE) { - return E_INVALIDARG; - } - } - - // Convert the boolean visibility into SW_SHOW and SW_HIDE - - INT Mode = (Visible == OATRUE ? SW_SHOWNORMAL : SW_HIDE); - DoShowWindow(Mode); - return NOERROR; -} - - -// Return OATRUE if the window is currently visible otherwise OAFALSE - -STDMETHODIMP CBaseControlWindow::get_Visible(long *pVisible) { - CheckPointer(pVisible,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - - // See if the base window has a WS_VISIBLE style - this will return TRUE - // even if the window is completely obscured by other desktop windows, we - // return FALSE if the window is not showing because of earlier calls - - BOOL Mode = IsWindowVisible(m_hwnd); - *pVisible = (Mode == TRUE ? OATRUE : OAFALSE); - return NOERROR; -} - - -// Change the left position of the base window. This keeps the window width -// and height properties the same so it effectively shunts the window left or -// right accordingly - there is the Width property to change that dimension - -STDMETHODIMP CBaseControlWindow::put_Left(long Left) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - BOOL bSuccess; - RECT WindowRect; - - // Get the current window position in a RECT - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - - if(GetParent(m_hwnd)) { - - MapWindowPoints(HWND_DESKTOP, GetParent(m_hwnd), (LPPOINT)&WindowRect, 2); - } - - // Adjust the coordinates ready for SetWindowPos, the window rectangle we - // get back from GetWindowRect is in left,top,right and bottom while the - // coordinates SetWindowPos wants are left,top,width and height values - - WindowRect.bottom = WindowRect.bottom - WindowRect.top; - WindowRect.right = WindowRect.right - WindowRect.left; - UINT WindowFlags = SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE; - - bSuccess = SetWindowPos(m_hwnd, // Window handle - HWND_TOP, // Put it at the top - Left, // New left position - WindowRect.top, // Leave top alone - WindowRect.right, // The WIDTH (not right) - WindowRect.bottom, // The HEIGHT (not bottom) - WindowFlags); // Show window options - - if(bSuccess == FALSE) { - return E_INVALIDARG; - } - return NOERROR; -} - - -// Return the current base window left position - -STDMETHODIMP CBaseControlWindow::get_Left(long *pLeft) { - CheckPointer(pLeft,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - RECT WindowRect; - - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - *pLeft = WindowRect.left; - return NOERROR; -} - - -// Change the current width of the base window. This property complements the -// left position property so we must keep the left edge constant and expand or -// contract to the right, the alternative would be to change the left edge so -// keeping the right edge constant but this is maybe a little more intuitive - -STDMETHODIMP CBaseControlWindow::put_Width(long Width) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - BOOL bSuccess; - RECT WindowRect; - - // Adjust the coordinates ready for SetWindowPos, the window rectangle we - // get back from GetWindowRect is in left,top,right and bottom while the - // coordinates SetWindowPos wants are left,top,width and height values - - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - - if(GetParent(m_hwnd)) { - - MapWindowPoints(HWND_DESKTOP, GetParent(m_hwnd), (LPPOINT)&WindowRect, 2); - } - - WindowRect.bottom = WindowRect.bottom - WindowRect.top; - UINT WindowFlags = SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE; - - // This seems to have a bug in that calling SetWindowPos on a window with - // just the width changing causes it to ignore the width that you pass in - // and sets it to a mimimum value of 110 pixels wide (Windows NT 3.51) - - bSuccess = SetWindowPos(m_hwnd, // Window handle - HWND_TOP, // Put it at the top - WindowRect.left, // Leave left alone - WindowRect.top, // Leave top alone - Width, // New WIDTH dimension - WindowRect.bottom, // The HEIGHT (not bottom) - WindowFlags); // Show window options - - if(bSuccess == FALSE) { - return E_INVALIDARG; - } - return NOERROR; -} - - -// Return the current base window width - -STDMETHODIMP CBaseControlWindow::get_Width(long *pWidth) { - CheckPointer(pWidth,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - RECT WindowRect; - - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - *pWidth = WindowRect.right - WindowRect.left; - return NOERROR; -} - - -// This allows the client program to change the top position for the window in -// the same way that changing the left position does not affect the width of -// the image so changing the top position does not affect the window height - -STDMETHODIMP CBaseControlWindow::put_Top(long Top) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - BOOL bSuccess; - RECT WindowRect; - - // Get the current window position in a RECT - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - - if(GetParent(m_hwnd)) { - - MapWindowPoints(HWND_DESKTOP, GetParent(m_hwnd), (LPPOINT)&WindowRect, 2); - } - - // Adjust the coordinates ready for SetWindowPos, the window rectangle we - // get back from GetWindowRect is in left,top,right and bottom while the - // coordinates SetWindowPos wants are left,top,width and height values - - WindowRect.bottom = WindowRect.bottom - WindowRect.top; - WindowRect.right = WindowRect.right - WindowRect.left; - UINT WindowFlags = SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE; - - bSuccess = SetWindowPos(m_hwnd, // Window handle - HWND_TOP, // Put it at the top - WindowRect.left, // Leave left alone - Top, // New top position - WindowRect.right, // The WIDTH (not right) - WindowRect.bottom, // The HEIGHT (not bottom) - WindowFlags); // Show window flags - - if(bSuccess == FALSE) { - return E_INVALIDARG; - } - return NOERROR; -} - - -// Return the current base window top position - -STDMETHODIMP CBaseControlWindow::get_Top(long *pTop) { - CheckPointer(pTop,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - RECT WindowRect; - - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - *pTop = WindowRect.top; - return NOERROR; -} - - -// Change the height of the window, this complements the top property so when -// we change this we must keep the top position for the base window, as said -// before we could keep the bottom and grow upwards although this is perhaps -// a little more intuitive since we already have a top position property - -STDMETHODIMP CBaseControlWindow::put_Height(long Height) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - BOOL bSuccess; - RECT WindowRect; - - // Adjust the coordinates ready for SetWindowPos, the window rectangle we - // get back from GetWindowRect is in left,top,right and bottom while the - // coordinates SetWindowPos wants are left,top,width and height values - - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - - if(GetParent(m_hwnd)) { - - MapWindowPoints(HWND_DESKTOP, GetParent(m_hwnd), (LPPOINT)&WindowRect, 2); - } - - WindowRect.right = WindowRect.right - WindowRect.left; - UINT WindowFlags = SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE; - - bSuccess = SetWindowPos(m_hwnd, // Window handle - HWND_TOP, // Put it at the top - WindowRect.left, // Leave left alone - WindowRect.top, // Leave top alone - WindowRect.right, // The WIDTH (not right) - Height, // New height dimension - WindowFlags); // Show window flags - - if(bSuccess == FALSE) { - return E_INVALIDARG; - } - return NOERROR; -} - - -// Return the current base window height - -STDMETHODIMP CBaseControlWindow::get_Height(long *pHeight) { - CheckPointer(pHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - RECT WindowRect; - - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - *pHeight = WindowRect.bottom - WindowRect.top; - return NOERROR; -} - - -// This can be called to change the owning window. Setting the owner is done -// through this function, however to make the window a true child window the -// style must also be set to WS_CHILD. After resetting the owner to NULL an -// application should also set the style to WS_OVERLAPPED | WS_CLIPCHILDREN. - -// We cannot lock the object here because the SetParent causes an interthread -// SendMessage to the owner window. If they are in GetState we will sit here -// incomplete with the critical section locked therefore blocking out source -// filter threads from accessing us. Because the source thread can't enter us -// it can't get buffers or call EndOfStream so the GetState will not complete - -STDMETHODIMP CBaseControlWindow::put_Owner(OAHWND Owner) { - // Check we are connected otherwise reject the call - - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - m_hwndOwner = (HWND) Owner; - HWND hwndParent = m_hwndOwner; - - // Add or remove WS_CHILD as appropriate - - LONG Style = GetWindowLong(m_hwnd,GWL_STYLE); - if(Owner == NULL) { - Style &= (~WS_CHILD); - } - else { - Style |= (WS_CHILD); - } - SetWindowLong(m_hwnd,GWL_STYLE,Style); - - // Don't call this with the filter locked - - SetParent(m_hwnd,hwndParent); - - PaintWindow(TRUE); - NOTE1("Changed parent %lx",hwndParent); - - return NOERROR; -} - - -// This complements the put_Owner to get the current owning window property -// we always return NOERROR although the returned window handle may be NULL -// to indicate no owning window (the desktop window doesn't qualify as one) -// If an application sets the owner we call SetParent, however that returns -// NULL until the WS_CHILD bit is set on, so we store the owner internally - -STDMETHODIMP CBaseControlWindow::get_Owner(OAHWND *Owner) { - CheckPointer(Owner,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - *Owner = (OAHWND) m_hwndOwner; - return NOERROR; -} - - -// And renderer supporting IVideoWindow may have an HWND set who will get any -// keyboard and mouse messages we receive posted on to them. This is separate -// from setting an owning window. By separating the two, applications may get -// messages sent on even when they have set no owner (perhaps it's maximised) - -STDMETHODIMP CBaseControlWindow::put_MessageDrain(OAHWND Drain) { - // Check we are connected otherwise reject the call - - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - m_hwndDrain = (HWND) Drain; - return NOERROR; -} - - -// Return the current message drain - -STDMETHODIMP CBaseControlWindow::get_MessageDrain(OAHWND *Drain) { - CheckPointer(Drain,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - *Drain = (OAHWND) m_hwndDrain; - return NOERROR; -} - - -// This is called by the filter graph to inform us of a message we should know -// is being sent to our owning window. We have this because as a child window -// we do not get certain messages that are only sent to top level windows. We -// must see the palette changed/changing/query messages so that we know if we -// have the foreground palette or not. We pass the message on to our window -// using SendMessage - this will cause an interthread send message to occur - -STDMETHODIMP -CBaseControlWindow::NotifyOwnerMessage(OAHWND hwnd, // Window handle - long uMsg, // Message ID - LONG_PTR wParam, // Parameters - LONG_PTR lParam) // for message -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - - // Only interested in these Windows messages - - switch(uMsg) { - - case WM_SYSCOLORCHANGE: - case WM_PALETTECHANGED: - case WM_PALETTEISCHANGING: - case WM_QUERYNEWPALETTE: - case WM_DEVMODECHANGE: - case WM_DISPLAYCHANGE: - case WM_ACTIVATEAPP: - - // If we do not have an owner then ignore - - if(m_hwndOwner == NULL) { - return NOERROR; - } - SendMessage(m_hwnd,uMsg,(WPARAM)wParam,(LPARAM)lParam); - break; - - // do NOT fwd WM_MOVE. the parameters are the location of the parent - // window, NOT what the renderer should be looking at. But we need - // to make sure the overlay is moved with the parent window, so we - // do this. - case WM_MOVE: - PostMessage(m_hwnd,WM_PAINT,0,0); - break; - } - return NOERROR; -} - - -// Allow an application to have us set the base window in the foreground. We -// have this because it is difficult for one thread to do do this to a window -// owned by another thread. We ask the base window class to do the real work - -STDMETHODIMP CBaseControlWindow::SetWindowForeground(long Focus) { - // Check this is a valid automation boolean type - - if(Focus != OATRUE) { - if(Focus != OAFALSE) { - return E_INVALIDARG; - } - } - - // We shouldn't lock as this sends a message - - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - BOOL bFocus = (Focus == OATRUE ? TRUE : FALSE); - DoSetWindowForeground(bFocus); - - return NOERROR; -} - - -// This allows a client to set the complete window size and position in one -// atomic operation. The same affect can be had by changing each dimension -// in turn through their individual properties although some flashing will -// occur as each of them gets updated (they are better set at design time) - -STDMETHODIMP -CBaseControlWindow::SetWindowPosition(long Left,long Top,long Width,long Height) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - BOOL bSuccess; - - // Set the new size and position - UINT WindowFlags = SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE; - - ASSERT(IsWindow(m_hwnd)); - bSuccess = SetWindowPos(m_hwnd, // Window handle - HWND_TOP, // Put it at the top - Left, // Left position - Top, // Top position - Width, // Window width - Height, // Window height - WindowFlags); // Show window flags - ASSERT(bSuccess); -#ifdef DEBUG - DbgLog((LOG_TRACE, 1, TEXT("SWP failed error %d"), GetLastError())); -#endif - if(bSuccess == FALSE) { - return E_INVALIDARG; - } - return NOERROR; -} - - -// This complements the SetWindowPosition to return the current window place -// in device coordinates. As before the same information can be retrived by -// calling the property get functions individually but this is atomic and is -// therefore more suitable to a live environment rather than design time - -STDMETHODIMP -CBaseControlWindow::GetWindowPosition(long *pLeft,long *pTop,long *pWidth,long *pHeight) { - // Should check the pointers are not NULL - - CheckPointer(pLeft,E_POINTER); - CheckPointer(pTop,E_POINTER); - CheckPointer(pWidth,E_POINTER); - CheckPointer(pHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - RECT WindowRect; - - // Get the current window coordinates - - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - - // Convert the RECT into left,top,width and height values - - *pLeft = WindowRect.left; - *pTop = WindowRect.top; - *pWidth = WindowRect.right - WindowRect.left; - *pHeight = WindowRect.bottom - WindowRect.top; - - return NOERROR; -} - - -// When a window is maximised or iconic calling GetWindowPosition will return -// the current window position (likewise for the properties). However if the -// restored size (ie the size we'll return to when normally shown) is needed -// then this should be used. When in a normal position (neither iconic nor -// maximised) then this returns the same coordinates as GetWindowPosition - -STDMETHODIMP -CBaseControlWindow::GetRestorePosition(long *pLeft,long *pTop,long *pWidth,long *pHeight) { - // Should check the pointers are not NULL - - CheckPointer(pLeft,E_POINTER); - CheckPointer(pTop,E_POINTER); - CheckPointer(pWidth,E_POINTER); - CheckPointer(pHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - - // Use GetWindowPlacement to find the restore position - - WINDOWPLACEMENT Place; - Place.length = sizeof(WINDOWPLACEMENT); - EXECUTE_ASSERT(GetWindowPlacement(m_hwnd,&Place)); - - RECT WorkArea; - - // We must take into account any task bar present - - if(SystemParametersInfo(SPI_GETWORKAREA,0,&WorkArea,FALSE) == TRUE) { - if(GetParent(m_hwnd) == NULL) { - Place.rcNormalPosition.top += WorkArea.top; - Place.rcNormalPosition.bottom += WorkArea.top; - Place.rcNormalPosition.left += WorkArea.left; - Place.rcNormalPosition.right += WorkArea.left; - } - } - - // Convert the RECT into left,top,width and height values - - *pLeft = Place.rcNormalPosition.left; - *pTop = Place.rcNormalPosition.top; - *pWidth = Place.rcNormalPosition.right - Place.rcNormalPosition.left; - *pHeight = Place.rcNormalPosition.bottom - Place.rcNormalPosition.top; - - return NOERROR; -} - - -// Return the current border colour, if we are playing something to a subset -// of the base window display there is an outside area exposed. The default -// action is to paint this colour in the Windows background colour (defined -// as value COLOR_WINDOW) We reset to this default when we're disconnected - -STDMETHODIMP CBaseControlWindow::get_BorderColor(long *Color) { - CheckPointer(Color,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - *Color = (long) m_BorderColour; - return NOERROR; -} - - -// This can be called to set the current border colour - -STDMETHODIMP CBaseControlWindow::put_BorderColor(long Color) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - - // Have the window repainted with the new border colour - - m_BorderColour = (COLORREF) Color; - PaintWindow(TRUE); - return NOERROR; -} - - -// Delegate fullscreen handling to plug in distributor - -STDMETHODIMP CBaseControlWindow::get_FullScreenMode(long *FullScreenMode) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CheckPointer(FullScreenMode,E_POINTER); - return E_NOTIMPL; -} - - -// Delegate fullscreen handling to plug in distributor - -STDMETHODIMP CBaseControlWindow::put_FullScreenMode(long FullScreenMode) { - return E_NOTIMPL; -} - - -// This sets the auto show property, this property causes the base window to -// be displayed whenever we change state. This allows an application to have -// to do nothing to have the window appear but still allow them to change the -// default behaviour if for example they want to keep it hidden for longer - -STDMETHODIMP CBaseControlWindow::put_AutoShow(long AutoShow) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - - // Check this is a valid automation boolean type - - if(AutoShow != OATRUE) { - if(AutoShow != OAFALSE) { - return E_INVALIDARG; - } - } - - m_bAutoShow = (AutoShow == OATRUE ? TRUE : FALSE); - return NOERROR; -} - - -// This can be called to get the current auto show flag. The flag is updated -// when we connect and disconnect and through this interface all of which are -// controlled and serialised by means of the main renderer critical section - -STDMETHODIMP CBaseControlWindow::get_AutoShow(long *AutoShow) { - CheckPointer(AutoShow,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - *AutoShow = (m_bAutoShow == TRUE ? OATRUE : OAFALSE); - return NOERROR; -} - - -// Return the minimum ideal image size for the current video. This may differ -// to the actual video dimensions because we may be using DirectDraw hardware -// that has specific stretching requirements. For example the Cirrus Logic -// cards have a minimum stretch factor depending on the overlay surface size - -STDMETHODIMP -CBaseControlWindow::GetMinIdealImageSize(long *pWidth,long *pHeight) { - CheckPointer(pWidth,E_POINTER); - CheckPointer(pHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - FILTER_STATE State; - - // Must not be stopped for this to work correctly - - m_pFilter->GetState(0,&State); - if(State == State_Stopped) { - return VFW_E_WRONG_STATE; - } - - RECT DefaultRect = GetDefaultRect(); - *pWidth = WIDTH(&DefaultRect); - *pHeight = HEIGHT(&DefaultRect); - return NOERROR; -} - - -// Return the maximum ideal image size for the current video. This may differ -// to the actual video dimensions because we may be using DirectDraw hardware -// that has specific stretching requirements. For example the Cirrus Logic -// cards have a maximum stretch factor depending on the overlay surface size - -STDMETHODIMP -CBaseControlWindow::GetMaxIdealImageSize(long *pWidth,long *pHeight) { - CheckPointer(pWidth,E_POINTER); - CheckPointer(pHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - FILTER_STATE State; - - // Must not be stopped for this to work correctly - - m_pFilter->GetState(0,&State); - if(State == State_Stopped) { - return VFW_E_WRONG_STATE; - } - - RECT DefaultRect = GetDefaultRect(); - *pWidth = WIDTH(&DefaultRect); - *pHeight = HEIGHT(&DefaultRect); - return NOERROR; -} - - -// Allow an application to hide the cursor on our window - -STDMETHODIMP -CBaseControlWindow::HideCursor(long HideCursor) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - - // Check this is a valid automation boolean type - - if(HideCursor != OATRUE) { - if(HideCursor != OAFALSE) { - return E_INVALIDARG; - } - } - - m_bCursorHidden = (HideCursor == OATRUE ? TRUE : FALSE); - return NOERROR; -} - - -// Returns whether we have the cursor hidden or not - -STDMETHODIMP CBaseControlWindow::IsCursorHidden(long *CursorHidden) { - CheckPointer(CursorHidden,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - *CursorHidden = (m_bCursorHidden == TRUE ? OATRUE : OAFALSE); - return NOERROR; -} - - -// This class implements the IBasicVideo control functions (dual interface) -// we support a large number of properties and methods designed to allow the -// client (whether it be an automation controller or a C/C++ application) to -// set and get a number of video related properties such as the native video -// size. We support some methods that duplicate the properties but provide a -// more direct and efficient mechanism as many values may be changed in one - -CBaseControlVideo::CBaseControlVideo( - CBaseFilter *pFilter, // Owning filter - CCritSec *pInterfaceLock, // Locking object - TCHAR *pName, // Object description - LPUNKNOWN pUnk, // Normal COM ownership - HRESULT *phr) : // OLE return code - - CBaseBasicVideo(pName,pUnk), - m_pFilter(pFilter), - m_pInterfaceLock(pInterfaceLock), - m_pPin(NULL) { - ASSERT(m_pFilter); - ASSERT(m_pInterfaceLock); - ASSERT(phr); -} - -// Return an approximate average time per frame - -STDMETHODIMP CBaseControlVideo::get_AvgTimePerFrame(REFTIME *pAvgTimePerFrame) { - CheckPointer(pAvgTimePerFrame,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if(pVideoInfo == NULL) - return E_OUTOFMEMORY; - COARefTime AvgTime(pVideoInfo->AvgTimePerFrame); - *pAvgTimePerFrame = (REFTIME) AvgTime; - - return NOERROR; -} - - -// Return an approximate bit rate for the video - -STDMETHODIMP CBaseControlVideo::get_BitRate(long *pBitRate) { - CheckPointer(pBitRate,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if(pVideoInfo == NULL) - return E_OUTOFMEMORY; - *pBitRate = pVideoInfo->dwBitRate; - return NOERROR; -} - - -// Return an approximate bit error rate - -STDMETHODIMP CBaseControlVideo::get_BitErrorRate(long *pBitErrorRate) { - CheckPointer(pBitErrorRate,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if(pVideoInfo == NULL) - return E_OUTOFMEMORY; - *pBitErrorRate = pVideoInfo->dwBitErrorRate; - return NOERROR; -} - - -// This returns the current video width - -STDMETHODIMP CBaseControlVideo::get_VideoWidth(long *pVideoWidth) { - CheckPointer(pVideoWidth,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if(pVideoInfo == NULL) - return E_OUTOFMEMORY; - *pVideoWidth = pVideoInfo->bmiHeader.biWidth; - return NOERROR; -} - - -// This returns the current video height - -STDMETHODIMP CBaseControlVideo::get_VideoHeight(long *pVideoHeight) { - CheckPointer(pVideoHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if(pVideoInfo == NULL) - return E_OUTOFMEMORY; - *pVideoHeight = pVideoInfo->bmiHeader.biHeight; - return NOERROR; -} - - -// This returns the current palette the video is using as an array allocated -// by the user. To remain consistent we use PALETTEENTRY fields to return the -// colours in rather than RGBQUADs that multimedia decided to use. The memory -// is allocated by the user so we simple copy each in turn. We check that the -// number of entries requested and the start position offset are both valid -// If the number of entries evaluates to zero then we return an S_FALSE code - -STDMETHODIMP CBaseControlVideo::GetVideoPaletteEntries(long StartIndex, - long Entries, - long *pRetrieved, - long *pPalette) { - CheckPointer(pRetrieved,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - CMediaType MediaType; - - // Get the video format from the derived class - - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if(pVideoInfo == NULL) - return E_OUTOFMEMORY; - BITMAPINFOHEADER *pHeader = HEADER(pVideoInfo); - - // Is the current format palettised - - if(PALETTISED(pVideoInfo) == FALSE) { - *pRetrieved = 0; - return VFW_E_NO_PALETTE_AVAILABLE; - } - - // Do they just want to know how many are available - - if(pPalette == NULL) { - *pRetrieved = pHeader->biClrUsed; - return NOERROR; - } - - // Make sure the start position is a valid offset - - if(StartIndex >= (LONG) pHeader->biClrUsed || StartIndex < 0) { - *pRetrieved = 0; - return E_INVALIDARG; - } - - // Correct the number we can retrieve - - LONG Available = (LONG) pHeader->biClrUsed - StartIndex; - *pRetrieved = max(0,min(Available,Entries)); - if(*pRetrieved == 0) { - return S_FALSE; - } - - // Copy the palette entries to the output buffer - - PALETTEENTRY *pEntries = (PALETTEENTRY *) pPalette; - RGBQUAD *pColours = COLORS(pVideoInfo) + StartIndex; - - for(LONG Count = 0;Count < *pRetrieved;Count++) { - pEntries[Count].peRed = pColours[Count].rgbRed; - pEntries[Count].peGreen = pColours[Count].rgbGreen; - pEntries[Count].peBlue = pColours[Count].rgbBlue; - pEntries[Count].peFlags = 0; - } - return NOERROR; -} - - -// This returns the current video dimensions as a method rather than a number -// of individual property get calls. For the same reasons as said before we -// cannot access the renderer media type directly as the window object thread -// may be updating it since dynamic format changes may change these values - -STDMETHODIMP CBaseControlVideo::GetVideoSize(long *pWidth,long *pHeight) { - CheckPointer(pWidth,E_POINTER); - CheckPointer(pHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - - // Get the video format from the derived class - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if(pVideoInfo == NULL) - return E_OUTOFMEMORY; - *pWidth = pVideoInfo->bmiHeader.biWidth; - *pHeight = pVideoInfo->bmiHeader.biHeight; - return NOERROR; -} - - -// Set the source video rectangle as left,top,right and bottom coordinates -// rather than left,top,width and height as per OLE automation interfaces -// Then pass the rectangle on to the window object to set the source - -STDMETHODIMP -CBaseControlVideo::SetSourcePosition(long Left,long Top,long Width,long Height) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - SourceRect.left = Left; - SourceRect.top = Top; - SourceRect.right = Left + Width; - SourceRect.bottom = Top + Height; - - // Check the source rectangle is valid - - HRESULT hr = CheckSourceRect(&SourceRect); - if(FAILED(hr)) { - return hr; - } - - // Now set the source rectangle - - hr = SetSourceRect(&SourceRect); - if(FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the source rectangle in left,top,width and height rather than the -// left,top,right and bottom values that RECT uses (and which the window -// object returns through GetSourceRect) which requires a little work - -STDMETHODIMP -CBaseControlVideo::GetSourcePosition(long *pLeft,long *pTop,long *pWidth,long *pHeight) { - // Should check the pointers are non NULL - - CheckPointer(pLeft,E_POINTER); - CheckPointer(pTop,E_POINTER); - CheckPointer(pWidth,E_POINTER); - CheckPointer(pHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - RECT SourceRect; - - CAutoLock cInterfaceLock(m_pInterfaceLock); - GetSourceRect(&SourceRect); - - *pLeft = SourceRect.left; - *pTop = SourceRect.top; - *pWidth = WIDTH(&SourceRect); - *pHeight = HEIGHT(&SourceRect); - - return NOERROR; -} - - -// Set the video destination as left,top,right and bottom coordinates rather -// than the left,top,width and height uses as per OLE automation interfaces -// Then pass the rectangle on to the window object to set the destination - -STDMETHODIMP -CBaseControlVideo::SetDestinationPosition(long Left,long Top,long Width,long Height) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - - DestinationRect.left = Left; - DestinationRect.top = Top; - DestinationRect.right = Left + Width; - DestinationRect.bottom = Top + Height; - - // Check the target rectangle is valid - - HRESULT hr = CheckTargetRect(&DestinationRect); - if(FAILED(hr)) { - return hr; - } - - // Now set the new target rectangle - - hr = SetTargetRect(&DestinationRect); - if(FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the destination rectangle in left,top,width and height rather than -// the left,top,right and bottom values that RECT uses (and which the window -// object returns through GetDestinationRect) which requires a little work - -STDMETHODIMP -CBaseControlVideo::GetDestinationPosition(long *pLeft,long *pTop,long *pWidth,long *pHeight) { - // Should check the pointers are not NULL - - CheckPointer(pLeft,E_POINTER); - CheckPointer(pTop,E_POINTER); - CheckPointer(pWidth,E_POINTER); - CheckPointer(pHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - RECT DestinationRect; - - CAutoLock cInterfaceLock(m_pInterfaceLock); - GetTargetRect(&DestinationRect); - - *pLeft = DestinationRect.left; - *pTop = DestinationRect.top; - *pWidth = WIDTH(&DestinationRect); - *pHeight = HEIGHT(&DestinationRect); - - return NOERROR; -} - - -// Set the source left position, the source rectangle we get back from the -// window object is a true rectangle in left,top,right and bottom positions -// so all we have to do is to update the left position and pass it back. We -// must keep the current width constant when we're updating this property - -STDMETHODIMP CBaseControlVideo::put_SourceLeft(long SourceLeft) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - GetSourceRect(&SourceRect); - SourceRect.right = SourceLeft + WIDTH(&SourceRect); - SourceRect.left = SourceLeft; - - // Check the source rectangle is valid - - HRESULT hr = CheckSourceRect(&SourceRect); - if(FAILED(hr)) { - return hr; - } - - // Now set the source rectangle - - hr = SetSourceRect(&SourceRect); - if(FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the current left source video position - -STDMETHODIMP CBaseControlVideo::get_SourceLeft(long *pSourceLeft) { - CheckPointer(pSourceLeft,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - - GetSourceRect(&SourceRect); - *pSourceLeft = SourceRect.left; - return NOERROR; -} - - -// Set the source width, we get the current source rectangle and then update -// the right position to be the left position (thereby keeping it constant) -// plus the new source width we are passed in (it expands to the right) - -STDMETHODIMP CBaseControlVideo::put_SourceWidth(long SourceWidth) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - GetSourceRect(&SourceRect); - SourceRect.right = SourceRect.left + SourceWidth; - - // Check the source rectangle is valid - - HRESULT hr = CheckSourceRect(&SourceRect); - if(FAILED(hr)) { - return hr; - } - - // Now set the source rectangle - - hr = SetSourceRect(&SourceRect); - if(FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the current source width - -STDMETHODIMP CBaseControlVideo::get_SourceWidth(long *pSourceWidth) { - CheckPointer(pSourceWidth,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - - GetSourceRect(&SourceRect); - *pSourceWidth = WIDTH(&SourceRect); - return NOERROR; -} - - -// Set the source top position - changing this property does not affect the -// current source height. So changing this shunts the source rectangle up and -// down appropriately. Changing the height complements this functionality by -// keeping the top position constant and simply changing the source height - -STDMETHODIMP CBaseControlVideo::put_SourceTop(long SourceTop) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - GetSourceRect(&SourceRect); - SourceRect.bottom = SourceTop + HEIGHT(&SourceRect); - SourceRect.top = SourceTop; - - // Check the source rectangle is valid - - HRESULT hr = CheckSourceRect(&SourceRect); - if(FAILED(hr)) { - return hr; - } - - // Now set the source rectangle - - hr = SetSourceRect(&SourceRect); - if(FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the current top position - -STDMETHODIMP CBaseControlVideo::get_SourceTop(long *pSourceTop) { - CheckPointer(pSourceTop,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - - GetSourceRect(&SourceRect); - *pSourceTop = SourceRect.top; - return NOERROR; -} - - -// Set the source height - -STDMETHODIMP CBaseControlVideo::put_SourceHeight(long SourceHeight) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - GetSourceRect(&SourceRect); - SourceRect.bottom = SourceRect.top + SourceHeight; - - // Check the source rectangle is valid - - HRESULT hr = CheckSourceRect(&SourceRect); - if(FAILED(hr)) { - return hr; - } - - // Now set the source rectangle - - hr = SetSourceRect(&SourceRect); - if(FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the current source height - -STDMETHODIMP CBaseControlVideo::get_SourceHeight(long *pSourceHeight) { - CheckPointer(pSourceHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - - GetSourceRect(&SourceRect); - *pSourceHeight = HEIGHT(&SourceRect); - return NOERROR; -} - - -// Set the target left position, the target rectangle we get back from the -// window object is a true rectangle in left,top,right and bottom positions -// so all we have to do is to update the left position and pass it back. We -// must keep the current width constant when we're updating this property - -STDMETHODIMP CBaseControlVideo::put_DestinationLeft(long DestinationLeft) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - GetTargetRect(&DestinationRect); - DestinationRect.right = DestinationLeft + WIDTH(&DestinationRect); - DestinationRect.left = DestinationLeft; - - // Check the target rectangle is valid - - HRESULT hr = CheckTargetRect(&DestinationRect); - if(FAILED(hr)) { - return hr; - } - - // Now set the new target rectangle - - hr = SetTargetRect(&DestinationRect); - if(FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the left position for the destination rectangle - -STDMETHODIMP CBaseControlVideo::get_DestinationLeft(long *pDestinationLeft) { - CheckPointer(pDestinationLeft,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - - GetTargetRect(&DestinationRect); - *pDestinationLeft = DestinationRect.left; - return NOERROR; -} - - -// Set the destination width - -STDMETHODIMP CBaseControlVideo::put_DestinationWidth(long DestinationWidth) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - GetTargetRect(&DestinationRect); - DestinationRect.right = DestinationRect.left + DestinationWidth; - - // Check the target rectangle is valid - - HRESULT hr = CheckTargetRect(&DestinationRect); - if(FAILED(hr)) { - return hr; - } - - // Now set the new target rectangle - - hr = SetTargetRect(&DestinationRect); - if(FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the width for the destination rectangle - -STDMETHODIMP CBaseControlVideo::get_DestinationWidth(long *pDestinationWidth) { - CheckPointer(pDestinationWidth,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - - GetTargetRect(&DestinationRect); - *pDestinationWidth = WIDTH(&DestinationRect); - return NOERROR; -} - - -// Set the target top position - changing this property does not affect the -// current target height. So changing this shunts the target rectangle up and -// down appropriately. Changing the height complements this functionality by -// keeping the top position constant and simply changing the target height - -STDMETHODIMP CBaseControlVideo::put_DestinationTop(long DestinationTop) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - GetTargetRect(&DestinationRect); - DestinationRect.bottom = DestinationTop + HEIGHT(&DestinationRect); - DestinationRect.top = DestinationTop; - - // Check the target rectangle is valid - - HRESULT hr = CheckTargetRect(&DestinationRect); - if(FAILED(hr)) { - return hr; - } - - // Now set the new target rectangle - - hr = SetTargetRect(&DestinationRect); - if(FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the top position for the destination rectangle - -STDMETHODIMP CBaseControlVideo::get_DestinationTop(long *pDestinationTop) { - CheckPointer(pDestinationTop,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - - GetTargetRect(&DestinationRect); - *pDestinationTop = DestinationRect.top; - return NOERROR; -} - - -// Set the destination height - -STDMETHODIMP CBaseControlVideo::put_DestinationHeight(long DestinationHeight) { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - GetTargetRect(&DestinationRect); - DestinationRect.bottom = DestinationRect.top + DestinationHeight; - - // Check the target rectangle is valid - - HRESULT hr = CheckTargetRect(&DestinationRect); - if(FAILED(hr)) { - return hr; - } - - // Now set the new target rectangle - - hr = SetTargetRect(&DestinationRect); - if(FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the height for the destination rectangle - -STDMETHODIMP CBaseControlVideo::get_DestinationHeight(long *pDestinationHeight) { - CheckPointer(pDestinationHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - - GetTargetRect(&DestinationRect); - *pDestinationHeight = HEIGHT(&DestinationRect); - return NOERROR; -} - - -// Reset the source rectangle to the full video dimensions - -STDMETHODIMP CBaseControlVideo::SetDefaultSourcePosition() { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - HRESULT hr = SetDefaultSourceRect(); - if(FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return S_OK if we're using the default source otherwise S_FALSE - -STDMETHODIMP CBaseControlVideo::IsUsingDefaultSource() { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - return IsDefaultSourceRect(); -} - - -// Reset the video renderer to use the entire playback area - -STDMETHODIMP CBaseControlVideo::SetDefaultDestinationPosition() { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - HRESULT hr = SetDefaultTargetRect(); - if(FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return S_OK if we're using the default target otherwise S_FALSE - -STDMETHODIMP CBaseControlVideo::IsUsingDefaultDestination() { - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - return IsDefaultTargetRect(); -} - - -// Return a copy of the current image in the video renderer - -STDMETHODIMP -CBaseControlVideo::GetCurrentImage(long *pBufferSize,long *pVideoImage) { - CheckPointer(pBufferSize,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - FILTER_STATE State; - - // Make sure we are in a paused state - - if(pVideoImage != NULL) { - m_pFilter->GetState(0,&State); - if(State != State_Paused) { - return VFW_E_NOT_PAUSED; - } - return GetStaticImage(pBufferSize,pVideoImage); - } - - // Just return the memory required - - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if(pVideoInfo == NULL) - return E_OUTOFMEMORY; - RECT SourceRect; - GetSourceRect(&SourceRect); - return GetImageSize(pVideoInfo,pBufferSize,&SourceRect); -} - - -// An application has two ways of using GetCurrentImage, one is to pass a real -// buffer which should be filled with the current image. The other is to pass -// a NULL buffer pointer which is interpreted as asking us to return how much -// memory is required for the image. The constraints for when the latter can -// be called are much looser. To calculate the memory required we synthesize -// a VIDEOINFO that takes into account the source rectangle that's being used - -HRESULT CBaseControlVideo::GetImageSize(VIDEOINFOHEADER *pVideoInfo, - LONG *pBufferSize, - RECT *pSourceRect) { - NOTE("Entering GetImageSize"); - ASSERT(pSourceRect); - - // Check we have the correct input parameters - - if(pSourceRect == NULL || - pVideoInfo == NULL || - pBufferSize == NULL) { - - return E_UNEXPECTED; - } - - // Is the data format compatible - - if(pVideoInfo->bmiHeader.biCompression != BI_RGB) { - if(pVideoInfo->bmiHeader.biCompression != BI_BITFIELDS) { - return E_INVALIDARG; - } - } - - ASSERT(IsRectEmpty(pSourceRect) == FALSE); - - BITMAPINFOHEADER bih; - bih.biWidth = WIDTH(pSourceRect); - bih.biHeight = HEIGHT(pSourceRect); - bih.biBitCount = pVideoInfo->bmiHeader.biBitCount; - LONG Size = DIBSIZE(bih); - Size += GetBitmapFormatSize(HEADER(pVideoInfo)) - SIZE_PREHEADER; - *pBufferSize = Size; - - return NOERROR; -} - - -// Given an IMediaSample containing a linear buffer with an image and a type -// describing the bitmap make a rendering of the image into the output buffer -// This may be called by derived classes who render typical video images to -// handle the IBasicVideo GetCurrentImage method. The pVideoImage pointer may -// be NULL when passed to GetCurrentImage in which case GetImageSize will be -// called instead, which will just do the calculation of the memory required - -HRESULT CBaseControlVideo::CopyImage(IMediaSample *pMediaSample, - VIDEOINFOHEADER *pVideoInfo, - LONG *pBufferSize, - BYTE *pVideoImage, - RECT *pSourceRect) { - NOTE("Entering CopyImage"); - ASSERT(pSourceRect); - BYTE *pCurrentImage; - - // Check we have an image to copy - - if(pMediaSample == NULL || pSourceRect == NULL || - pVideoInfo == NULL || pVideoImage == NULL || - pBufferSize == NULL) { - - return E_UNEXPECTED; - } - - // Is the data format compatible - - if(pVideoInfo->bmiHeader.biCompression != BI_RGB) { - if(pVideoInfo->bmiHeader.biCompression != BI_BITFIELDS) { - return E_INVALIDARG; - } - } - - ASSERT(IsRectEmpty(pSourceRect) == FALSE); - - BITMAPINFOHEADER bih; - bih.biWidth = WIDTH(pSourceRect); - bih.biHeight = HEIGHT(pSourceRect); - bih.biBitCount = pVideoInfo->bmiHeader.biBitCount; - LONG Size = GetBitmapFormatSize(HEADER(pVideoInfo)) - SIZE_PREHEADER; - LONG Total = Size + DIBSIZE(bih); - - // Make sure we have a large enough buffer - - if(*pBufferSize < Total) { - return E_OUTOFMEMORY; - } - - // Copy the BITMAPINFO - - CopyMemory((PVOID)pVideoImage, (PVOID)&pVideoInfo->bmiHeader, Size); - ((BITMAPINFOHEADER *)pVideoImage)->biWidth = WIDTH(pSourceRect); - ((BITMAPINFOHEADER *)pVideoImage)->biHeight = HEIGHT(pSourceRect); - ((BITMAPINFOHEADER *)pVideoImage)->biSizeImage = DIBSIZE(bih); - BYTE *pImageData = pVideoImage + Size; - - // Get the pointer to it's image data - - HRESULT hr = pMediaSample->GetPointer(&pCurrentImage); - if(FAILED(hr)) { - return hr; - } - - // Now we are ready to start copying the source scan lines - - LONG ScanLine = (pVideoInfo->bmiHeader.biBitCount / 8) * WIDTH(pSourceRect); - LONG LinesToSkip = pVideoInfo->bmiHeader.biHeight; - LinesToSkip -= pSourceRect->top + HEIGHT(pSourceRect); - pCurrentImage += LinesToSkip * DIBWIDTHBYTES(pVideoInfo->bmiHeader); - pCurrentImage += pSourceRect->left * (pVideoInfo->bmiHeader.biBitCount / 8); - - // Even money on this GP faulting sometime... - - for(LONG Line = 0;Line < HEIGHT(pSourceRect);Line++) { - CopyMemory((PVOID)pImageData, (PVOID)pCurrentImage, ScanLine); - pImageData += DIBWIDTHBYTES(*(BITMAPINFOHEADER *)pVideoImage); - pCurrentImage += DIBWIDTHBYTES(pVideoInfo->bmiHeader); - } - return NOERROR; -} - - -// Called when we change media types either during connection or dynamically -// We inform the filter graph and therefore the application that the video -// size may have changed, we don't bother looking to see if it really has as -// we leave that to the application - the dimensions are the event parameters - -HRESULT CBaseControlVideo::OnVideoSizeChange() { - // Get the video format from the derived class - - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if(pVideoInfo == NULL) - return E_OUTOFMEMORY; - WORD Width = (WORD) pVideoInfo->bmiHeader.biWidth; - WORD Height = (WORD) pVideoInfo->bmiHeader.biHeight; - - return m_pFilter->NotifyEvent(EC_VIDEO_SIZE_CHANGED, - MAKELPARAM(Width,Height), - MAKEWPARAM(0,0)); -} - - -// Set the video source rectangle. We must check the source rectangle against -// the actual video dimensions otherwise when we come to draw the pictures we -// get access violations as GDI tries to touch data outside of the image data -// Although we store the rectangle in left, top, right and bottom coordinates -// instead of left, top, width and height as OLE uses we do take into account -// that the rectangle is used up to, but not including, the right column and -// bottom row of pixels, see the Win32 documentation on RECT for more details - -HRESULT CBaseControlVideo::CheckSourceRect(RECT *pSourceRect) { - CheckPointer(pSourceRect,E_POINTER); - LONG Width,Height; - GetVideoSize(&Width,&Height); - - // Check the coordinates are greater than zero - // and that the rectangle is valid (leftleft >= pSourceRect->right) || - (pSourceRect->left < 0) || - (pSourceRect->top >= pSourceRect->bottom) || - (pSourceRect->top < 0)) { - - return E_INVALIDARG; - } - - // Check the coordinates are less than the extents - - if((pSourceRect->right > Width) || - (pSourceRect->bottom > Height)) { - - return E_INVALIDARG; - } - return NOERROR; -} - - -// Check the target rectangle has some valid coordinates, which amounts to -// little more than checking the destination rectangle isn't empty. Derived -// classes may call this when they have their SetTargetRect method called to -// check the rectangle validity, we do not update the rectangles passed in -// Although we store the rectangle in left, top, right and bottom coordinates -// instead of left, top, width and height as OLE uses we do take into account -// that the rectangle is used up to, but not including, the right column and -// bottom row of pixels, see the Win32 documentation on RECT for more details - -HRESULT CBaseControlVideo::CheckTargetRect(RECT *pTargetRect) { - // Check the pointer is valid - - if(pTargetRect == NULL) { - return E_POINTER; - } - - // These overflow the WIDTH and HEIGHT checks - - if(pTargetRect->left > pTargetRect->right || - pTargetRect->top > pTargetRect->bottom) { - return E_INVALIDARG; - } - - // Check the rectangle has valid coordinates - - if(WIDTH(pTargetRect) <= 0 || HEIGHT(pTargetRect) <= 0) { - return E_INVALIDARG; - } - - ASSERT(IsRectEmpty(pTargetRect) == FALSE); - return NOERROR; -} - - diff --git a/src/BaseClasses/winctrl.h b/src/BaseClasses/winctrl.h deleted file mode 100644 index cd90697869..0000000000 --- a/src/BaseClasses/winctrl.h +++ /dev/null @@ -1,224 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WinCtrl.h -// -// Desc: DirectShow base classes - defines classes for video control -// interfaces. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __WINCTRL__ -#define __WINCTRL__ - -#define ABSOL(x) (x < 0 ? -x : x) -#define NEGAT(x) (x > 0 ? -x : x) - -// Helper -BOOL WINAPI PossiblyEatMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - -class CBaseControlWindow : public CBaseVideoWindow, public CBaseWindow -{ -protected: - - CBaseFilter *m_pFilter; // Pointer to owning media filter - CBasePin *m_pPin; // Controls media types for connection - CCritSec *m_pInterfaceLock; // Externally defined critical section - COLORREF m_BorderColour; // Current window border colour - BOOL m_bAutoShow; // What happens when the state changes - HWND m_hwndOwner; // Owner window that we optionally have - HWND m_hwndDrain; // HWND to post any messages received - BOOL m_bCursorHidden; // Should we hide the window cursor - -public: - - // Internal methods for other objects to get information out - - HRESULT DoSetWindowStyle(long Style,long WindowLong); - HRESULT DoGetWindowStyle(long *pStyle,long WindowLong); - BOOL IsAutoShowEnabled() { return m_bAutoShow; }; - COLORREF GetBorderColour() { return m_BorderColour; }; - HWND GetOwnerWindow() { return m_hwndOwner; }; - BOOL IsCursorHidden() { return m_bCursorHidden; }; - - inline BOOL PossiblyEatMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) - { - return ::PossiblyEatMessage(m_hwndDrain, uMsg, wParam, lParam); - } - - // Derived classes must call this to set the pin the filter is using - // We don't have the pin passed in to the constructor (as we do with - // the CBaseFilter object) because filters typically create the - // pins dynamically when requested in CBaseFilter::GetPin. This can - // not be called from our constructor because is is a virtual method - - void SetControlWindowPin(CBasePin *pPin) { - m_pPin = pPin; - } - -public: - - CBaseControlWindow(CBaseFilter *pFilter, // Owning media filter - CCritSec *pInterfaceLock, // Locking object - TCHAR *pName, // Object description - LPUNKNOWN pUnk, // Normal COM ownership - HRESULT *phr); // OLE return code - - // These are the properties we support - - STDMETHODIMP put_Caption(BSTR strCaption); - STDMETHODIMP get_Caption(BSTR *pstrCaption); - STDMETHODIMP put_AutoShow(long AutoShow); - STDMETHODIMP get_AutoShow(long *AutoShow); - STDMETHODIMP put_WindowStyle(long WindowStyle); - STDMETHODIMP get_WindowStyle(long *pWindowStyle); - STDMETHODIMP put_WindowStyleEx(long WindowStyleEx); - STDMETHODIMP get_WindowStyleEx(long *pWindowStyleEx); - STDMETHODIMP put_WindowState(long WindowState); - STDMETHODIMP get_WindowState(long *pWindowState); - STDMETHODIMP put_BackgroundPalette(long BackgroundPalette); - STDMETHODIMP get_BackgroundPalette(long *pBackgroundPalette); - STDMETHODIMP put_Visible(long Visible); - STDMETHODIMP get_Visible(long *pVisible); - STDMETHODIMP put_Left(long Left); - STDMETHODIMP get_Left(long *pLeft); - STDMETHODIMP put_Width(long Width); - STDMETHODIMP get_Width(long *pWidth); - STDMETHODIMP put_Top(long Top); - STDMETHODIMP get_Top(long *pTop); - STDMETHODIMP put_Height(long Height); - STDMETHODIMP get_Height(long *pHeight); - STDMETHODIMP put_Owner(OAHWND Owner); - STDMETHODIMP get_Owner(OAHWND *Owner); - STDMETHODIMP put_MessageDrain(OAHWND Drain); - STDMETHODIMP get_MessageDrain(OAHWND *Drain); - STDMETHODIMP get_BorderColor(long *Color); - STDMETHODIMP put_BorderColor(long Color); - STDMETHODIMP get_FullScreenMode(long *FullScreenMode); - STDMETHODIMP put_FullScreenMode(long FullScreenMode); - - // And these are the methods - - STDMETHODIMP SetWindowForeground(long Focus); - STDMETHODIMP NotifyOwnerMessage(OAHWND hwnd,long uMsg,LONG_PTR wParam,LONG_PTR lParam); - STDMETHODIMP GetMinIdealImageSize(long *pWidth,long *pHeight); - STDMETHODIMP GetMaxIdealImageSize(long *pWidth,long *pHeight); - STDMETHODIMP SetWindowPosition(long Left,long Top,long Width,long Height); - STDMETHODIMP GetWindowPosition(long *pLeft,long *pTop,long *pWidth,long *pHeight); - STDMETHODIMP GetRestorePosition(long *pLeft,long *pTop,long *pWidth,long *pHeight); - STDMETHODIMP HideCursor(long HideCursor); - STDMETHODIMP IsCursorHidden(long *CursorHidden); -}; - -// This class implements the IBasicVideo interface - -class CBaseControlVideo : public CBaseBasicVideo -{ -protected: - - CBaseFilter *m_pFilter; // Pointer to owning media filter - CBasePin *m_pPin; // Controls media types for connection - CCritSec *m_pInterfaceLock; // Externally defined critical section - -public: - - // Derived classes must provide these for the implementation - - virtual HRESULT IsDefaultTargetRect() PURE; - virtual HRESULT SetDefaultTargetRect() PURE; - virtual HRESULT SetTargetRect(RECT *pTargetRect) PURE; - virtual HRESULT GetTargetRect(RECT *pTargetRect) PURE; - virtual HRESULT IsDefaultSourceRect() PURE; - virtual HRESULT SetDefaultSourceRect() PURE; - virtual HRESULT SetSourceRect(RECT *pSourceRect) PURE; - virtual HRESULT GetSourceRect(RECT *pSourceRect) PURE; - virtual HRESULT GetStaticImage(long *pBufferSize,long *pDIBImage) PURE; - - // Derived classes must override this to return a VIDEOINFO representing - // the video format. We cannot call IPin ConnectionMediaType to get this - // format because various filters dynamically change the type when using - // DirectDraw such that the format shows the position of the logical - // bitmap in a frame buffer surface, so the size might be returned as - // 1024x768 pixels instead of 320x240 which is the real video dimensions - - virtual VIDEOINFOHEADER *GetVideoFormat() PURE; - - // Helper functions for creating memory renderings of a DIB image - - HRESULT GetImageSize(VIDEOINFOHEADER *pVideoInfo, - LONG *pBufferSize, - RECT *pSourceRect); - - HRESULT CopyImage(IMediaSample *pMediaSample, - VIDEOINFOHEADER *pVideoInfo, - LONG *pBufferSize, - BYTE *pVideoImage, - RECT *pSourceRect); - - // Override this if you want notifying when the rectangles change - virtual HRESULT OnUpdateRectangles() { return NOERROR; }; - virtual HRESULT OnVideoSizeChange(); - - // Derived classes must call this to set the pin the filter is using - // We don't have the pin passed in to the constructor (as we do with - // the CBaseFilter object) because filters typically create the - // pins dynamically when requested in CBaseFilter::GetPin. This can - // not be called from our constructor because is is a virtual method - - void SetControlVideoPin(CBasePin *pPin) { - m_pPin = pPin; - } - - // Helper methods for checking rectangles - virtual HRESULT CheckSourceRect(RECT *pSourceRect); - virtual HRESULT CheckTargetRect(RECT *pTargetRect); - -public: - - CBaseControlVideo(CBaseFilter *pFilter, // Owning media filter - CCritSec *pInterfaceLock, // Serialise interface - TCHAR *pName, // Object description - LPUNKNOWN pUnk, // Normal COM ownership - HRESULT *phr); // OLE return code - - // These are the properties we support - - STDMETHODIMP get_AvgTimePerFrame(REFTIME *pAvgTimePerFrame); - STDMETHODIMP get_BitRate(long *pBitRate); - STDMETHODIMP get_BitErrorRate(long *pBitErrorRate); - STDMETHODIMP get_VideoWidth(long *pVideoWidth); - STDMETHODIMP get_VideoHeight(long *pVideoHeight); - STDMETHODIMP put_SourceLeft(long SourceLeft); - STDMETHODIMP get_SourceLeft(long *pSourceLeft); - STDMETHODIMP put_SourceWidth(long SourceWidth); - STDMETHODIMP get_SourceWidth(long *pSourceWidth); - STDMETHODIMP put_SourceTop(long SourceTop); - STDMETHODIMP get_SourceTop(long *pSourceTop); - STDMETHODIMP put_SourceHeight(long SourceHeight); - STDMETHODIMP get_SourceHeight(long *pSourceHeight); - STDMETHODIMP put_DestinationLeft(long DestinationLeft); - STDMETHODIMP get_DestinationLeft(long *pDestinationLeft); - STDMETHODIMP put_DestinationWidth(long DestinationWidth); - STDMETHODIMP get_DestinationWidth(long *pDestinationWidth); - STDMETHODIMP put_DestinationTop(long DestinationTop); - STDMETHODIMP get_DestinationTop(long *pDestinationTop); - STDMETHODIMP put_DestinationHeight(long DestinationHeight); - STDMETHODIMP get_DestinationHeight(long *pDestinationHeight); - - // And these are the methods - - STDMETHODIMP GetVideoSize(long *pWidth,long *pHeight); - STDMETHODIMP SetSourcePosition(long Left,long Top,long Width,long Height); - STDMETHODIMP GetSourcePosition(long *pLeft,long *pTop,long *pWidth,long *pHeight); - STDMETHODIMP GetVideoPaletteEntries(long StartIndex,long Entries,long *pRetrieved,long *pPalette); - STDMETHODIMP SetDefaultSourcePosition(); - STDMETHODIMP IsUsingDefaultSource(); - STDMETHODIMP SetDestinationPosition(long Left,long Top,long Width,long Height); - STDMETHODIMP GetDestinationPosition(long *pLeft,long *pTop,long *pWidth,long *pHeight); - STDMETHODIMP SetDefaultDestinationPosition(); - STDMETHODIMP IsUsingDefaultDestination(); - STDMETHODIMP GetCurrentImage(long *pBufferSize,long *pVideoImage); -}; - -#endif // __WINCTRL__ - diff --git a/src/BaseClasses/winutil.cpp b/src/BaseClasses/winutil.cpp deleted file mode 100644 index df9c10dc0d..0000000000 --- a/src/BaseClasses/winutil.cpp +++ /dev/null @@ -1,2696 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WinUtil.cpp -// -// Desc: DirectShow base classes - implements generic window handler class. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include -#include -#include - -static UINT MsgDestroy; - -// Constructor - -CBaseWindow::CBaseWindow(BOOL bDoGetDC, bool bDoPostToDestroy) : - m_hInstance(g_hInst), - m_hwnd(NULL), - m_hdc(NULL), - m_bActivated(FALSE), - m_pClassName(NULL), - m_ClassStyles(0), - m_WindowStyles(0), - m_WindowStylesEx(0), - m_ShowStageMessage(0), - m_ShowStageTop(0), - m_MemoryDC(NULL), - m_hPalette(NULL), - m_bBackground(FALSE), -#ifdef DEBUG - m_bRealizing(FALSE), -#endif - m_bNoRealize(FALSE), - m_bDoPostToDestroy(bDoPostToDestroy) -{ - m_bDoGetDC = bDoGetDC; -} - - -// Prepare a window by spinning off a worker thread to do the creation and -// also poll the message input queue. We leave this to be called by derived -// classes because they might want to override methods like MessageLoop and -// InitialiseWindow, if we do this during construction they'll ALWAYS call -// this base class methods. We make the worker thread create the window so -// it owns it rather than the filter graph thread which is constructing us - -HRESULT CBaseWindow::PrepareWindow() -{ - if (m_hwnd) return NOERROR; - ASSERT(m_hwnd == NULL); - ASSERT(m_hdc == NULL); - - // Get the derived object's window and class styles - - m_pClassName = GetClassWindowStyles(&m_ClassStyles, - &m_WindowStyles, - &m_WindowStylesEx); - if (m_pClassName == NULL) { - return E_FAIL; - } - - // Register our special private messages - m_ShowStageMessage = RegisterWindowMessage(SHOWSTAGE); - - // RegisterWindowMessage() returns 0 if an error occurs. - if (0 == m_ShowStageMessage) { - return AmGetLastErrorToHResult(); - } - - m_ShowStageTop = RegisterWindowMessage(SHOWSTAGETOP); - if (0 == m_ShowStageTop) { - return AmGetLastErrorToHResult(); - } - - m_RealizePalette = RegisterWindowMessage(REALIZEPALETTE); - if (0 == m_RealizePalette) { - return AmGetLastErrorToHResult(); - } - - MsgDestroy = RegisterWindowMessage(TEXT("AM_DESTROY")); - if (0 == MsgDestroy) { - return AmGetLastErrorToHResult(); - } - - return DoCreateWindow(); -} - - -// Destructor just a placeholder so that we know it becomes virtual -// Derived classes MUST call DoneWithWindow in their destructors so -// that no messages arrive after the derived class constructor ends - -#ifdef DEBUG -CBaseWindow::~CBaseWindow() -{ - ASSERT(m_hwnd == NULL); - ASSERT(m_hdc == NULL); -} -#endif - - -// We use the sync worker event to have the window destroyed. All we do is -// signal the event and wait on the window thread handle. Trying to send it -// messages causes too many problems, furthermore to be on the safe side we -// just wait on the thread handle while it returns WAIT_TIMEOUT or there is -// a sent message to process on this thread. If the constructor failed to -// create the thread in the first place then the loop will get terminated - -HRESULT CBaseWindow::DoneWithWindow() -{ - // - // Before doing anything, check that someone has not already killed the - // Video Renderer window. If it has been killed we need to tidy up - // a DC that the window was using. If we don't do this check - // the following GetWindowThreadProcessId test fails, but the SendMessage - // goes nowhere and we leak the DC. - // - if (!IsWindow(m_hwnd)) { - - // - // This is not a leak, the window manager automatically free's - // hdc's that were got via GetDC, which is the case here. - // We set it to NULL so that we don't get any asserts later. - // - m_hdc = NULL; - - // - // We need to free this DC though because USER32 does not know - // anything about it. - // - if (m_MemoryDC) - { - EXECUTE_ASSERT(DeleteDC(m_MemoryDC)); - m_MemoryDC = NULL; - } - - // Reset the window variables - m_hwnd = NULL; - return NOERROR; - } - - - if (GetWindowThreadProcessId(m_hwnd, NULL) != GetCurrentThreadId()) { - - if (m_bDoPostToDestroy) { - - CAMEvent m_evDone; - - // We must post a message to destroy the window - // That way we can't be in the middle of processing a - // message posted to our window when we do go away - // Sending a message gives less synchronization. - PostMessage(m_hwnd, MsgDestroy, (WPARAM)(HANDLE)m_evDone, 0); - WaitDispatchingMessages(m_evDone, INFINITE); - } else { - SendMessage(m_hwnd, MsgDestroy, 0, 0); - } - return NOERROR; - } - const HWND hwnd = m_hwnd; - if (hwnd == NULL) { - return NOERROR; - } - - InactivateWindow(); - NOTE("Inactivated"); - - // Reset the window styles before destruction - - SetWindowLong(hwnd,GWL_STYLE,m_WindowStyles); - ASSERT(GetParent(hwnd) == NULL); - NOTE1("Reset window styles %d",m_WindowStyles); - - // UnintialiseWindow sets m_hwnd to NULL so save a copy - UninitialiseWindow(); - DbgLog((LOG_TRACE, 2, TEXT("Destroying 0x%8.8X"), hwnd)); - if (!DestroyWindow(hwnd)) { - DbgLog((LOG_TRACE, 0, TEXT("DestroyWindow %8.8X failed code %d"), - hwnd, GetLastError())); - DbgBreak(""); - } - - // Reset our state so we can be prepared again - - m_pClassName = NULL; - m_ClassStyles = 0; - m_WindowStyles = 0; - m_WindowStylesEx = 0; - m_ShowStageMessage = 0; - m_ShowStageTop = 0; - - return NOERROR; -} - - -// Called at the end to put the window in an inactive state. The pending list -// will always have been cleared by this time so event if the worker thread -// gets has been signaled and gets in to render something it will find both -// the state has been changed and that there are no available sample images -// Since we wait on the window thread to complete we don't lock the object - -HRESULT CBaseWindow::InactivateWindow() -{ - // Has the window been activated - if (m_bActivated == FALSE) { - return S_FALSE; - } - - m_bActivated = FALSE; - ShowWindow(m_hwnd,SW_HIDE); - return NOERROR; -} - - -HRESULT CBaseWindow::CompleteConnect() -{ - m_bActivated = FALSE; - return NOERROR; -} - -// This displays a normal window. We ask the base window class for default -// sizes which unless overriden will return DEFWIDTH and DEFHEIGHT. We go -// through a couple of extra hoops to get the client area the right size -// as the object specifies which accounts for the AdjustWindowRectEx calls -// We also DWORD align the left and top coordinates of the window here to -// maximise the chance of being able to use DCI/DirectDraw primary surface - -HRESULT CBaseWindow::ActivateWindow() -{ - // Has the window been sized and positioned already - - if (m_bActivated == TRUE || GetParent(m_hwnd) != NULL) { - - SetWindowPos(m_hwnd, // Our window handle - HWND_TOP, // Put it at the top - 0, 0, 0, 0, // Leave in current position - SWP_NOMOVE | // Don't change it's place - SWP_NOSIZE); // Change Z-order only - - m_bActivated = TRUE; - return S_FALSE; - } - - // Calculate the desired client rectangle - - RECT WindowRect, ClientRect = GetDefaultRect(); - GetWindowRect(m_hwnd,&WindowRect); - AdjustWindowRectEx(&ClientRect,GetWindowLong(m_hwnd,GWL_STYLE), - FALSE,GetWindowLong(m_hwnd,GWL_EXSTYLE)); - - // Align left and top edges on DWORD boundaries - - UINT WindowFlags = (SWP_NOACTIVATE | SWP_FRAMECHANGED); - WindowRect.left -= (WindowRect.left & 3); - WindowRect.top -= (WindowRect.top & 3); - - SetWindowPos(m_hwnd, // Window handle - HWND_TOP, // Put it at the top - WindowRect.left, // Align left edge - WindowRect.top, // And also top place - WIDTH(&ClientRect), // Horizontal size - HEIGHT(&ClientRect), // Vertical size - WindowFlags); // Don't show window - - m_bActivated = TRUE; - return NOERROR; -} - - -// This can be used to DWORD align the window for maximum performance - -HRESULT CBaseWindow::PerformanceAlignWindow() -{ - RECT ClientRect,WindowRect; - GetWindowRect(m_hwnd,&WindowRect); - ASSERT(m_bActivated == TRUE); - - // Don't do this if we're owned - - if (GetParent(m_hwnd)) { - return NOERROR; - } - - // Align left and top edges on DWORD boundaries - - GetClientRect(m_hwnd, &ClientRect); - MapWindowPoints(m_hwnd, HWND_DESKTOP, (LPPOINT) &ClientRect, 2); - WindowRect.left -= (ClientRect.left & 3); - WindowRect.top -= (ClientRect.top & 3); - UINT WindowFlags = (SWP_NOACTIVATE | SWP_NOSIZE); - - SetWindowPos(m_hwnd, // Window handle - HWND_TOP, // Put it at the top - WindowRect.left, // Align left edge - WindowRect.top, // And also top place - (int) 0,(int) 0, // Ignore these sizes - WindowFlags); // Don't show window - - return NOERROR; -} - - -// Install a palette into the base window - we may be called by a different -// thread to the one that owns the window. We have to be careful how we do -// the palette realisation as we could be a different thread to the window -// which would cause an inter thread send message. Therefore we realise the -// palette by sending it a special message but without the window locked - -HRESULT CBaseWindow::SetPalette(HPALETTE hPalette) -{ - // We must own the window lock during the change - { - CAutoLock cWindowLock(&m_WindowLock); - CAutoLock cPaletteLock(&m_PaletteLock); - ASSERT(hPalette); - m_hPalette = hPalette; - } - return SetPalette(); -} - - -HRESULT CBaseWindow::SetPalette() -{ - if (!m_bNoRealize) { - SendMessage(m_hwnd, m_RealizePalette, 0, 0); - return S_OK; - } else { - // Just select the palette - ASSERT(m_hdc); - ASSERT(m_MemoryDC); - - CAutoLock cPaletteLock(&m_PaletteLock); - SelectPalette(m_hdc,m_hPalette,m_bBackground); - SelectPalette(m_MemoryDC,m_hPalette,m_bBackground); - - return S_OK; - } -} - - -void CBaseWindow::UnsetPalette() -{ - CAutoLock cWindowLock(&m_WindowLock); - CAutoLock cPaletteLock(&m_PaletteLock); - - // Get a standard VGA colour palette - - HPALETTE hPalette = (HPALETTE) GetStockObject(DEFAULT_PALETTE); - ASSERT(hPalette); - - SelectPalette(GetWindowHDC(), hPalette, TRUE); - SelectPalette(GetMemoryHDC(), hPalette, TRUE); - - m_hPalette = NULL; -} - - -void CBaseWindow::LockPaletteLock() -{ - m_PaletteLock.Lock(); -} - - -void CBaseWindow::UnlockPaletteLock() -{ - m_PaletteLock.Unlock(); -} - - -// Realise our palettes in the window and device contexts - -HRESULT CBaseWindow::DoRealisePalette(BOOL bForceBackground) -{ - { - CAutoLock cPaletteLock(&m_PaletteLock); - - if (m_hPalette == NULL) { - return NOERROR; - } - - // Realize the palette on the window thread - ASSERT(m_hdc); - ASSERT(m_MemoryDC); - - SelectPalette(m_hdc,m_hPalette,m_bBackground || bForceBackground); - SelectPalette(m_MemoryDC,m_hPalette,m_bBackground); - } - - // If we grab a critical section here we can deadlock - // with the window thread because one of the side effects - // of RealizePalette is to send a WM_PALETTECHANGED message - // to every window in the system. In our handling - // of WM_PALETTECHANGED we used to grab this CS too. - // The really bad case is when our renderer calls DoRealisePalette() - // while we're in the middle of processing a palette change - // for another window. - // So don't hold the critical section while actually realising - // the palette. In any case USER is meant to manage palette - // handling - we shouldn't have to serialize everything as well - ASSERT(CritCheckOut(&m_WindowLock)); - ASSERT(CritCheckOut(&m_PaletteLock)); - - EXECUTE_ASSERT(RealizePalette(m_hdc) != GDI_ERROR); - EXECUTE_ASSERT(RealizePalette(m_MemoryDC) != GDI_ERROR); - - return (GdiFlush() == FALSE ? S_FALSE : S_OK); -} - - -// This is the global window procedure - -LRESULT CALLBACK WndProc(HWND hwnd, // Window handle - UINT uMsg, // Message ID - WPARAM wParam, // First parameter - LPARAM lParam) // Other parameter -{ - - // Get the window long that holds our window object pointer - // If it is NULL then we are initialising the window in which - // case the object pointer has been passed in the window creation - // structure. IF we get any messages before WM_NCCREATE we will - // pass them to DefWindowProc. - - CBaseWindow *pBaseWindow = (CBaseWindow *)GetWindowLongPtr(hwnd,0); - if (pBaseWindow == NULL) { - - // Get the structure pointer from the create struct. - // We can only do this for WM_NCCREATE which should be one of - // the first messages we receive. Anything before this will - // have to be passed to DefWindowProc (i.e. WM_GETMINMAXINFO) - - // If the message is WM_NCCREATE we set our pBaseWindow pointer - // and will then place it in the window structure - - // turn off WS_EX_LAYOUTRTL style for quartz windows - if (uMsg == WM_NCCREATE) { - SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) & ~0x400000); - } - - if ((uMsg != WM_NCCREATE) - || (NULL == (pBaseWindow = *(CBaseWindow**) ((LPCREATESTRUCT)lParam)->lpCreateParams))) - { - return(DefWindowProc(hwnd, uMsg, wParam, lParam)); - } - - // Set the window LONG to be the object who created us -#ifdef DEBUG - SetLastError(0); // because of the way SetWindowLong works -#endif - LONG_PTR rc = SetWindowLongPtr(hwnd, (DWORD) 0, (LONG_PTR) pBaseWindow); -#ifdef DEBUG - if (0 == rc) { - // SetWindowLong MIGHT have failed. (Read the docs which admit - // that it is awkward to work out if you have had an error.) - LONG lasterror = GetLastError(); - ASSERT(0 == lasterror); - // If this is not the case we have not set the pBaseWindow pointer - // into the window structure and we will blow up. - } -#endif - - } - // See if this is the packet of death - if (uMsg == MsgDestroy && uMsg != 0) { - pBaseWindow->DoneWithWindow(); - if (pBaseWindow->m_bDoPostToDestroy) { - EXECUTE_ASSERT(SetEvent((HANDLE)wParam)); - } - return 0; - } - return pBaseWindow->OnReceiveMessage(hwnd,uMsg,wParam,lParam); -} - - -// When the window size changes we adjust our member variables that -// contain the dimensions of the client rectangle for our window so -// that we come to render an image we will know whether to stretch - -BOOL CBaseWindow::OnSize(LONG Width, LONG Height) -{ - m_Width = Width; - m_Height = Height; - return TRUE; -} - - -// This function handles the WM_CLOSE message - -BOOL CBaseWindow::OnClose() -{ - ShowWindow(m_hwnd,SW_HIDE); - return TRUE; -} - - -// This is called by the worker window thread when it receives a terminate -// message from the window object destructor to delete all the resources we -// allocated during initialisation. By the time the worker thread exits all -// processing will have been completed as the source filter disconnection -// flushes the image pending sample, therefore the GdiFlush should succeed - -HRESULT CBaseWindow::UninitialiseWindow() -{ - // Have we already cleaned up - - if (m_hwnd == NULL) { - ASSERT(m_hdc == NULL); - ASSERT(m_MemoryDC == NULL); - return NOERROR; - } - - // Release the window resources - - EXECUTE_ASSERT(GdiFlush()); - - if (m_hdc) - { - EXECUTE_ASSERT(ReleaseDC(m_hwnd,m_hdc)); - m_hdc = NULL; - } - - if (m_MemoryDC) - { - EXECUTE_ASSERT(DeleteDC(m_MemoryDC)); - m_MemoryDC = NULL; - } - - // Reset the window variables - m_hwnd = NULL; - - return NOERROR; -} - - -// This is called by the worker window thread after it has created the main -// window and it wants to initialise the rest of the owner objects window -// variables such as the device contexts. We execute this function with the -// critical section still locked. Nothing in this function must generate any -// SendMessage calls to the window because this is executing on the window -// thread so the message will never be processed and we will deadlock - -#pragma warning(disable:4706) // C4706: assignment within conditional expression - -HRESULT CBaseWindow::InitialiseWindow(HWND hwnd) -{ - // Initialise the window variables - - ASSERT(IsWindow(hwnd)); - m_hwnd = hwnd; - - if (m_bDoGetDC) - { - EXECUTE_ASSERT(m_hdc = GetDC(hwnd)); - EXECUTE_ASSERT(m_MemoryDC = CreateCompatibleDC(m_hdc)); - - EXECUTE_ASSERT(SetStretchBltMode(m_hdc,COLORONCOLOR)); - EXECUTE_ASSERT(SetStretchBltMode(m_MemoryDC,COLORONCOLOR)); - } - - return NOERROR; -} - -#pragma warning(default:4706) // C4706: assignment within conditional expression - - -HRESULT CBaseWindow::DoCreateWindow() -{ - WNDCLASS wndclass; // Used to register classes - BOOL bRegistered; // Is this class registered - HWND hwnd; // Handle to our window - - bRegistered = GetClassInfo(m_hInstance, // Module instance - m_pClassName, // Window class - &wndclass); // Info structure - - // if the window is to be used for drawing puposes and we are getting a DC - // for the entire lifetime of the window then changes the class style to do - // say so. If we don't set this flag then the DC comes from the cache and is - // really bad. - if (m_bDoGetDC) - { - m_ClassStyles |= CS_OWNDC; - } - - if (bRegistered == FALSE) { - - // Register the renderer window class - - wndclass.lpszClassName = m_pClassName; - wndclass.style = m_ClassStyles; - wndclass.lpfnWndProc = WndProc; - wndclass.cbClsExtra = 0; - wndclass.cbWndExtra = sizeof(CBaseWindow *); - wndclass.hInstance = m_hInstance; - wndclass.hIcon = NULL; - wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); - wndclass.hbrBackground = (HBRUSH) NULL; - wndclass.lpszMenuName = NULL; - - RegisterClass(&wndclass); - } - - // Create the frame window. Pass the pBaseWindow information in the - // CreateStruct which allows our message handling loop to get hold of - // the pBaseWindow pointer. - - CBaseWindow *pBaseWindow = this; // The owner window object - hwnd = CreateWindowEx(m_WindowStylesEx, // Extended styles - m_pClassName, // Registered name - TEXT("ActiveMovie Window"), // Window title - m_WindowStyles, // Window styles - CW_USEDEFAULT, // Start x position - CW_USEDEFAULT, // Start y position - DEFWIDTH, // Window width - DEFHEIGHT, // Window height - NULL, // Parent handle - NULL, // Menu handle - m_hInstance, // Instance handle - &pBaseWindow); // Creation data - - // If we failed signal an error to the object constructor (based on the - // last Win32 error on this thread) then signal the constructor thread - // to continue, release the mutex to let others have a go and exit - - if (hwnd == NULL) { - DWORD Error = GetLastError(); - return AmHresultFromWin32(Error); - } - - // Check the window LONG is the object who created us - ASSERT(GetWindowLongPtr(hwnd, 0) == (LONG_PTR)this); - - // Initialise the window and then signal the constructor so that it can - // continue and then finally unlock the object's critical section. The - // window class is left registered even after we terminate the thread - // as we don't know when the last window has been closed. So we allow - // the operating system to free the class resources as appropriate - - InitialiseWindow(hwnd); - - DbgLog((LOG_TRACE, 2, TEXT("Created window class (%s) HWND(%8.8X)"), - m_pClassName, hwnd)); - - return S_OK; -} - - -// The base class provides some default handling and calls DefWindowProc - -LRESULT CBaseWindow::OnReceiveMessage(HWND hwnd, // Window handle - UINT uMsg, // Message ID - WPARAM wParam, // First parameter - LPARAM lParam) // Other parameter -{ - ASSERT(IsWindow(hwnd)); - - if (PossiblyEatMessage(uMsg, wParam, lParam)) - return 0; - - // This is sent by the IVideoWindow SetWindowForeground method. If the - // window is invisible we will show it and make it topmost without the - // foreground focus. If the window is visible it will also be made the - // topmost window without the foreground focus. If wParam is TRUE then - // for both cases the window will be forced into the foreground focus - - if (uMsg == m_ShowStageMessage) { - - BOOL bVisible = IsWindowVisible(hwnd); - SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | - (bVisible ? SWP_NOACTIVATE : 0)); - - // Should we bring the window to the foreground - if (wParam == TRUE) { - SetForegroundWindow(hwnd); - } - return (LRESULT) 1; - } - - // When we go fullscreen we have to add the WS_EX_TOPMOST style to the - // video window so that it comes out above any task bar (this is more - // relevant to WindowsNT than Windows95). However the SetWindowPos call - // must be on the same thread as that which created the window. The - // wParam parameter can be TRUE or FALSE to set and reset the topmost - - if (uMsg == m_ShowStageTop) { - HWND HwndTop = (wParam == TRUE ? HWND_TOPMOST : HWND_NOTOPMOST); - BOOL bVisible = IsWindowVisible(hwnd); - SetWindowPos(hwnd, HwndTop, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | - (wParam == TRUE ? SWP_SHOWWINDOW : 0) | - (bVisible ? SWP_NOACTIVATE : 0)); - return (LRESULT) 1; - } - - // New palette stuff - if (uMsg == m_RealizePalette) { - ASSERT(m_hwnd == hwnd); - return OnPaletteChange(m_hwnd,WM_QUERYNEWPALETTE); - } - - switch (uMsg) { - - // Repaint the window if the system colours change - - case WM_SYSCOLORCHANGE: - - InvalidateRect(hwnd,NULL,FALSE); - return (LRESULT) 1; - - // Somebody has changed the palette - case WM_PALETTECHANGED: - - OnPaletteChange((HWND)wParam,uMsg); - return (LRESULT) 0; - - // We are about to receive the keyboard focus so we ask GDI to realise - // our logical palette again and hopefully it will be fully installed - // without any mapping having to be done during any picture rendering - - case WM_QUERYNEWPALETTE: - ASSERT(m_hwnd == hwnd); - return OnPaletteChange(m_hwnd,uMsg); - - // do NOT fwd WM_MOVE. the parameters are the location of the parent - // window, NOT what the renderer should be looking at. But we need - // to make sure the overlay is moved with the parent window, so we - // do this. - case WM_MOVE: - if (IsWindowVisible(m_hwnd)) { - PostMessage(m_hwnd,WM_PAINT,0,0); - } - break; - - // Store the width and height as useful base class members - - case WM_SIZE: - - OnSize(LOWORD(lParam), HIWORD(lParam)); - return (LRESULT) 0; - - // Intercept the WM_CLOSE messages to hide the window - - case WM_CLOSE: - - OnClose(); - return (LRESULT) 0; - } - return DefWindowProc(hwnd,uMsg,wParam,lParam); -} - - -// This handles the Windows palette change messages - if we do realise our -// palette then we return TRUE otherwise we return FALSE. If our window is -// foreground application then we should get first choice of colours in the -// system palette entries. We get best performance when our logical palette -// includes the standard VGA colours (at the beginning and end) otherwise -// GDI may have to map from our palette to the device palette while drawing - -LRESULT CBaseWindow::OnPaletteChange(HWND hwnd,UINT Message) -{ - // First check we are not changing the palette during closedown - - if (m_hwnd == NULL || hwnd == NULL) { - return (LRESULT) 0; - } - ASSERT(!m_bRealizing); - - // Should we realise our palette again - - if ((Message == WM_QUERYNEWPALETTE || hwnd != m_hwnd)) { - // It seems that even if we're invisible that we can get asked - // to realize our palette and this can cause really ugly side-effects - // Seems like there's another bug but this masks it a least for the - // shutting down case. - if (!IsWindowVisible(m_hwnd)) { - DbgLog((LOG_TRACE, 1, TEXT("Realizing when invisible!"))); - return (LRESULT) 0; - } - - // Avoid recursion with multiple graphs in the same app -#ifdef DEBUG - m_bRealizing = TRUE; -#endif - DoRealisePalette(Message != WM_QUERYNEWPALETTE); -#ifdef DEBUG - m_bRealizing = FALSE; -#endif - - // Should we redraw the window with the new palette - if (Message == WM_PALETTECHANGED) { - InvalidateRect(m_hwnd,NULL,FALSE); - } - } - - return (LRESULT) 1; -} - - -// Determine if the window exists. - -bool CBaseWindow::WindowExists() -{ - return !!IsWindow(m_hwnd); -} - - -// Return the default window rectangle - -RECT CBaseWindow::GetDefaultRect() -{ - RECT DefaultRect = {0,0,DEFWIDTH,DEFHEIGHT}; - ASSERT(m_hwnd); - // ASSERT(m_hdc); - return DefaultRect; -} - - -// Return the current window width - -LONG CBaseWindow::GetWindowWidth() -{ - ASSERT(m_hwnd); - // ASSERT(m_hdc); - return m_Width; -} - - -// Return the current window height - -LONG CBaseWindow::GetWindowHeight() -{ - ASSERT(m_hwnd); - // ASSERT(m_hdc); - return m_Height; -} - - -// Return the window handle - -HWND CBaseWindow::GetWindowHWND() -{ - ASSERT(m_hwnd); - // ASSERT(m_hdc); - return m_hwnd; -} - - -// Return the window drawing device context - -HDC CBaseWindow::GetWindowHDC() -{ - ASSERT(m_hwnd); - ASSERT(m_hdc); - return m_hdc; -} - - -// Return the offscreen window drawing device context - -HDC CBaseWindow::GetMemoryHDC() -{ - ASSERT(m_hwnd); - ASSERT(m_MemoryDC); - return m_MemoryDC; -} - - -#ifdef DEBUG -HPALETTE CBaseWindow::GetPalette() -{ - // The palette lock should always be held when accessing - // m_hPalette. - ASSERT(CritCheckIn(&m_PaletteLock)); - return m_hPalette; -} -#endif // DEBUG - - -// This is available to clients who want to change the window visiblity. It's -// little more than an indirection to the Win32 ShowWindow although these is -// some benefit in going through here as this function may change sometime - -HRESULT CBaseWindow::DoShowWindow(LONG ShowCmd) -{ - ShowWindow(m_hwnd,ShowCmd); - return NOERROR; -} - - -// Generate a WM_PAINT message for the video window - -void CBaseWindow::PaintWindow(BOOL bErase) -{ - InvalidateRect(m_hwnd,NULL,bErase); -} - - -// Allow an application to have us set the video window in the foreground. We -// have this because it is difficult for one thread to do do this to a window -// owned by another thread. Rather than expose the message we use to execute -// the inter thread send message we provide the interface function. All we do -// is to SendMessage to the video window renderer thread with a WM_SHOWSTAGE - -void CBaseWindow::DoSetWindowForeground(BOOL bFocus) -{ - SendMessage(m_hwnd,m_ShowStageMessage,(WPARAM) bFocus,(LPARAM) 0); -} - - -// Constructor initialises the owning object pointer. Since we are a worker -// class for the main window object we have relatively few state variables to -// look after. We are given device context handles to use later on as well as -// the source and destination rectangles (but reset them here just in case) - -CDrawImage::CDrawImage(CBaseWindow *pBaseWindow) : - m_pBaseWindow(pBaseWindow), - m_hdc(NULL), - m_MemoryDC(NULL), - m_bStretch(FALSE), - m_pMediaType(NULL), - m_bUsingImageAllocator(FALSE) -{ - ASSERT(pBaseWindow); - ResetPaletteVersion(); - SetRectEmpty(&m_TargetRect); - SetRectEmpty(&m_SourceRect); - - m_perfidRenderTime = MSR_REGISTER(TEXT("Single Blt time")); -} - - -// Overlay the image time stamps on the picture. Access to this method is -// serialised by the caller. We display the sample start and end times on -// top of the video using TextOut on the device context we are handed. If -// there isn't enough room in the window for the times we don't show them - -void CDrawImage::DisplaySampleTimes(IMediaSample *pSample) -{ -#ifdef DEBUG - // - // Only allow the "annoying" time messages if the users has turned the - // logging "way up" - // - BOOL bAccept = DbgCheckModuleLevel(LOG_TRACE, 5); - if (bAccept == FALSE) { - return; - } -#endif - - TCHAR szTimes[TIMELENGTH]; // Time stamp strings - ASSERT(pSample); // Quick sanity check - RECT ClientRect; // Client window size - SIZE Size; // Size of text output - - // Get the time stamps and window size - - pSample->GetTime((REFERENCE_TIME*)&m_StartSample, (REFERENCE_TIME*)&m_EndSample); - HWND hwnd = m_pBaseWindow->GetWindowHWND(); - EXECUTE_ASSERT(GetClientRect(hwnd,&ClientRect)); - - // Format the sample time stamps - - wsprintf(szTimes,TEXT("%08d : %08d"), - m_StartSample.Millisecs(), - m_EndSample.Millisecs()); - - ASSERT(lstrlen(szTimes) < TIMELENGTH); - - // Put the times in the middle at the bottom of the window - - GetTextExtentPoint32(m_hdc,szTimes,lstrlen(szTimes),&Size); - INT XPos = ((ClientRect.right - ClientRect.left) - Size.cx) / 2; - INT YPos = ((ClientRect.bottom - ClientRect.top) - Size.cy) * 4 / 5; - - // Check the window is big enough to have sample times displayed - - if ((XPos > 0) && (YPos > 0)) { - TextOut(m_hdc,XPos,YPos,szTimes,lstrlen(szTimes)); - } -} - - -// This is called when the drawing code sees that the image has a down level -// palette cookie. We simply call the SetDIBColorTable Windows API with the -// palette that is found after the BITMAPINFOHEADER - we return no errors - -void CDrawImage::UpdateColourTable(HDC hdc,BITMAPINFOHEADER *pbmi) -{ - ASSERT(pbmi->biClrUsed); - RGBQUAD *pColourTable = (RGBQUAD *)(pbmi+1); - - // Set the new palette in the device context - - UINT uiReturn = SetDIBColorTable(hdc,(UINT) 0, - pbmi->biClrUsed, - pColourTable); - - // Should always succeed but check in debug builds - ASSERT(uiReturn == pbmi->biClrUsed); -} - - -// No source rectangle scaling is done by the base class - -RECT CDrawImage::ScaleSourceRect(const RECT *pSource) -{ - ASSERT(pSource); - return *pSource; -} - - -// This is called when the funky output pin uses our allocator. The samples we -// allocate are special because the memory is shared between us and GDI thus -// removing one copy when we ask for the image to be rendered. The source type -// information is in the main renderer m_mtIn field which is initialised when -// the media type is agreed in SetMediaType, the media type may be changed on -// the fly if, for example, the source filter needs to change the palette - -void CDrawImage::FastRender(IMediaSample *pMediaSample) -{ - BITMAPINFOHEADER *pbmi; // Image format data - DIBDATA *pDibData; // Stores DIB information - BYTE *pImage; // Pointer to image data - HBITMAP hOldBitmap; // Store the old bitmap - CImageSample *pSample; // Pointer to C++ object - - ASSERT(m_pMediaType); - - // From the untyped source format block get the VIDEOINFO and subsequently - // the BITMAPINFOHEADER structure. We can cast the IMediaSample interface - // to a CImageSample object so we can retrieve it's DIBSECTION details - - pbmi = HEADER(m_pMediaType->Format()); - pSample = (CImageSample *) pMediaSample; - pDibData = pSample->GetDIBData(); - hOldBitmap = (HBITMAP) SelectObject(m_MemoryDC,pDibData->hBitmap); - - // Get a pointer to the real image data - - HRESULT hr = pMediaSample->GetPointer(&pImage); - if (FAILED(hr)) { - return; - } - - // Do we need to update the colour table, we increment our palette cookie - // each time we get a dynamic format change. The sample palette cookie is - // stored in the DIBDATA structure so we try to keep the fields in sync - // By the time we get to draw the images the format change will be done - // so all we do is ask the renderer for what it's palette version is - - if (pDibData->PaletteVersion < GetPaletteVersion()) { - ASSERT(pbmi->biBitCount <= iPALETTE); - UpdateColourTable(m_MemoryDC,pbmi); - pDibData->PaletteVersion = GetPaletteVersion(); - } - - // This allows derived classes to change the source rectangle that we do - // the drawing with. For example a renderer may ask a codec to stretch - // the video from 320x240 to 640x480, in which case the source we see in - // here will still be 320x240, although the source we want to draw with - // should be scaled up to 640x480. The base class implementation of this - // method does nothing but return the same rectangle as we are passed in - - RECT SourceRect = ScaleSourceRect(&m_SourceRect); - - // Is the window the same size as the video - - if (m_bStretch == FALSE) { - - // Put the image straight into the window - - BitBlt( - (HDC) m_hdc, // Target device HDC - m_TargetRect.left, // X sink position - m_TargetRect.top, // Y sink position - m_TargetRect.right - m_TargetRect.left, // Destination width - m_TargetRect.bottom - m_TargetRect.top, // Destination height - m_MemoryDC, // Source device context - SourceRect.left, // X source position - SourceRect.top, // Y source position - SRCCOPY); // Simple copy - - } else { - - // Stretch the image when copying to the window - - StretchBlt( - (HDC) m_hdc, // Target device HDC - m_TargetRect.left, // X sink position - m_TargetRect.top, // Y sink position - m_TargetRect.right - m_TargetRect.left, // Destination width - m_TargetRect.bottom - m_TargetRect.top, // Destination height - m_MemoryDC, // Source device HDC - SourceRect.left, // X source position - SourceRect.top, // Y source position - SourceRect.right - SourceRect.left, // Source width - SourceRect.bottom - SourceRect.top, // Source height - SRCCOPY); // Simple copy - } - - // This displays the sample times over the top of the image. This used to - // draw the times into the offscreen device context however that actually - // writes the text into the image data buffer which may not be writable - - #ifdef DEBUG - DisplaySampleTimes(pMediaSample); - #endif - - // Put the old bitmap back into the device context so we don't leak - SelectObject(m_MemoryDC,hOldBitmap); -} - - -// This is called when there is a sample ready to be drawn, unfortunately the -// output pin was being rotten and didn't choose our super excellent shared -// memory DIB allocator so we have to do this slow render using boring old GDI -// SetDIBitsToDevice and StretchDIBits. The down side of using these GDI -// functions is that the image data has to be copied across from our address -// space into theirs before going to the screen (although in reality the cost -// is small because all they do is to map the buffer into their address space) - -void CDrawImage::SlowRender(IMediaSample *pMediaSample) -{ - // Get the BITMAPINFOHEADER for the connection - - ASSERT(m_pMediaType); - BITMAPINFOHEADER *pbmi = HEADER(m_pMediaType->Format()); - BYTE *pImage; - - // Get the image data buffer - - HRESULT hr = pMediaSample->GetPointer(&pImage); - if (FAILED(hr)) { - return; - } - - // This allows derived classes to change the source rectangle that we do - // the drawing with. For example a renderer may ask a codec to stretch - // the video from 320x240 to 640x480, in which case the source we see in - // here will still be 320x240, although the source we want to draw with - // should be scaled up to 640x480. The base class implementation of this - // method does nothing but return the same rectangle as we are passed in - - RECT SourceRect = ScaleSourceRect(&m_SourceRect); - - LONG lAdjustedSourceTop = SourceRect.top; - // if the origin of bitmap is bottom-left, adjust soruce_rect_top - // to be the bottom-left corner instead of the top-left. - if (pbmi->biHeight > 0) { - lAdjustedSourceTop = pbmi->biHeight - SourceRect.bottom; - } - // Is the window the same size as the video - - if (m_bStretch == FALSE) { - - // Put the image straight into the window - - SetDIBitsToDevice( - (HDC) m_hdc, // Target device HDC - m_TargetRect.left, // X sink position - m_TargetRect.top, // Y sink position - m_TargetRect.right - m_TargetRect.left, // Destination width - m_TargetRect.bottom - m_TargetRect.top, // Destination height - SourceRect.left, // X source position - lAdjustedSourceTop, // Adjusted Y source position - (UINT) 0, // Start scan line - pbmi->biHeight, // Scan lines present - pImage, // Image data - (BITMAPINFO *) pbmi, // DIB header - DIB_RGB_COLORS); // Type of palette - - } else { - - // Stretch the image when copying to the window - - StretchDIBits( - (HDC) m_hdc, // Target device HDC - m_TargetRect.left, // X sink position - m_TargetRect.top, // Y sink position - m_TargetRect.right - m_TargetRect.left, // Destination width - m_TargetRect.bottom - m_TargetRect.top, // Destination height - SourceRect.left, // X source position - lAdjustedSourceTop, // Adjusted Y source position - SourceRect.right - SourceRect.left, // Source width - SourceRect.bottom - SourceRect.top, // Source height - pImage, // Image data - (BITMAPINFO *) pbmi, // DIB header - DIB_RGB_COLORS, // Type of palette - SRCCOPY); // Simple image copy - } - - // This shows the sample reference times over the top of the image which - // looks a little flickery. I tried using GdiSetBatchLimit and GdiFlush to - // control the screen updates but it doesn't quite work as expected and - // only partially reduces the flicker. I also tried using a memory context - // and combining the two in that before doing a final BitBlt operation to - // the screen, unfortunately this has considerable performance penalties - // and also means that this code is not executed when compiled retail - - #ifdef DEBUG - DisplaySampleTimes(pMediaSample); - #endif -} - - -// This is called with an IMediaSample interface on the image to be drawn. We -// decide on the drawing mechanism based on who's allocator we are using. We -// may be called when the window wants an image painted by WM_PAINT messages -// We can't realise the palette here because we have the renderer lock, any -// call to realise may cause an interthread send message to the window thread -// which may in turn be waiting to get the renderer lock before servicing it - -BOOL CDrawImage::DrawImage(IMediaSample *pMediaSample) -{ - ASSERT(m_hdc); - ASSERT(m_MemoryDC); - NotifyStartDraw(); - - // If the output pin used our allocator then the samples passed are in - // fact CVideoSample objects that contain CreateDIBSection data that we - // use to do faster image rendering, they may optionally also contain a - // DirectDraw surface pointer in which case we do not do the drawing - - if (m_bUsingImageAllocator == FALSE) { - SlowRender(pMediaSample); - EXECUTE_ASSERT(GdiFlush()); - NotifyEndDraw(); - return TRUE; - } - - // This is a DIBSECTION buffer - - FastRender(pMediaSample); - EXECUTE_ASSERT(GdiFlush()); - NotifyEndDraw(); - return TRUE; -} - - -BOOL CDrawImage::DrawVideoImageHere( - HDC hdc, - IMediaSample *pMediaSample, - LPRECT lprcSrc, - LPRECT lprcDst - ) -{ - ASSERT(m_pMediaType); - BITMAPINFOHEADER *pbmi = HEADER(m_pMediaType->Format()); - BYTE *pImage; - - // Get the image data buffer - - HRESULT hr = pMediaSample->GetPointer(&pImage); - if (FAILED(hr)) { - return FALSE; - } - - RECT SourceRect; - RECT TargetRect; - - if (lprcSrc) - SourceRect = *lprcSrc; - else - SourceRect = ScaleSourceRect(&m_SourceRect); - - if (lprcDst) - TargetRect = *lprcDst; - else - TargetRect = m_TargetRect; - - LONG lAdjustedSourceTop = SourceRect.top; - // if the origin of bitmap is bottom-left, adjust soruce_rect_top - // to be the bottom-left corner instead of the top-left. - if (pbmi->biHeight > 0) { - lAdjustedSourceTop = pbmi->biHeight - SourceRect.bottom; - } - - - // Stretch the image when copying to the DC - - BOOL bRet = (0 != StretchDIBits(hdc, - TargetRect.left, - TargetRect.top, - TargetRect.right - TargetRect.left, - TargetRect.bottom - TargetRect.top, - SourceRect.left, - lAdjustedSourceTop, - SourceRect.right - SourceRect.left, - SourceRect.bottom - SourceRect.top, - pImage, - (BITMAPINFO *)pbmi, - DIB_RGB_COLORS, - SRCCOPY)); - return bRet; -} - - -// This is called by the owning window object after it has created the window -// and it's drawing contexts. We are constructed with the base window we'll -// be drawing into so when given the notification we retrive the device HDCs -// to draw with. We cannot call these in our constructor as they are virtual - -void CDrawImage::SetDrawContext() -{ - m_MemoryDC = m_pBaseWindow->GetMemoryHDC(); - m_hdc = m_pBaseWindow->GetWindowHDC(); -} - - -// This is called to set the target rectangle in the video window, it will be -// called whenever a WM_SIZE message is retrieved from the message queue. We -// simply store the rectangle and use it later when we do the drawing calls - -void CDrawImage::SetTargetRect(RECT *pTargetRect) -{ - ASSERT(pTargetRect); - m_TargetRect = *pTargetRect; - SetStretchMode(); -} - - -// Return the current target rectangle - -void CDrawImage::GetTargetRect(RECT *pTargetRect) -{ - ASSERT(pTargetRect); - *pTargetRect = m_TargetRect; -} - - -// This is called when we want to change the section of the image to draw. We -// use this information in the drawing operation calls later on. We must also -// see if the source and destination rectangles have the same dimensions. If -// not we must stretch during the drawing rather than a direct pixel copy - -void CDrawImage::SetSourceRect(RECT *pSourceRect) -{ - ASSERT(pSourceRect); - m_SourceRect = *pSourceRect; - SetStretchMode(); -} - - -// Return the current source rectangle - -void CDrawImage::GetSourceRect(RECT *pSourceRect) -{ - ASSERT(pSourceRect); - *pSourceRect = m_SourceRect; -} - - -// This is called when either the source or destination rectanges change so we -// can update the stretch flag. If the rectangles don't match we stretch the -// video during the drawing otherwise we call the fast pixel copy functions -// NOTE the source and/or the destination rectangle may be completely empty - -void CDrawImage::SetStretchMode() -{ - // Calculate the overall rectangle dimensions - - LONG SourceWidth = m_SourceRect.right - m_SourceRect.left; - LONG SinkWidth = m_TargetRect.right - m_TargetRect.left; - LONG SourceHeight = m_SourceRect.bottom - m_SourceRect.top; - LONG SinkHeight = m_TargetRect.bottom - m_TargetRect.top; - - m_bStretch = TRUE; - if (SourceWidth == SinkWidth) { - if (SourceHeight == SinkHeight) { - m_bStretch = FALSE; - } - } -} - - -// Tell us whose allocator we are using. This should be called with TRUE if -// the filter agrees to use an allocator based around the CImageAllocator -// SDK base class - whose image buffers are made through CreateDIBSection. -// Otherwise this should be called with FALSE and we will draw the images -// using SetDIBitsToDevice and StretchDIBitsToDevice. None of these calls -// can handle buffers which have non zero strides (like DirectDraw uses) - -void CDrawImage::NotifyAllocator(BOOL bUsingImageAllocator) -{ - m_bUsingImageAllocator = bUsingImageAllocator; -} - - -// Are we using the image DIBSECTION allocator - -BOOL CDrawImage::UsingImageAllocator() -{ - return m_bUsingImageAllocator; -} - - -// We need the media type of the connection so that we can get the BITMAPINFO -// from it. We use that in the calls to draw the image such as StretchDIBits -// and also when updating the colour table held in shared memory DIBSECTIONs - -void CDrawImage::NotifyMediaType(CMediaType *pMediaType) -{ - m_pMediaType = pMediaType; -} - - -// We store in this object a cookie maintaining the current palette version. -// Each time a palettised format is changed we increment this value so that -// when we come to draw the images we look at the colour table value they -// have and if less than the current we know to update it. This version is -// only needed and indeed used when working with shared memory DIBSECTIONs - -LONG CDrawImage::GetPaletteVersion() -{ - return m_PaletteVersion; -} - - -// Resets the current palette version number - -void CDrawImage::ResetPaletteVersion() -{ - m_PaletteVersion = PALETTE_VERSION; -} - - -// Increment the current palette version - -void CDrawImage::IncrementPaletteVersion() -{ - m_PaletteVersion++; -} - - -// Constructor must initialise the base allocator. Each sample we create has a -// palette version cookie on board. When the source filter changes the palette -// during streaming the window object increments an internal cookie counter it -// keeps as well. When it comes to render the samples it looks at the cookie -// values and if they don't match then it knows to update the sample's colour -// table. However we always create samples with a cookie of PALETTE_VERSION -// If there have been multiple format changes and we disconnect and reconnect -// thereby causing the samples to be reallocated we will create them with a -// cookie much lower than the current version, this isn't a problem since it -// will be seen by the window object and the versions will then be updated - -CImageAllocator::CImageAllocator(CBaseFilter *pFilter, - TCHAR *pName, - HRESULT *phr) : - CBaseAllocator(pName,NULL,phr,TRUE,TRUE), - m_pFilter(pFilter) -{ - ASSERT(phr); - ASSERT(pFilter); -} - - -// Check our DIB buffers have been released - -#ifdef DEBUG -CImageAllocator::~CImageAllocator() -{ - ASSERT(m_bCommitted == FALSE); -} -#endif - - -// Called from destructor and also from base class to free resources. We work -// our way through the list of media samples deleting the DIBSECTION created -// for each. All samples should be back in our list so there is no chance a -// filter is still using one to write on the display or hold on a pending list - -void CImageAllocator::Free() -{ - ASSERT(m_lAllocated == m_lFree.GetCount()); - EXECUTE_ASSERT(GdiFlush()); - CImageSample *pSample; - DIBDATA *pDibData; - - while (m_lFree.GetCount() != 0) { - pSample = (CImageSample *) m_lFree.RemoveHead(); - pDibData = pSample->GetDIBData(); - EXECUTE_ASSERT(DeleteObject(pDibData->hBitmap)); - EXECUTE_ASSERT(CloseHandle(pDibData->hMapping)); - delete pSample; - } - - m_lAllocated = 0; -} - - -// Prepare the allocator by checking all the input parameters - -STDMETHODIMP CImageAllocator::CheckSizes(ALLOCATOR_PROPERTIES *pRequest) -{ - // Check we have a valid connection - - if (m_pMediaType == NULL) { - return VFW_E_NOT_CONNECTED; - } - - // NOTE We always create a DIB section with the source format type which - // may contain a source palette. When we do the BitBlt drawing operation - // the target display device may contain a different palette (we may not - // have the focus) in which case GDI will do after the palette mapping - - VIDEOINFOHEADER *pVideoInfo = (VIDEOINFOHEADER *) m_pMediaType->Format(); - - // When we call CreateDIBSection it implicitly maps only enough memory - // for the image as defined by thee BITMAPINFOHEADER. If the user asks - // for an image smaller than this then we reject the call, if they ask - // for an image larger than this then we return what they can have - - if ((DWORD) pRequest->cbBuffer < pVideoInfo->bmiHeader.biSizeImage) { - return E_INVALIDARG; - } - - // Reject buffer prefixes - - if (pRequest->cbPrefix > 0) { - return E_INVALIDARG; - } - - pRequest->cbBuffer = pVideoInfo->bmiHeader.biSizeImage; - return NOERROR; -} - - -// Agree the number of media sample buffers and their sizes. The base class -// this allocator is derived from allows samples to be aligned only on byte -// boundaries NOTE the buffers are not allocated until the Commit call - -STDMETHODIMP CImageAllocator::SetProperties( - ALLOCATOR_PROPERTIES * pRequest, - ALLOCATOR_PROPERTIES * pActual) -{ - ALLOCATOR_PROPERTIES Adjusted = *pRequest; - - // Check the parameters fit with the current connection - - HRESULT hr = CheckSizes(&Adjusted); - if (FAILED(hr)) { - return hr; - } - return CBaseAllocator::SetProperties(&Adjusted, pActual); -} - - -// Commit the memory by allocating the agreed number of media samples. For -// each sample we are committed to creating we have a CImageSample object -// that we use to manage it's resources. This is initialised with a DIBDATA -// structure that contains amongst other things the GDI DIBSECTION handle -// We will access the renderer media type during this so we must have locked -// (to prevent the format changing for example). The class overrides Commit -// and Decommit to do this locking (base class Commit in turn calls Alloc) - -HRESULT CImageAllocator::Alloc(void) -{ - ASSERT(m_pMediaType); - CImageSample *pSample; - DIBDATA DibData; - - // Check the base allocator says it's ok to continue - - HRESULT hr = CBaseAllocator::Alloc(); - if (FAILED(hr)) { - return hr; - } - - // We create a new memory mapped object although we don't map it into our - // address space because GDI does that in CreateDIBSection. It is possible - // that we run out of resources before creating all the samples in which - // case the available sample list is left with those already created - - ASSERT(m_lAllocated == 0); - while (m_lAllocated < m_lCount) { - - // Create and initialise a shared memory GDI buffer - - HRESULT hr = CreateDIB(m_lSize,DibData); - if (FAILED(hr)) { - return hr; - } - - // Create the sample object and pass it the DIBDATA - - pSample = CreateImageSample(DibData.pBase,m_lSize); - if (pSample == NULL) { - EXECUTE_ASSERT(DeleteObject(DibData.hBitmap)); - EXECUTE_ASSERT(CloseHandle(DibData.hMapping)); - return E_OUTOFMEMORY; - } - - // Add the completed sample to the available list - - pSample->SetDIBData(&DibData); - m_lFree.Add(pSample); - m_lAllocated++; - } - return NOERROR; -} - - -// We have a virtual method that allocates the samples so that a derived class -// may override it and allocate more specialised sample objects. So long as it -// derives its samples from CImageSample then all this code will still work ok - -CImageSample *CImageAllocator::CreateImageSample(LPBYTE pData,LONG Length) -{ - HRESULT hr = NOERROR; - CImageSample *pSample; - - // Allocate the new sample and check the return codes - - pSample = new CImageSample((CBaseAllocator *) this, // Base class - NAME("Video sample"), // DEBUG name - (HRESULT *) &hr, // Return code - (LPBYTE) pData, // DIB address - (LONG) Length); // Size of DIB - - if (pSample == NULL || FAILED(hr)) { - delete pSample; - return NULL; - } - return pSample; -} - - -// This function allocates a shared memory block for use by the source filter -// generating DIBs for us to render. The memory block is created in shared -// memory so that GDI doesn't have to copy the memory when we do a BitBlt - -HRESULT CImageAllocator::CreateDIB(LONG InSize,DIBDATA &DibData) -{ - BITMAPINFO *pbmi; // Format information for pin - BYTE *pBase; // Pointer to the actual image - HANDLE hMapping; // Handle to mapped object - HBITMAP hBitmap; // DIB section bitmap handle - - // Create a file mapping object and map into our address space - - hMapping = CreateFileMapping(hMEMORY, // Use system page file - NULL, // No security attributes - PAGE_READWRITE, // Full access to memory - (DWORD) 0, // Less than 4Gb in size - InSize, // Size of buffer - NULL); // No name to section - if (hMapping == NULL) { - DWORD Error = GetLastError(); - return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, Error); - } - - // NOTE We always create a DIB section with the source format type which - // may contain a source palette. When we do the BitBlt drawing operation - // the target display device may contain a different palette (we may not - // have the focus) in which case GDI will do after the palette mapping - - pbmi = (BITMAPINFO *) HEADER(m_pMediaType->Format()); - if (m_pMediaType == NULL) { - DbgBreak("Invalid media type"); - } - - hBitmap = CreateDIBSection((HDC) NULL, // NO device context - pbmi, // Format information - DIB_RGB_COLORS, // Use the palette - (VOID **) &pBase, // Pointer to image data - hMapping, // Mapped memory handle - (DWORD) 0); // Offset into memory - - if (hBitmap == NULL || pBase == NULL) { - EXECUTE_ASSERT(CloseHandle(hMapping)); - DWORD Error = GetLastError(); - return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, Error); - } - - // Initialise the DIB information structure - - DibData.hBitmap = hBitmap; - DibData.hMapping = hMapping; - DibData.pBase = pBase; - DibData.PaletteVersion = PALETTE_VERSION; - GetObject(hBitmap,sizeof(DIBSECTION),(VOID *)&DibData.DibSection); - - return NOERROR; -} - - -// We use the media type during the DIBSECTION creation - -void CImageAllocator::NotifyMediaType(CMediaType *pMediaType) -{ - m_pMediaType = pMediaType; -} - - -// Overriden to increment the owning object's reference count - -STDMETHODIMP_(ULONG) CImageAllocator::NonDelegatingAddRef() -{ - return m_pFilter->AddRef(); -} - - -// Overriden to decrement the owning object's reference count - -STDMETHODIMP_(ULONG) CImageAllocator::NonDelegatingRelease() -{ - return m_pFilter->Release(); -} - - -// If you derive a class from CMediaSample that has to transport specialised -// member variables and entry points then there are three alternate solutions -// The first is to create a memory buffer larger than actually required by the -// sample and store your information either at the beginning of it or at the -// end, the former being moderately safer allowing for misbehaving transform -// filters. You then adjust the buffer address when you create the base media -// sample. This has the disadvantage of breaking up the memory allocated to -// the samples into separate blocks. The second solution is to implement a -// class derived from CMediaSample and support additional interface(s) that -// convey your private data. This means defining a custom interface. The final -// alternative is to create a class that inherits from CMediaSample and adds -// the private data structures, when you get an IMediaSample in your Receive() -// call check to see if your allocator is being used, and if it is then cast -// the IMediaSample into one of your objects. Additional checks can be made -// to ensure the sample's this pointer is known to be one of your own objects - -CImageSample::CImageSample(CBaseAllocator *pAllocator, - TCHAR *pName, - HRESULT *phr, - LPBYTE pBuffer, - LONG length) : - CMediaSample(pName,pAllocator,phr,pBuffer,length), - m_bInit(FALSE) -{ - ASSERT(pAllocator); - ASSERT(pBuffer); -} - - -// Set the shared memory DIB information - -void CImageSample::SetDIBData(DIBDATA *pDibData) -{ - ASSERT(pDibData); - m_DibData = *pDibData; - m_bInit = TRUE; -} - - -// Retrieve the shared memory DIB data - -DIBDATA *CImageSample::GetDIBData() -{ - ASSERT(m_bInit == TRUE); - return &m_DibData; -} - - -// This class handles the creation of a palette. It is fairly specialist and -// is intended to simplify palette management for video renderer filters. It -// is for this reason that the constructor requires three other objects with -// which it interacts, namely a base media filter, a base window and a base -// drawing object although the base window or the draw object may be NULL to -// ignore that part of us. We try not to create and install palettes unless -// absolutely necessary as they typically require WM_PALETTECHANGED messages -// to be sent to every window thread in the system which is very expensive - -CImagePalette::CImagePalette(CBaseFilter *pBaseFilter, - CBaseWindow *pBaseWindow, - CDrawImage *pDrawImage) : - m_pBaseWindow(pBaseWindow), - m_pFilter(pBaseFilter), - m_pDrawImage(pDrawImage), - m_hPalette(NULL) -{ - ASSERT(m_pFilter); -} - - -// Destructor - -#ifdef DEBUG -CImagePalette::~CImagePalette() -{ - ASSERT(m_hPalette == NULL); -} -#endif - - -// We allow dynamic format changes of the palette but rather than change the -// palette every time we call this to work out whether an update is required. -// If the original type didn't use a palette and the new one does (or vica -// versa) then we return TRUE. If neither formats use a palette we'll return -// FALSE. If both formats use a palette we compare their colours and return -// FALSE if they match. This therefore short circuits palette creation unless -// absolutely necessary since installing palettes is an expensive operation - -BOOL CImagePalette::ShouldUpdate(const VIDEOINFOHEADER *pNewInfo, - const VIDEOINFOHEADER *pOldInfo) -{ - // We may not have a current format yet - - if (pOldInfo == NULL) { - return TRUE; - } - - // Do both formats not require a palette - - if (ContainsPalette(pNewInfo) == FALSE) { - if (ContainsPalette(pOldInfo) == FALSE) { - return FALSE; - } - } - - // Compare the colours to see if they match - - DWORD VideoEntries = pNewInfo->bmiHeader.biClrUsed; - if (ContainsPalette(pNewInfo) == TRUE) - if (ContainsPalette(pOldInfo) == TRUE) - if (pOldInfo->bmiHeader.biClrUsed == VideoEntries) - if (pOldInfo->bmiHeader.biClrUsed > 0) - if (memcmp((PVOID) GetBitmapPalette(pNewInfo), - (PVOID) GetBitmapPalette(pOldInfo), - VideoEntries * sizeof(RGBQUAD)) == 0) { - - return FALSE; - } - return TRUE; -} - - -// This is normally called when the input pin type is set to install a palette -// We will typically be called from two different places. The first is when we -// have negotiated a palettised media type after connection, the other is when -// we receive a new type during processing with an updated palette in which -// case we must remove and release the resources held by the current palette - -// We can be passed an optional device name if we wish to prepare a palette -// for a specific monitor on a multi monitor system - -HRESULT CImagePalette::PreparePalette(const CMediaType *pmtNew, - const CMediaType *pmtOld, - LPSTR szDevice) -{ - const VIDEOINFOHEADER *pNewInfo = (VIDEOINFOHEADER *) pmtNew->Format(); - const VIDEOINFOHEADER *pOldInfo = (VIDEOINFOHEADER *) pmtOld->Format(); - ASSERT(pNewInfo); - - // This is an performance optimisation, when we get a media type we check - // to see if the format requires a palette change. If either we need one - // when previously we didn't or vica versa then this returns TRUE, if we - // previously needed a palette and we do now it compares their colours - - if (ShouldUpdate(pNewInfo,pOldInfo) == FALSE) { - NOTE("No update needed"); - return S_FALSE; - } - - // We must notify the filter graph that the application may have changed - // the palette although in practice we don't bother checking to see if it - // is really different. If it tries to get the palette either the window - // or renderer lock will ensure it doesn't get in until we are finished - - RemovePalette(); - m_pFilter->NotifyEvent(EC_PALETTE_CHANGED,0,0); - - // Do we need a palette for the new format - - if (ContainsPalette(pNewInfo) == FALSE) { - NOTE("New has no palette"); - return S_FALSE; - } - - if (m_pBaseWindow) { - m_pBaseWindow->LockPaletteLock(); - } - - // If we're changing the palette on the fly then we increment our palette - // cookie which is compared against the cookie also stored in all of our - // DIBSECTION media samples. If they don't match when we come to draw it - // then we know the sample is out of date and we'll update it's palette - - NOTE("Making new colour palette"); - m_hPalette = MakePalette(pNewInfo, szDevice); - ASSERT(m_hPalette != NULL); - - if (m_pBaseWindow) { - m_pBaseWindow->UnlockPaletteLock(); - } - - // The window in which the new palette is to be realised may be a NULL - // pointer to signal that no window is in use, if so we don't call it - // Some filters just want to use this object to create/manage palettes - - if (m_pBaseWindow) m_pBaseWindow->SetPalette(m_hPalette); - - // This is the only time where we need access to the draw object to say - // to it that a new palette will be arriving on a sample real soon. The - // constructor may take a NULL pointer in which case we don't call this - - if (m_pDrawImage) m_pDrawImage->IncrementPaletteVersion(); - return NOERROR; -} - - -// Helper function to copy a palette out of any kind of VIDEOINFO (ie it may -// be YUV or true colour) into a palettised VIDEOINFO. We use this changing -// palettes on DirectDraw samples as a source filter can attach a palette to -// any buffer (eg YUV) and hand it back. We make a new palette out of that -// format and then copy the palette colours into the current connection type - -HRESULT CImagePalette::CopyPalette(const CMediaType *pSrc,CMediaType *pDest) -{ - // Reset the destination palette before starting - - VIDEOINFOHEADER *pDestInfo = (VIDEOINFOHEADER *) pDest->Format(); - pDestInfo->bmiHeader.biClrUsed = 0; - pDestInfo->bmiHeader.biClrImportant = 0; - - // Does the destination have a palette - - if (PALETTISED(pDestInfo) == FALSE) { - NOTE("No destination palette"); - return S_FALSE; - } - - // Does the source contain a palette - - const VIDEOINFOHEADER *pSrcInfo = (VIDEOINFOHEADER *) pSrc->Format(); - if (ContainsPalette(pSrcInfo) == FALSE) { - NOTE("No source palette"); - return S_FALSE; - } - - // The number of colours may be zero filled - - DWORD PaletteEntries = pSrcInfo->bmiHeader.biClrUsed; - if (PaletteEntries == 0) { - DWORD Maximum = (1 << pSrcInfo->bmiHeader.biBitCount); - NOTE1("Setting maximum colours (%d)",Maximum); - PaletteEntries = Maximum; - } - - // Make sure the destination has enough room for the palette - - ASSERT(pSrcInfo->bmiHeader.biClrUsed <= iPALETTE_COLORS); - ASSERT(pSrcInfo->bmiHeader.biClrImportant <= PaletteEntries); - ASSERT(COLORS(pDestInfo) == GetBitmapPalette(pDestInfo)); - pDestInfo->bmiHeader.biClrUsed = PaletteEntries; - pDestInfo->bmiHeader.biClrImportant = pSrcInfo->bmiHeader.biClrImportant; - ULONG BitmapSize = GetBitmapFormatSize(HEADER(pSrcInfo)); - - if (pDest->FormatLength() < BitmapSize) { - NOTE("Reallocating destination"); - pDest->ReallocFormatBuffer(BitmapSize); - } - - // Now copy the palette colours across - - CopyMemory((PVOID) COLORS(pDestInfo), - (PVOID) GetBitmapPalette(pSrcInfo), - PaletteEntries * sizeof(RGBQUAD)); - - return NOERROR; -} - - -// This is normally called when the palette is changed (typically during a -// dynamic format change) to remove any palette we previously installed. We -// replace it (if necessary) in the video window with a standard VGA palette -// that should always be available even if this is a true colour display - -HRESULT CImagePalette::RemovePalette() -{ - if (m_pBaseWindow) { - m_pBaseWindow->LockPaletteLock(); - } - - // Do we have a palette to remove - - if (m_hPalette != NULL) { - - if (m_pBaseWindow) { - // Make sure that the window's palette handle matches - // our palette handle. - ASSERT(m_hPalette == m_pBaseWindow->GetPalette()); - - m_pBaseWindow->UnsetPalette(); - } - - EXECUTE_ASSERT(DeleteObject(m_hPalette)); - m_hPalette = NULL; - } - - if (m_pBaseWindow) { - m_pBaseWindow->UnlockPaletteLock(); - } - - return NOERROR; -} - - -// Called to create a palette for the object, the data structure used by GDI -// to describe a palette is a LOGPALETTE, this includes a variable number of -// PALETTEENTRY fields which are the colours, we have to convert the RGBQUAD -// colour fields we are handed in a BITMAPINFO from the media type into these -// This handles extraction of palettes from true colour and YUV media formats - -// We can be passed an optional device name if we wish to prepare a palette -// for a specific monitor on a multi monitor system - -HPALETTE CImagePalette::MakePalette(const VIDEOINFOHEADER *pVideoInfo, LPSTR szDevice) -{ - ASSERT(ContainsPalette(pVideoInfo) == TRUE); - ASSERT(pVideoInfo->bmiHeader.biClrUsed <= iPALETTE_COLORS); - BITMAPINFOHEADER *pHeader = HEADER(pVideoInfo); - - const RGBQUAD *pColours; // Pointer to the palette - LOGPALETTE *lp; // Used to create a palette - HPALETTE hPalette; // Logical palette object - - lp = (LOGPALETTE *) new BYTE[sizeof(LOGPALETTE) + SIZE_PALETTE]; - if (lp == NULL) { - return NULL; - } - - // Unfortunately for some hare brained reason a GDI palette entry (a - // PALETTEENTRY structure) is different to a palette entry from a DIB - // format (a RGBQUAD structure) so we have to do the field conversion - // The VIDEOINFO containing the palette may be a true colour type so - // we use GetBitmapPalette to skip over any bit fields if they exist - - lp->palVersion = PALVERSION; - lp->palNumEntries = (USHORT) pHeader->biClrUsed; - if (lp->palNumEntries == 0) - lp->palNumEntries = (WORD) (1 << pHeader->biBitCount); - pColours = GetBitmapPalette(pVideoInfo); - - for (DWORD dwCount = 0;dwCount < lp->palNumEntries;dwCount++) { - lp->palPalEntry[dwCount].peRed = pColours[dwCount].rgbRed; - lp->palPalEntry[dwCount].peGreen = pColours[dwCount].rgbGreen; - lp->palPalEntry[dwCount].peBlue = pColours[dwCount].rgbBlue; - lp->palPalEntry[dwCount].peFlags = 0; - } - - MakeIdentityPalette(lp->palPalEntry, lp->palNumEntries, szDevice); - - // Create a logical palette - - hPalette = CreatePalette(lp); - ASSERT(hPalette != NULL); - delete[] lp; - return hPalette; -} - - -// GDI does a fair job of compressing the palette entries you give it, so for -// example if you have five entries with an RGB colour (0,0,0) it will remove -// all but one of them. When you subsequently draw an image it will map from -// your logical palette to the compressed device palette. This function looks -// to see if it is trying to be an identity palette and if so sets the flags -// field in the PALETTEENTRYs so they remain expanded to boost performance - -// We can be passed an optional device name if we wish to prepare a palette -// for a specific monitor on a multi monitor system - -HRESULT CImagePalette::MakeIdentityPalette(PALETTEENTRY *pEntry,INT iColours, LPSTR szDevice) -{ - PALETTEENTRY SystemEntries[10]; // System palette entries - BOOL bIdentityPalette = TRUE; // Is an identity palette - ASSERT(iColours <= iPALETTE_COLORS); // Should have a palette - const int PalLoCount = 10; // First ten reserved colours - const int PalHiStart = 246; // Last VGA palette entries - - // Does this have the full colour range - - if (iColours < 10) { - return S_FALSE; - } - - // Apparently some displays have odd numbers of system colours - - // Get a DC on the right monitor - it's ugly, but this is the way you have - // to do it - HDC hdc; - if (szDevice == NULL || lstrcmpiA(szDevice, "DISPLAY") == 0) - hdc = CreateDCA("DISPLAY", NULL, NULL, NULL); - else - hdc = CreateDCA(NULL, szDevice, NULL, NULL); - if (NULL == hdc) { - return E_OUTOFMEMORY; - } - INT Reserved = GetDeviceCaps(hdc,NUMRESERVED); - if (Reserved != 20) { - DeleteDC(hdc); - return S_FALSE; - } - - // Compare our palette against the first ten system entries. The reason I - // don't do a memory compare between our two arrays of colours is because - // I am not sure what will be in the flags fields for the system entries - - UINT Result = GetSystemPaletteEntries(hdc,0,PalLoCount,SystemEntries); - UINT Count; - for (Count = 0;Count < Result;Count++) { - if (SystemEntries[Count].peRed != pEntry[Count].peRed || - SystemEntries[Count].peGreen != pEntry[Count].peGreen || - SystemEntries[Count].peBlue != pEntry[Count].peBlue) { - bIdentityPalette = FALSE; - } - } - - // And likewise compare against the last ten entries - - Result = GetSystemPaletteEntries(hdc,PalHiStart,PalLoCount,SystemEntries); - for (Count = 0;Count < Result;Count++) { - if (INT(Count) + PalHiStart < iColours) { - if (SystemEntries[Count].peRed != pEntry[PalHiStart + Count].peRed || - SystemEntries[Count].peGreen != pEntry[PalHiStart + Count].peGreen || - SystemEntries[Count].peBlue != pEntry[PalHiStart + Count].peBlue) { - bIdentityPalette = FALSE; - } - } - } - - // If not an identity palette then return S_FALSE - - DeleteDC(hdc); - if (bIdentityPalette == FALSE) { - return S_FALSE; - } - - // Set the non VGA entries so that GDI doesn't map them - - for (Count = PalLoCount;INT(Count) < min(PalHiStart,iColours);Count++) { - pEntry[Count].peFlags = PC_NOCOLLAPSE; - } - return NOERROR; -} - - -// Constructor initialises the VIDEOINFO we keep storing the current display -// format. The format can be changed at any time, to reset the format held -// by us call the RefreshDisplayType directly (it's a public method). Since -// more than one thread will typically call us (ie window threads resetting -// the type and source threads in the type checking methods) we have a lock - -CImageDisplay::CImageDisplay() -{ - RefreshDisplayType(NULL); -} - - - -// This initialises the format we hold which contains the display device type -// We do a conversion on the display device type in here so that when we start -// type checking input formats we can assume that certain fields have been set -// correctly, an example is when we make the 16 bit mask fields explicit. This -// is normally called when we receive WM_DEVMODECHANGED device change messages - -// The optional szDeviceName parameter tells us which monitor we are interested -// in for a multi monitor system - -HRESULT CImageDisplay::RefreshDisplayType(LPSTR szDeviceName) -{ - CAutoLock cDisplayLock(this); - - // Set the preferred format type - - ZeroMemory((PVOID)&m_Display,sizeof(VIDEOINFOHEADER)+sizeof(TRUECOLORINFO)); - m_Display.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - m_Display.bmiHeader.biBitCount = FALSE; - - // Get the bit depth of a device compatible bitmap - - // get caps of whichever monitor they are interested in (multi monitor) - HDC hdcDisplay; - // it's ugly, but this is the way you have to do it - if (szDeviceName == NULL || lstrcmpiA(szDeviceName, "DISPLAY") == 0) - hdcDisplay = CreateDCA("DISPLAY", NULL, NULL, NULL); - else - hdcDisplay = CreateDCA(NULL, szDeviceName, NULL, NULL); - if (hdcDisplay == NULL) { - ASSERT(FALSE); - DbgLog((LOG_ERROR,1,TEXT("ACK! Can't get a DC for %hs"), - szDeviceName ? szDeviceName : "")); - return E_FAIL; - } else { - DbgLog((LOG_TRACE,3,TEXT("Created a DC for %s"), - szDeviceName ? szDeviceName : "")); - } - HBITMAP hbm = CreateCompatibleBitmap(hdcDisplay,1,1); - if ( hbm ) - { - GetDIBits(hdcDisplay,hbm,0,1,NULL,(BITMAPINFO *)&m_Display.bmiHeader,DIB_RGB_COLORS); - - // This call will get the colour table or the proper bitfields - GetDIBits(hdcDisplay,hbm,0,1,NULL,(BITMAPINFO *)&m_Display.bmiHeader,DIB_RGB_COLORS); - DeleteObject(hbm); - } - DeleteDC(hdcDisplay); - - // Complete the display type initialisation - - ASSERT(CheckHeaderValidity(&m_Display)); - UpdateFormat(&m_Display); - DbgLog((LOG_TRACE,3,TEXT("New DISPLAY bit depth =%d"), - m_Display.bmiHeader.biBitCount)); - return NOERROR; -} - - -// We assume throughout this code that any bitfields masks are allowed no -// more than eight bits to store a colour component. This checks that the -// bit count assumption is enforced and also makes sure that all the bits -// set are contiguous. We return a boolean TRUE if the field checks out ok - -BOOL CImageDisplay::CheckBitFields(const VIDEOINFO *pInput) -{ - DWORD *pBitFields = (DWORD *) BITMASKS(pInput); - - for (INT iColour = iRED;iColour <= iBLUE;iColour++) { - - // First of all work out how many bits are set - - DWORD SetBits = CountSetBits(pBitFields[iColour]); - if (SetBits > iMAXBITS || SetBits == 0) { - NOTE1("Bit fields for component %d invalid",iColour); - return FALSE; - } - - // Next work out the number of zero bits prefix - DWORD PrefixBits = CountPrefixBits(pBitFields[iColour]); - - // This is going to see if all the bits set are contiguous (as they - // should be). We know how much to shift them right by from the - // count of prefix bits. The number of bits set defines a mask, we - // invert this (ones complement) and AND it with the shifted bit - // fields. If the result is NON zero then there are bit(s) sticking - // out the left hand end which means they are not contiguous - - DWORD TestField = pBitFields[iColour] >> PrefixBits; - DWORD Mask = ULONG_MAX << SetBits; - if (TestField & Mask) { - NOTE1("Bit fields for component %d not contiguous",iColour); - return FALSE; - } - } - return TRUE; -} - - -// This counts the number of bits set in the input field - -DWORD CImageDisplay::CountSetBits(DWORD Field) -{ - // This is a relatively well known bit counting algorithm - - DWORD Count = 0; - DWORD init = Field; - - // Until the input is exhausted, count the number of bits - - while (init) { - init = init & (init - 1); // Turn off the bottommost bit - Count++; - } - return Count; -} - - -// This counts the number of zero bits upto the first one set NOTE the input -// field should have been previously checked to ensure there is at least one -// set although if we don't find one set we return the impossible value 32 - -DWORD CImageDisplay::CountPrefixBits(DWORD Field) -{ - DWORD Mask = 1; - DWORD Count = 0; - - while (TRUE) { - if (Field & Mask) { - return Count; - } - Count++; - - ASSERT(Mask != 0x80000000); - if (Mask == 0x80000000) { - return Count; - } - Mask <<= 1; - } -} - - -// This is called to check the BITMAPINFOHEADER for the input type. There are -// many implicit dependancies between the fields in a header structure which -// if we validate now make for easier manipulation in subsequent handling. We -// also check that the BITMAPINFOHEADER matches it's specification such that -// fields likes the number of planes is one, that it's structure size is set -// correctly and that the bitmap dimensions have not been set as negative - -BOOL CImageDisplay::CheckHeaderValidity(const VIDEOINFO *pInput) -{ - // Check the bitmap width and height are not negative. - - if (pInput->bmiHeader.biWidth <= 0 || - pInput->bmiHeader.biHeight <= 0) { - NOTE("Invalid bitmap dimensions"); - return FALSE; - } - - // Check the compression is either BI_RGB or BI_BITFIELDS - - if (pInput->bmiHeader.biCompression != BI_RGB) { - if (pInput->bmiHeader.biCompression != BI_BITFIELDS) { - NOTE("Invalid compression format"); - return FALSE; - } - } - - // If BI_BITFIELDS compression format check the colour depth - - if (pInput->bmiHeader.biCompression == BI_BITFIELDS) { - if (pInput->bmiHeader.biBitCount != 16) { - if (pInput->bmiHeader.biBitCount != 32) { - NOTE("BI_BITFIELDS not 16/32 bit depth"); - return FALSE; - } - } - } - - // Check the assumptions about the layout of the bit fields - - if (pInput->bmiHeader.biCompression == BI_BITFIELDS) { - if (CheckBitFields(pInput) == FALSE) { - NOTE("Bit fields are not valid"); - return FALSE; - } - } - - // Are the number of planes equal to one - - if (pInput->bmiHeader.biPlanes != 1) { - NOTE("Number of planes not one"); - return FALSE; - } - - // Check the image size is consistent (it can be zero) - - if (pInput->bmiHeader.biSizeImage != GetBitmapSize(&pInput->bmiHeader)) { - if (pInput->bmiHeader.biSizeImage) { - NOTE("Image size incorrectly set"); - return FALSE; - } - } - - // Check the size of the structure - - if (pInput->bmiHeader.biSize != sizeof(BITMAPINFOHEADER)) { - NOTE("Size of BITMAPINFOHEADER wrong"); - return FALSE; - } - return CheckPaletteHeader(pInput); -} - - -// This runs a few simple tests against the palette fields in the input to -// see if it looks vaguely correct. The tests look at the number of palette -// colours present, the number considered important and the biCompression -// field which should always be BI_RGB as no other formats are meaningful - -BOOL CImageDisplay::CheckPaletteHeader(const VIDEOINFO *pInput) -{ - // The checks here are for palettised videos only - - if (PALETTISED(pInput) == FALSE) { - if (pInput->bmiHeader.biClrUsed) { - NOTE("Invalid palette entries"); - return FALSE; - } - return TRUE; - } - - // Compression type of BI_BITFIELDS is meaningless for palette video - - if (pInput->bmiHeader.biCompression != BI_RGB) { - NOTE("Palettised video must be BI_RGB"); - return FALSE; - } - - // Check the number of palette colours is correct - - if (pInput->bmiHeader.biClrUsed > PALETTE_ENTRIES(pInput)) { - NOTE("Too many colours in palette"); - return FALSE; - } - - // The number of important colours shouldn't exceed the number used - - if (pInput->bmiHeader.biClrImportant > pInput->bmiHeader.biClrUsed) { - NOTE("Too many important colours"); - return FALSE; - } - return TRUE; -} - - -// Return the format of the video display - -const VIDEOINFO *CImageDisplay::GetDisplayFormat() -{ - return &m_Display; -} - - -// Return TRUE if the display uses a palette - -BOOL CImageDisplay::IsPalettised() -{ - return PALETTISED(&m_Display); -} - - -// Return the bit depth of the current display setting - -WORD CImageDisplay::GetDisplayDepth() -{ - return m_Display.bmiHeader.biBitCount; -} - - -// Initialise the optional fields in a VIDEOINFO. These are mainly to do with -// the source and destination rectangles and palette information such as the -// number of colours present. It simplifies our code just a little if we don't -// have to keep checking for all the different valid permutations in a header -// every time we want to do anything with it (an example would be creating a -// palette). We set the base class media type before calling this function so -// that the media types between the pins match after a connection is made - -HRESULT CImageDisplay::UpdateFormat(VIDEOINFO *pVideoInfo) -{ - ASSERT(pVideoInfo); - - BITMAPINFOHEADER *pbmi = HEADER(pVideoInfo); - SetRectEmpty(&pVideoInfo->rcSource); - SetRectEmpty(&pVideoInfo->rcTarget); - - // Set the number of colours explicitly - - if (PALETTISED(pVideoInfo)) { - if (pVideoInfo->bmiHeader.biClrUsed == 0) { - pVideoInfo->bmiHeader.biClrUsed = PALETTE_ENTRIES(pVideoInfo); - } - } - - // The number of important colours shouldn't exceed the number used, on - // some displays the number of important colours is not initialised when - // retrieving the display type so we set the colours used correctly - - if (pVideoInfo->bmiHeader.biClrImportant > pVideoInfo->bmiHeader.biClrUsed) { - pVideoInfo->bmiHeader.biClrImportant = PALETTE_ENTRIES(pVideoInfo); - } - - // Change the image size field to be explicit - - if (pVideoInfo->bmiHeader.biSizeImage == 0) { - pVideoInfo->bmiHeader.biSizeImage = GetBitmapSize(&pVideoInfo->bmiHeader); - } - return NOERROR; -} - - -// Lots of video rendering filters want code to check proposed formats are ok -// This checks the VIDEOINFO we are passed as a media type. If the media type -// is a valid media type then we return NOERROR otherwise E_INVALIDARG. Note -// however we only accept formats that can be easily displayed in the display -// so if we are on a 16 bit device we will not accept 24 bit images. The one -// complexity is that most displays draw 8 bit palettised images efficiently -// Also if the input format is less colour bits per pixel then we also accept - -HRESULT CImageDisplay::CheckVideoType(const VIDEOINFO *pInput) -{ - // First of all check the VIDEOINFOHEADER looks correct - - if (CheckHeaderValidity(pInput) == FALSE) { - return E_INVALIDARG; - } - - // Virtually all devices support palettised images efficiently - - if (m_Display.bmiHeader.biBitCount == pInput->bmiHeader.biBitCount) { - if (PALETTISED(pInput) == TRUE) { - ASSERT(PALETTISED(&m_Display) == TRUE); - NOTE("(Video) Type connection ACCEPTED"); - return NOERROR; - } - } - - - // Is the display depth greater than the input format - - if (m_Display.bmiHeader.biBitCount > pInput->bmiHeader.biBitCount) { - NOTE("(Video) Mismatch agreed"); - return NOERROR; - } - - // Is the display depth less than the input format - - if (m_Display.bmiHeader.biBitCount < pInput->bmiHeader.biBitCount) { - NOTE("(Video) Format mismatch"); - return E_INVALIDARG; - } - - - // Both input and display formats are either BI_RGB or BI_BITFIELDS - - ASSERT(m_Display.bmiHeader.biBitCount == pInput->bmiHeader.biBitCount); - ASSERT(PALETTISED(pInput) == FALSE); - ASSERT(PALETTISED(&m_Display) == FALSE); - - // BI_RGB 16 bit representation is implicitly RGB555, and likewise BI_RGB - // 24 bit representation is RGB888. So we initialise a pointer to the bit - // fields they really mean and check against the display device format - // This is only going to be called when both formats are equal bits pixel - - const DWORD *pInputMask = GetBitMasks(pInput); - const DWORD *pDisplayMask = GetBitMasks((VIDEOINFO *)&m_Display); - - if (pInputMask[iRED] != pDisplayMask[iRED] || - pInputMask[iGREEN] != pDisplayMask[iGREEN] || - pInputMask[iBLUE] != pDisplayMask[iBLUE]) { - - NOTE("(Video) Bit field mismatch"); - return E_INVALIDARG; - } - - NOTE("(Video) Type connection ACCEPTED"); - return NOERROR; -} - - -// Return the bit masks for the true colour VIDEOINFO provided - -const DWORD *CImageDisplay::GetBitMasks(const VIDEOINFO *pVideoInfo) -{ - static const DWORD FailMasks[] = {0,0,0}; - - if (pVideoInfo->bmiHeader.biCompression == BI_BITFIELDS) { - return BITMASKS(pVideoInfo); - } - - ASSERT(pVideoInfo->bmiHeader.biCompression == BI_RGB); - - switch (pVideoInfo->bmiHeader.biBitCount) { - case 16: return bits555; - case 24: return bits888; - case 32: return bits888; - default: return FailMasks; - } -} - - -// Check to see if we can support media type pmtIn as proposed by the output -// pin - We first check that the major media type is video and also identify -// the media sub type. Then we thoroughly check the VIDEOINFO type provided -// As well as the contained VIDEOINFO being correct the major type must be -// video, the subtype a recognised video format and the type GUID correct - -HRESULT CImageDisplay::CheckMediaType(const CMediaType *pmtIn) -{ - // Does this have a VIDEOINFOHEADER format block - - const GUID *pFormatType = pmtIn->FormatType(); - if (*pFormatType != FORMAT_VideoInfo) { - NOTE("Format GUID not a VIDEOINFOHEADER"); - return E_INVALIDARG; - } - ASSERT(pmtIn->Format()); - - // Check the format looks reasonably ok - - ULONG Length = pmtIn->FormatLength(); - if (Length < SIZE_VIDEOHEADER) { - NOTE("Format smaller than a VIDEOHEADER"); - return E_FAIL; - } - - VIDEOINFO *pInput = (VIDEOINFO *) pmtIn->Format(); - - // Check the major type is MEDIATYPE_Video - - const GUID *pMajorType = pmtIn->Type(); - if (*pMajorType != MEDIATYPE_Video) { - NOTE("Major type not MEDIATYPE_Video"); - return E_INVALIDARG; - } - - // Check we can identify the media subtype - - const GUID *pSubType = pmtIn->Subtype(); - if (GetBitCount(pSubType) == USHRT_MAX) { - NOTE("Invalid video media subtype"); - return E_INVALIDARG; - } - return CheckVideoType(pInput); -} - - -// Given a video format described by a VIDEOINFO structure we return the mask -// that is used to obtain the range of acceptable colours for this type, for -// example, the mask for a 24 bit true colour format is 0xFF in all cases. A -// 16 bit 5:6:5 display format uses 0xF8, 0xFC and 0xF8, therefore given any -// RGB triplets we can AND them with these fields to find one that is valid - -BOOL CImageDisplay::GetColourMask(DWORD *pMaskRed, - DWORD *pMaskGreen, - DWORD *pMaskBlue) -{ - CAutoLock cDisplayLock(this); - *pMaskRed = 0xFF; - *pMaskGreen = 0xFF; - *pMaskBlue = 0xFF; - - // If this format is palettised then it doesn't have bit fields - - if (m_Display.bmiHeader.biBitCount < 16) { - return FALSE; - } - - // If this is a 24 bit true colour display then it can handle all the - // possible colour component ranges described by a byte. It is never - // allowed for a 24 bit colour depth image to have BI_BITFIELDS set - - if (m_Display.bmiHeader.biBitCount == 24) { - ASSERT(m_Display.bmiHeader.biCompression == BI_RGB); - return TRUE; - } - - // Calculate the mask based on the format's bit fields - - const DWORD *pBitFields = (DWORD *) GetBitMasks((VIDEOINFO *)&m_Display); - DWORD *pOutputMask[] = { pMaskRed, pMaskGreen, pMaskBlue }; - - // We know from earlier testing that there are no more than iMAXBITS - // bits set in the mask and that they are all contiguous. All that - // therefore remains is to shift them into the correct position - - for (INT iColour = iRED;iColour <= iBLUE;iColour++) { - - // This works out how many bits there are and where they live - - DWORD PrefixBits = CountPrefixBits(pBitFields[iColour]); - DWORD SetBits = CountSetBits(pBitFields[iColour]); - - // The first shift moves the bit field so that it is right justified - // in the DWORD, after which we then shift it back left which then - // puts the leading bit in the bytes most significant bit position - - *(pOutputMask[iColour]) = pBitFields[iColour] >> PrefixBits; - *(pOutputMask[iColour]) <<= (iMAXBITS - SetBits); - } - return TRUE; -} - - -/* Helper to convert to VIDEOINFOHEADER2 -*/ -STDAPI ConvertVideoInfoToVideoInfo2(AM_MEDIA_TYPE *pmt) -{ - ASSERT(pmt->formattype == FORMAT_VideoInfo); - VIDEOINFO *pVideoInfo = (VIDEOINFO *)pmt->pbFormat; - PVOID pvNew = CoTaskMemAlloc(pmt->cbFormat + sizeof(VIDEOINFOHEADER2) - - sizeof(VIDEOINFOHEADER)); - if (pvNew == NULL) { - return E_OUTOFMEMORY; - } - CopyMemory(pvNew, pmt->pbFormat, FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader)); - ZeroMemory((PBYTE)pvNew + FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader), - sizeof(VIDEOINFOHEADER2) - sizeof(VIDEOINFOHEADER)); - CopyMemory((PBYTE)pvNew + FIELD_OFFSET(VIDEOINFOHEADER2, bmiHeader), - pmt->pbFormat + FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader), - pmt->cbFormat - FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader)); - VIDEOINFOHEADER2 *pVideoInfo2 = (VIDEOINFOHEADER2 *)pvNew; - pVideoInfo2->dwPictAspectRatioX = (DWORD)pVideoInfo2->bmiHeader.biWidth; - pVideoInfo2->dwPictAspectRatioY = (DWORD)pVideoInfo2->bmiHeader.biHeight; - pmt->formattype = FORMAT_VideoInfo2; - CoTaskMemFree(pmt->pbFormat); - pmt->pbFormat = (PBYTE)pvNew; - pmt->cbFormat += sizeof(VIDEOINFOHEADER2) - sizeof(VIDEOINFOHEADER); - return S_OK; -} diff --git a/src/BaseClasses/winutil.h b/src/BaseClasses/winutil.h deleted file mode 100644 index cb002c9324..0000000000 --- a/src/BaseClasses/winutil.h +++ /dev/null @@ -1,414 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WinUtil.h -// -// Desc: DirectShow base classes - defines generic handler classes. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// Make sure that you call PrepareWindow to initialise the window after -// the object has been constructed. It is a separate method so that -// derived classes can override useful methods like MessageLoop. Also -// any derived class must call DoneWithWindow in its destructor. If it -// doesn't a message may be retrieved and call a derived class member -// function while a thread is executing the base class destructor code - -#ifndef __WINUTIL__ -#define __WINUTIL__ - -const int DEFWIDTH = 320; // Initial window width -const int DEFHEIGHT = 240; // Initial window height -const int CAPTION = 256; // Maximum length of caption -const int TIMELENGTH = 50; // Maximum length of times -const int PROFILESTR = 128; // Normal profile string -const WORD PALVERSION = 0x300; // GDI palette version -const LONG PALETTE_VERSION = (LONG) 1; // Initial palette version -const COLORREF VIDEO_COLOUR = 0; // Defaults to black background -const HANDLE hMEMORY = (HANDLE) (-1); // Says to open as memory file - -#define WIDTH(x) ((*(x)).right - (*(x)).left) -#define HEIGHT(x) ((*(x)).bottom - (*(x)).top) -#define SHOWSTAGE TEXT("WM_SHOWSTAGE") -#define SHOWSTAGETOP TEXT("WM_SHOWSTAGETOP") -#define REALIZEPALETTE TEXT("WM_REALIZEPALETTE") - -class AM_NOVTABLE CBaseWindow -{ -protected: - - HINSTANCE m_hInstance; // Global module instance handle - HWND m_hwnd; // Handle for our window - HDC m_hdc; // Device context for the window - LONG m_Width; // Client window width - LONG m_Height; // Client window height - BOOL m_bActivated; // Has the window been activated - LPTSTR m_pClassName; // Static string holding class name - DWORD m_ClassStyles; // Passed in to our constructor - DWORD m_WindowStyles; // Likewise the initial window styles - DWORD m_WindowStylesEx; // And the extended window styles - UINT m_ShowStageMessage; // Have the window shown with focus - UINT m_ShowStageTop; // Makes the window WS_EX_TOPMOST - UINT m_RealizePalette; // Makes us realize our new palette - HDC m_MemoryDC; // Used for fast BitBlt operations - HPALETTE m_hPalette; // Handle to any palette we may have - BYTE m_bNoRealize; // Don't realize palette now - BYTE m_bBackground; // Should we realise in background - BYTE m_bRealizing; // already realizing the palette - CCritSec m_WindowLock; // Serialise window object access - BOOL m_bDoGetDC; // Should this window get a DC - bool m_bDoPostToDestroy; // Use PostMessage to destroy - CCritSec m_PaletteLock; // This lock protects m_hPalette. - // It should be held anytime the - // program use the value of m_hPalette. - - // Maps windows message procedure into C++ methods - friend LRESULT CALLBACK WndProc(HWND hwnd, // Window handle - UINT uMsg, // Message ID - WPARAM wParam, // First parameter - LPARAM lParam); // Other parameter - - virtual LRESULT OnPaletteChange(HWND hwnd, UINT Message); - -public: - - CBaseWindow(BOOL bDoGetDC = TRUE, bool bPostToDestroy = false); - -#ifdef DEBUG - virtual ~CBaseWindow(); -#endif - - virtual HRESULT DoneWithWindow(); - virtual HRESULT PrepareWindow(); - virtual HRESULT InactivateWindow(); - virtual HRESULT ActivateWindow(); - virtual BOOL OnSize(LONG Width, LONG Height); - virtual BOOL OnClose(); - virtual RECT GetDefaultRect(); - virtual HRESULT UninitialiseWindow(); - virtual HRESULT InitialiseWindow(HWND hwnd); - - HRESULT CompleteConnect(); - HRESULT DoCreateWindow(); - - HRESULT PerformanceAlignWindow(); - HRESULT DoShowWindow(LONG ShowCmd); - void PaintWindow(BOOL bErase); - void DoSetWindowForeground(BOOL bFocus); - virtual HRESULT SetPalette(HPALETTE hPalette); - - void SetRealize(BOOL bRealize) - { - m_bNoRealize = !bRealize; - } - - // Jump over to the window thread to set the current palette - HRESULT SetPalette(); - void UnsetPalette(void); - virtual HRESULT DoRealisePalette(BOOL bForceBackground = FALSE); - - void LockPaletteLock(); - void UnlockPaletteLock(); - - virtual BOOL PossiblyEatMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) - { return FALSE; }; - - // Access our window information - - bool WindowExists(); - LONG GetWindowWidth(); - LONG GetWindowHeight(); - HWND GetWindowHWND(); - HDC GetMemoryHDC(); - HDC GetWindowHDC(); - - #ifdef DEBUG - HPALETTE GetPalette(); - #endif // DEBUG - - // This is the window procedure the derived object should override - - virtual LRESULT OnReceiveMessage(HWND hwnd, // Window handle - UINT uMsg, // Message ID - WPARAM wParam, // First parameter - LPARAM lParam); // Other parameter - - // Must be overriden to return class and window styles - - virtual LPTSTR GetClassWindowStyles( - DWORD *pClassStyles, // Class styles - DWORD *pWindowStyles, // Window styles - DWORD *pWindowStylesEx) PURE; // Extended styles -}; - - -// This helper class is entirely subservient to the owning CBaseWindow object -// All this object does is to split out the actual drawing operation from the -// main object (because it was becoming too large). We have a number of entry -// points to set things like the draw device contexts, to implement the actual -// drawing and to set the destination rectangle in the client window. We have -// no critical section locking in this class because we are used exclusively -// by the owning window object which looks after serialising calls into us - -// If you want to use this class make sure you call NotifyAllocator once the -// allocate has been agreed, also call NotifyMediaType with a pointer to a -// NON stack based CMediaType once that has been set (we keep a pointer to -// the original rather than taking a copy). When the palette changes call -// IncrementPaletteVersion (easiest thing to do is to also call this method -// in the SetMediaType method most filters implement). Finally before you -// start rendering anything call SetDrawContext so that we can get the HDCs -// for drawing from the CBaseWindow object we are given during construction - -class CDrawImage -{ -protected: - - CBaseWindow *m_pBaseWindow; // Owning video window object - CRefTime m_StartSample; // Start time for the current sample - CRefTime m_EndSample; // And likewise it's end sample time - HDC m_hdc; // Main window device context - HDC m_MemoryDC; // Offscreen draw device context - RECT m_TargetRect; // Target destination rectangle - RECT m_SourceRect; // Source image rectangle - BOOL m_bStretch; // Do we have to stretch the images - BOOL m_bUsingImageAllocator; // Are the samples shared DIBSECTIONs - CMediaType *m_pMediaType; // Pointer to the current format - int m_perfidRenderTime; // Time taken to render an image - LONG m_PaletteVersion; // Current palette version cookie - - // Draw the video images in the window - - void SlowRender(IMediaSample *pMediaSample); - void FastRender(IMediaSample *pMediaSample); - void DisplaySampleTimes(IMediaSample *pSample); - void UpdateColourTable(HDC hdc,BITMAPINFOHEADER *pbmi); - void SetStretchMode(); - -public: - - // Used to control the image drawing - - CDrawImage(CBaseWindow *pBaseWindow); - BOOL DrawImage(IMediaSample *pMediaSample); - BOOL DrawVideoImageHere(HDC hdc, IMediaSample *pMediaSample, - LPRECT lprcSrc, LPRECT lprcDst); - void SetDrawContext(); - void SetTargetRect(RECT *pTargetRect); - void SetSourceRect(RECT *pSourceRect); - void GetTargetRect(RECT *pTargetRect); - void GetSourceRect(RECT *pSourceRect); - virtual RECT ScaleSourceRect(const RECT *pSource); - - // Handle updating palettes as they change - - LONG GetPaletteVersion(); - void ResetPaletteVersion(); - void IncrementPaletteVersion(); - - // Tell us media types and allocator assignments - - void NotifyAllocator(BOOL bUsingImageAllocator); - void NotifyMediaType(CMediaType *pMediaType); - BOOL UsingImageAllocator(); - - // Called when we are about to draw an image - - void NotifyStartDraw() { - MSR_START(m_perfidRenderTime); - }; - - // Called when we complete an image rendering - - void NotifyEndDraw() { - MSR_STOP(m_perfidRenderTime); - }; -}; - - -// This is the structure used to keep information about each GDI DIB. All the -// samples we create from our allocator will have a DIBSECTION allocated to -// them. When we receive the sample we know we can BitBlt straight to an HDC - -typedef struct tagDIBDATA { - - LONG PaletteVersion; // Current palette version in use - DIBSECTION DibSection; // Details of DIB section allocated - HBITMAP hBitmap; // Handle to bitmap for drawing - HANDLE hMapping; // Handle to shared memory block - BYTE *pBase; // Pointer to base memory address - -} DIBDATA; - - -// This class inherits from CMediaSample and uses all of it's methods but it -// overrides the constructor to initialise itself with the DIBDATA structure -// When we come to render an IMediaSample we will know if we are using our own -// allocator, and if we are, we can cast the IMediaSample to a pointer to one -// of these are retrieve the DIB section information and hence the HBITMAP - -class CImageSample : public CMediaSample -{ -protected: - - DIBDATA m_DibData; // Information about the DIBSECTION - BOOL m_bInit; // Is the DIB information setup - -public: - - // Constructor - - CImageSample(CBaseAllocator *pAllocator, - TCHAR *pName, - HRESULT *phr, - LPBYTE pBuffer, - LONG length); - - // Maintain the DIB/DirectDraw state - - void SetDIBData(DIBDATA *pDibData); - DIBDATA *GetDIBData(); -}; - - -// This is an allocator based on the abstract CBaseAllocator base class that -// allocates sample buffers in shared memory. The number and size of these -// are determined when the output pin calls Prepare on us. The shared memory -// blocks are used in subsequent calls to GDI CreateDIBSection, once that -// has been done the output pin can fill the buffers with data which will -// then be handed to GDI through BitBlt calls and thereby remove one copy - -class CImageAllocator : public CBaseAllocator -{ -protected: - - CBaseFilter *m_pFilter; // Delegate reference counts to - CMediaType *m_pMediaType; // Pointer to the current format - - // Used to create and delete samples - - HRESULT Alloc(); - void Free(); - - // Manage the shared DIBSECTION and DCI/DirectDraw buffers - - HRESULT CreateDIB(LONG InSize,DIBDATA &DibData); - STDMETHODIMP CheckSizes(ALLOCATOR_PROPERTIES *pRequest); - virtual CImageSample *CreateImageSample(LPBYTE pData,LONG Length); - -public: - - // Constructor and destructor - - CImageAllocator(CBaseFilter *pFilter,TCHAR *pName,HRESULT *phr); -#ifdef DEBUG - ~CImageAllocator(); -#endif - - STDMETHODIMP_(ULONG) NonDelegatingAddRef(); - STDMETHODIMP_(ULONG) NonDelegatingRelease(); - void NotifyMediaType(CMediaType *pMediaType); - - // Agree the number of buffers to be used and their size - - STDMETHODIMP SetProperties( - ALLOCATOR_PROPERTIES *pRequest, - ALLOCATOR_PROPERTIES *pActual); -}; - - -// This class is a fairly specialised helper class for image renderers that -// have to create and manage palettes. The CBaseWindow class looks after -// realising palettes once they have been installed. This class can be used -// to create the palette handles from a media format (which must contain a -// VIDEOINFO structure in the format block). We try to make the palette an -// identity palette to maximise performance and also only change palettes -// if actually required to (we compare palette colours before updating). -// All the methods are virtual so that they can be overriden if so required - -class CImagePalette -{ -protected: - - CBaseWindow *m_pBaseWindow; // Window to realise palette in - CBaseFilter *m_pFilter; // Media filter to send events - CDrawImage *m_pDrawImage; // Object who will be drawing - HPALETTE m_hPalette; // The palette handle we own - -public: - - CImagePalette(CBaseFilter *pBaseFilter, - CBaseWindow *pBaseWindow, - CDrawImage *pDrawImage); - -#ifdef DEBUG - virtual ~CImagePalette(); -#endif - - static HPALETTE MakePalette(const VIDEOINFOHEADER *pVideoInfo, LPSTR szDevice); - HRESULT RemovePalette(); - static HRESULT MakeIdentityPalette(PALETTEENTRY *pEntry,INT iColours, LPSTR szDevice); - HRESULT CopyPalette(const CMediaType *pSrc,CMediaType *pDest); - BOOL ShouldUpdate(const VIDEOINFOHEADER *pNewInfo,const VIDEOINFOHEADER *pOldInfo); - HRESULT PreparePalette(const CMediaType *pmtNew,const CMediaType *pmtOld,LPSTR szDevice); - - BOOL DrawVideoImageHere(HDC hdc, IMediaSample *pMediaSample, LPRECT lprcSrc, LPRECT lprcDst) - { - return m_pDrawImage->DrawVideoImageHere(hdc, pMediaSample, lprcSrc,lprcDst); - } -}; - - -// Another helper class really for video based renderers. Most such renderers -// need to know what the display format is to some degree or another. This -// class initialises itself with the display format. The format can be asked -// for through GetDisplayFormat and various other accessor functions. If a -// filter detects a display format change (perhaps it gets a WM_DEVMODECHANGE -// message then it can call RefreshDisplayType to reset that format). Also -// many video renderers will want to check formats as they are proposed by -// source filters. This class provides methods to check formats and only -// accept those video formats that can be efficiently drawn using GDI calls - -class CImageDisplay : public CCritSec -{ -protected: - - // This holds the display format; biSize should not be too big, so we can - // safely use the VIDEOINFO structure - VIDEOINFO m_Display; - - static DWORD CountSetBits(const DWORD Field); - static DWORD CountPrefixBits(const DWORD Field); - static BOOL CheckBitFields(const VIDEOINFO *pInput); - -public: - - // Constructor and destructor - - CImageDisplay(); - - // Used to manage BITMAPINFOHEADERs and the display format - - const VIDEOINFO *GetDisplayFormat(); - HRESULT RefreshDisplayType(LPSTR szDeviceName); - static BOOL CheckHeaderValidity(const VIDEOINFO *pInput); - static BOOL CheckPaletteHeader(const VIDEOINFO *pInput); - BOOL IsPalettised(); - WORD GetDisplayDepth(); - - // Provide simple video format type checking - - HRESULT CheckMediaType(const CMediaType *pmtIn); - HRESULT CheckVideoType(const VIDEOINFO *pInput); - HRESULT UpdateFormat(VIDEOINFO *pVideoInfo); - const DWORD *GetBitMasks(const VIDEOINFO *pVideoInfo); - - BOOL GetColourMask(DWORD *pMaskRed, - DWORD *pMaskGreen, - DWORD *pMaskBlue); -}; - -// Convert a FORMAT_VideoInfo to FORMAT_VideoInfo2 -STDAPI ConvertVideoInfoToVideoInfo2(AM_MEDIA_TYPE *pmt); - -#endif // __WINUTIL__ - diff --git a/src/BaseClasses/wxdebug.cpp b/src/BaseClasses/wxdebug.cpp deleted file mode 100644 index b8087ae922..0000000000 --- a/src/BaseClasses/wxdebug.cpp +++ /dev/null @@ -1,1311 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WXDebug.cpp -// -// Desc: DirectShow base classes - implements ActiveX system debugging -// facilities. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#define _WINDLL - -#include -#include -#include - -#ifdef DEBUG -#ifdef UNICODE -#ifndef _UNICODE -#define _UNICODE -#endif // _UNICODE -#endif // UNICODE -#endif // DEBUG - -#include - -#ifdef DEBUG - -// The Win32 wsprintf() function writes a maximum of 1024 characters to it's output buffer. -// See the documentation for wsprintf()'s lpOut parameter for more information. -const INT iDEBUGINFO = 1024; // Used to format strings - -/* For every module and executable we store a debugging level for each of - the five categories (eg LOG_ERROR and LOG_TIMING). This makes it easy - to isolate and debug individual modules without seeing everybody elses - spurious debug output. The keys are stored in the registry under the - HKEY_LOCAL_MACHINE\SOFTWARE\Debug\\ key values - NOTE these must be in the same order as their enumeration definition */ - -TCHAR *pKeyNames[] = { - TEXT("TIMING"), // Timing and performance measurements - TEXT("TRACE"), // General step point call tracing - TEXT("MEMORY"), // Memory and object allocation/destruction - TEXT("LOCKING"), // Locking/unlocking of critical sections - TEXT("ERROR"), // Debug error notification - TEXT("CUSTOM1"), - TEXT("CUSTOM2"), - TEXT("CUSTOM3"), - TEXT("CUSTOM4"), - TEXT("CUSTOM5") - }; - -const TCHAR CAutoTrace::_szEntering[] = TEXT("Entering: %s"); -const TCHAR CAutoTrace::_szLeaving[] = TEXT("Leaving: %s"); - -const INT iMAXLEVELS = NUMELMS(pKeyNames); // Maximum debug categories - -HINSTANCE m_hInst; // Module instance handle -TCHAR m_ModuleName[iDEBUGINFO]; // Cut down module name -DWORD m_Levels[iMAXLEVELS]; // Debug level per category -CRITICAL_SECTION m_CSDebug; // Controls access to list -DWORD m_dwNextCookie; // Next active object ID -ObjectDesc *pListHead = NULL; // First active object -DWORD m_dwObjectCount; // Active object count -BOOL m_bInit = FALSE; // Have we been initialised -HANDLE m_hOutput = INVALID_HANDLE_VALUE; // Optional output written here -DWORD dwWaitTimeout = INFINITE; // Default timeout value -DWORD dwTimeOffset; // Time of first DbgLog call -bool g_fUseKASSERT = false; // don't create messagebox -bool g_fDbgInDllEntryPoint = false; -bool g_fAutoRefreshLevels = false; - -const TCHAR *pBaseKey = TEXT("SOFTWARE\\Debug"); -const TCHAR *pGlobalKey = TEXT("GLOBAL"); -static CHAR *pUnknownName = "UNKNOWN"; - -TCHAR *TimeoutName = TEXT("TIMEOUT"); - -/* This sets the instance handle that the debug library uses to find - the module's file name from the Win32 GetModuleFileName function */ - -void WINAPI DbgInitialise(HINSTANCE hInst) { - InitializeCriticalSection(&m_CSDebug); - m_bInit = TRUE; - - m_hInst = hInst; - DbgInitModuleName(); - if(GetProfileInt(m_ModuleName, TEXT("BreakOnLoad"), 0)) - DebugBreak(); - DbgInitModuleSettings(false); - DbgInitGlobalSettings(true); - dwTimeOffset = timeGetTime(); -} - - -/* This is called to clear up any resources the debug library uses - at the - moment we delete our critical section and the object list. The values we - retrieve from the registry are all done during initialisation but we don't - go looking for update notifications while we are running, if the values - are changed then the application has to be restarted to pick them up */ - -void WINAPI DbgTerminate() { - if(m_hOutput != INVALID_HANDLE_VALUE) { - EXECUTE_ASSERT(CloseHandle(m_hOutput)); - m_hOutput = INVALID_HANDLE_VALUE; - } - DeleteCriticalSection(&m_CSDebug); - m_bInit = FALSE; -} - - -/* This is called by DbgInitLogLevels to read the debug settings - for each logging category for this module from the registry */ - -void WINAPI DbgInitKeyLevels(HKEY hKey, bool fTakeMax) { - LONG lReturn; // Create key return value - LONG lKeyPos; // Current key category - DWORD dwKeySize; // Size of the key value - DWORD dwKeyType; // Receives it's type - DWORD dwKeyValue; // This fields value - - /* Try and read a value for each key position in turn */ - for(lKeyPos = 0;lKeyPos < iMAXLEVELS;lKeyPos++) { - - dwKeySize = sizeof(DWORD); - lReturn = RegQueryValueEx(hKey, // Handle to an open key - pKeyNames[lKeyPos], // Subkey name derivation - NULL, // Reserved field - &dwKeyType, // Returns the field type - (LPBYTE) &dwKeyValue, // Returns the field's value - &dwKeySize); // Number of bytes transferred - - /* If either the key was not available or it was not a DWORD value - then we ensure only the high priority debug logging is output - but we try and update the field to a zero filled DWORD value */ - - if(lReturn != ERROR_SUCCESS || dwKeyType != REG_DWORD) { - - dwKeyValue = 0; - lReturn = RegSetValueEx(hKey, // Handle of an open key - pKeyNames[lKeyPos], // Address of subkey name - (DWORD) 0, // Reserved field - REG_DWORD, // Type of the key field - (PBYTE) &dwKeyValue, // Value for the field - sizeof(DWORD)); // Size of the field buffer - - if(lReturn != ERROR_SUCCESS) { - DbgLog((LOG_ERROR,0,TEXT("Could not create subkey %s"),pKeyNames[lKeyPos])); - dwKeyValue = 0; - } - } - if(fTakeMax) { - m_Levels[lKeyPos] = max(dwKeyValue,m_Levels[lKeyPos]); - } - else { - if((m_Levels[lKeyPos] & LOG_FORCIBLY_SET) == 0) { - m_Levels[lKeyPos] = dwKeyValue; - } - } - } - - /* Read the timeout value for catching hangs */ - dwKeySize = sizeof(DWORD); - lReturn = RegQueryValueEx(hKey, // Handle to an open key - TimeoutName, // Subkey name derivation - NULL, // Reserved field - &dwKeyType, // Returns the field type - (LPBYTE) &dwWaitTimeout, // Returns the field's value - &dwKeySize); // Number of bytes transferred - - /* If either the key was not available or it was not a DWORD value - then we ensure only the high priority debug logging is output - but we try and update the field to a zero filled DWORD value */ - - if(lReturn != ERROR_SUCCESS || dwKeyType != REG_DWORD) { - - dwWaitTimeout = INFINITE; - lReturn = RegSetValueEx(hKey, // Handle of an open key - TimeoutName, // Address of subkey name - (DWORD) 0, // Reserved field - REG_DWORD, // Type of the key field - (PBYTE) &dwWaitTimeout, // Value for the field - sizeof(DWORD)); // Size of the field buffer - - if(lReturn != ERROR_SUCCESS) { - DbgLog((LOG_ERROR,0,TEXT("Could not create subkey %s"),pKeyNames[lKeyPos])); - dwWaitTimeout = INFINITE; - } - } -} - -void WINAPI DbgOutString(LPCTSTR psz) { - if(m_hOutput != INVALID_HANDLE_VALUE) { - UINT cb = lstrlen(psz); - DWORD dw; -#ifdef UNICODE - CHAR szDest[2048]; - WideCharToMultiByte(CP_ACP, 0, psz, -1, szDest, NUMELMS(szDest), 0, 0); - WriteFile(m_hOutput, szDest, cb, &dw, NULL); -#else - WriteFile(m_hOutput, psz, cb, &dw, NULL); -#endif - } - else { - OutputDebugString(psz); - } -} - -/* Called by DbgInitGlobalSettings to setup alternate logging destinations - */ - -void WINAPI DbgInitLogTo( - HKEY hKey) { - LONG lReturn; - DWORD dwKeyType; - DWORD dwKeySize; - TCHAR szFile[MAX_PATH] = {0}; - static const TCHAR cszKey[] = TEXT("LogToFile"); - - dwKeySize = MAX_PATH; - lReturn = RegQueryValueEx(hKey, // Handle to an open key - cszKey, // Subkey name derivation - NULL, // Reserved field - &dwKeyType, // Returns the field type - (LPBYTE) szFile, // Returns the field's value - &dwKeySize); // Number of bytes transferred - - // create an empty key if it does not already exist - // - if(lReturn != ERROR_SUCCESS || dwKeyType != REG_SZ) { - dwKeySize = sizeof(TCHAR); - lReturn = RegSetValueEx(hKey, // Handle of an open key - cszKey, // Address of subkey name - (DWORD) 0, // Reserved field - REG_SZ, // Type of the key field - (PBYTE)szFile, // Value for the field - dwKeySize); // Size of the field buffer - } - - // if an output-to was specified. try to open it. - // - if(m_hOutput != INVALID_HANDLE_VALUE) { - EXECUTE_ASSERT(CloseHandle(m_hOutput)); - m_hOutput = INVALID_HANDLE_VALUE; - } - if(szFile[0] != 0) { - if(!lstrcmpi(szFile, TEXT("Console"))) { - m_hOutput = GetStdHandle(STD_OUTPUT_HANDLE); - if(m_hOutput == INVALID_HANDLE_VALUE) { - AllocConsole(); - m_hOutput = GetStdHandle(STD_OUTPUT_HANDLE); - } - SetConsoleTitle(TEXT("ActiveX Debug Output")); - } - else if(szFile[0] && - lstrcmpi(szFile, TEXT("Debug")) && - lstrcmpi(szFile, TEXT("Debugger")) && - lstrcmpi(szFile, TEXT("Deb"))) { - m_hOutput = CreateFile(szFile, GENERIC_WRITE, - FILE_SHARE_READ, - NULL, OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL); - if(INVALID_HANDLE_VALUE != m_hOutput) { - static const TCHAR cszBar[] = TEXT("\r\n\r\n=====DbgInitialize()=====\r\n\r\n"); - SetFilePointer(m_hOutput, 0, NULL, FILE_END); - DbgOutString(cszBar); - } - } - } -} - - - -/* This is called by DbgInitLogLevels to read the global debug settings for - each logging category for this module from the registry. Normally each - module has it's own values set for it's different debug categories but - setting the global SOFTWARE\Debug\Global applies them to ALL modules */ - -void WINAPI DbgInitGlobalSettings(bool fTakeMax) { - LONG lReturn; // Create key return value - TCHAR szInfo[iDEBUGINFO]; // Constructs key names - HKEY hGlobalKey; // Global override key - - /* Construct the global base key name */ - wsprintf(szInfo,TEXT("%s\\%s"),pBaseKey,pGlobalKey); - - /* Create or open the key for this module */ - lReturn = RegCreateKeyEx(HKEY_LOCAL_MACHINE, // Handle of an open key - szInfo, // Address of subkey name - (DWORD) 0, // Reserved value - NULL, // Address of class name - (DWORD) 0, // Special options flags - KEY_ALL_ACCESS, // Desired security access - NULL, // Key security descriptor - &hGlobalKey, // Opened handle buffer - NULL); // What really happened - - if(lReturn != ERROR_SUCCESS) { - DbgLog((LOG_ERROR,0,TEXT("Could not access GLOBAL module key"))); - return; - } - - DbgInitKeyLevels(hGlobalKey, fTakeMax); - RegCloseKey(hGlobalKey); -} - - -/* This sets the debugging log levels for the different categories. We start - by opening (or creating if not already available) the SOFTWARE\Debug key - that all these settings live under. We then look at the global values - set under SOFTWARE\Debug\Global which apply on top of the individual - module settings. We then load the individual module registry settings */ - -void WINAPI DbgInitModuleSettings(bool fTakeMax) { - LONG lReturn; // Create key return value - TCHAR szInfo[iDEBUGINFO]; // Constructs key names - HKEY hModuleKey; // Module key handle - - /* Construct the base key name */ - wsprintf(szInfo,TEXT("%s\\%s"),pBaseKey,m_ModuleName); - - /* Create or open the key for this module */ - lReturn = RegCreateKeyEx(HKEY_LOCAL_MACHINE, // Handle of an open key - szInfo, // Address of subkey name - (DWORD) 0, // Reserved value - NULL, // Address of class name - (DWORD) 0, // Special options flags - KEY_ALL_ACCESS, // Desired security access - NULL, // Key security descriptor - &hModuleKey, // Opened handle buffer - NULL); // What really happened - - if(lReturn != ERROR_SUCCESS) { - DbgLog((LOG_ERROR,0,TEXT("Could not access module key"))); - return; - } - - DbgInitLogTo(hModuleKey); - DbgInitKeyLevels(hModuleKey, fTakeMax); - RegCloseKey(hModuleKey); -} - - -/* Initialise the module file name */ - -void WINAPI DbgInitModuleName() { - TCHAR FullName[iDEBUGINFO]; // Load the full path and module name - TCHAR *pName; // Searches from the end for a backslash - - GetModuleFileName(m_hInst,FullName,iDEBUGINFO); - pName = _tcsrchr(FullName,'\\'); - if(pName == NULL) { - pName = FullName; - } - else { - pName++; - } - lstrcpy(m_ModuleName,pName); -} - -struct MsgBoxMsg { - HWND hwnd; - TCHAR *szTitle; - TCHAR *szMessage; - DWORD dwFlags; - INT iResult; -}; - -// -// create a thread to call MessageBox(). calling MessageBox() on -// random threads at bad times can confuse the host (eg IE). -// -DWORD WINAPI MsgBoxThread( - LPVOID lpParameter // thread data - ) -{ - MsgBoxMsg *pmsg = (MsgBoxMsg *)lpParameter; - pmsg->iResult = MessageBox(pmsg->hwnd, - pmsg->szTitle, - pmsg->szMessage, - pmsg->dwFlags); - - return 0; -} - -INT MessageBoxOtherThread( - HWND hwnd, - TCHAR *szTitle, - TCHAR *szMessage, - DWORD dwFlags) { - if(g_fDbgInDllEntryPoint) { - // can't wait on another thread because we have the loader - // lock held in the dll entry point. - return MessageBox(hwnd, szTitle, szMessage, dwFlags); - } - else { - MsgBoxMsg msg = {hwnd, szTitle, szMessage, dwFlags, 0}; - DWORD dwid; - HANDLE hThread = CreateThread(0, // security - 0, // stack size - MsgBoxThread, - (void *)&msg, // arg - 0, // flags - &dwid); - if(hThread) { - WaitForSingleObject(hThread, INFINITE); - CloseHandle(hThread); - return msg.iResult; - } - - // break into debugger on failure. - return IDCANCEL; - } -} - -/* Displays a message box if the condition evaluated to FALSE */ - -void WINAPI DbgAssert(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine) { - if(g_fUseKASSERT) { - DbgKernelAssert(pCondition, pFileName, iLine); - } - else { - - TCHAR szInfo[iDEBUGINFO]; - - wsprintf(szInfo, TEXT("%s \nAt line %d of %s\nContinue? (Cancel to debug)"), - pCondition, iLine, pFileName); - - INT MsgId = MessageBoxOtherThread(NULL,szInfo,TEXT("ASSERT Failed"), - MB_SYSTEMMODAL | - MB_ICONHAND | - MB_YESNOCANCEL | - MB_SETFOREGROUND); - - switch(MsgId) { - case IDNO: /* Kill the application */ - FatalAppExit(FALSE, TEXT("Application terminated")); - break; - - case IDCANCEL: /* Break into the debugger */ - DebugBreak(); - break; - - case IDYES: /* Ignore assertion continue execution */ - break; - } - } -} - -/* Displays a message box at a break point */ - -void WINAPI DbgBreakPoint(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine) { - if(g_fUseKASSERT) { - DbgKernelAssert(pCondition, pFileName, iLine); - } - else { - TCHAR szInfo[iDEBUGINFO]; - - wsprintf(szInfo, TEXT("%s \nAt line %d of %s\nContinue? (Cancel to debug)"), - pCondition, iLine, pFileName); - - INT MsgId = MessageBoxOtherThread(NULL,szInfo,TEXT("Hard coded break point"), - MB_SYSTEMMODAL | - MB_ICONHAND | - MB_YESNOCANCEL | - MB_SETFOREGROUND); - - switch(MsgId) { - case IDNO: /* Kill the application */ - FatalAppExit(FALSE, TEXT("Application terminated")); - break; - - case IDCANCEL: /* Break into the debugger */ - DebugBreak(); - break; - - case IDYES: /* Ignore break point continue execution */ - break; - } - } -} - -void WINAPI DbgBreakPoint(const TCHAR *pFileName,INT iLine,const TCHAR* szFormatString,...) { - // A debug break point message can have at most 2000 characters if - // ANSI or UNICODE characters are being used. A debug break point message - // can have between 1000 and 2000 double byte characters in it. If a - // particular message needs more characters, then the value of this constant - // should be increased. - const DWORD MAX_BREAK_POINT_MESSAGE_SIZE = 2000; - - TCHAR szBreakPointMessage[MAX_BREAK_POINT_MESSAGE_SIZE]; - - const DWORD MAX_CHARS_IN_BREAK_POINT_MESSAGE = sizeof(szBreakPointMessage) / sizeof(TCHAR); - - va_list va; - va_start(va, szFormatString); - - int nReturnValue = _vsntprintf(szBreakPointMessage, MAX_CHARS_IN_BREAK_POINT_MESSAGE, szFormatString, va); - - va_end(va); - - // _vsnprintf() returns -1 if an error occurs. - if(-1 == nReturnValue) { - DbgBreak("ERROR in DbgBreakPoint(). The variable length debug message could not be displayed because _vsnprintf() failed."); - return; - } - - ::DbgBreakPoint(szBreakPointMessage, pFileName, iLine); -} - - -/* When we initialised the library we stored in the m_Levels array the current - debug output level for this module for each of the five categories. When - some debug logging is sent to us it can be sent with a combination of the - categories (if it is applicable to many for example) in which case we map - the type's categories into their current debug levels and see if any of - them can be accepted. The function looks at each bit position in turn from - the input type field and then compares it's debug level with the modules. - - A level of 0 means that output is always sent to the debugger. This is - due to producing output if the input level is <= m_Levels. -*/ - - -BOOL WINAPI DbgCheckModuleLevel(DWORD Type,DWORD Level) { - if(g_fAutoRefreshLevels) { - // re-read the registry every second. We cannot use RegNotify() to - // notice registry changes because it's not available on win9x. - /*NABIL: This needed to be a static int, not ust static*/ - static int g_dwLastRefresh = 0; - DWORD dwTime = timeGetTime(); - if(dwTime - g_dwLastRefresh > 1000) { - g_dwLastRefresh = dwTime; - - // there's a race condition: multiple threads could update the - // values. plus read and write not synchronized. no harm - // though. - DbgInitModuleSettings(false); - } - } - - - DWORD Mask = 0x01; - - // If no valid bits are set return FALSE - if((Type & ((1<m_szName = szObjectName; - pObject->m_wszName = wszObjectName; - pObject->m_dwCookie = ++m_dwNextCookie; - pObject->m_pNext = pListHead; - - pListHead = pObject; - m_dwObjectCount++; - - DWORD ObjectCookie = pObject->m_dwCookie; - ASSERT(ObjectCookie); - - if(wszObjectName) { - DbgLog((LOG_MEMORY,2,TEXT("Object created %d (%ls) %d Active"), - pObject->m_dwCookie, wszObjectName, m_dwObjectCount)); - } - else { - DbgLog((LOG_MEMORY,2,TEXT("Object created %d (%hs) %d Active"), - pObject->m_dwCookie, szObjectName, m_dwObjectCount)); - } - - LeaveCriticalSection(&m_CSDebug); - return ObjectCookie; -} - - -/* This is called by the CBaseObject destructor when an object is about to be - destroyed, we are passed the cookie we returned during construction that - identifies this object. We scan the object list for a matching cookie and - remove the object if successful. We also update the active object count */ - -BOOL WINAPI DbgRegisterObjectDestruction(DWORD dwCookie) { - /* Grab the list critical section */ - EnterCriticalSection(&m_CSDebug); - - ObjectDesc *pObject = pListHead; - ObjectDesc *pPrevious = NULL; - - /* Scan the object list looking for a cookie match */ - - while(pObject) { - if(pObject->m_dwCookie == dwCookie) { - break; - } - pPrevious = pObject; - pObject = pObject->m_pNext; - } - - if(pObject == NULL) { - DbgBreak("Apparently destroying a bogus object"); - LeaveCriticalSection(&m_CSDebug); - return FALSE; - } - - /* Is the object at the head of the list */ - - if(pPrevious == NULL) { - pListHead = pObject->m_pNext; - } - else { - pPrevious->m_pNext = pObject->m_pNext; - } - - /* Delete the object and update the housekeeping information */ - - m_dwObjectCount--; - - if(pObject->m_wszName) { - DbgLog((LOG_MEMORY,2,TEXT("Object destroyed %d (%ls) %d Active"), - pObject->m_dwCookie, pObject->m_wszName, m_dwObjectCount)); - } - else { - DbgLog((LOG_MEMORY,2,TEXT("Object destroyed %d (%hs) %d Active"), - pObject->m_dwCookie, pObject->m_szName, m_dwObjectCount)); - } - - delete pObject; - LeaveCriticalSection(&m_CSDebug); - return TRUE; -} - - -/* This runs through the active object list displaying their details */ - -void WINAPI DbgDumpObjectRegister() { - TCHAR szInfo[iDEBUGINFO]; - - /* Grab the list critical section */ - - EnterCriticalSection(&m_CSDebug); - ObjectDesc *pObject = pListHead; - - /* Scan the object list displaying the name and cookie */ - - DbgLog((LOG_MEMORY,2,TEXT(""))); - DbgLog((LOG_MEMORY,2,TEXT(" ID Object Description"))); - DbgLog((LOG_MEMORY,2,TEXT(""))); - - while(pObject) { - if(pObject->m_wszName) { - wsprintf(szInfo,TEXT("%5d (%8x) %30ls"),pObject->m_dwCookie, &pObject, pObject->m_wszName); - } - else { - wsprintf(szInfo,TEXT("%5d (%8x) %30hs"),pObject->m_dwCookie, &pObject, pObject->m_szName); - } - DbgLog((LOG_MEMORY,2,szInfo)); - pObject = pObject->m_pNext; - } - - wsprintf(szInfo,TEXT("Total object count %5d"),m_dwObjectCount); - DbgLog((LOG_MEMORY,2,TEXT(""))); - DbgLog((LOG_MEMORY,1,szInfo)); - LeaveCriticalSection(&m_CSDebug); -} - -/* Debug infinite wait stuff */ -DWORD WINAPI DbgWaitForSingleObject(HANDLE h) { - DWORD dwWaitResult; - do { - dwWaitResult = WaitForSingleObject(h, dwWaitTimeout); - ASSERT(dwWaitResult == WAIT_OBJECT_0); - } while(dwWaitResult == WAIT_TIMEOUT); - return dwWaitResult; -} -DWORD WINAPI DbgWaitForMultipleObjects(DWORD nCount, - CONST HANDLE *lpHandles, - BOOL bWaitAll) { - DWORD dwWaitResult; - do { - dwWaitResult = WaitForMultipleObjects(nCount, - lpHandles, - bWaitAll, - dwWaitTimeout); - ASSERT((DWORD)(dwWaitResult - WAIT_OBJECT_0) < MAXIMUM_WAIT_OBJECTS); - } while(dwWaitResult == WAIT_TIMEOUT); - return dwWaitResult; -} - -void WINAPI DbgSetWaitTimeout(DWORD dwTimeout) { - dwWaitTimeout = dwTimeout; -} - -#endif /* DEBUG */ - -#ifdef _OBJBASE_H_ - - /* Stuff for printing out our GUID names */ - - GUID_STRING_ENTRY g_GuidNames[] = { - #define OUR_GUID_ENTRY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - { #name, { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } }, - #include - }; - - CGuidNameList GuidNames; - int g_cGuidNames = sizeof(g_GuidNames) / sizeof(g_GuidNames[0]); - - char *CGuidNameList::operator [] (const GUID &guid) { - for(int i = 0; i < g_cGuidNames; i++) { - if(g_GuidNames[i].guid == guid) { - return g_GuidNames[i].szName; - } - } - if(guid == GUID_NULL) { - return "GUID_NULL"; - } - - // !!! add something to print FOURCC guids? - - // shouldn't this print the hex CLSID? - return "Unknown GUID Name"; -} - -#endif /* _OBJBASE_H_ */ - -/* CDisp class - display our data types */ - -// clashes with REFERENCE_TIME -CDisp::CDisp(LONGLONG ll, int Format) { - // note: this could be combined with CDisp(LONGLONG) by - // introducing a default format of CDISP_REFTIME - LARGE_INTEGER li; - li.QuadPart = ll; - switch(Format) { - case CDISP_DEC: { - TCHAR temp[20]; - int pos=20; - temp[--pos] = 0; - int digit; - // always output at least one digit - do { - // Get the rightmost digit - we only need the low word - digit = li.LowPart % 10; - li.QuadPart /= 10; - temp[--pos] = (TCHAR) (digit+TEXT('0')); - } while(li.QuadPart); - wsprintf(m_String, TEXT("%s"), temp+pos); - break; - } - case CDISP_HEX: - default: - wsprintf(m_String, TEXT("0x%X%8.8X"), li.HighPart, li.LowPart); - } -}; - -CDisp::CDisp(REFCLSID clsid) { - WCHAR strClass[CHARS_IN_GUID+1]; - StringFromGUID2(clsid, strClass, sizeof(strClass) / sizeof(strClass[0])); - ASSERT(sizeof(m_String)/sizeof(m_String[0]) >= CHARS_IN_GUID+1); - wsprintf(m_String, TEXT("%ls"), strClass); -}; - -#ifdef __STREAMS__ -/* Display stuff */ -CDisp::CDisp(CRefTime llTime) { - LPTSTR lpsz = m_String; - LONGLONG llDiv; - if(llTime < 0) { - llTime = -llTime; - lpsz += wsprintf(lpsz, TEXT("-")); - } - llDiv = (LONGLONG)24 * 3600 * 10000000; - if(llTime >= llDiv) { - lpsz += wsprintf(lpsz, TEXT("%d days "), (LONG)(llTime / llDiv)); - llTime = llTime % llDiv; - } - llDiv = (LONGLONG)3600 * 10000000; - if(llTime >= llDiv) { - lpsz += wsprintf(lpsz, TEXT("%d hrs "), (LONG)(llTime / llDiv)); - llTime = llTime % llDiv; - } - llDiv = (LONGLONG)60 * 10000000; - if(llTime >= llDiv) { - lpsz += wsprintf(lpsz, TEXT("%d mins "), (LONG)(llTime / llDiv)); - llTime = llTime % llDiv; - } - wsprintf(lpsz, TEXT("%d.%3.3d sec"), - (LONG)llTime / 10000000, - (LONG)((llTime % 10000000) / 10000)); -}; - -#endif // __STREAMS__ - - -/* Display pin */ -CDisp::CDisp(IPin *pPin) { - PIN_INFO pi; - TCHAR str[MAX_PIN_NAME]; - CLSID clsid; - - if(pPin) { - pPin->QueryPinInfo(&pi); - pi.pFilter->GetClassID(&clsid); - QueryPinInfoReleaseFilter(pi); -#ifndef UNICODE - WideCharToMultiByte(GetACP(), 0, pi.achName, lstrlenW(pi.achName) + 1, - str, MAX_PIN_NAME, NULL, NULL); -#else - lstrcpy(str, pi.achName); -#endif - } - else { - lstrcpy(str, TEXT("NULL IPin")); - } - - m_pString = (PTCHAR) new TCHAR[lstrlen(str)+64]; - if(!m_pString) { - return; - } - - wsprintf(m_pString, TEXT("%hs(%s)"), GuidNames[clsid], str); -} - -/* Display filter or pin */ -CDisp::CDisp(IUnknown *pUnk) { - IBaseFilter *pf; - HRESULT hr = pUnk->QueryInterface(IID_IBaseFilter, (void **)&pf); - if(SUCCEEDED(hr)) { - FILTER_INFO fi; - hr = pf->QueryFilterInfo(&fi); - if(SUCCEEDED(hr)) { - QueryFilterInfoReleaseGraph(fi); - - m_pString = new TCHAR[lstrlenW(fi.achName) + 1]; - if(m_pString) { - wsprintf(m_pString, TEXT("%ls"), fi.achName); - } - } - - pf->Release(); - - return; - } - - IPin *pp; - hr = pUnk->QueryInterface(IID_IPin, (void **)&pp); - if(SUCCEEDED(hr)) { - CDisp::CDisp(pp); - pp->Release(); - return; - } -} - - -CDisp::~CDisp() { -} - -CDispBasic::~CDispBasic() { - if(m_pString != m_String) { - delete [] m_pString; - } -} - -CDisp::CDisp(double d) { -#ifdef DEBUG - _stprintf(m_String, TEXT("%.16g"), d); -#else - wsprintf(m_String, TEXT("%d.%03d"), (int) d, (int) ((d - (int) d) * 1000)); -#endif -} - - -/* If built for debug this will display the media type details. We convert the - major and subtypes into strings and also ask the base classes for a string - description of the subtype, so MEDIASUBTYPE_RGB565 becomes RGB 565 16 bit - We also display the fields in the BITMAPINFOHEADER structure, this should - succeed as we do not accept input types unless the format is big enough */ - -#ifdef DEBUG -void WINAPI DisplayType(LPTSTR label, const AM_MEDIA_TYPE *pmtIn) { - - /* Dump the GUID types and a short description */ - - DbgLog((LOG_TRACE,5,TEXT(""))); - DbgLog((LOG_TRACE,2,TEXT("%s M type %s S type %s"), label, - GuidNames[pmtIn->majortype], - GuidNames[pmtIn->subtype])); - DbgLog((LOG_TRACE,5,TEXT("Subtype description %s"),GetSubtypeName(&pmtIn->subtype))); - - /* Dump the generic media types */ - - if(pmtIn->bTemporalCompression) { - DbgLog((LOG_TRACE,5,TEXT("Temporally compressed"))); - } - else { - DbgLog((LOG_TRACE,5,TEXT("Not temporally compressed"))); - } - - if(pmtIn->bFixedSizeSamples) { - DbgLog((LOG_TRACE,5,TEXT("Sample size %d"),pmtIn->lSampleSize)); - } - else { - DbgLog((LOG_TRACE,5,TEXT("Variable size samples"))); - } - - if(pmtIn->formattype == FORMAT_VideoInfo) { - /* Dump the contents of the BITMAPINFOHEADER structure */ - BITMAPINFOHEADER *pbmi = HEADER(pmtIn->pbFormat); - VIDEOINFOHEADER *pVideoInfo = (VIDEOINFOHEADER *)pmtIn->pbFormat; - - DbgLog((LOG_TRACE,5,TEXT("Source rectangle (Left %d Top %d Right %d Bottom %d)"), - pVideoInfo->rcSource.left, - pVideoInfo->rcSource.top, - pVideoInfo->rcSource.right, - pVideoInfo->rcSource.bottom)); - - DbgLog((LOG_TRACE,5,TEXT("Target rectangle (Left %d Top %d Right %d Bottom %d)"), - pVideoInfo->rcTarget.left, - pVideoInfo->rcTarget.top, - pVideoInfo->rcTarget.right, - pVideoInfo->rcTarget.bottom)); - - DbgLog((LOG_TRACE,5,TEXT("Size of BITMAPINFO structure %d"),pbmi->biSize)); - if(pbmi->biCompression < 256) { - DbgLog((LOG_TRACE,2,TEXT("%dx%dx%d bit (%d)"), - pbmi->biWidth, pbmi->biHeight, - pbmi->biBitCount, pbmi->biCompression)); - } - else { - DbgLog((LOG_TRACE,2,TEXT("%dx%dx%d bit '%4.4hs'"), - pbmi->biWidth, pbmi->biHeight, - pbmi->biBitCount, &pbmi->biCompression)); - } - - DbgLog((LOG_TRACE,2,TEXT("Image size %d"),pbmi->biSizeImage)); - DbgLog((LOG_TRACE,5,TEXT("Planes %d"),pbmi->biPlanes)); - DbgLog((LOG_TRACE,5,TEXT("X Pels per metre %d"),pbmi->biXPelsPerMeter)); - DbgLog((LOG_TRACE,5,TEXT("Y Pels per metre %d"),pbmi->biYPelsPerMeter)); - DbgLog((LOG_TRACE,5,TEXT("Colours used %d"),pbmi->biClrUsed)); - - } - else if(pmtIn->majortype == MEDIATYPE_Audio) { - DbgLog((LOG_TRACE,2,TEXT(" Format type %hs"), - GuidNames[pmtIn->formattype])); - DbgLog((LOG_TRACE,2,TEXT(" Subtype %hs"), - GuidNames[pmtIn->subtype])); - - if((pmtIn->subtype != MEDIASUBTYPE_MPEG1Packet) - && (pmtIn->cbFormat >= sizeof(PCMWAVEFORMAT))) { - /* Dump the contents of the WAVEFORMATEX type-specific format structure */ - - WAVEFORMATEX *pwfx = (WAVEFORMATEX *) pmtIn->pbFormat; - DbgLog((LOG_TRACE,2,TEXT("wFormatTag %u"), pwfx->wFormatTag)); - DbgLog((LOG_TRACE,2,TEXT("nChannels %u"), pwfx->nChannels)); - DbgLog((LOG_TRACE,2,TEXT("nSamplesPerSec %lu"), pwfx->nSamplesPerSec)); - DbgLog((LOG_TRACE,2,TEXT("nAvgBytesPerSec %lu"), pwfx->nAvgBytesPerSec)); - DbgLog((LOG_TRACE,2,TEXT("nBlockAlign %u"), pwfx->nBlockAlign)); - DbgLog((LOG_TRACE,2,TEXT("wBitsPerSample %u"), pwfx->wBitsPerSample)); - - /* PCM uses a WAVEFORMAT and does not have the extra size field */ - - if(pmtIn->cbFormat >= sizeof(WAVEFORMATEX)) { - DbgLog((LOG_TRACE,2,TEXT("cbSize %u"), pwfx->cbSize)); - } - } - else { - } - - } - else { - DbgLog((LOG_TRACE,2,TEXT(" Format type %hs"), - GuidNames[pmtIn->formattype])); - // !!!! should add code to dump wave format, others - } -} - - -void WINAPI DumpGraph(IFilterGraph *pGraph, DWORD dwLevel) { - if(!pGraph) { - return; - } - - IEnumFilters *pFilters; - - DbgLog((LOG_TRACE,dwLevel,TEXT("DumpGraph [%x]"), pGraph)); - - if(FAILED(pGraph->EnumFilters(&pFilters))) { - DbgLog((LOG_TRACE,dwLevel,TEXT("EnumFilters failed!"))); - } - - IBaseFilter *pFilter; - ULONG n; - while(pFilters->Next(1, &pFilter, &n) == S_OK) { - FILTER_INFO info; - - if(FAILED(pFilter->QueryFilterInfo(&info))) { - DbgLog((LOG_TRACE,dwLevel,TEXT(" Filter [%x] -- failed QueryFilterInfo"), pFilter)); - } - else { - QueryFilterInfoReleaseGraph(info); - - // !!! should QueryVendorInfo here! - - DbgLog((LOG_TRACE,dwLevel,TEXT(" Filter [%x] '%ls'"), pFilter, info.achName)); - - IEnumPins *pins; - - if(FAILED(pFilter->EnumPins(&pins))) { - DbgLog((LOG_TRACE,dwLevel,TEXT("EnumPins failed!"))); - } - else { - - IPin *pPin; - while(pins->Next(1, &pPin, &n) == S_OK) { - PIN_INFO info; - - if(FAILED(pPin->QueryPinInfo(&info))) { - DbgLog((LOG_TRACE,dwLevel,TEXT(" Pin [%x] -- failed QueryPinInfo"), pPin)); - } - else { - QueryPinInfoReleaseFilter(info); - - IPin *pPinConnected = NULL; - - HRESULT hr = pPin->ConnectedTo(&pPinConnected); - - if(pPinConnected) { - DbgLog((LOG_TRACE,dwLevel,TEXT(" Pin [%x] '%ls' [%sput]") - TEXT(" Connected to pin [%x]"), - pPin, info.achName, - info.dir == PINDIR_INPUT ? TEXT("In") : TEXT("Out"), - pPinConnected)); - - pPinConnected->Release(); - - // perhaps we should really dump the type both ways as a sanity - // check? - if(info.dir == PINDIR_OUTPUT) { - AM_MEDIA_TYPE mt; - - hr = pPin->ConnectionMediaType(&mt); - - if(SUCCEEDED(hr)) { - DisplayType(TEXT("Connection type"), &mt); - - FreeMediaType(mt); - } - } - } - else { - DbgLog((LOG_TRACE,dwLevel, - TEXT(" Pin [%x] '%ls' [%sput]"), - pPin, info.achName, - info.dir == PINDIR_INPUT ? TEXT("In") : TEXT("Out"))); - - } - } - - pPin->Release(); - - } - - pins->Release(); - } - - } - - pFilter->Release(); - } - - pFilters->Release(); - -} - -#endif - - diff --git a/src/BaseClasses/wxdebug.h b/src/BaseClasses/wxdebug.h deleted file mode 100644 index 4addf00c74..0000000000 --- a/src/BaseClasses/wxdebug.h +++ /dev/null @@ -1,379 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WXDebug.h -// -// Desc: DirectShow base classes - provides debugging facilities. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __WXDEBUG__ -#define __WXDEBUG__ - -// This library provides fairly straight forward debugging functionality, this -// is split into two main sections. The first is assertion handling, there are -// three types of assertions provided here. The most commonly used one is the -// ASSERT(condition) macro which will pop up a message box including the file -// and line number if the condition evaluates to FALSE. Then there is the -// EXECUTE_ASSERT macro which is the same as ASSERT except the condition will -// still be executed in NON debug builds. The final type of assertion is the -// KASSERT macro which is more suitable for pure (perhaps kernel) filters as -// the condition is printed onto the debugger rather than in a message box. -// -// The other part of the debug module facilties is general purpose logging. -// This is accessed by calling DbgLog(). The function takes a type and level -// field which define the type of informational string you are presenting and -// it's relative importance. The type field can be a combination (one or more) -// of LOG_TIMING, LOG_TRACE, LOG_MEMORY, LOG_LOCKING and LOG_ERROR. The level -// is a DWORD value where zero defines highest important. Use of zero as the -// debug logging level is to be encouraged ONLY for major errors or events as -// they will ALWAYS be displayed on the debugger. Other debug output has it's -// level matched against the current debug output level stored in the registry -// for this module and if less than the current setting it will be displayed. -// -// Each module or executable has it's own debug output level for each of the -// five types. These are read in when the DbgInitialise function is called -// for DLLs linking to STRMBASE.LIB this is done automatically when the DLL -// is loaded, executables must call it explicitely with the module instance -// handle given to them through the WINMAIN entry point. An executable must -// also call DbgTerminate when they have finished to clean up the resources -// the debug library uses, once again this is done automatically for DLLs - -// These are the five different categories of logging information - -enum { LOG_TIMING = 0x01, // Timing and performance measurements - LOG_TRACE = 0x02, // General step point call tracing - LOG_MEMORY = 0x04, // Memory and object allocation/destruction - LOG_LOCKING = 0x08, // Locking/unlocking of critical sections - LOG_ERROR = 0x10, // Debug error notification - LOG_CUSTOM1 = 0x20, - LOG_CUSTOM2 = 0x40, - LOG_CUSTOM3 = 0x80, - LOG_CUSTOM4 = 0x100, - LOG_CUSTOM5 = 0x200, -}; - -#define LOG_FORCIBLY_SET 0x80000000 - -enum { CDISP_HEX = 0x01, - CDISP_DEC = 0x02}; - -// For each object created derived from CBaseObject (in debug builds) we -// create a descriptor that holds it's name (statically allocated memory) -// and a cookie we assign it. We keep a list of all the active objects -// we have registered so that we can dump a list of remaining objects - -typedef struct tag_ObjectDesc { - const CHAR *m_szName; - const WCHAR *m_wszName; - DWORD m_dwCookie; - tag_ObjectDesc *m_pNext; -} ObjectDesc; - -#define DLLIMPORT __declspec(dllimport) -#define DLLEXPORT __declspec(dllexport) - -#ifdef DEBUG - - #define NAME(x) TEXT(x) - - // These are used internally by the debug library (PRIVATE) - - void WINAPI DbgInitKeyLevels(HKEY hKey, bool fTakeMax); - void WINAPI DbgInitGlobalSettings(bool fTakeMax); - void WINAPI DbgInitModuleSettings(bool fTakeMax); - void WINAPI DbgInitModuleName(); - DWORD WINAPI DbgRegisterObjectCreation( - const CHAR *szObjectName, const WCHAR *wszObjectName); - - BOOL WINAPI DbgRegisterObjectDestruction(DWORD dwCookie); - - // These are the PUBLIC entry points - - BOOL WINAPI DbgCheckModuleLevel(DWORD Type,DWORD Level); - void WINAPI DbgSetModuleLevel(DWORD Type,DWORD Level); - void WINAPI DbgSetAutoRefreshLevels(bool fAuto); - - // Initialise the library with the module handle - - void WINAPI DbgInitialise(HINSTANCE hInst); - void WINAPI DbgTerminate(); - - void WINAPI DbgDumpObjectRegister(); - - // Display error and logging to the user - - void WINAPI DbgAssert(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine); - void WINAPI DbgBreakPoint(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine); - void WINAPI DbgBreakPoint(const TCHAR *pFileName,INT iLine,const TCHAR* szFormatString,...); - - void WINAPI DbgKernelAssert(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine); - void WINAPI DbgLogInfo(DWORD Type,DWORD Level,const TCHAR *pFormat,...); -#ifdef UNICODE - void WINAPI DbgLogInfo(DWORD Type,DWORD Level,const CHAR *pFormat,...); - void WINAPI DbgAssert(const CHAR *pCondition,const CHAR *pFileName,INT iLine); - void WINAPI DbgBreakPoint(const CHAR *pCondition,const CHAR *pFileName,INT iLine); - void WINAPI DbgKernelAssert(const CHAR *pCondition,const CHAR *pFileName,INT iLine); -#endif - void WINAPI DbgOutString(LPCTSTR psz); - - // Debug infinite wait stuff - DWORD WINAPI DbgWaitForSingleObject(HANDLE h); - DWORD WINAPI DbgWaitForMultipleObjects(DWORD nCount, - CONST HANDLE *lpHandles, - BOOL bWaitAll); - void WINAPI DbgSetWaitTimeout(DWORD dwTimeout); - -#ifdef __strmif_h__ - // Display a media type: Terse at level 2, verbose at level 5 - void WINAPI DisplayType(LPTSTR label, const AM_MEDIA_TYPE *pmtIn); - - // Dump lots of information about a filter graph - void WINAPI DumpGraph(IFilterGraph *pGraph, DWORD dwLevel); -#endif - - #define KASSERT(_x_) if (!(_x_)) \ - DbgKernelAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__) - - // Break on the debugger without putting up a message box - // message goes to debugger instead - - #define KDbgBreak(_x_) \ - DbgKernelAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__) - - // We chose a common name for our ASSERT macro, MFC also uses this name - // So long as the implementation evaluates the condition and handles it - // then we will be ok. Rather than override the behaviour expected we - // will leave whatever first defines ASSERT as the handler (i.e. MFC) - #ifndef ASSERT - #define ASSERT(_x_) if (!(_x_)) \ - DbgAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__) - #endif - - #define DbgAssertAligned( _ptr_, _alignment_ ) ASSERT( ((DWORD_PTR) (_ptr_)) % (_alignment_) == 0) - - // Put up a message box informing the user of a halt - // condition in the program - - #define DbgBreak(_x_) \ - DbgBreakPoint(TEXT(#_x_),TEXT(__FILE__),__LINE__) - - #define EXECUTE_ASSERT(_x_) ASSERT(_x_) - #define DbgLog(_x_) DbgLogInfo _x_ - // MFC style trace macros - - #define NOTE(_x_) DbgLog((LOG_TRACE,5,TEXT(_x_))) - #define NOTE1(_x_,a) DbgLog((LOG_TRACE,5,TEXT(_x_),a)) - #define NOTE2(_x_,a,b) DbgLog((LOG_TRACE,5,TEXT(_x_),a,b)) - #define NOTE3(_x_,a,b,c) DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c)) - #define NOTE4(_x_,a,b,c,d) DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c,d)) - #define NOTE5(_x_,a,b,c,d,e) DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c,d,e)) - -#else - - // Retail builds make public debug functions inert - WARNING the source - // files do not define or build any of the entry points in debug builds - // (public entry points compile to nothing) so if you go trying to call - // any of the private entry points in your source they won't compile - - #define NAME(_x_) ((TCHAR *) NULL) - - #define DbgInitialise(hInst) - #define DbgTerminate() - #define DbgLog(_x_) 0 - #define DbgOutString(psz) - #define DbgAssertAligned( _ptr_, _alignment_ ) 0 - - #define DbgRegisterObjectCreation(pObjectName) - #define DbgRegisterObjectDestruction(dwCookie) - #define DbgDumpObjectRegister() - - #define DbgCheckModuleLevel(Type,Level) - #define DbgSetModuleLevel(Type,Level) - #define DbgSetAutoRefreshLevels(fAuto) - - #define DbgWaitForSingleObject(h) WaitForSingleObject(h, INFINITE) - #define DbgWaitForMultipleObjects(nCount, lpHandles, bWaitAll) \ - WaitForMultipleObjects(nCount, lpHandles, bWaitAll, INFINITE) - #define DbgSetWaitTimeout(dwTimeout) - - #define KDbgBreak(_x_) - #define DbgBreak(_x_) - - #define KASSERT(_x_) ((void)0) - #ifndef ASSERT - #define ASSERT(_x_) ((void)0) - #endif - #define EXECUTE_ASSERT(_x_) ((void)(_x_)) - - // MFC style trace macros - - #define NOTE(_x_) ((void)0) - #define NOTE1(_x_,a) ((void)0) - #define NOTE2(_x_,a,b) ((void)0) - #define NOTE3(_x_,a,b,c) ((void)0) - #define NOTE4(_x_,a,b,c,d) ((void)0) - #define NOTE5(_x_,a,b,c,d,e) ((void)0) - - #define DisplayType(label, pmtIn) ((void)0) - #define DumpGraph(pGraph, label) ((void)0) -#endif - - -// Checks a pointer which should be non NULL - can be used as follows. - -#define CheckPointer(p,ret) {if((p)==NULL) return (ret);} - -// HRESULT Foo(VOID *pBar) -// { -// CheckPointer(pBar,E_INVALIDARG) -// } -// -// Or if the function returns a boolean -// -// BOOL Foo(VOID *pBar) -// { -// CheckPointer(pBar,FALSE) -// } - -// These validate pointers when symbol VFWROBUST is defined -// This will normally be defined in debug not retail builds - -#ifdef DEBUG - #define VFWROBUST -#endif - -#ifdef VFWROBUST - - #define ValidateReadPtr(p,cb) \ - {if(IsBadReadPtr((PVOID)p,cb) == TRUE) \ - DbgBreak("Invalid read pointer");} - - #define ValidateWritePtr(p,cb) \ - {if(IsBadWritePtr((PVOID)p,cb) == TRUE) \ - DbgBreak("Invalid write pointer");} - - #define ValidateReadWritePtr(p,cb) \ - {ValidateReadPtr(p,cb) ValidateWritePtr(p,cb)} - - #define ValidateStringPtr(p) \ - {if(IsBadStringPtr((LPCTSTR)p,INFINITE) == TRUE) \ - DbgBreak("Invalid string pointer");} - - #define ValidateStringPtrA(p) \ - {if(IsBadStringPtrA((LPCSTR)p,INFINITE) == TRUE) \ - DbgBreak("Invalid ANSI string pointer");} - - #define ValidateStringPtrW(p) \ - {if(IsBadStringPtrW((LPCWSTR)p,INFINITE) == TRUE) \ - DbgBreak("Invalid UNICODE string pointer");} - -#else - #define ValidateReadPtr(p,cb) 0 - #define ValidateWritePtr(p,cb) 0 - #define ValidateReadWritePtr(p,cb) 0 - #define ValidateStringPtr(p) 0 - #define ValidateStringPtrA(p) 0 - #define ValidateStringPtrW(p) 0 -#endif - - -#ifdef _OBJBASE_H_ - - // Outputting GUID names. If you want to include the name - // associated with a GUID (eg CLSID_...) then - // - // GuidNames[yourGUID] - // - // Returns the name defined in uuids.h as a string - - typedef struct { - CHAR *szName; - GUID guid; - } GUID_STRING_ENTRY; - - class CGuidNameList { - public: - CHAR *operator [] (const GUID& guid); - }; - - extern CGuidNameList GuidNames; - -#endif - -#ifndef REMIND - // REMIND macro - generates warning as reminder to complete coding - // (eg) usage: - // - // #pragma message (REMIND("Add automation support")) - - - #define QUOTE(x) #x - #define QQUOTE(y) QUOTE(y) - #define REMIND(str) __FILE__ "(" QQUOTE(__LINE__) ") : " str -#endif - -// Method to display objects in a useful format -// -// eg If you want to display a LONGLONG ll in a debug string do (eg) -// -// DbgLog((LOG_TRACE, n, TEXT("Value is %s"), (LPCTSTR)CDisp(ll, CDISP_HEX))); - - -class CDispBasic -{ -public: - CDispBasic() { m_pString = m_String; }; - ~CDispBasic(); -protected: - PTCHAR m_pString; // normally points to m_String... unless too much data - TCHAR m_String[50]; -}; -class CDisp : public CDispBasic -{ -public: - CDisp(LONGLONG ll, int Format = CDISP_HEX); // Display a LONGLONG in CDISP_HEX or CDISP_DEC form - CDisp(REFCLSID clsid); // Display a GUID - CDisp(double d); // Display a floating point number -#ifdef __strmif_h__ -#ifdef __STREAMS__ - CDisp(CRefTime t); // Display a Reference Time -#endif - CDisp(IPin *pPin); // Display a pin as {filter clsid}(pin name) - CDisp(IUnknown *pUnk); // Display a filter or pin -#endif // __strmif_h__ - ~CDisp(); - - // Implement cast to (LPCTSTR) as parameter to logger - operator LPCTSTR() - { - return (LPCTSTR)m_pString; - }; -}; - - -#if defined(DEBUG) -class CAutoTrace -{ -private: - const TCHAR* _szBlkName; - const int _level; - static const TCHAR _szEntering[]; - static const TCHAR _szLeaving[]; -public: - CAutoTrace(const TCHAR* szBlkName, const int level = 15) - : _szBlkName(szBlkName), _level(level) - {DbgLog((LOG_TRACE, _level, _szEntering, _szBlkName));} - - ~CAutoTrace() - {DbgLog((LOG_TRACE, _level, _szLeaving, _szBlkName));} -}; - -#define AMTRACE(_x_) CAutoTrace __trace _x_ -#else -#define AMTRACE(_x_) -#endif - -#endif // __WXDEBUG__ - - diff --git a/src/BaseClasses/wxlist.cpp b/src/BaseClasses/wxlist.cpp deleted file mode 100644 index 214d096969..0000000000 --- a/src/BaseClasses/wxlist.cpp +++ /dev/null @@ -1,885 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WXList.cpp -// -// Desc: DirectShow base classes - implements a non-MFC based generic list -// template class. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -/* A generic list of pointers to objects. - Objectives: avoid using MFC libraries in ndm kernel mode and - provide a really useful list type. - - The class is thread safe in that separate threads may add and - delete items in the list concurrently although the application - must ensure that constructor and destructor access is suitably - synchronised. - - The list name must not conflict with MFC classes as an - application may use both - - The nodes form a doubly linked, NULL terminated chain with an anchor - block (the list object per se) holding pointers to the first and last - nodes and a count of the nodes. - There is a node cache to reduce the allocation and freeing overhead. - It optionally (determined at construction time) has an Event which is - set whenever the list becomes non-empty and reset whenever it becomes - empty. - It optionally (determined at construction time) has a Critical Section - which is entered during the important part of each operation. (About - all you can do outside it is some parameter checking). - - The node cache is a repository of nodes that are NOT in the list to speed - up storage allocation. Each list has its own cache to reduce locking and - serialising. The list accesses are serialised anyway for a given list - a - common cache would mean that we would have to separately serialise access - of all lists within the cache. Because the cache only stores nodes that are - not in the list, releasing the cache does not release any list nodes. This - means that list nodes can be copied or rechained from one list to another - without danger of creating a dangling reference if the original cache goes - away. - - Questionable design decisions: - 1. Retaining the warts for compatibility - 2. Keeping an element count -i.e. counting whenever we do anything - instead of only when we want the count. - 3. Making the chain pointers NULL terminated. If the list object - itself looks just like a node and the list is kept as a ring then - it reduces the number of special cases. All inserts look the same. -*/ - - -#include - -/* set cursor to the position of each element of list in turn */ -#define INTERNALTRAVERSELIST(list, cursor) \ -for ( cursor = (list).GetHeadPositionI() \ - ; cursor!=NULL \ - ; cursor = (list).Next(cursor) \ - ) - - -/* set cursor to the position of each element of list in turn - in reverse order -*/ -#define INTERNALREVERSETRAVERSELIST(list, cursor) \ -for ( cursor = (list).GetTailPositionI() \ - ; cursor!=NULL \ - ; cursor = (list).Prev(cursor) \ - ) - -/* Constructor calls a separate initialisation function that - creates a node cache, optionally creates a lock object - and optionally creates a signaling object. - - By default we create a locking object, a DEFAULTCACHE sized - cache but no event object so the list cannot be used in calls - to WaitForSingleObject -*/ -CBaseList::CBaseList(TCHAR *pName, // Descriptive list name - INT iItems) : // Node cache size -#ifdef DEBUG - CBaseObject(pName), -#endif - m_pFirst(NULL), - m_pLast(NULL), - m_Count(0), - m_Cache(iItems) -{ -} // constructor - -CBaseList::CBaseList(TCHAR *pName) : // Descriptive list name -#ifdef DEBUG - CBaseObject(pName), -#endif - m_pFirst(NULL), - m_pLast(NULL), - m_Count(0), - m_Cache(DEFAULTCACHE) -{ -} // constructor - -#ifdef UNICODE -CBaseList::CBaseList(CHAR *pName, // Descriptive list name - INT iItems) : // Node cache size -#ifdef DEBUG - CBaseObject(pName), -#endif - m_pFirst(NULL), - m_pLast(NULL), - m_Count(0), - m_Cache(iItems) -{ -} // constructor - -CBaseList::CBaseList(CHAR *pName) : // Descriptive list name -#ifdef DEBUG - CBaseObject(pName), -#endif - m_pFirst(NULL), - m_pLast(NULL), - m_Count(0), - m_Cache(DEFAULTCACHE) -{ -} // constructor - -#endif - -/* The destructor enumerates all the node objects in the list and - in the cache deleting each in turn. We do not do any processing - on the objects that the list holds (i.e. points to) so if they - represent interfaces for example the creator of the list should - ensure that each of them is released before deleting us -*/ -CBaseList::~CBaseList() -{ - /* Delete all our list nodes */ - - RemoveAll(); - -} // destructor - -/* Remove all the nodes from the list but don't do anything - with the objects that each node looks after (this is the - responsibility of the creator). - Aa a last act we reset the signalling event - (if available) to indicate to clients that the list - does not have any entries in it. -*/ -void CBaseList::RemoveAll() -{ - /* Free up all the CNode objects NOTE we don't bother putting the - deleted nodes into the cache as this method is only really called - in serious times of change such as when we are being deleted at - which point the cache will be deleted anway */ - - CNode *pn = m_pFirst; - while (pn) { - CNode *op = pn; - pn = pn->Next(); - delete op; - } - - /* Reset the object count and the list pointers */ - - m_Count = 0; - m_pFirst = m_pLast = NULL; - -} // RemoveAll - - - -/* Return a position enumerator for the entire list. - A position enumerator is a pointer to a node object cast to a - transparent type so all we do is return the head/tail node - pointer in the list. - WARNING because the position is a pointer to a node there is - an implicit assumption for users a the list class that after - deleting an object from the list that any other position - enumerators that you have may be invalid (since the node - may be gone). -*/ -POSITION CBaseList::GetHeadPositionI() const -{ - return (POSITION) m_pFirst; -} // GetHeadPosition - - - -POSITION CBaseList::GetTailPositionI() const -{ - return (POSITION) m_pLast; -} // GetTailPosition - - - -/* Get the number of objects in the list, - Get the lock before accessing the count. - Locking may not be entirely necessary but it has the side effect - of making sure that all operations are complete before we get it. - So for example if a list is being added to this list then that - will have completed in full before we continue rather than seeing - an intermediate albeit valid state -*/ -int CBaseList::GetCountI() const -{ - return m_Count; -} // GetCount - - - -/* Return the object at rp, update rp to the next object from - the list or NULL if you have moved over the last object. - You may still call this function once we return NULL but - we will continue to return a NULL position value -*/ -void *CBaseList::GetNextI(POSITION& rp) const -{ - /* have we reached the end of the list */ - - if (rp == NULL) { - return NULL; - } - - /* Lock the object before continuing */ - - void *pObject; - - /* Copy the original position then step on */ - - CNode *pn = (CNode *) rp; - ASSERT(pn != NULL); - rp = (POSITION) pn->Next(); - - /* Get the object at the original position from the list */ - - pObject = pn->GetData(); - // ASSERT(pObject != NULL); // NULL pointers in the list are allowed. - return pObject; -} //GetNext - - - -/* Return the object at p. - Asking for the object at NULL ASSERTs then returns NULL - The object is NOT locked. The list is not being changed - in any way. If another thread is busy deleting the object - then locking would only result in a change from one bad - behaviour to another. -*/ -void *CBaseList::GetI(POSITION p) const -{ - if (p == NULL) { - return NULL; - } - - CNode * pn = (CNode *) p; - void *pObject = pn->GetData(); - // ASSERT(pObject != NULL); // NULL pointers in the list are allowed. - return pObject; -} //Get - - - -/* Return the first position in the list which holds the given pointer. - Return NULL if it's not found. -*/ -POSITION CBaseList::FindI( void * pObj) const -{ - POSITION pn; - INTERNALTRAVERSELIST(*this, pn){ - if (GetI(pn)==pObj) { - return pn; - } - } - return NULL; -} // Find - - - -/* Remove the first node in the list (deletes the pointer to its object - from the list, does not free the object itself). - Return the pointer to its object or NULL if empty -*/ -void *CBaseList::RemoveHeadI() -{ - /* All we do is get the head position and ask for that to be deleted. - We could special case this since some of the code path checking - in Remove() is redundant as we know there is no previous - node for example but it seems to gain little over the - added complexity - */ - - return RemoveI((POSITION)m_pFirst); -} // RemoveHead - - - -/* Remove the last node in the list (deletes the pointer to its object - from the list, does not free the object itself). - Return the pointer to its object or NULL if empty -*/ -void *CBaseList::RemoveTailI() -{ - /* All we do is get the tail position and ask for that to be deleted. - We could special case this since some of the code path checking - in Remove() is redundant as we know there is no previous - node for example but it seems to gain little over the - added complexity - */ - - return RemoveI((POSITION)m_pLast); -} // RemoveTail - - - -/* Remove the pointer to the object in this position from the list. - Deal with all the chain pointers - Return a pointer to the object removed from the list. - The node object that is freed as a result - of this operation is added to the node cache where - it can be used again. - Remove(NULL) is a harmless no-op - but probably is a wart. -*/ -void *CBaseList::RemoveI(POSITION pos) -{ - /* Lock the critical section before continuing */ - - // ASSERT (pos!=NULL); // Removing NULL is to be harmless! - if (pos==NULL) return NULL; - - - CNode *pCurrent = (CNode *) pos; - ASSERT(pCurrent != NULL); - - /* Update the previous node */ - - CNode *pNode = pCurrent->Prev(); - if (pNode == NULL) { - m_pFirst = pCurrent->Next(); - } else { - pNode->SetNext(pCurrent->Next()); - } - - /* Update the following node */ - - pNode = pCurrent->Next(); - if (pNode == NULL) { - m_pLast = pCurrent->Prev(); - } else { - pNode->SetPrev(pCurrent->Prev()); - } - - /* Get the object this node was looking after */ - - void *pObject = pCurrent->GetData(); - - // ASSERT(pObject != NULL); // NULL pointers in the list are allowed. - - /* Try and add the node object to the cache - - a NULL return code from the cache means we ran out of room. - The cache size is fixed by a constructor argument when the - list is created and defaults to DEFAULTCACHE. - This means that the cache will have room for this many - node objects. So if you have a list of media samples - and you know there will never be more than five active at - any given time of them for example then override the default - constructor - */ - - m_Cache.AddToCache(pCurrent); - - /* If the list is empty then reset the list event */ - - --m_Count; - ASSERT(m_Count >= 0); - return pObject; -} // Remove - - - -/* Add this object to the tail end of our list - Return the new tail position. -*/ - -POSITION CBaseList::AddTailI(void *pObject) -{ - /* Lock the critical section before continuing */ - - CNode *pNode; - // ASSERT(pObject); // NULL pointers in the list are allowed. - - /* If there is a node objects in the cache then use - that otherwise we will have to create a new one */ - - pNode = (CNode *) m_Cache.RemoveFromCache(); - if (pNode == NULL) { - pNode = new CNode; - } - - /* Check we have a valid object */ - - if (pNode == NULL) { - return NULL; - } - - /* Initialise all the CNode object - just in case it came from the cache - */ - - pNode->SetData(pObject); - pNode->SetNext(NULL); - pNode->SetPrev(m_pLast); - - if (m_pLast == NULL) { - m_pFirst = pNode; - } else { - m_pLast->SetNext(pNode); - } - - /* Set the new last node pointer and also increment the number - of list entries, the critical section is unlocked when we - exit the function - */ - - m_pLast = pNode; - ++m_Count; - - return (POSITION) pNode; -} // AddTail(object) - - - -/* Add this object to the head end of our list - Return the new head position. -*/ -POSITION CBaseList::AddHeadI(void *pObject) -{ - CNode *pNode; - // ASSERT(pObject); // NULL pointers in the list are allowed. - - /* If there is a node objects in the cache then use - that otherwise we will have to create a new one */ - - pNode = (CNode *) m_Cache.RemoveFromCache(); - if (pNode == NULL) { - pNode = new CNode; - } - - /* Check we have a valid object */ - - if (pNode == NULL) { - return NULL; - } - - /* Initialise all the CNode object - just in case it came from the cache - */ - - pNode->SetData(pObject); - - /* chain it in (set four pointers) */ - pNode->SetPrev(NULL); - pNode->SetNext(m_pFirst); - - if (m_pFirst == NULL) { - m_pLast = pNode; - } else { - m_pFirst->SetPrev(pNode); - } - m_pFirst = pNode; - - ++m_Count; - - return (POSITION) pNode; -} // AddHead(object) - - - -/* Add all the elements in *pList to the tail of this list. - Return TRUE if it all worked, FALSE if it didn't. - If it fails some elements may have been added. -*/ -BOOL CBaseList::AddTail(CBaseList *pList) -{ - /* lock the object before starting then enumerate - each entry in the source list and add them one by one to - our list (while still holding the object lock) - Lock the other list too. - */ - POSITION pos = pList->GetHeadPositionI(); - - while (pos) { - if (NULL == AddTailI(pList->GetNextI(pos))) { - return FALSE; - } - } - return TRUE; -} // AddTail(list) - - - -/* Add all the elements in *pList to the head of this list. - Return TRUE if it all worked, FALSE if it didn't. - If it fails some elements may have been added. -*/ -BOOL CBaseList::AddHead(CBaseList *pList) -{ - /* lock the object before starting then enumerate - each entry in the source list and add them one by one to - our list (while still holding the object lock) - Lock the other list too. - - To avoid reversing the list, traverse it backwards. - */ - - POSITION pos; - - INTERNALREVERSETRAVERSELIST(*pList, pos) { - if (NULL== AddHeadI(pList->GetI(pos))){ - return FALSE; - } - } - return TRUE; -} // AddHead(list) - - - -/* Add the object after position p - p is still valid after the operation. - AddAfter(NULL,x) adds x to the start - same as AddHead - Return the position of the new object, NULL if it failed -*/ -POSITION CBaseList::AddAfterI(POSITION pos, void * pObj) -{ - if (pos==NULL) - return AddHeadI(pObj); - - /* As someone else might be furkling with the list - - Lock the critical section before continuing - */ - CNode *pAfter = (CNode *) pos; - ASSERT(pAfter != NULL); - if (pAfter==m_pLast) - return AddTailI(pObj); - - /* set pnode to point to a new node, preferably from the cache */ - - CNode *pNode = (CNode *) m_Cache.RemoveFromCache(); - if (pNode == NULL) { - pNode = new CNode; - } - - /* Check we have a valid object */ - - if (pNode == NULL) { - return NULL; - } - - /* Initialise all the CNode object - just in case it came from the cache - */ - - pNode->SetData(pObj); - - /* It is to be added to the middle of the list - there is a before - and after node. Chain it after pAfter, before pBefore. - */ - CNode * pBefore = pAfter->Next(); - ASSERT(pBefore != NULL); - - /* chain it in (set four pointers) */ - pNode->SetPrev(pAfter); - pNode->SetNext(pBefore); - pBefore->SetPrev(pNode); - pAfter->SetNext(pNode); - - ++m_Count; - - return (POSITION) pNode; - -} // AddAfter(object) - - - -BOOL CBaseList::AddAfter(POSITION p, CBaseList *pList) -{ - POSITION pos; - INTERNALTRAVERSELIST(*pList, pos) { - /* p follows along the elements being added */ - p = AddAfterI(p, pList->GetI(pos)); - if (p==NULL) return FALSE; - } - return TRUE; -} // AddAfter(list) - - - -/* Mirror images: - Add the element or list after position p. - p is still valid after the operation. - AddBefore(NULL,x) adds x to the end - same as AddTail -*/ -POSITION CBaseList::AddBeforeI(POSITION pos, void * pObj) -{ - if (pos==NULL) - return AddTailI(pObj); - - /* set pnode to point to a new node, preferably from the cache */ - - CNode *pBefore = (CNode *) pos; - ASSERT(pBefore != NULL); - if (pBefore==m_pFirst) - return AddHeadI(pObj); - - CNode * pNode = (CNode *) m_Cache.RemoveFromCache(); - if (pNode == NULL) { - pNode = new CNode; - } - - /* Check we have a valid object */ - - if (pNode == NULL) { - return NULL; - } - - /* Initialise all the CNode object - just in case it came from the cache - */ - - pNode->SetData(pObj); - - /* It is to be added to the middle of the list - there is a before - and after node. Chain it after pAfter, before pBefore. - */ - - CNode * pAfter = pBefore->Prev(); - ASSERT(pAfter != NULL); - - /* chain it in (set four pointers) */ - pNode->SetPrev(pAfter); - pNode->SetNext(pBefore); - pBefore->SetPrev(pNode); - pAfter->SetNext(pNode); - - ++m_Count; - - return (POSITION) pNode; - -} // Addbefore(object) - - - -BOOL CBaseList::AddBefore(POSITION p, CBaseList *pList) -{ - POSITION pos; - INTERNALREVERSETRAVERSELIST(*pList, pos) { - /* p follows along the elements being added */ - p = AddBeforeI(p, pList->GetI(pos)); - if (p==NULL) return FALSE; - } - return TRUE; -} // AddBefore(list) - - - -/* Split *this after position p in *this - Retain as *this the tail portion of the original *this - Add the head portion to the tail end of *pList - Return TRUE if it all worked, FALSE if it didn't. - - e.g. - foo->MoveToTail(foo->GetHeadPosition(), bar); - moves one element from the head of foo to the tail of bar - foo->MoveToTail(NULL, bar); - is a no-op - foo->MoveToTail(foo->GetTailPosition, bar); - concatenates foo onto the end of bar and empties foo. - - A better, except excessively long name might be - MoveElementsFromHeadThroughPositionToOtherTail -*/ -BOOL CBaseList::MoveToTail - (POSITION pos, CBaseList *pList) -{ - /* Algorithm: - Note that the elements (including their order) in the concatenation - of *pList to the head of *this is invariant. - 1. Count elements to be moved - 2. Join *pList onto the head of this to make one long chain - 3. Set first/Last pointers in *this and *pList - 4. Break the chain at the new place - 5. Adjust counts - 6. Set/Reset any events - */ - - if (pos==NULL) return TRUE; // no-op. Eliminates special cases later. - - - /* Make cMove the number of nodes to move */ - CNode * p = (CNode *)pos; - int cMove = 0; // number of nodes to move - while(p!=NULL) { - p = p->Prev(); - ++cMove; - } - - - /* Join the two chains together */ - if (pList->m_pLast!=NULL) - pList->m_pLast->SetNext(m_pFirst); - if (m_pFirst!=NULL) - m_pFirst->SetPrev(pList->m_pLast); - - - /* set first and last pointers */ - p = (CNode *)pos; - - if (pList->m_pFirst==NULL) - pList->m_pFirst = m_pFirst; - m_pFirst = p->Next(); - if (m_pFirst==NULL) - m_pLast = NULL; - pList->m_pLast = p; - - - /* Break the chain after p to create the new pieces */ - if (m_pFirst!=NULL) - m_pFirst->SetPrev(NULL); - p->SetNext(NULL); - - - /* Adjust the counts */ - m_Count -= cMove; - pList->m_Count += cMove; - - return TRUE; - -} // MoveToTail - - - -/* Mirror image of MoveToTail: - Split *this before position p in *this. - Retain in *this the head portion of the original *this - Add the tail portion to the start (i.e. head) of *pList - Return TRUE if it all worked, FALSE if it didn't. - - e.g. - foo->MoveToHead(foo->GetTailPosition(), bar); - moves one element from the tail of foo to the head of bar - foo->MoveToHead(NULL, bar); - is a no-op - foo->MoveToHead(foo->GetHeadPosition, bar); - concatenates foo onto the start of bar and empties foo. -*/ -BOOL CBaseList::MoveToHead - (POSITION pos, CBaseList *pList) -{ - - /* See the comments on the algorithm in MoveToTail */ - - if (pos==NULL) return TRUE; // no-op. Eliminates special cases later. - - /* Make cMove the number of nodes to move */ - CNode * p = (CNode *)pos; - int cMove = 0; // number of nodes to move - while(p!=NULL) { - p = p->Next(); - ++cMove; - } - - - /* Join the two chains together */ - if (pList->m_pFirst!=NULL) - pList->m_pFirst->SetPrev(m_pLast); - if (m_pLast!=NULL) - m_pLast->SetNext(pList->m_pFirst); - - - /* set first and last pointers */ - p = (CNode *)pos; - - - if (pList->m_pLast==NULL) - pList->m_pLast = m_pLast; - - m_pLast = p->Prev(); - if (m_pLast==NULL) - m_pFirst = NULL; - pList->m_pFirst = p; - - - /* Break the chain after p to create the new pieces */ - if (m_pLast!=NULL) - m_pLast->SetNext(NULL); - p->SetPrev(NULL); - - - /* Adjust the counts */ - m_Count -= cMove; - pList->m_Count += cMove; - - return TRUE; - -} // MoveToHead - - - -/* Reverse the order of the [pointers to] objects in *this -*/ -void CBaseList::Reverse() -{ - /* algorithm: - The obvious booby trap is that you flip pointers around and lose - addressability to the node that you are going to process next. - The easy way to avoid this is do do one chain at a time. - - Run along the forward chain, - For each node, set the reverse pointer to the one ahead of us. - The reverse chain is now a copy of the old forward chain, including - the NULL termination. - - Run along the reverse chain (i.e. old forward chain again) - For each node set the forward pointer of the node ahead to point back - to the one we're standing on. - The first node needs special treatment, - it's new forward pointer is NULL. - Finally set the First/Last pointers - - */ - CNode * p; - - // Yes we COULD use a traverse, but it would look funny! - p = m_pFirst; - while (p!=NULL) { - CNode * q; - q = p->Next(); - p->SetNext(p->Prev()); - p->SetPrev(q); - p = q; - } - - p = m_pFirst; - m_pFirst = m_pLast; - m_pLast = p; - - -#if 0 // old version - - if (m_pFirst==NULL) return; // empty list - if (m_pFirst->Next()==NULL) return; // single node list - - - /* run along forward chain */ - for ( p = m_pFirst - ; p!=NULL - ; p = p->Next() - ){ - p->SetPrev(p->Next()); - } - - - /* special case first element */ - m_pFirst->SetNext(NULL); // fix the old first element - - - /* run along new reverse chain i.e. old forward chain again */ - for ( p = m_pFirst // start at the old first element - ; p->Prev()!=NULL // while there's a node still to be set - ; p = p->Prev() // work in the same direction as before - ){ - p->Prev()->SetNext(p); - } - - - /* fix forward and reverse pointers - - the triple XOR swap would work but all the casts look hideous */ - p = m_pFirst; - m_pFirst = m_pLast; - m_pLast = p; -#endif - -} // Reverse diff --git a/src/BaseClasses/wxlist.h b/src/BaseClasses/wxlist.h deleted file mode 100644 index 3f4c190435..0000000000 --- a/src/BaseClasses/wxlist.h +++ /dev/null @@ -1,551 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WXList.h -// -// Desc: DirectShow base classes - defines a non-MFC generic template list -// class. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -/* A generic list of pointers to objects. - No storage management or copying is done on the objects pointed to. - Objectives: avoid using MFC libraries in ndm kernel mode and - provide a really useful list type. - - The class is thread safe in that separate threads may add and - delete items in the list concurrently although the application - must ensure that constructor and destructor access is suitably - synchronised. An application can cause deadlock with operations - which use two lists by simultaneously calling - list1->Operation(list2) and list2->Operation(list1). So don't! - - The names must not conflict with MFC classes as an application - may use both. - */ - -#ifndef __WXLIST__ -#define __WXLIST__ - - /* A POSITION represents (in some fashion that's opaque) a cursor - on the list that can be set to identify any element. NULL is - a valid value and several operations regard NULL as the position - "one step off the end of the list". (In an n element list there - are n+1 places to insert and NULL is that "n+1-th" value). - The POSITION of an element in the list is only invalidated if - that element is deleted. Move operations may mean that what - was a valid POSITION in one list is now a valid POSITION in - a different list. - - Some operations which at first sight are illegal are allowed as - harmless no-ops. For instance RemoveHead is legal on an empty - list and it returns NULL. This allows an atomic way to test if - there is an element there, and if so, get it. The two operations - AddTail and RemoveHead thus implement a MONITOR (See Hoare's paper). - - Single element operations return POSITIONs, non-NULL means it worked. - whole list operations return a BOOL. TRUE means it all worked. - - This definition is the same as the POSITION type for MFCs, so we must - avoid defining it twice. - */ -#ifndef __AFX_H__ -struct __POSITION { int unused; }; -typedef __POSITION* POSITION; -#endif - -const int DEFAULTCACHE = 10; /* Default node object cache size */ - -/* A class representing one node in a list. - Each node knows a pointer to it's adjacent nodes and also a pointer - to the object that it looks after. - All of these pointers can be retrieved or set through member functions. -*/ -class CBaseList -#ifdef DEBUG - : public CBaseObject -#endif -{ - /* Making these classes inherit from CBaseObject does nothing - functionally but it allows us to check there are no memory - leaks in debug builds. - */ - -public: - -#ifdef DEBUG - class CNode : public CBaseObject { -#else - class CNode { -#endif - - CNode *m_pPrev; /* Previous node in the list */ - CNode *m_pNext; /* Next node in the list */ - void *m_pObject; /* Pointer to the object */ - - public: - - /* Constructor - initialise the object's pointers */ - CNode() -#ifdef DEBUG - : CBaseObject(NAME("List node")) -#endif - { - }; - - - /* Return the previous node before this one */ - CNode *Prev() const { return m_pPrev; }; - - - /* Return the next node after this one */ - CNode *Next() const { return m_pNext; }; - - - /* Set the previous node before this one */ - void SetPrev(CNode *p) { m_pPrev = p; }; - - - /* Set the next node after this one */ - void SetNext(CNode *p) { m_pNext = p; }; - - - /* Get the pointer to the object for this node */ - void *GetData() const { return m_pObject; }; - - - /* Set the pointer to the object for this node */ - void SetData(void *p) { m_pObject = p; }; - }; - - class CNodeCache - { - public: - CNodeCache(INT iCacheSize) : m_iCacheSize(iCacheSize), - m_pHead(NULL), - m_iUsed(0) - {}; - ~CNodeCache() { - CNode *pNode = m_pHead; - while (pNode) { - CNode *pCurrent = pNode; - pNode = pNode->Next(); - delete pCurrent; - } - }; - void AddToCache(CNode *pNode) - { - if (m_iUsed < m_iCacheSize) { - pNode->SetNext(m_pHead); - m_pHead = pNode; - m_iUsed++; - } else { - delete pNode; - } - }; - CNode *RemoveFromCache() - { - CNode *pNode = m_pHead; - if (pNode != NULL) { - m_pHead = pNode->Next(); - m_iUsed--; - ASSERT(m_iUsed >= 0); - } else { - ASSERT(m_iUsed == 0); - } - return pNode; - }; - private: - INT m_iCacheSize; - INT m_iUsed; - CNode *m_pHead; - }; - -protected: - - CNode* m_pFirst; /* Pointer to first node in the list */ - CNode* m_pLast; /* Pointer to the last node in the list */ - LONG m_Count; /* Number of nodes currently in the list */ - -private: - - CNodeCache m_Cache; /* Cache of unused node pointers */ - -private: - - /* These override the default copy constructor and assignment - operator for all list classes. They are in the private class - declaration section so that anybody trying to pass a list - object by value will generate a compile time error of - "cannot access the private member function". If these were - not here then the compiler will create default constructors - and assignment operators which when executed first take a - copy of all member variables and then during destruction - delete them all. This must not be done for any heap - allocated data. - */ - CBaseList(const CBaseList &refList); - CBaseList &operator=(const CBaseList &refList); - -public: - - CBaseList(TCHAR *pName, - INT iItems); - - CBaseList(TCHAR *pName); -#ifdef UNICODE - CBaseList(CHAR *pName, - INT iItems); - - CBaseList(CHAR *pName); -#endif - ~CBaseList(); - - /* Remove all the nodes from *this i.e. make the list empty */ - void RemoveAll(); - - - /* Return a cursor which identifies the first element of *this */ - POSITION GetHeadPositionI() const; - - - /* Return a cursor which identifies the last element of *this */ - POSITION GetTailPositionI() const; - - - /* Return the number of objects in *this */ - int GetCountI() const; - -protected: - /* Return the pointer to the object at rp, - Update rp to the next node in *this - but make it NULL if it was at the end of *this. - This is a wart retained for backwards compatibility. - GetPrev is not implemented. - Use Next, Prev and Get separately. - */ - void *GetNextI(POSITION& rp) const; - - - /* Return a pointer to the object at p - Asking for the object at NULL will return NULL harmlessly. - */ - void *GetI(POSITION p) const; - -public: - /* return the next / prev position in *this - return NULL when going past the end/start. - Next(NULL) is same as GetHeadPosition() - Prev(NULL) is same as GetTailPosition() - An n element list therefore behaves like a n+1 element - cycle with NULL at the start/end. - - !!WARNING!! - This handling of NULL is DIFFERENT from GetNext. - - Some reasons are: - 1. For a list of n items there are n+1 positions to insert - These are conveniently encoded as the n POSITIONs and NULL. - 2. If you are keeping a list sorted (fairly common) and you - search forward for an element to insert before and don't - find it you finish up with NULL as the element before which - to insert. You then want that NULL to be a valid POSITION - so that you can insert before it and you want that insertion - point to mean the (n+1)-th one that doesn't have a POSITION. - (symmetrically if you are working backwards through the list). - 3. It simplifies the algebra which the methods generate. - e.g. AddBefore(p,x) is identical to AddAfter(Prev(p),x) - in ALL cases. All the other arguments probably are reflections - of the algebraic point. - */ - POSITION Next(POSITION pos) const - { - if (pos == NULL) { - return (POSITION) m_pFirst; - } - CNode *pn = (CNode *) pos; - return (POSITION) pn->Next(); - } //Next - - // See Next - POSITION Prev(POSITION pos) const - { - if (pos == NULL) { - return (POSITION) m_pLast; - } - CNode *pn = (CNode *) pos; - return (POSITION) pn->Prev(); - } //Prev - - - /* Return the first position in *this which holds the given - pointer. Return NULL if the pointer was not not found. - */ -protected: - POSITION FindI( void * pObj) const; - - // ??? Should there be (or even should there be only) - // ??? POSITION FindNextAfter(void * pObj, POSITION p) - // ??? And of course FindPrevBefore too. - // ??? List.Find(&Obj) then becomes List.FindNextAfter(&Obj, NULL) - - - /* Remove the first node in *this (deletes the pointer to its - object from the list, does not free the object itself). - Return the pointer to its object. - If *this was already empty it will harmlessly return NULL. - */ - void *RemoveHeadI(); - - - /* Remove the last node in *this (deletes the pointer to its - object from the list, does not free the object itself). - Return the pointer to its object. - If *this was already empty it will harmlessly return NULL. - */ - void *RemoveTailI(); - - - /* Remove the node identified by p from the list (deletes the pointer - to its object from the list, does not free the object itself). - Asking to Remove the object at NULL will harmlessly return NULL. - Return the pointer to the object removed. - */ - void *RemoveI(POSITION p); - - /* Add single object *pObj to become a new last element of the list. - Return the new tail position, NULL if it fails. - If you are adding a COM objects, you might want AddRef it first. - Other existing POSITIONs in *this are still valid - */ - POSITION AddTailI(void * pObj); -public: - - - /* Add all the elements in *pList to the tail of *this. - This duplicates all the nodes in *pList (i.e. duplicates - all its pointers to objects). It does not duplicate the objects. - If you are adding a list of pointers to a COM object into the list - it's a good idea to AddRef them all it when you AddTail it. - Return TRUE if it all worked, FALSE if it didn't. - If it fails some elements may have been added. - Existing POSITIONs in *this are still valid - - If you actually want to MOVE the elements, use MoveToTail instead. - */ - BOOL AddTail(CBaseList *pList); - - - /* Mirror images of AddHead: */ - - /* Add single object to become a new first element of the list. - Return the new head position, NULL if it fails. - Existing POSITIONs in *this are still valid - */ -protected: - POSITION AddHeadI(void * pObj); -public: - - /* Add all the elements in *pList to the head of *this. - Same warnings apply as for AddTail. - Return TRUE if it all worked, FALSE if it didn't. - If it fails some of the objects may have been added. - - If you actually want to MOVE the elements, use MoveToHead instead. - */ - BOOL AddHead(CBaseList *pList); - - - /* Add the object *pObj to *this after position p in *this. - AddAfter(NULL,x) adds x to the start - equivalent to AddHead - Return the position of the object added, NULL if it failed. - Existing POSITIONs in *this are undisturbed, including p. - */ -protected: - POSITION AddAfterI(POSITION p, void * pObj); -public: - - /* Add the list *pList to *this after position p in *this - AddAfter(NULL,x) adds x to the start - equivalent to AddHead - Return TRUE if it all worked, FALSE if it didn't. - If it fails, some of the objects may be added - Existing POSITIONs in *this are undisturbed, including p. - */ - BOOL AddAfter(POSITION p, CBaseList *pList); - - - /* Mirror images: - Add the object *pObj to this-List after position p in *this. - AddBefore(NULL,x) adds x to the end - equivalent to AddTail - Return the position of the new object, NULL if it fails - Existing POSITIONs in *this are undisturbed, including p. - */ - protected: - POSITION AddBeforeI(POSITION p, void * pObj); - public: - - /* Add the list *pList to *this before position p in *this - AddAfter(NULL,x) adds x to the start - equivalent to AddHead - Return TRUE if it all worked, FALSE if it didn't. - If it fails, some of the objects may be added - Existing POSITIONs in *this are undisturbed, including p. - */ - BOOL AddBefore(POSITION p, CBaseList *pList); - - - /* Note that AddAfter(p,x) is equivalent to AddBefore(Next(p),x) - even in cases where p is NULL or Next(p) is NULL. - Similarly for mirror images etc. - This may make it easier to argue about programs. - */ - - - - /* The following operations do not copy any elements. - They move existing blocks of elements around by switching pointers. - They are fairly efficient for long lists as for short lists. - (Alas, the Count slows things down). - - They split the list into two parts. - One part remains as the original list, the other part - is appended to the second list. There are eight possible - variations: - Split the list {after/before} a given element - keep the {head/tail} portion in the original list - append the rest to the {head/tail} of the new list. - - Since After is strictly equivalent to Before Next - we are not in serious need of the Before/After variants. - That leaves only four. - - If you are processing a list left to right and dumping - the bits that you have processed into another list as - you go, the Tail/Tail variant gives the most natural result. - If you are processing in reverse order, Head/Head is best. - - By using NULL positions and empty lists judiciously either - of the other two can be built up in two operations. - - The definition of NULL (see Next/Prev etc) means that - degenerate cases include - "move all elements to new list" - "Split a list into two lists" - "Concatenate two lists" - (and quite a few no-ops) - - !!WARNING!! The type checking won't buy you much if you get list - positions muddled up - e.g. use a POSITION that's in a different - list and see what a mess you get! - */ - - /* Split *this after position p in *this - Retain as *this the tail portion of the original *this - Add the head portion to the tail end of *pList - Return TRUE if it all worked, FALSE if it didn't. - - e.g. - foo->MoveToTail(foo->GetHeadPosition(), bar); - moves one element from the head of foo to the tail of bar - foo->MoveToTail(NULL, bar); - is a no-op, returns NULL - foo->MoveToTail(foo->GetTailPosition, bar); - concatenates foo onto the end of bar and empties foo. - - A better, except excessively long name might be - MoveElementsFromHeadThroughPositionToOtherTail - */ - BOOL MoveToTail(POSITION pos, CBaseList *pList); - - - /* Mirror image: - Split *this before position p in *this. - Retain in *this the head portion of the original *this - Add the tail portion to the start (i.e. head) of *pList - - e.g. - foo->MoveToHead(foo->GetTailPosition(), bar); - moves one element from the tail of foo to the head of bar - foo->MoveToHead(NULL, bar); - is a no-op, returns NULL - foo->MoveToHead(foo->GetHeadPosition, bar); - concatenates foo onto the start of bar and empties foo. - */ - BOOL MoveToHead(POSITION pos, CBaseList *pList); - - - /* Reverse the order of the [pointers to] objects in *this - */ - void Reverse(); - - - /* set cursor to the position of each element of list in turn */ - #define TRAVERSELIST(list, cursor) \ - for ( cursor = (list).GetHeadPosition() \ - ; cursor!=NULL \ - ; cursor = (list).Next(cursor) \ - ) - - - /* set cursor to the position of each element of list in turn - in reverse order - */ - #define REVERSETRAVERSELIST(list, cursor) \ - for ( cursor = (list).GetTailPosition() \ - ; cursor!=NULL \ - ; cursor = (list).Prev(cursor) \ - ) - -}; // end of class declaration - -template class CGenericList : public CBaseList -{ -public: - CGenericList(TCHAR *pName, - INT iItems, - BOOL bLock = TRUE, - BOOL bAlert = FALSE) : - CBaseList(pName, iItems) { - UNREFERENCED_PARAMETER(bAlert); - UNREFERENCED_PARAMETER(bLock); - }; - CGenericList(TCHAR *pName) : - CBaseList(pName) { - }; - - POSITION GetHeadPosition() const { return (POSITION)m_pFirst; } - POSITION GetTailPosition() const { return (POSITION)m_pLast; } - int GetCount() const { return m_Count; } - - OBJECT *GetNext(POSITION& rp) const { return (OBJECT *) GetNextI(rp); } - - OBJECT *Get(POSITION p) const { return (OBJECT *) GetI(p); } - OBJECT *GetHead() const { return Get(GetHeadPosition()); } - - OBJECT *RemoveHead() { return (OBJECT *) RemoveHeadI(); } - - OBJECT *RemoveTail() { return (OBJECT *) RemoveTailI(); } - - OBJECT *Remove(POSITION p) { return (OBJECT *) RemoveI(p); } - POSITION AddBefore(POSITION p, OBJECT * pObj) { return AddBeforeI(p, pObj); } - POSITION AddAfter(POSITION p, OBJECT * pObj) { return AddAfterI(p, pObj); } - POSITION AddHead(OBJECT * pObj) { return AddHeadI(pObj); } - POSITION AddTail(OBJECT * pObj) { return AddTailI(pObj); } - BOOL AddTail(CGenericList *pList) - { return CBaseList::AddTail((CBaseList *) pList); } - BOOL AddHead(CGenericList *pList) - { return CBaseList::AddHead((CBaseList *) pList); } - BOOL AddAfter(POSITION p, CGenericList *pList) - { return CBaseList::AddAfter(p, (CBaseList *) pList); }; - BOOL AddBefore(POSITION p, CGenericList *pList) - { return CBaseList::AddBefore(p, (CBaseList *) pList); }; - POSITION Find( OBJECT * pObj) const { return FindI(pObj); } -}; // end of class declaration - - - -/* These define the standard list types */ - -typedef CGenericList CBaseObjectList; -typedef CGenericList CBaseInterfaceList; - -#endif /* __WXLIST__ */ - diff --git a/src/BaseClasses/wxutil.cpp b/src/BaseClasses/wxutil.cpp deleted file mode 100644 index 065d84e346..0000000000 --- a/src/BaseClasses/wxutil.cpp +++ /dev/null @@ -1,1210 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WXUtil.cpp -// -// Desc: DirectShow base classes - implements helper classes for building -// multimedia filters. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ -#include -#include - -// -// Declare function from largeint.h we need so that PPC can build -// - -// -// Enlarged integer divide - 64-bits / 32-bits > 32-bits -// - -#ifndef _X86_ - -#define LLtoU64(x) (*(unsigned __int64*)(void*)(&(x))) - -__inline -ULONG -WINAPI -EnlargedUnsignedDivide( - IN ULARGE_INTEGER Dividend, - IN ULONG Divisor, - IN PULONG Remainder - ) { - // return remainder if necessary - if(Remainder != NULL) - *Remainder = (ULONG)(LLtoU64(Dividend) % Divisor); - return (ULONG)(LLtoU64(Dividend) / Divisor); -} - -#else -__inline -ULONG -WINAPI -EnlargedUnsignedDivide( - IN ULARGE_INTEGER Dividend, - IN ULONG Divisor, - IN PULONG Remainder - ) { - ULONG ulResult; - _asm { - mov eax,Dividend.LowPart - mov edx,Dividend.HighPart - mov ecx,Remainder - div Divisor - or ecx,ecx - jz short label - mov [ecx],edx - label: - mov ulResult,eax - } - return ulResult; -} -#endif - -// --- CAMEvent ----------------------- -CAMEvent::CAMEvent(BOOL fManualReset) { - m_hEvent = CreateEvent(NULL, fManualReset, FALSE, NULL); -} - -CAMEvent::~CAMEvent() { - if(m_hEvent) { - EXECUTE_ASSERT(CloseHandle(m_hEvent)); - } -} - - -// --- CAMMsgEvent ----------------------- -// One routine. The rest is handled in CAMEvent - -BOOL CAMMsgEvent::WaitMsg(DWORD dwTimeout) { - // wait for the event to be signalled, or for the - // timeout (in MS) to expire. allow SENT messages - // to be processed while we wait - DWORD dwWait; - DWORD dwStartTime=0; - - // set the waiting period. - DWORD dwWaitTime = dwTimeout; - - // the timeout will eventually run down as we iterate - // processing messages. grab the start time so that - // we can calculate elapsed times. - if(dwWaitTime != INFINITE) { - dwStartTime = timeGetTime(); - } - - do { - dwWait = MsgWaitForMultipleObjects(1,&m_hEvent,FALSE, dwWaitTime, QS_SENDMESSAGE); - if(dwWait == WAIT_OBJECT_0 + 1) { - MSG Message; - PeekMessage(&Message,NULL,0,0,PM_NOREMOVE); - - // If we have an explicit length of time to wait calculate - // the next wake up point - which might be now. - // If dwTimeout is INFINITE, it stays INFINITE - if(dwWaitTime != INFINITE) { - - DWORD dwElapsed = timeGetTime()-dwStartTime; - - dwWaitTime = - (dwElapsed >= dwTimeout) - ? 0 // wake up with WAIT_TIMEOUT - : dwTimeout-dwElapsed; - } - } - } while(dwWait == WAIT_OBJECT_0 + 1); - - // return TRUE if we woke on the event handle, - // FALSE if we timed out. - return (dwWait == WAIT_OBJECT_0); -} - -// --- CAMThread ---------------------- - - -CAMThread::CAMThread() - : m_EventSend(TRUE) // must be manual-reset for CheckRequest() -{ - m_hThread = NULL; -} - -CAMThread::~CAMThread() { - Close(); -} - - -// when the thread starts, it calls this function. We unwrap the 'this' -//pointer and call ThreadProc. -DWORD WINAPI -CAMThread::InitialThreadProc(LPVOID pv) { - HRESULT hrCoInit = CAMThread::CoInitializeHelper(); - if(FAILED(hrCoInit)) { - DbgLog((LOG_ERROR, 1, TEXT("CoInitializeEx failed."))); - } - - CAMThread * pThread = (CAMThread *) pv; - - HRESULT hr = pThread->ThreadProc(); - - if(SUCCEEDED(hrCoInit)) { - CoUninitialize(); - } - - return hr; -} - -BOOL -CAMThread::Create() { - DWORD threadid; - - CAutoLock lock(&m_AccessLock); - - if(ThreadExists()) { - return FALSE; - } - - m_hThread = CreateThread(NULL, - 0, - CAMThread::InitialThreadProc, - this, - 0, - &threadid); - - if(!m_hThread) { - return FALSE; - } - - return TRUE; -} - -DWORD -CAMThread::CallWorker(DWORD dwParam) { - // lock access to the worker thread for scope of this object - CAutoLock lock(&m_AccessLock); - - if(!ThreadExists()) { - return (DWORD) E_FAIL; - } - - // set the parameter - m_dwParam = dwParam; - - // signal the worker thread - m_EventSend.Set(); - - // wait for the completion to be signalled - m_EventComplete.Wait(); - - // done - this is the thread's return value - return m_dwReturnVal; -} - -// Wait for a request from the client -DWORD -CAMThread::GetRequest() { - m_EventSend.Wait(); - return m_dwParam; -} - -// is there a request? -BOOL -CAMThread::CheckRequest(DWORD * pParam) { - if(!m_EventSend.Check()) { - return FALSE; - } - else { - if(pParam) { - *pParam = m_dwParam; - } - return TRUE; - } -} - -// reply to the request -void -CAMThread::Reply(DWORD dw) { - m_dwReturnVal = dw; - - // The request is now complete so CheckRequest should fail from - // now on - // - // This event should be reset BEFORE we signal the client or - // the client may Set it before we reset it and we'll then - // reset it (!) - - m_EventSend.Reset(); - - // Tell the client we're finished - - m_EventComplete.Set(); -} - -HRESULT CAMThread::CoInitializeHelper() { - // call CoInitializeEx and tell OLE not to create a window (this - // thread probably won't dispatch messages and will hang on - // broadcast msgs o/w). - // - // If CoInitEx is not available, threads that don't call CoCreate - // aren't affected. Threads that do will have to handle the - // failure. Perhaps we should fall back to CoInitialize and risk - // hanging? - // - - // older versions of ole32.dll don't have CoInitializeEx - - HRESULT hr = E_FAIL; - HINSTANCE hOle = GetModuleHandle(TEXT("ole32.dll")); - if(hOle) { - typedef HRESULT(STDAPICALLTYPE *PCoInitializeEx)( - LPVOID pvReserved, DWORD dwCoInit); - PCoInitializeEx pCoInitializeEx = - (PCoInitializeEx)(GetProcAddress(hOle, "CoInitializeEx")); - if(pCoInitializeEx) { - hr = (*pCoInitializeEx)(0, 0x4 ); /*NABIL: Changed this to the constant, rather than the Variable...*/ - } - } - else { - // caller must load ole32.dll - DbgBreak("couldn't locate ole32.dll"); - } - - return hr; -} - - -// destructor for CMsgThread - cleans up any messages left in the -// queue when the thread exited -CMsgThread::~CMsgThread() { - if(m_hThread != NULL) { - WaitForSingleObject(m_hThread, INFINITE); - EXECUTE_ASSERT(CloseHandle(m_hThread)); - } - - POSITION pos = m_ThreadQueue.GetHeadPosition(); - while(pos) { - CMsg * pMsg = m_ThreadQueue.GetNext(pos); - delete pMsg; - } - m_ThreadQueue.RemoveAll(); - - if(m_hSem != NULL) { - EXECUTE_ASSERT(CloseHandle(m_hSem)); - } -} - -BOOL -CMsgThread::CreateThread( - ) { - m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL); - if(m_hSem == NULL) { - return FALSE; - } - - m_hThread = ::CreateThread(NULL, 0, DefaultThreadProc, - (LPVOID)this, 0, &m_ThreadId); - return m_hThread != NULL; -} - - -// This is the threads message pump. Here we get and dispatch messages to -// clients thread proc until the client refuses to process a message. -// The client returns a non-zero value to stop the message pump, this -// value becomes the threads exit code. - -DWORD WINAPI -CMsgThread::DefaultThreadProc( - LPVOID lpParam - ) { - CMsgThread *lpThis = (CMsgThread *)lpParam; - CMsg msg; - LRESULT lResult; - - // !!! - CoInitialize(NULL); - - // allow a derived class to handle thread startup - lpThis->OnThreadInit(); - - do { - lpThis->GetThreadMsg(&msg); - lResult = lpThis->ThreadMessageProc(msg.uMsg,msg.dwFlags, - msg.lpParam, msg.pEvent); - } while(lResult == 0L); - - // !!! - CoUninitialize(); - - return (DWORD)lResult; -} - - -// Block until the next message is placed on the list m_ThreadQueue. -// copies the message to the message pointed to by *pmsg -void -CMsgThread::GetThreadMsg(CMsg *msg) { - CMsg * pmsg = NULL; - - // keep trying until a message appears - while(TRUE) { { - CAutoLock lck(&m_Lock); - pmsg = m_ThreadQueue.RemoveHead(); - if(pmsg == NULL) { - m_lWaiting++; - } - else { - break; - } - } - // the semaphore will be signalled when it is non-empty - WaitForSingleObject(m_hSem, INFINITE); - } - // copy fields to caller's CMsg - *msg = *pmsg; - - // this CMsg was allocated by the 'new' in PutThreadMsg - delete pmsg; - -} - - -// NOTE: as we need to use the same binaries on Win95 as on NT this code should -// be compiled WITHOUT unicode being defined. Otherwise we will not pick up -// these internal routines and the binary will not run on Win95. - -#ifndef UNICODE - -#pragma warning(disable:4706) // C4706: assignment within conditional expression - -// Windows 95 doesn't implement this, so we provide an implementation. -LPWSTR -WINAPI -lstrcpyWInternal( - LPWSTR lpString1, - LPCWSTR lpString2 - ) { - LPWSTR lpReturn = lpString1; - while(*lpString1++ = *lpString2++); - - return lpReturn; -} - -// Windows 95 doesn't implement this, so we provide an implementation. -LPWSTR -WINAPI -lstrcpynWInternal( - LPWSTR lpString1, - LPCWSTR lpString2, - int iMaxLength - ) { - ASSERT(iMaxLength); - LPWSTR lpReturn = lpString1; - if(iMaxLength) { - while(--iMaxLength && (*lpString1++ = *lpString2++)); - - // If we ran out of room (which will be the case if - // iMaxLength is now 0) we still need to terminate the - // string. - if(!iMaxLength) *lpString1 = L'\0'; - } - return lpReturn; -} - -#pragma warning(default:4706) // C4706: assignment within conditional expression - -int -WINAPI -lstrcmpWInternal( - LPCWSTR lpString1, - LPCWSTR lpString2 - ) { - do { - WCHAR c1 = *lpString1; - WCHAR c2 = *lpString2; - if(c1 != c2) - return (int) c1 - (int) c2; - } while(*lpString1++ && *lpString2++); - return 0; -} - - -int -WINAPI -lstrcmpiWInternal( - LPCWSTR lpString1, - LPCWSTR lpString2 - ) { - do { - WCHAR c1 = *lpString1; - WCHAR c2 = *lpString2; - if(c1 >= L'A' && c1 <= L'Z') - c1 -= (WCHAR) (L'A' - L'a'); - if(c2 >= L'A' && c2 <= L'Z') - c2 -= (WCHAR) (L'A' - L'a'); - - if(c1 != c2) - return (int) c1 - (int) c2; - } while(*lpString1++ && *lpString2++); - - return 0; -} - - -int -WINAPI -lstrlenWInternal( - LPCWSTR lpString - ) { - int i = -1; - while(*(lpString+(++i))) - ; - return i; -} - - -int WINAPIV wsprintfWInternal(LPWSTR wszOut, LPCWSTR pszFmt, ...) { - char fmt[256]; // !!! - char ach[256]; // !!! - int i; - - va_list va; - va_start(va, pszFmt); - WideCharToMultiByte(GetACP(), 0, pszFmt, -1, fmt, 256, NULL, NULL); - i = wvsprintfA(ach, fmt, va); - va_end(va); - - MultiByteToWideChar(CP_ACP, 0, ach, -1, wszOut, i+1); - - return i; -} -#else - -// need to provide the implementations in unicode for non-unicode -// builds linking with the unicode strmbase.lib -LPWSTR WINAPI lstrcpyWInternal( - LPWSTR lpString1, - LPCWSTR lpString2 - ) { - return lstrcpyW(lpString1, lpString2); -} - -LPWSTR WINAPI lstrcpynWInternal( - LPWSTR lpString1, - LPCWSTR lpString2, - int iMaxLength - ) { - return lstrcpynW(lpString1, lpString2, iMaxLength); -} - -int WINAPI lstrcmpWInternal( - LPCWSTR lpString1, - LPCWSTR lpString2 - ) { - return lstrcmpW(lpString1, lpString2); -} - - -int WINAPI lstrcmpiWInternal( - LPCWSTR lpString1, - LPCWSTR lpString2 - ) { - return lstrcmpiW(lpString1, lpString2); -} - - -int WINAPI lstrlenWInternal( - LPCWSTR lpString - ) { - return lstrlenW(lpString); -} - - -int WINAPIV wsprintfWInternal( - LPWSTR wszOut, LPCWSTR pszFmt, ...) { - va_list va; - va_start(va, pszFmt); - int i = wvsprintfW(wszOut, pszFmt, va); - va_end(va); - return i; -} -#endif - - -// Helper function - convert int to WSTR -void WINAPI IntToWstr(int i, LPWSTR wstr) { -#ifdef UNICODE - wsprintf(wstr, L"%d", i); -#else - TCHAR temp[32]; - wsprintf(temp, "%d", i); - MultiByteToWideChar(CP_ACP, 0, temp, -1, wstr, 32); -#endif -} // IntToWstr - - -#if 0 -void * memchrInternal(const void *pv, int c, size_t sz) { - BYTE *pb = (BYTE *) pv; - while(sz--) { - if(*pb == c) - return (void *) pb; - pb++; - } - return NULL; -} -#endif - - -#define MEMORY_ALIGNMENT 4 -#define MEMORY_ALIGNMENT_LOG2 2 -#define MEMORY_ALIGNMENT_MASK MEMORY_ALIGNMENT - 1 - -void * __stdcall memmoveInternal(void * dst, const void * src, size_t count) { - void * ret = dst; - -#ifdef _X86_ - if(dst <= src || (char *)dst >= ((char *)src + count)) { - - /* - * Non-Overlapping Buffers - * copy from lower addresses to higher addresses - */ - _asm { - mov esi,src - mov edi,dst - mov ecx,count - cld - mov edx,ecx - and edx,MEMORY_ALIGNMENT_MASK - shr ecx,MEMORY_ALIGNMENT_LOG2 - rep movsd - or ecx,edx - jz memmove_done - rep movsb - memmove_done: - } - } - else { - - /* - * Overlapping Buffers - * copy from higher addresses to lower addresses - */ - _asm { - mov esi,src - mov edi,dst - mov ecx,count - std - add esi,ecx - add edi,ecx - dec esi - dec edi - rep movsb - cld - } - } -#else - MoveMemory(dst, src, count); -#endif - - return ret; -} - -/* Arithmetic functions to help with time format conversions -*/ - -#ifdef _M_ALPHA -// work around bug in version 12.00.8385 of the alpha compiler where -// UInt32x32To64 sign-extends its arguments (?) -#undef UInt32x32To64 -#define UInt32x32To64(a, b) (((ULONGLONG)((ULONG)(a)) & 0xffffffff) * ((ULONGLONG)((ULONG)(b)) & 0xffffffff)) -#endif - -/* Compute (a * b + d) / c */ -LONGLONG WINAPI llMulDiv(LONGLONG a, LONGLONG b, LONGLONG c, LONGLONG d) { - /* Compute the absolute values to avoid signed arithmetic problems */ - ULARGE_INTEGER ua, ub; - DWORDLONG uc; - - ua.QuadPart = (DWORDLONG)(a >= 0 ? a : -a); - ub.QuadPart = (DWORDLONG)(b >= 0 ? b : -b); - uc = (DWORDLONG)(c >= 0 ? c : -c); - BOOL bSign = (a < 0) ^ (b < 0); - - /* Do long multiplication */ - ULARGE_INTEGER p[2]; - p[0].QuadPart = UInt32x32To64(ua.LowPart, ub.LowPart); - - /* This next computation cannot overflow into p[1].HighPart because - the max number we can compute here is: - - (2 ** 32 - 1) * (2 ** 32 - 1) + // ua.LowPart * ub.LowPart - (2 ** 32) * (2 ** 31) * (2 ** 32 - 1) * 2 // x.LowPart * y.HighPart * 2 - - == 2 ** 96 - 2 ** 64 + (2 ** 64 - 2 ** 33 + 1) - == 2 ** 96 - 2 ** 33 + 1 - < 2 ** 96 - */ - - ULARGE_INTEGER x; - x.QuadPart = UInt32x32To64(ua.LowPart, ub.HighPart) + - UInt32x32To64(ua.HighPart, ub.LowPart) + - p[0].HighPart; - p[0].HighPart = x.LowPart; - p[1].QuadPart = UInt32x32To64(ua.HighPart, ub.HighPart) + x.HighPart; - - if(d != 0) { - ULARGE_INTEGER ud[2]; - if(bSign) { - ud[0].QuadPart = (DWORDLONG)(-d); - if(d > 0) { - /* -d < 0 */ - ud[1].QuadPart = (DWORDLONG)(LONGLONG)-1; - } - else { - ud[1].QuadPart = (DWORDLONG)0; - } - } - else { - ud[0].QuadPart = (DWORDLONG)d; - if(d < 0) { - ud[1].QuadPart = (DWORDLONG)(LONGLONG)-1; - } - else { - ud[1].QuadPart = (DWORDLONG)0; - } - } - /* Now do extended addition */ - ULARGE_INTEGER uliTotal; - - /* Add ls DWORDs */ - uliTotal.QuadPart = (DWORDLONG)ud[0].LowPart + p[0].LowPart; - p[0].LowPart = uliTotal.LowPart; - - /* Propagate carry */ - uliTotal.LowPart = uliTotal.HighPart; - uliTotal.HighPart = 0; - - /* Add 2nd most ls DWORDs */ - uliTotal.QuadPart += (DWORDLONG)ud[0].HighPart + p[0].HighPart; - p[0].HighPart = uliTotal.LowPart; - - /* Propagate carry */ - uliTotal.LowPart = uliTotal.HighPart; - uliTotal.HighPart = 0; - - /* Add MS DWORDLONGs - no carry expected */ - p[1].QuadPart += ud[1].QuadPart + uliTotal.QuadPart; - - /* Now see if we got a sign change from the addition */ - if((LONG)p[1].HighPart < 0) { - bSign = !bSign; - - /* Negate the current value (ugh!) */ - p[0].QuadPart = ~p[0].QuadPart; - p[1].QuadPart = ~p[1].QuadPart; - p[0].QuadPart += 1; - p[1].QuadPart += (p[0].QuadPart == 0); - } - } - - /* Now for the division */ - if(c < 0) { - bSign = !bSign; - } - - - /* This will catch c == 0 and overflow */ - if(uc <= p[1].QuadPart) { - return bSign ? (LONGLONG)0x8000000000000000 : - (LONGLONG)0x7FFFFFFFFFFFFFFF; - } - - DWORDLONG ullResult; - - /* Do the division */ - /* If the dividend is a DWORD_LONG use the compiler */ - if(p[1].QuadPart == 0) { - ullResult = p[0].QuadPart / uc; - return bSign ? -(LONGLONG)ullResult : (LONGLONG)ullResult; - } - - /* If the divisor is a DWORD then its simpler */ - ULARGE_INTEGER ulic; - ulic.QuadPart = uc; - if(ulic.HighPart == 0) { - ULARGE_INTEGER uliDividend; - ULARGE_INTEGER uliResult; - DWORD dwDivisor = (DWORD)uc; - // ASSERT(p[1].HighPart == 0 && p[1].LowPart < dwDivisor); - uliDividend.HighPart = p[1].LowPart; - uliDividend.LowPart = p[0].HighPart; -#ifndef USE_LARGEINT - uliResult.HighPart = (DWORD)(uliDividend.QuadPart / dwDivisor); - p[0].HighPart = (DWORD)(uliDividend.QuadPart % dwDivisor); - uliResult.LowPart = 0; - uliResult.QuadPart = p[0].QuadPart / dwDivisor + uliResult.QuadPart; -#else - /* NOTE - this routine will take exceptions if - the result does not fit in a DWORD - */ - if(uliDividend.QuadPart >= (DWORDLONG)dwDivisor) { - uliResult.HighPart = EnlargedUnsignedDivide(uliDividend, - dwDivisor, - &p[0].HighPart); - } - else { - uliResult.HighPart = 0; - } - uliResult.LowPart = EnlargedUnsignedDivide(p[0], - dwDivisor, - NULL); -#endif - return bSign ? -(LONGLONG)uliResult.QuadPart : - (LONGLONG)uliResult.QuadPart; - } - - - ullResult = 0; - - /* OK - do long division */ - for(int i = 0; i < 64; i++) { - ullResult <<= 1; - - /* Shift 128 bit p left 1 */ - p[1].QuadPart <<= 1; - if((p[0].HighPart & 0x80000000) != 0) { - p[1].LowPart++; - } - p[0].QuadPart <<= 1; - - /* Compare */ - if(uc <= p[1].QuadPart) { - p[1].QuadPart -= uc; - ullResult += 1; - } - } - - return bSign ? - (LONGLONG)ullResult : (LONGLONG)ullResult; -} - -LONGLONG WINAPI Int64x32Div32(LONGLONG a, LONG b, LONG c, LONG d) { - ULARGE_INTEGER ua; - DWORD ub; - DWORD uc; - - /* Compute the absolute values to avoid signed arithmetic problems */ - ua.QuadPart = (DWORDLONG)(a >= 0 ? a : -a); - ub = (DWORD)(b >= 0 ? b : -b); - uc = (DWORD)(c >= 0 ? c : -c); - BOOL bSign = (a < 0) ^ (b < 0); - - /* Do long multiplication */ - ULARGE_INTEGER p0; - DWORD p1; - p0.QuadPart = UInt32x32To64(ua.LowPart, ub); - - if(ua.HighPart != 0) { - ULARGE_INTEGER x; - x.QuadPart = UInt32x32To64(ua.HighPart, ub) + p0.HighPart; - p0.HighPart = x.LowPart; - p1 = x.HighPart; - } - else { - p1 = 0; - } - - if(d != 0) { - ULARGE_INTEGER ud0; - DWORD ud1; - - if(bSign) { - // - // Cast d to LONGLONG first otherwise -0x80000000 sign extends - // incorrectly - // - ud0.QuadPart = (DWORDLONG)(-(LONGLONG)d); - if(d > 0) { - /* -d < 0 */ - ud1 = (DWORD)-1; - } - else { - ud1 = (DWORD)0; - } - } - else { - ud0.QuadPart = (DWORDLONG)d; - if(d < 0) { - ud1 = (DWORD)-1; - } - else { - ud1 = (DWORD)0; - } - } - /* Now do extended addition */ - ULARGE_INTEGER uliTotal; - - /* Add ls DWORDs */ - uliTotal.QuadPart = (DWORDLONG)ud0.LowPart + p0.LowPart; - p0.LowPart = uliTotal.LowPart; - - /* Propagate carry */ - uliTotal.LowPart = uliTotal.HighPart; - uliTotal.HighPart = 0; - - /* Add 2nd most ls DWORDs */ - uliTotal.QuadPart += (DWORDLONG)ud0.HighPart + p0.HighPart; - p0.HighPart = uliTotal.LowPart; - - /* Add MS DWORDLONGs - no carry expected */ - p1 += ud1 + uliTotal.HighPart; - - /* Now see if we got a sign change from the addition */ - if((LONG)p1 < 0) { - bSign = !bSign; - - /* Negate the current value (ugh!) */ - p0.QuadPart = ~p0.QuadPart; - p1 = ~p1; - p0.QuadPart += 1; - p1 += (p0.QuadPart == 0); - } - } - - /* Now for the division */ - if(c < 0) { - bSign = !bSign; - } - - - /* This will catch c == 0 and overflow */ - if(uc <= p1) { - return bSign ? (LONGLONG)0x8000000000000000 : - (LONGLONG)0x7FFFFFFFFFFFFFFF; - } - - /* Do the division */ - - /* If the divisor is a DWORD then its simpler */ - ULARGE_INTEGER uliDividend; - ULARGE_INTEGER uliResult; - DWORD dwDivisor = uc; - uliDividend.HighPart = p1; - uliDividend.LowPart = p0.HighPart; - /* NOTE - this routine will take exceptions if - the result does not fit in a DWORD - */ - if(uliDividend.QuadPart >= (DWORDLONG)dwDivisor) { - uliResult.HighPart = EnlargedUnsignedDivide(uliDividend, - dwDivisor, - &p0.HighPart); - } - else { - uliResult.HighPart = 0; - } - uliResult.LowPart = EnlargedUnsignedDivide(p0, - dwDivisor, - NULL); - return bSign ? -(LONGLONG)uliResult.QuadPart : - (LONGLONG)uliResult.QuadPart; -} - -#ifdef DEBUG -/******************************Public*Routine******************************\ -* Debug CCritSec helpers -* -* We provide debug versions of the Constructor, destructor, Lock and Unlock -* routines. The debug code tracks who owns each critical section by -* maintaining a depth count. -* -* History: -* -\**************************************************************************/ - -CCritSec::CCritSec() { - InitializeCriticalSection(&m_CritSec); - m_currentOwner = m_lockCount = 0; - m_fTrace = FALSE; -} - -CCritSec::~CCritSec() { - DeleteCriticalSection(&m_CritSec); -} - -void CCritSec::Lock() { - UINT tracelevel=3; - DWORD us = GetCurrentThreadId(); - DWORD currentOwner = m_currentOwner; - if(currentOwner && (currentOwner != us)) { - // already owned, but not by us - if(m_fTrace) { - DbgLog((LOG_LOCKING, 2, TEXT("Thread %d about to wait for lock %x owned by %d"), - GetCurrentThreadId(), &m_CritSec, currentOwner)); - tracelevel=2; - // if we saw the message about waiting for the critical - // section we ensure we see the message when we get the - // critical section - } - } - EnterCriticalSection(&m_CritSec); - if(0 == m_lockCount++) { - // we now own it for the first time. Set owner information - m_currentOwner = us; - - if(m_fTrace) { - DbgLog((LOG_LOCKING, tracelevel, TEXT("Thread %d now owns lock %x"), m_currentOwner, &m_CritSec)); - } - } -} - -void CCritSec::Unlock() { - if(0 == --m_lockCount) { - // about to be unowned - if(m_fTrace) { - DbgLog((LOG_LOCKING, 3, TEXT("Thread %d releasing lock %x"), m_currentOwner, &m_CritSec)); - } - - m_currentOwner = 0; - } - LeaveCriticalSection(&m_CritSec); -} - -void WINAPI DbgLockTrace(CCritSec * pcCrit, BOOL fTrace) { - pcCrit->m_fTrace = fTrace; -} - -BOOL WINAPI CritCheckIn(CCritSec * pcCrit) { - return (GetCurrentThreadId() == pcCrit->m_currentOwner); -} - -BOOL WINAPI CritCheckIn(const CCritSec * pcCrit) { - return (GetCurrentThreadId() == pcCrit->m_currentOwner); -} - -BOOL WINAPI CritCheckOut(CCritSec * pcCrit) { - return (GetCurrentThreadId() != pcCrit->m_currentOwner); -} - -BOOL WINAPI CritCheckOut(const CCritSec * pcCrit) { - return (GetCurrentThreadId() != pcCrit->m_currentOwner); -} -#endif - -/*NABIL: I un-commented this...*/ -STDAPI WriteBSTR(BSTR *pstrDest, LPCWSTR szSrc) { - *pstrDest = SysAllocString(szSrc); - if(!(*pstrDest)) return E_OUTOFMEMORY; - return NOERROR; -} -/*END un-comment*/ - -/* -STDAPI FreeBSTR(BSTR* pstr) { - if(*pstr == NULL) return S_FALSE; - SysFreeString(*pstr); - return NOERROR; -} -*/ - -// Return a wide string - allocating memory for it -// Returns: -// S_OK - no error -// E_POINTER - ppszReturn == NULL -// E_OUTOFMEMORY - can't allocate memory for returned string -STDAPI AMGetWideString(LPCWSTR psz, LPWSTR *ppszReturn) { - CheckPointer(ppszReturn, E_POINTER); - ValidateReadWritePtr(ppszReturn, sizeof(LPWSTR)); - DWORD nameLen = sizeof(WCHAR) * (lstrlenW(psz)+1); - *ppszReturn = (LPWSTR)CoTaskMemAlloc(nameLen); - if(*ppszReturn == NULL) { - return E_OUTOFMEMORY; - } - CopyMemory(*ppszReturn, psz, nameLen); - return NOERROR; -} - -// Waits for the HANDLE hObject. While waiting messages sent -// to windows on our thread by SendMessage will be processed. -// Using this function to do waits and mutual exclusion -// avoids some deadlocks in objects with windows. -// Return codes are the same as for WaitForSingleObject -DWORD WINAPI WaitDispatchingMessages( - HANDLE hObject, - DWORD dwWait, - HWND hwnd, - UINT uMsg, - HANDLE hEvent) { - BOOL bPeeked = FALSE; - DWORD dwResult; - DWORD dwStart=0; - DWORD dwThreadPriority=0; - - static UINT uMsgId = 0; - - HANDLE hObjects[2] = { hObject, hEvent }; - if(dwWait != INFINITE && dwWait != 0) { - dwStart = GetTickCount(); - } - for(; ;) { - DWORD nCount = NULL != hEvent ? 2 : 1; - - // Minimize the chance of actually dispatching any messages - // by seeing if we can lock immediately. - dwResult = WaitForMultipleObjects(nCount, hObjects, FALSE, 0); - if(dwResult < WAIT_OBJECT_0 + nCount) { - break; - } - - DWORD dwTimeOut = dwWait; - if(dwTimeOut > 10) { - dwTimeOut = 10; - } - dwResult = MsgWaitForMultipleObjects(nCount, - hObjects, - FALSE, - dwTimeOut, - hwnd == NULL ? QS_SENDMESSAGE : - QS_SENDMESSAGE + QS_POSTMESSAGE); - if(dwResult == WAIT_OBJECT_0 + nCount || - dwResult == WAIT_TIMEOUT && dwTimeOut != dwWait) { - MSG msg; - if(hwnd != NULL) { - while(PeekMessage(&msg, hwnd, uMsg, uMsg, PM_REMOVE)) { - DispatchMessage(&msg); - } - } - // Do this anyway - the previous peek doesn't flush out the - // messages - PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); - - if(dwWait != INFINITE && dwWait != 0) { - DWORD dwNow = GetTickCount(); - - // Working with differences handles wrap-around - DWORD dwDiff = dwNow - dwStart; - if(dwDiff > dwWait) { - dwWait = 0; - } - else { - dwWait -= dwDiff; - } - dwStart = dwNow; - } - if(!bPeeked) { - // Raise our priority to prevent our message queue - // building up - dwThreadPriority = GetThreadPriority(GetCurrentThread()); - if(dwThreadPriority < THREAD_PRIORITY_HIGHEST) { - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); - } - bPeeked = TRUE; - } - } - else { - break; - } - } - if(bPeeked) { - SetThreadPriority(GetCurrentThread(), dwThreadPriority); - if(HIWORD(GetQueueStatus(QS_POSTMESSAGE)) & QS_POSTMESSAGE) { - if(uMsgId == 0) { - uMsgId = RegisterWindowMessage(TEXT("AMUnblock")); - } - if(uMsgId != 0) { - MSG msg; - // Remove old ones - while(PeekMessage(&msg, (HWND)-1, uMsgId, uMsgId, PM_REMOVE)) { - } - } - PostThreadMessage(GetCurrentThreadId(), uMsgId, 0, 0); - } - } - return dwResult; -} - -HRESULT AmGetLastErrorToHResult() { - DWORD dwLastError = GetLastError(); - if(dwLastError != 0) { - return HRESULT_FROM_WIN32(dwLastError); - } - else { - return E_FAIL; - } -} - -IUnknown* QzAtlComPtrAssign(IUnknown** pp, IUnknown* lp) { - if(lp != NULL) - lp->AddRef(); - if(*pp) - (*pp)->Release(); - *pp = lp; - return lp; -} - -/****************************************************************************** - -CompatibleTimeSetEvent - - CompatibleTimeSetEvent() sets the TIME_KILL_SYNCHRONOUS flag before calling -timeSetEvent() if the current operating system supports it. TIME_KILL_SYNCHRONOUS -is supported on Windows XP and later operating systems. - -Parameters: -- The same parameters as timeSetEvent(). See timeSetEvent()'s documentation in -the Platform SDK for more information. - -Return Value: -- The same return value as timeSetEvent(). See timeSetEvent()'s documentation in -the Platform SDK for more information. - -******************************************************************************/ -MMRESULT CompatibleTimeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent ) { - // - // Building for Windows XP - // ----------------------- - // If you want to target Windows XP specifically to use its new features, - // you must set WINVER=0x501 in the sample project file. You must also - // install the Windows XP Platform SDK, however, to ensure that you have the - // latest header files. For example, this CompatibleTimeSetEvent() method - // uses the new TIME_KILL_SYNCHRONOUS flag only if (WINVER >= 0x501). This flag - // is conditionally defined in the Windows XP Platform SDK in mmsystem.h, - // but only if WINVER is also set to 0x501 when compiling. To prevent build - // issues, upgrade to the latest version of the Platform SDK. - // - -#if WINVER >= 0x0501 - { - static bool fCheckedVersion = false; - static bool fTimeKillSynchronousFlagAvailable = false; - - if(!fCheckedVersion) { - fTimeKillSynchronousFlagAvailable = TimeKillSynchronousFlagAvailable(); - fCheckedVersion = true; - } - - if(fTimeKillSynchronousFlagAvailable) { - fuEvent = fuEvent | TIME_KILL_SYNCHRONOUS; - } - } -#endif // WINVER >= 0x0501 - - return timeSetEvent(uDelay, uResolution, lpTimeProc, dwUser, fuEvent); -} - -bool TimeKillSynchronousFlagAvailable( void ) { - OSVERSIONINFO osverinfo; - - osverinfo.dwOSVersionInfoSize = sizeof(osverinfo); - - if(GetVersionEx(&osverinfo)) { - - // Windows XP's major version is 5 and its' minor version is 1. - // timeSetEvent() started supporting the TIME_KILL_SYNCHRONOUS flag - // in Windows XP. - if((osverinfo.dwMajorVersion > 5) || - ( (osverinfo.dwMajorVersion == 5) && (osverinfo.dwMinorVersion >= 1) )) { - return true; - } - } - - return false; -} - diff --git a/src/BaseClasses/wxutil.h b/src/BaseClasses/wxutil.h deleted file mode 100644 index 92941e87dd..0000000000 --- a/src/BaseClasses/wxutil.h +++ /dev/null @@ -1,533 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WXUtil.h -// -// Desc: DirectShow base classes - defines helper classes and functions for -// building multimedia filters. -// -// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __WXUTIL__ -#define __WXUTIL__ - -// eliminate spurious "statement has no effect" warnings. -#pragma warning(disable: 4705) - -// wrapper for whatever critical section we have -class CCritSec { - - // make copy constructor and assignment operator inaccessible - - CCritSec(const CCritSec &refCritSec); - CCritSec &operator=(const CCritSec &refCritSec); - - CRITICAL_SECTION m_CritSec; - -#ifdef DEBUG -public: - DWORD m_currentOwner; - DWORD m_lockCount; - BOOL m_fTrace; // Trace this one -public: - CCritSec(); - ~CCritSec(); - void Lock(); - void Unlock(); -#else - -public: - CCritSec() { - InitializeCriticalSection(&m_CritSec); - }; - - ~CCritSec() { - DeleteCriticalSection(&m_CritSec); - }; - - void Lock() { - EnterCriticalSection(&m_CritSec); - }; - - void Unlock() { - LeaveCriticalSection(&m_CritSec); - }; -#endif -}; - -// -// To make deadlocks easier to track it is useful to insert in the -// code an assertion that says whether we own a critical section or -// not. We make the routines that do the checking globals to avoid -// having different numbers of member functions in the debug and -// retail class implementations of CCritSec. In addition we provide -// a routine that allows usage of specific critical sections to be -// traced. This is NOT on by default - there are far too many. -// - -#ifdef DEBUG - BOOL WINAPI CritCheckIn(CCritSec * pcCrit); - BOOL WINAPI CritCheckIn(const CCritSec * pcCrit); - BOOL WINAPI CritCheckOut(CCritSec * pcCrit); - BOOL WINAPI CritCheckOut(const CCritSec * pcCrit); - void WINAPI DbgLockTrace(CCritSec * pcCrit, BOOL fTrace); -#else - #define CritCheckIn(x) TRUE - #define CritCheckOut(x) TRUE - #define DbgLockTrace(pc, fT) -#endif - - -// locks a critical section, and unlocks it automatically -// when the lock goes out of scope -class CAutoLock { - - // make copy constructor and assignment operator inaccessible - - CAutoLock(const CAutoLock &refAutoLock); - CAutoLock &operator=(const CAutoLock &refAutoLock); - -protected: - CCritSec * m_pLock; - -public: - CAutoLock(CCritSec * plock) - { - m_pLock = plock; - m_pLock->Lock(); - }; - - ~CAutoLock() { - m_pLock->Unlock(); - }; -}; - - - -// wrapper for event objects -class CAMEvent -{ - - // make copy constructor and assignment operator inaccessible - - CAMEvent(const CAMEvent &refEvent); - CAMEvent &operator=(const CAMEvent &refEvent); - -protected: - HANDLE m_hEvent; -public: - CAMEvent(BOOL fManualReset = FALSE); - ~CAMEvent(); - - // Cast to HANDLE - we don't support this as an lvalue - operator HANDLE () const { return m_hEvent; }; - - void Set() {EXECUTE_ASSERT(SetEvent(m_hEvent));}; - BOOL Wait(DWORD dwTimeout = INFINITE) { - return (WaitForSingleObject(m_hEvent, dwTimeout) == WAIT_OBJECT_0); - }; - void Reset() { ResetEvent(m_hEvent); }; - BOOL Check() { return Wait(0); }; -}; - - -// wrapper for event objects that do message processing -// This adds ONE method to the CAMEvent object to allow sent -// messages to be processed while waiting - -class CAMMsgEvent : public CAMEvent -{ - -public: - - // Allow SEND messages to be processed while waiting - BOOL WaitMsg(DWORD dwTimeout = INFINITE); -}; - -// old name supported for the time being -#define CTimeoutEvent CAMEvent - -// support for a worker thread - -// simple thread class supports creation of worker thread, synchronization -// and communication. Can be derived to simplify parameter passing -class AM_NOVTABLE CAMThread { - - // make copy constructor and assignment operator inaccessible - - CAMThread(const CAMThread &refThread); - CAMThread &operator=(const CAMThread &refThread); - - CAMEvent m_EventSend; - CAMEvent m_EventComplete; - - DWORD m_dwParam; - DWORD m_dwReturnVal; - -protected: - HANDLE m_hThread; - - // thread will run this function on startup - // must be supplied by derived class - virtual DWORD ThreadProc() = 0; - -public: - CAMThread(); - virtual ~CAMThread(); - - CCritSec m_AccessLock; // locks access by client threads - CCritSec m_WorkerLock; // locks access to shared objects - - // thread initially runs this. param is actually 'this'. function - // just gets this and calls ThreadProc - static DWORD WINAPI InitialThreadProc(LPVOID pv); - - // start thread running - error if already running - BOOL Create(); - - // signal the thread, and block for a response - // - DWORD CallWorker(DWORD); - - // accessor thread calls this when done with thread (having told thread - // to exit) - void Close() { - HANDLE hThread = (HANDLE)InterlockedExchangePointer(&m_hThread, 0); - if (hThread) { - WaitForSingleObject(hThread, INFINITE); - CloseHandle(hThread); - } - }; - - // ThreadExists - // Return TRUE if the thread exists. FALSE otherwise - BOOL ThreadExists(void) const - { - if (m_hThread == 0) { - return FALSE; - } else { - return TRUE; - } - } - - // wait for the next request - DWORD GetRequest(); - - // is there a request? - BOOL CheckRequest(DWORD * pParam); - - // reply to the request - void Reply(DWORD); - - // If you want to do WaitForMultipleObjects you'll need to include - // this handle in your wait list or you won't be responsive - HANDLE GetRequestHandle() const { return m_EventSend; }; - - // Find out what the request was - DWORD GetRequestParam() const { return m_dwParam; }; - - // call CoInitializeEx (COINIT_DISABLE_OLE1DDE) if - // available. S_FALSE means it's not available. - static HRESULT CoInitializeHelper(); -}; - - -// CQueue -// -// Implements a simple Queue ADT. The queue contains a finite number of -// objects, access to which is controlled by a semaphore. The semaphore -// is created with an initial count (N). Each time an object is added -// a call to WaitForSingleObject is made on the semaphore's handle. When -// this function returns a slot has been reserved in the queue for the new -// object. If no slots are available the function blocks until one becomes -// available. Each time an object is removed from the queue ReleaseSemaphore -// is called on the semaphore's handle, thus freeing a slot in the queue. -// If no objects are present in the queue the function blocks until an -// object has been added. - -#define DEFAULT_QUEUESIZE 2 - -template class CQueue { -private: - HANDLE hSemPut; // Semaphore controlling queue "putting" - HANDLE hSemGet; // Semaphore controlling queue "getting" - CRITICAL_SECTION CritSect; // Thread seriallization - int nMax; // Max objects allowed in queue - int iNextPut; // Array index of next "PutMsg" - int iNextGet; // Array index of next "GetMsg" - T *QueueObjects; // Array of objects (ptr's to void) - - void Initialize(int n) { - iNextPut = iNextGet = 0; - nMax = n; - InitializeCriticalSection(&CritSect); - hSemPut = CreateSemaphore(NULL, n, n, NULL); - hSemGet = CreateSemaphore(NULL, 0, n, NULL); - QueueObjects = new T[n]; - } - - -public: - CQueue(int n) { - Initialize(n); - } - - CQueue() { - Initialize(DEFAULT_QUEUESIZE); - } - - ~CQueue() { - delete [] QueueObjects; - DeleteCriticalSection(&CritSect); - CloseHandle(hSemPut); - CloseHandle(hSemGet); - } - - T GetQueueObject() { - int iSlot; - T Object; - LONG lPrevious; - - // Wait for someone to put something on our queue, returns straight - // away is there is already an object on the queue. - // - WaitForSingleObject(hSemGet, INFINITE); - - EnterCriticalSection(&CritSect); - iSlot = iNextGet++ % nMax; - Object = QueueObjects[iSlot]; - LeaveCriticalSection(&CritSect); - - // Release anyone waiting to put an object onto our queue as there - // is now space available in the queue. - // - ReleaseSemaphore(hSemPut, 1L, &lPrevious); - return Object; - } - - void PutQueueObject(T Object) { - int iSlot; - LONG lPrevious; - - // Wait for someone to get something from our queue, returns straight - // away is there is already an empty slot on the queue. - // - WaitForSingleObject(hSemPut, INFINITE); - - EnterCriticalSection(&CritSect); - iSlot = iNextPut++ % nMax; - QueueObjects[iSlot] = Object; - LeaveCriticalSection(&CritSect); - - // Release anyone waiting to remove an object from our queue as there - // is now an object available to be removed. - // - ReleaseSemaphore(hSemGet, 1L, &lPrevious); - } -}; - -// miscellaneous string conversion functions -// NOTE: as we need to use the same binaries on Win95 as on NT this code should -// be compiled WITHOUT unicode being defined. Otherwise we will not pick up -// these internal routines and the binary will not run on Win95. - -int WINAPIV wsprintfWInternal(LPWSTR, LPCWSTR, ...); - -LPWSTR -WINAPI -lstrcpyWInternal( - LPWSTR lpString1, - LPCWSTR lpString2 - ); -LPWSTR -WINAPI -lstrcpynWInternal( - LPWSTR lpString1, - LPCWSTR lpString2, - int iMaxLength - ); -int -WINAPI -lstrcmpWInternal( - LPCWSTR lpString1, - LPCWSTR lpString2 - ); -int -WINAPI -lstrcmpiWInternal( - LPCWSTR lpString1, - LPCWSTR lpString2 - ); -int -WINAPI -lstrlenWInternal( - LPCWSTR lpString - ); - -#ifndef UNICODE -#define wsprintfW wsprintfWInternal -#define lstrcpyW lstrcpyWInternal -#define lstrcpynW lstrcpynWInternal -#define lstrcmpW lstrcmpWInternal -#define lstrcmpiW lstrcmpiWInternal -#define lstrlenW lstrlenWInternal -#endif - -extern "C" -void * __stdcall memmoveInternal(void *, const void *, size_t); - -inline void * __cdecl memchrInternal(const void *buf, int chr, size_t cnt) -{ -#ifdef _X86_ - void *pRet = NULL; - - _asm { - cld // make sure we get the direction right - mov ecx, cnt // num of bytes to scan - mov edi, buf // pointer byte stream - mov eax, chr // byte to scan for - repne scasb // look for the byte in the byte stream - jnz exit_memchr // Z flag set if byte found - dec edi // scasb always increments edi even when it - // finds the required byte - mov pRet, edi -exit_memchr: - } - return pRet; - -#else - while ( cnt && (*(unsigned char *)buf != (unsigned char)chr) ) { - buf = (unsigned char *)buf + 1; - cnt--; - } - - return(cnt ? (void *)buf : NULL); -#endif -} - -void WINAPI IntToWstr(int i, LPWSTR wstr); - -#define WstrToInt(sz) _wtoi(sz) -#define atoiW(sz) _wtoi(sz) -#define atoiA(sz) atoi(sz) - -// These are available to help managing bitmap VIDEOINFOHEADER media structures - -extern const DWORD bits555[3]; -extern const DWORD bits565[3]; -extern const DWORD bits888[3]; - -// These help convert between VIDEOINFOHEADER and BITMAPINFO structures - -STDAPI_(const GUID) GetTrueColorType(const BITMAPINFOHEADER *pbmiHeader); -STDAPI_(const GUID) GetBitmapSubtype(const BITMAPINFOHEADER *pbmiHeader); -STDAPI_(WORD) GetBitCount(const GUID *pSubtype); - -// strmbase.lib implements this for compatibility with people who -// managed to link to this directly. we don't want to advertise it. -// -// STDAPI_(/* T */ CHAR *) GetSubtypeName(const GUID *pSubtype); - -STDAPI_(CHAR *) GetSubtypeNameA(const GUID *pSubtype); -STDAPI_(WCHAR *) GetSubtypeNameW(const GUID *pSubtype); - -#ifdef UNICODE -#define GetSubtypeName GetSubtypeNameW -#else -#define GetSubtypeName GetSubtypeNameA -#endif - -STDAPI_(LONG) GetBitmapFormatSize(const BITMAPINFOHEADER *pHeader); -STDAPI_(DWORD) GetBitmapSize(const BITMAPINFOHEADER *pHeader); -STDAPI_(BOOL) ContainsPalette(const VIDEOINFOHEADER *pVideoInfo); -STDAPI_(const RGBQUAD *) GetBitmapPalette(const VIDEOINFOHEADER *pVideoInfo); - - -// Compares two interfaces and returns TRUE if they are on the same object -BOOL WINAPI IsEqualObject(IUnknown *pFirst, IUnknown *pSecond); - -// This is for comparing pins -#define EqualPins(pPin1, pPin2) IsEqualObject(pPin1, pPin2) - - -// Arithmetic helper functions - -// Compute (a * b + rnd) / c -LONGLONG WINAPI llMulDiv(LONGLONG a, LONGLONG b, LONGLONG c, LONGLONG rnd); -LONGLONG WINAPI Int64x32Div32(LONGLONG a, LONG b, LONG c, LONG rnd); - - -// Avoids us dyna-linking to SysAllocString to copy BSTR strings -STDAPI WriteBSTR(BSTR * pstrDest, LPCWSTR szSrc); -STDAPI FreeBSTR(BSTR* pstr); - -// Return a wide string - allocating memory for it -// Returns: -// S_OK - no error -// E_POINTER - ppszReturn == NULL -// E_OUTOFMEMORY - can't allocate memory for returned string -STDAPI AMGetWideString(LPCWSTR pszString, LPWSTR *ppszReturn); - -// Special wait for objects owning windows -DWORD WINAPI WaitDispatchingMessages( - HANDLE hObject, - DWORD dwWait, - HWND hwnd = NULL, - UINT uMsg = 0, - HANDLE hEvent = NULL); - -// HRESULT_FROM_WIN32 converts ERROR_SUCCESS to a success code, but in -// our use of HRESULT_FROM_WIN32, it typically means a function failed -// to call SetLastError(), and we still want a failure code. -// -#define AmHresultFromWin32(x) (MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, x)) - -// call GetLastError and return an HRESULT value that will fail the -// SUCCEEDED() macro. -HRESULT AmGetLastErrorToHResult(void); - -// duplicate of ATL's CComPtr to avoid linker conflicts. - -IUnknown* QzAtlComPtrAssign(IUnknown** pp, IUnknown* lp); - -template -class QzCComPtr -{ -public: - typedef T _PtrClass; - QzCComPtr() {p=NULL;} - QzCComPtr(T* lp) - { - if ((p = lp) != NULL) - p->AddRef(); - } - QzCComPtr(const QzCComPtr& lp) - { - if ((p = lp.p) != NULL) - p->AddRef(); - } - ~QzCComPtr() {if (p) p->Release();} - void Release() {if (p) p->Release(); p=NULL;} - operator T*() {return (T*)p;} - T& operator*() {ASSERT(p!=NULL); return *p; } - //The assert on operator& usually indicates a bug. If this is really - //what is needed, however, take the address of the p member explicitly. - T** operator&() { ASSERT(p==NULL); return &p; } - T* operator->() { ASSERT(p!=NULL); return p; } - T* operator=(T* lp){return (T*)QzAtlComPtrAssign((IUnknown**)&p, lp);} - T* operator=(const QzCComPtr& lp) - { - return (T*)QzAtlComPtrAssign((IUnknown**)&p, lp.p); - } -#if _MSC_VER>1020 - bool operator!(){return (p == NULL);} -#else - BOOL operator!(){return (p == NULL) ? TRUE : FALSE;} -#endif - T* p; -}; - -MMRESULT CompatibleTimeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent ); -bool TimeKillSynchronousFlagAvailable( void ); - -#endif /* __WXUTIL__ */

BZ^7}^S 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ĞhdvBIj61}(&X(a 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