|
|
//==========================================================================;
//
// 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; }
|