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

📄 dx_video_render_wce.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
字号:
    /*//////////////////////////////////////////////////////////////////////////////
//
//                  INTEL CORPORATION PROPRIETARY INFORMATION
//     This software is supplied under the terms of a license agreement or
//     nondisclosure agreement with Intel Corporation and may not be copied
//     or disclosed except in accordance with the terms of that agreement.
//          Copyright(c) 2003-2006 Intel Corporation. All Rights Reserved.
//
*/

#include "umc_defs.h"

#if defined(UMC_ENABLE_DXWCE_VIDEO_RENDER)

#include "ippi.h"
#include "umc_video_data.h"
#include "dx_video_render_wce.h"

namespace UMC
{

DXWCEVideoRenderParams::DXWCEVideoRenderParams() :
    m_hWnd(NULL)
{

} // DXWCEVideoRenderParams::DXWCEVideoRenderParams() :

static DDPIXELFORMAT ddpfOverlayFormats[] =
{
    {sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('Y','V','1','2'), 0, 0, 0, 0, 0},   // YV12
    {sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('Y','U','Y','V'), 0, 0, 0, 0, 0},   // YUYV
    {sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('U','Y','V','Y'), 0, 0, 0, 0, 0},   // UYVY
    {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x7C00, 0x03e0, 0x001F, 0},               // 16-bit RGB 5:5:5
    {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0xF800, 0x07e0, 0x001F, 0}                // 16-bit RGB 5:6:5
};

DXWCEVideoRender::DXWCEVideoRender() :
    m_hWnd(NULL),
    m_pDD(NULL),
    m_pDDSPrimary(NULL),
    m_pDDSOverlay(NULL),
    m_bShow(true)
{
    memset(&m_SrcRect, 0, sizeof(m_SrcRect));
    memset(&m_SrcRect, 0, sizeof(m_DstRect));

} // DXWCEVideoRender::DXWCEVideoRender() :

DXWCEVideoRender::~DXWCEVideoRender()
{
    Close();

} // DXWCEVideoRender::~DXWCEVideoRender()

HRESULT DXWCEVideoRender::InitDDraw(HWND hWnd, UMC::RECT Rect)
{
    HRESULT         hRet = DD_OK;
    LPDIRECTDRAW    pDD = NULL;
    DDSURFACEDESC2  ddsd;
    DDCAPS          ddcaps;

    if (DD_OK == hRet)
    {
        hRet = DirectDrawCreate(NULL, &pDD, NULL);
        if (DD_OK != hRet)
            vm_debug_trace(VM_DEBUG_INFO,VM_STRING("DirectDrawCreate FAILED"));
    }

    // Fetch DirectDraw4 interface.
    if (DD_OK == hRet)
    {
        hRet = pDD->QueryInterface(IID_IDirectDraw4, (LPVOID*)&m_pDD);
        if (hRet != DD_OK)
            vm_debug_trace(VM_DEBUG_INFO,VM_STRING("QueryInterface FAILED"));
        else
        {
            pDD->Release();
            pDD = NULL;
        }
    }

    // Get normal mode.
    if (DD_OK == hRet)
    {
        hRet = m_pDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL);
        if (hRet != DD_OK)
            vm_debug_trace(VM_DEBUG_INFO,VM_STRING("SetCooperativeLevel FAILED"));
    }

    // Get a primary surface interface pointer (only needed for init.)
    if (DD_OK == hRet)
    {
        memset(&ddsd, 0, sizeof(ddsd));
        ddsd.dwSize = sizeof(ddsd);
        ddsd.dwFlags = DDSD_CAPS;
        ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
        hRet = m_pDD->CreateSurface(&ddsd, &m_pDDSPrimary, NULL);
        if (hRet != DD_OK)
            vm_debug_trace(VM_DEBUG_INFO,VM_STRING("CreateSurface FAILED"));
    }

    // See if we can support overlays.
    if (DD_OK == hRet)
    {
        memset(&ddcaps, 0, sizeof(ddcaps));
        ddcaps.dwSize = sizeof(ddcaps);
        hRet = m_pDD->GetCaps(&ddcaps,NULL);
        if (hRet != DD_OK)
            vm_debug_trace(VM_DEBUG_INFO,VM_STRING("GetCaps FAILED"));
    }

    if (DD_OK == hRet && !(ddcaps.dwCaps & DDCAPS_OVERLAY))
    {
        vm_debug_trace(VM_DEBUG_INFO,VM_STRING("Overlays are not supported in hardware!"));
        hRet = DDERR_INVALIDSURFACETYPE;
    }

