Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

568 lines
13 KiB

  1. #include "precomp.h"
  2. #define ZONE_AP ZONE_DP
  3. #define _GetState() (m_dwState & DP_MASK_STATE)
  4. #define _SetState(s) (m_dwState = (m_dwState & ~DP_MASK_STATE) | (s & DP_MASK_STATE))
  5. #define _GetPlatform() (m_dwState & DP_MASK_PLATFORM)
  6. #define _SetPlatform(s) (m_dwState = (m_dwState & ~DP_MASK_PLATFORM) | (s & DP_MASK_PLATFORM))
  7. int g_videoin_prepare = 0;
  8. int g_videoout_prepare = 0;
  9. ///////////////////////////////////////////////////////
  10. //
  11. // Public methods
  12. //
  13. HRESULT VideoPacket::Initialize ( MEDIAPACKETINIT * p )
  14. {
  15. HRESULT hr = DPR_SUCCESS;
  16. ULONG cbSizeDevData;
  17. ULONG cbSizeRawData;
  18. FX_ENTRY ("VdPckt::Init")
  19. m_pBS = NULL;
  20. if (p == NULL)
  21. {
  22. DEBUGMSG (ZONE_AP, ("%s: invalid parameter (null ptr)\r\n", _fx_));
  23. return DPR_INVALID_PARAMETER;
  24. }
  25. if (p->dwFlags & DP_FLAG_SEND) {
  26. cbSizeDevData = p->cbSizeDevData;
  27. cbSizeRawData = p->cbSizeRawData;
  28. if (IsSameMediaFormat(p->pStrmConvSrcFmt, p->pDevFmt))
  29. p->cbSizeRawData = 0;
  30. p->cbSizeDevData = 0;
  31. }
  32. hr = MediaPacket::Initialize( p);
  33. // LOOKLOOK RP - if DP_FLAG_SEND, then we've allocated a memory header for the dev buffer,
  34. // but haven't actually allocated memory for the buffer
  35. if (p->dwFlags & DP_FLAG_SEND) {
  36. m_pDevData->data = NULL;
  37. m_pDevData->length = cbSizeDevData;
  38. }
  39. if (hr != DPR_SUCCESS)
  40. goto MyExit;
  41. // allocate conversion header only if m_pWaveData != m_pNetData
  42. if (m_pRawData != m_pNetData)
  43. {
  44. if (m_dwState & DP_FLAG_VCM)
  45. {
  46. m_pStrmConvHdr = MemAlloc (sizeof (VCMSTREAMHEADER));
  47. if (m_pStrmConvHdr == NULL)
  48. {
  49. DEBUGMSG (ZONE_AP, ("%s: MemAlloc4 (%ld) failed\r\n",
  50. _fx_, (ULONG) sizeof (VCMSTREAMHEADER)));
  51. hr = DPR_OUT_OF_MEMORY;
  52. goto MyExit;
  53. }
  54. }
  55. else
  56. {
  57. DEBUGMSG (ZONE_AP, ("%s: invalid platform (vcm)\r\n", _fx_));
  58. hr = DPR_INVALID_PLATFORM;
  59. goto MyExit;
  60. }
  61. }
  62. else
  63. {
  64. m_pStrmConvHdr = NULL;
  65. }
  66. MakeSilence ();
  67. MyExit:
  68. if (hr != DPR_SUCCESS)
  69. {
  70. m_fInitialized = FALSE;
  71. Release();
  72. }
  73. return hr;
  74. }
  75. HRESULT VideoPacket::Play ( MMIODEST *pmmioDest, UINT uDataType )
  76. {
  77. return DPR_INVALID_HANDLE;
  78. }
  79. HRESULT VideoPacket::Record ( void )
  80. {
  81. FX_ENTRY ("VdPckt::Record")
  82. LOG((LOGMSG_VID_RECORD,m_index));
  83. if (_GetState () != MP_STATE_RESET)
  84. {
  85. DEBUGMSG (ZONE_AP, ("%s: out of seq, state=0x%lX\r\n", _fx_, m_dwState));
  86. return DPR_OUT_OF_SEQUENCE;
  87. }
  88. if (m_pBS && m_pDevData->data) {
  89. m_pBS->UnlockBits(NULL, m_pDevData->data);
  90. m_pBS->Release();
  91. m_pDevData->data = NULL;
  92. m_pBS = NULL;
  93. }
  94. _SetState (MP_STATE_RECORDING);
  95. return DPR_SUCCESS;
  96. }
  97. HRESULT VideoPacket::SetSurface (IBitmapSurface *pBS)
  98. {
  99. void* pBits;
  100. long pitch;
  101. FX_ENTRY ("VdPckt::SetSurface")
  102. if (pBS) {
  103. m_pBS = pBS;
  104. m_pBS->LockBits(NULL, 0, &pBits, &pitch);
  105. if (!pBits) {
  106. m_pBS->UnlockBits(NULL, pBits);
  107. return ERROR_IO_INCOMPLETE;
  108. }
  109. m_pBS->AddRef();
  110. m_pDevData->data = (UCHAR *)pBits;
  111. return DPR_SUCCESS;
  112. }
  113. return E_INVALIDARG;
  114. }
  115. HRESULT VideoPacket::Recycle ( void )
  116. {
  117. if (m_pBS && m_pDevData->data) {
  118. m_pBS->UnlockBits(NULL, m_pDevData->data);
  119. m_pBS->Release();
  120. m_pDevData->data = NULL;
  121. m_pBS = NULL;
  122. }
  123. return MediaPacket::Recycle();
  124. }
  125. BOOL VideoPacket::IsBufferDone ( void )
  126. {
  127. FX_ENTRY ("VdPckt::IsBufferDone")
  128. if (m_hDev)
  129. {
  130. if (m_dwState & DP_FLAG_VIDEO)
  131. {
  132. //LOOKLOOK RP - what does this need to do?
  133. #if 1
  134. return TRUE;
  135. #else
  136. ~~~ return (((VIDEOINOUTHDR *) m_pDevHdr)->dwFlags & WHDR_DONE);
  137. #endif
  138. }
  139. }
  140. return FALSE;
  141. }
  142. HRESULT VideoPacket::MakeSilence ( void )
  143. {
  144. // create white noise!!!
  145. FX_ENTRY ("VdPckt::MakeSilence")
  146. if (m_pDevFmt)
  147. {
  148. if (m_pDevData)
  149. {
  150. // Don't need to do anything, what's on screen should do it.
  151. CopyPreviousBuf ((VIDEOFORMATEX *) m_pDevFmt, (PBYTE) m_pDevData->data,
  152. (ULONG) m_pDevData->length);
  153. }
  154. }
  155. _SetState(MP_STATE_RESET);
  156. return DPR_SUCCESS;
  157. }
  158. HRESULT VideoPacket::GetSignalStrength ( PDWORD pdwMaxStrength )
  159. {
  160. FX_ENTRY ("VdPckt::GetSignalStrength")
  161. // For now send each and every frame.
  162. // But you should consider sending only the frames if they
  163. // are really different of the previously sent one.
  164. // This will save quite some bandwidth when there is no or
  165. // very little activity in the video frames.
  166. return DPR_NOT_YET_IMPLEMENTED;
  167. }
  168. HRESULT VideoPacket::Interpolate ( MediaPacket * pPrev, MediaPacket * pNext)
  169. {
  170. HRESULT hr = DPR_SUCCESS;
  171. DPHANDLE hPrevDev;
  172. NETBUF *pPrevDevData;
  173. PVOID pPrevDevHdr;
  174. VIDEOFORMATEX *pPrevpfDev;
  175. VIDEOFORMATEX *pNextpfDev;
  176. NETBUF *pNextDevData;
  177. PVOID pNextDevHdr;
  178. FX_ENTRY ("VdPckt::Interpolate")
  179. DEBUGMSG (ZONE_AP, ("%s: can't interpolate\r\n", _fx_));
  180. hr = DPR_INVALID_HANDLE;
  181. return hr;
  182. }
  183. HRESULT VideoPacket::Open ( UINT uType, DPHANDLE hdl )
  184. // called by RxStream or TxStream
  185. {
  186. HRESULT hr = DPR_SUCCESS;
  187. MMRESULT mmr;
  188. FX_ENTRY ("VdPckt::Open")
  189. switch (uType)
  190. {
  191. #ifdef PREP_HDR_PER_CONV
  192. case MP_TYPE_RECVSTRMCONV:
  193. m_hStrmConv = hdl;
  194. break;
  195. #endif
  196. case MP_TYPE_STREAMCONV:
  197. if ((m_hStrmConv = hdl) != NULL)
  198. {
  199. if (m_dwState & DP_FLAG_VCM)
  200. {
  201. // initialize the header
  202. ZeroMemory (m_pStrmConvHdr, sizeof (VCMSTREAMHEADER));
  203. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->cbStruct = sizeof (VCMSTREAMHEADER);
  204. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->fdwStatus = 0;
  205. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->dwUser = 0;
  206. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->dwSrcUser = 0;
  207. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->cbSrcLengthUsed = 0;
  208. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->dwDstUser = 0;
  209. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->cbDstLengthUsed = 0;
  210. if (m_pNetData && m_pRawData)
  211. {
  212. if (m_dwState & DP_FLAG_SEND)
  213. {
  214. if (m_pRawData->data) {
  215. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->pbSrc = m_pRawData->data;
  216. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->cbSrcLength = m_pRawData->length;
  217. }
  218. else {
  219. // don't have a static raw buffer, so let vcmStreamPrepareHeader
  220. // lock the net buffer twice
  221. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->pbSrc = m_pNetData->data;
  222. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->cbSrcLength = m_pNetData->length;
  223. }
  224. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->pbDst = m_pNetData->data;
  225. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->cbDstLength = m_pNetData->length;
  226. }
  227. else
  228. if (m_dwState & DP_FLAG_RECV)
  229. {
  230. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->pbSrc = m_pNetData->data;
  231. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->cbSrcLength = m_pNetData->length;
  232. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->pbDst = m_pRawData->data;
  233. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->cbDstLength = m_pRawData->length;
  234. }
  235. // prepare the header
  236. mmr = vcmStreamPrepareHeader ((HVCMSTREAM) m_hStrmConv,
  237. (VCMSTREAMHEADER *) m_pStrmConvHdr, 0);
  238. if (mmr != MMSYSERR_NOERROR)
  239. {
  240. DEBUGMSG (ZONE_AP, ("%s: vcmStreamPrepareHeader failed, mmr=%ld\r\n", _fx_, (ULONG) mmr));
  241. hr = DPR_CANT_PREPARE_HEADER;
  242. goto MyExit;
  243. }
  244. m_fStrmPrepared = TRUE;
  245. }
  246. else
  247. m_fStrmPrepared = FALSE;
  248. }
  249. else
  250. {
  251. hr = DPR_INVALID_PLATFORM;
  252. goto MyExit;
  253. }
  254. }
  255. break;
  256. case MP_TYPE_DEV:
  257. if ((m_hDev = hdl) != NULL)
  258. {
  259. if (m_dwState & DP_FLAG_VIDEO)
  260. {
  261. if (m_dwState & DP_FLAG_SEND)
  262. {
  263. g_videoin_prepare++;
  264. }
  265. else
  266. if (m_dwState & DP_FLAG_RECV)
  267. {
  268. g_videoout_prepare++;
  269. }
  270. else
  271. {
  272. hr = DPR_INVALID_PARAMETER;
  273. goto MyExit;
  274. }
  275. m_fDevPrepared = TRUE;
  276. }
  277. else
  278. {
  279. hr = DPR_INVALID_PLATFORM;
  280. goto MyExit;
  281. }
  282. }
  283. else
  284. {
  285. hr = DPR_INVALID_HANDLE;
  286. goto MyExit;
  287. }
  288. break;
  289. default:
  290. hr = DPR_INVALID_PARAMETER;
  291. goto MyExit;
  292. }
  293. MyExit:
  294. return hr;
  295. }
  296. HRESULT VideoPacket::Close ( UINT uType )
  297. // called by RxStream or TxStream
  298. {
  299. HRESULT hr = DPR_SUCCESS;
  300. MMRESULT mmr;
  301. FX_ENTRY ("VdPckt::Close")
  302. switch (uType)
  303. {
  304. case MP_TYPE_RECVSTRMCONV:
  305. case MP_TYPE_STREAMCONV:
  306. if (m_hStrmConv)
  307. {
  308. if (m_dwState & DP_FLAG_VCM)
  309. {
  310. if (m_fStrmPrepared)
  311. {
  312. // unprepare the header
  313. if ((m_dwState & DP_FLAG_SEND) && !m_pRawData->data)
  314. {
  315. // don't have a static raw buffer, so let vcmStreamUnprepareHeader
  316. // unlock the net buffer twice to unwind what Open did
  317. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->pbSrc = m_pNetData->data;
  318. ((VCMSTREAMHEADER *) m_pStrmConvHdr)->cbSrcLength = m_pNetData->length;
  319. }
  320. mmr = vcmStreamUnprepareHeader ((HVCMSTREAM) m_hStrmConv,
  321. (VCMSTREAMHEADER *) m_pStrmConvHdr, 0);
  322. m_fStrmPrepared = FALSE; // don't care about any error
  323. if (mmr != MMSYSERR_NOERROR)
  324. {
  325. DEBUGMSG (ZONE_AP, ("%s: vcmStreamUnprepareHeader failed, mmr=%ld\r\n", _fx_, (ULONG) mmr));
  326. hr = DPR_CANT_UNPREPARE_HEADER;
  327. goto MyExit;
  328. }
  329. }
  330. }
  331. if (uType == MP_TYPE_STREAMCONV) m_hStrmConv = NULL;
  332. }
  333. break;
  334. case MP_TYPE_DEV:
  335. if (m_hDev)
  336. {
  337. if (m_fDevPrepared)
  338. {
  339. if (m_dwState & DP_FLAG_SEND)
  340. {
  341. g_videoin_prepare--;
  342. }
  343. else
  344. if (m_dwState & DP_FLAG_RECV)
  345. {
  346. g_videoout_prepare--;
  347. }
  348. else
  349. {
  350. hr = DPR_INVALID_PARAMETER;
  351. goto MyExit;
  352. }
  353. m_fDevPrepared = FALSE; // don't care about any error
  354. }
  355. m_hDev = NULL;
  356. }
  357. else
  358. {
  359. hr = DPR_INVALID_HANDLE;
  360. goto MyExit;
  361. }
  362. break;
  363. default:
  364. hr = DPR_INVALID_PARAMETER;
  365. goto MyExit;
  366. }
  367. MyExit:
  368. return hr;
  369. }
  370. void VideoPacket::WriteToFile (MMIODEST *pmmioDest)
  371. {
  372. MMRESULT mmr;
  373. long dwDataLength;
  374. FX_ENTRY ("VdPckt::WriteToFile")
  375. #ifdef need_video_file_io
  376. // BUGBUG - this stuff doesn't work
  377. if (dwDataLength = (DWORD)(pmmioDest->dwDataLength + m_pDevData->length) > pmmioDest->dwMaxDataLength ? (DWORD)(pmmioDest->dwMaxDataLength - pmmioDest->dwDataLength) : m_pDevData->length)
  378. {
  379. if (mmioWrite(pmmioDest->hmmioDst, (char *) m_pDevData->data, dwDataLength) != (LONG)m_pDevData->length)
  380. mmr = MMSYSERR_ERROR;
  381. else
  382. pmmioDest->dwDataLength += dwDataLength;
  383. if ((mmr == MMSYSERR_ERROR) || (pmmioDest->dwDataLength == pmmioDest->dwMaxDataLength))
  384. {
  385. mmr = mmioAscend(pmmioDest->hmmioDst, &(pmmioDest->ckDst), 0);
  386. mmr = mmioAscend(pmmioDest->hmmioDst, &(pmmioDest->ckDstRIFF), 0);
  387. mmr = mmioClose(pmmioDest->hmmioDst, 0);
  388. pmmioDest->hmmioDst = NULL;
  389. }
  390. }
  391. #endif
  392. }
  393. void VideoPacket::ReadFromFile (MMIOSRC *pmmioSrc)
  394. {
  395. long lNumBytesRead;
  396. FX_ENTRY ("VdPckt::ReadFromFile")
  397. #ifdef need_video_file_io
  398. // BUGBUG - this stuff doesn't work
  399. if (((VIDEOINOUTHDR *) m_pDevHdr)->dwBytesUsed)
  400. {
  401. MyRead:
  402. if ((pmmioSrc->dwDataLength + ((VIDEOINOUTHDR *) m_pDevHdr)->dwBytesUsed) <= pmmioSrc->dwMaxDataLength)
  403. {
  404. lNumBytesRead = mmioRead(pmmioSrc->hmmioSrc, ((VIDEOINOUTHDR *) m_pDevHdr)->pData, ((VIDEOINOUTHDR *) m_pDevHdr)->dwBytesUsed);
  405. pmmioSrc->dwDataLength += lNumBytesRead;
  406. }
  407. else
  408. {
  409. lNumBytesRead = mmioRead(pmmioSrc->hmmioSrc, ((VIDEOINOUTHDR *) m_pDevHdr)->pData, pmmioSrc->dwMaxDataLength - pmmioSrc->dwDataLength);
  410. pmmioSrc->dwDataLength += lNumBytesRead;
  411. CopyPreviousBuf ((VIDEOFORMATEX *) m_pDevFmt, (PBYTE) ((VIDEOINOUTHDR *) m_pDevHdr)->pData + lNumBytesRead, ((VIDEOINOUTHDR *) m_pDevHdr)->dwBytesUsed - lNumBytesRead);
  412. pmmioSrc->dwDataLength = 0;
  413. lNumBytesRead = 0;
  414. }
  415. if (!lNumBytesRead)
  416. {
  417. if (pmmioSrc->fLoop && !pmmioSrc->fDisconnectAfterPlayback)
  418. {
  419. // Reset file pointer to beginning of data
  420. mmioAscend(pmmioSrc->hmmioSrc, &(pmmioSrc->ckSrc), 0);
  421. if (-1L == mmioSeek(pmmioSrc->hmmioSrc, pmmioSrc->ckSrcRIFF.dwDataOffset + sizeof(FOURCC), SEEK_SET))
  422. {
  423. DEBUGMSG (1, ("MediaControl::OpenSrcFile: Couldn't seek in file, mmr=%ld\r\n", (ULONG) 0L));
  424. goto MyMMIOErrorExit2;
  425. }
  426. pmmioSrc->ckSrc.ckid = mmioFOURCC('d', 'a', 't', 'a');
  427. if (mmioDescend(pmmioSrc->hmmioSrc, &(pmmioSrc->ckSrc), &(pmmioSrc->ckSrcRIFF), MMIO_FINDCHUNK))
  428. {
  429. DEBUGMSG (1, ("MediaControl::OpenSrcFile: Couldn't locate 'data' chunk, mmr=%ld\r\n", (ULONG) 0L));
  430. goto MyMMIOErrorExit2;
  431. }
  432. // At this point, the src file is sitting at the very
  433. // beginning of its data chunks--so we can read from the src file...
  434. goto MyRead;
  435. MyMMIOErrorExit2:
  436. mmioAscend(pmmioSrc->hmmioSrc, &(pmmioSrc->ckSrcRIFF), 0);
  437. mmioClose(pmmioSrc->hmmioSrc, 0);
  438. pmmioSrc->hmmioSrc = NULL;
  439. }
  440. else
  441. {
  442. mmioAscend(pmmioSrc->hmmioSrc, &(pmmioSrc->ckSrcRIFF), 0);
  443. mmioClose(pmmioSrc->hmmioSrc, 0);
  444. pmmioSrc->hmmioSrc = NULL;
  445. /* Dont want to disconnect the whole connection
  446. * TODO: investigate closing the channel
  447. if (pmmioSrc->fDisconnectAfterPlayback)
  448. pConnection->SetMode(CMT_Disconnect);
  449. */
  450. }
  451. }
  452. }
  453. #endif
  454. }
  455. BOOL VideoPacket::IsSameMediaFormat(PVOID fmt1,PVOID fmt2)
  456. {
  457. return IsSameFormat(fmt1,fmt2);
  458. }
  459. // returns length of uncompressed video data in buffer
  460. // NOTE: not used yet
  461. DWORD
  462. VideoPacket::GetDevDataSamples()
  463. {
  464. // samples == frames for video and we only deal with one frame per pkt for now.
  465. return 1;
  466. }