Source code of Windows XP (NT5)
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.

228 lines
7.3 KiB

  1. //==========================================================================;
  2. //
  3. // Copyright (c) Microsoft Corporation 1999-2000.
  4. //
  5. //--------------------------------------------------------------------------;
  6. //
  7. // MSVidBDATuner.cpp : Implementation of CMSVidBDATuner
  8. //
  9. #include "stdafx.h"
  10. #ifndef TUNING_MODEL_ONLY
  11. #include "MSVidCtl.h"
  12. #include "BDATuner.h"
  13. DEFINE_EXTERN_OBJECT_ENTRY(CLSID_MSVidBDATunerDevice, CMSVidBDATuner)
  14. /////////////////////////////////////////////////////////////////////////////
  15. // CMSVidBDATuner
  16. STDMETHODIMP CMSVidBDATuner::InterfaceSupportsErrorInfo(REFIID riid)
  17. {
  18. static const IID* arr[] =
  19. {
  20. &IID_IMSVidTuner,
  21. &__uuidof(CMSVidBDATuner)
  22. };
  23. for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
  24. {
  25. if (InlineIsEqualGUID(*arr[i],riid))
  26. return S_OK;
  27. }
  28. return S_FALSE;
  29. }
  30. HRESULT CMSVidBDATuner::Unload(void) {
  31. BroadcastUnadvise();
  32. IMSVidGraphSegmentImpl<CMSVidBDATuner, MSVidSEG_SOURCE, &KSCATEGORY_BDA_RECEIVER_COMPONENT>::Unload();
  33. m_iNetworkProvider = -1;
  34. m_iTIF = -1;
  35. return NOERROR;
  36. }
  37. HRESULT CMSVidBDATuner::UpdateTR(TNTuneRequest &tr) {
  38. PQBDATuner pt(m_Filters[m_iNetworkProvider]);
  39. return pt->get_TuneRequest(&tr);
  40. }
  41. HRESULT CMSVidBDATuner::DoTune(TNTuneRequest &tr) {
  42. if (m_iNetworkProvider == -1) {
  43. return S_FALSE;
  44. }
  45. PQBDATuner pt(m_Filters[m_iNetworkProvider]);
  46. if (!pt) {
  47. return Error(IDS_INVALID_TR, __uuidof(CMSVidBDATuner), DISP_E_TYPEMISMATCH);
  48. }
  49. return pt->put_TuneRequest(tr);
  50. }
  51. HRESULT CMSVidBDATuner::put_Container(IMSVidGraphSegmentContainer *pCtl) {
  52. if (!m_fInit) {
  53. return Error(IDS_OBJ_NO_INIT, __uuidof(CMSVidBDATuner), CO_E_NOTINITIALIZED);
  54. }
  55. try {
  56. if (!pCtl) {
  57. return Unload();
  58. }
  59. if (m_pContainer) {
  60. if (!m_pContainer.IsEqualObject(VWSegmentContainer(pCtl))) {
  61. return Error(IDS_OBJ_ALREADY_INIT, __uuidof(CMSVidBDATuner), CO_E_ALREADYINITIALIZED);
  62. } else {
  63. return NO_ERROR;
  64. }
  65. }
  66. // DON'T addref the container. we're guaranteed nested lifetimes
  67. // and an addref creates circular refcounts so we never unload.
  68. m_pContainer.p = pCtl;
  69. m_pGraph = m_pContainer.GetGraph();
  70. if (!m_pCurrentTR) {
  71. // if we don't have a tune request we can't tell what NP we need.
  72. return Error(IDS_NO_NP, __uuidof(CMSVidBDATuner), E_FAIL);
  73. }
  74. // bring in the right network provider
  75. if (!m_pSystemEnum) {
  76. m_pSystemEnum = PQCreateDevEnum(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER);
  77. }
  78. DSDevices pnpenum(m_pSystemEnum, KSCATEGORY_BDA_NETWORK_PROVIDER);
  79. if (!pnpenum) {
  80. TRACELM(TRACE_ERROR, "CMSVidBDATuner::put_Container() can't create network provider category enumerator");
  81. return Error(IDS_NO_NP_CAT, __uuidof(CMSVidBDATuner), E_FAIL);
  82. }
  83. DSDevices::iterator i = pnpenum.begin();
  84. DSFilter np;
  85. for (;i != pnpenum.end(); ++i) {
  86. np = m_pGraph.AddMoniker(*i);
  87. if (!np) {
  88. continue;
  89. }
  90. PQTuner pt(np);
  91. if (pt) {
  92. HRESULT hr = pt->put_TuningSpace(m_pCurrentTR.TuningSpace());
  93. if (SUCCEEDED(hr)) {
  94. hr = pt->put_TuneRequest(m_pCurrentTR);
  95. if (SUCCEEDED(hr)) {
  96. break;
  97. }
  98. }
  99. }
  100. bool rc = m_pGraph.RemoveFilter(np);
  101. if (!rc) {
  102. return E_UNEXPECTED;
  103. }
  104. }
  105. if (i == pnpenum.end()) {
  106. TRACELM(TRACE_ERROR, "CMSVidBDATuner::put_Container() can't load network provider");
  107. return Error(IDS_NO_NP, __uuidof(CMSVidBDATuner), E_FAIL);
  108. }
  109. _ASSERT(!!np);
  110. m_Filters.push_back(np);
  111. m_iNetworkProvider = m_Filters.size() - 1;
  112. TRACELM(TRACE_DETAIL, "CMSVidBDATuner::put_Container() attempting to load tuners from KSCATEGORY_BDA_NETWORK_TUNER");
  113. HRESULT hr = LoadTunerSection(np, KSCATEGORY_BDA_NETWORK_TUNER);
  114. if (FAILED(hr)) {
  115. TRACELM(TRACE_DETAIL, "CMSVidBDATuner::put_Container() attempting to load tuners from KSCATEGORY_BDA_RECEIVER_COMPONENT");
  116. hr = LoadTunerSection(np, KSCATEGORY_BDA_RECEIVER_COMPONENT);
  117. if (FAILED(hr)) {
  118. m_Filters.clear();
  119. m_iNetworkProvider = -1;
  120. return hr;
  121. }
  122. }
  123. hr = BroadcastAdvise();
  124. if (FAILED(hr)) {
  125. TRACELM(TRACE_ERROR, "CMSVidTVTuner::put_Container() can't advise for broadcast events");
  126. return E_UNEXPECTED;
  127. }
  128. return NOERROR;
  129. } catch (ComException &e) {
  130. return e;
  131. } catch(...) {
  132. return E_UNEXPECTED;
  133. }
  134. return NOERROR;
  135. }
  136. HRESULT CMSVidBDATuner::LoadTunerSection(DSFilter& np, const GUID& kscategory) {
  137. TRACELM(TRACE_DETAIL, "CMSVidBDATuner::LoadTunerSection()");
  138. DSFilter tuner;
  139. DSFilterList added;
  140. DSDevices ptunerenum(m_pSystemEnum, kscategory);
  141. DSDevices::iterator i = ptunerenum.begin();
  142. for (; i != ptunerenum.end(); ++i) {
  143. tuner = m_pGraph.AddMoniker(*i);
  144. if (!tuner) {
  145. continue;
  146. }
  147. // connect np to decode
  148. HRESULT hr = m_pGraph.Connect(np, tuner, added);
  149. if (FAILED(hr)) {
  150. bool rc = m_pGraph.RemoveFilter(tuner);
  151. if (!rc) {
  152. return E_UNEXPECTED;
  153. }
  154. continue;
  155. }
  156. m_Filters.insert(m_Filters.end(), added.begin(), added.end());
  157. added.clear();
  158. // bring in the all right tifs
  159. DSDevices ptife(m_pSystemEnum, KSCATEGORY_BDA_TRANSPORT_INFORMATION);
  160. DSDevices::iterator itif = ptife.begin();
  161. DSFilter tif;
  162. int cTIFsAdded = 0;
  163. for (;itif != ptife.end(); ++itif) {
  164. tif = m_pGraph.AddMoniker(*itif);
  165. if (!tif) {
  166. continue;
  167. }
  168. // connect np to tif
  169. hr = m_pGraph.Connect(np, tif, added);
  170. if (FAILED(hr)) {
  171. TRACELSM(TRACE_ERROR, (dbgDump << "CMSVidBDATuner::LoadTunerSection() can't connect network provider to transport information filter, trying next tif " << hr), "");
  172. bool rc = m_pGraph.RemoveFilter(tif);
  173. if (!rc) {
  174. return E_UNEXPECTED;
  175. }
  176. } else {
  177. ++cTIFsAdded;
  178. m_Filters.push_back(tif);
  179. m_iTIF = m_Filters.size() - 1;
  180. m_Filters.insert(m_Filters.end(), added.begin(), added.end());
  181. added.clear();
  182. }
  183. }
  184. if (cTIFsAdded) {
  185. break;
  186. }
  187. // no tifs found for this "tuner", try the next one
  188. bool rc = m_pGraph.RemoveFilter(tuner);
  189. if (!rc) {
  190. return E_UNEXPECTED;
  191. }
  192. }
  193. if ( i == ptunerenum.end()) {
  194. TRACELM(TRACE_ERROR, "CMSVidBDATuner::LoadTunerSection() can't connect network provider to any transport information filters.");
  195. return Error(IDS_CANT_CONNECT_NP_TIF, __uuidof(CMSVidBDATuner), E_FAIL);
  196. }
  197. m_Filters.push_back(tuner);
  198. m_iTuner = m_Filters.size() - 1;
  199. return NOERROR;
  200. }
  201. HRESULT CMSVidBDATuner::Fire(GUID gEventID) {
  202. TRACELM(TRACE_DETAIL, "CMSVidBDATuner::Fire()");
  203. if (gEventID == EVENTID_TuningChanged) {
  204. Fire_OnTuneChanged(this);
  205. }
  206. return NOERROR;
  207. }
  208. #endif //TUNING_MODEL_ONLY
  209. // end of file - MSVidBDATuner.cpp