⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 halvpe.cpp

📁 SM501基于ARMV4/ARMV4I平台
💻 CPP
📖 第 1 页 / 共 4 页
字号:
void SMI::VPE_SetCap(DWORD dwMask, DWORD dwVal)
{
	DWORD dwMode = PEEK_32(CAPTURE_CONTROL);
	dwMode = (dwMode & dwMask) | dwVal;

    POKE_32(CAPTURE_CONTROL, dwMode);
}

BOOL SMI::VPE_WaitForVSync(DWORD dwTimeOut)
{
#ifndef DISABLE_INTERRUPT_MANAGEMENT
	DWORD retVal = FALSE;

 	if (!m_bZVPortEvent) {
	    	// Worst case : we are prempted right after m_bZVPortEvent is set to
    		// TRUE, and then we hit a vertical retrace. This causes m_bZVPortEvent to
	    	// be harmlessly set with no threads waiting. We also miss that vsync.

    		m_bZVPortEvent = TRUE;
    
		    DWORD retWait = WaitForSingleObject(m_hZVPortEvent,
                                     dwTimeOut);

    		m_bZVPortEvent = FALSE;

    		switch (retWait) {
			case WAIT_OBJECT_0:
				retVal = TRUE;
	 		    break;
		    case WAIT_TIMEOUT:
		      	DEBUGMSG(GPE_ZONE_WARNING, (L"Timeout waiting for vertical retrace!\n"));
				break;
		    case WAIT_FAILED:
				DEBUGMSG(GPE_ZONE_ERROR,(L"Wait on vertical retrace failed\n"));
      			break;
    		}
	}
	else {
    		DEBUGMSG(GPE_ZONE_ERROR, (L"Another thread is already waiting on the vsync!\n"));
	}

	return retVal;
#else
	return FALSE;
#endif
}

void vpeIntHandlerEntry(SMI* pSMI)
{
	pSMI->VPE_IntHandler();
}

void SMI::VPE_IntHandler()
{
#ifndef DISABLE_INTERRUPT_MANAGEMENT
	if (m_bZVPortEvent) 
    {
		SetEvent(m_hZVPortEvent);
	}

	POKE_32(RAW_INT_STATUS, FIELD_SET(0, RAW_INT_STATUS, ZVPORT, CLEAR));
	VPE_ProcessCapture();
#endif
}
int	SMI::VPE_CurrentBuffer()
{
    DWORD capture_ctrl = 0;
    capture_ctrl = PEEK_32(CAPTURE_CONTROL);

	return(FIELD_GET(capture_ctrl, CAPTURE_CONTROL, FIELD));
}

