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

📄 camerawindow.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
 *
 *  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 + -