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

📄 agl_drv.c

📁 audio-video-codecs.rar语音编解码器
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *
 *               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) 2001-2006 Intel Corporation. All Rights Reserved.
 *
 */

#include <umc_defs.h>

#ifdef UMC_ENABLE_AGL_VIDEO_RENDER

#include "agl_drv.h"
#include <pthread.h>
#include <stdio.h>
#include <ippi.h>
#include <ipps.h>
#include <Carbon/Carbon.h>

/* -------------------------------------------------------------------------- */

#define MODULE              "AGL(video driver)"
#define FUNCTION            "<Undefined Function>"
#define ERR_STRING(msg)     VIDEO_DRV_ERR_STRING(MODULE, FUNCTION, msg)
#define ERR_SET(err, msg)   VIDEO_DRV_ERR_SET   (MODULE, err, FUNCTION, msg)
#define WRN_SET(err, msg)   VIDEO_DRV_WRN_SET   (MODULE, err, FUNCTION, msg)
#define DBG_SET(msg)        VIDEO_DRV_DBG_SET   (MODULE, FUNCTION, msg)

/* -------------------------------------------------------------------------- */

/* Name: INTERPOLATION_TYPE.
 *
 * Purpose:
 *  Define interpolation type for frames resizing (used ippiResize).
 */
#define UMC_AGL_INTER_TYPE  IPPI_INTER_NN

/* -------------------------------------------------------------------------- */

const VideoDrvSpec AGLVideoDrvSpec =
{
    VM_STRING(MODULE),
    VideoDrvFalse,
    VideoDrvVideoMemInternal | VideoDrvVideoMemExternal,
    umc_agl_Init,
    umc_agl_Close,
    umc_vdrv_CreateBuffers,
    umc_vdrv_FreeBuffers,
    NULL,
    NULL,
    NULL,
    NULL,
    umc_agl_RenderFrame,
    umc_agl_SetVideoMode,
    umc_agl_GetWindow,
    umc_agl_RunEventLoop
};

/* -------------------------------------------------------------------------- */

/* Name: umc_agl_mutex.
 *
 * Purpose:
 *  1. This global variable is used to permit multythreading calls of
 *  umc_agl_Init function. Without this mutex applications failed on calling
 *  Carbon function CreateNewWindow. For other information see bugzilla,
 *  bug #3720.
 *  2. This global variable is used to permit multythreading calls of
 *  umc_agl_RunEventLoop.
 */

static pthread_mutex_t umc_agl_mutex = PTHREAD_MUTEX_INITIALIZER;

/* -------------------------------------------------------------------------- */

/* Name: umc_agl_GetAvailableRect.
 *
 * Purpose:
 *  Modifies <src_rect> if it can't be displayed on the screen.
 *
 * Parameters:
 *  src_rect    - source rectangle;
 *  dst_rect    - destination rectangle.
 */

vm_status umc_agl_GetAvailableRect(const VideoDrvRect* src_rect, Rect* dst_rect)
{
#undef  FUNCTION
#define FUNCTION "umc_agl_GetAvailableRect"
    vm_status       result      = VM_OK;
    Rect            disp_rect;

    DBG_SET("+");
    if (VM_OK == result)
    {
        if ((NULL == src_rect) || (NULL == dst_rect))
        {
            ERR_SET(VM_NULL_PTR, "null ptr");
        }
    }
    if (VM_OK == result)
    {
        /* Getting available rectangle from the current graphics device. */
        if (noErr != GetAvailableWindowPositioningBounds(GetGDevice(), &disp_rect))
            ERR_SET(VM_OPERATION_FAILED, "GetAvailableWindowPositioningBounds");
    }
    if (VM_OK == result)
    {
        dst_rect->left   = src_rect->x;
        dst_rect->top    = src_rect->y;
        dst_rect->right  = dst_rect->left + src_rect->w;
        dst_rect->bottom = dst_rect->top + src_rect->h;
        /* Modifying of the source rectangle (if needed). */
        if (dst_rect->left < disp_rect.left) dst_rect->left = disp_rect.left;
        /* 2 - for window title region. */
        if (dst_rect->top < 2*disp_rect.top) dst_rect->top = 2*disp_rect.top;
        if (dst_rect->right > disp_rect.right) dst_rect->right = disp_rect.right;
        if (dst_rect->bottom > disp_rect.bottom) dst_rect->bottom = disp_rect.bottom;
    }
    DBG_SET("-");
}

/* -------------------------------------------------------------------------- */

/* Name: umc_agl_WindowEventHandler.
 *
 * Purpose:
 *  Handle windows events.
 *
 * Parameters:
 *  See MacOS help references for list and description of parameters for this
 * function.
 */
OSStatus umc_agl_WindowEventHandler(EventHandlerCallRef inCallRef,
                                    EventRef inEvent,
                                    void *inUserData)
{
#undef  FUNCTION
#define FUNCTION "umc_agl_WindowEventHandler"
    OSStatus     result         = noErr;
    VideoDriver* driver         = (VideoDriver*)inUserData;
    UInt32       eventKind      = GetEventKind(inEvent);
    VideoDrvRect rect;
    Rect         bounds_rect;

    DBG_SET("+");
    switch (eventKind)
    {
    case kEventWindowBoundsChanged:
        result = GetEventParameter(inEvent,
                                   kEventParamCurrentBounds, typeQDRectangle,
                                   NULL, sizeof(Rect), NULL, &bounds_rect);
        if (noErr == result)
        {
            rect.x = bounds_rect.left;
            rect.w = bounds_rect.right  - bounds_rect.left;
            rect.y = bounds_rect.top;
            rect.h = bounds_rect.bottom - bounds_rect.top;
            umc_agl_SetVideoMode(driver, &rect, VideoDrvOrdinary);
        }
        break;
    default:
        CallNextEventHandler(inCallRef, inEvent);   /* Standard handler call. */
        break;
    }
    DBG_SET("-");
    return result;
}