void SMI::VPE_ProcessCapture()
{
#ifndef DISABLE_INTERRUPT_MANAGEMENT
    PLIST_ENTRY pEntry;
    PFLIP_EXTENSION pFlipExt;

		return;
 
            if(!m_Autoflip.pCaptureEntry1  && !m_Autoflip.pCaptureEntry2)
            {
                // Just start.
                pEntry = RemoveHeadList(&m_Autoflip.EmptyFrameQueue);
				pFlipExt = (PFLIP_EXTENSION)(((PUCHAR)pEntry) - FIELDOFFSET(FLIP_EXTENSION, ListEntry));
				VPE_SetDst(pFlipExt->fpVidMem);
				m_Autoflip.pCaptureEntry1 = pEntry;

                pEntry = RemoveHeadList(&m_Autoflip.EmptyFrameQueue);
				pFlipExt = (PFLIP_EXTENSION)(((PUCHAR)pEntry) - FIELDOFFSET(FLIP_EXTENSION, ListEntry));
				VPE_SetDst2(pFlipExt->fpVidMem);
				m_Autoflip.pCaptureEntry2 = pEntry;
            }
            else if(VPE_CurrentBuffer() == 1)
            {
                // Buffer2 is just filled.
                // 1) Complete the display field if exists.
                if(m_Autoflip.pDisplayEntry)
                {
                    InsertTailList(&m_Autoflip.EmptyFrameQueue, m_Autoflip.pDisplayEntry);
                }

                // 2) Display the newly captured field.
                pEntry = m_Autoflip.pCaptureEntry2;
				pFlipExt = (PFLIP_EXTENSION)(((PUCHAR)pEntry) - FIELDOFFSET(FLIP_EXTENSION, ListEntry));
                VPE_EnableOverlayWindow(pFlipExt->fpVidMem);
                
                // Correct BOB display.
                if(VPE_IsEvenField())
                {
                    // The captured field is even field.
					POKE_32(VIDEO_INITIAL_SCALE, 
						FIELD_VALUE(0, VIDEO_INITIAL_SCALE, FB_1, 0) |
						FIELD_VALUE(0, VIDEO_INITIAL_SCALE, FB_0, 0) |
						0);

                }
                else
                {
                    // The captured field is odd field.
					POKE_32(VIDEO_INITIAL_SCALE, 
						FIELD_VALUE(0, VIDEO_INITIAL_SCALE, FB_1, 0x800) |
						FIELD_VALUE(0, VIDEO_INITIAL_SCALE, FB_0, 0x800) |
						0);
                }

                m_Autoflip.pDisplayEntry = pEntry;

                // 3) Set the next capture field.
                pEntry = RemoveHeadList(&m_Autoflip.EmptyFrameQueue);
				pFlipExt = (PFLIP_EXTENSION)(((PUCHAR)pEntry) - FIELDOFFSET(FLIP_EXTENSION, ListEntry));
				VPE_SetDst2(pFlipExt->fpVidMem);
				m_Autoflip.pCaptureEntry2 = pEntry;
            }
            else
            {
                // Buffer1 is just filled.
                // 1) Complete the display field if exists.
                if(m_Autoflip.pDisplayEntry)
                {
                    InsertTailList(&m_Autoflip.EmptyFrameQueue, m_Autoflip.pDisplayEntry);
                }

                // 2) Display the newly captured field.
                pEntry = m_Autoflip.pCaptureEntry1;
				pFlipExt = (PFLIP_EXTENSION)(((PUCHAR)pEntry) - FIELDOFFSET(FLIP_EXTENSION, ListEntry));
                VPE_EnableOverlayWindow(pFlipExt->fpVidMem);

                // Correct BOB display.
                if(VPE_IsEvenField())
                {
                    // The captured field is even field.
					POKE_32(VIDEO_INITIAL_SCALE, 
						FIELD_VALUE(0, VIDEO_INITIAL_SCALE, FB_1, 0) |
						FIELD_VALUE(0, VIDEO_INITIAL_SCALE, FB_0, 0) |
						0);

                }
                else
                {
                    // The captured field is odd field.
					POKE_32(VIDEO_INITIAL_SCALE, 
						FIELD_VALUE(0, VIDEO_INITIAL_SCALE, FB_1, 0x800) |
						FIELD_VALUE(0, VIDEO_INITIAL_SCALE, FB_0, 0x800) |
						0);
                }

                m_Autoflip.pDisplayEntry = pEntry;

                // 3) Set the next capture field.
                pEntry = RemoveHeadList(&m_Autoflip.EmptyFrameQueue);
				pFlipExt = (PFLIP_EXTENSION)(((PUCHAR)pEntry) - FIELDOFFSET(FLIP_EXTENSION, ListEntry));
				VPE_SetDst(pFlipExt->fpVidMem);
				m_Autoflip.pCaptureEntry1 = pEntry;
            }
#endif
}

// When use software autoflip, we need minimum 3 field buffers and maximum 8 field buffers. 
// Inside m_Autoflip structure,
// EmptyFrameQueue  queues all the empty buffers, initially it contains all the field surfaces allocated by user app;
// pCaptureEntry1   desinates the first capture buffer when using hardware double buffer capture, initially it's NULL;
// pCaptureEntry2   desinates the second capture buffer when using hardware double buffer capture, initially it's NULL;
// pDisplayEntry    desinates the buffer which is being displayed, initially it's NULL.
void SMI::VPE_InitSwAutoflip(DWORD *pInput)
{
#ifndef DISABLE_INTERRUPT_MANAGEMENT
    DWORD numOfSurfaces = pInput[0];

    InitializeListHead(&m_Autoflip.EmptyFrameQueue);

    m_Autoflip.pCaptureEntry1 = NULL;
    m_Autoflip.pCaptureEntry2 = NULL;
    m_Autoflip.pDisplayEntry = NULL;

    for(DWORD i=0; i<numOfSurfaces; i++)
    {
        m_Autoflip.FlipEntries[i].surfaceIndex = i;
        m_Autoflip.FlipEntries[i].fpVidMem = pInput[i+1];
        InsertTailList(&m_Autoflip.EmptyFrameQueue, &m_Autoflip.FlipEntries[i].ListEntry);
    }
#endif
}

