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

📄 mp4encdrv.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
字号:
/*------------------------------------------------------------------------------
--                                                                            --
--       This software is confidential and proprietary and may be used        --
--        only as expressly authorized by a licensing agreement from          --
--                                                                            --
--                            Hantro Products Oy.                             --
--                                                                            --
--      In the event of publication, the following notice is applicable:      --
--                                                                            --
--                   (C) COPYRIGHT 2005 HANTRO PRODUCTS OY                    --
--                            ALL RIGHTS RESERVED                             --
--                                                                            --
--          The entire notice above must be reproduced on all copies.         --
--                                                                            --
--------------------------------------------------------------------------------
--
--  Project  : 1200s
--
--  Abstract : Stream Device Driver for the 5251_encoder in WinCE 5.0/MX31
--
-------------------------------------------------------------------------------*/


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

    Table of context

    1. Include headers
    2. Module defines
    3. Local static data
    4. Local function prototypes
    5. Functions

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


/*------------------------------------------------------------------------------
    1. Include headers
------------------------------------------------------------------------------*/

// WinCE and MX31 BSP
#include <windows.h>
#include <pkfuncs.h>
#include <ceddk.h>
#include <pm.h>
#include <csp.h>

// mp4enc
#include "enchw.h"


/*------------------------------------------------------------------------------
    2. Module defines
------------------------------------------------------------------------------*/

#define ENCDRV_ENCRUNNING_TIMEOUT_COUNT    100    // max number of sleeps
#define ENCDRV_ENCRUNNING_TIMEOUT_SLEEP     10    // length of sleep in ms
#define ENCDRV_ENCRUNNING_RECOVERY_TIME   1000    // sleep time after hw stuck
#define ENCDRV_ENCHW_TIMEOUT              1000    // timeout waiting for HW ready

#define ENCDRVDBG           1
#define ENCDRVDBG_EXTRA     0

/*------------------------------------------------------------------------------
    3. Local static data
------------------------------------------------------------------------------*/

static EncHw_t* g_EncHw = NULL;
static CEDEVICE_POWER_STATE g_PowerState = PwrDeviceUnspecified;

/*------------------------------------------------------------------------------
    4. Local function prototypes
------------------------------------------------------------------------------*/

static void DoPowerDown(void);
static void DoPowerUp(void);

/*------------------------------------------------------------------------------
    5. Functions
------------------------------------------------------------------------------*/

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

    DoPowerDown

    Power management is done responding to IOCTLs from Power Manager, and
    not in XXX_PowerDown/Up entry points called by device.exe. This way one
    may call higher level API functions, like as Sleep().

------------------------------------------------------------------------------*/
static void DoPowerDown(void)
{
    BOOL status;

    // Request access to encoder hw. If timed-out (stucked in control
    // code?), shutdown encoder anyway.
    status = ENCHW_LOCK( g_EncHw, ENCDRV_ENCHW_TIMEOUT );
    if( !status )
        DEBUGMSG( ENCDRVDBG, (_T("DoPowerDown(): EncHw timeout, shutting down without encoder-running check!\r\n")) );
    else
    {
        u32 timeout = ENCDRV_ENCRUNNING_TIMEOUT_COUNT;
        u32 reg10 = 0;

        #if ENCDRVDBG_EXTRA
        reg10 = EncHw_ReadReg( g_EncHw, 0x10 );
        #endif

        // Wait end of encoding to prevent frame lost. ~30ms in worst case (VGA
        // frame). In timeout (HW stucked), reset ASIC, sleep and suspend anyway.
        while( (EncHw_ReadReg(g_EncHw,0x10)&1<<1) && timeout-- )
        {
            Sleep( ENCDRV_ENCRUNNING_TIMEOUT_SLEEP );
        }

        if( EncHw_ReadReg(g_EncHw,0x10) & 1<<1 )
        {
            DEBUGMSG( ENCDRVDBG, (_T("DoPowerDown(): HW *not* ready!\r\n")) );
            EncHw_WriteReg( g_EncHw, 0x10, EncHw_ReadReg(g_EncHw,0x10) & (~0x01) );
            Sleep( ENCDRV_ENCRUNNING_RECOVERY_TIME );
        }

        DEBUGMSG( ENCDRVDBG_EXTRA, (_T("DoPowerDown(): reg10=%08X, time=%d\r\n"), reg10, timeout) );
    }

    // Shutdown encoder clock
    DDKClockSetGatingMode( DDK_CLOCK_GATE_INDEX_MPEG4, DDK_CLOCK_GATE_MODE_DISABLED );
}

/*------------------------------------------------------------------------------
    DoPowerUp
------------------------------------------------------------------------------*/
static void DoPowerUp(void)
{
    DEBUGMSG( ENCDRVDBG_EXTRA,(_T("IOCTL_PowerUp()\r\n")) );

    // Restore encoder clock
    DDKClockSetGatingMode( DDK_CLOCK_GATE_INDEX_MPEG4, DDK_CLOCK_GATE_MODE_ENABLED_ALL );

    ENCHW_UNLOCK( g_EncHw );
}

