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

📄 agl_drv.c

📁 audio-video-codecs.rar语音编解码器
💻 C
📖 第 1 页 / 共 2 页
字号:
#define FUNCTION "umc_agl_SetVideoMode"
    vm_status       result  = VM_OK;
    AGLDrv*         drv     = (AGLDrv*)((NULL != driver)? driver->m_pDrv: NULL);
    VideoDrvRect    src_rect;
    Rect            title_rect;
    Ipp32s          w, h;

    DBG_SET("+");
    if ((NULL == drv) || (NULL == rect))
    {
        ERR_SET(VM_NULL_PTR, "null ptr");
    }
    vm_mutex_lock(&(drv->mtx_resize));  /* Preventing rendering. */
    if (VM_OK == result)
    {
        memcpy(&src_rect, rect, sizeof(VideoDrvRect));
        /* Sizes corrections:
         *  - width alignment at 8: needed for resizing using ippiResize().
         */
        src_rect.w &= ~7;
        /* Resizing window. */
        umc_agl_GetAvailableRect(&src_rect, &(drv->win_rect));
        w = drv->win_rect.right  - drv->win_rect.left;
        h = drv->win_rect.bottom - drv->win_rect.top;

        MoveWindow(drv->win, drv->win_rect.left, drv->win_rect.top, true);
        SizeWindow(drv->win, w, h, true);

        /* Resizing of the screen buffer. */
        if (NULL != drv->screen_buffer) ippsFree(drv->screen_buffer);
        if ((w == driver->img_width) && (h == driver->img_height))
            drv->screen_buffer = NULL;  /* Some optimization. */
        else
            drv->screen_buffer = ippsMalloc_8u(w*h*3);
        /* Changing AGL context.
         *
         * Remark: this is done because aglUpdateContext doesn't work properly.
         */
        if ((NULL != drv->agl_ctx) && (GL_TRUE != aglDestroyContext(drv->agl_ctx)))
        {
            WRN_SET(VM_OK, "aglDestroyContext");
        }
        if (VM_OK == result)
        {
            /* Creating an AGL context */
            drv->agl_ctx = aglCreateContext(drv->agl_fmt, NULL);
            if(AGL_NO_ERROR != aglGetError())
            {
                ERR_SET(VM_OPERATION_FAILED, "aglCreateContext");
            }
        }
    }
    vm_mutex_unlock(&(drv->mtx_resize));
    DBG_SET("-");
    return result;
}

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

/* void */
VIDEO_DRV_CLOSE_FUNC(umc_agl_Close, driver)
{
#undef  FUNCTION
#define FUNCTION "umc_agl_Close"
    vm_status   result  = VM_OK;
    AGLDrv*     drv     = (AGLDrv*)((NULL != driver)? driver->m_pDrv: NULL);

    DBG_SET("+");
    if (NULL == drv)
    {
        ERR_SET(VM_NULL_PTR, "null ptr");
    }
    if (VM_OK == result)
    {
        if (vm_mutex_is_valid(&(drv->mtx_resize)))
        {
            vm_mutex_unlock (&(drv->mtx_resize));
            vm_mutex_destroy(&(drv->mtx_resize));
        }
        /* Destroy AGL rendering context */
        aglDestroyContext(drv->agl_ctx);
        /* Free resources used by pixel format */
        aglDestroyPixelFormat(drv->agl_fmt);
        if (NULL != drv->screen_buffer)
        {
            ippsFree(drv->screen_buffer);
            drv->screen_buffer = NULL;
        }
        ippsFree(drv);
        driver->m_pDrv = NULL;
    }
    DBG_SET("-");
    return;
}

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

/* Name: umc_agl_SetWorkRegion.
 *
 * Purpose:
 *  Set clip (output) rectangle for rendering.
 *
 * Parameters:
 *  driver  - pointer to the driver specification;
 *  rect    - user specified rectangle in the window for output (can be NULL).
 */
vm_status umc_agl_SetWorkRegion(VideoDriver *driver, VideoDrvRect *rect)
{
#undef  FUNCTION
#define FUNCTION "umc_agl_SetWorkRegion"
    vm_status   result  = VM_OK;
    AGLDrv*     drv     = (AGLDrv*)((NULL != driver)? driver->m_pDrv: NULL);
    RgnHandle   workRgn = NewRgn(), userRgn = NewRgn();
    Rect        rectWork;

    DBG_SET("+");
    if (NULL == drv)
    {
        ERR_SET(VM_NULL_PTR, "null ptr");
    }
    if (VM_OK == result)
    {
        /* Attaching the context to the window and setting context current. */
        if (GL_TRUE != aglSetDrawable(drv->agl_ctx, GetWindowPort(drv->win)))
        {
            ERR_SET(VM_OK, "aglSetDrawable");
        }
    }
    if (VM_OK == result)
    {
        /* Setting work region. */
        if (noErr != GetWindowRegion(drv->win, kWindowContentRgn, workRgn))
        {
            ERR_SET(VM_OK, "GetWindowRegion");
        }
    }
    if (VM_OK == result)
    {
        /* Defining work region in window's local coordinates. */
        GetRegionBounds(workRgn, &rectWork);
        OffsetRgn(workRgn, -rectWork.left, -rectWork.top);
        if (NULL != rect)
        {
            /* Defining user specified region in window's local coordinates. */
            SetEmptyRgn(userRgn);
            OpenRgn();
            MoveTo(rect->x, rect->y);
            LineTo(rect->x + rect->w, rect->y);
            LineTo(rect->x + rect->w, rect->y + rect->h);
            LineTo(rect->x, rect->y+rect->h);
            CloseRgn(userRgn);
            /* Resetting work region as intersection of previous work and user's
             * regions.
             */
            SectRgn(workRgn, userRgn, workRgn);
        }
        aglSetInteger(drv->agl_ctx, AGL_CLIP_REGION, (const GLint*)workRgn);
        aglEnable(drv->agl_ctx, AGL_CLIP_REGION);
    }
    DisposeRgn(workRgn);
    DisposeRgn(userRgn);
    DBG_SET("-");
    return result;
}

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