void SMI::VPE_InitInterrupt()
{
#ifndef DISABLE_INTERRUPT_MANAGEMENT
	m_bZVPortEvent = FALSE;

	m_hZVPortEvent = CreateEvent(NULL, 
			FALSE, // Auto-reset
 		  	FALSE, // Initially not signaled
			NULL);

	if (m_hZVPortEvent == NULL)
	{
		DEBUGMSG(GPE_ZONE_ERROR, (TEXT("SMI::InitZVPortInterrupt Failed!\r\n")));
		m_bZVPortEvent = TRUE;
	}

			// Register PWM interrupt handler
	RegisterHandler(
		vpeIntHandlerEntry,
		FIELD_SET(0, INT_MASK, ZVPORT, ENABLE));

#endif //DISABLE_INTERRUPT_MANAGEMENT
}

void SMI::VPE_DisableInterrupt()
{
#ifndef DISABLE_INTERRUPT_MANAGEMENT

	// Register PWM interrupt handler
	DisableHandler(
		FIELD_SET(0, INT_MASK, ZVPORT, ENABLE));

	if (m_hZVPortEvent != NULL)
	{
		if (m_bZVPortEvent) 
    	{
			SetEvent(m_hZVPortEvent);
			Sleep(200);
		}

		m_bZVPortEvent = TRUE;
		CloseHandle(m_hZVPortEvent);
	}

#endif //DISABLE_INTERRUPT_MANAGEMENT
}

