/******************************************************************* * * 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); }