Windows2003-3790/enduser/netmeeting/av/codecs/dec/dech263/dispatch.c
2020-09-30 16:53:55 +02:00

671 lines
19 KiB
C

/*
* @DEC_COPYRIGHT@
*/
/*
* HISTORY
* $Log: h263_dispatch.c,v $
* $EndLog$
*/
/*
**++
** FACILITY: Workstation Multimedia (WMM) v1.0
**
** FILE NAME: h263_dispatch.c
** MODULE NAME: h263_dispatch.c
**
** MODULE DESCRIPTION:
** H.263 ICM driver message dispatch routine.
**
** Functions
**
** DriverProc (Entry point into codec)
** ICH263Message (ICM message handler. Calls routines in h263.c)
** ICH263ClientThread (Thread for processing most messages)
** ICH263ProcessThread (Thread for processing compress/decompress)
**
** Private functions:
**
** DESIGN OVERVIEW:
** Accept the DriverProc message and dispatch to the proper
** handler.
**
**--
*/
#include <stdio.h>
#include <windows.h>
#include "h26x_int.h"
#ifdef _SLIBDEBUG_
#define _DEBUG_ 0 /* detailed debuging statements */
#define _VERBOSE_ 1 /* show progress */
#define _VERIFY_ 1 /* verify correct operation */
#define _WARN_ 1 /* warnings about strange behavior */
#endif
static CRITICAL_SECTION h263CritSect; /* Critical section for multi-thread protection */
static HMODULE ghModule=NULL; /* Global handle to Module */
#define BOGUS_DRIVER_ID -1 /* Used during open on NT */
#ifdef WIN32
#define CHECKANDLOCK(x) if (((void *)lParam1==NULL) || (int)lParam2<sizeof(x)) \
return ((unsigned int)ICERR_BADPARAM);
#define UNLOCK
#else
#define CHECKANDLOCK(x) { \
int size = lParam2; \
if (noChecklParam2 && size < sizeof(x)) \
size = sizeof(x); \
if (((void *)lParam1 == NULL) || size < sizeof(x)) \
return ((unsigned int)ICERR_BADPARAM); \
}
#define UNLOCK
#endif
/***************************************************************************
***************************************************************************/
MMRESULT CALLBACK ICH263Message(DWORD_PTR driverHandle,
UINT uiMessage,
LPARAM lParam1,
LPARAM lParam2,
H26XINFO *info)
{
ICINFO *icinfo;
LPBITMAPINFOHEADER lpbiIn;
LPBITMAPINFOHEADER lpbiOut;
ICDECOMPRESS *icDecompress;
DWORD biSizeIn;
DWORD biSizeOut;
MMRESULT ret;
_SlibDebug(_DEBUG_,
ScDebugPrintf("ICH263Message(DriverID=%p, message=%d, lParam1=%p,lParam1=%p, info=%p)\n",
driverHandle, uiMessage, lParam1, lParam2, info) );
switch (uiMessage)
{
/*********************************************************************
ICM messages
*********************************************************************/
case ICM_CONFIGURE:
/*
* return ICERR_OK if you will do a configure box, error otherwise
*/
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_CONFIGURE:\n") );
if (lParam1 == -1)
return ICH263QueryConfigure(info) ? ICERR_OK :
ICERR_UNSUPPORTED;
else
return ICH263Configure(info);
case ICM_ABOUT:
/*
* return ICERR_OK if you will do a about box, error otherwise
*/
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_ABOUT::\n") );
if (lParam1 == -1)
return ICH263QueryAbout(info) ? ICERR_OK :
ICERR_UNSUPPORTED;
else
return ICH263About(info);
case ICM_GETSTATE:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_GETSTATE::\n") );
if ((LPVOID)lParam1!=NULL) /* getting state size */
{
char *stateinfo=(char *)lParam1; /* for debugging break point */
memset(stateinfo, 0, 0x60);
}
return (0x60);
case ICM_SETSTATE:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_SETSTATE::\n") );
if ((LPVOID)lParam1!=NULL) /* getting state size */
{
char *stateinfo=(char *)lParam1; /* for debugging break point */
int i=0;
i=i+1;
}
if (info->dwRTP==EC_RTP_MODE_OFF) /* must be NetMeeting, turn on RTP */
info->dwRTP=EC_RTP_MODE_A;
return (0x60);
case ICM_GETINFO:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_GETINFO::\n") );
icinfo = (ICINFO FAR *)lParam1;
if (icinfo == NULL)
return sizeof(ICINFO);
if ((DWORD)lParam2 < sizeof(ICINFO))
return 0;
ret = ICH263GetInfo(info, icinfo, (DWORD)lParam2);
UNLOCK;
return ret;
case ICM_GETDEFAULTQUALITY:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_GETDEFAULTQUALITY::\n") );
CHECKANDLOCK(DWORD);
ret = ICH263GetDefaultQuality(info, (DWORD *)lParam1);
UNLOCK;
return ret;
case ICM_GETQUALITY:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_GETQUALITY::\n") );
CHECKANDLOCK(DWORD);
ret = ICH263GetQuality(info, (DWORD *)lParam1);
UNLOCK;
return ret;
case ICM_SETQUALITY:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_SETQUALITY::\n") );
CHECKANDLOCK(DWORD);
ret = ICH263SetQuality(info, (DWORD)lParam1);
UNLOCK;
return ret;
case ICM_GETDEFAULTKEYFRAMERATE:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_GETDEFAULTKEYFRAMERATE:::\n") );
return ((unsigned int)ICERR_UNSUPPORTED);
case DECH26X_CUSTOM_ENCODER_CONTROL:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------DECH26X_CUSTOM_ENCODER_CONTROL:::\n") );
return(ICH263CustomEncoder(info, (DWORD)lParam2, (WORD)lParam2));
/*********************************************************************
compression messages
*********************************************************************/
case ICM_COMPRESS_QUERY:
_SlibDebug(_DEBUG_, ScDebugPrintf("------ICM_COMPRESS_QUERY::\n") );
if ((lpbiIn = (LPBITMAPINFOHEADER)lParam1) == NULL)
return ((unsigned int)ICERR_BADPARAM);
lpbiOut = (LPBITMAPINFOHEADER)lParam2;
_SlibDebug(_DEBUG_, ScDebugPrintf(" lpbiIn: %s\n", BMHtoString(lpbiIn)) );
_SlibDebug(_DEBUG_, ScDebugPrintf(" lpbiOut: %s\n", BMHtoString(lpbiOut)) );
/* Lock the memory - have to lock the structure first, and iff
* that works, lock the rest
*/
biSizeIn = lpbiIn->biSize;
if (lpbiOut)
biSizeOut = lpbiOut->biSize;
if ((biSizeIn != sizeof(BITMAPINFOHEADER))
|| (lpbiOut && biSizeOut != sizeof(BITMAPINFOHEADER))) {
UNLOCK;
if ((biSizeIn < sizeof(BITMAPINFOHEADER))
|| (lpbiOut && (biSizeOut < sizeof(BITMAPINFOHEADER))))
return ((unsigned int)ICERR_BADPARAM);
}
ret = ICH263CompressQuery(info, lpbiIn, lpbiOut);
UNLOCK;
return ret;
case ICM_COMPRESS_BEGIN:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_COMPRESS_BEGIN::\n") );
lpbiIn = (LPBITMAPINFOHEADER)lParam1;
lpbiOut = (LPBITMAPINFOHEADER)lParam2;
_SlibDebug(_VERBOSE_, ScDebugPrintf(" lpbiIn: %s\n", BMHtoString(lpbiIn)) );
_SlibDebug(_VERBOSE_, ScDebugPrintf(" lpbiOut: %s\n", BMHtoString(lpbiOut)) );
if (lpbiIn == NULL || lpbiOut == NULL)
return ((unsigned int)ICERR_BADPARAM);
/* Lock the memory - have to lock the structure first, and iff
* that works, lock the rest
*/
biSizeIn = lpbiIn->biSize;
biSizeOut = lpbiOut->biSize;
if (biSizeIn != sizeof(BITMAPINFOHEADER) ||
biSizeOut != sizeof(BITMAPINFOHEADER))
{
_SlibDebug(_VERBOSE_,
ScDebugPrintf("biSizeIn or biSizeOut > sizeof(BITMAPINFOHEADER)\n") );
UNLOCK;
if ((biSizeIn < sizeof(BITMAPINFOHEADER))
|| (biSizeOut < sizeof(BITMAPINFOHEADER)))
return ((unsigned int)ICERR_BADPARAM);
}
ret = ICH263CompressBegin(info, lpbiIn, lpbiOut);
UNLOCK;
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_COMPRESS_BEGIN:: Done\n") );
return ret;
case ICM_COMPRESS_GET_FORMAT:
_SlibDebug(_DEBUG_, ScDebugPrintf("------ICM_COMPRESS_GET_FORMAT::\n") );
/* Nobody uses lpbiIn in this function. Don't lock anything,
* the lower layers will have to do any necessary locking.
*/
return ICH263CompressGetFormat(info,
(LPBITMAPINFOHEADER)lParam1,
(LPBITMAPINFOHEADER)lParam2);
case ICM_COMPRESS_GET_SIZE:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_COMPRESS_GET_SIZE::\n") );
lpbiIn = (LPBITMAPINFOHEADER)lParam1;
lpbiOut = (LPBITMAPINFOHEADER)lParam2;
return(ICH263CompressGetSize(lpbiIn));
case ICM_COMPRESS:
_SlibDebug(_DEBUG_, ScDebugPrintf("------ICM_COMPRESS::\n") );
ret = ICH263Compress(info, (ICCOMPRESS *) lParam1, (DWORD)lParam2);
return ret;
case ICM_COMPRESS_END:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_COMPRESS_END::\n") );
return ICH263CompressEnd(info);
/*********************************************************************
decompress messages
*********************************************************************/
case ICM_DECOMPRESS_GET_FORMAT:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_DECOMPRESS_GET_FORMAT::\n") );
/* Nobody uses lpbiIn in this function. Don't lock anything,
* the lower layers will have to do any necessary locking.
*/
return ICH263DecompressGetFormat(info,
(LPBITMAPINFOHEADER)lParam1,
(LPBITMAPINFOHEADER)lParam2);
case ICM_DECOMPRESS_GET_PALETTE:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_DECOMPRESS_GET_PALETTE::\n") );
if ((lpbiIn = (LPBITMAPINFOHEADER)lParam1) == NULL)
return ((unsigned int)ICERR_BADPARAM);
if ((biSizeIn = lpbiIn->biSize) != sizeof(BITMAPINFOHEADER)) {
UNLOCK;
if (biSizeIn < sizeof(BITMAPINFOHEADER))
return (unsigned int)ICERR_BADPARAM;
}
/*ret = ICH263DecompressGetPalette(info,
(LPBITMAPINFOHEADER)lParam1,
(LPBITMAPINFOHEADER)lParam2);
*/
ret = (MMRESULT)ICERR_BADPARAM;
UNLOCK;
return ret;
case ICM_DECOMPRESS_SET_PALETTE:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_DECOMPRESS_SET_PALETTE::\n") );
return ((unsigned int)ICERR_UNSUPPORTED);
case ICM_DECOMPRESS_QUERY:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_DECOMPRESS_QUERY::\n") );
if ((lpbiIn = (LPBITMAPINFOHEADER)lParam1) == NULL)
return ((unsigned int)ICERR_BADPARAM);
lpbiOut = (LPBITMAPINFOHEADER)lParam2;
_SlibDebug(_VERBOSE_, ScDebugPrintf(" lpbiIn: %s\n", BMHtoString(lpbiIn)) );
_SlibDebug(_VERBOSE_, ScDebugPrintf(" lpbiOut: %s\n", BMHtoString(lpbiOut)) );
/* Lock the memory - have to lock the structure first, and iff
* that works, lock the rest
*/
biSizeIn = lpbiIn->biSize;
if (lpbiOut)
biSizeOut = lpbiOut->biSize;
if ((biSizeIn != sizeof(BITMAPINFOHEADER))
|| (lpbiOut && biSizeOut != sizeof(BITMAPINFOHEADER))) {
UNLOCK;
if ((biSizeIn < sizeof(BITMAPINFOHEADER))
|| (lpbiOut && (biSizeOut < sizeof(BITMAPINFOHEADER))))
return (unsigned int)ICERR_BADPARAM;
}
ret = ICH263DecompressQuery(info, lpbiIn, lpbiOut);
UNLOCK;
return ret;
case ICM_DECOMPRESS_BEGIN:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_DECOMPRESS_BEGIN::\n") );
if (((lpbiIn = (LPBITMAPINFOHEADER)lParam1) == NULL)
|| ((lpbiOut = (LPBITMAPINFOHEADER)lParam2) == NULL))
return ((unsigned int)ICERR_BADPARAM);
/* Lock the memory - have to lock the structure first, and iff
* that works, lock the rest
*/
biSizeIn = lpbiIn->biSize;
biSizeOut = lpbiOut->biSize;
if ((biSizeIn != sizeof(BITMAPINFOHEADER))
|| (biSizeOut != sizeof(BITMAPINFOHEADER))) {
UNLOCK;
if ((biSizeIn < sizeof(BITMAPINFOHEADER))
|| (biSizeOut < sizeof(BITMAPINFOHEADER)))
return ((unsigned int)ICERR_BADPARAM);
}
ret = ICH263DecompressBegin(info, lpbiIn, lpbiOut);
UNLOCK;
return ret;
case ICM_DECOMPRESS:
_SlibDebug(_DEBUG_, ScDebugPrintf("------ICM_DECOMPRESS::\n") );
icDecompress = (ICDECOMPRESS *)(void *)lParam1;
if ((void *)lParam1==NULL && (void *)lParam2==NULL)
return (unsigned int)ICERR_BADPARAM;
ret = ICH263Decompress(info, (ICDECOMPRESS *) lParam1, (DWORD)lParam2);
return ret;
case ICM_DECOMPRESS_END:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_DECOMPRESS_END::\n") );
ret = ICH263DecompressEnd(info);
return ret;
case ICM_COMPRESS_FRAMES_INFO:
_SlibDebug(_VERBOSE_, ScDebugPrintf("------ICM_COMPRESS_FRAMES_INFO\n") );
if ((LPVOID)lParam1==NULL ||
lParam2<sizeof(ICCOMPRESSFRAMES))
return (unsigned int)ICERR_BADPARAM;
{
ICCOMPRESSFRAMES *cf=(ICCOMPRESSFRAMES*)lParam1;
_SlibDebug(_VERBOSE_,
ScDebugPrintf("Start=%ld, Count=%ld, Quality=%ld, DataRate=%ld (%5.1f Kb/s), KeyRate=%ld, FPS=%4.1f\n",
cf->lStartFrame,cf->lFrameCount,cf->lQuality,
cf->lDataRate, cf->lDataRate*8.0/1000, cf->lKeyRate, cf->dwRate*1.0/cf->dwScale) );
/* info->dwBitrate=cf->lDataRate*8; */
info->dwQuality=cf->lQuality;
/* info->fFrameRate=(float)(cf->dwRate*1.0/cf->dwScale); */
}
return (unsigned int)ICERR_OK;
}
_SlibDebug(_VERBOSE_,
ScDebugPrintf("ICH263Message(DriverID=%p, message=%d, lParam1=%p,lParam1=%p, info=%p) Unsupported\n",
driverHandle, uiMessage, lParam1, lParam2, info) );
return ((unsigned int)ICERR_UNSUPPORTED);
}
/*
**++
** FUNCTIONAL_NAME: DriverProc
**
** FUNCTIONAL_DESCRIPTION:
** main and only entry point for the server into this driver
**
** FORMAL PARAMETERS:
** client pointer
** driverHandle, returned by us on a DRV_OPEN message
** driverID allocated and passed by the server
** message to handle
** parameters
**
** RETURN VALUE:
**
** COMMENTS:
**
** DESIGN:
**
**/
#define DLLEXPORT
MMRESULT DLLEXPORT APIENTRY
DriverProc(
DWORD_PTR dwDriverID,
HDRVR hDriver,
UINT message,
LPARAM lParam1,
LPARAM lParam2
)
{
MMRESULT ret = DRV_OK;
BOOL notfound = FALSE;
H26XINFO *info = NULL;
void *client = 0; /* Dummy client pointer for other calls. */
/*
* On NT, use __try {} __except() {} to catch
* error conditions.
*/
#ifdef HANDLE_EXCEPTIONS
__try { /* try..except */
__try { /* try..finally */
#endif
/*
* Protect threads from interfering with each other.
* To protect against a crash at shutdown, make sure
* that the critical section has not been deleted.
*/
if( h263CritSect.DebugInfo )
EnterCriticalSection( &h263CritSect ) ;
_SlibDebug(_DEBUG_,
ScDebugPrintf("DriverProc(DriverID=%p,hDriver=%p,message=%d,lParam1=%p,lParam2=%p)\n",
dwDriverID, hDriver, message, lParam1, lParam2) );
switch (message) {
case DRV_LOAD:
ret = DRV_OK;
_SlibDebug(_VERBOSE_, ScDebugPrintf("------DRV_LOAD returns %d\n", ret) );
break;
case DRV_ENABLE:
ret = 0;
_SlibDebug(_VERBOSE_, ScDebugPrintf("------DRV_ENABLE returns %d\n", ret) );
break;
case DRV_DISABLE:
ret = DRV_OK;
_SlibDebug(_VERBOSE_, ScDebugPrintf("------DRV_DISABLE returns %d\n", ret) );
break;
case DRV_FREE:
ret = DRV_OK;
_SlibDebug(_VERBOSE_, ScDebugPrintf("------DRV_FREE returns %d\n", ret) );
break;
case DRV_OPEN:
/* If lParam2 is NULL, then the app is trying to do a CONFIGURE.
* Return BOGUS_DRIVER_ID, since we don't support CONFIGURE.
*/
if( lParam2 == (LONG_PTR) NULL )
ret = (MMRESULT)BOGUS_DRIVER_ID;
else /* lParam2 is an ICOPEN structure, let's really open */
ret = (MMRESULT)((ULONG_PTR)ICH263Open((void *) lParam2));
_SlibDebug(_VERBOSE_, ScDebugPrintf("------DRV_OPEN returns %d\n", ret) );
break;
case DRV_CLOSE:
_SlibDebug(_VERBOSE_,
ScDebugPrintf("------DRV_CLOSE. client %d DriverID %p\n",
client, dwDriverID) );
ret = 0 ;
if ((INT_PTR)dwDriverID != BOGUS_DRIVER_ID)
{
info = IChic2info((HIC)dwDriverID);
if (info)
ICH263Close(info, FALSE);
else
ret = ((unsigned int)ICERR_BADHANDLE);
}
break;
case DRV_QUERYCONFIGURE:
/*
* this is a GLOBAL query configure
*/
ret = ICH263QueryConfigure(info);
break;
case DRV_CONFIGURE:
/*
* this is a GLOBAL configure ('cause we don't get a configure
* for each of our procs, we must have just one configure)
*/
ret = ICH263Configure(info);
break;
case DRV_INSTALL:
case DRV_REMOVE:
case DRV_EXITSESSION:
break;
default:
info = IChic2info((HIC)dwDriverID);
if (info)
ret = ICH263Message(dwDriverID,
message,
lParam1,
lParam2,
info ) ;
else
ret = ((unsigned int)ICERR_BADHANDLE) ;
}
#ifdef HANDLE_EXCEPTIONS
} __finally {
#endif /* HANDLE_EXCEPTIONS */
/*
* Leave the critical section, so we don't
* deadlock.
*/
if( h263CritSect.DebugInfo )
LeaveCriticalSection( &h263CritSect );
#ifdef HANDLE_EXCEPTIONS
} /* try..finally */
} __except(EXCEPTION_EXECUTE_HANDLER) {
/*
* NT exception handler. If anything went
* wrong in the __try {} section, we will
* end up here.
*/
#if defined(EXCEPTION_MESSAGES) && defined(H263_SUPPORT)
// MessageBox(NULL, "Exception in H263 DriverProc", "Warning", MB_OK);
#elif defined(EXCEPTION_MESSAGES)
// MessageBox(NULL, "Exception in H261 DriverProc", "Warning", MB_OK);
#endif
/*
* Return an error code.
*/
return((MMRESULT)ICERR_INTERNAL);
} /* try..except */
#endif /* HANDLE_EXCEPTIONS */
_SlibDebug(_DEBUG_||_VERBOSE_, ScDebugPrintf("return is %d\n", ret) );
return ret;
}
/*
* Dummy DriverPostReply routine, it does nothing.
* It should never be called on NT.
*/
DriverPostReply(void *client,
DWORD ret,
DWORD arg )
{
return 0;
}
#ifndef INITCRT
#define INITCRT
#endif
#ifdef INITCRT
BOOL WINAPI _CRT_INIT(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
#endif
/*
* This DllEntryPoint is needed on NT in order for
* an application to connect to a dll properly.
*/
DLLEXPORT BOOL WINAPI
DllEntryPoint(
HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpReserved)
{
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
/*
* We're being loaded - save our handle in a global.
*/
ghModule = (HMODULE) hinstDLL;
/*
* Initialize the Critical Section that we use
* to ensure Threads don't stomp on each other.
*/
InitializeCriticalSection( &h263CritSect ) ;
/*
* A Process is also a thread, so deliberately
* fall into DLL_THREAD_ATTACH.
*/
case DLL_THREAD_ATTACH:
/*
* A Thread have been created that may
* be calling this DLL.
* Initialize the C run_time library.
*/
#ifdef INITCRT
if( !_CRT_INIT( hinstDLL, fdwReason, lpReserved ) )
return FALSE ;
#endif /* INITCRT */
break;
case DLL_PROCESS_DETACH:
/*
* We are shutting down. Perform some cleanup
* so that lingering threads won't try to work
* and maybe access violate.
*/
TerminateH263() ;
/*
* Delete the Critical Section that we created
* at load time.
*/
DeleteCriticalSection( &h263CritSect ) ;
/*
* A Process is also a thread so deliberately
* fall through to DLL_THREAD_DETACH.
*/
case DLL_THREAD_DETACH:
/*
* Close down the C run-time library.
*/
#ifdef INITCRT
if( !_CRT_INIT( hinstDLL, fdwReason, lpReserved ) )
return FALSE ;
#endif /* INITCRT */
break;
}
return (TRUE);
}