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