00001 #pragma once
00002
00014 #include "WinMediaBuffer.h"
00015
00016 #include <mmreg.h>
00017 #include <avrt.h>
00018 #include <MMSystem.h>
00019
00020
00021
00022 #pragma comment(lib, "avrt.lib")
00023 #pragma comment(lib, "winmm.lib")
00024
00025
00026
00027 namespace jbxwl {
00028
00029
00030 class CWinAudioStream : public IStream
00031 {
00032 public:
00033
00034 CWinAudioStream(IMediaObject *pObj);
00035 virtual ~CWinAudioStream(void);
00036
00037 BOOL startCapture(WAVEFORMATEX* format=NULL);
00038 void stopCapture (void);
00039 Buffer input(void);
00040
00041
00042 BOOL openOutput(ULONG bufcount=100, WAVEFORMATEX* format=NULL);
00043 void closeOutput(void);
00044 void output(Buffer buf);
00045
00046 private:
00047
00048 void freeOutputHeaders(void);
00049
00050 public:
00052
00053
00054 STDMETHODIMP_(ULONG) AddRef(void) { return InterlockedIncrement(&m_cRef);}
00055
00056 STDMETHODIMP_(ULONG) Release(void)
00057 {
00058 UINT ref = InterlockedDecrement(&m_cRef);
00059 if (ref==0) delete this;
00060 return ref;
00061 }
00062
00063 STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
00064 {
00065 if (riid==IID_IUnknown) {
00066 AddRef();
00067 *ppv = (IUnknown*)this;
00068 return S_OK;
00069 }
00070 else if (riid==IID_IStream) {
00071 AddRef();
00072 *ppv = (IStream*)this;
00073 return S_OK;
00074 }
00075 else return E_NOINTERFACE;
00076 }
00077
00078 public:
00080
00081
00082 STDMETHODIMP Read(void*, ULONG, ULONG*);
00083 STDMETHODIMP Seek(LARGE_INTEGER, DWORD, ULARGE_INTEGER*);
00084 STDMETHODIMP Write(const void*, ULONG, ULONG*);
00085
00086
00087 STDMETHODIMP SetSize(ULARGE_INTEGER) { return E_NOTIMPL;}
00088 STDMETHODIMP CopyTo(IStream*, ULARGE_INTEGER, ULARGE_INTEGER*, ULARGE_INTEGER*) { return E_NOTIMPL;}
00089 STDMETHODIMP Commit(DWORD) { return E_NOTIMPL;}
00090 STDMETHODIMP Revert(void) { return E_NOTIMPL;}
00091 STDMETHODIMP LockRegion (ULARGE_INTEGER, ULARGE_INTEGER, DWORD) { return E_NOTIMPL;}
00092 STDMETHODIMP UnlockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD) { return E_NOTIMPL;}
00093 STDMETHODIMP Stat(STATSTG*, DWORD) { return E_NOTIMPL;}
00094 STDMETHODIMP Clone(IStream**) { return E_NOTIMPL;}
00095
00096 private:
00097 CRITICAL_SECTION m_lock;
00098
00099 UINT m_cRef;
00100 IMediaObject* m_pMediaObj;
00101
00102 private:
00103 static const UINT MaxReadBuffers = 20;
00104
00105 HANDLE m_hStopEvent;
00106 HANDLE m_hDataReady;
00107
00108 CWinThread* m_captureThread;
00109
00110 MediaBufferStack m_bufferStack;
00111 MediaBufferQueue m_bufferQueue;
00112
00113 CWinMediaBuffer* m_writeBuffer;
00114 CWinMediaBuffer* m_readBuffer;
00115
00116 ULONG m_readBufferSize;
00117 ULONG m_readBufferCount;
00118 ULONG m_readBufferIndex;
00119
00120 private:
00121 static const UINT MaxOutputBuffers = 2*1024*1024;
00122
00123 HWAVEOUT m_hWave;
00124 WAVEHDR* m_waveHeaders;
00125
00126 ULONG m_outputBufferNum;
00127 ULONG m_outputBufferIndex;
00128
00129 Buffer m_streamData;
00130
00131 private:
00132 CWinMediaBuffer* GetWriteBuffer(void);
00133 void Back2BufferStack(CWinMediaBuffer* pMediaBuf);
00134 void Back2BufferStackAll(void);
00135
00136 void QueueCapturedData(BYTE* pData, UINT cbData);
00137 void QueueCapturedBuffer(CWinMediaBuffer* pMediaBuf);
00138
00139 void ReadOneBuffer(BYTE** ppbData, ULONG* pcbData);
00140
00141 static UINT CaptureThread(LPVOID pParam);
00142 UINT CaptureThread(void);
00143
00144
00145 BOOL IsCapturing(void)
00146 {
00147 return (m_hStopEvent!=NULL) && (WaitForSingleObject(m_hStopEvent,0)!=WAIT_OBJECT_0);
00148 }
00149 };
00150
00151
00152 }
00153
00154