    // Get alignment info to compute our overlay surface size.
    if (DD_OK == hRet)
    {
        m_SrcRect.left = Rect.left;
        m_SrcRect.top = Rect.top;
        m_SrcRect.right = Rect.right;
        m_SrcRect.bottom = Rect.bottom;
        if (ddcaps.dwCaps & DDCAPS_ALIGNSIZESRC && ddcaps.dwAlignSizeSrc)
            m_SrcRect.right += m_SrcRect.right % ddcaps.dwAlignSizeSrc;

        // Create the overlay flipping surface. We will attempt the pixel
        // formats in our table one at a time until we find one that jives.

        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 = m_SrcRect.right;
        ddsd.dwHeight = m_SrcRect.bottom;
        ddsd.dwBackBufferCount = 1;

#if defined(_WIN32_WCE) && (defined(x86) || defined(_X86_))
        ddsd.ddpfPixelFormat = ddpfOverlayFormats[0];
#else // ! defined(_WIN32_WCE) && (defined(x86) || defined(_X86_))
        ddsd.ddpfPixelFormat = ddpfOverlayFormats[4];
#endif // defined(_WIN32_WCE) && (defined(x86) || defined(_X86_))
        hRet = m_pDD->CreateSurface(&ddsd, &m_pDDSOverlay, NULL);

        if (hRet != DD_OK)
            vm_debug_trace(VM_DEBUG_INFO,VM_STRING("Unable to create overlay surface!"));
    }

    // Finish setting up the overlay.
    if (DD_OK == hRet)
    {
        Ipp32s StretchFactor1000 = ddcaps.dwMinOverlayStretch > 1000 ?
                                (ddcaps.dwMinOverlayStretch) : (1000);
        m_DstRect.left = 0;
        m_DstRect.top = 0;
        // Adding 999 takes care of integer truncation problems.
        m_DstRect.right  = (m_SrcRect.right * StretchFactor1000 + 999) / 1000;
        m_DstRect.bottom = m_SrcRect.bottom * StretchFactor1000 / 1000;
        if (ddcaps.dwCaps & DDCAPS_ALIGNSIZEDEST && ddcaps.dwAlignSizeDest)
        {
          m_DstRect.right = (Ipp32s)((m_DstRect.right +
                                   ddcaps.dwAlignSizeDest - 1) /
                            ddcaps.dwAlignSizeDest) * ddcaps.dwAlignSizeDest;
        }

        // Set the flags we'll send to UpdateOverlay
        Ipp32u 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
        DDOVERLAYFX ovfx;
        memset(&ovfx, 0, sizeof(ovfx));
        ovfx.dwSize = sizeof(ovfx);
        if (ddcaps.dwCKeyCaps & DDCKEYCAPS_SRCOVERLAY)
        {
            dwUpdateFlags |= DDOVER_KEYSRCOVERRIDE | DDOVER_DDFX;

            // Create an overlay FX structure so we can specify a source color
            // key. This information is ignored if the DDOVER_SRCKEYOVERRIDE
            // flag isn't set.

            // black as the color key
            ovfx.dckSrcColorkey.dwColorSpaceLowValue = 0;
            ovfx.dckSrcColorkey.dwColorSpaceHighValue = 0;
        }

        // Update the overlay parameters.

        hRet = m_pDDSOverlay->UpdateOverlay(&m_SrcRect,
                                            m_pDDSPrimary,
                                            &m_DstRect,
                                            dwUpdateFlags,
                                            &ovfx);
        if (hRet != DD_OK)
            vm_debug_trace(VM_DEBUG_INFO,VM_STRING("Unable to show overlay surface!"));
    }
    return hRet;

} // HRESULT DXWCEVideoRender::InitDDraw(HWND hWnd, UMC::RECT Rect)

Status DXWCEVideoRender::Init(MediaReceiverParams* pInit)
{
    Status umcRes = UMC_OK;
    DXWCEVideoRenderParams* pParams = DynamicCast<DXWCEVideoRenderParams>(pInit);

    if (NULL == pParams)
        umcRes = UMC_ERR_NULL_PTR;

    if (UMC_OK == umcRes)
        umcRes = MobileVideoRender::Init(pInit);

    if (UMC_OK == umcRes)
    {
        m_hWnd = pParams->m_hWnd;
        UMCRect2Rect(pParams->disp, m_DstRect);
        VM_ASSERT(NULL != m_hWnd);
        if (NULL == m_hWnd)
            umcRes = UMC_ERR_NULL_PTR;
    }

  if (UMC_OK == umcRes && !GetWindowRect( m_hWnd, &m_DstRect ))
      umcRes = UMC_ERR_FAILED;

    HBRUSH hBrush = NULL;
    if (UMC_OK == umcRes)
    {
        hBrush = CreateSolidBrush(0);
        if (NULL == hBrush)
            umcRes = UMC_ERR_FAILED;
    }

    if (UMC_OK == umcRes && 0 == FillRect(GetDC(m_hWnd),&m_DstRect, hBrush))
        umcRes = UMC_ERR_FAILED;

    if (UMC_OK == umcRes)
    {
        HRESULT hRet = InitDDraw(pParams->m_hWnd, pParams->disp);
        if (FAILED(hRet))
            umcRes = UMC_ERR_FAILED;
    }
    return umcRes;

} // Status DXWCEVideoRender::Init(MediaReceiverParams* pInit)

