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.

405 lines
16 KiB

  1. //
  2. // Copyright (c) 1996 - 1998 Microsoft Corporation. All Rights Reserved.
  3. //
  4. // ActiveMovie Line 21 Decoder filter
  5. //
  6. extern const AMOVIESETUP_FILTER sudLine21Dec ;
  7. #ifndef _INC_L21DFILT_H
  8. #define _INC_L21DFILT_H
  9. #pragma pack(push, 1)
  10. //
  11. // DVD Line21 data come as a user data packet from the GOP header.
  12. // A struct for per frame/field based data and a valid flag definition.
  13. //
  14. // From DVD specifications...
  15. #define AM_L21_GOPUD_HDR_STARTCODE 0x000001B2
  16. #define AM_L21_GOPUD_HDR_INDICATOR 0x4343
  17. #define AM_L21_GOPUD_HDR_RESERVED 0x01F8
  18. #define AM_L21_GOPUD_HDR_TOPFIELD_FLAG 0x1
  19. #define AM_L21_GOPUD_ELEM_MARKERBITS 0x7F
  20. #define AM_L21_GOPUD_ELEM_VALIDFLAG 0x1
  21. // There can be max 63 frames/fields' worth data per packet as there are
  22. // 6 bits to represent this number in the packet.
  23. #define AM_L21_GOPUD_ELEMENT_MAX 63
  24. typedef struct _AM_L21_GOPUD_ELEMENT {
  25. BYTE bMarker_Switch ;
  26. BYTE chFirst ;
  27. BYTE chSecond ;
  28. } AM_L21_GOPUD_ELEMENT, *PAM_L21_GOPUD_ELEMENT ;
  29. typedef struct _AM_L21_GOPUD_HEADER {
  30. BYTE abL21StartCode[4] ;
  31. BYTE abL21Indicator[2] ;
  32. BYTE abL21Reserved[2] ;
  33. BYTE bTopField_Rsrvd_NumElems ;
  34. } AM_L21_GOPUD_HEADER, *PAM_L21_GOPUD_HEADER ;
  35. typedef struct _AM_L21_GOPUD_PACKET {
  36. AM_L21_GOPUD_HEADER Header ;
  37. AM_L21_GOPUD_ELEMENT aElements[AM_L21_GOPUD_ELEMENT_MAX] ;
  38. } AM_L21_GOPUD_PACKET, *PAM_L21_GOPUD_PACKET ;
  39. #define GETGOPUD_NUMELEMENTS(pGOPUDPacket) ((pGOPUDPacket)->Header.bTopField_Rsrvd_NumElems & 0x3F)
  40. #define GETGOPUD_PACKETSIZE(pGOPUDPacket) (LONG)(sizeof(AM_L21_GOPUD_HEADER) + GETGOPUD_NUMELEMENTS(pGOPUDPacket) * sizeof(AM_L21_GOPUD_ELEMENT))
  41. #define GETGOPUDPACKET_ELEMENT(pGOPUDPacket, i) ((pGOPUDPacket)->aElements[i])
  42. #define GETGOPUD_ELEM_MARKERBITS(Elem) ((((Elem).bMarker_Switch & 0xFE) >> 1) & 0x7F)
  43. #define GETGOPUD_ELEM_SWITCHBITS(Elem) ((Elem).bMarker_Switch & 0x01)
  44. #define GETGOPUD_L21STARTCODE(Header) \
  45. ( (DWORD)((Header).abL21StartCode[0]) << 24 | \
  46. (DWORD)((Header).abL21StartCode[1]) << 16 | \
  47. (DWORD)((Header).abL21StartCode[2]) << 8 | \
  48. (DWORD)((Header).abL21StartCode[3]) )
  49. #define GETGOPUD_L21INDICATOR(Header) \
  50. ( (DWORD)((Header).abL21Indicator[0]) << 8 | \
  51. (DWORD)((Header).abL21Indicator[1]) )
  52. #define GETGOPUD_L21RESERVED(Header) \
  53. ( (DWORD)((Header).abL21Reserved[0]) << 8 | \
  54. (DWORD)((Header).abL21Reserved[1]) )
  55. #define GOPUD_HEADERLENGTH (4+2+2+1)
  56. #define GETGOPUD_ELEMENT(pGOPUDPkt, i) (pGOPUDPkt + GOPUD_HEADERLENGTH + sizeof(AM_L21_GOPUD_ELEMENT) * i)
  57. #define ISGOPUD_TOPFIELDFIRST(pGOPUDPacket) ((pGOPUDPacket)->Header.bTopField_Rsrvd_NumElems & 0x80)
  58. //
  59. // ATSC Line21 data come as a user data packet from the GOP header.
  60. // A struct for per frame/field based data and a valid flag definition.
  61. //
  62. // From ATSC Standards for Coding 25/50Hz Video (A/63) specifications...
  63. #define AM_L21_ATSCUD_HDR_STARTCODE 0x000001B2
  64. #define AM_L21_ATSCUD_HDR_IDENTIFIER 0x47413934
  65. #define AM_L21_ATSCUD_HDR_TYPECODE_EIA 0x03
  66. #define AM_L21_ATSCUD_HDR_EM_DATA_FLAG 0x80
  67. #define AM_L21_ATSCUD_HDR_CC_DATA_FLAG 0x40
  68. #define AM_L21_ATSCUD_HDR_ADDL_DATA_FLAG 0x20
  69. #define AM_L21_ATSCUD_HDR_CC_COUNT_MASK 0x1F
  70. #define AM_L21_ATSCUD_HDR_NEXTBITS_ON 0x01
  71. #define AM_L21_ATSCUD_ELEM_MARKERBITS 0xF8
  72. #define AM_L21_ATSCUD_ELEM_VALID_FLAG 0x04
  73. #define AM_L21_ATSCUD_ELEM_TYPE_FLAG 0x03
  74. #define AM_L21_ATSCUD_MARKERBITS 0xFF
  75. #define AM_L21_ATSCUD_HDR_NEXTBITS_FLAG 0x00000100
  76. // There can be max 31 frames/fields' worth data per packet as there are
  77. // 5 bits to represent this number in the packet.
  78. #define AM_L21_ATSCUD_ELEMENT_MAX 31
  79. typedef struct _AM_L21_ATSCUD_ELEMENT {
  80. BYTE bCCMarker_Valid_Type ;
  81. BYTE chFirst ;
  82. BYTE chSecond ;
  83. } AM_L21_ATSCUD_ELEMENT, *PAM_L21_ATSCUD_ELEMENT ;
  84. typedef struct _AM_L21_ATSCUD_HEADER {
  85. BYTE abL21StartCode[4] ;
  86. BYTE abL21Identifier[4] ;
  87. BYTE bL21UDTypeCode ;
  88. BYTE bL21DataFlags_Count ;
  89. BYTE bL21EMData ;
  90. } AM_L21_ATSCUD_HEADER, *PAM_L21_ATSCUD_HEADER ;
  91. typedef struct _AM_L21_ATSCUD_PACKET {
  92. AM_L21_ATSCUD_HEADER Header ;
  93. AM_L21_ATSCUD_ELEMENT aElements[AM_L21_ATSCUD_ELEMENT_MAX] ;
  94. BYTE bMarkerBits ;
  95. } AM_L21_ATSCUD_PACKET, *PAM_L21_ATSCUD_PACKET ;
  96. #define GETATSCUD_NUMELEMENTS(pATSCUDPacket) ((pATSCUDPacket)->Header.bL21DataFlags_Count & AM_L21_ATSCUD_HDR_CC_COUNT_MASK)
  97. #define GETATSCUD_PACKETSIZE(pATSCUDPacket) (LONG)(sizeof(AM_L21_ATSCUD_HEADER) + \
  98. GETATSCUD_NUMELEMENTS(pATSCUDPacket) * sizeof(AM_L21_ATSCUD_ELEMENT) + \
  99. sizeof(BYTE))
  100. #define GETATSCUDPACKET_ELEMENT(pATSCUDPacket, i) ((pATSCUDPacket)->aElements[i])
  101. #define GETATSCUD_ELEM_MARKERBITS(Elem) (((Elem).bCCMarker_Valid_Type & AM_L21_ATSCUD_ELEM_MARKERBITS) >> 3)
  102. #define GETATSCUD_STARTCODE(Header) \
  103. ( (DWORD)((Header).abL21StartCode[0]) << 24 | \
  104. (DWORD)((Header).abL21StartCode[1]) << 16 | \
  105. (DWORD)((Header).abL21StartCode[2]) << 8 | \
  106. (DWORD)((Header).abL21StartCode[3]) )
  107. #define GETATSCUD_IDENTIFIER(Header) \
  108. ( (DWORD)((Header).abL21Identifier[0]) << 24 | \
  109. (DWORD)((Header).abL21Identifier[1]) << 16 | \
  110. (DWORD)((Header).abL21Identifier[2]) << 8 | \
  111. (DWORD)((Header).abL21Identifier[3]) )
  112. #define GETATSCUD_TYPECODE(Header) (DWORD)((Header).bL21UDTypeCode)
  113. #define ISATSCUD_TYPE_EIA(pATSCUDPacket) (AM_L21_ATSCUD_HDR_TYPECODE_EIA == \
  114. ((pATSCUDPacket)->Header.bL21UDTypeCode & 0xFF))
  115. #define ISATSCUD_EM_DATA(pATSCUDPacket) (AM_L21_ATSCUD_HDR_EM_DATA_FLAG == \
  116. ((pATSCUDPacket)->Header.bL21DataFlags_Count & AM_L21_ATSCUD_HDR_EM_DATA_FLAG))
  117. #define ISATSCUD_CC_DATA(pATSCUDPacket) (AM_L21_ATSCUD_HDR_CC_DATA_FLAG == \
  118. ((pATSCUDPacket)->Header.bL21DataFlags_Count & AM_L21_ATSCUD_HDR_CC_DATA_FLAG))
  119. #define ISATSCUD_ADDL_DATA(pATSCUDPacket) (AM_L21_ATSCUD_HDR_ADDL_DATA_FLAG == \
  120. ((pATSCUDPacket)->Header.bL21DataFlags_Count & AM_L21_ATSCUD_HDR_ADDL_DATA_FLAG))
  121. #define GETATSCUD_EM_DATA(pATSCUDPacket) ((pATSCUDPacket)->Header.bL21EMData)
  122. #define ISATSCUD_ELEM_MARKERBITS_VALID(Elem) (AM_L21_ATSCUD_ELEM_MARKERBITS == \
  123. ((Elem).bCCMarker_Valid_Type & AM_L21_ATSCUD_ELEM_MARKERBITS))
  124. #define ISATSCUD_ELEM_CCVALID(Elem) (AM_L21_ATSCUD_ELEM_VALID_FLAG == \
  125. ((Elem).bCCMarker_Valid_Type & AM_L21_ATSCUD_ELEM_VALID_FLAG))
  126. #define GETATSCUD_ELEM_CCTYPE(Elem) (DWORD)((Elem).bCCMarker_Valid_Type & AM_L21_ATSCUD_ELEM_TYPE_FLAG))
  127. #define GETATSCUD_MARKERBITS(pATSCUDPacket) (DWORD)((pATSCUDPacket)->bMarkerBits)
  128. #define ISATSCUD_MARKER_BITSVALID(pATSCUDPacket) (AM_L21_ATSCUD_MARKERBITS == \
  129. ((pATSCUDPacket)->bMarkerBits & AM_L21_ATSCUD_MARKERBITS))
  130. // Header = StartCode + Id + TypeCode + (EM_CC_Addl_Data + CCCount) + EM_Data
  131. #define ATSCUD_HEADERLENGTH (4+4+1+1+1)
  132. #define GETATSCUD_ELEMENT(pATSCUDPkt, i) ((BYTE)(pATSCUDPkt) + ATSCUD_HEADERLENGTH + \
  133. sizeof(AM_L21_ATSCUD_ELEMENT) * i)
  134. // CC type in GOP packet
  135. typedef enum {
  136. GOP_CCTYPE_Unknown = 0, // Invalid
  137. GOP_CCTYPE_None, // all 0 -- filler packet
  138. GOP_CCTYPE_DVD, // DVD CC packets
  139. GOP_CCTYPE_ATSC, // ATSC CC packets
  140. } GOPPACKET_CCTYPE ;
  141. // Some more flag, struct and macro definitions...
  142. #define AM_L21_INFO_FIELDBASED 0x0001
  143. #define AM_L21_INFO_TOPFIELDFIRST 0x0003
  144. #define AM_L21_INFO_BOTTOMFIELDFIRST 0x0005
  145. typedef struct _AM_LINE21INFO {
  146. DWORD dwFieldFlags ;
  147. UINT uWidth ;
  148. UINT uHeight ;
  149. UINT uBitDepth ;
  150. DWORD dwAvgMSecPerSample ;
  151. } AM_LINE21INFO, *PAM_LINE21INFO ;
  152. //
  153. // Message Window class (for handling WM_TIMER messages) definition
  154. //
  155. class CMessageWindow
  156. {
  157. public:
  158. CMessageWindow() ;
  159. ~CMessageWindow() ;
  160. HWND GetHandle() {
  161. return m_hWnd ;
  162. } ;
  163. int AddCount() {
  164. m_iCount++ ;
  165. return m_iCount ;
  166. } ;
  167. int ReleaseCount() {
  168. if (GetHandle() == NULL) // something wrong -- get out of here
  169. return 0 ;
  170. m_iCount-- ;
  171. ASSERT(m_iCount >= 0) ;
  172. if (m_iCount < 0) // paranoia!!!
  173. m_iCount = 0 ;
  174. return m_iCount ;
  175. } ;
  176. private:
  177. HWND m_hWnd ;
  178. int m_iCount ;
  179. static LRESULT CALLBACK MsgWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
  180. } ;
  181. #define ISRECTEQUAL(r1, r2) (r1.top == r2.top && r1.left == r2.left && r1.right == r2.right && r1.bottom == r2.bottom)
  182. //
  183. // Line 21 Decoder class definition
  184. //
  185. class CLine21DecFilter : public CTransformFilter,
  186. // public ISpecifyPropertyPages, -- WILL DO LATER
  187. public IAMLine21Decoder
  188. {
  189. friend class CMessageWindow ;
  190. private:
  191. static CMessageWindow *m_pMsgWnd ; // hidden window to process WM_TIMER messages
  192. public:
  193. //
  194. // Constructor and destructor
  195. //
  196. CLine21DecFilter(TCHAR *, LPUNKNOWN, HRESULT *) ;
  197. ~CLine21DecFilter() ;
  198. //
  199. // Standard COM stuff
  200. //
  201. // this goes in the factory template table to create new instances
  202. static CUnknown * CreateInstance(LPUNKNOWN, HRESULT *) ;
  203. static void InitClass(BOOL, const CLSID *) ;
  204. STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void **ppv) ;
  205. DECLARE_IUNKNOWN ;
  206. //
  207. // CTranformFilter overrides
  208. //
  209. // I must override it
  210. HRESULT Transform(IMediaSample * pIn, IMediaSample * pOut) ;
  211. // Real stuff is in here...
  212. HRESULT Receive(IMediaSample * pIn) ;
  213. // check if you can support mtIn
  214. HRESULT CheckInputType(const CMediaType* mtIn) ;
  215. // check if you can support the transform from this input to
  216. // this output
  217. HRESULT CheckTransform(const CMediaType* mtIn,
  218. const CMediaType* mtOut) ;
  219. // called from CBaseOutputPin to prepare the allocator's count
  220. // of buffers and sizes
  221. HRESULT DecideBufferSize(IMemAllocator * pAllocator,
  222. ALLOCATOR_PROPERTIES *pProperties) ;
  223. // overriden to know when the media type is set
  224. HRESULT SetMediaType(PIN_DIRECTION direction,const CMediaType *pmt) ;
  225. // overriden to suggest OUTPUT pin media types
  226. HRESULT GetMediaType(int iPosition, CMediaType *pMediaType) ;
  227. HRESULT EndOfStream(void) ;
  228. HRESULT BeginFlush(void) ;
  229. HRESULT EndFlush(void) ;
  230. STDMETHODIMP GetState(DWORD dwMSecs, FILTER_STATE *State) ;
  231. // overridden to know when we're starting/stopping the decoding
  232. STDMETHODIMP Stop(void) ;
  233. STDMETHODIMP Pause(void) ;
  234. // overridden to know when connections are completed, so that we can get
  235. // the media type (actualy format) info for caching
  236. HRESULT CompleteConnect(PIN_DIRECTION dir, IPin *pReceivePin) ;
  237. // Override to know when we disconnect from in/output side to not use
  238. // any specified output format any more.
  239. HRESULT BreakConnect(PIN_DIRECTION dir) ;
  240. #if 0 // no QM for now
  241. // We also override this one as we handle the quality management messages
  242. HRESULT AlterQuality(Quality q) ;
  243. #endif // #if 0
  244. //
  245. // ISpecifyPropertyPages method
  246. //
  247. // STDMETHODIMP GetPages(CAUUID *pPages) ;
  248. //
  249. // IAMLine21Decoder interface methods
  250. //
  251. STDMETHODIMP GetDecoderLevel(AM_LINE21_CCLEVEL *lpLevel) ;
  252. STDMETHODIMP GetCurrentService(AM_LINE21_CCSERVICE *lpService) ;
  253. STDMETHODIMP SetCurrentService(AM_LINE21_CCSERVICE Service) ;
  254. STDMETHODIMP GetServiceState(AM_LINE21_CCSTATE *lpState) ;
  255. STDMETHODIMP SetServiceState(AM_LINE21_CCSTATE State) ;
  256. STDMETHODIMP GetOutputFormat(LPBITMAPINFOHEADER lpbmih) ;
  257. STDMETHODIMP SetOutputFormat(LPBITMAPINFO lpbmi) ;
  258. STDMETHODIMP GetBackgroundColor(DWORD *pdwPhysColor) ;
  259. STDMETHODIMP SetBackgroundColor(DWORD dwPhysColor) ;
  260. STDMETHODIMP GetRedrawAlways(LPBOOL lpbOption) ;
  261. STDMETHODIMP SetRedrawAlways(BOOL bOption) ;
  262. STDMETHODIMP GetDrawBackgroundMode(AM_LINE21_DRAWBGMODE *lpMode) ;
  263. STDMETHODIMP SetDrawBackgroundMode(AM_LINE21_DRAWBGMODE Mode) ;
  264. private: // data
  265. // Pointer to output buffer (cacheing for efficiency)
  266. LPBYTE m_pbOutBuffer ;
  267. // Line21 Data Decoder class that takes 2 bytes and converts to a bitmap
  268. CLine21DataDecoder m_L21Dec ;
  269. // What input format type is being used (better to use an integer flag)
  270. AM_LINE21_CCSUBTYPEID m_eSubTypeIDIn ;
  271. GOPPACKET_CCTYPE m_eGOP_CCType ; // if GOPPackets used, what type data (DVD/ATSC/...)
  272. REFERENCE_TIME m_rtTimePerSample ; // (in 100 nSec) interval per byte pair from a packet (for GOP packet type)
  273. REFERENCE_TIME m_rtStart ; // start time for an output sample
  274. REFERENCE_TIME m_rtStop ; // stop time for an out output sample
  275. REFERENCE_TIME m_rtLastSample ; // start time of last delivered sample
  276. LONGLONG m_llMediaStart ; // media time start (rarely used, but...)
  277. REFERENCE_TIME m_llMediaStop ; // media time stop (rarely used, but...)
  278. // flag to detect if we must send an output sample
  279. BOOL m_bMustOutput ;
  280. // flag to remember if the last input sample was a discontiuity sample
  281. BOOL m_bDiscontLast ;
  282. // If the upstream filter doesn't specify any format type, use one from
  283. // our internal defaults
  284. VIDEOINFO *m_pviDefFmt ;
  285. DWORD m_dwDefFmtSize ;
  286. // Keep a copy of last output sample's bounding rect
  287. RECT m_rectLastOutput ;
  288. IPin *m_pPinDown ; // downstream pin connected to our output
  289. CMediaType m_mtOutput ; // current output mediatype (cached)
  290. //
  291. // For timer arrangement to complete any scrolling in roll-up mode
  292. // or to clear old CC (only in byte pair mode as DVD doesn't need it),
  293. // if input data flow stops in the middle.
  294. //
  295. UINT_PTR m_uTimerID ; // timer id
  296. UINT m_uTimerCount ; // count of how many times TimerProc() was entered;
  297. // used for timing out CC in byte pair mode.
  298. BOOL m_bTimerClearReqd ; // timer reqd for clearing old CC
  299. //
  300. // Data for Blending Param operation on the OverlayMixer's in pin
  301. //
  302. DWORD m_dwBlendParam ; // blend param from Get..() call
  303. BOOL m_bBlendingState ; // CC blending state last set
  304. #if 0 // no QM for now
  305. // number of samples to skip between every output CC sample for QM handling
  306. int m_iSkipSamples ;
  307. #endif // #if 0
  308. #ifdef PERF
  309. int m_idDelvWait ;
  310. #endif // PERF
  311. private: // functions
  312. void GetActualColorKey(void) ;
  313. AM_LINE21_CCSUBTYPEID MapGUIDToID(const GUID *pFormatIn) ;
  314. BOOL VerifyGOPUDPacketData(PAM_L21_GOPUD_PACKET pGOPUDPacket) ;
  315. BOOL VerifyATSCUDPacketData(PAM_L21_ATSCUD_PACKET pATSCUDPacket) ;
  316. BOOL IsFillerPacket(BYTE *pGOPPacket) ;
  317. DWORD GetOwnPalette(int iNumEntries, PALETTEENTRY *ppe) ;
  318. HRESULT GetDefaultFormatInfo(void) ;
  319. BOOL IsValidFormat(BYTE *pbFormat) ;
  320. HRESULT SendOutputSample(IMediaSample *pIn,
  321. REFERENCE_TIME *prtStart, REFERENCE_TIME *prtStop) ;
  322. void SetBlendingState(BOOL bState) ;
  323. void SetupTimerIfReqd(BOOL bTimerClearReqd) ;
  324. void FreeTimer(void) ;
  325. static void CALLBACK TimerProc(HWND hWnd, UINT uMsg, UINT_PTR uID, DWORD dwTime) ;
  326. GOPPACKET_CCTYPE DetectGOPPacketDataType(BYTE *pGOPPacket) ;
  327. HRESULT ProcessGOPPacket_DVD(IMediaSample *pIn) ;
  328. HRESULT ProcessGOPPacket_ATSC(IMediaSample *pIn) ;
  329. #if 0 // no QM for now
  330. inline int GetSkipSamples(void) { return m_iSkipSamples ; }
  331. inline void ResetSkipSamples(void) { m_iSkipSamples = 0 ; } ;
  332. #endif // #if 0
  333. } ;
  334. #pragma pack(pop)
  335. #endif // _INC_L21DFILT_H