CFilterTitleOverlay.cpp
上传用户:hhs829
上传日期:2022-06-17
资源大小:586k
文件大小:13k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. //
  2. // CFilterTitleOverlay.cpp
  3. //
  4. #include <streams.h>          // quartz, includes windows
  5. // Eliminate two expected level 4 warnings from the Microsoft compiler.
  6. // The class does not have an assignment or copy operator, and so cannot
  7. // be passed by value.  This is normal.  This file compiles clean at the
  8. // highest (most picky) warning level (-W4).
  9. #pragma warning(disable: 4511 4512)
  10. #include <measure.h>          // performance measurement (MSR_)
  11. #include <initguid.h>
  12. #if (1100 > _MSC_VER)
  13. #include <olectlid.h>
  14. #else
  15. #include <olectl.h>
  16. #endif
  17. #include "CFilterTitleOverlay.h"
  18. #include "CTitleOverlayProp.h"
  19. #include "CSysTimeOverlayController.h"
  20. #include "CScrollController.h"
  21. // {E3FB4BFE-8E5C-4aec-8162-7DA55BE486A1}
  22. DEFINE_GUID(CLSID_HQTitleOverlay, 
  23. 0xe3fb4bfe, 0x8e5c, 0x4aec, 0x81, 0x62, 0x7d, 0xa5, 0x5b, 0xe4, 0x86, 0xa1);
  24. // {E70FE57A-19AA-4a4c-B39A-408D49D73851}
  25. DEFINE_GUID(CLSID_HQTitleOverlayProp, 
  26. 0xe70fe57a, 0x19aa, 0x4a4c, 0xb3, 0x9a, 0x40, 0x8d, 0x49, 0xd7, 0x38, 0x51);
  27. //
  28. // setup data
  29. //
  30. const AMOVIESETUP_MEDIATYPE sudPinTypes =
  31. {
  32.     &MEDIATYPE_NULL,            // Major type
  33.     &MEDIASUBTYPE_NULL          // Minor type
  34. };
  35. const AMOVIESETUP_PIN psudPins[] =
  36. {
  37.     {
  38.         L"Input",           // String pin name
  39.         FALSE,              // Is it rendered
  40.         FALSE,              // Is it an output
  41.         FALSE,              // Allowed none
  42.         FALSE,              // Allowed many
  43.         &CLSID_NULL,        // Connects to filter
  44.         L"Output",          // Connects to pin
  45.         1,                  // Number of types
  46.         &sudPinTypes },     // The pin details
  47.       { L"Output",          // String pin name
  48.         FALSE,              // Is it rendered
  49.         TRUE,               // Is it an output
  50.         FALSE,              // Allowed none
  51.         FALSE,              // Allowed many
  52.         &CLSID_NULL,        // Connects to filter
  53.         L"Input",           // Connects to pin
  54.         1,                  // Number of types
  55.         &sudPinTypes        // The pin details
  56.     }
  57. };
  58. const AMOVIESETUP_FILTER sudFilter =
  59. {
  60.     &CLSID_HQTitleOverlay,       // Filter CLSID
  61.     L"HQ Title Overlay Std.",    // Filter name
  62.     MERIT_DO_NOT_USE,        // Its merit
  63.     2,                       // Number of pins
  64.     psudPins                 // Pin details
  65. };
  66. // List of class IDs and creator functions for the class factory. This
  67. // provides the link between the OLE entry point in the DLL and an object
  68. // being created. The class factory will call the static CreateInstance
  69. CFactoryTemplate g_Templates[] = 
  70. {
  71.     { 
  72. L"HQ Title Overlay Std.",
  73. &CLSID_HQTitleOverlay,
  74. CFilterTitleOverlay::CreateInstance,
  75. NULL,
  76. &sudFilter 
  77. },
  78. L"HQ Title Overlay Property Page",
  79. &CLSID_HQTitleOverlayProp,
  80. CTitleOverlayProp::CreateInstance 
  81. }
  82. };
  83. int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
  84. // ----------------------------------------------------------------------------
  85. //            Filter implementation
  86. // ----------------------------------------------------------------------------
  87. CFilterTitleOverlay::CFilterTitleOverlay(TCHAR *tszName, LPUNKNOWN punk, HRESULT *phr) : 
  88. CTransInPlaceFilter(tszName, punk, CLSID_HQTitleOverlay, phr)
  89. {
  90. mOverlayType = OT_STATIC;
  91. mOverlayController     = new COverlayController();
  92. mNeedEstimateFrameRate = FALSE;
  93. char szTitle[] = "Hello, DirectShow!"; 
  94. put_Title(szTitle, sizeof(szTitle));
  95. }
  96. CFilterTitleOverlay::~CFilterTitleOverlay()
  97. {
  98. ReleaseOverlayController();
  99. }
  100. void CFilterTitleOverlay::ReleaseOverlayController(void)
  101. {
  102. if (mOverlayController)
  103. {
  104. delete mOverlayController;
  105. mOverlayController = NULL;
  106. }
  107. }
  108. //
  109. // CreateInstance
  110. //
  111. // Override CClassFactory method.
  112. // Provide the way for COM to create a CNullInPlace object
  113. //
  114. CUnknown * WINAPI CFilterTitleOverlay::CreateInstance(LPUNKNOWN punk, HRESULT *phr) 
  115. {
  116. #if 1
  117. char    szCreatorPath[256], szCreatorName[256];
  118. ::strcpy(szCreatorPath, "");
  119. ::strcpy(szCreatorName, "");
  120. HMODULE hModule = ::GetModuleHandle(NULL);
  121. ::GetModuleFileName(hModule, szCreatorPath, 256);
  122. char * backSlash = ::strrchr(szCreatorPath, '\');
  123. if (backSlash)
  124. {
  125. strcpy(szCreatorName, backSlash);
  126. }
  127. ::_strlwr(szCreatorName);
  128. // Please specify your app name with lowercase
  129. if (::strstr(szCreatorName, "graphedt") == NULL &&
  130. ::strstr(szCreatorName, "ourapp") == NULL)
  131. {
  132. *phr = E_FAIL;
  133. return NULL;
  134. }
  135. #endif
  136. CFilterTitleOverlay *pNewObject = new CFilterTitleOverlay(NAME("TitleOverlay"), punk, phr);
  137. if (pNewObject == NULL) 
  138. {
  139. *phr = E_OUTOFMEMORY;
  140. }
  141. return pNewObject;
  142. //
  143. // Basic COM - used here to reveal our own interfaces
  144. STDMETHODIMP CFilterTitleOverlay::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
  145. {
  146. CheckPointer(ppv, E_POINTER);
  147. if (riid == IID_ISpecifyPropertyPages) 
  148. {
  149. return GetInterface((ISpecifyPropertyPages *) this, ppv);
  150. }
  151. else if (riid == IID_ITitleOverlay)
  152. {
  153. return GetInterface((ITitleOverlay *) this, ppv);
  154. }
  155. else 
  156. {
  157. return CTransInPlaceFilter::NonDelegatingQueryInterface(riid, ppv);
  158. }
  159. } // NonDelegatingQueryInterface
  160. // Only RGB 32/24/565/555 supported 
  161. HRESULT CFilterTitleOverlay::CheckInputType(const CMediaType* mtIn)
  162. {
  163. // Dynamic format change will never be allowed!
  164. if (IsStopped() && *mtIn->Type() == MEDIATYPE_Video)
  165. {
  166. if (*mtIn->Subtype() == MEDIASUBTYPE_RGB32 ||
  167. *mtIn->Subtype() == MEDIASUBTYPE_RGB24 ||
  168. *mtIn->Subtype() == MEDIASUBTYPE_RGB555 ||
  169. *mtIn->Subtype() == MEDIASUBTYPE_RGB565)
  170. {
  171. return NOERROR;
  172. }
  173. }
  174. return E_INVALIDARG;
  175. }
  176. HRESULT CFilterTitleOverlay::Transform(IMediaSample *pSample)
  177. {
  178. // If we cann't read frame rate info from input pin's connection media type,
  179. // We estimate it from the first sample's time stamp!
  180. if (mNeedEstimateFrameRate)
  181. {
  182. mNeedEstimateFrameRate = FALSE;
  183. REFERENCE_TIME  startTime = 0;
  184. REFERENCE_TIME  endTime   = 0;
  185. double          estimated = 25;
  186. if (SUCCEEDED(pSample->GetTime(&startTime, &endTime)))
  187. {
  188. estimated = 1.0 * UNITS / (endTime - startTime);
  189. }
  190. mOverlayController->SetEstimatedFrameRate(estimated);
  191. }
  192. if (mOverlayType != OT_NONE)
  193. {
  194. PBYTE  pData = NULL;
  195. pSample->GetPointer(&pData);
  196. mOverlayController->DoTitleOverlay(pData);
  197. }
  198. return NOERROR;
  199. }
  200. HRESULT CFilterTitleOverlay::SetInputVideoInfoToController(void)
  201. {
  202. if (mOverlayController && m_pInput && m_pInput->IsConnected())
  203. {
  204. CMediaType  mt = m_pInput->CurrentMediaType();
  205. if (mt.formattype != FORMAT_VideoInfo)
  206. {
  207. return E_FAIL;
  208. }
  209. RGB_FORMAT   colorSpace = FT_NONE;
  210. if (mt.subtype == MEDIASUBTYPE_RGB32)  // Determine RGB format
  211. {
  212. colorSpace = FT_RGB32;
  213. }
  214. else if (mt.subtype == MEDIASUBTYPE_RGB24)
  215. {
  216. colorSpace = FT_RGB24;
  217. }
  218. else if (mt.subtype == MEDIASUBTYPE_RGB555)
  219. {
  220. colorSpace = FT_RGB555;
  221. }
  222. else if (mt.subtype == MEDIASUBTYPE_RGB565)
  223. {
  224. colorSpace = FT_RGB565;
  225. }
  226. else if (mt.subtype == MEDIASUBTYPE_RGB8)
  227. {
  228. colorSpace = FT_RGB8;
  229. }
  230. mOverlayController->SetInputColorSpace(colorSpace);
  231. VIDEOINFOHEADER * pHeader = (VIDEOINFOHEADER *) mt.pbFormat;
  232. mNeedEstimateFrameRate    = pHeader->AvgTimePerFrame > 0 ? FALSE : TRUE;
  233. mOverlayController->SetInputVideoInfo(pHeader);
  234. return NOERROR;
  235. }
  236. return E_FAIL;
  237. }
  238. HRESULT CFilterTitleOverlay::CompleteConnect(PIN_DIRECTION direction, IPin *pReceivePin)
  239. {
  240. HRESULT hr = CTransInPlaceFilter::CompleteConnect(direction, pReceivePin);
  241. if (SUCCEEDED(hr) && direction == PINDIR_INPUT)
  242. {
  243. hr = SetInputVideoInfoToController();
  244. }
  245. return hr;
  246. }
  247. HRESULT CFilterTitleOverlay::StartStreaming()
  248. {
  249. BOOL pass = mOverlayController->StartTitleOverlay();
  250. return pass ? S_OK : E_FAIL;
  251. }
  252. HRESULT CFilterTitleOverlay::StopStreaming()
  253. {
  254. mOverlayController->StopTitleOverlay();
  255. return NOERROR;
  256. }
  257. // --- ISpecifyPropertyPages ---
  258. STDMETHODIMP CFilterTitleOverlay::GetPages(CAUUID *pPages)
  259. {
  260. pPages->cElems = 1;
  261. pPages->pElems = (GUID *) CoTaskMemAlloc(sizeof(GUID));
  262. if (pPages->pElems == NULL) 
  263. {
  264. return E_OUTOFMEMORY;
  265. }
  266. *(pPages->pElems) = CLSID_HQTitleOverlayProp;
  267. return NOERROR;
  268. }
  269. // 当字符叠加的类型改变时,需要生成新的应用逻辑控制类对象实例,
  270. // 并且在新生成的控制对象上设置参数信息。
  271. void CFilterTitleOverlay::SideEffectOverlayTypeChanged(void)
  272. {
  273. ReleaseOverlayController();
  274. switch (mOverlayType)
  275. {
  276. case OT_SYSTIME:
  277. mOverlayController = new CSysTimeOverlayController();
  278. break;
  279. case OT_SCROLL_TOP:
  280. mOverlayController = new CScrollController();
  281. ((CScrollController*) mOverlayController)->SetScrollBottomOrTop(FALSE);
  282. break;
  283. case OT_SCROLL_BOTTOM:
  284. mOverlayController = new CScrollController();
  285. ((CScrollController*) mOverlayController)->SetScrollBottomOrTop(TRUE);
  286. break;
  287. case OT_NONE:
  288. case OT_STATIC:
  289. default:
  290. mOverlayController = new COverlayController();
  291. }
  292. // Make sure to set input video info to the new controller 
  293. SetInputVideoInfoToController();
  294. }
  295. // --- ITitleOverlay methods ---
  296. STDMETHODIMP CFilterTitleOverlay::put_TitleOverlayType(long inOverlayType)
  297. {
  298. CAutoLock   lockit(&mITitleOverlaySync);
  299. // When filter graph is active, change overlay type is not allowed!
  300. if (m_State != State_Stopped)
  301. {
  302. return E_UNEXPECTED;
  303. }
  304. if (mOverlayType != (OVERLAY_TYPE)inOverlayType)
  305. {
  306. mOverlayType = (OVERLAY_TYPE)inOverlayType;
  307. SideEffectOverlayTypeChanged();
  308. }
  309. return NOERROR;
  310. }
  311. STDMETHODIMP CFilterTitleOverlay::get_TitleOverlayType(long * outOverlayType)
  312. {
  313. CAutoLock   lockit(&mITitleOverlaySync);
  314. *outOverlayType = mOverlayType;
  315. return NOERROR;
  316. }
  317. STDMETHODIMP CFilterTitleOverlay::put_TitleOverlayStyle(int inUsingCover)
  318. {
  319. CAutoLock   lockit(&mITitleOverlaySync);
  320. mOverlayController->SetOverlayStyle(inUsingCover);
  321. return NOERROR;
  322. }
  323. STDMETHODIMP CFilterTitleOverlay::get_TitleOverlayStyle(int * outUsingCover)
  324. {
  325. CAutoLock   lockit(&mITitleOverlaySync);
  326. mOverlayController->GetOverlayStyle(outUsingCover);
  327. return NOERROR;
  328. }
  329. STDMETHODIMP CFilterTitleOverlay::put_Title(const char * inTitle, int inLength)
  330. {
  331. CAutoLock   lockit(&mITitleOverlaySync);
  332. // When filter graph is active, change title text is not allowed!
  333. if (m_State != State_Stopped)
  334. {
  335. return E_UNEXPECTED;
  336. }
  337. mOverlayController->SetTitle(inTitle, inLength);
  338. return NOERROR;
  339. }
  340. STDMETHODIMP CFilterTitleOverlay::get_Title(char * outBuffer, int * outLength)
  341. {
  342. CAutoLock   lockit(&mITitleOverlaySync);
  343. *outLength = mOverlayController->GetTitle(outBuffer);
  344. return NOERROR;
  345. }
  346. STDMETHODIMP CFilterTitleOverlay::put_TitleColor(BYTE inR, BYTE inG, BYTE inB)
  347. {
  348. CAutoLock   lockit(&mITitleOverlaySync);
  349. mOverlayController->SetTitleColor(inR, inG, inB);
  350. return NOERROR;
  351. }
  352. STDMETHODIMP CFilterTitleOverlay::get_TitleColor(BYTE * outR, BYTE * outG, BYTE * outB)
  353. {
  354. CAutoLock   lockit(&mITitleOverlaySync);
  355. mOverlayController->GetTitleColor(outR, outG, outB);
  356. return NOERROR;
  357. }
  358. STDMETHODIMP CFilterTitleOverlay::put_TitleStartPosition(POINT inStartPos)
  359. {
  360. CAutoLock   lockit(&mITitleOverlaySync);
  361. mOverlayController->SetTitleStartPosition(inStartPos);
  362. return NOERROR;
  363. }
  364. STDMETHODIMP CFilterTitleOverlay::get_TitleStartPosition(POINT * outStartPos)
  365. {
  366. CAutoLock   lockit(&mITitleOverlaySync);
  367. mOverlayController->GetTitleStartPosition(outStartPos);
  368. return NOERROR;
  369. }
  370. STDMETHODIMP CFilterTitleOverlay::put_TitleFont(LOGFONT inFont)
  371. {
  372. CAutoLock   lockit(&mITitleOverlaySync);
  373. mOverlayController->SetTitleFont(inFont);
  374. return NOERROR;
  375. }
  376. STDMETHODIMP CFilterTitleOverlay::get_TitleFont(LOGFONT * outFont)
  377. {
  378. CAutoLock   lockit(&mITitleOverlaySync);
  379. mOverlayController->GetTitleFont(outFont);
  380. return NOERROR;
  381. }
  382. STDMETHODIMP CFilterTitleOverlay::put_TitleDuration(double inStart, double inEnd)
  383. {
  384. CAutoLock   lockit(&mITitleOverlaySync);
  385. mOverlayController->SetTitleDuration(inStart, inEnd);
  386. return NOERROR;
  387. }
  388. STDMETHODIMP CFilterTitleOverlay::get_TitleDuration(double * outStart, double * outEnd)
  389. {
  390. CAutoLock   lockit(&mITitleOverlaySync);
  391. mOverlayController->GetTitleDuration(outStart, outEnd);
  392. return NOERROR;
  393. }
  394. /******************************Public Routine******************************
  395. * exported entry points for registration and
  396. * unregistration (in this case they only call
  397. * through to default implmentations).
  398. *
  399. *
  400. *
  401. * History:
  402. *
  403. **************************************************************************/
  404. STDAPI DllRegisterServer()
  405. {
  406. return AMovieDllRegisterServer2( TRUE );
  407. }
  408. STDAPI DllUnregisterServer()
  409. {
  410. return AMovieDllRegisterServer2( FALSE );
  411. }
  412. // Microsoft C Compiler will give hundreds of warnings about
  413. // unused inline functions in header files.  Try to disable them.
  414. #pragma warning( disable:4514)