mirror of https://github.com/tongzx/nt5src
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
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);
|
|
|
|
}
|
|
|
|
|