ULONG SMI::HandleSMIVPEAPI(ULONG cjIn, PVOID pvIn, ULONG cjOut, PVOID pvOut)
{
	int RetVal = 0; // Not Supported

	if (((cjIn >= sizeof(SMIVPEAPI)) && (pvIn != NULL)) &&
		((cjOut >= sizeof(SMIVPEAPI)) && (pvOut != NULL)))
	{
		SMIVPEAPI *pSmiVpeOut = (SMIVPEAPI *)pvOut;
		SMIVPEAPI *pSmiVpe = (SMIVPEAPI *)pvIn;
		DWORD dwMask = 0;
		RetVal = -1;

		switch (pSmiVpe->dwCommand)
		{
		case SMIVPEAPI_FIELD_SWAP:
			RetVal = 1;
		    if (pSmiVpe->dwParam == SMIVPEAPI_ENABLE)
				VPE_EnableFieldSwap();
			else if (pSmiVpe->dwParam == SMIVPEAPI_DISABLE)
				VPE_DisableFieldSwap();
			else
				RetVal = -2;
			break;
		case SMIVPEAPI_BYTE_SWAP:
			RetVal = 1;
		    if (pSmiVpe->dwParam == SMIVPEAPI_ENABLE)
				VPE_EnableByteSwap();
			else if (pSmiVpe->dwParam == SMIVPEAPI_DISABLE)
				VPE_DisableByteSwap();
			else
				RetVal = -2;
			break;
		case SMIVPEAPI_UV_SWAP:
			RetVal = 1;
			dwMask = FIELD_SET(0, CAPTURE_CONTROL, UV_SWAP, ENABLE);
		    if (pSmiVpe->dwParam == SMIVPEAPI_ENABLE)
				VPE_SetCap(dwMask, dwMask);
			else if (pSmiVpe->dwParam == SMIVPEAPI_DISABLE)
				VPE_SetCap(dwMask, 0);
			else
				RetVal = -2;
			break;
		case SMIVPEAPI_CAPTURE_SIZE:
			RetVal = 1;
			dwMask = FIELD_SET(0, CAPTURE_CONTROL, CAPTURE_SIZE, 8);
		    if (pSmiVpe->dwParam == SMIVPEAPI_8BIT)
				VPE_SetCap(dwMask, dwMask);
			else if (pSmiVpe->dwParam == SMIVPEAPI_16BIT)
				VPE_SetCap(dwMask, 0);
			else
				RetVal = -2;
			break;
		case SMIVPEAPI_FORMAT:
			RetVal = 1;
			dwMask = FIELD_SET(0, CAPTURE_CONTROL, CAPTURE_FORMAT, RGB);
		    if (pSmiVpe->dwParam == SMIVPEAPI_RGB)
				VPE_SetCap(dwMask, dwMask);
			else if (pSmiVpe->dwParam == SMIVPEAPI_YUV)
				VPE_SetCap(dwMask, 0);
			else
				RetVal = -2;
			break;
		case SMIVPEAPI_CLOCK_POLARITY:
			RetVal = 1;
			dwMask = FIELD_SET(0, CAPTURE_CONTROL, CLOCK_POLARITY, ACTIVE_LOW);
		    if (pSmiVpe->dwParam == SMIVPEAPI_ACTIVE_LOW)
				VPE_SetCap(dwMask, dwMask);
			else if (pSmiVpe->dwParam == SMIVPEAPI_ACTIVE_HIGH)
				VPE_SetCap(dwMask, 0);
			else
				RetVal = -2;
			break;
		case SMIVPEAPI_HREF_PHASE:
			RetVal = 1;
			dwMask = FIELD_SET(0, CAPTURE_CONTROL, HREF_PHASE, ACTIVE_LOW);
		    if (pSmiVpe->dwParam == SMIVPEAPI_ACTIVE_LOW)
				VPE_SetCap(dwMask, dwMask);
			else if (pSmiVpe->dwParam == SMIVPEAPI_ACTIVE_HIGH)
				VPE_SetCap(dwMask, 0);
			else
				RetVal = -2;
			break;
		case SMIVPEAPI_VSYNC_PHASE:
			RetVal = 1;
			dwMask = FIELD_SET(0, CAPTURE_CONTROL, VSYNC_PHASE, ACTIVE_LOW);
		    if (pSmiVpe->dwParam == SMIVPEAPI_ACTIVE_LOW)
				VPE_SetCap(dwMask, dwMask);
			else if (pSmiVpe->dwParam == SMIVPEAPI_ACTIVE_HIGH)
				VPE_SetCap(dwMask, 0);
			else
				RetVal = -2;
			break;
		case SMIVPEAPI_FIELD_DETECT:
			RetVal = 1;
			dwMask = FIELD_SET(0, CAPTURE_CONTROL, FIELD_DETECT, FALLING);
		    if (pSmiVpe->dwParam == SMIVPEAPI_FALLING)
				VPE_SetCap(dwMask, dwMask);
			else if (pSmiVpe->dwParam == SMIVPEAPI_RISING)
				VPE_SetCap(dwMask, 0);
			else
				RetVal = -2;
			break;
		case SMIVPEAPI_2TO1HSHRINK:
			RetVal = 1;
			dwMask = FIELD_SET(0, CAPTURE_CONTROL, 2TO1_HORIZONTAL_SHRINK, ENABLE);
		    if (pSmiVpe->dwParam == SMIVPEAPI_ENABLE)
				VPE_SetCap(dwMask, dwMask);
			else if (pSmiVpe->dwParam == SMIVPEAPI_DISABLE)
				VPE_SetCap(dwMask, 0);
			else
				RetVal = -2;
			break;
		case SMIVPEAPI_2TO1VSHRINK:
			RetVal = 1;
			dwMask = FIELD_SET(0, CAPTURE_CONTROL, 2TO1_VERTICAL_SHRINK, ENABLE);
		    if (pSmiVpe->dwParam == SMIVPEAPI_ENABLE)
				VPE_SetCap(dwMask, dwMask);
			else if (pSmiVpe->dwParam == SMIVPEAPI_DISABLE)
				VPE_SetCap(dwMask, 0);
			else
				RetVal = -2;
			break;
		case SMIVPEAPI_HAVE:
			RetVal = 1;
			dwMask = FIELD_SET(0, CAPTURE_CONTROL, HORIZONTAL_AVE, ENABLE);
		    if (pSmiVpe->dwParam == SMIVPEAPI_ENABLE)
				VPE_SetCap(dwMask, dwMask);
			else if (pSmiVpe->dwParam == SMIVPEAPI_DISABLE)
				VPE_SetCap(dwMask, 0);
			else
				RetVal = -2;
			break;
		case SMIVPEAPI_VIDEO_VINTERPOLATE:
			RetVal = 1;
		    if (pSmiVpe->dwParam == SMIVPEAPI_ENABLE)
				Video_SetVerticalMode(INTERPOLATE);
			else if (pSmiVpe->dwParam == SMIVPEAPI_DISABLE)
				Video_SetVerticalMode(REPLICATE);
			else
				RetVal = -2;
			break;
		case SMIVPEAPI_VIDEO_HINTERPOLATE:
			RetVal = 1;
		    if (pSmiVpe->dwParam == SMIVPEAPI_ENABLE)
				Video_SetHorizontalMode(INTERPOLATE);
			else if (pSmiVpe->dwParam == SMIVPEAPI_DISABLE)
				Video_SetHorizontalMode(REPLICATE);
			else
				RetVal = -2;
			break;
		}
	}
	else
	{
		RetVal = -1;
	}

	if (RetVal == -1)
		SetLastError (ERROR_INVALID_PARAMETER);

	return (ULONG) RetVal;
}


#endif // VPE_ENABLE

#endif // DD_ENABLE

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -