📄 dvdcmd.c
字号:
}
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_GET_STREAM_STATE:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_GET_STREAM_STATE\r\n") );
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_GET_STREAM_PROPERTY:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_GET_STREAM_PROPERTY\r\n") );
GetVpeProperty( pSrb );
if( pSrb->Status != STATUS_PENDING ) {
StreamClassStreamNotification( ReadyForNextStreamControlRequest,
pSrb->StreamObject );
StreamClassStreamNotification( StreamRequestComplete,
pSrb->StreamObject,
pSrb );
}
return;
case SRB_SET_STREAM_PROPERTY:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_SET_STREAM_PROPERTY\r\n") );
SetVpeProperty( pSrb );
break;
case SRB_OPEN_MASTER_CLOCK:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_OPEN_MASTER_CLOCK\r\n") );
hMaster = pSrb->CommandData.MasterClockHandle;
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_CLOSE_MASTER_CLOCK:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_CLOSE_MASTER_CLOCK\r\n") );
hMaster = pSrb->CommandData.MasterClockHandle;
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_INDICATE_MASTER_CLOCK:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_INDICATE_MASTER_CLOCK\r\n") );
hClk = pSrb->CommandData.MasterClockHandle;
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_UNKNOWN_STREAM_COMMAND:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_UNKNOWN_STREAM_COMMAND\r\n") );
TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
case SRB_SET_STREAM_RATE:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_SET_STREAM_RATE\r\n") );
TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
case SRB_PROPOSE_DATA_FORMAT:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_PROPOSE_DATA_FORMAT\r\n") );
TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
default:
DebugPrint( (DebugLevelTrace, "DVDTS: default %d(0x%x)\r\n", pSrb->Command, pSrb->Command ) );
TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
}
StreamClassStreamNotification( ReadyForNextStreamControlRequest,
pSrb->StreamObject );
StreamClassStreamNotification( StreamRequestComplete,
pSrb->StreamObject,
pSrb );
}
/*
** CCReceiveDataPacket()
*/
VOID STREAMAPI CCReceiveDataPacket( IN PHW_STREAM_REQUEST_BLOCK pSrb )
{
PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
DebugPrint(( DebugLevelVerbose, "DVDTS:CCReceiveDataPacket---------\r\n" ));
switch( pSrb->Command ) {
case SRB_READ_DATA:
DebugPrint(( DebugLevelVerbose, "DVDTS: SRB_READ_DATA\r\n" ));
DebugPrint(( DebugLevelTrace, "DVDTS: put queue CC pSrb = 0x%x\r\n", pSrb ));
CCQueue_put( pHwDevExt, pSrb );
pSrb->Status = STATUS_PENDING;
pSrb->TimeoutCounter = 0; // prevent the packet from timing out, ever
StreamClassStreamNotification( ReadyForNextStreamDataRequest,
pSrb->StreamObject );
return;
case SRB_WRITE_DATA:
DebugPrint(( DebugLevelTrace, "DVDTS: SRB_WRITE_DATA\r\n" ));
TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
default:
DebugPrint(( DebugLevelTrace, "DVDTS: default %d(0x%x)\r\n", pSrb->Command, pSrb->Command ));
TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
}
StreamClassStreamNotification( ReadyForNextStreamDataRequest,
pSrb->StreamObject );
StreamClassStreamNotification( StreamRequestComplete,
pSrb->StreamObject,
pSrb );
}
/*
** CCReceiveCtrlPacket()
*/
VOID STREAMAPI CCReceiveCtrlPacket( IN PHW_STREAM_REQUEST_BLOCK pSrb )
{
PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
DebugPrint(( DebugLevelTrace, "DVDTS:CCReceiveCtrlPacket---------\r\n" ));
switch( pSrb->Command ) {
case SRB_SET_STREAM_STATE:
DebugPrint(( DebugLevelTrace, "DVDTS: SRB_SET_STREAM_STATE\r\n" ));
switch( pSrb->CommandData.StreamState ) {
case KSSTATE_STOP:
DebugPrint(( DebugLevelTrace, "DVDTS: KSSTATE_STOP\r\n" ));
break;
case KSSTATE_PAUSE:
DebugPrint(( DebugLevelTrace, "DVDTS: KSSTATE_PAUSE\r\n" ));
break;
case KSSTATE_RUN:
DebugPrint(( DebugLevelTrace, "DVDTS: KSSTATE_RUN\r\n" ));
break;
}
((PSTREAMEX)(pHwDevExt->pstroCC->HwStreamExtension))->state = pSrb->CommandData.StreamState;
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_GET_STREAM_STATE:
DebugPrint(( DebugLevelTrace, "DVDTS: SRB_GET_STREAM_STATE\r\n" ));
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_GET_STREAM_PROPERTY:
DebugPrint(( DebugLevelTrace, "DVDTS: SRB_GET_STREAM_PROPERTY\r\n" ));
GetCCProperty( pSrb );
break;
case SRB_SET_STREAM_PROPERTY:
DebugPrint(( DebugLevelTrace, "DVDTS: SRB_SET_STREAM_PROPERTY\r\n" ));
SetCCProperty( pSrb );
break;
case SRB_OPEN_MASTER_CLOCK:
DebugPrint( (DebugLevelTrace, "DVDTS: SRB_OPEN_MASTER_CLOCK\r\n") );
hMaster = pSrb->CommandData.MasterClockHandle;
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_CLOSE_MASTER_CLOCK:
DebugPrint(( DebugLevelTrace, "DVDTS: SRB_CLOSE_MASTER_CLOCK\r\n" ));
hMaster = pSrb->CommandData.MasterClockHandle;
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_INDICATE_MASTER_CLOCK:
DebugPrint(( DebugLevelTrace, "DVDTS: SRB_INDICATE_MASTER_CLOCK\r\n" ));
hClk = pSrb->CommandData.MasterClockHandle;
pSrb->Status = STATUS_SUCCESS;
break;
case SRB_UNKNOWN_STREAM_COMMAND:
DebugPrint(( DebugLevelTrace, "DVDTS: SRB_UNKNOWN_STREAM_COMMAND\r\n" ));
TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
case SRB_SET_STREAM_RATE:
DebugPrint(( DebugLevelTrace, "DVDTS: SRB_SET_STREAM_RATE\r\n" ));
TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
case SRB_PROPOSE_DATA_FORMAT:
DebugPrint(( DebugLevelTrace, "DVDTS: SRB_PROPOSE_DATA_FORMAT\r\n" ));
TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
default:
DebugPrint(( DebugLevelTrace, "DVDTS: default %d(0x%x)\r\n", pSrb->Command, pSrb->Command ));
TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
}
StreamClassStreamNotification( ReadyForNextStreamControlRequest,
pSrb->StreamObject );
StreamClassStreamNotification( StreamRequestComplete,
pSrb->StreamObject,
pSrb );
}
void VideoQueryAccept(PHW_STREAM_REQUEST_BLOCK pSrb)
{
PKSDATAFORMAT pfmt = pSrb->CommandData.OpenFormat;
ULONGLONG tptr = (ULONGLONG) pfmt + sizeof (KSDATAFORMAT);
KS_MPEGVIDEOINFO2 * pblock = (KS_MPEGVIDEOINFO2 *)tptr;
DebugPrint( (DebugLevelTrace, "DVDTS:VideoQueryAccept\r\n" ) );
//
// pick up the format block and examine it. Default to not implemented
//
pSrb->Status = STATUS_NOT_IMPLEMENTED;
if (pfmt->FormatSize != sizeof(KSDATAFORMAT) + sizeof(KS_MPEGVIDEOINFO2))
{
return;
}
pSrb->Status = STATUS_SUCCESS;
}
void ProcessVideoFormat( PKSDATAFORMAT pfmt, PHW_DEVICE_EXTENSION pHwDevExt )
{
ULONGLONG tptr = (ULONGLONG) pfmt + sizeof (KSDATAFORMAT);
KS_MPEGVIDEOINFO2 * VidFmt = (KS_MPEGVIDEOINFO2 *)tptr;
DebugPrint( (DebugLevelTrace, "DVDTS:ProcessVideoFormat\r\n" ) );
if( pfmt->FormatSize != sizeof(KSDATAFORMAT) + sizeof(KS_MPEGVIDEOINFO2) ) {
TRAP;
return;
}
//
// copy the picture aspect ratio for now
//
pHwDevExt->VPFmt.dwPictAspectRatioX = VidFmt->hdr.dwPictAspectRatioX;
pHwDevExt->VPFmt.dwPictAspectRatioY = VidFmt->hdr.dwPictAspectRatioY;
DebugPrint(( DebugLevelTrace, "DVDTS: AspectRatioX %d\r\n", VidFmt->hdr.dwPictAspectRatioX ));
DebugPrint(( DebugLevelTrace, "DVDTS: AspectRatioY %d\r\n", VidFmt->hdr.dwPictAspectRatioY ));
if( pHwDevExt->VPFmt.dwPictAspectRatioX == 4 && pHwDevExt->VPFmt.dwPictAspectRatioY == 3 ) {
decCGuard_CPGD_SET_ASPECT( pHwDevExt, 0 );
}
else if (pHwDevExt->VPFmt.dwPictAspectRatioX == 16 && pHwDevExt->VPFmt.dwPictAspectRatioY == 9 ) {
decCGuard_CPGD_SET_ASPECT( pHwDevExt, 1 );
}
//
// check for pan scan enabled
//
if( VidFmt->dwFlags & KS_MPEG2_DoPanScan )
DebugPrint(( DebugLevelTrace, "DVDTS: KS_MPEG2_DoPanScan\r\n" ));
if( VidFmt->dwFlags & KS_MPEG2_DVDLine21Field1 )
DebugPrint(( DebugLevelTrace, "DVDTS: KS_MPEG2_DVDLine21Field1\r\n" ));
if( VidFmt->dwFlags & KS_MPEG2_DVDLine21Field2 )
DebugPrint(( DebugLevelTrace, "DVDTS: KS_MPEG2_DVDLine21Field2\r\n" ));
if( VidFmt->dwFlags & KS_MPEG2_SourceIsLetterboxed )
DebugPrint(( DebugLevelTrace, "DVDTS: KS_MPEG2_SourceIsLetterboxed\r\n" ));
if( VidFmt->dwFlags & KS_MPEG2_FilmCameraMode )
DebugPrint(( DebugLevelTrace, "DVDTS: KS_MPEG2_FilmCameraMode\r\n" ));
if (VidFmt->dwFlags & KS_MPEG2_DoPanScan)
{
TRAP;
//
// under pan scan for DVD for NTSC, we must be going to a 540 by
// 480 bit image, from a 720 x 480 (or 704 x 480) We will
// use this as the base starting dimensions. If the Sequence
// header provides other sizes, then those should be updated,
// and the Video port connection should be updated when the
// sequence header is received.
//
//
// change the picture aspect ratio. Since we will be stretching
// from 540 to 720 in the horizontal direction, our aspect ratio
// will
//
pHwDevExt->VPFmt.dwPictAspectRatioX = (VidFmt->hdr.dwPictAspectRatioX * (54000 / 72));
pHwDevExt->VPFmt.dwPictAspectRatioY = VidFmt->hdr.dwPictAspectRatioY * 1000;
}
//
// call the IVPConfig interface here
//
if (pHwDevExt->pstroYUV &&
((PSTREAMEX)(pHwDevExt->pstroYUV->HwStreamExtension))->EventCount)
{
StreamClassStreamNotification(
SignalMultipleStreamEvents,
pHwDevExt->pstroYUV,
&MY_KSEVENTSETID_VPNOTIFY,
KSEVENT_VPNOTIFY_FORMATCHANGE
);
}
}
// Debug
void BadWait( DWORD dwTime )
{
DWORD st, et;
st = GetCurrentTime_ms();
for( ; ; ) {
KeStallExecutionProcessor( 1 );
et = GetCurrentTime_ms();
if( st + dwTime < et )
break;
}
DebugPrint( (DebugLevelTrace, "DVDTS:wait %dms\r\n", et - st ) );
}
void VideoDataDiscontinuity( PHW_DEVICE_EXTENSION pHwDevExt )
{
pHwDevExt->DataDiscontFlagCount |= VIDEO_DISCONT_FLAG;
pHwDevExt->bVideoQueue = TRUE;
}
void AudioDataDiscontinuity( PHW_DEVICE_EXTENSION pHwDevExt )
{
pHwDevExt->DataDiscontFlagCount |= AUDIO_DISCONT_FLAG;
pHwDevExt->bAudioQueue = TRUE;
}
void SubpicDataDiscontinuity( PHW_DEVICE_EXTENSION pHwDevExt )
{
pHwDevExt->DataDiscontFlagCount |= SUBPIC_DISCONT_FLAG;
pHwDevExt->bSubpicQueue = TRUE;
}
void ClearDataDiscontinuity( PHW_DEVICE_EXTENSION pHwDevExt )
{
pHwDevExt->DataDiscontFlagCount = 0;
}
void VideoTimeDiscontinuity( PHW_DEVICE_EXTENSION pHwDevExt )
{
}
void AudioTimeDiscontinuity( PHW_DEVICE_EXTENSION pHwDevExt )
{
}
void SubpicTimeDiscontinuity( PHW_DEVICE_EXTENSION pHwDevExt )
{
}
void ClearTimeDiscontinuity( PHW_DEVICE_EXTENSION pHwDevExt )
{
pHwDevExt->TimeDiscontFlagCount = 0;
}
void FastSlowControl( PHW_STREAM_REQUEST_BLOCK pSrb )
{
PHW_DEVICE_EXTENSION pHwDevExt = (PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension;
ULONG i;
PKSSTREAM_HEADER pStruc;
PUCHAR pDat;
LONGLONG pts = 0;
LONGLONG dts = 0;
LONGLONG tmp = 0;
LONG Rate;
LONGLONG start;
REFERENCE_TIME InterceptTime;
for( i = 0; i < pSrb->NumberOfBuffers; i++ ) {
pStruc = &((PKSSTREAM_HEADER)(pSrb->CommandData.DataBufferArray))[i];
if( pStruc->DataUsed ) {
pDat = (PUCHAR)pStruc->Data;
if( *(pDat+21) & 0x80 ) {
pts += ((DWORD)(*(pDat+23) & 0x0E)) << 29;
pts += ((DWORD)(*(pDat+24) & 0xFF)) << 22;
pts += ((DWORD)(*(pDat+25) & 0xFE)) << 14;
pts += ((DWORD)(*(pDat+26) & 0xFF)) << 7;
pts += ((DWORD)(*(pDat+27) & 0xFE)) >> 1;
DebugPrint( (DebugLevelTrace, "DVDTS:ReceiveDataPacket PTS 0x%lx(100ns)\r\n", pts * 1000 / 9));
}
}
}
pts = 0;
// if( decGetVideoPlayMode( pHwDevExt ) == PLAY_MODE_FAST ) {
if( decGetVideoRunMode( pHwDevExt ) == PLAY_MODE_FAST ) {
// DebugPrint( (DebugLevelTrace, "DVDTS: FastSlowControl\r\n") );
Rate = pHwDevExt->Rate;
InterceptTime = pHwDevExt->InterceptTime;
start = pHwDevExt->StartTime * 9 / 1000;
for( i = 0; i < pSrb->NumberOfBuffers; i++ ) {
pStruc = &((PKSSTREAM_HEADER)(pSrb->CommandData.DataBufferArray))[i];
if( pStruc->DataUsed ) {
pDat = (PUCHAR)pStruc->Data;
// PTS modify
if( *(pDat+21) & 0x80 ) {
pts += ((DWORD)(*(pDat+23) & 0x0E)) << 29;
pts += ((DWORD)(*(pDat+24) & 0xFF)) << 22;
pts += ((DWORD)(*(pDat+25) & 0xFE)) << 14;
pts += ((DWORD)(*(pDat+26) & 0xFF)) << 7;
pts += ((DWORD)(*(pDat+27) & 0xFE)) >> 1;
DebugPrint( (DebugLevelTrace, "DVDTS: PTS before Rate Change = %lx\r\n", pts ));
// DebugPrint( (DebugLevelTrace, "DVDTS: Rate = %lx\r\n", Rate ));
// DebugPrint( (DebugLevelTrace, "DVDTS: InterceptTime = %lx\r\n", InterceptTime ));
tmp = pts;
// pts = Rate * ( pts - ConvertStrmtoPTS(InterceptTime) ) / 10000;
pts = Rate * ( pts - (InterceptTime * 9 / 1000) ) / 10000;
*(pDat+23) = (UCHAR)(((pts & 0xC0000000) >> 29) | 0x11);
*(pDat+24) = (UCHAR)(((pts & 0x3FC00000) >> 22) | 0x00);
*(pDat+25) = (UCHAR)(((pts & 0x003F8000) >> 14) | 0x01);
*(pDat+26) = (UCHAR)(((pts & 0x00007F80) >> 7) |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -