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.

1390 lines
49 KiB

  1. // $Header: G:/SwDev/WDM/Video/bt848/rcs/Decoder.cpp 1.5 1998/04/29 22:43:31 tomz Exp $
  2. #include "mytypes.h"
  3. #include "Scaler.h"
  4. #include "decoder.h"
  5. #include "constr.h"
  6. #include "dcdrvals.h"
  7. #define CON_vs_BRI // HW does contrast incorrectly, try to adjust in SW
  8. //===========================================================================
  9. // Bt848 Decoder Class Implementation
  10. //===========================================================================
  11. /////////////////////////////////////////////////////////////////////////////
  12. // Constructor
  13. /////////////////////////////////////////////////////////////////////////////
  14. Decoder::Decoder( DWORD *xtals ) :
  15. // init register min, max, default
  16. m_regHue( HueMin, HueMax, HueDef ),
  17. m_regSaturationNTSC( SatMinNTSC, SatMaxNTSC, SatDefNTSC ),
  18. m_regSaturationSECAM( SatMinSECAM, SatMaxSECAM, SatDefSECAM ),
  19. m_regContrast( ConMin, ConMax, ConDef ),
  20. m_regBrightness( BrtMin, BrtMax, BrtDef ),
  21. m_param( ParamMin, ParamMax, ParamDef ),
  22. CONSTRUCT_REGISTERS
  23. {
  24. Xtals_ [0] = *xtals;
  25. Xtals_ [1] = *(xtals + 1 );
  26. // need to set this to 0x4F
  27. decRegWC_UP = 0x4F;
  28. // and this one to 0x7F to make sure CRUSH bit works
  29. decRegWC_DN = 0x7F;
  30. // HACTIVE should always be 0
  31. decFieldHACTIVE = 0;
  32. // HSFMT (odd and even) should always be 0
  33. decFieldHSFMT = decFieldODD_HSFMT = 0;
  34. // Instead of using default values, set some registers fields to optimum values
  35. SetLumaDecimation( true );
  36. SetChromaAGC( true );
  37. SetLowColorAutoRemoval( true );
  38. SetAdaptiveAGC( false );
  39. // for contrast adjustment purpose
  40. regBright = 0x00; // brightness register value before adjustment
  41. regContrast = 0xD8; // contrast register value before adjustment
  42. // Initialize these Values so we can Get the correct property values jbc 3/13/98
  43. // Perhaps get should read the actual values set in the decoder but this is quick and works for now
  44. // [!!!]
  45. m_briParam = 5000; // jbc 3/13/98
  46. m_satParam = 5000; // jbc 3/13/98
  47. m_conParam = 5000; // jbc 3/13/98
  48. m_hueParam = 5000; // jbc 3/13/98
  49. };
  50. /////////////////////////////////////////////////////////////////////////////
  51. // Destructor
  52. /////////////////////////////////////////////////////////////////////////////
  53. Decoder::~Decoder()
  54. {
  55. }
  56. //===== Device Status register ==============================================
  57. /////////////////////////////////////////////////////////////////////////////
  58. // Method: BYTE Decoder::GetDeviceStatusReg( void )
  59. // Purpose: Obtain device status register value
  60. // Input: None
  61. // Output: None
  62. // Return: value of status register in BYTE
  63. /////////////////////////////////////////////////////////////////////////////
  64. BYTE Decoder::GetDeviceStatusReg( void )
  65. {
  66. BYTE status = (BYTE)decRegSTATUS;
  67. decRegSTATUS = 0x00;
  68. return status;
  69. }
  70. /////////////////////////////////////////////////////////////////////////////
  71. // Method: bool Decoder::IsVideoPresent( void )
  72. // Purpose: Detect if video is present
  73. // Input: None
  74. // Output: None
  75. // Return: true if video present; else false
  76. /////////////////////////////////////////////////////////////////////////////
  77. bool Decoder::IsVideoPresent( void )
  78. {
  79. return (bool) (decFieldPRES == 1);
  80. }
  81. /////////////////////////////////////////////////////////////////////////////
  82. // Method: bool Decoder::IsDeviceInHLock( void )
  83. // Purpose: Detect if device is in H-lock
  84. // Input: None
  85. // Output: None
  86. // Return: true if device in H-lock; else false
  87. /////////////////////////////////////////////////////////////////////////////
  88. bool Decoder::IsDeviceInHLock( void )
  89. {
  90. return (bool) (decFieldHLOC == 1);
  91. }
  92. /////////////////////////////////////////////////////////////////////////////
  93. // Method: bool Decoder::IsEvenField( void )
  94. // Purpose: Reflect whether an even or odd field is being decoded
  95. // Input: None
  96. // Output: None
  97. // Return: true if even field; else false
  98. /////////////////////////////////////////////////////////////////////////////
  99. bool Decoder::IsEvenField( void )
  100. {
  101. return (bool) (decFieldEVENFIELD == 1);
  102. }
  103. /////////////////////////////////////////////////////////////////////////////
  104. // Method: bool Decoder::Is525LinesVideo( void )
  105. // Purpose: Check to see if we are dealing with 525 lines video signal
  106. // Input: None
  107. // Output: None
  108. // Return: true if 525 lines detected; else false (assume 625 lines)
  109. /////////////////////////////////////////////////////////////////////////////
  110. bool Decoder::Is525LinesVideo( void )
  111. {
  112. return (bool) (decFieldNUML == 0); //525
  113. }
  114. /////////////////////////////////////////////////////////////////////////////
  115. // Method: bool Decoder::IsCrystal0Selected( void )
  116. // Purpose: Reflect whether XTAL0 or XTAL1 is selected
  117. // Input: None
  118. // Output: None
  119. // Return: true if XTAL0 selected; else false (XTAL1 selected)
  120. /////////////////////////////////////////////////////////////////////////////
  121. bool Decoder::IsCrystal0Selected( void )
  122. {
  123. return (bool) (decFieldCSEL == 0);
  124. }
  125. /////////////////////////////////////////////////////////////////////////////
  126. // Method: bool Decoder::IsLumaOverflow( void )
  127. // Purpose: Indicates if luma ADC overflow
  128. // Input: None
  129. // Output: None
  130. // Return: true if luma ADC overflow; else false
  131. /////////////////////////////////////////////////////////////////////////////
  132. bool Decoder::IsLumaOverflow( void )
  133. {
  134. return (bool) (decFieldLOF == 1);
  135. }
  136. /////////////////////////////////////////////////////////////////////////////
  137. // Method: void Decoder::ResetLumaOverflow( void )
  138. // Purpose: Reset luma ADC overflow bit
  139. // Input: None
  140. // Output: None
  141. // Return: None
  142. /////////////////////////////////////////////////////////////////////////////
  143. void Decoder::ResetLumaOverflow( void )
  144. {
  145. decFieldLOF = 0; // write to it will reset the bit
  146. }
  147. /////////////////////////////////////////////////////////////////////////////
  148. // Method: bool Decoder::IsChromaOverflow( void )
  149. // Purpose: Indicates if chroma ADC overflow
  150. // Input: None
  151. // Output: None
  152. // Return: true if chroma ADC overflow; else false
  153. /////////////////////////////////////////////////////////////////////////////
  154. bool Decoder::IsChromaOverflow( void )
  155. {
  156. return (bool) (decFieldCOF == 1);
  157. }
  158. /////////////////////////////////////////////////////////////////////////////
  159. // Method: void Decoder::ResetChromaOverflow( void )
  160. // Purpose: Reset chroma ADC overflow bit
  161. // Input: None
  162. // Output: None
  163. // Return: None
  164. /////////////////////////////////////////////////////////////////////////////
  165. void Decoder::ResetChromaOverflow( void )
  166. {
  167. decFieldCOF = 0; // write to it will reset the bit
  168. }
  169. //===== Input Format register ===============================================
  170. /////////////////////////////////////////////////////////////////////////////
  171. // Method: ErrorCode Decoder::SetVideoInput( Connector source )
  172. // Purpose: Select which connector as input
  173. // Input: Connector source - SVideo, Tuner, Composite
  174. // Output: None
  175. // Return: Fail if error in parameter, else Success
  176. /////////////////////////////////////////////////////////////////////////////
  177. ErrorCode Decoder::SetVideoInput( Connector source )
  178. {
  179. if ( ( source != ConSVideo ) &&
  180. ( source != ConTuner ) &&
  181. ( source != ConComposite ) )
  182. return Fail;
  183. decFieldMUXSEL = source;
  184. // set to composite or Y/C component video depends on video source
  185. SetCompositeVideo( ( source == ConSVideo ) ? false : true );
  186. return Success;
  187. }
  188. /////////////////////////////////////////////////////////////////////////////
  189. // Method: int Decoder::GetVideoInput( void )
  190. // Purpose: Get which connector is input
  191. // Input: None
  192. // Output: None
  193. // Return: Video source - SVideo, Tuner, Composite
  194. /////////////////////////////////////////////////////////////////////////////
  195. int Decoder::GetVideoInput( void )
  196. {
  197. return ((int)decFieldMUXSEL);
  198. }
  199. /////////////////////////////////////////////////////////////////////////////
  200. // Method: ErrorCode Decoder::SetCrystal( Crystal crystalNo )
  201. // Purpose: Select which crystal as input
  202. // Input: Crystal crystalNo:
  203. // XT0 - Crystal_XT0
  204. // XT1 - Crystal_XT1
  205. // Auto select - Crystal_AutoSelect
  206. // Output: None
  207. // Return: Fail if error in parameter, else Success
  208. /////////////////////////////////////////////////////////////////////////////
  209. ErrorCode Decoder::SetCrystal( Crystal crystalNo )
  210. {
  211. if ( ( crystalNo < Crystal_XT0 ) || ( crystalNo > Crystal_AutoSelect ) )
  212. return Fail;
  213. decFieldXTSEL = crystalNo;
  214. return Success;
  215. }
  216. /////////////////////////////////////////////////////////////////////////////
  217. // Method: int Decoder::GetCrystal( void )
  218. // Purpose: Get which crystal is input
  219. // Input: None
  220. // Output: None
  221. // Return: Crystal Number:
  222. // XT0 - Crystal_XT0
  223. // XT1 - Crystal_XT1
  224. // Auto select - Crystal_AutoSelect
  225. /////////////////////////////////////////////////////////////////////////////
  226. int Decoder::GetCrystal( void )
  227. {
  228. return ((int)decFieldXTSEL);
  229. }
  230. /////////////////////////////////////////////////////////////////////////////
  231. // Method: ErrorCode Decoder::SetVideoFormat( VideoFormat format )
  232. // Purpose: Set video format
  233. // Input: Video format -
  234. // Auto format: VFormat_AutoDetect
  235. // NTSC (M): VFormat_NTSC
  236. // PAL (B, D, G, H, I): VFormat_PAL_BDGHI
  237. // PAL (M): VFormat_PAL_M
  238. // PAL(N): VFormat_PAL_N
  239. // SECAM: VFormat_SECAM
  240. // Output: None
  241. // Return: Fail if error in parameter, else Success
  242. // Notes: Available video formats are: NTSC, PAL(B, D, G, H, I), PAL(M),
  243. // PAL(N), SECAM
  244. // This function also sets the AGCDelay (ADELAY) and BrustDelay
  245. // (BDELAY) registers
  246. /////////////////////////////////////////////////////////////////////////////
  247. ErrorCode Decoder::SetVideoFormat( VideoFormat format )
  248. {
  249. if ( (format < VFormat_AutoDetect) ||
  250. (format > VFormat_SECAM) ||
  251. (format == VFormat_Reserved2) )
  252. return Fail;
  253. switch (format)
  254. {
  255. case VFormat_NTSC:
  256. decFieldFORMAT = format;
  257. decRegADELAY = 0x68;
  258. decRegBDELAY = 0x5D;
  259. SetChromaComb( true ); // enable chroma comb
  260. SelectCrystal( NTSC_xtal ); // select NTSC crystal
  261. break;
  262. case VFormat_PAL_BDGHI:
  263. case VFormat_PAL_M:
  264. case VFormat_PAL_N:
  265. decFieldFORMAT = format;
  266. decRegADELAY = 0x7F;
  267. decRegBDELAY = 0x72;
  268. SetChromaComb( true ); // enable chroma comb
  269. SelectCrystal( PAL_xtal ); // select PAL crystal
  270. break;
  271. case VFormat_SECAM:
  272. decFieldFORMAT = format;
  273. decRegADELAY = 0x7F;
  274. decRegBDELAY = 0xA0;
  275. SetChromaComb( false ); // disable chroma comb
  276. SelectCrystal( PAL_xtal ); // select PAL crystal
  277. break;
  278. default: // VFormat_AutoDetect
  279. // auto format detect by examining the number of lines
  280. if ( Decoder::Is525LinesVideo() ) // lines == 525 -> NTSC
  281. Decoder::SetVideoFormat( VFormat_NTSC );
  282. else // lines == 625 -> PAL/SECAM
  283. Decoder::SetVideoFormat( VFormat_PAL_BDGHI ); // PAL_BDGHI covers most areas
  284. }
  285. SetSaturation( m_satParam );
  286. return Success;
  287. }
  288. /////////////////////////////////////////////////////////////////////////////
  289. // Method: int Decoder::GetVideoFormat( void )
  290. // Purpose: Obtain video format
  291. // Input: None
  292. // Output: None
  293. // Return: Video format
  294. // Auto format: VFormat_AutoDetect
  295. // NTSC (M): VFormat_NTSC
  296. // PAL (B, D, G, H, I): VFormat_PAL_BDGHI
  297. // PAL (M): VFormat_PAL_M
  298. // PAL(N): VFormat_PAL_N
  299. // SECAM: VFormat_SECAM
  300. /////////////////////////////////////////////////////////////////////////////
  301. int Decoder::GetVideoFormat( void )
  302. {
  303. BYTE bFormat = (BYTE)decFieldFORMAT;
  304. if ( !bFormat ) // autodetection enabled
  305. return Is525LinesVideo() ? VFormat_NTSC : VFormat_SECAM;
  306. else
  307. return bFormat;
  308. }
  309. //===== Temporal Decimation register ========================================
  310. /////////////////////////////////////////////////////////////////////////////
  311. // Method: ErrorCode Decoder::SetRate( bool fields, VidField even, int rate )
  312. // Purpose: Set frames or fields rate
  313. // Input: bool fields - true for fields, false for frames
  314. // VidField even - true to start decimation with even field, false odd
  315. // int rate - decimation rate: frames (1-50/60); fields(1-25/30)
  316. // Output: None
  317. // Return: Fail if error in parameter, else Success
  318. /////////////////////////////////////////////////////////////////////////////
  319. ErrorCode Decoder::SetRate( bool fields, VidField vf, int rate )
  320. {
  321. int nMax;
  322. if ( Is525LinesVideo() == true )
  323. nMax = 30; // NTSC
  324. else
  325. nMax = 25; // PAL/SECAM
  326. // if setting frame rate, double the max value
  327. if ( fields == false )
  328. nMax *= 2;
  329. if ( rate < 0 || rate > nMax )
  330. return Fail;
  331. decFieldDEC_FIELD = (fields == false) ? Off : On;
  332. decFieldDEC_FIELDALIGN = (vf == VF_Even) ? On : Off;
  333. int nDrop = (BYTE) nMax - rate;
  334. decFieldDEC_RAT = (BYTE) (fields == false) ? nDrop : nDrop * 2;
  335. return Success;
  336. }
  337. //===== Brightness Control register =========================================
  338. /////////////////////////////////////////////////////////////////////////////
  339. // Method: ErrorCode Decoder::SetBrightness( int param )
  340. // Purpose: Set video brightness
  341. // Input: int param - parameter value (0-255; default 128)
  342. // Output: None
  343. // Return: Fail if error in parameter, else Success
  344. // Note: See IsAdjustContrast() for detailed description of the contrast
  345. // adjustment calculation
  346. /////////////////////////////////////////////////////////////////////////////
  347. ErrorCode Decoder::SetBrightness( int param )
  348. {
  349. if( m_param.OutOfRange( param ) )
  350. return Fail;
  351. // perform mapping to our range
  352. int mapped;
  353. if ( Mapping( param, m_param, &mapped, m_regBrightness ) == Fail )
  354. return Fail;
  355. m_briParam = (WORD)param;
  356. // calculate brightness value
  357. int value = (128 * mapped) / m_regBrightness.Max() ;
  358. // need to limit the value to 0x7F (+50%) because 0x80 is -50%!
  359. if (( mapped > 0 ) && ( value == 0x80 ))
  360. value = 0x7F;
  361. // perform adjustment of brightness register if adjustment is needed
  362. if ( IsAdjustContrast() )
  363. {
  364. regBright = value; // brightness value before adjustment
  365. long A = (long)regBright * (long)0xD8;
  366. long B = 64 * ( (long)0xD8 - (long)regContrast );
  367. long temp = 0x00;
  368. if ( regContrast != 0 ) // already limit contrast > zero; just in case here
  369. temp = ( ( A + B ) / (long)regContrast );
  370. temp = ( temp < -128 ) ? -128 : ( ( temp > 127 ) ? 127 : temp );
  371. value = (BYTE)temp;
  372. }
  373. decRegBRIGHT = (BYTE)value;
  374. return Success;
  375. }
  376. /////////////////////////////////////////////////////////////////////////////
  377. // Method: int Decoder::GetBrightness( void )
  378. // Purpose: Obtain brightness value
  379. // Input: None
  380. // Output: None
  381. // Return: Brightness parameter (0-255)
  382. /////////////////////////////////////////////////////////////////////////////
  383. int Decoder::GetBrightness( void )
  384. {
  385. return m_briParam;
  386. }
  387. //===== Miscellaneous Control register (E_CONTROL, O_CONTROL) ===============
  388. /////////////////////////////////////////////////////////////////////////////
  389. // Method: void Decoder::SetLumaNotchFilter( bool mode )
  390. // Purpose: Enable/Disable luma notch filter
  391. // Input: bool mode - true = Enable; false = Disable
  392. // Output: None
  393. // Return: None
  394. /////////////////////////////////////////////////////////////////////////////
  395. void Decoder::SetLumaNotchFilter( bool mode )
  396. {
  397. decFieldLNOTCH = decFieldODD_LNOTCH = (mode == false) ? On : Off; // reverse
  398. }
  399. /////////////////////////////////////////////////////////////////////////////
  400. // Method: bool Decoder::IsLumaNotchFilter( void )
  401. // Purpose: Check if luma notch filter is enable or disable
  402. // Input: None
  403. // Output: None
  404. // Return: true = Enable; false = Disable
  405. /////////////////////////////////////////////////////////////////////////////
  406. bool Decoder::IsLumaNotchFilter( void )
  407. {
  408. return (decFieldLNOTCH == Off) ? true : false; // reverse
  409. }
  410. /////////////////////////////////////////////////////////////////////////////
  411. // Method: void Decoder::SetCompositeVideo( bool mode )
  412. // Purpose: Select composite or Y/C component video
  413. // Input: bool mode - true = Composite; false = Y/C Component
  414. // Output: None
  415. // Return: None
  416. /////////////////////////////////////////////////////////////////////////////
  417. void Decoder::SetCompositeVideo( bool mode )
  418. {
  419. if ( mode == true )
  420. {
  421. // composite video
  422. decFieldCOMP = decFieldODD_COMP = Off;
  423. Decoder::SetChromaADC( false ); // disable chroma ADC
  424. Decoder::SetLumaNotchFilter( true ); // enable luma notch filter
  425. }
  426. else
  427. {
  428. // Y/C Component video
  429. decFieldCOMP = decFieldODD_COMP = On;
  430. Decoder::SetChromaADC( true ); // enable chroma ADC
  431. Decoder::SetLumaNotchFilter( false ); // disable luma notch filter
  432. }
  433. }
  434. /////////////////////////////////////////////////////////////////////////////
  435. // Method: bool Decoder::IsCompositeVideo( void )
  436. // Purpose: Check if selected composite or Y/C component video
  437. // Input: None
  438. // Output: None
  439. // Return: true = Composite; false = Y/C Component
  440. /////////////////////////////////////////////////////////////////////////////
  441. bool Decoder::IsCompositeVideo( void )
  442. {
  443. return (decFieldCOMP == Off) ? true : false; // reverse
  444. }
  445. /////////////////////////////////////////////////////////////////////////////
  446. // Method: void Decoder::SetLumaDecimation( bool mode )
  447. // Purpose: Enable/Disable luma decimation filter
  448. // Input: bool mode - true = Enable; false = Disable
  449. // Output: None
  450. // Return: None
  451. /////////////////////////////////////////////////////////////////////////////
  452. void Decoder::SetLumaDecimation( bool mode )
  453. {
  454. // value of 0 turns the decimation on
  455. decFieldLDEC = decFieldODD_LDEC = (mode == true) ? 0 : 1;
  456. }
  457. /////////////////////////////////////////////////////////////////////////////
  458. // Method: bool Decoder::IsLumaDecimation( void )
  459. // Purpose: Check if luma decimation filter is enable or disable
  460. // Input: None
  461. // Output: None
  462. // Return: true = Enable; false = Disable
  463. /////////////////////////////////////////////////////////////////////////////
  464. bool Decoder::IsLumaDecimation( void )
  465. {
  466. return (decFieldLDEC == Off) ? true : false; // reverse
  467. }
  468. /////////////////////////////////////////////////////////////////////////////
  469. // Method: void Decoder::SetCbFirst( bool mode )
  470. // Purpose: Control whether the first pixel of a line is a Cb or Cr pixel
  471. // Input: bool mode - true = Normal Cb, Cr order, false = Invert Cb, Cr order
  472. // Output: None
  473. // Return: None
  474. /////////////////////////////////////////////////////////////////////////////
  475. void Decoder::SetCbFirst( bool mode )
  476. {
  477. decFieldCBSENSE = decFieldODD_CBSENSE = (mode == false) ? On : Off; // reverse
  478. }
  479. /////////////////////////////////////////////////////////////////////////////
  480. // Method: bool Decoder::IsCbFirst( void )
  481. // Purpose: Check if the first pixel of a line is a Cb or Cr pixel
  482. // Input: None
  483. // Output: None
  484. // Return: true = Normal Cb, Cr order, false = Invert Cb, Cr order
  485. /////////////////////////////////////////////////////////////////////////////
  486. bool Decoder::IsCbFirst( void )
  487. {
  488. return (decFieldCBSENSE == Off) ? true : false; // reverse
  489. }
  490. //===== Luma Gain register (CON_MSB, CONTRAST_LO) ===========================
  491. /////////////////////////////////////////////////////////////////////////////
  492. // Method: ErrorCode Decoder::SetContrast( int param )
  493. // Purpose: Set video contrast
  494. // Input: int param - parameter value (0-255; default 128)
  495. // Output: None
  496. // Return: Fail if error in parameter, else Success
  497. // Note: See IsAdjustContrast() for detailed description of the contrast
  498. // adjustment calculation
  499. /////////////////////////////////////////////////////////////////////////////
  500. ErrorCode Decoder::SetContrast( int param )
  501. {
  502. if( m_param.OutOfRange( param ) )
  503. return Fail;
  504. bool adjustContrast = IsAdjustContrast(); // is contrast need to be adjusted
  505. // if adjust contrast is needed, make sure contrast reg value != 0
  506. if ( adjustContrast )
  507. m_regContrast = CRegInfo( 1, ConMax, ConDef );
  508. // perform mapping to our range
  509. int mapped;
  510. if ( Mapping( param, m_param, &mapped, m_regContrast ) == Fail )
  511. return Fail;
  512. m_conParam = (WORD)param;
  513. // calculate contrast
  514. DWORD value = (DWORD)0x1FF * (DWORD)mapped;
  515. value /= (DWORD)m_regContrast.Max();
  516. if ( value > 0x1FF )
  517. value = 0x1FF;
  518. // contrast is set by a 9 bit value; set LSB first
  519. decRegCONTRAST_LO = value;
  520. // now set the Miscellaneous Control Register CON_V_MSB to the 9th bit value
  521. decFieldCON_MSB = decFieldODD_CON_MSB = ( (value & 0x0100) ? On : Off );
  522. // perform adjustment of brightness register if adjustment is needed
  523. if ( adjustContrast )
  524. {
  525. regContrast = (WORD)value; // contrast value
  526. long A = (long)regBright * (long)0xD8;
  527. long B = 64 * ( (long)0xD8 - (long)regContrast );
  528. long temp = 0x00;
  529. if ( regContrast != 0 ) // already limit contrast > zero; just in case here
  530. temp = ( ( A + B ) / (long)regContrast );
  531. temp = ( temp < -128 ) ? -128 : ( ( temp > 127 ) ? 127 : temp );
  532. decRegBRIGHT = (BYTE)temp;
  533. }
  534. return Success;
  535. }
  536. /////////////////////////////////////////////////////////////////////////////
  537. // Method: int Decoder::GetContrast( void )
  538. // Purpose: Obtain contrast value
  539. // Input: None
  540. // Output: None
  541. // Return: Contrast parameter (0-255)
  542. /////////////////////////////////////////////////////////////////////////////
  543. int Decoder::GetContrast( void )
  544. {
  545. return m_conParam;
  546. }
  547. //===== Chroma Gain register (SAT_U_MSB, SAT_V_MSB, SAT_U_LO, SAT_V_LO) =====
  548. /////////////////////////////////////////////////////////////////////////////
  549. // Method: ErrorCode Decoder::SetSaturation( int param )
  550. // Purpose: Set color saturation by modifying U and V values
  551. // Input: int param - parameter value (0-255; default 128)
  552. // Output: None
  553. // Return: Fail if error in parameter, else Success
  554. /////////////////////////////////////////////////////////////////////////////
  555. ErrorCode Decoder::SetSaturation( int param )
  556. {
  557. if( m_param.OutOfRange( param ) )
  558. return Fail;
  559. // color saturation is controlled by two nine bit values:
  560. // ChromaU & ChromaV
  561. // To maintain normal color balance, the ratio between the 2 register
  562. // values should be kept at the power-up default ratio
  563. // Note that U & V values for NTSC and PAL are the same, SECAM is different
  564. WORD nominalNTSC_U = 0xFE; // nominal value (i.e. 100%) for NTSC/PAL
  565. WORD nominalNTSC_V = 0xB4;
  566. WORD nominalSECAM_U = 0x87; // nominal value (i.e. 100%) for SECAM
  567. WORD nominalSECAM_V = 0x85;
  568. CRegInfo regSat; // selected saturation register; NTSC/PAL or SECAM
  569. WORD nominal_U, nominal_V; // selected nominal U and V value; NTSC/PAL or SECAM
  570. // select U & V values of either NTSC/PAL or SECAM to be used for calculation
  571. if ( GetVideoFormat() == VFormat_SECAM )
  572. {
  573. nominal_U = nominalSECAM_U;
  574. nominal_V = nominalSECAM_V;
  575. regSat = m_regSaturationSECAM;
  576. }
  577. else
  578. {
  579. nominal_U = nominalNTSC_U;
  580. nominal_V = nominalNTSC_V;
  581. regSat = m_regSaturationNTSC;
  582. }
  583. // perform mapping to our range
  584. int mapped;
  585. if ( Mapping( param, m_param, &mapped, regSat ) == Fail )
  586. return Fail;
  587. m_satParam = (WORD)param;
  588. WORD max_nominal = max( nominal_U, nominal_V );
  589. // calculate U and V values
  590. WORD Uvalue = (WORD) ( (DWORD)mapped * (DWORD)nominal_U / (DWORD)max_nominal );
  591. WORD Vvalue = (WORD) ( (DWORD)mapped * (DWORD)nominal_V / (DWORD)max_nominal );
  592. // set U
  593. decRegSAT_U_LO = Uvalue;
  594. // now set the Miscellaneous Control Register SAT_U_MSB to the 9th bit value
  595. decFieldSAT_U_MSB = decFieldODD_SAT_U_MSB = ( (Uvalue & 0x0100) ? On : Off );
  596. // set V
  597. decRegSAT_V_LO = Vvalue;
  598. // now set the Miscellaneous Control Register SAT_V_MSB to the 9th bit value
  599. decFieldSAT_V_MSB = decFieldODD_SAT_V_MSB = ( (Vvalue & 0x0100) ? On : Off );
  600. return Success;
  601. }
  602. /////////////////////////////////////////////////////////////////////////////
  603. // Method: int Decoder::GetSaturation( void )
  604. // Purpose: Obtain saturation value
  605. // Input: None
  606. // Output: None
  607. // Return: Saturation parameter (0-255)
  608. /////////////////////////////////////////////////////////////////////////////
  609. int Decoder::GetSaturation( void )
  610. {
  611. return m_satParam;
  612. }
  613. //===== Hue Control register (HUE) ==========================================
  614. /////////////////////////////////////////////////////////////////////////////
  615. // Method: ErrorCode Decoder::SetHue( int param )
  616. // Purpose: Set video hue
  617. // Input: int param - parameter value (0-255; default 128)
  618. // Output: None
  619. // Return: Fail if error in parameter, else Success
  620. /////////////////////////////////////////////////////////////////////////////
  621. ErrorCode Decoder::SetHue( int param )
  622. {
  623. if( m_param.OutOfRange( param ) )
  624. return Fail;
  625. // perform mapping to our range
  626. int mapped;
  627. if ( Mapping( param, m_param, &mapped, m_regHue ) == Fail )
  628. return Fail;
  629. m_hueParam = (WORD)param;
  630. int value = (-128 * mapped) / m_regHue.Max();
  631. if (value > 127)
  632. value = 127;
  633. else if (value < -128)
  634. value = -128;
  635. decRegHUE = value;
  636. return Success;
  637. }
  638. /////////////////////////////////////////////////////////////////////////////
  639. // Method: int Decoder::GetHue( void )
  640. // Purpose: Obtain hue value
  641. // Input: None
  642. // Output: None
  643. // Return: Hue parameter (0-255)
  644. /////////////////////////////////////////////////////////////////////////////
  645. int Decoder::GetHue( void )
  646. {
  647. return m_hueParam;
  648. }
  649. //===== SC Loop Control register (E_SCLOOP, O_SCLOOP) =======================
  650. /////////////////////////////////////////////////////////////////////////////
  651. // Method: void Decoder::SetChromaAGC( bool mode )
  652. // Purpose: Enable/Disable Chroma AGC compensation
  653. // Input: bool mode - true = Enable, false = Disable
  654. // Output: None
  655. // Return: None
  656. /////////////////////////////////////////////////////////////////////////////
  657. void Decoder::SetChromaAGC( bool mode )
  658. {
  659. decFieldCAGC = decFieldODD_CAGC = (mode == false) ? Off : On;
  660. }
  661. /////////////////////////////////////////////////////////////////////////////
  662. // Method: bool Decoder::IsChromaAGC( void )
  663. // Purpose: Check if Chroma AGC compensation is enable or disable
  664. // Input: None
  665. // Output: None
  666. // Return: true = Enable, false = Disable
  667. /////////////////////////////////////////////////////////////////////////////
  668. bool Decoder::IsChromaAGC( void )
  669. {
  670. return (decFieldCAGC == On) ? true : false;
  671. }
  672. /////////////////////////////////////////////////////////////////////////////
  673. // Method: void Decoder::SetLowColorAutoRemoval( bool mode )
  674. // Purpose: Enable/Disable low color detection and removal
  675. // Input: bool mode - true = Enable, false = Disable
  676. // Output: None
  677. // Return: None
  678. /////////////////////////////////////////////////////////////////////////////
  679. void Decoder::SetLowColorAutoRemoval( bool mode )
  680. {
  681. decFieldCKILL = decFieldODD_CKILL = (mode == false) ? Off : On;
  682. }
  683. /////////////////////////////////////////////////////////////////////////////
  684. // Method: bool Decoder::IsLowColorAutoRemoval( void )
  685. // Purpose: Check if low color detection and removal is enable or disable
  686. // Input: None
  687. // Output: None
  688. // Return: true = Enable, false = Disable
  689. /////////////////////////////////////////////////////////////////////////////
  690. bool Decoder::IsLowColorAutoRemoval( void )
  691. {
  692. return (decFieldCKILL == On) ? true : false;
  693. }
  694. /////////////////////////////////////////////////////////////////////////////
  695. // Method: ErrorCode Decoder::SetHorizontalFilter( HorizFilter hFilter )
  696. // Purpose: Control the configuration of the optional 6-tap Horizontal Low-Pass filter
  697. // Input: HoriFilter hFilter:
  698. // Auto Format - HFilter_AutoFormat
  699. // CIF - HFilter_CIF
  700. // QCIF - HFilter_QCIF
  701. // ICON - HFilter_ICON
  702. // Output: None
  703. // Return: Fail if error in parameter, else Success
  704. /////////////////////////////////////////////////////////////////////////////
  705. ErrorCode Decoder::SetHorizontalFilter( HorizFilter hFilter )
  706. {
  707. if ( (hFilter < HFilter_AutoFormat) ||
  708. (hFilter > HFilter_ICON) )
  709. return Fail;
  710. decFieldHFILT = decFieldODD_HFILT = hFilter;
  711. return Success;
  712. }
  713. /////////////////////////////////////////////////////////////////////////////
  714. // Method: int Decoder::GetHorizontalFilter( void )
  715. // Purpose: Get the configuration of the optional 6-tap Horizontal Low-Pass filter
  716. // Input: None
  717. // Output: None
  718. // Return: Which filter is using:
  719. // Auto Format - HFilter_AutoFormat
  720. // CIF - HFilter_CIF
  721. // QCIF - HFilter_QCIF
  722. // ICON - HFilter_ICON
  723. /////////////////////////////////////////////////////////////////////////////
  724. int Decoder::GetHorizontalFilter( void )
  725. {
  726. return ((int)decFieldHFILT);
  727. }
  728. //===== Output Format register (OFORM) ======================================
  729. /////////////////////////////////////////////////////////////////////////////
  730. // Method: void Decoder::SetFullOutputRange( bool mode )
  731. // Purpose: Enable/Disable full output range
  732. // Input: bool mode - true = Enable, false = Disable
  733. // Output: None
  734. // Return: None
  735. /////////////////////////////////////////////////////////////////////////////
  736. void Decoder::SetFullOutputRange( bool mode )
  737. {
  738. decFieldRANGE = (mode == false) ? Off : On;
  739. }
  740. /////////////////////////////////////////////////////////////////////////////
  741. // Method: bool Decoder::IsFullOutputRange( void )
  742. // Purpose: Check if full output range is enable or disable
  743. // Input: None
  744. // Output: None
  745. // Return: true = Enable, false = Disable
  746. /////////////////////////////////////////////////////////////////////////////
  747. bool Decoder::IsFullOutputRange( void )
  748. {
  749. return (decFieldRANGE == On) ? true : false;
  750. }
  751. /////////////////////////////////////////////////////////////////////////////
  752. // Method: ErrorCode Decoder::SetLumaCoring( CoringLevel cLevel )
  753. // Purpose: Set luminance level such that luminance signal is truncated to zero
  754. // if below this level
  755. // Input: CoringLevel cLevel -
  756. // Coring_None: no coring
  757. // Coring_8: 8
  758. // Coring_16: 16
  759. // Coring_32: 32
  760. // Output: None
  761. // Return: Fail if error in parameter, else Success
  762. /////////////////////////////////////////////////////////////////////////////
  763. ErrorCode Decoder::SetLumaCoring( CoringLevel cLevel )
  764. {
  765. if ( ( cLevel < Coring_None) || ( cLevel > Coring_32 ) )
  766. return Fail;
  767. decFieldCORE = cLevel;
  768. return Success;
  769. }
  770. /////////////////////////////////////////////////////////////////////////////
  771. // Method: int Decoder::GetLumaCoring( void )
  772. // Purpose: Get luminance level such that luminance signal is truncated to zero
  773. // if below this level
  774. // Input: None
  775. // Output: None
  776. // Return: Luma coring level -
  777. // Coring_None: no coring
  778. // Coring_8: 8
  779. // Coring_16: 16
  780. // Coring_32: 32
  781. /////////////////////////////////////////////////////////////////////////////
  782. int Decoder::GetLumaCoring( void )
  783. {
  784. return ((int)decFieldCORE);
  785. }
  786. //===== Vertical Scaling register (E_VSCALE_HI, O_VSCALE_HI) ================
  787. /////////////////////////////////////////////////////////////////////////////
  788. // Method: void Decoder::SetChromaComb( bool mode )
  789. // Purpose: Enable/Disable chroma comb
  790. // Input: bool mode - true = Enable, false = Disable
  791. // Output: None
  792. // Return: None
  793. /////////////////////////////////////////////////////////////////////////////
  794. void Decoder::SetChromaComb( bool mode )
  795. {
  796. decFieldCOMB = (mode == false) ? Off : On;
  797. }
  798. /////////////////////////////////////////////////////////////////////////////
  799. // Method: bool Decoder::IsChromaComb( void )
  800. // Purpose: Check if chroma comb is enable or disable
  801. // Input: None
  802. // Output: None
  803. // Return: true = Enable, false = Disable
  804. /////////////////////////////////////////////////////////////////////////////
  805. bool Decoder::IsChromaComb( void )
  806. {
  807. return (decFieldCOMB == On) ? true : false;
  808. }
  809. //===== AGC Delay register (ADELAY) =========================================
  810. /////////////////////////////////////////////////////////////////////////////
  811. // Method: void Decoder::SetAGCDelay( BYTE value )
  812. // Purpose: Set AGC Delay register
  813. // Input: Value to be set to
  814. // Output: None
  815. // Return: None
  816. // NOTE: This function set the AGC Delay register to the specified value.
  817. // No calculation is involved.
  818. /////////////////////////////////////////////////////////////////////////////
  819. void Decoder::SetAGCDelay( BYTE value )
  820. {
  821. // [!!!] this was considered suspicious by someone...
  822. //#pragma message ("IS THIS GOOD?? ")
  823. decRegADELAY = value;
  824. }
  825. /////////////////////////////////////////////////////////////////////////////
  826. // Method: int Decoder::GetAGCDelay( void )
  827. // Purpose: Get AGC Delay register
  828. // Input: None
  829. // Output: None
  830. // Return: Register value
  831. /////////////////////////////////////////////////////////////////////////////
  832. int Decoder::GetAGCDelay( void )
  833. {
  834. return ((int)decRegADELAY);
  835. }
  836. //===== Burst Delay register (BDELAY) =========================================
  837. /////////////////////////////////////////////////////////////////////////////
  838. // Method: void Decoder::SetBurstDelay( BYTE value )
  839. // Purpose: Set Burst Delay register
  840. // Input: Value to be set to
  841. // Output: None
  842. // Return: None
  843. // NOTE: This function set the Burst Delay register to the specified value.
  844. // No calculation is involved.
  845. /////////////////////////////////////////////////////////////////////////////
  846. void Decoder::SetBurstDelay( BYTE value )
  847. {
  848. // [!!!] this was considered suspicious by someone...
  849. //#pragma message ("IS THIS GOOD?? ")
  850. decRegBDELAY = value;
  851. }
  852. /////////////////////////////////////////////////////////////////////////////
  853. // Method: int Decoder::GetBurstDelay( void )
  854. // Purpose: Get Burst Delay register
  855. // Input: None
  856. // Output: None
  857. // Return: Register value
  858. /////////////////////////////////////////////////////////////////////////////
  859. int Decoder::GetBurstDelay( void )
  860. {
  861. return ((int)decRegBDELAY);
  862. }
  863. //===== ADC Interface register (ADC) =========================================
  864. /////////////////////////////////////////////////////////////////////////////
  865. // Method: void Decoder::SetAnalogThresholdLow( bool mode )
  866. // Purpose: Define high/low threshold level below which SYNC signal can be detected
  867. // Input: bool mode - true = low threshold (~75mV), false = high threshold (~125mV)
  868. // Output: None
  869. // Return: None
  870. /////////////////////////////////////////////////////////////////////////////
  871. void Decoder::SetAnalogThresholdLow( bool mode )
  872. {
  873. decFieldSYNC_T = (mode == false) ? Off : On;
  874. }
  875. /////////////////////////////////////////////////////////////////////////////
  876. // Method: bool Decoder::IsAnalogThresholdLow( void )
  877. // Purpose: Check if high or low threshold level below which SYNC signal can be detected
  878. // Input: None
  879. // Output: None
  880. // Return: true = low threshold (~75mV), false = high threshold (~125mV)
  881. /////////////////////////////////////////////////////////////////////////////
  882. bool Decoder::IsAnalogThresholdLow( void )
  883. {
  884. return (decFieldSYNC_T == On) ? true : false;
  885. }
  886. /////////////////////////////////////////////////////////////////////////////
  887. // Method: void Decoder::SetAGCFunction( bool mode )
  888. // Purpose: Enable/Disable AGC function
  889. // Input: bool mode - true = Enable, false = Disable
  890. // Output: None
  891. // Return: None
  892. /////////////////////////////////////////////////////////////////////////////
  893. void Decoder::SetAGCFunction( bool mode )
  894. {
  895. decFieldAGC_EN = (mode == false) ? On : Off; // reverse
  896. }
  897. /////////////////////////////////////////////////////////////////////////////
  898. // Method: bool Decoder::IsAGCFunction( void )
  899. // Purpose: Check if AGC function is enable or disable
  900. // Input: None
  901. // Output: None
  902. // Return: true = Enable, false = Disable
  903. /////////////////////////////////////////////////////////////////////////////
  904. bool Decoder::IsAGCFunction( void )
  905. {
  906. return (decFieldAGC_EN == Off) ? true : false; // reverse
  907. }
  908. /////////////////////////////////////////////////////////////////////////////
  909. // Method: void Decoder::PowerDown( bool mode )
  910. // Purpose: Select normal or shut down clock operation
  911. // Input: bool mode - true = shut down, false = normal operation
  912. // Output: None
  913. // Return: None
  914. /////////////////////////////////////////////////////////////////////////////
  915. void Decoder::PowerDown( bool mode )
  916. {
  917. decFieldCLK_SLEEP = (mode == false) ? Off : On;
  918. }
  919. /////////////////////////////////////////////////////////////////////////////
  920. // Method: bool Decoder::IsPowerDown( void )
  921. // Purpose: Check if clock operation has been shut down
  922. // Input: None
  923. // Output: None
  924. // Return: true = shut down, false = normal operation
  925. /////////////////////////////////////////////////////////////////////////////
  926. bool Decoder::IsPowerDown( void )
  927. {
  928. return (decFieldCLK_SLEEP == On) ? true : false;
  929. }
  930. /////////////////////////////////////////////////////////////////////////////
  931. // Method: void Decoder::SetLumaADC( bool mode )
  932. // Purpose: Select normal or sleep Y ADC operation
  933. // Input: bool mode - true = normal, false = sleep
  934. // Output: None
  935. // Return: None
  936. /////////////////////////////////////////////////////////////////////////////
  937. void Decoder::SetLumaADC( bool mode )
  938. {
  939. decFieldY_SLEEP = (mode == false) ? On : Off; // reverse
  940. }
  941. /////////////////////////////////////////////////////////////////////////////
  942. // Method: bool Decoder::IsLumaADC( void )
  943. // Purpose: Check if Y ADC operation is in normal operation or sleeping
  944. // Input: None
  945. // Output: None
  946. // Return: true = normal, false = sleep
  947. /////////////////////////////////////////////////////////////////////////////
  948. bool Decoder::IsLumaADC( void )
  949. {
  950. return (decFieldY_SLEEP == Off) ? true : false; // reverse
  951. }
  952. /////////////////////////////////////////////////////////////////////////////
  953. // Method: void Decoder::SetChromaADC( bool mode )
  954. // Purpose: Select normal or sleep C ADC operation
  955. // Input: bool mode - true = normal, false = sleep
  956. // Output: None
  957. // Return: None
  958. /////////////////////////////////////////////////////////////////////////////
  959. void Decoder::SetChromaADC( bool mode )
  960. {
  961. decFieldC_SLEEP = (mode == false) ? On : Off; // reverse
  962. }
  963. /////////////////////////////////////////////////////////////////////////////
  964. // Method: bool Decoder::IsChromaADC( void )
  965. // Purpose: Check if C ADC operation is in normal operation or sleeping
  966. // Input: None
  967. // Output: None
  968. // Return: true = normal, false = sleep
  969. /////////////////////////////////////////////////////////////////////////////
  970. bool Decoder::IsChromaADC( void )
  971. {
  972. return (decFieldC_SLEEP == Off) ? true : false; // reverse
  973. }
  974. /*^^////////////////////////////////////////////////////////////////////////////
  975. // Method: void Decoder::SetAdaptiveAGC( bool mode )
  976. // Purpose: Set adaptive or non-adaptive AGC operation
  977. // Input: bool mode - true = Adaptive, false = Non-adaptive
  978. // Output: None
  979. // Return: None
  980. *////////////////////////////////////////////////////////////////////////////
  981. void Decoder::SetAdaptiveAGC( bool mode )
  982. {
  983. decFieldCRUSH = (mode == false) ? Off : On;
  984. }
  985. /////////////////////////////////////////////////////////////////////////////
  986. // Method: bool Decoder::IsAdaptiveAGC( void )
  987. // Purpose: Check if adaptive or non-adaptive AGC operation is selected
  988. // Input: None
  989. // Output: None
  990. // Return: true = Adaptive, false = Non-adaptive
  991. /////////////////////////////////////////////////////////////////////////////
  992. bool Decoder::IsAdaptiveAGC( void )
  993. {
  994. return (decFieldCRUSH == On) ? true : false;
  995. }
  996. //===== Software Reset register (SRESET) ====================================
  997. /////////////////////////////////////////////////////////////////////////////
  998. // Method: void Decoder::SoftwareReset( void )
  999. // Purpose: Perform software reset; all registers set to default values
  1000. // Input: None
  1001. // Output: None
  1002. // Return: None
  1003. /////////////////////////////////////////////////////////////////////////////
  1004. void Decoder::SoftwareReset( void )
  1005. {
  1006. decRegSRESET = 0x00; // write any value will do
  1007. }
  1008. /////////////////////////////////////////////////////////////////////////////
  1009. // Method: void Decoder::SelectCrystal( char useCrystal )
  1010. // Purpose: Select correct crystal for NTSC or PAL
  1011. // Input: char useCrystal - 'N' for NTSC; 'P' for PAL
  1012. // Output: None
  1013. // Return: None
  1014. // NOTE: Assume at most 2 crystals installed in hardware. i.e. 1 for NTSC
  1015. // and the other for PAL/SECAM.
  1016. // If there is only 1 crystal exists (which must be crystal XT0),
  1017. // do nothing since it is already selected.
  1018. /////////////////////////////////////////////////////////////////////////////
  1019. void Decoder::SelectCrystal( int useCrystal )
  1020. {
  1021. if ( Xtals_ [0] && Xtals_ [1] ) {
  1022. // compare with what we want to use
  1023. if ( ( IsCrystal0Selected() && ( Xtals_ [0] != (DWORD) useCrystal ) ) ||
  1024. ( !IsCrystal0Selected() && ( Xtals_ [0] == (DWORD) useCrystal ) ) )
  1025. // need to change crystal
  1026. SetCrystal( IsCrystal0Selected() ? Crystal_XT1 : Crystal_XT0 );
  1027. }
  1028. }
  1029. /////////////////////////////////////////////////////////////////////////////
  1030. // Method: ErrorCode Decoder::Mapping( int fromValue, CRegInfo fromRange,
  1031. // int * toValue, CRegInfo toRange )
  1032. // Purpose: Map a value in certain range to a value in another range
  1033. // Input: int fromValue - value to be mapped from
  1034. // CRegInfo fromRange - range of value mapping from
  1035. // CRegInfo toRange - range of value mapping to
  1036. // Output: int * toValue - mapped value
  1037. // Return: Fail if error in parameter, else Success
  1038. // Comment: No range checking is performed here. Assume parameters are in
  1039. // valid ranges.
  1040. // The mapping function does not assume default is always the mid
  1041. // point of the whole range. It only assumes default values of the
  1042. // two ranges correspond to each other.
  1043. //
  1044. // The mapping formula is:
  1045. //
  1046. // For fromRange.Min() <= fromValue <= fromRange.Default():
  1047. //
  1048. // fromValue * (toRange.Default() - toRange.Min())
  1049. // ------------------------------------------------ + toRange.Min()
  1050. // fromRange.Default() - fromRange.Min()
  1051. //
  1052. // For fromRange.Default() < fromValue <= fromRange.Max():
  1053. //
  1054. // (fromValue - fromRange.Default()) * (toRange.Max() - toRange.Default())
  1055. // --------------------------------------------------------------------- + toRange.Default()
  1056. // fromRange.Max() - fromRange.Default()
  1057. //
  1058. ////////////////////////////////////////////////////////////////////////////
  1059. ErrorCode Decoder::Mapping( int fromValue, CRegInfo fromRange,
  1060. int * toValue, CRegInfo toRange )
  1061. {
  1062. // calculate intermediate values
  1063. DWORD ToLowRange = toRange.Default() - toRange.Min();
  1064. DWORD FromLowRange = fromRange.Default() - fromRange.Min();
  1065. DWORD ToHighRange = toRange.Max() - toRange.Default();
  1066. DWORD FromHighRange = fromRange.Max() - fromRange.Default();
  1067. // prevent divide by zero
  1068. if ( !FromLowRange || !FromHighRange )
  1069. return ( Fail );
  1070. // perform mapping
  1071. if ( fromValue <= fromRange.Default() )
  1072. *toValue = (int) (DWORD)fromValue * ToLowRange / FromLowRange +
  1073. (DWORD)toRange.Min();
  1074. else
  1075. *toValue = (int) ( (DWORD)fromValue - (DWORD)fromRange.Default() ) *
  1076. ToHighRange / FromHighRange + (DWORD)toRange.Default();
  1077. return ( Success );
  1078. }
  1079. /////////////////////////////////////////////////////////////////////////////
  1080. // Method: bool Decoder::IsAdjustContrast( void )
  1081. // Purpose: Check registry key whether adjust contrast is needed
  1082. // Input: None
  1083. // Output: None
  1084. // Return: true = adjust contrast, false = don't adjust contrast
  1085. // Note: If adjust contrast is turn on, brightness register value will be
  1086. // adjusted such that it remains a constant after the calculation
  1087. // performed by the hardware.
  1088. //
  1089. // The formula is:
  1090. // To keep brightness constant (i.e. not affect by changing contrast)
  1091. // set brightness to B/(C/C0)
  1092. // where B is value of brightness before adjustment
  1093. // C is contrast value
  1094. // C0 is nominal contrast value (0xD8)
  1095. //
  1096. // To adjust the contrast level such that it is at the middle of
  1097. // black and white: set brightness to (B * C0 + 64 * (C0 - C))/C
  1098. // (this is what Intel wants)
  1099. //
  1100. // Currently there is still limitation of how much adjustment
  1101. // can be performed. For example, if brightness is already high,
  1102. // (i.e. brightness reg value close to 0x7F), lowering contrast
  1103. // until a certain level will have no adjustment effect on brightness.
  1104. // In fact, it would even bring down brightness to darkness.
  1105. //
  1106. // Example 1: if brightness is at nominal value (0x00), contrast can
  1107. // only go down to 0x47 (brightness adjustment is already
  1108. // at max of 0x7F) before it starts affecting brightness
  1109. // which takes it darkness.
  1110. // Example 2: if brightness is at nominal value (0x00), contrast can
  1111. // go all the way up with brightness adjusted correctly.
  1112. // However, the max adjustment used is only 0xDC and
  1113. // the max adjustment we can use is 0x&F.
  1114. // Example 3: if brightness is at max (0x7F), lowering contrast
  1115. // cannot be compensated by adjusting brightness anymore.
  1116. // The result is gradually taking brightness to darkness.
  1117. // Example 4: if brightness is at min (0x80), lowering contrast has
  1118. // no visual effect. Bringing contrast to max is using
  1119. // 0xA5 in brightness for compensation.
  1120. //
  1121. // One last note, the center is defined as the middle of the
  1122. // gamma adjusted luminance level. Changing it to use the middle of
  1123. // the linear (RGB) luminance level is possible.
  1124. /////////////////////////////////////////////////////////////////////////////
  1125. bool Decoder::IsAdjustContrast( void )
  1126. {
  1127. return false;
  1128. /*
  1129. // locate adjust contrast information in the registry
  1130. // the key to look for in registry is:
  1131. // Bt848\AdjustContrast - 0 = don't adjust contrast
  1132. // 1 = adjust contrast
  1133. VRegistryKey vkey( PRK_CLASSES_ROOT, "Bt848" );
  1134. // make sure the key exists
  1135. if ( vkey.lastError() == ERROR_SUCCESS )
  1136. {
  1137. char * adjustContrastKey = "AdjustContrast";
  1138. char key[3];
  1139. DWORD keyLen = 2; // need only first char; '0' or '1'
  1140. // get the registry value and check it, if exist
  1141. if ( ( vkey.getSubkeyValue( adjustContrastKey, key, (DWORD *)&keyLen ) ) &&
  1142. ( key[0] == '1' ) )
  1143. return ( true );
  1144. }
  1145. return ( false );
  1146. */
  1147. }
  1148. /* Function: SelectFlags
  1149. * Purpose: Selects video standard flags
  1150. * Input: val: DWORD - value to switch on
  1151. * flags: LONG & - flags fo here
  1152. * Output: None
  1153. */
  1154. void SelectFlags( DWORD val, LONG &flags )
  1155. {
  1156. switch ( val ) {
  1157. case NTSC_xtal:
  1158. flags |= KS_AnalogVideo_NTSC_M;
  1159. break;
  1160. case PAL_xtal:
  1161. flags |= KS_AnalogVideo_PAL_M | KS_AnalogVideo_PAL_N |
  1162. KS_AnalogVideo_PAL_B | KS_AnalogVideo_PAL_D |
  1163. KS_AnalogVideo_PAL_H | KS_AnalogVideo_PAL_I |
  1164. KS_AnalogVideo_SECAM_B | KS_AnalogVideo_SECAM_D |
  1165. KS_AnalogVideo_SECAM_G | KS_AnalogVideo_SECAM_H |
  1166. KS_AnalogVideo_SECAM_K | KS_AnalogVideo_SECAM_K1 |
  1167. KS_AnalogVideo_SECAM_L;
  1168. break;
  1169. }
  1170. }
  1171. /* Method: Decoder::GetSupportedStandards
  1172. * Purpose: Returns supported standards
  1173. * Input: None
  1174. * Output: LONG: standard flags
  1175. */
  1176. LONG Decoder::GetSupportedStandards()
  1177. {
  1178. LONG standards =0;
  1179. SelectFlags( Xtals_ [0], standards );
  1180. SelectFlags( Xtals_ [1], standards );
  1181. return standards;
  1182. }