554 lines
12 KiB
C
554 lines
12 KiB
C
/*******************************************************************
|
||
*
|
||
* 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);
|
||
|
||
}
|
||
|
||
|