/******************************************************************************** Copyright (C) 2012 Hugh Bailey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ********************************************************************************/ #pragma once #include void PackPlanar(LPBYTE convertBuffer, LPBYTE lpPlanar, UINT renderCX, UINT renderCY, UINT pitch, UINT startY, UINT endY, UINT linePitch, UINT lineShift); enum DeviceColorType { DeviceOutputType_RGB, //planar 4:2:0 DeviceOutputType_I420, DeviceOutputType_YV12, //packed 4:2:2 DeviceOutputType_YVYU, DeviceOutputType_YUY2, DeviceOutputType_UYVY, DeviceOutputType_HDYC, }; struct SampleData { //IMediaSample *sample; LPBYTE lpData; long dataLength; int cx, cy; bool bAudio; LONGLONG timestamp; volatile long refs; inline SampleData() {refs = 1;} inline ~SampleData() {Free(lpData);} //sample->Release();} inline void AddRef() {++refs;} inline void Release() { if(!InterlockedDecrement(&refs)) delete this; } }; struct ConvertData { LPBYTE input, output; SampleData *sample; HANDLE hSignalConvert, hSignalComplete; bool bKillThread; UINT width, height; UINT pitch; UINT startY, endY; UINT linePitch, lineShift; }; class DeviceSource; class DeviceAudioSource : public AudioSource { DeviceSource *device; UINT sampleSegmentSize, sampleFrameCount; HANDLE hAudioMutex; List sampleBuffer; List outputBuffer; int offset; protected: virtual bool GetNextBuffer(void **buffer, UINT *numFrames, QWORD *timestamp); virtual void ReleaseBuffer(); virtual CTSTR GetDeviceName() const; public: bool Initialize(DeviceSource *parent); ~DeviceAudioSource(); void ReceiveAudio(LPBYTE lpData, UINT dataLength); void FlushSamples(); inline void SetAudioOffset(int offset) {this->offset = offset; SetTimeOffset(offset);} }; class DeviceSource : public ImageSource { friend class DeviceAudioSource; friend class CapturePin; IGraphBuilder *graph; ICaptureGraphBuilder2 *capture; IMediaControl *control; IBaseFilter *deviceFilter; IBaseFilter *audioDeviceFilter; CaptureFilter *captureFilter; IBaseFilter *audioFilter; // Audio renderer filter //--------------------------------- WAVEFORMATEX audioFormat; DeviceAudioSource *audioOut; bool bRequestVolume; float fNewVol; UINT enteredSceneCount; //--------------------------------- DeviceColorType colorType; String strDevice, strDeviceName, strDeviceID; String strAudioDevice, strAudioName, strAudioID; bool bFlipVertical, bFlipHorizontal, bDeviceHasAudio, bUsePointFiltering, bUseAudioRender; UINT64 frameInterval; UINT renderCX, renderCY; UINT newCX, newCY; UINT lastSampleCX, lastSampleCY; UINT imageCX, imageCY; UINT linePitch, lineShift, lineSize; BOOL bUseCustomResolution; UINT preferredOutputType; BOOL fullRange; int colorSpace; BOOL use709; struct { int type; //DeinterlacingType char fieldOrder; //DeinterlacingFieldOrder char processor; //DeinterlacingProcessor bool curField, bNewFrame; bool doublesFramerate; bool needsPreviousFrame; bool isReady; std::unique_ptr texture; UINT imageCX, imageCY; std::unique_ptr vertexShader; FuturePixelShader pixelShader; } deinterlacer; bool bFirstFrame; bool bUseThreadedConversion; bool bReadyToDraw; int soundOutputType; bool bOutputAudioToDesktop; Texture *texture, *previousTexture; XElement *data; UINT texturePitch; bool bCapturing, bFiltersLoaded; Shader *colorConvertShader; Shader *drawShader; bool bUseBuffering; HANDLE hStopSampleEvent; HANDLE hSampleMutex; HANDLE hSampleThread; UINT bufferTime; // 100-nsec units (same as REFERENCE_TIME) SampleData *latestVideoSample; List samples; UINT opacity; int gamma; //--------------------------------- LPBYTE lpImageBuffer; ConvertData *convertData; HANDLE *hConvertThreads; //--------------------------------- bool bUseChromaKey; DWORD keyColor; Color4 keyChroma; Color4 keyBaseColor; int keySimilarity; int keyBlend; int keySpillReduction; //--------------------------------- void ChangeSize(bool bSucceeded = true, bool bForce = false); void KillThreads(); String ChooseShader(); String ChooseDeinterlacingShader(); void Convert422To444(LPBYTE convertBuffer, LPBYTE lp422, UINT pitch, bool bLeadingY); void FlushSamples() { OSEnterMutex(hSampleMutex); for (UINT i=0; i