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.
582 lines
17 KiB
582 lines
17 KiB
//==========================================================================;
|
|
//
|
|
// CWDMVideoPortStream - Video Port Stream class implementation
|
|
//
|
|
// $Date: 05 Aug 1998 11:11:22 $
|
|
// $Revision: 1.0 $
|
|
// $Author: Tashjian $
|
|
//
|
|
// $Copyright: (c) 1997 - 1998 ATI Technologies Inc. All Rights Reserved. $
|
|
//
|
|
//==========================================================================;
|
|
|
|
extern "C"
|
|
{
|
|
#include "strmini.h"
|
|
#include "ksmedia.h"
|
|
}
|
|
|
|
#include "wdmvdec.h"
|
|
#include "wdmdrv.h"
|
|
#include "aticonfg.h"
|
|
#include "capdebug.h"
|
|
|
|
|
|
CWDMVideoPortStream::CWDMVideoPortStream(PHW_STREAM_OBJECT pStreamObject,
|
|
CWDMVideoDecoder * pVideoDecoder,
|
|
PUINT puiErrorCode)
|
|
: CWDMVideoStream(pStreamObject, pVideoDecoder, puiErrorCode)
|
|
{
|
|
DBGTRACE(("CWDMVideoPortStream::CWDMVideoPortStream()\n"));
|
|
|
|
int StreamNumber = pStreamObject->StreamNumber;
|
|
|
|
if (StreamNumber == STREAM_VPVideo)
|
|
{
|
|
}
|
|
else if (StreamNumber == STREAM_VPVBI)
|
|
{
|
|
}
|
|
|
|
*puiErrorCode = WDMMINI_NOERROR;
|
|
}
|
|
|
|
|
|
CWDMVideoPortStream::~CWDMVideoPortStream()
|
|
{
|
|
DBGTRACE(("CWDMVideoPortStream::~CWDMVideoPortStream()\n"));
|
|
|
|
if (m_Registered)
|
|
{
|
|
m_pVideoPort->UnregisterForDirectDrawEvents( this);
|
|
}
|
|
}
|
|
|
|
|
|
VOID STREAMAPI CWDMVideoPortStream::VideoReceiveDataPacket(IN PHW_STREAM_REQUEST_BLOCK pSrb)
|
|
{
|
|
DBGERROR(("Unexpected data packet on non VP stream.\n"));
|
|
ASSERT(0);
|
|
}
|
|
|
|
/*
|
|
** VideoSetProperty()
|
|
**
|
|
** Routine to process video property requests
|
|
**
|
|
** Arguments:
|
|
**
|
|
** pSrb - pointer to the stream request block for properties
|
|
**
|
|
** Returns:
|
|
**
|
|
** Side Effects: none
|
|
*/
|
|
|
|
VOID CWDMVideoPortStream::VideoSetProperty(PHW_STREAM_REQUEST_BLOCK pSrb)
|
|
{
|
|
PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
|
|
|
|
if (IsEqualGUID (KSPROPSETID_VPConfig, pSPD->Property->Set)) {
|
|
SetVideoPortProperty (pSrb);
|
|
}
|
|
else if (IsEqualGUID (KSPROPSETID_VPVBIConfig, pSPD->Property->Set)) {
|
|
SetVideoPortVBIProperty (pSrb);
|
|
}
|
|
else {
|
|
pSrb->Status = STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
}
|
|
|
|
/*
|
|
** VideoGetProperty()
|
|
**
|
|
** Routine to process video property requests
|
|
**
|
|
** Arguments:
|
|
**
|
|
** pSrb - pointer to the stream request block for properties
|
|
**
|
|
** Returns:
|
|
**
|
|
** Side Effects: none
|
|
*/
|
|
|
|
VOID CWDMVideoPortStream::VideoGetProperty(PHW_STREAM_REQUEST_BLOCK pSrb)
|
|
{
|
|
PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
|
|
|
|
if (IsEqualGUID (KSPROPSETID_Connection, pSPD->Property->Set)) {
|
|
VideoStreamGetConnectionProperty (pSrb);
|
|
}
|
|
else if (IsEqualGUID (KSPROPSETID_VPConfig, pSPD->Property->Set)) {
|
|
m_pDevice->GetVideoPortProperty (pSrb);
|
|
}
|
|
else if (IsEqualGUID (KSPROPSETID_VPVBIConfig, pSPD->Property->Set)) {
|
|
m_pDevice->GetVideoPortVBIProperty (pSrb);
|
|
}
|
|
else {
|
|
pSrb->Status = STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
}
|
|
|
|
/*
|
|
** VideoSetState()
|
|
**
|
|
** Sets the current state of the requested stream
|
|
**
|
|
** Arguments:
|
|
**
|
|
** pSrb - pointer to the stream request block for properties
|
|
**
|
|
** Returns:
|
|
**
|
|
** Side Effects: none
|
|
*/
|
|
|
|
VOID CWDMVideoPortStream::VideoSetState(PHW_STREAM_REQUEST_BLOCK pSrb, BOOL bVPConnected, BOOL bVPVBIConnected)
|
|
{
|
|
//
|
|
// For each stream, the following states are used:
|
|
//
|
|
// Stop: Absolute minimum resources are used. No outstanding IRPs.
|
|
// Pause: Getting ready to run. Allocate needed resources so that
|
|
// the eventual transition to Run is as fast as possible.
|
|
// SRBs will be queued at either the Stream class or in your
|
|
// driver.
|
|
// Run: Streaming.
|
|
//
|
|
// Moving to Stop or Run ALWAYS transitions through Pause, so that ONLY
|
|
// the following transitions are possible:
|
|
//
|
|
// Stop -> Pause
|
|
// Pause -> Run
|
|
// Run -> Pause
|
|
// Pause -> Stop
|
|
//
|
|
// Note that it is quite possible to transition repeatedly between states:
|
|
// Stop -> Pause -> Stop -> Pause -> Run -> Pause -> Run -> Pause -> Stop
|
|
//
|
|
|
|
DBGINFO(("CWDMVideoPortStream::VideoSetState for stream %d\n", pSrb->StreamObject->StreamNumber));
|
|
|
|
pSrb->Status = STATUS_SUCCESS;
|
|
|
|
switch (pSrb->CommandData.StreamState)
|
|
|
|
{
|
|
case KSSTATE_STOP:
|
|
DBGINFO((" state KSSTATE_STOP"));
|
|
m_pDevice->SetOutputEnabled(FALSE);
|
|
|
|
// Reset the overridden flag so that the next time we go to the
|
|
// Run state, output will be enabled (unless the app overrides
|
|
// it again later). We should really do this after the graph
|
|
// has been stopped so that if a filter that has yet to be stopped
|
|
// cleans up by clearing the flag, it is not considered to be
|
|
// overriding it again. Since we are not called after the graph
|
|
// has been fully stopped, this is the best we can do.
|
|
//
|
|
// An alternative (and probably less confusing) approach is to
|
|
// leave the overridden flag set and force the app to control
|
|
// the output enabled feature if it changes it once.
|
|
//
|
|
// We have decided to follow the latter approach.
|
|
|
|
// m_pDevice->SetOutputEnabledOverridden(FALSE);
|
|
break;
|
|
|
|
case KSSTATE_ACQUIRE:
|
|
DBGINFO((" state KSSTATE_ACQUIRE"));
|
|
ASSERT(m_KSState == KSSTATE_STOP);
|
|
break;
|
|
|
|
case KSSTATE_PAUSE:
|
|
DBGINFO((" state KSSTATE_PAUSE"));
|
|
|
|
if (m_pVideoDecoder->PreEventOccurred() &&
|
|
(!m_pDevice->IsOutputEnabledOverridden() || m_pDevice->IsOutputEnabled()) &&
|
|
(m_KSState == KSSTATE_STOP || m_KSState == KSSTATE_ACQUIRE))
|
|
{
|
|
DBGERROR(("VpStrm Pause: Overridden = %d, OutputEnabled = %d",
|
|
m_pDevice->IsOutputEnabledOverridden(),
|
|
m_pDevice->IsOutputEnabled()
|
|
));
|
|
|
|
pSrb->Status = STATUS_UNSUCCESSFUL;
|
|
}
|
|
break;
|
|
|
|
case KSSTATE_RUN:
|
|
DBGINFO((" state KSSTATE_RUN"));
|
|
|
|
ASSERT(m_KSState == KSSTATE_ACQUIRE || m_KSState == KSSTATE_PAUSE);
|
|
|
|
if (m_pVideoDecoder->PreEventOccurred() &&
|
|
(!m_pDevice->IsOutputEnabledOverridden() ||
|
|
m_pDevice->IsOutputEnabled()))
|
|
{
|
|
DBGERROR(("VpStrm Run: Overridden = %d, OutputEnabled = %d",
|
|
m_pDevice->IsOutputEnabledOverridden(),
|
|
m_pDevice->IsOutputEnabled()
|
|
));
|
|
pSrb->Status = STATUS_UNSUCCESSFUL;
|
|
}
|
|
else if (!m_pDevice->IsOutputEnabledOverridden())
|
|
m_pDevice->SetOutputEnabled(TRUE);
|
|
break;
|
|
}
|
|
|
|
if (pSrb->Status == STATUS_SUCCESS) {
|
|
m_KSState = pSrb->CommandData.StreamState;
|
|
DBGINFO((" entered\n"));
|
|
}
|
|
else
|
|
DBGINFO((" NOT entered ***\n"));
|
|
}
|
|
|
|
|
|
VOID CWDMVideoPortStream::SetVideoPortProperty(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
|
|
|
|
pSrb->Status = STATUS_SUCCESS;
|
|
|
|
ASSERT (m_pDevice != NULL);
|
|
switch (Id)
|
|
{
|
|
case KSPROPERTY_VPCONFIG_DDRAWHANDLE:
|
|
ASSERT (nS >= sizeof(ULONG_PTR));
|
|
|
|
if (!m_pVideoPort->ConfigDirectDrawHandle(*(PULONG_PTR)pSpd->PropertyInfo)) {
|
|
pSrb->Status = STATUS_UNSUCCESSFUL;
|
|
break;
|
|
}
|
|
|
|
if (!m_Registered) {
|
|
m_Registered = m_pVideoPort->RegisterForDirectDrawEvents(this);
|
|
if (!m_Registered) {
|
|
pSrb->Status = STATUS_UNSUCCESSFUL;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_VIDEOPORTID:
|
|
ASSERT (nS >= sizeof(ULONG));
|
|
|
|
if (!m_pVideoPort->ConfigVideoPortHandle(*(PULONG)pSpd->PropertyInfo)) {
|
|
pSrb->Status = STATUS_UNSUCCESSFUL;
|
|
}
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_DDRAWSURFACEHANDLE:
|
|
ASSERT (nS >= sizeof(ULONG_PTR));
|
|
{
|
|
// This sample does not use the surface kernel handles,
|
|
// but the validation is as follows.
|
|
ULONG_PTR cHandles = *(PULONG_PTR)pSpd->PropertyInfo;
|
|
if (nS != (cHandles + 1) * sizeof(ULONG_PTR)) {
|
|
|
|
pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
|
|
break;
|
|
}
|
|
|
|
m_pVideoDecoder->ResetEvents();
|
|
}
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_SETCONNECTINFO :
|
|
ASSERT (nS >= sizeof(ULONG));
|
|
{
|
|
// Indexes are correlated to the implementation of KSPROPERTY_VPCONFIG_GETCONNECTINFO
|
|
ULONG Index = *(PULONG)pSpd->PropertyInfo;
|
|
switch (Index)
|
|
{
|
|
case 0:
|
|
m_pDevice->Set16BitDataStream(FALSE);
|
|
break;
|
|
|
|
#ifdef BT829_SUPPORT_16BIT
|
|
case 1:
|
|
m_pDevice->Set16BitDataStream(TRUE);
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
pSrb->Status = STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_INVERTPOLARITY :
|
|
m_pDevice->SetHighOdd(!m_pDevice->IsHighOdd());
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_SETVIDEOFORMAT :
|
|
ASSERT (nS >= sizeof(ULONG));
|
|
|
|
//
|
|
// pSrb->CommandData.PropertInfo->PropertyInfo
|
|
// points to a ULONG which is an index into the array of
|
|
// VIDEOFORMAT structs returned to the caller from the
|
|
// Get call to FORMATINFO
|
|
//
|
|
// Since the sample only supports one FORMAT type right
|
|
// now, we will ensure that the requested index is 0.
|
|
//
|
|
|
|
switch (*(PULONG)pSrb->CommandData.PropertyInfo->PropertyInfo)
|
|
{
|
|
case 0:
|
|
|
|
//
|
|
// at this point, we would program the hardware to use
|
|
// the right connection information for the videoport.
|
|
// since we are only supporting one connection, we don't
|
|
// need to do anything, so we will just indicate success
|
|
//
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
pSrb->Status = STATUS_NO_MATCH;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_INFORMVPINPUT:
|
|
ASSERT (nS >= sizeof(DDPIXELFORMAT));
|
|
|
|
// This would be supported if we wanted to be informed of the available formats
|
|
pSrb->Status = STATUS_NOT_IMPLEMENTED;
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_SCALEFACTOR :
|
|
ASSERT (nS >= sizeof(KS_AMVPSIZE));
|
|
{
|
|
PKS_AMVPSIZE pAMVPSize;
|
|
|
|
pAMVPSize = (PKS_AMVPSIZE)(pSrb->CommandData.PropertyInfo->PropertyInfo);
|
|
|
|
MRect t(0, 0, pAMVPSize->dwWidth, pAMVPSize->dwHeight);
|
|
|
|
m_pDevice->SetRect(t);
|
|
}
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_SURFACEPARAMS :
|
|
ASSERT(nS >= sizeof(KSVPSURFACEPARAMS));
|
|
|
|
m_pDevice->ConfigVPSurfaceParams((PKSVPSURFACEPARAMS)pSpd->PropertyInfo);
|
|
break;
|
|
|
|
default:
|
|
TRAP();
|
|
pSrb->Status = STATUS_NOT_IMPLEMENTED;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID CWDMVideoPortStream::SetVideoPortVBIProperty(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
|
|
|
|
pSrb->Status = STATUS_SUCCESS;
|
|
|
|
ASSERT (m_pDevice != NULL);
|
|
switch (Id)
|
|
{
|
|
case KSPROPERTY_VPCONFIG_DDRAWHANDLE:
|
|
ASSERT (nS >= sizeof(ULONG_PTR));
|
|
|
|
if (!m_pVideoPort->ConfigDirectDrawHandle(*(PULONG_PTR)pSpd->PropertyInfo)) {
|
|
pSrb->Status = STATUS_UNSUCCESSFUL;
|
|
break;
|
|
}
|
|
|
|
if (!m_Registered) {
|
|
m_Registered = m_pVideoPort->RegisterForDirectDrawEvents(this);
|
|
if (!m_Registered) {
|
|
pSrb->Status = STATUS_UNSUCCESSFUL;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_VIDEOPORTID:
|
|
ASSERT (nS >= sizeof(ULONG));
|
|
|
|
if (!m_pVideoPort->ConfigVideoPortHandle(*(PULONG)pSpd->PropertyInfo)) {
|
|
pSrb->Status = STATUS_UNSUCCESSFUL;
|
|
}
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_DDRAWSURFACEHANDLE:
|
|
ASSERT (nS >= sizeof(ULONG_PTR));
|
|
{
|
|
// This sample does not use the surface kernel handles,
|
|
// but the validation is as follows.
|
|
ULONG_PTR cHandles = *(PULONG_PTR)pSpd->PropertyInfo;
|
|
if (nS != (cHandles + 1) * sizeof(ULONG_PTR)) {
|
|
|
|
pSrb->Status = STATUS_INVALID_BUFFER_SIZE;
|
|
break;
|
|
}
|
|
|
|
m_pVideoDecoder->ResetEvents();
|
|
}
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_SETCONNECTINFO :
|
|
ASSERT (nS >= sizeof(ULONG));
|
|
{
|
|
// Indexes are correlated to the implementation of KSPROPERTY_VPCONFIG_GETCONNECTINFO
|
|
ULONG Index = *(PULONG)pSpd->PropertyInfo;
|
|
switch (Index)
|
|
{
|
|
case 0:
|
|
m_pDevice->Set16BitDataStream(FALSE);
|
|
break;
|
|
|
|
#ifdef BT829_SUPPORT_16BIT
|
|
case 1:
|
|
m_pDevice->Set16BitDataStream(TRUE);
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
pSrb->Status = STATUS_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_INVERTPOLARITY :
|
|
m_pDevice->SetHighOdd(!m_pDevice->IsHighOdd());
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_SETVIDEOFORMAT :
|
|
ASSERT (nS >= sizeof(ULONG));
|
|
|
|
//
|
|
// pSrb->CommandData.PropertInfo->PropertyInfo
|
|
// points to a ULONG which is an index into the array of
|
|
// VIDEOFORMAT structs returned to the caller from the
|
|
// Get call to FORMATINFO
|
|
//
|
|
// Since the sample only supports one FORMAT type right
|
|
// now, we will ensure that the requested index is 0.
|
|
//
|
|
|
|
switch (*(PULONG)pSrb->CommandData.PropertyInfo->PropertyInfo)
|
|
{
|
|
case 0:
|
|
|
|
//
|
|
// at this point, we would program the hardware to use
|
|
// the right connection information for the videoport.
|
|
// since we are only supporting one connection, we don't
|
|
// need to do anything, so we will just indicate success
|
|
//
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
pSrb->Status = STATUS_NO_MATCH;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_INFORMVPINPUT:
|
|
ASSERT (nS >= sizeof(DDPIXELFORMAT));
|
|
|
|
// This would be supported if we wanted to be informed of the available formats
|
|
pSrb->Status = STATUS_NOT_IMPLEMENTED;
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_SCALEFACTOR :
|
|
ASSERT (nS >= sizeof(KS_AMVPSIZE));
|
|
|
|
// TBD
|
|
pSrb->Status = STATUS_NOT_IMPLEMENTED;
|
|
break;
|
|
|
|
case KSPROPERTY_VPCONFIG_SURFACEPARAMS :
|
|
ASSERT(nS >= sizeof(KSVPSURFACEPARAMS));
|
|
|
|
m_pDevice->ConfigVPVBISurfaceParams((PKSVPSURFACEPARAMS)pSpd->PropertyInfo);
|
|
break;
|
|
|
|
default:
|
|
TRAP();
|
|
pSrb->Status = STATUS_NOT_IMPLEMENTED;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
VOID CWDMVideoPortStream::PreResChange()
|
|
{
|
|
DBGTRACE(("DDNOTIFY_PRERESCHANGE; stream = %d\n", m_pStreamObject->StreamNumber));
|
|
|
|
m_pVideoDecoder->SetPreEvent();
|
|
}
|
|
|
|
|
|
VOID CWDMVideoPortStream::PostResChange()
|
|
{
|
|
DBGTRACE(("DDNOTIFY_POSTRESCHANGE; stream = %d\n", m_pStreamObject->StreamNumber));
|
|
|
|
m_pVideoDecoder->SetPostEvent();
|
|
DBGTRACE(("Before Attempted Renegotiation due to DDNOTIFY_POSTRESCHANGE\n"));
|
|
AttemptRenegotiation();
|
|
DBGTRACE(("Afer Attempted Renegotiation due to DDNOTIFY_POSTRESCHANGE\n"));
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID CWDMVideoPortStream::PreDosBox()
|
|
{
|
|
DBGTRACE(("DDNOTIFY_PREDOSBOX; stream = %d\n", m_pStreamObject->StreamNumber));
|
|
|
|
m_pVideoDecoder->SetPreEvent();
|
|
}
|
|
|
|
|
|
|
|
VOID CWDMVideoPortStream::PostDosBox()
|
|
{
|
|
DBGTRACE(("DDNOTIFY_POSTDOSBOX; stream = %d\n", m_pStreamObject->StreamNumber));
|
|
|
|
m_pVideoDecoder->SetPostEvent();
|
|
DBGTRACE(("Before Attempted Renegotiation due to DDNOTIFY_POSTDOSBOX\n"));
|
|
AttemptRenegotiation();
|
|
DBGTRACE(("After Attempted Renegotiation due to DDNOTIFY_POSTDOSBOX\n"));
|
|
}
|
|
|
|
NTSTATUS STREAMAPI VPStreamEventProc (PHW_EVENT_DESCRIPTOR pEvent)
|
|
{
|
|
CWDMVideoPortStream* pstrm=(CWDMVideoPortStream*)pEvent->StreamObject->HwStreamExtension;
|
|
pstrm->StreamEventProc(pEvent);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS STREAMAPI VPVBIStreamEventProc (PHW_EVENT_DESCRIPTOR pEvent)
|
|
{
|
|
CWDMVideoPortStream* pstrm=(CWDMVideoPortStream*)pEvent->StreamObject->HwStreamExtension;
|
|
pstrm->StreamEventProc(pEvent);
|
|
return STATUS_SUCCESS;
|
|
}
|