Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

553 lines
12 KiB

/*******************************************************************
*
* MPVIDEO.C
*
* Copyright (C) 1995 SGS-THOMSON Microelectronics.
*
*
* PORT/MINIPORT Interface Video Routines
*
*******************************************************************/
#include "common.h"
#include "strmini.h"
#include "mpst.h"
#include "mpinit.h"
#include "mpvideo.h"
#include "debug.h"
#include "dmpeg.h"
void mpstCommandComplete(PHW_STREAM_REQUEST_BLOCK pSrb);
ULONG miniPortCancelVideo(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
{
ULONG dwErrCode = NO_ERROR;
// TBD
pMrb->Status = STATUS_SUCCESS;
if(pHwDevExt->VideoDeviceExt.pCurrentSRB != NULL)
{
// Still to send a packet
pHwDevExt->VideoDeviceExt.pCurrentSRB->Status = STATUS_CANCELLED;
//MpegPortNotification(RequestComplete,VideoDevice,pHwDevExt,
// pHwDevExt->VideoDeviceExt.pCurrentSRB);
//MpegPortNotification(NextRequest,VideoDevice,pHwDevExt);
// Now kill the timer
//MpegPortNotification(RequestTimerCall, VideoDevice,
// pHwDevExt, NULL, 0);
pHwDevExt->VideoDeviceExt.pCurrentSRB = NULL;
}
return dwErrCode;
}
ULONG miniPortClearVideoBuffer(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
{
ULONG dwErrCode = NO_ERROR;
// STB
pHwDevExt = pHwDevExt; // Remove Warning
pMrb = pMrb; // Remove Warning
dwErrCode = ERROR_COMMAND_NOT_IMPLEMENTED;
return dwErrCode;
}
ULONG miniPortVideoEnable(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
{
ULONG dwErrCode = NO_ERROR;
pHwDevExt = pHwDevExt; // Remove Warning
pMrb = pMrb; // Remove Warning
// mpstEnableVideo ( TRUE );
return dwErrCode;
}
ULONG miniPortVideoDisable(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
{
ULONG dwErrCode = NO_ERROR;
pHwDevExt = pHwDevExt; // Remove Warning
pMrb = pMrb; // Remove Warning
// mpstEnableVideo(FALSE);
return dwErrCode;
}
ULONG miniPortVideoEndOfStream(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
{
ULONG dwErrCode = NO_ERROR;
miniPortVideoStop(pMrb, pHwDevExt);
return dwErrCode;
}
ULONG miniPortVideoGetAttribute(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
{
ULONG dwErrCode = NO_ERROR;
pHwDevExt = pHwDevExt; // Remove Warning
#ifdef DEFINEME
switch(pMrb->CommandData.pAttribute->Attribute)
{
// STB
case MpegAttrVideoAGC :
case MpegAttrVideoChannel :
case MpegAttrVideoClamp :
case MpegAttrVideoCoring :
case MpegAttrVideoGain :
case MpegAttrVideoGenLock :
case MpegAttrVideoHue :
case MpegAttrVideoMode :
case MpegAttrVideoSaturation :
case MpegAttrVideoSharpness :
case MpegAttrVideoSignalType :
pMrb->Status = STATUS_INVALID_PARAMETER;
break;
}
#endif
return dwErrCode;
}
ULONG miniPortVideoGetStc(PHW_STREAM_REQUEST_BLOCK pMrb, PHW_DEVICE_EXTENSION pHwDevExt)
{
ULONG dwErrCode = NO_ERROR;
pHwDevExt = pHwDevExt; // Remove Warning
pMrb = pMrb; // Remove Warning
#if 0
// TBI
*pMrb->CommandData.pPresentationDelta = pHwDevExt->VideoDeviceExt.videoSTC;
// pMrb->Status = STATUS_INVALID_PARAMETER;
#endif
return dwErrCode;
}
void VideoPacketStub(PHW_STREAM_OBJECT pstrm)
{
//
// VideoTimerCallBack(pSrb->StreamObject);
//
dmpgDisableIRQ();
StreamClassCallAtNewPriority(pstrm, pstrm->HwDeviceExtension,
Dispatch,
VideoTimerCallBack, pstrm);
}
VOID miniPortVideoPacket(PHW_STREAM_REQUEST_BLOCK pSrb)
{
ULONG dwErrCode = NO_ERROR;
ULONG uSent=0;
PHW_DEVICE_EXTENSION pHwDevExt =
((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
PVIDEO_DEVICE_EXTENSION pvidex =
&(((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension)->VideoDeviceExt);
//
// set up for initial parsing of the scatter gather packet.
//
pvidex->cPacket = pvidex->cOffs = 0;
if (!pSrb->CommandData.DataBuffer) {
return(miniPortVideoEndOfStream(pSrb, pHwDevExt));
}
pvidex->pPacket = &(pSrb->CommandData.DataBuffer->DataPacket);
pvidex->pCurrentSRB = pSrb;
pHwDevExt->VideoDeviceExt.videoSTC =
pvidex->pPacket->PresentationDelta;
VideoPacketStub(pSrb->StreamObject);
}
VOID miniPortGetProperty(PHW_STREAM_REQUEST_BLOCK pSrb)
{
PHW_DEVICE_EXTENSION phwdevext =
((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
TRAP
switch (pSrb->CommandData.PropertyInfo->PropertySetID)
{
case 0:
TRAP
// mpstGetVidLvl(pSrb);
break;
default:
break;
}
pSrb->Status = STATUS_SUCCESS;
mpstCtrlCommandComplete(pSrb);
}
VOID miniPortSetState(PHW_STREAM_REQUEST_BLOCK pSrb)
{
PHW_DEVICE_EXTENSION phwdevext =
((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
switch (pSrb->CommandData.StreamState)
{
case KSSTATE_STOP:
miniPortVideoStop(pSrb, phwdevext);
break;
case KSSTATE_PAUSE:
miniPortVideoPause(pSrb, phwdevext);
break;
case KSSTATE_RUN:
miniPortVideoPlay(pSrb, phwdevext);
}
pSrb->Status = STATUS_SUCCESS;
mpstCtrlCommandComplete(pSrb);
}
ULONG miniPortVideoPause(PHW_STREAM_REQUEST_BLOCK pSrb, PHW_DEVICE_EXTENSION pHwDevExt)
{
ULONG dwErrCode = NO_ERROR;
pSrb = pSrb; // Remove Warning
// mpstVideoPause ();
dmpgPause();
pHwDevExt->VideoDeviceExt.DeviceState = KSSTATE_PAUSE;
return dwErrCode;
}
ULONG miniPortVideoPlay(PHW_STREAM_REQUEST_BLOCK pSrb, PHW_DEVICE_EXTENSION pHwDevExt)
{
ULONG dwErrCode = NO_ERROR;
// mpstVideoPlay();
DebugPrint((DebugLevelVerbose, "Calling Play!!!!"));
dmpgPlay();
pHwDevExt->VideoDeviceExt.DeviceState = KSSTATE_RUN;
pSrb = pSrb; // Remove Warning
return dwErrCode;
}
ULONG miniPortVideoQueryInfo (PHW_STREAM_REQUEST_BLOCK pSrb, PHW_DEVICE_EXTENSION pHwDevExt)
{
ULONG dwErrCode = NO_ERROR;
#ifdef DEFINEME
pSrb -> CommandData.pDeviceInfo->DeviceState =
pHwDevExt->VideoDeviceExt.DeviceState;
pSrb -> CommandData.pDeviceInfo->DecoderBufferSize = mpstVideoDecoderBufferSize();
pSrb -> CommandData.pDeviceInfo->DecoderBufferFullness = mpstVideoDecoderBufferFullness();
#endif
return dwErrCode;
}
ULONG miniPortVideoReset(PHW_STREAM_REQUEST_BLOCK pSrb, PHW_DEVICE_EXTENSION pHwDevExt)
{
ULONG dwErrCode = NO_ERROR;
// TBC
// mpstVideoReset();
dmpgSeek();
pHwDevExt->VideoDeviceExt.DeviceState = KSSTATE_PAUSE;
pSrb->Status = STATUS_SUCCESS;
return dwErrCode;
}
ULONG miniPortVideoSetAttribute(PHW_STREAM_REQUEST_BLOCK pSrb, PHW_DEVICE_EXTENSION pHwDevExt)
{
ULONG dwErrCode = NO_ERROR;
pHwDevExt = pHwDevExt; // Remove Warning
// STB
#ifdef DEFINEME
switch(pSrb->CommandData.pAttribute->Attribute)
{
case MpegAttrVideoAGC :
case MpegAttrVideoChannel :
case MpegAttrVideoClamp :
case MpegAttrVideoCoring :
case MpegAttrVideoGain :
case MpegAttrVideoGenLock :
case MpegAttrVideoHue :
case MpegAttrVideoMode :
case MpegAttrVideoSaturation :
case MpegAttrVideoSharpness :
case MpegAttrVideoSignalType :
dwErrCode = ERROR_COMMAND_NOT_IMPLEMENTED;
break;
}
#endif
return dwErrCode;
}
ULONG miniPortVideoSetStc(PHW_STREAM_REQUEST_BLOCK pSrb, PHW_DEVICE_EXTENSION pHwDevExt)
{
ULONG dwErrCode = NO_ERROR;
pHwDevExt = pHwDevExt; // Remove Warning
pSrb = pSrb; // Remove Warning
#if 0
// TBI
// pSrb->Status = STATUS_INVALID_PARAMETER;
#endif
return dwErrCode;
}
ULONG miniPortVideoStop (PHW_STREAM_REQUEST_BLOCK pSrb, PHW_DEVICE_EXTENSION pHwDevExt)
{
ULONG dwErrCode = NO_ERROR;
// TBC
pHwDevExt->VideoDeviceExt.DeviceState = KSSTATE_PAUSE;
if(pHwDevExt->VideoDeviceExt.pCurrentSRB != NULL)
{
// Still to send a packet
pHwDevExt->VideoDeviceExt.pCurrentSRB->Status = STATUS_CANCELLED;
StreamClassStreamNotification(ReadyForNextStreamDataRequest,
pHwDevExt->VideoDeviceExt.pCurrentSRB->StreamObject);
StreamClassStreamNotification(StreamRequestComplete,
pHwDevExt->VideoDeviceExt.pCurrentSRB->StreamObject,
pHwDevExt->VideoDeviceExt.pCurrentSRB);
//
// request a timer callback
//
StreamClassScheduleTimer(pSrb->StreamObject, pSrb->HwDeviceExtension,
0, VideoPacketStub, pSrb->StreamObject);
pHwDevExt->VideoDeviceExt.pCurrentSRB =
pHwDevExt->pCurSrb = NULL;
}
// mpstVideoStop();
dmpgStop();
pSrb->Status = STATUS_SUCCESS;
return dwErrCode;
}
VOID VideoTimerCallBack(PHW_STREAM_OBJECT pstrm)
{
PHW_DEVICE_EXTENSION pdevext = pstrm->HwDeviceExtension;
PHW_STREAM_REQUEST_BLOCK pSrb;
ULONG uSent;
PVIDEO_DEVICE_EXTENSION pvidex = &(pdevext->VideoDeviceExt);
pSrb = pvidex->pCurrentSRB;
// dmpgEnableIRQ();
if (!pSrb)
{
TRAP
return;
}
do
{
uSent = mpstVideoPacket(pSrb);
pvidex->cOffs += uSent;
//
// check if we finished this packet. If so, go on to the
// next packet
//
if (pvidex->cOffs >=
pvidex->pPacket->DataPacketLength)
{
pvidex->pPacket++;
//
// reset the packet offset
//
pvidex->cOffs = 0;
pvidex->cPacket = (ULONG)pvidex->cPacket
+ sizeof (KSDATA_PACKET);
//
// if we have finished all the packets, then we are done
//
if (pvidex->cPacket >=
pSrb->CommandData.DataBuffer->DataHeader.DataSize)
{
pSrb->Status = STATUS_SUCCESS;
pvidex->pCurrentSRB = 0;
mpstCommandComplete(pSrb);
StreamClassCallAtNewPriority(pstrm,
pstrm->HwDeviceExtension,
High,
StubMpegEnableIRQ,
pstrm);
return;
}
}
} while (uSent);
//
// request a timer callback
//
StreamClassScheduleTimer(pstrm, pstrm->HwDeviceExtension,
VIDEO_PACKET_TIMER, VideoPacketStub, pstrm);
StreamClassCallAtNewPriority(pstrm,
pstrm->HwDeviceExtension,
High,
StubMpegEnableIRQ,
pstrm);
}
void StubMpegEnableIRQ(PHW_STREAM_OBJECT pstrm)
{
dmpgEnableIRQ();
}
ULONG mpstVideoPacket(PHW_STREAM_REQUEST_BLOCK pSrb)
{
PVIDEO_DEVICE_EXTENSION pvidex =
&(((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension)->VideoDeviceExt);
PUCHAR pPacket;
ULONG uLen;
ULONG cPacket;
PUCHAR p;
#define MAX_SIZE 8192
//
// find out how many bytes we can squeeze in
//
uLen = MAX_SIZE; //(BUF_FULL - VideoGetBBL()) * 256;
if(pvidex -> cOffs == 0)
{
p = (PUCHAR)(pvidex->pPacket->DataPacket);
pvidex->cOffs = p[8]+9;
}
cPacket = pvidex->pPacket->DataPacketLength - pvidex->cOffs;
uLen = uLen > cPacket ? cPacket : uLen;
if(uLen > MAX_SIZE)
uLen = MAX_SIZE;
// AVSYNC BUG to be fixed here.
// Dont Latch PTS every time.
if (uLen)
{
//
// send the bytes that we can fit
//
return dmpgSendVideo((PDWORD)(((ULONG)pvidex->pPacket->DataPacket) + pvidex->cOffs), uLen);
}
return uLen;
}
/////////////////////////////////////////////////////////////////////////
//
// Function : mpstCommandComplete
// Args : SRB
// Returns : none
//
// Purpose:
// Performs a completion callback on a given request,
// and then dequeues any outstanding requests
//
// Last Modified 10.1.96 by JBS
//
/////////////////////////////////////////////////////////////////////////
void mpstCommandComplete(PHW_STREAM_REQUEST_BLOCK pSrb)
{
PHW_STREAM_REQUEST_BLOCK pNextSrb;
PHW_DEVICE_EXTENSION pHwDevExt =
((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
//
// see if there is a request outstanding on either queue.
// if there is, go ahead and start it.
//
//
// Note: this code cannot be re-entered!
//
pHwDevExt ->pCurSrb = 0;
StreamStartCommand(pHwDevExt);
//
// now, go ahead and complete this request
//
StreamClassStreamNotification(ReadyForNextStreamDataRequest,
pSrb->StreamObject);
StreamClassStreamNotification(StreamRequestComplete,
pSrb->StreamObject,
pSrb);
}