📄 mp4encdrv.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 + -