/* -------------------------------------------------------------------------- */

/* vm_status */
VIDEO_DRV_INIT_FUNC (umc_agl_Init, driver, params)
{
#undef  FUNCTION
#define FUNCTION "umc_agl_Init"
    vm_status           result          = VM_OK;
    AGLDrv*             drv             = (AGLDrv*)ippsMalloc_8u(sizeof(AGLDrv));
    AGLVideoDrvParams*  pParams         = (AGLVideoDrvParams*) params;
    WindowAttributes    windowAttr;
    VideoDrvRect        obtainedRect;
    EventTypeSpec       windowEvents[]  =
    {
        {kEventClassWindow, kEventWindowBoundsChanged}
    };
    ProcessSerialNumber frProcess, curProcess;
    Boolean             sameProcess;

    DBG_SET("+");
    pthread_mutex_lock(&umc_agl_mutex);
    if (VM_OK == result)
    {
        if (drv == NULL)
        {
            ERR_SET(VM_OPERATION_FAILED, "memory allocation");
        }
    }
    if (VM_OK == result)
    {
        if ((NULL == driver) || (NULL == pParams))
        {
            ERR_SET(VM_NULL_PTR, "null ptr");
        }
    }
    if (VM_OK == result)
    {
        driver->m_pDrv      = drv;
        driver->img_width   = pParams->common.img_width;
        driver->img_height  = pParams->common.img_height;
        driver->m_VideoMemType  = VideoDrvVideoMemInternal;
        ippsZero_8u((Ipp8u*)&(driver->m_VideoMemInfo), sizeof(VideoDrvVideoMemInfo));
        ippsCopy_8u((const Ipp8u*)&AGLVideoDrvSpec, (Ipp8u*)&(driver->m_DrvSpec), sizeof(VideoDrvSpec));
        drv->screen_buffer  = NULL;
        drv->agl_ctx        = NULL;
        drv->win            = NULL;
        umc_agl_GetAvailableRect(&(pParams->common.win_rect),&(drv->win_rect));
    }
    if (VM_OK == result)
    {
        vm_mutex_set_invalid(&(drv->mtx_resize));
        result = vm_mutex_init(&(drv->mtx_resize));
    }
    if (VM_OK == result)
    {
        windowAttr = kWindowStandardDocumentAttributes  |
                     kWindowStandardHandlerAttribute    |
                     kWindowLiveResizeAttribute         |
                     kWindowCompositingAttribute;
        /* Creating a window. */
        if (noErr != CreateNewWindow(kDocumentWindowClass,
                                     windowAttr,
                                     &(drv->win_rect),
                                     &(drv->win)))
        {
            ERR_SET(VM_OPERATION_FAILED, "CreateNewWindow");
        }
    }
    if (VM_OK == result)
    {
        /* Trying to install standard window event handler. */
        if (noErr != InstallStandardEventHandler(GetWindowEventTarget(drv->win)))
        {
            WRN_SET(VM_OK, "InstallStandardEventHandler");
        }

        /* Trying to install window event handler. */
        if (noErr != InstallWindowEventHandler(drv->win,
                                               NewEventHandlerUPP(umc_agl_WindowEventHandler),
                                               GetEventTypeCount(windowEvents),
                                               windowEvents,
                                               driver,
                                               &(drv->win_handler)))
        {
            WRN_SET(VM_OK, "InstallWindowEventHandler");
        }
    }
    if (VM_OK == result)
    {
        ShowWindow(drv->win);
    }
    if (VM_OK == result)
    {
        /* Choosing pixel format */
        GLint attrib[] = {AGL_RGBA, AGL_DOUBLEBUFFER, AGL_NONE};
        drv->agl_fmt = aglChoosePixelFormat(NULL, 0, attrib);
        if (AGL_NO_ERROR != aglGetError())
        {
            ERR_SET(VM_OPERATION_FAILED, "aglChoosePixelFormat");
        }
        drv->agl_ctx = NULL;
    }
    if (result == VM_OK)
    {
        obtainedRect.x  = drv->win_rect.left;
        obtainedRect.y  = drv->win_rect.top;
        obtainedRect.w  = drv->win_rect.right  - drv->win_rect.left;
        obtainedRect.h  = drv->win_rect.bottom - drv->win_rect.top;
        result = umc_agl_SetVideoMode(driver, &obtainedRect, VideoDrvOrdinary);
    }
    if (VM_OK == result)
    {
        /* Driver was initialized successfully. Transforming application to
         * foreground one.
         */
        if ((noErr == GetFrontProcess(&frProcess)) &&
            (noErr == GetCurrentProcess(&curProcess)))
        {
            if ((noErr == SameProcess(&frProcess, &curProcess, &sameProcess)) &&
                (false == sameProcess))
            {
                TransformProcessType(&curProcess,
                                     kProcessTransformToForegroundApplication);
            }
            SetFrontProcessWithOptions(&curProcess,kSetFrontProcessFrontWindowOnly);
        }
    }
    else
    {
        /* Driver initialization failed. Releasing memory. */
        if (drv != NULL) { ippsFree(drv); driver->m_pDrv = NULL; }
    }
    pthread_mutex_unlock(&umc_agl_mutex);
    DBG_SET("-");
    return result;
}

/* -------------------------------------------------------------------------- */

/* vm_status */
VIDEO_DRV_SET_VIDEO_MODE_FUNC(umc_agl_SetVideoMode, driver, rect, mode)
{
#undef  FUNCTION

⌨️ 快捷键说明

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