📄 camerawindow.cpp
字号:
/*
*
* Copyright (C) 2004-2006,2007, Freescale Semiconductor, Inc. All Rights Reserved.
* THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
* AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
*
* File: APPS/CAMAPP/CCameraWindow.cpp
* Purpose: The implementation of the CCameraWindow class
* Notes:
*
*/
/*********************************************************************
INCLUDE FILES
*********************************************************************/
#include <windows.h>
#include <ddraw.h>
#include <Devload.h>
#include <tchar.h>
#define _COMCTL32_
#include <commctrl.h>
#undef _COMCTL32_
#include <commdlg.h>
#include "CameraWindow.h"
#include "OptionsDlg.h"
#include "bsp.h"
#include "display_vf.h"
#include "pwingdi.h"
#include "cdib.h"
/*********************************************************************
MACRO DEFINITIONS
*********************************************************************/
// This macro for select display mode.If enable this macro, we use direct
// draw mode for display,the performance is better when we use this mode.
// But the menu item sometimes don't show correctly.
// If we disable this macro, we use stretchDIBit mode to display the frames,
// The performance is not good, but the program is more simple.
// #define DIRECT_DRAW_MODE
#define SKIN_HEIGHT 40
#define SKIN_WIDTH 240
#define BUTTON_HEIGHT 20
#define BUTTON_WIDTH 50
#define SKIN_MARGIN 1
#undef USE_CAPTURE_PIN // in MX27, capture pin is used for encoder and
// this does not support RGB so no use for saving image
/*********************************************************************
GLOBAL DEFINITIONS
*********************************************************************/
/*********************************************************************
GLOBAL OR STATIC VARIABLES
*********************************************************************/
/*********************************************************************
STATIC FUNCTION PROTOTYPES
*********************************************************************/
#ifdef DIRECT_DRAW_MODE
LPDIRECTDRAW g_pDD = NULL; // DirectDraw object
LPDIRECTDRAWSURFACE g_pDDSPrimary = NULL; // Primary Surface.
LPDIRECTDRAWSURFACE g_pDDSOverlay = NULL; // The overlay primary.
LPDIRECTDRAWSURFACE g_pDDSOverback = NULL; // The overlay back.
static void ReleaseAllObjects(void)
{
RETAILMSG(CAMAPP_DEBUG_MSG, (TEXT("Release all resource for direct draw! \r\n")));
if (g_pDDSOverback != NULL)
{
g_pDDSOverback->Release();
g_pDDSOverback = NULL;
}
if (g_pDDSOverlay != NULL)
{
// Use UpdateOverlay() with the DDOVER_HIDE flag to remove an overlay from the display.
g_pDDSOverlay->UpdateOverlay(NULL, g_pDDSPrimary, NULL, DDOVER_HIDE, NULL);
g_pDDSOverlay->Release();
g_pDDSOverlay = NULL;
}
if (g_pDDSPrimary != NULL)
{
g_pDDSPrimary->Release();
g_pDDSPrimary = NULL;
}
if (g_pDD != NULL)
{
g_pDD->Release();
g_pDD = NULL;
}
}
/***********************************************************************
*
* FUNCTION: EnumFunction()
*
* DESCRIPTION: Desc: Enumeration callback for surfaces in flipping chain. We expect this
* function to be called once with the surface interface pointer of
* our back buffer (we only ask for a single back buffer.)
*
* PARAMETERS: None
*
* RETURNS: A double word value for ExitThread()
*
**********************************************************************/
static HRESULT PASCAL
EnumFunction(LPDIRECTDRAWSURFACE pSurface,
LPDDSURFACEDESC lpSurfaceDesc,
LPVOID lpContext)
{
static BOOL bCalled = FALSE;
if (!bCalled) {
*((LPDIRECTDRAWSURFACE *)lpContext) = pSurface;
bCalled = TRUE;
return DDENUMRET_OK;
}
else {
RETAILMSG(CAMAPP_DEBUG_MSG, (TEXT("Enumerated more than surface? \r\n")));
pSurface->Release();
return DDENUMRET_CANCEL;
}
}
/***********************************************************************
*
* FUNCTION: CamApp_PreviewThread
*
* DESCRIPTION: This function is Preview thread.
*
* PARAMETERS: None
*
* RETURNS: A double word value for ExitThread()
*
**********************************************************************/
UINT32 CamApp_PreviewThread(LPVOID lpParameter)
{
PCAMERAWINDOW pCamWin = reinterpret_cast<PCAMERAWINDOW>(lpParameter);
UINT8 *pbySrcBuffer = NULL, *pbyDstBuffer = NULL;
UINT16 displayHeight = 0;
UINT16 displayWidth = 0;
DWORD size,flags;
DWORD dBytesTransferred;
DWORD height = 0;
BOOL bRotation = FALSE;
BOOL bResult = FALSE;
BOOL DDraw_Changed = FALSE;
RECT rc,rs,rd;
DWORD dwUpdateFlags;
DWORD StretchFactor1000;
DDCAPS ddcaps;
HRESULT hRet;
LPDIRECTDRAW pDD = NULL;
DDOVERLAYFX ovfx;
DDSURFACEDESC ddsd;
CSBUFFER_INFO csBufferInfo;
CS_MSGQUEUE_BUFFER CsMsgQBuff;
DDPIXELFORMAT ddpfOverlayFormats = {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0xF800, 0x07e0, 0x001F, 0};
RETAILMSG(CAMAPP_DEBUG_MSG, (TEXT("CamApp_PreviewThread+\r\n")));
csBufferInfo.dwCommand = CS_ENQUEUE;
csBufferInfo.pStreamDescriptor= pCamWin->m_pPreviewStreamDesc;
//Init rectangle information.
::GetClientRect(pCamWin->m_hWnd, &rc);
pCamWin->m_DisplayInfo.screenWidth =(UINT16)(rc.right - rc.left);
pCamWin->m_DisplayInfo.screenHeight = (UINT16)( rc.bottom - rc.top - SKIN_HEIGHT - GetSystemMetrics(SM_CYMENU));
rs.left = 0;
rs.top = 0;
rs.right = pCamWin->m_DisplayInfo.screenWidth;
rs.bottom = pCamWin->m_DisplayInfo.screenHeight;
rd.left = 0;
rd.top = GetSystemMetrics(SM_CYMENU);
rd.right = pCamWin->m_DisplayInfo.screenWidth;
rd.bottom = pCamWin->m_DisplayInfo.screenHeight + GetSystemMetrics(SM_CYMENU);
// Initialize DDraw resource.
hRet = DirectDrawCreate(NULL, &g_pDD, NULL);
if (DD_OK != hRet)
{
ReleaseAllObjects();
RETAILMSG(CAMAPP_ERROR_MSG, (TEXT("CamApp_PreviewThread:Init DDraw resource failure? \r\n")));
return 0;
}
hRet = g_pDD->SetCooperativeLevel(pCamWin->m_hWnd, DDSCL_NORMAL);
if (DD_OK != hRet)
{
ReleaseAllObjects();
RETAILMSG(CAMAPP_ERROR_MSG, (TEXT("CamApp_PreviewThread:Init DDraw resource failure? \r\n")));
return 0;
}
// Get a primary surface interface pointer (only needed for init.)
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL);
if (DD_OK != hRet)
{
ReleaseAllObjects();
RETAILMSG(CAMAPP_ERROR_MSG, (TEXT("CamApp_PreviewThread:Init DDraw resource failure? \r\n")));
return 0;
}
// See if we can support overlays.
memset(&ddcaps, 0, sizeof(ddcaps));
ddcaps.dwSize = sizeof(ddcaps);
hRet = g_pDD->GetCaps(&ddcaps,NULL);
if (DD_OK != hRet)
{
ReleaseAllObjects();
RETAILMSG(CAMAPP_ERROR_MSG, (TEXT("CamApp_PreviewThread:Init DDraw resource failure? \r\n")));
return 0;
}
if (ddcaps.dwOverlayCaps == 0)
{
ReleaseAllObjects();
RETAILMSG(CAMAPP_ERROR_MSG, (TEXT("CamApp_PreviewThread:Init DDraw resource failure? \r\n")));
return 0;
}
// Adjust rs and rd size,or it will fails when UpdateOverlay().
if (ddcaps.dwAlignSizeSrc != 0)
{
rs.right += rs.right % ddcaps.dwAlignSizeSrc;
}
StretchFactor1000 = ddcaps.dwMinOverlayStretch > 1000 ? ddcaps.dwMinOverlayStretch : 1000;
if (ddcaps.dwAlignBoundaryDest)
{
rd.left = rd.left - rd.left % ddcaps.dwAlignBoundaryDest;
}
else
{
rd.left = rd.left;
}
// Adding 999 takes care of integer truncation problems.
rd.right = (rd.right * StretchFactor1000 + 999) / 1000 ;
rd.bottom = rd.bottom * StretchFactor1000 / 1000;
if (ddcaps.dwAlignSizeDest != 0)
{
rd.right = ((rd.right + ddcaps.dwAlignSizeDest - 1)/ ddcaps.dwAlignSizeDest) *ddcaps.dwAlignSizeDest;
}
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_FLIP; // | DDSCAPS_COMPLEX | DDSCAPS_VIDEOMEMORY;
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_BACKBUFFERCOUNT | DDSD_PIXELFORMAT;
ddsd.dwWidth = rs.right;
ddsd.dwHeight = rs.bottom;
ddsd.dwBackBufferCount = 1;
ddsd.ddpfPixelFormat = ddpfOverlayFormats;
hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSOverlay, NULL);
if (DD_OK != hRet)
{
ReleaseAllObjects();
RETAILMSG(CAMAPP_ERROR_MSG, (TEXT("CamApp_PreviewThread:Init DDraw resource failure? \r\n")));
return 0;
}
hRet = g_pDDSOverlay->EnumAttachedSurfaces(&g_pDDSOverback, EnumFunction);
if (DD_OK != hRet)
{
ReleaseAllObjects();
RETAILMSG(CAMAPP_ERROR_MSG, (TEXT("CamApp_PreviewThread:Init DDraw resource failure? \r\n")));
return 0;
}
// Set the flags we'll send to UpdateOverlay
dwUpdateFlags = DDOVER_SHOW;
// Does the overlay hardware support source color keying?
// If so, we can hide the black background around the image.
// This probably won't work with YUV formats
memset(&ovfx, 0, sizeof(ovfx));
ovfx.dwSize = sizeof(ovfx);
if (ddcaps.dwOverlayCaps & DDOVERLAYCAPS_CKEYDEST)
{
dwUpdateFlags |= DDOVER_KEYDESTOVERRIDE;
// This information is ignored if the DDOVER_SRCKEYOVERRIDE flag isn't set.
//ovfx.dckDestColorkey.dwColorSpaceLowValue=0x841; // black as the color key
ovfx.dckDestColorkey.dwColorSpaceLowValue=0; // black as the color key
ovfx.dckDestColorkey.dwColorSpaceHighValue=0;
}
hRet = g_pDDSOverlay->UpdateOverlay(&rs, g_pDDSPrimary, &rd, dwUpdateFlags,&ovfx);
if (DD_OK != hRet)
{
ReleaseAllObjects();
RETAILMSG(CAMAPP_ERROR_MSG, (TEXT("CamApp_PreviewThread:Init DDraw resource failure? \r\n")));
return 0;
}
while (!pCamWin->m_bCamAppThreadTerminate)
{
bRotation = pCamWin->m_bRotation;
if (!pCamWin->m_bRotation)
{
pCamWin->m_DisplayInfo.imageWidth = (UINT16)abs(pCamWin->m_PreviewDataFormat.VideoInfoHeader.bmiHeader.biWidth);
pCamWin->m_DisplayInfo.imageHeight = (UINT16)abs(pCamWin->m_PreviewDataFormat.VideoInfoHeader.bmiHeader.biHeight);
}
else
{
pCamWin->m_DisplayInfo.imageWidth = (UINT16)abs(pCamWin->m_PreviewDataFormat.VideoInfoHeader.bmiHeader.biHeight);
pCamWin->m_DisplayInfo.imageHeight = (UINT16)abs(pCamWin->m_PreviewDataFormat.VideoInfoHeader.bmiHeader.biWidth);
}
if (pCamWin->m_DisplayInfo.imageWidth >= pCamWin->m_DisplayInfo.screenWidth)
{
pCamWin->m_DisplayInfo.xOffset = 0;
displayWidth = pCamWin->m_DisplayInfo.screenWidth;
}
else
{
pCamWin->m_DisplayInfo.xOffset = (UINT16)(rc.left + (pCamWin->m_DisplayInfo.screenWidth - pCamWin->m_DisplayInfo.imageWidth)/2);
displayWidth = pCamWin->m_DisplayInfo.imageWidth;
}
if (pCamWin->m_DisplayInfo.imageHeight >= pCamWin->m_DisplayInfo.screenHeight)
{
pCamWin->m_DisplayInfo.yOffset = (UINT16)(rc.top + GetSystemMetrics(SM_CYMENU));
displayHeight = pCamWin->m_DisplayInfo.screenHeight;
}
else
{
pCamWin->m_DisplayInfo.yOffset = (UINT16)(rc.top + GetSystemMetrics(SM_CYMENU) + (pCamWin->m_DisplayInfo.screenHeight- pCamWin->m_DisplayInfo.imageHeight)/2);
displayHeight = pCamWin->m_DisplayInfo.imageHeight;
}
if (pCamWin->m_bPreviewRunning)
RETAILMSG(CAMAPP_DEBUG_MSG,(TEXT("CamApp_PreviewThread: m_bPreviewRunning = TRUE.\r\n")));
else
RETAILMSG(CAMAPP_DEBUG_MSG,(TEXT("CamApp_PreviewThread: m_bPreviewRunning = FALSE.\r\n")));
EnterCriticalSection(&pCamWin->m_csPreview);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -