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.

421 lines
11 KiB

  1. // $Header: G:/SwDev/WDM/Video/bt848/rcs/Field.h 1.12 1998/05/08 18:18:51 tomz Exp $
  2. #ifndef __FIELD_H
  3. #define __FIELD_H
  4. /* Type: VideoStream
  5. * Purpose: Identifies a video stream channel
  6. * Note: Not all of these are used today. It should be a fairly minor job to
  7. * start using them, though
  8. */
  9. typedef enum
  10. {
  11. VS_Below = -1,
  12. VS_Field1, VS_Field2, VS_VBI1, VS_VBI2, VS_Analog, VS_CC, VS_EDS,
  13. VS_Raw,
  14. VS_Above
  15. } VideoStream;
  16. #define STREAM_IDX_CAPTURE 0
  17. #define STREAM_IDX_PREVIEW 1
  18. #define STREAM_IDX_VBI 2
  19. #define STREAM_IDX_ANALOG 3
  20. #include "mytypes.h"
  21. #include "scaler.h"
  22. #include "pscolspc.h"
  23. #include "viddefs.h"
  24. #include "queue.h"
  25. #include "preg.h"
  26. #include "chanifac.h"
  27. const MaxProgsForField = 2;
  28. typedef Queue<DataBuf> VidBufQueue;
  29. /* Class: Field
  30. * Purpose: Encapsulates the operation of a single video field provided by BtPisces
  31. * Attributes:
  32. * Operations:
  33. */
  34. extern "C" VOID STREAMAPI AdapterCancelPacket(IN PHW_STREAM_REQUEST_BLOCK Srb);
  35. class Field
  36. {
  37. private:
  38. PsColorSpace LocalColSpace_;
  39. VidBufQueue *BufQue_;
  40. DWORD dwPitch_;
  41. bool Started_;
  42. int SkipCount_;
  43. long TimePerFrame_;
  44. LONGLONG LapsedTime_;
  45. LONG FrameTiming_;
  46. VideoStream VidStrm_;
  47. // used to notify video channel
  48. ChanIface *callback_;
  49. bool Paired_;
  50. bool ready_;
  51. // this is used by the video channel to report timestamps
  52. LONGLONG InterruptCounter_;
  53. LONGLONG FrameCounter_;
  54. RegField &CaptureEnable_;
  55. public:
  56. bool Interrupt_;
  57. Field( RegField &CapEn, RegBase *ColReg, RegBase *WordSwap,
  58. RegBase *ByteSwap );
  59. virtual ~Field() {}
  60. inline void CancelSrbList( )
  61. {
  62. while( !BufQue_->IsEmpty( ) )
  63. {
  64. DataBuf buf = BufQue_->Get();
  65. AdapterCancelPacket( buf.pSrb_ );
  66. }
  67. BufQue_->Flush();
  68. }
  69. void Notify( PVOID pTag, bool skipped )
  70. { if ( callback_ ) callback_->Notify( pTag, skipped ); }
  71. void SetStreamID( VideoStream );
  72. VideoStream GetStreamID();
  73. void ResetCounters();
  74. virtual ErrorCode SetAnalogWindow( MRect &r ) = 0;
  75. virtual void GetAnalogWindow( MRect &r ) = 0;
  76. virtual ErrorCode SetDigitalWindow( MRect &r ) = 0;
  77. virtual void GetDigitalWindow( MRect &r ) = 0;
  78. void SetBufPitch( DWORD dwP ) {
  79. dwPitch_ = dwP;
  80. DebugOut((1, "SetBufPitch(%d)\n", dwPitch_));
  81. }
  82. DWORD GetBufPitch() { return dwPitch_; }
  83. virtual void SetColorFormat( ColFmt aColor )
  84. { LocalColSpace_.SetColorFormat( aColor ); }
  85. virtual ColFmt GetColorFormat()
  86. { return LocalColSpace_.GetColorFormat(); }
  87. DataBuf GetNextBuffer();
  88. void SetFrameRate( long time );
  89. void SetPaired( bool p );
  90. bool GetPaired();
  91. void SetReady( bool flag );
  92. bool GetReady();
  93. void SetBufQuePtr( VidBufQueue *pQ ) { BufQue_ = pQ; }
  94. VidBufQueue &GetCurrentQue() { return *BufQue_; }
  95. void SetCallback( ChanIface *iface ) { callback_ = iface;}
  96. State Start();
  97. void Stop();
  98. bool IsStarted() { return Started_; }
  99. State Skip();
  100. // called by the BtPiscess::ProcessRISCIntr()
  101. void GotInterrupt() { InterruptCounter_++; }
  102. void GetCounters( LONGLONG &FrameNo, LONGLONG &drop );
  103. void SetStandardTiming( LONG t );
  104. LONG GetStandardTiming();
  105. };
  106. /* Class: FieldWithScaler
  107. * Purpose: Adds scaling capability to a field
  108. * Attributes:
  109. * Operations:
  110. */
  111. class FieldWithScaler : public Field
  112. {
  113. private:
  114. Scaler LocalScaler_;
  115. public:
  116. FieldWithScaler( RegField &CapEn, VidField field, RegBase *ColReg,
  117. RegBase *WordSwap, RegBase *ByteSwap ) : LocalScaler_( field ),
  118. Field( CapEn, ColReg, WordSwap, ByteSwap ) {}
  119. virtual ErrorCode SetAnalogWindow( MRect &r ) { return LocalScaler_.SetAnalogWin( r ); }
  120. virtual void GetAnalogWindow( MRect &r ) { LocalScaler_.GetAnalogWin( r ); }
  121. virtual ErrorCode SetDigitalWindow( MRect &r ) { return LocalScaler_.SetDigitalWin( r ); }
  122. virtual void GetDigitalWindow( MRect &r ) { LocalScaler_.GetDigitalWin( r ); }
  123. void VideoFormatChanged( VideoFormat format );
  124. void TurnVFilter( State s );
  125. };
  126. /* Class: VBIField
  127. * Purpose: Encapsulates the operation of a VBI data 'field'
  128. * Attributes:
  129. * Operations:
  130. */
  131. class VBIField : public Field
  132. {
  133. private:
  134. DECLARE_VBIPACKETSIZE;
  135. DECLARE_VBIDELAY;
  136. MRect AnalogWin_;
  137. MRect DigitalWin_;
  138. public:
  139. VBIField( RegField &CapEn ) : Field( CapEn, NULL, NULL, NULL ),
  140. CONSTRUCT_VBIPACKETSIZE, CONSTRUCT_VBIDELAY
  141. {}
  142. virtual void SetColorFormat( ColFmt ) {}
  143. virtual ColFmt GetColorFormat() { return CF_VBI; };
  144. virtual ErrorCode SetAnalogWindow( MRect &r ) { AnalogWin_ = r; return Success; }
  145. virtual void GetAnalogWindow( MRect &r ) { r = AnalogWin_; }
  146. virtual ErrorCode SetDigitalWindow( MRect &r )
  147. {
  148. DigitalWin_ = r;
  149. DWORD dwNoOfDWORDs = r.Width() / 4;
  150. // SetBufPitch( r.Width() * ColorSpace( CF_VBI ).GetBitCount() / 8 );
  151. VBI_PKT_LO = (BYTE)dwNoOfDWORDs;
  152. VBI_PKT_HI = dwNoOfDWORDs > 0xff; // set the 9th bit
  153. VBI_HDELAY = r.left;
  154. return Success;
  155. }
  156. virtual void GetDigitalWindow( MRect &r ) { r = DigitalWin_; }
  157. ~VBIField() {}
  158. };
  159. inline Field::Field( RegField &CapEn, RegBase *ColReg, RegBase *WordSwap,
  160. RegBase *ByteSwap ) : SkipCount_( 0 ), CaptureEnable_( CapEn ),
  161. LocalColSpace_( CF_RGB32, *ColReg, *WordSwap, *ByteSwap ),
  162. Started_( false ), callback_( NULL ), BufQue_( NULL ), dwPitch_( 0 ),
  163. TimePerFrame_( 333667 ), LapsedTime_( 0 ),InterruptCounter_( 0 ),
  164. FrameCounter_( 0 ), Interrupt_( true ), FrameTiming_( 333667 )
  165. {
  166. }
  167. /* Method: Field::SetFrameRate
  168. * Purpose: Sets frame rate
  169. * Input: time: long, time in 100s nanoseconds per frame
  170. */
  171. inline void Field::SetFrameRate( long time )
  172. {
  173. TimePerFrame_ = time;
  174. // this is needed to make sure very first get returns a buffer
  175. LapsedTime_ = time;
  176. }
  177. inline void Field::SetStreamID( VideoStream st )
  178. {
  179. VidStrm_ = st;
  180. }
  181. inline VideoStream Field::GetStreamID()
  182. {
  183. return VidStrm_;
  184. }
  185. inline void Field::SetPaired( bool p )
  186. {
  187. Paired_ = p;
  188. }
  189. inline bool Field::GetPaired()
  190. {
  191. return Paired_;
  192. }
  193. inline void Field::GetCounters( LONGLONG &FrameNo, LONGLONG &drop )
  194. {
  195. // Frame number is what frame index we should be on.
  196. // Use interrupt count, not just frames returned.
  197. FrameNo = InterruptCounter_;
  198. // Drop count = number of interrupts - number of completed buffers
  199. drop = InterruptCounter_ - FrameCounter_;
  200. if ( drop > 0 )
  201. {
  202. drop--;
  203. // We've reported the drops, so show frame count as caught
  204. // up to interrupt count
  205. FrameCounter_ += drop;
  206. DebugOut((1, "%d,", drop));
  207. }
  208. else if ( drop < 0 )
  209. {
  210. DebugOut((1, "*** %d ***,", drop));
  211. }
  212. else
  213. {
  214. DebugOut((1, "0,"));
  215. }
  216. }
  217. inline void Field::ResetCounters()
  218. {
  219. FrameCounter_ = InterruptCounter_ = 0;
  220. }
  221. inline void Field::SetReady( bool flag )
  222. {
  223. ready_ = flag;
  224. }
  225. inline bool Field::GetReady()
  226. {
  227. return ready_;
  228. }
  229. inline void Field::SetStandardTiming( LONG t )
  230. {
  231. FrameTiming_ = t;
  232. }
  233. inline LONG Field::GetStandardTiming()
  234. {
  235. return FrameTiming_;
  236. }
  237. /* Method: Field::GetNextBuffer
  238. * Purpose: Returns next buffer from the queue, if time is correct for it.
  239. * Input: None
  240. */
  241. inline DataBuf Field::GetNextBuffer()
  242. {
  243. // that's how long it takes to capture a frame of video
  244. LapsedTime_ += GetStandardTiming();
  245. DataBuf buf;
  246. // [TMZ] [!!!] - hack, disable wait 'cause it doesn't work
  247. //if ( LapsedTime_ >= TimePerFrame_ ) {
  248. if ( 1 ) {
  249. // have to increment the frame number if we want that frame only
  250. if ( IsStarted() ) {
  251. GotInterrupt();
  252. }
  253. //#define FORCE_BUFFER_SKIP_TESTING
  254. #ifdef FORCE_BUFFER_SKIP_TESTING
  255. static int iTestSkip = 0;
  256. BOOL bEmpty = BufQue_->IsEmpty();
  257. DebugOut((0, "Queue(%x) bEmpty = %d\n", BufQue_, bEmpty));
  258. if ( iTestSkip++ & 1 ) {
  259. // Every other query should look like the buffer is empty.
  260. bEmpty = TRUE;
  261. DebugOut((1, " [override] set bEmpty = %d\n", bEmpty));
  262. }
  263. if ( !bEmpty ) {
  264. buf = BufQue_->Get();
  265. DebugOut((1, " GotBuf addr %X\n", buf.pData_ ) );
  266. LapsedTime_ = 0;
  267. FrameCounter_++;
  268. } else {
  269. DebugOut((1, " No buffer in que at %d\n",LapsedTime_));
  270. if ( !IsStarted() ) {
  271. InterruptCounter_--;
  272. FrameCounter_--;
  273. }
  274. }
  275. #else
  276. if ( !BufQue_->IsEmpty() ) {
  277. buf = BufQue_->Get();
  278. DebugOut((1, "GotBuf addr %X\n", buf.pData_ ) );
  279. LapsedTime_ = 0;
  280. FrameCounter_++;
  281. } else {
  282. DebugOut((1, "No buffer in que at %d\n",LapsedTime_));
  283. if ( !IsStarted() ) {
  284. InterruptCounter_--;
  285. FrameCounter_--;
  286. }
  287. }
  288. #endif
  289. }
  290. DebugOut((1, "returning buf {pSrb=%x, pData=%x}\n", buf.pSrb_, buf.pData_ ) );
  291. return buf;
  292. }
  293. /* Method: Field::Start
  294. * Purpose: Initiates the data flow out of decoder into the FIFO
  295. * Input: None
  296. * Output: State: Off if channel was off; On if channel was on
  297. */
  298. inline State Field::Start()
  299. {
  300. Trace t("Field::Start()");
  301. Started_ = true;
  302. State RetVal = SkipCount_ >= MaxProgsForField ? Off : On;
  303. SkipCount_--;
  304. if ( SkipCount_ < 0 )
  305. SkipCount_ = 0;
  306. CaptureEnable_ = On;
  307. return RetVal;
  308. }
  309. inline void Field::Stop()
  310. {
  311. Trace t("Field::Stop()");
  312. Started_ = false;
  313. CaptureEnable_ = Off;
  314. LapsedTime_ = TimePerFrame_;
  315. }
  316. /* Method: Field::Skip
  317. * Purpose: Increments the skip count and stops the data flow if it exceeds the max
  318. * Input: None
  319. * Output: State: Off if channel is stopped; On if channel remains running
  320. */
  321. inline State Field::Skip()
  322. {
  323. Trace t("Field::Skip()");
  324. SkipCount_++;
  325. if ( SkipCount_ >= MaxProgsForField ) {
  326. Stop();
  327. return Off;
  328. }
  329. return On;
  330. }
  331. inline void FieldWithScaler::VideoFormatChanged( VideoFormat format )
  332. {
  333. LocalScaler_.VideoFormatChanged( format );
  334. }
  335. inline void FieldWithScaler::TurnVFilter( State s )
  336. {
  337. LocalScaler_.TurnVFilter( s );
  338. }
  339. #endif