TVStreamSink.cpp
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:11k
源码类别:

P2P编程

开发平台:

Visual C++

  1. /*
  2. *  Openmysee
  3. *
  4. *  This program is free software; you can redistribute it and/or modify
  5. *  it under the terms of the GNU General Public License as published by
  6. *  the Free Software Foundation; either version 2 of the License, or
  7. *  (at your option) any later version.
  8. *
  9. *  This program is distributed in the hope that it will be useful,
  10. *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. *  GNU General Public License for more details.
  13. *
  14. *  You should have received a copy of the GNU General Public License
  15. *  along with this program; if not, write to the Free Software
  16. *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17. *
  18. */
  19. #include "stdafx.h"
  20. #include "uuids.h"
  21. #include "TVstreamsink.h"
  22. #include "TVstreamsinkpins.h"
  23. #include "CaptureServer.h"
  24. // filter info
  25. const AMOVIESETUP_MEDIATYPE sudPinTypes =
  26. {
  27.     &MEDIATYPE_NULL,            // Major type
  28.     &MEDIASUBTYPE_NULL          // Minor type
  29. };
  30. const AMOVIESETUP_PIN sudPins =
  31. {
  32.     L"Input",                   // Pin string name
  33.     FALSE,                      // Is it rendered
  34.     FALSE,                      // Is it an output
  35.     FALSE,                      // Allowed none
  36.     FALSE,                      // Likewise many
  37.     &CLSID_NULL,                // Connects to filter
  38.     NULL,                       // Connects to pin
  39.     1,                          // Number of types
  40.     &sudPinTypes                // Pin information
  41. };
  42. const AMOVIESETUP_FILTER sudTVStreamSink =
  43. {
  44.     &CLSID_TVStreamSink,       // clsID
  45.     L"TV Stream Sink(fix mms)",// strName
  46.     MERIT_DO_NOT_USE,          // dwMerit
  47.     1,                         // nPins
  48.     &sudPins                   // lpPin
  49. };
  50. // class factory info
  51. CFactoryTemplate g_Templates[]= 
  52. {
  53.     {L"TV Stream Sink(fix mms)", &CLSID_TVStreamSink, CTVStreamSink::CreateInstance, NULL, &sudTVStreamSink},
  54. };
  55. int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
  56. //////////////////////////////////////////////////////////////////////////////
  57. /////////
  58. CCritSec CTVStreamSink::m_Lock;
  59. CTVStreamSink::CTVStreamSink(LPUNKNOWN pUnk, CCritSec *pLock, HRESULT *phr) : 
  60. CBaseFilter(NAME("TVStreamSink filter"), pUnk, pLock, CLSID_TVStreamSink), 
  61. m_pFileName(0), m_pVideoPin(0), m_pAudioPin(0) {
  62. if(!cs.Init()) {
  63. *phr = E_OUTOFMEMORY;
  64. return;
  65. }
  66. m_pVideoPin = new CTVStreamSinkInputPin(this,
  67.    &m_Lock,
  68.    phr,
  69.    L"Video", 
  70.    FALSE);
  71.     if (m_pVideoPin == NULL) 
  72. {
  73.         *phr = E_OUTOFMEMORY;
  74.         return;
  75.     }
  76. m_pAudioPin = new CTVStreamSinkInputPin(this,
  77.    &m_Lock,
  78.    phr,
  79.    L"Audio", 
  80.    TRUE);
  81.     if (m_pAudioPin == NULL) 
  82. {
  83.         *phr = E_OUTOFMEMORY;
  84.         return;
  85.     }
  86. m_iIsStop = 0;
  87. m_iState = 1;//0为运行,1为停止。-1为发生意外错误停止
  88. TRACE1("CTVStreamSink::CTVStreamSink因为bytethesamecounter非正常退出n");
  89. *phr = S_OK;
  90. }
  91. CTVStreamSink::~CTVStreamSink()
  92. {
  93. m_iIsStop = 0;
  94. SAFE_ARRAYDELETE(m_pFileName);
  95.     SAFE_DELETE(m_pVideoPin);
  96. SAFE_DELETE(m_pAudioPin);
  97. }
  98. CUnknown * WINAPI CTVStreamSink::CreateInstance(LPUNKNOWN pUnk, HRESULT * phr)
  99. {   
  100. CTVStreamSink* pSink = new CTVStreamSink(pUnk, &m_Lock, phr);
  101. if(pSink == NULL)
  102. *phr = E_OUTOFMEMORY;
  103. pSink->CreateDebugInfo();
  104. //TraceLog1("beginn");
  105. return pSink;
  106. }
  107. int CTVStreamSink::GetPinCount()
  108. {
  109. return 2;
  110. }
  111. CBasePin* CTVStreamSink::GetPin(int n)
  112. {
  113. if(n == 0) // sink only support one input pin
  114.         return m_pVideoPin;
  115. else if(n == 1)
  116. return m_pAudioPin;
  117. else
  118.         return NULL;
  119. }
  120. STDMETHODIMP CTVStreamSink::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
  121. {
  122. CheckPointer(ppv,E_POINTER);
  123.     CAutoLock lock(&m_Lock);
  124.     // Do we have this interface
  125.     if (riid == IID_IFileSinkFilter) 
  126.         return GetInterface((IFileSinkFilter *) this, ppv);
  127. else if(IID_ITVSouceConfig == riid)
  128. return GetInterface((ITVSourceConfig *) this, ppv);
  129. else
  130. return CBaseFilter::NonDelegatingQueryInterface(riid, ppv);
  131. }
  132. STDMETHODIMP CTVStreamSink::Run(REFERENCE_TIME tStart)
  133. {
  134. HRESULT hr;
  135. CAutoLock cObjectLock(m_pLock);
  136. CAutoLock lolock(&m_Lock);
  137. hr = CBaseFilter::Run(tStart);
  138. if(SUCCEEDED(hr))
  139. {
  140. m_iIsStop = 0;
  141. TRACE1("CTVStreamSink::Run开始运行n");
  142. m_iState = 0;//0为运行,1为停止。-1为发生意外错误停止
  143. BOOL ii = m_pVideoPin->IsConnected();
  144. ii = m_pAudioPin->IsConnected();
  145. if (FALSE == cs.m_bIsOnlyOnePin && (FALSE == m_pVideoPin->IsConnected() 
  146. ||FALSE == m_pAudioPin->IsConnected()))
  147. {
  148. //MessageBox(NULL, "很抱歉,配置错误,此时是您转化的是单音频","错误", MB_OK|MB_ICONSTOP);
  149. TraceLog1("很抱歉,配置错误,此时是您转化的是单音频");
  150. return E_FAIL;
  151. }
  152. }
  153.     return hr;
  154. }
  155. //创建调试信息日志
  156. bool CTVStreamSink::CreateDebugInfo()
  157. {
  158.     char strPath[255];
  159. char strLogFileName[255];
  160. //首先设置日志打印选项
  161. CDebugTrace::SetTraceLevel(6);
  162. CDebugTrace::SetTraceOptions(CDebugTrace::GetTraceOptions() 
  163. | CDebugTrace::Timestamp & ~CDebugTrace::LogLevel 
  164. & ~CDebugTrace::FileAndLine | CDebugTrace::AppendToFile
  165. & ~CDebugTrace::PrintToConsole);
  166. if (!GetModuleFileName(NULL,strPath, 255))
  167. {
  168. TRACE1("CMediaCenter::CreateDebugInfo:GetModuleFileName()函数返回失败!n");
  169. return false;
  170. }
  171. //从strPath中去掉文件名,从而取得可执行文件的路径;
  172. int nPosition = 0;
  173. nPosition = (int)(strrchr(strPath,'\') - strPath);
  174. strPath[nPosition+1] = '';
  175. //生成日志目录
  176. strcat(strPath, "日志文件\");
  177. if(TRUE != CreateDirectory(strPath, NULL))
  178. {
  179. int i = GetLastError();
  180. if (ERROR_ACCESS_DENIED != i && ERROR_ALREADY_EXISTS != i)
  181. {
  182. MessageBox(NULL, "创建文件夹失败", "错误", MB_OK|MB_ICONSTOP);
  183. }
  184. }
  185. //生成TRACE文件名
  186. SYSTEMTIME loSystemTime;
  187. GetLocalTime(&loSystemTime);
  188. sprintf(strLogFileName, "%sGetZZLDisplay%4d%02d%02d%s", strPath,loSystemTime.wYear,
  189. loSystemTime.wMonth,loSystemTime.wDay,".log");
  190. //sprintf(strLogFileName, "%sUTMedia%4d%02d%02d%s", strPath,loSystemTime.wYear,
  191. // loSystemTime.wMonth,loSystemTime.wDay,".log");
  192. //strcat(strPath, "GetZZLDisplay.log");
  193. CDebugTrace::SetLogFileName(strLogFileName);
  194. return true;
  195. }
  196. STDMETHODIMP CTVStreamSink::Pause()
  197. {
  198. CAutoLock cObjectLock(m_pLock);
  199.     return CBaseFilter::Pause();
  200. }
  201. STDMETHODIMP CTVStreamSink::Stop()
  202. {
  203. CAutoLock cObjectLock(m_pLock);
  204. m_iState = -1;//0为运行,1为停止(全部文件转化完成为停止)。-1为发生意外错误停止(用户点击Stop为意外停止)
  205. //cs.Stop();
  206. TRACE5("CTVStreamSink::Stop非正常退出m_iState = -1n");
  207.     return CBaseFilter::Stop();
  208. }
  209. STDMETHODIMP CTVStreamSink::SetFileName(LPCOLESTR pszFileName,const AM_MEDIA_TYPE *pmt)
  210. {
  211. // Is this a valid filename supplied
  212.     CheckPointer(pszFileName,E_POINTER);
  213. if(wcslen(pszFileName) > MAX_PATH)
  214.         return ERROR_FILENAME_EXCED_RANGE;
  215.     // Take a copy of the filename
  216.     m_pFileName = new WCHAR[1+lstrlenW(pszFileName)];
  217.     if (m_pFileName == 0)
  218.         return E_OUTOFMEMORY;
  219.     wcscpy(m_pFileName,pszFileName);
  220. return S_OK;
  221. }
  222. STDMETHODIMP CTVStreamSink::GetCurFile(LPOLESTR * ppszFileName,AM_MEDIA_TYPE *pmt)
  223. {
  224. CheckPointer(ppszFileName, E_POINTER);
  225. *ppszFileName = NULL;
  226.     if (m_pFileName != NULL) 
  227.     {
  228.         *ppszFileName = (LPOLESTR)
  229.         QzTaskMemAlloc(sizeof(WCHAR) * (1+lstrlenW(m_pFileName)));
  230.         if (*ppszFileName != NULL) 
  231.         {
  232.             wcscpy(*ppszFileName, m_pFileName);
  233.         }
  234.     }
  235.     if(pmt) 
  236.     {
  237.         ZeroMemory(pmt, sizeof(*pmt));
  238.         pmt->majortype = MEDIATYPE_NULL;
  239.         pmt->subtype = MEDIASUBTYPE_NULL;
  240.     }
  241.     return S_OK;
  242. }
  243. HRESULT CTVStreamSink::WriteFormatTypeHeader(CMediaType *pmt, BOOL isAudio)
  244. {
  245.     CAutoLock lock(&m_Lock);
  246.     if(isAudio) {
  247.         if(pmt->formattype != FORMAT_WaveFormatEx) {
  248.             return E_FAIL;
  249.         }
  250.     }
  251.     else {
  252.         if(pmt->formattype != FORMAT_VideoInfo && pmt->formattype != FORMAT_MPEGVideo) {
  253.             return E_FAIL;
  254.         }
  255.     }
  256. //ISampleSize: 如果这个字段非零,表示这是每个sample的尺寸,
  257. //             如果是零,则表示sample的尺寸会改变。
  258.     //bFixdSizeSamples: 如果这个布尔类型的标记是TRUE,表示ISampleSize有效,
  259. //                  否则,你可以忽略ISampleSize。
  260. //bTemporalCompression: 如果这个布尔类型的标记是FALSE,表示所有帧都是关键帧。
  261. TVMEDIATYPESECTION tms;
  262. memset(&tms, 0, sizeof(tms));
  263. tms.majortype = pmt->majortype;
  264. tms.subtype = pmt->subtype;
  265. tms.formattype = pmt->formattype;
  266. tms.lSampleSize = pmt->lSampleSize;
  267. tms.bFixedSizeSamples = pmt->bFixedSizeSamples;
  268. tms.bTemporalCompression = pmt->bTemporalCompression;
  269. tms.bThisPinOnly = false;
  270. tms.cbFormat = pmt->cbFormat;
  271. /*
  272. if(isAudio) {
  273. DeleteFile("c:\audio.xxx");
  274. char temp[64];
  275. sprintf(temp, "cbFormat: %d. rn", pmt->cbFormat);
  276. HANDLE hFile = CreateFile("c:\audio.xxx", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  277. if(hFile == INVALID_HANDLE_VALUE) {
  278. MessageBox(0, "c:\audio.xxx", _T("无法写入GTV文件"), MB_OK|MB_ICONERROR);
  279. return VFW_E_CANNOT_RENDER;
  280. }
  281. DWORD TTT = 0;
  282. if(!WriteFile(hFile, temp, strlen(temp), &TTT, NULL) || TTT == 0) {
  283. MessageBox(0, "c:\audio.xxx", _T("无法写入GTV文件"), MB_OK|MB_ICONERROR);
  284. return VFW_E_CANNOT_RENDER;
  285. }
  286. TTT = 0;
  287. if(!WriteFile(hFile, pmt->pbFormat, pmt->cbFormat, &TTT, NULL) || TTT == 0) {
  288. MessageBox(0, "c:\audio.xxx", _T("无法写入GTV文件"), MB_OK|MB_ICONERROR);
  289. return VFW_E_CANNOT_RENDER;
  290. }
  291. CloseHandle(hFile);
  292. }
  293. */
  294. BOOL bRet = cs.SetFormatData(tms, pmt->pbFormat, isAudio);
  295. return (TRUE == bRet) ? S_OK : S_FALSE;
  296. }
  297. STDMETHODIMP_(float) CTVStreamSink::GetCompressedSpeed()
  298. {
  299. return cs.GetSpeedInKBPS();
  300. }
  301. STDMETHODIMP_(BOOL) CTVStreamSink::Login(int userID, char* pass) {
  302. if(!pass)
  303. return FALSE;
  304. cs.cfgData.userID = userID;
  305. cs.cfgData.password = pass;
  306. cs.cfgData.canLogin = TRUE;
  307. return TRUE;
  308. }
  309. STDMETHODIMP_(int) CTVStreamSink::CheckPassword()
  310. {
  311. return cs.passwordStatus;
  312. }
  313. STDMETHODIMP_(LONGLONG) CTVStreamSink::GetTotalBytes()
  314. {
  315.     return cs.GetTotalBytes();
  316. }
  317. STDMETHODIMP_(void) CTVStreamSink::SetAudioOrVideoOnly(BOOL isAudio)
  318. {
  319. cs.SetAudioOrVideoOnly(isAudio);
  320. }
  321. STDMETHODIMP_(void) CTVStreamSink::SetParentWindow(HWND handle)
  322. {
  323. cs.parentWindow = handle;
  324. }
  325. STDMETHODIMP_(void) CTVStreamSink::SetProgramStorePath(LPCTSTR path)
  326. {
  327. if(path)
  328. cs.cfgData.savePath = path;
  329. }
  330. STDMETHODIMP_(void) CTVStreamSink::SetChannelName(LPCTSTR astrChannelName)
  331. {
  332. if (astrChannelName)
  333. {
  334. cs.cfgData.chnlStr = astrChannelName;
  335. }
  336. }
  337. STDMETHODIMP_(void) CTVStreamSink::GetZZLState(int* apiState)
  338. {
  339.  *apiState = m_iState;
  340. }
  341. STDMETHODIMP_(bool) CTVStreamSink::EndOfStream()
  342. {
  343. return (cs.m_bIsOnlyOnePin? (m_iIsStop >= 1):(m_iIsStop >= 2));
  344. }