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.

1403 lines
37 KiB

  1. #include "precomp.h"
  2. #ifndef OLDSTUFF
  3. extern IRTP *g_pIRTP;
  4. #endif
  5. STDMETHODIMP ImpICommChan::StandbyInit(LPGUID lpMID, LPIH323PubCap pCapObject,
  6. IMediaChannel* pMediaStreamSend)
  7. {
  8. if((!lpMID) || (!pCapObject))
  9. return CHAN_E_INVALID_PARAM;
  10. m_MediaID = *lpMID;
  11. bIsSendDirection = TRUE;
  12. m_pMediaStream = pMediaStreamSend;
  13. m_pMediaStream->AddRef();
  14. // keeps a cap object ref
  15. pCapObject->AddRef();
  16. m_pCapObject = pCapObject;
  17. return hrSuccess;
  18. }
  19. STDMETHODIMP ImpICommChan::QueryInterface( REFIID iid, void ** ppvObject)
  20. {
  21. // this breaks the rules for the official COM QueryInterface because
  22. // the interfaces that are queried for are not necessarily real COM
  23. // interfaces. The reflexive property of QueryInterface would be broken in
  24. // that case.
  25. HRESULT hr = E_NOINTERFACE;
  26. if(!ppvObject)
  27. return hr;
  28. *ppvObject = 0;
  29. if(iid == IID_IUnknown)
  30. {
  31. *ppvObject = this;
  32. hr = hrSuccess;
  33. AddRef();
  34. }
  35. else if((iid == IID_ICommChannel))
  36. {
  37. *ppvObject = (ICommChannel *)this;
  38. hr = hrSuccess;
  39. AddRef();
  40. }
  41. else if((iid == IID_ICtrlCommChannel))
  42. {
  43. *ppvObject = (ICtrlCommChan *)this;
  44. hr = hrSuccess;
  45. AddRef();
  46. }
  47. else if((iid == IID_IStreamSignal))
  48. {
  49. *ppvObject = (IStreamSignal *)this;
  50. hr = hrSuccess;
  51. AddRef();
  52. }
  53. else if((iid == IID_IAppAudioCap ) && m_pCapObject)
  54. {
  55. hr = m_pCapObject->QueryInterface(iid, ppvObject);
  56. }
  57. else if((iid == IID_IAppVidCap ) && m_pCapObject)
  58. {
  59. hr = m_pCapObject->QueryInterface(iid, ppvObject);
  60. }
  61. else if((iid == IID_IDualPubCap) && m_pCapObject)
  62. {
  63. hr = m_pCapObject->QueryInterface(iid, ppvObject);
  64. }
  65. else if(iid == IID_IVideoRender)
  66. {
  67. hr=hrSuccess;
  68. if(!m_pMediaStream && m_pH323ConfAdvise)
  69. {
  70. hr = m_pH323ConfAdvise->GetMediaChannel(&m_MediaID,
  71. bIsSendDirection, &m_pMediaStream);
  72. }
  73. if(HR_SUCCEEDED(hr))
  74. {
  75. hr = m_pMediaStream->QueryInterface(iid, ppvObject);
  76. }
  77. }
  78. else if(iid == IID_IVideoChannel)
  79. {
  80. hr=hrSuccess;
  81. if(!m_pMediaStream && m_pH323ConfAdvise)
  82. {
  83. hr = m_pH323ConfAdvise->GetMediaChannel(&m_MediaID,
  84. bIsSendDirection, &m_pMediaStream);
  85. }
  86. if(HR_SUCCEEDED(hr))
  87. {
  88. hr = m_pMediaStream->QueryInterface(iid, ppvObject);
  89. }
  90. }
  91. return (hr);
  92. }
  93. ULONG ImpICommChan::AddRef()
  94. {
  95. m_uRef++;
  96. DEBUGMSG(ZONE_REFCOUNT,("ImpICommChan::AddRef:(0x%08lX)->AddRef() m_uRef = 0x%08lX\r\n",this, m_uRef ));
  97. return m_uRef;
  98. }
  99. ULONG ImpICommChan::Release()
  100. {
  101. m_uRef--;
  102. if(m_uRef == 0)
  103. {
  104. DEBUGMSG(ZONE_REFCOUNT,("ImpICommChan::Release:(0x%08lX)->Releasing\r\n", this));
  105. delete this;
  106. return 0;
  107. }
  108. else
  109. {
  110. DEBUGMSG(ZONE_REFCOUNT,("ImpICommChan::Release:(0x%08lX)->Release() m_uRef = 0x%08lX\r\n",this, m_uRef ));
  111. return m_uRef;
  112. }
  113. }
  114. HRESULT ImpICommChan::GetMediaType(LPGUID pGuid)
  115. {
  116. if(!pGuid)
  117. return CHAN_E_INVALID_PARAM;
  118. *pGuid = m_MediaID;
  119. return hrSuccess;
  120. }
  121. HRESULT ImpICommChan::IsChannelOpen(BOOL *pbOpen)
  122. {
  123. if(!pbOpen)
  124. return CHAN_E_INVALID_PARAM;
  125. *pbOpen = (IsComchOpen()) ? TRUE:FALSE;
  126. return hrSuccess;
  127. }
  128. STDMETHODIMP ImpICommChan::GetProperty(DWORD prop, PVOID pBuf, LPUINT pcbBuf)
  129. {
  130. #define CHECKSIZE(type) if(*pcbBuf != sizeof(type)) return CHAN_E_INVALID_PARAM;
  131. #define OUTPROP(type) *(type *)pBuf
  132. if(!pBuf || !pcbBuf)
  133. return CHAN_E_INVALID_PARAM;
  134. switch (prop)
  135. {
  136. case PROP_TS_TRADEOFF:
  137. CHECKSIZE(DWORD);
  138. OUTPROP(DWORD) = m_TemporalSpatialTradeoff;
  139. break;
  140. case PROP_REMOTE_TS_CAPABLE:
  141. CHECKSIZE(BOOL);
  142. OUTPROP(BOOL) = m_bPublicizeTSTradeoff;
  143. break;
  144. case PROP_CHANNEL_ENABLED:
  145. CHECKSIZE(BOOL);
  146. OUTPROP(BOOL) = (m_dwFlags & COMCH_ENABLED )? TRUE:FALSE;
  147. break;
  148. case PROP_LOCAL_FORMAT_ID:
  149. CHECKSIZE(MEDIA_FORMAT_ID);
  150. OUTPROP(MEDIA_FORMAT_ID) = m_LocalFmt;
  151. break;
  152. case PROP_REMOTE_FORMAT_ID:
  153. CHECKSIZE(MEDIA_FORMAT_ID);
  154. OUTPROP(MEDIA_FORMAT_ID) = m_RemoteFmt;
  155. break;
  156. case PROP_REMOTE_PAUSED:
  157. CHECKSIZE(BOOL);
  158. OUTPROP(BOOL) = (IsStreamingRemote())? FALSE:TRUE;
  159. break;
  160. case PROP_LOCAL_PAUSE_RECV:
  161. case PROP_LOCAL_PAUSE_SEND:
  162. CHECKSIZE(BOOL);
  163. OUTPROP(BOOL) = IsPausedLocal();
  164. break;
  165. case PROP_VIDEO_PREVIEW_ON:
  166. CHECKSIZE(BOOL);
  167. OUTPROP(BOOL) = IsStreamingStandby();
  168. break;
  169. case PROP_VIDEO_PREVIEW_STANDBY:
  170. CHECKSIZE(BOOL);
  171. OUTPROP(BOOL) = IsConfigStandby();
  172. break;
  173. default:
  174. if(m_pMediaStream)
  175. {
  176. // we don't recognize this property, pass to media control
  177. return m_pMediaStream->GetProperty(prop, pBuf, (LPUINT)pcbBuf);
  178. }
  179. else
  180. return CHAN_E_INVALID_PARAM;
  181. break;
  182. }
  183. return hrSuccess;
  184. }
  185. // Some properties are not writeable by client code. CtrlChanSetProperty allows setting of
  186. // those properties. This method is *not* exposed in ICommChannel
  187. STDMETHODIMP ImpICommChan::CtrlChanSetProperty(DWORD prop, PVOID pBuf, DWORD cbBuf)
  188. {
  189. FX_ENTRY("ImpICommChan::CtrlChanSetProperty");
  190. BOOL bTemp;
  191. HRESULT hr = hrSuccess;
  192. if(!pBuf || !pBuf || !cbBuf)
  193. return CHAN_E_INVALID_PARAM;
  194. #define CHECKSIZEIN(type) if(cbBuf != sizeof(type)) return CHAN_E_INVALID_PARAM;
  195. #define INPROP(type) *(type *)pBuf
  196. switch (prop)
  197. {
  198. case PROP_TS_TRADEOFF_IND: // remote sender changed T/S tradeoff of what it is
  199. if(bIsSendDirection) // sending (valid for receive channels only)
  200. return CHAN_E_INVALID_PARAM;
  201. m_TemporalSpatialTradeoff = INPROP(DWORD);
  202. if(m_pH323ConfAdvise && m_pCtlChan)
  203. {
  204. DEBUGMSG(ZONE_COMMCHAN,("%s:issuing notification 0x%08lX\r\n",_fx_, CHANNEL_VIDEO_TS_TRADEOFF));
  205. m_pH323ConfAdvise->ChannelEvent(this, m_pCtlChan->GetIConnIF(), CHANNEL_VIDEO_TS_TRADEOFF);
  206. }
  207. break;
  208. case PROP_REMOTE_FORMAT_ID:
  209. CHECKSIZEIN(DWORD);
  210. m_RemoteFmt = INPROP(DWORD);
  211. break;
  212. case PROP_REMOTE_TS_CAPABLE: // only valid for receive channels
  213. if(bIsSendDirection)
  214. return CHAN_E_INVALID_PARAM;
  215. else
  216. {
  217. CHECKSIZEIN(BOOL);
  218. m_bPublicizeTSTradeoff = INPROP(BOOL);
  219. DEBUGMSG (ZONE_COMMCHAN,("%s:remote TS tradeoff cap %d\r\n", _fx_, m_bPublicizeTSTradeoff));
  220. }
  221. break;
  222. default:
  223. return SetProperty(prop, pBuf, cbBuf);
  224. break;
  225. }
  226. return hr;
  227. }
  228. STDMETHODIMP ImpICommChan::Preview(MEDIA_FORMAT_ID idLocalFormat, IMediaChannel * pMediaStream)
  229. {
  230. HRESULT hr = hrSuccess;
  231. FX_ENTRY("ImpICommChan::Preview");
  232. SHOW_OBJ_ETIME("ImpICommChan::Preview");
  233. LPVOID lpvFormatDetails;
  234. UINT uFormatSize;
  235. if(!bIsSendDirection)
  236. {
  237. hr = CHAN_E_INVALID_PARAM;
  238. goto EXIT;
  239. }
  240. if(NULL == pMediaStream)
  241. {
  242. // preview off
  243. if(IsStreamingStandby())
  244. {
  245. DEBUGMSG(ZONE_COMMCHAN,("%s:(%s)transition to preview OFF\r\n",_fx_,
  246. (bIsSendDirection)?"send":"recv"));
  247. //turn preview off.
  248. // if network side is paused or closed, stop all streaming
  249. if(!IsComchOpen() || !IsStreamingNet())
  250. {
  251. DEBUGMSG(ZONE_COMMCHAN,("%s:(%s)stopping local stream\r\n",_fx_,
  252. (bIsSendDirection)?"send":"recv"));
  253. // Stop the stream, but DO NOT UNCONFIGURE becase we want to
  254. // be able to start later
  255. hr = m_pMediaStream->Stop();
  256. if(!HR_SUCCEEDED(hr))
  257. {
  258. DEBUGMSG(ZONE_COMMCHAN,("%s:(%s)Stop() returned 0x%08lx\r\n",_fx_,
  259. (bIsSendDirection)?"send":"recv", hr));
  260. }
  261. SHOW_OBJ_ETIME("ImpICommChan::Preview - stopped");
  262. LocalStreamFlagOff();
  263. }
  264. // else just need to turn off flag
  265. StandbyFlagOff();
  266. }
  267. else
  268. DEBUGMSG(ZONE_COMMCHAN,("%s:(%s) no change (%s)\r\n",_fx_,
  269. (bIsSendDirection)?"send":"recv", "OFF"));
  270. }
  271. else
  272. {
  273. // preview on
  274. ASSERT(m_pCapObject);
  275. if(idLocalFormat == INVALID_MEDIA_FORMAT)
  276. {
  277. hr = CHAN_E_INVALID_PARAM;
  278. goto EXIT;
  279. }
  280. ASSERT(!(m_pMediaStream && (m_pMediaStream != pMediaStream)));
  281. if (m_pMediaStream == NULL)
  282. {
  283. m_pMediaStream = pMediaStream;
  284. m_pMediaStream->AddRef();
  285. }
  286. if(!IsStreamingStandby())
  287. {
  288. DEBUGMSG(ZONE_COMMCHAN,("%s:(%s)transition to preview ON\r\n",_fx_,
  289. (bIsSendDirection)?"send":"recv"));
  290. // turn preview on.
  291. if(!IsStreamingLocal())
  292. {
  293. ASSERT(!IsStreamingNet());
  294. if(IsComchOpen())
  295. {
  296. // if the channel is open, local streaming should only be off
  297. // if the network side of the channel is paused.
  298. //ASSERT(!IsStreamingNet());
  299. }
  300. else
  301. {
  302. // ensure that the stream does not come up with network send enabled
  303. // (!!!!! override default stream behavior !!!!!)
  304. BOOL bPause = TRUE;
  305. hr = m_pMediaStream->SetProperty(
  306. (bIsSendDirection)? PROP_PAUSE_SEND:PROP_PAUSE_RECV,
  307. &bPause, sizeof(bPause));
  308. // get format info for the specified format
  309. m_pCapObject->GetEncodeFormatDetails(idLocalFormat, &lpvFormatDetails, &uFormatSize);
  310. // fire up the local stream
  311. // this is now a two step process
  312. hr = m_pMediaStream->Configure((BYTE*)lpvFormatDetails, uFormatSize,
  313. NULL, 0, (IUnknown*)(ImpICommChan *)this);
  314. if(!HR_SUCCEEDED(hr))
  315. {
  316. ERRORMESSAGE(("%s: m_pMediaStream->Configure returned 0x%08lX\r\n", _fx_, hr));
  317. goto EXIT;
  318. }
  319. m_pMediaStream->SetNetworkInterface(NULL);
  320. if(!HR_SUCCEEDED(hr))
  321. {
  322. ERRORMESSAGE(("%s: m_pMediaStream->SetNetworkInterface returned 0x%08lX\r\n", _fx_, hr));
  323. goto EXIT;
  324. }
  325. SHOW_OBJ_ETIME("ImpICommChan::Preview - config'd for preview");
  326. }
  327. // Start the stream
  328. hr = m_pMediaStream->Start();
  329. if(!HR_SUCCEEDED(hr))
  330. {
  331. ERRORMESSAGE(("%s: m_pMediaStream->Start returned 0x%08lX\r\n", _fx_, hr));
  332. goto EXIT;
  333. }
  334. SHOW_OBJ_ETIME("ImpICommChan::Preview - started preview");
  335. LocalStreamFlagOn();
  336. }
  337. // else // just need to set flag to make preview sticky
  338. StandbyFlagOn();
  339. }
  340. else
  341. DEBUGMSG(ZONE_COMMCHAN,("%s:(%s) no change (%s)\r\n",_fx_,
  342. (bIsSendDirection)?"send":"recv", "ON"));
  343. }
  344. EXIT:
  345. return hr;
  346. }
  347. STDMETHODIMP ImpICommChan::PauseNetworkStream(BOOL fPause)
  348. {
  349. if(fPause)
  350. LocalPauseFlagOn();
  351. else
  352. LocalPauseFlagOff();
  353. return PauseNet(fPause, FALSE);
  354. }
  355. BOOL ImpICommChan::IsNetworkStreamPaused(VOID)
  356. {
  357. return IsPausedLocal();
  358. }
  359. BOOL ImpICommChan::IsRemotePaused(VOID)
  360. {
  361. return (IsStreamingRemote())? FALSE:TRUE;
  362. }
  363. STDMETHODIMP ImpICommChan::PauseNet(BOOL bPause, BOOL bRemoteInitiated)
  364. {
  365. HRESULT hr = hrSuccess;
  366. FX_ENTRY("ImpICommChan::PauseNet");
  367. // issue notification
  368. if(bRemoteInitiated)
  369. {
  370. // keep track of remote state
  371. if(bPause)
  372. RemoteStreamFlagOff();
  373. else
  374. RemoteStreamFlagOn();
  375. if(!IsNotificationSupressed())
  376. {
  377. if(m_pH323ConfAdvise && m_pCtlChan)
  378. {
  379. DEBUGMSG(ZONE_COMMCHAN,("%s:issuing %s notification \r\n",_fx_,
  380. (bPause)?"pause":"un-pause"));
  381. m_pH323ConfAdvise->ChannelEvent(this, m_pCtlChan->GetIConnIF(),
  382. (bPause)? CHANNEL_REMOTE_PAUSE_ON: CHANNEL_REMOTE_PAUSE_OFF);
  383. }
  384. else
  385. DEBUGMSG(ZONE_COMMCHAN,("%s:not issuing %s notification: m_pH323ConfAdvise: 0x%08lX, m_pCtlChan:0x%08lX \r\n"
  386. ,_fx_, (bPause)?"pause":"un-pause", m_pH323ConfAdvise,m_pCtlChan));
  387. }
  388. }
  389. if(bPause && IsStreamingNet())
  390. {
  391. ASSERT(IsComchOpen());
  392. // deactivate the channel
  393. DEBUGMSG(ZONE_COMMCHAN,("%s:(%s)transition to pause\r\n",_fx_,
  394. (bIsSendDirection)?"send":"recv" ));
  395. if(!bRemoteInitiated)
  396. {
  397. // locally initiated, so signal remote
  398. if(bIsSendDirection)
  399. {
  400. DEBUGMSG (ZONE_COMMCHAN,("%s:signaling pause of %s channel\r\n",
  401. _fx_, (bIsSendDirection)?"send":"recv" ));
  402. // signal remote
  403. MiscellaneousIndication mi;
  404. mi.type.choice = logicalChannelInactive_chosen;
  405. hr = m_pCtlChan->MiscChannelIndication(this, &mi);
  406. if(!HR_SUCCEEDED(hr))
  407. {
  408. DEBUGMSG (ZONE_COMMCHAN,("%s:(%s) CC_Mute returned 0x%08lx\r\n",
  409. _fx_, (bIsSendDirection)?"send":"recv", hr));
  410. hr = hrSuccess; // don't care about signaling error, act normal
  411. }
  412. }
  413. }
  414. //
  415. hr = m_pMediaStream->SetProperty(
  416. (bIsSendDirection)? PROP_PAUSE_SEND:PROP_PAUSE_RECV,
  417. &bPause, sizeof(bPause));
  418. NetworkStreamFlagOff();
  419. // LOOKLOOK - can't stop receive streams because they can't be restarted
  420. // check this with GeorgeJ
  421. // if(!IsStreamingStandby()) // need local stream for anything?
  422. if(!IsStreamingStandby() && bIsSendDirection) // need local stream for anything?
  423. {
  424. DEBUGMSG(ZONE_COMMCHAN,("%s:(%s)stopping local stream\r\n",_fx_,
  425. (bIsSendDirection)?"send":"recv"));
  426. // can shut off local streaming now
  427. hr = m_pMediaStream->Stop();
  428. LocalStreamFlagOff();
  429. }
  430. }
  431. else if(!bPause && !IsStreamingNet())
  432. {
  433. DEBUGMSG(ZONE_COMMCHAN,("%s:(%s)transition to unpause\r\n",_fx_,
  434. (bIsSendDirection)?"send":"recv"));
  435. if(IsComchOpen())
  436. {
  437. // activate the channel
  438. if(!bRemoteInitiated)
  439. {
  440. // locally initiated, so signal remote
  441. if(bIsSendDirection)
  442. {
  443. DEBUGMSG (ZONE_COMMCHAN,("%s:signaling UNpause of %s channel\r\n",
  444. _fx_, (bIsSendDirection)?"send":"recv" ));
  445. // signal remote
  446. MiscellaneousIndication mi;
  447. mi.type.choice = logicalChannelActive_chosen;
  448. hr = m_pCtlChan->MiscChannelIndication(this, &mi);
  449. if(!HR_SUCCEEDED(hr))
  450. {
  451. DEBUGMSG (ZONE_COMMCHAN,("%s:(%s) CC_UnMute returned 0x%08lx\r\n",
  452. _fx_, (bIsSendDirection)?"send":"recv", hr));
  453. hr = hrSuccess; // don't care about signaling error, act normal
  454. }
  455. }
  456. }
  457. else
  458. {
  459. // remotely initiated OR special case first time channel is unpaused
  460. // after opening
  461. AllowNotifications(); // stop supressing notifications
  462. }
  463. if(!IsPausedLocal())
  464. {
  465. // MUST ensure unpaused state before starting stream ????
  466. hr = m_pMediaStream->SetProperty(
  467. (bIsSendDirection)? PROP_PAUSE_SEND:PROP_PAUSE_RECV,
  468. &bPause, sizeof(bPause));
  469. // check local streaming state, start it if needed
  470. if(!IsStreamingLocal())
  471. {
  472. DEBUGMSG(ZONE_COMMCHAN,("%s:(%s)starting local stream\r\n",_fx_,
  473. (bIsSendDirection)?"send":"recv"));
  474. // need to startup stream
  475. hr = m_pMediaStream->Start();
  476. LocalStreamFlagOn();
  477. }
  478. else
  479. {
  480. if(bIsSendDirection)
  481. {
  482. DEBUGMSG(ZONE_COMMCHAN,("%s:(%s)already streaming locally\r\n",_fx_,
  483. (bIsSendDirection)?"send":"recv" ));
  484. DEBUGMSG(ZONE_COMMCHAN,("%s:(%s)RESTARTING local stream\r\n",_fx_,
  485. (bIsSendDirection)?"send":"recv"));
  486. // This is temporary until it is possible to start the
  487. // network side of a running stream
  488. hr = m_pMediaStream->Stop();
  489. hr = m_pMediaStream->Start();
  490. }
  491. }
  492. NetworkStreamFlagOn();
  493. //
  494. // if this is a receive video channel, make the sender send an I-frame now
  495. //
  496. if(!bIsSendDirection && (GetTickCount() > (m_dwLastUpdateTick + MIN_IFRAME_REQ_TICKS)))
  497. {
  498. if((MEDIA_TYPE_H323VIDEO == m_MediaID))
  499. {
  500. MiscellaneousCommand *pmc = (MiscellaneousCommand *) MemAlloc(sizeof(MiscellaneousCommand));
  501. if(NULL != pmc)
  502. {
  503. // pmc.logicalChannelNumber = ?; ** call control fills this in **
  504. pmc->type.choice = videoFastUpdatePicture_chosen;
  505. // do the control channel signaling for THIS channel
  506. hr = m_pCtlChan->MiscChannelCommand(this, pmc);
  507. MemFree(pmc);
  508. }
  509. else
  510. {
  511. hr = E_OUTOFMEMORY;
  512. }
  513. }
  514. m_dwLastUpdateTick = GetTickCount();
  515. }
  516. }
  517. }
  518. else
  519. ERRORMESSAGE(("%s:(%s) Not open: bPause=%d, streaming=%d\r\n", _fx_,
  520. (bIsSendDirection)?"send":"recv", bPause, IsStreamingNet()));
  521. }
  522. else
  523. {
  524. ERRORMESSAGE(("%s:(%s) bPause=%d, streaming=%d\r\n", _fx_,
  525. (bIsSendDirection)?"send":"recv", bPause, IsStreamingNet()));
  526. }
  527. return hr;
  528. }
  529. STDMETHODIMP ImpICommChan::SetProperty(DWORD prop, PVOID pBuf, UINT cbBuf)
  530. {
  531. FX_ENTRY("ImpICommChan::SetProperty");
  532. BOOL bTemp;
  533. HRESULT hr = hrSuccess;
  534. if(!pBuf || !pBuf || !cbBuf)
  535. return CHAN_E_INVALID_PARAM;
  536. #define CHECKSIZEIN(type) if(cbBuf != sizeof(type)) return CHAN_E_INVALID_PARAM;
  537. #define INPROP(type) *(type *)pBuf
  538. #define SetMediaProperty() \
  539. if(m_pMediaStream) \
  540. {return m_pMediaStream->SetProperty(prop, pBuf, cbBuf); } \
  541. else hr = CHAN_E_INVALID_PARAM;
  542. switch (prop)
  543. {
  544. // (read only) case PROP_REMOTE_FORMAT_ID:
  545. // (read only) case PROP_LOCAL_FORMAT_ID:
  546. // (read only) case PROP_REMOTE_TS_CAPABLE:
  547. case PROP_TS_TRADEOFF:
  548. CHECKSIZEIN(DWORD);
  549. if(bIsSendDirection) // set local T/S tradeoff, then signal remote
  550. {
  551. // scale value - input is 0-31, (lower number = higher quality and lower frame rate)
  552. m_TemporalSpatialTradeoff = INPROP(DWORD);
  553. DEBUGMSG (ZONE_COMMCHAN,("%s:TS tradeoff (tx) %d\r\n", _fx_, m_TemporalSpatialTradeoff));
  554. // change our compression
  555. if (m_pMediaStream)
  556. {
  557. hr = m_pMediaStream->SetProperty(PROP_VIDEO_IMAGE_QUALITY,
  558. &m_TemporalSpatialTradeoff, sizeof (m_TemporalSpatialTradeoff));
  559. }
  560. if(m_bPublicizeTSTradeoff && m_pCtlChan) // check our own capability and if in a call
  561. {
  562. // we said we supported TS tradeoff, so we have to signal our
  563. // new value
  564. MiscellaneousIndication mi;
  565. // mi.logicalChannelNumber = ?; ** call control fills this in **
  566. mi.type.choice = MIn_tp_vdTmprlSptlTrdOff_chosen;
  567. mi.type.u.MIn_tp_vdTmprlSptlTrdOff = LOWORD(m_TemporalSpatialTradeoff);
  568. // do the control channel signaling for THIS channel
  569. hr = m_pCtlChan->MiscChannelIndication(this, &mi);
  570. }
  571. }
  572. else // signal remote to change its T/S tradoff of its send channel
  573. {
  574. m_TemporalSpatialTradeoff = INPROP(DWORD);
  575. DEBUGMSG (ZONE_COMMCHAN,("%s:TS tradeoff (rx) %d\r\n", _fx_, m_TemporalSpatialTradeoff));
  576. if(m_bPublicizeTSTradeoff && m_pCtlChan)// check remote's TS capability
  577. {
  578. MiscellaneousCommand *pmc = (MiscellaneousCommand *) MemAlloc(sizeof(MiscellaneousCommand));
  579. if(NULL != pmc)
  580. {
  581. // pmc.logicalChannelNumber = ?; ** call control fills this in **
  582. pmc->type.choice = MCd_tp_vdTmprlSptlTrdOff_chosen;
  583. pmc->type.u.MCd_tp_vdTmprlSptlTrdOff = LOWORD(m_TemporalSpatialTradeoff);
  584. hr = m_pCtlChan->MiscChannelCommand(this, pmc);
  585. MemFree(pmc);
  586. }
  587. else
  588. {
  589. hr = E_OUTOFMEMORY;
  590. }
  591. }
  592. else // remote said it does not support TS tradeoff
  593. return CHAN_E_INVALID_PARAM;
  594. }
  595. break;
  596. case PROP_CHANNEL_ENABLED:
  597. CHECKSIZEIN(BOOL);
  598. if(INPROP(BOOL))
  599. {
  600. m_dwFlags |= COMCH_ENABLED;
  601. }
  602. else
  603. {
  604. m_dwFlags &= ~COMCH_ENABLED;
  605. }
  606. break;
  607. //
  608. // Media streaming properties
  609. //
  610. case PROP_LOCAL_PAUSE_RECV:
  611. case PROP_LOCAL_PAUSE_SEND:
  612. CHECKSIZEIN(BOOL);
  613. bTemp = INPROP(BOOL);
  614. if(bTemp)
  615. LocalPauseFlagOn();
  616. else
  617. LocalPauseFlagOff();
  618. hr = PauseNet(bTemp, FALSE);
  619. break;
  620. case PROP_PAUSE_RECV:
  621. case PROP_PAUSE_SEND:
  622. CHECKSIZEIN(BOOL);
  623. hr = PauseNet(INPROP(BOOL), FALSE);
  624. break;
  625. // case PROP_PAUSE_RECV:
  626. // SetMediaProperty();
  627. // break;
  628. case PROP_VIDEO_PREVIEW_ON:
  629. ASSERT(0);
  630. break;
  631. case PROP_VIDEO_PREVIEW_STANDBY:
  632. CHECKSIZEIN(BOOL);
  633. bTemp = INPROP(BOOL);
  634. if(bTemp)
  635. StandbyConfigFlagOn();
  636. else
  637. StandbyConfigFlagOff();
  638. break;
  639. default:
  640. // we don't recognize this property, pass to media control
  641. if(m_pMediaStream)
  642. {
  643. return m_pMediaStream->SetProperty(prop, pBuf, cbBuf);
  644. }
  645. else
  646. hr = CHAN_E_INVALID_PARAM;
  647. break;
  648. }
  649. return hr;
  650. }
  651. HRESULT ImpICommChan::EnableOpen(BOOL bEnable)
  652. {
  653. if(bEnable)
  654. {
  655. m_dwFlags |= COMCH_ENABLED;
  656. }
  657. else
  658. {
  659. m_dwFlags &= ~COMCH_ENABLED;
  660. }
  661. return hrSuccess;
  662. }
  663. HRESULT ImpICommChan::GetLocalParams(LPVOID lpvChannelParams, UINT uBufSize)
  664. {
  665. if(!lpvChannelParams || !pLocalParams || !uBufSize)
  666. return CHAN_E_INVALID_PARAM;
  667. if(uBufSize < uLocalParamSize)
  668. return CHAN_E_INVALID_PARAM;
  669. memcpy(lpvChannelParams, pLocalParams, uLocalParamSize);
  670. return hrSuccess;
  671. }
  672. HRESULT ImpICommChan::ConfigureStream(MEDIA_FORMAT_ID idLocalFormat)
  673. {
  674. FX_ENTRY("ImpICommChan::ConfigureStream");
  675. HRESULT hr;
  676. ASSERT(m_pRTPChan && m_pCapObject);
  677. LPVOID lpvFormatGoo;
  678. UINT uFormatGooSize;
  679. IUnknown *pUnknown=NULL;
  680. // get format info for Configure()
  681. if(bIsSendDirection)
  682. {
  683. m_pCapObject->GetEncodeFormatDetails(idLocalFormat, &lpvFormatGoo, &uFormatGooSize);
  684. }
  685. else
  686. {
  687. m_pCapObject->GetDecodeFormatDetails(idLocalFormat, &lpvFormatGoo, &uFormatGooSize);
  688. }
  689. hr = m_pMediaStream->Configure((BYTE*)lpvFormatGoo, uFormatGooSize,
  690. (BYTE*)pLocalParams, uLocalParamSize,
  691. (IUnknown*)(ImpICommChan *)this);
  692. if(!HR_SUCCEEDED(hr))
  693. {
  694. ERRORMESSAGE(("%s: Configure returned 0x%08lX\r\n", _fx_, hr));
  695. }
  696. // SetNetworkInterface expects an IUnknown pointer
  697. // the IUnknown wil be QI'd for either an IRTPSend or an IRTPRecv
  698. // interface. The IUnknown should be free'd by the caller.
  699. if (m_pRTPChan)
  700. {
  701. m_pRTPChan->QueryInterface(IID_IUnknown, (void**)&pUnknown);
  702. ASSERT(pUnknown);
  703. }
  704. hr = m_pMediaStream->SetNetworkInterface(pUnknown);
  705. if(!HR_SUCCEEDED(hr))
  706. {
  707. ERRORMESSAGE(("%s: SetNetworkInterface returned 0x%08lX\r\n", _fx_, hr));
  708. }
  709. if (pUnknown)
  710. {
  711. pUnknown->Release();
  712. }
  713. return hr;
  714. }
  715. HRESULT ImpICommChan::ConfigureCapability(LPVOID lpvRemoteChannelParams, UINT uRemoteParamSize,
  716. LPVOID lpvLocalParams, UINT uGivenLocalParamSize)
  717. {
  718. HRESULT hr= hrSuccess;
  719. if(!lpvRemoteChannelParams)
  720. return CHAN_E_INVALID_PARAM;
  721. if(pRemoteParams)
  722. {
  723. MemFree(pRemoteParams);
  724. pRemoteParams = NULL;
  725. }
  726. // if uParamSize ==0, it means that the memory that lpvRemoteChannelParams points to
  727. // is being supplied
  728. if(uRemoteParamSize)
  729. {
  730. pRemoteParams = MemAlloc(uRemoteParamSize);
  731. if(pRemoteParams)
  732. {
  733. memcpy(pRemoteParams, lpvRemoteChannelParams, uRemoteParamSize);
  734. }
  735. }
  736. else
  737. pRemoteParams = lpvRemoteChannelParams;
  738. if(lpvLocalParams)
  739. {
  740. // memory for local parameters is always supplied by the caller
  741. if (!uGivenLocalParamSize)
  742. {
  743. hr = CHAN_E_INVALID_PARAM;
  744. goto EXIT;
  745. }
  746. if(pLocalParams)
  747. {
  748. MemFree(pLocalParams);
  749. // not needed pLocalParams= NULL;
  750. }
  751. uLocalParamSize = uGivenLocalParamSize;
  752. pLocalParams = lpvLocalParams;
  753. }
  754. EXIT:
  755. return hr;
  756. }
  757. HRESULT ImpICommChan::OnChannelClose(DWORD dwStatus)
  758. {
  759. HRESULT hr = hrSuccess;
  760. FX_ENTRY("ImpICommChan::OnChannelClose");
  761. BOOL fCloseAction = FALSE;
  762. SHOW_OBJ_ETIME("ImpICommChan::OnChannelClose");
  763. m_dwFlags &= ~COMCH_OPEN_PENDING;
  764. switch(dwStatus)
  765. {
  766. case CHANNEL_CLOSED:
  767. DEBUGMSG(ZONE_COMMCHAN,("%s:closing (%s)\r\n"
  768. ,_fx_, (bIsSendDirection)?"send":"recv"));
  769. if(IsComchOpen())
  770. {
  771. fCloseAction = TRUE;
  772. m_dwFlags &= ~COMCH_OPEN;
  773. }
  774. else
  775. {
  776. ERRORMESSAGE(("%s: %d notification when not open (%s)\r\n", _fx_,
  777. dwStatus,(bIsSendDirection)?"send":"recv"));
  778. }
  779. break;
  780. //case CHANNEL_REJECTED:
  781. //case CHANNEL_NO_CAPABILITY:
  782. default:
  783. break;
  784. }
  785. // clear general purpose channel handle
  786. dwhChannel = 0;
  787. // LOOKLOOK **** RIGHT HERE ***
  788. // ** need to notify the UI of the channel event ON_CLOSING so that the last
  789. // frame can be grabbed for rendering (a still picture is better than a black window)
  790. // LOOKLOOK **** RIGHT HERE ***
  791. // Now check preview state
  792. if(IsStreamingStandby() && bIsSendDirection )
  793. {
  794. if (m_pMediaStream != NULL)
  795. {
  796. DEBUGMSG(ZONE_COMMCHAN,("%s:transition back to preview\r\n" ,_fx_));
  797. // need to stop sending and reconfigure for preview
  798. // make sure send is paused
  799. DWORD dwProp = TRUE;
  800. hr = m_pMediaStream->SetProperty (PROP_PAUSE_SEND,&dwProp, sizeof(dwProp));
  801. if(!HR_SUCCEEDED(hr))
  802. {
  803. ERRORMESSAGE(("%s: m_pMediaStream->SetProperty returned 0x%08lX\r\n", _fx_, hr));
  804. // do what now?
  805. }
  806. NetworkStreamFlagOff();
  807. hr = m_pMediaStream->Stop();
  808. LocalStreamFlagOff();
  809. StandbyFlagOff();
  810. ASSERT(hr == S_OK);
  811. }
  812. else
  813. {
  814. NetworkStreamFlagOff();
  815. LocalStreamFlagOff();
  816. }
  817. if(fCloseAction)
  818. {
  819. // Cleanup RTP session. This is a NOP if the opposite direction is still open.
  820. if (m_pRTPChan)
  821. {
  822. m_pRTPChan->Release();
  823. m_pRTPChan = NULL;
  824. }
  825. }
  826. }
  827. else // not previewing
  828. {
  829. //
  830. // Stop the media stream
  831. //
  832. if (m_pMediaStream)
  833. {
  834. hr = m_pMediaStream->Stop(); // probably not necessary
  835. ASSERT(hr == S_OK);
  836. // implement "capture device standby": don't unconfigure if
  837. // the standby flag is set and it is a send stream.
  838. if(!IsConfigStandby() || !bIsSendDirection)
  839. {
  840. if(!bIsSendDirection) // keep send stream reference until *this* object is released
  841. {
  842. m_pMediaStream->Release();
  843. m_pMediaStream = NULL;
  844. }
  845. }
  846. }
  847. SHOW_OBJ_ETIME("ImpICommChan::OnChannelClose - stream stopped");
  848. if(fCloseAction)
  849. {
  850. // Cleanup RTP session. This is a NOP if the opposite direction is still open.
  851. if (m_pRTPChan)
  852. {
  853. m_pRTPChan->Release();
  854. m_pRTPChan = NULL;
  855. }
  856. }
  857. StreamFlagsOff();
  858. }// end if not previewing
  859. if(m_pH323ConfAdvise && m_pCtlChan)
  860. {
  861. DEBUGMSG(ZONE_COMMCHAN,("%s:issuing notification 0x%08lX\r\n",_fx_, dwStatus));
  862. m_pH323ConfAdvise->ChannelEvent(this, m_pCtlChan->GetIConnIF(), dwStatus);
  863. }
  864. return hr;
  865. }
  866. HRESULT ImpICommChan::OnChannelOpening()
  867. {
  868. ASSERT((m_dwFlags & COMCH_OPEN_PENDING) ==0);
  869. m_dwFlags |= COMCH_OPEN_PENDING;
  870. return hrSuccess;
  871. }
  872. HRESULT ImpICommChan::OnChannelOpen(DWORD dwStatus)
  873. {
  874. HRESULT hr;
  875. BOOL bConfigured = FALSE, bNewStream = FALSE; // these bools make error cleanup cleaner
  876. FX_ENTRY("ImpICommChan::OnChannelOpen");
  877. SHOW_OBJ_ETIME("ImpICommChan::OnChannelOpen");
  878. // the open is no longer pending, regardless of success or failure
  879. m_dwFlags &= ~COMCH_OPEN_PENDING;
  880. m_dwLastUpdateTick = 0; // reset tick count of last I-frame request so that one
  881. // will be requested
  882. if(IsComchOpen())
  883. {
  884. ERRORMESSAGE(("%s: %d notification when open (%s)\r\n", _fx_,
  885. dwStatus, (bIsSendDirection)?"send":"recv"));
  886. }
  887. switch(dwStatus)
  888. {
  889. case CHANNEL_OPEN:
  890. m_dwFlags |= (COMCH_OPEN | COMCH_SUPPRESS_NOTIFICATION);
  891. break;
  892. default:
  893. dwStatus = CHANNEL_OPEN_ERROR;
  894. // fall through to notification
  895. case CHANNEL_REJECTED:
  896. case CHANNEL_NO_CAPABILITY:
  897. goto NOTIFICATION;
  898. break;
  899. }
  900. // The channel is open as far as call control is concerned.
  901. // if previewing, the stream already exists. We don't want another, nor do we
  902. // want to tear it down at channel close time or in error cases
  903. if(!m_pMediaStream)
  904. {
  905. ASSERT(!IsStreamingLocal() &&m_pH323ConfAdvise); // can't be streaming without a stream
  906. bNewStream = TRUE;
  907. // Associate the media streaming endpoint with this channel
  908. // see above
  909. hr = m_pH323ConfAdvise->GetMediaChannel(&m_MediaID,
  910. bIsSendDirection, &m_pMediaStream);
  911. if(!HR_SUCCEEDED(hr))
  912. {
  913. ERRORMESSAGE(("%s: m_pH323ConfAdvise->GetMediaChannel returned 0x%08lX\r\n", _fx_, hr));
  914. goto ERROR_NOTIFICATION;
  915. }
  916. }
  917. if(IsStreamingLocal())
  918. {
  919. DEBUGMSG(ZONE_COMMCHAN,("%s:(%s)transition:preview -> send\r\n",_fx_,
  920. (bIsSendDirection)?"send":"recv"));
  921. // need to stop stream while configuring ( ***** check w/ RichP ******)
  922. hr = m_pMediaStream->Stop();
  923. LocalStreamFlagOff();
  924. }
  925. // notify upper layers of channel open now
  926. if(m_pH323ConfAdvise && m_pCtlChan)
  927. {
  928. DEBUGMSG(ZONE_COMMCHAN,("%s:issuing CHANNEL_OPEN notification\r\n",_fx_));
  929. m_pH323ConfAdvise->ChannelEvent(this, m_pCtlChan->GetIConnIF(), dwStatus);
  930. }
  931. dwStatus = CHANNEL_ACTIVE; // new status! notification is posted below
  932. ASSERT(m_pRTPChan);
  933. // get format info for Configure()
  934. hr = ConfigureStream(m_LocalFmt);
  935. if(!HR_SUCCEEDED(hr))
  936. {
  937. ERRORMESSAGE(("%s: Configure returned 0x%08lX\r\n", _fx_, hr));
  938. goto ERROR_NOTIFICATION;
  939. }
  940. SHOW_OBJ_ETIME("ImpICommChan::OnChannelOpen - configured stream");
  941. bConfigured = TRUE;
  942. // turn on flow to the network
  943. // SupressNotification() // pre-initialized above in both CHANNEL_OPEN_xxx cases
  944. PauseNet(FALSE, TRUE); // unpause,
  945. //dwStatus = CHANNEL_ACTIVE;
  946. SHOW_OBJ_ETIME("ImpICommChan::OnChannelOpen - unpaused");
  947. NOTIFICATION:
  948. if(m_pH323ConfAdvise && m_pCtlChan)
  949. {
  950. DEBUGMSG(ZONE_COMMCHAN,("%s:issuing notification 0x%08lX\r\n",_fx_, dwStatus));
  951. m_pH323ConfAdvise->ChannelEvent(this, m_pCtlChan->GetIConnIF(), dwStatus);
  952. }
  953. else
  954. DEBUGMSG(ZONE_COMMCHAN,("%s: *** not issuing notification 0x%08lX m_pH323ConfAdvise: 0x%08lX, m_pCtlChan:0x%08lX \r\n"
  955. ,_fx_, dwStatus,m_pH323ConfAdvise,m_pCtlChan));
  956. SHOW_OBJ_ETIME("ImpICommChan::OnChannelOpen - done ");
  957. return hr;
  958. ERROR_NOTIFICATION:
  959. dwStatus = CHANNEL_OPEN_ERROR;
  960. if(m_pMediaStream)
  961. {
  962. if(bNewStream) // was the media stream just created?
  963. {
  964. m_pMediaStream->Release();
  965. m_pMediaStream = NULL;
  966. }
  967. }
  968. if(m_pH323ConfAdvise && m_pCtlChan)
  969. {
  970. DEBUGMSG(ZONE_COMMCHAN,("%s:issuing notification 0x%08lX\r\n",_fx_, dwStatus));
  971. m_pH323ConfAdvise->ChannelEvent(this, m_pCtlChan->GetIConnIF(), dwStatus);
  972. }
  973. else
  974. DEBUGMSG(ZONE_COMMCHAN,("%s: *** not issuing notification 0x%08lX m_pH323ConfAdvise: 0x%08lX, m_pCtlChan:0x%08lX \r\n"
  975. ,_fx_, dwStatus,m_pH323ConfAdvise,m_pCtlChan));
  976. // close the channel.
  977. if(m_pCtlChan)
  978. {
  979. // close channel, but hr already contains the relevant return code
  980. m_pCtlChan->CloseChannel(this);
  981. }
  982. return hr;
  983. }
  984. HRESULT ImpICommChan::Open(MEDIA_FORMAT_ID idLocalFormat, IH323Endpoint *pConnection)
  985. {
  986. HRESULT hr;
  987. MEDIA_FORMAT_ID idRemoteFormat;
  988. IConfAdvise * pConfAdvise = NULL;
  989. if((m_dwFlags & COMCH_OPEN_PENDING) || IsComchOpen() || (idLocalFormat == INVALID_MEDIA_FORMAT) || !pConnection)
  990. return CHAN_E_INVALID_PARAM;
  991. if(!m_pCtlChan) // this channel is not part of a call
  992. {
  993. hr = pConnection->QueryInterface(IID_IConfAdvise, (void **)&pConfAdvise);
  994. if(!HR_SUCCEEDED(hr))
  995. goto EXIT;
  996. hr = pConfAdvise->AddCommChannel(this);
  997. if(!HR_SUCCEEDED(hr))
  998. goto EXIT;
  999. ASSERT(m_pCtlChan && m_pCapObject);
  1000. }
  1001. hr = m_pCapObject->ResolveToLocalFormat(idLocalFormat, &idRemoteFormat);
  1002. if(!HR_SUCCEEDED(hr))
  1003. goto EXIT;
  1004. // start the control channel stuff needed to open the channel
  1005. hr = m_pCtlChan->OpenChannel((ICtrlCommChan*)this, m_pCapObject,
  1006. idLocalFormat, idRemoteFormat);
  1007. EXIT:
  1008. if(pConfAdvise)
  1009. pConfAdvise->Release();
  1010. return hr;
  1011. }
  1012. HRESULT ImpICommChan::Close()
  1013. {
  1014. HRESULT hr = CHAN_E_INVALID_PARAM;
  1015. if(!IsComchOpen() || !m_pCtlChan)
  1016. goto EXIT;
  1017. if(!bIsSendDirection)
  1018. goto EXIT;
  1019. hr = m_pCtlChan->CloseChannel(this);
  1020. EXIT:
  1021. return hr;
  1022. }
  1023. HRESULT ImpICommChan::BeginControlSession(IControlChannel *pCtlChan, LPIH323PubCap pCapObject)
  1024. {
  1025. // this channel is now "in a call".
  1026. // LOOKLOOK - it might help to notify (ICommChannel notifications to client)
  1027. // that the channel is part of a call now.
  1028. ASSERT((m_pCtlChan == NULL) && pCtlChan && pCapObject);
  1029. if(m_pCapObject)
  1030. {
  1031. m_pCapObject->Release();
  1032. }
  1033. m_pCtlChan = pCtlChan;
  1034. m_pCapObject = pCapObject;
  1035. m_pCapObject->AddRef();
  1036. return hrSuccess;
  1037. }
  1038. HRESULT ImpICommChan::EndControlSession()
  1039. {
  1040. // this channel is no longer "in a call".
  1041. m_pCtlChan = NULL;
  1042. return hrSuccess;
  1043. }
  1044. BOOL ImpICommChan::SelectPorts(LPIControlChannel pCtlChannel)
  1045. {
  1046. // create the RTP channel
  1047. HRESULT hr;
  1048. PSOCKADDR_IN psin=NULL;
  1049. pCtlChannel->GetLocalAddress(&psin);
  1050. PORT savedPort = psin->sin_port;
  1051. if (!m_pRTPChan) {
  1052. UINT sessFlags = bIsSendDirection ? SESSIONF_SEND : SESSIONF_RECV;
  1053. UINT sessId;
  1054. GUID mediaGuid;
  1055. GetMediaType(&mediaGuid);
  1056. if (mediaGuid == MEDIA_TYPE_H323VIDEO)
  1057. {
  1058. sessFlags |= SESSIONF_VIDEO;
  1059. sessId = 2;
  1060. }
  1061. else
  1062. {
  1063. sessId = 1;
  1064. sessFlags |= SESSIONF_AUDIO;
  1065. }
  1066. psin->sin_port = 0; // zero port forces RTP to choose a port
  1067. hr = g_pIRTP->OpenSession(sessId, sessFlags,
  1068. (BYTE *)psin, sizeof(PSOCKADDR_IN),
  1069. &m_pRTPChan);
  1070. }
  1071. else
  1072. hr = m_pRTPChan->SetLocalAddress((BYTE *)psin,sizeof(SOCKADDR_IN));
  1073. psin->sin_port = savedPort;
  1074. return hr==S_OK;
  1075. }
  1076. // get the address and port of the base port that was selected by SelectPorts().
  1077. // in this typical implementation, that is the address/port of the RTCP channel
  1078. PSOCKADDR_IN ImpICommChan::GetLocalAddress()
  1079. {
  1080. #ifdef OLDSTUFF
  1081. return m_pRTPChan ? m_pRTPChan->GetChannelDescription()->pLocalAddr : NULL;
  1082. #else
  1083. const BYTE *pAddr;
  1084. UINT cbAddr;
  1085. HRESULT hr;
  1086. hr = m_pRTPChan->GetLocalAddress(&pAddr, &cbAddr);
  1087. return (SUCCEEDED(hr)) ? (PSOCKADDR_IN) pAddr : NULL;
  1088. #endif
  1089. }
  1090. STDMETHODIMP ImpICommChan::GetRemoteAddress(PSOCKADDR_IN pAddrOutput)
  1091. {
  1092. HRESULT hr;
  1093. if (!pAddrOutput)
  1094. {
  1095. return CHAN_E_INVALID_PARAM;
  1096. }
  1097. const BYTE *pAddr;
  1098. UINT cbAddr;
  1099. hr = m_pRTPChan->GetRemoteRTPAddress(&pAddr, &cbAddr);
  1100. if(SUCCEEDED(hr))
  1101. {
  1102. ASSERT(cbAddr == sizeof(SOCKADDR_IN));
  1103. *pAddrOutput = *((PSOCKADDR_IN) pAddr);
  1104. }
  1105. return hrSuccess;
  1106. }
  1107. UINT ImpICommChan::Reset()
  1108. {
  1109. UINT uret;
  1110. ASSERT(!IsComchOpen());
  1111. if (m_pRTPChan) {
  1112. uret = m_pRTPChan->Release();
  1113. m_pRTPChan = NULL;
  1114. } else
  1115. uret = 0;
  1116. return uret;
  1117. }
  1118. PORT ImpICommChan::GetLocalRTPPort()
  1119. {
  1120. #ifdef OLDSTUFF
  1121. return (m_pRTPChan ? ntohs(m_pRTPChan->GetChannelDescription()->pLocalAddr->sin_port) : 0);
  1122. #else
  1123. const BYTE *pAddr;
  1124. UINT cbAddr;
  1125. HRESULT hr;
  1126. hr = m_pRTPChan->GetLocalAddress(&pAddr, &cbAddr);
  1127. return (SUCCEEDED(hr)) ? ntohs(((PSOCKADDR_IN) pAddr)->sin_port) : 0;
  1128. #endif
  1129. }
  1130. PORT ImpICommChan::GetLocalRTCPPort()
  1131. {
  1132. #ifdef OLDSTUFF
  1133. return (m_pRTPChan ? ntohs(m_pRTPChan->GetChannelDescription()->pLocalRTCPAddr->sin_port) : 0);
  1134. #else
  1135. const BYTE *pAddr;
  1136. UINT cbAddr;
  1137. HRESULT hr;
  1138. hr = m_pRTPChan->GetLocalAddress(&pAddr, &cbAddr);
  1139. return (SUCCEEDED(hr)) ? ntohs(((PSOCKADDR_IN) pAddr)->sin_port)+1 : 0;
  1140. #endif
  1141. }
  1142. HRESULT ImpICommChan::AcceptRemoteRTCPAddress(PSOCKADDR_IN pSinC)
  1143. {
  1144. HRESULT hr;
  1145. #ifdef OLDSTUFF
  1146. if (!m_pRTPChan) {
  1147. RTPCHANNELDESC chanDesc = {0};
  1148. GetMediaType(&chanDesc.mediaId);
  1149. chanDesc.pRemoteRTCPAddr = pSinC;
  1150. hr = CreateRTPChannel(&chanDesc, &m_pRTPChan);
  1151. } else
  1152. hr = m_pRTPChan->SetRemoteAddresses(NULL,pSinC);
  1153. #else
  1154. hr = m_pRTPChan->SetRemoteRTCPAddress((BYTE *)pSinC, sizeof(SOCKADDR_IN));
  1155. #endif
  1156. return hr;
  1157. }
  1158. HRESULT ImpICommChan::AcceptRemoteAddress(PSOCKADDR_IN pSinD)
  1159. {
  1160. HRESULT hr;
  1161. hr = m_pRTPChan->SetRemoteRTPAddress((BYTE *)pSinD, sizeof(SOCKADDR_IN));
  1162. return hr;
  1163. }
  1164. HRESULT ImpICommChan::SetAdviseInterface(IH323ConfAdvise *pH323ConfAdvise)
  1165. {
  1166. if (!pH323ConfAdvise)
  1167. {
  1168. return CHAN_E_INVALID_PARAM;
  1169. }
  1170. m_pH323ConfAdvise = pH323ConfAdvise;
  1171. return hrSuccess;
  1172. }
  1173. STDMETHODIMP ImpICommChan::PictureUpdateRequest()
  1174. {
  1175. FX_ENTRY ("ImpICommChan::PictureUpdateRequest");
  1176. HRESULT hr;
  1177. if (!m_pCtlChan)
  1178. {
  1179. return CHAN_E_NOT_OPEN;
  1180. }
  1181. if(bIsSendDirection || (MEDIA_TYPE_H323VIDEO != m_MediaID))
  1182. {
  1183. return CHAN_E_INVALID_PARAM;
  1184. }
  1185. // issue miscellaneous command for picture update
  1186. MiscellaneousCommand *pmc = (MiscellaneousCommand *) MemAlloc(sizeof(MiscellaneousCommand));
  1187. if(NULL != pmc)
  1188. {
  1189. // pmc.logicalChannelNumber = ?; ** call control fills this in **
  1190. pmc->type.choice = videoFastUpdatePicture_chosen;
  1191. // do the control channel signaling for THIS channel
  1192. hr = m_pCtlChan->MiscChannelCommand(this, pmc);
  1193. // record the tick count of this command
  1194. m_dwLastUpdateTick = GetTickCount();
  1195. MemFree(pmc);
  1196. pmc = NULL;
  1197. }
  1198. else
  1199. {
  1200. hr = E_OUTOFMEMORY;
  1201. }
  1202. return hr;
  1203. }
  1204. STDMETHODIMP ImpICommChan::GetVersionInfo(
  1205. PCC_VENDORINFO *ppLocalVendorInfo,
  1206. PCC_VENDORINFO *ppRemoteVendorInfo)
  1207. {
  1208. FX_ENTRY ("ImpICommChan::GetVersionInfo");
  1209. if (!m_pCtlChan)
  1210. {
  1211. return CHAN_E_INVALID_PARAM;
  1212. }
  1213. return m_pCtlChan->GetVersionInfo(ppLocalVendorInfo, ppRemoteVendorInfo);
  1214. }
  1215. ImpICommChan::ImpICommChan ()
  1216. :pRemoteParams(NULL),
  1217. m_pMediaStream(NULL),
  1218. pLocalParams(NULL),
  1219. uLocalParamSize(0),
  1220. m_pCtlChan(NULL),
  1221. m_pH323ConfAdvise(NULL),
  1222. m_pCapObject(NULL),
  1223. m_dwFlags(0),
  1224. dwhChannel(0),
  1225. m_LocalFmt(INVALID_MEDIA_FORMAT),
  1226. m_RemoteFmt(INVALID_MEDIA_FORMAT),
  1227. m_TemporalSpatialTradeoff(0), // default to highest resolution
  1228. m_bPublicizeTSTradeoff(FALSE),
  1229. m_uRef(1)
  1230. {
  1231. ZeroMemory(&m_MediaID, sizeof(m_MediaID));
  1232. }
  1233. ImpICommChan::~ImpICommChan ()
  1234. {
  1235. if(pRemoteParams)
  1236. MemFree(pRemoteParams);
  1237. if(pLocalParams)
  1238. MemFree(pLocalParams);
  1239. if(m_pMediaStream)
  1240. {
  1241. m_pMediaStream->Stop(); // probably not necessary
  1242. m_pMediaStream->Release();
  1243. m_pMediaStream = NULL;
  1244. }
  1245. if(m_pCapObject)
  1246. m_pCapObject->Release();
  1247. }