/*------------------------------------------------------------------------------
    MPE_Init
------------------------------------------------------------------------------*/
DWORD MPE_Init( LPCTSTR context )
{
    // Init encoder hw wrapper for register access
    g_EncHw = EncHw_Init();
    if( g_EncHw==NULL )
    {
        DEBUGMSG( ENCDRVDBG, (_T("MPE_Init: EncHw_Init() failed!\n")) );
        return 0;
    }

    // Init power state cache
    g_PowerState = D0;

    DEBUGMSG( ENCDRVDBG_EXTRA, (_T("MPE_Init(%s) Ok!\n"), context) );

    // Created EncHw is used as handle for device driver
    return (DWORD)g_EncHw;
}

/*------------------------------------------------------------------------------
    MPE_Deinit
------------------------------------------------------------------------------*/
BOOL MPE_Deinit( DWORD context )
{
    // Assert we are releasing the same, single MPE instance
    ASSERT( context == (DWORD)g_EncHw );

    // Release EncHW wrapper
    if( g_EncHw != NULL )
    {
        EncHw_Release( g_EncHw );
        g_EncHw = NULL;
    }

    // Reset power state cache
    g_PowerState = PwrDeviceUnspecified;

    DEBUGMSG( ENCDRVDBG_EXTRA, (_T("MPE_Deinit() Ok!\n")) );
    return TRUE;
}

/*------------------------------------------------------------------------------
    MPE_IOControl
------------------------------------------------------------------------------*/
BOOL MPE_IOControl( DWORD context, DWORD ioctl, PUCHAR inBuf, DWORD inBufLen,
                    PUCHAR outBuf, DWORD outBufLen, PDWORD bytesTransferred )
{
    ASSERT( context == (DWORD)g_EncHw );

    switch( ioctl )
    {
        case IOCTL_POWER_CAPABILITIES:
        {   
            POWER_CAPABILITIES* caps = (POWER_CAPABILITIES*) outBuf;
            memset( caps, 0, sizeof(POWER_CAPABILITIES) );

            // Only D0 and D4 states supported
            caps->DeviceDx = 0x11;

            *bytesTransferred = sizeof(POWER_CAPABILITIES);
            break;
        }

        case IOCTL_POWER_GET:
        {
            // Return cached power state
            *(PCEDEVICE_POWER_STATE) outBuf = g_PowerState;
            *bytesTransferred = sizeof(CEDEVICE_POWER_STATE);
            break;
        }

        case IOCTL_POWER_SET:
        {
            g_PowerState = *(PCEDEVICE_POWER_STATE) outBuf;
            *bytesTransferred = sizeof(CEDEVICE_POWER_STATE);

            // Handle PowerUp or PowerDown
            if( g_PowerState==D0 ) DoPowerUp();
            else if( g_PowerState==D4 ) DoPowerDown();
            else return FALSE;

            break;
        }

        // Fail for any other IOCTL
        case IOCTL_REGISTER_POWER_RELATIONSHIP:
        case IOCTL_POWER_QUERY:
        default:
            return FALSE;
    }

    return TRUE;
}

/*------------------------------------------------------------------------------
    MPE_PowerDown
------------------------------------------------------------------------------*/
void MPE_PowerDown( DWORD context )
{
    // Empty implementation, all power management handled by IOCTL
}

/*------------------------------------------------------------------------------
    MPE_PowerUp
------------------------------------------------------------------------------*/
void MPE_PowerUp( DWORD context )
{
    // Empty implementation, all power management handled by IOCTL
}

/*------------------------------------------------------------------------------
    MPE_Open
------------------------------------------------------------------------------*/
DWORD MPE_Open( DWORD context, DWORD access, DWORD mode )
{
    // Nothing to be done, just associate the returned file context with
    // the given device driver context
    return context;
}

/*------------------------------------------------------------------------------
    MPE_Close
------------------------------------------------------------------------------*/
BOOL MPE_Close( DWORD context ) 
{
    // Nothing to be done
    return TRUE;
}

/*------------------------------------------------------------------------------
    MPE_Read
------------------------------------------------------------------------------*/
DWORD MPE_Read( DWORD context, LPVOID buf, DWORD len )
{
    // Read not supported
    return 0;
}

/*------------------------------------------------------------------------------
    MPE_Write
------------------------------------------------------------------------------*/
DWORD MPE_Write( DWORD context, LPVOID buf, DWORD len ) 
{
    // Write not supported
    return 0;
}

/*------------------------------------------------------------------------------
    MPE_Seek
------------------------------------------------------------------------------*/
ULONG MPE_Seek( PVOID context, LONG position, DWORD type )
{
    // Seek not supported
    return (DWORD)-1;
}

⌨️ 快捷键说明

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