/* vm_status */
VIDEO_DRV_RENDER_FRAME_FUNC (umc_agl_RenderFrame, driver, frame, rect)
{
#undef  FUNCTION
#define FUNCTION "umc_agl_RenderFrame"
    vm_status   result      = VM_OK;
    AGLDrv*     drv         = (AGLDrv*)((NULL != driver)? driver->m_pDrv: NULL);
    GLboolean   render_fl   = GL_TRUE;
    IppiSize    srcSize, dstSize;
    IppiRect    srcRect;
    Ipp32s      srcStep, dstStep;
    Ipp8u*      buffer      = NULL;

    DBG_SET("+");
    if (NULL == drv)
    {
        ERR_SET(VM_NULL_PTR, "null ptr");
    }
    vm_mutex_lock (&(drv->mtx_resize)); /* Preventing resize. */
    if (VM_OK == result)
    {
        if (VM_OK != umc_agl_SetWorkRegion(driver, rect))
        {
            render_fl = GL_FALSE;
            WRN_SET(VM_OK, "umc_agl_SetWorkRegion");
        }
        /* Setting the OpenGL current context. */
        if (GL_TRUE != aglSetCurrentContext(drv->agl_ctx))
        {
            render_fl = GL_FALSE;
            WRN_SET(VM_OK, "aglSetCurrentContext");
        }
        if (render_fl == GL_TRUE)
        {
            /* Setting destination image sizes. */
            dstSize.width   = drv->win_rect.right  - drv->win_rect.left;
            dstSize.height  = drv->win_rect.bottom - drv->win_rect.top;

            if (NULL != drv->screen_buffer)
            {
                buffer = drv->screen_buffer;
                /* Preparing for resize. */
                srcSize.width   = driver->img_width;
                srcSize.height  = driver->img_height;
                srcRect.x       = 0;
                srcRect.y       = 0;
                srcRect.width   = srcSize.width;
                srcRect.height  = srcSize.height;
                srcStep         = 3*(srcSize.width);
                dstStep         = 3*(dstSize.width);
                /* Resizing. */
                if (ippStsNoErr != ippiResize_8u_C3R(frame, srcSize, srcStep, srcRect,
                                                     drv->screen_buffer, dstStep, dstSize,
                                                     (Ipp64f)dstSize.width  / (Ipp64f)srcRect.width,
                                                     (Ipp64f)dstSize.height / (Ipp64f)srcRect.height,
                                                     UMC_AGL_INTER_TYPE))
                    ERR_SET(VM_OPERATION_FAILED, "ippiResize_8u_C3R");
            }
            else buffer = frame;
            /* Microsoft to Direct buffer conversion. */
            /* Horizontal and Vertical Flip. */
            glRasterPos2f(-1, 1);
            glPixelZoom(1, -1);

            glEnable(GL_ALPHA_TEST);
            glClearColor(1,1,1,0);
            glClear(GL_COLOR_BUFFER_BIT);

            glDrawPixels(dstSize.width,
                         dstSize.height,
                         GL_BGR,
                         GL_UNSIGNED_BYTE,
                         buffer);
            aglSwapBuffers(drv->agl_ctx);
        }
    }
    vm_mutex_unlock (&(drv->mtx_resize));
    DBG_SET("-");
    return result;
}

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

/* void* */
VIDEO_DRV_GET_WINDOW_FUNC(umc_agl_GetWindow, driver)
{
#undef  FUNCTION
#define FUNCTION "umc_agl_GetWindow"
    void*   win;
    AGLDrv* drv = (AGLDrv*)((NULL != driver)? driver->m_pDrv: NULL);

    DBG_SET("+");
    if (NULL == drv)
    {
        win = NULL;
        DBG_SET("null ptr");
    }
    else
    {
        win = drv->win;
    }
    DBG_SET("-");
    return win;
}

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

/* vm_status */
VIDEO_DRV_RUN_EVENT_LOOP_FUNC(umc_agl_RunEventLoop, driver)
{
#undef  FUNCTION
#define FUNCTION "umc_agl_RunEventLoop"
    vm_status       result  = VM_OK;
    AGLDrv*         drv     = (AGLDrv*)((NULL != driver)? driver->m_pDrv: NULL);
    EventRef        theEvent;
    EventTargetRef  theTarget;
    OSStatus        theErr;

    DBG_SET("+");
    if (NULL == drv)
    {
        ERR_SET(VM_NULL_PTR, "null ptr");
    }
    pthread_mutex_lock(&umc_agl_mutex);
    if (VM_OK == result)
    {
        do
        {
            /* Getting all events from queue. */
            theTarget   = GetEventDispatcherTarget();
            theErr      = ReceiveNextEvent(0, NULL, kEventDurationNoWait, true, &theEvent);
            if ((noErr == theErr) && (NULL != theEvent))
            {
                SendEventToEventTarget(theEvent, theTarget);
                ReleaseEvent(theEvent);
            }
            else break;
        } while (1);
    }
    pthread_mutex_unlock(&umc_agl_mutex);
    DBG_SET("-");
    return result;
}

#endif /* defined(UMC_ENABLE_AGL_VIDEO_RENDER) */

⌨️ 快捷键说明

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