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
1052 lines
34 KiB
//==========================================================================;
|
|
//
|
|
// Device - Implementation of the Bt829 CVideoDecoderDevice
|
|
//
|
|
// $Date: 28 Aug 1998 14:44:20 $
|
|
// $Revision: 1.2 $
|
|
// $Author: Tashjian $
|
|
//
|
|
// $Copyright: (c) 1997 - 1998 ATI Technologies Inc. All Rights Reserved. $
|
|
//
|
|
//==========================================================================;
|
|
|
|
#include "register.h"
|
|
#include "defaults.h"
|
|
#include "device.h"
|
|
#include "mediums.h"
|
|
#include "capdebug.h"
|
|
#include "StrmInfo.h"
|
|
|
|
#include "initguid.h"
|
|
DEFINE_GUID(DDVPTYPE_BROOKTREE, 0x1352A560L,0xDA61,0x11CF,0x9B,0x06,0x00,0xA0,0xC9,0x03,0xA3,0xB8);
|
|
|
|
|
|
#ifdef BT829_SUPPORT_16BIT
|
|
#define BT829_VPCONNECTIONS_NUMBER 2
|
|
#else
|
|
#define BT829_VPCONNECTIONS_NUMBER 1
|
|
#endif
|
|
#define BT829_PIXELFORMATS_NUMBER 1
|
|
#define NTSC_FRAME_RATE 30
|
|
#define PAL_FRAME_RATE 25
|
|
#define BT829_LOST_LINES 2 // BT829
|
|
#define BT829A_LOST_LINES 3 // BT829a
|
|
|
|
|
|
Device::Device( PPORT_CONFIGURATION_INFORMATION ConfigInfo,
|
|
PDEVICE_PARMS pDeviceParms,
|
|
PUINT puiError) :
|
|
|
|
m_pDeviceParms(pDeviceParms),
|
|
|
|
// Corresponds to KS_DEFAULTs
|
|
hue(128),
|
|
saturation(128),
|
|
contrast(128),
|
|
brightness(128),
|
|
source(ConTuner),
|
|
VBIEN(FALSE),
|
|
VBIFMT(FALSE),
|
|
|
|
// Beware of these hardcoded values
|
|
|
|
//Paul: Setup default for NTSC and PAL
|
|
NTSCDecoderWidth(720),
|
|
NTSCDecoderHeight(240),
|
|
PALDecoderWidth(720),
|
|
PALDecoderHeight(288),
|
|
// Now set via registry
|
|
defaultDecoderWidth(720),
|
|
defaultDecoderHeight(240)
|
|
{
|
|
*puiError = 0;
|
|
|
|
RegisterB devRegIDCODE (0x17, RO, pDeviceParms);
|
|
RegField devFieldPART_ID (devRegIDCODE, 4, 4);
|
|
RegField devFieldPART_REV (devRegIDCODE, 0, 4);
|
|
|
|
m_pDeviceParms->chipID = (int)devFieldPART_ID;
|
|
m_pDeviceParms->chipRev = (int)devFieldPART_REV;
|
|
|
|
DBGINFO(("Chip ID: 0x%x\n", m_pDeviceParms->chipID));
|
|
DBGINFO(("Chip revision: 0x%x\n", m_pDeviceParms->chipRev));
|
|
|
|
// Bt829 should have a PartID of 1110b (0xe).
|
|
if (m_pDeviceParms->chipID != 0xe)
|
|
{
|
|
DBGERROR(("I2c failure or wrong decoder.\n"));
|
|
*puiError = 1;
|
|
return;
|
|
}
|
|
|
|
PDEVICE_DATA_EXTENSION pHwExt = (PDEVICE_DATA_EXTENSION)ConfigInfo->HwDeviceExtension;
|
|
decoder = (Decoder *) new ((PVOID)&pHwExt->CDecoder) Decoder(m_pDeviceParms);
|
|
scaler = (Scaler *) new ((PVOID)&pHwExt->CScaler) Scaler(m_pDeviceParms);
|
|
xbar = (CrossBar *) new ((PVOID)&pHwExt->CXbar) CrossBar();
|
|
|
|
UseRegistryValues(ConfigInfo);
|
|
|
|
// According to Brooktree, 4 is the magic dividing line
|
|
// between 829 and 829a. Apparently, there is an 829b on the
|
|
// horizon, but I don't have the details yet.
|
|
// This is meant to be a kind of fail-safe
|
|
/*
|
|
if (pHwExt->chipRev < 4) {
|
|
outputEnablePolarity = 0;
|
|
}
|
|
*/
|
|
|
|
if (defaultDecoderWidth != 360 && defaultDecoderWidth != 720)
|
|
{
|
|
DBGERROR(("Unexpected defaultDecoderWidth: %d.\n", defaultDecoderWidth));
|
|
TRAP();
|
|
}
|
|
|
|
destRect = MRect(0, 0, defaultDecoderWidth, defaultDecoderHeight);
|
|
|
|
RestoreState();
|
|
|
|
// by default, outputs will be tri-stated. Transitioning to the run state will enable it.
|
|
SetOutputEnabled(FALSE);
|
|
}
|
|
|
|
Device::~Device()
|
|
{
|
|
delete decoder;
|
|
delete scaler;
|
|
delete xbar;
|
|
}
|
|
|
|
void Device::SaveState()
|
|
{
|
|
// save picture attributes
|
|
hue = decoder->GetHue();
|
|
saturation = decoder->GetSaturation();
|
|
contrast = decoder->GetContrast();
|
|
brightness = decoder->GetBrightness();
|
|
|
|
// save video source
|
|
source = GetVideoInput();
|
|
|
|
// save configuration of data stream to video port
|
|
isCodeInDataStream = IsCodeInsertionEnabled();
|
|
is16 = Is16BitDataStream();
|
|
|
|
// save VBI related settings
|
|
VBIEN = IsVBIEN();
|
|
VBIFMT = IsVBIFMT();
|
|
|
|
// save scaling dimensions
|
|
scaler->GetDigitalWin(destRect);
|
|
}
|
|
|
|
void Device::RestoreState(DWORD dwStreamsOpen)
|
|
{
|
|
Reset();
|
|
|
|
// (re)initialize image
|
|
decoder->SetInterlaced(FALSE);
|
|
decoder->SetHue(hue);
|
|
decoder->SetSaturation(saturation);
|
|
decoder->SetContrast(contrast);
|
|
decoder->SetBrightness(brightness);
|
|
|
|
// (re)initialize video source
|
|
SetVideoInput(source);
|
|
|
|
SetOutputEnablePolarity(m_pDeviceParms->outputEnablePolarity);
|
|
|
|
// (re)initialize corresponding xbar setting.
|
|
Route(0, (ULONG)source);
|
|
|
|
// (re)initialize configuration of data stream to video port
|
|
SetCodeInsertionEnabled(isCodeInDataStream);
|
|
Set16BitDataStream(is16);
|
|
|
|
// restore VBI settings
|
|
SetVBIEN(VBIEN);
|
|
SetVBIFMT(VBIFMT);
|
|
|
|
SetVideoDecoderStandard( GetVideoDecoderStandard() );
|
|
// initialize scaling dimensions
|
|
//SetRect(destRect); Paul: Use set video decoder standard instead
|
|
|
|
if(!dwStreamsOpen)
|
|
SetOutputEnabled(IsOutputEnabled());
|
|
}
|
|
|
|
void Device::SetRect(MRect &rect)
|
|
{
|
|
destRect = rect;
|
|
scaler->SetAnalogWin(rect);
|
|
scaler->SetDigitalWin(rect);
|
|
|
|
// for Debugging
|
|
#ifdef DBG
|
|
scaler->DumpSomeState();
|
|
#endif
|
|
}
|
|
|
|
void Device::Reset()
|
|
{
|
|
SoftwareReset();
|
|
}
|
|
|
|
int Device::GetDecoderWidth()
|
|
{
|
|
MRect tmpRect;
|
|
scaler->GetDigitalWin(tmpRect);
|
|
|
|
return tmpRect.right;
|
|
}
|
|
|
|
int Device::GetDecoderHeight()
|
|
{
|
|
MRect tmpRect;
|
|
scaler->GetDigitalWin(tmpRect);
|
|
|
|
return tmpRect.bottom;
|
|
}
|
|
|
|
int Device::GetDefaultDecoderWidth()
|
|
{
|
|
return defaultDecoderWidth;
|
|
}
|
|
|
|
int Device::GetDefaultDecoderHeight()
|
|
{
|
|
return defaultDecoderHeight;
|
|
}
|
|
|
|
int Device::GetPartID()
|
|
{
|
|
return m_pDeviceParms->chipID;
|
|
}
|
|
|
|
int Device::GetPartRev()
|
|
{
|
|
return m_pDeviceParms->chipRev;
|
|
}
|
|
|
|
NTSTATUS
|
|
Device::GetRegistryValue(
|
|
IN HANDLE Handle,
|
|
IN PWCHAR KeyNameString,
|
|
IN ULONG KeyNameStringLength,
|
|
IN PWCHAR Data,
|
|
IN ULONG DataLength
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Reads the specified registry value
|
|
|
|
Arguments:
|
|
|
|
Handle - handle to the registry key
|
|
KeyNameString - value to read
|
|
KeyNameStringLength - length of string
|
|
Data - buffer to read data into
|
|
DataLength - length of data buffer
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS returned as appropriate
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
UNICODE_STRING KeyName;
|
|
ULONG Length;
|
|
PKEY_VALUE_FULL_INFORMATION FullInfo;
|
|
|
|
RtlInitUnicodeString(&KeyName, KeyNameString);
|
|
|
|
Length = sizeof(KEY_VALUE_FULL_INFORMATION) +
|
|
KeyNameStringLength + DataLength;
|
|
|
|
FullInfo = (struct _KEY_VALUE_FULL_INFORMATION *)ExAllocatePool(PagedPool, Length);
|
|
|
|
if (FullInfo) {
|
|
Status = ZwQueryValueKey(Handle,
|
|
&KeyName,
|
|
KeyValueFullInformation,
|
|
FullInfo,
|
|
Length,
|
|
&Length);
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
if (DataLength >= FullInfo->DataLength) {
|
|
RtlCopyMemory(Data, ((PUCHAR) FullInfo) + FullInfo->DataOffset, FullInfo->DataLength);
|
|
|
|
} else {
|
|
|
|
TRAP();
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
} // buffer right length
|
|
|
|
} // if success
|
|
ExFreePool(FullInfo);
|
|
|
|
} // if fullinfo
|
|
return Status;
|
|
|
|
}
|
|
|
|
#define MAX_REG_STRING_LENGTH 128
|
|
|
|
|
|
VOID
|
|
Device::UseRegistryValues(PPORT_CONFIGURATION_INFORMATION ConfigInfo)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Reads all registry values for the device
|
|
|
|
Arguments:
|
|
|
|
PhysicalDeviceObject - pointer to the PDO
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
HANDLE handle;
|
|
|
|
WCHAR MUX0String[] = L"MUX0";
|
|
WCHAR MUX1String[] = L"MUX1";
|
|
WCHAR MUX2String[] = L"MUX2";
|
|
WCHAR buf[MAX_REG_STRING_LENGTH];
|
|
|
|
ASSERT(KeGetCurrentIrql() <= PASSIVE_LEVEL);
|
|
|
|
Status = IoOpenDeviceRegistryKey(ConfigInfo->RealPhysicalDeviceObject,
|
|
PLUGPLAY_REGKEY_DRIVER,
|
|
STANDARD_RIGHTS_ALL,
|
|
&handle);
|
|
|
|
//
|
|
// now get all of the registry settings for
|
|
// initializing the decoder
|
|
//
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
// =========================
|
|
// Does NOT check that the registry settings "make sense";
|
|
// e.g., that all three inputs aren't set to SVideo.
|
|
|
|
|
|
// =========================
|
|
// Do MUX0
|
|
// =========================
|
|
Status = GetRegistryValue(handle,
|
|
MUX0String,
|
|
sizeof(MUX0String),
|
|
buf,
|
|
sizeof(buf));
|
|
|
|
if ((NT_SUCCESS(Status)) && (buf))
|
|
{
|
|
if (stringsEqual(buf, L"svideo"))
|
|
{xbar->InputPins[0] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_SVideo, -1, &CrossbarMediums[2]);}
|
|
else if (stringsEqual(buf, L"tuner"))
|
|
{xbar->InputPins[0] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_Tuner, -1, &CrossbarMediums[1]);}
|
|
else if (stringsEqual(buf, L"composite"))
|
|
{xbar->InputPins[0] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_Composite, -1, &CrossbarMediums[0]);}
|
|
else if (stringsEqual(buf, L"none"))
|
|
{
|
|
TRAP();
|
|
}
|
|
else
|
|
{
|
|
TRAP();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TRAP();
|
|
}
|
|
|
|
|
|
// =========================
|
|
// Do MUX1
|
|
// =========================
|
|
Status = GetRegistryValue(handle,
|
|
MUX1String,
|
|
sizeof(MUX1String),
|
|
buf,
|
|
sizeof(buf));
|
|
|
|
if ((NT_SUCCESS(Status)) && (buf))
|
|
{
|
|
if (stringsEqual(buf, L"svideo"))
|
|
{xbar->InputPins[1] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_SVideo, -1, &CrossbarMediums[2]);}
|
|
else if (stringsEqual(buf, L"tuner"))
|
|
{xbar->InputPins[1] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_Tuner, -1, &CrossbarMediums[1]);}
|
|
else if (stringsEqual(buf, L"composite"))
|
|
{xbar->InputPins[1] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_Composite, -1, &CrossbarMediums[0]);}
|
|
else if (stringsEqual(buf, L"none"))
|
|
{
|
|
TRAP();
|
|
}
|
|
else
|
|
{
|
|
TRAP();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TRAP();
|
|
}
|
|
|
|
|
|
// =========================
|
|
// Do MUX2
|
|
// =========================
|
|
Status = GetRegistryValue(handle,
|
|
MUX2String,
|
|
sizeof(MUX2String),
|
|
buf,
|
|
sizeof(buf));
|
|
|
|
if ((NT_SUCCESS(Status)) && (buf))
|
|
{
|
|
if (stringsEqual(buf, L"svideo"))
|
|
{xbar->InputPins[2] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_SVideo, -1, &CrossbarMediums[2]);}
|
|
else if (stringsEqual(buf, L"tuner"))
|
|
{xbar->InputPins[2] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_Tuner, -1, &CrossbarMediums[1]);}
|
|
else if (stringsEqual(buf, L"composite"))
|
|
{xbar->InputPins[2] = _XBAR_PIN_DESCRIPTION(KS_PhysConn_Video_Composite, -1, &CrossbarMediums[0]);}
|
|
else if (stringsEqual(buf, L"none"))
|
|
{
|
|
TRAP();
|
|
}
|
|
else
|
|
{
|
|
TRAP();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TRAP();
|
|
}
|
|
|
|
|
|
// =========================
|
|
// 8 or 16 bit data width
|
|
// =========================
|
|
|
|
is16 = FALSE;
|
|
|
|
|
|
// =========================
|
|
// Control codes embedded in data stream?
|
|
// =========================
|
|
|
|
isCodeInDataStream = TRUE;
|
|
|
|
|
|
//Paul: If hardcoding, might as well leave this with the constructor
|
|
//defaultDecoderWidth = 720;
|
|
|
|
//
|
|
// close the registry handle.
|
|
//
|
|
|
|
ZwClose(handle);
|
|
|
|
} // status = success
|
|
}
|
|
|
|
BOOL Device::stringsEqual(PWCHAR pwc1, PWCHAR pwc2)
|
|
{
|
|
UNICODE_STRING us1, us2;
|
|
RtlInitUnicodeString(&us1, pwc1);
|
|
RtlInitUnicodeString(&us2, pwc2);
|
|
|
|
// case INsensitive
|
|
return (RtlEqualUnicodeString(&us1, &us2, TRUE));
|
|
}
|
|
// ==========================================
|
|
|
|
void Device::GetVideoPortProperty(PHW_STREAM_REQUEST_BLOCK pSrb)
|
|
{
|
|
PSTREAM_PROPERTY_DESCRIPTOR pSpd = pSrb->CommandData.PropertyInfo;
|
|
ULONG Id = pSpd->Property->Id; // index of the property
|
|
ULONG nS = pSpd->PropertyOutputSize; // size of data supplied
|
|
ULONG standard = GetVideoDecoderStandard();
|
|
|
|
switch (Id)
|
|
{
|
|
case KSPROPERTY_VPCONFIG_NUMCONNECTINFO :
|
|
ASSERT(nS >= sizeof(ULONG));
|
|
|
|
// 2 VideoPort connections are possible
|
|
*(PULONG)(pSpd->PropertyInfo) = BT829_VPCONNECTIONS_NUMBER;
|
|
|
|
pSrb->ActualBytesTransferred = sizeof(ULONG);
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_GETCONNECTINFO :
|
|
|
|
ASSERT(nS >= sizeof(DDVIDEOPORTCONNECT));
|
|
|
|
{
|
|
PKSMULTIPLE_DATA_PROP MultiProperty = (PKSMULTIPLE_DATA_PROP)pSpd->Property;
|
|
|
|
if (MultiProperty->MultipleItem.Count == BT829_VPCONNECTIONS_NUMBER &&
|
|
MultiProperty->MultipleItem.Size == sizeof(DDVIDEOPORTCONNECT)) {
|
|
|
|
if (nS >= BT829_VPCONNECTIONS_NUMBER * sizeof(DDVIDEOPORTCONNECT)) {
|
|
|
|
LPDDVIDEOPORTCONNECT pConnectInfo;
|
|
|
|
pConnectInfo = (LPDDVIDEOPORTCONNECT) pSpd->PropertyInfo;
|
|
|
|
// fill in the DDVIDEOPORTCONNECT structure offset 0
|
|
pConnectInfo->dwSize = sizeof(DDVIDEOPORTCONNECT);
|
|
pConnectInfo->dwPortWidth = 8;
|
|
pConnectInfo->guidTypeID = DDVPTYPE_BROOKTREE;
|
|
pConnectInfo->dwFlags = DDVPCONNECT_INVERTPOLARITY;
|
|
pConnectInfo->dwReserved1 = 0;
|
|
|
|
#ifdef BT829_SUPPORT_16BIT
|
|
// fill in the DDVIDEOPORTCONNECT structure offset 1
|
|
pConnectInfo ++;
|
|
pConnectInfo->dwSize = sizeof(DDVIDEOPORTCONNECT);
|
|
pConnectInfo->guidTypeID = DDVPTYPE_BROOKTREE;
|
|
pConnectInfo->dwPortWidth = 16;
|
|
pConnectInfo->dwFlags = DDVPCONNECT_INVERTPOLARITY;
|
|
pConnectInfo->dwReserved1 = 0;
|
|
#endif
|
|
pSrb->ActualBytesTransferred = BT829_VPCONNECTIONS_NUMBER * sizeof(DDVIDEOPORTCONNECT);
|
|
}
|
|
else {
|
|
pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
|
|
}
|
|
}
|
|
else {
|
|
pSrb->Status = STATUS_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_NUMVIDEOFORMAT :
|
|
ASSERT(nS >= sizeof(ULONG));
|
|
|
|
*(PULONG)(pSpd->PropertyInfo) = BT829_PIXELFORMATS_NUMBER;
|
|
|
|
pSrb->ActualBytesTransferred = sizeof(ULONG);
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_GETVIDEOFORMAT :
|
|
|
|
ASSERT(nS >= sizeof(DDPIXELFORMAT));
|
|
|
|
{
|
|
PKSMULTIPLE_DATA_PROP MultiProperty = (PKSMULTIPLE_DATA_PROP)pSpd->Property;
|
|
|
|
if (MultiProperty->MultipleItem.Count == BT829_PIXELFORMATS_NUMBER &&
|
|
MultiProperty->MultipleItem.Size == sizeof(DDPIXELFORMAT)) {
|
|
|
|
if (nS >= BT829_PIXELFORMATS_NUMBER * sizeof(DDPIXELFORMAT)) {
|
|
|
|
ASSERT(BT829_PIXELFORMATS_NUMBER == 1); // as currently implemented, this must be true
|
|
|
|
LPDDPIXELFORMAT pPixelFormat;
|
|
|
|
pPixelFormat = (LPDDPIXELFORMAT) pSpd->PropertyInfo;
|
|
|
|
RtlZeroMemory(pPixelFormat, BT829_PIXELFORMATS_NUMBER * sizeof(DDPIXELFORMAT));
|
|
|
|
// fill in the DDPIXELFORMAT structure
|
|
pPixelFormat->dwSize = sizeof(DDPIXELFORMAT);
|
|
pPixelFormat->dwFlags = DDPF_FOURCC;
|
|
pPixelFormat->dwFourCC = FOURCC_UYVY;
|
|
pPixelFormat->dwYUVBitCount = 16;
|
|
pPixelFormat->dwYBitMask = (DWORD)0xFF00FF00;
|
|
pPixelFormat->dwUBitMask = (DWORD)0x000000FF;
|
|
pPixelFormat->dwVBitMask = (DWORD)0x00FF0000;
|
|
pPixelFormat->dwYUVZBitMask = 0;
|
|
|
|
pSrb->ActualBytesTransferred = BT829_PIXELFORMATS_NUMBER * sizeof(DDPIXELFORMAT);
|
|
}
|
|
else {
|
|
pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
|
|
}
|
|
}
|
|
else {
|
|
pSrb->Status = STATUS_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_VPDATAINFO :
|
|
|
|
ASSERT(nS >= sizeof(KS_AMVPDATAINFO));
|
|
|
|
{
|
|
// Clear the portion of the buffer we plan to return
|
|
RtlZeroMemory(pSpd->PropertyInfo, sizeof(KS_AMVPDATAINFO));
|
|
|
|
PKS_AMVPDATAINFO pAMVPDataInfo;
|
|
|
|
pAMVPDataInfo = (PKS_AMVPDATAINFO) pSpd->PropertyInfo;
|
|
|
|
int decoderLostLines = (GetPartRev() >= 4) ?
|
|
BT829A_LOST_LINES : BT829_LOST_LINES;
|
|
|
|
// the values are sortof hardcoded for NTSC at this point
|
|
// VBI values will need to be tweaked
|
|
pAMVPDataInfo->dwSize = sizeof(KS_AMVPDATAINFO);
|
|
|
|
if ( standard & ( KS_AnalogVideo_NTSC_Mask | KS_AnalogVideo_PAL_M ) ) // NTSC rectangle?
|
|
pAMVPDataInfo->dwMicrosecondsPerField = 16667;
|
|
else
|
|
pAMVPDataInfo->dwMicrosecondsPerField = 20000;
|
|
|
|
pAMVPDataInfo->bEnableDoubleClock = FALSE;
|
|
pAMVPDataInfo->bEnableVACT = FALSE;
|
|
|
|
pAMVPDataInfo->lHalfLinesOdd = 0;
|
|
pAMVPDataInfo->lHalfLinesEven = 1;
|
|
|
|
pAMVPDataInfo->bFieldPolarityInverted = FALSE;
|
|
pAMVPDataInfo->bDataIsInterlaced = TRUE;
|
|
pAMVPDataInfo->dwNumLinesInVREF = 6 - decoderLostLines;
|
|
|
|
pAMVPDataInfo->amvpDimInfo.dwFieldWidth = GetDecoderWidth();
|
|
|
|
// Beware of hard-coded numbers
|
|
pAMVPDataInfo->amvpDimInfo.dwVBIWidth = VBISamples;
|
|
|
|
if ( standard & ( KS_AnalogVideo_NTSC_Mask | KS_AnalogVideo_PAL_M ) ) // NTSC rectangle?
|
|
{
|
|
pAMVPDataInfo->amvpDimInfo.dwVBIHeight = NTSCVBIEnd - decoderLostLines;
|
|
pAMVPDataInfo->amvpDimInfo.dwFieldHeight =
|
|
GetDecoderHeight() +
|
|
pAMVPDataInfo->amvpDimInfo.dwVBIHeight;
|
|
/*
|
|
(NTSCVBIEnd - 1) - // the '- 1' makes VBIEnd zero-based
|
|
decoderLostLines -
|
|
pAMVPDataInfo->dwNumLinesInVREF;
|
|
*/
|
|
|
|
pAMVPDataInfo->amvpDimInfo.rcValidRegion.top = NTSCVBIEnd - decoderLostLines;
|
|
}
|
|
else
|
|
{
|
|
pAMVPDataInfo->amvpDimInfo.dwVBIHeight = PALVBIEnd - decoderLostLines;
|
|
pAMVPDataInfo->amvpDimInfo.dwFieldHeight =
|
|
GetDecoderHeight() +
|
|
pAMVPDataInfo->amvpDimInfo.dwVBIHeight;
|
|
/*
|
|
(PALVBIEnd - 1) - // the '- 1' makes VBIEnd zero-based
|
|
decoderLostLines -
|
|
pAMVPDataInfo->dwNumLinesInVREF;
|
|
*/
|
|
|
|
pAMVPDataInfo->amvpDimInfo.rcValidRegion.top = PALVBIEnd - decoderLostLines;
|
|
}
|
|
|
|
pAMVPDataInfo->amvpDimInfo.rcValidRegion.left = 0;
|
|
pAMVPDataInfo->amvpDimInfo.rcValidRegion.right = pAMVPDataInfo->amvpDimInfo.dwFieldWidth;
|
|
pAMVPDataInfo->amvpDimInfo.rcValidRegion.bottom = pAMVPDataInfo->amvpDimInfo.dwFieldHeight;
|
|
|
|
pAMVPDataInfo->dwPictAspectRatioX = 4;
|
|
pAMVPDataInfo->dwPictAspectRatioY = 3;
|
|
|
|
pSrb->ActualBytesTransferred = sizeof(KS_AMVPDATAINFO);
|
|
}
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_MAXPIXELRATE :
|
|
ASSERT(nS >= sizeof(KSVPMAXPIXELRATE));
|
|
|
|
{
|
|
PKSVPMAXPIXELRATE pKSPixelRate;
|
|
|
|
int decoderHeight = GetDecoderHeight();
|
|
int decoderWidth = GetDecoderWidth();
|
|
|
|
pKSPixelRate = (PKSVPMAXPIXELRATE) pSpd->PropertyInfo;
|
|
|
|
pKSPixelRate->Size.dwWidth = decoderWidth;
|
|
pKSPixelRate->Size.dwHeight = decoderHeight;
|
|
if ( standard & ( KS_AnalogVideo_NTSC_Mask | KS_AnalogVideo_PAL_M ) ) // NTSC rectangle?
|
|
pKSPixelRate->MaxPixelsPerSecond = decoderWidth * decoderHeight * NTSC_FRAME_RATE;
|
|
else
|
|
pKSPixelRate->MaxPixelsPerSecond = decoderWidth * decoderHeight * PAL_FRAME_RATE;
|
|
pKSPixelRate->Reserved = 0;
|
|
|
|
pSrb->ActualBytesTransferred = sizeof(KSVPMAXPIXELRATE);
|
|
}
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_DECIMATIONCAPABILITY :
|
|
*(PBOOL)(pSpd->PropertyInfo) = TRUE;
|
|
pSrb->ActualBytesTransferred = sizeof(BOOL);
|
|
break;
|
|
|
|
default:
|
|
TRAP();
|
|
pSrb->ActualBytesTransferred = 0;
|
|
pSrb->Status = STATUS_NOT_IMPLEMENTED;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Device::GetVideoPortVBIProperty(PHW_STREAM_REQUEST_BLOCK pSrb)
|
|
{
|
|
PSTREAM_PROPERTY_DESCRIPTOR pSpd = pSrb->CommandData.PropertyInfo;
|
|
ULONG Id = pSpd->Property->Id; // index of the property
|
|
ULONG nS = pSpd->PropertyOutputSize; // size of data supplied
|
|
ULONG standard = GetVideoDecoderStandard();
|
|
|
|
switch (Id)
|
|
{
|
|
case KSPROPERTY_VPCONFIG_NUMCONNECTINFO :
|
|
ASSERT(nS >= sizeof(ULONG));
|
|
|
|
// 2 VideoPort connections are possible
|
|
*(PULONG)(pSpd->PropertyInfo) = BT829_VPCONNECTIONS_NUMBER;
|
|
|
|
pSrb->ActualBytesTransferred = sizeof(ULONG);
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_GETCONNECTINFO :
|
|
|
|
ASSERT(nS >= sizeof(DDVIDEOPORTCONNECT));
|
|
|
|
{
|
|
PKSMULTIPLE_DATA_PROP MultiProperty = (PKSMULTIPLE_DATA_PROP)pSpd->Property;
|
|
|
|
if (MultiProperty->MultipleItem.Count == BT829_VPCONNECTIONS_NUMBER &&
|
|
MultiProperty->MultipleItem.Size == sizeof(DDVIDEOPORTCONNECT)) {
|
|
|
|
if (nS >= BT829_VPCONNECTIONS_NUMBER * sizeof(DDVIDEOPORTCONNECT)) {
|
|
|
|
LPDDVIDEOPORTCONNECT pConnectInfo;
|
|
|
|
pConnectInfo = (LPDDVIDEOPORTCONNECT) pSpd->PropertyInfo;
|
|
|
|
// fill in the DDVIDEOPORTCONNECT structure offset 0
|
|
pConnectInfo->dwSize = sizeof(DDVIDEOPORTCONNECT);
|
|
pConnectInfo->dwPortWidth = 8;
|
|
pConnectInfo->guidTypeID = DDVPTYPE_BROOKTREE;
|
|
pConnectInfo->dwFlags = DDVPCONNECT_INVERTPOLARITY;
|
|
pConnectInfo->dwReserved1 = 0;
|
|
|
|
#ifdef BT829_SUPPORT_16BIT
|
|
// fill in the DDVIDEOPORTCONNECT structure offset 1
|
|
pConnectInfo ++;
|
|
pConnectInfo->dwSize = sizeof(DDVIDEOPORTCONNECT);
|
|
pConnectInfo->guidTypeID = DDVPTYPE_BROOKTREE;
|
|
pConnectInfo->dwPortWidth = 16;
|
|
pConnectInfo->dwFlags = DDVPCONNECT_INVERTPOLARITY;
|
|
pConnectInfo->dwReserved1 = 0;
|
|
#endif
|
|
pSrb->ActualBytesTransferred = BT829_VPCONNECTIONS_NUMBER * sizeof(DDVIDEOPORTCONNECT);
|
|
}
|
|
else {
|
|
pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
|
|
}
|
|
}
|
|
else {
|
|
pSrb->Status = STATUS_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_NUMVIDEOFORMAT :
|
|
ASSERT(nS >= sizeof(ULONG));
|
|
|
|
*(PULONG)(pSpd->PropertyInfo) = BT829_PIXELFORMATS_NUMBER;
|
|
|
|
pSrb->ActualBytesTransferred = sizeof(ULONG);
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_GETVIDEOFORMAT :
|
|
|
|
ASSERT(nS >= sizeof(DDPIXELFORMAT));
|
|
|
|
{
|
|
PKSMULTIPLE_DATA_PROP MultiProperty = (PKSMULTIPLE_DATA_PROP)pSpd->Property;
|
|
|
|
if (MultiProperty->MultipleItem.Count == BT829_PIXELFORMATS_NUMBER &&
|
|
MultiProperty->MultipleItem.Size == sizeof(DDPIXELFORMAT)) {
|
|
|
|
if (nS >= BT829_PIXELFORMATS_NUMBER * sizeof(DDPIXELFORMAT)) {
|
|
|
|
ASSERT(BT829_PIXELFORMATS_NUMBER == 1); // as currently implemented, this must be true
|
|
|
|
LPDDPIXELFORMAT pPixelFormat;
|
|
|
|
pPixelFormat = (LPDDPIXELFORMAT) pSpd->PropertyInfo;
|
|
|
|
RtlZeroMemory(pPixelFormat, BT829_PIXELFORMATS_NUMBER * sizeof(DDPIXELFORMAT));
|
|
|
|
// fill in the DDPIXELFORMAT structure
|
|
pPixelFormat->dwSize = sizeof(DDPIXELFORMAT);
|
|
pPixelFormat->dwFlags = DDPF_FOURCC;
|
|
pPixelFormat->dwFourCC = FOURCC_VBID;
|
|
pPixelFormat->dwYUVBitCount = 8;
|
|
|
|
pSrb->ActualBytesTransferred = BT829_PIXELFORMATS_NUMBER * sizeof(DDPIXELFORMAT);
|
|
}
|
|
else {
|
|
pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
|
|
}
|
|
}
|
|
else {
|
|
pSrb->Status = STATUS_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_VPDATAINFO :
|
|
|
|
ASSERT(nS >= sizeof(KS_AMVPDATAINFO));
|
|
|
|
{
|
|
// Clear the portion of the buffer we plan to return
|
|
RtlZeroMemory(pSpd->PropertyInfo, sizeof(KS_AMVPDATAINFO));
|
|
|
|
PKS_AMVPDATAINFO pAMVPDataInfo;
|
|
|
|
pAMVPDataInfo = (PKS_AMVPDATAINFO) pSpd->PropertyInfo;
|
|
|
|
int decoderLostLines = (GetPartRev() >= 4) ?
|
|
BT829A_LOST_LINES : BT829_LOST_LINES;
|
|
|
|
// the values are sortof hardcoded for NTSC at this point
|
|
// VBI values will need to be tweaked
|
|
pAMVPDataInfo->dwSize = sizeof(KS_AMVPDATAINFO);
|
|
|
|
if ( standard & ( KS_AnalogVideo_NTSC_Mask | KS_AnalogVideo_PAL_M ) ) // NTSC rectangle?
|
|
pAMVPDataInfo->dwMicrosecondsPerField = 16667;
|
|
else
|
|
pAMVPDataInfo->dwMicrosecondsPerField = 20000;
|
|
|
|
pAMVPDataInfo->bEnableDoubleClock = FALSE;
|
|
pAMVPDataInfo->bEnableVACT = FALSE;
|
|
|
|
pAMVPDataInfo->lHalfLinesOdd = 0;
|
|
pAMVPDataInfo->lHalfLinesEven = 1;
|
|
|
|
pAMVPDataInfo->bFieldPolarityInverted = FALSE;
|
|
pAMVPDataInfo->bDataIsInterlaced = TRUE;
|
|
pAMVPDataInfo->dwNumLinesInVREF = 6 - decoderLostLines;
|
|
|
|
pAMVPDataInfo->amvpDimInfo.dwFieldWidth = GetDecoderWidth();
|
|
|
|
// Beware of hard-coded numbers
|
|
pAMVPDataInfo->amvpDimInfo.dwVBIWidth = VBISamples;
|
|
|
|
if ( standard & ( KS_AnalogVideo_NTSC_Mask | KS_AnalogVideo_PAL_M ) ) // NTSC rectangle?
|
|
{
|
|
pAMVPDataInfo->amvpDimInfo.dwVBIHeight = NTSCVBIEnd - decoderLostLines;
|
|
pAMVPDataInfo->amvpDimInfo.dwFieldHeight =
|
|
GetDecoderHeight() +
|
|
pAMVPDataInfo->amvpDimInfo.dwVBIHeight;
|
|
/*
|
|
(NTSCVBIEnd - 1) - // the '- 1' makes VBIEnd zero-based
|
|
decoderLostLines -
|
|
pAMVPDataInfo->dwNumLinesInVREF;
|
|
*/
|
|
|
|
pAMVPDataInfo->amvpDimInfo.rcValidRegion.top = NTSCVBIStart - 1 - decoderLostLines;
|
|
}
|
|
else
|
|
{
|
|
pAMVPDataInfo->amvpDimInfo.dwVBIHeight = PALVBIEnd - decoderLostLines;
|
|
pAMVPDataInfo->amvpDimInfo.dwFieldHeight =
|
|
GetDecoderHeight() +
|
|
pAMVPDataInfo->amvpDimInfo.dwVBIHeight;
|
|
/*
|
|
(PALVBIEnd - 1) - // the '- 1' makes VBIEnd zero-based
|
|
decoderLostLines -
|
|
pAMVPDataInfo->dwNumLinesInVREF;
|
|
*/
|
|
|
|
pAMVPDataInfo->amvpDimInfo.rcValidRegion.top = PALVBIStart - 1 - decoderLostLines;
|
|
}
|
|
|
|
pAMVPDataInfo->amvpDimInfo.rcValidRegion.left = 0;
|
|
pAMVPDataInfo->amvpDimInfo.rcValidRegion.right = pAMVPDataInfo->amvpDimInfo.dwVBIWidth;
|
|
pAMVPDataInfo->amvpDimInfo.rcValidRegion.bottom = pAMVPDataInfo->amvpDimInfo.dwVBIHeight;
|
|
|
|
pSrb->ActualBytesTransferred = sizeof(KS_AMVPDATAINFO);
|
|
}
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_MAXPIXELRATE :
|
|
ASSERT(nS >= sizeof(KSVPMAXPIXELRATE));
|
|
|
|
{
|
|
PKSVPMAXPIXELRATE pKSPixelRate;
|
|
|
|
int decoderHeight = GetDecoderHeight();
|
|
int decoderWidth = GetDecoderWidth();
|
|
|
|
pKSPixelRate = (PKSVPMAXPIXELRATE) pSpd->PropertyInfo;
|
|
|
|
pKSPixelRate->Size.dwWidth = decoderWidth;
|
|
pKSPixelRate->Size.dwHeight = decoderHeight;
|
|
if ( standard & ( KS_AnalogVideo_NTSC_Mask | KS_AnalogVideo_PAL_M ) ) // NTSC rectangle?
|
|
pKSPixelRate->MaxPixelsPerSecond = decoderWidth * decoderHeight * NTSC_FRAME_RATE;
|
|
else
|
|
pKSPixelRate->MaxPixelsPerSecond = decoderWidth * decoderHeight * PAL_FRAME_RATE;
|
|
pKSPixelRate->Reserved = 0;
|
|
|
|
pSrb->ActualBytesTransferred = sizeof(KSVPMAXPIXELRATE);
|
|
}
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_DECIMATIONCAPABILITY :
|
|
*(PBOOL)(pSpd->PropertyInfo) = FALSE;
|
|
pSrb->ActualBytesTransferred = sizeof(BOOL);
|
|
break;
|
|
|
|
default:
|
|
TRAP();
|
|
pSrb->ActualBytesTransferred = 0;
|
|
pSrb->Status = STATUS_NOT_IMPLEMENTED;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Device::ConfigVPSurfaceParams(PKSVPSURFACEPARAMS pSurfaceParams)
|
|
{
|
|
DBGINFO(("VP Surface Params:\n"));
|
|
DBGINFO(("dwPitch = %d\n",pSurfaceParams->dwPitch));
|
|
DBGINFO(("dwXOrigin = %d\n",pSurfaceParams->dwXOrigin));
|
|
DBGINFO(("dwYOrigin = %d\n",pSurfaceParams->dwYOrigin));
|
|
|
|
VideoSurfaceOriginX = pSurfaceParams->dwXOrigin;
|
|
VideoSurfaceOriginY = pSurfaceParams->dwYOrigin;
|
|
VideoSurfacePitch = pSurfaceParams->dwPitch;
|
|
}
|
|
|
|
|
|
|
|
void Device::ConfigVPVBISurfaceParams(PKSVPSURFACEPARAMS pSurfaceParams)
|
|
{
|
|
DBGINFO(("VP VBI Surface Params:\n"));
|
|
DBGINFO(("dwPitch = %d\n",pSurfaceParams->dwPitch));
|
|
DBGINFO(("dwXOrigin = %d\n",pSurfaceParams->dwXOrigin));
|
|
DBGINFO(("dwYOrigin = %d\n",pSurfaceParams->dwYOrigin));
|
|
|
|
VBISurfaceOriginX = pSurfaceParams->dwXOrigin;
|
|
VBISurfaceOriginY = pSurfaceParams->dwYOrigin;
|
|
VBISurfacePitch = pSurfaceParams->dwPitch;
|
|
}
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
// VideoProcAmp functions
|
|
// -------------------------------------------------------------------
|
|
|
|
NTSTATUS Device::SetProcAmpProperty(ULONG Id, LONG Value)
|
|
{
|
|
switch (Id) {
|
|
case KSPROPERTY_VIDEOPROCAMP_BRIGHTNESS:
|
|
|
|
decoder->SetBrightness(Value);
|
|
break;
|
|
|
|
case KSPROPERTY_VIDEOPROCAMP_CONTRAST:
|
|
|
|
decoder->SetContrast(Value);
|
|
break;
|
|
|
|
case KSPROPERTY_VIDEOPROCAMP_HUE:
|
|
|
|
decoder->SetHue(Value);
|
|
break;
|
|
|
|
case KSPROPERTY_VIDEOPROCAMP_SATURATION:
|
|
|
|
decoder->SetSaturation(Value);
|
|
break;
|
|
|
|
default:
|
|
TRAP();
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
break;
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS Device::GetProcAmpProperty(ULONG Id, PLONG pValue)
|
|
{
|
|
switch (Id) {
|
|
|
|
case KSPROPERTY_VIDEOPROCAMP_BRIGHTNESS:
|
|
*pValue = decoder->GetBrightness();
|
|
break;
|
|
|
|
case KSPROPERTY_VIDEOPROCAMP_CONTRAST:
|
|
*pValue = decoder->GetContrast();
|
|
break;
|
|
|
|
case KSPROPERTY_VIDEOPROCAMP_HUE:
|
|
*pValue = decoder->GetHue();
|
|
break;
|
|
|
|
case KSPROPERTY_VIDEOPROCAMP_SATURATION:
|
|
*pValue = decoder->GetSaturation();
|
|
break;
|
|
|
|
default:
|
|
TRAP();
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
break;
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
BOOL Device::SetVideoDecoderStandard(DWORD standard) //Paul: Changed
|
|
{
|
|
if ( decoder->SetVideoDecoderStandard(standard) )
|
|
{
|
|
switch (standard)
|
|
{
|
|
case KS_AnalogVideo_NTSC_M:
|
|
scaler->VideoFormatChanged( VFormat_NTSC );
|
|
break;
|
|
case KS_AnalogVideo_NTSC_M_J:
|
|
scaler->VideoFormatChanged( VFormat_NTSC_J );
|
|
break;
|
|
case KS_AnalogVideo_PAL_B:
|
|
case KS_AnalogVideo_PAL_D:
|
|
case KS_AnalogVideo_PAL_G:
|
|
case KS_AnalogVideo_PAL_H:
|
|
case KS_AnalogVideo_PAL_I:
|
|
scaler->VideoFormatChanged( VFormat_PAL_BDGHI ); // PAL_BDGHI covers most areas
|
|
break;
|
|
case KS_AnalogVideo_PAL_M:
|
|
scaler->VideoFormatChanged( VFormat_PAL_M );
|
|
break;
|
|
case KS_AnalogVideo_PAL_N:
|
|
scaler->VideoFormatChanged( VFormat_PAL_N_COMB );
|
|
break;
|
|
default: //Paul: SECAM
|
|
scaler->VideoFormatChanged( VFormat_SECAM );
|
|
}
|
|
//SetRect(destRect);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|