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.

1052 lines
34 KiB

  1. //==========================================================================;
  2. //
  3. // Device - Implementation of the Bt829 CVideoDecoderDevice
  4. //
  5. // $Date: 28 Aug 1998 14:44:20 $
  6. // $Revision: 1.2 $
  7. // $Author: Tashjian $
  8. //
  9. // $Copyright: (c) 1997 - 1998 ATI Technologies Inc. All Rights Reserved. $
  10. //
  11. //==========================================================================;
  12. #include "register.h"
  13. #include "defaults.h"
  14. #include "device.h"
  15. #include "mediums.h"
  16. #include "capdebug.h"
  17. #include "StrmInfo.h"
  18. #include "initguid.h"
  19. DEFINE_GUID(DDVPTYPE_BROOKTREE, 0x1352A560L,0xDA61,0x11CF,0x9B,0x06,0x00,0xA0,0xC9,0x03,0xA3,0xB8);
  20. #ifdef BT829_SUPPORT_16BIT
  21. #define BT829_VPCONNECTIONS_NUMBER 2
  22. #else
  23. #define BT829_VPCONNECTIONS_NUMBER 1
  24. #endif
  25. #define BT829_PIXELFORMATS_NUMBER 1
  26. #define NTSC_FRAME_RATE 30
  27. #define PAL_FRAME_RATE 25
  28. #define BT829_LOST_LINES 2 // BT829
  29. #define BT829A_LOST_LINES 3 // BT829a
  30. Device::Device( PPORT_CONFIGURATION_INFORMATION ConfigInfo,
  31. PDEVICE_PARMS pDeviceParms,
  32. PUINT puiError) :
  33. m_pDeviceParms(pDeviceParms),
  34. // Corresponds to KS_DEFAULTs
  35. hue(128),
  36. saturation(128),
  37. contrast(128),
  38. brightness(128),
  39. source(ConTuner),
  40. VBIEN(FALSE),
  41. VBIFMT(FALSE),
  42. // Beware of these hardcoded values
  43. //Paul: Setup default for NTSC and PAL
  44. NTSCDecoderWidth(720),
  45. NTSCDecoderHeight(240),
  46. PALDecoderWidth(720),
  47. PALDecoderHeight(288),
  48. // Now set via registry
  49. defaultDecoderWidth(720),
  50. defaultDecoderHeight(240)
  51. {
  52. *puiError = 0;
  53. RegisterB devRegIDCODE (0x17, RO, pDeviceParms);
  54. RegField devFieldPART_ID (devRegIDCODE, 4, 4);
  55. RegField devFieldPART_REV (devRegIDCODE, 0, 4);
  56. m_pDeviceParms->chipID = (int)devFieldPART_ID;
  57. m_pDeviceParms->chipRev = (int)devFieldPART_REV;
  58. DBGINFO(("Chip ID: 0x%x\n", m_pDeviceParms->chipID));
  59. DBGINFO(("Chip revision: 0x%x\n", m_pDeviceParms->chipRev));
  60. // Bt829 should have a PartID of 1110b (0xe).
  61. if (m_pDeviceParms->chipID != 0xe)
  62. {
  63. DBGERROR(("I2c failure or wrong decoder.\n"));
  64. *puiError = 1;
  65. return;
  66. }
  67. PDEVICE_DATA_EXTENSION pHwExt = (PDEVICE_DATA_EXTENSION)ConfigInfo->HwDeviceExtension;
  68. decoder = (Decoder *) new ((PVOID)&pHwExt->CDecoder) Decoder(m_pDeviceParms);
  69. scaler = (Scaler *) new ((PVOID)&pHwExt->CScaler) Scaler(m_pDeviceParms);
  70. xbar = (CrossBar *) new ((PVOID)&pHwExt->CXbar) CrossBar();
  71. UseRegistryValues(ConfigInfo);
  72. // According to Brooktree, 4 is the magic dividing line
  73. // between 829 and 829a. Apparently, there is an 829b on the
  74. // horizon, but I don't have the details yet.
  75. // This is meant to be a kind of fail-safe
  76. /*
  77. if (pHwExt->chipRev < 4) {
  78. outputEnablePolarity = 0;
  79. }
  80. */
  81. if (defaultDecoderWidth != 360 && defaultDecoderWidth != 720)
  82. {
  83. DBGERROR(("Unexpected defaultDecoderWidth: %d.\n", defaultDecoderWidth));
  84. TRAP();
  85. }
  86. destRect = MRect(0, 0, defaultDecoderWidth, defaultDecoderHeight);
  87. RestoreState();
  88. // by default, outputs will be tri-stated. Transitioning to the run state will enable it.
  89. SetOutputEnabled(FALSE);
  90. }
  91. Device::~Device()
  92. {
  93. delete decoder;
  94. delete scaler;
  95. delete xbar;
  96. }
  97. void Device::SaveState()
  98. {
  99. // save picture attributes
  100. hue = decoder->GetHue();
  101. saturation = decoder->GetSaturation();
  102. contrast = decoder->GetContrast();
  103. brightness = decoder->GetBrightness();
  104. // save video source
  105. source = GetVideoInput();
  106. // save configuration of data stream to video port
  107. isCodeInDataStream = IsCodeInsertionEnabled();
  108. is16 = Is16BitDataStream();
  109. // save VBI related settings
  110. VBIEN = IsVBIEN();
  111. VBIFMT = IsVBIFMT();
  112. // save scaling dimensions
  113. scaler->GetDigitalWin(destRect);
  114. }
  115. void Device::RestoreState(DWORD dwStreamsOpen)
  116. {
  117. Reset();
  118. // (re)initialize image
  119. decoder->SetInterlaced(FALSE);
  120. decoder->SetHue(hue);
  121. decoder->SetSaturation(saturation);
  122. decoder->SetContrast(contrast);
  123. decoder->SetBrightness(brightness);
  124. // (re)initialize video source
  125. SetVideoInput(source);
  126. SetOutputEnablePolarity(m_pDeviceParms->outputEnablePolarity);
  127. // (re)initialize corresponding xbar setting.
  128. Route(0, (ULONG)source);
  129. // (re)initialize configuration of data stream to video port
  130. SetCodeInsertionEnabled(isCodeInDataStream);
  131. Set16BitDataStream(is16);
  132. // restore VBI settings
  133. SetVBIEN(VBIEN);
  134. SetVBIFMT(VBIFMT);
  135. SetVideoDecoderStandard( GetVideoDecoderStandard() );
  136. // initialize scaling dimensions
  137. //SetRect(destRect); Paul: Use set video decoder standard instead
  138. if(!dwStreamsOpen)
  139. SetOutputEnabled(IsOutputEnabled());
  140. }
  141. void Device::SetRect(MRect &rect)
  142. {
  143. destRect = rect;
  144. scaler->SetAnalogWin(rect);
  145. scaler->SetDigitalWin(rect);
  146. // for Debugging
  147. #ifdef DBG
  148. scaler->DumpSomeState();
  149. #endif
  150. }
  151. void Device::Reset()
  152. {
  153. SoftwareReset();
  154. }
  155. int Device::GetDecoderWidth()
  156. {
  157. MRect tmpRect;
  158. scaler->GetDigitalWin(tmpRect);
  159. return tmpRect.right;
  160. }
  161. int Device::GetDecoderHeight()
  162. {
  163. MRect tmpRect;
  164. scaler->GetDigitalWin(tmpRect);
  165. return tmpRect.bottom;
  166. }
  167. int Device::GetDefaultDecoderWidth()
  168. {
  169. return defaultDecoderWidth;
  170. }
  171. int Device::GetDefaultDecoderHeight()
  172. {
  173. return defaultDecoderHeight;
  174. }
  175. int Device::GetPartID()
  176. {
  177. return m_pDeviceParms->chipID;
  178. }
  179. int Device::GetPartRev()
  180. {
  181. return m_pDeviceParms->chipRev;
  182. }
  183. NTSTATUS
  184. Device::GetRegistryValue(
  185. IN HANDLE Handle,
  186. IN PWCHAR KeyNameString,
  187. IN ULONG KeyNameStringLength,
  188. IN PWCHAR Data,
  189. IN ULONG DataLength
  190. )
  191. /*++
  192. Routine Description:
  193. Reads the specified registry value
  194. Arguments:
  195. Handle - handle to the registry key
  196. KeyNameString - value to read
  197. KeyNameStringLength - length of string
  198. Data - buffer to read data into
  199. DataLength - length of data buffer
  200. Return Value:
  201. NTSTATUS returned as appropriate
  202. --*/
  203. {
  204. NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
  205. UNICODE_STRING KeyName;
  206. ULONG Length;
  207. PKEY_VALUE_FULL_INFORMATION FullInfo;
  208. RtlInitUnicodeString(&KeyName, KeyNameString);
  209. Length = sizeof(KEY_VALUE_FULL_INFORMATION) +
  210. KeyNameStringLength + DataLength;
  211. FullInfo = (struct _KEY_VALUE_FULL_INFORMATION *)ExAllocatePool(PagedPool, Length);
  212. if (FullInfo) {
  213. Status = ZwQueryValueKey(Handle,
  214. &KeyName,
  215. KeyValueFullInformation,
  216. FullInfo,
  217. Length,
  218. &Length);
  219. if (NT_SUCCESS(Status)) {
  220. if (DataLength >= FullInfo->DataLength) {
  221. RtlCopyMemory(Data, ((PUCHAR) FullInfo) + FullInfo->DataOffset, FullInfo->DataLength);
  222. } else {
  223. TRAP();
  224. Status = STATUS_BUFFER_TOO_SMALL;
  225. } // buffer right length
  226. } // if success
  227. ExFreePool(FullInfo);
  228. } // if fullinfo
  229. return Status;
  230. }
  231. #define MAX_REG_STRING_LENGTH 128
  232. VOID
  233. Device::UseRegistryValues(PPORT_CONFIGURATION_INFORMATION ConfigInfo)
  234. /*++
  235. Routine Description:
  236. Reads all registry values for the device
  237. Arguments:
  238. PhysicalDeviceObject - pointer to the PDO
  239. Return Value:
  240. None.
  241. --*/
  242. {
  243. NTSTATUS Status;
  244. HANDLE handle;
  245. WCHAR MUX0String[] = L"MUX0";
  246. WCHAR MUX1String[] = L"MUX1";
  247. WCHAR MUX2String[] = L"MUX2";
  248. WCHAR buf[MAX_REG_STRING_LENGTH];
  249. ASSERT(KeGetCurrentIrql() <= PASSIVE_LEVEL);
  250. Status = IoOpenDeviceRegistryKey(ConfigInfo->RealPhysicalDeviceObject,
  251. PLUGPLAY_REGKEY_DRIVER,
  252. STANDARD_RIGHTS_ALL,
  253. &handle);
  254. //
  255. // now get all of the registry settings for
  256. // initializing the decoder
  257. //
  258. if (NT_SUCCESS(Status)) {
  259. // =========================
  260. // Does NOT check that the registry settings "make sense";
  261. // e.g., that all three inputs aren't set to SVideo.
  262. // =========================
  263. // Do MUX0
  264. // =========================
  265. Status = GetRegistryValue(handle,
  266. MUX0String,
  267. sizeof(MUX0String),
  268. buf,
  269. sizeof(buf));
  270. if ((NT_SUCCESS(Status)) && (buf))
  271. {
  272. if (stringsEqual(buf, L"svideo"))
  273. {xbar->InputPins[0] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_SVideo, -1, &CrossbarMediums[2]);}
  274. else if (stringsEqual(buf, L"tuner"))
  275. {xbar->InputPins[0] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_Tuner, -1, &CrossbarMediums[1]);}
  276. else if (stringsEqual(buf, L"composite"))
  277. {xbar->InputPins[0] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_Composite, -1, &CrossbarMediums[0]);}
  278. else if (stringsEqual(buf, L"none"))
  279. {
  280. TRAP();
  281. }
  282. else
  283. {
  284. TRAP();
  285. }
  286. }
  287. else
  288. {
  289. TRAP();
  290. }
  291. // =========================
  292. // Do MUX1
  293. // =========================
  294. Status = GetRegistryValue(handle,
  295. MUX1String,
  296. sizeof(MUX1String),
  297. buf,
  298. sizeof(buf));
  299. if ((NT_SUCCESS(Status)) && (buf))
  300. {
  301. if (stringsEqual(buf, L"svideo"))
  302. {xbar->InputPins[1] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_SVideo, -1, &CrossbarMediums[2]);}
  303. else if (stringsEqual(buf, L"tuner"))
  304. {xbar->InputPins[1] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_Tuner, -1, &CrossbarMediums[1]);}
  305. else if (stringsEqual(buf, L"composite"))
  306. {xbar->InputPins[1] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_Composite, -1, &CrossbarMediums[0]);}
  307. else if (stringsEqual(buf, L"none"))
  308. {
  309. TRAP();
  310. }
  311. else
  312. {
  313. TRAP();
  314. }
  315. }
  316. else
  317. {
  318. TRAP();
  319. }
  320. // =========================
  321. // Do MUX2
  322. // =========================
  323. Status = GetRegistryValue(handle,
  324. MUX2String,
  325. sizeof(MUX2String),
  326. buf,
  327. sizeof(buf));
  328. if ((NT_SUCCESS(Status)) && (buf))
  329. {
  330. if (stringsEqual(buf, L"svideo"))
  331. {xbar->InputPins[2] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_SVideo, -1, &CrossbarMediums[2]);}
  332. else if (stringsEqual(buf, L"tuner"))
  333. {xbar->InputPins[2] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_Tuner, -1, &CrossbarMediums[1]);}
  334. else if (stringsEqual(buf, L"composite"))
  335. {xbar->InputPins[2] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_Composite, -1, &CrossbarMediums[0]);}
  336. else if (stringsEqual(buf, L"none"))
  337. {
  338. TRAP();
  339. }
  340. else
  341. {
  342. TRAP();
  343. }
  344. }
  345. else
  346. {
  347. TRAP();
  348. }
  349. // =========================
  350. // 8 or 16 bit data width
  351. // =========================
  352. is16 = FALSE;
  353. // =========================
  354. // Control codes embedded in data stream?
  355. // =========================
  356. isCodeInDataStream = TRUE;
  357. //Paul: If hardcoding, might as well leave this with the constructor
  358. //defaultDecoderWidth = 720;
  359. //
  360. // close the registry handle.
  361. //
  362. ZwClose(handle);
  363. } // status = success
  364. }
  365. BOOL Device::stringsEqual(PWCHAR pwc1, PWCHAR pwc2)
  366. {
  367. UNICODE_STRING us1, us2;
  368. RtlInitUnicodeString(&us1, pwc1);
  369. RtlInitUnicodeString(&us2, pwc2);
  370. // case INsensitive
  371. return (RtlEqualUnicodeString(&us1, &us2, TRUE));
  372. }
  373. // ==========================================
  374. void Device::GetVideoPortProperty(PHW_STREAM_REQUEST_BLOCK pSrb)
  375. {
  376. PSTREAM_PROPERTY_DESCRIPTOR pSpd = pSrb->CommandData.PropertyInfo;
  377. ULONG Id = pSpd->Property->Id; // index of the property
  378. ULONG nS = pSpd->PropertyOutputSize; // size of data supplied
  379. ULONG standard = GetVideoDecoderStandard();
  380. switch (Id)
  381. {
  382. case KSPROPERTY_VPCONFIG_NUMCONNECTINFO :
  383. ASSERT(nS >= sizeof(ULONG));
  384. // 2 VideoPort connections are possible
  385. *(PULONG)(pSpd->PropertyInfo) = BT829_VPCONNECTIONS_NUMBER;
  386. pSrb->ActualBytesTransferred = sizeof(ULONG);
  387. break;
  388. case KSPROPERTY_VPCONFIG_GETCONNECTINFO :
  389. ASSERT(nS >= sizeof(DDVIDEOPORTCONNECT));
  390. {
  391. PKSMULTIPLE_DATA_PROP MultiProperty = (PKSMULTIPLE_DATA_PROP)pSpd->Property;
  392. if (MultiProperty->MultipleItem.Count == BT829_VPCONNECTIONS_NUMBER &&
  393. MultiProperty->MultipleItem.Size == sizeof(DDVIDEOPORTCONNECT)) {
  394. if (nS >= BT829_VPCONNECTIONS_NUMBER * sizeof(DDVIDEOPORTCONNECT)) {
  395. LPDDVIDEOPORTCONNECT pConnectInfo;
  396. pConnectInfo = (LPDDVIDEOPORTCONNECT) pSpd->PropertyInfo;
  397. // fill in the DDVIDEOPORTCONNECT structure offset 0
  398. pConnectInfo->dwSize = sizeof(DDVIDEOPORTCONNECT);
  399. pConnectInfo->dwPortWidth = 8;
  400. pConnectInfo->guidTypeID = DDVPTYPE_BROOKTREE;
  401. pConnectInfo->dwFlags = DDVPCONNECT_INVERTPOLARITY;
  402. pConnectInfo->dwReserved1 = 0;
  403. #ifdef BT829_SUPPORT_16BIT
  404. // fill in the DDVIDEOPORTCONNECT structure offset 1
  405. pConnectInfo ++;
  406. pConnectInfo->dwSize = sizeof(DDVIDEOPORTCONNECT);
  407. pConnectInfo->guidTypeID = DDVPTYPE_BROOKTREE;
  408. pConnectInfo->dwPortWidth = 16;
  409. pConnectInfo->dwFlags = DDVPCONNECT_INVERTPOLARITY;
  410. pConnectInfo->dwReserved1 = 0;
  411. #endif
  412. pSrb->ActualBytesTransferred = BT829_VPCONNECTIONS_NUMBER * sizeof(DDVIDEOPORTCONNECT);
  413. }
  414. else {
  415. pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
  416. }
  417. }
  418. else {
  419. pSrb->Status = STATUS_INVALID_PARAMETER;
  420. }
  421. }
  422. break;
  423. case KSPROPERTY_VPCONFIG_NUMVIDEOFORMAT :
  424. ASSERT(nS >= sizeof(ULONG));
  425. *(PULONG)(pSpd->PropertyInfo) = BT829_PIXELFORMATS_NUMBER;
  426. pSrb->ActualBytesTransferred = sizeof(ULONG);
  427. break;
  428. case KSPROPERTY_VPCONFIG_GETVIDEOFORMAT :
  429. ASSERT(nS >= sizeof(DDPIXELFORMAT));
  430. {
  431. PKSMULTIPLE_DATA_PROP MultiProperty = (PKSMULTIPLE_DATA_PROP)pSpd->Property;
  432. if (MultiProperty->MultipleItem.Count == BT829_PIXELFORMATS_NUMBER &&
  433. MultiProperty->MultipleItem.Size == sizeof(DDPIXELFORMAT)) {
  434. if (nS >= BT829_PIXELFORMATS_NUMBER * sizeof(DDPIXELFORMAT)) {
  435. ASSERT(BT829_PIXELFORMATS_NUMBER == 1); // as currently implemented, this must be true
  436. LPDDPIXELFORMAT pPixelFormat;
  437. pPixelFormat = (LPDDPIXELFORMAT) pSpd->PropertyInfo;
  438. RtlZeroMemory(pPixelFormat, BT829_PIXELFORMATS_NUMBER * sizeof(DDPIXELFORMAT));
  439. // fill in the DDPIXELFORMAT structure
  440. pPixelFormat->dwSize = sizeof(DDPIXELFORMAT);
  441. pPixelFormat->dwFlags = DDPF_FOURCC;
  442. pPixelFormat->dwFourCC = FOURCC_UYVY;
  443. pPixelFormat->dwYUVBitCount = 16;
  444. pPixelFormat->dwYBitMask = (DWORD)0xFF00FF00;
  445. pPixelFormat->dwUBitMask = (DWORD)0x000000FF;
  446. pPixelFormat->dwVBitMask = (DWORD)0x00FF0000;
  447. pPixelFormat->dwYUVZBitMask = 0;
  448. pSrb->ActualBytesTransferred = BT829_PIXELFORMATS_NUMBER * sizeof(DDPIXELFORMAT);
  449. }
  450. else {
  451. pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
  452. }
  453. }
  454. else {
  455. pSrb->Status = STATUS_INVALID_PARAMETER;
  456. }
  457. }
  458. break;
  459. case KSPROPERTY_VPCONFIG_VPDATAINFO :
  460. ASSERT(nS >= sizeof(KS_AMVPDATAINFO));
  461. {
  462. // Clear the portion of the buffer we plan to return
  463. RtlZeroMemory(pSpd->PropertyInfo, sizeof(KS_AMVPDATAINFO));
  464. PKS_AMVPDATAINFO pAMVPDataInfo;
  465. pAMVPDataInfo = (PKS_AMVPDATAINFO) pSpd->PropertyInfo;
  466. int decoderLostLines = (GetPartRev() >= 4) ?
  467. BT829A_LOST_LINES : BT829_LOST_LINES;
  468. // the values are sortof hardcoded for NTSC at this point
  469. // VBI values will need to be tweaked
  470. pAMVPDataInfo->dwSize = sizeof(KS_AMVPDATAINFO);
  471. if ( standard & ( KS_AnalogVideo_NTSC_Mask | KS_AnalogVideo_PAL_M ) ) // NTSC rectangle?
  472. pAMVPDataInfo->dwMicrosecondsPerField = 16667;
  473. else
  474. pAMVPDataInfo->dwMicrosecondsPerField = 20000;
  475. pAMVPDataInfo->bEnableDoubleClock = FALSE;
  476. pAMVPDataInfo->bEnableVACT = FALSE;
  477. pAMVPDataInfo->lHalfLinesOdd = 0;
  478. pAMVPDataInfo->lHalfLinesEven = 1;
  479. pAMVPDataInfo->bFieldPolarityInverted = FALSE;
  480. pAMVPDataInfo->bDataIsInterlaced = TRUE;
  481. pAMVPDataInfo->dwNumLinesInVREF = 6 - decoderLostLines;
  482. pAMVPDataInfo->amvpDimInfo.dwFieldWidth = GetDecoderWidth();
  483. // Beware of hard-coded numbers
  484. pAMVPDataInfo->amvpDimInfo.dwVBIWidth = VBISamples;
  485. if ( standard & ( KS_AnalogVideo_NTSC_Mask | KS_AnalogVideo_PAL_M ) ) // NTSC rectangle?
  486. {
  487. pAMVPDataInfo->amvpDimInfo.dwVBIHeight = NTSCVBIEnd - decoderLostLines;
  488. pAMVPDataInfo->amvpDimInfo.dwFieldHeight =
  489. GetDecoderHeight() +
  490. pAMVPDataInfo->amvpDimInfo.dwVBIHeight;
  491. /*
  492. (NTSCVBIEnd - 1) - // the '- 1' makes VBIEnd zero-based
  493. decoderLostLines -
  494. pAMVPDataInfo->dwNumLinesInVREF;
  495. */
  496. pAMVPDataInfo->amvpDimInfo.rcValidRegion.top = NTSCVBIEnd - decoderLostLines;
  497. }
  498. else
  499. {
  500. pAMVPDataInfo->amvpDimInfo.dwVBIHeight = PALVBIEnd - decoderLostLines;
  501. pAMVPDataInfo->amvpDimInfo.dwFieldHeight =
  502. GetDecoderHeight() +
  503. pAMVPDataInfo->amvpDimInfo.dwVBIHeight;
  504. /*
  505. (PALVBIEnd - 1) - // the '- 1' makes VBIEnd zero-based
  506. decoderLostLines -
  507. pAMVPDataInfo->dwNumLinesInVREF;
  508. */
  509. pAMVPDataInfo->amvpDimInfo.rcValidRegion.top = PALVBIEnd - decoderLostLines;
  510. }
  511. pAMVPDataInfo->amvpDimInfo.rcValidRegion.left = 0;
  512. pAMVPDataInfo->amvpDimInfo.rcValidRegion.right = pAMVPDataInfo->amvpDimInfo.dwFieldWidth;
  513. pAMVPDataInfo->amvpDimInfo.rcValidRegion.bottom = pAMVPDataInfo->amvpDimInfo.dwFieldHeight;
  514. pAMVPDataInfo->dwPictAspectRatioX = 4;
  515. pAMVPDataInfo->dwPictAspectRatioY = 3;
  516. pSrb->ActualBytesTransferred = sizeof(KS_AMVPDATAINFO);
  517. }
  518. break;
  519. case KSPROPERTY_VPCONFIG_MAXPIXELRATE :
  520. ASSERT(nS >= sizeof(KSVPMAXPIXELRATE));
  521. {
  522. PKSVPMAXPIXELRATE pKSPixelRate;
  523. int decoderHeight = GetDecoderHeight();
  524. int decoderWidth = GetDecoderWidth();
  525. pKSPixelRate = (PKSVPMAXPIXELRATE) pSpd->PropertyInfo;
  526. pKSPixelRate->Size.dwWidth = decoderWidth;
  527. pKSPixelRate->Size.dwHeight = decoderHeight;
  528. if ( standard & ( KS_AnalogVideo_NTSC_Mask | KS_AnalogVideo_PAL_M ) ) // NTSC rectangle?
  529. pKSPixelRate->MaxPixelsPerSecond = decoderWidth * decoderHeight * NTSC_FRAME_RATE;
  530. else
  531. pKSPixelRate->MaxPixelsPerSecond = decoderWidth * decoderHeight * PAL_FRAME_RATE;
  532. pKSPixelRate->Reserved = 0;
  533. pSrb->ActualBytesTransferred = sizeof(KSVPMAXPIXELRATE);
  534. }
  535. break;
  536. case KSPROPERTY_VPCONFIG_DECIMATIONCAPABILITY :
  537. *(PBOOL)(pSpd->PropertyInfo) = TRUE;
  538. pSrb->ActualBytesTransferred = sizeof(BOOL);
  539. break;
  540. default:
  541. TRAP();
  542. pSrb->ActualBytesTransferred = 0;
  543. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  544. break;
  545. }
  546. }
  547. void Device::GetVideoPortVBIProperty(PHW_STREAM_REQUEST_BLOCK pSrb)
  548. {
  549. PSTREAM_PROPERTY_DESCRIPTOR pSpd = pSrb->CommandData.PropertyInfo;
  550. ULONG Id = pSpd->Property->Id; // index of the property
  551. ULONG nS = pSpd->PropertyOutputSize; // size of data supplied
  552. ULONG standard = GetVideoDecoderStandard();
  553. switch (Id)
  554. {
  555. case KSPROPERTY_VPCONFIG_NUMCONNECTINFO :
  556. ASSERT(nS >= sizeof(ULONG));
  557. // 2 VideoPort connections are possible
  558. *(PULONG)(pSpd->PropertyInfo) = BT829_VPCONNECTIONS_NUMBER;
  559. pSrb->ActualBytesTransferred = sizeof(ULONG);
  560. break;
  561. case KSPROPERTY_VPCONFIG_GETCONNECTINFO :
  562. ASSERT(nS >= sizeof(DDVIDEOPORTCONNECT));
  563. {
  564. PKSMULTIPLE_DATA_PROP MultiProperty = (PKSMULTIPLE_DATA_PROP)pSpd->Property;
  565. if (MultiProperty->MultipleItem.Count == BT829_VPCONNECTIONS_NUMBER &&
  566. MultiProperty->MultipleItem.Size == sizeof(DDVIDEOPORTCONNECT)) {
  567. if (nS >= BT829_VPCONNECTIONS_NUMBER * sizeof(DDVIDEOPORTCONNECT)) {
  568. LPDDVIDEOPORTCONNECT pConnectInfo;
  569. pConnectInfo = (LPDDVIDEOPORTCONNECT) pSpd->PropertyInfo;
  570. // fill in the DDVIDEOPORTCONNECT structure offset 0
  571. pConnectInfo->dwSize = sizeof(DDVIDEOPORTCONNECT);
  572. pConnectInfo->dwPortWidth = 8;
  573. pConnectInfo->guidTypeID = DDVPTYPE_BROOKTREE;
  574. pConnectInfo->dwFlags = DDVPCONNECT_INVERTPOLARITY;
  575. pConnectInfo->dwReserved1 = 0;
  576. #ifdef BT829_SUPPORT_16BIT
  577. // fill in the DDVIDEOPORTCONNECT structure offset 1
  578. pConnectInfo ++;
  579. pConnectInfo->dwSize = sizeof(DDVIDEOPORTCONNECT);
  580. pConnectInfo->guidTypeID = DDVPTYPE_BROOKTREE;
  581. pConnectInfo->dwPortWidth = 16;
  582. pConnectInfo->dwFlags = DDVPCONNECT_INVERTPOLARITY;
  583. pConnectInfo->dwReserved1 = 0;
  584. #endif
  585. pSrb->ActualBytesTransferred = BT829_VPCONNECTIONS_NUMBER * sizeof(DDVIDEOPORTCONNECT);
  586. }
  587. else {
  588. pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
  589. }
  590. }
  591. else {
  592. pSrb->Status = STATUS_INVALID_PARAMETER;
  593. }
  594. }
  595. break;
  596. case KSPROPERTY_VPCONFIG_NUMVIDEOFORMAT :
  597. ASSERT(nS >= sizeof(ULONG));
  598. *(PULONG)(pSpd->PropertyInfo) = BT829_PIXELFORMATS_NUMBER;
  599. pSrb->ActualBytesTransferred = sizeof(ULONG);
  600. break;
  601. case KSPROPERTY_VPCONFIG_GETVIDEOFORMAT :
  602. ASSERT(nS >= sizeof(DDPIXELFORMAT));
  603. {
  604. PKSMULTIPLE_DATA_PROP MultiProperty = (PKSMULTIPLE_DATA_PROP)pSpd->Property;
  605. if (MultiProperty->MultipleItem.Count == BT829_PIXELFORMATS_NUMBER &&
  606. MultiProperty->MultipleItem.Size == sizeof(DDPIXELFORMAT)) {
  607. if (nS >= BT829_PIXELFORMATS_NUMBER * sizeof(DDPIXELFORMAT)) {
  608. ASSERT(BT829_PIXELFORMATS_NUMBER == 1); // as currently implemented, this must be true
  609. LPDDPIXELFORMAT pPixelFormat;
  610. pPixelFormat = (LPDDPIXELFORMAT) pSpd->PropertyInfo;
  611. RtlZeroMemory(pPixelFormat, BT829_PIXELFORMATS_NUMBER * sizeof(DDPIXELFORMAT));
  612. // fill in the DDPIXELFORMAT structure
  613. pPixelFormat->dwSize = sizeof(DDPIXELFORMAT);
  614. pPixelFormat->dwFlags = DDPF_FOURCC;
  615. pPixelFormat->dwFourCC = FOURCC_VBID;
  616. pPixelFormat->dwYUVBitCount = 8;
  617. pSrb->ActualBytesTransferred = BT829_PIXELFORMATS_NUMBER * sizeof(DDPIXELFORMAT);
  618. }
  619. else {
  620. pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
  621. }
  622. }
  623. else {
  624. pSrb->Status = STATUS_INVALID_PARAMETER;
  625. }
  626. }
  627. break;
  628. case KSPROPERTY_VPCONFIG_VPDATAINFO :
  629. ASSERT(nS >= sizeof(KS_AMVPDATAINFO));
  630. {
  631. // Clear the portion of the buffer we plan to return
  632. RtlZeroMemory(pSpd->PropertyInfo, sizeof(KS_AMVPDATAINFO));
  633. PKS_AMVPDATAINFO pAMVPDataInfo;
  634. pAMVPDataInfo = (PKS_AMVPDATAINFO) pSpd->PropertyInfo;
  635. int decoderLostLines = (GetPartRev() >= 4) ?
  636. BT829A_LOST_LINES : BT829_LOST_LINES;
  637. // the values are sortof hardcoded for NTSC at this point
  638. // VBI values will need to be tweaked
  639. pAMVPDataInfo->dwSize = sizeof(KS_AMVPDATAINFO);
  640. if ( standard & ( KS_AnalogVideo_NTSC_Mask | KS_AnalogVideo_PAL_M ) ) // NTSC rectangle?
  641. pAMVPDataInfo->dwMicrosecondsPerField = 16667;
  642. else
  643. pAMVPDataInfo->dwMicrosecondsPerField = 20000;
  644. pAMVPDataInfo->bEnableDoubleClock = FALSE;
  645. pAMVPDataInfo->bEnableVACT = FALSE;
  646. pAMVPDataInfo->lHalfLinesOdd = 0;
  647. pAMVPDataInfo->lHalfLinesEven = 1;
  648. pAMVPDataInfo->bFieldPolarityInverted = FALSE;
  649. pAMVPDataInfo->bDataIsInterlaced = TRUE;
  650. pAMVPDataInfo->dwNumLinesInVREF = 6 - decoderLostLines;
  651. pAMVPDataInfo->amvpDimInfo.dwFieldWidth = GetDecoderWidth();
  652. // Beware of hard-coded numbers
  653. pAMVPDataInfo->amvpDimInfo.dwVBIWidth = VBISamples;
  654. if ( standard & ( KS_AnalogVideo_NTSC_Mask | KS_AnalogVideo_PAL_M ) ) // NTSC rectangle?
  655. {
  656. pAMVPDataInfo->amvpDimInfo.dwVBIHeight = NTSCVBIEnd - decoderLostLines;
  657. pAMVPDataInfo->amvpDimInfo.dwFieldHeight =
  658. GetDecoderHeight() +
  659. pAMVPDataInfo->amvpDimInfo.dwVBIHeight;
  660. /*
  661. (NTSCVBIEnd - 1) - // the '- 1' makes VBIEnd zero-based
  662. decoderLostLines -
  663. pAMVPDataInfo->dwNumLinesInVREF;
  664. */
  665. pAMVPDataInfo->amvpDimInfo.rcValidRegion.top = NTSCVBIStart - 1 - decoderLostLines;
  666. }
  667. else
  668. {
  669. pAMVPDataInfo->amvpDimInfo.dwVBIHeight = PALVBIEnd - decoderLostLines;
  670. pAMVPDataInfo->amvpDimInfo.dwFieldHeight =
  671. GetDecoderHeight() +
  672. pAMVPDataInfo->amvpDimInfo.dwVBIHeight;
  673. /*
  674. (PALVBIEnd - 1) - // the '- 1' makes VBIEnd zero-based
  675. decoderLostLines -
  676. pAMVPDataInfo->dwNumLinesInVREF;
  677. */
  678. pAMVPDataInfo->amvpDimInfo.rcValidRegion.top = PALVBIStart - 1 - decoderLostLines;
  679. }
  680. pAMVPDataInfo->amvpDimInfo.rcValidRegion.left = 0;
  681. pAMVPDataInfo->amvpDimInfo.rcValidRegion.right = pAMVPDataInfo->amvpDimInfo.dwVBIWidth;
  682. pAMVPDataInfo->amvpDimInfo.rcValidRegion.bottom = pAMVPDataInfo->amvpDimInfo.dwVBIHeight;
  683. pSrb->ActualBytesTransferred = sizeof(KS_AMVPDATAINFO);
  684. }
  685. break;
  686. case KSPROPERTY_VPCONFIG_MAXPIXELRATE :
  687. ASSERT(nS >= sizeof(KSVPMAXPIXELRATE));
  688. {
  689. PKSVPMAXPIXELRATE pKSPixelRate;
  690. int decoderHeight = GetDecoderHeight();
  691. int decoderWidth = GetDecoderWidth();
  692. pKSPixelRate = (PKSVPMAXPIXELRATE) pSpd->PropertyInfo;
  693. pKSPixelRate->Size.dwWidth = decoderWidth;
  694. pKSPixelRate->Size.dwHeight = decoderHeight;
  695. if ( standard & ( KS_AnalogVideo_NTSC_Mask | KS_AnalogVideo_PAL_M ) ) // NTSC rectangle?
  696. pKSPixelRate->MaxPixelsPerSecond = decoderWidth * decoderHeight * NTSC_FRAME_RATE;
  697. else
  698. pKSPixelRate->MaxPixelsPerSecond = decoderWidth * decoderHeight * PAL_FRAME_RATE;
  699. pKSPixelRate->Reserved = 0;
  700. pSrb->ActualBytesTransferred = sizeof(KSVPMAXPIXELRATE);
  701. }
  702. break;
  703. case KSPROPERTY_VPCONFIG_DECIMATIONCAPABILITY :
  704. *(PBOOL)(pSpd->PropertyInfo) = FALSE;
  705. pSrb->ActualBytesTransferred = sizeof(BOOL);
  706. break;
  707. default:
  708. TRAP();
  709. pSrb->ActualBytesTransferred = 0;
  710. pSrb->Status = STATUS_NOT_IMPLEMENTED;
  711. break;
  712. }
  713. }
  714. void Device::ConfigVPSurfaceParams(PKSVPSURFACEPARAMS pSurfaceParams)
  715. {
  716. DBGINFO(("VP Surface Params:\n"));
  717. DBGINFO(("dwPitch = %d\n",pSurfaceParams->dwPitch));
  718. DBGINFO(("dwXOrigin = %d\n",pSurfaceParams->dwXOrigin));
  719. DBGINFO(("dwYOrigin = %d\n",pSurfaceParams->dwYOrigin));
  720. VideoSurfaceOriginX = pSurfaceParams->dwXOrigin;
  721. VideoSurfaceOriginY = pSurfaceParams->dwYOrigin;
  722. VideoSurfacePitch = pSurfaceParams->dwPitch;
  723. }
  724. void Device::ConfigVPVBISurfaceParams(PKSVPSURFACEPARAMS pSurfaceParams)
  725. {
  726. DBGINFO(("VP VBI Surface Params:\n"));
  727. DBGINFO(("dwPitch = %d\n",pSurfaceParams->dwPitch));
  728. DBGINFO(("dwXOrigin = %d\n",pSurfaceParams->dwXOrigin));
  729. DBGINFO(("dwYOrigin = %d\n",pSurfaceParams->dwYOrigin));
  730. VBISurfaceOriginX = pSurfaceParams->dwXOrigin;
  731. VBISurfaceOriginY = pSurfaceParams->dwYOrigin;
  732. VBISurfacePitch = pSurfaceParams->dwPitch;
  733. }
  734. // -------------------------------------------------------------------
  735. // VideoProcAmp functions
  736. // -------------------------------------------------------------------
  737. NTSTATUS Device::SetProcAmpProperty(ULONG Id, LONG Value)
  738. {
  739. switch (Id) {
  740. case KSPROPERTY_VIDEOPROCAMP_BRIGHTNESS:
  741. decoder->SetBrightness(Value);
  742. break;
  743. case KSPROPERTY_VIDEOPROCAMP_CONTRAST:
  744. decoder->SetContrast(Value);
  745. break;
  746. case KSPROPERTY_VIDEOPROCAMP_HUE:
  747. decoder->SetHue(Value);
  748. break;
  749. case KSPROPERTY_VIDEOPROCAMP_SATURATION:
  750. decoder->SetSaturation(Value);
  751. break;
  752. default:
  753. TRAP();
  754. return STATUS_NOT_IMPLEMENTED;
  755. break;
  756. }
  757. return STATUS_SUCCESS;
  758. }
  759. NTSTATUS Device::GetProcAmpProperty(ULONG Id, PLONG pValue)
  760. {
  761. switch (Id) {
  762. case KSPROPERTY_VIDEOPROCAMP_BRIGHTNESS:
  763. *pValue = decoder->GetBrightness();
  764. break;
  765. case KSPROPERTY_VIDEOPROCAMP_CONTRAST:
  766. *pValue = decoder->GetContrast();
  767. break;
  768. case KSPROPERTY_VIDEOPROCAMP_HUE:
  769. *pValue = decoder->GetHue();
  770. break;
  771. case KSPROPERTY_VIDEOPROCAMP_SATURATION:
  772. *pValue = decoder->GetSaturation();
  773. break;
  774. default:
  775. TRAP();
  776. return STATUS_NOT_IMPLEMENTED;
  777. break;
  778. }
  779. return STATUS_SUCCESS;
  780. }
  781. BOOL Device::SetVideoDecoderStandard(DWORD standard) //Paul: Changed
  782. {
  783. if ( decoder->SetVideoDecoderStandard(standard) )
  784. {
  785. switch (standard)
  786. {
  787. case KS_AnalogVideo_NTSC_M:
  788. scaler->VideoFormatChanged( VFormat_NTSC );
  789. break;
  790. case KS_AnalogVideo_NTSC_M_J:
  791. scaler->VideoFormatChanged( VFormat_NTSC_J );
  792. break;
  793. case KS_AnalogVideo_PAL_B:
  794. case KS_AnalogVideo_PAL_D:
  795. case KS_AnalogVideo_PAL_G:
  796. case KS_AnalogVideo_PAL_H:
  797. case KS_AnalogVideo_PAL_I:
  798. scaler->VideoFormatChanged( VFormat_PAL_BDGHI ); // PAL_BDGHI covers most areas
  799. break;
  800. case KS_AnalogVideo_PAL_M:
  801. scaler->VideoFormatChanged( VFormat_PAL_M );
  802. break;
  803. case KS_AnalogVideo_PAL_N:
  804. scaler->VideoFormatChanged( VFormat_PAL_N_COMB );
  805. break;
  806. default: //Paul: SECAM
  807. scaler->VideoFormatChanged( VFormat_SECAM );
  808. }
  809. //SetRect(destRect);
  810. return TRUE;
  811. }
  812. return FALSE;
  813. }