Status DXWCEVideoRender::Close()
{
    Status umcRes = MobileVideoRender::Close();

    if (NULL != m_pDDSOverlay)
    {
        // Use UpdateOverlay() with the DDOVER_HIDE flag to remove an overlay
        // from the display.
        m_pDDSOverlay->UpdateOverlay(NULL,
                                     m_pDDSPrimary,
                                     NULL,
                                     DDOVER_HIDE,
                                     NULL);
        m_pDDSOverlay->Release();
        m_pDDSOverlay = NULL;
    }

    if (NULL != m_pDDSPrimary)
    {
        m_pDDSPrimary->Release();
        m_pDDSPrimary = NULL;
    }

    if (NULL != m_pDD)
    {
        m_pDD->Release();
        m_pDD = NULL;
    }

    m_hWnd = 0;
    memset(&m_SrcRect, 0, sizeof(m_SrcRect));
    memset(&m_SrcRect, 0, sizeof(m_DstRect));

    return umcRes;

} // Status DXWCEVideoRender::Close()

// Lock input buffer
Status DXWCEVideoRender::LockInputBuffer(MediaData* pInData)
{
    Status umcRes = UMC_OK;
    DDSURFACEDESC2 ddsd;
    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);

    VideoData* pVideoData = DynamicCast<VideoData>(pInData);

    if (NULL == pVideoData)
        umcRes = UMC_ERR_NULL_PTR;

    if (UMC_OK == umcRes && NULL == m_pDDSOverlay)
        umcRes = UMC_ERR_NOT_INITIALIZED;

    //  Wait for the end od prev frame or Stop()
    while (UMC_OK == umcRes &&
           !m_bStopFlag &&
           m_dfFrameTime != -1.0 &&
           UMC_ERR_TIMEOUT == m_ReadySema.Wait(1000));

    if (UMC_OK == umcRes && (m_bStopFlag || m_dfFrameTime == -1.0))
        umcRes = UMC_ERR_END_OF_STREAM;

    if (UMC_OK == umcRes)
    {
        HRESULT hRes = m_pDDSOverlay->Lock(NULL,
                                           &ddsd,
                                           DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT,
                                           NULL);
        if (FAILED(hRes))
            umcRes = UMC_ERR_FAILED;
    }

    if (UMC_OK == umcRes)
    {
        Ipp32u uiSize = ddsd.dwWidth * ddsd.dwHeight;
        pVideoData->SetDest((LPBYTE)ddsd.lpSurface,
                            ((LPBYTE)ddsd.lpSurface) + uiSize,
                            ((LPBYTE)ddsd.lpSurface) + uiSize + uiSize / 4);

        if (NULL != ddsd.lpSurface)
            pVideoData->SetPitch(ddsd.lPitch, ddsd.lPitch / 2, ddsd.lPitch / 2);
        else
            pVideoData->SetPitch(0);
    }
    else
    {
        pVideoData->SetDest(NULL);
        pVideoData->SetPitch(0);
    }
    return umcRes;

} // Status DXWCEVideoRender::LockInputBuffer(MediaData* pInData)

// Unlock input buffer
Status DXWCEVideoRender::UnLockInputBuffer(MediaData *pInData,
                                           Status StreamStatus)
{
    Status umcRes = UMC_OK;
    VideoData* pVideoData = DynamicCast<VideoData, MediaData>(pInData);

    if (NULL == pVideoData)
        umcRes = UMC_ERR_NULL_PTR;

    if (UMC_OK == umcRes && NULL == m_pDDSOverlay)
        umcRes = UMC_ERR_NOT_INITIALIZED;

    if (UMC_OK == umcRes)
    {
        HRESULT hRes = m_pDDSOverlay->Unlock(NULL);
        if (FAILED(hRes))
            umcRes = UMC_ERR_FAILED;
    }

    if (UMC_OK == umcRes)
    {
        Ipp64f dfEndTime;
        pVideoData->GetTime(m_dfFrameTime, dfEndTime);
        umcRes = m_DoneSema.Signal();
    }

    if (UMC_ERR_END_OF_STREAM == StreamStatus)
        Stop();

    return umcRes;

} // Status DXWCEVideoRender::UnLockInputBuffer(MediaData *pInData,

Status DXWCEVideoRender::RenderFrame()
{
  Status umcRes = UMC_OK;

    if (NULL == m_pDDSPrimary && NULL == m_pDDSOverlay)
        umcRes = UMC_ERR_NOT_INITIALIZED;

    if (UMC_OK == umcRes)
    {
        Ipp32u dwShowCmd = m_bShow ? DDOVER_SHOW : DDOVER_HIDE;

        HRESULT hRes = m_pDDSOverlay->UpdateOverlay(&m_SrcRect, m_pDDSPrimary,
                                                    &m_DstRect, dwShowCmd, 0);
        if (FAILED(hRes))
            umcRes = UMC_ERR_FAILED;
    }

    if (UMC_OK == umcRes)
        umcRes = MobileVideoRender::RenderFrame();

    return umcRes;

} // Status DXWCEVideoRender::RenderFrame()

} // namespace UMC

#endif // defined(UMC_ENABLE_DXWCE_VIDEO_RENDER)

⌨️ 快捷键说明

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